Loading net/wireless/reg.c +86 −17 Original line number Diff line number Diff line Loading @@ -1338,6 +1338,7 @@ get_reg_request_treatment(struct wiphy *wiphy, switch (pending_request->initiator) { case NL80211_REGDOM_SET_BY_CORE: case NL80211_REGDOM_SET_BY_USER: case NL80211_REGDOM_SET_BY_DRIVER: return REG_REQ_IGNORE; case NL80211_REGDOM_SET_BY_COUNTRY_IE: if (reg_request_cell_base(lr)) { Loading Loading @@ -1372,23 +1373,6 @@ get_reg_request_treatment(struct wiphy *wiphy, return REG_REQ_ALREADY_SET; } return REG_REQ_OK; case NL80211_REGDOM_SET_BY_DRIVER: if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { if (regdom_changes(pending_request->alpha2)) return REG_REQ_OK; return REG_REQ_ALREADY_SET; } /* * This would happen if you unplug and plug your card * back in or if you add a new device for which the previously * loaded card also agrees on the regulatory domain. */ if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && !regdom_changes(pending_request->alpha2)) return REG_REQ_ALREADY_SET; return REG_REQ_INTERSECT; } return REG_REQ_IGNORE; Loading Loading @@ -1514,6 +1498,89 @@ reg_process_hint_user(struct regulatory_request *user_request) return REG_REQ_OK; } static enum reg_request_treatment __reg_process_hint_driver(struct regulatory_request *driver_request) { struct regulatory_request *lr = get_last_request(); if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { if (regdom_changes(driver_request->alpha2)) return REG_REQ_OK; return REG_REQ_ALREADY_SET; } /* * This would happen if you unplug and plug your card * back in or if you add a new device for which the previously * loaded card also agrees on the regulatory domain. */ if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && !regdom_changes(driver_request->alpha2)) return REG_REQ_ALREADY_SET; return REG_REQ_INTERSECT; } /** * reg_process_hint_driver - process driver regulatory requests * @driver_request: a pending driver regulatory request * * The wireless subsystem can use this function to process * a regulatory request issued by an 802.11 driver. * * Returns one of the different reg request treatment values. */ static enum reg_request_treatment reg_process_hint_driver(struct wiphy *wiphy, struct regulatory_request *driver_request) { const struct ieee80211_regdomain *regd; enum reg_request_treatment treatment; struct regulatory_request *lr; treatment = __reg_process_hint_driver(driver_request); switch (treatment) { case REG_REQ_OK: break; case REG_REQ_IGNORE: kfree(driver_request); return treatment; case REG_REQ_INTERSECT: /* fall through */ case REG_REQ_ALREADY_SET: regd = reg_copy_regd(get_cfg80211_regdom()); if (IS_ERR(regd)) { kfree(driver_request); return REG_REQ_IGNORE; } rcu_assign_pointer(wiphy->regd, regd); } lr = get_last_request(); if (lr != &core_request_world && lr) kfree_rcu(lr, rcu_head); driver_request->intersect = treatment == REG_REQ_INTERSECT; driver_request->processed = false; rcu_assign_pointer(last_request, driver_request); /* * 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 (treatment == REG_REQ_ALREADY_SET) { nl80211_send_reg_change_event(driver_request); reg_set_request_processed(); return treatment; } if (call_crda(driver_request->alpha2)) return REG_REQ_IGNORE; return REG_REQ_OK; } /** * __regulatory_hint - hint to the wireless core a regulatory domain * @wiphy: if the hint comes from country information from an AP, this Loading Loading @@ -1637,6 +1704,8 @@ static void reg_process_hint(struct regulatory_request *reg_request) schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); return; case NL80211_REGDOM_SET_BY_DRIVER: treatment = reg_process_hint_driver(wiphy, reg_request); break; case NL80211_REGDOM_SET_BY_COUNTRY_IE: treatment = __regulatory_hint(wiphy, reg_request); break; Loading Loading
net/wireless/reg.c +86 −17 Original line number Diff line number Diff line Loading @@ -1338,6 +1338,7 @@ get_reg_request_treatment(struct wiphy *wiphy, switch (pending_request->initiator) { case NL80211_REGDOM_SET_BY_CORE: case NL80211_REGDOM_SET_BY_USER: case NL80211_REGDOM_SET_BY_DRIVER: return REG_REQ_IGNORE; case NL80211_REGDOM_SET_BY_COUNTRY_IE: if (reg_request_cell_base(lr)) { Loading Loading @@ -1372,23 +1373,6 @@ get_reg_request_treatment(struct wiphy *wiphy, return REG_REQ_ALREADY_SET; } return REG_REQ_OK; case NL80211_REGDOM_SET_BY_DRIVER: if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { if (regdom_changes(pending_request->alpha2)) return REG_REQ_OK; return REG_REQ_ALREADY_SET; } /* * This would happen if you unplug and plug your card * back in or if you add a new device for which the previously * loaded card also agrees on the regulatory domain. */ if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && !regdom_changes(pending_request->alpha2)) return REG_REQ_ALREADY_SET; return REG_REQ_INTERSECT; } return REG_REQ_IGNORE; Loading Loading @@ -1514,6 +1498,89 @@ reg_process_hint_user(struct regulatory_request *user_request) return REG_REQ_OK; } static enum reg_request_treatment __reg_process_hint_driver(struct regulatory_request *driver_request) { struct regulatory_request *lr = get_last_request(); if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { if (regdom_changes(driver_request->alpha2)) return REG_REQ_OK; return REG_REQ_ALREADY_SET; } /* * This would happen if you unplug and plug your card * back in or if you add a new device for which the previously * loaded card also agrees on the regulatory domain. */ if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && !regdom_changes(driver_request->alpha2)) return REG_REQ_ALREADY_SET; return REG_REQ_INTERSECT; } /** * reg_process_hint_driver - process driver regulatory requests * @driver_request: a pending driver regulatory request * * The wireless subsystem can use this function to process * a regulatory request issued by an 802.11 driver. * * Returns one of the different reg request treatment values. */ static enum reg_request_treatment reg_process_hint_driver(struct wiphy *wiphy, struct regulatory_request *driver_request) { const struct ieee80211_regdomain *regd; enum reg_request_treatment treatment; struct regulatory_request *lr; treatment = __reg_process_hint_driver(driver_request); switch (treatment) { case REG_REQ_OK: break; case REG_REQ_IGNORE: kfree(driver_request); return treatment; case REG_REQ_INTERSECT: /* fall through */ case REG_REQ_ALREADY_SET: regd = reg_copy_regd(get_cfg80211_regdom()); if (IS_ERR(regd)) { kfree(driver_request); return REG_REQ_IGNORE; } rcu_assign_pointer(wiphy->regd, regd); } lr = get_last_request(); if (lr != &core_request_world && lr) kfree_rcu(lr, rcu_head); driver_request->intersect = treatment == REG_REQ_INTERSECT; driver_request->processed = false; rcu_assign_pointer(last_request, driver_request); /* * 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 (treatment == REG_REQ_ALREADY_SET) { nl80211_send_reg_change_event(driver_request); reg_set_request_processed(); return treatment; } if (call_crda(driver_request->alpha2)) return REG_REQ_IGNORE; return REG_REQ_OK; } /** * __regulatory_hint - hint to the wireless core a regulatory domain * @wiphy: if the hint comes from country information from an AP, this Loading Loading @@ -1637,6 +1704,8 @@ static void reg_process_hint(struct regulatory_request *reg_request) schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); return; case NL80211_REGDOM_SET_BY_DRIVER: treatment = reg_process_hint_driver(wiphy, reg_request); break; case NL80211_REGDOM_SET_BY_COUNTRY_IE: treatment = __regulatory_hint(wiphy, reg_request); break; Loading