예제 #1
0
파일: ps.c 프로젝트: AICP/kernel_moto_shamu
void rtl_lps_change_work_callback(struct work_struct *work)
{
	struct rtl_works *rtlworks =
	    container_of(work, struct rtl_works, lps_change_work);
	struct ieee80211_hw *hw = rtlworks->hw;
	struct rtl_priv *rtlpriv = rtl_priv(hw);

	if (rtlpriv->enter_ps)
		rtl_lps_enter(hw);
	else
		rtl_lps_leave(hw);
}
예제 #2
0
/*********************************************************
 *
 * wq & timer callback functions
 *
 *********************************************************/
void rtl_watchdog_wq_callback(void *data)
{
	struct rtl_works *rtlworks = container_of_dwork_rtl(data,
							    struct rtl_works,
							    watchdog_wq);
	struct ieee80211_hw *hw = rtlworks->hw;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));

	bool b_busytraffic = false;
	bool b_higher_busytraffic = false;
	bool b_higher_busyrxtraffic = false;
	bool b_higher_busytxtraffic = false;

	u8 idx = 0;
	u32 rx_cnt_inp4eriod = 0;
	u32 tx_cnt_inp4eriod = 0;
	u32 aver_rx_cnt_inperiod = 0;
	u32 aver_tx_cnt_inperiod = 0;

	bool benter_ps = false;

	if (is_hal_stop(rtlhal))
		return;

	/* <1> Determine if action frame is allowed */
	if (mac->link_state > MAC80211_NOLINK) {
		if (mac->cnt_after_linked < 20)
			mac->cnt_after_linked++;
	} else {
		mac->cnt_after_linked = 0;
	}

	/* <2> DM */
	rtlpriv->cfg->ops->dm_watchdog(hw);

	/*
	 *<3> to check if traffic busy, if
	 * busytraffic we don't change channel
	 */
	if (mac->link_state >= MAC80211_LINKED) {

		/* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */
		for (idx = 0; idx <= 2; idx++) {
			rtlpriv->link_info.num_rx_in4period[idx] =
			    rtlpriv->link_info.num_rx_in4period[idx + 1];
			rtlpriv->link_info.num_tx_in4period[idx] =
			    rtlpriv->link_info.num_tx_in4period[idx + 1];
		}
		rtlpriv->link_info.num_rx_in4period[3] =
		    rtlpriv->link_info.num_rx_inperiod;
		rtlpriv->link_info.num_tx_in4period[3] =
		    rtlpriv->link_info.num_tx_inperiod;
		for (idx = 0; idx <= 3; idx++) {
			rx_cnt_inp4eriod +=
			    rtlpriv->link_info.num_rx_in4period[idx];
			tx_cnt_inp4eriod +=
			    rtlpriv->link_info.num_tx_in4period[idx];
		}
		aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;
		aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;

		/* (2) check traffic busy */
		if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100)
			b_busytraffic = true;

		/* Higher Tx/Rx data. */
		if (aver_rx_cnt_inperiod > 4000 ||
		    aver_tx_cnt_inperiod > 4000) {
			b_higher_busytraffic = true;

			/* Extremely high Rx data. */
			if (aver_rx_cnt_inperiod > 5000)
				b_higher_busyrxtraffic = true;
			else
				b_higher_busytxtraffic = false;
		}

		if (((rtlpriv->link_info.num_rx_inperiod +
		      rtlpriv->link_info.num_tx_inperiod) > 8) ||
		    (rtlpriv->link_info.num_rx_inperiod > 2))
			benter_ps = false;
		else
			benter_ps = true;

		/* LeisurePS only work in infra mode. */
		if (benter_ps)
			rtl_lps_enter(hw);
		else
			rtl_lps_leave(hw);
	}

	rtlpriv->link_info.num_rx_inperiod = 0;
	rtlpriv->link_info.num_tx_inperiod = 0;

	rtlpriv->link_info.b_busytraffic = b_busytraffic;
	rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic;
	rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic;

}
예제 #3
0
void rtl_watchdog_wq_callback(void *data)
{
	struct rtl_works *rtlworks = container_of_dwork_rtl(data,
							    struct rtl_works,
							    watchdog_wq);
	struct ieee80211_hw *hw = rtlworks->hw;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
	bool busytraffic = false;
	bool higher_busytraffic = false;
	bool higher_busyrxtraffic = false;
	u8 idx, tid;
	u32 rx_cnt_inp4eriod = 0;
	u32 tx_cnt_inp4eriod = 0;
	u32 aver_rx_cnt_inperiod = 0;
	u32 aver_tx_cnt_inperiod = 0;
	u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0};
	u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0};
	bool enter_ps = false;

	if (is_hal_stop(rtlhal))
		return;

	
	if (mac->link_state > MAC80211_NOLINK) {
		if (mac->cnt_after_linked < 20)
			mac->cnt_after_linked++;
	} else {
		mac->cnt_after_linked = 0;
	}

	if (mac->link_state >= MAC80211_LINKED) {

		
		for (idx = 0; idx <= 2; idx++) {
			rtlpriv->link_info.num_rx_in4period[idx] =
			    rtlpriv->link_info.num_rx_in4period[idx + 1];
			rtlpriv->link_info.num_tx_in4period[idx] =
			    rtlpriv->link_info.num_tx_in4period[idx + 1];
		}
		rtlpriv->link_info.num_rx_in4period[3] =
		    rtlpriv->link_info.num_rx_inperiod;
		rtlpriv->link_info.num_tx_in4period[3] =
		    rtlpriv->link_info.num_tx_inperiod;
		for (idx = 0; idx <= 3; idx++) {
			rx_cnt_inp4eriod +=
			    rtlpriv->link_info.num_rx_in4period[idx];
			tx_cnt_inp4eriod +=
			    rtlpriv->link_info.num_tx_in4period[idx];
		}
		aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;
		aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;

		
		if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100)
			busytraffic = true;

		
		if (aver_rx_cnt_inperiod > 4000 ||
		    aver_tx_cnt_inperiod > 4000) {
			higher_busytraffic = true;

			
			if (aver_rx_cnt_inperiod > 5000)
				higher_busyrxtraffic = true;
		}

		
		for (tid = 0; tid <= 7; tid++) {
			for (idx = 0; idx <= 2; idx++)
				rtlpriv->link_info.tidtx_in4period[tid][idx] =
				  rtlpriv->link_info.tidtx_in4period[tid]
				  [idx + 1];
			rtlpriv->link_info.tidtx_in4period[tid][3] =
				rtlpriv->link_info.tidtx_inperiod[tid];

			for (idx = 0; idx <= 3; idx++)
				tidtx_inp4eriod[tid] +=
				  rtlpriv->link_info.tidtx_in4period[tid][idx];
			aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4;
			if (aver_tidtx_inperiod[tid] > 5000)
				rtlpriv->link_info.higher_busytxtraffic[tid] =
						   true;
			else
				rtlpriv->link_info.higher_busytxtraffic[tid] =
						   false;
		}

		if (((rtlpriv->link_info.num_rx_inperiod +
		      rtlpriv->link_info.num_tx_inperiod) > 8) ||
		    (rtlpriv->link_info.num_rx_inperiod > 2))
			enter_ps = false;
		else
			enter_ps = true;

		
		if (enter_ps)
			rtl_lps_enter(hw);
		else
			rtl_lps_leave(hw);
	}

	rtlpriv->link_info.num_rx_inperiod = 0;
	rtlpriv->link_info.num_tx_inperiod = 0;
	for (tid = 0; tid <= 7; tid++)
		rtlpriv->link_info.tidtx_inperiod[tid] = 0;

	rtlpriv->link_info.busytraffic = busytraffic;
	rtlpriv->link_info.higher_busytraffic = higher_busytraffic;
	rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;

	
	rtlpriv->cfg->ops->dm_watchdog(hw);
}