]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge tag 'mac80211-next-for-davem-2015-08-14' mac80211-next.git
authorKalle Valo <kvalo@codeaurora.org>
Tue, 18 Aug 2015 05:44:22 +0000 (08:44 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 18 Aug 2015 05:44:22 +0000 (08:44 +0300)
iwlwifi needs new mac80211 patches so merge mac80211-next.git to
wireless-drivers-next.git.

1  2 
drivers/net/wireless/iwlwifi/dvm/dev.h
drivers/net/wireless/iwlwifi/dvm/rx.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/sta.c

index 1f51757f4a93f43ae0d9db9da1daaace43b0a933,074977ede34391380c8c2383435847ae5dddb8a7..0ba3e56d6015b16feb34acc71c36a81d42453eb6
@@@ -669,6 -669,8 +669,8 @@@ struct iwl_priv 
        /* ieee device used by generic ieee processing code */
        struct ieee80211_hw *hw;
  
+       struct napi_struct *napi;
        struct list_head calib_results;
  
        struct workqueue_struct *workqueue;
        enum ieee80211_band band;
        u8 valid_contexts;
  
 -      int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
 -                                     struct iwl_rx_cmd_buffer *rxb,
 -                                     struct iwl_device_cmd *cmd);
 +      void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
 +                                     struct iwl_rx_cmd_buffer *rxb);
  
        struct iwl_notif_wait_data notif_wait;
  
