diff --git a/devlink/devlink.c b/devlink/devlink.c
index b41b06f9..edcc5a79 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -3640,6 +3640,77 @@ struct dl_param {
 	} value;
 };
 
+/* Get the parameter value from the options and convert it to the
+ * appropriate type.
+ * @dl: dl struct
+ * @nla_type: type of the parameter value
+ * @param: parameter struct to store the value
+ * Returns: 0 on success, -errno on failure
+ */
+static int dl_param_opts_get(struct dl *dl, enum devlink_dyn_attr_type type,
+			     struct dl_param *param)
+{
+	uint32_t val_u32 = UINT32_MAX;
+	bool conv_exists;
+	int err = 0;
+
+	conv_exists = param_val_conv_exists(param_val_conv, PARAM_VAL_CONV_LEN,
+					    dl->opts.param_name);
+	param->type = type;
+	if (!conv_exists ||
+	    type == DEVLINK_DYN_ATTR_TYPE_STRING ||
+	    type == DEVLINK_DYN_ATTR_TYPE_FLAG ||
+	    type == DEVLINK_DYN_ATTR_TYPE_U32_ARRAY) {
+		switch (type) {
+		case DEVLINK_DYN_ATTR_TYPE_U8:
+			err = get_u8(&param->value.vu8, dl->opts.param_value, 10);
+			break;
+		case DEVLINK_DYN_ATTR_TYPE_U16:
+			err = get_u16(&param->value.vu16, dl->opts.param_value, 10);
+			break;
+		case DEVLINK_DYN_ATTR_TYPE_U32:
+			err = get_u32(&param->value.vu32, dl->opts.param_value, 10);
+			break;
+		case DEVLINK_DYN_ATTR_TYPE_FLAG:
+			err = strtobool(dl->opts.param_value, &param->value.vbool);
+			break;
+		case DEVLINK_DYN_ATTR_TYPE_STRING:
+			param->value.vstr = dl->opts.param_value;
+			err = 0;
+			break;
+		default:
+			err = -ENOTSUP;
+		}
+		return err;
+	}
+
+	/* conv_exists */
+	switch (type) {
+	case DEVLINK_DYN_ATTR_TYPE_U8:
+		err = param_val_conv_uint_get(param_val_conv, PARAM_VAL_CONV_LEN,
+					      dl->opts.param_name, dl->opts.param_value,
+					      &val_u32);
+		param->value.vu8 = val_u32;
+		break;
+	case DEVLINK_DYN_ATTR_TYPE_U16:
+		err = param_val_conv_uint_get(param_val_conv, PARAM_VAL_CONV_LEN,
+					      dl->opts.param_name, dl->opts.param_value,
+					      &val_u32);
+		param->value.vu16 = val_u32;
+		break;
+	case DEVLINK_DYN_ATTR_TYPE_U32:
+		err = param_val_conv_uint_get(param_val_conv, PARAM_VAL_CONV_LEN,
+					      dl->opts.param_name, dl->opts.param_value,
+					      &val_u32);
+		param->value.vu32 = val_u32;
+		break;
+	default:
+		err = -ENOTSUP;
+	}
+
+	return err;
+}
+
 static int cmd_param_set_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
@@ -3717,12 +3788,8 @@ static int cmd_param_set_cb(const struct nlmsghdr *nlh, void *data)
 static int cmd_dev_param_set(struct dl *dl)
 {
 	struct dl_param kparam = {}; /* kernel param */
+	struct dl_param uparam = {}; /* user param */
 	struct nlmsghdr *nlh;
-	bool conv_exists;
-	uint32_t val_u32 = 0;
-	uint16_t val_u16;
-	uint8_t val_u8;
-	bool val_bool;
 	int err;
 
 	err = dl_argv_parse(dl, DL_OPT_HANDLE |
@@ -3750,74 +3817,38 @@ static int cmd_dev_param_set(struct dl *dl)
 			       NLM_F_REQUEST | NLM_F_ACK);
 	dl_opts_put(nlh, dl);
 
-	conv_exists = param_val_conv_exists(param_val_conv, PARAM_VAL_CONV_LEN,
-					    dl->opts.param_name);
+	err = dl_param_opts_get(dl, kparam.type, &uparam);
+	if (err)
+		goto err_param_value_parse;
 
 	mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_TYPE, kparam.type);
 	switch (kparam.type) {
 	case DEVLINK_DYN_ATTR_TYPE_U8:
-		if (conv_exists) {
-			err = param_val_conv_uint_get(param_val_conv,
-						      PARAM_VAL_CONV_LEN,
-						      dl->opts.param_name,
-						      dl->opts.param_value,
-						      &val_u32);
-			val_u8 = val_u32;
-		} else {
-			err = get_u8(&val_u8, dl->opts.param_value, 10);
-		}
-		if (err)
-			goto err_param_value_parse;
-		if (val_u8 == kparam.value.vu8)
+		if (uparam.value.vu8 == kparam.value.vu8)
 			return 0;
-		mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u8);
+		mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, uparam.value.vu8);
 		break;
 	case DEVLINK_DYN_ATTR_TYPE_U16:
-		if (conv_exists) {
-			err = param_val_conv_uint_get(param_val_conv,
-						      PARAM_VAL_CONV_LEN,
-						      dl->opts.param_name,
-						      dl->opts.param_value,
-						      &val_u32);
-			val_u16 = val_u32;
-		} else {
-			err = get_u16(&val_u16, dl->opts.param_value, 10);
-		}
-		if (err)
-			goto err_param_value_parse;
-		if (val_u16 == kparam.value.vu16)
+		if (uparam.value.vu16 == kparam.value.vu16)
 			return 0;
