/* *Always apply Radar/DFS rules on *freq range 5260 MHz - 5700 MHz */ static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; unsigned int i; if (!wiphy->bands[IEEE80211_BAND_5GHZ]) return; sband = wiphy->bands[IEEE80211_BAND_5GHZ]; for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; if (!_rtl_is_radar_freq(ch->center_freq)) continue; /* *We always enable radar detection/DFS on this *frequency range. Additionally we also apply on *this frequency range: *- If STA mode does not yet have DFS supports disable * active scanning *- If adhoc mode does not support DFS yet then disable * adhoc in the frequency. *- If AP mode does not yet support radar detection/DFS *do not allow AP mode */ if (!(ch->flags & IEEE80211_CHAN_DISABLED)) ch->flags |= IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN; } }
static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, enum nl80211_reg_initiator initiator) { enum ieee80211_band band; struct ieee80211_supported_band *sband; const struct ieee80211_reg_rule *reg_rule; struct ieee80211_channel *ch; #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) u32 bandwidth = 0; int r; #endif unsigned int i; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { if (!wiphy->bands[band]) continue; sband = wiphy->bands[band]; for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; if (_rtl_is_radar_freq(ch->center_freq) || (ch->flags & IEEE80211_CHAN_RADAR)) continue; if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) reg_rule = freq_reg_info(wiphy, ch->center_freq); if (IS_ERR(reg_rule)) continue; #else r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); if (r) continue; #endif /* *If 11d had a rule for this channel ensure *we enable adhoc/beaconing if it allows us to *use it. Note that we would have disabled it *by applying our static world regdomain by *default during init, prior to calling our *regulatory_hint(). */ if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) ch->flags &= ~IEEE80211_CHAN_NO_IBSS; if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; } else { if (ch->beacon_found) ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN); } } } }
static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, enum nl80211_reg_initiator initiator) { enum ieee80211_band band; struct ieee80211_supported_band *sband; const struct ieee80211_reg_rule *reg_rule; struct ieee80211_channel *ch; unsigned int i; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { if (!wiphy->bands[band]) continue; sband = wiphy->bands[band]; for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; if (_rtl_is_radar_freq(ch->center_freq) || (ch->flags & IEEE80211_CHAN_RADAR)) continue; if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq)); if (IS_ERR(reg_rule)) continue; /* *If 11d had a rule for this channel ensure *we enable adhoc/beaconing if it allows us to *use it. Note that we would have disabled it *by applying our static world regdomain by *default during init, prior to calling our *regulatory_hint(). */ if (!(reg_rule->flags & NL80211_RRF_NO_IR)) ch->flags &= ~IEEE80211_CHAN_NO_IR; } else { if (ch->beacon_found) ch->flags &= ~IEEE80211_CHAN_NO_IR; } } } }
/* Allows active scan scan on Ch 12 and 13 */ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, enum nl80211_reg_initiator initiator) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; const struct ieee80211_reg_rule *reg_rule; #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) u32 bandwidth = 0; int r; #endif if (!wiphy->bands[IEEE80211_BAND_2GHZ]) return; sband = wiphy->bands[IEEE80211_BAND_2GHZ]; /* *If no country IE has been received always enable active scan *on these channels. This is only done for specific regulatory SKUs */ if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { ch = &sband->channels[11]; /* CH 12 */ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; ch = &sband->channels[12]; /* CH 13 */ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; return; } /* *If a country IE has been recieved check its rule for this *channel first before enabling active scan. The passive scan *would have been enforced by the initial processing of our *custom regulatory domain. */ ch = &sband->channels[11]; /* CH 12 */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) reg_rule = freq_reg_info(wiphy, ch->center_freq); if (!IS_ERR(reg_rule)) { #else r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); if (!r) { #endif if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; } ch = &sband->channels[12]; /* CH 13 */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) reg_rule = freq_reg_info(wiphy, ch->center_freq); if (!IS_ERR(reg_rule)) { #else r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule); if (!r) { #endif if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; } } /* *Always apply Radar/DFS rules on *freq range 5260 MHz - 5700 MHz */ static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; unsigned int i; if (!wiphy->bands[IEEE80211_BAND_5GHZ]) return; sband = wiphy->bands[IEEE80211_BAND_5GHZ]; for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; if (!_rtl_is_radar_freq(ch->center_freq)) continue; /* *We always enable radar detection/DFS on this *frequency range. Additionally we also apply on *this frequency range: *- If STA mode does not yet have DFS supports disable * active scanning *- If adhoc mode does not support DFS yet then disable * adhoc in the frequency. *- If AP mode does not yet support radar detection/DFS *do not allow AP mode */ if (!(ch->flags & IEEE80211_CHAN_DISABLED)) ch->flags |= IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN; } } static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, enum nl80211_reg_initiator initiator, struct rtl_regulatory *reg) { _rtl_reg_apply_beaconing_flags(wiphy, initiator); _rtl_reg_apply_active_scan_flags(wiphy, initiator); return; }