__le32 max_ampdu_cnt;
 } __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_1 */
 
+#define IWL_TLC_NOTIF_INIT_RATE_POS 0
+#define IWL_TLC_NOTIF_INIT_RATE_MSK BIT(IWL_TLC_NOTIF_INIT_RATE_POS)
+#define IWL_TLC_NOTIF_REQ_INTERVAL (500)
+
+/**
+ * struct iwl_tlc_notif_req_config_cmd - request notif on specific changes
+ * @sta_id: relevant station
+ * @reserved1: reserved
+ * @flags: bitmap of requested notifications %IWL_TLC_NOTIF_INIT_\*
+ * @interval: minimum time between notifications from TLC to the driver (msec)
+ * @reserved2: reserved
+ */
+struct iwl_tlc_notif_req_config_cmd {
+       u8 sta_id;
+       u8 reserved1;
+       __le16 flags;
+       __le16 interval;
+       __le16 reserved2;
+} __packed; /* TLC_MNG_NOTIF_REQ_CMD_API_S_VER_1 */
+
+/**
+ * struct iwl_tlc_update_notif - TLC notification from FW
+ * @sta_id: station id
+ * @reserved: reserved
+ * @flags: bitmap of notifications reported
+ * @values: field per flag in struct iwl_tlc_notif_req_config_cmd
+ */
+struct iwl_tlc_update_notif {
+       u8 sta_id;
+       u8 reserved;
+       __le16 flags;
+       __le32 values[16];
+} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_1 */
+
 /*
  * These serve as indexes into
  * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
 
                iwl_mvm_rx_queue_notif(mvm, rxb, 0);
        else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
                iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
+       else if (cmd == WIDE_ID(DATA_PATH_GROUP, TLC_MNG_UPDATE_NOTIF))
+               iwl_mvm_tlc_update_notif(mvm, pkt);
        else
                iwl_mvm_rx_common(mvm, rxb, pkt);
 }
 
        }
 }
 
+static void rs_fw_tlc_mng_notif_req_config(struct iwl_mvm *mvm, u8 sta_id)
+{
+       u32 cmd_id = iwl_cmd_id(TLC_MNG_NOTIF_REQ_CMD, DATA_PATH_GROUP, 0);
+       struct iwl_tlc_notif_req_config_cmd cfg_cmd = {
+               .sta_id = sta_id,
+               .flags = cpu_to_le16(IWL_TLC_NOTIF_INIT_RATE_MSK),
+               .interval = cpu_to_le16(IWL_TLC_NOTIF_REQ_INTERVAL),
+       };
+       int ret;
+
+       ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
+       if (ret)
+               IWL_ERR(mvm, "Failed to send TLC notif request (%d)\n", ret);
+}
+
+void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
+{
+       struct iwl_tlc_update_notif *notif;
+       struct iwl_mvm_sta *mvmsta;
+       struct iwl_lq_sta_rs_fw *lq_sta;
+
+       notif = (void *)pkt->data;
+       mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, notif->sta_id);
+
+       if (!mvmsta) {
+               IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n",
+                       notif->sta_id);
+               return;
+       }
+
+       lq_sta = &mvmsta->lq_sta.rs_fw;
+
+       if (le16_to_cpu(notif->flags) & IWL_TLC_NOTIF_INIT_RATE_MSK) {
+               lq_sta->last_rate_n_flags =
+                       le32_to_cpu(notif->values[IWL_TLC_NOTIF_INIT_RATE_POS]);
+               IWL_DEBUG_RATE(mvm, "new rate_n_flags: 0x%X\n",
+                              lq_sta->last_rate_n_flags);
+       }
+}
+
 void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                     enum nl80211_band band)
 {
        ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
        if (ret)
                IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
+
+       rs_fw_tlc_mng_notif_req_config(mvm, cfg_cmd.sta_id);
 }
 
 int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,