-		mnl_attr_put_u16(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u16);
+		mnl_attr_put_u16(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, uparam.value.vu16);
 		break;
 	case DEVLINK_DYN_ATTR_TYPE_U32:
-		if (conv_exists)
-			err = param_val_conv_uint_get(param_val_conv,
-						      PARAM_VAL_CONV_LEN,
-						      dl->opts.param_name,
-						      dl->opts.param_value,
-						      &val_u32);
-		else
-			err = get_u32(&val_u32, dl->opts.param_value, 10);
-		if (err)
-			goto err_param_value_parse;
-		if (val_u32 == kparam.value.vu32)
+		if (uparam.value.vu32 == kparam.value.vu32)
 			return 0;
-		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u32);
+		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, uparam.value.vu32);
 		break;
 	case DEVLINK_DYN_ATTR_TYPE_FLAG:
-		err = strtobool(dl->opts.param_value, &val_bool);
-		if (err)
-			goto err_param_value_parse;
-		if (val_bool == kparam.value.vbool)
+		if (uparam.value.vbool == kparam.value.vbool)
 			return 0;
-		if (val_bool)
+		if (uparam.value.vbool)
 			mnl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA,
 				     0, NULL);
 		break;
 	case DEVLINK_DYN_ATTR_TYPE_STRING:
 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA,
-				  dl->opts.param_value);
-		if (!strcmp(dl->opts.param_value, kparam.value.vstr))
+				  uparam.value.vstr);
+		if (!strcmp(uparam.value.vstr, kparam.value.vstr))
 			return 0;
 		break;
 	default:
@@ -5225,12 +5256,8 @@ static int cmd_port_function_set(struct dl *dl)
 static int cmd_port_param_set(struct dl *dl)
 {
 	struct dl_param kparam = {}; /* kernel param */
+	struct dl_param uparam = {}; /* user param */
 	struct nlmsghdr *nlh;
-	bool conv_exists;
-	uint32_t val_u32 = 0;
-	uint16_t val_u16;
-	uint8_t val_u8;
-	bool val_bool;
 	int err;
 
 	err = dl_argv_parse(dl, DL_OPT_HANDLEP |
@@ -5254,74 +5281,38 @@ static int cmd_port_param_set(struct dl *dl)
 					  NLM_F_REQUEST | NLM_F_ACK);
 	dl_opts_put(nlh, dl);
 
-	conv_exists = param_val_conv_exists(param_val_conv, PARAM_VAL_CONV_LEN,
-					    dl->opts.param_name);
+	err = dl_param_opts_get(dl, kparam.type, &uparam);
+	if (err)
+		goto err_param_value_parse;
 
 	mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_TYPE, kparam.type);
 	switch (kparam.type) {
 	case DEVLINK_DYN_ATTR_TYPE_U8:
-		if (conv_exists) {
-			err = param_val_conv_uint_get(param_val_conv,
-						      PARAM_VAL_CONV_LEN,
-						      dl->opts.param_name,
-						      dl->opts.param_value,
-						      &val_u32);
-			val_u8 = val_u32;
-		} else {
-			err = get_u8(&val_u8, dl->opts.param_value, 10);
-		}
-		if (err)
-			goto err_param_value_parse;
-		if (val_u8 == kparam.value.vu8)
+		if (uparam.value.vu8 == kparam.value.vu8)
 			return 0;
-		mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u8);
+		mnl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, uparam.value.vu8);
 		break;
 	case DEVLINK_DYN_ATTR_TYPE_U16:
-		if (conv_exists) {
-			err = param_val_conv_uint_get(param_val_conv,
-						      PARAM_VAL_CONV_LEN,
-						      dl->opts.param_name,
-						      dl->opts.param_value,
-						      &val_u32);
-			val_u16 = val_u32;
-		} else {
-			err = get_u16(&val_u16, dl->opts.param_value, 10);
-		}
-		if (err)
-			goto err_param_value_parse;
-		if (val_u16 == kparam.value.vu16)
+		if (uparam.value.vu16 == kparam.value.vu16)
 			return 0;
-		mnl_attr_put_u16(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u16);
+		mnl_attr_put_u16(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, uparam.value.vu16);
 		break;
 	case DEVLINK_DYN_ATTR_TYPE_U32:
-		if (conv_exists)
-			err = param_val_conv_uint_get(param_val_conv,
-						      PARAM_VAL_CONV_LEN,
-						      dl->opts.param_name,
-						      dl->opts.param_value,
-						      &val_u32);
-		else
-			err = get_u32(&val_u32, dl->opts.param_value, 10);
-		if (err)
-			goto err_param_value_parse;
-		if (val_u32 == kparam.value.vu32)
+		if (uparam.value.vu32 == kparam.value.vu32)
 			return 0;
-		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, val_u32);
+		mnl_attr_put_u32(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, uparam.value.vu32);
 		break;
 	case DEVLINK_DYN_ATTR_TYPE_FLAG:
-		err = strtobool(dl->opts.param_value, &val_bool);
-		if (err)
-			goto err_param_value_parse;
-		if (val_bool == kparam.value.vbool)
+		if (uparam.value.vbool == kparam.value.vbool)
 			return 0;
-		if (val_bool)
+		if (uparam.value.vbool)
 			mnl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA,
 				     0, NULL);
 		break;
 	case DEVLINK_DYN_ATTR_TYPE_STRING:
 		mnl_attr_put_strz(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA,
-				  dl->opts.param_value);
-		if (!strcmp(dl->opts.param_value, kparam.value.vstr))
+				  uparam.value.vstr);
+		if (!strcmp(uparam.value.vstr, kparam.value.vstr))
 			return 0;
 		break;
 	default:
