diff --git a/src/core/agent.c b/src/core/agent.c
index 5df9bc35ff28d2ac6508c303d18d7562ac5d5df2..fc6797b530a85e26fcd2869554a20e559e1890b3 100644
--- a/src/core/agent.c
+++ b/src/core/agent.c
@@ -1989,6 +1989,72 @@ static void agent_add_to_bridge(struct agent *a, char *ifname)
 	}
 }
 
+static void agent_disable_local_cntlr(struct agent *a)
+{
+	char pid[8] = {0};
+
+	/** TODO: use pidfile */
+	chrCmd(pid, sizeof(pid), "pidof mapcontroller");
+	if (strlen(pid)) {
+		set_value_by_string("mapcontroller", "controller",
+				"enabled", "0",	UCI_TYPE_STRING);
+		trace("found pid %s of mapcontroller, sending SIGHUP\n",
+				pid);
+		kill(atoi(pid), SIGHUP);
+	}
+}
+
+static void ethport_event_handler(void *agent, struct blob_attr *msg)
+{
+	char ifname[16] = {0}, link[8] = {0};
+	struct agent *a = (struct agent *) agent;
+	struct blob_attr *tb[4];
+	static const struct blobmsg_policy ev_attr[4] = {
+		[0] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING },
+		[1] = { .name = "link", .type = BLOBMSG_TYPE_STRING },
+		[2] = { .name = "speed", .type = BLOBMSG_TYPE_TABLE },
+		[3] = { .name = "duplex", .type = BLOBMSG_TYPE_TABLE },
+	};
+	bool up, down;
+
+	blobmsg_parse(ev_attr, 4, tb, blob_data(msg), blob_len(msg));
+
+	if (!tb[0] || !tb[1]) /* only need ifname and link status */
+		return;
+
+	strncpy(ifname,	blobmsg_data(tb[0]), sizeof(ifname) - 1);
+	strncpy(link, blobmsg_data(tb[1]), sizeof(link) - 1);
+
+	up = !strcmp(link, "up");
+	down = !strcmp(link, "down");
+
+	if (up) {
+		int i;
+
+		/* if is wan port getting a link up, active acs and do cntlr discovery*/
+		if (!strncmp(a->ethwan, ifname, IFNAMSIZ)) {
+			if (a->cfg.discovery_proto == DISCOVERY_AUTOMATIC)
+				agent_disable_local_cntlr(a);
+
+			dbg("|%s:%d| link up event received\n", __func__,
+					__LINE__);
+
+			/** upon connecting to new network - allow radios to be
+			 * reconfigured
+				*/
+			for (i = 0; i < a->num_radios; i++) {
+				dbg("|%s:%d| setting radio %s into active state\n",
+						__func__, __LINE__, a->radios[i].name);
+				a->radios[i].state = ACS_ACTIVE;
+			}
+
+			uloop_timeout_set(&a->autocfg_dispatcher, 5 * 1000);
+		}
+	} else if (down) {
+		// TODO
+	}
+}
+
 static void wifi_bsta_event_handler(void *agent, struct blob_attr *msg)
 {
 	char ifname[16] = {0}, event[16] = {0}, bssid_str[18] = {0};
@@ -2038,20 +2104,13 @@ static void wifi_bsta_event_handler(void *agent, struct blob_attr *msg)
 	if (add) {
 		int i;
 		time_t now;
-		char pid[8] = {0};
 
 		time(&now);
 
 		bk->connected = true;
 
-		/** TODO: use pidfile */
-		chrCmd(pid, sizeof(pid), "pidof mapcontroller");
-		if (strlen(pid)) {
-			set_value_by_string("mapcontroller", "controller", "enabled", "0",
-				UCI_TYPE_STRING);
-			trace("found pid %s of mapcontroller, sending SIGHUP\n", pid);
-			kill(atoi(pid), SIGHUP);
-		}
+		if (a->cfg.discovery_proto == DISCOVERY_AUTOMATIC)
+			agent_disable_local_cntlr(a);
 
 		dbg("|%s:%d| connect event received\n", __func__, __LINE__);
 
@@ -2191,7 +2250,8 @@ static void ubus_wifi_event_handler(struct ubus_context *ctx,
 		{ "wifi.radio", wifi_radio_event_handler },
 		{ "wifi.iface", wifi_iface_event_handler },
 		{ "wps_credentials", wifi_wps_creds_event_handler },
-		{ "wifi.bsta", wifi_bsta_event_handler }
+		{ "wifi.bsta", wifi_bsta_event_handler },
+		{ "ethport", ethport_event_handler }
 	};
 
 	str = blobmsg_format_json(msg, true);
@@ -3787,7 +3847,7 @@ int start_agent(void)
 	ubus_add_uloop(ctx);
 
 	agent_config_init(&w->cfg);
-
+	agent_config_get_ethwan(w->ethwan);
 	memcpy(w->cntlr_almac, w->cfg.cntlr_almac, 6);
 	if (w->cfg.brcm_setup) {
 		int ret;
@@ -3825,6 +3885,7 @@ int start_agent(void)
 
 	agent_init_interfaces(w);
 
+	ubus_register_event_handler(ctx, &w->wifi_evh, "ethport");
 	ubus_register_event_handler(ctx, &w->wifi_evh, "wifi.*");
 	ubus_register_event_handler(ctx, &w->wifi_evh, "wps_credentials");
 	ubus_register_event_handler(ctx, &w->ieee1905_evh, "ieee1905.*");
diff --git a/src/core/agent.h b/src/core/agent.h
index 85f281ec8dcc871ca8d815fc429f1b081e63fe0f..f3bceea810efcdb19a6d790497dfc19044d156a7 100644
--- a/src/core/agent.h
+++ b/src/core/agent.h
@@ -414,6 +414,7 @@ struct agent {
 	int debug;
 	uint8_t almac[6];
 	uint8_t cntlr_almac[6];
+	char ethwan[16];
 	struct uloop_timeout heartbeat;
 	struct uloop_timeout autocfg_dispatcher;
 	struct list_head fhlist;
diff --git a/src/core/config.c b/src/core/config.c
index 05af1f4cc370b82a2e6ddc9e6e50fe20c4aac4ed..34be6920c4a03f257a5e871f9cf5b5a8b0de997f 100644
--- a/src/core/config.c
+++ b/src/core/config.c
@@ -281,6 +281,33 @@ out:
 	return rv;
 }
 
+char *agent_config_get_ethwan(char *ifname)
+{
+	struct uci_context *ctx;
+	struct uci_ptr ptr = {0};
+
+	ctx = uci_alloc_context();
+	if (!ctx)
+		return NULL;
+
+	//ptr.value = value;
+	ptr.package = "ports";
+	ptr.section = "WAN";
+	ptr.option = "ifname";
+	ptr.target = UCI_TYPE_OPTION;
+
+	if (uci_lookup_ptr(ctx, &ptr, NULL, false)) {
+		uci_free_context(ctx);
+		return NULL;
+	}
+
+	strncpy(ifname, ptr.o->v.string, 15);
+
+	uci_free_context(ctx);
+	return ifname;
+}
+
+
 struct uci_section *config_add_section(struct uci_context *ctx,
 		struct uci_package *pkg, const char *config, const char *type,
 		const char *key, const char *value)
@@ -1248,6 +1275,7 @@ static int agent_config_get_wifi_agent(struct agent_config *a,
 		A_EXCLUDE_BTM,
 		A_AL_BRIDGE,
 		A_NETDEV,
+		A_DISCOVERY_PROTO,
 		NUM_POLICIES
 	};
 	const struct uci_parse_option opts[] = {
@@ -1261,6 +1289,7 @@ static int agent_config_get_wifi_agent(struct agent_config *a,
 		{ .name = "exclude_btm", .type = UCI_TYPE_LIST },
 		{ .name = "al_bridge", .type = UCI_TYPE_STRING },
 		{ .name = "netdev", .type = UCI_TYPE_STRING },
+		{ .name = "discovery_proto", .type = UCI_TYPE_STRING }
 	};
 	struct uci_option *tb[NUM_POLICIES];
 
@@ -1325,6 +1354,15 @@ static int agent_config_get_wifi_agent(struct agent_config *a,
 		strncpy(a->netdev, (a->brcm_setup)?"wl":"wlan", sizeof(a->netdev) - 1);
 	}
 
+	if (tb[A_DISCOVERY_PROTO]) {
+		const char *proto = tb[A_DISCOVERY_PROTO]->v.string;
+
+		if (!strncmp(proto, "static", 6))
+			a->discovery_proto = DISCOVERY_STATIC;
+		if (!strncmp(proto, "auto", 4)) /* defaults to auto */
+			a->discovery_proto = DISCOVERY_AUTOMATIC;
+	}
+
 	return 0;
 }
 
diff --git a/src/core/config.h b/src/core/config.h
index 5594f026e85ef222691e8897b2a2fe14c895eb1e..075058d4396361af0ba8314ef058592088a07c49 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -143,6 +143,11 @@ struct agent_config_radio {
 	struct list_head list;
 };
 
+enum discovery_protocol {
+	DISCOVERY_AUTOMATIC,        /* controller will disable itself upon various network events */
+	DISCOVERY_STATIC,           /* controller shall not have any dynamic handling */
+};
+
 struct agent_config {
 	bool enabled;
 	int debug_level;
@@ -168,6 +173,9 @@ struct agent_config {
 
 	/** STAs excluded from BTM req steering; list of stax structs */
 	struct list_head steer_btm_excludelist;
+
+	enum discovery_protocol discovery_proto;
+
 };
 
 #if 0
@@ -199,6 +207,7 @@ int wifi_set_iface_bssid(const char *ifname, uint8_t *bssid);
 char *uci_get_bridge(char *ifname, char *bridge);
 
 /* END TODO */
+char *agent_config_get_ethwan(char *ifname);
 
 int agent_config_init(struct agent_config *cfg);
 int agent_config_reload(struct agent_config *cfg);