ath10k: deduplicate wmi service ready logic
[cascardo/linux.git] / drivers / net / wireless / ath / ath10k / wmi.c
index 3e22134..a7c11b2 100644 (file)
@@ -609,9 +609,44 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = {
        .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
 };
 
+static void
+ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
+                          const struct wmi_channel_arg *arg)
+{
+       u32 flags = 0;
+
+       memset(ch, 0, sizeof(*ch));
+
+       if (arg->passive)
+               flags |= WMI_CHAN_FLAG_PASSIVE;
+       if (arg->allow_ibss)
+               flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED;
+       if (arg->allow_ht)
+               flags |= WMI_CHAN_FLAG_ALLOW_HT;
+       if (arg->allow_vht)
+               flags |= WMI_CHAN_FLAG_ALLOW_VHT;
+       if (arg->ht40plus)
+               flags |= WMI_CHAN_FLAG_HT40_PLUS;
+       if (arg->chan_radar)
+               flags |= WMI_CHAN_FLAG_DFS;
+
+       ch->mhz = __cpu_to_le32(arg->freq);
+       ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1);
+       ch->band_center_freq2 = 0;
+       ch->min_power = arg->min_power;
+       ch->max_power = arg->max_power;
+       ch->reg_power = arg->max_reg_power;
+       ch->antenna_max = arg->max_antenna_gain;
+
+       /* mode & flags share storage */
+       ch->mode = arg->mode;
+       ch->flags |= __cpu_to_le32(flags);
+}
+
 int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
 {
        int ret;
+
        ret = wait_for_completion_timeout(&ar->wmi.service_ready,
                                          WMI_SERVICE_READY_TIMEOUT_HZ);
        return ret;
@@ -620,6 +655,7 @@ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
 int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar)
 {
        int ret;
+
        ret = wait_for_completion_timeout(&ar->wmi.unified_ready,
                                          WMI_UNIFIED_READY_TIMEOUT_HZ);
        return ret;
@@ -792,7 +828,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
        cmd->hdr.tx_power = 0;
        cmd->hdr.buf_len = __cpu_to_le32(buf_len);
 
-       memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN);
+       ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr));
        memcpy(cmd->buf, skb->data, skb->len);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n",
@@ -1384,6 +1420,8 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
        struct ieee80211_tim_ie *tim;
        u8 *ies, *ie;
        u8 ie_len, pvm_len;
+       __le32 t;
+       u32 v;
 
        /* if next SWBA has no tim_changed the tim_bitmap is garbage.
         * we must copy the bitmap upon change and reuse it later */
@@ -1394,8 +1432,8 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
                             sizeof(bcn_info->tim_info.tim_bitmap));
 
                for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) {
-                       __le32 t = bcn_info->tim_info.tim_bitmap[i / 4];
-                       u32 v = __le32_to_cpu(t);
+                       t = bcn_info->tim_info.tim_bitmap[i / 4];
+                       v = __le32_to_cpu(t);
                        arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF;
                }
 
@@ -1511,7 +1549,6 @@ static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa)
        u8 opp_ps_info = noa->ctwindow_oppps;
        bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT);
 
-
        if (!noa_descriptors && !opps_enabled)
                return len;
 
@@ -1568,7 +1605,6 @@ cleanup:
        kfree(old_data);
 }
 
-
 static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
 {
        struct wmi_host_swba_event *ev;
@@ -1577,6 +1613,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
        struct wmi_bcn_info *bcn_info;
        struct ath10k_vif *arvif;
        struct sk_buff *bcn;
+       dma_addr_t paddr;
        int ret, vdev_id = 0;
 
        ev = (struct wmi_host_swba_event *)skb->data;
@@ -1645,22 +1682,29 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
                                ath10k_warn(ar, "SWBA overrun on vdev %d\n",
                                            arvif->vdev_id);
 
-                       dma_unmap_single(arvif->ar->dev,
-                                        ATH10K_SKB_CB(arvif->beacon)->paddr,
-                                        arvif->beacon->len, DMA_TO_DEVICE);
-                       dev_kfree_skb_any(arvif->beacon);
-                       arvif->beacon = NULL;
+                       ath10k_mac_vif_beacon_free(arvif);
                }
 
