/* * Handle station leaving bss. */ void ieee80211_node_saveq_cleanup(struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; /* vap is already deleted */ if (vap == NULL) return; if (vap->iv_opmode == IEEE80211_M_HOSTAP) { ieee80211_mlme_node_leave(ni); } else { ieee80211node_clear_flag(ni, IEEE80211_NODE_PWR_MGT); #if NOT_YET if (ieee80211node_has_flag(ni, IEEE80211_NODE_UAPSD_TRIG)) { ieee80211node_clear_flag(ni, IEEE80211_NODE_UAPSD_TRIG); IEEE80211_UAPSD_LOCK(ni->ni_ic); ni->ni_ic->ic_uapsdmaxtriggers--; IEEE80211_UAPSD_UNLOCK(ni->ni_ic); } #endif } if ((ieee80211_node_saveq_drain(ni) != 0) && (vap->iv_set_tim != NULL)) vap->iv_set_tim(ni, 0); IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, "%s %u sta's in ps mode \n", __func__,vap->iv_ps_sta); }
static bool ieee80211_pwrsave_smps_check(ieee80211_pwrsave_smps_t smps) { u_int16_t i, throughput = 0, rssi; struct ieee80211vap *vap = smps->ips_vap; struct ieee80211com *ic = vap->iv_ic; if (!smps->ips_connected || !ieee80211_vap_ready_is_set(vap) || (vap->iv_opmode != IEEE80211_M_STA) || (!ieee80211node_has_flag(vap->iv_bss, IEEE80211_NODE_HT))) { return FALSE; } /* SM power save check. * SM Power save is enabled if, * - There is no data traffic or * - Throughput is less than threshold and RSSI is greater than threshold. */ throughput = vap->iv_txrxbytes / (IEEE80211_PWRSAVE_TIMER_INTERVAL * 125); // in Mbps rssi = ic->ic_node_getrssi(vap->iv_bss, -1, IEEE80211_RSSI_BEACON); vap->iv_txrxbytes = 0; // Clear byte counter smps->ips_smpsDataHistory[smps->ips_smpsCurrDataIndex++] = throughput; smps->ips_smpsCurrDataIndex = smps->ips_smpsCurrDataIndex % IEEE80211_SMPS_DATAHIST_NUM; /* We calculate average throughput over the past samples */ throughput = 0; for (i = 0; i < IEEE80211_SMPS_DATAHIST_NUM; i++) { throughput += smps->ips_smpsDataHistory[i]; } throughput /= IEEE80211_SMPS_DATAHIST_NUM; /* * We make the thresholds slightly different for SM power save enable & disable to get * over the ping-pong effect when calculated throughput is close to the threshold value. * SMPS Enable Threshold = Registry Value * SMPS Disable Threshold = Registry Value + IEEE80211_SMPS_THRESH_DIFF */ if (!throughput || ((throughput < vap->iv_smps_datathresh) && (rssi > vap->iv_smps_rssithresh))) { /* Receive criteria met, do SM power save. */ ieee80211_pwrsave_smps_event(smps, IEEE80211_SMPS_ENABLE); } else if ((throughput > (vap->iv_smps_datathresh + IEEE80211_SMPS_THRESH_DIFF)) || (rssi < vap->iv_smps_rssithresh)) { ieee80211_pwrsave_smps_event(smps, IEEE80211_SMPS_DISABLE); } return TRUE; }