index c91374fe9a5859e251f2252aa2f9965afb1cf4a7,5a91f5d6b1dcc5de325bb9465c995cebb096c710..15176981dc8f62c8754a6f939989fdc1863f0368
@@@ -123,8 -123,9 +123,8 @@@ const char *const iwl_dvm_cmd_strings[R
   *
   ******************************************************************************/
  
 -static int iwlagn_rx_reply_error(struct iwl_priv *priv,
 -                             struct iwl_rx_cmd_buffer *rxb,
 -                             struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_reply_error(struct iwl_priv *priv,
 +                                struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_error_resp *err_resp = (void *)pkt->data;
                err_resp->cmd_id,
                le16_to_cpu(err_resp->bad_cmd_seq_num),
                le32_to_cpu(err_resp->error_info));
 -      return 0;
  }
  
 -static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
 -                             struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_csa_notification *csa = (void *)pkt->data;
        struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
  
        if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
 -              return 0;
 +              return;
  
        if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
                rxon->channel = csa->channel;
                        le16_to_cpu(csa->channel));
                iwl_chswitch_done(priv, false);
        }
 -      return 0;
  }
  
  
 -static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
 -                                        struct iwl_rx_cmd_buffer *rxb,
 -                                        struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv,
 +                                           struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_spectrum_notification *report = (void *)pkt->data;
        if (!report->state) {
                IWL_DEBUG_11H(priv,
                        "Spectrum Measure Notification: Start\n");
 -              return 0;
 +              return;
        }
  
        memcpy(&priv->measure_report, report, sizeof(*report));
        priv->measurement_status |= MEASUREMENT_READY;
 -      return 0;
  }
  
 -static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
 -                                struct iwl_rx_cmd_buffer *rxb,
 -                                struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv,
 +                                   struct iwl_rx_cmd_buffer *rxb)
  {
  #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
                     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
  #endif
 -      return 0;
  }
  
 -static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
 -                                           struct iwl_rx_cmd_buffer *rxb,
 -                                           struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
 +                                              struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u32 __maybe_unused len = iwl_rx_packet_len(pkt);
        IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
                        "notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len);
        iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len);
 -      return 0;
  }
  
 -static int iwlagn_rx_beacon_notif(struct iwl_priv *priv,
 -                              struct iwl_rx_cmd_buffer *rxb,
 -                              struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_beacon_notif(struct iwl_priv *priv,
 +                                 struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwlagn_beacon_notif *beacon = (void *)pkt->data;
  #endif
  
        priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
 -
 -      return 0;
  }
  
  /**
@@@ -435,8 -448,9 +435,8 @@@ iwlagn_accumulative_statistics(struct i
  }
  #endif
  
 -static int iwlagn_rx_statistics(struct iwl_priv *priv,
 -                            struct iwl_rx_cmd_buffer *rxb,
 -                            struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_statistics(struct iwl_priv *priv,
 +                               struct iwl_rx_cmd_buffer *rxb)
  {
        unsigned long stamp = jiffies;
        const int reg_recalib_period = 60;
                          len, sizeof(struct iwl_bt_notif_statistics),
                          sizeof(struct iwl_notif_statistics));
                spin_unlock(&priv->statistics.lock);
 -              return 0;
 +              return;
        }
  
        change = common->temperature != priv->statistics.common.temperature ||
                priv->lib->temperature(priv);
  
        spin_unlock(&priv->statistics.lock);
 -
 -      return 0;
  }
  
 -static int iwlagn_rx_reply_statistics(struct iwl_priv *priv,
 -                                  struct iwl_rx_cmd_buffer *rxb,
 -                                  struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_reply_statistics(struct iwl_priv *priv,
 +                                     struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_notif_statistics *stats = (void *)pkt->data;
  #endif
                IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
        }
 -      iwlagn_rx_statistics(priv, rxb, cmd);
 -      return 0;
 +
 +      iwlagn_rx_statistics(priv, rxb);
  }
  
  /* Handle notification from uCode that card's power state is changing
   * due to software, hardware, or critical temperature RFKILL */
 -static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
 -                                  struct iwl_rx_cmd_buffer *rxb,
 -                                  struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_card_state_notif(struct iwl_priv *priv,
 +                                     struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_card_state_notif *card_state_notif = (void *)pkt->data;
             test_bit(STATUS_RF_KILL_HW, &priv->status)))
                wiphy_rfkill_set_hw_state(priv->hw->wiphy,
                        test_bit(STATUS_RF_KILL_HW, &priv->status));
 -      return 0;
  }
  
 -static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
 -                                     struct iwl_rx_cmd_buffer *rxb,
 -                                     struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv,
 +                                        struct iwl_rx_cmd_buffer *rxb)
  
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
                if (!test_bit(STATUS_SCANNING, &priv->status))
                        iwl_init_sensitivity(priv);
        }
 -      return 0;
  }
  
  /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
   * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
 -static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
 -                              struct iwl_rx_cmd_buffer *rxb,
 -                              struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
 +                                 struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
  
        priv->ampdu_ref++;
        memcpy(&priv->last_phy_res, pkt->data,
               sizeof(struct iwl_rx_phy_res));
 -      return 0;
  }
  
  /*
@@@ -763,7 -786,7 +763,7 @@@ static void iwlagn_pass_packet_to_mac80
  
        memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
  
-       ieee80211_rx(priv->hw, skb);
+       ieee80211_rx_napi(priv->hw, skb, priv->napi);
  }
  
  static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
@@@ -867,8 -890,9 +867,8 @@@ static int iwlagn_calc_rssi(struct iwl_
  }
  
  /* Called for REPLY_RX_MPDU_CMD */
 -static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
 -                          struct iwl_rx_cmd_buffer *rxb,
 -                          struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_reply_rx(struct iwl_priv *priv,
 +                             struct iwl_rx_cmd_buffer *rxb)
  {
        struct ieee80211_hdr *header;
        struct ieee80211_rx_status rx_status = {};
  
        if (!priv->last_phy_res_valid) {
                IWL_ERR(priv, "MPDU frame without cached PHY data\n");
 -              return 0;
 +              return;
        }
        phy_res = &priv->last_phy_res;
        amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data;
        if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
                IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d\n",
                                phy_res->cfg_phy_cnt);
 -              return 0;
 +              return;
        }
  
        if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
            !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
                IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
                                le32_to_cpu(rx_pkt_status));
 -              return 0;
 +              return;
        }
  
        /* This will be used in several places later */
  
        iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status,
                                    rxb, &rx_status);
 -      return 0;
  }
  
 -static int iwlagn_rx_noa_notification(struct iwl_priv *priv,
 -                                    struct iwl_rx_cmd_buffer *rxb,
 -                                    struct iwl_device_cmd *cmd)
 +static void iwlagn_rx_noa_notification(struct iwl_priv *priv,
 +                                     struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_wipan_noa_data *new_data, *old_data;
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
  
        if (old_data)
                kfree_rcu(old_data, rcu_head);
 -
 -      return 0;
  }
  
  /**
   */
  void iwl_setup_rx_handlers(struct iwl_priv *priv)
  {
 -      int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
 -                             struct iwl_device_cmd *cmd);
 +      void (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb);
  
        handlers = priv->rx_handlers;
  
                iwlagn_bt_rx_handler_setup(priv);
  }
  
 -int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
 -                  struct iwl_device_cmd *cmd)
 +void iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
 -      int err = 0;
  
        /*
         * Do the notification wait before RX handlers so
         *   rx_handlers table.  See iwl_setup_rx_handlers() */
        if (priv->rx_handlers[pkt->hdr.cmd]) {
                priv->rx_handlers_stats[pkt->hdr.cmd]++;
 -              err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
 +              priv->rx_handlers[pkt->hdr.cmd](priv, rxb);
        } else {
                /* No handling needed */
                IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
                             iwl_dvm_get_cmd_string(pkt->hdr.cmd),
                             pkt->hdr.cmd);
        }
 -      return err;
  }
