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