// SPDX-License-Identifier: GPL-2.0 /****************************************************************************** * * Copyright(c) 2009-2010 Realtek Corporation. * *****************************************************************************/ #include #include #include /* * REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags) */ /* * Only these channels all allow active * scan on all world regulatory domains */ /* 2G chan 01 - chan 11 */ #define RTW_2GHZ_CH01_11 \ REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0) /* * We enable active scan on these a case * by case basis by regulatory domain */ /* 2G chan 12 - chan 13, PASSIV SCAN */ #define RTW_2GHZ_CH12_13 \ REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20, \ NL80211_RRF_PASSIVE_SCAN) static const struct ieee80211_regdomain rtw_regdom_rd = { .n_reg_rules = 2, .alpha2 = "99", .reg_rules = { RTW_2GHZ_CH01_11, RTW_2GHZ_CH12_13, } }; static int rtw_ieee80211_channel_to_frequency(int chan, int band) { /* NL80211_BAND_2GHZ */ if (chan == 14) return 2484; else if (chan < 14) return 2407 + chan * 5; else return 0; /* not supported */ } static void _rtw_reg_apply_flags(struct wiphy *wiphy) { struct adapter *padapter = wiphy_to_adapter(wiphy); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct rt_channel_info *channel_set = pmlmeext->channel_set; u8 max_chan_nums = pmlmeext->max_chan_nums; struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; unsigned int i, j; u16 channel; u32 freq; /* all channels disable */ for (i = 0; i < NUM_NL80211_BANDS; i++) { sband = wiphy->bands[i]; if (sband) { for (j = 0; j < sband->n_channels; j++) { ch = &sband->channels[j]; if (ch) ch->flags = IEEE80211_CHAN_DISABLED; } } } /* channels apply by channel plans. */ for (i = 0; i < max_chan_nums; i++) { channel = channel_set[i].ChannelNum; freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ); ch = ieee80211_get_channel(wiphy, freq); if (ch) { if (channel_set[i].ScanType == SCAN_PASSIVE) ch->flags = IEEE80211_CHAN_NO_IR; else ch->flags = 0; } } } static int _rtw_reg_notifier_apply(struct wiphy *wiphy, struct regulatory_request *request, struct rtw_regulatory *reg) { /* Hard code flags */ _rtw_reg_apply_flags(wiphy); return 0; } static const struct ieee80211_regdomain *_rtw_regdomain_select(struct rtw_regulatory *reg) { return &rtw_regdom_rd; } static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy, void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request * request)) { const struct ieee80211_regdomain *regd; wiphy->reg_notifier = reg_notifier; wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; regd = _rtw_regdomain_select(reg); wiphy_apply_custom_regulatory(wiphy, regd); /* Hard code flags */ _rtw_reg_apply_flags(wiphy); } void rtw_regd_init(struct wiphy *wiphy, void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)) { _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier); } void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) { struct rtw_regulatory *reg = NULL; _rtw_reg_notifier_apply(wiphy, request, reg); }