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 * The full GNU General Public License is included in this distribution in the 10 * file called LICENSE. 11 * 12 * Contact Information: 13 * wlanfae <wlanfae@realtek.com> 14******************************************************************************/ 15#include "dot11d.h" 16 17struct channel_list { 18 u8 Channel[32]; 19 u8 Len; 20}; 21 22static struct channel_list ChannelPlan[] = { 23 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 24 149, 153, 157, 161, 165}, 24}, 25 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, 26 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 27 60, 64}, 21}, 28 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 29 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 30 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 31 56, 60, 64}, 22}, 32 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 33 56, 60, 64}, 22}, 34 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 35 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 36 56, 60, 64}, 22}, 37 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 38 56, 60, 64}, 22}, 39 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, 40 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 41 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 42 56, 60, 64}, 21} 43}; 44 45void dot11d_init(struct rtllib_device *ieee) 46{ 47 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); 48 49 pDot11dInfo->bEnabled = false; 50 51 pDot11dInfo->State = DOT11D_STATE_NONE; 52 pDot11dInfo->CountryIeLen = 0; 53 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); 54 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); 55 RESET_CIE_WATCHDOG(ieee); 56 57} 58EXPORT_SYMBOL(dot11d_init); 59 60void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee) 61{ 62 int i, max_chan = 14, min_chan = 1; 63 64 ieee->bGlobalDomain = false; 65 66 if (ChannelPlan[channel_plan].Len != 0) { 67 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, 68 sizeof(GET_DOT11D_INFO(ieee)->channel_map)); 69 for (i = 0; i < ChannelPlan[channel_plan].Len; i++) { 70 if (ChannelPlan[channel_plan].Channel[i] < min_chan || 71 ChannelPlan[channel_plan].Channel[i] > max_chan) 72 break; 73 GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan 74 [channel_plan].Channel[i]] = 1; 75 } 76 } 77 78 switch (channel_plan) { 79 case COUNTRY_CODE_GLOBAL_DOMAIN: 80 ieee->bGlobalDomain = true; 81 for (i = 12; i <= 14; i++) 82 GET_DOT11D_INFO(ieee)->channel_map[i] = 2; 83 ieee->IbssStartChnl = 10; 84 ieee->ibss_maxjoin_chal = 11; 85 break; 86 87 case COUNTRY_CODE_WORLD_WIDE_13: 88 for (i = 12; i <= 13; i++) 89 GET_DOT11D_INFO(ieee)->channel_map[i] = 2; 90 ieee->IbssStartChnl = 10; 91 ieee->ibss_maxjoin_chal = 11; 92 break; 93 94 default: 95 ieee->IbssStartChnl = 1; 96 ieee->ibss_maxjoin_chal = 14; 97 break; 98 } 99} 100EXPORT_SYMBOL(Dot11d_Channelmap); 101 102 103void Dot11d_Reset(struct rtllib_device *ieee) 104{ 105 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); 106 u32 i; 107 108 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); 109 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); 110 for (i = 1; i <= 11; i++) 111 (pDot11dInfo->channel_map)[i] = 1; 112 for (i = 12; i <= 14; i++) 113 (pDot11dInfo->channel_map)[i] = 2; 114 pDot11dInfo->State = DOT11D_STATE_NONE; 115 pDot11dInfo->CountryIeLen = 0; 116 RESET_CIE_WATCHDOG(ieee); 117} 118 119void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, 120 u16 CoutryIeLen, u8 *pCoutryIe) 121{ 122 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 123 u8 i, j, NumTriples, MaxChnlNum; 124 struct chnl_txpow_triple *pTriple; 125 126 memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); 127 memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); 128 MaxChnlNum = 0; 129 NumTriples = (CoutryIeLen - 3) / 3; 130 pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3); 131 for (i = 0; i < NumTriples; i++) { 132 if (MaxChnlNum >= pTriple->FirstChnl) { 133 netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); 134 return; 135 } 136 if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + 137 pTriple->NumChnls)) { 138 netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n"); 139 return; 140 } 141 142 for (j = 0; j < pTriple->NumChnls; j++) { 143 pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; 144 pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = 145 pTriple->MaxTxPowerInDbm; 146 MaxChnlNum = pTriple->FirstChnl + j; 147 } 148 149 pTriple = (struct chnl_txpow_triple *)((u8 *)pTriple + 3); 150 } 151 152 UPDATE_CIE_SRC(dev, pTaddr); 153 154 pDot11dInfo->CountryIeLen = CoutryIeLen; 155 memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen); 156 pDot11dInfo->State = DOT11D_STATE_LEARNED; 157} 158 159void DOT11D_ScanComplete(struct rtllib_device *dev) 160{ 161 struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); 162 163 switch (pDot11dInfo->State) { 164 case DOT11D_STATE_LEARNED: 165 pDot11dInfo->State = DOT11D_STATE_DONE; 166 break; 167 case DOT11D_STATE_DONE: 168 Dot11d_Reset(dev); 169 break; 170 case DOT11D_STATE_NONE: 171 break; 172 } 173} 174