1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2009-2010 Realtek Corporation. 5 * 6 *****************************************************************************/ 7 8 #include <drv_types.h> 9 #include <rtw_debug.h> 10 11 #include <rtw_wifi_regd.h> 12 13 /* 14 * REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags) 15 */ 16 17 /* 18 * Only these channels all allow active 19 * scan on all world regulatory domains 20 */ 21 22 /* 2G chan 01 - chan 11 */ 23 #define RTW_2GHZ_CH01_11 \ 24 REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0) 25 26 /* 27 * We enable active scan on these a case 28 * by case basis by regulatory domain 29 */ 30 31 /* 2G chan 12 - chan 13, PASSIV SCAN */ 32 #define RTW_2GHZ_CH12_13 \ 33 REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20, \ 34 NL80211_RRF_PASSIVE_SCAN) 35 36 /* 2G chan 14, PASSIVS SCAN, NO OFDM (B only) */ 37 #define RTW_2GHZ_CH14 \ 38 REG_RULE(2484 - 10, 2484 + 10, 40, 0, 20, \ 39 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) 40 41 static const struct ieee80211_regdomain rtw_regdom_rd = { 42 .n_reg_rules = 3, 43 .alpha2 = "99", 44 .reg_rules = { 45 RTW_2GHZ_CH01_11, 46 RTW_2GHZ_CH12_13, 47 } 48 }; 49 50 static int rtw_ieee80211_channel_to_frequency(int chan, int band) 51 { 52 /* see 802.11 17.3.8.3.2 and Annex J 53 * there are overlapping channel numbers in 5GHz and 2GHz bands 54 */ 55 56 /* NL80211_BAND_2GHZ */ 57 if (chan == 14) 58 return 2484; 59 else if (chan < 14) 60 return 2407 + chan * 5; 61 else 62 return 0; /* not supported */ 63 } 64 65 static void _rtw_reg_apply_flags(struct wiphy *wiphy) 66 { 67 struct adapter *padapter = wiphy_to_adapter(wiphy); 68 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 69 RT_CHANNEL_INFO *channel_set = pmlmeext->channel_set; 70 u8 max_chan_nums = pmlmeext->max_chan_nums; 71 72 struct ieee80211_supported_band *sband; 73 struct ieee80211_channel *ch; 74 unsigned int i, j; 75 u16 channel; 76 u32 freq; 77 78 /* all channels disable */ 79 for (i = 0; i < NUM_NL80211_BANDS; i++) { 80 sband = wiphy->bands[i]; 81 82 if (sband) { 83 for (j = 0; j < sband->n_channels; j++) { 84 ch = &sband->channels[j]; 85 86 if (ch) 87 ch->flags = IEEE80211_CHAN_DISABLED; 88 } 89 } 90 } 91 92 /* channels apply by channel plans. */ 93 for (i = 0; i < max_chan_nums; i++) { 94 channel = channel_set[i].ChannelNum; 95 freq = 96 rtw_ieee80211_channel_to_frequency(channel, 97 NL80211_BAND_2GHZ); 98 99 ch = ieee80211_get_channel(wiphy, freq); 100 if (ch) { 101 if (channel_set[i].ScanType == SCAN_PASSIVE) 102 ch->flags = IEEE80211_CHAN_NO_IR; 103 else 104 ch->flags = 0; 105 } 106 } 107 } 108 109 static int _rtw_reg_notifier_apply(struct wiphy *wiphy, 110 struct regulatory_request *request, 111 struct rtw_regulatory *reg) 112 { 113 /* Hard code flags */ 114 _rtw_reg_apply_flags(wiphy); 115 return 0; 116 } 117 118 static const struct ieee80211_regdomain *_rtw_regdomain_select(struct 119 rtw_regulatory 120 *reg) 121 { 122 return &rtw_regdom_rd; 123 } 124 125 static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, 126 struct wiphy *wiphy, 127 void (*reg_notifier)(struct wiphy *wiphy, 128 struct 129 regulatory_request * 130 request)) 131 { 132 const struct ieee80211_regdomain *regd; 133 134 wiphy->reg_notifier = reg_notifier; 135 136 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 137 wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; 138 wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; 139 140 regd = _rtw_regdomain_select(reg); 141 wiphy_apply_custom_regulatory(wiphy, regd); 142 143 /* Hard code flags */ 144 _rtw_reg_apply_flags(wiphy); 145 } 146 147 int rtw_regd_init(struct adapter *padapter, 148 void (*reg_notifier)(struct wiphy *wiphy, 149 struct regulatory_request *request)) 150 { 151 struct wiphy *wiphy = padapter->rtw_wdev->wiphy; 152 153 _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier); 154 155 return 0; 156 } 157 158 void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) 159 { 160 struct rtw_regulatory *reg = NULL; 161 162 DBG_8192C("%s\n", __func__); 163 164 _rtw_reg_notifier_apply(wiphy, request, reg); 165 } 166