Merge branch 'for-linus' of git://www.jni.nu/cris
[GitHub/mt8127/android_kernel_alcatel_ttab.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 }