Merge commit 'v2.6.29' into timers/core
[linux-2.6] / drivers / staging / rtl8187se / ieee80211 / dot11d.c
1 #ifdef ENABLE_DOT11D\r
2 //-----------------------------------------------------------------------------\r
3 //      File:\r
4 //              Dot11d.c\r
5 //\r
6 //      Description:\r
7 //              Implement 802.11d. \r
8 //\r
9 //-----------------------------------------------------------------------------\r
10 \r
11 #include "dot11d.h"\r
12 \r
13 void\r
14 Dot11d_Init(struct ieee80211_device *ieee)\r
15 {\r
16         PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);\r
17 \r
18         pDot11dInfo->bEnabled = 0;\r
19 \r
20         pDot11dInfo->State = DOT11D_STATE_NONE;\r
21         pDot11dInfo->CountryIeLen = 0;\r
22         memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);  \r
23         memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);\r
24         RESET_CIE_WATCHDOG(ieee);\r
25 \r
26         printk("Dot11d_Init()\n");\r
27 }\r
28 \r
29 //\r
30 //      Description:\r
31 //              Reset to the state as we are just entering a regulatory domain.\r
32 //\r
33 void\r
34 Dot11d_Reset(struct ieee80211_device *ieee)\r
35 {\r
36         u32 i;\r
37         PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);\r
38 \r
39         // Clear old channel map\r
40         memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);\r
41         memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);\r
42         // Set new channel map\r
43         for (i=1; i<=11; i++) {\r
44                 (pDot11dInfo->channel_map)[i] = 1;\r
45         }\r
46         for (i=12; i<=14; i++) {\r
47                 (pDot11dInfo->channel_map)[i] = 2;\r
48         }\r
49 \r
50         pDot11dInfo->State = DOT11D_STATE_NONE;\r
51         pDot11dInfo->CountryIeLen = 0;\r
52         RESET_CIE_WATCHDOG(ieee);\r
53 \r
54         //printk("Dot11d_Reset()\n");\r
55 }\r
56 \r
57 //\r
58 //      Description:\r
59 //              Update country IE from Beacon or Probe Resopnse \r
60 //              and configure PHY for operation in the regulatory domain.\r
61 //\r
62 //      TODO: \r
63 //              Configure Tx power.\r
64 //\r
65 //      Assumption:\r
66 //              1. IS_DOT11D_ENABLE() is TRUE.\r
67 //              2. Input IE is an valid one.\r
68 //\r
69 void\r
70 Dot11d_UpdateCountryIe(\r
71         struct ieee80211_device *dev,\r
72         u8 *            pTaddr,\r
73         u16     CoutryIeLen,\r
74         u8 * pCoutryIe   \r
75         )\r
76 {\r
77         PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);\r
78         u8 i, j, NumTriples, MaxChnlNum;\r
79         PCHNL_TXPOWER_TRIPLE pTriple;\r
80 \r
81         if((CoutryIeLen - 3)%3 != 0)\r
82         {\r
83                 printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");\r
84                 Dot11d_Reset(dev);\r
85                 return;\r
86         }\r
87 \r
88         memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);\r
89         memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);\r
90         MaxChnlNum = 0;\r
91         NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.\r
92         pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);\r
93         for(i = 0; i < NumTriples; i++)\r
94         {\r
95                 if(MaxChnlNum >= pTriple->FirstChnl)\r
96                 { // It is not in a monotonically increasing order, so stop processing.\r
97                         printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");\r
98                         Dot11d_Reset(dev);\r
99                         return; \r
100                 }\r
101                 if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))\r
102                 { // It is not a valid set of channel id, so stop processing.\r
103                         printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");\r
104                         Dot11d_Reset(dev);\r
105                         return; \r
106                 }\r
107 \r
108                 for(j = 0 ; j < pTriple->NumChnls; j++)\r
109                 {\r
110                         pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;\r
111                         pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;\r
112                         MaxChnlNum = pTriple->FirstChnl + j;\r
113                 }       \r
114 \r
115                 pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);\r
116         }\r
117 #if 1\r
118         //printk("Dot11d_UpdateCountryIe(): Channel List:\n");\r
119         printk("Channel List:");\r
120         for(i=1; i<= MAX_CHANNEL_NUMBER; i++)\r
121                 if(pDot11dInfo->channel_map[i] > 0)\r
122                         printk(" %d", i);\r
123         printk("\n");\r
124 #endif\r
125 \r
126         UPDATE_CIE_SRC(dev, pTaddr);\r
127 \r
128         pDot11dInfo->CountryIeLen = CoutryIeLen;\r
129         memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);\r
130         pDot11dInfo->State = DOT11D_STATE_LEARNED;\r
131 }\r
132 \r
133 void dump_chnl_map(u8 * channel_map)\r
134 {\r
135         int i;\r
136         printk("Channel List:");\r
137         for(i=1; i<= MAX_CHANNEL_NUMBER; i++)\r
138                 if(channel_map[i] > 0)\r
139                         printk(" %d(%d)", i, channel_map[i]);\r
140         printk("\n");\r
141 }\r
142 \r
143 u8\r
144 DOT11D_GetMaxTxPwrInDbm(\r
145         struct ieee80211_device *dev,\r
146         u8 Channel\r
147         )\r
148 {\r
149         PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);\r
150         u8 MaxTxPwrInDbm = 255;\r
151 \r
152         if(MAX_CHANNEL_NUMBER < Channel)\r
153         { \r
154                 printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");\r
155                 return MaxTxPwrInDbm; \r
156         }\r
157         if(pDot11dInfo->channel_map[Channel])\r
158         {\r
159                 MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];  \r
160         }\r
161 \r
162         return MaxTxPwrInDbm;\r
163 }\r
164 \r
165 \r
166 void\r
167 DOT11D_ScanComplete(\r
168         struct ieee80211_device * dev\r
169         )\r
170 {\r
171         PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);\r
172 \r
173         switch(pDot11dInfo->State)\r
174         {\r
175         case DOT11D_STATE_LEARNED:\r
176                 pDot11dInfo->State = DOT11D_STATE_DONE;\r
177                 break;\r
178 \r
179         case DOT11D_STATE_DONE:\r
180                 if( GET_CIE_WATCHDOG(dev) == 0 )\r
181                 { // Reset country IE if previous one is gone. \r
182                         Dot11d_Reset(dev); \r
183                 }\r
184                 break;\r
185         case DOT11D_STATE_NONE:\r
186                 break;\r
187         }\r
188 }\r
189 \r
190 int IsLegalChannel(\r
191         struct ieee80211_device * dev,\r
192         u8 channel\r
193 )\r
194 {\r
195         PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);\r
196 \r
197         if(MAX_CHANNEL_NUMBER < channel)\r
198         { \r
199                 printk("IsLegalChannel(): Invalid Channel\n");\r
200                 return 0; \r
201         }\r
202         if(pDot11dInfo->channel_map[channel] > 0)\r
203                 return 1;\r
204         return 0;\r
205 }\r
206 \r
207 int ToLegalChannel(\r
208         struct ieee80211_device * dev,\r
209         u8 channel\r
210 )\r
211 {\r
212         PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);\r
213         u8 default_chn = 0;\r
214         u32 i = 0;\r
215 \r
216         for (i=1; i<= MAX_CHANNEL_NUMBER; i++)\r
217         {\r
218                 if(pDot11dInfo->channel_map[i] > 0)\r
219                 {\r
220                         default_chn = i;\r
221                         break;\r
222                 }\r
223         }\r
224 \r
225         if(MAX_CHANNEL_NUMBER < channel)\r
226         { \r
227                 printk("IsLegalChannel(): Invalid Channel\n");\r
228                 return default_chn; \r
229         }\r
230         \r
231         if(pDot11dInfo->channel_map[channel] > 0)\r
232                 return channel;\r
233         \r
234         return default_chn;\r
235 }\r
236 \r
237 #if 0\r
238 EXPORT_SYMBOL(Dot11d_Init);\r
239 EXPORT_SYMBOL(Dot11d_Reset);\r
240 EXPORT_SYMBOL(Dot11d_UpdateCountryIe);\r
241 EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);\r
242 EXPORT_SYMBOL(DOT11D_ScanComplete);\r
243 EXPORT_SYMBOL(IsLegalChannel);\r
244 EXPORT_SYMBOL(ToLegalChannel);\r
245 #endif\r
246 #endif\r