Merge branch 'for-linus' of git://www.jni.nu/cris
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / otus / 80211core / cic.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 #include "ratectrl.h"
19
20
21 void zfUpdateBssid(zdev_t* dev, u8_t* bssid)
22 {
23
24 zmw_get_wlan_dev(dev);
25
26 //zmw_declare_for_critical_section();
27
28 //zmw_enter_critical_section(dev);
29 wd->sta.bssid[0] = bssid[0] + (((u16_t) bssid[1]) << 8);
30 wd->sta.bssid[1] = bssid[2] + (((u16_t) bssid[3]) << 8);
31 wd->sta.bssid[2] = bssid[4] + (((u16_t) bssid[5]) << 8);
32 //zmw_leave_critical_section(dev);
33
34 zfHpSetBssid(dev, bssid);
35
36 }
37
38 /************************************************************************************/
39 /* */
40 /* FUNCTION DESCRIPTION zfResetSupportRate */
41 /* Reset support rate to default value. */
42 /* */
43 /* INPUTS */
44 /* dev : device pointer */
45 /* type: ZM_DEFAULT_SUPPORT_RATE_ZERO => reset to zero */
46 /* ZM_DEFAULT_SUPPORT_RATE_DISCONNECT => reset to disconnect status */
47 /* ZM_DEFAULT_SUPPORT_RATE_IBSS_B => reset to IBSS creator(b mode) */
48 /* ZM_DEFAULT_SUPPORT_RATE_IBSS_AG => reset to IBSS creator(a/g mode) */
49 /* */
50 /************************************************************************************/
51 void zfResetSupportRate(zdev_t* dev, u8_t type)
52 {
53 zmw_get_wlan_dev(dev);
54
55 switch(type)
56 {
57 case ZM_DEFAULT_SUPPORT_RATE_ZERO:
58 wd->bRate = 0;
59 wd->bRateBasic = 0;
60 wd->gRate = 0;
61 wd->gRateBasic = 0;
62 break;
63 case ZM_DEFAULT_SUPPORT_RATE_DISCONNECT:
64 wd->bRate = 0xf;
65 wd->bRateBasic = 0xf;
66 wd->gRate = 0xff;
67 wd->gRateBasic = 0x15;
68 break;
69 case ZM_DEFAULT_SUPPORT_RATE_IBSS_B:
70 wd->bRate = 0xf;
71 wd->bRateBasic = 0xf;
72 wd->gRate = 0;
73 wd->gRateBasic = 0;
74 break;
75 case ZM_DEFAULT_SUPPORT_RATE_IBSS_AG:
76 wd->bRate = 0xf;
77 wd->bRateBasic = 0xf;
78 wd->gRate = 0xff;
79 wd->gRateBasic = 0;
80 break;
81 }
82 }
83
84 void zfUpdateSupportRate(zdev_t* dev, u8_t* rateArray)
85 {
86 u8_t bRate=0, bRateBasic=0, gRate=0, gRateBasic=0;
87 u8_t length = rateArray[1];
88 u8_t i, j;
89
90 zmw_get_wlan_dev(dev);
91
92 for(i=2; i<length+2; i++)
93 {
94 for(j=0; j<4; j++)
95 {
96 if ( (rateArray[i] & 0x7f) == zg11bRateTbl[j] )
97 {
98 bRate |= (1 << j);
99 if ( rateArray[i] & 0x80 )
100 {
101 bRateBasic |= (1 << j);
102 }
103 }
104 }
105
106 if ( j == 4 )
107 {
108 for(j=0; j<8; j++)
109 {
110 if ( (rateArray[i] & 0x7f) == zg11gRateTbl[j] )
111 {
112 gRate |= (1 << j);
113 if ( rateArray[i] & 0x80 )
114 {
115 gRateBasic |= (1 << j);
116 }
117 }
118 }
119 }
120 }
121
122
123 wd->bRate |= bRate;
124 wd->bRateBasic |= bRateBasic;
125 wd->gRate |= gRate;
126 wd->gRateBasic |= gRateBasic;
127 }
128
129 u8_t zfIsGOnlyMode(zdev_t* dev, u16_t frequency, u8_t* rateArray)
130 {
131 u8_t length = rateArray[1];
132 u8_t i, j;
133
134 if (frequency < 3000) {
135 for (i = 2; i < length+2; i++) {
136 for (j = 0; j < 8; j++) {
137 if ( ((rateArray[i] & 0x7f) == zg11gRateTbl[j])
138 && (rateArray[i] & 0x80) ) {
139 return 1;
140 }
141 }
142 }
143 }
144
145 return 0;
146 }
147
148 void zfGatherBMode(zdev_t* dev, u8_t* rateArray, u8_t* extrateArray)
149 {
150 u8_t gatherBMode[ZM_MAX_SUPP_RATES_IE_SIZE + 2];
151 u8_t i, j, k = 0;
152 u8_t length;
153
154 gatherBMode[0] = ZM_WLAN_EID_SUPPORT_RATE;
155 gatherBMode[1] = 0;
156
157 length = rateArray[1];
158 for (i = 2; i < length+2; i++) {
159 for (j = 0; j < 4; j++) {
160 if ( (rateArray[i] & 0x7f) == zg11bRateTbl[j] ) {
161 gatherBMode[2+k] = rateArray[i];
162
163 gatherBMode[1]++;
164 k++;
165 }
166 }
167 }
168
169 length = extrateArray[1];
170 for (i = 2; i < length+2; i++) {
171 for (j = 0; j < 4; j++) {
172 if ( (extrateArray[i] & 0x7f) == zg11bRateTbl[j] ) {
173 gatherBMode[2+k] = extrateArray[i];
174
175 gatherBMode[1]++;
176 k++;
177 }
178 }
179 }
180
181 extrateArray[0] = extrateArray[1] = 0;
182 zfMemoryCopy(rateArray, gatherBMode, gatherBMode[1]+2);
183 }
184
185 u16_t zfGetRandomNumber(zdev_t* dev, u16_t initValue)
186 {
187 #if 0
188 /* Compiler/Linker error on Linux */
189 if ( initValue )
190 {
191 srand(initValue);
192 }
193
194 return ((u16_t)rand());
195 #endif
196 return 0;
197 }
198
199 u8_t zfPSDeviceSleep(zdev_t* dev)
200 {
201 //zmw_get_wlan_dev(dev);
202
203 /* enter PS mode */
204
205 return 0;
206 }
207
208 u8_t zcOfdmPhyCrtlToRate[] =
209 {
210 /* 0x8=48M, 0x9=24M, 0xa=12M, 0xb=6M, 0xc=54M, 0xd=36M, 0xe=18M, 0xf=9M */
211 10, 8, 6, 4, 11, 9, 7, 5
212 };
213
214 u8_t zfPhyCtrlToRate(u32_t phyCtrl)
215 {
216 u32_t mt, mcs, sg;
217 u8_t rate = 0;
218
219 mt = phyCtrl & 0x3;
220 mcs = (phyCtrl>>18) & 0x3f;
221 sg = (phyCtrl>>31) & 0x1;
222
223 if ((mt == 0) && (mcs <=3))
224 {
225 rate = (u8_t)mcs;
226 }
227 else if ((mt == 1) && (mcs >= 0x8) && (mcs <= 0xf))
228 {
229 rate = zcOfdmPhyCrtlToRate[mcs-8];
230 }
231 else if ((mt == 2) && (mcs <= 15))
232 {
233 rate = (u8_t)mcs + 12;
234 if(sg) {
235 if (mcs != 7)
236 {
237 rate = (u8_t)mcs + 12 + 2;
238 }
239 else //MCS7-SG
240 {
241 rate = (u8_t)30;
242 }
243 }
244 }
245
246 return rate;
247 }
248
249
250 void zfCoreEvent(zdev_t* dev, u16_t event, u8_t* rsp)
251 {
252 u16_t i;
253 zbuf_t* psBuf;
254 u8_t moreData;
255 u8_t vap = 0;
256 u8_t peerIdx;
257 s8_t res;
258 zmw_get_wlan_dev(dev);
259 zmw_declare_for_critical_section();
260
261
262 if (event == 0) //Beacon Event
263 {
264 if ( wd->wlanMode == ZM_MODE_AP )
265 {
266 zfApSendBeacon(dev);
267
268 if (wd->CurrentDtimCount == 0)
269 {
270 /* TODO : Send queued broadcast frames at BC/MC event */
271 do
272 {
273 psBuf = NULL;
274 moreData = 0;
275 zmw_enter_critical_section(dev);
276 if (wd->ap.bcmcTail[vap] != wd->ap.bcmcHead[vap])
277 {
278 //zm_msg0_mm(ZM_LV_0, "Send BCMC frames");
279 psBuf = wd->ap.bcmcArray[vap][wd->ap.bcmcHead[vap]];
280 wd->ap.bcmcHead[vap] = (wd->ap.bcmcHead[vap] + 1)
281 & (ZM_BCMC_ARRAY_SIZE - 1);
282 if (wd->ap.bcmcTail[vap] != wd->ap.bcmcHead[vap])
283 {
284 moreData = 0x20;
285 }
286 }
287 zmw_leave_critical_section(dev);
288 if (psBuf != NULL)
289 {
290 /* TODO : config moreData bit */
291 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF,
292 moreData);
293 }
294 } while(psBuf != NULL);
295
296 }
297 }
298 else
299 {
300 /* STA mode */
301 if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE )
302 {
303 /* send queued packets */
304 for(i=0; i<wd->sta.staPSDataCount; i++)
305 {
306 zfTxSendEth(dev, wd->sta.staPSDataQueue[i], 0,
307 ZM_EXTERNAL_ALLOC_BUF, 0);
308 }
309
310 wd->sta.staPSDataCount = 0;
311 }
312
313 if ( wd->wlanMode == ZM_MODE_IBSS )
314 {
315 zfStaSendBeacon(dev);
316 wd->sta.ibssAtimTimer = ZM_BIT_15 | wd->sta.atimWindow;
317 }
318
319 zfPowerSavingMgrPreTBTTInterrupt(dev);
320 }
321 } //if (event == 0) //Beacon Event
322 else if (event == 1) //Retry completed event
323 {
324 u32_t retryRate;
325
326 retryRate = (u32_t)(rsp[6]) + (((u32_t)(rsp[7]))<<8)
327 + (((u32_t)(rsp[8]))<<16) + (((u32_t)(rsp[9]))<<24);
328 /* Degrade Tx Rate */
329 if (wd->wlanMode == ZM_MODE_AP)
330 {
331 zmw_enter_critical_section(dev);
332 i = zfApFindSta(dev, (u16_t*)rsp);
333 if (i != 0xffff)
334 {
335 zfRateCtrlTxFailEvent(dev, &wd->ap.staTable[i].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate));
336 }
337 zmw_leave_critical_section(dev);
338 }
339 else
340 {
341 zmw_enter_critical_section(dev);
342 res = zfStaFindOppositeByMACAddr(dev, (u16_t*)rsp, &peerIdx);
343 if ( res == 0 )
344 {
345 zfRateCtrlTxFailEvent(dev, &wd->sta.oppositeInfo[peerIdx].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate));
346 }
347 zmw_leave_critical_section(dev);
348 }
349 } //else if (event == 1) //Retry completed event
350 else if (event == 2) //Tx Fail event
351 {
352 u32_t retryRate;
353
354 retryRate = (u32_t)(rsp[6]) + (((u32_t)(rsp[7]))<<8)
355 + (((u32_t)(rsp[8]))<<16) + (((u32_t)(rsp[9]))<<24);
356
357 /* Degrade Tx Rate */
358 if (wd->wlanMode == ZM_MODE_AP)
359 {
360 zmw_enter_critical_section(dev);
361 i = zfApFindSta(dev, (u16_t*)rsp);
362 if (i != 0xffff)
363 {
364 zfRateCtrlTxFailEvent(dev, &wd->ap.staTable[i].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate));
365 }
366 zmw_leave_critical_section(dev);
367
368 zfApSendFailure(dev, rsp);
369 }
370 else
371 {
372 zmw_enter_critical_section(dev);
373 res = zfStaFindOppositeByMACAddr(dev, (u16_t*)rsp, &peerIdx);
374 if ( res == 0 )
375 {
376 zfRateCtrlTxFailEvent(dev, &wd->sta.oppositeInfo[peerIdx].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate));
377 }
378 zmw_leave_critical_section(dev);
379 }
380 } //else if (event == 2) //Tx Fail event
381 else if (event == 3) //Tx Comp event
382 {
383 u32_t retryRate;
384
385 retryRate = (u32_t)(rsp[6]) + (((u32_t)(rsp[7]))<<8)
386 + (((u32_t)(rsp[8]))<<16) + (((u32_t)(rsp[9]))<<24);
387
388 /* TODO : Tx completed, used for rate control probing */
389 if (wd->wlanMode == ZM_MODE_AP)
390 {
391 zmw_enter_critical_section(dev);
392 i = zfApFindSta(dev, (u16_t*)rsp);
393 if (i != 0xffff)
394 {
395 zfRateCtrlTxSuccessEvent(dev, &wd->ap.staTable[i].rcCell, zfPhyCtrlToRate(retryRate));
396 }
397 zmw_leave_critical_section(dev);
398 }
399 else
400 {
401 zmw_enter_critical_section(dev);
402 res = zfStaFindOppositeByMACAddr(dev, (u16_t*)rsp, &peerIdx);
403 if ( res == 0 )
404 {
405 zfRateCtrlTxSuccessEvent(dev, &wd->sta.oppositeInfo[peerIdx].rcCell, zfPhyCtrlToRate(retryRate));
406 }
407 zmw_leave_critical_section(dev);
408 }
409 } //else if (event == 3) //Tx Comp event
410 else if (event == 4) //BA failed count
411 {
412 u32_t fail;
413 u32_t rate;
414 peerIdx = 0;
415
416 fail=((u32_t*)rsp)[0] & 0xFFFF;
417 rate=((u32_t*)rsp)[0] >> 16;
418
419 if (rate > 15) {
420 rate = (rate & 0xF) + 12 + 2;
421 }
422 else {
423 rate = rate + 12;
424 }
425
426 zmw_enter_critical_section(dev);
427 zfRateCtrlTxFailEvent(dev, &wd->sta.oppositeInfo[peerIdx].rcCell, (u8_t)rate, fail);
428 zmw_leave_critical_section(dev);
429 }
430 }
431
432 void zfBeaconCfgInterrupt(zdev_t* dev, u8_t* rsp)
433 {
434 u32_t txBeaconCounter;
435
436 zmw_get_wlan_dev(dev);
437
438 zmw_declare_for_critical_section();
439
440 if ( wd->wlanMode == ZM_MODE_IBSS )
441 {
442 txBeaconCounter = *((u32_t *)rsp);
443 if ( wd->sta.beaconTxCnt != txBeaconCounter )
444 {
445 wd->sta.txBeaconInd = 1;
446
447 zmw_enter_critical_section(dev);
448 wd->tickIbssSendBeacon = 0;
449 zmw_leave_critical_section(dev);
450 }
451 else
452 {
453 wd->sta.txBeaconInd = 0;
454 }
455
456 #ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION
457 if ( wd->sta.txBeaconInd && wd->sta.ibssDelayedInd )
458 {
459 if (wd->zfcbIbssPartnerNotify != NULL)
460 {
461 wd->zfcbIbssPartnerNotify(dev, 1, &wd->sta.ibssDelayedIndEvent);
462 }
463
464 wd->sta.ibssDelayedInd = 0;
465 }
466 #endif
467
468 wd->sta.beaconTxCnt = txBeaconCounter;
469
470 // Need to check if the time is expired after ATIM window??
471
472 // Check if we have buffered any data for those stations that are sleeping
473 // If it's true, then transmitting ATIM pkt to notify them
474
475 #ifdef ZM_ENABLE_IBSS_PS
476 // TODO: Need to check if the station receive our ATIM pkt???
477 zfStaIbssPSSend(dev);
478
479 if ( wd->sta.atimWindow == 0 )
480 {
481 // We won't receive the end of ATIM isr so we fake it
482 zfPowerSavingMgrAtimWinExpired(dev);
483 }
484 #endif
485 }
486 }
487
488 void zfEndOfAtimWindowInterrupt(zdev_t* dev)
489 {
490 #ifdef ZM_ENABLE_IBSS_PS
491 zmw_get_wlan_dev(dev);
492
493 if ( wd->wlanMode == ZM_MODE_IBSS )
494 {
495 // Transmit any queued pkt for the stations!!
496 zfPowerSavingMgrAtimWinExpired(dev);
497 }
498 #endif
499 }