+static void handle_reg_beacon(struct wiphy *wiphy,
+ unsigned int chan_idx,
+ struct reg_beacon *reg_beacon)
+{
+#ifdef CONFIG_CFG80211_REG_DEBUG
+#define REG_DEBUG_BEACON_FLAG(desc) \
+ printk(KERN_DEBUG "cfg80211: Enabling " desc " on " \
+ "frequency: %d MHz (Ch %d) on %s\n", \
+ reg_beacon->chan.center_freq, \
+ ieee80211_frequency_to_channel(reg_beacon->chan.center_freq), \
+ wiphy_name(wiphy));
+#else
+#define REG_DEBUG_BEACON_FLAG(desc) do {} while (0)
+#endif
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *chan;
+
+ assert_cfg80211_lock();
+
+ sband = wiphy->bands[reg_beacon->chan.band];
+ chan = &sband->channels[chan_idx];
+
+ if (likely(chan->center_freq != reg_beacon->chan.center_freq))
+ return;
+
+ if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+ chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ REG_DEBUG_BEACON_FLAG("active scanning");
+ }
+
+ if (chan->flags & IEEE80211_CHAN_NO_IBSS) {
+ chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
+ REG_DEBUG_BEACON_FLAG("beaconing");
+ }
+
+ chan->beacon_found = true;
+#undef REG_DEBUG_BEACON_FLAG
+}
+
+/*
+ * Called when a scan on a wiphy finds a beacon on
+ * new channel
+ */
+static void wiphy_update_new_beacon(struct wiphy *wiphy,
+ struct reg_beacon *reg_beacon)
+{
+ unsigned int i;
+ struct ieee80211_supported_band *sband;
+
+ assert_cfg80211_lock();
+
+ if (!wiphy->bands[reg_beacon->chan.band])
+ return;
+
+ sband = wiphy->bands[reg_beacon->chan.band];
+
+ for (i = 0; i < sband->n_channels; i++)
+ handle_reg_beacon(wiphy, i, reg_beacon);
+}
+
+/*
+ * Called upon reg changes or a new wiphy is added
+ */
+static void wiphy_update_beacon_reg(struct wiphy *wiphy)
+{
+ unsigned int i;
+ struct ieee80211_supported_band *sband;
+ struct reg_beacon *reg_beacon;
+
+ assert_cfg80211_lock();
+
+ if (list_empty(®_beacon_list))
+ return;
+
+ list_for_each_entry(reg_beacon, ®_beacon_list, list) {
+ if (!wiphy->bands[reg_beacon->chan.band])
+ continue;
+ sband = wiphy->bands[reg_beacon->chan.band];
+ for (i = 0; i < sband->n_channels; i++)
+ handle_reg_beacon(wiphy, i, reg_beacon);
+ }
+}
+
+static bool reg_is_world_roaming(struct wiphy *wiphy)
+{
+ if (is_world_regdom(cfg80211_regdomain->alpha2) ||
+ (wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
+ return true;
+ if (last_request->initiator != REGDOM_SET_BY_COUNTRY_IE &&
+ wiphy->custom_regulatory)
+ return true;
+ return false;
+}
+
+/* Reap the advantages of previously found beacons */
+static void reg_process_beacons(struct wiphy *wiphy)
+{
+ if (!reg_is_world_roaming(wiphy))
+ return;
+ wiphy_update_beacon_reg(wiphy);
+}
+