-               ATH10K_SKB_CB(bcn)->paddr = dma_map_single(arvif->ar->dev,
-                                                          bcn->data, bcn->len,
-                                                          DMA_TO_DEVICE);
-               ret = dma_mapping_error(arvif->ar->dev,
-                                       ATH10K_SKB_CB(bcn)->paddr);
-               if (ret) {
-                       ath10k_warn(ar, "failed to map beacon: %d\n", ret);
-                       dev_kfree_skb_any(bcn);
-                       goto skip;
+               if (!arvif->beacon_buf) {
+                       paddr = dma_map_single(arvif->ar->dev, bcn->data,
+                                              bcn->len, DMA_TO_DEVICE);
+                       ret = dma_mapping_error(arvif->ar->dev, paddr);
+                       if (ret) {
+                               ath10k_warn(ar, "failed to map beacon: %d\n",
+                                           ret);
+                               dev_kfree_skb_any(bcn);
+                               goto skip;
+                       }
+
+                       ATH10K_SKB_CB(bcn)->paddr = paddr;
+               } else {
+                       if (bcn->len > IEEE80211_MAX_FRAME_LEN) {
+                               ath10k_warn(ar, "trimming beacon %d -> %d bytes!\n",
+                                           bcn->len, IEEE80211_MAX_FRAME_LEN);
+                               skb_trim(bcn, IEEE80211_MAX_FRAME_LEN);
+                       }
+                       memcpy(arvif->beacon_buf, bcn->data, bcn->len);
+                       ATH10K_SKB_CB(bcn)->paddr = arvif->beacon_paddr;
                }
 
                arvif->beacon = bcn;
@@ -1859,9 +1903,10 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar,
        }
 }
 
-static void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
-                               struct wmi_single_phyerr_rx_event *event,
-                               u64 tsf)
+static void
+ath10k_wmi_event_spectral_scan(struct ath10k *ar,
+                              struct wmi_single_phyerr_rx_event *event,
+                              u64 tsf)
 {
        int buf_len, tlv_len, res, i = 0;
        struct phyerr_tlv *tlv;
@@ -1989,7 +2034,7 @@ static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
 }
 
 static void ath10k_wmi_event_profile_match(struct ath10k *ar,
-                                   struct sk_buff *skb)
+                                          struct sk_buff *skb)
 {
        ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n");
 }
@@ -2040,13 +2085,13 @@ static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar,
 }
 
 static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
-                                            struct sk_buff *skb)
+                                                   struct sk_buff *skb)
 {
        ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n");
 }
 
 static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
-                                            struct sk_buff *skb)
+                                                   struct sk_buff *skb)
 {
        ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n");
 }
@@ -2082,7 +2127,7 @@ static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar,
 }
 
 static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar,
-                                        struct sk_buff *skb)
+                                               struct sk_buff *skb)
 {
        ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n");
 }
@@ -2106,7 +2151,7 @@ static void ath10k_wmi_event_addba_complete(struct ath10k *ar,
 }
 
 static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
-                                               struct sk_buff *skb)
+                                                      struct sk_buff *skb)
 {
        ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n");
 }
@@ -2130,7 +2175,7 @@ static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar,
 }
 
 static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
-                                     u32 num_units, u32 unit_len)
+                                    u32 num_units, u32 unit_len)
 {
        dma_addr_t paddr;
        u32 pool_size;
@@ -2160,30 +2205,113 @@ static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
        return 0;
 }
 
