Browse Source

regulatory: use proper enum for return values

Instead of treating special error codes specially,
like -EALREADY, introduce a real enum for all the
needed possibilities and use it.

Acked-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Johannes Berg 12 years ago
parent
commit
2f92212b71
1 changed files with 69 additions and 64 deletions
  1. 69 64
      net/wireless/reg.c

+ 69 - 64
net/wireless/reg.c

@@ -65,6 +65,13 @@
 #define REG_DBG_PRINT(args...)
 #endif
 
+enum reg_request_treatment {
+	REG_REQ_OK,
+	REG_REQ_IGNORE,
+	REG_REQ_INTERSECT,
+	REG_REQ_ALREADY_SET,
+};
+
 static struct regulatory_request core_request_world = {
 	.initiator = NL80211_REGDOM_SET_BY_CORE,
 	.alpha2[0] = '0',
@@ -925,16 +932,17 @@ bool reg_last_request_cell_base(void)
 
 #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
 /* Core specific check */
-static int reg_ignore_cell_hint(struct regulatory_request *pending_request)
+static enum reg_request_treatment
+reg_ignore_cell_hint(struct regulatory_request *pending_request)
 {
 	if (!reg_num_devs_support_basehint)
-		return -EOPNOTSUPP;
+		return REG_REQ_IGNORE;
 
 	if (reg_request_cell_base(last_request) &&
 	    !regdom_changes(pending_request->alpha2))
-		return -EALREADY;
+		return REG_REQ_ALREADY_SET;
 
-	return 0;
+	return REG_REQ_OK;
 }
 
 /* Device specific check */
@@ -945,7 +953,7 @@ static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy)
 #else
 static int reg_ignore_cell_hint(struct regulatory_request *pending_request)
 {
-	return -EOPNOTSUPP;
+	return REG_REQ_IGNORE;
 }
 
 static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy)
@@ -1308,15 +1316,10 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
 
-/*
- * Return value which can be used by ignore_request() to indicate
- * it has been determined we should intersect two regulatory domains
- */
-#define REG_INTERSECT	1
-
 /* This has the logic which determines when a new request
  * should be ignored. */
