at v3.2 216 lines 6.4 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} 61 62void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee) 63{ 64 int i, max_chan = 14, min_chan = 1; 65 66 ieee->bGlobalDomain = false; 67 68 if (ChannelPlan[channel_plan].Len != 0) { 69 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, 70 sizeof(GET_DOT11D_INFO(ieee)->channel_map)); 71 for (i = 0; i < ChannelPlan[channel_plan].Len; i++) { 72 if (ChannelPlan[channel_plan].Channel[i] < min_chan || 73 ChannelPlan[channel_plan].Channel[i] > max_chan) 74 break; 75 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan 76 [channel_plan].Channel[i]] = 1; 77 } 78 } 79 80 switch (channel_plan) { 81 case COUNTRY_CODE_GLOBAL_DOMAIN: 82 ieee->bGlobalDomain = true; 83 for (i = 12; i <= 14; i++) 84 GET_DOT11D_INFO(ieee)->channel_map[i] = 2; 85 ieee->IbssStartChnl = 10; 86 ieee->ibss_maxjoin_chal = 11; 87 break; 88 89 case COUNTRY_CODE_WORLD_WIDE_13: 90 for (i = 12; i <= 13; i++) 91 GET_DOT11D_INFO(ieee)->channel_map[i] = 2; 92 ieee->IbssStartChnl = 10; 93 ieee->ibss_maxjoin_chal = 11; 94 break; 95 96 default: 97 ieee->IbssStartChnl = 1; 98 ieee->ibss_maxjoin_chal = 14; 99 break; 100 } 101} 102 103 104void Dot11d_Reset(struct rtllib_device *ieee) 105{ 106 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); 107 u32 i; 108 109 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); 110 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); 111 for (i = 1; i <= 11; i++) 112 (pDot11dInfo->channel_map)[i] = 1; 113 for (i = 12; i <= 14; i++) 114 (pDot11dInfo->channel_map)[i] = 2; 115 pDot11dInfo->State = DOT11D_STATE_NONE; 116 pDot11dInfo->CountryIeLen = 0; 117 RESET_CIE_WATCHDOG(ieee); 118} 119 120void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, 121 u16 CoutryIeLen, u8 *pCoutryIe) 122{ 123 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 124 u8 i, j, NumTriples, MaxChnlNum; 125 struct chnl_txpow_triple *pTriple; 126 127 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); 128 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); 129 MaxChnlNum = 0; 130 NumTriples = (CoutryIeLen - 3) / 3; 131 pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3); 132 for (i = 0; i < NumTriples; i++) { 133 if (MaxChnlNum >= pTriple->FirstChnl) { 134 printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid" 135 " country IE, skip it........1\n"); 136 return; 137 } 138 if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + 139 pTriple->NumChnls)) { 140 printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid " 141 "country IE, skip it........2\n"); 142 return; 143 } 144 145 for (j = 0 ; j < pTriple->NumChnls; j++) { 146 pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; 147 pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = 148 pTriple->MaxTxPowerInDbm; 149 MaxChnlNum = pTriple->FirstChnl + j; 150 } 151 152 pTriple = (struct chnl_txpow_triple *)((u8*)pTriple + 3); 153 } 154 155 UPDATE_CIE_SRC(dev, pTaddr); 156 157 pDot11dInfo->CountryIeLen = CoutryIeLen; 158 memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen); 159 pDot11dInfo->State = DOT11D_STATE_LEARNED; 160} 161 162u8 DOT11D_GetMaxTxPwrInDbm(struct rtllib_device *dev, u8 Channel) 163{ 164 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 165 u8 MaxTxPwrInDbm = 255; 166 167 if (MAX_CHANNEL_NUMBER < Channel) { 168 printk(KERN_INFO "DOT11D_GetMaxTxPwrInDbm(): Invalid " 169 "Channel\n"); 170 return MaxTxPwrInDbm; 171 } 172 if (pDot11dInfo->channel_map[Channel]) 173 MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel]; 174 175 return MaxTxPwrInDbm; 176} 177 178void DOT11D_ScanComplete(struct rtllib_device *dev) 179{ 180 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 181 182 switch (pDot11dInfo->State) { 183 case DOT11D_STATE_LEARNED: 184 pDot11dInfo->State = DOT11D_STATE_DONE; 185 break; 186 case DOT11D_STATE_DONE: 187 Dot11d_Reset(dev); 188 break; 189 case DOT11D_STATE_NONE: 190 break; 191 } 192} 193 194int ToLegalChannel(struct rtllib_device *dev, u8 channel) 195{ 196 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 197 u8 default_chn = 0; 198 u32 i; 199 200 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) { 201 if (pDot11dInfo->channel_map[i] > 0) { 202 default_chn = i; 203 break; 204 } 205 } 206 207 if (MAX_CHANNEL_NUMBER < channel) { 208 printk(KERN_ERR "%s(): Invalid Channel\n", __func__); 209 return default_chn; 210 } 211 212 if (pDot11dInfo->channel_map[channel] > 0) 213 return channel; 214 215 return default_chn; 216}