index 95f326dc0b1ff4b373a8362899403a0c3d875e66,605f57a2c6be4c76f07a36cd99ccbc91d81f44c4..6b0956a9129a5aec7966770770db693ec453780c
@@@ -80,7 -80,6 +80,7 @@@
  #include "sta.h"
  #include "fw-api.h"
  #include "constants.h"
 +#include "tof.h"
  
  #define IWL_INVALID_MAC80211_QUEUE    0xff
  #define IWL_MVM_MAX_ADDRESSES         5
@@@ -123,7 -122,8 +123,7 @@@ extern const struct ieee80211_ops iwl_m
   *    be up'ed after the INIT fw asserted. This is useful to be able to use
   *    proprietary tools over testmode to debug the INIT fw.
   * @tfd_q_hang_detect: enabled the detection of hung transmit queues
 - * @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power
 - *    Save)-2(default), LP(Low Power)-3
 + * @power_scheme: one of enum iwl_power_scheme
   */
  struct iwl_mvm_mod_params {
        bool init_dbg;
@@@ -357,7 -357,6 +357,7 @@@ struct iwl_mvm_vif_bf_data 
   *    # of received beacons accumulated over FW restart, and the current
   *    average signal of beacons retrieved from the firmware
   * @csa_failed: CSA failed to schedule time event, report an error later
 + * @features: hw features active for this vif
   */
  struct iwl_mvm_vif {
        struct iwl_mvm *mvm;
        /* Indicates that CSA countdown may be started */
        bool csa_countdown;
        bool csa_failed;
 +
 +      /* TCP Checksum Offload */
 +      netdev_features_t features;
  };
  
  static inline struct iwl_mvm_vif *
@@@ -563,6 -559,7 +563,7 @@@ struct iwl_mvm 
        const struct iwl_cfg *cfg;
        struct iwl_phy_db *phy_db;
        struct ieee80211_hw *hw;
+       struct napi_struct *napi;
  
        /* for protecting access to iwl_mvm */
        struct mutex mutex;
         * can hold 16 keys at most. Reflect this fact.
         */
        unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
 +      u8 fw_key_deleted[STA_KEY_MAX_NUM];
  
        /* references taken by the driver and spinlock protecting them */
        spinlock_t refs_lock;
        struct iwl_mvm_shared_mem_cfg shared_mem_cfg;
  
        u32 ciphers[6];
 +      struct iwl_mvm_tof_data tof_data;
  };
  
  /* Extract MVM priv from op_mode and _hw */
@@@ -947,12 -942,6 +948,12 @@@ static inline bool iwl_mvm_bt_is_rrc_su
                IWL_MVM_BT_COEX_RRC;
  }
  
 +static inline bool iwl_mvm_is_csum_supported(struct iwl_mvm *mvm)
 +{
 +      return fw_has_capa(&mvm->fw->ucode_capa,
 +                         IWL_UCODE_TLV_CAPA_CSUM_SUPPORT);
 +}
 +
  extern const u8 iwl_mvm_ac_to_tx_fifo[];
  
  struct iwl_rate_info {
@@@ -986,12 -975,12 +987,12 @@@ u8 iwl_mvm_next_antenna(struct iwl_mvm 
  /* Tx / Host Commands */
  int __must_check iwl_mvm_send_cmd(struct iwl_mvm *mvm,
                                  struct iwl_host_cmd *cmd);
 -int __must_check iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u8 id,
 +int __must_check iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id,
                                      u32 flags, u16 len, const void *data);
  int __must_check iwl_mvm_send_cmd_status(struct iwl_mvm *mvm,
                                         struct iwl_host_cmd *cmd,
                                         u32 *status);
 -int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u8 id,
 +int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id,
                                             u16 len, const void *data,
                                             u32 *status);
  int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
