return -EINVAL;
 
        if (tbl->column != RS_COLUMN_INVALID) {
-               struct lq_sta_pers *pers = &mvmsta->lq_sta.pers;
+               struct lq_sta_pers *pers = &mvmsta->lq_sta.rs_drv.pers;
 
                pers->tx_stats[tbl->column][scale_index].total += attempts;
                pers->tx_stats[tbl->column][scale_index].success += successes;
        u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);
        u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
-       struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
+       struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
 
        /* Treat uninitialized rate scaling data same as non-existing. */
        if (!lq_sta) {
 
 /* Save info about RSSI of last Rx */
 void rs_update_last_rssi(struct iwl_mvm *mvm,
-                        struct iwl_lq_sta *lq_sta,
+                        struct iwl_mvm_sta *mvmsta,
                         struct ieee80211_rx_status *rx_status)
 {
+       struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
        int i;
 
        lq_sta->pers.chains = rx_status->chains;
 static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
                        struct ieee80211_tx_rate_control *txrc)
 {
-       struct sk_buff *skb = txrc->skb;
-       struct iwl_op_mode *op_mode __maybe_unused =
-                       (struct iwl_op_mode *)mvm_r;
+       struct iwl_op_mode *op_mode = mvm_r;
        struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
+       struct sk_buff *skb = txrc->skb;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct iwl_lq_sta *lq_sta = mvm_sta;
+       struct iwl_lq_sta *lq_sta;
        struct rs_rate *optimal_rate;
        u32 last_ucode_rate;
 
                mvm_sta = NULL;
        }
 
-       /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */
-
-       /* Treat uninitialized rate scaling data same as non-existing. */
-       if (lq_sta && !lq_sta->pers.drv) {
-               IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
-               mvm_sta = NULL;
-       }
-
        /* Send management frames and NO_ACK data using lowest rate. */
        if (rate_control_send_low(sta, mvm_sta, txrc))
                return;
 
+       if (!mvm_sta)
+               return;
+
+       lq_sta = mvm_sta;
        iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags,
                                  info->band, &info->control.rates[0]);
        info->control.rates[0].count = 1;
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
        struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;
        struct iwl_mvm *mvm  = IWL_OP_MODE_GET_MVM(op_mode);
-       struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
+       struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
 
        IWL_DEBUG_RATE(mvm, "create station rate scale window\n");
 
        memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));
        lq_sta->pers.last_rssi = S8_MIN;
 
-       return &mvmsta->lq_sta;
+       return lq_sta;
 }
 
 static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
        struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
        struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
-       struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
+       struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
        struct ieee80211_supported_band *sband;
        unsigned long supp; /* must be unsigned long for for_each_set_bit */
 
 {
        struct rs_bfer_active_iter_data *data = _data;
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
-       struct iwl_lq_cmd *lq_cmd = &mvmsta->lq_sta.lq;
+       struct iwl_lq_cmd *lq_cmd = &mvmsta->lq_sta.rs_drv.lq;
        u32 ss_params = le32_to_cpu(lq_cmd->ss_params);
 
        if (sta == data->exclude_sta)
 
        /* Disallow BFER on another STA if active and we're a higher priority */
        if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) {
-               struct iwl_lq_cmd *bfersta_lq_cmd = &bfer_mvmsta->lq_sta.lq;
+               struct iwl_lq_cmd *bfersta_lq_cmd =
+                       &bfer_mvmsta->lq_sta.rs_drv.lq;
                u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params);
 
                bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED;
 
        struct iwl_lq_sta *lq_sta = file->private_data;
        struct iwl_mvm_sta *mvmsta =
-               container_of(lq_sta, struct iwl_mvm_sta, lq_sta);
+               container_of(lq_sta, struct iwl_mvm_sta, lq_sta.rs_drv);
        struct iwl_mvm *mvm;
        struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
        struct rs_rate *rate = &tbl->rate;
        struct iwl_lq_sta *lq_sta = priv_sta;
        struct iwl_mvm_sta *mvmsta;
 
-       mvmsta = container_of(lq_sta, struct iwl_mvm_sta, lq_sta);
+       mvmsta = container_of(lq_sta, struct iwl_mvm_sta, lq_sta.rs_drv);
 
        if (!mvmsta->vif)
                return;
 int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
                          bool enable)
 {
-       struct iwl_lq_cmd *lq = &mvmsta->lq_sta.lq;
+       struct iwl_lq_cmd *lq = &mvmsta->lq_sta.rs_drv.lq;
 
        lockdep_assert_held(&mvm->mutex);
 
 
        char    mcs[IWL_MAX_MCS_DISPLAY_SIZE];
 };
 
+/**
+ * struct iwl_lq_sta_rs_fw - rate and related statistics for RS in FW
+ * @last_rate_n_flags: last rate reported by FW
+ * @sta_id: the id of the station
+#ifdef CONFIG_MAC80211_DEBUGFS
+ * @dbg_fixed_rate: for debug, use fixed rate if not 0
+ * @dbg_agg_frame_count_lim: for debug, max number of frames in A-MPDU
+#endif
+ * @chains: bitmask of chains reported in %chain_signal
+ * @chain_signal: per chain signal strength
+ * @last_rssi: last rssi reported
+ * @drv: pointer back to the driver data
+ */
+
+struct iwl_lq_sta_rs_fw {
+       /* last tx rate_n_flags */
+       u32 last_rate_n_flags;
+
+       /* persistent fields - initialized only once - keep last! */
+       struct lq_sta_pers_rs_fw {
+               u32 sta_id;
+#ifdef CONFIG_MAC80211_DEBUGFS
+               u32 dbg_fixed_rate;
+               u16 dbg_agg_frame_count_lim;
+#endif
+               u8 chains;
+               s8 chain_signal[IEEE80211_MAX_CHAINS];
+               s8 last_rssi;
+               struct iwl_mvm *drv;
+       } pers;
+};
+
 /**
  * struct iwl_rate_scale_data -- tx success history for one rate
  */
 
 int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
                          bool enable);
-
 #endif /* __rs__ */