struct ath12k *ar;
        int ret;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        ret = ath12k_mac_config(ar, changed);
        if (ret)
        struct ath12k *ar;
        struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
 
        int ret;
        int i;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
 
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
        struct ath12k *ar;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
        ath12k_scan_abort(ar);
            key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
                return 1;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
             new_state == IEEE80211_STA_NOTEXIST))
                cancel_work_sync(&arsta->update_wk);
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
 
        if (txpwr > ATH12K_TX_POWER_MAX_VAL || txpwr < ATH12K_TX_POWER_MIN_VAL)
                return -EINVAL;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
 
        struct ath12k_peer *peer;
        u32 bw, smps;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        spin_lock_bh(&ar->ab->base_lock);
 
        struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
        int ret;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
        ret = ath12k_mac_conf_tx(arvif, link_id, ac, params);
 static int ath12k_mac_op_start(struct ieee80211_hw *hw)
 {
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
-       struct ath12k *ar = ath12k_ah_to_ar(ah);
+       struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
        struct ath12k_base *ab = ar->ab;
        int ret;
 
 static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
 {
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
-       struct ath12k *ar = ath12k_ah_to_ar(ah);
+       struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
 
        ath12k_mac_drain_tx(ar);
 
 
        vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        mutex_lock(&ar->conf_mutex);
        unsigned long time_left;
        int ret;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        mutex_lock(&ar->conf_mutex);
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
        struct ath12k *ar;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
 
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
        struct ath12k *ar;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
 
        struct ath12k *ar;
        int ret;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
        ret = __ath12k_set_antenna(ar, tx_ant, rx_ant);
        struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
        int ret = -EINVAL;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
        ret = ath12k_mac_ampdu_action(arvif, params);
        struct ath12k *ar;
        struct ath12k_base *ab;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        ath12k_dbg(ab, ATH12K_DBG_MAC,
        struct ath12k *ar;
        struct ath12k_base *ab;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        ath12k_dbg(ab, ATH12K_DBG_MAC,
        struct ath12k *ar;
        struct ath12k_base *ab;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        mutex_lock(&ar->conf_mutex);
        int ret;
        struct ath12k_wmi_peer_create_arg param;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        mutex_lock(&ar->conf_mutex);
        struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
        int ret;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        mutex_lock(&ar->conf_mutex);
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
        struct ath12k *ar;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
 
        struct ath12k *ar;
        int param_id = WMI_VDEV_PARAM_RTS_THRESHOLD, ret;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        ret = ath12k_set_vdev_param_to_all_vifs(ar, param_id, value);
 
                                u32 queues, bool drop)
 {
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
-       struct ath12k *ar = ath12k_ah_to_ar(ah);
+       struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
 
        if (drop)
                return;
        if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
                return;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
        ab = ar->ab;
 
        mutex_lock(&ar->conf_mutex);
        if (idx >= ATH12K_NUM_CHANS)
                return -ENOENT;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        ar_survey = &ar->survey[idx];
 
        struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
        struct ath12k *ar;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
 
        u32 scan_time_msec;
        int ret;
 
-       ar = ath12k_ah_to_ar(ah);
+       ar = ath12k_ah_to_ar(ah, 0);
 
        mutex_lock(&ar->conf_mutex);
        spin_lock_bh(&ar->data_lock);
 
 static u16 ath12k_mac_get_ifmodes(struct ath12k_hw *ah)
 {
-       struct ath12k *ar = ath12k_ah_to_ar(ah);
+       struct ath12k *ar;
+       int i;
        u16 interface_modes = U16_MAX;
 
-       interface_modes &= ar->ab->hw_params->interface_modes;
+       for_each_ar(ah, ar, i)
+               interface_modes &= ar->ab->hw_params->interface_modes;
 
        return interface_modes == U16_MAX ? 0 : interface_modes;
 }
 static bool ath12k_mac_is_iface_mode_enable(struct ath12k_hw *ah,
                                            enum nl80211_iftype type)
 {
-       struct ath12k *ar = ath12k_ah_to_ar(ah);
+       struct ath12k *ar;
+       int i;
        u16 interface_modes, mode;
        bool is_enable = true;
 
        mode = BIT(type);
-
-       interface_modes = ar->ab->hw_params->interface_modes;
-       if (!(interface_modes & mode))
-               is_enable = false;
+       for_each_ar(ah, ar, i) {
+               interface_modes = ar->ab->hw_params->interface_modes;
+               if (!(interface_modes & mode)) {
+                       is_enable = false;
+                       break;
+               }
+       }
 
        return is_enable;
 }
 {
        struct ieee80211_hw *hw = ah->hw;
        struct wiphy *wiphy = hw->wiphy;
-       struct ath12k *ar = ath12k_ah_to_ar(ah);
+       struct ath12k *ar;
+       int i;
 
-       cancel_work_sync(&ar->regd_update_work);
+       for_each_ar(ah, ar, i)
+               cancel_work_sync(&ar->regd_update_work);
 
        ieee80211_unregister_hw(hw);
 
-       ath12k_mac_cleanup_unregister(ar);
+       for_each_ar(ah, ar, i)
+               ath12k_mac_cleanup_unregister(ar);
 
        kfree(wiphy->iface_combinations[0].limits);
        kfree(wiphy->iface_combinations);
 {
        struct ieee80211_hw *hw = ah->hw;
        struct wiphy *wiphy = hw->wiphy;
-       struct ath12k *ar = ath12k_ah_to_ar(ah);
+       struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
        struct ath12k_base *ab = ar->ab;
        struct ath12k_pdev *pdev;
        struct ath12k_pdev_cap *cap;
                WLAN_CIPHER_SUITE_GCMP_256,
                WLAN_CIPHER_SUITE_CCMP_256,
        };
-       int ret;
-       u32 ht_cap = 0;
+       int ret, i, j;
+       u32 ht_cap = U32_MAX, antennas_rx = 0, antennas_tx = 0;
+       bool is_6ghz = false, is_raw_mode = false, is_monitor_disable = false;
+       u8 *mac_addr = NULL;
 
-       pdev = ar->pdev;
+       wiphy->max_ap_assoc_sta = 0;
 
-       if (ab->pdevs_macaddr_valid)
-               ether_addr_copy(ar->mac_addr, pdev->mac_addr);
-       else
-               ether_addr_copy(ar->mac_addr, ab->mac_addr);
+       for_each_ar(ah, ar, i) {
+               u32 ht_cap_info = 0;
 
-       ret = ath12k_mac_setup_register(ar, &ht_cap, hw->wiphy->bands);
-       if (ret)
-               goto out;
+               pdev = ar->pdev;
+               if (ar->ab->pdevs_macaddr_valid) {
+                       ether_addr_copy(ar->mac_addr, pdev->mac_addr);
+               } else {
+                       ether_addr_copy(ar->mac_addr, ar->ab->mac_addr);
+                       ar->mac_addr[4] += ar->pdev_idx;
+               }
+
+               ret = ath12k_mac_setup_register(ar, &ht_cap_info, hw->wiphy->bands);
+               if (ret)
+                       goto err_cleanup_unregister;
 
-       wiphy->max_ap_assoc_sta = ar->max_num_stations;
+               ht_cap &= ht_cap_info;
+               wiphy->max_ap_assoc_sta += ar->max_num_stations;
+
+               /* Advertise the max antenna support of all radios, driver can handle
+                * per pdev specific antenna setting based on pdev cap when antenna
+                * changes are made
+                */
+               cap = &pdev->cap;
 
-       cap = &pdev->cap;
+               antennas_rx = max_t(u32, antennas_rx, cap->rx_chain_mask);
+               antennas_tx = max_t(u32, antennas_tx, cap->tx_chain_mask);
 
-       wiphy->available_antennas_rx = cap->rx_chain_mask;
-       wiphy->available_antennas_tx = cap->tx_chain_mask;
+               if (ar->supports_6ghz)
+                       is_6ghz = true;
 
-       SET_IEEE80211_PERM_ADDR(hw, ar->mac_addr);
+               if (test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags))
+                       is_raw_mode = true;
+
+               if (!ar->ab->hw_params->supports_monitor)
+                       is_monitor_disable = true;
+
+               if (i == 0)
+                       mac_addr = ar->mac_addr;
+               else
+                       mac_addr = ab->mac_addr;
+       }
+
+       wiphy->available_antennas_rx = antennas_rx;
+       wiphy->available_antennas_tx = antennas_tx;
+
+       SET_IEEE80211_PERM_ADDR(hw, mac_addr);
        SET_IEEE80211_DEV(hw, ab->dev);
 
        ret = ath12k_mac_setup_iface_combinations(ah);
        if (ret) {
                ath12k_err(ab, "failed to setup interface combinations: %d\n", ret);
-               goto err_cleanup_unregister;
+               goto err_complete_cleanup_unregister;
        }
 
        wiphy->interface_modes = ath12k_mac_get_ifmodes(ah);
 
-       if (wiphy->bands[NL80211_BAND_2GHZ] &&
+       if (ah->num_radio == 1 &&
+           wiphy->bands[NL80211_BAND_2GHZ] &&
            wiphy->bands[NL80211_BAND_5GHZ] &&
            wiphy->bands[NL80211_BAND_6GHZ])
                ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
        wiphy->iftype_ext_capab = ath12k_iftypes_ext_capa;
        wiphy->num_iftype_ext_capab = ARRAY_SIZE(ath12k_iftypes_ext_capa);
 
-       if (ar->supports_6ghz) {
+       if (is_6ghz) {
                wiphy_ext_feature_set(wiphy,
                                      NL80211_EXT_FEATURE_FILS_DISCOVERY);
                wiphy_ext_feature_set(wiphy,
 
        ath12k_reg_init(hw);
 
-       if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) {
+       if (!is_raw_mode) {
                hw->netdev_features = NETIF_F_HW_CSUM;
                ieee80211_hw_set(hw, SW_CRYPTO_CONTROL);
                ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
                goto err_free_if_combs;
        }
 
-       if (!ab->hw_params->supports_monitor)
+       if (is_monitor_disable)
                /* There's a race between calling ieee80211_register_hw()
                 * and here where the monitor mode is enabled for a little
                 * while. But that time is so short and in practise it make
                 */
                wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
 
-       /* Apply the regd received during initialization */
-       ret = ath12k_regd_update(ar, true);
-       if (ret) {
-               ath12k_err(ar->ab, "ath12k regd update failed: %d\n", ret);
-               goto err_unregister_hw;
+       for_each_ar(ah, ar, i) {
+               /* Apply the regd received during initialization */
+               ret = ath12k_regd_update(ar, true);
+               if (ret) {
+                       ath12k_err(ar->ab, "ath12k regd update failed: %d\n", ret);
+                       goto err_unregister_hw;
+               }
        }
 
        ath12k_debugfs_register(ar);
        kfree(wiphy->iface_combinations[0].limits);
        kfree(wiphy->iface_combinations);
 
+err_complete_cleanup_unregister:
+       i = ah->num_radio;
+
 err_cleanup_unregister:
-       ath12k_mac_cleanup_unregister(ar);
+       for (j = 0; j < i; j++) {
+               ar = ath12k_ah_to_ar(ah, j);
+               ath12k_mac_cleanup_unregister(ar);
+       }
 
-out:
        SET_IEEE80211_DEV(hw, NULL);
 
        return ret;
                pdev_idx = pdev_map[i].pdev_idx;
                pdev = &ab->pdevs[pdev_idx];
 
-               ar = ath12k_ah_to_ar(ah);
+               ar = ath12k_ah_to_ar(ah, i);
                ar->ah = ah;
                ar->ab = ab;
                ar->hw_link_id = i;