Staging: otus: 80211core: Hoist assign from if
[safe/jmp/linux-2.6] / 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 }