staging: __FUNCTION__ is gcc-specific, use __func__
[deliverable/linux.git] / drivers / staging / rt2870 / 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 Fonchi 03-12-2007 created
37 */
38
39 #include "../rt_config.h"
40
41 typedef struct _RADAR_DURATION_TABLE
42 {
43 ULONG RDDurRegion;
44 ULONG RadarSignalDuration;
45 ULONG Tolerance;
46 } RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
47
48
49 static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
50 {
51 {9, 250, 250, 250}, // CE
52 {4, 250, 250, 250}, // FCC
53 {4, 250, 250, 250}, // JAP
54 {15, 250, 250, 250}, // JAP_W53
55 {4, 250, 250, 250} // JAP_W56
56 };
57
58 /*
59 ========================================================================
60
61 Routine Description:
62 Bbp Radar detection routine
63
64 Arguments:
65 pAd Pointer to our adapter
66
67 Return Value:
68
69 ========================================================================
70 */
71 VOID BbpRadarDetectionStart(
72 IN PRTMP_ADAPTER pAd)
73 {
74 UINT8 RadarPeriod;
75
76 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
77 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
78 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
79 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
80 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
81 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
82
83 #if 0
84 // toggle Rx enable bit for radar detection.
85 // it's Andy's recommand.
86 {
87 UINT32 Value;
88 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
89 Value |= (0x1 << 3);
90 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
91 Value &= ~(0x1 << 3);
92 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
93 }
94 #endif
95 RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
96 (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
97
98 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
99 RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
100
101 RadarDetectionStart(pAd, 0, RadarPeriod);
102 return;
103 }
104
105 /*
106 ========================================================================
107
108 Routine Description:
109 Bbp Radar detection routine
110
111 Arguments:
112 pAd Pointer to our adapter
113
114 Return Value:
115
116 ========================================================================
117 */
118 VOID BbpRadarDetectionStop(
119 IN PRTMP_ADAPTER pAd)
120 {
121 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
122 RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
123
124 RadarDetectionStop(pAd);
125 return;
126 }
127
128 /*
129 ========================================================================
130
131 Routine Description:
132 Radar detection routine
133
134 Arguments:
135 pAd Pointer to our adapter
136
137 Return Value:
138
139 ========================================================================
140 */
141 VOID RadarDetectionStart(
142 IN PRTMP_ADAPTER pAd,
143 IN BOOLEAN CTSProtect,
144 IN UINT8 CTSPeriod)
145 {
146 UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
147 UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
148
149 if (CTSProtect != 0)
150 {
151 switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
152 {
153 case FCC:
154 case JAP_W56:
155 CtsProtect = 0x03;
156 break;
157
158 case CE:
159 case JAP_W53:
160 default:
161 CtsProtect = 0x02;
162 break;
163 }
164 }
165 else
166 CtsProtect = 0x01;
167
168
169 // send start-RD with CTS protection command to MCU
170 // highbyte [7] reserve
171 // highbyte [6:5] 0x: stop Carrier/Radar detection
172 // highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
173 // highbyte [4:0] Radar/carrier detection duration. In 1ms.
174
175 // lowbyte [7:0] Radar/carrier detection period, in 1ms.
176 AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
177 //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
178
179 return;
180 }
181
182 /*
183 ========================================================================
184
185 Routine Description:
186 Radar detection routine
187
188 Arguments:
189 pAd Pointer to our adapter
190
191 Return Value:
192 TRUE Found radar signal
193 FALSE Not found radar signal
194
195 ========================================================================
196 */
197 VOID RadarDetectionStop(
198 IN PRTMP_ADAPTER pAd)
199 {
200 DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
201 AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
202
203 return;
204 }
205
206 /*
207 ========================================================================
208
209 Routine Description:
210 Radar channel check routine
211
212 Arguments:
213 pAd Pointer to our adapter
214
215 Return Value:
216 TRUE need to do radar detect
217 FALSE need not to do radar detect
218
219 ========================================================================
220 */
221 BOOLEAN RadarChannelCheck(
222 IN PRTMP_ADAPTER pAd,
223 IN UCHAR Ch)
224 {
225 #if 1
226 INT i;
227 BOOLEAN result = FALSE;
228
229 for (i=0; i<pAd->ChannelListNum; i++)
230 {
231 if (Ch == pAd->ChannelList[i].Channel)
232 {
233 result = pAd->ChannelList[i].DfsReq;
234 break;
235 }
236 }
237
238 return result;
239 #else
240 INT i;
241 UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
242
243 for (i=0; i<15; i++)
244 {
245 if (Ch == Channel[i])
246 {
247 break;
248 }
249 }
250
251 if (i != 15)
252 return TRUE;
253 else
254 return FALSE;
255 #endif
256 }
257
258 ULONG JapRadarType(
259 IN PRTMP_ADAPTER pAd)
260 {
261 ULONG i;
262 const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
263
264 if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
265 {
266 return pAd->CommonCfg.RadarDetect.RDDurRegion;
267 }
268
269 for (i=0; i<15; i++)
270 {
271 if (pAd->CommonCfg.Channel == Channel[i])
272 {
273 break;
274 }
275 }
276
277 if (i < 4)
278 return JAP_W53;
279 else if (i < 15)
280 return JAP_W56;
281 else
282 return JAP; // W52
283
284 }
285
286 ULONG RTMPBbpReadRadarDuration(
287 IN PRTMP_ADAPTER pAd)
288 {
289 UINT8 byteValue = 0;
290 ULONG result;
291
292 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
293
294 result = 0;
295 switch (byteValue)
296 {
297 case 1: // radar signal detected by pulse mode.
298 case 2: // radar signal detected by width mode.
299 result = RTMPReadRadarDuration(pAd);
300 break;
301
302 case 0: // No radar signal.
303 default:
304
305 result = 0;
306 break;
307 }
308
309 return result;
310 }
311
312 ULONG RTMPReadRadarDuration(
313 IN PRTMP_ADAPTER pAd)
314 {
315 ULONG result = 0;
316
317 #ifdef DFS_SUPPORT
318 UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
319
320 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
321 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
322 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
323 result = (duration1 << 16) + (duration2 << 8) + duration3;
324 #endif // DFS_SUPPORT //
325
326 return result;
327
328 }
329
330 VOID RTMPCleanRadarDuration(
331 IN PRTMP_ADAPTER pAd)
332 {
333 return;
334 }
335
336 /*
337 ========================================================================
338 Routine Description:
339 Radar wave detection. The API should be invoke each second.
340
341 Arguments:
342 pAd - Adapter pointer
343
344 Return Value:
345 None
346
347 ========================================================================
348 */
349 VOID ApRadarDetectPeriodic(
350 IN PRTMP_ADAPTER pAd)
351 {
352 INT i;
353
354 pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
355
356 for (i=0; i<pAd->ChannelListNum; i++)
357 {
358 if (pAd->ChannelList[i].RemainingTimeForUse > 0)
359 {
360 pAd->ChannelList[i].RemainingTimeForUse --;
361 if ((pAd->Mlme.PeriodicRound%5) == 0)
362 {
363 DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
364 }
365 }
366 }
367
368 //radar detect
369 if ((pAd->CommonCfg.Channel > 14)
370 && (pAd->CommonCfg.bIEEE80211H == 1)
371 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
372 {
373 RadarDetectPeriodic(pAd);
374 }
375
376 return;
377 }
378
379 // Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
380 // Before switch channel, driver needs doing channel switch announcement.
381 VOID RadarDetectPeriodic(
382 IN PRTMP_ADAPTER pAd)
383 {
384 // need to check channel availability, after switch channel
385 if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
386 return;
387
388 // channel availability check time is 60sec, use 65 for assurance
389 if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
390 {
391 DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
392 BbpRadarDetectionStop(pAd);
393 AsicEnableBssSync(pAd);
394 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
395
396
397 return;
398 }
399
400 return;
401 }
402
403
404 /*
405 ==========================================================================
406 Description:
407 change channel moving time for DFS testing.
408
409 Arguments:
410 pAdapter Pointer to our adapter
411 wrq Pointer to the ioctl argument
412
413 Return Value:
414 None
415
416 Note:
417 Usage:
418 1.) iwpriv ra0 set ChMovTime=[value]
419 ==========================================================================
420 */
421 INT Set_ChMovingTime_Proc(
422 IN PRTMP_ADAPTER pAd,
423 IN PUCHAR arg)
424 {
425 UINT8 Value;
426
427 Value = simple_strtol(arg, 0, 10);
428
429 pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
430
431 DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
432 pAd->CommonCfg.RadarDetect.ChMovingTime));
433
434 return TRUE;
435 }
436
437 INT Set_LongPulseRadarTh_Proc(
438 IN PRTMP_ADAPTER pAd,
439 IN PUCHAR arg)
440 {
441 UINT8 Value;
442
443 Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
444
445 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
446
447 DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
448 pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
449
450 return TRUE;
451 }
452
453
This page took 0.039109 seconds and 5 git commands to generate.