4bd43f507c
Initial dump of the otus USB wireless network driver. It builds properly, but a lot of work needs to be done cleaning it up before it can be merged into the wireless driver tree. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
1228 lines
33 KiB
C
1228 lines
33 KiB
C
/*
|
|
* Copyright (c) 2007-2008 Atheros Communications Inc.
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include "cprecomp.h"
|
|
|
|
u8_t zfQueryOppositeRate(zdev_t* dev, u8_t dst_mac[6], u8_t frameType)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
/* For AP's rate adaption */
|
|
if ( wd->wlanMode == ZM_MODE_AP )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* For STA's rate adaption */
|
|
if ( (frameType & 0x0c) == ZM_WLAN_DATA_FRAME )
|
|
{
|
|
if ( ZM_IS_MULTICAST(dst_mac) )
|
|
{
|
|
return wd->sta.mTxRate;
|
|
}
|
|
else
|
|
{
|
|
return wd->sta.uTxRate;
|
|
}
|
|
}
|
|
|
|
return wd->sta.mmTxRate;
|
|
}
|
|
|
|
void zfCopyToIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src,
|
|
u16_t offset, u16_t length)
|
|
{
|
|
u16_t i;
|
|
|
|
for(i=0; i<length;i++)
|
|
{
|
|
zmw_tx_buf_writeb(dev, buf, offset+i, src[i]);
|
|
}
|
|
}
|
|
|
|
void zfCopyToRxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src,
|
|
u16_t offset, u16_t length)
|
|
{
|
|
u16_t i;
|
|
|
|
for(i=0; i<length;i++)
|
|
{
|
|
zmw_rx_buf_writeb(dev, buf, offset+i, src[i]);
|
|
}
|
|
}
|
|
|
|
void zfCopyFromIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* dst,
|
|
u16_t offset, u16_t length)
|
|
{
|
|
u16_t i;
|
|
|
|
for(i=0; i<length; i++)
|
|
{
|
|
dst[i] = zmw_tx_buf_readb(dev, buf, offset+i);
|
|
}
|
|
}
|
|
|
|
void zfCopyFromRxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* dst,
|
|
u16_t offset, u16_t length)
|
|
{
|
|
u16_t i;
|
|
|
|
for(i=0; i<length; i++)
|
|
{
|
|
dst[i] = zmw_rx_buf_readb(dev, buf, offset+i);
|
|
}
|
|
}
|
|
|
|
#if 1
|
|
void zfMemoryCopy(u8_t* dst, u8_t* src, u16_t length)
|
|
{
|
|
zfwMemoryCopy(dst, src, length);
|
|
}
|
|
|
|
void zfMemoryMove(u8_t* dst, u8_t* src, u16_t length)
|
|
{
|
|
zfwMemoryMove(dst, src, length);
|
|
}
|
|
|
|
void zfZeroMemory(u8_t* va, u16_t length)
|
|
{
|
|
zfwZeroMemory(va, length);
|
|
}
|
|
|
|
u8_t zfMemoryIsEqual(u8_t* m1, u8_t* m2, u16_t length)
|
|
{
|
|
return zfwMemoryIsEqual(m1, m2, length);
|
|
}
|
|
#endif
|
|
|
|
u8_t zfRxBufferEqualToStr(zdev_t* dev, zbuf_t* buf,
|
|
const u8_t* str, u16_t offset, u16_t length)
|
|
{
|
|
u16_t i;
|
|
u8_t ch;
|
|
|
|
for(i=0; i<length; i++)
|
|
{
|
|
ch = zmw_rx_buf_readb(dev, buf, offset+i);
|
|
if ( ch != str[i] )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void zfTxBufferCopy(zdev_t*dev, zbuf_t* dst, zbuf_t* src,
|
|
u16_t dstOffset, u16_t srcOffset, u16_t length)
|
|
{
|
|
u16_t i;
|
|
|
|
for(i=0; i<length; i++)
|
|
{
|
|
zmw_tx_buf_writeb(dev, dst, dstOffset+i,
|
|
zmw_tx_buf_readb(dev, src, srcOffset+i));
|
|
}
|
|
}
|
|
|
|
void zfRxBufferCopy(zdev_t*dev, zbuf_t* dst, zbuf_t* src,
|
|
u16_t dstOffset, u16_t srcOffset, u16_t length)
|
|
{
|
|
u16_t i;
|
|
|
|
for(i=0; i<length; i++)
|
|
{
|
|
zmw_rx_buf_writeb(dev, dst, dstOffset+i,
|
|
zmw_rx_buf_readb(dev, src, srcOffset+i));
|
|
}
|
|
}
|
|
|
|
|
|
void zfCollectHWTally(zdev_t*dev, u32_t* rsp, u8_t id)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zmw_declare_for_critical_section();
|
|
|
|
zmw_enter_critical_section(dev);
|
|
|
|
if (id == 0)
|
|
{
|
|
wd->commTally.Hw_UnderrunCnt += (0xFFFF & rsp[1]);
|
|
wd->commTally.Hw_TotalRxFrm += rsp[2];
|
|
wd->commTally.Hw_CRC32Cnt += rsp[3];
|
|
wd->commTally.Hw_CRC16Cnt += rsp[4];
|
|
#ifdef ZM_ENABLE_NATIVE_WIFI
|
|
/* These code are here to satisfy Vista DTM */
|
|
wd->commTally.Hw_DecrypErr_UNI += ((rsp[5]>50) && (rsp[5]<60))?50:rsp[5];
|
|
#else
|
|
wd->commTally.Hw_DecrypErr_UNI += rsp[5];
|
|
#endif
|
|
wd->commTally.Hw_RxFIFOOverrun += rsp[6];
|
|
wd->commTally.Hw_DecrypErr_Mul += rsp[7];
|
|
wd->commTally.Hw_RetryCnt += rsp[8];
|
|
wd->commTally.Hw_TotalTxFrm += rsp[9];
|
|
wd->commTally.Hw_RxTimeOut +=rsp[10];
|
|
|
|
wd->commTally.Tx_MPDU += rsp[11];
|
|
wd->commTally.BA_Fail += rsp[12];
|
|
wd->commTally.Hw_Tx_AMPDU += rsp[13];
|
|
wd->commTally.Hw_Tx_MPDU += rsp[14];
|
|
wd->commTally.RateCtrlTxMPDU += rsp[11];
|
|
wd->commTally.RateCtrlBAFail += rsp[12];
|
|
}
|
|
else
|
|
{
|
|
wd->commTally.Hw_RxMPDU += rsp[1];
|
|
wd->commTally.Hw_RxDropMPDU += rsp[2];
|
|
wd->commTally.Hw_RxDelMPDU += rsp[3];
|
|
|
|
wd->commTally.Hw_RxPhyMiscError += rsp[4];
|
|
wd->commTally.Hw_RxPhyXRError += rsp[5];
|
|
wd->commTally.Hw_RxPhyOFDMError += rsp[6];
|
|
wd->commTally.Hw_RxPhyCCKError += rsp[7];
|
|
wd->commTally.Hw_RxPhyHTError += rsp[8];
|
|
wd->commTally.Hw_RxPhyTotalCount += rsp[9];
|
|
}
|
|
|
|
zmw_leave_critical_section(dev);
|
|
|
|
if (id == 0)
|
|
{
|
|
zm_msg1_mm(ZM_LV_1, "rsplen =", rsp[0]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_UnderrunCnt = ", (0xFFFF & rsp[1]));
|
|
zm_msg1_mm(ZM_LV_1, "Hw_TotalRxFrm = ", rsp[2]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_CRC32Cnt = ", rsp[3]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_CRC16Cnt = ", rsp[4]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_UNI = ", rsp[5]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxFIFOOverrun = ", rsp[6]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_Mul = ", rsp[7]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RetryCnt = ", rsp[8]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_TotalTxFrm = ", rsp[9]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxTimeOut = ", rsp[10]);
|
|
zm_msg1_mm(ZM_LV_1, "Tx_MPDU = ", rsp[11]);
|
|
zm_msg1_mm(ZM_LV_1, "BA_Fail = ", rsp[12]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_Tx_AMPDU = ", rsp[13]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_Tx_MPDU = ", rsp[14]);
|
|
}
|
|
else
|
|
{
|
|
zm_msg1_mm(ZM_LV_1, "rsplen = ", rsp[0]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxMPDU = ", (0xFFFF & rsp[1]));
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxDropMPDU = ", rsp[2]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxDelMPDU = ", rsp[3]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxPhyMiscError = ", rsp[4]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxPhyXRError = ", rsp[5]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxPhyOFDMError = ", rsp[6]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxPhyCCKError = ", rsp[7]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxPhyHTError = ", rsp[8]);
|
|
zm_msg1_mm(ZM_LV_1, "Hw_RxPhyTotalCount = ", rsp[9]);
|
|
}
|
|
|
|
}
|
|
|
|
/* Timer related functions */
|
|
void zfTimerInit(zdev_t* dev)
|
|
{
|
|
u8_t i;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zm_debug_msg0("");
|
|
|
|
wd->timerList.freeCount = ZM_MAX_TIMER_COUNT;
|
|
wd->timerList.head = &(wd->timerList.list[0]);
|
|
wd->timerList.tail = &(wd->timerList.list[ZM_MAX_TIMER_COUNT-1]);
|
|
wd->timerList.head->pre = NULL;
|
|
wd->timerList.head->next = &(wd->timerList.list[1]);
|
|
wd->timerList.tail->pre = &(wd->timerList.list[ZM_MAX_TIMER_COUNT-2]);
|
|
wd->timerList.tail->next = NULL;
|
|
|
|
for( i=1; i<(ZM_MAX_TIMER_COUNT-1); i++ )
|
|
{
|
|
wd->timerList.list[i].pre = &(wd->timerList.list[i-1]);
|
|
wd->timerList.list[i].next = &(wd->timerList.list[i+1]);
|
|
}
|
|
|
|
wd->bTimerReady = TRUE;
|
|
}
|
|
|
|
|
|
u16_t zfTimerSchedule(zdev_t* dev, u16_t event, u32_t tick)
|
|
{
|
|
struct zsTimerEntry *pFreeEntry;
|
|
struct zsTimerEntry *pEntry;
|
|
u8_t i, count;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
if ( wd->timerList.freeCount == 0 )
|
|
{
|
|
zm_debug_msg0("no more timer");
|
|
return 1;
|
|
}
|
|
|
|
//zm_debug_msg2("event = ", event);
|
|
//zm_debug_msg1("target tick = ", wd->tick + tick);
|
|
|
|
count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount;
|
|
|
|
if ( count == 0 )
|
|
{
|
|
wd->timerList.freeCount--;
|
|
wd->timerList.head->event = event;
|
|
wd->timerList.head->timer = wd->tick + tick;
|
|
//zm_debug_msg1("free timer count = ", wd->timerList.freeCount);
|
|
|
|
return 0;
|
|
}
|
|
|
|
pFreeEntry = wd->timerList.tail;
|
|
pFreeEntry->timer = wd->tick + tick;
|
|
pFreeEntry->event = event;
|
|
wd->timerList.tail = pFreeEntry->pre;
|
|
pEntry = wd->timerList.head;
|
|
|
|
for( i=0; i<count; i++ )
|
|
{
|
|
// prevent from the case of tick overflow
|
|
if ( ( pEntry->timer > pFreeEntry->timer )&&
|
|
((pEntry->timer - pFreeEntry->timer) < 1000000000) )
|
|
{
|
|
if ( i != 0 )
|
|
{
|
|
pFreeEntry->pre = pEntry->pre;
|
|
pFreeEntry->pre->next = pFreeEntry;
|
|
}
|
|
else
|
|
{
|
|
pFreeEntry->pre = NULL;
|
|
}
|
|
|
|
pEntry->pre = pFreeEntry;
|
|
pFreeEntry->next = pEntry;
|
|
break;
|
|
}
|
|
|
|
pEntry = pEntry->next;
|
|
}
|
|
|
|
if ( i == 0 )
|
|
{
|
|
wd->timerList.head = pFreeEntry;
|
|
}
|
|
|
|
if ( i == count )
|
|
{
|
|
pFreeEntry->pre = pEntry->pre;
|
|
pFreeEntry->pre->next = pFreeEntry;
|
|
pEntry->pre = pFreeEntry;
|
|
pFreeEntry->next = pEntry;
|
|
}
|
|
|
|
wd->timerList.freeCount--;
|
|
//zm_debug_msg1("free timer count = ", wd->timerList.freeCount);
|
|
|
|
return 0;
|
|
}
|
|
|
|
u16_t zfTimerCancel(zdev_t* dev, u16_t event)
|
|
{
|
|
struct zsTimerEntry *pEntry;
|
|
u8_t i, count;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
//zm_debug_msg2("event = ", event);
|
|
//zm_debug_msg1("free timer count(b) = ", wd->timerList.freeCount);
|
|
|
|
pEntry = wd->timerList.head;
|
|
count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount;
|
|
|
|
for( i=0; i<count; i++ )
|
|
{
|
|
if ( pEntry->event == event )
|
|
{
|
|
if ( pEntry == wd->timerList.head )
|
|
{ /* remove head entry */
|
|
wd->timerList.head = pEntry->next;
|
|
wd->timerList.tail->next = pEntry;
|
|
pEntry->pre = wd->timerList.tail;
|
|
wd->timerList.tail = pEntry;
|
|
pEntry = wd->timerList.head;
|
|
}
|
|
else
|
|
{ /* remove non-head entry */
|
|
pEntry->pre->next = pEntry->next;
|
|
pEntry->next->pre = pEntry->pre;
|
|
wd->timerList.tail->next = pEntry;
|
|
pEntry->pre = wd->timerList.tail;
|
|
wd->timerList.tail = pEntry;
|
|
pEntry = pEntry->next;
|
|
}
|
|
|
|
wd->timerList.freeCount++;
|
|
}
|
|
else
|
|
{
|
|
pEntry = pEntry->next;
|
|
}
|
|
}
|
|
|
|
//zm_debug_msg1("free timer count(a) = ", wd->timerList.freeCount);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void zfTimerClear(zdev_t* dev)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
wd->timerList.freeCount = ZM_MAX_TIMER_COUNT;
|
|
}
|
|
|
|
u16_t zfTimerCheckAndHandle(zdev_t* dev)
|
|
{
|
|
struct zsTimerEntry *pEntry;
|
|
struct zsTimerEntry *pTheLastEntry = NULL;
|
|
u16_t event[ZM_MAX_TIMER_COUNT];
|
|
u8_t i, j=0, count;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zmw_declare_for_critical_section();
|
|
|
|
if ( !wd->bTimerReady )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
zmw_enter_critical_section(dev);
|
|
|
|
pEntry = wd->timerList.head;
|
|
count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount;
|
|
|
|
for( i=0; i<count; i++ )
|
|
{
|
|
// prevent from the case of tick overflow
|
|
if ( ( pEntry->timer > wd->tick )&&
|
|
((pEntry->timer - wd->tick) < 1000000000) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
event[j++] = pEntry->event;
|
|
pTheLastEntry = pEntry;
|
|
pEntry = pEntry->next;
|
|
}
|
|
|
|
if ( j > 0 )
|
|
{
|
|
wd->timerList.tail->next = wd->timerList.head;
|
|
wd->timerList.head->pre = wd->timerList.tail;
|
|
wd->timerList.head = pEntry;
|
|
wd->timerList.tail = pTheLastEntry;
|
|
wd->timerList.freeCount += j;
|
|
//zm_debug_msg1("free timer count = ", wd->timerList.freeCount);
|
|
}
|
|
|
|
zmw_leave_critical_section(dev);
|
|
|
|
zfProcessEvent(dev, event, j);
|
|
|
|
return 0;
|
|
}
|
|
|
|
u32_t zfCoreSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type,
|
|
u16_t* mac, u32_t* key)
|
|
{
|
|
u32_t ret;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
zmw_declare_for_critical_section();
|
|
|
|
zmw_enter_critical_section(dev);
|
|
wd->sta.flagKeyChanging++;
|
|
zm_debug_msg1(" zfCoreSetKey++++ ", wd->sta.flagKeyChanging);
|
|
zmw_leave_critical_section(dev);
|
|
|
|
ret = zfHpSetKey(dev, user, keyId, type, mac, key);
|
|
return ret;
|
|
}
|
|
|
|
void zfCoreSetKeyComplete(zdev_t* dev)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
zmw_declare_for_critical_section();
|
|
|
|
#if 0
|
|
wd->sta.flagKeyChanging = 0;
|
|
#else
|
|
if(wd->sta.flagKeyChanging)
|
|
{
|
|
zmw_enter_critical_section(dev);
|
|
wd->sta.flagKeyChanging--;
|
|
zmw_leave_critical_section(dev);
|
|
}
|
|
#endif
|
|
zm_debug_msg1(" zfCoreSetKeyComplete--- ", wd->sta.flagKeyChanging);
|
|
|
|
zfPushVtxq(dev);
|
|
}
|
|
|
|
void zfCoreHalInitComplete(zdev_t* dev)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
zmw_declare_for_critical_section();
|
|
|
|
zmw_enter_critical_section(dev);
|
|
wd->halState = ZM_HAL_STATE_RUNNING;
|
|
zmw_leave_critical_section(dev);
|
|
|
|
zfPushVtxq(dev);
|
|
}
|
|
|
|
void zfCoreMacAddressNotify(zdev_t* dev, u8_t* addr)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
wd->macAddr[0] = addr[0] | ((u16_t)addr[1]<<8);
|
|
wd->macAddr[1] = addr[2] | ((u16_t)addr[3]<<8);
|
|
wd->macAddr[2] = addr[4] | ((u16_t)addr[5]<<8);
|
|
|
|
|
|
//zfHpSetMacAddress(dev, wd->macAddr, 0);
|
|
if (wd->zfcbMacAddressNotify != NULL)
|
|
{
|
|
wd->zfcbMacAddressNotify(dev, addr);
|
|
}
|
|
}
|
|
|
|
void zfCoreSetIsoName(zdev_t* dev, u8_t* isoName)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
wd->ws.countryIsoName[0] = isoName[0];
|
|
wd->ws.countryIsoName[1] = isoName[1];
|
|
wd->ws.countryIsoName[2] = '\0';
|
|
}
|
|
|
|
|
|
extern void zfScanMgrScanEventStart(zdev_t* dev);
|
|
extern u8_t zfScanMgrScanEventTimeout(zdev_t* dev);
|
|
extern void zfScanMgrScanEventRetry(zdev_t* dev);
|
|
|
|
void zfProcessEvent(zdev_t* dev, u16_t* eventArray, u8_t eventCount)
|
|
{
|
|
u8_t i, j, bypass = FALSE;
|
|
u16_t eventBypass[32];
|
|
u8_t eventBypassCount = 0;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zmw_declare_for_critical_section();
|
|
|
|
zfZeroMemory((u8_t*) eventBypass, 64);
|
|
|
|
for( i=0; i<eventCount; i++ )
|
|
{
|
|
for( j=0; j<eventBypassCount; j++ )
|
|
{
|
|
if ( eventBypass[j] == eventArray[i] )
|
|
{
|
|
bypass = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( bypass )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
switch( eventArray[i] )
|
|
{
|
|
case ZM_EVENT_SCAN:
|
|
{
|
|
zfScanMgrScanEventStart(dev);
|
|
eventBypass[eventBypassCount++] = ZM_EVENT_IN_SCAN;
|
|
eventBypass[eventBypassCount++] = ZM_EVENT_TIMEOUT_SCAN;
|
|
}
|
|
break;
|
|
|
|
case ZM_EVENT_TIMEOUT_SCAN:
|
|
{
|
|
u8_t res;
|
|
|
|
res = zfScanMgrScanEventTimeout(dev);
|
|
if ( res == 0 )
|
|
{
|
|
eventBypass[eventBypassCount++] = ZM_EVENT_TIMEOUT_SCAN;
|
|
}
|
|
else if ( res == 1 )
|
|
{
|
|
eventBypass[eventBypassCount++] = ZM_EVENT_IN_SCAN;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ZM_EVENT_IBSS_MONITOR:
|
|
{
|
|
zfStaIbssMonitoring(dev, 0);
|
|
}
|
|
break;
|
|
|
|
case ZM_EVENT_IN_SCAN:
|
|
{
|
|
zfScanMgrScanEventRetry(dev);
|
|
}
|
|
break;
|
|
|
|
case ZM_EVENT_CM_TIMER:
|
|
{
|
|
zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_TIMER");
|
|
|
|
wd->sta.cmMicFailureCount = 0;
|
|
}
|
|
break;
|
|
|
|
case ZM_EVENT_CM_DISCONNECT:
|
|
{
|
|
zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_DISCONNECT");
|
|
|
|
zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT);
|
|
|
|
zmw_enter_critical_section(dev);
|
|
//zfTimerSchedule(dev, ZM_EVENT_CM_BLOCK_TIMER,
|
|
// ZM_TICK_CM_BLOCK_TIMEOUT);
|
|
|
|
/* Timer Resolution on WinXP is 15/16 ms */
|
|
/* Decrease Time offset for <XP> Counter Measure */
|
|
zfTimerSchedule(dev, ZM_EVENT_CM_BLOCK_TIMER,
|
|
ZM_TICK_CM_BLOCK_TIMEOUT - ZM_TICK_CM_BLOCK_TIMEOUT_OFFSET);
|
|
|
|
zmw_leave_critical_section(dev);
|
|
wd->sta.cmMicFailureCount = 0;
|
|
//zfiWlanDisable(dev);
|
|
zfHpResetKeyCache(dev);
|
|
if (wd->zfcbConnectNotify != NULL)
|
|
{
|
|
wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_DISCONNECT_MIC_FAIL,
|
|
wd->sta.bssid);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ZM_EVENT_CM_BLOCK_TIMER:
|
|
{
|
|
zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_BLOCK_TIMER");
|
|
|
|
//zmw_enter_critical_section(dev);
|
|
wd->sta.cmDisallowSsidLength = 0;
|
|
if ( wd->sta.bAutoReconnect )
|
|
{
|
|
zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_BLOCK_TIMER:bAutoReconnect!=0");
|
|
zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
|
|
zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
|
|
}
|
|
//zmw_leave_critical_section(dev);
|
|
}
|
|
break;
|
|
|
|
case ZM_EVENT_TIMEOUT_ADDBA:
|
|
{
|
|
if (!wd->addbaComplete && (wd->addbaCount < 5))
|
|
{
|
|
zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0);
|
|
wd->addbaCount++;
|
|
zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100);
|
|
}
|
|
else
|
|
{
|
|
zfTimerCancel(dev, ZM_EVENT_TIMEOUT_ADDBA);
|
|
}
|
|
}
|
|
break;
|
|
|
|
#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
|
|
case ZM_EVENT_TIMEOUT_PERFORMANCE:
|
|
{
|
|
zfiPerformanceRefresh(dev);
|
|
}
|
|
break;
|
|
#endif
|
|
case ZM_EVENT_SKIP_COUNTERMEASURE:
|
|
//enable the Countermeasure
|
|
{
|
|
zm_debug_msg0("Countermeasure : Enable MIC Check ");
|
|
wd->TKIP_Group_KeyChanging = 0x0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void zfBssInfoCreate(zdev_t* dev)
|
|
{
|
|
u8_t i;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zmw_declare_for_critical_section();
|
|
|
|
zmw_enter_critical_section(dev);
|
|
|
|
wd->sta.bssList.bssCount = 0;
|
|
wd->sta.bssList.head = NULL;
|
|
wd->sta.bssList.tail = NULL;
|
|
wd->sta.bssInfoArrayHead = 0;
|
|
wd->sta.bssInfoArrayTail = 0;
|
|
wd->sta.bssInfoFreeCount = ZM_MAX_BSS;
|
|
|
|
for( i=0; i< ZM_MAX_BSS; i++ )
|
|
{
|
|
//wd->sta.bssInfoArray[i] = &(wd->sta.bssInfoPool[i]);
|
|
wd->sta.bssInfoArray[i] = zfwMemAllocate(dev, sizeof(struct zsBssInfo));
|
|
|
|
}
|
|
|
|
zmw_leave_critical_section(dev);
|
|
}
|
|
|
|
void zfBssInfoDestroy(zdev_t* dev)
|
|
{
|
|
u8_t i;
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zfBssInfoRefresh(dev, 1);
|
|
|
|
for( i=0; i< ZM_MAX_BSS; i++ )
|
|
{
|
|
if (wd->sta.bssInfoArray[i] != NULL)
|
|
{
|
|
zfwMemFree(dev, wd->sta.bssInfoArray[i], sizeof(struct zsBssInfo));
|
|
}
|
|
else
|
|
{
|
|
zm_assert(0);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
struct zsBssInfo* zfBssInfoAllocate(zdev_t* dev)
|
|
{
|
|
struct zsBssInfo* pBssInfo;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
if (wd->sta.bssInfoFreeCount == 0)
|
|
return NULL;
|
|
|
|
pBssInfo = wd->sta.bssInfoArray[wd->sta.bssInfoArrayHead];
|
|
wd->sta.bssInfoArray[wd->sta.bssInfoArrayHead] = NULL;
|
|
wd->sta.bssInfoArrayHead = (wd->sta.bssInfoArrayHead + 1) & (ZM_MAX_BSS - 1);
|
|
wd->sta.bssInfoFreeCount--;
|
|
|
|
zfZeroMemory((u8_t*)pBssInfo, sizeof(struct zsBssInfo));
|
|
|
|
return pBssInfo;
|
|
}
|
|
|
|
void zfBssInfoFree(zdev_t* dev, struct zsBssInfo* pBssInfo)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zm_assert(wd->sta.bssInfoArray[wd->sta.bssInfoArrayTail] == NULL);
|
|
|
|
pBssInfo->signalStrength = pBssInfo->signalQuality = 0;
|
|
pBssInfo->sortValue = 0;
|
|
|
|
wd->sta.bssInfoArray[wd->sta.bssInfoArrayTail] = pBssInfo;
|
|
wd->sta.bssInfoArrayTail = (wd->sta.bssInfoArrayTail + 1) & (ZM_MAX_BSS - 1);
|
|
wd->sta.bssInfoFreeCount++;
|
|
}
|
|
|
|
void zfBssInfoReorderList(zdev_t* dev)
|
|
{
|
|
struct zsBssInfo* pBssInfo = NULL;
|
|
struct zsBssInfo* pInsBssInfo = NULL;
|
|
struct zsBssInfo* pNextBssInfo = NULL;
|
|
struct zsBssInfo* pPreBssInfo = NULL;
|
|
u8_t i = 0;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zmw_declare_for_critical_section();
|
|
|
|
zmw_enter_critical_section(dev);
|
|
|
|
if (wd->sta.bssList.bssCount > 1)
|
|
{
|
|
pInsBssInfo = wd->sta.bssList.head;
|
|
wd->sta.bssList.tail = pInsBssInfo;
|
|
pBssInfo = pInsBssInfo->next;
|
|
pInsBssInfo->next = NULL;
|
|
while (pBssInfo != NULL)
|
|
{
|
|
i = 0;
|
|
while (1)
|
|
{
|
|
// if (pBssInfo->signalStrength >= pInsBssInfo->signalStrength)
|
|
if( pBssInfo->sortValue >= pInsBssInfo->sortValue)
|
|
{
|
|
if (i==0)
|
|
{
|
|
//Insert BssInfo to head
|
|
wd->sta.bssList.head = pBssInfo;
|
|
pNextBssInfo = pBssInfo->next;
|
|
pBssInfo->next = pInsBssInfo;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
//Insert BssInfo to neither head nor tail
|
|
pPreBssInfo->next = pBssInfo;
|
|
pNextBssInfo = pBssInfo->next;
|
|
pBssInfo->next = pInsBssInfo;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pInsBssInfo->next != NULL)
|
|
{
|
|
//Signal strength smaller than current BssInfo, check next
|
|
pPreBssInfo = pInsBssInfo;
|
|
pInsBssInfo = pInsBssInfo->next;
|
|
}
|
|
else
|
|
{
|
|
//Insert BssInfo to tail
|
|
pInsBssInfo->next = pBssInfo;
|
|
pNextBssInfo = pBssInfo->next;
|
|
wd->sta.bssList.tail = pBssInfo;
|
|
pBssInfo->next = NULL;
|
|
break;
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
pBssInfo = pNextBssInfo;
|
|
pInsBssInfo = wd->sta.bssList.head;
|
|
}
|
|
} //if (wd->sta.bssList.bssCount > 1)
|
|
|
|
zmw_leave_critical_section(dev);
|
|
}
|
|
|
|
void zfBssInfoInsertToList(zdev_t* dev, struct zsBssInfo* pBssInfo)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zm_assert(pBssInfo);
|
|
|
|
//zm_debug_msg2("pBssInfo = ", pBssInfo);
|
|
|
|
if ( wd->sta.bssList.bssCount == 0 )
|
|
{
|
|
wd->sta.bssList.head = pBssInfo;
|
|
wd->sta.bssList.tail = pBssInfo;
|
|
}
|
|
else
|
|
{
|
|
wd->sta.bssList.tail->next = pBssInfo;
|
|
wd->sta.bssList.tail = pBssInfo;
|
|
}
|
|
|
|
pBssInfo->next = NULL;
|
|
wd->sta.bssList.bssCount++;
|
|
|
|
//zm_debug_msg2("bss count = ", wd->sta.bssList.bssCount);
|
|
}
|
|
|
|
void zfBssInfoRemoveFromList(zdev_t* dev, struct zsBssInfo* pBssInfo)
|
|
{
|
|
struct zsBssInfo* pNowBssInfo;
|
|
struct zsBssInfo* pPreBssInfo = NULL;
|
|
u8_t i;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
zm_assert(pBssInfo);
|
|
zm_assert(wd->sta.bssList.bssCount);
|
|
|
|
//zm_debug_msg2("pBssInfo = ", pBssInfo);
|
|
|
|
pNowBssInfo = wd->sta.bssList.head;
|
|
|
|
for( i=0; i<wd->sta.bssList.bssCount; i++ )
|
|
{
|
|
if ( pNowBssInfo == pBssInfo )
|
|
{
|
|
if ( i == 0 )
|
|
{ /* remove head */
|
|
wd->sta.bssList.head = pBssInfo->next;
|
|
}
|
|
else
|
|
{
|
|
pPreBssInfo->next = pBssInfo->next;
|
|
}
|
|
|
|
if ( i == (wd->sta.bssList.bssCount - 1) )
|
|
{ /* remove tail */
|
|
wd->sta.bssList.tail = pPreBssInfo;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
pPreBssInfo = pNowBssInfo;
|
|
pNowBssInfo = pNowBssInfo->next;
|
|
}
|
|
|
|
zm_assert(i != wd->sta.bssList.bssCount);
|
|
wd->sta.bssList.bssCount--;
|
|
|
|
//zm_debug_msg2("bss count = ", wd->sta.bssList.bssCount);
|
|
}
|
|
|
|
void zfBssInfoRefresh(zdev_t* dev, u16_t mode)
|
|
{
|
|
struct zsBssInfo* pBssInfo;
|
|
struct zsBssInfo* pNextBssInfo;
|
|
u8_t i, bssCount;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
pBssInfo = wd->sta.bssList.head;
|
|
bssCount = wd->sta.bssList.bssCount;
|
|
|
|
for( i=0; i<bssCount; i++ )
|
|
{
|
|
if (mode == 1)
|
|
{
|
|
pNextBssInfo = pBssInfo->next;
|
|
zfBssInfoRemoveFromList(dev, pBssInfo);
|
|
zfBssInfoFree(dev, pBssInfo);
|
|
pBssInfo = pNextBssInfo;
|
|
}
|
|
else
|
|
{
|
|
if ( pBssInfo->flag & ZM_BSS_INFO_VALID_BIT )
|
|
{ /* this one must be kept */
|
|
pBssInfo->flag &= ~ZM_BSS_INFO_VALID_BIT;
|
|
pBssInfo = pBssInfo->next;
|
|
}
|
|
else
|
|
{
|
|
#define ZM_BSS_CACHE_TIME_IN_MS 20000
|
|
if ((wd->tick - pBssInfo->tick) > (ZM_BSS_CACHE_TIME_IN_MS/ZM_MS_PER_TICK))
|
|
{
|
|
pNextBssInfo = pBssInfo->next;
|
|
zfBssInfoRemoveFromList(dev, pBssInfo);
|
|
zfBssInfoFree(dev, pBssInfo);
|
|
pBssInfo = pNextBssInfo;
|
|
}
|
|
else
|
|
{
|
|
pBssInfo = pBssInfo->next;
|
|
}
|
|
}
|
|
}
|
|
} //for( i=0; i<bssCount; i++ )
|
|
return;
|
|
}
|
|
|
|
void zfDumpSSID(u8_t length, u8_t *value)
|
|
{
|
|
u8_t buf[50];
|
|
u8_t tmpLength = length;
|
|
|
|
if ( tmpLength > 49 )
|
|
{
|
|
tmpLength = 49;
|
|
}
|
|
|
|
zfMemoryCopy(buf, value, tmpLength);
|
|
buf[tmpLength] = '\0';
|
|
//printk("SSID: %s\n", buf);
|
|
//zm_debug_msg_s("ssid = ", value);
|
|
}
|
|
|
|
void zfCoreReinit(zdev_t* dev)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
wd->sta.flagKeyChanging = 0;
|
|
wd->sta.flagFreqChanging = 0;
|
|
}
|
|
|
|
void zfGenerateRandomBSSID(zdev_t* dev, u8_t *MACAddr, u8_t *BSSID)
|
|
{
|
|
//ULONGLONG time;
|
|
u32_t time;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
time = wd->tick;
|
|
|
|
//
|
|
// Initialize the random BSSID to be the same as MAC address.
|
|
//
|
|
|
|
// RtlCopyMemory(BSSID, MACAddr, sizeof(DOT11_MAC_ADDRESS));
|
|
zfMemoryCopy(BSSID, MACAddr, 6);
|
|
|
|
//
|
|
// Get the system time in 10 millisecond.
|
|
//
|
|
|
|
// NdisGetCurrentSystemTime((PLARGE_INTEGER)&time);
|
|
// time /= 100000;
|
|
|
|
//
|
|
// Randomize the first 4 bytes of BSSID.
|
|
//
|
|
|
|
BSSID[0] ^= (u8_t)(time & 0xff);
|
|
BSSID[0] &= ~0x01; // Turn off multicast bit
|
|
BSSID[0] |= 0x02; // Turn on local bit
|
|
|
|
time >>= 8;
|
|
BSSID[1] ^= (u8_t)(time & 0xff);
|
|
|
|
time >>= 8;
|
|
BSSID[2] ^= (u8_t)(time & 0xff);
|
|
|
|
time >>= 8;
|
|
BSSID[3] ^= (u8_t)(time & 0xff);
|
|
}
|
|
|
|
u8_t zfiWlanGetDestAddrFromBuf(zdev_t *dev, zbuf_t *buf, u16_t *macAddr)
|
|
{
|
|
#ifdef ZM_ENABLE_NATIVE_WIFI
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
|
|
{
|
|
/* DA */
|
|
macAddr[0] = zmw_tx_buf_readh(dev, buf, 16);
|
|
macAddr[1] = zmw_tx_buf_readh(dev, buf, 18);
|
|
macAddr[2] = zmw_tx_buf_readh(dev, buf, 20);
|
|
}
|
|
else if ( wd->wlanMode == ZM_MODE_IBSS )
|
|
{
|
|
/* DA */
|
|
macAddr[0] = zmw_tx_buf_readh(dev, buf, 4);
|
|
macAddr[1] = zmw_tx_buf_readh(dev, buf, 6);
|
|
macAddr[2] = zmw_tx_buf_readh(dev, buf, 8);
|
|
}
|
|
else if ( wd->wlanMode == ZM_MODE_AP )
|
|
{
|
|
/* DA */
|
|
macAddr[0] = zmw_tx_buf_readh(dev, buf, 4);
|
|
macAddr[1] = zmw_tx_buf_readh(dev, buf, 6);
|
|
macAddr[2] = zmw_tx_buf_readh(dev, buf, 8);
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
#else
|
|
/* DA */
|
|
macAddr[0] = zmw_tx_buf_readh(dev, buf, 0);
|
|
macAddr[1] = zmw_tx_buf_readh(dev, buf, 2);
|
|
macAddr[2] = zmw_tx_buf_readh(dev, buf, 4);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Leave an empty line below to remove warning message on some compiler */
|
|
|
|
u16_t zfFindCleanFrequency(zdev_t* dev, u32_t adhocMode)
|
|
{
|
|
u8_t i, j;
|
|
u16_t returnChannel;
|
|
u16_t count_24G = 0, min24GIndex = 0;
|
|
u16_t count_5G = 0, min5GIndex = 0;
|
|
u16_t CombinationBssNumberIn24G[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
u16_t BssNumberIn24G[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
u16_t Array_24G[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
u16_t BssNumberIn5G[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
u16_t Array_5G[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
struct zsBssInfo* pBssInfo;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
if ((pBssInfo = wd->sta.bssList.head) == NULL)
|
|
{
|
|
if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G ||
|
|
adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG )
|
|
{
|
|
returnChannel = zfChGetFirst2GhzChannel(dev);
|
|
}
|
|
else
|
|
{
|
|
returnChannel = zfChGetFirst5GhzChannel(dev);
|
|
}
|
|
|
|
return returnChannel;
|
|
}
|
|
|
|
/* #1 Get Allowed Channel following Country Code ! */
|
|
zmw_declare_for_critical_section();
|
|
zmw_enter_critical_section(dev);
|
|
for (i = 0; i < wd->regulationTable.allowChannelCnt; i++)
|
|
{
|
|
if (wd->regulationTable.allowChannel[i].channel < 3000)
|
|
{ // 2.4GHz
|
|
Array_24G[count_24G] = wd->regulationTable.allowChannel[i].channel;
|
|
count_24G++;
|
|
}
|
|
else
|
|
{ // 5GHz
|
|
count_5G++;
|
|
Array_5G[i] = wd->regulationTable.allowChannel[i].channel;
|
|
}
|
|
}
|
|
zmw_leave_critical_section(dev);
|
|
|
|
while( pBssInfo != NULL )
|
|
{
|
|
/* #2_1 Count BSS number in some specificed frequency in 2.4GHz band ! */
|
|
if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G ||
|
|
adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG )
|
|
{
|
|
for( i=0; i<=(count_24G+3); i++ )
|
|
{
|
|
if( pBssInfo->frequency == Array_24G[i] )
|
|
{ // Array_24G[0] correspond to BssNumberIn24G[2]
|
|
BssNumberIn24G[pBssInfo->channel+1]++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* #2_2 Count BSS number in some specificed frequency in 5GHz band ! */
|
|
if( adhocMode == ZM_ADHOCBAND_A || adhocMode == ZM_ADHOCBAND_ABG )
|
|
{
|
|
for( i=0; i<count_5G; i++ )
|
|
{ // 5GHz channel is not equal to array index
|
|
if( pBssInfo->frequency == Array_5G[i] )
|
|
{ // Array_5G[0] correspond to BssNumberIn5G[0]
|
|
BssNumberIn5G[i]++;
|
|
}
|
|
}
|
|
}
|
|
|
|
pBssInfo = pBssInfo->next;
|
|
}
|
|
|
|
#if 0
|
|
for(i=0; i<=(count_24G+3); i++)
|
|
{
|
|
printk("2.4GHz Before combin, %d BSS network : %d", i, BssNumberIn24G[i]);
|
|
}
|
|
|
|
for(i=0; i<count_5G; i++)
|
|
{
|
|
printk("5GHz Before combin, %d BSS network : %d", i, BssNumberIn5G[i]);
|
|
}
|
|
#endif
|
|
|
|
if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G ||
|
|
adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG )
|
|
{
|
|
/* #3_1 Count BSS number that influence the specificed frequency in 2.4GHz ! */
|
|
for( j=0; j<count_24G; j++ )
|
|
{
|
|
CombinationBssNumberIn24G[j] = BssNumberIn24G[j] + BssNumberIn24G[j+1] +
|
|
BssNumberIn24G[j+2] + BssNumberIn24G[j+3] +
|
|
BssNumberIn24G[j+4];
|
|
//printk("After combine, the number of BSS network channel %d is %d",
|
|
// j , CombinationBssNumberIn24G[j]);
|
|
}
|
|
|
|
/* #4_1 Find the less utilized frequency in 2.4GHz band ! */
|
|
min24GIndex = zfFindMinimumUtilizationChannelIndex(dev, CombinationBssNumberIn24G, count_24G);
|
|
}
|
|
|
|
/* #4_2 Find the less utilized frequency in 5GHz band ! */
|
|
if( adhocMode == ZM_ADHOCBAND_A || adhocMode == ZM_ADHOCBAND_ABG )
|
|
{
|
|
min5GIndex = zfFindMinimumUtilizationChannelIndex(dev, BssNumberIn5G, count_5G);
|
|
}
|
|
|
|
if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || adhocMode == ZM_ADHOCBAND_BG )
|
|
{
|
|
return Array_24G[min24GIndex];
|
|
}
|
|
else if( adhocMode == ZM_ADHOCBAND_A )
|
|
{
|
|
return Array_5G[min5GIndex];
|
|
}
|
|
else if( adhocMode == ZM_ADHOCBAND_ABG )
|
|
{
|
|
if ( CombinationBssNumberIn24G[min24GIndex] <= BssNumberIn5G[min5GIndex] )
|
|
return Array_24G[min24GIndex];
|
|
else
|
|
return Array_5G[min5GIndex];
|
|
}
|
|
else
|
|
return 2412;
|
|
}
|
|
|
|
u16_t zfFindMinimumUtilizationChannelIndex(zdev_t* dev, u16_t* array, u16_t count)
|
|
{
|
|
u8_t i;
|
|
u16_t tempMinIndex, tempMinValue;
|
|
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
i = 1;
|
|
tempMinIndex = 0;
|
|
tempMinValue = array[tempMinIndex];
|
|
while( i< count )
|
|
{
|
|
if( array[i] < tempMinValue )
|
|
{
|
|
tempMinValue = array[i];
|
|
tempMinIndex = i;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return tempMinIndex;
|
|
}
|
|
|
|
u8_t zfCompareWithBssid(zdev_t* dev, u16_t* bssid)
|
|
{
|
|
zmw_get_wlan_dev(dev);
|
|
|
|
if ( zfMemoryIsEqual((u8_t*)bssid, (u8_t*)wd->sta.bssid, 6) )
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|