The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/iwlwifi/mvm/d3.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
    2 /*
    3  * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
    4  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
    5  * Copyright (C) 2016-2017 Intel Deutschland GmbH
    6  */
    7 #include <linux/etherdevice.h>
    8 #include <linux/ip.h>
    9 #include <linux/fs.h>
   10 #include <net/cfg80211.h>
   11 #include <net/ipv6.h>
   12 #include <net/tcp.h>
   13 #include <net/addrconf.h>
   14 #include "iwl-modparams.h"
   15 #include "fw-api.h"
   16 #include "mvm.h"
   17 #include "fw/img.h"
   18 
   19 void iwl_mvm_set_rekey_data(struct ieee80211_hw *hw,
   20                             struct ieee80211_vif *vif,
   21                             struct cfg80211_gtk_rekey_data *data)
   22 {
   23         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
   24         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
   25 
   26         mutex_lock(&mvm->mutex);
   27 
   28         mvmvif->rekey_data.kek_len = data->kek_len;
   29         mvmvif->rekey_data.kck_len = data->kck_len;
   30         memcpy(mvmvif->rekey_data.kek, data->kek, data->kek_len);
   31         memcpy(mvmvif->rekey_data.kck, data->kck, data->kck_len);
   32         mvmvif->rekey_data.akm = data->akm & 0xFF;
   33         mvmvif->rekey_data.replay_ctr =
   34                 cpu_to_le64(be64_to_cpup((const __be64 *)data->replay_ctr));
   35         mvmvif->rekey_data.valid = true;
   36 
   37         mutex_unlock(&mvm->mutex);
   38 }
   39 
   40 #if IS_ENABLED(CONFIG_IPV6)
   41 void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
   42                               struct ieee80211_vif *vif,
   43                               struct inet6_dev *idev)
   44 {
   45         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
   46         struct inet6_ifaddr *ifa;
   47         int idx = 0;
   48 
   49         memset(mvmvif->tentative_addrs, 0, sizeof(mvmvif->tentative_addrs));
   50 
   51         read_lock_bh(&idev->lock);
   52         list_for_each_entry(ifa, &idev->addr_list, if_list) {
   53                 mvmvif->target_ipv6_addrs[idx] = ifa->addr;
   54                 if (ifa->flags & IFA_F_TENTATIVE)
   55                         __set_bit(idx, mvmvif->tentative_addrs);
   56                 idx++;
   57                 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX)
   58                         break;
   59         }
   60         read_unlock_bh(&idev->lock);
   61 
   62         mvmvif->num_target_ipv6_addrs = idx;
   63 }
   64 #endif
   65 
   66 void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
   67                                      struct ieee80211_vif *vif, int idx)
   68 {
   69         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
   70 
   71         mvmvif->tx_key_idx = idx;
   72 }
   73 
   74 static void iwl_mvm_convert_p1k(u16 *p1k, __le16 *out)
   75 {
   76         int i;
   77 
   78         for (i = 0; i < IWL_P1K_SIZE; i++)
   79                 out[i] = cpu_to_le16(p1k[i]);
   80 }
   81 
   82 static const u8 *iwl_mvm_find_max_pn(struct ieee80211_key_conf *key,
   83                                      struct iwl_mvm_key_pn *ptk_pn,
   84                                      struct ieee80211_key_seq *seq,
   85                                      int tid, int queues)
   86 {
   87         const u8 *ret = seq->ccmp.pn;
   88         int i;
   89 
   90         /* get the PN from mac80211, used on the default queue */
   91         ieee80211_get_key_rx_seq(key, tid, seq);
   92 
   93         /* and use the internal data for the other queues */
   94         for (i = 1; i < queues; i++) {
   95                 const u8 *tmp = ptk_pn->q[i].pn[tid];
   96 
   97                 if (memcmp(ret, tmp, IEEE80211_CCMP_PN_LEN) <= 0)
   98                         ret = tmp;
   99         }
  100 
  101         return ret;
  102 }
  103 
  104 struct wowlan_key_reprogram_data {
  105         bool error;
  106         int wep_key_idx;
  107 };
  108 
  109 static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
  110                                         struct ieee80211_vif *vif,
  111                                         struct ieee80211_sta *sta,
  112                                         struct ieee80211_key_conf *key,
  113                                         void *_data)
  114 {
  115         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
  116         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  117         struct wowlan_key_reprogram_data *data = _data;
  118         int ret;
  119 
  120         switch (key->cipher) {
  121         case WLAN_CIPHER_SUITE_WEP40:
  122         case WLAN_CIPHER_SUITE_WEP104: { /* hack it for now */
  123                 struct {
  124                         struct iwl_mvm_wep_key_cmd wep_key_cmd;
  125                         struct iwl_mvm_wep_key wep_key;
  126                 } __packed wkc = {
  127                         .wep_key_cmd.mac_id_n_color =
  128                                 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
  129                                                                 mvmvif->color)),
  130                         .wep_key_cmd.num_keys = 1,
  131                         /* firmware sets STA_KEY_FLG_WEP_13BYTES */
  132                         .wep_key_cmd.decryption_type = STA_KEY_FLG_WEP,
  133                         .wep_key.key_index = key->keyidx,
  134                         .wep_key.key_size = key->keylen,
  135                 };
  136 
  137                 /*
  138                  * This will fail -- the key functions don't set support
  139                  * pairwise WEP keys. However, that's better than silently
  140                  * failing WoWLAN. Or maybe not?
  141                  */
  142                 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
  143                         break;
  144 
  145                 memcpy(&wkc.wep_key.key[3], key->key, key->keylen);
  146                 if (key->keyidx == mvmvif->tx_key_idx) {
  147                         /* TX key must be at offset 0 */
  148                         wkc.wep_key.key_offset = 0;
  149                 } else {
  150                         /* others start at 1 */
  151                         data->wep_key_idx++;
  152                         wkc.wep_key.key_offset = data->wep_key_idx;
  153                 }
  154 
  155                 mutex_lock(&mvm->mutex);
  156                 ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, 0, sizeof(wkc), &wkc);
  157                 data->error = ret != 0;
  158 
  159                 mvm->ptk_ivlen = key->iv_len;
  160                 mvm->ptk_icvlen = key->icv_len;
  161                 mvm->gtk_ivlen = key->iv_len;
  162                 mvm->gtk_icvlen = key->icv_len;
  163                 mutex_unlock(&mvm->mutex);
  164 
  165                 /* don't upload key again */
  166                 return;
  167         }
  168         default:
  169                 data->error = true;
  170                 return;
  171         case WLAN_CIPHER_SUITE_BIP_GMAC_256:
  172         case WLAN_CIPHER_SUITE_BIP_GMAC_128:
  173                 return;
  174         case WLAN_CIPHER_SUITE_AES_CMAC:
  175                 /*
  176                  * Ignore CMAC keys -- the WoWLAN firmware doesn't support them
  177                  * but we also shouldn't abort suspend due to that. It does have
  178                  * support for the IGTK key renewal, but doesn't really use the
  179                  * IGTK for anything. This means we could spuriously wake up or
  180                  * be deauthenticated, but that was considered acceptable.
  181                  */
  182                 return;
  183         case WLAN_CIPHER_SUITE_TKIP:
  184         case WLAN_CIPHER_SUITE_CCMP:
  185         case WLAN_CIPHER_SUITE_GCMP:
  186         case WLAN_CIPHER_SUITE_GCMP_256:
  187                 break;
  188         }
  189 
  190         mutex_lock(&mvm->mutex);
  191         /*
  192          * The D3 firmware hardcodes the key offset 0 as the key it
  193          * uses to transmit packets to the AP, i.e. the PTK.
  194          */
  195         if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
  196                 mvm->ptk_ivlen = key->iv_len;
  197                 mvm->ptk_icvlen = key->icv_len;
  198                 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
  199         } else {
  200                 /*
  201                  * firmware only supports TSC/RSC for a single key,
  202                  * so if there are multiple keep overwriting them
  203                  * with new ones -- this relies on mac80211 doing
  204                  * list_add_tail().
  205                  */
  206                 mvm->gtk_ivlen = key->iv_len;
  207                 mvm->gtk_icvlen = key->icv_len;
  208                 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
  209         }
  210         mutex_unlock(&mvm->mutex);
  211         data->error = ret != 0;
  212 }
  213 
  214 struct wowlan_key_rsc_tsc_data {
  215         struct iwl_wowlan_rsc_tsc_params_cmd_v4 *rsc_tsc;
  216         bool have_rsc_tsc;
  217 };
  218 
  219 static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw *hw,
  220                                             struct ieee80211_vif *vif,
  221                                             struct ieee80211_sta *sta,
  222                                             struct ieee80211_key_conf *key,
  223                                             void *_data)
  224 {
  225         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
  226         struct wowlan_key_rsc_tsc_data *data = _data;
  227         struct aes_sc *aes_sc;
  228         struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
  229         struct ieee80211_key_seq seq;
  230         int i;
  231 
  232         switch (key->cipher) {
  233         default:
  234                 break;
  235         case WLAN_CIPHER_SUITE_TKIP:
  236                 if (sta) {
  237                         u64 pn64;
  238 
  239                         tkip_sc =
  240                            data->rsc_tsc->params.all_tsc_rsc.tkip.unicast_rsc;
  241                         tkip_tx_sc =
  242                                 &data->rsc_tsc->params.all_tsc_rsc.tkip.tsc;
  243 
  244                         pn64 = atomic64_read(&key->tx_pn);
  245                         tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64));
  246                         tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64));
  247                 } else {
  248                         tkip_sc =
  249                           data->rsc_tsc->params.all_tsc_rsc.tkip.multicast_rsc;
  250                 }
  251 
  252                 /*
  253                  * For non-QoS this relies on the fact that both the uCode and
  254                  * mac80211 use TID 0 (as they need to to avoid replay attacks)
  255                  * for checking the IV in the frames.
  256                  */
  257                 for (i = 0; i < IWL_NUM_RSC; i++) {
  258                         ieee80211_get_key_rx_seq(key, i, &seq);
  259                         tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
  260                         tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
  261                 }
  262 
  263                 data->have_rsc_tsc = true;
  264                 break;
  265         case WLAN_CIPHER_SUITE_CCMP:
  266         case WLAN_CIPHER_SUITE_GCMP:
  267         case WLAN_CIPHER_SUITE_GCMP_256:
  268                 if (sta) {
  269                         struct aes_sc *aes_tx_sc;
  270                         u64 pn64;
  271 
  272                         aes_sc =
  273                            data->rsc_tsc->params.all_tsc_rsc.aes.unicast_rsc;
  274                         aes_tx_sc =
  275                                 &data->rsc_tsc->params.all_tsc_rsc.aes.tsc;
  276 
  277                         pn64 = atomic64_read(&key->tx_pn);
  278                         aes_tx_sc->pn = cpu_to_le64(pn64);
  279                 } else {
  280                         aes_sc =
  281                            data->rsc_tsc->params.all_tsc_rsc.aes.multicast_rsc;
  282                 }
  283 
  284                 /*
  285                  * For non-QoS this relies on the fact that both the uCode and
  286                  * mac80211/our RX code use TID 0 for checking the PN.
  287                  */
  288                 if (sta && iwl_mvm_has_new_rx_api(mvm)) {
  289                         struct iwl_mvm_sta *mvmsta;
  290                         struct iwl_mvm_key_pn *ptk_pn;
  291                         const u8 *pn;
  292 
  293                         mvmsta = iwl_mvm_sta_from_mac80211(sta);
  294                         rcu_read_lock();
  295                         ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
  296                         if (WARN_ON(!ptk_pn)) {
  297                                 rcu_read_unlock();
  298                                 break;
  299                         }
  300 
  301                         for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
  302                                 pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i,
  303                                                 mvm->trans->num_rx_queues);
  304                                 aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
  305                                                            ((u64)pn[4] << 8) |
  306                                                            ((u64)pn[3] << 16) |
  307                                                            ((u64)pn[2] << 24) |
  308                                                            ((u64)pn[1] << 32) |
  309                                                            ((u64)pn[0] << 40));
  310                         }
  311 
  312                         rcu_read_unlock();
  313                 } else {
  314                         for (i = 0; i < IWL_NUM_RSC; i++) {
  315                                 u8 *pn = seq.ccmp.pn;
  316 
  317                                 ieee80211_get_key_rx_seq(key, i, &seq);
  318                                 aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
  319                                                            ((u64)pn[4] << 8) |
  320                                                            ((u64)pn[3] << 16) |
  321                                                            ((u64)pn[2] << 24) |
  322                                                            ((u64)pn[1] << 32) |
  323                                                            ((u64)pn[0] << 40));
  324                         }
  325                 }
  326                 data->have_rsc_tsc = true;
  327                 break;
  328         }
  329 }
  330 
  331 struct wowlan_key_rsc_v5_data {
  332         struct iwl_wowlan_rsc_tsc_params_cmd *rsc;
  333         bool have_rsc;
  334         int gtks;
  335         int gtk_ids[4];
  336 };
  337 
  338 static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw *hw,
  339                                            struct ieee80211_vif *vif,
  340                                            struct ieee80211_sta *sta,
  341                                            struct ieee80211_key_conf *key,
  342                                            void *_data)
  343 {
  344         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
  345         struct wowlan_key_rsc_v5_data *data = _data;
  346         struct ieee80211_key_seq seq;
  347         __le64 *rsc;
  348         int i;
  349 
  350         /* only for ciphers that can be PTK/GTK */
  351         switch (key->cipher) {
  352         default:
  353                 return;
  354         case WLAN_CIPHER_SUITE_TKIP:
  355         case WLAN_CIPHER_SUITE_CCMP:
  356         case WLAN_CIPHER_SUITE_GCMP:
  357         case WLAN_CIPHER_SUITE_GCMP_256:
  358                 break;
  359         }
  360 
  361         if (sta) {
  362                 rsc = data->rsc->ucast_rsc;
  363         } else {
  364                 if (WARN_ON(data->gtks >= ARRAY_SIZE(data->gtk_ids)))
  365                         return;
  366                 data->gtk_ids[data->gtks] = key->keyidx;
  367                 rsc = data->rsc->mcast_rsc[data->gtks % 2];
  368                 if (WARN_ON(key->keyidx >=
  369                                 ARRAY_SIZE(data->rsc->mcast_key_id_map)))
  370                         return;
  371                 data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2;
  372                 if (data->gtks >= 2) {
  373                         int prev = data->gtks - 2;
  374                         int prev_idx = data->gtk_ids[prev];
  375 
  376                         data->rsc->mcast_key_id_map[prev_idx] =
  377                                 IWL_MCAST_KEY_MAP_INVALID;
  378                 }
  379                 data->gtks++;
  380         }
  381 
  382         switch (key->cipher) {
  383         default:
  384                 WARN_ON(1);
  385                 break;
  386         case WLAN_CIPHER_SUITE_TKIP:
  387 
  388                 /*
  389                  * For non-QoS this relies on the fact that both the uCode and
  390                  * mac80211 use TID 0 (as they need to to avoid replay attacks)
  391                  * for checking the IV in the frames.
  392                  */
  393                 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
  394                         ieee80211_get_key_rx_seq(key, i, &seq);
  395 
  396                         rsc[i] = cpu_to_le64(((u64)seq.tkip.iv32 << 16) |
  397                                              seq.tkip.iv16);
  398                 }
  399 
  400                 data->have_rsc = true;
  401                 break;
  402         case WLAN_CIPHER_SUITE_CCMP:
  403         case WLAN_CIPHER_SUITE_GCMP:
  404         case WLAN_CIPHER_SUITE_GCMP_256:
  405                 /*
  406                  * For non-QoS this relies on the fact that both the uCode and
  407                  * mac80211/our RX code use TID 0 for checking the PN.
  408                  */
  409                 if (sta) {
  410                         struct iwl_mvm_sta *mvmsta;
  411                         struct iwl_mvm_key_pn *ptk_pn;
  412                         const u8 *pn;
  413 
  414                         mvmsta = iwl_mvm_sta_from_mac80211(sta);
  415                         rcu_read_lock();
  416                         ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
  417                         if (WARN_ON(!ptk_pn)) {
  418                                 rcu_read_unlock();
  419                                 break;
  420                         }
  421 
  422                         for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
  423                                 pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i,
  424                                                 mvm->trans->num_rx_queues);
  425                                 rsc[i] = cpu_to_le64((u64)pn[5] |
  426                                                      ((u64)pn[4] << 8) |
  427                                                      ((u64)pn[3] << 16) |
  428                                                      ((u64)pn[2] << 24) |
  429                                                      ((u64)pn[1] << 32) |
  430                                                      ((u64)pn[0] << 40));
  431                         }
  432 
  433                         rcu_read_unlock();
  434                 } else {
  435                         for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
  436                                 u8 *pn = seq.ccmp.pn;
  437 
  438                                 ieee80211_get_key_rx_seq(key, i, &seq);
  439                                 rsc[i] = cpu_to_le64((u64)pn[5] |
  440                                                      ((u64)pn[4] << 8) |
  441                                                      ((u64)pn[3] << 16) |
  442                                                      ((u64)pn[2] << 24) |
  443                                                      ((u64)pn[1] << 32) |
  444                                                      ((u64)pn[0] << 40));
  445                         }
  446                 }
  447                 data->have_rsc = true;
  448                 break;
  449         }
  450 }
  451 
  452 static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
  453                                          struct ieee80211_vif *vif)
  454 {
  455         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  456         int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TSC_RSC_PARAM,
  457                                         IWL_FW_CMD_VER_UNKNOWN);
  458         int ret;
  459 
  460         if (ver == 5) {
  461                 struct wowlan_key_rsc_v5_data data = {};
  462                 int i;
  463 
  464                 data.rsc = kmalloc(sizeof(*data.rsc), GFP_KERNEL);
  465                 if (!data.rsc)
  466                         return -ENOMEM;
  467 
  468                 memset(data.rsc, 0xff, sizeof(*data.rsc));
  469 
  470                 for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++)
  471                         data.rsc->mcast_key_id_map[i] =
  472                                 IWL_MCAST_KEY_MAP_INVALID;
  473                 data.rsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
  474 
  475                 ieee80211_iter_keys(mvm->hw, vif,
  476                                     iwl_mvm_wowlan_get_rsc_v5_data,
  477                                     &data);
  478 
  479                 if (data.have_rsc)
  480                         ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
  481                                                    CMD_ASYNC, sizeof(*data.rsc),
  482                                                    data.rsc);
  483                 else
  484                         ret = 0;
  485                 kfree(data.rsc);
  486         } else if (ver == 4 || ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
  487                 struct wowlan_key_rsc_tsc_data data = {};
  488                 int size;
  489 
  490                 data.rsc_tsc = kzalloc(sizeof(*data.rsc_tsc), GFP_KERNEL);
  491                 if (!data.rsc_tsc)
  492                         return -ENOMEM;
  493 
  494                 if (ver == 4) {
  495                         size = sizeof(*data.rsc_tsc);
  496                         data.rsc_tsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
  497                 } else {
  498                         /* ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN */
  499                         size = sizeof(data.rsc_tsc->params);
  500                 }
  501 
  502                 ieee80211_iter_keys(mvm->hw, vif,
  503                                     iwl_mvm_wowlan_get_rsc_tsc_data,
  504                                     &data);
  505 
  506                 if (data.have_rsc_tsc)
  507                         ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
  508                                                    CMD_ASYNC, size,
  509                                                    data.rsc_tsc);
  510                 else
  511                         ret = 0;
  512                 kfree(data.rsc_tsc);
  513         } else {
  514                 ret = 0;
  515                 WARN_ON_ONCE(1);
  516         }
  517 
  518         return ret;
  519 }
  520 
  521 struct wowlan_key_tkip_data {
  522         struct iwl_wowlan_tkip_params_cmd tkip;
  523         bool have_tkip_keys;
  524 };
  525 
  526 static void iwl_mvm_wowlan_get_tkip_data(struct ieee80211_hw *hw,
  527                                          struct ieee80211_vif *vif,
  528                                          struct ieee80211_sta *sta,
  529                                          struct ieee80211_key_conf *key,
  530                                          void *_data)
  531 {
  532         struct wowlan_key_tkip_data *data = _data;
  533         struct iwl_p1k_cache *rx_p1ks;
  534         u8 *rx_mic_key;
  535         struct ieee80211_key_seq seq;
  536         u32 cur_rx_iv32 = 0;
  537         u16 p1k[IWL_P1K_SIZE];
  538         int i;
  539 
  540         switch (key->cipher) {
  541         default:
  542                 break;
  543         case WLAN_CIPHER_SUITE_TKIP:
  544                 if (sta) {
  545                         u64 pn64;
  546 
  547                         rx_p1ks = data->tkip.rx_uni;
  548 
  549                         pn64 = atomic64_read(&key->tx_pn);
  550 
  551                         ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64),
  552                                                   p1k);
  553                         iwl_mvm_convert_p1k(p1k, data->tkip.tx.p1k);
  554 
  555                         memcpy(data->tkip.mic_keys.tx,
  556                                &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
  557                                IWL_MIC_KEY_SIZE);
  558 
  559                         rx_mic_key = data->tkip.mic_keys.rx_unicast;
  560                 } else {
  561                         rx_p1ks = data->tkip.rx_multi;
  562                         rx_mic_key = data->tkip.mic_keys.rx_mcast;
  563                 }
  564 
  565                 for (i = 0; i < IWL_NUM_RSC; i++) {
  566                         /* wrapping isn't allowed, AP must rekey */
  567                         if (seq.tkip.iv32 > cur_rx_iv32)
  568                                 cur_rx_iv32 = seq.tkip.iv32;
  569                 }
  570 
  571                 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
  572                                           cur_rx_iv32, p1k);
  573                 iwl_mvm_convert_p1k(p1k, rx_p1ks[0].p1k);
  574                 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
  575                                           cur_rx_iv32 + 1, p1k);
  576                 iwl_mvm_convert_p1k(p1k, rx_p1ks[1].p1k);
  577 
  578                 memcpy(rx_mic_key,
  579                        &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
  580                        IWL_MIC_KEY_SIZE);
  581 
  582                 data->have_tkip_keys = true;
  583                 break;
  584         }
  585 }
  586 
  587 struct wowlan_key_gtk_type_iter {
  588         struct iwl_wowlan_kek_kck_material_cmd_v4 *kek_kck_cmd;
  589 };
  590 
  591 static void iwl_mvm_wowlan_gtk_type_iter(struct ieee80211_hw *hw,
  592                                          struct ieee80211_vif *vif,
  593                                          struct ieee80211_sta *sta,
  594                                          struct ieee80211_key_conf *key,
  595                                          void *_data)
  596 {
  597         struct wowlan_key_gtk_type_iter *data = _data;
  598 
  599         switch (key->cipher) {
  600         default:
  601                 return;
  602         case WLAN_CIPHER_SUITE_BIP_GMAC_256:
  603         case WLAN_CIPHER_SUITE_BIP_GMAC_128:
  604                 data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_GCMP);
  605                 return;
  606         case WLAN_CIPHER_SUITE_AES_CMAC:
  607                 data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_CCM);
  608                 return;
  609         case WLAN_CIPHER_SUITE_CCMP:
  610                 if (!sta)
  611                         data->kek_kck_cmd->gtk_cipher =
  612                                 cpu_to_le32(STA_KEY_FLG_CCM);
  613                 break;
  614         case WLAN_CIPHER_SUITE_GCMP:
  615         case WLAN_CIPHER_SUITE_GCMP_256:
  616                 if (!sta)
  617                         data->kek_kck_cmd->gtk_cipher =
  618                                 cpu_to_le32(STA_KEY_FLG_GCMP);
  619                 break;
  620         }
  621 }
  622 
  623 static int iwl_mvm_send_patterns_v1(struct iwl_mvm *mvm,
  624                                     struct cfg80211_wowlan *wowlan)
  625 {
  626         struct iwl_wowlan_patterns_cmd_v1 *pattern_cmd;
  627         struct iwl_host_cmd cmd = {
  628                 .id = WOWLAN_PATTERNS,
  629                 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
  630         };
  631         int i, err;
  632 
  633         if (!wowlan->n_patterns)
  634                 return 0;
  635 
  636         cmd.len[0] = struct_size(pattern_cmd, patterns, wowlan->n_patterns);
  637 
  638         pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
  639         if (!pattern_cmd)
  640                 return -ENOMEM;
  641 
  642         pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);
  643 
  644         for (i = 0; i < wowlan->n_patterns; i++) {
  645                 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
  646 
  647                 memcpy(&pattern_cmd->patterns[i].mask,
  648                        wowlan->patterns[i].mask, mask_len);
  649                 memcpy(&pattern_cmd->patterns[i].pattern,
  650                        wowlan->patterns[i].pattern,
  651                        wowlan->patterns[i].pattern_len);
  652                 pattern_cmd->patterns[i].mask_size = mask_len;
  653                 pattern_cmd->patterns[i].pattern_size =
  654                         wowlan->patterns[i].pattern_len;
  655         }
  656 
  657         cmd.data[0] = pattern_cmd;
  658         err = iwl_mvm_send_cmd(mvm, &cmd);
  659         kfree(pattern_cmd);
  660         return err;
  661 }
  662 
  663 static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
  664                                  struct ieee80211_vif *vif,
  665                                  struct cfg80211_wowlan *wowlan)
  666 {
  667         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  668         struct iwl_wowlan_patterns_cmd *pattern_cmd;
  669         struct iwl_host_cmd cmd = {
  670                 .id = WOWLAN_PATTERNS,
  671                 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
  672         };
  673         int i, err;
  674         int ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
  675                                         IWL_FW_CMD_VER_UNKNOWN);
  676 
  677         if (!wowlan->n_patterns)
  678                 return 0;
  679 
  680         cmd.len[0] = sizeof(*pattern_cmd) +
  681                 wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern_v2);
  682 
  683         pattern_cmd = kzalloc(cmd.len[0], GFP_KERNEL);
  684         if (!pattern_cmd)
  685                 return -ENOMEM;
  686 
  687         pattern_cmd->n_patterns = wowlan->n_patterns;
  688         if (ver >= 3)
  689                 pattern_cmd->sta_id = mvmvif->ap_sta_id;
  690 
  691         for (i = 0; i < wowlan->n_patterns; i++) {
  692                 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
  693 
  694                 pattern_cmd->patterns[i].pattern_type =
  695                         WOWLAN_PATTERN_TYPE_BITMASK;
  696 
  697                 memcpy(&pattern_cmd->patterns[i].u.bitmask.mask,
  698                        wowlan->patterns[i].mask, mask_len);
  699                 memcpy(&pattern_cmd->patterns[i].u.bitmask.pattern,
  700                        wowlan->patterns[i].pattern,
  701                        wowlan->patterns[i].pattern_len);
  702                 pattern_cmd->patterns[i].u.bitmask.mask_size = mask_len;
  703                 pattern_cmd->patterns[i].u.bitmask.pattern_size =
  704                         wowlan->patterns[i].pattern_len;
  705         }
  706 
  707         cmd.data[0] = pattern_cmd;
  708         err = iwl_mvm_send_cmd(mvm, &cmd);
  709         kfree(pattern_cmd);
  710         return err;
  711 }
  712 
  713 static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
  714                                 struct ieee80211_sta *ap_sta)
  715 {
  716         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  717         struct ieee80211_chanctx_conf *ctx;
  718         u8 chains_static, chains_dynamic;
  719         struct cfg80211_chan_def chandef;
  720         int ret, i;
  721         struct iwl_binding_cmd_v1 binding_cmd = {};
  722         struct iwl_time_quota_cmd quota_cmd = {};
  723         struct iwl_time_quota_data *quota;
  724         u32 status;
  725 
  726         if (WARN_ON_ONCE(iwl_mvm_is_cdb_supported(mvm)))
  727                 return -EINVAL;
  728 
  729         /* add back the PHY */
  730         if (WARN_ON(!mvmvif->phy_ctxt))
  731                 return -EINVAL;
  732 
  733         rcu_read_lock();
  734         ctx = rcu_dereference(vif->chanctx_conf);
  735         if (WARN_ON(!ctx)) {
  736                 rcu_read_unlock();
  737                 return -EINVAL;
  738         }
  739         chandef = ctx->def;
  740         chains_static = ctx->rx_chains_static;
  741         chains_dynamic = ctx->rx_chains_dynamic;
  742         rcu_read_unlock();
  743 
  744         ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt, &chandef,
  745                                    chains_static, chains_dynamic);
  746         if (ret)
  747                 return ret;
  748 
  749         /* add back the MAC */
  750         mvmvif->uploaded = false;
  751 
  752         if (WARN_ON(!vif->bss_conf.assoc))
  753                 return -EINVAL;
  754 
  755         ret = iwl_mvm_mac_ctxt_add(mvm, vif);
  756         if (ret)
  757                 return ret;
  758 
  759         /* add back binding - XXX refactor? */
  760         binding_cmd.id_and_color =
  761                 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
  762                                                 mvmvif->phy_ctxt->color));
  763         binding_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
  764         binding_cmd.phy =
  765                 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
  766                                                 mvmvif->phy_ctxt->color));
  767         binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
  768                                                               mvmvif->color));
  769         for (i = 1; i < MAX_MACS_IN_BINDING; i++)
  770                 binding_cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
  771 
  772         status = 0;
  773         ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD,
  774                                           IWL_BINDING_CMD_SIZE_V1, &binding_cmd,
  775                                           &status);
  776         if (ret) {
  777                 IWL_ERR(mvm, "Failed to add binding: %d\n", ret);
  778                 return ret;
  779         }
  780 
  781         if (status) {
  782                 IWL_ERR(mvm, "Binding command failed: %u\n", status);
  783                 return -EIO;
  784         }
  785 
  786         ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false, 0);
  787         if (ret)
  788                 return ret;
  789         rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
  790 
  791         ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
  792         if (ret)
  793                 return ret;
  794 
  795         /* and some quota */
  796         quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, 0);
  797         quota->id_and_color =
  798                 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
  799                                                 mvmvif->phy_ctxt->color));
  800         quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
  801         quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
  802 
  803         for (i = 1; i < MAX_BINDINGS; i++) {
  804                 quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, i);
  805                 quota->id_and_color = cpu_to_le32(FW_CTXT_INVALID);
  806         }
  807 
  808         ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
  809                                    iwl_mvm_quota_cmd_size(mvm), &quota_cmd);
  810         if (ret)
  811                 IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
  812 
  813         if (iwl_mvm_is_lar_supported(mvm) && iwl_mvm_init_fw_regd(mvm))
  814                 IWL_ERR(mvm, "Failed to initialize D3 LAR information\n");
  815 
  816         return 0;
  817 }
  818 
  819 static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
  820                                        struct ieee80211_vif *vif)
  821 {
  822         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  823         struct iwl_nonqos_seq_query_cmd query_cmd = {
  824                 .get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_GET),
  825                 .mac_id_n_color =
  826                         cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
  827                                                         mvmvif->color)),
  828         };
  829         struct iwl_host_cmd cmd = {
  830                 .id = NON_QOS_TX_COUNTER_CMD,
  831                 .flags = CMD_WANT_SKB,
  832         };
  833         int err;
  834         u32 size;
  835 
  836         cmd.data[0] = &query_cmd;
  837         cmd.len[0] = sizeof(query_cmd);
  838 
  839         err = iwl_mvm_send_cmd(mvm, &cmd);
  840         if (err)
  841                 return err;
  842 
  843         size = iwl_rx_packet_payload_len(cmd.resp_pkt);
  844         if (size < sizeof(__le16)) {
  845                 err = -EINVAL;
  846         } else {
  847                 err = le16_to_cpup((__le16 *)cmd.resp_pkt->data);
  848                 /* firmware returns next, not last-used seqno */
  849                 err = (u16) (err - 0x10);
  850         }
  851 
  852         iwl_free_resp(&cmd);
  853         return err;
  854 }
  855 
  856 void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
  857 {
  858         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  859         struct iwl_nonqos_seq_query_cmd query_cmd = {
  860                 .get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_SET),
  861                 .mac_id_n_color =
  862                         cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
  863                                                         mvmvif->color)),
  864                 .value = cpu_to_le16(mvmvif->seqno),
  865         };
  866 
  867         /* return if called during restart, not resume from D3 */
  868         if (!mvmvif->seqno_valid)
  869                 return;
  870 
  871         mvmvif->seqno_valid = false;
  872 
  873         if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, 0,
  874                                  sizeof(query_cmd), &query_cmd))
  875                 IWL_ERR(mvm, "failed to set non-QoS seqno\n");
  876 }
  877 
  878 static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm)
  879 {
  880         iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
  881 
  882         iwl_mvm_stop_device(mvm);
  883         /*
  884          * Set the HW restart bit -- this is mostly true as we're
  885          * going to load new firmware and reprogram that, though
  886          * the reprogramming is going to be manual to avoid adding
  887          * all the MACs that aren't support.
  888          * We don't have to clear up everything though because the
  889          * reprogramming is manual. When we resume, we'll actually
  890          * go through a proper restart sequence again to switch
  891          * back to the runtime firmware image.
  892          */
  893         set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
  894 
  895         /* the fw is reset, so all the keys are cleared */
  896         memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
  897 
  898         mvm->ptk_ivlen = 0;
  899         mvm->ptk_icvlen = 0;
  900         mvm->ptk_ivlen = 0;
  901         mvm->ptk_icvlen = 0;
  902 
  903         return iwl_mvm_load_d3_fw(mvm);
  904 }
  905 
  906 static int
  907 iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
  908                           struct cfg80211_wowlan *wowlan,
  909                           struct iwl_wowlan_config_cmd *wowlan_config_cmd,
  910                           struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
  911                           struct ieee80211_sta *ap_sta)
  912 {
  913         struct iwl_mvm_sta *mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
  914 
  915         /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
  916 
  917         wowlan_config_cmd->is_11n_connection =
  918                                         ap_sta->deflink.ht_cap.ht_supported;
  919         wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
  920                 ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
  921 
  922         if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) < 6) {
  923                 /* Query the last used seqno and set it */
  924                 int ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
  925 
  926                 if (ret < 0)
  927                         return ret;
  928 
  929                 wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret);
  930         }
  931 
  932         iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, wowlan_config_cmd);
  933 
  934         if (wowlan->disconnect)
  935                 wowlan_config_cmd->wakeup_filter |=
  936                         cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
  937                                     IWL_WOWLAN_WAKEUP_LINK_CHANGE);
  938         if (wowlan->magic_pkt)
  939                 wowlan_config_cmd->wakeup_filter |=
  940                         cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
  941         if (wowlan->gtk_rekey_failure)
  942                 wowlan_config_cmd->wakeup_filter |=
  943                         cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
  944         if (wowlan->eap_identity_req)
  945                 wowlan_config_cmd->wakeup_filter |=
  946                         cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
  947         if (wowlan->four_way_handshake)
  948                 wowlan_config_cmd->wakeup_filter |=
  949                         cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
  950         if (wowlan->n_patterns)
  951                 wowlan_config_cmd->wakeup_filter |=
  952                         cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
  953 
  954         if (wowlan->rfkill_release)
  955                 wowlan_config_cmd->wakeup_filter |=
  956                         cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
  957 
  958         if (wowlan->tcp) {
  959                 /*
  960                  * Set the "link change" (really "link lost") flag as well
  961                  * since that implies losing the TCP connection.
  962                  */
  963                 wowlan_config_cmd->wakeup_filter |=
  964                         cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
  965                                     IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
  966                                     IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
  967                                     IWL_WOWLAN_WAKEUP_LINK_CHANGE);
  968         }
  969 
  970         if (wowlan->any) {
  971                 wowlan_config_cmd->wakeup_filter |=
  972                         cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
  973                                     IWL_WOWLAN_WAKEUP_LINK_CHANGE |
  974                                     IWL_WOWLAN_WAKEUP_RX_FRAME |
  975                                     IWL_WOWLAN_WAKEUP_BCN_FILTERING);
  976         }
  977 
  978         return 0;
  979 }
  980 
  981 static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
  982                                             struct ieee80211_vif *vif)
  983 {
  984         bool unified = fw_has_capa(&mvm->fw->ucode_capa,
  985                                    IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
  986         struct wowlan_key_reprogram_data key_data = {};
  987         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  988         int ret;
  989         u8 cmd_ver;
  990         size_t cmd_size;
  991 
  992         if (!unified) {
  993                 /*
  994                  * if we have to configure keys, call ieee80211_iter_keys(),
  995                  * as we need non-atomic context in order to take the
  996                  * required locks.
  997                  */
  998                 /*
  999                  * Note that currently we don't use CMD_ASYNC in the iterator.
 1000                  * In case of key_data.configure_keys, all the configured
 1001                  * commands are SYNC, and iwl_mvm_wowlan_program_keys() will
 1002                  * take care of locking/unlocking mvm->mutex.
 1003                  */
 1004                 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
 1005                                     &key_data);
 1006 
 1007                 if (key_data.error)
 1008                         return -EIO;
 1009         }
 1010 
 1011         ret = iwl_mvm_wowlan_config_rsc_tsc(mvm, vif);
 1012         if (ret)
 1013                 return ret;
 1014 
 1015         if (!fw_has_api(&mvm->fw->ucode_capa,
 1016                         IWL_UCODE_TLV_API_TKIP_MIC_KEYS)) {
 1017                 int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TKIP_PARAM,
 1018                                                 IWL_FW_CMD_VER_UNKNOWN);
 1019                 struct wowlan_key_tkip_data tkip_data = {};
 1020                 int size;
 1021 
 1022                 if (ver == 2) {
 1023                         size = sizeof(tkip_data.tkip);
 1024                         tkip_data.tkip.sta_id =
 1025                                 cpu_to_le32(mvmvif->ap_sta_id);
 1026                 } else if (ver == 1 || ver == IWL_FW_CMD_VER_UNKNOWN) {
 1027                         size = sizeof(struct iwl_wowlan_tkip_params_cmd_ver_1);
 1028                 } else {
 1029                         WARN_ON_ONCE(1);
 1030                         return -EINVAL;
 1031                 }
 1032 
 1033                 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_tkip_data,
 1034                                     &tkip_data);
 1035 
 1036                 if (tkip_data.have_tkip_keys) {
 1037                         /* send relevant data according to CMD version */
 1038                         ret = iwl_mvm_send_cmd_pdu(mvm,
 1039                                                    WOWLAN_TKIP_PARAM,
 1040                                                    CMD_ASYNC, size,
 1041                                                    &tkip_data.tkip);
 1042                         if (ret)
 1043                                 return ret;
 1044                 }
 1045         }
 1046 
 1047         /* configure rekey data only if offloaded rekey is supported (d3) */
 1048         if (mvmvif->rekey_data.valid) {
 1049                 struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {};
 1050                 struct iwl_wowlan_kek_kck_material_cmd_v4 *_kek_kck_cmd =
 1051                         &kek_kck_cmd;
 1052                 struct wowlan_key_gtk_type_iter gtk_type_data = {
 1053                         .kek_kck_cmd = _kek_kck_cmd,
 1054                 };
 1055 
 1056                 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
 1057                                                 WOWLAN_KEK_KCK_MATERIAL,
 1058                                                 IWL_FW_CMD_VER_UNKNOWN);
 1059                 if (WARN_ON(cmd_ver != 2 && cmd_ver != 3 && cmd_ver != 4 &&
 1060                             cmd_ver != IWL_FW_CMD_VER_UNKNOWN))
 1061                         return -EINVAL;
 1062 
 1063                 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_gtk_type_iter,
 1064                                     &gtk_type_data);
 1065 
 1066                 memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
 1067                        mvmvif->rekey_data.kck_len);
 1068                 kek_kck_cmd.kck_len = cpu_to_le16(mvmvif->rekey_data.kck_len);
 1069                 memcpy(kek_kck_cmd.kek, mvmvif->rekey_data.kek,
 1070                        mvmvif->rekey_data.kek_len);
 1071                 kek_kck_cmd.kek_len = cpu_to_le16(mvmvif->rekey_data.kek_len);
 1072                 kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr;
 1073                 kek_kck_cmd.akm = cpu_to_le32(mvmvif->rekey_data.akm);
 1074                 kek_kck_cmd.sta_id = cpu_to_le32(mvmvif->ap_sta_id);
 1075 
 1076                 if (cmd_ver == 4) {
 1077                         cmd_size = sizeof(struct iwl_wowlan_kek_kck_material_cmd_v4);
 1078                 } else {
 1079                         if (cmd_ver == 3)
 1080                                 cmd_size =
 1081                                         sizeof(struct iwl_wowlan_kek_kck_material_cmd_v3);
 1082                         else
 1083                                 cmd_size =
 1084                                         sizeof(struct iwl_wowlan_kek_kck_material_cmd_v2);
 1085                         /* skip the sta_id at the beginning */
 1086                         _kek_kck_cmd = (void *)
 1087                                 ((u8 *)_kek_kck_cmd + sizeof(kek_kck_cmd.sta_id));
 1088                 }
 1089 
 1090                 IWL_DEBUG_WOWLAN(mvm, "setting akm %d\n",
 1091                                  mvmvif->rekey_data.akm);
 1092 
 1093                 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_KEK_KCK_MATERIAL,
 1094                                            CMD_ASYNC, cmd_size, _kek_kck_cmd);
 1095                 if (ret)
 1096                         return ret;
 1097         }
 1098 
 1099         return 0;
 1100 }
 1101 
 1102 static int
 1103 iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
 1104                       struct cfg80211_wowlan *wowlan,
 1105                       struct iwl_wowlan_config_cmd *wowlan_config_cmd,
 1106                       struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
 1107                       struct ieee80211_sta *ap_sta)
 1108 {
 1109         int ret;
 1110         bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 1111                                          IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 1112 
 1113         mvm->offload_tid = wowlan_config_cmd->offloading_tid;
 1114 
 1115         if (!unified_image) {
 1116                 ret = iwl_mvm_switch_to_d3(mvm);
 1117                 if (ret)
 1118                         return ret;
 1119 
 1120                 ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
 1121                 if (ret)
 1122                         return ret;
 1123         }
 1124 
 1125         /*
 1126          * This needs to be unlocked due to lock ordering
 1127          * constraints. Since we're in the suspend path
 1128          * that isn't really a problem though.
 1129          */
 1130         mutex_unlock(&mvm->mutex);
 1131         ret = iwl_mvm_wowlan_config_key_params(mvm, vif);
 1132         mutex_lock(&mvm->mutex);
 1133         if (ret)
 1134                 return ret;
 1135 
 1136         ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
 1137                                    sizeof(*wowlan_config_cmd),
 1138                                    wowlan_config_cmd);
 1139         if (ret)
 1140                 return ret;
 1141 
 1142         if (fw_has_api(&mvm->fw->ucode_capa,
 1143                        IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE))
 1144                 ret = iwl_mvm_send_patterns(mvm, vif, wowlan);
 1145         else
 1146                 ret = iwl_mvm_send_patterns_v1(mvm, wowlan);
 1147         if (ret)
 1148                 return ret;
 1149 
 1150         return iwl_mvm_send_proto_offload(mvm, vif, false, true, 0);
 1151 }
 1152 
 1153 static int
 1154 iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
 1155                          struct cfg80211_wowlan *wowlan,
 1156                          struct cfg80211_sched_scan_request *nd_config,
 1157                          struct ieee80211_vif *vif)
 1158 {
 1159         int ret;
 1160         bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 1161                                          IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 1162 
 1163         if (!unified_image) {
 1164                 ret = iwl_mvm_switch_to_d3(mvm);
 1165                 if (ret)
 1166                         return ret;
 1167         } else {
 1168                 /* In theory, we wouldn't have to stop a running sched
 1169                  * scan in order to start another one (for
 1170                  * net-detect).  But in practice this doesn't seem to
 1171                  * work properly, so stop any running sched_scan now.
 1172                  */
 1173                 ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
 1174                 if (ret)
 1175                         return ret;
 1176         }
 1177 
 1178         ret = iwl_mvm_sched_scan_start(mvm, vif, nd_config, &mvm->nd_ies,
 1179                                        IWL_MVM_SCAN_NETDETECT);
 1180         if (ret)
 1181                 return ret;
 1182 
 1183         if (WARN_ON(mvm->nd_match_sets || mvm->nd_channels))
 1184                 return -EBUSY;
 1185 
 1186         /* save the sched scan matchsets... */
 1187         if (nd_config->n_match_sets) {
 1188                 mvm->nd_match_sets = kmemdup(nd_config->match_sets,
 1189                                              sizeof(*nd_config->match_sets) *
 1190                                              nd_config->n_match_sets,
 1191                                              GFP_KERNEL);
 1192                 if (mvm->nd_match_sets)
 1193                         mvm->n_nd_match_sets = nd_config->n_match_sets;
 1194         }
 1195 
 1196         /* ...and the sched scan channels for later reporting */
 1197         mvm->nd_channels = kmemdup(nd_config->channels,
 1198                                    sizeof(*nd_config->channels) *
 1199                                    nd_config->n_channels,
 1200                                    GFP_KERNEL);
 1201         if (mvm->nd_channels)
 1202                 mvm->n_nd_channels = nd_config->n_channels;
 1203 
 1204         return 0;
 1205 }
 1206 
 1207 static void iwl_mvm_free_nd(struct iwl_mvm *mvm)
 1208 {
 1209         kfree(mvm->nd_match_sets);
 1210         mvm->nd_match_sets = NULL;
 1211         mvm->n_nd_match_sets = 0;
 1212         kfree(mvm->nd_channels);
 1213         mvm->nd_channels = NULL;
 1214         mvm->n_nd_channels = 0;
 1215 }
 1216 
 1217 static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
 1218                              struct cfg80211_wowlan *wowlan,
 1219                              bool test)
 1220 {
 1221         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 1222         struct ieee80211_vif *vif = NULL;
 1223         struct iwl_mvm_vif *mvmvif = NULL;
 1224         struct ieee80211_sta *ap_sta = NULL;
 1225         struct iwl_d3_manager_config d3_cfg_cmd_data = {
 1226                 /*
 1227                  * Program the minimum sleep time to 10 seconds, as many
 1228                  * platforms have issues processing a wakeup signal while
 1229                  * still being in the process of suspending.
 1230                  */
 1231                 .min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
 1232         };
 1233         struct iwl_host_cmd d3_cfg_cmd = {
 1234                 .id = D3_CONFIG_CMD,
 1235                 .flags = CMD_WANT_SKB | CMD_SEND_IN_D3,
 1236                 .data[0] = &d3_cfg_cmd_data,
 1237                 .len[0] = sizeof(d3_cfg_cmd_data),
 1238         };
 1239         int ret;
 1240         int len __maybe_unused;
 1241         bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 1242                                          IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 1243 
 1244         if (!wowlan) {
 1245                 /*
 1246                  * mac80211 shouldn't get here, but for D3 test
 1247                  * it doesn't warrant a warning
 1248                  */
 1249                 WARN_ON(!test);
 1250                 return -EINVAL;
 1251         }
 1252 
 1253         mutex_lock(&mvm->mutex);
 1254 
 1255         set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
 1256 
 1257         synchronize_net();
 1258 
 1259         vif = iwl_mvm_get_bss_vif(mvm);
 1260         if (IS_ERR_OR_NULL(vif)) {
 1261                 ret = 1;
 1262                 goto out_noreset;
 1263         }
 1264 
 1265         mvmvif = iwl_mvm_vif_from_mac80211(vif);
 1266 
 1267         if (mvmvif->ap_sta_id == IWL_MVM_INVALID_STA) {
 1268                 /* if we're not associated, this must be netdetect */
 1269                 if (!wowlan->nd_config) {
 1270                         ret = 1;
 1271                         goto out_noreset;
 1272                 }
 1273 
 1274                 ret = iwl_mvm_netdetect_config(
 1275                         mvm, wowlan, wowlan->nd_config, vif);
 1276                 if (ret)
 1277                         goto out;
 1278 
 1279                 mvm->net_detect = true;
 1280         } else {
 1281                 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
 1282 
 1283                 wowlan_config_cmd.sta_id = mvmvif->ap_sta_id;
 1284 
 1285                 ap_sta = rcu_dereference_protected(
 1286                         mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
 1287                         lockdep_is_held(&mvm->mutex));
 1288                 if (IS_ERR_OR_NULL(ap_sta)) {
 1289                         ret = -EINVAL;
 1290                         goto out_noreset;
 1291                 }
 1292 
 1293                 ret = iwl_mvm_get_wowlan_config(mvm, wowlan, &wowlan_config_cmd,
 1294                                                 vif, mvmvif, ap_sta);
 1295                 if (ret)
 1296                         goto out_noreset;
 1297                 ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd,
 1298                                             vif, mvmvif, ap_sta);
 1299                 if (ret)
 1300                         goto out;
 1301 
 1302                 mvm->net_detect = false;
 1303         }
 1304 
 1305         ret = iwl_mvm_power_update_device(mvm);
 1306         if (ret)
 1307                 goto out;
 1308 
 1309         ret = iwl_mvm_power_update_mac(mvm);
 1310         if (ret)
 1311                 goto out;
 1312 
 1313 #ifdef CONFIG_IWLWIFI_DEBUGFS
 1314         if (mvm->d3_wake_sysassert)
 1315                 d3_cfg_cmd_data.wakeup_flags |=
 1316                         cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR);
 1317 #endif
 1318 
 1319         /*
 1320          * Prior to 9000 device family the driver needs to stop the dbg
 1321          * recording before entering D3. In later devices the FW stops the
 1322          * recording automatically.
 1323          */
 1324         if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
 1325                 iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true);
 1326 
 1327         mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;
 1328 
 1329         /* must be last -- this switches firmware state */
 1330         ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
 1331         if (ret)
 1332                 goto out;
 1333 #ifdef CONFIG_IWLWIFI_DEBUGFS
 1334         len = iwl_rx_packet_payload_len(d3_cfg_cmd.resp_pkt);
 1335         if (len >= sizeof(u32)) {
 1336                 mvm->d3_test_pme_ptr =
 1337                         le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data);
 1338         }
 1339 #endif
 1340         iwl_free_resp(&d3_cfg_cmd);
 1341 
 1342         clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
 1343 
 1344         ret = iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
 1345  out:
 1346         if (ret < 0) {
 1347                 iwl_mvm_free_nd(mvm);
 1348 
 1349                 if (!unified_image) {
 1350                         if (mvm->fw_restart > 0) {
 1351                                 mvm->fw_restart--;
 1352                                 ieee80211_restart_hw(mvm->hw);
 1353                         }
 1354                 }
 1355 
 1356                 clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
 1357         }
 1358  out_noreset:
 1359         mutex_unlock(&mvm->mutex);
 1360 
 1361         return ret;
 1362 }
 1363 
 1364 int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
 1365 {
 1366         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 1367 
 1368         iwl_mvm_pause_tcm(mvm, true);
 1369 
 1370         iwl_fw_runtime_suspend(&mvm->fwrt);
 1371 
 1372         return __iwl_mvm_suspend(hw, wowlan, false);
 1373 }
 1374 
 1375 /* converted data from the different status responses */
 1376 struct iwl_wowlan_status_data {
 1377         u64 replay_ctr;
 1378         u32 num_of_gtk_rekeys;
 1379         u32 received_beacons;
 1380         u32 wakeup_reasons;
 1381         u32 wake_packet_length;
 1382         u32 wake_packet_bufsize;
 1383         u16 pattern_number;
 1384         u16 non_qos_seq_ctr;
 1385         u16 qos_seq_ctr[8];
 1386         u8 tid_tear_down;
 1387 
 1388         struct {
 1389                 /* including RX MIC key for TKIP */
 1390                 u8 key[WOWLAN_KEY_MAX_SIZE];
 1391                 u8 len;
 1392                 u8 flags;
 1393         } gtk;
 1394 
 1395         struct {
 1396                 /*
 1397                  * We store both the TKIP and AES representations
 1398                  * coming from the firmware because we decode the
 1399                  * data from there before we iterate the keys and
 1400                  * know which one we need.
 1401                  */
 1402                 struct {
 1403                         struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
 1404                 } tkip, aes;
 1405 
 1406                 /*
 1407                  * We use -1 for when we have valid data but don't know
 1408                  * the key ID from firmware, and thus it needs to be
 1409                  * installed with the last key (depending on rekeying).
 1410                  */
 1411                 s8 key_id;
 1412                 bool valid;
 1413         } gtk_seq[2];
 1414 
 1415         struct {
 1416                 /* Same as above */
 1417                 struct {
 1418                         struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
 1419                         u64 tx_pn;
 1420                 } tkip, aes;
 1421         } ptk;
 1422 
 1423         struct {
 1424                 u64 ipn;
 1425                 u8 key[WOWLAN_KEY_MAX_SIZE];
 1426                 u8 len;
 1427                 u8 flags;
 1428         } igtk;
 1429 
 1430         u8 wake_packet[];
 1431 };
 1432 
 1433 static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
 1434                                           struct ieee80211_vif *vif,
 1435                                           struct iwl_wowlan_status_data *status)
 1436 {
 1437         struct sk_buff *pkt = NULL;
 1438         struct cfg80211_wowlan_wakeup wakeup = {
 1439                 .pattern_idx = -1,
 1440         };
 1441         struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
 1442         u32 reasons = status->wakeup_reasons;
 1443 
 1444         if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
 1445                 wakeup_report = NULL;
 1446                 goto report;
 1447         }
 1448 
 1449         pm_wakeup_event(mvm->dev, 0);
 1450 
 1451         if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
 1452                 wakeup.magic_pkt = true;
 1453 
 1454         if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
 1455                 wakeup.pattern_idx =
 1456                         status->pattern_number;
 1457 
 1458         if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
 1459                        IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
 1460                 wakeup.disconnect = true;
 1461 
 1462         if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
 1463                 wakeup.gtk_rekey_failure = true;
 1464 
 1465         if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
 1466                 wakeup.rfkill_release = true;
 1467 
 1468         if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
 1469                 wakeup.eap_identity_req = true;
 1470 
 1471         if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
 1472                 wakeup.four_way_handshake = true;
 1473 
 1474         if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
 1475                 wakeup.tcp_connlost = true;
 1476 
 1477         if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
 1478                 wakeup.tcp_nomoretokens = true;
 1479 
 1480         if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
 1481                 wakeup.tcp_match = true;
 1482 
 1483         if (status->wake_packet_bufsize) {
 1484                 int pktsize = status->wake_packet_bufsize;
 1485                 int pktlen = status->wake_packet_length;
 1486                 const u8 *pktdata = status->wake_packet;
 1487                 const struct ieee80211_hdr *hdr = (const void *)pktdata;
 1488                 int truncated = pktlen - pktsize;
 1489 
 1490                 /* this would be a firmware bug */
 1491                 if (WARN_ON_ONCE(truncated < 0))
 1492                         truncated = 0;
 1493 
 1494                 if (ieee80211_is_data(hdr->frame_control)) {
 1495                         int hdrlen = ieee80211_hdrlen(hdr->frame_control);
 1496                         int ivlen = 0, icvlen = 4; /* also FCS */
 1497 
 1498                         pkt = alloc_skb(pktsize, GFP_KERNEL);
 1499                         if (!pkt)
 1500                                 goto report;
 1501 
 1502                         skb_put_data(pkt, pktdata, hdrlen);
 1503                         pktdata += hdrlen;
 1504                         pktsize -= hdrlen;
 1505 
 1506                         if (ieee80211_has_protected(hdr->frame_control)) {
 1507                                 /*
 1508                                  * This is unlocked and using gtk_i(c)vlen,
 1509                                  * but since everything is under RTNL still
 1510                                  * that's not really a problem - changing
 1511                                  * it would be difficult.
 1512                                  */
 1513                                 if (is_multicast_ether_addr(hdr->addr1)) {
 1514                                         ivlen = mvm->gtk_ivlen;
 1515                                         icvlen += mvm->gtk_icvlen;
 1516                                 } else {
 1517                                         ivlen = mvm->ptk_ivlen;
 1518                                         icvlen += mvm->ptk_icvlen;
 1519                                 }
 1520                         }
 1521 
 1522                         /* if truncated, FCS/ICV is (partially) gone */
 1523                         if (truncated >= icvlen) {
 1524                                 icvlen = 0;
 1525                                 truncated -= icvlen;
 1526                         } else {
 1527                                 icvlen -= truncated;
 1528                                 truncated = 0;
 1529                         }
 1530 
 1531                         pktsize -= ivlen + icvlen;
 1532                         pktdata += ivlen;
 1533 
 1534                         skb_put_data(pkt, pktdata, pktsize);
 1535 
 1536                         if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
 1537                                 goto report;
 1538                         wakeup.packet = pkt->data;
 1539                         wakeup.packet_present_len = pkt->len;
 1540                         wakeup.packet_len = pkt->len - truncated;
 1541                         wakeup.packet_80211 = false;
 1542                 } else {
 1543                         int fcslen = 4;
 1544 
 1545                         if (truncated >= 4) {
 1546                                 truncated -= 4;
 1547                                 fcslen = 0;
 1548                         } else {
 1549                                 fcslen -= truncated;
 1550                                 truncated = 0;
 1551                         }
 1552                         pktsize -= fcslen;
 1553                         wakeup.packet = status->wake_packet;
 1554                         wakeup.packet_present_len = pktsize;
 1555                         wakeup.packet_len = pktlen - truncated;
 1556                         wakeup.packet_80211 = true;
 1557                 }
 1558         }
 1559 
 1560  report:
 1561         ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
 1562         kfree_skb(pkt);
 1563 }
 1564 
 1565 static void iwl_mvm_le64_to_aes_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
 1566 {
 1567         u64 pn = le64_to_cpu(le_pn);
 1568 
 1569         seq->ccmp.pn[0] = pn >> 40;
 1570         seq->ccmp.pn[1] = pn >> 32;
 1571         seq->ccmp.pn[2] = pn >> 24;
 1572         seq->ccmp.pn[3] = pn >> 16;
 1573         seq->ccmp.pn[4] = pn >> 8;
 1574         seq->ccmp.pn[5] = pn;
 1575 }
 1576 
 1577 static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
 1578                                   struct ieee80211_key_seq *seq)
 1579 {
 1580         iwl_mvm_le64_to_aes_seq(sc->pn, seq);
 1581 }
 1582 
 1583 static void iwl_mvm_le64_to_tkip_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
 1584 {
 1585         u64 pn = le64_to_cpu(le_pn);
 1586 
 1587         seq->tkip.iv16 = (u16)pn;
 1588         seq->tkip.iv32 = (u32)(pn >> 16);
 1589 }
 1590 
 1591 static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc,
 1592                                    struct ieee80211_key_seq *seq)
 1593 {
 1594         seq->tkip.iv32 = le32_to_cpu(sc->iv32);
 1595         seq->tkip.iv16 = le16_to_cpu(sc->iv16);
 1596 }
 1597 
 1598 static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf *key,
 1599                                         struct ieee80211_key_seq *seq)
 1600 {
 1601         int tid;
 1602 
 1603         for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
 1604                 ieee80211_set_key_rx_seq(key, tid, &seq[tid]);
 1605 }
 1606 
 1607 static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm *mvm,
 1608                                        struct iwl_wowlan_status_data *status,
 1609                                        struct ieee80211_sta *sta,
 1610                                        struct ieee80211_key_conf *key)
 1611 {
 1612         struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 1613         struct iwl_mvm_key_pn *ptk_pn;
 1614         int tid;
 1615 
 1616         iwl_mvm_set_key_rx_seq_tids(key, status->ptk.aes.seq);
 1617 
 1618         if (!iwl_mvm_has_new_rx_api(mvm))
 1619                 return;
 1620 
 1621 
 1622         rcu_read_lock();
 1623         ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
 1624         if (WARN_ON(!ptk_pn)) {
 1625                 rcu_read_unlock();
 1626                 return;
 1627         }
 1628 
 1629         for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
 1630                 int i;
 1631 
 1632                 for (i = 1; i < mvm->trans->num_rx_queues; i++)
 1633                         memcpy(ptk_pn->q[i].pn[tid],
 1634                                status->ptk.aes.seq[tid].ccmp.pn,
 1635                                IEEE80211_CCMP_PN_LEN);
 1636         }
 1637         rcu_read_unlock();
 1638 }
 1639 
 1640 static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
 1641                                          union iwl_all_tsc_rsc *sc)
 1642 {
 1643         int i;
 1644 
 1645         BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
 1646         BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
 1647 
 1648         /* GTK RX counters */
 1649         for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
 1650                 iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i],
 1651                                        &status->gtk_seq[0].tkip.seq[i]);
 1652                 iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i],
 1653                                       &status->gtk_seq[0].aes.seq[i]);
 1654         }
 1655         status->gtk_seq[0].valid = true;
 1656         status->gtk_seq[0].key_id = -1;
 1657 
 1658         /* PTK TX counter */
 1659         status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) |
 1660                                  ((u64)le32_to_cpu(sc->tkip.tsc.iv32) << 16);
 1661         status->ptk.aes.tx_pn = le64_to_cpu(sc->aes.tsc.pn);
 1662 
 1663         /* PTK RX counters */
 1664         for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
 1665                 iwl_mvm_tkip_sc_to_seq(&sc->tkip.unicast_rsc[i],
 1666                                        &status->ptk.tkip.seq[i]);
 1667                 iwl_mvm_aes_sc_to_seq(&sc->aes.unicast_rsc[i],
 1668                                       &status->ptk.aes.seq[i]);
 1669         }
 1670 }
 1671 
 1672 static void
 1673 iwl_mvm_convert_key_counters_v5_gtk_seq(struct iwl_wowlan_status_data *status,
 1674                                         struct iwl_wowlan_all_rsc_tsc_v5 *sc,
 1675                                         unsigned int idx, unsigned int key_id)
 1676 {
 1677         int tid;
 1678 
 1679         for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
 1680                 iwl_mvm_le64_to_tkip_seq(sc->mcast_rsc[idx][tid],
 1681                                          &status->gtk_seq[idx].tkip.seq[tid]);
 1682                 iwl_mvm_le64_to_aes_seq(sc->mcast_rsc[idx][tid],
 1683                                         &status->gtk_seq[idx].aes.seq[tid]);
 1684         }
 1685 
 1686         status->gtk_seq[idx].valid = true;
 1687         status->gtk_seq[idx].key_id = key_id;
 1688 }
 1689 
 1690 static void
 1691 iwl_mvm_convert_key_counters_v5(struct iwl_wowlan_status_data *status,
 1692                                 struct iwl_wowlan_all_rsc_tsc_v5 *sc)
 1693 {
 1694         int i, tid;
 1695 
 1696         BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
 1697         BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
 1698         BUILD_BUG_ON(ARRAY_SIZE(sc->mcast_rsc) != ARRAY_SIZE(status->gtk_seq));
 1699 
 1700         /* GTK RX counters */
 1701         for (i = 0; i < ARRAY_SIZE(sc->mcast_key_id_map); i++) {
 1702                 u8 entry = sc->mcast_key_id_map[i];
 1703 
 1704                 if (entry < ARRAY_SIZE(sc->mcast_rsc))
 1705                         iwl_mvm_convert_key_counters_v5_gtk_seq(status, sc,
 1706                                                                 entry, i);
 1707         }
 1708 
 1709         /* PTK TX counters not needed, assigned in device */
 1710 
 1711         /* PTK RX counters */
 1712         for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
 1713                 iwl_mvm_le64_to_tkip_seq(sc->ucast_rsc[tid],
 1714                                          &status->ptk.tkip.seq[tid]);
 1715                 iwl_mvm_le64_to_aes_seq(sc->ucast_rsc[tid],
 1716                                         &status->ptk.aes.seq[tid]);
 1717         }
 1718 }
 1719 
 1720 static void iwl_mvm_set_key_rx_seq_idx(struct ieee80211_key_conf *key,
 1721                                        struct iwl_wowlan_status_data *status,
 1722                                        int idx)
 1723 {
 1724         switch (key->cipher) {
 1725         case WLAN_CIPHER_SUITE_CCMP:
 1726         case WLAN_CIPHER_SUITE_GCMP:
 1727         case WLAN_CIPHER_SUITE_GCMP_256:
 1728                 iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].aes.seq);
 1729                 break;
 1730         case WLAN_CIPHER_SUITE_TKIP:
 1731                 iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].tkip.seq);
 1732                 break;
 1733         default:
 1734                 WARN_ON(1);
 1735         }
 1736 }
 1737 
 1738 static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
 1739                                    struct iwl_wowlan_status_data *status,
 1740                                    bool installed)
 1741 {
 1742         int i;
 1743 
 1744         for (i = 0; i < ARRAY_SIZE(status->gtk_seq); i++) {
 1745                 if (!status->gtk_seq[i].valid)
 1746                         continue;
 1747 
 1748                 /* Handle the case where we know the key ID */
 1749                 if (status->gtk_seq[i].key_id == key->keyidx) {
 1750                         s8 new_key_id = -1;
 1751 
 1752                         if (status->num_of_gtk_rekeys)
 1753                                 new_key_id = status->gtk.flags &
 1754                                                 IWL_WOWLAN_GTK_IDX_MASK;
 1755 
 1756                         /* Don't install a new key's value to an old key */
 1757                         if (new_key_id != key->keyidx)
 1758                                 iwl_mvm_set_key_rx_seq_idx(key, status, i);
 1759                         continue;
 1760                 }
 1761 
 1762                 /* handle the case where we didn't, last key only */
 1763                 if (status->gtk_seq[i].key_id == -1 &&
 1764                     (!status->num_of_gtk_rekeys || installed))
 1765                         iwl_mvm_set_key_rx_seq_idx(key, status, i);
 1766         }
 1767 }
 1768 
 1769 struct iwl_mvm_d3_gtk_iter_data {
 1770         struct iwl_mvm *mvm;
 1771         struct iwl_wowlan_status_data *status;
 1772         void *last_gtk;
 1773         u32 cipher;
 1774         bool find_phase, unhandled_cipher;
 1775         int num_keys;
 1776 };
 1777 
 1778 static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
 1779                                    struct ieee80211_vif *vif,
 1780                                    struct ieee80211_sta *sta,
 1781                                    struct ieee80211_key_conf *key,
 1782                                    void *_data)
 1783 {
 1784         struct iwl_mvm_d3_gtk_iter_data *data = _data;
 1785         struct iwl_wowlan_status_data *status = data->status;
 1786 
 1787         if (data->unhandled_cipher)
 1788                 return;
 1789 
 1790         switch (key->cipher) {
 1791         case WLAN_CIPHER_SUITE_WEP40:
 1792         case WLAN_CIPHER_SUITE_WEP104:
 1793                 /* ignore WEP completely, nothing to do */
 1794                 return;
 1795         case WLAN_CIPHER_SUITE_CCMP:
 1796         case WLAN_CIPHER_SUITE_GCMP:
 1797         case WLAN_CIPHER_SUITE_GCMP_256:
 1798         case WLAN_CIPHER_SUITE_TKIP:
 1799                 /* we support these */
 1800                 break;
 1801         default:
 1802                 /* everything else (even CMAC for MFP) - disconnect from AP */
 1803                 data->unhandled_cipher = true;
 1804                 return;
 1805         }
 1806 
 1807         data->num_keys++;
 1808 
 1809         /*
 1810          * pairwise key - update sequence counters only;
 1811          * note that this assumes no TDLS sessions are active
 1812          */
 1813         if (sta) {
 1814                 if (data->find_phase)
 1815                         return;
 1816 
 1817                 switch (key->cipher) {
 1818                 case WLAN_CIPHER_SUITE_CCMP:
 1819                 case WLAN_CIPHER_SUITE_GCMP:
 1820                 case WLAN_CIPHER_SUITE_GCMP_256:
 1821                         atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn);
 1822                         iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key);
 1823                         break;
 1824                 case WLAN_CIPHER_SUITE_TKIP:
 1825                         atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn);
 1826                         iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq);
 1827                         break;
 1828                 }
 1829 
 1830                 /* that's it for this key */
 1831                 return;
 1832         }
 1833 
 1834         if (data->find_phase) {
 1835                 data->last_gtk = key;
 1836                 data->cipher = key->cipher;
 1837                 return;
 1838         }
 1839 
 1840         if (data->status->num_of_gtk_rekeys)
 1841                 ieee80211_remove_key(key);
 1842 
 1843         if (data->last_gtk == key)
 1844                 iwl_mvm_set_key_rx_seq(key, data->status, false);
 1845 }
 1846 
 1847 static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
 1848                                           struct ieee80211_vif *vif,
 1849                                           struct iwl_wowlan_status_data *status)
 1850 {
 1851         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 1852         struct iwl_mvm_d3_gtk_iter_data gtkdata = {
 1853                 .mvm = mvm,
 1854                 .status = status,
 1855         };
 1856         u32 disconnection_reasons =
 1857                 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
 1858                 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
 1859 
 1860         if (!status || !vif->bss_conf.bssid)
 1861                 return false;
 1862 
 1863         if (status->wakeup_reasons & disconnection_reasons)
 1864                 return false;
 1865 
 1866         /* find last GTK that we used initially, if any */
 1867         gtkdata.find_phase = true;
 1868         ieee80211_iter_keys(mvm->hw, vif,
 1869                             iwl_mvm_d3_update_keys, &gtkdata);
 1870         /* not trying to keep connections with MFP/unhandled ciphers */
 1871         if (gtkdata.unhandled_cipher)
 1872                 return false;
 1873         if (!gtkdata.num_keys)
 1874                 goto out;
 1875         if (!gtkdata.last_gtk)
 1876                 return false;
 1877 
 1878         /*
 1879          * invalidate all other GTKs that might still exist and update
 1880          * the one that we used
 1881          */
 1882         gtkdata.find_phase = false;
 1883         ieee80211_iter_keys(mvm->hw, vif,
 1884                             iwl_mvm_d3_update_keys, &gtkdata);
 1885 
 1886         IWL_DEBUG_WOWLAN(mvm, "num of GTK rekeying %d\n",
 1887                          status->num_of_gtk_rekeys);
 1888         if (status->num_of_gtk_rekeys) {
 1889                 struct ieee80211_key_conf *key;
 1890                 struct {
 1891                         struct ieee80211_key_conf conf;
 1892                         u8 key[32];
 1893                 } conf = {
 1894                         .conf.cipher = gtkdata.cipher,
 1895                         .conf.keyidx =
 1896                                 status->gtk.flags & IWL_WOWLAN_GTK_IDX_MASK,
 1897                 };
 1898                 __be64 replay_ctr;
 1899 
 1900                 IWL_DEBUG_WOWLAN(mvm,
 1901                                  "Received from FW GTK cipher %d, key index %d\n",
 1902                                  conf.conf.cipher, conf.conf.keyidx);
 1903 
 1904                 BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP);
 1905                 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP);
 1906                 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256);
 1907                 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP);
 1908                 BUILD_BUG_ON(sizeof(conf.key) < sizeof(status->gtk.key));
 1909 
 1910                 memcpy(conf.conf.key, status->gtk.key, sizeof(status->gtk.key));
 1911 
 1912                 switch (gtkdata.cipher) {
 1913                 case WLAN_CIPHER_SUITE_CCMP:
 1914                 case WLAN_CIPHER_SUITE_GCMP:
 1915                         conf.conf.keylen = WLAN_KEY_LEN_CCMP;
 1916                         break;
 1917                 case WLAN_CIPHER_SUITE_GCMP_256:
 1918                         conf.conf.keylen = WLAN_KEY_LEN_GCMP_256;
 1919                         break;
 1920                 case WLAN_CIPHER_SUITE_TKIP:
 1921                         conf.conf.keylen = WLAN_KEY_LEN_TKIP;
 1922                         break;
 1923                 }
 1924 
 1925                 key = ieee80211_gtk_rekey_add(vif, &conf.conf);
 1926                 if (IS_ERR(key))
 1927                         return false;
 1928                 iwl_mvm_set_key_rx_seq(key, status, true);
 1929 
 1930                 replay_ctr = cpu_to_be64(status->replay_ctr);
 1931 
 1932                 ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
 1933                                            (void *)&replay_ctr, GFP_KERNEL);
 1934         }
 1935 
 1936 out:
 1937         if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
 1938                                     WOWLAN_GET_STATUSES, 0) < 10) {
 1939                 mvmvif->seqno_valid = true;
 1940                 /* +0x10 because the set API expects next-to-use, not last-used */
 1941                 mvmvif->seqno = status->non_qos_seq_ctr + 0x10;
 1942         }
 1943 
 1944         return true;
 1945 }
 1946 
 1947 /* Occasionally, templates would be nice. This is one of those times ... */
 1948 #define iwl_mvm_parse_wowlan_status_common(_ver)                        \
 1949 static struct iwl_wowlan_status_data *                                  \
 1950 iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm,        \
 1951                                             struct iwl_wowlan_status_ ##_ver *data,\
 1952                                             int len)                    \
 1953 {                                                                       \
 1954         struct iwl_wowlan_status_data *status;                          \
 1955         int data_size, i;                                               \
 1956                                                                         \
 1957         if (len < sizeof(*data)) {                                      \
 1958                 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");      \
 1959                 return ERR_PTR(-EIO);                                   \
 1960         }                                                               \
 1961                                                                         \
 1962         data_size = ALIGN(le32_to_cpu(data->wake_packet_bufsize), 4);   \
 1963         if (len != sizeof(*data) + data_size) {                         \
 1964                 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");      \
 1965                 return ERR_PTR(-EIO);                                   \
 1966         }                                                               \
 1967                                                                         \
 1968         status = kzalloc(sizeof(*status) + data_size, GFP_KERNEL);      \
 1969         if (!status)                                                    \
 1970                 return ERR_PTR(-ENOMEM);                                \
 1971                                                                         \
 1972         /* copy all the common fields */                                \
 1973         status->replay_ctr = le64_to_cpu(data->replay_ctr);             \
 1974         status->pattern_number = le16_to_cpu(data->pattern_number);     \
 1975         status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr);   \
 1976         for (i = 0; i < 8; i++)                                         \
 1977                 status->qos_seq_ctr[i] =                                \
 1978                         le16_to_cpu(data->qos_seq_ctr[i]);              \
 1979         status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons);     \
 1980         status->num_of_gtk_rekeys =                                     \
 1981                 le32_to_cpu(data->num_of_gtk_rekeys);                   \
 1982         status->received_beacons = le32_to_cpu(data->received_beacons); \
 1983         status->wake_packet_length =                                    \
 1984                 le32_to_cpu(data->wake_packet_length);                  \
 1985         status->wake_packet_bufsize =                                   \
 1986                 le32_to_cpu(data->wake_packet_bufsize);                 \
 1987         memcpy(status->wake_packet, data->wake_packet,                  \
 1988                status->wake_packet_bufsize);                            \
 1989                                                                         \
 1990         return status;                                                  \
 1991 }
 1992 
 1993 iwl_mvm_parse_wowlan_status_common(v6)
 1994 iwl_mvm_parse_wowlan_status_common(v7)
 1995 iwl_mvm_parse_wowlan_status_common(v9)
 1996 iwl_mvm_parse_wowlan_status_common(v12)
 1997 
 1998 static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status,
 1999                                    struct iwl_wowlan_gtk_status_v2 *data)
 2000 {
 2001         BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key));
 2002         BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
 2003                      sizeof(data->tkip_mic_key) >
 2004                      sizeof(status->gtk.key));
 2005 
 2006         status->gtk.len = data->key_len;
 2007         status->gtk.flags = data->key_flags;
 2008 
 2009         memcpy(status->gtk.key, data->key, sizeof(data->key));
 2010 
 2011         /* if it's as long as the TKIP encryption key, copy MIC key */
 2012         if (status->gtk.len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
 2013                 memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
 2014                        data->tkip_mic_key, sizeof(data->tkip_mic_key));
 2015 }
 2016 
 2017 static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data *status,
 2018                                    struct iwl_wowlan_gtk_status_v3 *data)
 2019 {
 2020         /* The parts we need are identical in v2 and v3 */
 2021 #define CHECK(_f) do {                                                  \
 2022         BUILD_BUG_ON(offsetof(struct iwl_wowlan_gtk_status_v2, _f) !=   \
 2023                      offsetof(struct iwl_wowlan_gtk_status_v3, _f));    \
 2024         BUILD_BUG_ON(offsetofend(struct iwl_wowlan_gtk_status_v2, _f) !=\
 2025                      offsetofend(struct iwl_wowlan_gtk_status_v3, _f)); \
 2026 } while (0)
 2027 
 2028         CHECK(key);
 2029         CHECK(key_len);
 2030         CHECK(key_flags);
 2031         CHECK(tkip_mic_key);
 2032 #undef CHECK
 2033 
 2034         iwl_mvm_convert_gtk_v2(status, (void *)data);
 2035 }
 2036 
 2037 static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
 2038                                  struct iwl_wowlan_igtk_status *data)
 2039 {
 2040         const u8 *ipn = data->ipn;
 2041 
 2042         BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key));
 2043 
 2044         status->igtk.len = data->key_len;
 2045         status->igtk.flags = data->key_flags;
 2046 
 2047         memcpy(status->igtk.key, data->key, sizeof(data->key));
 2048 
 2049         status->igtk.ipn = ((u64)ipn[5] <<  0) |
 2050                            ((u64)ipn[4] <<  8) |
 2051                            ((u64)ipn[3] << 16) |
 2052                            ((u64)ipn[2] << 24) |
 2053                            ((u64)ipn[1] << 32) |
 2054                            ((u64)ipn[0] << 40);
 2055 }
 2056 
 2057 static struct iwl_wowlan_status_data *
 2058 iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
 2059 {
 2060         struct iwl_wowlan_status_data *status;
 2061         struct iwl_wowlan_get_status_cmd get_status_cmd = {
 2062                 .sta_id = cpu_to_le32(sta_id),
 2063         };
 2064         struct iwl_host_cmd cmd = {
 2065                 .id = WOWLAN_GET_STATUSES,
 2066                 .flags = CMD_WANT_SKB,
 2067                 .data = { &get_status_cmd, },
 2068                 .len = { sizeof(get_status_cmd), },
 2069         };
 2070         int ret, len;
 2071         u8 notif_ver;
 2072         u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
 2073                                            IWL_FW_CMD_VER_UNKNOWN);
 2074 
 2075         if (cmd_ver == IWL_FW_CMD_VER_UNKNOWN)
 2076                 cmd.len[0] = 0;
 2077 
 2078         lockdep_assert_held(&mvm->mutex);
 2079 
 2080         ret = iwl_mvm_send_cmd(mvm, &cmd);
 2081         if (ret) {
 2082                 IWL_ERR(mvm, "failed to query wakeup status (%d)\n", ret);
 2083                 return ERR_PTR(ret);
 2084         }
 2085 
 2086         len = iwl_rx_packet_payload_len(cmd.resp_pkt);
 2087 
 2088         /* default to 7 (when we have IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL) */
 2089         notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
 2090                                             WOWLAN_GET_STATUSES, 0);
 2091         if (!notif_ver)
 2092                 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
 2093                                                     WOWLAN_GET_STATUSES, 7);
 2094 
 2095         if (!fw_has_api(&mvm->fw->ucode_capa,
 2096                         IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) {
 2097                 struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data;
 2098 
 2099                 status = iwl_mvm_parse_wowlan_status_common_v6(mvm, v6, len);
 2100                 if (IS_ERR(status))
 2101                         goto out_free_resp;
 2102 
 2103                 BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) >
 2104                              sizeof(status->gtk.key));
 2105                 BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
 2106                              sizeof(v6->gtk.tkip_mic_key) >
 2107                              sizeof(status->gtk.key));
 2108 
 2109                 /* copy GTK info to the right place */
 2110                 memcpy(status->gtk.key, v6->gtk.decrypt_key,
 2111                        sizeof(v6->gtk.decrypt_key));
 2112                 memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
 2113                        v6->gtk.tkip_mic_key,
 2114                        sizeof(v6->gtk.tkip_mic_key));
 2115 
 2116                 iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc);
 2117 
 2118                 /* hardcode the key length to 16 since v6 only supports 16 */
 2119                 status->gtk.len = 16;
 2120 
 2121                 /*
 2122                  * The key index only uses 2 bits (values 0 to 3) and
 2123                  * we always set bit 7 which means this is the
 2124                  * currently used key.
 2125                  */
 2126                 status->gtk.flags = v6->gtk.key_index | BIT(7);
 2127         } else if (notif_ver == 7) {
 2128                 struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data;
 2129 
 2130                 status = iwl_mvm_parse_wowlan_status_common_v7(mvm, v7, len);
 2131                 if (IS_ERR(status))
 2132                         goto out_free_resp;
 2133 
 2134                 iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc);
 2135                 iwl_mvm_convert_gtk_v2(status, &v7->gtk[0]);
 2136                 iwl_mvm_convert_igtk(status, &v7->igtk[0]);
 2137         } else if (notif_ver == 9 || notif_ver == 10 || notif_ver == 11) {
 2138                 struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data;
 2139 
 2140                 /* these three command versions have same layout and size, the
 2141                  * difference is only in a few not used (reserved) fields.
 2142                  */
 2143                 status = iwl_mvm_parse_wowlan_status_common_v9(mvm, v9, len);
 2144                 if (IS_ERR(status))
 2145                         goto out_free_resp;
 2146 
 2147                 iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc);
 2148                 iwl_mvm_convert_gtk_v2(status, &v9->gtk[0]);
 2149                 iwl_mvm_convert_igtk(status, &v9->igtk[0]);
 2150 
 2151                 status->tid_tear_down = v9->tid_tear_down;
 2152         } else if (notif_ver == 12) {
 2153                 struct iwl_wowlan_status_v12 *v12 = (void *)cmd.resp_pkt->data;
 2154 
 2155                 status = iwl_mvm_parse_wowlan_status_common_v12(mvm, v12, len);
 2156                 if (IS_ERR(status))
 2157                         goto out_free_resp;
 2158 
 2159                 iwl_mvm_convert_key_counters_v5(status, &v12->gtk[0].sc);
 2160                 iwl_mvm_convert_gtk_v3(status, &v12->gtk[0]);
 2161                 iwl_mvm_convert_igtk(status, &v12->igtk[0]);
 2162 
 2163                 status->tid_tear_down = v12->tid_tear_down;
 2164         } else {
 2165                 IWL_ERR(mvm,
 2166                         "Firmware advertises unknown WoWLAN status response %d!\n",
 2167                         notif_ver);
 2168                 status = ERR_PTR(-EIO);
 2169         }
 2170 
 2171 out_free_resp:
 2172         iwl_free_resp(&cmd);
 2173         return status;
 2174 }
 2175 
 2176 static struct iwl_wowlan_status_data *
 2177 iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, u8 sta_id)
 2178 {
 2179         u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, OFFLOADS_QUERY_CMD,
 2180                                            IWL_FW_CMD_VER_UNKNOWN);
 2181         __le32 station_id = cpu_to_le32(sta_id);
 2182         u32 cmd_size = cmd_ver != IWL_FW_CMD_VER_UNKNOWN ? sizeof(station_id) : 0;
 2183 
 2184         if (!mvm->net_detect) {
 2185                 /* only for tracing for now */
 2186                 int ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0,
 2187                                                cmd_size, &station_id);
 2188                 if (ret)
 2189                         IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret);
 2190         }
 2191 
 2192         return iwl_mvm_send_wowlan_get_status(mvm, sta_id);
 2193 }
 2194 
 2195 /* releases the MVM mutex */
 2196 static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
 2197                                          struct ieee80211_vif *vif)
 2198 {
 2199         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 2200         struct iwl_wowlan_status_data *status;
 2201         int i;
 2202         bool keep;
 2203         struct iwl_mvm_sta *mvm_ap_sta;
 2204 
 2205         status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id);
 2206         if (IS_ERR(status))
 2207                 goto out_unlock;
 2208 
 2209         IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n",
 2210                          status->wakeup_reasons);
 2211 
 2212         /* still at hard-coded place 0 for D3 image */
 2213         mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, 0);
 2214         if (!mvm_ap_sta)
 2215                 goto out_free;
 2216 
 2217         for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
 2218                 u16 seq = status->qos_seq_ctr[i];
 2219                 /* firmware stores last-used value, we store next value */
 2220                 seq += 0x10;
 2221                 mvm_ap_sta->tid_data[i].seq_number = seq;
 2222         }
 2223 
 2224         if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
 2225                 i = mvm->offload_tid;
 2226                 iwl_trans_set_q_ptrs(mvm->trans,
 2227                                      mvm_ap_sta->tid_data[i].txq_id,
 2228                                      mvm_ap_sta->tid_data[i].seq_number >> 4);
 2229         }
 2230 
 2231         /* now we have all the data we need, unlock to avoid mac80211 issues */
 2232         mutex_unlock(&mvm->mutex);
 2233 
 2234         iwl_mvm_report_wakeup_reasons(mvm, vif, status);
 2235 
 2236         keep = iwl_mvm_setup_connection_keep(mvm, vif, status);
 2237 
 2238         kfree(status);
 2239         return keep;
 2240 
 2241 out_free:
 2242         kfree(status);
 2243 out_unlock:
 2244         mutex_unlock(&mvm->mutex);
 2245         return false;
 2246 }
 2247 
 2248 #define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \
 2249                           IWL_SCAN_MAX_PROFILES)
 2250 
 2251 struct iwl_mvm_nd_query_results {
 2252         u32 matched_profiles;
 2253         u8 matches[ND_QUERY_BUF_LEN];
 2254 };
 2255 
 2256 static int
 2257 iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
 2258                                 struct iwl_mvm_nd_query_results *results)
 2259 {
 2260         struct iwl_scan_offload_profiles_query *query;
 2261         struct iwl_host_cmd cmd = {
 2262                 .id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
 2263                 .flags = CMD_WANT_SKB,
 2264         };
 2265         int ret, len;
 2266         size_t query_len, matches_len;
 2267         int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw);
 2268 
 2269         ret = iwl_mvm_send_cmd(mvm, &cmd);
 2270         if (ret) {
 2271                 IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
 2272                 return ret;
 2273         }
 2274 
 2275         if (fw_has_api(&mvm->fw->ucode_capa,
 2276                        IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
 2277                 query_len = sizeof(struct iwl_scan_offload_profiles_query);
 2278                 matches_len = sizeof(struct iwl_scan_offload_profile_match) *
 2279                         max_profiles;
 2280         } else {
 2281                 query_len = sizeof(struct iwl_scan_offload_profiles_query_v1);
 2282                 matches_len = sizeof(struct iwl_scan_offload_profile_match_v1) *
 2283                         max_profiles;
 2284         }
 2285 
 2286         len = iwl_rx_packet_payload_len(cmd.resp_pkt);
 2287         if (len < query_len) {
 2288                 IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
 2289                 ret = -EIO;
 2290                 goto out_free_resp;
 2291         }
 2292 
 2293         query = (void *)cmd.resp_pkt->data;
 2294 
 2295         results->matched_profiles = le32_to_cpu(query->matched_profiles);
 2296         memcpy(results->matches, query->matches, matches_len);
 2297 
 2298 #ifdef CONFIG_IWLWIFI_DEBUGFS
 2299         mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done);
 2300 #endif
 2301 
 2302 out_free_resp:
 2303         iwl_free_resp(&cmd);
 2304         return ret;
 2305 }
 2306 
 2307 static int iwl_mvm_query_num_match_chans(struct iwl_mvm *mvm,
 2308                                          struct iwl_mvm_nd_query_results *query,
 2309                                          int idx)
 2310 {
 2311         int n_chans = 0, i;
 2312 
 2313         if (fw_has_api(&mvm->fw->ucode_capa,
 2314                        IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
 2315                 struct iwl_scan_offload_profile_match *matches =
 2316                         (struct iwl_scan_offload_profile_match *)query->matches;
 2317 
 2318                 for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; i++)
 2319                         n_chans += hweight8(matches[idx].matching_channels[i]);
 2320         } else {
 2321                 struct iwl_scan_offload_profile_match_v1 *matches =
 2322                         (struct iwl_scan_offload_profile_match_v1 *)query->matches;
 2323 
 2324                 for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1; i++)
 2325                         n_chans += hweight8(matches[idx].matching_channels[i]);
 2326         }
 2327 
 2328         return n_chans;
 2329 }
 2330 
 2331 static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm,
 2332                                     struct iwl_mvm_nd_query_results *query,
 2333                                     struct cfg80211_wowlan_nd_match *match,
 2334                                     int idx)
 2335 {
 2336         int i;
 2337 
 2338         if (fw_has_api(&mvm->fw->ucode_capa,
 2339                        IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
 2340                 struct iwl_scan_offload_profile_match *matches =
 2341                         (struct iwl_scan_offload_profile_match *)query->matches;
 2342 
 2343                 for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; i++)
 2344                         if (matches[idx].matching_channels[i / 8] & (BIT(i % 8)))
 2345                                 match->channels[match->n_channels++] =
 2346                                         mvm->nd_channels[i]->center_freq;
 2347         } else {
 2348                 struct iwl_scan_offload_profile_match_v1 *matches =
 2349                         (struct iwl_scan_offload_profile_match_v1 *)query->matches;
 2350 
 2351                 for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1 * 8; i++)
 2352                         if (matches[idx].matching_channels[i / 8] & (BIT(i % 8)))
 2353                                 match->channels[match->n_channels++] =
 2354                                         mvm->nd_channels[i]->center_freq;
 2355         }
 2356 }
 2357 
 2358 static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
 2359                                             struct ieee80211_vif *vif)
 2360 {
 2361         struct cfg80211_wowlan_nd_info *net_detect = NULL;
 2362         struct cfg80211_wowlan_wakeup wakeup = {
 2363                 .pattern_idx = -1,
 2364         };
 2365         struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
 2366         struct iwl_wowlan_status_data *status;
 2367         struct iwl_mvm_nd_query_results query;
 2368         unsigned long matched_profiles;
 2369         u32 reasons = 0;
 2370         int i, n_matches, ret;
 2371 
 2372         status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA);
 2373         if (!IS_ERR(status)) {
 2374                 reasons = status->wakeup_reasons;
 2375                 kfree(status);
 2376         }
 2377 
 2378         if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
 2379                 wakeup.rfkill_release = true;
 2380 
 2381         if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
 2382                 goto out;
 2383 
 2384         ret = iwl_mvm_netdetect_query_results(mvm, &query);
 2385         if (ret || !query.matched_profiles) {
 2386                 wakeup_report = NULL;
 2387                 goto out;
 2388         }
 2389 
 2390         matched_profiles = query.matched_profiles;
 2391         if (mvm->n_nd_match_sets) {
 2392                 n_matches = hweight_long(matched_profiles);
 2393         } else {
 2394                 IWL_ERR(mvm, "no net detect match information available\n");
 2395                 n_matches = 0;
 2396         }
 2397 
 2398         net_detect = kzalloc(struct_size(net_detect, matches, n_matches),
 2399                              GFP_KERNEL);
 2400         if (!net_detect || !n_matches)
 2401                 goto out_report_nd;
 2402 
 2403         for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) {
 2404                 struct cfg80211_wowlan_nd_match *match;
 2405                 int idx, n_channels = 0;
 2406 
 2407                 n_channels = iwl_mvm_query_num_match_chans(mvm, &query, i);
 2408 
 2409                 match = kzalloc(struct_size(match, channels, n_channels),
 2410                                 GFP_KERNEL);
 2411                 if (!match)
 2412                         goto out_report_nd;
 2413 
 2414                 net_detect->matches[net_detect->n_matches++] = match;
 2415 
 2416                 /* We inverted the order of the SSIDs in the scan
 2417                  * request, so invert the index here.
 2418                  */
 2419                 idx = mvm->n_nd_match_sets - i - 1;
 2420                 match->ssid.ssid_len = mvm->nd_match_sets[idx].ssid.ssid_len;
 2421                 memcpy(match->ssid.ssid, mvm->nd_match_sets[idx].ssid.ssid,
 2422                        match->ssid.ssid_len);
 2423 
 2424                 if (mvm->n_nd_channels < n_channels)
 2425                         continue;
 2426 
 2427                 iwl_mvm_query_set_freqs(mvm, &query, match, i);
 2428         }
 2429 
 2430 out_report_nd:
 2431         wakeup.net_detect = net_detect;
 2432 out:
 2433         iwl_mvm_free_nd(mvm);
 2434 
 2435         mutex_unlock(&mvm->mutex);
 2436         ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
 2437 
 2438         if (net_detect) {
 2439                 for (i = 0; i < net_detect->n_matches; i++)
 2440                         kfree(net_detect->matches[i]);
 2441                 kfree(net_detect);
 2442         }
 2443 }
 2444 
 2445 static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
 2446                                        struct ieee80211_vif *vif)
 2447 {
 2448         /* skip the one we keep connection on */
 2449         if (data == vif)
 2450                 return;
 2451 
 2452         if (vif->type == NL80211_IFTYPE_STATION)
 2453                 ieee80211_resume_disconnect(vif);
 2454 }
 2455 
 2456 static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
 2457 {
 2458         struct error_table_start {
 2459                 /* cf. struct iwl_error_event_table */
 2460                 u32 valid;
 2461                 __le32 err_id;
 2462         } err_info;
 2463 
 2464         if (!base)
 2465                 return false;
 2466 
 2467         iwl_trans_read_mem_bytes(trans, base,
 2468                                  &err_info, sizeof(err_info));
 2469         if (err_info.valid && err_id)
 2470                 *err_id = le32_to_cpu(err_info.err_id);
 2471 
 2472         return !!err_info.valid;
 2473 }
 2474 
 2475 static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
 2476                                    struct ieee80211_vif *vif)
 2477 {
 2478         u32 err_id;
 2479 
 2480         /* check for lmac1 error */
 2481         if (iwl_mvm_rt_status(mvm->trans,
 2482                               mvm->trans->dbg.lmac_error_event_table[0],
 2483                               &err_id)) {
 2484                 if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
 2485                         struct cfg80211_wowlan_wakeup wakeup = {
 2486                                 .rfkill_release = true,
 2487                         };
 2488                         ieee80211_report_wowlan_wakeup(vif, &wakeup,
 2489                                                        GFP_KERNEL);
 2490                 }
 2491                 return true;
 2492         }
 2493 
 2494         /* check if we have lmac2 set and check for error */
 2495         if (iwl_mvm_rt_status(mvm->trans,
 2496                               mvm->trans->dbg.lmac_error_event_table[1], NULL))
 2497                 return true;
 2498 
 2499         /* check for umac error */
 2500         if (iwl_mvm_rt_status(mvm->trans,
 2501                               mvm->trans->dbg.umac_error_event_table, NULL))
 2502                 return true;
 2503 
 2504         return false;
 2505 }
 2506 
 2507 static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
 2508 {
 2509         struct ieee80211_vif *vif = NULL;
 2510         int ret = 1;
 2511         enum iwl_d3_status d3_status;
 2512         bool keep = false;
 2513         bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 2514                                          IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 2515         bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa,
 2516                                       IWL_UCODE_TLV_CAPA_D0I3_END_FIRST);
 2517 
 2518         mutex_lock(&mvm->mutex);
 2519 
 2520         mvm->last_reset_or_resume_time_jiffies = jiffies;
 2521 
 2522         /* get the BSS vif pointer again */
 2523         vif = iwl_mvm_get_bss_vif(mvm);
 2524         if (IS_ERR_OR_NULL(vif))
 2525                 goto err;
 2526 
 2527         iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
 2528 
 2529         if (iwl_mvm_check_rt_status(mvm, vif)) {
 2530                 set_bit(STATUS_FW_ERROR, &mvm->trans->status);
 2531                 iwl_mvm_dump_nic_error_log(mvm);
 2532                 iwl_dbg_tlv_time_point(&mvm->fwrt,
 2533                                        IWL_FW_INI_TIME_POINT_FW_ASSERT, NULL);
 2534                 iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
 2535                                         false, 0);
 2536                 ret = 1;
 2537                 goto err;
 2538         }
 2539 
 2540         ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
 2541         if (ret)
 2542                 goto err;
 2543 
 2544         if (d3_status != IWL_D3_STATUS_ALIVE) {
 2545                 IWL_INFO(mvm, "Device was reset during suspend\n");
 2546                 goto err;
 2547         }
 2548 
 2549         if (d0i3_first) {
 2550                 struct iwl_host_cmd cmd = {
 2551                         .id = D0I3_END_CMD,
 2552                         .flags = CMD_WANT_SKB | CMD_SEND_IN_D3,
 2553                 };
 2554                 int len;
 2555 
 2556                 ret = iwl_mvm_send_cmd(mvm, &cmd);
 2557                 if (ret < 0) {
 2558                         IWL_ERR(mvm, "Failed to send D0I3_END_CMD first (%d)\n",
 2559                                 ret);
 2560                         goto err;
 2561                 }
 2562                 switch (mvm->cmd_ver.d0i3_resp) {
 2563                 case 0:
 2564                         break;
 2565                 case 1:
 2566                         len = iwl_rx_packet_payload_len(cmd.resp_pkt);
 2567                         if (len != sizeof(u32)) {
 2568                                 IWL_ERR(mvm,
 2569                                         "Error with D0I3_END_CMD response size (%d)\n",
 2570                                         len);
 2571                                 goto err;
 2572                         }
 2573                         if (IWL_D0I3_RESET_REQUIRE &
 2574                             le32_to_cpu(*(__le32 *)cmd.resp_pkt->data)) {
 2575                                 iwl_write32(mvm->trans, CSR_RESET,
 2576                                             CSR_RESET_REG_FLAG_FORCE_NMI);
 2577                                 iwl_free_resp(&cmd);
 2578                         }
 2579                         break;
 2580                 default:
 2581                         WARN_ON(1);
 2582                 }
 2583         }
 2584 
 2585         /* after the successful handshake, we're out of D3 */
 2586         mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
 2587 
 2588         /*
 2589          * Query the current location and source from the D3 firmware so we
 2590          * can play it back when we re-intiailize the D0 firmware
 2591          */
 2592         iwl_mvm_update_changed_regdom(mvm);
 2593 
 2594         /* Re-configure PPAG settings */
 2595         iwl_mvm_ppag_send_cmd(mvm);
 2596 
 2597         if (!unified_image)
 2598                 /*  Re-configure default SAR profile */
 2599                 iwl_mvm_sar_select_profile(mvm, 1, 1);
 2600 
 2601         if (mvm->net_detect) {
 2602                 /* If this is a non-unified image, we restart the FW,
 2603                  * so no need to stop the netdetect scan.  If that
 2604                  * fails, continue and try to get the wake-up reasons,
 2605                  * but trigger a HW restart by keeping a failure code
 2606                  * in ret.
 2607                  */
 2608                 if (unified_image)
 2609                         ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT,
 2610                                                 false);
 2611 
 2612                 iwl_mvm_query_netdetect_reasons(mvm, vif);
 2613                 /* has unlocked the mutex, so skip that */
 2614                 goto out;
 2615         } else {
 2616                 keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
 2617 #ifdef CONFIG_IWLWIFI_DEBUGFS
 2618                 if (keep)
 2619                         mvm->keep_vif = vif;
 2620 #endif
 2621                 /* has unlocked the mutex, so skip that */
 2622                 goto out_iterate;
 2623         }
 2624 
 2625 err:
 2626         iwl_mvm_free_nd(mvm);
 2627         mutex_unlock(&mvm->mutex);
 2628 
 2629 out_iterate:
 2630         if (!test)
 2631                 ieee80211_iterate_active_interfaces_mtx(mvm->hw,
 2632                         IEEE80211_IFACE_ITER_NORMAL,
 2633                         iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
 2634 
 2635 out:
 2636         clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
 2637 
 2638         /* no need to reset the device in unified images, if successful */
 2639         if (unified_image && !ret) {
 2640                 /* nothing else to do if we already sent D0I3_END_CMD */
 2641                 if (d0i3_first)
 2642                         return 0;
 2643 
 2644                 ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
 2645                 if (!ret)
 2646                         return 0;
 2647         }
 2648 
 2649         /*
 2650          * Reconfigure the device in one of the following cases:
 2651          * 1. We are not using a unified image
 2652          * 2. We are using a unified image but had an error while exiting D3
 2653          */
 2654         set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
 2655 
 2656         /* regardless of what happened, we're now out of D3 */
 2657         mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
 2658 
 2659         return 1;
 2660 }
 2661 
 2662 int iwl_mvm_resume(struct ieee80211_hw *hw)
 2663 {
 2664         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 2665         int ret;
 2666 
 2667         ret = __iwl_mvm_resume(mvm, false);
 2668 
 2669         iwl_mvm_resume_tcm(mvm);
 2670 
 2671         iwl_fw_runtime_resume(&mvm->fwrt);
 2672 
 2673         return ret;
 2674 }
 2675 
 2676 void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled)
 2677 {
 2678         struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 2679 
 2680         device_set_wakeup_enable(mvm->trans->dev, enabled);
 2681 }
 2682 
 2683 #ifdef CONFIG_IWLWIFI_DEBUGFS
 2684 static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
 2685 {
 2686         struct iwl_mvm *mvm = inode->i_private;
 2687         int err;
 2688 
 2689         if (mvm->d3_test_active)
 2690                 return -EBUSY;
 2691 
 2692         file->private_data = inode->i_private;
 2693 
 2694         iwl_mvm_pause_tcm(mvm, true);
 2695 
 2696         iwl_fw_runtime_suspend(&mvm->fwrt);
 2697 
 2698         /* start pseudo D3 */
 2699         rtnl_lock();
 2700         wiphy_lock(mvm->hw->wiphy);
 2701         err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true);
 2702         wiphy_unlock(mvm->hw->wiphy);
 2703         rtnl_unlock();
 2704         if (err > 0)
 2705                 err = -EINVAL;
 2706         if (err)
 2707                 return err;
 2708 
 2709         mvm->d3_test_active = true;
 2710         mvm->keep_vif = NULL;
 2711         return 0;
 2712 }
 2713 
 2714 static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
 2715                                     size_t count, loff_t *ppos)
 2716 {
 2717         struct iwl_mvm *mvm = file->private_data;
 2718         u32 pme_asserted;
 2719 
 2720         while (true) {
 2721                 /* read pme_ptr if available */
 2722                 if (mvm->d3_test_pme_ptr) {
 2723                         pme_asserted = iwl_trans_read_mem32(mvm->trans,
 2724                                                 mvm->d3_test_pme_ptr);
 2725                         if (pme_asserted)
 2726                                 break;
 2727                 }
 2728 
 2729                 if (msleep_interruptible(100))
 2730                         break;
 2731         }
 2732 
 2733         return 0;
 2734 }
 2735 
 2736 static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
 2737                                               struct ieee80211_vif *vif)
 2738 {
 2739         /* skip the one we keep connection on */
 2740         if (_data == vif)
 2741                 return;
 2742 
 2743         if (vif->type == NL80211_IFTYPE_STATION)
 2744                 ieee80211_connection_loss(vif);
 2745 }
 2746 
 2747 static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
 2748 {
 2749         struct iwl_mvm *mvm = inode->i_private;
 2750         bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 2751                                          IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 2752 
 2753         mvm->d3_test_active = false;
 2754 
 2755         iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
 2756 
 2757         rtnl_lock();
 2758         wiphy_lock(mvm->hw->wiphy);
 2759         __iwl_mvm_resume(mvm, true);
 2760         wiphy_unlock(mvm->hw->wiphy);
 2761         rtnl_unlock();
 2762 
 2763         iwl_mvm_resume_tcm(mvm);
 2764 
 2765         iwl_fw_runtime_resume(&mvm->fwrt);
 2766 
 2767         iwl_abort_notification_waits(&mvm->notif_wait);
 2768         if (!unified_image) {
 2769                 int remaining_time = 10;
 2770 
 2771                 ieee80211_restart_hw(mvm->hw);
 2772 
 2773                 /* wait for restart and disconnect all interfaces */
 2774                 while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
 2775                        remaining_time > 0) {
 2776                         remaining_time--;
 2777                         msleep(1000);
 2778                 }
 2779 
 2780                 if (remaining_time == 0)
 2781                         IWL_ERR(mvm, "Timed out waiting for HW restart!\n");
 2782         }
 2783 
 2784         ieee80211_iterate_active_interfaces_atomic(
 2785                 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
 2786                 iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif);
 2787 
 2788         return 0;
 2789 }
 2790 
 2791 const struct file_operations iwl_dbgfs_d3_test_ops = {
 2792         .llseek = no_llseek,
 2793         .open = iwl_mvm_d3_test_open,
 2794         .read = iwl_mvm_d3_test_read,
 2795         .release = iwl_mvm_d3_test_release,
 2796 };
 2797 #endif

Cache object: d41fe884c7c55027d209b65a83ab0550


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.