sar.o \
                coex.o \
                ps.o \
+               chan.o \
                ser.o
 
 obj-$(CONFIG_RTW89_8852A) += rtw89_8852a.o
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/* Copyright(c) 2020-2022  Realtek Corporation
+ */
+
+#include "chan.h"
+
+bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
+                             enum rtw89_sub_entity_idx idx,
+                             const struct rtw89_chan *new)
+{
+       struct rtw89_hal *hal = &rtwdev->hal;
+       struct rtw89_chan *chan = &hal->chan[idx];
+       struct rtw89_chan_rcd *rcd = &hal->chan_rcd[idx];
+       bool band_changed;
+
+       rcd->prev_primary_channel = chan->primary_channel;
+       rcd->prev_band_type = chan->band_type;
+       band_changed = new->band_type != chan->band_type;
+
+       *chan = *new;
+       return band_changed;
+}
 
        WRITE_ONCE(hal->entity_active, active);
 }
 
+bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
+                             enum rtw89_sub_entity_idx idx,
+                             const struct rtw89_chan *new);
+
 #endif
 
 void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
                              struct rtw89_sta *rtwsta, enum btc_role_state state)
 {
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
        struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
        struct rtw89_btc *btc = &rtwdev->btc;
                    vif->type == NL80211_IFTYPE_STATION);
        rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port);
        rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n",
-                   hal->current_band_type, hal->current_channel,
-                   hal->current_band_width);
+                   chan->band_type, chan->channel, chan->band_width);
        rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n",
                    state == BTC_ROLE_MSTS_STA_CONN_END);
        rtw89_debug(rtwdev, RTW89_DBG_BTC,
        r.connected = MLME_LINKED;
        r.bcn_period = vif->bss_conf.beacon_int;
        r.dtim_period = vif->bss_conf.dtim_period;
-       r.band = hal->current_band_type;
-       r.ch = hal->current_channel;
-       r.bw = hal->current_band_width;
+       r.band = chan->band_type;
+       r.ch = chan->channel;
+       r.bw = chan->band_width;
        ether_addr_copy(r.mac_addr, rtwvif->mac_addr);
 
        if (rtwsta && vif->type == NL80211_IFTYPE_STATION)
 
                                  enum rtw89_phy_idx phy_idx,
                                  enum rtw89_rf_path_bit paths)
 {
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        u8 phy_map;
 
        phy_map = FIELD_PREP(BTC_RFK_PATH_MAP, paths) |
                  FIELD_PREP(BTC_RFK_PHY_MAP, BIT(phy_idx)) |
-                 FIELD_PREP(BTC_RFK_BAND_MAP, hal->current_band_type);
+                 FIELD_PREP(BTC_RFK_BAND_MAP, chan->band_type);
 
        return phy_map;
 }
 
 {
        struct ieee80211_hw *hw = rtwdev->hw;
        const struct rtw89_chip_info *chip = rtwdev->chip;
-       struct rtw89_hal *hal = &rtwdev->hal;
        struct rtw89_chan chan;
        struct rtw89_channel_help_params bak;
-       u8 center_chan, bandwidth;
        bool band_changed;
        bool entity_active;
 
        if (WARN(chan.channel == 0, "Invalid channel\n"))
                return;
 
-       center_chan = chan.channel;
-       bandwidth = chan.band_width;
-       band_changed = hal->current_band_type != chan.band_type;
-
-       hal->current_band_width = bandwidth;
-       hal->current_channel = center_chan;
-       hal->current_freq = chan.freq;
-       hal->prev_primary_channel = hal->current_primary_channel;
-       hal->prev_band_type = hal->current_band_type;
-       hal->current_primary_channel = chan.primary_channel;
-       hal->current_band_type = chan.band_type;
-       hal->current_subband = chan.subband_type;
+       band_changed = rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &chan);
 
        rtw89_set_entity_state(rtwdev, true);
 
        rtw89_chip_set_channel_done(rtwdev, &bak);
 
        if (!entity_active || band_changed) {
-               rtw89_btc_ntfy_switch_band(rtwdev, RTW89_PHY_0, hal->current_band_type);
+               rtw89_btc_ntfy_switch_band(rtwdev, RTW89_PHY_0, chan.band_type);
                rtw89_chip_rfk_band_changed(rtwdev);
        }
 }
        struct sk_buff *skb = tx_req->skb;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ieee80211_vif *vif = tx_info->control.vif;
