at v3.13 218 lines 6.5 kB view raw
1/****************************************************************************** 2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. 3 * 4 * This program is distributed in the hope that it will be useful, but WITHOUT 5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 7 * more details. 8 * 9 * You should have received a copy of the GNU General Public License along with 10 * this program; if not, write to the Free Software Foundation, Inc., 11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 12 * 13 * The full GNU General Public License is included in this distribution in the 14 * file called LICENSE. 15 * 16 * Contact Information: 17 * wlanfae <wlanfae@realtek.com> 18******************************************************************************/ 19#include "dot11d.h" 20 21struct channel_list { 22 u8 Channel[32]; 23 u8 Len; 24}; 25 26static struct channel_list ChannelPlan[] = { 27 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 28 149, 153, 157, 161, 165}, 24}, 29 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, 30 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 31 60, 64}, 21}, 32 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 33 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 34 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 35 56, 60, 64}, 22}, 36 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 37 56, 60, 64}, 22}, 38 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 39 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 40 56, 60, 64}, 22}, 41 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 42 56, 60, 64}, 22}, 43 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, 44 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 45 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 46 56, 60, 64}, 21} 47}; 48 49void dot11d_init(struct rtllib_device *ieee) 50{ 51 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); 52 pDot11dInfo->bEnabled = false; 53 54 pDot11dInfo->State = DOT11D_STATE_NONE; 55 pDot11dInfo->CountryIeLen = 0; 56 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); 57 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); 58 RESET_CIE_WATCHDOG(ieee); 59 60} 61EXPORT_SYMBOL(dot11d_init); 62 63void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee) 64{ 65 int i, max_chan = 14, min_chan = 1; 66 67 ieee->bGlobalDomain = false; 68 69 if (ChannelPlan[channel_plan].Len != 0) { 70 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, 71 sizeof(GET_DOT11D_INFO(ieee)->channel_map)); 72 for (i = 0; i < ChannelPlan[channel_plan].Len; i++) { 73 if (ChannelPlan[channel_plan].Channel[i] < min_chan || 74 ChannelPlan[channel_plan].Channel[i] > max_chan) 75 break; 76 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan 77 [channel_plan].Channel[i]] = 1; 78 } 79 } 80 81 switch (channel_plan) { 82 case COUNTRY_CODE_GLOBAL_DOMAIN: 83 ieee->bGlobalDomain = true; 84 for (i = 12; i <= 14; i++) 85 GET_DOT11D_INFO(ieee)->channel_map[i] = 2; 86 ieee->IbssStartChnl = 10; 87 ieee->ibss_maxjoin_chal = 11; 88 break; 89 90 case COUNTRY_CODE_WORLD_WIDE_13: 91 for (i = 12; i <= 13; i++) 92 GET_DOT11D_INFO(ieee)->channel_map[i] = 2; 93 ieee->IbssStartChnl = 10; 94 ieee->ibss_maxjoin_chal = 11; 95 break; 96 97 default: 98 ieee->IbssStartChnl = 1; 99 ieee->ibss_maxjoin_chal = 14; 100 break; 101 } 102} 103EXPORT_SYMBOL(Dot11d_Channelmap); 104 105 106void Dot11d_Reset(struct rtllib_device *ieee) 107{ 108 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); 109 u32 i; 110 111 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); 112 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); 113 for (i = 1; i <= 11; i++) 114 (pDot11dInfo->channel_map)[i] = 1; 115 for (i = 12; i <= 14; i++) 116 (pDot11dInfo->channel_map)[i] = 2; 117 pDot11dInfo->State = DOT11D_STATE_NONE; 118 pDot11dInfo->CountryIeLen = 0; 119 RESET_CIE_WATCHDOG(ieee); 120} 121 122void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, 123 u16 CoutryIeLen, u8 *pCoutryIe) 124{ 125 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 126 u8 i, j, NumTriples, MaxChnlNum; 127 struct chnl_txpow_triple *pTriple; 128 129 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); 130 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); 131 MaxChnlNum = 0; 132 NumTriples = (CoutryIeLen - 3) / 3; 133 pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3); 134 for (i = 0; i < NumTriples; i++) { 135 if (MaxChnlNum >= pTriple->FirstChnl) { 136 printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid" 137 " country IE, skip it........1\n"); 138 return; 139 } 140 if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + 141 pTriple->NumChnls)) { 142 printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid " 143 "country IE, skip it........2\n"); 144 return; 145 } 146 147 for (j = 0 ; j < pTriple->NumChnls; j++) { 148 pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; 149 pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = 150 pTriple->MaxTxPowerInDbm; 151 MaxChnlNum = pTriple->FirstChnl + j; 152 } 153 154 pTriple = (struct chnl_txpow_triple *)((u8 *)pTriple + 3); 155 } 156 157 UPDATE_CIE_SRC(dev, pTaddr); 158 159 pDot11dInfo->CountryIeLen = CoutryIeLen; 160 memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen); 161 pDot11dInfo->State = DOT11D_STATE_LEARNED; 162} 163 164u8 DOT11D_GetMaxTxPwrInDbm(struct rtllib_device *dev, u8 Channel) 165{ 166 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 167 u8 MaxTxPwrInDbm = 255; 168 169 if (MAX_CHANNEL_NUMBER < Channel) { 170 printk(KERN_INFO "DOT11D_GetMaxTxPwrInDbm(): Invalid " 171 "Channel\n"); 172 return MaxTxPwrInDbm; 173 } 174 if (pDot11dInfo->channel_map[Channel]) 175 MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel]; 176 177 return MaxTxPwrInDbm; 178} 179 180void DOT11D_ScanComplete(struct rtllib_device *dev) 181{ 182 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 183 184 switch (pDot11dInfo->State) { 185 case DOT11D_STATE_LEARNED: 186 pDot11dInfo->State = DOT11D_STATE_DONE; 187 break; 188 case DOT11D_STATE_DONE: 189 Dot11d_Reset(dev); 190 break; 191 case DOT11D_STATE_NONE: 192 break; 193 } 194} 195 196int ToLegalChannel(struct rtllib_device *dev, u8 channel) 197{ 198 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 199 u8 default_chn = 0; 200 u32 i; 201 202 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) { 203 if (pDot11dInfo->channel_map[i] > 0) { 204 default_chn = i; 205 break; 206 } 207 } 208 209 if (MAX_CHANNEL_NUMBER < channel) { 210 printk(KERN_ERR "%s(): Invalid Channel\n", __func__); 211 return default_chn; 212 } 213 214 if (pDot11dInfo->channel_map[channel] > 0) 215 return channel; 216 217 return default_chn; 218}