diff --git a/wifimngr.c b/wifimngr.c
index 94259214b1edf2ec3d3f7f6f466de02c9f919837..e093a047945cfdef5745bff115c83ca54f3c3b48 100644
--- a/wifimngr.c
+++ b/wifimngr.c
@@ -208,14 +208,7 @@ static const struct blobmsg_policy wl_vif_policy[__WL_MAX] = {
 	[VIF_NAME] = { .name = "vif", .type = BLOBMSG_TYPE_STRING },
 };
 
-
-static int wl_status(struct ubus_context *ctx, struct ubus_object *obj,
-		struct ubus_request_data *req, const char *method,
-		struct blob_attr *msg)
-{
-	struct blob_attr *tb[__WL_MAX];
-	char syspath[32];
-	char wldev[8];
+static int wl_dump_status(struct blob_buf *bb, char *wldev) {
 	ifstatus_t isup;
 	uint32_t channel;
 	int band = 0;
@@ -229,24 +222,8 @@ static int wl_status(struct ubus_context *ctx, struct ubus_object *obj,
 	char enc_buf[64] = {0};
 	char cpr_buf[32] = {0};
 	struct bss b;
-	struct blob_buf bb;
 	struct wifi_ap_stats ap_stats;
 
-	memset(&bb, 0, sizeof(bb));
-	blobmsg_parse(wl_vif_policy, __WL_MAX, tb, blob_data(msg), blob_len(msg));
-
-	if (!(tb[VIF_NAME]))
-		return UBUS_STATUS_INVALID_ARGUMENT;
-
-	memset(wldev, '\0', sizeof(wldev));
-	strcpy(wldev, blobmsg_data(tb[VIF_NAME]));
-
-#if 0	// TODO - is_valid_interface()
-	snprintf(syspath, 32, "/sys/class/net/%s", wldev);
-	if (stat(syspath, &s))
-		return UBUS_STATUS_INVALID_ARGUMENT;
-#endif
-
 	wifi_get_ifstatus(wldev, &isup);
 	wifi_get_channel(wldev, &channel);
 	if (channel && channel > 14)
@@ -259,36 +236,84 @@ static int wl_status(struct ubus_context *ctx, struct ubus_object *obj,
 	wifi_get_bandwidth(wldev, &bandwidth);
 	wifi_get_noise(wldev, &noise);
 
-	blob_buf_init(&bb, 0);
-	blobmsg_add_string(&bb, "wldev", wldev);
-	blobmsg_add_u32(&bb, "radio", isup);
-	blobmsg_add_string(&bb, "ssid", ssid);
-	blobmsg_add_string(&bb, "bssid", bssid);
+	blobmsg_add_string(bb, "wldev", wldev);
+	blobmsg_add_u32(bb, "radio", isup);
+	blobmsg_add_string(bb, "ssid", ssid);
+	blobmsg_add_string(bb, "bssid", bssid);
 	if (enc == CIPHER_NONE)
-		blobmsg_add_string(&bb, "encryption", "DISABLED");
+		blobmsg_add_string(bb, "encryption", "DISABLED");
 	else if (!!(enc & CIPHER_WEP)) {
-		blobmsg_add_string(&bb, "encryption", "WEP");
+		blobmsg_add_string(bb, "encryption", "WEP");
 	} else {
-		blobmsg_add_string(&bb, "encryption",
+		blobmsg_add_string(bb, "encryption",
 			etostr(auth, auth_buf, AUTH_MAX, auth_str));
 	}
-	blobmsg_add_u32(&bb, "frequency", (band == 1) ? 5 : 2);
-	blobmsg_add_u32(&bb, "channel", channel);
-	blobmsg_add_u32(&bb, "bandwidth", bandwidth);
-	blobmsg_add_u32(&bb, "noise", noise);
-	blobmsg_add_u64(&bb, "rate", rate);
+	blobmsg_add_u32(bb, "frequency", (band == 1) ? 5 : 2);
+	blobmsg_add_u32(bb, "channel", channel);
+	blobmsg_add_u32(bb, "bandwidth", bandwidth);
+	blobmsg_add_u32(bb, "noise", noise);
+	blobmsg_add_u64(bb, "rate", rate);
 
 	memset(&b, 0, sizeof(struct bss));
 	if (!wifi_get_bss_info(wldev, &b)) {
-		blobmsg_add_u32(&bb, "stas", b.load.sta_count);
-		blobmsg_add_u32(&bb, "bssload", b.load.utilization);
+		blobmsg_add_u32(bb, "stas", b.load.sta_count);
+		blobmsg_add_u32(bb, "bssload", b.load.utilization);
 	}
 
 	memset(&ap_stats, 0, sizeof(struct wifi_ap_stats));
 	wifi_get_ap_stats(wldev, &ap_stats);
 
-	blobmsg_add_u32(&bb, "rx_bytes", ap_stats.rx_bytes);
-	blobmsg_add_u32(&bb, "tx_bytes", ap_stats.tx_bytes);
+	blobmsg_add_u32(bb, "rx_bytes", ap_stats.rx_bytes);
+	blobmsg_add_u32(bb, "tx_bytes", ap_stats.tx_bytes);
+
+	return 0;
+}
+
+static int wl_status(struct ubus_context *ctx, struct ubus_object *obj,
+		struct ubus_request_data *req, const char *method,
+		struct blob_attr *msg)
+{
+	struct blob_attr *tb[__WL_MAX];
+	char syspath[32];
+	char wldev[8];
+	struct blob_buf bb;
+
+	memset(&bb, 0, sizeof(bb));
+	blob_buf_init(&bb, 0);
+	blobmsg_parse(wl_vif_policy, __WL_MAX, tb, blob_data(msg), blob_len(msg));
+
+	if (!(tb[VIF_NAME])) {
+		char wldevs[16][16];
+		void *arr, *obj;
+		int n, i;
+
+		arr = blobmsg_open_array(&bb, "access_points");
+		n = uci_get_wifi_devices(wldevs);
+		for (i = 0; i < n; i++) {
+			char wifs[16][16];
+			int m, j;
+
+			m = uci_get_wifi_interfaces(wldevs[i], wifs, "ap");
+			for (j = 0; j < m; j++) {
+				obj = blobmsg_open_table(&bb, "access_point");
+				wl_dump_status(&bb, wifs[j]);
+				blobmsg_close_table(&bb, obj);
+			}
+		}
+
+		blobmsg_close_array(&bb, arr);
+	} else {
+		memset(wldev, '\0', sizeof(wldev));
+		strcpy(wldev, blobmsg_data(tb[VIF_NAME]));
+#if 0	// TODO - is_valid_interface()
+		snprintf(syspath, 32, "/sys/class/net/%s", wldev);
+		if (stat(syspath, &s)) {
+			blob_buf_free(&bb);
+			return UBUS_STATUS_INVALID_ARGUMENT;
+		}
+#endif
+		wl_dump_status(&bb, wldev);
+	}
 
 	ubus_send_reply(ctx, req, bb.head);
 	blob_buf_free(&bb);