-       struct rtw89_hal *hal = &rtwdev->hal;
-       u16 lowest_rate = hal->current_band_type == RTW89_BAND_2G ?
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u16 lowest_rate = chan->band_type == RTW89_BAND_2G ?
                          RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6;
 
        if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta)
        struct ieee80211_vif *vif = tx_req->vif;
        struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
        struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        u8 qsel, ch_dma;
 
        qsel = desc_info->hiq ? RTW89_TX_QSEL_B0_HI : RTW89_TX_QSEL_B0_MGMT;
        desc_info->data_rate = rtw89_core_get_mgmt_rate(rtwdev, tx_req);
 
        rtw89_debug(rtwdev, RTW89_DBG_TXRX,
-                   "tx mgmt frame with rate 0x%x on channel %d (bw %d)\n",
-                   desc_info->data_rate, rtwdev->hal.current_channel,
-                   rtwdev->hal.current_band_width);
+                   "tx mgmt frame with rate 0x%x on channel %d (band %d, bw %d)\n",
+                   desc_info->data_rate, chan->channel, chan->band_type,
+                   chan->band_width);
 }
 
 static void
        };
        const struct rtw89_chip_info *chip = rtwdev->chip;
        struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        u8 om_bandwidth;
 
        if (!chip->dis_2g_40m_ul_ofdma ||
-           hal->current_band_type != RTW89_BAND_2G ||
-           hal->current_band_width != RTW89_CHANNEL_WIDTH_40)
+           chan->band_type != RTW89_BAND_2G ||
+           chan->band_width != RTW89_CHANNEL_WIDTH_40)
                return;
 
-       om_bandwidth = hal->current_band_width < ARRAY_SIZE(rtw89_bandwidth_to_om) ?
-                      rtw89_bandwidth_to_om[hal->current_band_width] : 0;
+       om_bandwidth = chan->band_width < ARRAY_SIZE(rtw89_bandwidth_to_om) ?
+                      rtw89_bandwidth_to_om[chan->band_width] : 0;
        *htc = le32_encode_bits(RTW89_HTC_VARIANT_HE, RTW89_HTC_MASK_VARIANT) |
               le32_encode_bits(RTW89_HTC_VARIANT_HE_CID_OM, RTW89_HTC_MASK_CTL_ID) |
               le32_encode_bits(hal->rx_nss - 1, RTW89_HTC_MASK_HTC_OM_RX_NSS) |
        struct ieee80211_vif *vif = tx_req->vif;
        struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
        struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info;
        struct sk_buff *skb = tx_req->skb;
        u8 tid, tid_indicate;
 
        if (rate_pattern->enable)
                desc_info->data_retry_lowest_rate = rate_pattern->rate;
-       else if (hal->current_band_type == RTW89_BAND_2G)
+       else if (chan->band_type == RTW89_BAND_2G)
                desc_info->data_retry_lowest_rate = RTW89_HW_RATE_CCK1;
        else
                desc_info->data_retry_lowest_rate = RTW89_HW_RATE_OFDM6;
 static void rtw89_correct_cck_chan(struct rtw89_dev *rtwdev,
                                   struct ieee80211_rx_status *status)
 {
-       u16 chan = rtwdev->hal.prev_primary_channel;
-       u8 band = chan <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
+       const struct rtw89_chan_rcd *rcd =
+               rtw89_chan_rcd_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u16 chan = rcd->prev_primary_channel;
+       u8 band = rcd->prev_band_type == RTW89_BAND_2G ?
+                 NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
 
        if (status->band != NL80211_BAND_2GHZ &&
            status->encoding == RX_ENC_LEGACY &&
                                        struct ieee80211_rx_status *rx_status)
 {
        struct ieee80211_hw *hw = rtwdev->hw;
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        u16 data_rate;
        u8 data_rate_mode;
 
 
        if (rtwdev->scanning &&
            RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
-               u8 chan = hal->current_primary_channel;
-               u8 band = hal->current_band_type;
+               u8 chan = cur->primary_channel;
+               u8 band = cur->band_type;
                enum nl80211_band nl_band;
 
                nl_band = rtw89_hw_to_nl80211_band(band);
 void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
                           const u8 *mac_addr, bool hw_scan)
 {
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 
        rtwdev->scanning = true;
        rtw89_leave_lps(rtwdev);
                rtw89_leave_ips(rtwdev);
 
        ether_addr_copy(rtwvif->mac_addr, mac_addr);
-       rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, hal->current_band_type);
+       rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type);
        rtw89_chip_rfk_scan(rtwdev, true);
        rtw89_hci_recalc_int_mit(rtwdev);
 
 
        RTW89_PHY_MAX
 };
 
+enum rtw89_sub_entity_idx {
+       RTW89_SUB_ENTITY_0 = 0,
+
+       NUM_OF_RTW89_SUB_ENTITY,
+};
+
 enum rtw89_rf_path {
        RF_PATH_A = 0,
        RF_PATH_B = 1,
        enum rtw89_sc_offset pri_ch_idx;
 };
 
