diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/ps.c')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/ps.c | 125 | 
1 files changed, 112 insertions, 13 deletions
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 0d81f766fd0..50504942ded 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -32,6 +32,106 @@  #include "base.h"  #include "ps.h" +/*	Description: + *		This routine deals with the Power Configuration CMD + *		 parsing for RTL8723/RTL8188E Series IC. + *	Assumption: + *		We should follow specific format that was released from HW SD. + */ +bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, +			      u8 faversion, u8 interface_type, +			      struct wlan_pwr_cfg pwrcfgcmd[]) +{ +	struct wlan_pwr_cfg cfg_cmd = {0}; +	bool polling_bit = false; +	u32 ary_idx = 0; +	u8 value = 0; +	u32 offset = 0; +	u32 polling_count = 0; +	u32 max_polling_cnt = 5000; + +	do { +		cfg_cmd = pwrcfgcmd[ary_idx]; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +			"rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x)," +			"interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", +			GET_PWR_CFG_OFFSET(cfg_cmd), +					   GET_PWR_CFG_CUT_MASK(cfg_cmd), +			GET_PWR_CFG_FAB_MASK(cfg_cmd), +					     GET_PWR_CFG_INTF_MASK(cfg_cmd), +			GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), +			GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); + +		if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) && +		    (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) && +		    (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) { +			switch (GET_PWR_CFG_CMD(cfg_cmd)) { +			case PWR_CMD_READ: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"); +				break; +			case PWR_CMD_WRITE: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n"); +				offset = GET_PWR_CFG_OFFSET(cfg_cmd); + +				/*Read the value from system register*/ +				value = rtl_read_byte(rtlpriv, offset); +				value &= (~(GET_PWR_CFG_MASK(cfg_cmd))); +				value |= (GET_PWR_CFG_VALUE(cfg_cmd) & +					  GET_PWR_CFG_MASK(cfg_cmd)); + +				/*Write the value back to sytem register*/ +				rtl_write_byte(rtlpriv, offset, value); +				break; +			case PWR_CMD_POLLING: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"); +				polling_bit = false; +				offset = GET_PWR_CFG_OFFSET(cfg_cmd); + +				do { +					value = rtl_read_byte(rtlpriv, offset); + +					value &= GET_PWR_CFG_MASK(cfg_cmd); +					if (value == +					    (GET_PWR_CFG_VALUE(cfg_cmd) +					    & GET_PWR_CFG_MASK(cfg_cmd))) +						polling_bit = true; +					else +						udelay(10); + +					if (polling_count++ > max_polling_cnt) +						return false; +				} while (!polling_bit); +				break; +			case PWR_CMD_DELAY: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n"); +				if (GET_PWR_CFG_VALUE(cfg_cmd) == +				    PWRSEQ_DELAY_US) +					udelay(GET_PWR_CFG_OFFSET(cfg_cmd)); +				else +					mdelay(GET_PWR_CFG_OFFSET(cfg_cmd)); +				break; +			case PWR_CMD_END: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n"); +				return true; +			default: +				RT_ASSERT(false, +					 "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n"); +				break; +			} + +		} +		ary_idx++; +	} while (1); + +	return true; +} +EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing); +  bool rtl_ps_enable_nic(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -48,7 +148,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)  	/*<2> Enable Adapter */  	if (rtlpriv->cfg->ops->hw_init(hw)) -		return 1; +		return false;  	RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);  	/*<3> Enable Interrupt */ @@ -478,7 +578,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)  		return;  	/* and only beacons from the associated BSSID, please */ -	if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) +	if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))  		return;  	rtlpriv->psc.last_beacon = jiffies; @@ -659,7 +759,7 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,  			   unsigned int len)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct ieee80211_mgmt *mgmt = (void *)data; +	struct ieee80211_mgmt *mgmt = data;  	struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);  	u8 *pos, *end, *ie;  	u16 noa_len; @@ -758,7 +858,7 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,  			      unsigned int len)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct ieee80211_mgmt *mgmt = (void *)data; +	struct ieee80211_mgmt *mgmt = data;  	struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);  	u8 noa_num, index, i, noa_index = 0;  	u8 *pos, *end, *ie; @@ -850,9 +950,8 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  	switch (p2p_ps_state) {  	case P2P_PS_DISABLE:  		p2pinfo->p2p_ps_state = p2p_ps_state; -		rtlpriv->cfg->ops->set_hw_reg(hw, -				 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, -				 (u8 *)(&p2p_ps_state)); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, +					      &p2p_ps_state);  		p2pinfo->noa_index = 0;  		p2pinfo->ctwindow = 0; @@ -864,7 +963,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  				rtlps->smart_ps = 2;  				rtlpriv->cfg->ops->set_hw_reg(hw,  					 HW_VAR_H2C_FW_PWRMODE, -					 (u8 *)(&rtlps->pwr_mode)); +					 &rtlps->pwr_mode);  			}  		}  		break; @@ -877,12 +976,12 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  					rtlps->smart_ps = 0;  					rtlpriv->cfg->ops->set_hw_reg(hw,  						 HW_VAR_H2C_FW_PWRMODE, -						 (u8 *)(&rtlps->pwr_mode)); +						 &rtlps->pwr_mode);  				}  			}  			rtlpriv->cfg->ops->set_hw_reg(hw,  				 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, -				 (u8 *)(&p2p_ps_state)); +				 &p2p_ps_state);  		}  		break;  	case P2P_PS_SCAN: @@ -892,7 +991,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  			p2pinfo->p2p_ps_state = p2p_ps_state;  			rtlpriv->cfg->ops->set_hw_reg(hw,  				 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, -				 (u8 *)(&p2p_ps_state)); +				 &p2p_ps_state);  		}  		break;  	default: @@ -912,7 +1011,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	struct ieee80211_hdr *hdr = (void *)data; +	struct ieee80211_hdr *hdr = data;  	if (!mac->p2p)  		return; @@ -923,7 +1022,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)  		return;  	/* and only beacons from the associated BSSID, please */ -	if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) +	if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))  		return;  	/* check if this really is a beacon */  | 
