return rec;
 }
 
+static const struct rtw89_acpi_sar_recognition *
+rtw89_acpi_evaluate_dynamic_sar(struct rtw89_dev *rtwdev,
+                               struct rtw89_sar_cfg_acpi *cfg)
+{
+       const struct rtw89_acpi_sar_recognition *rec = NULL;
+       const struct rtw89_acpi_dynamic_sar_hdr *hdr;
+       struct rtw89_acpi_sar_rec_parm parm = {};
+       struct rtw89_sar_table_from_acpi *tbl;
+       const struct rtw89_acpi_data *data;
+       u32 len;
+
+       data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_DYNAMIC_SAR);
+       if (!data)
+               return NULL;
+
+       rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load dynamic sar\n");
+
+       len = data->len;
+       if (len <= sizeof(*hdr)) {
+               rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len);
+               goto out;
+       }
+
+       hdr = (typeof(hdr))data->buf;
+
+       parm.cid = le16_to_cpu(hdr->cid);
+       parm.rev = hdr->rev;
+       parm.tbl_cnt = hdr->cnt;
+       parm.pld_len = len - sizeof(*hdr);
+
+       rec = rtw89_acpi_sar_recognize(rtwdev, &parm);
+       if (!rec)
+               goto out;
+
+       for (unsigned int i = 0; i < hdr->cnt; i++) {
+               const u8 *content = hdr->content + rec->id.size * i;
+               struct rtw89_sar_entry_from_acpi tmp = {};
+
+               rec->load(rtwdev, rec, content, &tmp);
+
+               tbl = &cfg->tables[i];
+               for (u8 regd = 0; regd < RTW89_REGD_NUM; regd++)
+                       tbl->entries[regd] = tmp;
+       }
+
+       cfg->valid_num = hdr->cnt;
+
+out:
+       kfree(data);
+       return rec;
+}
+
+int rtw89_acpi_evaluate_dynamic_sar_indicator(struct rtw89_dev *rtwdev,
+                                             struct rtw89_sar_cfg_acpi *cfg,
+                                             bool *poll_changed)
+{
+       struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator;
+       struct rtw89_sar_indicator_from_acpi tmp = *ind;
+       const struct rtw89_acpi_data *data;
+       const u8 *tbl_base1_by_ant;
+       enum rtw89_rf_path path;
+       int ret = 0;
+       u32 len;
+
+       data = rtw89_acpi_evaluate_method(rtwdev, RTW89_ACPI_METHOD_DYNAMIC_SAR_INDICATOR);
+       if (!data)
+               return -EFAULT;
+
+       if (!poll_changed)
+               rtw89_debug(rtwdev, RTW89_DBG_ACPI, "acpi load dynamic sar indicator\n");
+
+       len = data->len;
+       if (len != ind->fields) {
+               rtw89_debug(rtwdev, RTW89_DBG_ACPI, "invalid buf len %u\n", len);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       tbl_base1_by_ant = data->buf;
+
+       for (path = 0; path < NUM_OF_RTW89_ACPI_SAR_RF_PATH; path++) {
+               u8 antidx = ind->rfpath_to_antidx(path);
+               u8 sel;
+
+               if (antidx >= ind->fields)
+                       antidx = 0;
+
+               /* convert the table index from 1-based to 0-based */
+               sel = tbl_base1_by_ant[antidx] - 1;
+               if (sel >= cfg->valid_num)
+                       sel = 0;
+
+               tmp.tblsel[path] = sel;
+       }
+
+       if (memcmp(ind, &tmp, sizeof(*ind)) == 0) {
+               if (poll_changed)
+                       *poll_changed = false;
+       } else {
+               if (poll_changed)
+                       *poll_changed = true;
+
+               *ind = tmp;
+       }
+
+out:
+       kfree(data);
+       return ret;
+}
+
 int rtw89_acpi_evaluate_sar(struct rtw89_dev *rtwdev,
                            struct rtw89_sar_cfg_acpi *cfg)
 {
+       struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator;
        const struct rtw89_acpi_sar_recognition *rec;
+       bool fetch_indicator = false;
+       int ret;
 
        rec = rtw89_acpi_evaluate_static_sar(rtwdev, cfg);
+       if (rec)
+               goto recognized;
+
+       rec = rtw89_acpi_evaluate_dynamic_sar(rtwdev, cfg);
        if (!rec)
                return -ENOENT;
 
+       fetch_indicator = true;
+
+recognized:
        switch (rec->id.cid) {
        case RTW89_ACPI_SAR_CID_HP:
                cfg->downgrade_2tx = 3 << TXPWR_FACTOR_OF_RTW89_ACPI_SAR;
+               ind->fields = RTW89_ACPI_SAR_ANT_NR_STD;
                break;
        case RTW89_ACPI_SAR_CID_RT:
                cfg->downgrade_2tx = 0;
+               ind->fields = 1;
                break;
        default:
                return -EFAULT;
        }
 
+       if (fetch_indicator) {
+               ind->rfpath_to_antidx = rec->rfpath_to_antidx;
+               ret = rtw89_acpi_evaluate_dynamic_sar_indicator(rtwdev, cfg, NULL);
+               if (ret)
+                       fetch_indicator = false;
+       }
+
+       if (!fetch_indicator)
+               memset(ind->tblsel, 0, sizeof(ind->tblsel));
+
+       ind->enable_sync = fetch_indicator;
        return 0;
 }
 
 #define RTW89_ACPI_SAR_ANT_NR_SML 2
 
 #define RTW89_ACPI_METHOD_STATIC_SAR "WRDS"
+#define RTW89_ACPI_METHOD_DYNAMIC_SAR "RWRD"
+#define RTW89_ACPI_METHOD_DYNAMIC_SAR_INDICATOR "RWSI"
 
 struct rtw89_acpi_sar_std_legacy {
        u8 v[RTW89_ACPI_SAR_ANT_NR_STD][RTW89_ACPI_SAR_SUBBAND_NR_LEGACY];
        u8 content[];
 } __packed;
 
+struct rtw89_acpi_dynamic_sar_hdr {
+       __le16 cid;
+       u8 rev;
+       u8 cnt;
+       u8 content[];
+} __packed;
+
 struct rtw89_acpi_sar_identifier {
        enum rtw89_acpi_sar_cid cid;
        enum rtw89_acpi_sar_rev rev;
                             struct rtw89_acpi_rtag_result *res);
 int rtw89_acpi_evaluate_sar(struct rtw89_dev *rtwdev,
                            struct rtw89_sar_cfg_acpi *cfg);
+int rtw89_acpi_evaluate_dynamic_sar_indicator(struct rtw89_dev *rtwdev,
+                                             struct rtw89_sar_cfg_acpi *cfg,
+                                             bool *changed);
 
 #endif
 
        rtw89_phy_antdiv_track(rtwdev);
        rtw89_phy_ul_tb_ctrl_track(rtwdev);
        rtw89_phy_edcca_track(rtwdev);
-       rtw89_tas_track(rtwdev);
+       rtw89_sar_track(rtwdev);
        rtw89_chanctx_track(rtwdev);
        rtw89_core_rfkill_poll(rtwdev, false);
 
 
        struct rtw89_sar_entry_from_acpi entries[RTW89_REGD_NUM];
 };
 
