diff --git a/src/agent.c b/src/agent.c
index 4acbafd1a0d9f582cda0bde99ce97e624df074fd..daeaa1b1d42e90cce38f26d402468557041a8c28 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -1796,6 +1796,40 @@ static void agent_sta_clean_rssi(struct sta *s)
 	s->num_rssi = 0;
 }
 
+static int agent_modify_assoc_status(struct netif_ap *ap, bool allowed)
+{
+	int ret = 0;
+
+	ret = wifi_set_ap_mbo_association_mode(ap->ifname, !allowed);
+	if (!ret) {
+		ap->cfg->disallow_assoc = !allowed;
+		uci_apply_bss_association_mode(ap->ifname, !allowed);
+	}
+
+	return ret;
+}
+
+static int agent_notify_assoc_status(struct agent *a, uint8_t *bssid, bool allowed)
+{
+	trace("%s: --->\n", __func__);
+
+	struct bss_data {
+		uint8_t bssid[6];
+		uint8_t status;
+	} bss_data;
+	int ret = 0;
+
+	memcpy(bss_data.bssid, bssid, ETH_ALEN);
+	if (allowed)
+		bss_data.status = STA_ASSOC_ALLOWED;
+	else
+		bss_data.status = STA_ASSOC_NOT_ALLOWED;
+
+	ret = send_assoc_status_notification(a, 1, &bss_data);
+
+	return ret;
+}
+
 static struct sta *wifi_add_sta(struct agent *a, const char *ifname,
 				unsigned char *macaddr)
 {
@@ -1827,8 +1861,15 @@ static struct sta *wifi_add_sta(struct agent *a, const char *ifname,
 
 			oldap = agent_get_ap(a, sptr->bssid);
 			if (oldap) {
-				if (oldap->num_sta > 0)
+				if (oldap->num_sta > 0) {
 					oldap->num_sta--;
+					if (oldap->num_sta == oldap->max_sta - 1) {
+						/* Set association mode in driver and update config */
+						agent_modify_assoc_status(ap, true);
+						/* Notify ctrl that adding STA is allowed again */
+						agent_notify_assoc_status(a, oldap->bssid, true);
+					}
+				}
 			}
 			clear_sta(sptr);
 		}
@@ -1869,6 +1910,13 @@ static struct sta *wifi_add_sta(struct agent *a, const char *ifname,
 	/* Remove from unassociated list */
 	agent_del_unassoc_sta(a, new->macaddr);
 
+	if (ap->max_sta && ap->num_sta >= ap->max_sta) {
+		/* Set association mode in driver and update config */
+		agent_modify_assoc_status(ap, false);
+		/* Notify ctrl that adding more STA is disallowed */
+		agent_notify_assoc_status(a, ap->bssid, false);
+	}
+
 	timer_set(&new->sta_timer, 1 * 1000);
 	return new;
 }
@@ -1986,8 +2034,15 @@ static int wifi_del_sta(struct agent *a, const char *ifname,
 		if (!memcmp(s->macaddr, macaddr, 6)) {
 			dbg("Delete STA " MACFMT "record\n",
 						MAC2STR(macaddr));
-			if (ap->num_sta > 0)
-				 ap->num_sta--;
+			if (ap->num_sta > 0) {
+				ap->num_sta--;
+				if (ap->num_sta == ap->max_sta - 1) {
+					/* Set association mode in driver and update config */
+					agent_modify_assoc_status(ap, true);
+					/* Notify ctrl that adding STA is allowed again */
+					agent_notify_assoc_status(a, ap->bssid, true);
+				}
+			}
 			clear_sta(s);
 			return 0;
 		}
@@ -3288,7 +3343,7 @@ static void agent_init_ifaces_assoc_mode(struct agent *a)
 					WIFI_REASON_SERVICE_NOT_AUTHORIZED_IN_THIS_LOCATION);
 			}
 
-			wifi_set_backhaul_bss_association_mode(ap->ifname,
+			wifi_set_ap_mbo_association_mode(ap->ifname,
 							ap->cfg->disallow_assoc);
 		}
 	}
@@ -3299,7 +3354,7 @@ static void apply_iface_assocation_mode(struct agent *a, const char *ifname)
 	struct netif_ap *ap = agent_get_ap_by_ifname(a, ifname);
 
 	if (ap) {
-		wifi_set_backhaul_bss_association_mode(ifname,
+		wifi_set_ap_mbo_association_mode(ifname,
 						       ap->cfg->disallow_assoc);
 	}
 }
