diff --git a/libwifi/chlist.c b/libwifi/chlist.c
index d4ab5df48c4ec6e700eaeb4700bf031866b1c0a3..b5eb34467b92d79366a47b4b9e4fc8400d128cc7 100644
--- a/libwifi/chlist.c
+++ b/libwifi/chlist.c
@@ -1754,3 +1754,23 @@ int wifi_get_opclass_pref(const char *name, int *num_opclass, struct wifi_opclas
 {
 	return radio_get_supported_opclass(name, num_opclass, o, 1);
 }
+
+enum wifi_bw bcmwl_opclass_to_bw(uint32_t opclass)
+{
+	struct wifi_opclass *tab;
+	struct wifi_opclass *ptr;
+	int i;
+
+	tab = (struct wifi_opclass *)wifi_opclass_global;
+
+	for (i = 0; i < wifi_opclass_global_size; i++) {
+		ptr = tab + i;
+		if (ptr->g_opclass == opclass)
+			break;
+	}
+
+	if (i == wifi_opclass_global_size)
+		return BW20;
+
+	return ptr->bw;
+}
diff --git a/libwifi/modules/broadcom/brcm.c b/libwifi/modules/broadcom/brcm.c
index 72a7c22903ae4d4e750768332dab52981488951d..0b9d231e09cd7f7f349aadbe4d407a3ec5d79d4c 100644
--- a/libwifi/modules/broadcom/brcm.c
+++ b/libwifi/modules/broadcom/brcm.c
@@ -845,8 +845,9 @@ static int iface_req_beacon_report(const char *ifname, uint8_t *sta,
 {
 	libwifi_dbg("[%s] %s called\n", ifname, __func__);
 
-	if (param_sz > 0 && param != NULL)
-		return hostapd_cli_iface_req_beacon(ifname, sta, param, param_sz);
+	if (param_sz > 0 && param != NULL) {
+		return bcmwl_req_beacon_report(ifname, sta, param, param_sz);
+	}
 
 	/* No params passed - use default (minimal) configuration */
 	return hostapd_cli_iface_req_beacon_default(ifname, sta);
diff --git a/libwifi/modules/broadcom/broadcom.h b/libwifi/modules/broadcom/broadcom.h
index b1c167145589c3baa9734e3d37ed93adbf84c13a..6ec5a74ad2d36cd0a3441912a9e9b04448f84265 100644
--- a/libwifi/modules/broadcom/broadcom.h
+++ b/libwifi/modules/broadcom/broadcom.h
@@ -497,6 +497,7 @@ typedef double		float64;
 #define DOT11_BSSTYPE_ANY			2	/* d11 any BSS type */
 #define DOT11_SCANTYPE_ACTIVE			0	/* d11 scan active */
 #define DOT11_SCANTYPE_PASSIVE			1	/* d11 scan passive */
+#define DOT11_MAX_SSID_LEN              32  /* d11 max ssid length */
 
 /* uint32 list */
 typedef struct wl_uint32_list {
@@ -1111,6 +1112,27 @@ typedef struct bcnreq {
 	uint16_t reps;
 } bcnreq_t;
 
+typedef struct {
+        uint32_t num;
+        chanspec_t list[1];
+} chanspec_list_t;
+
+#define WL_RRM_BCN_REQ_VER      1
+typedef struct bcn_req {                                                                                                                                                                       
+        uint8_t version;
+        uint8_t bcn_mode;
+        uint8_t pad_1[2];
+        int32_t dur;
+        int32_t channel;
+        struct ether_addr da;
+        uint16_t random_int;
+        wlc_ssid_t ssid;
+        uint16_t reps;
+        uint8_t req_elements;
+        uint8_t pad_2;
+        chanspec_list_t chspec_list;
+} bcn_req_t;
+
 #ifdef BCM_imp26
 typedef struct wl_bsstrans_req {
 	uint16 tbtt;	/* time of BSS to end of life, in unit of TBTT */
diff --git a/libwifi/modules/broadcom/wlctrl.c b/libwifi/modules/broadcom/wlctrl.c
index 3520b36505f444e37088ac84fcaf423922b16a89..474f2701f43abc4d07b02acc480c2ef32cb06d77 100644
--- a/libwifi/modules/broadcom/wlctrl.c
+++ b/libwifi/modules/broadcom/wlctrl.c
@@ -4809,3 +4809,174 @@ int bcmwl_iface_get_4addr_parent(const char *ifname, char *parent)
 
 	return 0;
 }
+
+static int bcm_calc_bcnreq_size(struct wifi_beacon_req *param, size_t param_sz)
+{
+	int alloc_len = sizeof(bcn_req_t);
+	uint8_t *pos = NULL;
+	uint8_t *end = NULL;
+	int i;
+
+	if (param_sz == 0)
+		return alloc_len;
+
+	pos = (uint8_t *) param->variable;
+	end = pos + param_sz - sizeof(struct wifi_beacon_req);
+
+	while (pos < end) {
+		int channel_num = 0;
+
+	 	switch (pos[0]) {
+		case WIFI_BCNREQ_AP_CHAN_REPORT:
+			if (pos[1] > 1) {
+				for (i = 0; i < pos[1] - 1; i++) {
+					channel_num ++;
+				}
+			}
+			if (channel_num > 0)
+				alloc_len += (sizeof(chanspec_t) * channel_num);
+			pos += pos[1] + 2;
+			break;
+	 	default:
+	 		pos += pos[1] + 2;
+	 		break;
+	 	}
+	}
+
+	return alloc_len;
+}
+
+int bcmwl_req_beacon_report(const char *ifname, uint8_t *sta,
+                struct wifi_beacon_req *param, size_t param_sz)
+{	
+	uint8_t *pos = NULL;
+	uint8_t *end = NULL;
+	char buf[512] = {0};
+	bcn_req_t *bcnreq;
+	int swap, i = 0;
+	int alloc_len = 0;
+
+	if (sta == NULL) {
+		libwifi_err("[%s] Destination address of STA is required\n", __func__);
+		return -1;
+	}
+
+	if (param->mode > WIFI_BCNREQ_MODE_TABLE) {
+		libwifi_err("[%s] Invalid bcn mode: %i\n", __func__, param->mode);
+		return -1;
+	}
+
+	alloc_len = bcm_calc_bcnreq_size(param, param_sz);
+	bcnreq = calloc(1, alloc_len);
+	if (!bcnreq) {
+		libwifi_err("[%s] Failed to alloc bcn req, requested size:%i \n", __func__, alloc_len);
+		return -1;
+	}
+
+	swap = wl_swap(ifname);
+
+	memcpy(bcnreq->da.octet, sta, 6);
+
+	bcnreq->version = WL_RRM_BCN_REQ_VER;
+	bcnreq->bcn_mode = param->mode;
+
+	pos = (uint8_t *) param->variable;
+
+	if (param_sz > 0)
+		end = pos + param_sz - sizeof(struct wifi_beacon_req);
+	
+	while (pos < end) {
+		int channel_num = 0;
+
+	 	switch (pos[0]) {
+	 	case WIFI_BCNREQ_SSID:
+			if (pos[1] > DOT11_MAX_SSID_LEN) {
+				libwifi_err("ERROR: SSID size:%d exceed max allowed: %d\n", pos[1], DOT11_MAX_SSID_LEN);
+				return -1;
+			}
+			bcnreq->ssid.SSID_len = pos[1];
+	 		strncpy(bcnreq->ssid.SSID, &pos[2], bcnreq->ssid.SSID_len);
+	 		pos += pos[1] + 2;
+	 		break;
+		case WIFI_BCNREQ_REP_DETAIL:
+			if (pos[1] == 1)
+				libwifi_dbg("Beacon req reporting detail:%i\n", pos[2]);
+			pos += pos[1] + 2;
+			break;
+		case WIFI_BCNREQ_REQUEST:
+			if (pos[1] > 0)
+				bcnreq->req_elements = 1;
+			pos += pos[1] + 2;
+			break;
+		case WIFI_BCNREQ_AP_CHAN_REPORT:
+			if (pos[1] > 1) {
+				for (i = 0; i < pos[1] - 1; i++) {
+					libwifi_dbg("channel report opclas:%i, ch:%i, bw:%i\n", pos[2], pos[3+i], (int)bcmwl_opclass_to_bw(pos[2]));
+					channel_num ++;
+				}
+			}
+			if (channel_num > 0) {
+				enum wifi_bw bw;
+				chanspec_t chspec_bw, chspec_band;
+				i = bcnreq->chspec_list.num;
+				bw = bcmwl_opclass_to_bw(pos[2]);
+				/* figure out chspec bw */
+				switch (bw) {
+					case BW20:
+						chspec_bw = WL_CHANSPEC_BW_20;
+						break;
+					case BW40:
+						chspec_bw = WL_CHANSPEC_BW_40;
+						break;
+					case BW80:
+						chspec_bw = WL_CHANSPEC_BW_80;
+						break;
+					case BW160:
+						chspec_bw = WL_CHANSPEC_BW_160;
+						break;
+					case BW8080:
+						chspec_bw = WL_CHANSPEC_BW_8080;
+						break;
+					default:
+						chspec_bw = WL_CHANSPEC_BW_20;
+				}
+				for (; i < (bcnreq->chspec_list.num + channel_num); i++) {
+					if (pos[3 + i] > 35)
+						chspec_band = WL_CHANSPEC_BAND_5G;
+					else
+						chspec_band = 0;
+
+					libwifi_dbg("chanspec list[%i]=0x%x\n", i, (pos[3+i] | chspec_bw | chspec_band));
+					bcnreq->chspec_list.list[i] = (pos[3+i] | chspec_bw | chspec_band);
+				}
+				bcnreq->chspec_list.num += channel_num;
+			}
+			pos += pos[1] + 2;
+			break;
+	 	default:
+	 		pos += pos[1] + 2;
+	 		break;
+	 	}
+	}
+
+	if (swap) {
+		bcnreq->dur = BCMSWAP16(param->duration);
+		bcnreq->random_int = BCMSWAP16(param->rand_interval);
+		bcnreq->channel = BCMSWAP32(param->channel);
+		bcnreq->reps = BCMSWAP16(0);
+	} else {
+		bcnreq->dur = param->duration;
+		bcnreq->random_int = param->rand_interval;
+		bcnreq->channel = param->channel;
+		bcnreq->reps = 0;
+	}
+
+	if (wl_iovar_set(ifname, "rrm_bcn_req", bcnreq, alloc_len, buf, 512) < 0) {
+		libwifi_err("wl_iovar_set error!!\n");
+		free(bcnreq);
+		return -1;
+	}
+
+	free(bcnreq);
+	return 0;
+}  
diff --git a/libwifi/modules/broadcom/wlctrl.h b/libwifi/modules/broadcom/wlctrl.h
index dacbcfbebbfa5b5fd37c5e52f7595d5a438b389d..116c5c5a93cffef16c2e87af7326113b427468d4 100644
--- a/libwifi/modules/broadcom/wlctrl.h
+++ b/libwifi/modules/broadcom/wlctrl.h
@@ -59,4 +59,7 @@ int bcmwl_enable_event_bit(const char *ifname, unsigned int bit);
 int bcmwl_disable_event_bit(const char *ifname, unsigned int bit);
 
 int bcmwl_radio_reset_chanim_stats(const char *name);
+
+int bcmwl_req_beacon_report(const char *ifname, uint8_t *sta,
+                        struct wifi_beacon_req *param, size_t param_sz);
 #endif /* WLCTRL_H */
diff --git a/libwifi/wifi.h b/libwifi/wifi.h
index fcd816ff0a960a973d5704a0a9b63db7c4936a57..d8f080da177e243045a4ea934ece708df5349950 100644
--- a/libwifi/wifi.h
+++ b/libwifi/wifi.h
@@ -2233,6 +2233,8 @@ int wifi_freq_to_channel(int freq);
 
 const int *chan2list(int chan, int bw);
 
+enum wifi_bw bcmwl_opclass_to_bw(uint32_t opclass);
+
 /** Iterator for information elements */
 #define wifi_foreach_ie(e, _iebuf, _len)				\
 	for ((e) = (_iebuf);						\