+struct rtw89_sar_indicator_from_acpi {
+       bool enable_sync;
+       unsigned int fields;
+       u8 (*rfpath_to_antidx)(enum rtw89_rf_path rfpath);
+
+       /* Select among @tables of container, rtw89_sar_cfg_acpi, by path.
+        * Not design with pointers since addresses will be invalid after
+        * sync content with local container instance.
+        */
+       u8 tblsel[NUM_OF_RTW89_ACPI_SAR_RF_PATH];
+};
+
 struct rtw89_sar_cfg_acpi {
        u8 downgrade_2tx;
        unsigned int valid_num;
        struct rtw89_sar_table_from_acpi tables[MAX_NUM_OF_RTW89_ACPI_SAR_TBL];
+       struct rtw89_sar_indicator_from_acpi indicator;
 };
 
 struct rtw89_sar_info {
 
        return 0;
 }
 
+static const struct rtw89_sar_entry_from_acpi *
+rtw89_sar_cfg_acpi_get_ent(const struct rtw89_sar_cfg_acpi *rtwsar,
+                          enum rtw89_rf_path path,
+                          enum rtw89_regulation_type regd)
+{
+       const struct rtw89_sar_indicator_from_acpi *ind = &rtwsar->indicator;
+       const struct rtw89_sar_table_from_acpi *tbl;
+       u8 sel;
+
+       sel = ind->tblsel[path];
+       tbl = &rtwsar->tables[sel];
+
+       return &tbl->entries[regd];
+}
+
 static
 s32 rtw89_sar_cfg_acpi_get_min(const struct rtw89_sar_entry_from_acpi *ent,
                               enum rtw89_rf_path path,
                                       s32 *cfg)
 {
        const struct rtw89_sar_cfg_acpi *rtwsar = &rtwdev->sar.cfg_acpi;
-       const struct rtw89_sar_table_from_acpi *tbl = rtwsar->tables;
+       const struct rtw89_sar_entry_from_acpi *ent_a, *ent_b;
        enum rtw89_acpi_sar_subband subband_l, subband_h;
-       const struct rtw89_sar_entry_from_acpi *ent;
        u32 center_freq = sar_parm->center_freq;
        const struct rtw89_6ghz_span *span;
        enum rtw89_regulation_type regd;
 
        band = rtw89_acpi_sar_subband_to_band(rtwdev, subband_l);
        regd = rtw89_regd_get(rtwdev, band);
-       ent = &tbl->entries[regd];
 
-       cfg_a = rtw89_sar_cfg_acpi_get_min(ent, RF_PATH_A, subband_l, subband_h);
-       cfg_b = rtw89_sar_cfg_acpi_get_min(ent, RF_PATH_B, subband_l, subband_h);
+       ent_a = rtw89_sar_cfg_acpi_get_ent(rtwsar, RF_PATH_A, regd);
+       ent_b = rtw89_sar_cfg_acpi_get_ent(rtwsar, RF_PATH_B, regd);
+
+       cfg_a = rtw89_sar_cfg_acpi_get_min(ent_a, RF_PATH_A, subband_l, subband_h);
+       cfg_b = rtw89_sar_cfg_acpi_get_min(ent_b, RF_PATH_B, subband_l, subband_h);
        *cfg = min(cfg_a, cfg_b);
 
        if (sar_parm->ntx == RTW89_2TX)
        return true;
 }
 