@@@ -1000,6 -989,10 +1001,6 @@@ int iwl_mvm_tx_skb_non_sta(struct iwl_m
  void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
                        struct iwl_tx_cmd *tx_cmd,
                        struct ieee80211_tx_info *info, u8 sta_id);
 -void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
 -                             struct ieee80211_tx_info *info,
 -                             struct iwl_tx_cmd *tx_cmd,
 -                             struct sk_buff *skb_frag);
  void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
                            struct ieee80211_tx_info *info,
                            struct ieee80211_sta *sta, __le16 fc);
@@@ -1011,17 -1004,6 +1012,17 @@@ static inline const char *iwl_mvm_get_t
  int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, bool sync);
  void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm);
  
 +static inline void iwl_mvm_set_tx_cmd_ccmp(struct ieee80211_tx_info *info,
 +                                         struct iwl_tx_cmd *tx_cmd)
 +{
 +      struct ieee80211_key_conf *keyconf = info->control.hw_key;
 +
 +      tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
 +      memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
 +      if (info->flags & IEEE80211_TX_CTL_AMPDU)
 +              tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_CCMP_AGG);
 +}
 +
  static inline void iwl_mvm_wait_for_async_handlers(struct iwl_mvm *mvm)
  {
        flush_work(&mvm->async_handlers_wk);
  /* Statistics */
  void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
                                  struct iwl_rx_packet *pkt);
 -int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
 -                        struct iwl_rx_cmd_buffer *rxb,
 -                        struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
 +                         struct iwl_rx_cmd_buffer *rxb);
  int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear);
  void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm);
  
@@@ -1077,19 -1060,27 +1078,19 @@@ bool iwl_mvm_bcast_filter_build_cmd(str
   * FW notifications / CMD responses handlers
   * Convention: iwl_mvm_rx_<NAME OF THE CMD>
   */
 -int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                        struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                     struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                    struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                      struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
 -                                struct iwl_rx_cmd_buffer *rxb,
 -                                struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                        struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm,
 -                              struct iwl_rx_cmd_buffer *rxb,
 -                              struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                          struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_shared_mem_cfg_notif(struct iwl_mvm *mvm,
 -                                  struct iwl_rx_cmd_buffer *rxb,
 -                                  struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
 +                                 struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_card_state_notif(struct iwl_mvm *mvm,
 +                               struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm,
 +                           struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_shared_mem_cfg_notif(struct iwl_mvm *mvm,
 +                                   struct iwl_rx_cmd_buffer *rxb);
  
  /* MVM PHY */
  int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
@@@ -1116,10 -1107,12 +1117,10 @@@ int iwl_mvm_mac_ctxt_remove(struct iwl_
  u32 iwl_mvm_mac_get_queues_mask(struct ieee80211_vif *vif);
  int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
                                    struct ieee80211_vif *vif);
 -int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
 -                          struct iwl_rx_cmd_buffer *rxb,
 -                          struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
 -                                  struct iwl_rx_cmd_buffer *rxb,
 -                                  struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
 +                           struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
 +                                   struct iwl_rx_cmd_buffer *rxb);
  void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
                                    struct ieee80211_vif *vif);
  unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
@@@ -1143,24 -1136,29 +1144,24 @@@ int iwl_mvm_max_scan_ie_len(struct iwl_
  void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm);
  
  /* Scheduled scan */
 -int iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
 -                                      struct iwl_rx_cmd_buffer *rxb,
 -                                      struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_lmac_scan_iter_complete_notif(struct iwl_mvm *mvm,
 -                                           struct iwl_rx_cmd_buffer *rxb,
 -                                           struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
 +                                       struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_lmac_scan_iter_complete_notif(struct iwl_mvm *mvm,
 +                                            struct iwl_rx_cmd_buffer *rxb);
  int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
                             struct ieee80211_vif *vif,
                             struct cfg80211_sched_scan_request *req,
                             struct ieee80211_scan_ies *ies,
                             int type);
 -int iwl_mvm_rx_scan_match_found(struct iwl_mvm *mvm,
 -                              struct iwl_rx_cmd_buffer *rxb,
 -                              struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_scan_match_found(struct iwl_mvm *mvm,
 +                               struct iwl_rx_cmd_buffer *rxb);
  
  /* UMAC scan */
  int iwl_mvm_config_scan(struct iwl_mvm *mvm);
 -int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
 -                                      struct iwl_rx_cmd_buffer *rxb,
 -                                      struct iwl_device_cmd *cmd);
 -int iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
 -                                           struct iwl_rx_cmd_buffer *rxb,
 -                                           struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
 +                                       struct iwl_rx_cmd_buffer *rxb);
 +void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
 +                                            struct iwl_rx_cmd_buffer *rxb);
  
  /* MVM debugfs */
  #ifdef CONFIG_IWLWIFI_DEBUGFS