-static int ignore_request(struct wiphy *wiphy,
+static enum reg_request_treatment
+get_reg_request_treatment(struct wiphy *wiphy,
 			  struct regulatory_request *pending_request)
 {
 	struct wiphy *last_wiphy = NULL;
@@ -1325,17 +1328,17 @@ static int ignore_request(struct wiphy *wiphy,
 
 	/* All initial requests are respected */
 	if (!last_request)
-		return 0;
+		return REG_REQ_OK;
 
 	switch (pending_request->initiator) {
 	case NL80211_REGDOM_SET_BY_CORE:
-		return 0;
+		return REG_REQ_OK;
 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
 		if (reg_request_cell_base(last_request)) {
 			/* Trust a Cell base station over the AP's country IE */
 			if (regdom_changes(pending_request->alpha2))
-				return -EOPNOTSUPP;
-			return -EALREADY;
+				return REG_REQ_IGNORE;
+			return REG_REQ_ALREADY_SET;
 		}
 
 		last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
@@ -1352,23 +1355,23 @@ static int ignore_request(struct wiphy *wiphy,
 				 * to be correct. Reject second one for now.
 				 */
 				if (regdom_changes(pending_request->alpha2))
-					return -EOPNOTSUPP;
-				return -EALREADY;
+					return REG_REQ_IGNORE;
+				return REG_REQ_ALREADY_SET;
 			}
 			/*
 			 * Two consecutive Country IE hints on the same wiphy.
 			 * This should be picked up early by the driver/stack
 			 */
 			if (WARN_ON(regdom_changes(pending_request->alpha2)))
-				return 0;
-			return -EALREADY;
+				return REG_REQ_OK;
+			return REG_REQ_ALREADY_SET;
 		}
 		return 0;
 	case NL80211_REGDOM_SET_BY_DRIVER:
 		if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) {
 			if (regdom_changes(pending_request->alpha2))
-				return 0;
-			return -EALREADY;
+				return REG_REQ_OK;
+			return REG_REQ_ALREADY_SET;
 		}
 
 		/*
@@ -1378,25 +1381,25 @@ static int ignore_request(struct wiphy *wiphy,
 		 */
 		if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
 		    !regdom_changes(pending_request->alpha2))
-			return -EALREADY;
+			return REG_REQ_ALREADY_SET;
 
-		return REG_INTERSECT;
+		return REG_REQ_INTERSECT;
 	case NL80211_REGDOM_SET_BY_USER:
 		if (reg_request_cell_base(pending_request))
 			return reg_ignore_cell_hint(pending_request);
 
 		if (reg_request_cell_base(last_request))
-			return -EOPNOTSUPP;
+			return REG_REQ_IGNORE;
 
 		if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
-			return REG_INTERSECT;
+			return REG_REQ_INTERSECT;
 		/*
 		 * If the user knows better the user should set the regdom
 		 * to their country before the IE is picked up
 		 */
 		if (last_request->initiator == NL80211_REGDOM_SET_BY_USER &&
 		    last_request->intersect)
-			return -EOPNOTSUPP;
+			return REG_REQ_IGNORE;
 		/*
 		 * Process user requests only after previous user/driver/core
 		 * requests have been processed
@@ -1405,15 +1408,15 @@ static int ignore_request(struct wiphy *wiphy,
 		     last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
 		     last_request->initiator == NL80211_REGDOM_SET_BY_USER) &&
 		    regdom_changes(last_request->alpha2))
-			return -EAGAIN;
+			return REG_REQ_IGNORE;
 
 		if (!regdom_changes(pending_request->alpha2))
-			return -EALREADY;
+			return REG_REQ_ALREADY_SET;
 
-		return 0;
+		return REG_REQ_OK;
 	}
 
-	return -EINVAL;
+	return REG_REQ_IGNORE;
 }
 
 static void reg_set_request_processed(void)
@@ -1443,23 +1446,24 @@ static void reg_set_request_processed(void)
  * The Wireless subsystem can use this function to hint to the wireless core
  * what it believes should be the current regulatory domain.
  *
- * Returns zero if all went fine, %-EALREADY if a regulatory domain had
- * already been set or other standard error codes.
+ * Returns one of the different reg request treatment values.
  *
  * Caller must hold &cfg80211_mutex and &reg_mutex
  */
-static int __regulatory_hint(struct wiphy *wiphy,
-			     struct regulatory_request *pending_request)
+static enum reg_request_treatment
+__regulatory_hint(struct wiphy *wiphy,
+		  struct regulatory_request *pending_request)
 {
 	const struct ieee80211_regdomain *regd;
 	bool intersect = false;
-	int r = 0;
+	enum reg_request_treatment treatment;
 
 	assert_cfg80211_lock();
 
-	r = ignore_request(wiphy, pending_request);
+	treatment = get_reg_request_treatment(wiphy, pending_request);
 
-	if (r == REG_INTERSECT) {
+	switch (treatment) {
+	case REG_REQ_INTERSECT:
 		if (pending_request->initiator ==
 		    NL80211_REGDOM_SET_BY_DRIVER) {
 			regd = reg_copy_regd(cfg80211_regdomain);
@@ -1470,26 +1474,28 @@ static int __regulatory_hint(struct wiphy *wiphy,
 			wiphy->regd = regd;
 		}
 		intersect = true;
-	} else if (r) {
+		break;
+	case REG_REQ_OK:
+		break;
+	default:
 		/*
 		 * If the regulatory domain being requested by the
 		 * driver has already been set just copy it to the
 		 * wiphy
 		 */
-		if (r == -EALREADY &&
-		    pending_request->initiator ==
-		    NL80211_REGDOM_SET_BY_DRIVER) {
+		if (treatment == REG_REQ_ALREADY_SET &&
+		    pending_request->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
 			regd = reg_copy_regd(cfg80211_regdomain);
 			if (IS_ERR(regd)) {
 				kfree(pending_request);
-				return PTR_ERR(regd);
+				return REG_REQ_IGNORE;
 			}
-			r = -EALREADY;
+			treatment = REG_REQ_ALREADY_SET;
 			wiphy->regd = regd;
 			goto new_request;
 		}
 		kfree(pending_request);
-		return r;
+		return treatment;
 	}
 
 new_request:
@@ -1506,28 +1512,29 @@ new_request:
 		user_alpha2[1] = last_request->alpha2[1];
 	}
 
-	/* When r == REG_INTERSECT we do need to call CRDA */
-	if (r < 0) {
+	/* When r == REG_REQ_INTERSECT we do need to call CRDA */
+	if (treatment != REG_REQ_OK && treatment != REG_REQ_INTERSECT) {
 		/*
 		 * Since CRDA will not be called in this case as we already
 		 * have applied the requested regulatory domain before we just
 		 * inform userspace we have processed the request
 		 */
-		if (r == -EALREADY) {
+		if (treatment == REG_REQ_ALREADY_SET) {
 			nl80211_send_reg_change_event(last_request);
 			reg_set_request_processed();
 		}
-		return r;
+		return treatment;
 	}
 
-	return call_crda(last_request->alpha2);
+	if (call_crda(last_request->alpha2))
+		return REG_REQ_IGNORE;
+	return REG_REQ_OK;
 }
 
 /* This processes *all* regulatory hints */
 static void reg_process_hint(struct regulatory_request *reg_request,
 			     enum nl80211_reg_initiator reg_initiator)
 {
-	int r = 0;
 	struct wiphy *wiphy = NULL;
 
 	BUG_ON(!reg_request->alpha2);
@@ -1540,20 +1547,18 @@ static void reg_process_hint(struct regulatory_request *reg_request,
 		return;
 	}
 
-	r = __regulatory_hint(wiphy, reg_request);
-	/* This is required so that the orig_* parameters are saved */
-	if (r == -EALREADY && wiphy &&
-	    wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {
-		wiphy_update_regulatory(wiphy, reg_initiator);
-		return;
+	switch (__regulatory_hint(wiphy, reg_request)) {
+	case REG_REQ_ALREADY_SET:
+		/* This is required so that the orig_* parameters are saved */
+		if (wiphy && wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
+			wiphy_update_regulatory(wiphy, reg_initiator);
+		break;
+	default:
+		if (reg_initiator == NL80211_REGDOM_SET_BY_USER)
+			schedule_delayed_work(&reg_timeout,
+					      msecs_to_jiffies(3142));
+		break;
 	}
-
-	/*
-	 * We only time out user hints, given that they should be the only
-	 * source of bogus requests.
-	 */
-	if (r != -EALREADY && reg_initiator == NL80211_REGDOM_SET_BY_USER)
-		schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
 }
 
 /*