-static void rtw89_tas_state_update(struct rtw89_dev *rtwdev,
-                                  enum rtw89_tas_state state)
+static bool __rtw89_tas_state_update(struct rtw89_dev *rtwdev,
+                                    enum rtw89_tas_state state)
 {
        struct rtw89_tas_info *tas = &rtwdev->tas;
 
        if (tas->state == state)
-               return;
+               return false;
 
        rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: switch state: %s -> %s\n",
                    rtw89_tas_state_str(tas->state), rtw89_tas_state_str(state));
 
        tas->state = state;
+       return true;
+}
+
+static void rtw89_tas_state_update(struct rtw89_dev *rtwdev,
+                                  enum rtw89_tas_state state)
+{
+       if (!__rtw89_tas_state_update(rtwdev, state))
+               return;
+
        rtw89_core_set_chip_txpwr(rtwdev);
 }
 
                    rtw89_linear_to_db_quarter(div_u64(txpwr, PERCENT)));
 }
 
-static void rtw89_tas_rolling_average(struct rtw89_dev *rtwdev)
+static bool rtw89_tas_rolling_average(struct rtw89_dev *rtwdev)
 {
        struct rtw89_tas_info *tas = &rtwdev->tas;
        s32 dpr_on_threshold, dpr_off_threshold;
        else if (txpwr_avg < dpr_off_threshold)
                state = RTW89_TAS_STATE_DPR_OFF;
        else
-               return;
+               return false;
 
-       rtw89_tas_state_update(rtwdev, state);
+       return __rtw89_tas_state_update(rtwdev, state);
 }
 
 static void rtw89_tas_init(struct rtw89_dev *rtwdev)
                    "tas: band: %u, freq: %u\n", chan->band_type, chan->freq);
 }
 