@@@ -1199,8 -1197,9 +1200,8 @@@ int iwl_mvm_power_mac_dbgfs_read(struc
                                 char *buf, int bufsz);
  
  void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 -int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
 -                                           struct iwl_rx_cmd_buffer *rxb,
 -                                           struct iwl_device_cmd *cmd);
 +void iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
 +                                            struct iwl_rx_cmd_buffer *rxb);
  
  #ifdef CONFIG_IWLWIFI_LEDS
  int iwl_mvm_leds_init(struct iwl_mvm *mvm);
@@@ -1256,8 -1255,9 +1257,8 @@@ int _iwl_mvm_exit_d0i3(struct iwl_mvm *
  
  /* BT Coex */
  int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
 -int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
 -                           struct iwl_rx_cmd_buffer *rxb,
 -                           struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
 +                            struct iwl_rx_cmd_buffer *rxb);
  void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                           enum ieee80211_rssi_event_data);
  void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm);
@@@ -1275,8 -1275,9 +1276,8 @@@ u8 iwl_mvm_bt_coex_tx_prio(struct iwl_m
  bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm);
  void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm);
  int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm);
 -int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
 -                               struct iwl_rx_cmd_buffer *rxb,
 -                               struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
 +                                struct iwl_rx_cmd_buffer *rxb);
  void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                               enum ieee80211_rssi_event_data);
  u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm,
@@@ -1285,8 -1286,9 +1286,8 @@@ bool iwl_mvm_bt_coex_is_mimo_allowed_ol
                                         struct ieee80211_sta *sta);
  bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm,
                                        enum ieee80211_band band);
 -int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
 -                                    struct iwl_rx_cmd_buffer *rxb,
 -                                    struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
 +                                     struct iwl_rx_cmd_buffer *rxb);
  
  /* beacon filtering */
  #ifdef CONFIG_IWLWIFI_DEBUGFS
@@@ -1375,8 -1377,9 +1376,8 @@@ static inline void iwl_mvm_enable_agg_t
  /* Thermal management and CT-kill */
  void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
  void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp);
 -int iwl_mvm_temp_notif(struct iwl_mvm *mvm,
 -                     struct iwl_rx_cmd_buffer *rxb,
 -                     struct iwl_device_cmd *cmd);
 +void iwl_mvm_temp_notif(struct iwl_mvm *mvm,
 +                      struct iwl_rx_cmd_buffer *rxb);
  void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
  void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff);
  void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
@@@ -1388,8 -1391,9 +1389,8 @@@ struct iwl_mcc_update_resp 
  iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
                   enum iwl_mcc_source src_id);
  int iwl_mvm_init_mcc(struct iwl_mvm *mvm);
 -int iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
 -                             struct iwl_rx_cmd_buffer *rxb,
 -                             struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
 +                              struct iwl_rx_cmd_buffer *rxb);
  struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
                                                  const char *alpha2,
                                                  enum iwl_mcc_source src_id,
@@@ -1428,7 -1432,8 +1429,7 @@@ void iwl_mvm_tdls_recv_channel_switch(s
  void iwl_mvm_tdls_cancel_channel_switch(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif,
                                        struct ieee80211_sta *sta);
 -int iwl_mvm_rx_tdls_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                        struct iwl_device_cmd *cmd);
 +void iwl_mvm_rx_tdls_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
  void iwl_mvm_tdls_ch_switch_work(struct work_struct *work);
  
  struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
index 6957d026e4bd1cd442637001551b44dc28d24101,3967df63e0f3822a53b0d120cfc811773e5f44c0..c8327f1a077a7518eddbe859bacc94d0a0bfd281
@@@ -201,15 -201,14 +201,15 @@@ static void iwl_mvm_nic_config(struct i
  }
  
  struct iwl_rx_handlers {
 -      u8 cmd_id;
 +      u16 cmd_id;
        bool async;
 -      int (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                struct iwl_device_cmd *cmd);
 +      void (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
  };
  
  #define RX_HANDLER(_cmd_id, _fn, _async)      \
        { .cmd_id = _cmd_id , .fn = _fn , .async = _async }
 +#define RX_HANDLER_GRP(_grp, _cmd, _fn, _async)       \
 +      { .cmd_id = WIDE_ID(_grp, _cmd), .fn = _fn, .async = _async }
  
  /*
   * Handlers for fw notifications
   * called from a worker with mvm->mutex held.
   */
  static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
 -      RX_HANDLER(REPLY_RX_MPDU_CMD, iwl_mvm_rx_rx_mpdu, false),
        RX_HANDLER(REPLY_RX_PHY_CMD, iwl_mvm_rx_rx_phy_cmd, false),
        RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, false),
        RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false),
        RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif,
                   true),
        RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif, false),
 +      RX_HANDLER(TOF_NOTIFICATION, iwl_mvm_tof_resp_handler, true),
  
  };
  #undef RX_HANDLER
 +#undef RX_HANDLER_GRP
  #define CMD(x) [x] = #x
  
  static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