+static int ath10k_wmi_main_pull_svc_rdy_ev(struct sk_buff *skb,
+                                          struct wmi_svc_rdy_ev_arg *arg)
+{
+       struct wmi_service_ready_event *ev;
+       size_t i, n;
+
+       if (skb->len < sizeof(*ev))
+               return -EPROTO;
+
+       ev = (void *)skb->data;
+       skb_pull(skb, sizeof(*ev));
+       arg->min_tx_power = ev->hw_min_tx_power;
+       arg->max_tx_power = ev->hw_max_tx_power;
+       arg->ht_cap = ev->ht_cap_info;
+       arg->vht_cap = ev->vht_cap_info;
+       arg->sw_ver0 = ev->sw_version;
+       arg->sw_ver1 = ev->sw_version_1;
+       arg->phy_capab = ev->phy_capability;
+       arg->num_rf_chains = ev->num_rf_chains;
+       arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd;
+       arg->num_mem_reqs = ev->num_mem_reqs;
+       arg->service_map = ev->wmi_service_bitmap;
+
+       n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs),
+                 ARRAY_SIZE(arg->mem_reqs));
+       for (i = 0; i < n; i++)
+               arg->mem_reqs[i] = &ev->mem_reqs[i];
+
+       if (skb->len <
+           __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0]))
+               return -EPROTO;
+
+       return 0;
+}
+
+static int ath10k_wmi_10x_pull_svc_rdy_ev(struct sk_buff *skb,
+                                         struct wmi_svc_rdy_ev_arg *arg)
+{
+       struct wmi_10x_service_ready_event *ev;
+       int i, n;
+
+       if (skb->len < sizeof(*ev))
+               return -EPROTO;
+
+       ev = (void *)skb->data;
+       skb_pull(skb, sizeof(*ev));
+       arg->min_tx_power = ev->hw_min_tx_power;
+       arg->max_tx_power = ev->hw_max_tx_power;
+       arg->ht_cap = ev->ht_cap_info;
+       arg->vht_cap = ev->vht_cap_info;
+       arg->sw_ver0 = ev->sw_version;
+       arg->phy_capab = ev->phy_capability;
+       arg->num_rf_chains = ev->num_rf_chains;
+       arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd;
+       arg->num_mem_reqs = ev->num_mem_reqs;
+       arg->service_map = ev->wmi_service_bitmap;
+
+       n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs),
+                 ARRAY_SIZE(arg->mem_reqs));
+       for (i = 0; i < n; i++)
+               arg->mem_reqs[i] = &ev->mem_reqs[i];
+
+       if (skb->len <
+           __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0]))
+               return -EPROTO;
+
+       return 0;
+}
+
 static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
                                              struct sk_buff *skb)
 {
-       struct wmi_service_ready_event *ev = (void *)skb->data;
+       struct wmi_svc_rdy_ev_arg arg = {};
+       u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i;
        DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {};
+       int ret;
+
+       if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
+               ret = ath10k_wmi_10x_pull_svc_rdy_ev(skb, &arg);
+               wmi_10x_svc_map(arg.service_map, svc_bmap);
+       } else {
+               ret = ath10k_wmi_main_pull_svc_rdy_ev(skb, &arg);
+               wmi_main_svc_map(arg.service_map, svc_bmap);
+       }
 
-       if (skb->len < sizeof(*ev)) {
-               ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n",
-                           skb->len, sizeof(*ev));
+       if (ret) {
+               ath10k_warn(ar, "failed to parse service ready: %d\n", ret);
                return;
        }
 
-       ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power);
-       ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power);
-       ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info);
-       ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info);
+       ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power);
+       ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power);
+       ar->ht_cap_info = __le32_to_cpu(arg.ht_cap);
+       ar->vht_cap_info = __le32_to_cpu(arg.vht_cap);
        ar->fw_version_major =
-               (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24;
-       ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff);
+               (__le32_to_cpu(arg.sw_ver0) & 0xff000000) >> 24;
+       ar->fw_version_minor = (__le32_to_cpu(arg.sw_ver0) & 0x00ffffff);
        ar->fw_version_release =
-               (__le32_to_cpu(ev->sw_version_1) & 0xffff0000) >> 16;
-       ar->fw_version_build = (__le32_to_cpu(ev->sw_version_1) & 0x0000ffff);
-       ar->phy_capability = __le32_to_cpu(ev->phy_capability);
-       ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains);
+               (__le32_to_cpu(arg.sw_ver1) & 0xffff0000) >> 16;
+       ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff);
+       ar->phy_capability = __le32_to_cpu(arg.phy_capab);
+       ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains);
+       ar->ath_common.regulatory.current_rd = __le32_to_cpu(arg.eeprom_rd);
+
+       ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap));
+       ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
+                       arg.service_map, sizeof(arg.service_map));
 
        /* only manually set fw features when not using FW IE format */
        if (ar->fw_api == 1 && ar->fw_version_build > 636)
@@ -2195,13 +2323,8 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
                ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM;
        }
 
-       ar->ath_common.regulatory.current_rd =
-               __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd);
-
-       wmi_main_svc_map(ev->wmi_service_bitmap, svc_bmap);
-       ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap));
-       ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
-                       ev->wmi_service_bitmap, sizeof(ev->wmi_service_bitmap));
+       ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1;
+       ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1;
 
        if (strlen(ar->hw->wiphy->fw_version) == 0) {
                snprintf(ar->hw->wiphy->fw_version,
@@ -2213,93 +2336,18 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
                         ar->fw_version_build);
        }
 
