upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / staging / otus / 80211core / freqctrl.c
1 /*
2  * Copyright (c) 2007-2008 Atheros Communications Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include "cprecomp.h"
18
19 /* zfAddFreqChangeReq should be called inside the critical section */
20 static void zfAddFreqChangeReq(zdev_t* dev, u16_t frequency, u8_t bw40,
21         u8_t extOffset, zfpFreqChangeCompleteCb cb)
22 {
23     zmw_get_wlan_dev(dev);
24
25 //printk("zfAddFreqChangeReq  freqReqQueueTail%d\n", wd->freqCtrl.freqReqQueueTail);
26     wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueTail] = frequency;
27     wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueTail] = bw40;
28     wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueTail] = extOffset;
29     wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueTail] = cb;
30     wd->freqCtrl.freqReqQueueTail++;
31     if ( wd->freqCtrl.freqReqQueueTail >= ZM_MAX_FREQ_REQ_QUEUE )
32     {
33         wd->freqCtrl.freqReqQueueTail = 0;
34     }
35 }
36
37 void zfCoreSetFrequencyV2(zdev_t* dev, u16_t frequency, zfpFreqChangeCompleteCb cb)
38 {
39     zfCoreSetFrequencyEx(dev, frequency, 0, 0, cb);
40 }
41
42 void zfCoreSetFrequencyExV2(zdev_t* dev, u16_t frequency, u8_t bw40,
43         u8_t extOffset, zfpFreqChangeCompleteCb cb, u8_t forceSetFreq)
44 {
45     u8_t setFreqImmed = 0;
46     u8_t initRF = 0;
47     zmw_get_wlan_dev(dev);
48     zmw_declare_for_critical_section();
49
50     zm_msg1_scan(ZM_LV_1, "Freq=", frequency);
51
52     zmw_enter_critical_section(dev);
53     if ((wd->sta.currentFrequency == frequency)
54         && (wd->sta.currentBw40 == bw40)
55         && (wd->sta.currentExtOffset == extOffset))
56     {
57         if ( forceSetFreq == 0 && wd->sta.flagFreqChanging == 0 )
58         {
59             goto done;
60         }
61     }
62 #ifdef ZM_FB50
63     /*if(frequency!=2437) {
64         zmw_leave_critical_section(dev);
65         return;
66     }*/
67 #endif
68
69     zfAddFreqChangeReq(dev, frequency, bw40, extOffset, cb);
70
71 //    zm_assert( wd->sta.flagFreqChanging == 0 );
72     //wd->sta.flagFreqChanging = 1;
73     if ( wd->sta.flagFreqChanging == 0 )
74     {
75         if ((wd->sta.currentBw40 != bw40) || (wd->sta.currentExtOffset != extOffset))
76         {
77             initRF = 1;
78         }
79         wd->sta.currentFrequency = frequency;
80         wd->sta.currentBw40 = bw40;
81         wd->sta.currentExtOffset = extOffset;
82         setFreqImmed = 1;
83     }
84     wd->sta.flagFreqChanging++;
85
86     zmw_leave_critical_section(dev);
87
88     if ( setFreqImmed )
89     {
90         //zfHpSetFrequency(dev, frequency, 0);
91         if ( forceSetFreq )
92         { // Cold reset to reset the frequency after scanning !
93             zm_debug_msg0("#6_1 20070917");
94             zm_debug_msg0("It is happen!!! No error message");
95             zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, 2);
96         }
97         else
98         {
99         zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, initRF);
100         }
101
102         if (    zfStaIsConnected(dev)
103              && (frequency == wd->frequency)) {
104             wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
105         }
106     }
107     return;
108
109 done:
110     zmw_leave_critical_section(dev);
111
112     if ( cb != NULL )
113     {
114         cb(dev);
115     }
116     zfPushVtxq(dev);
117     return;
118 }
119
120 void zfCoreSetFrequencyEx(zdev_t* dev, u16_t frequency, u8_t bw40,
121         u8_t extOffset, zfpFreqChangeCompleteCb cb)
122 {
123     zfCoreSetFrequencyExV2(dev, frequency, bw40, extOffset, cb, 0);
124 }
125
126 void zfCoreSetFrequency(zdev_t* dev, u16_t frequency)
127 {
128     zfCoreSetFrequencyV2(dev, frequency, NULL);
129 }
130
131 /* zfRemoveFreqChangeReq SHOULD NOT be called inside the critical section */
132 static void zfRemoveFreqChangeReq(zdev_t* dev)
133 {
134     zfpFreqChangeCompleteCb cb = NULL;
135     u16_t frequency;
136     u8_t bw40;
137     u8_t extOffset;
138     u16_t compFreq = 0;
139     u8_t compBw40 = 0;
140     u8_t compExtOffset = 0;
141
142     zmw_get_wlan_dev(dev);
143     zmw_declare_for_critical_section();
144
145     zmw_enter_critical_section(dev);
146
147     if (wd->freqCtrl.freqReqQueueHead != wd->freqCtrl.freqReqQueueTail)
148     {
149         zm_msg1_scan(ZM_LV_1, "Freq=",
150                 wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead]);
151         compFreq = wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead];
152         compBw40 = wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueHead];
153         compExtOffset = wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueHead];
154
155         wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] = 0;
156         cb = wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueHead];
157         wd->freqCtrl.freqReqQueueHead++;
158         if ( wd->freqCtrl.freqReqQueueHead >= ZM_MAX_FREQ_REQ_QUEUE )
159         {
160             wd->freqCtrl.freqReqQueueHead = 0;
161         }
162     }
163     zmw_leave_critical_section(dev);
164
165     if ( cb != NULL )
166     {
167         cb(dev);
168     }
169
170     zmw_enter_critical_section(dev);
171     while (wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] != 0)
172     {
173         frequency = wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead];
174         bw40 = wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueHead];
175         extOffset=wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueHead];
176         if ((compFreq == frequency)
177             && (compBw40 == bw40)
178             && (compExtOffset == extOffset))
179         {
180             /* Duplicated frequency command */
181             zm_msg1_scan(ZM_LV_1, "Duplicated Freq=", frequency);
182
183             cb = wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueHead];
184             wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] = 0;
185             wd->freqCtrl.freqReqQueueHead++;
186
187             if ( wd->freqCtrl.freqReqQueueHead >= ZM_MAX_FREQ_REQ_QUEUE )
188             {
189                 wd->freqCtrl.freqReqQueueHead = 0;
190             }
191
192             if ( wd->sta.flagFreqChanging != 0 )
193             {
194                 wd->sta.flagFreqChanging--;
195             }
196
197             zmw_leave_critical_section(dev);
198             if ( cb != NULL )
199             {
200                 cb(dev);
201             }
202             zmw_enter_critical_section(dev);
203         }
204         else
205         {
206             u8_t    initRF = 0;
207             if ((wd->sta.currentBw40 != bw40) || (wd->sta.currentExtOffset != extOffset))
208             {
209                 initRF = 1;
210             }
211             wd->sta.currentFrequency = frequency;
212             wd->sta.currentBw40 = bw40;
213             wd->sta.currentExtOffset = extOffset;
214             zmw_leave_critical_section(dev);
215
216             zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, initRF);
217             if (    zfStaIsConnected(dev)
218                 && (frequency == wd->frequency)) {
219                 wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev);
220             }
221
222             return;
223         }
224     }
225     zmw_leave_critical_section(dev);
226
227     return;
228 }
229
230 void zfCoreSetFrequencyComplete(zdev_t* dev)
231 {
232     zmw_get_wlan_dev(dev);
233     zmw_declare_for_critical_section();
234
235     zm_msg1_scan(ZM_LV_1, "flagFreqChanging=", wd->sta.flagFreqChanging);
236
237     zmw_enter_critical_section(dev);
238     //wd->sta.flagFreqChanging = 0;
239     if ( wd->sta.flagFreqChanging != 0 )
240     {
241         wd->sta.flagFreqChanging--;
242     }
243
244     zmw_leave_critical_section(dev);
245
246     zfRemoveFreqChangeReq(dev);
247
248     zfPushVtxq(dev);
249     return;
250 }
251
252 void zfReSetCurrentFrequency(zdev_t* dev)
253 {
254     zmw_get_wlan_dev(dev);
255
256     zm_debug_msg0("It is happen!!! No error message");
257
258     zfCoreSetFrequencyExV2(dev, wd->frequency, 0, 0, NULL, 1);
259 }