First Support on Ginger and OMAP TI
[linux-ginger.git] / drivers / staging / rt3090 / common / dfs.c
blobc15704ae2f24c55cddc90a590c25974627668466
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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 *************************************************************************
27 Module Name:
28 ap_dfs.c
30 Abstract:
31 Support DFS function.
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
38 #include "../rt_config.h"
41 typedef struct _RADAR_DURATION_TABLE
43 ULONG RDDurRegion;
44 ULONG RadarSignalDuration;
45 ULONG Tolerance;
46 } RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
50 UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
52 {9, 250, 250, 250}, // CE
53 #ifdef DFS_FCC_BW40_FIX
54 {1, 250, 250, 250}, // FCC
55 #else
56 {4, 250, 250, 250}, // FCC
57 #endif
58 {4, 250, 250, 250}, // JAP
59 {15, 250, 250, 250}, // JAP_W53
60 {4, 250, 250, 250} // JAP_W56
63 #ifdef TONE_RADAR_DETECT_SUPPORT
64 static void ToneRadarProgram(PRTMP_ADAPTER pAd);
65 static void ToneRadarEnable(PRTMP_ADAPTER pAd);
66 #endif // TONE_RADAR_DETECT_SUPPORT //
68 #ifdef DFS_SUPPORT
70 ========================================================================
72 Routine Description:
73 Bbp Radar detection routine
75 Arguments:
76 pAd Pointer to our adapter
78 Return Value:
80 ========================================================================
82 VOID BbpRadarDetectionStart(
83 IN PRTMP_ADAPTER pAd)
85 UINT8 RadarPeriod;
87 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
88 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
89 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
90 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
91 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
92 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
94 #ifdef MERGE_ARCH_TEAM
95 if ((pAd->CommonCfg.RadarDetect.RDDurRegion == JAP) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56))
97 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
98 pAd->CommonCfg.RadarDetect.RDDurRegion = JapRadarType(pAd);
99 if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56)
101 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
103 else if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53)
105 pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
107 #ifdef CARRIER_DETECTION_SUPPORT
108 pAd->CommonCfg.CarrierDetect.Enable = 1;
109 #endif // CARRIER_DETECTION_SUPPORT //
111 #endif // MERGE_ARCH_TEAM //
113 RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
114 (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
116 #ifdef MERGE_ARCH_TEAM
119 #else // Original RT28xx source code.
120 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
121 RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
122 #endif // MERGE_ARCH_TEAM //
124 RadarDetectionStart(pAd, 0, RadarPeriod);
125 return;
129 ========================================================================
131 Routine Description:
132 Bbp Radar detection routine
134 Arguments:
135 pAd Pointer to our adapter
137 Return Value:
139 ========================================================================
141 VOID BbpRadarDetectionStop(
142 IN PRTMP_ADAPTER pAd)
144 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
145 RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
147 RadarDetectionStop(pAd);
148 return;
152 ========================================================================
154 Routine Description:
155 Radar detection routine
157 Arguments:
158 pAd Pointer to our adapter
160 Return Value:
162 ========================================================================
164 VOID RadarDetectionStart(
165 IN PRTMP_ADAPTER pAd,
166 IN BOOLEAN CTSProtect,
167 IN UINT8 CTSPeriod)
169 UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
170 UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
172 if (CTSProtect != 0)
174 switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
176 case FCC:
177 case JAP_W56:
178 CtsProtect = 0x03;
179 break;
181 case JAP:
183 UCHAR RDDurRegion;
184 RDDurRegion = JapRadarType(pAd);
185 if (RDDurRegion == JAP_W56)
186 CtsProtect = 0x03;
187 else
188 CtsProtect = 0x02;
189 break;
192 case CE:
193 case JAP_W53:
194 default:
195 CtsProtect = 0x02;
196 break;
199 else
200 CtsProtect = 0x01;
203 // send start-RD with CTS protection command to MCU
204 // highbyte [7] reserve
205 // highbyte [6:5] 0x: stop Carrier/Radar detection
206 // highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
207 // highbyte [4:0] Radar/carrier detection duration. In 1ms.
209 // lowbyte [7:0] Radar/carrier detection period, in 1ms.
210 AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
211 //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
213 return;
217 ========================================================================
219 Routine Description:
220 Radar detection routine
222 Arguments:
223 pAd Pointer to our adapter
225 Return Value:
226 TRUE Found radar signal
227 FALSE Not found radar signal
229 ========================================================================
231 VOID RadarDetectionStop(
232 IN PRTMP_ADAPTER pAd)
234 DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
235 AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
237 return;
239 #endif // DFS_SUPPORT //
243 ========================================================================
245 Routine Description:
246 Radar channel check routine
248 Arguments:
249 pAd Pointer to our adapter
251 Return Value:
252 TRUE need to do radar detect
253 FALSE need not to do radar detect
255 ========================================================================
257 BOOLEAN RadarChannelCheck(
258 IN PRTMP_ADAPTER pAd,
259 IN UCHAR Ch)
261 INT i;
262 BOOLEAN result = FALSE;
264 for (i=0; i<pAd->ChannelListNum; i++)
266 if (Ch == pAd->ChannelList[i].Channel)
268 result = pAd->ChannelList[i].DfsReq;
269 break;
273 return result;
276 #ifdef DFS_SUPPORT
278 ULONG JapRadarType(
279 IN PRTMP_ADAPTER pAd)
281 ULONG i;
282 const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
284 if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
286 return pAd->CommonCfg.RadarDetect.RDDurRegion;
289 for (i=0; i<15; i++)
291 if (pAd->CommonCfg.Channel == Channel[i])
293 break;
297 if (i < 4)
298 return JAP_W53;
299 else if (i < 15)
300 return JAP_W56;
301 else
302 return JAP; // W52
306 ULONG RTMPBbpReadRadarDuration(
307 IN PRTMP_ADAPTER pAd)
309 UINT8 byteValue = 0;
310 ULONG result;
312 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
314 result = 0;
315 switch (byteValue)
317 case 1: // radar signal detected by pulse mode.
318 case 2: // radar signal detected by width mode.
319 result = RTMPReadRadarDuration(pAd);
320 break;
322 case 0: // No radar signal.
323 default:
325 result = 0;
326 break;
329 return result;
332 ULONG RTMPReadRadarDuration(
333 IN PRTMP_ADAPTER pAd)
335 ULONG result = 0;
337 #ifdef DFS_SUPPORT
338 UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
341 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
342 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
343 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
344 result = (duration1 << 16) + (duration2 << 8) + duration3;
345 #endif // DFS_SUPPORT //
347 return result;
351 VOID RTMPCleanRadarDuration(
352 IN PRTMP_ADAPTER pAd)
354 return;
358 ========================================================================
359 Routine Description:
360 Radar wave detection. The API should be invoke each second.
362 Arguments:
363 pAd - Adapter pointer
365 Return Value:
366 None
368 ========================================================================
370 VOID ApRadarDetectPeriodic(
371 IN PRTMP_ADAPTER pAd)
373 INT i;
375 pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
377 for (i=0; i<pAd->ChannelListNum; i++)
380 if (pAd->ChannelList[i].RemainingTimeForUse > 0)
382 pAd->ChannelList[i].RemainingTimeForUse --;
383 if ((pAd->Mlme.PeriodicRound%5) == 0)
385 DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
390 //radar detect
391 if ((pAd->CommonCfg.Channel > 14)
392 && (pAd->CommonCfg.bIEEE80211H == 1)
393 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
395 RadarDetectPeriodic(pAd);
398 return;
401 // Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
402 // Before switch channel, driver needs doing channel switch announcement.
403 VOID RadarDetectPeriodic(
404 IN PRTMP_ADAPTER pAd)
407 // need to check channel availability, after switch channel
408 if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
409 return;
413 // channel availability check time is 60sec, use 65 for assurance
414 if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
416 DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
417 BbpRadarDetectionStop(pAd);
420 AsicEnableBssSync(pAd);
421 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
425 return;
428 return;
430 #endif // DFS_SUPPORT //
432 #ifdef DFS_SUPPORT
434 ==========================================================================
435 Description:
436 change channel moving time for DFS testing.
438 Arguments:
439 pAdapter Pointer to our adapter
440 wrq Pointer to the ioctl argument
442 Return Value:
443 None
445 Note:
446 Usage:
447 1.) iwpriv ra0 set ChMovTime=[value]
448 ==========================================================================
450 INT Set_ChMovingTime_Proc(
451 IN PRTMP_ADAPTER pAd,
452 IN PSTRING arg)
454 UINT8 Value;
456 Value = (UINT8) simple_strtol(arg, 0, 10);
458 pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
460 DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
461 pAd->CommonCfg.RadarDetect.ChMovingTime));
463 return TRUE;
466 INT Set_LongPulseRadarTh_Proc(
467 IN PRTMP_ADAPTER pAd,
468 IN PSTRING arg)
470 UINT8 Value;
472 Value = (UINT8) simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
474 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
476 DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
477 pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
479 return TRUE;
481 #endif // DFS_SUPPORT //