@@@ -472,8 -470,6 +472,8 @@@ iwl_op_mode_mvm_start(struct iwl_trans 
        trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
        trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
        trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
 +      trans_cfg.wide_cmd_header = fw_has_api(&mvm->fw->ucode_capa,
 +                                             IWL_UCODE_TLV_API_WIDE_CMD_HDR);
  
        if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)
                trans_cfg.bc_table_dword = true;
        /* rpm starts with a taken ref. only set the appropriate bit here. */
        mvm->refs[IWL_MVM_REF_UCODE_DOWN] = 1;
  
 +      iwl_mvm_tof_init(mvm);
 +
        return op_mode;
  
   out_unregister:
@@@ -629,15 -623,14 +629,15 @@@ static void iwl_op_mode_mvm_stop(struc
        for (i = 0; i < NVM_MAX_NUM_SECTIONS; i++)
                kfree(mvm->nvm_sections[i].data);
  
 +      iwl_mvm_tof_clean(mvm);
 +
        ieee80211_free_hw(mvm->hw);
  }
  
  struct iwl_async_handler_entry {
        struct list_head list;
        struct iwl_rx_cmd_buffer rxb;
 -      int (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                struct iwl_device_cmd *cmd);
 +      void (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
  };
  
  void iwl_mvm_async_handlers_purge(struct iwl_mvm *mvm)
@@@ -674,7 -667,9 +674,7 @@@ static void iwl_mvm_async_handlers_wk(s
        spin_unlock_bh(&mvm->async_handlers_lock);
  
        list_for_each_entry_safe(entry, tmp, &local_list, list) {
 -              if (entry->fn(mvm, &entry->rxb, NULL))
 -                      IWL_WARN(mvm,
 -                               "returned value from ASYNC handlers are ignored\n");
 +              entry->fn(mvm, &entry->rxb);
                iwl_free_rxb(&entry->rxb);
                list_del(&entry->list);
                kfree(entry);
@@@ -703,29 -698,24 +703,29 @@@ static inline void iwl_mvm_rx_check_tri
                if (!cmds_trig->cmds[i].cmd_id)
                        break;
  
 -              if (cmds_trig->cmds[i].cmd_id != pkt->hdr.cmd)
 +              if (cmds_trig->cmds[i].cmd_id != pkt->hdr.cmd ||
 +                  cmds_trig->cmds[i].group_id != pkt->hdr.group_id)
                        continue;
  
                iwl_mvm_fw_dbg_collect_trig(mvm, trig,
 -                                          "CMD 0x%02x received",
 -                                          pkt->hdr.cmd);
 +                                          "CMD 0x%02x.%02x received",
 +                                          pkt->hdr.group_id, pkt->hdr.cmd);
                break;
        }
  }
  
 -static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
 -                             struct iwl_rx_cmd_buffer *rxb,
 -                             struct iwl_device_cmd *cmd)
 +static void iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
 +                              struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
        u8 i;
  
 +      if (likely(pkt->hdr.cmd == REPLY_RX_MPDU_CMD)) {
 +              iwl_mvm_rx_rx_mpdu(mvm, rxb);
 +              return;
 +      }
 +
        iwl_mvm_rx_check_trigger(mvm, pkt);
  
        /*
                const struct iwl_rx_handlers *rx_h = &iwl_mvm_rx_handlers[i];
                struct iwl_async_handler_entry *entry;
  
 -              if (rx_h->cmd_id != pkt->hdr.cmd)
 +              if (rx_h->cmd_id != WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd))
                        continue;
  
 -              if (!rx_h->async)
 -                      return rx_h->fn(mvm, rxb, cmd);
 +              if (!rx_h->async) {
 +                      rx_h->fn(mvm, rxb);
 +                      return;
 +              }
  
                entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
                /* we can't do much... */
                if (!entry)
 -                      return 0;
 +                      return;
  
                entry->rxb._page = rxb_steal_page(rxb);
                entry->rxb._offset = rxb->_offset;
                schedule_work(&mvm->async_handlers_wk);
                break;
        }
 -
 -      return 0;
  }
  
  static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
