static void wlan_node_timeout(void *arg) { struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg; bss_t *bss, *nextBss; A_UINT8 myBssid[IEEE80211_ADDR_LEN]; wmi_get_current_bssid(nt->nt_wmip, myBssid); IEEE80211_NODE_LOCK(nt); bss = nt->nt_node_first; while (bss != NULL) { nextBss = bss->ni_list_next; if ((A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) && (bss->ni_tstamp <= A_MS_TICKGET())) { /* * free up all but the current bss - if set */ wlan_node_reclaim(nt, bss); } bss = nextBss; } IEEE80211_NODE_UNLOCK(nt); A_TIMEOUT_MS(&nt->nt_inact_timer, WLAN_NODE_INACT_TIMEOUT_MSEC, 0); }
/* * This routine is called to initialize the rate control parameters * in the SIB. It is called initially during system initialization * or when a station is associated with the AP. */ void rcSibInit(struct atheros_node *pSib) { struct TxRateCtrl_s *pRc = &pSib->txRateCtrl; #if 0 /* NB: caller assumed to zero state */ A_MEM_ZERO((char *)pSib, sizeof(*pSib)); #endif pRc->rssiDownTime = A_MS_TICKGET(); }
void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, const A_UINT8 *macaddr) { A_INT32 hash; A_MEMCPY(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN); hash = IEEE80211_NODE_HASH(macaddr); ieee80211_node_initref(ni); /* mark referenced */ ni->ni_tstamp = A_MS_TICKGET() + WLAN_NODE_INACT_TIMEOUT_MSEC; IEEE80211_NODE_LOCK(nt); /* Insert at the end of the node list */ ni->ni_list_next = NULL; ni->ni_list_prev = nt->nt_node_last; if(nt->nt_node_last != NULL) { nt->nt_node_last->ni_list_next = ni; } nt->nt_node_last = ni; if(nt->nt_node_first == NULL) { nt->nt_node_first = ni; } /* Insert into the hash list i.e. the bucket */ if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL) { nt->nt_hash[hash]->ni_hash_prev = ni; } ni->ni_hash_prev = NULL; nt->nt_hash[hash] = ni; IEEE80211_NODE_UNLOCK(nt); }
static void rcUpdate_ht(struct ath_softc_tgt *sc, struct ath_node_target *an, int txRate, A_BOOL Xretries, int retries, A_UINT8 curTxAnt, A_UINT16 nFrames, A_UINT16 nBad) { TX_RATE_CTRL *pRc; A_UINT32 nowMsec = A_MS_TICKGET(); A_BOOL stateChange = FALSE; A_UINT8 lastPer; int rate,count; struct atheros_node *pSib = ATH_NODE_ATHEROS(an); struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc; RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode]; u_int32_t txRateKbps; static A_UINT32 nRetry2PerLookup[10] = { 100 * 0 / 1, // 0 100 * 1 / 4, // 25 100 * 1 / 2, // 50 100 * 3 / 4, // 75 100 * 4 / 5, // 80 100 * 5 / 6, // 83.3 100 * 6 / 7, // 85.7 100 * 7 / 8, // 87.5 100 * 8 / 9, // 88.8 100 * 9 / 10 // 90 }; if (!pSib) return; pRc = (TX_RATE_CTRL *)(pSib); ASSERT(retries >= 0 && retries < MAX_TX_RETRIES); ASSERT(txRate >= 0); if (txRate < 0) { return; } lastPer = pRc->state[txRate].per; if (Xretries) { /* Update the PER. */ if (Xretries == 1) { pRc->state[txRate].per += 30; if (pRc->state[txRate].per > 100) { pRc->state[txRate].per = 100; } } else { /* Xretries == 2 */ count = sizeof(nRetry2PerLookup) / sizeof(nRetry2PerLookup[0]); if (retries >= count) { retries = count - 1; } /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per - (pRc->state[txRate].per / 8) + ((100) / 8)); } /* Xretries == 1 or 2 */ if (pRc->probeRate == txRate) pRc->probeRate = 0; } else { /* Xretries == 0 */ /* * Update the PER. Make sure it doesn't index out of array's bounds. */ count = sizeof(nRetry2PerLookup) / sizeof(nRetry2PerLookup[0]); if (retries >= count) { retries = count - 1; } if (nBad) { /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ /* * Assuming that nFrames is not 0. The current PER * from the retries is 100 * retries / (retries+1), * since the first retries attempts failed, and the * next one worked. For the one that worked, nBad * subframes out of nFrames wored, so the PER for * that part is 100 * nBad / nFrames, and it contributes * 100 * nBad / (nFrames * (retries+1)) to the above * PER. The expression below is a simplified version * of the sum of these two terms. */ if (nFrames > 0) pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per - (pRc->state[txRate].per / 8) + ((100*(retries*nFrames + nBad)/(nFrames*(retries+1))) / 8)); } else { /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per - (pRc->state[txRate].per / 8) + (nRetry2PerLookup[retries] / 8)); } /* * If we got at most one retry then increase the max rate if * this was a probe. Otherwise, ignore the probe. */ if (pRc->probeRate && pRc->probeRate == txRate) { if (retries > 0 || 2 * nBad > nFrames) { /* * Since we probed with just a single attempt, * any retries means the probe failed. Also, * if the attempt worked, but more than half * the subframes were bad then also consider * the probe a failure. */ pRc->probeRate = 0; } else { pRc->rateMaxPhy = pRc->probeRate; if (pRc->state[pRc->probeRate].per > 30) { pRc->state[pRc->probeRate].per = 20; } pRc->probeRate = 0; /* * Since this probe succeeded, we allow the next probe * twice as soon. This allows the maxRate to move up * faster if the probes are succesful. */ pRc->probeTime = nowMsec - pRateTable->probeInterval / 2; } } if (retries > 0) { /* * Don't update anything. We don't know if this was because * of collisions or poor signal. * * Later: if rssiAck is close to pRc->state[txRate].rssiThres * and we see lots of retries, then we could increase * pRc->state[txRate].rssiThres. */ pRc->hwMaxRetryPktCnt = 0; } else { /* * It worked with no retries. First ignore bogus (small) * rssiAck values. */ if (txRate == pRc->rateMaxPhy && pRc->hwMaxRetryPktCnt < 255) { pRc->hwMaxRetryPktCnt++; } } } /* For all cases */ ASSERT((pRc->rateMaxPhy >= 0 && pRc->rateMaxPhy <= pRc->rateTableSize && pRc->rateMaxPhy != INVALID_RATE_MAX)); /* * If this rate looks bad (high PER) then stop using it for * a while (except if we are probing). */ if (pRc->state[txRate].per >= 55 && txRate > 0 && pRateTable->info[txRate].rateKbps <= pRateTable->info[pRc->rateMaxPhy].rateKbps) { rcGetNextLowerValidTxRate(pRateTable, pRc, (A_UINT8) txRate, &pRc->rateMaxPhy); /* Don't probe for a little while. */ pRc->probeTime = nowMsec; } /* Make sure the rates below this have lower PER */ /* Monotonicity is kept only for rates below the current rate. */ if (pRc->state[txRate].per < lastPer) { for (rate = txRate - 1; rate >= 0; rate--) { if (pRateTable->info[rate].phy != pRateTable->info[txRate].phy) { break; } if (pRc->state[rate].per > pRc->state[rate+1].per) { pRc->state[rate].per = pRc->state[rate+1].per; } } } /* Maintain monotonicity for rates above the current rate*/ for (rate = txRate; rate < pRc->rateTableSize - 1; rate++) { if (pRc->state[rate+1].per < pRc->state[rate].per) { pRc->state[rate+1].per = pRc->state[rate].per; } } /* Every so often, we reduce the thresholds and PER (different for CCK and OFDM). */ if (nowMsec - pRc->perDownTime >= pRateTable->rssiReduceInterval) { for (rate = 0; rate < pRc->rateTableSize; rate++) { pRc->state[rate].per = 7*pRc->state[rate].per/8; } pRc->perDownTime = nowMsec; } }
static A_UINT8 rcRateFind_ht(struct ath_softc_tgt *sc, struct atheros_node *pSib, const RATE_TABLE_11N *pRateTable, A_BOOL probeAllowed, A_BOOL *isProbing) { A_UINT32 dt; A_UINT32 bestThruput, thisThruput; A_UINT32 nowMsec; A_UINT8 rate, nextRate, bestRate; A_RSSI rssiLast, rssiReduce = 0; A_UINT8 maxIndex, minIndex; A_INT8 index; TX_RATE_CTRL *pRc = NULL; pRc = (TX_RATE_CTRL *)(pSib ? (pSib) : NULL); *isProbing = FALSE; /* * Age (reduce) last ack rssi based on how old it is. * The bizarre numbers are so the delta is 160msec, * meaning we divide by 16. * 0msec <= dt <= 25msec: don't derate * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB * 185msec <= dt: derate by 10dB */ nowMsec = A_MS_TICKGET(); dt = nowMsec - pRc->rssiTime; /* * Now look up the rate in the rssi table and return it. * If no rates match then we return 0 (lowest rate) */ bestThruput = 0; maxIndex = pRc->maxValidRate-1; minIndex = 0; bestRate = minIndex; /* * Try the higher rate first. It will reduce memory moving time * if we have very good channel characteristics. */ for (index = maxIndex; index >= minIndex ; index--) { A_UINT8 perThres; rate = pRc->validRateIndex[index]; if (rate > pRc->rateMaxPhy) { continue; } /* if the best throughput is already larger than the userRateKbps.. * then we could skip of rest of calculation.. */ if( bestThruput >= pRateTable->info[rate].userRateKbps) break; /* * For TCP the average collision rate is around 11%, * so we ignore PERs less than this. This is to * prevent the rate we are currently using (whose * PER might be in the 10-15 range because of TCP * collisions) looking worse than the next lower * rate whose PER has decayed close to 0. If we * used to next lower rate, its PER would grow to * 10-15 and we would be worse off then staying * at the current rate. */ perThres = pRc->state[rate].per; if ( perThres < 12 ) { perThres = 12; } thisThruput = pRateTable->info[rate].userRateKbps * (100 - perThres); if (bestThruput <= thisThruput) { bestThruput = thisThruput; bestRate = rate; } } rate = bestRate; /* * Must check the actual rate (rateKbps) to account for non-monoticity of * 11g's rate table */ if (rate >= pRc->rateMaxPhy && probeAllowed) { rate = pRc->rateMaxPhy; /* Probe the next allowed phy state */ /* FIXME: Check to make sure ratMax is checked properly */ if (rcGetNextValidTxRate( pRateTable, pRc, rate, &nextRate) && (nowMsec - pRc->probeTime > pRateTable->probeInterval) && (pRc->hwMaxRetryPktCnt >= 1)) { rate = nextRate; pRc->probeRate = rate; pRc->probeTime = nowMsec; pRc->hwMaxRetryPktCnt = 0; *isProbing = TRUE; } } /* * Make sure rate is not higher than the allowed maximum. * We should also enforce the min, but I suspect the min is * normally 1 rather than 0 because of the rate 9 vs 6 issue * in the old code. */ if (rate > (pRc->rateTableSize - 1)) { rate = pRc->rateTableSize - 1; } /* record selected rate, which is used to decide if we want to do fast frame */ if (!(*isProbing) && pSib) { pSib->lastRateKbps = pRateTable->info[rate].rateKbps; ((struct atheros_softc*)sc->sc_rc)->currentTxRateKbps = pSib->lastRateKbps; ((struct atheros_softc*)sc->sc_rc)->currentTxRateIndex = rate; } return rate; }
/* * Determines and returns the new Tx rate index. */ A_UINT16 rcRateFind(struct ath_softc *sc, struct atheros_node *pSib, A_UINT32 frameLen, const RATE_TABLE *pRateTable, HAL_CHANNEL *curchan, int isretry) { #ifdef notyet WLAN_STA_CONFIG *pConfig = &pdevInfo->staConfig; VPORT_BSS *pVportXrBss = GET_XR_BSS(pdevInfo); WLAN_DATA_MAC_HEADER *pHdr = pDesc->pBufferVirtPtr.header; #endif struct TxRateCtrl_s *pRc; A_UINT32 dt; A_UINT32 bestThruput,thisThruput = 0; A_UINT32 nowMsec; A_UINT8 rate, nextRate, bestRate; A_RSSI rssiLast, rssiReduce; #if ATH_SUPERG_DYNTURBO A_UINT8 currentPrimeState = IS_CHAN_TURBO(curchan); /* 0 = regular; 1 = turbo */ A_UINT8 primeInUse = sc->sc_dturbo; #else A_UINT8 primeInUse = 0; A_UINT8 currentPrimeState = 0; #endif #ifdef notyet A_UINT8 xrRateAdaptation = FALSE; #endif int isChanTurbo = FALSE; A_UINT8 maxIndex, minIndex; A_INT8 index; int isProbing = FALSE; /* have the real rate control logic kick in */ pRc = &pSib->txRateCtrl; #if ATH_SUPERG_DYNTURBO /* * Reset primeInUse state, if we are currently using XR * rate tables or if we have any clients associated in XR mode */ #ifdef notyet if ((pRateTable == sc->sc_rates[WLAN_MODE_XR]) || (isXrAp(sc) && (pVportXrBss->bss.numAssociatedClients > 0))) { currentPrimeState = 0; primeInUse = 0; } #endif /* make sure that rateMax is correct when using TURBO_PRIME tables */ if (currentPrimeState) { pRc->rateMax = pRateTable->rateCount - 1; } else { pRc->rateMax = pRateTable->rateCount - 1 - pRateTable->numTurboRates; } #endif /* ATH_SUPERG_DYNTURBO */ rssiLast = median(pRc->rssiLast, pRc->rssiLastPrev, pRc->rssiLastPrev2); rssiReduce = 0; /* * Age (reduce) last ack rssi based on how old it is. * The bizarre numbers are so the delta is 160msec, * meaning we divide by 16. * 0msec <= dt <= 25msec: don't derate * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB * 185msec <= dt: derate by 10dB */ nowMsec = A_MS_TICKGET(); dt = nowMsec - pRc->rssiTime; if (dt >= 185) { rssiReduce = 10; } else if (dt >= 25) { rssiReduce = (A_UINT8)((dt - 25) >> 4); }
/* * Determines and returns the new Tx rate index. */ A_UINT16 rcRateFind(struct ath_softc *sc, struct atheros_node *pSib, A_UINT32 frameLen) { struct ieee80211com *ic = &sc->sc_ic; #ifdef notyet WLAN_STA_CONFIG *pConfig = &pdevInfo->staConfig; VPORT_BSS *pVportXrBss = GET_XR_BSS(pdevInfo); WLAN_DATA_MAC_HEADER *pHdr = pDesc->pBufferVirtPtr.header; #endif struct atheros_softc *asc = (struct atheros_softc *) sc->sc_rc; const RATE_TABLE *pRateTable = asc->hwRateTable[sc->sc_curmode]; struct TxRateCtrl_s *pRc; A_UINT32 dt; A_UINT32 bestThruput,thisThruput; A_UINT32 nowMsec; A_UINT8 rate, nextRate, bestRate; A_RSSI rssiLast, rssiReduce; #if TURBO_PRIME A_UINT8 primeInUse = sc->sc_dturbo; //A_UINT8 currentPrimeState = ((ic->ic_ath_cap & IEEE80211_ATHC_BOOST) > 0) ; A_UINT8 currentPrimeState = ((sc->sc_curmode == IEEE80211_MODE_TURBO_A) || (sc->sc_curmode == IEEE80211_MODE_TURBO_G)) ; /* 0 = regular; 1 = turbo */ #else A_UINT8 primeInUse = 0; A_UINT8 currentPrimeState = 0; #endif #ifdef notyet A_UINT8 xrRateAdaptation = FALSE; #endif A_BOOL isChanTurbo = FALSE; A_UINT8 maxIndex, minIndex; A_INT8 index; A_BOOL isProbing = FALSE; /* have the real rate control logic kick in */ pRc = &pSib->txRateCtrl; #if TURBO_PRIME /* * Reset primeInUse state, if we are currently using XR * rate tables or if we have any clients associated in XR mode */ #ifdef notyet if ((pRateTable == sc->sc_rates[WLAN_MODE_XR]) || (isXrAp(sc) && (pVportXrBss->bss.numAssociatedClients > 0))) { primeInUse = 0; } #endif #endif /* make sure that rateMax is correct when in TURBO_PRIME mode */ if (primeInUse) { if (currentPrimeState == 1) { pRc->rateMax = pRateTable->rateCount - 1; } else if (currentPrimeState == 0) { pRc->rateMax = pRateTable->rateCount - 1 - pRateTable->numTurboRates; } } rssiLast = median(pRc->rssiLast, pRc->rssiLastPrev, pRc->rssiLastPrev2); rssiReduce = 0; /* * Age (reduce) last ack rssi based on how old it is. * The bizarre numbers are so the delta is 160msec, * meaning we divide by 16. * 0msec <= dt <= 25msec: don't derate * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB * 185msec <= dt: derate by 10dB */ nowMsec = A_MS_TICKGET(); dt = nowMsec - pRc->rssiTime; if (dt >= 185) { rssiReduce = 10; } else if (dt >= 25) { rssiReduce = (A_UINT8)((dt - 25) >> 4); }
void CAR6KMini::WMITargetStatsEvent( WMI_TARGET_STATS *pTargetStats) { if(m_networkType == AP_NETWORK) { return; } int ac = 0; // Update the RSSI for now. if (m_Connected) { bss_t *pWmiNode = NULL; pWmiNode = wmi_find_node((wmi_t *)m_pWMI,m_PeerBSSID); if (pWmiNode) { pWmiNode->ni_rssi = pTargetStats->cservStats.cs_aveBeacon_rssi; wmi_node_return((wmi_t *)m_pWMI, pWmiNode); } m_RSSI = pTargetStats->cservStats.cs_aveBeacon_rssi; // // Check whether the current mode is adhoc mode (in case of single node Target returns // -95 or -96 RSSI values) since there is no specific event from // taregt to indicate whenever joiner is available, // host has to check below condition in order to avoid // null RSSI // if ((Ndis802_11IBSS == m_InfrastructureMode) && (RSSI_TO_ABS(m_RSSI) <= 0)) { m_RSSI = 0; // Max RSSI value } } // Update other target Stats. if (pTargetStats->txrxStats.tx_stats.tx_packets > pTargetStats->txrxStats.tx_stats.tx_failed_cnt) { m_tgtStats.TransmittedFragmentCount.QuadPart += (pTargetStats->txrxStats.tx_stats.tx_packets - pTargetStats->txrxStats.tx_stats.tx_failed_cnt); } else { m_tgtStats.TransmittedFragmentCount.QuadPart += 0; } m_tgtStats.MulticastTransmittedFrameCount.QuadPart += (pTargetStats->txrxStats.tx_stats.tx_multicast_pkts + \ pTargetStats->txrxStats.tx_stats.tx_broadcast_pkts); m_tgtStats.FailedCount.QuadPart += pTargetStats->txrxStats.tx_stats.tx_retry_cnt; m_tgtStats.RetryCount.QuadPart += pTargetStats->txrxStats.tx_stats.tx_mult_retry_cnt; m_tgtStats.MultipleRetryCount.QuadPart += pTargetStats->txrxStats.tx_stats.tx_mult_retry_cnt; m_tgtStats.RTSSuccessCount.QuadPart += pTargetStats->txrxStats.tx_stats.tx_rts_success_cnt; m_tgtStats.RTSFailureCount.QuadPart += pTargetStats->txrxStats.tx_stats.tx_rts_fail_cnt; m_tgtStats.FrameDuplicateCount.QuadPart += pTargetStats->txrxStats.rx_stats.rx_duplicate_frames; m_tgtStats.ReceivedFragmentCount.QuadPart += pTargetStats->txrxStats.rx_stats.rx_packets; m_tgtStats.MulticastReceivedFrameCount.QuadPart += (pTargetStats->txrxStats.rx_stats.rx_multicast_pkts + \ pTargetStats->txrxStats.rx_stats.rx_broadcast_pkts); m_tgtStats.FCSErrorCount.QuadPart += pTargetStats->txrxStats.rx_stats.rx_crcerr; m_txRate = wmi_get_rate (pTargetStats->txrxStats.tx_stats.tx_unicast_rate); m_rxRate = wmi_get_rate (pTargetStats->txrxStats.rx_stats.rx_unicast_rate); #ifdef OS_ROAM_MANAGEMENT m_RateInfo.TxRateFiltered = m_txRate; m_RateInfo.RxRateFiltered = m_rxRate; m_RateInfo.TxDataFrames += pTargetStats->txrxStats.tx_stats.tx_unicast_pkts; m_RateInfo.RxDataFrames += pTargetStats->txrxStats.rx_stats.rx_unicast_pkts; m_RateInfo.RssiFiltered = RSSI_TO_NDIS(pTargetStats->cservStats.cs_aveBeacon_rssi); if (m_Connected && (0 == pTargetStats->cservStats.cs_bmiss_cnt)) { m_RateInfo.LastRssiBeaconTime = A_MS_TICKGET(); } #endif /* RX/TX Stats */ m_tgtAllStats.tx_packets += pTargetStats->txrxStats.tx_stats.tx_packets; m_tgtAllStats.tx_bytes += pTargetStats->txrxStats.tx_stats.tx_bytes; m_tgtAllStats.tx_unicast_pkts += pTargetStats->txrxStats.tx_stats.tx_unicast_pkts; m_tgtAllStats.tx_unicast_bytes += pTargetStats->txrxStats.tx_stats.tx_unicast_bytes; m_tgtAllStats.tx_multicast_pkts += pTargetStats->txrxStats.tx_stats.tx_multicast_pkts; m_tgtAllStats.tx_multicast_bytes += pTargetStats->txrxStats.tx_stats.tx_multicast_bytes; m_tgtAllStats.tx_broadcast_pkts += pTargetStats->txrxStats.tx_stats.tx_broadcast_pkts; m_tgtAllStats.tx_broadcast_bytes += pTargetStats->txrxStats.tx_stats.tx_broadcast_bytes; m_tgtAllStats.tx_rts_success_cnt += pTargetStats->txrxStats.tx_stats.tx_rts_success_cnt; for (ac = 0; ac < WMM_NUM_AC; ac++) m_tgtAllStats.tx_packet_per_ac[ac] += pTargetStats->txrxStats.tx_stats.tx_packet_per_ac[ac]; m_tgtAllStats.tx_errors += pTargetStats->txrxStats.tx_stats.tx_errors; m_tgtAllStats.tx_failed_cnt += pTargetStats->txrxStats.tx_stats.tx_failed_cnt; m_tgtAllStats.tx_retry_cnt += pTargetStats->txrxStats.tx_stats.tx_retry_cnt; m_tgtAllStats.tx_mult_retry_cnt += pTargetStats->txrxStats.tx_stats.tx_mult_retry_cnt; m_tgtAllStats.tx_rts_fail_cnt += pTargetStats->txrxStats.tx_stats.tx_rts_fail_cnt; m_tgtAllStats.tx_unicast_rate = wmi_get_rate(pTargetStats->txrxStats.tx_stats.tx_unicast_rate); m_tgtAllStats.rx_packets += pTargetStats->txrxStats.rx_stats.rx_packets; m_tgtAllStats.rx_bytes += pTargetStats->txrxStats.rx_stats.rx_bytes; m_tgtAllStats.rx_unicast_pkts += pTargetStats->txrxStats.rx_stats.rx_unicast_pkts; m_tgtAllStats.rx_unicast_bytes += pTargetStats->txrxStats.rx_stats.rx_unicast_bytes; m_tgtAllStats.rx_multicast_pkts += pTargetStats->txrxStats.rx_stats.rx_multicast_pkts; m_tgtAllStats.rx_multicast_bytes += pTargetStats->txrxStats.rx_stats.rx_multicast_bytes; m_tgtAllStats.rx_broadcast_pkts += pTargetStats->txrxStats.rx_stats.rx_broadcast_pkts; m_tgtAllStats.rx_broadcast_bytes += pTargetStats->txrxStats.rx_stats.rx_broadcast_bytes; m_tgtAllStats.rx_fragment_pkt += pTargetStats->txrxStats.rx_stats.rx_fragment_pkt; m_tgtAllStats.rx_errors += pTargetStats->txrxStats.rx_stats.rx_errors; m_tgtAllStats.rx_crcerr += pTargetStats->txrxStats.rx_stats.rx_crcerr; m_tgtAllStats.rx_key_cache_miss += pTargetStats->txrxStats.rx_stats.rx_key_cache_miss; m_tgtAllStats.rx_decrypt_err += pTargetStats->txrxStats.rx_stats.rx_decrypt_err; m_tgtAllStats.rx_duplicate_frames += pTargetStats->txrxStats.rx_stats.rx_duplicate_frames; m_tgtAllStats.rx_unicast_rate = wmi_get_rate(pTargetStats->txrxStats.rx_stats.rx_unicast_rate); /* Cserv Stats */ m_tgtAllStats.cs_bmiss_cnt += pTargetStats->cservStats.cs_bmiss_cnt; m_tgtAllStats.cs_lowRssi_cnt += pTargetStats->cservStats.cs_lowRssi_cnt; m_tgtAllStats.cs_connect_cnt += pTargetStats->cservStats.cs_connect_cnt; m_tgtAllStats.cs_disconnect_cnt += pTargetStats->cservStats.cs_disconnect_cnt; m_tgtAllStats.cs_aveBeacon_snr = pTargetStats->cservStats.cs_aveBeacon_snr; m_tgtAllStats.cs_aveBeacon_rssi = pTargetStats->cservStats.cs_aveBeacon_rssi; m_tgtAllStats.cs_lastRoam_msec = pTargetStats->cservStats.cs_lastRoam_msec; m_tgtAllStats.cs_snr = pTargetStats->cservStats.cs_snr; m_tgtAllStats.cs_rssi = pTargetStats->cservStats.cs_rssi; /* WoW Stats */ m_tgtAllStats.wow_num_pkts_dropped += pTargetStats->wowStats.wow_num_pkts_dropped; m_tgtAllStats.wow_num_host_pkt_wakeups += pTargetStats->wowStats.wow_num_host_pkt_wakeups; m_tgtAllStats.wow_num_host_event_wakeups += pTargetStats->wowStats.wow_num_host_event_wakeups; m_tgtAllStats.wow_num_events_discarded += pTargetStats->wowStats.wow_num_events_discarded; /* TKIP,CCMP Stats */ m_tgtAllStats.tkip_local_mic_failure += pTargetStats->txrxStats.tkipCcmpStats.tkip_local_mic_failure; m_tgtAllStats.tkip_counter_measures_invoked += pTargetStats->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked; m_tgtAllStats.tkip_replays += pTargetStats->txrxStats.tkipCcmpStats.tkip_replays; m_tgtAllStats.tkip_format_errors += pTargetStats->txrxStats.tkipCcmpStats.tkip_format_errors; m_tgtAllStats.ccmp_format_errors += pTargetStats->txrxStats.tkipCcmpStats.ccmp_format_errors; m_tgtAllStats.ccmp_replays += pTargetStats->txrxStats.tkipCcmpStats.ccmp_replays; /* misc stats */ m_tgtAllStats.power_save_failure_cnt += pTargetStats->pmStats.power_save_failure_cnt; m_tgtAllStats.noise_floor_calibation = pTargetStats->noise_floor_calibation; m_tgtAllStats.lqVal = pTargetStats->lqVal; //post targetStats event NdisSetEvent(&m_tgtStatsEvent); return; }