• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
BbpRadarDetectionStart(IN PRTMP_ADAPTER pAd)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 */
BbpRadarDetectionStop(IN PRTMP_ADAPTER pAd)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 */
RadarDetectionStart(IN PRTMP_ADAPTER pAd,IN BOOLEAN CTSProtect,IN UINT8 CTSPeriod)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 */
RadarDetectionStop(IN PRTMP_ADAPTER pAd)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 */
RadarChannelCheck(IN PRTMP_ADAPTER pAd,IN UCHAR Ch)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 
JapRadarType(IN PRTMP_ADAPTER pAd)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 
RTMPBbpReadRadarDuration(IN PRTMP_ADAPTER pAd)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 
RTMPReadRadarDuration(IN PRTMP_ADAPTER pAd)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 
RTMPCleanRadarDuration(IN PRTMP_ADAPTER pAd)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 */
ApRadarDetectPeriodic(IN PRTMP_ADAPTER pAd)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.
RadarDetectPeriodic(IN PRTMP_ADAPTER pAd)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 */
Set_ChMovingTime_Proc(IN PRTMP_ADAPTER pAd,IN PUCHAR arg)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 
Set_LongPulseRadarTh_Proc(IN PRTMP_ADAPTER pAd,IN PUCHAR arg)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 
454