void zfCoreReinit(zdev_t* dev) { zmw_get_wlan_dev(dev); wd->sta.flagKeyChanging = 0; wd->sta.flagFreqChanging = 0; }
/* WLAN hardware will be shutdown and all resource will be release */ u16_t zfiWlanClose(zdev_t *dev) { zmw_get_wlan_dev(dev); zm_msg0_init(ZM_LV_0, "enter"); wd->state = ZM_WLAN_STATE_CLOSEDED; /* zfiWlanDisable(dev, 1); */ zfWlanReset(dev); zfHpStopRecv(dev); /* Disable MAC */ /* Disable PHY */ /* Disable RF */ zfHpRelease(dev); zfQueueDestroy(dev, wd->ap.uapsdQ); zfQueueDestroy(dev, wd->sta.uapsdQ); zfBssInfoDestroy(dev); #ifdef ZM_ENABLE_AGGREGATION /* add by honda */ zfAggRxFreeBuf(dev, 1); /* 1 for release structure memory */ /* end of add by honda */ #endif zm_msg0_init(ZM_LV_0, "exit"); return 0; }
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] = (struct zsBssInfo*)zfwMemAllocate(dev, sizeof(struct zsBssInfo)); } zmw_leave_critical_section(dev); }
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; }
u16_t zfGetCmd(zdev_t* dev, u32_t* cmd, u16_t* cmdLen, u16_t* src, u8_t** buf) { u16_t i; struct zsHpPriv* hpPriv; zmw_get_wlan_dev(dev); hpPriv=wd->hpPrivate; if (hpPriv->cmdTail == hpPriv->cmdHead) { return 3; } *cmdLen = hpPriv->cmdQ[hpPriv->cmdHead].cmdLen; *src = hpPriv->cmdQ[hpPriv->cmdHead].src; *buf = hpPriv->cmdQ[hpPriv->cmdHead].buf; for (i=0; i<((*cmdLen)>>2); i++) { cmd[i] = hpPriv->cmdQ[hpPriv->cmdHead].cmd[i]; } hpPriv->cmdHead = (hpPriv->cmdHead+1) & (ZM_CMD_QUEUE_SIZE-1); return 0; }
u16_t zfPutCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf) { u16_t i; struct zsHpPriv* hpPriv; zmw_get_wlan_dev(dev); hpPriv=wd->hpPrivate; /* Make sure command length < ZM_MAX_CMD_SIZE */ zm_assert(cmdLen <= ZM_MAX_CMD_SIZE); /* Make sure command queue not full */ //zm_assert(((hpPriv->cmdTail+1) & (ZM_CMD_QUEUE_SIZE-1)) != hpPriv->cmdHead); if (((hpPriv->cmdTail+1) & (ZM_CMD_QUEUE_SIZE-1)) == hpPriv->cmdHead ) { zm_debug_msg0("CMD queue full!!"); return 0; } hpPriv->cmdQ[hpPriv->cmdTail].cmdLen = cmdLen; hpPriv->cmdQ[hpPriv->cmdTail].src = src; hpPriv->cmdQ[hpPriv->cmdTail].buf = buf; for (i=0; i<(cmdLen>>2); i++) { hpPriv->cmdQ[hpPriv->cmdTail].cmd[i] = cmd[i]; } hpPriv->cmdTail = (hpPriv->cmdTail+1) & (ZM_CMD_QUEUE_SIZE-1); return 0; }
void zfSendCmdEx(zdev_t* dev) { u32_t ncmd[ZM_MAX_CMD_SIZE/4]; u16_t ncmdLen = 0; u16_t cmdFlag = 0; u16_t i; struct zsHpPriv* hpPriv; zmw_get_wlan_dev(dev); hpPriv=wd->hpPrivate; zmw_declare_for_critical_section(); zmw_enter_critical_section(dev); if (hpPriv->cmdPending == 0) { if (hpPriv->cmdTail != hpPriv->cmdSend) { cmdFlag = 1; /* Get queueing command */ ncmdLen= hpPriv->cmdQ[hpPriv->cmdSend].cmdLen; for (i=0; i<(ncmdLen>>2); i++) { ncmd[i] = hpPriv->cmdQ[hpPriv->cmdSend].cmd[i]; } hpPriv->cmdSend = (hpPriv->cmdSend+1) & (ZM_CMD_QUEUE_SIZE-1); hpPriv->cmdPending = 1; } }
void zfDeAmsdu(zdev_t* dev, zbuf_t* buf, u16_t vap, u8_t encryMode) { u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL; zbuf_t* subframeBuf; zmw_get_wlan_dev(dev); ZM_BUFFER_TRACE(dev, buf) if (encryMode == ZM_AES || encryMode == ZM_TKIP) { offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV); } else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128) { offset += ZM_SIZE_OF_IV; } /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */ while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL) { wd->commTally.NotifyNDISRxFrmCnt++; if (wd->zfcbRecvEth != NULL) { wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap); ZM_PERFORMANCE_RX_MSDU(dev, wd->tick); } } zfwBufFree(dev, buf, 0); return; }
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'; }
void zfHpAniAttach(zdev_t *dev) { #define N(a) (sizeof(a) / sizeof(a[0])) u32_t i; struct zsHpPriv *HpPriv; const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; const int coarseHigh[] = { -14, -14, -14, -14, -12 }; const int coarseLow[] = { -64, -64, -64, -64, -70 }; const int firpwr[] = { -78, -78, -78, -78, -80 }; zmw_get_wlan_dev(dev); HpPriv = (struct zsHpPriv *)wd->hpPrivate; for (i = 0; i < 5; i++) { HpPriv->totalSizeDesired[i] = totalSizeDesired[i]; HpPriv->coarseHigh[i] = coarseHigh[i]; HpPriv->coarseLow[i] = coarseLow[i]; HpPriv->firpwr[i] = firpwr[i]; } /* owl has phy counters */ HpPriv->hasHwPhyCounters = 1; memset((char *)&HpPriv->ani, 0, sizeof(HpPriv->ani)); for (i = 0; i < ARRAY_SIZE(HpPriv->ani); i++) { /* New ANI stuff */ HpPriv->ani[i].ofdmTrigHigh = ZM_HAL_ANI_OFDM_TRIG_HIGH; HpPriv->ani[i].ofdmTrigLow = ZM_HAL_ANI_OFDM_TRIG_LOW; HpPriv->ani[i].cckTrigHigh = ZM_HAL_ANI_CCK_TRIG_HIGH; HpPriv->ani[i].cckTrigLow = ZM_HAL_ANI_CCK_TRIG_LOW; HpPriv->ani[i].rssiThrHigh = ZM_HAL_ANI_RSSI_THR_HIGH; HpPriv->ani[i].rssiThrLow = ZM_HAL_ANI_RSSI_THR_LOW; HpPriv->ani[i].ofdmWeakSigDetectOff = !ZM_HAL_ANI_USE_OFDM_WEAK_SIG; HpPriv->ani[i].cckWeakSigThreshold = ZM_HAL_ANI_CCK_WEAK_SIG_THR; HpPriv->ani[i].spurImmunityLevel = ZM_HAL_ANI_SPUR_IMMUNE_LVL; HpPriv->ani[i].firstepLevel = ZM_HAL_ANI_FIRSTEP_LVL; if (HpPriv->hasHwPhyCounters) { HpPriv->ani[i].ofdmPhyErrBase = 0;//AR_PHY_COUNTMAX - ZM_HAL_ANI_OFDM_TRIG_HIGH; HpPriv->ani[i].cckPhyErrBase = 0;//AR_PHY_COUNTMAX - ZM_HAL_ANI_CCK_TRIG_HIGH; } } if (HpPriv->hasHwPhyCounters) { //zm_debug_msg2("Setting OfdmErrBase = 0x", HpPriv->ani[0].ofdmPhyErrBase); //zm_debug_msg2("Setting cckErrBase = 0x", HpPriv->ani[0].cckPhyErrBase); //OS_REG_WRITE(ah, AR_PHY_ERR_1, HpPriv->ani[0].ofdmPhyErrBase); //OS_REG_WRITE(ah, AR_PHY_ERR_2, HpPriv->ani[0].cckPhyErrBase); } HpPriv->aniPeriod = ZM_HAL_ANI_PERIOD; //if (ath_hal_enableANI) HpPriv->procPhyErr |= ZM_HAL_PROCESS_ANI; HpPriv->stats.ast_nodestats.ns_avgbrssi = ZM_RSSI_DUMMY_MARKER; HpPriv->stats.ast_nodestats.ns_avgrssi = ZM_RSSI_DUMMY_MARKER; HpPriv->stats.ast_nodestats.ns_avgtxrssi = ZM_RSSI_DUMMY_MARKER; #undef N }
void zfScanMgrInit(zdev_t* dev) { zmw_get_wlan_dev(dev); wd->sta.scanMgr.scanReqs[0] = 0; wd->sta.scanMgr.scanReqs[1] = 0; wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE; wd->sta.scanMgr.scanStartDelay = 3; //wd->sta.scanMgr.scanStartDelay = 0; }
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); }
s32_t BEACON_RSSI(zdev_t *dev) { s32_t rssi; struct zsHpPriv *HpPriv; zmw_get_wlan_dev(dev); HpPriv = (struct zsHpPriv *)wd->hpPrivate; rssi = ZM_HAL_EP_RND(HpPriv->stats.ast_nodestats.ns_avgbrssi, ZM_HAL_RSSI_EP_MULTIPLIER); return rssi; }
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; } }
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++; }
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; }
void zfScanMgrScanAck(zdev_t* dev) { zmw_get_wlan_dev(dev); zmw_declare_for_critical_section(); zmw_enter_critical_section(dev); wd->sta.scanMgr.scanStartDelay = 3; //wd->sta.scanMgr.scanStartDelay = 0; zmw_leave_critical_section(dev); return; }
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); } }
u8_t zfRateCtrlNextLowerRate(zdev_t* dev, struct zsRcCell* rcCell) { zmw_get_wlan_dev(dev); if (rcCell->currentRateIndex > 0) { rcCell->currentRateIndex--; rcCell->currentRate = rcCell->operationRateSet[rcCell->currentRateIndex]; } zm_msg1_tx(ZM_LV_0, "Lower Tx Rate=", rcCell->currentRate); //DbgPrint("Lower Tx Rate=%d", rcCell->currentRate); rcCell->failCount = rcCell->txCount = 0; rcCell->lasttxCount = 0; rcCell->lastTime = wd->tick; return rcCell->currentRate; }
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; }
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 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 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); }
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 zfHpAniCckErrTrigger(zdev_t* dev) { struct zsAniState *aniState; s32_t rssi; struct zsHpPriv *HpPriv; zmw_get_wlan_dev(dev); HpPriv = (struct zsHpPriv*)wd->hpPrivate; //HALASSERT(chan != NULL); if ((HpPriv->procPhyErr & ZM_HAL_PROCESS_ANI) == 0) return; /* first, raise noise immunity level, up to max */ aniState = HpPriv->curani; if (aniState->noiseImmunityLevel < ZM_HAL_NOISE_IMMUNE_MAX) { zfHpAniControl(dev, ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1); return; } rssi = BEACON_RSSI(dev); if (rssi > aniState->rssiThrLow) { /* * Beacon signal in mid and high range, raise firsteplevel. */ if (aniState->firstepLevel < ZM_HAL_FIRST_STEP_MAX) zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); } else { /* * Beacon rssi is low, zero firstepLevel to maximize * CCK sensitivity. */ if (wd->frequency < 3000) { if (aniState->firstepLevel > 0) zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, 0); } } }
void zfScanMgrScanEventRetry(zdev_t* dev) { zmw_get_wlan_dev(dev); if ( !wd->sta.bChannelScan ) { return; } if ( !wd->sta.bPassiveScan ) { zfScanSendProbeRequest(dev); #if 0 zmw_enter_critical_section(dev); zfTimerSchedule(dev, ZM_EVENT_IN_SCAN, ZM_TICK_IN_SCAN); zmw_leave_critical_section(dev); #endif } }
void zfInitCmdQueue(zdev_t* dev) { struct zsHpPriv* hpPriv; zmw_get_wlan_dev(dev); hpPriv = (struct zsHpPriv*)(wd->hpPrivate); zmw_declare_for_critical_section(); zmw_enter_critical_section(dev); #ifdef ZM_XP_USB_MULTCMD hpPriv->cmdTail = hpPriv->cmdHead = hpPriv->cmdSend = 0; #else hpPriv->cmdTail = hpPriv->cmdHead = 0; #endif hpPriv->cmdPending = 0; hpPriv->cmd.delayWcmdCount = 0; zmw_leave_critical_section(dev); }
void zfCoreCwmBusy(zdev_t* dev, u16_t busy) { zmw_get_wlan_dev(dev); zm_msg1_mm(ZM_LV_0, "CwmBusy=", busy); if(wd->cwm.cw_mode == CWM_MODE20) { wd->cwm.cw_width = CWM_WIDTH20; return; } if(wd->cwm.cw_mode == CWM_MODE40) { wd->cwm.cw_width = CWM_WIDTH40; return; } if (busy) { wd->cwm.cw_width = CWM_WIDTH20; return; } if((wd->wlanMode == ZM_MODE_INFRASTRUCTURE || wd->wlanMode == ZM_MODE_PSEUDO || wd->wlanMode == ZM_MODE_IBSS)) { if (wd->sta.ie.HtCap.HtCapInfo && HTCAP_SupChannelWidthSet != 0 && wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_RecomTxWidthSet != 0 && (wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_ExtChannelOffsetAbove) == 1) { wd->cwm.cw_width = CWM_WIDTH40; } else { wd->cwm.cw_width = CWM_WIDTH20; } return; } if(wd->wlanMode == ZM_MODE_AP) { wd->cwm.cw_width = CWM_WIDTH40; } }
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 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; }