-void rtw89_tas_track(struct rtw89_dev *rtwdev)
+static bool rtw89_tas_track(struct rtw89_dev *rtwdev)
 {
        struct rtw89_tas_info *tas = &rtwdev->tas;
        struct rtw89_hal *hal = &rtwdev->hal;
        s32 cfg;
 
        if (hal->disabled_dm_bitmap & BIT(RTW89_DM_TAS))
-               return;
+               return false;
 
        if (!rtw89_tas_is_active(rtwdev))
-               return;
+               return false;
 
-       if (!rtw89_tas_query_sar_config(rtwdev, &cfg) || tas->block_regd) {
-               rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR);
-               return;
-       }
+       if (!rtw89_tas_query_sar_config(rtwdev, &cfg) || tas->block_regd)
+               return __rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR);
 
        if (tas->pause)
-               return;
+               return false;
 
        rtw89_tas_window_update(rtwdev);
        rtw89_tas_history_update(rtwdev);
-       rtw89_tas_rolling_average(rtwdev);
+
+       return rtw89_tas_rolling_average(rtwdev);
 }
 
 void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start)
        rtw89_set_sar_from_acpi(rtwdev);
        rtw89_tas_init(rtwdev);
 }
+
+static bool rtw89_sar_track_acpi(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_sar_cfg_acpi *cfg = &rtwdev->sar.cfg_acpi;
+       struct rtw89_sar_indicator_from_acpi *ind = &cfg->indicator;
+       const enum rtw89_sar_sources src = rtwdev->sar.src;
+       bool changed;
+       int ret;
+
+       lockdep_assert_wiphy(rtwdev->hw->wiphy);
+
+       if (src != RTW89_SAR_SOURCE_ACPI)
+               return false;
+
+       if (!ind->enable_sync)
+               return false;
+
+       ret = rtw89_acpi_evaluate_dynamic_sar_indicator(rtwdev, cfg, &changed);
+       if (likely(!ret))
+               return changed;
+
+       rtw89_debug(rtwdev, RTW89_DBG_SAR,
+                   "%s: failed to track indicator: %d; reset and disable\n",
+                   __func__, ret);
+
+       memset(ind->tblsel, 0, sizeof(ind->tblsel));
+       ind->enable_sync = false;
+       return true;
+}
+
+void rtw89_sar_track(struct rtw89_dev *rtwdev)
+{
+       unsigned int changes = 0;
+
+       changes += rtw89_sar_track_acpi(rtwdev);
+       changes += rtw89_tas_track(rtwdev);
+
+       if (!changes)
+               return;
+
+       rtw89_core_set_chip_txpwr(rtwdev);
+}
 
 int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
                            const struct cfg80211_sar_specs *sar);
 void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force);
-void rtw89_tas_track(struct rtw89_dev *rtwdev);
 void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start);
 void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev,
                          enum rtw89_chanctx_state state);
 void rtw89_sar_init(struct rtw89_dev *rtwdev);
+void rtw89_sar_track(struct rtw89_dev *rtwdev);
 
 #endif