@@ -5082,10 +5137,10 @@ static void refresh_bssinfo(atimer_t *t)
 	struct netif_ap *ap = container_of(t, struct netif_ap, bss_timer);
 	struct agent *a = ap->agent;
 	struct wifi_ap_status ap_status = {};
-
 	int i;
 
-	dbg("%s: ap = %s\n", __func__, ap->ifname);
+	trace("%s: ap = %s\n", __func__, ap->ifname);
+
 	if (!wifi_ap_status(ap->ifname, &ap_status)) {
 #if (EASYMESH_VERSION >= 6)
 		struct wifi_mlsta mlsta[128] = {0};
@@ -5100,11 +5155,12 @@ static void refresh_bssinfo(atimer_t *t)
 		/* others.. */
 		if (ap_status.ap.bss.load.utilization != 0xff)
 			ap->bssload = ap_status.ap.bss.load.utilization;
+		ap->max_sta = ap_status.ap.assoclist_max;
 
-		dbg("ap: %s   bssid: " MACFMT
-				"  channel: %d   bssload: %d\n",
-				ap->ifname, MAC2STR(ap->bssid),
-				ap->channel, ap->bssload);
+		dbg("%s: ap: %s  max_sta: %d  bssid: " MACFMT
+		    "  channel: %d  bssload: %d\n",
+			__func__, ap->ifname, ap->max_sta,
+			MAC2STR(ap->bssid), ap->channel, ap->bssload);
 #if (EASYMESH_VERSION >= 6)
 		if (!wifi_get_mld_stations(ap, mlsta, &num_mlsta)) {
 			for (i = 0; i < num_mlsta; i++) {
@@ -5712,6 +5768,7 @@ struct netif_ap *netif_alloc_ap(const char *ifname)
 
 	timer_init(&n->nbr_timer, refresh_neighbor_list);
 	timer_init(&n->bss_timer, refresh_bssinfo);
+	timer_set(&n->bss_timer, BSS_REFRESH_INTERVAL);
 
 	return n;
 }
@@ -6061,6 +6118,7 @@ static void parse_apmld(struct ubus_request *req, int type,
 		[3] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
 		[4] = { .name = "links", .type = BLOBMSG_TYPE_ARRAY },
 		[5] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
+		[6] = { .name = "max_stations", .type = BLOBMSG_TYPE_INT32 },
 	};
 	struct netif_ap *ap = (struct netif_ap *)req->priv;
 	struct blob_attr *tb[ARRAY_SIZE(ap_attr)];
@@ -6072,7 +6130,7 @@ static void parse_apmld(struct ubus_request *req, int type,
 
 	blobmsg_parse(ap_attr, ARRAY_SIZE(ap_attr), tb, blob_data(msg), blob_len(msg));
 
-	if (!tb[0] || !tb[1] || !tb[2] || !tb[3] || !tb[4] || !tb[5]) {
+	if (!tb[0] || !tb[1] || !tb[2] || !tb[3] || !tb[4] || !tb[5] || !tb[6]) {
 		err("|%s:%d| missing some mandatory field!\n", __func__, __LINE__);
 		return;
 	}
@@ -6166,6 +6224,9 @@ static void parse_apmld(struct ubus_request *req, int type,
 		}
 
 	}
+
+	if (tb[6])
+		ap->max_sta = blobmsg_get_u32(tb[6]);
 }
 
 static void parse_affiliated_bsta(struct agent *a, struct bsta_mld *mld,
@@ -6334,6 +6395,7 @@ static void parse_ap(struct ubus_request *req, int type,
 		[12] = { .name = "linkid", .type = BLOBMSG_TYPE_INT32 },
 #endif
 		[13] = { .name = "band", .type = BLOBMSG_TYPE_STRING },
+		[14] = { .name = "max_stations", .type = BLOBMSG_TYPE_INT32 },
 	};
 	struct blob_attr *tb[ARRAY_SIZE(ap_attr)];
 
@@ -6395,6 +6457,9 @@ static void parse_ap(struct ubus_request *req, int type,
 			ap->band = BAND_UNKNOWN;
 	}
 
+	if (tb[14])
+		ap->max_sta = blobmsg_get_u32(tb[14]);
+
 }
 
 static int agent_radio_update_scanresults_element(struct wifi_radio_element *re, struct wifi_bss *bsss,
@@ -6519,21 +6584,24 @@ void agent_init_interfaces_post_actions(struct agent *a)
 
 	list_for_each_entry(re, &a->radiolist, list) {
 		list_for_each_entry(ap, &re->aplist, list) {
+			int num_sta = ap->max_sta ? ap->max_sta : 128;
+
 #if (EASYMESH_VERSION >= 6)
 			if (ap->is_affiliated_ap) {
 				struct wifi_mlsta mlsta[128] = {0};
-				int num_mlsta = 128;
 
-				if (wifi_get_mld_stations(ap, mlsta, &num_mlsta))
+				if (wifi_get_mld_stations(ap, mlsta, &num_sta))
 					continue;
 
-				for (i = 0; i < num_mlsta; i++) {
+				for (i = 0; i < num_sta; i++) {
 					if (!memcmp(mlsta[i].sta->bssid, ap->bssid, 6))
 						wifi_add_sta(a, ap->ifname, mlsta[i].sta->macaddr);
 				}
 			} else {
+#else
+			if (1) {
+#endif
 				uint8_t sta[128 * 6] = {};
-				int num_sta = 128;
 
 				if (wifi_get_assoclist(ap, sta, &num_sta))
 					continue;
@@ -6541,18 +6609,15 @@ void agent_init_interfaces_post_actions(struct agent *a)
 				for (i = 0; i < num_sta; i++)
 					wifi_add_sta(a, ap->ifname, &sta[i * 6]);
 			}
-#else
-			uint8_t sta[128 * 6] = {};
-			int num_sta = 128;
 
-			if (wifi_get_assoclist(ap, sta, &num_sta))
-				continue;
-
-			for (i = 0; i < num_sta; i++)
-				wifi_add_sta(a, ap->ifname, &sta[i * 6]);
-#endif
 			/* Block STas in WiFi if wifi is restarted at run-time */
 			assoc_ctrl_apply_restriction(a, ap);
+
+			/* Notify ctrl once upon start if adding STA is allowed */
+			if (ap->max_sta && !ap->sent_assocnotif) {
+				agent_notify_assoc_status(a, ap->bssid, num_sta >= ap->max_sta ? false : true);
+				ap->sent_assocnotif = true;
+			}
 		}
 
 		/* request scan results from the driver, etc */
@@ -6681,6 +6746,7 @@ int agent_init_interfaces(struct agent *a)
 				fn->cfg = f;
 				fn->agent = a;
 				strncpy(fn->radio_name, re->name, IFNAMSIZ-1);
+				fn->sent_assocnotif = false;
 
 				list_add(&fn->list, &re->aplist);
 			} else
@@ -6723,7 +6789,6 @@ int agent_init_interfaces(struct agent *a)
 		strncpy(bss->ssid, fn->ssid, sizeof(bss->ssid) - 1);
 		bss->enabled = fn->enabled;
 
-
 		for (k = 0; k < num_subfr; k++)
 			wifi_subscribe_frame(f->name, subfr[k].type, subfr[k].stype);
 
@@ -7347,6 +7412,7 @@ void clear_stalist(struct netif_ap *p)
 			p->num_sta--;
 		clear_sta(s);
 	}
+	agent_modify_assoc_status(p, true);
 }
 
 void clear_nbrlist(struct netif_ap *p)
diff --git a/src/agent.h b/src/agent.h
index e44fc068ce318956bf78249c34885c5d6be6d617..138409f5057d2cefa9ec62aa6b867411f8e96c53 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -328,7 +328,9 @@ struct netif_ap {
 	struct list_head restrict_stalist;  /* list of restrict_sta_entry */
 	struct list_head nbrlist;
 	int nbr_nr;
+	uint16_t max_sta; /* max number of stations: 0 - unlimited */
 	uint16_t num_sta;
+	bool sent_assocnotif;
 	struct list_head stalist;
 	struct agent *agent;
 
diff --git a/src/agent_map.c b/src/agent_map.c
index e379dc1e6b354d93b5ea84baad362f2df166128a..bb3d0944127e9c790388b7c07426d84ae2399d14 100644
--- a/src/agent_map.c
+++ b/src/agent_map.c
@@ -492,19 +492,22 @@ int send_sta_disassoc_stats(void *agent, struct cmdu_buff *cmdu)
 
 int send_assoc_status_notification(struct agent *a, int num_data, void *data)
 {
-	struct node *n;
+	struct node *n = NULL;
 	struct cmdu_buff *cmdu;
 
+	/* TODO: ensure 1905 sends msg as reliable multicast */
+
 	/* cntlr may not have its own node allocated */
 	cmdu = agent_gen_association_status_notify(a, num_data, data);
 	if (cmdu) {
-		memcpy(cmdu->origin, a->cfg.cntlr_almac, 6);
+		memcpy(cmdu->origin, a->cfg.cntlr_almac, ETH_ALEN);
 		agent_send_cmdu(a, cmdu);
 		cmdu_free(cmdu);
 	}
 
 	list_for_each_entry(n, &a->nodelist, list) {
-		if (!memcpy(n->alid, a->cfg.cntlr_almac, 6))
+		if (!memcmp(n->alid, a->cfg.cntlr_almac, ETH_ALEN))
+			/* skip cntlr - already sent */
 			continue;
 
 		cmdu = agent_gen_association_status_notify(a, num_data, data);
@@ -519,7 +522,6 @@ int send_assoc_status_notification(struct agent *a, int num_data, void *data)
 	return 0;
 }
 
-
 int send_tunneled_message(void *agent, struct cmdu_buff *cmdu)
 {
 	return 0;
diff --git a/src/agent_ubus.c b/src/agent_ubus.c
index ea47029bea5b4ce25d178567aedb7a86efc82fb6..7c38ae6d74bd34fc5a0128294ea998c046630f29 100644
--- a/src/agent_ubus.c
+++ b/src/agent_ubus.c
@@ -1299,7 +1299,7 @@ static int assoc_notify(struct ubus_context *ctx, struct ubus_object *obj,
 		 * '0x00' or '0x01'
 		 */
 		status = blobmsg_get_u32(tb1[1]);
-		if (!((status == 0x00) || (status == 0x01)))
+		if (!((status == STA_ASSOC_NOT_ALLOWED) || (status == STA_ASSOC_ALLOWED)))
 			continue;
 
 		tmp = realloc(bss_data, (num_data + 1) * sizeof(*bss_data));
diff --git a/src/assoc_ctrl.c b/src/assoc_ctrl.c
index aaea264e866f486fab8ccfac7cba94a4e83de9cd..3fd867c201c75b05f56c00787bc55f3975431093 100644
--- a/src/assoc_ctrl.c
+++ b/src/assoc_ctrl.c
@@ -389,7 +389,7 @@ int assoc_ctrl_process_request(void *agent, uint8_t *p,
 			  __func__, disallow ? "Disallow" : "Allow",
 			  MAC2STR(data->bssid), ap->ifname);
 
-		if (!wifi_set_backhaul_bss_association_mode(ap->ifname, disallow)) {
+		if (!wifi_set_ap_mbo_association_mode(ap->ifname, disallow)) {
 			ap->cfg->disallow_assoc = disallow;
 			uci_apply_bss_association_mode(ap->ifname, disallow);
 		}
diff --git a/src/wifi.c b/src/wifi.c
index ca2b12d37863ceb128869e4724d874b103576504..fe1ac3a55a9e53d92edd2152b7d3900b38a02c8e 100644
--- a/src/wifi.c
+++ b/src/wifi.c
@@ -428,7 +428,7 @@ int wifi_ap_stats(const char *ifname, struct wifi_ap_stats *stats)
 	return ret;
 }
 
-int wifi_set_backhaul_bss_association_mode(const char *ifname, bool disallow)
+int wifi_set_ap_mbo_association_mode(const char *ifname, bool disallow)
 {
 	struct ubus_context *ctx = ubus_connect(NULL);
 	int ret;
diff --git a/src/wifi.h b/src/wifi.h
index c21c832b3fb523901390834615d507376e9b2e0a..b904afc21f559f6a1bac69c94c7cd327f5b61016 100644
--- a/src/wifi.h
+++ b/src/wifi.h
@@ -134,7 +134,7 @@ int wifi_send_qos_map_conf(const char *ifname, uint8_t *macaddr);
 int wifi_sta_info(const char *ifname, struct wifi_sta *sta);
 int wifi_bsta_disconnect(struct netif_bk *bk, uint32_t reason);
 
-int wifi_set_backhaul_bss_association_mode(const char *ifname, bool disallow);
+int wifi_set_ap_mbo_association_mode(const char *ifname, bool disallow);
 
 /* WiFi send managment action frame*/
 int wifi_send_action(const char *ifname, uint8_t *dst_mac,
diff --git a/src/wifi_ubus.c b/src/wifi_ubus.c
index 5d8958367f03e32160f33ee5a58afd5e2baf2383..b7efc90a0ed280e924b6045d0e0a48a9e46e6a15 100644
--- a/src/wifi_ubus.c
+++ b/src/wifi_ubus.c
@@ -1219,19 +1219,20 @@ static void wifi_ubus_ap_status_cb(struct ubus_request *req,
 				   struct blob_attr *msg)
 {
 	struct ap_status_ctx *ctx = req->priv;
-        static const struct blobmsg_policy ap_status_policy[] = {
-                [0] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
-                [1] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
-                [2] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING },
-                [3] = { .name = "utilization", .type = BLOBMSG_TYPE_INT32 },
-                [4] = { .name = "capabilities", .type = BLOBMSG_TYPE_TABLE },
-                [5] = { .name = "standard", .type = BLOBMSG_TYPE_STRING },
-                [6] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 },
-                [7] = { .name = "status", .type = BLOBMSG_TYPE_STRING },
-                [8] = { .name = "num_stations", .type = BLOBMSG_TYPE_INT32 },
-                [9] = { .name = "enabled", .type = BLOBMSG_TYPE_BOOL },
-		[10] = { .name = "encryption", .type = BLOBMSG_TYPE_STRING },
-		[11] = { .name = "hidden", .type = BLOBMSG_TYPE_INT32 },
+	static const struct blobmsg_policy ap_status_policy[] = {
+			    [0] = { .name = "channel", .type = BLOBMSG_TYPE_INT32 },
+			    [1] = { .name = "bssid", .type = BLOBMSG_TYPE_STRING },
+			    [2] = { .name = "ssid", .type = BLOBMSG_TYPE_STRING },
+			    [3] = { .name = "utilization", .type = BLOBMSG_TYPE_INT32 },
+			    [4] = { .name = "capabilities", .type = BLOBMSG_TYPE_TABLE },
+			    [5] = { .name = "standard", .type = BLOBMSG_TYPE_STRING },
+			    [6] = { .name = "bandwidth", .type = BLOBMSG_TYPE_INT32 },
+			    [7] = { .name = "status", .type = BLOBMSG_TYPE_STRING },
+			    [8] = { .name = "num_stations", .type = BLOBMSG_TYPE_INT32 },
+			    [9] = { .name = "enabled", .type = BLOBMSG_TYPE_BOOL },
+			   [10] = { .name = "encryption", .type = BLOBMSG_TYPE_STRING },
+			   [11] = { .name = "hidden", .type = BLOBMSG_TYPE_INT32 },
+			   [12] = { .name = "max_stations", .type = BLOBMSG_TYPE_INT32 },
 	};
 	struct blob_attr *tb[ARRAY_SIZE(ap_status_policy)];
 	struct wifi_ap *ap;
@@ -1239,8 +1240,8 @@ static void wifi_ubus_ap_status_cb(struct ubus_request *req,
 	blobmsg_parse(ap_status_policy, ARRAY_SIZE(ap_status_policy),
 		      tb, blob_data(msg), blob_len(msg));
 
-	if (!tb[0] || !tb[1] || !tb[2] || !tb[3] || !tb[4] || !tb[5] ||
-	    !tb[6] || !tb[7] || !tb[8] || !tb[9] || !tb[10] || !tb[11]) {
+	if (!tb[0] || !tb[1] || !tb[2] || !tb[3] ||
+	    !tb[8] || !tb[9] || !tb[12]) {
 		ctx->status = -1;
 		return;
 	}
@@ -1253,12 +1254,13 @@ static void wifi_ubus_ap_status_cb(struct ubus_request *req,
 		return;
 	}
 	strncpy((char *) &ap->bss.ssid[0], blobmsg_get_string(tb[2]), sizeof(ap->bss.ssid));
-
 	ap->bss.load.utilization = blobmsg_get_u32(tb[3]);
-	ap->bss.load.sta_count = blobmsg_get_u32(tb[8]);
 
+	ap->bss.load.sta_count = blobmsg_get_u32(tb[8]);
 	ap->enabled = blobmsg_get_u32(tb[9]);
 
+	ap->assoclist_max = blobmsg_get_u32(tb[12]);
+
 	ctx->status = 0;
 }