-       /* FIXME: it probably should be better to support this */
-       if (__le32_to_cpu(ev->num_mem_reqs) > 0) {
-               ath10k_warn(ar, "target requested %d memory chunks; ignoring\n",
-                           __le32_to_cpu(ev->num_mem_reqs));
-       }
-
-       ath10k_dbg(ar, ATH10K_DBG_WMI,
-                  "wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n",
-                  __le32_to_cpu(ev->sw_version),
-                  __le32_to_cpu(ev->sw_version_1),
-                  __le32_to_cpu(ev->abi_version),
-                  __le32_to_cpu(ev->phy_capability),
-                  __le32_to_cpu(ev->ht_cap_info),
-                  __le32_to_cpu(ev->vht_cap_info),
-                  __le32_to_cpu(ev->vht_supp_mcs),
-                  __le32_to_cpu(ev->sys_cap_info),
-                  __le32_to_cpu(ev->num_mem_reqs),
-                  __le32_to_cpu(ev->num_rf_chains));
-
-       complete(&ar->wmi.service_ready);
-}
-
-static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
-                                                 struct sk_buff *skb)
-{
-       u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i;
-       int ret;
-       struct wmi_service_ready_event_10x *ev = (void *)skb->data;
-       DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {};
-
-       if (skb->len < sizeof(*ev)) {
-               ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n",
-                           skb->len, sizeof(*ev));
-               return;
-       }
-
-       ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power);
-       ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power);
-       ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info);
-       ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info);
-       ar->fw_version_major =
-               (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24;
-       ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff);
-       ar->phy_capability = __le32_to_cpu(ev->phy_capability);
-       ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains);
-
-       if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) {
-               ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n",
-                           ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM);
-               ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM;
-       }
-
-       ar->ath_common.regulatory.current_rd =
-               __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd);
-
-       wmi_10x_svc_map(ev->wmi_service_bitmap, svc_bmap);
-       ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap));
-       ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ",
-                       ev->wmi_service_bitmap, sizeof(ev->wmi_service_bitmap));
-
-       if (strlen(ar->hw->wiphy->fw_version) == 0) {
-               snprintf(ar->hw->wiphy->fw_version,
-                        sizeof(ar->hw->wiphy->fw_version),
-                        "%u.%u",
-                        ar->fw_version_major,
-                        ar->fw_version_minor);
-       }
-
-       num_mem_reqs = __le32_to_cpu(ev->num_mem_reqs);
-
-       if (num_mem_reqs > ATH10K_MAX_MEM_REQS) {
+       num_mem_reqs = __le32_to_cpu(arg.num_mem_reqs);
+       if (num_mem_reqs > WMI_MAX_MEM_REQS) {
                ath10k_warn(ar, "requested memory chunks number (%d) exceeds the limit\n",
                            num_mem_reqs);
                return;
        }
 
-       if (!num_mem_reqs)
-               goto exit;
-
-       ath10k_dbg(ar, ATH10K_DBG_WMI, "firmware has requested %d memory chunks\n",
-                  num_mem_reqs);
-
        for (i = 0; i < num_mem_reqs; ++i) {
-               req_id = __le32_to_cpu(ev->mem_reqs[i].req_id);
-               num_units = __le32_to_cpu(ev->mem_reqs[i].num_units);
-               unit_size = __le32_to_cpu(ev->mem_reqs[i].unit_size);
-               num_unit_info = __le32_to_cpu(ev->mem_reqs[i].num_unit_info);
+               req_id = __le32_to_cpu(arg.mem_reqs[i]->req_id);
+               num_units = __le32_to_cpu(arg.mem_reqs[i]->num_units);
+               unit_size = __le32_to_cpu(arg.mem_reqs[i]->unit_size);
+               num_unit_info = __le32_to_cpu(arg.mem_reqs[i]->num_unit_info);
 
                if (num_unit_info & NUM_UNITS_IS_NUM_PEERS)
                        /* number of units to allocate is number of
@@ -2313,7 +2361,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
                ath10k_dbg(ar, ATH10K_DBG_WMI,
                           "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n",
                           req_id,
-                          __le32_to_cpu(ev->mem_reqs[i].num_units),
+                          __le32_to_cpu(arg.mem_reqs[i]->num_units),
                           num_unit_info,
                           unit_size,
                           num_units);
@@ -2324,18 +2372,18 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
                        return;
        }
 
-exit:
        ath10k_dbg(ar, ATH10K_DBG_WMI,
-                  "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n",
-                  __le32_to_cpu(ev->sw_version),
-                  __le32_to_cpu(ev->abi_version),
-                  __le32_to_cpu(ev->phy_capability),
-                  __le32_to_cpu(ev->ht_cap_info),
-                  __le32_to_cpu(ev->vht_cap_info),
-                  __le32_to_cpu(ev->vht_supp_mcs),
-                  __le32_to_cpu(ev->sys_cap_info),
-                  __le32_to_cpu(ev->num_mem_reqs),
-                  __le32_to_cpu(ev->num_rf_chains));
+                  "wmi event service ready min_tx_power 0x%08x max_tx_power 0x%08x ht_cap 0x%08x vht_cap 0x%08x sw_ver0 0x%08x sw_ver1 0x%08x phy_capab 0x%08x num_rf_chains 0x%08x eeprom_rd 0x%08x num_mem_reqs 0x%08x\n",
+                  __le32_to_cpu(arg.min_tx_power),
+                  __le32_to_cpu(arg.max_tx_power),
+                  __le32_to_cpu(arg.ht_cap),
+                  __le32_to_cpu(arg.vht_cap),
+                  __le32_to_cpu(arg.sw_ver0),
+                  __le32_to_cpu(arg.sw_ver1),
+                  __le32_to_cpu(arg.phy_capab),
+                  __le32_to_cpu(arg.num_rf_chains),
+                  __le32_to_cpu(arg.eeprom_rd),
+                  __le32_to_cpu(arg.num_mem_reqs));
 
        complete(&ar->wmi.service_ready);
 }
@@ -2347,7 +2395,7 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb)
        if (WARN_ON(skb->len < sizeof(*ev)))
                return -EINVAL;
 
-       memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN);
+       ether_addr_copy(ar->mac_addr, ev->mac_addr.addr);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
                   "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n",
@@ -2583,7 +2631,7 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
                ath10k_wmi_event_vdev_resume_req(ar, skb);
                break;
        case WMI_10X_SERVICE_READY_EVENTID:
-               ath10k_wmi_10x_service_ready_event_rx(ar, skb);
+               ath10k_wmi_service_ready_event_rx(ar, skb);
                break;
        case WMI_10X_READY_EVENTID:
                ath10k_wmi_ready_event_rx(ar, skb);
@@ -2694,7 +2742,7 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb)
                ath10k_wmi_event_vdev_resume_req(ar, skb);
                break;
        case WMI_10_2_SERVICE_READY_EVENTID:
-               ath10k_wmi_10x_service_ready_event_rx(ar, skb);
+               ath10k_wmi_service_ready_event_rx(ar, skb);
                break;
        case WMI_10_2_READY_EVENTID:
                ath10k_wmi_ready_event_rx(ar, skb);
@@ -2729,45 +2777,6 @@ static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb)
        }
 }
 
-/* WMI Initialization functions */
-int ath10k_wmi_attach(struct ath10k *ar)
-{
-       if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
-               if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features))
-                       ar->wmi.cmd = &wmi_10_2_cmd_map;
-               else
-                       ar->wmi.cmd = &wmi_10x_cmd_map;
-
-               ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
-               ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
-       } else {
-               ar->wmi.cmd = &wmi_cmd_map;
-               ar->wmi.vdev_param = &wmi_vdev_param_map;
-               ar->wmi.pdev_param = &wmi_pdev_param_map;
-       }
-
-       init_completion(&ar->wmi.service_ready);
-       init_completion(&ar->wmi.unified_ready);
-       init_waitqueue_head(&ar->wmi.tx_credits_wq);
-
-       return 0;
-}
-
-void ath10k_wmi_detach(struct ath10k *ar)
-{
-       int i;
-
-       /* free the host memory chunks requested by firmware */
-       for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
-               dma_free_coherent(ar->dev,
-                                 ar->wmi.mem_chunks[i].len,
-                                 ar->wmi.mem_chunks[i].vaddr,
-                                 ar->wmi.mem_chunks[i].paddr);
-       }
-
-       ar->wmi.num_mem_chunks = 0;
-}
-
 int ath10k_wmi_connect(struct ath10k *ar)
 {
        int status;
@@ -2862,42 +2871,6 @@ int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
                                                         ctl2g, ctl5g);
 }
 
-int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
-                               const struct wmi_channel_arg *arg)
-{
-       struct wmi_set_channel_cmd *cmd;
-       struct sk_buff *skb;
-       u32 ch_flags = 0;
-
-       if (arg->passive)
-               return -EINVAL;
-
-       skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
-       if (!skb)
-               return -ENOMEM;
-
-       if (arg->chan_radar)
-               ch_flags |= WMI_CHAN_FLAG_DFS;
-
-       cmd = (struct wmi_set_channel_cmd *)skb->data;
-       cmd->chan.mhz               = __cpu_to_le32(arg->freq);
-       cmd->chan.band_center_freq1 = __cpu_to_le32(arg->freq);
-       cmd->chan.mode              = arg->mode;
-       cmd->chan.flags            |= __cpu_to_le32(ch_flags);
-       cmd->chan.min_power         = arg->min_power;
-       cmd->chan.max_power         = arg->max_power;
-       cmd->chan.reg_power         = arg->max_reg_power;
-       cmd->chan.reg_classid       = arg->reg_class_id;
-       cmd->chan.antenna_max       = arg->max_antenna_gain;
-
-       ath10k_dbg(ar, ATH10K_DBG_WMI,
-                  "wmi set channel mode %d freq %d\n",
-                  arg->mode, arg->freq);
-
-       return ath10k_wmi_cmd_send(ar, skb,
-                                  ar->wmi.cmd->pdev_set_channel_cmdid);
-}
-
 int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
 {
        struct wmi_pdev_suspend_cmd *cmd;
@@ -2948,13 +2921,34 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
        return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid);
 }
 
