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 static const struct ieee80211_regdomain rtw_regdom_rd = { 37 .n_reg_rules = 3, 38 .alpha2 = "99", 39 .reg_rules = { 40 RTW_2GHZ_CH01_11, 41 RTW_2GHZ_CH12_13, 42 } 43 }; 44 45 static int rtw_ieee80211_channel_to_frequency(int chan, int band) 46 { 47 /* see 802.11 17.3.8.3.2 and Annex J 48 * there are overlapping channel numbers in 5GHz and 2GHz bands 49 */ 50 51 /* NL80211_BAND_2GHZ */ 52 if (chan == 14) 53 return 2484; 54 else if (chan < 14) 55 return 2407 + chan * 5; 56 else 57 return 0; /* not supported */ 58 } 59 60 static void _rtw_reg_apply_flags(struct wiphy *wiphy) 61 { 62 struct adapter *padapter = wiphy_to_adapter(wiphy); 63 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 64 RT_CHANNEL_INFO *channel_set = pmlmeext->channel_set; 65 u8 max_chan_nums = pmlmeext->max_chan_nums; 66 67 struct ieee80211_supported_band *sband; 68 struct ieee80211_channel *ch; 69 unsigned int i, j; 70 u16 channel; 71 u32 freq; 72 73 /* all channels disable */ 74 for (i = 0; i < NUM_NL80211_BANDS; i++) { 75 sband = wiphy->bands[i]; 76 77 if (sband) { 78 for (j = 0; j < sband->n_channels; j++) { 79 ch = &sband->channels[j]; 80 81 if (ch) 82 ch->flags = IEEE80211_CHAN_DISABLED; 83 } 84 } 85 } 86 87 /* channels apply by channel plans. */ 88 for (i = 0; i < max_chan_nums; i++) { 89 channel = channel_set[i].ChannelNum; 90 freq = 91 rtw_ieee80211_channel_to_frequency(channel, 92 NL80211_BAND_2GHZ); 93 94 ch = ieee80211_get_channel(wiphy, freq); 95 if (ch) { 96 if (channel_set[i].ScanType == SCAN_PASSIVE) 97 ch->flags = IEEE80211_CHAN_NO_IR; 98 else 99 ch->flags = 0; 100 } 101 } 102 } 103 104 static int _rtw_reg_notifier_apply(struct wiphy *wiphy, 105 struct regulatory_request *request, 106 struct rtw_regulatory *reg) 107 { 108 /* Hard code flags */ 109 _rtw_reg_apply_flags(wiphy); 110 return 0; 111 } 112 113 static const struct ieee80211_regdomain *_rtw_regdomain_select(struct 114 rtw_regulatory 115 *reg) 116 { 117 return &rtw_regdom_rd; 118 } 119 120 static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, 121 struct wiphy *wiphy, 122 void (*reg_notifier)(struct wiphy *wiphy, 123 struct 124 regulatory_request * 125 request)) 126 { 127 const struct ieee80211_regdomain *regd; 128 129 wiphy->reg_notifier = reg_notifier; 130 131 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 132 wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; 133 wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; 134 135 regd = _rtw_regdomain_select(reg); 136 wiphy_apply_custom_regulatory(wiphy, regd); 137 138 /* Hard code flags */ 139 _rtw_reg_apply_flags(wiphy); 140 } 141 142 int rtw_regd_init(struct adapter *padapter, 143 void (*reg_notifier)(struct wiphy *wiphy, 144 struct regulatory_request *request)) 145 { 146 struct wiphy *wiphy = padapter->rtw_wdev->wiphy; 147 148 _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier); 149 150 return 0; 151 } 152 153 void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) 154 { 155 struct rtw_regulatory *reg = NULL; 156 157 DBG_8192C("%s\n", __func__); 158 159 _rtw_reg_notifier_apply(wiphy, request, reg); 160 } 161