diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ca11f31b3bec2bfa39600aab6c91756967108c12..9f4f8439e16ad6092439af5d09692a72120c6640 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2191,6 +2191,14 @@ static void print_regdomain_info(const struct ieee80211_regdomain *rd)
 	print_rd_rules(rd);
 }
 
+static int reg_set_rd_core(const struct ieee80211_regdomain *rd)
+{
+	if (!is_world_regdom(rd->alpha2))
+		return -EINVAL;
+	update_world_regdomain(rd);
+	return 0;
+}
+
 /* Takes ownership of rd only if it doesn't fail */
 static int __set_regdom(const struct ieee80211_regdomain *rd,
 			struct regulatory_request *lr)
@@ -2199,18 +2207,6 @@ static int __set_regdom(const struct ieee80211_regdomain *rd,
 	const struct ieee80211_regdomain *intersected_rd = NULL;
 	struct wiphy *request_wiphy;
 
-	/* Some basic sanity checks first */
-
-	if (!reg_is_valid_request(rd->alpha2))
-		return -EINVAL;
-
-	if (is_world_regdom(rd->alpha2)) {
-		if (lr->initiator != NL80211_REGDOM_SET_BY_CORE)
-			return -EINVAL;
-		update_world_regdomain(rd);
-		return 0;
-	}
-
 	if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) &&
 	    !is_unknown_alpha2(rd->alpha2))
 		return -EINVAL;
@@ -2320,10 +2316,28 @@ int set_regdom(const struct ieee80211_regdomain *rd)
 	struct regulatory_request *lr;
 	int r;
 
+	if (!reg_is_valid_request(rd->alpha2)) {
+		kfree(rd);
+		return -EINVAL;
+	}
+
 	lr = get_last_request();
 
 	/* Note that this doesn't update the wiphys, this is done below */
-	r = __set_regdom(rd, lr);
+	switch (lr->initiator) {
+	case NL80211_REGDOM_SET_BY_CORE:
+		r = reg_set_rd_core(rd);
+		break;
+	case NL80211_REGDOM_SET_BY_USER:
+	case NL80211_REGDOM_SET_BY_DRIVER:
+	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+		r = __set_regdom(rd, lr);
+		break;
+	default:
+		WARN(1, "invalid initiator %d\n", lr->initiator);
+		return -EINVAL;
+	}
+
 	if (r) {
 		if (r == -EALREADY)
 			reg_set_request_processed();