+static void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
+                                          struct wmi_host_mem_chunks *chunks)
+{
+       struct host_memory_chunk *chunk;
+       int i;
+
+       chunks->count = __cpu_to_le32(ar->wmi.num_mem_chunks);
+
+       for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
+               chunk = &chunks->items[i];
+               chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr);
+               chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len);
+               chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
+
+               ath10k_dbg(ar, ATH10K_DBG_WMI,
+                          "wmi chunk %d len %d requested, addr 0x%llx\n",
+                          i,
+                          ar->wmi.mem_chunks[i].len,
+                          (unsigned long long)ar->wmi.mem_chunks[i].paddr);
+       }
+}
+
 static int ath10k_wmi_main_cmd_init(struct ath10k *ar)
 {
        struct wmi_init_cmd *cmd;
        struct sk_buff *buf;
        struct wmi_resource_config config = {};
        u32 len, val;
-       int i;
 
        config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS);
        config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS);
@@ -3016,32 +3010,8 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar)
 
        cmd = (struct wmi_init_cmd *)buf->data;
 
-       if (ar->wmi.num_mem_chunks == 0) {
-               cmd->num_host_mem_chunks = 0;
-               goto out;
-       }
-
-       ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n",
-                  ar->wmi.num_mem_chunks);
-
-       cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
-
-       for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
-               cmd->host_mem_chunks[i].ptr =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].paddr);
-               cmd->host_mem_chunks[i].size =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].len);
-               cmd->host_mem_chunks[i].req_id =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
-
-               ath10k_dbg(ar, ATH10K_DBG_WMI,
-                          "wmi chunk %d len %d requested, addr 0x%llx\n",
-                          i,
-                          ar->wmi.mem_chunks[i].len,
-                          (unsigned long long)ar->wmi.mem_chunks[i].paddr);
-       }
-out:
        memcpy(&cmd->resource_config, &config, sizeof(config));
+       ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n");
        return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid);
@@ -3053,7 +3023,6 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
        struct sk_buff *buf;
        struct wmi_resource_config_10x config = {};
        u32 len, val;
-       int i;
 
        config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
        config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
@@ -3107,32 +3076,8 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
 
        cmd = (struct wmi_init_cmd_10x *)buf->data;
 
-       if (ar->wmi.num_mem_chunks == 0) {
-               cmd->num_host_mem_chunks = 0;
-               goto out;
-       }
-
-       ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n",
-                  ar->wmi.num_mem_chunks);
-
-       cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
-
-       for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
-               cmd->host_mem_chunks[i].ptr =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].paddr);
-               cmd->host_mem_chunks[i].size =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].len);
-               cmd->host_mem_chunks[i].req_id =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
-
-               ath10k_dbg(ar, ATH10K_DBG_WMI,
-                          "wmi chunk %d len %d requested, addr 0x%llx\n",
-                          i,
-                          ar->wmi.mem_chunks[i].len,
-                          (unsigned long long)ar->wmi.mem_chunks[i].paddr);
-       }
-out:
        memcpy(&cmd->resource_config, &config, sizeof(config));
+       ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n");
        return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid);
@@ -3144,7 +3089,6 @@ static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar)
        struct sk_buff *buf;
        struct wmi_resource_config_10x config = {};
        u32 len, val;
-       int i;
 
        config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
        config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
@@ -3198,32 +3142,8 @@ static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar)
 
        cmd = (struct wmi_init_cmd_10_2 *)buf->data;
 
-       if (ar->wmi.num_mem_chunks == 0) {
-               cmd->num_host_mem_chunks = 0;
-               goto out;
-       }
-
-       ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n",
-                  ar->wmi.num_mem_chunks);
-
-       cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
-
-       for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
-               cmd->host_mem_chunks[i].ptr =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].paddr);
-               cmd->host_mem_chunks[i].size =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].len);
-               cmd->host_mem_chunks[i].req_id =
-                       __cpu_to_le32(ar->wmi.mem_chunks[i].req_id);
-
-               ath10k_dbg(ar, ATH10K_DBG_WMI,
-                          "wmi chunk %d len %d requested, addr 0x%llx\n",
-                          i,
-                          ar->wmi.mem_chunks[i].len,
-                          (unsigned long long)ar->wmi.mem_chunks[i].paddr);
-       }
-out:
        memcpy(&cmd->resource_config.common, &config, sizeof(config));
+       ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n");
        return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid);
@@ -3493,7 +3413,7 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
        cmd->vdev_id      = __cpu_to_le32(vdev_id);
        cmd->vdev_type    = __cpu_to_le32(type);
        cmd->vdev_subtype = __cpu_to_le32(subtype);
-       memcpy(cmd->vdev_macaddr.addr, macaddr, ETH_ALEN);
+       ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
                   "WMI vdev create: id %d type %d subtype %d macaddr %pM\n",
@@ -3520,15 +3440,15 @@ int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id)
        return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid);
 }
 
-static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
-                               const struct wmi_vdev_start_request_arg *arg,
-                               u32 cmd_id)
+static int
+ath10k_wmi_vdev_start_restart(struct ath10k *ar,
+                             const struct wmi_vdev_start_request_arg *arg,
+                             u32 cmd_id)
 {
        struct wmi_vdev_start_request_cmd *cmd;
        struct sk_buff *skb;
        const char *cmdname;
        u32 flags = 0;
-       u32 ch_flags = 0;
 
        if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid &&
            cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid)
@@ -3555,8 +3475,6 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
                flags |= WMI_VDEV_START_HIDDEN_SSID;
        if (arg->pmf_enabled)
                flags |= WMI_VDEV_START_PMF_ENABLED;
-       if (arg->channel.chan_radar)
-               ch_flags |= WMI_CHAN_FLAG_DFS;
 
        cmd = (struct wmi_vdev_start_request_cmd *)skb->data;
        cmd->vdev_id         = __cpu_to_le32(arg->vdev_id);
@@ -3572,22 +3490,11 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
                memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
        }
 
-       cmd->chan.mhz = __cpu_to_le32(arg->channel.freq);
-
-       cmd->chan.band_center_freq1 =
-               __cpu_to_le32(arg->channel.band_center_freq1);
-
-       cmd->chan.mode = arg->channel.mode;
-       cmd->chan.flags |= __cpu_to_le32(ch_flags);
-       cmd->chan.min_power = arg->channel.min_power;
-       cmd->chan.max_power = arg->channel.max_power;
-       cmd->chan.reg_power = arg->channel.max_reg_power;
-       cmd->chan.reg_classid = arg->channel.reg_class_id;
-       cmd->chan.antenna_max = arg->channel.max_antenna_gain;
+       ath10k_wmi_put_wmi_channel(&cmd->chan, &arg->channel);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
-                  "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, "
-                  "ch_flags: 0x%0X, max_power: %d\n", cmdname, arg->vdev_id,
+                  "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n",
+                  cmdname, arg->vdev_id,
                   flags, arg->channel.freq, arg->channel.mode,
                   cmd->chan.flags, arg->channel.max_power);
 
@@ -3603,7 +3510,7 @@ int ath10k_wmi_vdev_start(struct ath10k *ar,
 }
 
 int ath10k_wmi_vdev_restart(struct ath10k *ar,
-                    const struct wmi_vdev_start_request_arg *arg)
+                           const struct wmi_vdev_start_request_arg *arg)
 {
        u32 cmd_id = ar->wmi.cmd->vdev_restart_request_cmdid;
 
@@ -3639,7 +3546,7 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
        cmd = (struct wmi_vdev_up_cmd *)skb->data;
        cmd->vdev_id       = __cpu_to_le32(vdev_id);
        cmd->vdev_assoc_id = __cpu_to_le32(aid);
-       memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN);
+       ether_addr_copy(cmd->vdev_bssid.addr, bssid);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
                   "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n",
@@ -3720,7 +3627,7 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar,
        cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
 
        if (arg->macaddr)
-               memcpy(cmd->peer_macaddr.addr, arg->macaddr, ETH_ALEN);
+               ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
        if (arg->key_data)
                memcpy(cmd->key_data, arg->key_data, arg->key_len);
 
@@ -3799,7 +3706,7 @@ int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
 
        cmd = (struct wmi_peer_create_cmd *)skb->data;
        cmd->vdev_id = __cpu_to_le32(vdev_id);
-       memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
+       ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
                   "wmi peer create vdev_id %d peer_addr %pM\n",
@@ -3819,7 +3726,7 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
 
        cmd = (struct wmi_peer_delete_cmd *)skb->data;
        cmd->vdev_id = __cpu_to_le32(vdev_id);
-       memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
+       ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
                   "wmi peer delete vdev_id %d peer_addr %pM\n",
