diff --git a/src/agent.c b/src/agent.c
index 1ec43cceca7a396015e56c966a8e04edada0f64f..10e0506ddb6a4437d218792b821a0ec9969e4134 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -1287,8 +1287,24 @@ static int update_sta_entry(struct agent *a, struct netif_ap *ap, struct wifi_st
 			s->rx_fail_pkts = e->stats.rx_fail_pkts;
 			s->rtx_pkts = e->stats.tx_retry_pkts;
 
-
 			memcpy(s->bssid, e->bssid, 6);
+
+			if (!!(e->caps.valid & WIFI_CAP_RM_VALID)) {
+				if (wifi_cap_isset(e->cbitmap, WIFI_CAP_RM_BCN_ACTIVE)) {
+					s->rrm_mode |= NBR_PARAM_BCN_ACTIVE;
+					s->supports_bcnreport = true;
+				}
+
+				if (wifi_cap_isset(e->cbitmap, WIFI_CAP_RM_BCN_PASSIVE)) {
+					s->rrm_mode |= NBR_PARAM_BCN_PASSIVE;
+					s->supports_bcnreport = true;
+				}
+
+				if (wifi_cap_isset(e->cbitmap, WIFI_CAP_RM_BCN_TABLE)) {
+					s->rrm_mode |= NBR_PARAM_BCN_TABLE;
+					s->supports_bcnreport = true;
+				}
+			}
 #ifdef UBUS_STA_INFO
 			wifiagent_log_stainfo(ap->agent, s);
 #endif
@@ -1301,7 +1317,8 @@ static int update_sta_entry(struct agent *a, struct netif_ap *ap, struct wifi_st
 
 static int agent_req_beacon_metrics(struct agent *a,
 	struct netif_ap *ap, uint8_t *sta_addr, uint8_t opclass,
-	uint8_t channel, uint8_t *bssid, uint8_t reporting_detail,
+	uint8_t channel, uint8_t *bssid,
+	uint8_t rrm_mode, uint8_t reporting_detail,
 	uint8_t ssid_len, char *ssid, uint8_t num_report,
 	uint8_t *report, uint8_t num_element, uint8_t *element)
 {
@@ -1322,6 +1339,7 @@ static int agent_req_beacon_metrics(struct agent *a,
 	param.report = report;
 	param.num_element = num_element;
 	param.element = element;
+	param.rrm_mode = rrm_mode;
 
 	return wifi_req_neighbor(ap->ifname, sta_addr, &param);
 }
@@ -1346,6 +1364,7 @@ static void wifi_sta_bcn_req(atimer_t *t)
 
 	agent_req_beacon_metrics(a, breq->ap, s->macaddr,
 			breq->opclass, breq->channel, breq->bssid,
+			s->rrm_mode,
 			breq->reporting_detail,
 			breq->ssid_len, breq->ssid, 0, NULL,
 			breq->num_element, breq->element);
diff --git a/src/agent.h b/src/agent.h
index 48f944f4789f6bbab99eb41d5cd8860a1c5db299..b8814114646c6179b644405e02c7f228a58d7f4b 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -494,6 +494,7 @@ struct sta {
 	int inform_leaving;                 /** flag indicating leaving BSS */
 	bool wait_for_cntlr_nbr;            /** awaiting pref nbr from cntlr */
 	bool supports_bcnreport;            /** supports 11K beacon reporting */
+	uint8_t rrm_mode;                   /** bitmap for ACTIVE/PASSIVE/TABLE */
 	atimer_t sta_timer;                 /** periodic run */
 	atimer_t sta_bcn_req_timer;         /** enqueue bcn requests */
 	struct list_head sta_nbrlist;       /** neighbor BSSs as seen by this STA */
diff --git a/src/wifi.h b/src/wifi.h
index 66575bf94236d8e3175f7ae4cae779f1a31f4691..ed926e4fa5a2480d68d2fa0b7b062bf602de05d0 100644
--- a/src/wifi.h
+++ b/src/wifi.h
@@ -49,10 +49,17 @@ struct wifi_radio_status {
 	uint32_t bandwidth;
 };
 
+enum nbr_param_bcn_mode {
+	NBR_PARAM_BCN_ACTIVE  = 1 << 0,
+	NBR_PARAM_BCN_PASSIVE = 1 << 1,
+	NBR_PARAM_BCN_TABLE   = 1 << 2,
+};
+
 struct wifi_request_neighbor_param {
 	uint8_t opclass;
 	uint8_t channel;
 	uint8_t *bssid;
+	uint8_t rrm_mode;
 	uint8_t reporting_detail;
 	uint8_t ssid_len;
 	char *ssid;
diff --git a/src/wifi_ubus.c b/src/wifi_ubus.c
index 74130cbb9f3113cc20943ad0f5bc5680246fa288..47f6e6fd7de61f60282e8d75d427899e8ca810bd 100644
--- a/src/wifi_ubus.c
+++ b/src/wifi_ubus.c
@@ -1718,10 +1718,16 @@ int wifi_ubus_req_neighbor(struct ubus_context *ubus_ctx, const char *ifname,
 		blobmsg_add_string(&bb, "bssid", bssid_macstr);
 	}
 
-	/* TODO: revisit */
-	/* Set mode to PASSIVE/100ms explicitly */
+	/* Start with passive mode by default */
 	blobmsg_add_string(&bb, "mode", "passive");
 	blobmsg_add_u32(&bb, "duration", 100);
+	if (!(param->rrm_mode & NBR_PARAM_BCN_PASSIVE)) {
+		/* passive not supported, check for active but keep passive otherwise */
+		if (param->rrm_mode & NBR_PARAM_BCN_ACTIVE) {
+			blobmsg_add_string(&bb, "mode", "active");
+			blobmsg_add_u32(&bb, "duration", 20);
+		}
+	}
 
 	if (param->reporting_detail)
 		blobmsg_add_u32(&bb, "reporting_detail", param->reporting_detail);
@@ -1813,9 +1819,29 @@ struct get_stas_ctx {
 };
 
 static int wifi_ubus_get_sta_caps(struct blob_attr *msg,
-				  struct wifi_caps *caps)
+				  struct wifi_caps *caps, uint8_t *cbitmap)
 {
-	/* TODO fill caps */
+	static const struct blobmsg_policy caps_policy[] = {
+			[0] = { .name = "bitmap", .type = BLOBMSG_TYPE_STRING },
+	};
+	struct blob_attr *caps_tb[ARRAY_SIZE(caps_policy)];
+	int len;
+
+	/* TODO: only updating cbitmap here, update caps (may be redundant) */
+
+	blobmsg_parse(caps_policy, ARRAY_SIZE(caps_policy), caps_tb,
+			blobmsg_data(msg), blobmsg_data_len(msg));
+
+	caps->valid &= ~WIFI_CAP_RM_VALID;
+
+	if (!caps_tb[0])
+		return -1;
+
+	len = strlen(blobmsg_get_string(caps_tb[0]));
+	if (!strtob(blobmsg_get_string(caps_tb[0]), len / 2, cbitmap))
+		return -1;
+
+	caps->valid |= WIFI_CAP_RM_VALID;
 	return 0;
 }
 
@@ -1963,7 +1989,7 @@ static int wifi_ubus_parse_sta(struct blob_attr *cur,
 		sta->est_tx_thput = blobmsg_get_u32(sta_tb[14]);
 
 		wifi_ubus_get_sta_rssi(sta_tb[12], sta->rssi, sizeof(sta->rssi));
-		wifi_ubus_get_sta_caps(sta_tb[10], &sta->caps);
+		wifi_ubus_get_sta_caps(sta_tb[10], &sta->caps, sta->cbitmap);
 		wifi_ubus_get_sta_stats(sta_tb[4], sta, &sta->stats);
 		if (sta_tb[16])
 			wifi_ubus_get_sta_rate(sta_tb[16], &sta->tx_rate);
@@ -2170,7 +2196,7 @@ static void wifi_sta_parse_mlo_links(struct ubus_request *req,
 		sta->est_tx_thput = blobmsg_get_u32(sta_tb[15]);
 
 		wifi_ubus_get_sta_rssi(sta_tb[13], sta->rssi, sizeof(sta->rssi));
-		wifi_ubus_get_sta_caps(sta_tb[11], &sta->caps);
+		wifi_ubus_get_sta_caps(sta_tb[11], &sta->caps, sta->cbitmap);
 		if (sta_tb[16])
 			wifi_ubus_get_sta_rate(sta_tb[16], &sta->tx_rate);
 		if (sta_tb[17])