2 * Copyright (c) 2007-2008 Atheros Communications Inc.
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.
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.
21 void zfUpdateBssid(zdev_t
* dev
, u8_t
* bssid
)
24 zmw_get_wlan_dev(dev
);
26 //zmw_declare_for_critical_section();
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);
34 zfHpSetBssid(dev
, bssid
);
38 /************************************************************************************/
40 /* FUNCTION DESCRIPTION zfResetSupportRate */
41 /* Reset support rate to default value. */
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) */
50 /************************************************************************************/
51 void zfResetSupportRate(zdev_t
* dev
, u8_t type
)
53 zmw_get_wlan_dev(dev
);
57 case ZM_DEFAULT_SUPPORT_RATE_ZERO
:
63 case ZM_DEFAULT_SUPPORT_RATE_DISCONNECT
:
67 wd
->gRateBasic
= 0x15;
69 case ZM_DEFAULT_SUPPORT_RATE_IBSS_B
:
75 case ZM_DEFAULT_SUPPORT_RATE_IBSS_AG
:
84 void zfUpdateSupportRate(zdev_t
* dev
, u8_t
* rateArray
)
86 u8_t bRate
=0, bRateBasic
=0, gRate
=0, gRateBasic
=0;
87 u8_t length
= rateArray
[1];
90 zmw_get_wlan_dev(dev
);
92 for(i
=2; i
<length
+2; i
++)
96 if ( (rateArray
[i
] & 0x7f) == zg11bRateTbl
[j
] )
99 if ( rateArray
[i
] & 0x80 )
101 bRateBasic
|= (1 << j
);
110 if ( (rateArray
[i
] & 0x7f) == zg11gRateTbl
[j
] )
113 if ( rateArray
[i
] & 0x80 )
115 gRateBasic
|= (1 << j
);
124 wd
->bRateBasic
|= bRateBasic
;
126 wd
->gRateBasic
|= gRateBasic
;
129 u8_t
zfIsGOnlyMode(zdev_t
* dev
, u16_t frequency
, u8_t
* rateArray
)
131 u8_t length
= rateArray
[1];
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) ) {
148 void zfGatherBMode(zdev_t
* dev
, u8_t
* rateArray
, u8_t
* extrateArray
)
150 u8_t gatherBMode
[ZM_MAX_SUPP_RATES_IE_SIZE
+ 2];
154 gatherBMode
[0] = ZM_WLAN_EID_SUPPORT_RATE
;
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
];
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
];
181 extrateArray
[0] = extrateArray
[1] = 0;
182 zfMemoryCopy(rateArray
, gatherBMode
, gatherBMode
[1]+2);
185 u16_t
zfGetRandomNumber(zdev_t
* dev
, u16_t initValue
)
188 /* Compiler/Linker error on Linux */
194 return ((u16_t
)rand());
199 u8_t
zfPSDeviceSleep(zdev_t
* dev
)
201 //zmw_get_wlan_dev(dev);
208 u8_t zcOfdmPhyCrtlToRate
[] =
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
214 u8_t
zfPhyCtrlToRate(u32_t phyCtrl
)
220 mcs
= (phyCtrl
>>18) & 0x3f;
221 sg
= (phyCtrl
>>31) & 0x1;
223 if ((mt
== 0) && (mcs
<=3))
227 else if ((mt
== 1) && (mcs
>= 0x8) && (mcs
<= 0xf))
229 rate
= zcOfdmPhyCrtlToRate
[mcs
-8];
231 else if ((mt
== 2) && (mcs
<= 15))
233 rate
= (u8_t
)mcs
+ 12;
237 rate
= (u8_t
)mcs
+ 12 + 2;
250 void zfCoreEvent(zdev_t
* dev
, u16_t event
, u8_t
* rsp
)
258 zmw_get_wlan_dev(dev
);
259 zmw_declare_for_critical_section();
262 if (event
== 0) //Beacon Event
264 if ( wd
->wlanMode
== ZM_MODE_AP
)
268 if (wd
->CurrentDtimCount
== 0)
270 /* TODO : Send queued broadcast frames at BC/MC event */
275 zmw_enter_critical_section(dev
);
276 if (wd
->ap
.bcmcTail
[vap
] != wd
->ap
.bcmcHead
[vap
])
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
])
287 zmw_leave_critical_section(dev
);
290 /* TODO : config moreData bit */
291 zfTxSendEth(dev
, psBuf
, 0, ZM_EXTERNAL_ALLOC_BUF
,
294 } while(psBuf
!= NULL
);
301 if ( wd
->sta
.powerSaveMode
> ZM_STA_PS_NONE
)
303 /* send queued packets */
304 for(i
=0; i
<wd
->sta
.staPSDataCount
; i
++)
306 zfTxSendEth(dev
, wd
->sta
.staPSDataQueue
[i
], 0,
307 ZM_EXTERNAL_ALLOC_BUF
, 0);
310 wd
->sta
.staPSDataCount
= 0;
313 if ( wd
->wlanMode
== ZM_MODE_IBSS
)
315 zfStaSendBeacon(dev
);
316 wd
->sta
.ibssAtimTimer
= ZM_BIT_15
| wd
->sta
.atimWindow
;
319 zfPowerSavingMgrPreTBTTInterrupt(dev
);
321 } //if (event == 0) //Beacon Event
322 else if (event
== 1) //Retry completed event
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
)
331 zmw_enter_critical_section(dev
);
332 i
= zfApFindSta(dev
, (u16_t
*)rsp
);
335 zfRateCtrlTxFailEvent(dev
, &wd
->ap
.staTable
[i
].rcCell
, 0,(u32_t
)zfPhyCtrlToRate(retryRate
));
337 zmw_leave_critical_section(dev
);
341 zmw_enter_critical_section(dev
);
342 res
= zfStaFindOppositeByMACAddr(dev
, (u16_t
*)rsp
, &peerIdx
);
345 zfRateCtrlTxFailEvent(dev
, &wd
->sta
.oppositeInfo
[peerIdx
].rcCell
, 0,(u32_t
)zfPhyCtrlToRate(retryRate
));
347 zmw_leave_critical_section(dev
);
349 } //else if (event == 1) //Retry completed event
350 else if (event
== 2) //Tx Fail event
354 retryRate
= (u32_t
)(rsp
[6]) + (((u32_t
)(rsp
[7]))<<8)
355 + (((u32_t
)(rsp
[8]))<<16) + (((u32_t
)(rsp
[9]))<<24);
357 /* Degrade Tx Rate */
358 if (wd
->wlanMode
== ZM_MODE_AP
)
360 zmw_enter_critical_section(dev
);
361 i
= zfApFindSta(dev
, (u16_t
*)rsp
);
364 zfRateCtrlTxFailEvent(dev
, &wd
->ap
.staTable
[i
].rcCell
, 0,(u32_t
)zfPhyCtrlToRate(retryRate
));
366 zmw_leave_critical_section(dev
);
368 zfApSendFailure(dev
, rsp
);
372 zmw_enter_critical_section(dev
);
373 res
= zfStaFindOppositeByMACAddr(dev
, (u16_t
*)rsp
, &peerIdx
);
376 zfRateCtrlTxFailEvent(dev
, &wd
->sta
.oppositeInfo
[peerIdx
].rcCell
, 0,(u32_t
)zfPhyCtrlToRate(retryRate
));
378 zmw_leave_critical_section(dev
);
380 } //else if (event == 2) //Tx Fail event
381 else if (event
== 3) //Tx Comp event
385 retryRate
= (u32_t
)(rsp
[6]) + (((u32_t
)(rsp
[7]))<<8)
386 + (((u32_t
)(rsp
[8]))<<16) + (((u32_t
)(rsp
[9]))<<24);
388 /* TODO : Tx completed, used for rate control probing */
389 if (wd
->wlanMode
== ZM_MODE_AP
)
391 zmw_enter_critical_section(dev
);
392 i
= zfApFindSta(dev
, (u16_t
*)rsp
);
395 zfRateCtrlTxSuccessEvent(dev
, &wd
->ap
.staTable
[i
].rcCell
, zfPhyCtrlToRate(retryRate
));
397 zmw_leave_critical_section(dev
);
401 zmw_enter_critical_section(dev
);
402 res
= zfStaFindOppositeByMACAddr(dev
, (u16_t
*)rsp
, &peerIdx
);
405 zfRateCtrlTxSuccessEvent(dev
, &wd
->sta
.oppositeInfo
[peerIdx
].rcCell
, zfPhyCtrlToRate(retryRate
));
407 zmw_leave_critical_section(dev
);
409 } //else if (event == 3) //Tx Comp event
410 else if (event
== 4) //BA failed count
416 fail
=((u32_t
*)rsp
)[0] & 0xFFFF;
417 rate
=((u32_t
*)rsp
)[0] >> 16;
420 rate
= (rate
& 0xF) + 12 + 2;
426 zmw_enter_critical_section(dev
);
427 zfRateCtrlTxFailEvent(dev
, &wd
->sta
.oppositeInfo
[peerIdx
].rcCell
, (u8_t
)rate
, fail
);
428 zmw_leave_critical_section(dev
);
432 void zfBeaconCfgInterrupt(zdev_t
* dev
, u8_t
* rsp
)
434 u32_t txBeaconCounter
;
436 zmw_get_wlan_dev(dev
);
438 zmw_declare_for_critical_section();
440 if ( wd
->wlanMode
== ZM_MODE_IBSS
)
442 txBeaconCounter
= *((u32_t
*)rsp
);
443 if ( wd
->sta
.beaconTxCnt
!= txBeaconCounter
)
445 wd
->sta
.txBeaconInd
= 1;
447 zmw_enter_critical_section(dev
);
448 wd
->tickIbssSendBeacon
= 0;
449 zmw_leave_critical_section(dev
);
453 wd
->sta
.txBeaconInd
= 0;
456 #ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION
457 if ( wd
->sta
.txBeaconInd
&& wd
->sta
.ibssDelayedInd
)
459 if (wd
->zfcbIbssPartnerNotify
!= NULL
)
461 wd
->zfcbIbssPartnerNotify(dev
, 1, &wd
->sta
.ibssDelayedIndEvent
);
464 wd
->sta
.ibssDelayedInd
= 0;
468 wd
->sta
.beaconTxCnt
= txBeaconCounter
;
470 // Need to check if the time is expired after ATIM window??
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
475 #ifdef ZM_ENABLE_IBSS_PS
476 // TODO: Need to check if the station receive our ATIM pkt???
477 zfStaIbssPSSend(dev
);
479 if ( wd
->sta
.atimWindow
== 0 )
481 // We won't receive the end of ATIM isr so we fake it
482 zfPowerSavingMgrAtimWinExpired(dev
);
488 void zfEndOfAtimWindowInterrupt(zdev_t
* dev
)
490 #ifdef ZM_ENABLE_IBSS_PS
491 zmw_get_wlan_dev(dev
);
493 if ( wd
->wlanMode
== ZM_MODE_IBSS
)
495 // Transmit any queued pkt for the stations!!
496 zfPowerSavingMgrAtimWinExpired(dev
);