]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/staging/rt2860/common/dfs.c
7b3890f631ea8e5873d79c7598b096e713b33ea0
[net-next-2.6.git] / drivers / staging / rt2860 / common / dfs.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27     Module Name:
28     ap_dfs.c
29
30     Abstract:
31     Support DFS function.
32
33     Revision History:
34     Who       When            What
35     --------  ----------      ----------------------------------------------
36 */
37
38 #include "../rt_config.h"
39
40 typedef struct _RADAR_DURATION_TABLE
41 {
42         ULONG RDDurRegion;
43         ULONG RadarSignalDuration;
44         ULONG Tolerance;
45 } RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
46
47
48
49 UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
50 {
51         {9, 250, 250, 250},             // CE
52 #ifdef DFS_FCC_BW40_FIX
53         {1, 250, 250, 250},             // FCC
54 #else
55         {4, 250, 250, 250},             // FCC
56 #endif
57         {4, 250, 250, 250},             // JAP
58         {15, 250, 250, 250},    // JAP_W53
59         {4, 250, 250, 250}              // JAP_W56
60 };
61
62 /*
63         ========================================================================
64
65         Routine Description:
66                 Bbp Radar detection routine
67
68         Arguments:
69                 pAd     Pointer to our adapter
70
71         Return Value:
72
73         ========================================================================
74 */
75 VOID BbpRadarDetectionStart(
76         IN PRTMP_ADAPTER pAd)
77 {
78         UINT8 RadarPeriod;
79
80         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
81         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
82         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
83         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
84         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
85         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
86
87 #ifdef MERGE_ARCH_TEAM
88         if ((pAd->CommonCfg.RadarDetect.RDDurRegion == JAP) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56))
89         {
90                 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
91                 pAd->CommonCfg.RadarDetect.RDDurRegion = JapRadarType(pAd);
92                 if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56)
93                 {
94                         pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
95                 }
96                 else if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53)
97                 {
98                         pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
99                 }
100         }
101 #endif // MERGE_ARCH_TEAM //
102
103         RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
104                         (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
105
106 #ifdef MERGE_ARCH_TEAM
107
108
109 #else // Original RT28xx source code.
110         RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
111         RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
112 #endif // MERGE_ARCH_TEAM //
113
114         RadarDetectionStart(pAd, 0, RadarPeriod);
115         return;
116 }
117
118 /*
119         ========================================================================
120
121         Routine Description:
122                 Bbp Radar detection routine
123
124         Arguments:
125                 pAd     Pointer to our adapter
126
127         Return Value:
128
129         ========================================================================
130 */
131 VOID BbpRadarDetectionStop(
132         IN PRTMP_ADAPTER pAd)
133 {
134         RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
135         RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
136
137         RadarDetectionStop(pAd);
138         return;
139 }
140
141 /*
142         ========================================================================
143
144         Routine Description:
145                 Radar detection routine
146
147         Arguments:
148                 pAd     Pointer to our adapter
149
150         Return Value:
151
152         ========================================================================
153 */
154 VOID RadarDetectionStart(
155         IN PRTMP_ADAPTER pAd,
156         IN BOOLEAN CTSProtect,
157         IN UINT8 CTSPeriod)
158 {
159         UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
160         UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
161
162         if (CTSProtect != 0)
163         {
164                 switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
165                 {
166                 case FCC:
167                 case JAP_W56:
168                         CtsProtect = 0x03;
169                         break;
170
171                 case JAP:
172                         {
173                                 UCHAR RDDurRegion;
174                                 RDDurRegion = JapRadarType(pAd);
175                                 if (RDDurRegion == JAP_W56)
176                                         CtsProtect = 0x03;
177                                 else
178                                         CtsProtect = 0x02;
179                                 break;
180                         }
181
182                 case CE:
183                 case JAP_W53:
184                 default:
185                         CtsProtect = 0x02;
186                         break;
187                 }
188         }
189         else
190                 CtsProtect = 0x01;
191
192
193         // send start-RD with CTS protection command to MCU
194         // highbyte [7]         reserve
195         // highbyte [6:5]       0x: stop Carrier/Radar detection
196         // highbyte [10]:       Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
197         // highbyte [4:0]       Radar/carrier detection duration. In 1ms.
198
199         // lowbyte [7:0]        Radar/carrier detection period, in 1ms.
200         AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
201         //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
202
203         return;
204 }
205
206 /*
207         ========================================================================
208
209         Routine Description:
210                 Radar detection routine
211
212         Arguments:
213                 pAd     Pointer to our adapter
214
215         Return Value:
216                 TRUE    Found radar signal
217                 FALSE   Not found radar signal
218
219         ========================================================================
220 */
221 VOID RadarDetectionStop(
222         IN PRTMP_ADAPTER        pAd)
223 {
224         DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
225         AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00);      // send start-RD with CTS protection command to MCU
226
227         return;
228 }
229
230 /*
231         ========================================================================
232
233         Routine Description:
234                 Radar channel check routine
235
236         Arguments:
237                 pAd     Pointer to our adapter
238
239         Return Value:
240                 TRUE    need to do radar detect
241                 FALSE   need not to do radar detect
242
243         ========================================================================
244 */
245 BOOLEAN RadarChannelCheck(
246         IN PRTMP_ADAPTER        pAd,
247         IN UCHAR                        Ch)
248 {
249         INT             i;
250         BOOLEAN result = FALSE;
251
252         for (i=0; i<pAd->ChannelListNum; i++)
253         {
254                 if (Ch == pAd->ChannelList[i].Channel)
255                 {
256                         result = pAd->ChannelList[i].DfsReq;
257                         break;
258                 }
259         }
260
261         return result;
262 }
263
264 ULONG JapRadarType(
265         IN PRTMP_ADAPTER pAd)
266 {
267         ULONG           i;
268         const UCHAR     Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
269
270         if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
271         {
272                 return pAd->CommonCfg.RadarDetect.RDDurRegion;
273         }
274
275         for (i=0; i<15; i++)
276         {
277                 if (pAd->CommonCfg.Channel == Channel[i])
278                 {
279                         break;
280                 }
281         }
282
283         if (i < 4)
284                 return JAP_W53;
285         else if (i < 15)
286                 return JAP_W56;
287         else
288                 return JAP; // W52
289
290 }
291
292 ULONG RTMPBbpReadRadarDuration(
293         IN PRTMP_ADAPTER        pAd)
294 {
295         UINT8 byteValue = 0;
296         ULONG result;
297
298         BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
299
300         result = 0;
301         switch (byteValue)
302         {
303         case 1: // radar signal detected by pulse mode.
304         case 2: // radar signal detected by width mode.
305                 result = RTMPReadRadarDuration(pAd);
306                 break;
307
308         case 0: // No radar signal.
309         default:
310
311                 result = 0;
312                 break;
313         }
314
315         return result;
316 }
317
318 ULONG RTMPReadRadarDuration(
319         IN PRTMP_ADAPTER        pAd)
320 {
321         ULONG result = 0;
322
323         return result;
324
325 }
326
327 VOID RTMPCleanRadarDuration(
328         IN PRTMP_ADAPTER        pAd)
329 {
330         return;
331 }
332
333 /*
334     ========================================================================
335     Routine Description:
336         Radar wave detection. The API should be invoke each second.
337
338     Arguments:
339         pAd         - Adapter pointer
340
341     Return Value:
342         None
343
344     ========================================================================
345 */
346 VOID ApRadarDetectPeriodic(
347         IN PRTMP_ADAPTER pAd)
348 {
349         INT     i;
350
351         pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
352
353         for (i=0; i<pAd->ChannelListNum; i++)
354         {
355                 if (pAd->ChannelList[i].RemainingTimeForUse > 0)
356                 {
357                         pAd->ChannelList[i].RemainingTimeForUse --;
358                         if ((pAd->Mlme.PeriodicRound%5) == 0)
359                         {
360                                 DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
361                         }
362                 }
363         }
364
365         //radar detect
366         if ((pAd->CommonCfg.Channel > 14)
367                 && (pAd->CommonCfg.bIEEE80211H == 1)
368                 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
369         {
370                 RadarDetectPeriodic(pAd);
371         }
372
373         return;
374 }
375
376 // Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
377 // Before switch channel, driver needs doing channel switch announcement.
378 VOID RadarDetectPeriodic(
379         IN PRTMP_ADAPTER        pAd)
380 {
381         // need to check channel availability, after switch channel
382         if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
383                         return;
384
385         // channel availability check time is 60sec, use 65 for assurance
386         if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
387         {
388                 DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
389                         BbpRadarDetectionStop(pAd);
390                 AsicEnableBssSync(pAd);
391                 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
392
393
394                 return;
395         }
396
397         return;
398 }
399
400
401 /*
402     ==========================================================================
403     Description:
404                 change channel moving time for DFS testing.
405
406         Arguments:
407             pAdapter                    Pointer to our adapter
408             wrq                         Pointer to the ioctl argument
409
410     Return Value:
411         None
412
413     Note:
414         Usage:
415                1.) iwpriv ra0 set ChMovTime=[value]
416     ==========================================================================
417 */
418 INT Set_ChMovingTime_Proc(
419         IN PRTMP_ADAPTER pAd,
420         IN PSTRING arg)
421 {
422         UINT8 Value;
423
424         Value = (UINT8) simple_strtol(arg, 0, 10);
425
426         pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
427
428         DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
429                 pAd->CommonCfg.RadarDetect.ChMovingTime));
430
431         return TRUE;
432 }
433
434 INT Set_LongPulseRadarTh_Proc(
435         IN PRTMP_ADAPTER pAd,
436         IN PSTRING arg)
437 {
438         UINT8 Value;
439
440         Value = (UINT8) simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
441
442         pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
443
444         DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
445                 pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
446
447         return TRUE;
448 }
449
450