diff --git a/docs/guide/copy_config.md b/docs/guide/copy_config.md
new file mode 100644
index 0000000000000000000000000000000000000000..6deba430b844cf27ec14865eb5f62cf15eaa23c2
--- /dev/null
+++ b/docs/guide/copy_config.md
@@ -0,0 +1,76 @@
+# Proposal for copy config on firmware change
+
+Currently we have different behaviour of config management based on following scenarios, which could be bit confusing for operators and end-users.
+
+## Scenario 1: Upgrade using ACS using '1 Firmware Image' and '6 Stored image'
+
+In this scenario, we provide a firmware default uci option to configure the config management
+
+```
+cwmp.cpe.fw_upgrade_keep_settings
+```
+
+If this option is enabled, then config is copied over to the next firmware.
+
+> Note: there is no way to change this behaviour from ACS, we only provide uci option, but no datamodel vendor extension
+
+## Scenario 2: Upgrade using USP Controller
+
+With USP it has many possibilities, user can
+
+1. Download and activate at the same time
+2. Download without Activate
+3. Activate the downloaded image immediately 
+4. Activate the downloaded image with a time-window
+
+Currently we do provide a vendor extended option in `Download()` command to manage the config
+```
+Device.DeviceInfo.FirmwareImage.{i}.Download() input:AutoActivate
+Device.DeviceInfo.FirmwareImage.{i}.Download() input:X_IOWRT_EU_KeepConfig
+```
+
+But, same is lacking in Activate() operate command
+```
+Device.DeviceInfo.FirmwareImage.{i}.Activate()
+Device.DeviceInfo.FirmwareImage.{i}.Activate() input:TimeWindow.{i}.End
+Device.DeviceInfo.FirmwareImage.{i}.Activate() input:TimeWindow.{i}.Mode
+Device.DeviceInfo.FirmwareImage.{i}.Activate() input:TimeWindow.{i}.Start
+```
+
+## Scenario 3: Switch the firmware with DM without upgrade
+
+Currently there is no way to manage the config, when user switches the bank using `Set` operation on `BootFirmwareImage`
+
+```
+Device.DeviceInfo.ActiveFirmwareImage
+Device.DeviceInfo.BootFirmwareImage
+```
+
+## Proposal: Unified config management
+
+In place of having separate but similar change in cwmp and usp, proposal is to have it in `sysmngr` config, and that will be used by both `ACS` and `USP Controller`.
+
+```bash
+# cat /etc/config/sysmngr
+
+config globals 'globals'
+        option log_level '4'
+	option keep_config 'Full'
+```
+
+keep_config should be an Enum, so that it can be updated later on for future extensions
+
+| Enum value  | Meaning   |
+| ----------  | --------- |
+| Full        | Similar to sysupgrade -b, copies full configuration |
+| None        | Do not copy config to the next firmware |
+
+This table can be further extended in the future with (how they will work is out of scope of this document),
+
+Datamodel => Meaning copy only datamodel config
+
+For datamodel Integration, we can add a 'rw' vendor extension to map with this new uci option
+
+Device.DeviceInfo.X_IOWRT_EU_ConfigBackup => sysmngr.globals.keep_config
+
+With this, operator can manage the Firmware upgrade behaviour from all different scenarios.
diff --git a/src/deviceinfo.c b/src/deviceinfo.c
index 212e8d2d15dace6b1ef6a5ec587a41a3966ed5a7..01b25affaa7d61bd5c037c31b4b5369b71d9ce76 100644
--- a/src/deviceinfo.c
+++ b/src/deviceinfo.c
@@ -227,6 +227,30 @@ static int get_deviceinfo_base_mac_addr(char *refparam, struct dmctx *ctx, void
 	return 0;
 }
 
