WCN36XX_HAL_START_SCAN_OFFLOAD_RSP = 205,
        WCN36XX_HAL_STOP_SCAN_OFFLOAD_REQ = 206,
        WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP = 207,
+       WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ = 208,
+       WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP = 209,
        WCN36XX_HAL_SCAN_OFFLOAD_IND = 210,
 
        WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233,
        u32 status;
 } __packed;
 
+#define WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK  0x000000ff
+#define WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK  0x0000ff00
+#define WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK  0x00ff0000
+#define WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK 0xff000000
+#define WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK 0x000000ff
+#define WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE  BIT(7)
+#define WCN36XX_HAL_CHAN_INFO_FLAG_DFS      BIT(10)
+#define WCN36XX_HAL_CHAN_INFO_FLAG_HT       BIT(11)
+#define WCN36XX_HAL_CHAN_INFO_FLAG_VHT      BIT(12)
+#define WCN36XX_HAL_CHAN_INFO_PHY_11A       0
+#define WCN36XX_HAL_CHAN_INFO_PHY_11BG      1
+#define WCN36XX_HAL_DEFAULT_ANT_GAIN        6
+#define WCN36XX_HAL_DEFAULT_MIN_POWER       6
+
+struct wcn36xx_hal_channel_param {
+       u32 mhz;
+       u32 band_center_freq1;
+       u32 band_center_freq2;
+       u32 channel_info;
+       u32 reg_info_1;
+       u32 reg_info_2;
+} __packed;
+
+struct wcn36xx_hal_update_channel_list_req_msg {
+       struct wcn36xx_hal_msg_header header;
+
+       u8 num_channel;
+       struct wcn36xx_hal_channel_param channels[80];
+} __packed;
+
 enum wcn36xx_hal_rate_index {
        HW_RATE_INDEX_1MBPS     = 0x82,
        HW_RATE_INDEX_2MBPS     = 0x84,
 
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/bitfield.h>
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
 #include <linux/bitops.h>
        return ret;
 }
 
+int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req)
+{
+       struct wcn36xx_hal_update_channel_list_req_msg *msg_body;
+       int ret, i;
+
+       msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL);
+       if (!msg_body)
+               return -ENOMEM;
+
+       INIT_HAL_MSG((*msg_body), WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ);
+
+       msg_body->num_channel = min_t(u8, req->n_channels, sizeof(msg_body->channels));
+       for (i = 0; i < msg_body->num_channel; i++) {
+               struct wcn36xx_hal_channel_param *param = &msg_body->channels[i];
+               u32 min_power = WCN36XX_HAL_DEFAULT_MIN_POWER;
+               u32 ant_gain = WCN36XX_HAL_DEFAULT_ANT_GAIN;
+
+               param->mhz = req->channels[i]->center_freq;
+               param->band_center_freq1 = req->channels[i]->center_freq;
+               param->band_center_freq2 = 0;
+
+               if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
+                       param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE;
+
+               if (req->channels[i]->flags & IEEE80211_CHAN_RADAR)
+                       param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_DFS;
+
+               if (req->channels[i]->band == NL80211_BAND_5GHZ) {
+                       param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_HT;
+                       param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_VHT;
+                       param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11A;
+               } else {
+                       param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11BG;
+               }
+
+               if (min_power > req->channels[i]->max_power)
+                       min_power = req->channels[i]->max_power;
+
+               if (req->channels[i]->max_antenna_gain)
+                       ant_gain = req->channels[i]->max_antenna_gain;
+
+               u32p_replace_bits(¶m->reg_info_1, min_power,
+                                 WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK);
+               u32p_replace_bits(¶m->reg_info_1, req->channels[i]->max_power,
+                                 WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK);
+               u32p_replace_bits(¶m->reg_info_1, req->channels[i]->max_reg_power,
+                                 WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK);
+               u32p_replace_bits(¶m->reg_info_1, 0,
+                                 WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK);
+               u32p_replace_bits(¶m->reg_info_2, ant_gain,
+                                 WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK);
+
+               wcn36xx_dbg(WCN36XX_DBG_HAL,
+                           "%s: freq=%u, channel_info=%08x, reg_info1=%08x, reg_info2=%08x\n",
+                           __func__, param->mhz, param->channel_info, param->reg_info_1,
+                           param->reg_info_2);
+       }
+
+       mutex_lock(&wcn->hal_mutex);
+
+       PREPARE_HAL_BUF(wcn->hal_buf, (*msg_body));
+
+       ret = wcn36xx_smd_send_and_wait(wcn, msg_body->header.len);
+       if (ret) {
+               wcn36xx_err("Sending hal_update_channel_list failed\n");
+               goto out;
+       }
+
+       ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
+       if (ret) {
+               wcn36xx_err("hal_update_channel_list response failed err=%d\n", ret);
+               goto out;
+       }
+
+out:
+       kfree(msg_body);
+       mutex_unlock(&wcn->hal_mutex);
+       return ret;
+}
+
 static int wcn36xx_smd_switch_channel_rsp(void *buf, size_t len)
 {
        struct wcn36xx_hal_switch_channel_rsp_msg *rsp;
        case WCN36XX_HAL_GTK_OFFLOAD_RSP:
        case WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP:
        case WCN36XX_HAL_HOST_RESUME_RSP:
+       case WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP:
                memcpy(wcn->hal_buf, buf, len);
                wcn->hal_rsp_len = len;
                complete(&wcn->hal_rsp_compl);