@@ -3840,7 +3747,7 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
        cmd = (struct wmi_peer_flush_tids_cmd *)skb->data;
        cmd->vdev_id         = __cpu_to_le32(vdev_id);
        cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
-       memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
+       ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
                   "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n",
@@ -3863,7 +3770,7 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id,
        cmd->vdev_id     = __cpu_to_le32(vdev_id);
        cmd->param_id    = __cpu_to_le32(param_id);
        cmd->param_value = __cpu_to_le32(param_value);
-       memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
+       ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
                   "wmi vdev %d peer 0x%pM set param %d value %d\n",
@@ -3934,7 +3841,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
        cmd->vdev_id = __cpu_to_le32(vdev_id);
        cmd->param_id = __cpu_to_le32(param_id);
        cmd->param_value = __cpu_to_le32(value);
-       memcpy(&cmd->peer_macaddr, mac, ETH_ALEN);
+       ether_addr_copy(cmd->peer_macaddr.addr, mac);
 
        ath10k_dbg(ar, ATH10K_DBG_WMI,
                   "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n",
@@ -3964,35 +3871,10 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar,
        cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
 
        for (i = 0; i < arg->n_channels; i++) {
-               u32 flags = 0;
-
                ch = &arg->channels[i];
                ci = &cmd->chan_info[i];
 
-               if (ch->passive)
-                       flags |= WMI_CHAN_FLAG_PASSIVE;
-               if (ch->allow_ibss)
-                       flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED;
-               if (ch->allow_ht)
-                       flags |= WMI_CHAN_FLAG_ALLOW_HT;
-               if (ch->allow_vht)
-                       flags |= WMI_CHAN_FLAG_ALLOW_VHT;
-               if (ch->ht40plus)
-                       flags |= WMI_CHAN_FLAG_HT40_PLUS;
-               if (ch->chan_radar)
-                       flags |= WMI_CHAN_FLAG_DFS;
-
-               ci->mhz               = __cpu_to_le32(ch->freq);
-               ci->band_center_freq1 = __cpu_to_le32(ch->freq);
-               ci->band_center_freq2 = 0;
-               ci->min_power         = ch->min_power;
-               ci->max_power         = ch->max_power;
-               ci->reg_power         = ch->max_reg_power;
-               ci->antenna_max       = ch->max_antenna_gain;
-
-               /* mode & flags share storage */
-               ci->mode              = ch->mode;
-               ci->flags            |= __cpu_to_le32(flags);
+               ath10k_wmi_put_wmi_channel(ci, ch);
        }
 
        return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid);
@@ -4018,7 +3900,7 @@ ath10k_wmi_peer_assoc_fill(struct ath10k *ar, void *buf,
        cmd->peer_vht_caps      = __cpu_to_le32(arg->peer_vht_caps);
        cmd->peer_phymode       = __cpu_to_le32(arg->peer_phymode);
 
-       memcpy(cmd->peer_macaddr.addr, arg->addr, ETH_ALEN);
+       ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
 
        cmd->peer_legacy_rates.num_rates =
                __cpu_to_le32(arg->peer_legacy_rates.num_rates);
@@ -4172,7 +4054,7 @@ static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
 }
 
 int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
-                       const struct wmi_pdev_set_wmm_params_arg *arg)
+                                  const struct wmi_pdev_set_wmm_params_arg *arg)
 {
        struct wmi_pdev_set_wmm_params *cmd;
        struct sk_buff *skb;
@@ -4263,3 +4145,41 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
 
        return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
 }
+
+int ath10k_wmi_attach(struct ath10k *ar)
+{
+       if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
+               if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features))
+                       ar->wmi.cmd = &wmi_10_2_cmd_map;
+               else
+                       ar->wmi.cmd = &wmi_10x_cmd_map;
+
+               ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
+               ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
+       } else {
+               ar->wmi.cmd = &wmi_cmd_map;
+               ar->wmi.vdev_param = &wmi_vdev_param_map;
+               ar->wmi.pdev_param = &wmi_pdev_param_map;
+       }
+
+       init_completion(&ar->wmi.service_ready);
+       init_completion(&ar->wmi.unified_ready);
+       init_waitqueue_head(&ar->wmi.tx_credits_wq);
+
+       return 0;
+}
+
+void ath10k_wmi_detach(struct ath10k *ar)
+{
+       int i;
+
+       /* free the host memory chunks requested by firmware */
+       for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
+               dma_free_coherent(ar->dev,
+                                 ar->wmi.mem_chunks[i].len,
+                                 ar->wmi.mem_chunks[i].vaddr,
+                                 ar->wmi.mem_chunks[i].paddr);
+       }
+
+       ar->wmi.num_mem_chunks = 0;
+}