+static int get_deviceinfo_keep_config(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	*value = dmuci_get_option_value_fallback_def("sysmngr", "globals", "keep_config", "1");
+	return 0;
+}
+
+static int set_deviceinfo_keep_config(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
+{
+	bool b;
+
+	switch (action) {
+	case VALUECHECK:
+		if (bbfdm_validate_boolean(ctx, value))
+			return FAULT_9007;
+		break;
+	case VALUESET:
+		string_to_bool(value, &b);
+		dmuci_set_value("sysmngr", "globals", "keep_config", b ? "1" : "0");
+		break;
+	}
+
+	return 0;
+}
+
 static int get_DeviceInfoFileDescriptors_Used(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
 	char val[32] = {'\0'};
@@ -345,6 +369,7 @@ DMLEAF tDeviceInfoParams[] = {
 
 #ifdef SYSMNGR_VENDOR_EXTENSIONS
 {CUSTOM_PREFIX"BaseMACAddress", &DMREAD, DMT_STRING, get_deviceinfo_base_mac_addr, NULL, BBFDM_BOTH},
+{CUSTOM_PREFIX"KeepConfig", &DMWRITE, DMT_BOOL, get_deviceinfo_keep_config, set_deviceinfo_keep_config, BBFDM_BOTH},
 #endif
 
 {0}
diff --git a/src/files/usr/share/bbfdm/scripts/bbf_activate_handler.sh b/src/files/usr/share/bbfdm/scripts/bbf_activate_handler.sh
index 8619310144b7bfcbfa885b5df3c2da0a2ac3590e..57c2caa917498e02df0e7fd13845d75ded136c06 100755
--- a/src/files/usr/share/bbfdm/scripts/bbf_activate_handler.sh
+++ b/src/files/usr/share/bbfdm/scripts/bbf_activate_handler.sh
@@ -19,6 +19,7 @@ log() {
 
 activate_and_reboot_device() {
 	local bank_id="${1}"
+	local keep_config="${2}"
 	local success
 
 	success=$(ubus call fwbank set_bootbank "{'bank':${bank_id}}" | jsonfilter -e @.success)
@@ -27,6 +28,14 @@ activate_and_reboot_device() {
 		exit 1
 	fi
 
+	if [ "${keep_config}" = "1" ]; then
+		success=$(/etc/sysmngr/fwbank call copy_config 2> /dev/null | jsonfilter -e @.success)
+		if [ "${success}" != "true" ]; then
+			log "Can't copy config"
+			exit 1
+		fi
+	fi
+
 	log "The device will restart after a few seconds"
 	ubus call rpc-sys reboot
 	exit 0
@@ -36,6 +45,7 @@ handle_whenidle_mode() {
 	local bank_id="${1}"
 	local end_time="${2}"
 	local force_activation="${3}"
+	local keep_config="${4}"
 	local diff=0
 	
 	[ ! -x "${CHECK_IDLE_FILE}" ] && {
@@ -71,7 +81,7 @@ handle_whenidle_mode() {
 	done
 
 	[ "${force_activation}" = "1" ] && {
-		activate_and_reboot_device "${bank_id}"
+		activate_and_reboot_device "${bank_id}" "${keep_config}"
 	}
 }
 
@@ -83,11 +93,11 @@ handle_confirmation_needed_mode() {
 
 ######################## main ########################
 if [ "${MODE}" = "Immediately" ] || [ "${MODE}" = "AnyTime" ]; then
-	activate_and_reboot_device "${2}"
+	activate_and_reboot_device "${2}" "${7}"
 elif [ "${MODE}" = "WhenIdle" ]; then
-	handle_whenidle_mode "${2}" "${3}" "${4}"
+	handle_whenidle_mode "${2}" "${3}" "${4}" "${7}"
 elif [ "${MODE}" = "ConfirmationNeeded" ]; then
-	handle_confirmation_needed_mode "${2}" "${3}" "${4}" "${5}" "${6}"
+	handle_confirmation_needed_mode "${2}" "${3}" "${4}" "${5}" "${6}" "${7}"
 else
 	log "[${MODE}] mode is not supported"
 	exit 1
diff --git a/src/fw_images.c b/src/fw_images.c
index 98769283e057db939ca57e14e2e748683139b438..e51a4e9d282d251bf73e9d1faf9f359e9d294639 100644
--- a/src/fw_images.c
+++ b/src/fw_images.c
@@ -12,13 +12,16 @@
 #include "utils.h"
 #include "fwbank.h"
 
-#define MAX_TIME_WINDOW 5
-
 struct sysupgrade_ev_data {
 	const char *bank_id;
 	bool status;
 };
 
+#define CRONTABS_ROOT "/etc/crontabs/root"
+#define ACTIVATE_HANDLER_FILE "/usr/share/bbfdm/scripts/bbf_activate_handler.sh"
+#define COPY_CONFIG_CMD "/etc/sysmngr/fwbank call copy_config 2> /dev/null"
+#define MAX_TIME_WINDOW 5
+
 /*************************************************************
 * COMMON FUNCTIONS
 **************************************************************/
@@ -92,7 +95,14 @@ static char *get_fwbank_bank_id(const char *option_name)
 	return bank_id ? bank_id : "";
 }
 
-static bool fwbank_set_bootbank(char *bank_id)
+static void fwbank_copy_config(void)
+{
+	char output[64] = {0};
+
+	run_cmd(COPY_CONFIG_CMD, output, sizeof(output));
+}
+
+static bool fwbank_set_bootbank(const char *bank_id)
 {
 	int res = sysmngr_fwbank_set_bootbank((uint32_t)DM_STRTOUL(bank_id), NULL);
 
@@ -102,7 +112,7 @@ static bool fwbank_set_bootbank(char *bank_id)
 static bool fwbank_upgrade(const char *path, const char *auto_activate, const char *bank_id, const char *keep_settings)
 {
 	json_object *json_obj = NULL;
-	int res = 0;
+	bool res = false;
 
 	dmubus_call_blocking("fwbank", "upgrade", UBUS_ARGS{{"path", path, String}, {"auto_activate", auto_activate, Boolean}, {"bank", bank_id, Integer}, {"keep_settings", keep_settings, Boolean}}, 4, &json_obj);
 
@@ -360,6 +370,7 @@ int set_device_boot_fwimage(char *refparam, struct dmctx *ctx, void *data, char
 {
 	char *allowed_objects[] = {"Device.DeviceInfo.FirmwareImage.", NULL};
 	struct dm_reference reference = {0};
+	char *keep_config = NULL;
 
 	bbfdm_get_reference_linker(ctx, value, &reference);
 
@@ -388,6 +399,12 @@ int set_device_boot_fwimage(char *refparam, struct dmctx *ctx, void *data, char
 
 				if (!fwbank_set_bootbank(bank_id + 1))
 					return FAULT_9001;
+
+				dmuci_set_value("sysmngr","globals", "switch_bank", "1");
+
+				keep_config = dmuci_get_option_value_fallback_def("sysmngr", "globals", "keep_config", "1");
+				if (DM_STRCMP(keep_config, "1") == 0)
+					fwbank_copy_config();
 			}
 			break;
 	}
@@ -516,9 +533,6 @@ static operation_args firmware_image_download_args = {
 		"CheckSumAlgorithm",
 		"CheckSum",
 		"CommandKey",
-#ifdef SYSMNGR_VENDOR_EXTENSIONS
-		CUSTOM_PREFIX"KeepConfig",
-#endif
 		NULL
 	}
 };
@@ -557,10 +571,9 @@ static int operate_DeviceInfoFirmwareImage_Download(char *refparam, struct dmctx
 	char *checksum_algorithm = dmjson_get_value((json_object *)value, 1, "CheckSumAlgorithm");
 	char *checksum = dmjson_get_value((json_object *)value, 1, "CheckSum");
 	char *commandKey = dmjson_get_value((json_object *)value, 1, "CommandKey");
-	char *keep_config = NULL;
-#ifdef SYSMNGR_VENDOR_EXTENSIONS
-	keep_config = dmjson_get_value((json_object *)value, 1, CUSTOM_PREFIX"KeepConfig");
-#endif
+
+	char *keep_config = dmuci_get_option_value_fallback_def("sysmngr", "globals", "keep_config", "1");
+
 	char *bank_id = get_fwbank_option_value(data, "id");
 
 	int res = bbf_fw_image_download(ctx->ubus_ctx, url, auto_activate, username, password, file_size, checksum_algorithm, checksum, bank_id, command, obj_path, commandKey, keep_config);
@@ -574,7 +587,6 @@ static int operate_DeviceInfoFirmwareImage_Download(char *refparam, struct dmctx
 
 static operation_args firmware_image_activate_args = {
 	.in = (const char *[]) {
-
 		"TimeWindow.{i}.Start",
 		"TimeWindow.{i}.End",
 		"TimeWindow.{i}.Mode",
@@ -592,9 +604,6 @@ static int get_operate_args_DeviceInfoFirmwareImage_Activate(char *refparam, str
 
 static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-#define CRONTABS_ROOT "/etc/crontabs/root"
-#define ACTIVATE_HANDLER_FILE "/usr/share/bbfdm/scripts/bbf_activate_handler.sh"
-
 	char *FW_Mode[] = {"AnyTime", "Immediately", "WhenIdle", "ConfirmationNeeded", NULL};
 	char *start_time[MAX_TIME_WINDOW] = {0};
 	char *end_time[MAX_TIME_WINDOW] = {0};
@@ -603,6 +612,8 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
 	char *max_retries[MAX_TIME_WINDOW] = {0};
 	int res = 0, last_idx = -1;
 
+	char *keep_config = dmuci_get_option_value_fallback_def("sysmngr", "globals", "keep_config", "1");
+
 	for (int i = 0; i < MAX_TIME_WINDOW; i++) {
 		char buf[32] = {0};
 
@@ -666,7 +677,7 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
 			t_time += start_t;
 			struct tm *tm_local = localtime(&t_time);
 
-			snprintf(buffer, sizeof(buffer), "%d %d %d %d * sh %s '%s' '%s' '%ld' '%d' '%s' '%s'\n",
+			snprintf(buffer, sizeof(buffer), "%d %d %d %d * sh %s '%s' '%s' '%ld' '%d' '%s' '%s' '%s'\n",
 											tm_local->tm_min,
 											tm_local->tm_hour,
 											tm_local->tm_mday,
@@ -677,7 +688,8 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
 											(DM_STRTOL(end_time[i]) - DM_STRTOL(start_time[i])),
 											(i == last_idx),
 											user_message[i],
-											max_retries[i]);
+											max_retries[i],
+											keep_config);
 
 			fprintf(file, "%s", buffer);
 		}
@@ -689,6 +701,9 @@ static int operate_DeviceInfoFirmwareImage_Activate(char *refparam, struct dmctx
 		if (!fwbank_set_bootbank(bank_id))
 			return USP_FAULT_COMMAND_FAILURE;
 
+		if (DM_STRCMP(keep_config, "1") == 0)
+			fwbank_copy_config();
+
 		bbfdm_task_fork(_exec_reboot, NULL, NULL, NULL);
 	}
 
diff --git a/src/fwbank.c b/src/fwbank.c
index 251f6315af1db6f1d44ec9b914558628a3fed399..773ef9f9f617f3a7a90023702ecf2e7b208f8958 100644
--- a/src/fwbank.c
+++ b/src/fwbank.c
@@ -709,8 +709,15 @@ static int upgrade_handler(struct ubus_context *ctx, struct ubus_object *obj,
 	if (tb[UPGRADE_BANK])
 		bank_id = blobmsg_get_u32(tb[UPGRADE_BANK]);
 
-	if (tb[UPGRADE_KEEP_SETTINGS])
+	if (tb[UPGRADE_KEEP_SETTINGS]) {
 		keep_settings = blobmsg_get_bool(tb[UPGRADE_KEEP_SETTINGS]);
+	} else {
+		char buf[8] = {0};
+
+		BBFDM_UCI_GET("sysmngr", "globals", "keep_config", "1", buf, sizeof(buf));
+		keep_settings = ((int)strtol(buf, NULL, 10) != 0);
+		BBFDM_DEBUG("'keep_settings' option is not provided. Falling back to the value from UCI config: 'sysmngr.globals.keep_config'");
+	}
 
 	res = sysmngr_fwbank_upgrade(fw_path, auto_activate, bank_id, keep_settings, req);