@@@ -1326,7 -1316,8 +1326,8 @@@ static void iwl_mvm_napi_add(struct iwl
  {
        struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
  
-       ieee80211_napi_add(mvm->hw, napi, napi_dev, poll, weight);
+       netif_napi_add(napi_dev, napi, poll, weight);
+       mvm->napi = napi;
  }
  
  static const struct iwl_op_mode_ops iwl_mvm_ops = {
index 65746145273e17dd49323fa97edc8f1be7b61e94,9ff0b4321df3b051d5e1ec3576e73036b578f53e..a0c27cc19759015c1148c97880755f9f0e4c0d89
@@@ -61,7 -61,6 +61,7 @@@
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *****************************************************************************/
 +#include <linux/skbuff.h>
  #include "iwl-trans.h"
  #include "mvm.h"
  #include "fw-api.h"
@@@ -72,7 -71,8 +72,7 @@@
   * Copies the phy information in mvm->last_phy_info, it will be used when the
   * actual data will come from the fw in the next packet.
   */
 -int iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                        struct iwl_device_cmd *cmd)
 +void iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
  
@@@ -86,6 -86,8 +86,6 @@@
                spin_unlock(&mvm->drv_stats_lock);
        }
  #endif
 -
 -      return 0;
  }
  
  /*
@@@ -127,7 -129,7 +127,7 @@@ static void iwl_mvm_pass_packet_to_mac8
                                fraglen, rxb->truesize);
        }
  
-       ieee80211_rx(mvm->hw, skb);
+       ieee80211_rx_napi(mvm->hw, skb, mvm->napi);
  }
  
  /*
@@@ -235,25 -237,13 +235,25 @@@ static u32 iwl_mvm_set_mac80211_rx_flag
        return 0;
  }
  
 +static void iwl_mvm_rx_csum(struct ieee80211_sta *sta,
 +                          struct sk_buff *skb,
 +                          u32 status)
 +{
 +      struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
 +      struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
 +
 +      if (mvmvif->features & NETIF_F_RXCSUM &&
 +          status & RX_MPDU_RES_STATUS_CSUM_DONE &&
 +          status & RX_MPDU_RES_STATUS_CSUM_OK)
 +              skb->ip_summed = CHECKSUM_UNNECESSARY;
 +}
 +
  /*
   * iwl_mvm_rx_rx_mpdu - REPLY_RX_MPDU_CMD handler
   *
   * Handles the actual data of the Rx packet from the fw
   */
 -int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
 -                     struct iwl_device_cmd *cmd)
 +void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
  {
        struct ieee80211_hdr *hdr;
        struct ieee80211_rx_status *rx_status;
        skb = alloc_skb(128, GFP_ATOMIC);
        if (!skb) {
                IWL_ERR(mvm, "alloc_skb failed\n");
 -              return 0;
 +              return;
        }
  
        rx_status = IEEE80211_SKB_RXCB(skb);
                IWL_DEBUG_DROP(mvm, "Bad decryption results 0x%08x\n",
                               rx_pkt_status);
                kfree_skb(skb);
 -              return 0;
 +              return;
        }
  
        if ((unlikely(phy_info->cfg_phy_cnt > 20))) {
                IWL_DEBUG_DROP(mvm, "dsp size out of range [0,20]: %d\n",
                               phy_info->cfg_phy_cnt);
                kfree_skb(skb);
 -              return 0;
 +              return;
        }
  
        /*
                }
        }
  
 +      if (sta && ieee80211_is_data(hdr->frame_control))
 +              iwl_mvm_rx_csum(sta, skb, rx_pkt_status);
 +
        rcu_read_unlock();
  
        /* set the preamble flag if appropriate */
  #endif
        iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status,
                                        crypt_len, rxb);
 -      return 0;
  }
  
  static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm,