+struct rtw89_chan_rcd {
+       u8 prev_primary_channel;
+       enum rtw89_band prev_band_type;
+};
+
 struct rtw89_channel_help_params {
        u32 tx_en;
 };
 struct rtw89_hal {
        u32 rx_fltr;
        u8 cv;
-       u8 current_channel;
-       u32 current_freq;
-       u8 prev_primary_channel;
-       u8 current_primary_channel;
-       enum rtw89_subband current_subband;
-       u8 current_band_width;
-       u8 prev_band_type;
-       u8 current_band_type;
        u32 sw_amsdu_max_size;
        u32 antenna_tx;
        u32 antenna_rx;
        bool support_igi;
 
        bool entity_active;
+
+       struct rtw89_chan chan[NUM_OF_RTW89_SUB_ENTITY];
+       struct rtw89_chan_rcd chan_rcd[NUM_OF_RTW89_SUB_ENTITY];
 };
 
 #define RTW89_MAX_MAC_ID_NUM 128
        rtwdev->chip->ops->set_channel_help(rtwdev, false, p);
 }
 
+static inline
+const struct rtw89_chan *rtw89_chan_get(struct rtw89_dev *rtwdev,
+                                       enum rtw89_sub_entity_idx idx)
+{
+       struct rtw89_hal *hal = &rtwdev->hal;
+
+       return &hal->chan[idx];
+}
+
+static inline
+const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev,
+                                               enum rtw89_sub_entity_idx idx)
+{
+       struct rtw89_hal *hal = &rtwdev->hal;
+
+       return &hal->chan_rcd[idx];
+}
+
 static inline void rtw89_chip_fem_setup(struct rtw89_dev *rtwdev)
 {
        const struct rtw89_chip_info *chip = rtwdev->chip;
 
 
 static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev)
 {
-       u8 band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 band = chan->band_type;
        u8 regd = rtw89_regd_get(rtwdev, band);
 
        switch (regd) {
 
  */
 
 #include "cam.h"
+#include "chan.h"
 #include "coex.h"
 #include "debug.h"
 #include "fw.h"
                                struct ieee80211_sta *sta)
 {
        const struct rtw89_chip_info *chip = rtwdev->chip;
-       struct rtw89_hal *hal = &rtwdev->hal;
        struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
        struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct sk_buff *skb;
        u8 pads[RTW89_PPE_BW_NUM];
        u8 mac_id = rtwsta ? rtwsta->mac_id : rtwvif->mac_id;
        SET_CTRL_INFO_OPERATION(skb->data, 1);
        SET_CMC_TBL_DISRTSFB(skb->data, 1);
        SET_CMC_TBL_DISDATAFB(skb->data, 1);
-       if (hal->current_band_type == RTW89_BAND_2G)
+       if (chan->band_type == RTW89_BAND_2G)
                SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_CCK1);
        else
                SET_CMC_TBL_RTS_RTY_LOWEST_RATE(skb->data, RTW89_HW_RATE_OFDM6);
 int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
                               struct rtw89_vif *rtwvif)
 {
-       struct rtw89_hal *hal = &rtwdev->hal;
        struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct sk_buff *skb;
        struct sk_buff *skb_beacon;
        u16 tim_offset;
        SET_BCN_UPD_MACID(skb->data, rtwvif->mac_id);
        SET_BCN_UPD_SSN_SEL(skb->data, RTW89_MGMT_HW_SSN_SEL);
        SET_BCN_UPD_SSN_MODE(skb->data, RTW89_MGMT_HW_SEQ_MODE);
-       SET_BCN_UPD_RATE(skb->data, hal->current_band_type == RTW89_BAND_2G ?
+       SET_BCN_UPD_RATE(skb->data, chan->band_type == RTW89_BAND_2G ?
                                    RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6);
 
        skb_put_data(skb, skb_beacon->data, skb_beacon->len);
 
 int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev)
 {
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
        struct rtw89_fw_h2c_rf_get_mccch *mccch;
        struct sk_buff *skb;
        mccch->ch_1 = cpu_to_le32(mcc_info->ch[1]);
        mccch->band_0 = cpu_to_le32(mcc_info->band[0]);
        mccch->band_1 = cpu_to_le32(mcc_info->band[1]);
-       mccch->current_channel = cpu_to_le32(rtwdev->hal.current_channel);
-       mccch->current_band_type = cpu_to_le32(rtwdev->hal.current_band_type);
+       mccch->current_channel = cpu_to_le32(chan->channel);
+       mccch->current_band_type = cpu_to_le32(chan->band_type);
 
        rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
                              H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
 void rtw89_store_op_chan(struct rtw89_dev *rtwdev, bool backup)
 {
        struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info;
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       struct rtw89_chan new;
 
        if (backup) {
-               scan_info->op_pri_ch = hal->current_primary_channel;
-               scan_info->op_chan = hal->current_channel;
-               scan_info->op_bw = hal->current_band_width;
-               scan_info->op_band = hal->current_band_type;
+               scan_info->op_pri_ch = cur->primary_channel;
+               scan_info->op_chan = cur->channel;
+               scan_info->op_bw = cur->band_width;
+               scan_info->op_band = cur->band_type;
        } else {
-               hal->current_primary_channel = scan_info->op_pri_ch;
-               hal->current_channel = scan_info->op_chan;
-               hal->current_band_width = scan_info->op_bw;
-               hal->current_band_type = scan_info->op_band;
+               new = *cur;
+               new.primary_channel = scan_info->op_pri_ch;
+               new.channel = scan_info->op_chan;
+               new.band_width = scan_info->op_bw;
+               new.band_type = scan_info->op_band;
+               rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new);
        }
 }
 
 
                           u32 len)
 {
        struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *cur = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       struct rtw89_chan new;
        u8 reason, status, tx_fail, band;
        u16 chan;
 
                rtw89_hw_scan_complete(rtwdev, vif, false);
                break;
        case RTW89_SCAN_ENTER_CH_NOTIFY:
-               hal->prev_band_type = hal->current_band_type;
-               hal->current_band_type = band;
-               hal->prev_primary_channel = hal->current_primary_channel;
-               hal->current_primary_channel = chan;
-               hal->current_channel = chan;
-               hal->current_band_width = RTW89_CHANNEL_WIDTH_20;
+               new = *cur;
+               new.channel = chan;
+               new.primary_channel = chan;
+               new.band_type = band;
+               new.band_width = RTW89_CHANNEL_WIDTH_20;
+               rtw89_assign_entity_chan(rtwdev, RTW89_SUB_ENTITY_0, &new);
                if (rtw89_is_op_chan(rtwdev, band, chan)) {
                        rtw89_store_op_chan(rtwdev, false);
                        ieee80211_wake_queues(rtwdev->hw);
 
                              struct rtw89_vif *rtwvif, u8 aifsn)
 {
        struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        u8 slot_time;
        u8 sifs;
 
        slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
-       sifs = rtwdev->hal.current_band_type == RTW89_BAND_5G ? 16 : 10;
+       sifs = chan->band_type == RTW89_BAND_5G ? 16 : 10;
 
        return aifsn * slot_time + sifs;
 }
 
 
 static u64 rtw89_phy_ra_mask_cfg(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta)
 {
-       struct rtw89_hal *hal = &rtwdev->hal;
        struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct cfg80211_bitrate_mask *mask = &rtwsta->mask;
        enum nl80211_band band;
        u64 cfg_mask;
        if (!rtwsta->use_cfg_mask)
                return -1;
 
-       switch (hal->current_band_type) {
+       switch (chan->band_type) {
        case RTW89_BAND_2G:
                band = NL80211_BAND_2GHZ;
                cfg_mask = u64_encode_bits(mask->control[NL80211_BAND_2GHZ].legacy,
                                           RA_MASK_OFDM_RATES);
                break;
        default:
-               rtw89_warn(rtwdev, "unhandled band type %d\n", hal->current_band_type);
+               rtw89_warn(rtwdev, "unhandled band type %d\n", chan->band_type);
                return -1;
        }
 
        struct rtw89_vif *rtwvif = rtwsta->rtwvif;
        struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern;
        struct rtw89_ra_info *ra = &rtwsta->ra;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        const u64 *high_rate_masks = rtw89_ra_mask_ht_rates;
        u8 rssi = ewma_rssi_read(&rtwsta->avg_rssi);
        u64 ra_mask = 0;
                        ldpc_en = 1;
        }
 
-       switch (rtwdev->hal.current_band_type) {
+       switch (chan->band_type) {
        case RTW89_BAND_2G:
                ra_mask |= sta->deflink.supp_rates[NL80211_BAND_2GHZ];
                if (sta->deflink.supp_rates[NL80211_BAND_2GHZ] <= 0xf)
        struct ieee80211_supported_band *sband;
        struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
        struct rtw89_phy_rate_pattern next_pattern = {0};
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        static const u16 hw_rate_he[] = {RTW89_HW_RATE_HE_NSS1_MCS0,
                                         RTW89_HW_RATE_HE_NSS2_MCS0,
                                         RTW89_HW_RATE_HE_NSS3_MCS0,
                                         RTW89_HW_RATE_MCS8,
                                         RTW89_HW_RATE_MCS16,
                                         RTW89_HW_RATE_MCS24};
-       u8 band = rtwdev->hal.current_band_type;
+       u8 band = chan->band_type;
        enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
        u8 tx_nss = rtwdev->hal.tx_nss;
        u8 i;
 s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev,
                               const struct rtw89_rate_desc *rate_desc)
 {
-       enum rtw89_band band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
        s8 *byr;
        u8 idx;
 
                              u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch)
 {
        const struct rtw89_chip_info *chip = rtwdev->chip;
-       u8 band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 band = chan->band_type;
        u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
        u8 regd = rtw89_regd_get(rtwdev, band);
        s8 lmt = 0, sar;
                                struct rtw89_txpwr_limit *lmt,
                                u8 ntx)
 {
-       u8 pri_ch = rtwdev->hal.current_primary_channel;
-       u8 ch = rtwdev->hal.current_channel;
-       u8 bw = rtwdev->hal.current_band_width;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 pri_ch = chan->primary_channel;
+       u8 ch = chan->channel;
+       u8 bw = chan->band_width;
 
        memset(lmt, 0, sizeof(*lmt));
 
                                        u8 ru, u8 ntx, u8 ch)
 {
        const struct rtw89_chip_info *chip = rtwdev->chip;
-       u8 band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 band = chan->band_type;
        u8 ch_idx = rtw89_channel_to_idx(rtwdev, band, ch);
        u8 regd = rtw89_regd_get(rtwdev, band);
        s8 lmt_ru = 0, sar;
                                   struct rtw89_txpwr_limit_ru *lmt_ru,
                                   u8 ntx)
 {
-       u8 ch = rtwdev->hal.current_channel;
-       u8 bw = rtwdev->hal.current_band_width;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
+       u8 bw = chan->band_width;
 
        memset(lmt_ru, 0, sizeof(*lmt_ru));
 
 static void rtw89_phy_dig_update_para(struct rtw89_dev *rtwdev)
 {
        struct rtw89_dig_info *dig = &rtwdev->dig;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        bool is_linked = rtwdev->total_sta_assoc > 0;
        const u16 *fa_th_src = NULL;
 
-       switch (rtwdev->hal.current_band_type) {
+       switch (chan->band_type) {
        case RTW89_BAND_2G:
                dig->lna_gain = dig->lna_gain_g;
                dig->tia_gain = dig->tia_gain_g;
 static void rtw89_phy_dig_dyn_pd_th(struct rtw89_dev *rtwdev, u8 rssi,
                                    bool enable)
 {
-       enum rtw89_bandwidth cbw = rtwdev->hal.current_band_width;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_bandwidth cbw = chan->band_width;
        struct rtw89_dig_info *dig = &rtwdev->dig;
        u8 final_rssi = 0, under_region = dig->pd_low_th_ofst;
        u8 ofdm_cca_th;
 
 static void rtw8852a_set_txpwr_byrate(struct rtw89_dev *rtwdev,
                                      enum rtw89_phy_idx phy_idx)
 {
-       u8 ch = rtwdev->hal.current_channel;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
        static const u8 rs[] = {
                RTW89_RS_CCK,
                RTW89_RS_OFDM,
                                     enum rtw89_phy_idx phy_idx)
 {
 #define __MAC_TXPWR_LMT_PAGE_SIZE 40
-       u8 ch = rtwdev->hal.current_channel;
-       u8 bw = rtwdev->hal.current_band_width;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
+       u8 bw = chan->band_width;
        struct rtw89_txpwr_limit lmt[NTX_NUM_8852A];
        u32 addr, val;
        const s8 *ptr;
                                        enum rtw89_phy_idx phy_idx)
 {
 #define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
-       u8 ch = rtwdev->hal.current_channel;
-       u8 bw = rtwdev->hal.current_band_width;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
+       u8 bw = chan->band_width;
        struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852A];
        u32 addr, val;
        const s8 *ptr;
                             struct rtw8852a_bb_pmac_info *tx_info,
                             enum rtw89_phy_idx idx)
 {
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+
        if (!tx_info->en_pmac_tx) {
                rtw8852a_stop_pmac_tx(rtwdev, tx_info, idx);
                rtw89_phy_write32_idx(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0, idx);
-               if (rtwdev->hal.current_band_type == RTW89_BAND_2G)
+               if (chan->band_type == RTW89_BAND_2G)
                        rtw89_phy_write32_clr(rtwdev, R_RXCCA, B_RXCCA_DIS);
                return;
        }
 
                             enum rtw89_phy_idx phy, u8 path)
 {
        struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        u32 reg_rf18 = 0x0, reg_35c = 0x0;
        u8 idx = 0;
        u8 get_empty_table = false;
        rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]cfg ch = %d\n", reg_rf18);
        reg_35c = rtw89_phy_read32_mask(rtwdev, 0x35c, 0x00000c00);
 
-       iqk_info->iqk_band[path] = hal->current_band_type;
-       iqk_info->iqk_bw[path] = hal->current_band_width;
-       iqk_info->iqk_ch[path] = hal->current_channel;
+       iqk_info->iqk_band[path] = chan->band_type;
+       iqk_info->iqk_bw[path] = chan->band_width;
+       iqk_info->iqk_ch[path] = chan->channel;
 
        rtw89_debug(rtwdev, RTW89_DBG_RFK,
                    "[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path,
                             enum rtw89_rf_path path)
 {
        struct rtw89_dpk_info *dpk = &rtwdev->dpk;
-       struct rtw89_hal *hal = &rtwdev->hal;
-
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        u8 kidx = dpk->cur_idx[path];
 
-       dpk->bp[path][kidx].band = hal->current_band_type;
-       dpk->bp[path][kidx].ch = hal->current_channel;
-       dpk->bp[path][kidx].bw = hal->current_band_width;
+       dpk->bp[path][kidx].band = chan->band_type;
+       dpk->bp[path][kidx].ch = chan->channel;
+       dpk->bp[path][kidx].bw = chan->band_width;
 
        rtw89_debug(rtwdev, RTW89_DBG_RFK,
                    "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
 #define DPK_RXBB_UPPER 0x1f
 #define DPK_RXBB_LOWER 0
 #define DPK_GL_CRIT 7
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0;
        u8 agc_cnt = 0;
        bool limited_rxbb = false;
                                    "[DPK] Adjust RXBB (%d) = 0x%x\n", offset,
                                    tmp_rxbb);
                        if (offset != 0 || agc_cnt == 0) {
-                               if (rtwdev->hal.current_band_width < RTW89_CHANNEL_WIDTH_80)
+                               if (chan->band_width < RTW89_CHANNEL_WIDTH_80)
                                        _dpk_bypass_rxcfir(rtwdev, path, true);
                                else
                                        _dpk_lbk_rxiqk(rtwdev, phy, path);
                              enum rtw89_rf_path path)
 {
        struct rtw89_dpk_info *dpk = &rtwdev->dpk;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        bool is_reload = false;
        u8 idx, cur_band, cur_ch;
 
-       cur_band = rtwdev->hal.current_band_type;
-       cur_ch = rtwdev->hal.current_channel;
+       cur_band = chan->band_type;
+       cur_ch = chan->channel;
 
        for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) {
                if (cur_band != dpk->bp[path][idx].band ||
 static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
 {
        struct rtw89_fem_info *fem = &rtwdev->fem;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 
-       if (fem->epa_2g && rtwdev->hal.current_band_type == RTW89_BAND_2G) {
+       if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) {
                rtw89_debug(rtwdev, RTW89_DBG_RFK,
                            "[DPK] Skip DPK due to 2G_ext_PA exist!!\n");
                return true;
-       } else if (fem->epa_5g && rtwdev->hal.current_band_type == RTW89_BAND_5G) {
+       } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) {
                rtw89_debug(rtwdev, RTW89_DBG_RFK,
                            "[DPK] Skip DPK due to 5G_ext_PA exist!!\n");
                return true;
 static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
                             enum rtw89_rf_path path)
 {
-       enum rtw89_band band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
 
        if (band == RTW89_BAND_2G)
                rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1);
 
 static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
 {
-       enum rtw89_band band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
 
        rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_sys_defs_tbl);
        rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
 static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
                                    enum rtw89_rf_path path)
 {
-       enum rtw89_band band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
 
        rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
                                 &rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl,
        __val;                                          \
 })
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
-       u8 ch = rtwdev->hal.current_channel;
-       u8 subband = rtwdev->hal.current_subband;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
+       u8 subband = chan->subband_type;
        const s8 *thm_up_a = NULL;
        const s8 *thm_down_a = NULL;
        const s8 *thm_up_b = NULL;
 static void _tssi_pak(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
                      enum rtw89_rf_path path)
 {
-       u8 subband = rtwdev->hal.current_subband;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 subband = chan->subband_type;
 
        switch (subband) {
        default:
                            enum rtw89_rf_path path)
 {
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
-       u8 ch = rtwdev->hal.current_channel;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
        u32 gidx, gidx_1st, gidx_2nd;
        s8 de_1st = 0;
        s8 de_2nd = 0;
                                 enum rtw89_rf_path path)
 {
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
-       u8 ch = rtwdev->hal.current_channel;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
        u32 tgidx, tgidx_1st, tgidx_2nd;
        s8 tde_1st = 0;
        s8 tde_2nd = 0;
 {
 #define __DE_MASK 0x003ff000
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        static const u32 r_cck_long[RF_PATH_NUM_8852A] = {0x5858, 0x7858};
        static const u32 r_cck_short[RF_PATH_NUM_8852A] = {0x5860, 0x7860};
        static const u32 r_mcs_20m[RF_PATH_NUM_8852A] = {0x5838, 0x7838};
        static const u32 r_mcs_80m_80m[RF_PATH_NUM_8852A] = {0x5850, 0x7850};
        static const u32 r_mcs_5m[RF_PATH_NUM_8852A] = {0x5828, 0x7828};
        static const u32 r_mcs_10m[RF_PATH_NUM_8852A] = {0x5830, 0x7830};
-       u8 ch = rtwdev->hal.current_channel;
+       u8 ch = chan->channel;
        u8 i, gidx;
        s8 ofdm_de;
        s8 trim_de;
 static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
 {
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
-       u8 ch = rtwdev->hal.current_channel, ch_tmp;
-       u8 bw = rtwdev->hal.current_band_width;
-       u8 subband = rtwdev->hal.current_subband;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel, ch_tmp;
+       u8 bw = chan->band_width;
+       u8 subband = chan->subband_type;
        s8 power;
        s32 xdbm;
 
 static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
 {
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        const struct rtw89_chip_info *mac_reg = rtwdev->chip;
-       u8 ch = rtwdev->hal.current_channel, ch_tmp;
-       u8 bw = rtwdev->hal.current_band_width;
+       u8 ch = chan->channel, ch_tmp;
+       u8 bw = chan->band_width;
        u32 tx_en;
        u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0);
        s8 power;
 
 static void rtw8852c_bb_reset_en(struct rtw89_dev *rtwdev,
                                 enum rtw89_phy_idx phy_idx, bool en)
 {
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
 
        if (en) {
                rtw89_phy_write32_idx(rtwdev, R_S0_HW_SI_DIS,
                                      B_S1_HW_SI_DIS_W_R_TRIG, 0x0, phy_idx);
                rtw89_phy_write32_idx(rtwdev, R_RSTB_ASYNC, B_RSTB_ASYNC_ALL, 1,
                                      phy_idx);
-               if (hal->current_band_type == RTW89_BAND_2G)
+               if (chan->band_type == RTW89_BAND_2G)
                        rtw89_phy_write32_mask(rtwdev, R_RXCCA_V1, B_RXCCA_DIS_V1, 0x0);
                rtw89_phy_write32_mask(rtwdev, R_PD_CTRL, B_PD_HIT_DIS, 0x0);
        } else {
 static void rtw8852c_set_txpwr_byrate(struct rtw89_dev *rtwdev,
                                      enum rtw89_phy_idx phy_idx)
 {
-       u8 ch = rtwdev->hal.current_channel;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
        static const u8 rs[] = {
                RTW89_RS_CCK,
                RTW89_RS_OFDM,
        __DECL_DFIR_ADDR(filter,
                         0x45BC, 0x45CC, 0x45D0, 0x45D4, 0x45D8, 0x45C0,
                         0x45C4, 0x45C8);
-       u8 ch = rtwdev->hal.current_channel;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
        const u32 *param;
        int i;
 
 static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
                                  enum rtw89_phy_idx phy_idx)
 {
-       u8 band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 band = chan->band_type;
        u8 regd = rtw89_regd_get(rtwdev, band);
        u8 tx_shape_cck = rtw89_8852c_tx_shape[band][RTW89_RS_CCK][regd];
        u8 tx_shape_ofdm = rtw89_8852c_tx_shape[band][RTW89_RS_OFDM][regd];
                                     enum rtw89_phy_idx phy_idx)
 {
 #define __MAC_TXPWR_LMT_PAGE_SIZE 40
-       u8 ch = rtwdev->hal.current_channel;
-       u8 bw = rtwdev->hal.current_band_width;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
+       u8 bw = chan->band_width;
        struct rtw89_txpwr_limit lmt[NTX_NUM_8852C];
        u32 addr, val;
        const s8 *ptr;
                                        enum rtw89_phy_idx phy_idx)
 {
 #define __MAC_TXPWR_LMT_RU_PAGE_SIZE 24
-       u8 ch = rtwdev->hal.current_channel;
-       u8 bw = rtwdev->hal.current_band_width;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
+       u8 bw = chan->band_width;
        struct rtw89_txpwr_limit_ru lmt_ru[NTX_NUM_8852C];
        u32 addr, val;
        const s8 *ptr;
 
 static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
 {
-       struct rtw89_hal *hal = &rtwdev->hal;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 band = chan->band_type;
        u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
        u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
 
                                               1);
                        rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
                                               1);
-                       rtw8852c_ctrl_btg(rtwdev, hal->current_band_type == RTW89_BAND_2G);
+                       rtw8852c_ctrl_btg(rtwdev, band == RTW89_BAND_2G);
                        rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
                                               rst_mask0, 1);
                        rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
 
 static void _iqk_get_ch_info(struct rtw89_dev *rtwdev,
                             enum rtw89_phy_idx phy, u8 path)
 {
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
-       struct rtw89_hal *hal = &rtwdev->hal;
 
        rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
 
-       iqk_info->iqk_band[path] = hal->current_band_type;
-       iqk_info->iqk_bw[path] = hal->current_band_width;
-       iqk_info->iqk_ch[path] = hal->current_channel;
+       iqk_info->iqk_band[path] = chan->band_type;
+       iqk_info->iqk_bw[path] = chan->band_width;
+       iqk_info->iqk_ch[path] = chan->channel;
 
        rtw89_debug(rtwdev, RTW89_DBG_RFK,
                    "[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path,
                             enum rtw89_phy_idx phy,
                             enum rtw89_rf_path path)
 {
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct rtw89_dpk_info *dpk = &rtwdev->dpk;
-       struct rtw89_hal *hal = &rtwdev->hal;
 
        u8 kidx = dpk->cur_idx[path];
 
-       dpk->bp[path][kidx].band = hal->current_band_type;
-       dpk->bp[path][kidx].ch = hal->current_channel;
-       dpk->bp[path][kidx].bw = hal->current_band_width;
+       dpk->bp[path][kidx].band = chan->band_type;
+       dpk->bp[path][kidx].ch = chan->channel;
+       dpk->bp[path][kidx].bw = chan->band_width;
 
        rtw89_debug(rtwdev, RTW89_DBG_RFK,
                    "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
 static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
                              enum rtw89_rf_path path)
 {
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct rtw89_dpk_info *dpk = &rtwdev->dpk;
        bool is_reload = false;
        u8 idx, cur_band, cur_ch;
 
-       cur_band = rtwdev->hal.current_band_type;
-       cur_ch = rtwdev->hal.current_channel;
+       cur_band = chan->band_type;
+       cur_ch = chan->channel;
 
        for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) {
                if (cur_band != dpk->bp[path][idx].band ||
 static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
 {
        struct rtw89_fem_info *fem = &rtwdev->fem;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 band = chan->band_type;
 
-       if (rtwdev->hal.cv == CHIP_CAV && rtwdev->hal.current_band_type != RTW89_BAND_2G) {
+       if (rtwdev->hal.cv == CHIP_CAV && band != RTW89_BAND_2G) {
                rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to CAV & not 2G!!\n");
                return true;
-       } else if (fem->epa_2g && rtwdev->hal.current_band_type == RTW89_BAND_2G) {
+       } else if (fem->epa_2g && band == RTW89_BAND_2G) {
                rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 2G_ext_PA exist!!\n");
                return true;
-       } else if (fem->epa_5g && rtwdev->hal.current_band_type == RTW89_BAND_5G) {
+       } else if (fem->epa_5g && band == RTW89_BAND_5G) {
                rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 5G_ext_PA exist!!\n");
                return true;
-       } else if (fem->epa_6g && rtwdev->hal.current_band_type == RTW89_BAND_6G) {
+       } else if (fem->epa_6g && band == RTW89_BAND_6G) {
                rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Skip DPK due to 6G_ext_PA exist!!\n");
                return true;
        }
 static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
                          enum rtw89_rf_path path)
 {
-       enum rtw89_band band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
 
        rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_sys_defs_tbl);
 
 static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
                          enum rtw89_rf_path path)
 {
-       enum rtw89_band band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
 
        if (path == RF_PATH_A) {
                rtw89_rfk_parser(rtwdev, &rtw8852c_tssi_dck_defs_a_tbl);
        __val;                                          \
 })
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
-       u8 ch = rtwdev->hal.current_channel;
-       u8 subband = rtwdev->hal.current_subband;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
+       u8 subband = chan->subband_type;
        const s8 *thm_up_a = NULL;
        const s8 *thm_down_a = NULL;
        const s8 *thm_up_b = NULL;
 static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
                                enum rtw89_rf_path path)
 {
-       enum rtw89_band band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
 
        if (path == RF_PATH_A) {
                rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
 static void _tssi_set_aligk_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
                                    enum rtw89_rf_path path)
 {
-       enum rtw89_band band = rtwdev->hal.current_band_type;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
        const struct rtw89_rfk_tbl *tbl;
 
        if (path == RF_PATH_A) {
                            enum rtw89_rf_path path)
 {
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
-       enum rtw89_band band = rtwdev->hal.current_band_type;
-       u8 ch = rtwdev->hal.current_channel;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
+       u8 ch = chan->channel;
        u32 gidx, gidx_1st, gidx_2nd;
        s8 de_1st;
        s8 de_2nd;
                                 enum rtw89_rf_path path)
 {
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
-       enum rtw89_band band = rtwdev->hal.current_band_type;
-       u8 ch = rtwdev->hal.current_channel;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
+       u8 ch = chan->channel;
        u32 tgidx, tgidx_1st, tgidx_2nd;
        s8 tde_1st = 0;
        s8 tde_2nd = 0;
                                  enum rtw89_phy_idx phy)
 {
        struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
-       u8 ch = rtwdev->hal.current_channel;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       u8 ch = chan->channel;
        u8 gidx;
        s8 ofdm_de;
        s8 trim_de;
 
 void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 {
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
        struct rtw89_mcc_info *mcc_info = &rtwdev->mcc;
        u8 idx = mcc_info->table_idx;
        int i;
        }
 
        mcc_info->table_idx = idx;
-       mcc_info->ch[idx] = rtwdev->hal.current_channel;
-       mcc_info->band[idx] = rtwdev->hal.current_band_type;
+       mcc_info->ch[idx] = chan->channel;
+       mcc_info->band[idx] = chan->band_type;
 }
 
 void rtw8852c_rck(struct rtw89_dev *rtwdev)
 
 static int rtw89_query_sar_config_common(struct rtw89_dev *rtwdev, s32 *cfg)
 {
        struct rtw89_sar_cfg_common *rtwsar = &rtwdev->sar.cfg_common;
-       struct rtw89_hal *hal = &rtwdev->hal;
-       enum rtw89_band band = hal->current_band_type;
-       u32 center_freq = hal->current_freq;
+       const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
+       enum rtw89_band band = chan->band_type;
+       u32 center_freq = chan->freq;
        const struct rtw89_sar_span *span = NULL;
        enum rtw89_sar_subband subband_l, subband_h;
        int idx;