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
)
190 u8_t
zfPSDeviceSleep(zdev_t
* dev
)
192 //zmw_get_wlan_dev(dev);
199 u8_t zcOfdmPhyCrtlToRate
[] =
201 /* 0x8=48M, 0x9=24M, 0xa=12M, 0xb=6M, 0xc=54M, 0xd=36M, 0xe=18M, 0xf=9M */
202 10, 8, 6, 4, 11, 9, 7, 5
205 u8_t
zfPhyCtrlToRate(u32_t phyCtrl
)
211 mcs
= (phyCtrl
>>18) & 0x3f;
212 sg
= (phyCtrl
>>31) & 0x1;
214 if ((mt
== 0) && (mcs
<=3))
218 else if ((mt
== 1) && (mcs
>= 0x8) && (mcs
<= 0xf))
220 rate
= zcOfdmPhyCrtlToRate
[mcs
-8];
222 else if ((mt
== 2) && (mcs
<= 15))
224 rate
= (u8_t
)mcs
+ 12;
228 rate
= (u8_t
)mcs
+ 12 + 2;
241 void zfCoreEvent(zdev_t
* dev
, u16_t event
, u8_t
* rsp
)
249 zmw_get_wlan_dev(dev
);
250 zmw_declare_for_critical_section();
253 if (event
== 0) //Beacon Event
255 if ( wd
->wlanMode
== ZM_MODE_AP
)
259 if (wd
->CurrentDtimCount
== 0)
261 /* TODO : Send queued broadcast frames at BC/MC event */
266 zmw_enter_critical_section(dev
);
267 if (wd
->ap
.bcmcTail
[vap
] != wd
->ap
.bcmcHead
[vap
])
269 //zm_msg0_mm(ZM_LV_0, "Send BCMC frames");
270 psBuf
= wd
->ap
.bcmcArray
[vap
][wd
->ap
.bcmcHead
[vap
]];
271 wd
->ap
.bcmcHead
[vap
] = (wd
->ap
.bcmcHead
[vap
] + 1)
272 & (ZM_BCMC_ARRAY_SIZE
- 1);
273 if (wd
->ap
.bcmcTail
[vap
] != wd
->ap
.bcmcHead
[vap
])
278 zmw_leave_critical_section(dev
);
281 /* TODO : config moreData bit */
282 zfTxSendEth(dev
, psBuf
, 0, ZM_EXTERNAL_ALLOC_BUF
,
285 } while(psBuf
!= NULL
);
292 if ( wd
->sta
.powerSaveMode
> ZM_STA_PS_NONE
)
294 /* send queued packets */
295 for(i
=0; i
<wd
->sta
.staPSDataCount
; i
++)
297 zfTxSendEth(dev
, wd
->sta
.staPSDataQueue
[i
], 0,
298 ZM_EXTERNAL_ALLOC_BUF
, 0);
301 wd
->sta
.staPSDataCount
= 0;
304 if ( wd
->wlanMode
== ZM_MODE_IBSS
)
306 zfStaSendBeacon(dev
);
307 wd
->sta
.ibssAtimTimer
= ZM_BIT_15
| wd
->sta
.atimWindow
;
310 zfPowerSavingMgrPreTBTTInterrupt(dev
);
312 } //if (event == 0) //Beacon Event
313 else if (event
== 1) //Retry completed event
317 retryRate
= (u32_t
)(rsp
[6]) + (((u32_t
)(rsp
[7]))<<8)
318 + (((u32_t
)(rsp
[8]))<<16) + (((u32_t
)(rsp
[9]))<<24);
319 /* Degrade Tx Rate */
320 if (wd
->wlanMode
== ZM_MODE_AP
)
322 zmw_enter_critical_section(dev
);
323 i
= zfApFindSta(dev
, (u16_t
*)rsp
);
326 zfRateCtrlTxFailEvent(dev
, &wd
->ap
.staTable
[i
].rcCell
, 0,(u32_t
)zfPhyCtrlToRate(retryRate
));
328 zmw_leave_critical_section(dev
);
332 zmw_enter_critical_section(dev
);
333 res
= zfStaFindOppositeByMACAddr(dev
, (u16_t
*)rsp
, &peerIdx
);
336 zfRateCtrlTxFailEvent(dev
, &wd
->sta
.oppositeInfo
[peerIdx
].rcCell
, 0,(u32_t
)zfPhyCtrlToRate(retryRate
));
338 zmw_leave_critical_section(dev
);
340 } //else if (event == 1) //Retry completed event
341 else if (event
== 2) //Tx Fail event
345 retryRate
= (u32_t
)(rsp
[6]) + (((u32_t
)(rsp
[7]))<<8)
346 + (((u32_t
)(rsp
[8]))<<16) + (((u32_t
)(rsp
[9]))<<24);
348 /* Degrade Tx Rate */
349 if (wd
->wlanMode
== ZM_MODE_AP
)
351 zmw_enter_critical_section(dev
);
352 i
= zfApFindSta(dev
, (u16_t
*)rsp
);
355 zfRateCtrlTxFailEvent(dev
, &wd
->ap
.staTable
[i
].rcCell
, 0,(u32_t
)zfPhyCtrlToRate(retryRate
));
357 zmw_leave_critical_section(dev
);
359 zfApSendFailure(dev
, rsp
);
363 zmw_enter_critical_section(dev
);
364 res
= zfStaFindOppositeByMACAddr(dev
, (u16_t
*)rsp
, &peerIdx
);
367 zfRateCtrlTxFailEvent(dev
, &wd
->sta
.oppositeInfo
[peerIdx
].rcCell
, 0,(u32_t
)zfPhyCtrlToRate(retryRate
));
369 zmw_leave_critical_section(dev
);
371 } //else if (event == 2) //Tx Fail event
372 else if (event
== 3) //Tx Comp event
376 retryRate
= (u32_t
)(rsp
[6]) + (((u32_t
)(rsp
[7]))<<8)
377 + (((u32_t
)(rsp
[8]))<<16) + (((u32_t
)(rsp
[9]))<<24);
379 /* TODO : Tx completed, used for rate control probing */
380 if (wd
->wlanMode
== ZM_MODE_AP
)
382 zmw_enter_critical_section(dev
);
383 i
= zfApFindSta(dev
, (u16_t
*)rsp
);
386 zfRateCtrlTxSuccessEvent(dev
, &wd
->ap
.staTable
[i
].rcCell
, zfPhyCtrlToRate(retryRate
));
388 zmw_leave_critical_section(dev
);
392 zmw_enter_critical_section(dev
);
393 res
= zfStaFindOppositeByMACAddr(dev
, (u16_t
*)rsp
, &peerIdx
);
396 zfRateCtrlTxSuccessEvent(dev
, &wd
->sta
.oppositeInfo
[peerIdx
].rcCell
, zfPhyCtrlToRate(retryRate
));
398 zmw_leave_critical_section(dev
);
400 } //else if (event == 3) //Tx Comp event
401 else if (event
== 4) //BA failed count
407 fail
=((u32_t
*)rsp
)[0] & 0xFFFF;
408 rate
=((u32_t
*)rsp
)[0] >> 16;
411 rate
= (rate
& 0xF) + 12 + 2;
417 zmw_enter_critical_section(dev
);
418 zfRateCtrlTxFailEvent(dev
, &wd
->sta
.oppositeInfo
[peerIdx
].rcCell
, (u8_t
)rate
, fail
);
419 zmw_leave_critical_section(dev
);
423 void zfBeaconCfgInterrupt(zdev_t
* dev
, u8_t
* rsp
)
425 u32_t txBeaconCounter
;
427 zmw_get_wlan_dev(dev
);
429 zmw_declare_for_critical_section();
431 if ( wd
->wlanMode
== ZM_MODE_IBSS
)
433 txBeaconCounter
= *((u32_t
*)rsp
);
434 if ( wd
->sta
.beaconTxCnt
!= txBeaconCounter
)
436 wd
->sta
.txBeaconInd
= 1;
438 zmw_enter_critical_section(dev
);
439 wd
->tickIbssSendBeacon
= 0;
440 zmw_leave_critical_section(dev
);
444 wd
->sta
.txBeaconInd
= 0;
447 #ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION
448 if ( wd
->sta
.txBeaconInd
&& wd
->sta
.ibssDelayedInd
)
450 if (wd
->zfcbIbssPartnerNotify
!= NULL
)
452 wd
->zfcbIbssPartnerNotify(dev
, 1, &wd
->sta
.ibssDelayedIndEvent
);
455 wd
->sta
.ibssDelayedInd
= 0;
459 wd
->sta
.beaconTxCnt
= txBeaconCounter
;
461 // Need to check if the time is expired after ATIM window??
463 // Check if we have buffered any data for those stations that are sleeping
464 // If it's true, then transmitting ATIM pkt to notify them
466 #ifdef ZM_ENABLE_IBSS_PS
467 // TODO: Need to check if the station receive our ATIM pkt???
468 zfStaIbssPSSend(dev
);
470 if ( wd
->sta
.atimWindow
== 0 )
472 // We won't receive the end of ATIM isr so we fake it
473 zfPowerSavingMgrAtimWinExpired(dev
);
479 void zfEndOfAtimWindowInterrupt(zdev_t
* dev
)
481 #ifdef ZM_ENABLE_IBSS_PS
482 zmw_get_wlan_dev(dev
);
484 if ( wd
->wlanMode
== ZM_MODE_IBSS
)
486 // Transmit any queued pkt for the stations!!
487 zfPowerSavingMgrAtimWinExpired(dev
);