@@@ -635,7 -623,10 +635,7 @@@ void iwl_mvm_handle_rx_statistics(struc
                iwl_rx_packet_payload_len(pkt));
  }
  
 -int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
 -                        struct iwl_rx_cmd_buffer *rxb,
 -                        struct iwl_device_cmd *cmd)
 +void iwl_mvm_rx_statistics(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
  {
        iwl_mvm_handle_rx_statistics(mvm, rxb_addr(rxb));
 -      return 0;
  }
index 2531aa3d6754a318df3045ceed55c521d99da4c1,3d2fbf1bc22656b9f68ff22dda7be43ba11862b6..df216cd0c98f4659d1c00d7d07c8adb31c8244c6
@@@ -1148,31 -1148,18 +1148,31 @@@ int iwl_mvm_sta_tx_agg_flush(struct iwl
  
  static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
  {
 -      int i;
 +      int i, max = -1, max_offs = -1;
  
        lockdep_assert_held(&mvm->mutex);
  
 -      i = find_first_zero_bit(mvm->fw_key_table, STA_KEY_MAX_NUM);
 +      /* Pick the unused key offset with the highest 'deleted'
 +       * counter. Every time a key is deleted, all the counters
 +       * are incremented and the one that was just deleted is
 +       * reset to zero. Thus, the highest counter is the one
 +       * that was deleted longest ago. Pick that one.
 +       */
 +      for (i = 0; i < STA_KEY_MAX_NUM; i++) {
 +              if (test_bit(i, mvm->fw_key_table))
 +                      continue;
 +              if (mvm->fw_key_deleted[i] > max) {
 +                      max = mvm->fw_key_deleted[i];
 +                      max_offs = i;
 +              }
 +      }
  
 -      if (i == STA_KEY_MAX_NUM)
 +      if (max_offs < 0)
                return STA_KEY_IDX_INVALID;
  
 -      __set_bit(i, mvm->fw_key_table);
 +      __set_bit(max_offs, mvm->fw_key_table);
  
 -      return i;
 +      return max_offs;
  }
  
  static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
@@@ -1290,8 -1277,6 +1290,6 @@@ static int iwl_mvm_send_sta_igtk(struc
                const u8 *pn;
  
                memcpy(igtk_cmd.IGTK, keyconf->key, keyconf->keylen);
-               ieee80211_aes_cmac_calculate_k1_k2(keyconf,
-                                                  igtk_cmd.K1, igtk_cmd.K2);
                ieee80211_get_key_rx_seq(keyconf, 0, &seq);
                pn = seq.aes_cmac.pn;
                igtk_cmd.receive_seq_cnt = cpu_to_le64(((u64) pn[5] << 0) |
@@@ -1414,7 -1399,6 +1412,7 @@@ int iwl_mvm_set_sta_key(struct iwl_mvm 
        bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE);
        u8 sta_id;
        int ret;
 +      static const u8 __maybe_unused zero_addr[ETH_ALEN] = {0};
  
        lockdep_assert_held(&mvm->mutex);
  
  end:
        IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n",
                      keyconf->cipher, keyconf->keylen, keyconf->keyidx,
 -                    sta->addr, ret);
 +                    sta ? sta->addr : zero_addr, ret);
        return ret;
  }
  
@@@ -1492,7 -1476,7 +1490,7 @@@ int iwl_mvm_remove_sta_key(struct iwl_m
  {
        bool mcast = !(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE);
        u8 sta_id;
 -      int ret;
 +      int ret, i;
  
        lockdep_assert_held(&mvm->mutex);
  
                return -ENOENT;
        }
  
 +      /* track which key was deleted last */
 +      for (i = 0; i < STA_KEY_MAX_NUM; i++) {
 +              if (mvm->fw_key_deleted[i] < U8_MAX)
 +                      mvm->fw_key_deleted[i]++;
 +      }
 +      mvm->fw_key_deleted[keyconf->hw_key_idx] = 0;
 +
        if (sta_id == IWL_MVM_STATION_COUNT) {
                IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n");
                return 0;
@@@ -1681,8 -1658,9 +1679,8 @@@ void iwl_mvm_sta_modify_sleep_tx_count(
                IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
  }
  
 -int iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
 -                        struct iwl_rx_cmd_buffer *rxb,
 -                        struct iwl_device_cmd *cmd)
 +void iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
 +                         struct iwl_rx_cmd_buffer *rxb)
  {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_mvm_eosp_notification *notif = (void *)pkt->data;
        u32 sta_id = le32_to_cpu(notif->sta_id);
  
        if (WARN_ON_ONCE(sta_id >= IWL_MVM_STATION_COUNT))
 -              return 0;
 +              return;
  
        rcu_read_lock();
        sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
        if (!IS_ERR_OR_NULL(sta))
                ieee80211_sta_eosp(sta);
        rcu_read_unlock();
 -
 -      return 0;
  }
  
  void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,