diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
50 files changed, 3412 insertions, 1579 deletions
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index b259f807ad2..ccb6da38fe2 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -50,8 +50,9 @@   *3) functions called by core.c   *4) wq & timer callback functions   *5) frame process functions - *6) sysfs functions - *7) ... + *6) IOT functions + *7) sysfs functions + *8) ...   */  /********************************************************* @@ -59,7 +60,7 @@   * mac80211 init functions   *   *********************************************************/ -static struct ieee80211_channel rtl_channeltable[] = { +static struct ieee80211_channel rtl_channeltable_2g[] = {  	{.center_freq = 2412, .hw_value = 1,},  	{.center_freq = 2417, .hw_value = 2,},  	{.center_freq = 2422, .hw_value = 3,}, @@ -76,7 +77,34 @@ static struct ieee80211_channel rtl_channeltable[] = {  	{.center_freq = 2484, .hw_value = 14,},  }; -static struct ieee80211_rate rtl_ratetable[] = { +static struct ieee80211_channel rtl_channeltable_5g[] = { +	{.center_freq = 5180, .hw_value = 36,}, +	{.center_freq = 5200, .hw_value = 40,}, +	{.center_freq = 5220, .hw_value = 44,}, +	{.center_freq = 5240, .hw_value = 48,}, +	{.center_freq = 5260, .hw_value = 52,}, +	{.center_freq = 5280, .hw_value = 56,}, +	{.center_freq = 5300, .hw_value = 60,}, +	{.center_freq = 5320, .hw_value = 64,}, +	{.center_freq = 5500, .hw_value = 100,}, +	{.center_freq = 5520, .hw_value = 104,}, +	{.center_freq = 5540, .hw_value = 108,}, +	{.center_freq = 5560, .hw_value = 112,}, +	{.center_freq = 5580, .hw_value = 116,}, +	{.center_freq = 5600, .hw_value = 120,}, +	{.center_freq = 5620, .hw_value = 124,}, +	{.center_freq = 5640, .hw_value = 128,}, +	{.center_freq = 5660, .hw_value = 132,}, +	{.center_freq = 5680, .hw_value = 136,}, +	{.center_freq = 5700, .hw_value = 140,}, +	{.center_freq = 5745, .hw_value = 149,}, +	{.center_freq = 5765, .hw_value = 153,}, +	{.center_freq = 5785, .hw_value = 157,}, +	{.center_freq = 5805, .hw_value = 161,}, +	{.center_freq = 5825, .hw_value = 165,}, +}; + +static struct ieee80211_rate rtl_ratetable_2g[] = {  	{.bitrate = 10, .hw_value = 0x00,},  	{.bitrate = 20, .hw_value = 0x01,},  	{.bitrate = 55, .hw_value = 0x02,}, @@ -91,18 +119,57 @@ static struct ieee80211_rate rtl_ratetable[] = {  	{.bitrate = 540, .hw_value = 0x0b,},  }; +static struct ieee80211_rate rtl_ratetable_5g[] = { +	{.bitrate = 60, .hw_value = 0x04,}, +	{.bitrate = 90, .hw_value = 0x05,}, +	{.bitrate = 120, .hw_value = 0x06,}, +	{.bitrate = 180, .hw_value = 0x07,}, +	{.bitrate = 240, .hw_value = 0x08,}, +	{.bitrate = 360, .hw_value = 0x09,}, +	{.bitrate = 480, .hw_value = 0x0a,}, +	{.bitrate = 540, .hw_value = 0x0b,}, +}; +  static const struct ieee80211_supported_band rtl_band_2ghz = {  	.band = IEEE80211_BAND_2GHZ, -	.channels = rtl_channeltable, -	.n_channels = ARRAY_SIZE(rtl_channeltable), +	.channels = rtl_channeltable_2g, +	.n_channels = ARRAY_SIZE(rtl_channeltable_2g), -	.bitrates = rtl_ratetable, -	.n_bitrates = ARRAY_SIZE(rtl_ratetable), +	.bitrates = rtl_ratetable_2g, +	.n_bitrates = ARRAY_SIZE(rtl_ratetable_2g),  	.ht_cap = {0},  }; +static struct ieee80211_supported_band rtl_band_5ghz = { +	.band = IEEE80211_BAND_5GHZ, + +	.channels = rtl_channeltable_5g, +	.n_channels = ARRAY_SIZE(rtl_channeltable_5g), + +	.bitrates = rtl_ratetable_5g, +	.n_bitrates = ARRAY_SIZE(rtl_ratetable_5g), + +	.ht_cap = {0}, +}; + +static const u8 tid_to_ac[] = { +	2, /* IEEE80211_AC_BE */ +	3, /* IEEE80211_AC_BK */ +	3, /* IEEE80211_AC_BK */ +	2, /* IEEE80211_AC_BE */ +	1, /* IEEE80211_AC_VI */ +	1, /* IEEE80211_AC_VI */ +	0, /* IEEE80211_AC_VO */ +	0, /* IEEE80211_AC_VO */ +}; + +u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid) +{ +	return tid_to_ac[tid]; +} +  static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,  				  struct ieee80211_sta_ht_cap *ht_cap)  { @@ -115,6 +182,9 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,  	    IEEE80211_HT_CAP_SGI_20 |  	    IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU; +	if (rtlpriv->rtlhal.disable_amsdu_8k) +		ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; +  	/*  	 *Maximum length of AMPDU that the STA can receive.  	 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) @@ -159,37 +229,99 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,  static void _rtl_init_mac80211(struct ieee80211_hw *hw)  { +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);  	struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));  	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));  	struct ieee80211_supported_band *sband; -	/* <1> use  mac->bands as mem for hw->wiphy->bands */ -	sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); -	/* -	 * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] -	 * to default value(1T1R) -	 */ -	memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, -	       sizeof(struct ieee80211_supported_band)); +	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset == +	    BAND_ON_BOTH) { +		/* 1: 2.4 G bands */ +		/* <1> use  mac->bands as mem for hw->wiphy->bands */ +		sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); + +		/* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] +		 * to default value(1T1R) */ +		memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz, +				sizeof(struct ieee80211_supported_band)); + +		/* <3> init ht cap base on ant_num */ +		_rtl_init_hw_ht_capab(hw, &sband->ht_cap); + +		/* <4> set mac->sband to wiphy->sband */ +		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + +		/* 2: 5 G bands */ +		/* <1> use  mac->bands as mem for hw->wiphy->bands */ +		sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); + +		/* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] +		 * to default value(1T1R) */ +		memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz, +				sizeof(struct ieee80211_supported_band)); + +		/* <3> init ht cap base on ant_num */ +		_rtl_init_hw_ht_capab(hw, &sband->ht_cap); + +		/* <4> set mac->sband to wiphy->sband */ +		hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; +	} else { +		if (rtlhal->current_bandtype == BAND_ON_2_4G) { +			/* <1> use  mac->bands as mem for hw->wiphy->bands */ +			sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]); + +			/* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ] +			 * to default value(1T1R) */ +			memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), +				 &rtl_band_2ghz, +				 sizeof(struct ieee80211_supported_band)); -	/* <3> init ht cap base on ant_num */ -	_rtl_init_hw_ht_capab(hw, &sband->ht_cap); +			/* <3> init ht cap base on ant_num */ +			_rtl_init_hw_ht_capab(hw, &sband->ht_cap); -	/* <4> set mac->sband to wiphy->sband */ -	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; +			/* <4> set mac->sband to wiphy->sband */ +			hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; +		} else if (rtlhal->current_bandtype == BAND_ON_5G) { +			/* <1> use  mac->bands as mem for hw->wiphy->bands */ +			sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]); +			/* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ] +			 * to default value(1T1R) */ +			memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), +				 &rtl_band_5ghz, +				 sizeof(struct ieee80211_supported_band)); + +			/* <3> init ht cap base on ant_num */ +			_rtl_init_hw_ht_capab(hw, &sband->ht_cap); + +			/* <4> set mac->sband to wiphy->sband */ +			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; +		} else { +			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, +				 ("Err BAND %d\n", +				 rtlhal->current_bandtype)); +		} +	}  	/* <5> set hw caps */  	hw->flags = IEEE80211_HW_SIGNAL_DBM |  	    IEEE80211_HW_RX_INCLUDES_FCS | -	    IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/ -	    /*IEEE80211_HW_SUPPORTS_PS | */ -	    /*IEEE80211_HW_PS_NULLFUNC_STACK | */ -	    /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ +	    IEEE80211_HW_BEACON_FILTER | +	    IEEE80211_HW_AMPDU_AGGREGATION |  	    IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0; +	/* swlps or hwlps has been set in diff chip in init_sw_vars */ +	if (rtlpriv->psc.swctrl_lps) +		hw->flags |= IEEE80211_HW_SUPPORTS_PS | +			IEEE80211_HW_PS_NULLFUNC_STACK | +			/* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */ +			0; +  	hw->wiphy->interface_modes = -	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); +	    BIT(NL80211_IFTYPE_AP) | +	    BIT(NL80211_IFTYPE_STATION) | +	    BIT(NL80211_IFTYPE_ADHOC);  	hw->wiphy->rts_threshold = 2347; @@ -199,9 +331,10 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)  	/* TODO: Correct this value for our hw */  	/* TODO: define these hard code value */  	hw->channel_change_time = 100; -	hw->max_listen_interval = 5; +	hw->max_listen_interval = 10;  	hw->max_rate_tries = 4;  	/* hw->max_rates = 1; */ +	hw->sta_data_size = sizeof(struct rtl_sta_info);  	/* <6> mac address */  	if (is_valid_ether_addr(rtlefuse->dev_addr)) { @@ -230,6 +363,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)  			  (void *)rtl_watchdog_wq_callback);  	INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,  			  (void *)rtl_ips_nic_off_wq_callback); +	INIT_DELAYED_WORK(&rtlpriv->works.ps_work, +			  (void *)rtl_swlps_wq_callback); +	INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq, +			  (void *)rtl_swlps_rfon_wq_callback);  } @@ -241,6 +378,8 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw)  	cancel_delayed_work(&rtlpriv->works.watchdog_wq);  	cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); +	cancel_delayed_work(&rtlpriv->works.ps_work); +	cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);  }  void rtl_init_rfkill(struct ieee80211_hw *hw) @@ -310,6 +449,8 @@ int rtl_init_core(struct ieee80211_hw *hw)  	spin_lock_init(&rtlpriv->locks.rf_ps_lock);  	spin_lock_init(&rtlpriv->locks.rf_lock);  	spin_lock_init(&rtlpriv->locks.lps_lock); +	spin_lock_init(&rtlpriv->locks.waitq_lock); +	spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);  	rtlmac->link_state = MAC80211_NOLINK; @@ -329,12 +470,6 @@ void rtl_init_rx_config(struct ieee80211_hw *hw)  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); -	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER, -				      (u8 *) (&mac->rx_mgt_filter)); -	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER, -				      (u8 *) (&mac->rx_ctrl_filter)); -	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER, -				      (u8 *) (&mac->rx_data_filter));  }  /********************************************************* @@ -361,28 +496,40 @@ static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,  }  static void _rtl_query_shortgi(struct ieee80211_hw *hw, +			       struct ieee80211_sta *sta,  			       struct rtl_tcb_desc *tcb_desc,  			       struct ieee80211_tx_info *info)  {  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	u8 rate_flag = info->control.rates[0].flags; - +	u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0;  	tcb_desc->use_shortgi = false; -	if (!mac->ht_enable) +	if (sta == NULL)  		return; -	if (!mac->sgi_40 && !mac->sgi_20) +	sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; +	sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + +	if (!(sta->ht_cap.ht_supported))  		return; -	if ((mac->bw_40 == true) && mac->sgi_40) +	if (!sgi_40 && !sgi_20) +		return; + +	if (mac->opmode == NL80211_IFTYPE_STATION) +		bw_40 = mac->bw_40; +	else if (mac->opmode == NL80211_IFTYPE_AP || +		mac->opmode == NL80211_IFTYPE_ADHOC) +		bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40; + +	if ((bw_40 == true) && sgi_40)  		tcb_desc->use_shortgi = true; -	else if ((mac->bw_40 == false) && mac->sgi_20) +	else if ((bw_40 == false) && sgi_20)  		tcb_desc->use_shortgi = true;  	if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))  		tcb_desc->use_shortgi = false; -  }  static void _rtl_query_protection_mode(struct ieee80211_hw *hw, @@ -410,19 +557,25 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw,  		tcb_desc->rts_enable = true;  		tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];  	} -  }  static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, +				   struct ieee80211_sta *sta,  				   struct rtl_tcb_desc *tcb_desc)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_sta_info *sta_entry = NULL; +	u8 ratr_index = 7; +	if (sta) { +		sta_entry = (struct rtl_sta_info *) sta->drv_priv; +		ratr_index = sta_entry->ratr_index; +	}  	if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) { -		if (mac->opmode == NL80211_IFTYPE_STATION) +		if (mac->opmode == NL80211_IFTYPE_STATION) {  			tcb_desc->ratr_index = 0; -		else if (mac->opmode == NL80211_IFTYPE_ADHOC) { +		} else if (mac->opmode == NL80211_IFTYPE_ADHOC) {  			if (tcb_desc->multicast || tcb_desc->broadcast) {  				tcb_desc->hw_rate =  				    rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; @@ -430,36 +583,61 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,  			} else {  				/* TODO */  			} +			tcb_desc->ratr_index = ratr_index; +		} else if (mac->opmode == NL80211_IFTYPE_AP) { +			tcb_desc->ratr_index = ratr_index;  		}  	}  	if (rtlpriv->dm.useramask) { -		/* TODO adhoc and station handled differently in the future */ -		tcb_desc->mac_id = 0; +		/* TODO we will differentiate adhoc and station futrue  */ +		if (mac->opmode == NL80211_IFTYPE_STATION) { +			tcb_desc->mac_id = 0; -		if ((mac->mode == WIRELESS_MODE_N_24G) || -		    (mac->mode == WIRELESS_MODE_N_5G)) { -			tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB; -		} else if (mac->mode & WIRELESS_MODE_G) { -			tcb_desc->ratr_index = RATR_INX_WIRELESS_GB; -		} else if (mac->mode & WIRELESS_MODE_B) { -			tcb_desc->ratr_index = RATR_INX_WIRELESS_B; +			if (mac->mode == WIRELESS_MODE_N_24G) +				tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB; +			else if (mac->mode == WIRELESS_MODE_N_5G) +				tcb_desc->ratr_index = RATR_INX_WIRELESS_NG; +			else if (mac->mode & WIRELESS_MODE_G) +				tcb_desc->ratr_index = RATR_INX_WIRELESS_GB; +			else if (mac->mode & WIRELESS_MODE_B) +				tcb_desc->ratr_index = RATR_INX_WIRELESS_B; +			else if (mac->mode & WIRELESS_MODE_A) +				tcb_desc->ratr_index = RATR_INX_WIRELESS_G; +		} else if (mac->opmode == NL80211_IFTYPE_AP || +			mac->opmode == NL80211_IFTYPE_ADHOC) { +			if (NULL != sta) { +				if (sta->aid > 0) +					tcb_desc->mac_id = sta->aid + 1; +				else +					tcb_desc->mac_id = 1; +			} else { +				tcb_desc->mac_id = 0; +			}  		}  	}  }  static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, +				      struct ieee80211_sta *sta,  				      struct rtl_tcb_desc *tcb_desc)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	tcb_desc->packet_bw = false; - -	if (!mac->bw_40 || !mac->ht_enable) +	if (!sta)  		return; - +	if (mac->opmode == NL80211_IFTYPE_AP || +	    mac->opmode == NL80211_IFTYPE_ADHOC) { +		if (!(sta->ht_cap.ht_supported) || +		    !(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) +			return; +	} else if (mac->opmode == NL80211_IFTYPE_STATION) { +		if (!mac->bw_40 || !(sta->ht_cap.ht_supported)) +			return; +	}  	if (tcb_desc->multicast || tcb_desc->broadcast)  		return; @@ -486,22 +664,21 @@ static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)  void rtl_get_tcb_desc(struct ieee80211_hw *hw,  		      struct ieee80211_tx_info *info, +		      struct ieee80211_sta *sta,  		      struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); +	struct ieee80211_hdr *hdr = rtl_get_hdr(skb);  	struct ieee80211_rate *txrate;  	__le16 fc = hdr->frame_control; -	memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc)); +	txrate = ieee80211_get_tx_rate(hw, info); +	tcb_desc->hw_rate = txrate->hw_value;  	if (ieee80211_is_data(fc)) { -		txrate = ieee80211_get_tx_rate(hw, info); -		tcb_desc->hw_rate = txrate->hw_value; -  		/* -		 *we set data rate RTL_RC_CCK_RATE1M +		 *we set data rate INX 0  		 *in rtl_rc.c   if skb is special data or  		 *mgt which need low data rate.  		 */ @@ -510,12 +687,11 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,  		 *So tcb_desc->hw_rate is just used for  		 *special data and mgt frames  		 */ -		if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) { +		if (info->control.rates[0].idx == 0 && +				ieee80211_is_nullfunc(fc)) {  			tcb_desc->use_driver_rate = true; -			tcb_desc->ratr_index = 7; +			tcb_desc->ratr_index = RATR_INX_WIRELESS_MC; -			tcb_desc->hw_rate = -			    rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];  			tcb_desc->disable_ratefallback = 1;  		} else {  			/* @@ -525,7 +701,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,  			 *and N rate will all be controlled by FW  			 *when tcb_desc->use_driver_rate = false  			 */ -			if (rtlmac->ht_enable) { +			if (sta && (sta->ht_cap.ht_supported)) {  				tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw);  			} else {  				if (rtlmac->mode == WIRELESS_MODE_B) { @@ -543,43 +719,25 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,  		else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))  			tcb_desc->broadcast = 1; -		_rtl_txrate_selectmode(hw, tcb_desc); -		_rtl_query_bandwidth_mode(hw, tcb_desc); +		_rtl_txrate_selectmode(hw, sta, tcb_desc); +		_rtl_query_bandwidth_mode(hw, sta, tcb_desc);  		_rtl_qurey_shortpreamble_mode(hw, tcb_desc, info); -		_rtl_query_shortgi(hw, tcb_desc, info); +		_rtl_query_shortgi(hw, sta, tcb_desc, info);  		_rtl_query_protection_mode(hw, tcb_desc, info);  	} else {  		tcb_desc->use_driver_rate = true; -		tcb_desc->ratr_index = 7; +		tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;  		tcb_desc->disable_ratefallback = 1;  		tcb_desc->mac_id = 0; - -		tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; +		tcb_desc->packet_bw = false;  	}  }  EXPORT_SYMBOL(rtl_get_tcb_desc); -bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) -{ -	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); -	__le16 fc = hdr->frame_control; - -	if (ieee80211_is_auth(fc)) { -		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); -		rtl_ips_nic_on(hw); - -		mac->link_state = MAC80211_LINKING; -	} - -	return true; -} -  bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)  {  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); +	struct ieee80211_hdr *hdr = rtl_get_hdr(skb);  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	__le16 fc = hdr->frame_control;  	u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); @@ -624,9 +782,8 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)  u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); -	__le16 fc = hdr->frame_control; +	__le16 fc = rtl_get_fc(skb);  	u16 ether_type;  	u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);  	const struct iphdr *ip; @@ -634,12 +791,11 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)  	if (!ieee80211_is_data(fc))  		return false; -	if (ieee80211_is_nullfunc(fc)) -		return true;  	ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +  			      SNAP_SIZE + PROTOC_TYPE_SIZE);  	ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); +	/*	ether_type = ntohs(ether_type); */  	if (ETH_P_IP == ether_type) {  		if (IPPROTO_UDP == ip->protocol) { @@ -696,61 +852,92 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)   * functions called by core.c   *   *********************************************************/ -int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn) +int rtl_tx_agg_start(struct ieee80211_hw *hw, +		struct ieee80211_sta *sta, u16 tid, u16 *ssn)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_tid_data *tid_data;  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_sta_info *sta_entry = NULL; -	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, -		 ("on ra = %pM tid = %d\n", ra, tid)); +	if (sta == NULL) +		return -EINVAL;  	if (unlikely(tid >= MAX_TID_COUNT))  		return -EINVAL; -	if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) { -		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, -			 ("Start AGG when state is not RTL_AGG_OFF !\n")); +	sta_entry = (struct rtl_sta_info *)sta->drv_priv; +	if (!sta_entry)  		return -ENXIO; -	} - -	tid_data = &mac->tids[tid]; -	*ssn = SEQ_TO_SN(tid_data->seq_number); +	tid_data = &sta_entry->tids[tid];  	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, -		 ("HW queue is empty tid:%d\n", tid)); -	tid_data->agg.agg_state = RTL_AGG_ON; +		 ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid, +		 tid_data->seq_number)); + +	*ssn = tid_data->seq_number; +	tid_data->agg.agg_state = RTL_AGG_START; -	ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid); +	ieee80211_start_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid);  	return 0;  } -int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid) +int rtl_tx_agg_stop(struct ieee80211_hw *hw, +		struct ieee80211_sta *sta, u16 tid)  { -	int ssn = -1;  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rtl_tid_data *tid_data; +	struct rtl_sta_info *sta_entry = NULL; + +	if (sta == NULL) +		return -EINVAL; -	if (!ra) { +	if (!sta->addr) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));  		return -EINVAL;  	} +	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, +		 ("on ra = %pM tid = %d\n", sta->addr, tid)); +  	if (unlikely(tid >= MAX_TID_COUNT))  		return -EINVAL; -	if (mac->tids[tid].agg.agg_state != RTL_AGG_ON) -		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, -			 ("Stopping AGG while state not ON or starting\n")); +	sta_entry = (struct rtl_sta_info *)sta->drv_priv; +	tid_data = &sta_entry->tids[tid]; +	sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; -	tid_data = &mac->tids[tid]; -	ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; +	ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid); -	mac->tids[tid].agg.agg_state = RTL_AGG_OFF; +	return 0; +} -	ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid); +int rtl_tx_agg_oper(struct ieee80211_hw *hw, +		struct ieee80211_sta *sta, u16 tid) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_tid_data *tid_data; +	struct rtl_sta_info *sta_entry = NULL; + +	if (sta == NULL) +		return -EINVAL; + +	if (!sta->addr) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); +		return -EINVAL; +	} + +	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, +		 ("on ra = %pM tid = %d\n", sta->addr, tid)); + +	if (unlikely(tid >= MAX_TID_COUNT)) +		return -EINVAL; + +	sta_entry = (struct rtl_sta_info *)sta->drv_priv; +	tid_data = &sta_entry->tids[tid]; +	sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL;  	return 0;  } @@ -769,18 +956,16 @@ void rtl_watchdog_wq_callback(void *data)  	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; -	bool higher_busytxtraffic = false; - -	u8 idx = 0; +	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)) @@ -794,9 +979,6 @@ void rtl_watchdog_wq_callback(void *data)  		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 @@ -835,8 +1017,27 @@ void rtl_watchdog_wq_callback(void *data)  			/* Extremely high Rx data. */  			if (aver_rx_cnt_inperiod > 5000)  				higher_busyrxtraffic = true; +		} + +		/* check every tid's tx traffic */ +		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 -				higher_busytxtraffic = false; +				rtlpriv->link_info.higher_busytxtraffic[tid] = +						   false;  		}  		if (((rtlpriv->link_info.num_rx_inperiod + @@ -855,11 +1056,15 @@ void rtl_watchdog_wq_callback(void *data)  	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; +	/* <3> DM */ +	rtlpriv->cfg->ops->dm_watchdog(hw);  }  void rtl_watch_dog_timer_callback(unsigned long data) @@ -876,6 +1081,268 @@ void rtl_watch_dog_timer_callback(unsigned long data)  /*********************************************************   * + * frame process functions + * + *********************************************************/ +u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie) +{ +	struct ieee80211_mgmt *mgmt = (void *)data; +	u8 *pos, *end; + +	pos = (u8 *)mgmt->u.beacon.variable; +	end = data + len; +	while (pos < end) { +		if (pos + 2 + pos[1] > end) +			return NULL; + +		if (pos[0] == ie) +			return pos; + +		pos += 2 + pos[1]; +	} +	return NULL; +} + +/* when we use 2 rx ants we send IEEE80211_SMPS_OFF */ +/* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */ +static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw, +		enum ieee80211_smps_mode smps, u8 *da, u8 *bssid) +{ +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	struct sk_buff *skb; +	struct ieee80211_mgmt *action_frame; + +	/* 27 = header + category + action + smps mode */ +	skb = dev_alloc_skb(27 + hw->extra_tx_headroom); +	if (!skb) +		return NULL; + +	skb_reserve(skb, hw->extra_tx_headroom); +	action_frame = (void *)skb_put(skb, 27); +	memset(action_frame, 0, 27); +	memcpy(action_frame->da, da, ETH_ALEN); +	memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN); +	memcpy(action_frame->bssid, bssid, ETH_ALEN); +	action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | +						  IEEE80211_STYPE_ACTION); +	action_frame->u.action.category = WLAN_CATEGORY_HT; +	action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS; +	switch (smps) { +	case IEEE80211_SMPS_AUTOMATIC:/* 0 */ +	case IEEE80211_SMPS_NUM_MODES:/* 4 */ +		WARN_ON(1); +	case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/ +		action_frame->u.action.u.ht_smps.smps_control = +				WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */ +		break; +	case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/ +		action_frame->u.action.u.ht_smps.smps_control = +				WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */ +		break; +	case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/ +		action_frame->u.action.u.ht_smps.smps_control = +				WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */ +		break; +	} + +	return skb; +} + +int rtl_send_smps_action(struct ieee80211_hw *hw, +		struct ieee80211_sta *sta, u8 *da, u8 *bssid, +		enum ieee80211_smps_mode smps) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct sk_buff *skb = rtl_make_smps_action(hw, smps, da, bssid); +	struct rtl_tcb_desc tcb_desc; +	memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + +	if (rtlpriv->mac80211.act_scanning) +		goto err_free; + +	if (!sta) +		goto err_free; + +	if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON)) +		goto err_free; + +	if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) +		goto err_free; + +	/* this is a type = mgmt * stype = action frame */ +	if (skb) { +		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +		struct rtl_sta_info *sta_entry = +			(struct rtl_sta_info *) sta->drv_priv; +		sta_entry->mimo_ps = smps; +		rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); + +		info->control.rates[0].idx = 0; +		info->control.sta = sta; +		info->band = hw->conf.channel->band; +		rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); +	} +err_free: +	return 0; +} + +/********************************************************* + * + * IOT functions + * + *********************************************************/ +static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw, +		struct octet_string vendor_ie) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	bool matched = false; +	static u8 athcap_1[] = { 0x00, 0x03, 0x7F }; +	static u8 athcap_2[] = { 0x00, 0x13, 0x74 }; +	static u8 broadcap_1[] = { 0x00, 0x10, 0x18 }; +	static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 }; +	static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 }; +	static u8 racap[] = { 0x00, 0x0c, 0x43 }; +	static u8 ciscocap[] = { 0x00, 0x40, 0x96 }; +	static u8 marvcap[] = { 0x00, 0x50, 0x43 }; + +	if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 || +		memcmp(vendor_ie.octet, athcap_2, 3) == 0) { +		rtlpriv->mac80211.vendor = PEER_ATH; +		matched = true; +	} else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 || +		memcmp(vendor_ie.octet, broadcap_2, 3) == 0 || +		memcmp(vendor_ie.octet, broadcap_3, 3) == 0) { +		rtlpriv->mac80211.vendor = PEER_BROAD; +		matched = true; +	} else if (memcmp(vendor_ie.octet, racap, 3) == 0) { +		rtlpriv->mac80211.vendor = PEER_RAL; +		matched = true; +	} else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) { +		rtlpriv->mac80211.vendor = PEER_CISCO; +		matched = true; +	} else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) { +		rtlpriv->mac80211.vendor = PEER_MARV; +		matched = true; +	} + +	return matched; +} + +static bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data, +		unsigned int len) +{ +	struct ieee80211_mgmt *mgmt = (void *)data; +	struct octet_string vendor_ie; +	u8 *pos, *end; + +	pos = (u8 *)mgmt->u.beacon.variable; +	end = data + len; +	while (pos < end) { +		if (pos[0] == 221) { +			vendor_ie.length = pos[1]; +			vendor_ie.octet = &pos[2]; +			if (rtl_chk_vendor_ouisub(hw, vendor_ie)) +				return true; +		} + +		if (pos + 2 + pos[1] > end) +			return false; + +		pos += 2 + pos[1]; +	} +	return false; +} + +void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *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; +	u32 vendor = PEER_UNKNOWN; + +	static u8 ap3_1[3] = { 0x00, 0x14, 0xbf }; +	static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 }; +	static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e }; +	static u8 ap4_1[3] = { 0x00, 0x90, 0xcc }; +	static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e }; +	static u8 ap4_3[3] = { 0x00, 0x18, 0x02 }; +	static u8 ap4_4[3] = { 0x00, 0x17, 0x3f }; +	static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf }; +	static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 }; +	static u8 ap5_2[3] = { 0x00, 0x21, 0x91 }; +	static u8 ap5_3[3] = { 0x00, 0x24, 0x01 }; +	static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 }; +	static u8 ap5_5[3] = { 0x00, 0x17, 0x9A }; +	static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 }; +	static u8 ap6_1[3] = { 0x00, 0x17, 0x94 }; +	static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 }; + +	if (mac->opmode != NL80211_IFTYPE_STATION) +		return; + +	if (mac->link_state == MAC80211_NOLINK) { +		mac->vendor = PEER_UNKNOWN; +		return; +	} + +	if (mac->cnt_after_linked > 2) +		return; + +	/* check if this really is a beacon */ +	if (!ieee80211_is_beacon(hdr->frame_control)) +		return; + +	/* min. beacon length + FCS_LEN */ +	if (len <= 40 + FCS_LEN) +		return; + +	/* and only beacons from the associated BSSID, please */ +	if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) +		return; + +	if (rtl_find_221_ie(hw, data, len)) +		vendor = mac->vendor; + +	if ((memcmp(mac->bssid, ap5_1, 3) == 0) || +		(memcmp(mac->bssid, ap5_2, 3) == 0) || +		(memcmp(mac->bssid, ap5_3, 3) == 0) || +		(memcmp(mac->bssid, ap5_4, 3) == 0) || +		(memcmp(mac->bssid, ap5_5, 3) == 0) || +		(memcmp(mac->bssid, ap5_6, 3) == 0) || +		vendor == PEER_ATH) { +		vendor = PEER_ATH; +		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n")); +	} else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || +		(memcmp(mac->bssid, ap4_5, 3) == 0) || +		(memcmp(mac->bssid, ap4_1, 3) == 0) || +		(memcmp(mac->bssid, ap4_2, 3) == 0) || +		(memcmp(mac->bssid, ap4_3, 3) == 0) || +		vendor == PEER_RAL) { +		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n")); +		vendor = PEER_RAL; +	} else if (memcmp(mac->bssid, ap6_1, 3) == 0 || +		vendor == PEER_CISCO) { +		vendor = PEER_CISCO; +		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n")); +	} else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || +		(memcmp(mac->bssid, ap3_2, 3) == 0) || +		(memcmp(mac->bssid, ap3_3, 3) == 0) || +		vendor == PEER_BROAD) { +		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n")); +		vendor = PEER_BROAD; +	} else if (memcmp(mac->bssid, ap7_1, 3) == 0 || +		vendor == PEER_MARV) { +		vendor = PEER_MARV; +		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n")); +	} + +	mac->vendor = vendor; +} + +/********************************************************* + *   * sysfs functions   *   *********************************************************/ @@ -941,12 +1408,13 @@ static int __init rtl_core_module_init(void)  	if (rtl_rate_control_register())  		printk(KERN_ERR "rtlwifi: Unable to register rtl_rc,"  		       "use default RC !!\n"); +  	return 0;  }  static void __exit rtl_core_module_exit(void)  { -	 /*RC*/ +	/*RC*/  	rtl_rate_control_unregister();  } diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 043045342bc..a91f3eee59c 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h @@ -24,13 +24,26 @@   * Hsinchu 300, Taiwan.   *   * Larry Finger <Larry.Finger@lwfinger.net> + *   *****************************************************************************/  #ifndef __RTL_BASE_H__  #define __RTL_BASE_H__ +enum ap_peer { +	PEER_UNKNOWN = 0, +	PEER_RTL = 1, +	PEER_RTL_92SE = 2, +	PEER_BROAD = 3, +	PEER_RAL = 4, +	PEER_ATH = 5, +	PEER_CISCO = 6, +	PEER_MARV = 7, +	PEER_AIRGO = 9, +	PEER_MAX = 10, +} ; +  #define RTL_DUMMY_OFFSET	0 -#define RTL_RX_DESC_SIZE	24  #define RTL_DUMMY_UNIT		8  #define RTL_TX_DUMMY_SIZE	(RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)  #define RTL_TX_DESC_SIZE	32 @@ -53,6 +66,14 @@  #define FRAME_OFFSET_SEQUENCE		22  #define FRAME_OFFSET_ADDRESS4		24 +#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val)		\ +	WRITEEF2BYTE(_hdr, _val) +#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val)	\ +	WRITEEF1BYTE(_hdr, _val) +#define SET_80211_HDR_PWR_MGNT(_hdr, _val)		\ +	SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val) +#define SET_80211_HDR_TO_DS(_hdr, _val)			\ +	SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)  #define SET_80211_PS_POLL_AID(_hdr, _val)		\  	(*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val)) @@ -64,11 +85,27 @@  #define SET_80211_HDR_DURATION(_hdr, _val)	\  	(*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val))  #define SET_80211_HDR_ADDRESS1(_hdr, _val)	\ -	memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN) +	CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8 *)(_val))  #define SET_80211_HDR_ADDRESS2(_hdr, _val)	\ -	memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN) +	CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8 *)(_val))  #define SET_80211_HDR_ADDRESS3(_hdr, _val)	\ -	memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN) +	CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val)) +#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val)  \ +	WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val) + +#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val)	\ +	WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val) +#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \ +	WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val) +#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \ +	WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val) +#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr)		\ +	READEF2BYTE(((u8 *)(__phdr)) + 34) +#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ +	WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val) +#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ +	SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \ +	(GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))  int rtl_init_core(struct ieee80211_hw *hw);  void rtl_deinit_core(struct ieee80211_hw *hw); @@ -80,18 +117,27 @@ void rtl_watch_dog_timer_callback(unsigned long data);  void rtl_deinit_deferred_work(struct ieee80211_hw *hw);  bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); -bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);  u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);  void rtl_watch_dog_timer_callback(unsigned long data); -int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, +int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_sta *sta,  		     u16 tid, u16 *ssn); -int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid); +int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_sta *sta, +		    u16 tid); +int rtl_tx_agg_oper(struct ieee80211_hw *hw, struct ieee80211_sta *sta, +		    u16 tid);  void rtl_watchdog_wq_callback(void *data);  void rtl_get_tcb_desc(struct ieee80211_hw *hw,  		      struct ieee80211_tx_info *info, +		      struct ieee80211_sta *sta,  		      struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc); +int rtl_send_smps_action(struct ieee80211_hw *hw, +		struct ieee80211_sta *sta, u8 *da, u8 *bssid, +		enum ieee80211_smps_mode smps); +u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); +void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); +u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid);  extern struct attribute_group rtl_attribute_group;  #endif diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 52c9c1367ca..7295af0536b 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -23,6 +23,8 @@   * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,   * Hsinchu 300, Taiwan.   * + * Larry Finger <Larry.Finger@lwfinger.net> + *   *****************************************************************************/  #include "wifi.h" @@ -49,7 +51,7 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,  	u32 target_content = 0;  	u8 entry_i; -	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,  		 ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",  		  key_cont_128[0], key_cont_128[1],  		  key_cont_128[2], key_cont_128[3], @@ -68,15 +70,13 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,  			rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],  					target_command); -			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, -				 ("rtl_cam_program_entry(): " -				  "WRITE %x: %x\n", +			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, +				 ("WRITE %x: %x\n",  				  rtlpriv->cfg->maps[WCAMI], target_content)); -			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,  				 ("The Key ID is %d\n", entry_no)); -			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, -				 ("rtl_cam_program_entry(): " -				  "WRITE %x: %x\n", +			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, +				 ("WRITE %x: %x\n",  				  rtlpriv->cfg->maps[RWCAM], target_command));  		} else if (entry_i == 1) { @@ -91,12 +91,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,  			rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],  					target_command); -			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, -				 ("rtl_cam_program_entry(): WRITE A4: %x\n", -				  target_content)); -			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, -				 ("rtl_cam_program_entry(): WRITE A0: %x\n", -				  target_command)); +			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, +				 ("WRITE A4: %x\n", target_content)); +			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, +				 ("WRITE A0: %x\n", target_command));  		} else { @@ -113,16 +111,14 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,  					target_command);  			udelay(100); -			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, -				 ("rtl_cam_program_entry(): WRITE A4: %x\n", -				  target_content)); -			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, -				 ("rtl_cam_program_entry(): WRITE A0: %x\n", -				  target_command)); +			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, +				 ("WRITE A4: %x\n", target_content)); +			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, +				 ("WRITE A0: %x\n", target_command));  		}  	} -	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,  		 ("after set key, usconfig:%x\n", us_config));  } @@ -289,3 +285,71 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)  }  EXPORT_SYMBOL(rtl_cam_empty_entry); + +u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4; +	u8 entry_idx = 0; +	u8 i, *addr; + +	if (NULL == sta_addr) { +		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, +			("sta_addr is NULL.\n")); +		return TOTAL_CAM_ENTRY; +	} +	/* Does STA already exist? */ +	for (i = 4; i < TOTAL_CAM_ENTRY; i++) { +		addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; +		if (memcmp(addr, sta_addr, ETH_ALEN) == 0) +			return i; +	} +	/* Get a free CAM entry. */ +	for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) { +		if ((bitmap & BIT(0)) == 0) { +			RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, +				("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", +				 rtlpriv->sec.hwsec_cam_bitmap, entry_idx)); +			rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx; +			memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx], +			       sta_addr, ETH_ALEN); +			return entry_idx; +		} +		bitmap = bitmap >> 1; +	} +	return TOTAL_CAM_ENTRY; +} +EXPORT_SYMBOL(rtl_cam_get_free_entry); + +void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 bitmap; +	u8 i, *addr; + +	if (NULL == sta_addr) { +		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, +			("sta_addr is NULL.\n")); +	} + +	if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\ +				sta_addr[4]|sta_addr[5]) == 0) { +		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, +			("sta_addr is 00:00:00:00:00:00.\n")); +		return; +	} +	/* Does STA already exist? */ +	for (i = 4; i < TOTAL_CAM_ENTRY; i++) { +		addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; +		bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i; +		if (((bitmap & BIT(0)) == BIT(0)) && +		    (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { +			/* Remove from HW Security CAM */ +			memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN); +			rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); +			printk(KERN_INFO "&&&&&&&&&del entry %d\n", i); +		} +	} +	return; +} +EXPORT_SYMBOL(rtl_cam_del_entry); diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h index dd82f057d53..c62da4eefc7 100644 --- a/drivers/net/wireless/rtlwifi/cam.h +++ b/drivers/net/wireless/rtlwifi/cam.h @@ -23,12 +23,13 @@   * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,   * Hsinchu 300, Taiwan.   * + * Larry Finger <Larry.Finger@lwfinger.net> + *   *****************************************************************************/  #ifndef __RTL_CAM_H_  #define __RTL_CAM_H_ -#define TOTAL_CAM_ENTRY					32  #define CAM_CONTENT_COUNT				8  #define CFG_DEFAULT_KEY					BIT(5) @@ -49,5 +50,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,  void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);  void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);  void rtl_cam_reset_sec_info(struct ieee80211_hw *hw); +u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr); +void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr);  #endif diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 8fed3c68761..fc89cd8c832 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -24,6 +24,7 @@   * Hsinchu 300, Taiwan.   *   * Larry Finger <Larry.Finger@lwfinger.net> + *   *****************************************************************************/  #include "wifi.h" @@ -70,6 +71,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw)  	mac->link_state = MAC80211_NOLINK;  	memset(mac->bssid, 0, 6); +	mac->vendor = PEER_UNKNOWN;  	/*reset sec info */  	rtl_cam_reset_sec_info(hw); @@ -85,6 +87,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_tcb_desc tcb_desc; +	memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));  	if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))  		goto err_free; @@ -92,8 +96,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)  	if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))  		goto err_free; - -	rtlpriv->intf_ops->adapter_tx(hw, skb); +	if (!rtlpriv->intf_ops->waitq_insert(hw, skb)) +		rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);  	return; @@ -134,10 +138,26 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,  		mac->link_state = MAC80211_LINKED;  		rtlpriv->cfg->ops->set_bcn_reg(hw); +		if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) +			mac->basic_rates = 0xfff; +		else +			mac->basic_rates = 0xff0; +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, +				(u8 *) (&mac->basic_rates)); +  		break;  	case NL80211_IFTYPE_AP:  		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  			 ("NL80211_IFTYPE_AP\n")); + +		mac->link_state = MAC80211_LINKED; +		rtlpriv->cfg->ops->set_bcn_reg(hw); +		if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) +			mac->basic_rates = 0xfff; +		else +			mac->basic_rates = 0xff0; +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, +				(u8 *) (&mac->basic_rates));  		break;  	default:  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, @@ -184,13 +204,12 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw,  	mac->vif = NULL;  	mac->link_state = MAC80211_NOLINK;  	memset(mac->bssid, 0, 6); +	mac->vendor = PEER_UNKNOWN;  	mac->opmode = NL80211_IFTYPE_UNSPECIFIED;  	rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); -  	mutex_unlock(&rtlpriv->locks.conf_mutex);  } -  static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -222,10 +241,25 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)  	/*For LPS */  	if (changed & IEEE80211_CONF_CHANGE_PS) { -		if (conf->flags & IEEE80211_CONF_PS) -			rtl_lps_enter(hw); -		else -			rtl_lps_leave(hw); +		cancel_delayed_work(&rtlpriv->works.ps_work); +		cancel_delayed_work(&rtlpriv->works.ps_rfon_wq); +		if (conf->flags & IEEE80211_CONF_PS) { +			rtlpriv->psc.sw_ps_enabled = true; +			/* sleep here is must, or we may recv the beacon and +			 * cause mac80211 into wrong ps state, this will cause +			 * power save nullfunc send fail, and further cause +			 * pkt loss, So sleep must quickly but not immediatly +			 * because that will cause nullfunc send by mac80211 +			 * fail, and cause pkt loss, we have tested that 5mA +			 * is worked very well */ +			if (!rtlpriv->psc.multi_buffered) +				queue_delayed_work(rtlpriv->works.rtl_wq, +						&rtlpriv->works.ps_work, +						MSECS(5)); +		} else { +			rtl_swlps_rf_awake(hw); +			rtlpriv->psc.sw_ps_enabled = false; +		}  	}  	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { @@ -257,7 +291,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)  		case NL80211_CHAN_NO_HT:  			/* SC */  			mac->cur_40_prime_sc = -			    PRIME_CHNL_OFFSET_DONT_CARE; +				PRIME_CHNL_OFFSET_DONT_CARE;  			rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;  			mac->bw_40 = false;  			break; @@ -265,7 +299,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)  			/* SC */  			mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;  			rtlphy->current_chan_bw = -			    HT_CHANNEL_WIDTH_20_40; +				HT_CHANNEL_WIDTH_20_40;  			mac->bw_40 = true;  			/*wide channel */ @@ -276,7 +310,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)  			/* SC */  			mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;  			rtlphy->current_chan_bw = -			    HT_CHANNEL_WIDTH_20_40; +				HT_CHANNEL_WIDTH_20_40;  			mac->bw_40 = true;  			/*wide channel */ @@ -286,16 +320,29 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)  		default:  			mac->bw_40 = false;  			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -				 ("switch case not processed\n")); +					("switch case not processed\n"));  			break;  		}  		if (wide_chan <= 0)  			wide_chan = 1; + +		/* In scanning, before we go offchannel we may send a ps=1 null +		 * to AP, and then we may send a ps = 0 null to AP quickly, but +		 * first null may have caused AP to put lots of packet to hw tx +		 * buffer. These packets must be tx'd before we go off channel +		 * so we must delay more time to let AP flush these packets +		 * before going offchannel, or dis-association or delete BA will +		 * happen by AP +		 */ +		if (rtlpriv->mac80211.offchan_deley) { +			rtlpriv->mac80211.offchan_deley = false; +			mdelay(50); +		}  		rtlphy->current_channel = wide_chan; -		rtlpriv->cfg->ops->set_channel_access(hw);  		rtlpriv->cfg->ops->switch_channel(hw); +		rtlpriv->cfg->ops->set_channel_access(hw);  		rtlpriv->cfg->ops->set_bw_mode(hw,  					       hw->conf.channel_type);  	} @@ -343,27 +390,28 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,  		}  	} -	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { -		/* -		 *TODO: BIT(5) is probe response BIT(8) is beacon -		 *TODO: Use define for BIT(5) and BIT(8) -		 */ -		if (*new_flags & FIF_BCN_PRBRESP_PROMISC) -			mac->rx_mgt_filter |= (BIT(5) | BIT(8)); -		else -			mac->rx_mgt_filter &= ~(BIT(5) | BIT(8)); +	/* if ssid not set to hw don't check bssid +	 * here just used for linked scanning, & linked +	 * and nolink check bssid is set in set network_type */ +	if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) && +		(mac->link_state >= MAC80211_LINKED)) { +		if (mac->opmode != NL80211_IFTYPE_AP) { +			if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { +				rtlpriv->cfg->ops->set_chk_bssid(hw, false); +			} else { +				rtlpriv->cfg->ops->set_chk_bssid(hw, true); +			} +		}  	}  	if (changed_flags & FIF_CONTROL) {  		if (*new_flags & FIF_CONTROL) {  			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; -			mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER;  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 ("Enable receive control frame.\n"));  		} else {  			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; -			mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER;  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 ("Disable receive control frame.\n"));  		} @@ -380,14 +428,54 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,  				 ("Disable receive other BSS's frame.\n"));  		}  	} - -	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf)); -	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER, -				      (u8 *) (&mac->rx_mgt_filter)); -	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER, -				      (u8 *) (&mac->rx_ctrl_filter));  } +static int rtl_op_sta_add(struct ieee80211_hw *hw, +			 struct ieee80211_vif *vif, +			 struct ieee80211_sta *sta) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_sta_info *sta_entry; +	if (sta) { +		sta_entry = (struct rtl_sta_info *) sta->drv_priv; +		if (rtlhal->current_bandtype == BAND_ON_2_4G) { +			sta_entry->wireless_mode = WIRELESS_MODE_G; +			if (sta->supp_rates[0] <= 0xf) +				sta_entry->wireless_mode = WIRELESS_MODE_B; +			if (sta->ht_cap.ht_supported == true) +				sta_entry->wireless_mode = WIRELESS_MODE_N_24G; +		} else if (rtlhal->current_bandtype == BAND_ON_5G) { +			sta_entry->wireless_mode = WIRELESS_MODE_A; +			if (sta->ht_cap.ht_supported == true) +				sta_entry->wireless_mode = WIRELESS_MODE_N_24G; +		} + +		/* I found some times mac80211 give wrong supp_rates for adhoc*/ +		if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) +			sta_entry->wireless_mode = WIRELESS_MODE_G; + +		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, +			("Add sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr))); +		rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); +	} +	return 0; +} +static int rtl_op_sta_remove(struct ieee80211_hw *hw, +				struct ieee80211_vif *vif, +				struct ieee80211_sta *sta) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_sta_info *sta_entry; +	if (sta) { +		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, +			("Remove sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr))); +		sta_entry = (struct rtl_sta_info *) sta->drv_priv; +		sta_entry->wireless_mode = 0; +		sta_entry->ratr_index = 0; +	} +	return 0; +}  static int _rtl_get_hal_qnum(u16 queue)  {  	int qnum; @@ -444,19 +532,18 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  			     struct ieee80211_bss_conf *bss_conf, u32 changed)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct ieee80211_sta *sta = NULL;  	mutex_lock(&rtlpriv->locks.conf_mutex); -  	if ((vif->type == NL80211_IFTYPE_ADHOC) ||  	    (vif->type == NL80211_IFTYPE_AP) ||  	    (vif->type == NL80211_IFTYPE_MESH_POINT)) { -  		if ((changed & BSS_CHANGED_BEACON) ||  		    (changed & BSS_CHANGED_BEACON_ENABLED &&  		     bss_conf->enable_beacon)) { -  			if (mac->beacon_enabled == 0) {  				RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,  					 ("BSS_CHANGED_BEACON_ENABLED\n")); @@ -468,8 +555,13 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  						rtlpriv->cfg->maps  						[RTL_IBSS_INT_MASKS],  						0); + +				if (rtlpriv->cfg->ops->linked_set_reg) +					rtlpriv->cfg->ops->linked_set_reg(hw);  			} -		} else { +		} +		if ((changed & BSS_CHANGED_BEACON_ENABLED && +			!bss_conf->enable_beacon)) {  			if (mac->beacon_enabled == 1) {  				RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,  					 ("ADHOC DISABLE BEACON\n")); @@ -480,7 +572,6 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  						[RTL_IBSS_INT_MASKS]);  			}  		} -  		if (changed & BSS_CHANGED_BEACON_INT) {  			RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,  				 ("BSS_CHANGED_BEACON_INT\n")); @@ -492,11 +583,25 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  	/*TODO: reference to enum ieee80211_bss_change */  	if (changed & BSS_CHANGED_ASSOC) {  		if (bss_conf->assoc) { +			/* we should reset all sec info & cam +			 * before set cam after linked, we should not +			 * reset in disassoc, that will cause tkip->wep +			 * fail because some flag will be wrong */ +			/* reset sec info */ +			rtl_cam_reset_sec_info(hw); +			/* reset cam to fix wep fail issue +			 * when change from wpa to wep */ +			rtl_cam_reset_all_entry(hw); +  			mac->link_state = MAC80211_LINKED;  			mac->cnt_after_linked = 0;  			mac->assoc_id = bss_conf->aid;  			memcpy(mac->bssid, bss_conf->bssid, 6); +			if (rtlpriv->cfg->ops->linked_set_reg) +				rtlpriv->cfg->ops->linked_set_reg(hw); +			if (mac->opmode == NL80211_IFTYPE_STATION && sta) +				rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,  				 ("BSS_CHANGED_ASSOC\n"));  		} else { @@ -505,9 +610,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  			mac->link_state = MAC80211_NOLINK;  			memset(mac->bssid, 0, 6); - -			/* reset sec info */ -			rtl_cam_reset_sec_info(hw); +			mac->vendor = PEER_UNKNOWN;  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,  				 ("BSS_CHANGED_UN_ASSOC\n")); @@ -544,14 +647,10 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  	}  	if (changed & BSS_CHANGED_HT) { -		struct ieee80211_sta *sta = NULL; -  		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,  			 ("BSS_CHANGED_HT\n")); -  		rcu_read_lock(); -		sta = ieee80211_find_sta(mac->vif, mac->bssid); - +		sta = get_sta(hw, vif, (u8 *)bss_conf->bssid);  		if (sta) {  			if (sta->ht_cap.ampdu_density >  			    mac->current_ampdu_density) @@ -573,9 +672,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  	}  	if (changed & BSS_CHANGED_BSSID) { -		struct ieee80211_sta *sta = NULL;  		u32 basic_rates; -		u8 i;  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,  					      (u8 *) bss_conf->bssid); @@ -583,96 +680,65 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,  			 (MAC_FMT "\n", MAC_ARG(bss_conf->bssid))); +		mac->vendor = PEER_UNKNOWN;  		memcpy(mac->bssid, bss_conf->bssid, 6); -		if (is_valid_ether_addr(bss_conf->bssid)) { -			switch (vif->type) { -			case NL80211_IFTYPE_UNSPECIFIED: -				break; -			case NL80211_IFTYPE_ADHOC: -				break; -			case NL80211_IFTYPE_STATION: -				break; -			case NL80211_IFTYPE_AP: -				break; -			default: -				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -					 ("switch case not process\n")); -				break; -			} -			rtlpriv->cfg->ops->set_network_type(hw, vif->type); -		} else -			rtlpriv->cfg->ops->set_network_type(hw, -					NL80211_IFTYPE_UNSPECIFIED); - -		memset(mac->mcs, 0, 16); -		mac->ht_enable = false; -		mac->sgi_40 = false; -		mac->sgi_20 = false; - -		if (!bss_conf->use_short_slot) -			mac->mode = WIRELESS_MODE_B; -		else -			mac->mode = WIRELESS_MODE_G; +		rtlpriv->cfg->ops->set_network_type(hw, vif->type);  		rcu_read_lock(); -		sta = ieee80211_find_sta(mac->vif, mac->bssid); - -		if (sta) { -			if (sta->ht_cap.ht_supported) { -				mac->mode = WIRELESS_MODE_N_24G; -				mac->ht_enable = true; -			} +		sta = get_sta(hw, vif, (u8 *)bss_conf->bssid); +		if (!sta) { +			rcu_read_unlock(); +			goto out; +		} -			if (mac->ht_enable) { -				u16 ht_cap = sta->ht_cap.cap; -				memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16); +		if (rtlhal->current_bandtype == BAND_ON_5G) { +			mac->mode = WIRELESS_MODE_A; +		} else { +			if (sta->supp_rates[0] <= 0xf) +				mac->mode = WIRELESS_MODE_B; +			else +				mac->mode = WIRELESS_MODE_G; +		} -				for (i = 0; i < 16; i++) -					RT_TRACE(rtlpriv, COMP_MAC80211, -						 DBG_LOUD, ("%x ", -							    mac->mcs[i])); -				RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, -					 ("\n")); +		if (sta->ht_cap.ht_supported) { +			if (rtlhal->current_bandtype == BAND_ON_2_4G) +				mac->mode = WIRELESS_MODE_N_24G; +			else +				mac->mode = WIRELESS_MODE_N_5G; +		} -				if (ht_cap & IEEE80211_HT_CAP_SGI_40) -					mac->sgi_40 = true; +		/* just station need it, because ibss & ap mode will +		 * set in sta_add, and will be NULL here */ +		if (mac->opmode == NL80211_IFTYPE_STATION) { +			struct rtl_sta_info *sta_entry; +			sta_entry = (struct rtl_sta_info *) sta->drv_priv; +			sta_entry->wireless_mode = mac->mode; +		} -				if (ht_cap & IEEE80211_HT_CAP_SGI_20) -					mac->sgi_20 = true; +		if (sta->ht_cap.ht_supported) { +			mac->ht_enable = true; -				/* -				 * for cisco 1252 bw20 it's wrong -				 * if (ht_cap & -				 *     IEEE80211_HT_CAP_SUP_WIDTH_20_40) { -				 *	mac->bw_40 = true; -				 * } -				 */ -			} +			/* +			 * for cisco 1252 bw20 it's wrong +			 * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { +			 *	mac->bw_40 = true; +			 * } +			 * */  		} -		rcu_read_unlock(); -		/*mac80211 just give us CCK rates any time -		 *So we add G rate in basic rates when -		 not in B mode*/  		if (changed & BSS_CHANGED_BASIC_RATES) { -			if (mac->mode == WIRELESS_MODE_B) -				basic_rates = bss_conf->basic_rates | 0x00f; +			/* for 5G must << RATE_6M_INDEX=4, +			 * because 5G have no cck rate*/ +			if (rtlhal->current_bandtype == BAND_ON_5G) +				basic_rates = sta->supp_rates[1] << 4;  			else -				basic_rates = bss_conf->basic_rates | 0xff0; - -			if (!vif) -				goto out; +				basic_rates = sta->supp_rates[0];  			mac->basic_rates = basic_rates;  			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,  					(u8 *) (&basic_rates)); - -			if (rtlpriv->dm.useramask) -				rtlpriv->cfg->ops->update_rate_mask(hw, 0); -			else -				rtlpriv->cfg->ops->update_rate_table(hw); -  		} +		rcu_read_unlock();  	}  	/* @@ -758,16 +824,17 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,  	case IEEE80211_AMPDU_TX_START:  		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,  			 ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); -		return rtl_tx_agg_start(hw, sta->addr, tid, ssn); +		return rtl_tx_agg_start(hw, sta, tid, ssn);  		break;  	case IEEE80211_AMPDU_TX_STOP:  		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,  			 ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); -		return rtl_tx_agg_stop(hw, sta->addr, tid); +		return rtl_tx_agg_stop(hw, sta, tid);  		break;  	case IEEE80211_AMPDU_TX_OPERATIONAL:  		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,  			 ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); +		rtl_tx_agg_oper(hw, sta, tid);  		break;  	case IEEE80211_AMPDU_RX_START:  		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, @@ -797,8 +864,12 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)  	if (mac->link_state == MAC80211_LINKED) {  		rtl_lps_leave(hw);  		mac->link_state = MAC80211_LINKED_SCANNING; -	} else +	} else {  		rtl_ips_nic_on(hw); +	} + +	/* Dual mac */ +	rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;  	rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);  	rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP); @@ -810,22 +881,19 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); - -	rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);  	mac->act_scanning = false; +	/* Dual mac */ +	rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; +  	if (mac->link_state == MAC80211_LINKED_SCANNING) {  		mac->link_state = MAC80211_LINKED; - -		/* fix fwlps issue */ -		rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); - -		if (rtlpriv->dm.useramask) -			rtlpriv->cfg->ops->update_rate_mask(hw, 0); -		else -			rtlpriv->cfg->ops->update_rate_table(hw); - +		if (mac->opmode == NL80211_IFTYPE_STATION) { +			/* fix fwlps issue */ +			rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); +		}  	} +	rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);  }  static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, @@ -856,49 +924,73 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  	rtl_ips_nic_on(hw);  	mutex_lock(&rtlpriv->locks.conf_mutex);  	/* <1> get encryption alg */ +  	switch (key->cipher) {  	case WLAN_CIPHER_SUITE_WEP40:  		key_type = WEP40_ENCRYPTION;  		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); -		rtlpriv->sec.use_defaultkey = true;  		break;  	case WLAN_CIPHER_SUITE_WEP104:  		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,  			 ("alg:WEP104\n"));  		key_type = WEP104_ENCRYPTION; -		rtlpriv->sec.use_defaultkey = true;  		break;  	case WLAN_CIPHER_SUITE_TKIP:  		key_type = TKIP_ENCRYPTION;  		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); -		if (mac->opmode == NL80211_IFTYPE_ADHOC) -			rtlpriv->sec.use_defaultkey = true;  		break;  	case WLAN_CIPHER_SUITE_CCMP:  		key_type = AESCCMP_ENCRYPTION;  		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); -		if (mac->opmode == NL80211_IFTYPE_ADHOC) -			rtlpriv->sec.use_defaultkey = true;  		break;  	default:  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 ("alg_err:%x!!!!:\n", key->cipher));  		goto out_unlock;  	} +	if (key_type == WEP40_ENCRYPTION || +			key_type == WEP104_ENCRYPTION || +			mac->opmode == NL80211_IFTYPE_ADHOC) +		rtlpriv->sec.use_defaultkey = true; +  	/* <2> get key_idx */  	key_idx = (u8) (key->keyidx);  	if (key_idx > 3)  		goto out_unlock;  	/* <3> if pairwise key enable_hw_sec */  	group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE); -	if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) || -	    rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { -		if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION && -		    (key_type == WEP40_ENCRYPTION || -		     key_type == WEP104_ENCRYPTION)) -			wep_only = true; -		rtlpriv->sec.pairwise_enc_algorithm = key_type; -		rtlpriv->cfg->ops->enable_hw_sec(hw); + +	/* wep always be group key, but there are two conditions: +	 * 1) wep only: is just for wep enc, in this condition +	 * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION +	 * will be true & enable_hw_sec will be set when wep +	 * ke setting. +	 * 2) wep(group) + AES(pairwise): some AP like cisco +	 * may use it, in this condition enable_hw_sec will not +	 * be set when wep key setting */ +	/* we must reset sec_info after lingked before set key, +	 * or some flag will be wrong*/ +	if (mac->opmode == NL80211_IFTYPE_AP) { +		if (!group_key || key_type == WEP40_ENCRYPTION || +			key_type == WEP104_ENCRYPTION) { +			if (group_key) +				wep_only = true; +			rtlpriv->cfg->ops->enable_hw_sec(hw); +		} +	} else { +		if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) || +		     rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) { +			if (rtlpriv->sec.pairwise_enc_algorithm == +			    NO_ENCRYPTION && +			    (key_type == WEP40_ENCRYPTION || +			    key_type == WEP104_ENCRYPTION)) +				wep_only = true; +			rtlpriv->sec.pairwise_enc_algorithm = key_type; +			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +				("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1" +				" TKIP:2 AES:4 WEP104:5)\n", key_type)); +			rtlpriv->cfg->ops->enable_hw_sec(hw); +		}  	}  	/* <4> set key based on cmd */  	switch (cmd) { @@ -930,6 +1022,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  			if (!sta) {  				RT_ASSERT(false, ("pairwise key withnot"  						  "mac_addr\n")); +  				err = -EOPNOTSUPP;  				goto out_unlock;  			} @@ -957,6 +1050,10 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,  			 ("disable key delete one entry\n"));  		/*set local buf about wep key. */ +		if (mac->opmode == NL80211_IFTYPE_AP) { +			if (sta) +				rtl_cam_del_entry(hw, sta->addr); +		}  		memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);  		rtlpriv->sec.key_len[key_idx] = 0;  		memcpy(mac_addr, zero_addr, ETH_ALEN); @@ -1009,6 +1106,18 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)  	mutex_unlock(&rtlpriv->locks.conf_mutex);  } +/* this function is called by mac80211 to flush tx buffer + * before switch channle or power save, or tx buffer packet + * maybe send after offchannel or rf sleep, this may cause + * dis-association by AP */ +static void rtl_op_flush(struct ieee80211_hw *hw, bool drop) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	if (rtlpriv->intf_ops->flush) +		rtlpriv->intf_ops->flush(hw, drop); +} +  const struct ieee80211_ops rtl_ops = {  	.start = rtl_op_start,  	.stop = rtl_op_stop, @@ -1017,6 +1126,8 @@ const struct ieee80211_ops rtl_ops = {  	.remove_interface = rtl_op_remove_interface,  	.config = rtl_op_config,  	.configure_filter = rtl_op_configure_filter, +	.sta_add = rtl_op_sta_add, +	.sta_remove = rtl_op_sta_remove,  	.set_key = rtl_op_set_key,  	.conf_tx = rtl_op_conf_tx,  	.bss_info_changed = rtl_op_bss_info_changed, @@ -1028,4 +1139,5 @@ const struct ieee80211_ops rtl_ops = {  	.sw_scan_start = rtl_op_sw_scan_start,  	.sw_scan_complete = rtl_op_sw_scan_complete,  	.rfkill_poll = rtl_op_rfkill_poll, +	.flush = rtl_op_flush,  }; diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 0ef31c3c619..4b247db2861 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -24,6 +24,7 @@   * Hsinchu 300, Taiwan.   *   * Larry Finger <Larry.Finger@lwfinger.net> + *   *****************************************************************************/  #ifndef __RTL_CORE_H__ diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 5d73c0f7012..510d42edb8c 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -52,8 +52,6 @@ static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {  	{11, 0, 0, 28}  }; -static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, -					u8 *pbuf);  static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,  				    u8 *value);  static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset, @@ -79,7 +77,7 @@ static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,  					u8 *targetdata);  static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,  				       u16 efuse_addr, u8 word_en, u8 *data); -static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, +static void efuse_power_switch(struct ieee80211_hw *hw, u8 write,  					u8 pwrstate);  static u16 efuse_get_current_size(struct ieee80211_hw *hw);  static u8 efuse_calculate_word_cnts(u8 word_en); @@ -115,8 +113,10 @@ u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)  	u8 bytetemp;  	u8 temp;  	u32 k = 0; +	const u32 efuse_len = +		rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; -	if (address < EFUSE_REAL_CONTENT_LEN) { +	if (address < efuse_len) {  		temp = address & 0xFF;  		rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,  			       temp); @@ -158,11 +158,13 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)  	u8 bytetemp;  	u8 temp;  	u32 k = 0; +	const u32 efuse_len = +		rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];  	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,  		 ("Addr=%x Data =%x\n", address, value)); -	if (address < EFUSE_REAL_CONTENT_LEN) { +	if (address < efuse_len) {  		rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);  		temp = address & 0xFF; @@ -198,7 +200,7 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)  } -static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf) +void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	u32 value32; @@ -233,24 +235,28 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); -	u8 efuse_tbl[EFUSE_MAP_LEN]; +	u8 efuse_tbl[HWSET_MAX_SIZE];  	u8 rtemp8[1];  	u16 efuse_addr = 0;  	u8 offset, wren;  	u16 i;  	u16 j; +	const u16 efuse_max_section = +		rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP]; +	const u32 efuse_len = +		rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];  	u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];  	u16 efuse_utilized = 0;  	u8 efuse_usage; -	if ((_offset + _size_byte) > EFUSE_MAP_LEN) { +	if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {  		RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,  			 ("read_efuse(): Invalid offset(%#x) with read "  			  "bytes(%#x)!!\n", _offset, _size_byte));  		return;  	} -	for (i = 0; i < EFUSE_MAX_SECTION; i++) +	for (i = 0; i < efuse_max_section; i++)  		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)  			efuse_word[i][j] = 0xFFFF; @@ -262,10 +268,10 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)  		efuse_addr++;  	} -	while ((*rtemp8 != 0xFF) && (efuse_addr < EFUSE_REAL_CONTENT_LEN)) { +	while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) {  		offset = ((*rtemp8 >> 4) & 0x0f); -		if (offset < EFUSE_MAX_SECTION) { +		if (offset < efuse_max_section) {  			wren = (*rtemp8 & 0x0f);  			RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,  				("offset-%d Worden=%x\n", offset, wren)); @@ -281,7 +287,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)  					efuse_utilized++;  					efuse_word[offset][i] = (*rtemp8 & 0xff); -					if (efuse_addr >= EFUSE_REAL_CONTENT_LEN) +					if (efuse_addr >= efuse_len)  						break;  					RTPRINT(rtlpriv, FEEPROM, @@ -294,7 +300,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)  					efuse_word[offset][i] |=  					    (((u16)*rtemp8 << 8) & 0xff00); -					if (efuse_addr >= EFUSE_REAL_CONTENT_LEN) +					if (efuse_addr >= efuse_len)  						break;  				} @@ -305,13 +311,13 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)  		RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,  			("Addr=%d\n", efuse_addr));  		read_efuse_byte(hw, efuse_addr, rtemp8); -		if (*rtemp8 != 0xFF && (efuse_addr < 512)) { +		if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) {  			efuse_utilized++;  			efuse_addr++;  		}  	} -	for (i = 0; i < EFUSE_MAX_SECTION; i++) { +	for (i = 0; i < efuse_max_section; i++) {  		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {  			efuse_tbl[(i * 8) + (j * 2)] =  			    (efuse_word[i][j] & 0xff); @@ -324,7 +330,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)  		pbuf[i] = efuse_tbl[_offset + i];  	rtlefuse->efuse_usedbytes = efuse_utilized; -	efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN); +	efuse_usage = (u8) ((efuse_utilized * 100) / efuse_len);  	rtlefuse->efuse_usedpercentage = efuse_usage;  	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,  				      (u8 *)&efuse_utilized); @@ -478,9 +484,10 @@ void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); -	if (rtlefuse->autoload_failflag == true) { -		memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, 128); -	} else +	if (rtlefuse->autoload_failflag == true) +		memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, +			rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); +	else  		efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);  	memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], @@ -632,8 +639,9 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)  static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)  { +	struct rtl_priv *rtlpriv = rtl_priv(hw);  	efuse_power_switch(hw, false, true); -	read_efuse(hw, 0, 128, efuse); +	read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);  	efuse_power_switch(hw, false, false);  } @@ -641,7 +649,7 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,  				u8 efuse_data, u8 offset, u8 *tmpdata,  				u8 *readstate)  { -	bool bdataempty = true; +	bool dataempty = true;  	u8 hoffset;  	u8 tmpidx;  	u8 hworden; @@ -657,13 +665,13 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,  			    &efuse_data)) {  				tmpdata[tmpidx] = efuse_data;  				if (efuse_data != 0xff) -					bdataempty = true; +					dataempty = true;  			}  		} -		if (bdataempty == true) +		if (dataempty == true) {  			*readstate = PG_STATE_DATA; -		else { +		} else {  			*efuse_addr = *efuse_addr + (word_cnts * 2) + 1;  			*readstate = PG_STATE_HEADER;  		} @@ -677,9 +685,7 @@ static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,  static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)  {  	u8 readstate = PG_STATE_HEADER; -  	bool continual = true; -  	u8 efuse_data, word_cnts = 0;  	u16 efuse_addr = 0;  	u8 tmpdata[8]; @@ -795,19 +801,20 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,  					tmp_word_en &= (~BIT(1));  				if ((target_pkt->word_en & BIT(2)) ^ -					(match_word_en & BIT(2))) +				     (match_word_en & BIT(2)))  					tmp_word_en &= (~BIT(2));  				if ((target_pkt->word_en & BIT(3)) ^ -				    (match_word_en & BIT(3))) +				     (match_word_en & BIT(3)))  					tmp_word_en &= (~BIT(3));  				if ((tmp_word_en & 0x0F) != 0x0F) {  					*efuse_addr = efuse_get_current_size(hw);  					target_pkt->offset = offset;  					target_pkt->word_en = tmp_word_en; -				} else +				} else {  					*continual = false; +				}  				*write_state = PG_STATE_HEADER;  				*repeat_times += 1;  				if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { @@ -842,9 +849,9 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,  	efuse_one_byte_write(hw, *efuse_addr, pg_header);  	efuse_one_byte_read(hw, *efuse_addr, &tmp_header); -	if (tmp_header == pg_header) +	if (tmp_header == pg_header) {  		*write_state = PG_STATE_DATA; -	else if (tmp_header == 0xFF) { +	} else if (tmp_header == 0xFF) {  		*write_state = PG_STATE_HEADER;  		*repeat_times += 1;  		if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) { @@ -871,11 +878,13 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,  						      reorg_worden,  						      originaldata);  				*efuse_addr = efuse_get_current_size(hw); -			 } else +			} else {  				*efuse_addr = *efuse_addr + (tmp_word_cnts * 2)  					      + 1; -		} else +			} +		} else {  			*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; +		}  		*write_state = PG_STATE_HEADER;  		*repeat_times += 1; @@ -1069,10 +1078,12 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,  static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	u8 tempval;  	u16 tmpV16; -	if (pwrstate) { +	if (pwrstate && (rtlhal->hw_type != +		HARDWARE_TYPE_RTL8192SE)) {  		tmpV16 = rtl_read_word(rtlpriv,  				       rtlpriv->cfg->maps[SYS_ISO_CTRL]);  		if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) { @@ -1105,13 +1116,22 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)  			tempval = rtl_read_byte(rtlpriv,  						rtlpriv->cfg->maps[EFUSE_TEST] +  						3); -			tempval &= 0x0F; -			tempval |= (VOLTAGE_V25 << 4); + +			if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) { +				tempval &= 0x0F; +				tempval |= (VOLTAGE_V25 << 4); +			} +  			rtl_write_byte(rtlpriv,  				       rtlpriv->cfg->maps[EFUSE_TEST] + 3,  				       (tempval | 0x80));  		} +		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { +			rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], +						0x03); +		} +  	} else {  		if (write) {  			tempval = rtl_read_byte(rtlpriv, @@ -1122,6 +1142,11 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)  				       (tempval & 0x7F));  		} +		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { +			rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK], +						0x02); +		} +  	}  } diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 47774dd4c2a..164dabaa761 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -30,9 +30,10 @@  #ifndef __RTL_EFUSE_H_  #define __RTL_EFUSE_H_ +#define EFUSE_IC_ID_OFFSET		506 +  #define EFUSE_REAL_CONTENT_LEN		512  #define EFUSE_MAP_LEN			128 -#define EFUSE_MAX_SECTION		16  #define EFUSE_MAX_WORD_UNIT		4  #define EFUSE_INIT_MAP			0 @@ -52,6 +53,7 @@  #define _PRE_EXECUTE_READ_CMD_  #define EFUSE_REPEAT_THRESHOLD_		3 +#define EFUSE_ERROE_HANDLE		1  struct efuse_map {  	u8 offset; @@ -103,6 +105,7 @@ struct efuse_priv {  	u8 tx_power_g[14];  }; +extern void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);  extern void efuse_initialize(struct ieee80211_hw *hw);  extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);  extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index c3dd4cc678b..3550c9fb96e 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -32,6 +32,7 @@  #include "pci.h"  #include "base.h"  #include "ps.h" +#include "efuse.h"  static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {  	INTEL_VENDOR_ID, @@ -40,6 +41,31 @@ static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {  	SIS_VENDOR_ID  }; +static const u8 ac_to_hwq[] = { +	VO_QUEUE, +	VI_QUEUE, +	BE_QUEUE, +	BK_QUEUE +}; + +static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw, +		       struct sk_buff *skb) +{ +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	__le16 fc = rtl_get_fc(skb); +	u8 queue_index = skb_get_queue_mapping(skb); + +	if (unlikely(ieee80211_is_beacon(fc))) +		return BEACON_QUEUE; +	if (ieee80211_is_mgmt(fc)) +		return MGNT_QUEUE; +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) +		if (ieee80211_is_nullfunc(fc)) +			return HIGH_QUEUE; + +	return ac_to_hwq[queue_index]; +} +  /* Update PCI dependent default settings*/  static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)  { @@ -48,6 +74,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; +	u8 init_aspm;  	ppsc->reg_rfps_level = 0;  	ppsc->support_aspm = 0; @@ -113,25 +140,45 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)  	/*Set HW definition to determine if it supports ASPM. */  	switch (rtlpci->const_support_pciaspm) { -	case 0: -		/*Not support ASPM. */ -		ppsc->support_aspm = false; -		break; -	case 1: -		/*Support ASPM. */ -		ppsc->support_aspm = true; -		ppsc->support_backdoor = true; -		break; +	case 0:{ +			/*Not support ASPM. */ +			bool support_aspm = false; +			ppsc->support_aspm = support_aspm; +			break; +		} +	case 1:{ +			/*Support ASPM. */ +			bool support_aspm = true; +			bool support_backdoor = true; +			ppsc->support_aspm = support_aspm; + +			/*if (priv->oem_id == RT_CID_TOSHIBA && +			   !priv->ndis_adapter.amd_l1_patch) +			   support_backdoor = false; */ + +			ppsc->support_backdoor = support_backdoor; + +			break; +		}  	case 2:  		/*ASPM value set by chipset. */ -		if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) -			ppsc->support_aspm = true; +		if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { +			bool support_aspm = true; +			ppsc->support_aspm = support_aspm; +		}  		break;  	default:  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 ("switch case not process\n"));  		break;  	} + +	/* toshiba aspm issue, toshiba will set aspm selfly +	 * so we should not set aspm in driver */ +	pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm); +	if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE && +		init_aspm == 0x43) +		ppsc->support_aspm = false;  }  static bool _rtl_pci_platform_switch_device_pci_aspm( @@ -139,8 +186,11 @@ static bool _rtl_pci_platform_switch_device_pci_aspm(  			u8 value)  {  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + +	if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) +		value |= 0x40; -	value |= 0x40;  	pci_write_config_byte(rtlpci->pdev, 0x80, value);  	return false; @@ -150,11 +200,13 @@ static bool _rtl_pci_platform_switch_device_pci_aspm(  static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)  {  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); -	u8 buffer; +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	buffer = value;  	pci_write_config_byte(rtlpci->pdev, 0x81, value); +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) +		udelay(100); +  	return true;  } @@ -175,6 +227,9 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)  	u16 aspmlevel = 0;  	u8 tmp_u1b = 0; +	if (!ppsc->support_aspm) +		return; +  	if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {  		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,  			 ("PCI(Bridge) UNKNOWN.\n")); @@ -228,6 +283,9 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)  	u8 u_pcibridge_aspmsetting;  	u8 u_device_aspmsetting; +	if (!ppsc->support_aspm) +		return; +  	if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {  		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,  			 ("PCI(Bridge) UNKNOWN.\n")); @@ -272,7 +330,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)  					     RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);  		RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);  	} -	udelay(200); +	udelay(100);  }  static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw) @@ -309,13 +367,13 @@ static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)  	u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;  	u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;  	u8 linkctrl_reg; -	u8 num4bBytes; +	u8 num4bbytes; -	num4bBytes = (capabilityoffset + 0x10) / 4; +	num4bbytes = (capabilityoffset + 0x10) / 4;  	/*Read  Link Control Register */  	rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS, -				     pcicfg_addrport + (num4bBytes << 2)); +				     pcicfg_addrport + (num4bbytes << 2));  	rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);  	pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; @@ -348,7 +406,7 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,  	pci_write_config_byte(pdev, 0x70f, tmp);  } -static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw) +static void rtl_pci_init_aspm(struct ieee80211_hw *hw)  {  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); @@ -362,52 +420,6 @@ static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw)  } -static void rtl_pci_init_aspm(struct ieee80211_hw *hw) -{ -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - -	/*close ASPM for AMD defaultly */ -	rtlpci->const_amdpci_aspm = 0; - -	/* -	 * ASPM PS mode. -	 * 0 - Disable ASPM, -	 * 1 - Enable ASPM without Clock Req, -	 * 2 - Enable ASPM with Clock Req, -	 * 3 - Always Enable ASPM with Clock Req, -	 * 4 - Always Enable ASPM without Clock Req. -	 * set defult to RTL8192CE:3 RTL8192E:2 -	 * */ -	rtlpci->const_pci_aspm = 3; - -	/*Setting for PCI-E device */ -	rtlpci->const_devicepci_aspm_setting = 0x03; - -	/*Setting for PCI-E bridge */ -	rtlpci->const_hostpci_aspm_setting = 0x02; - -	/* -	 * In Hw/Sw Radio Off situation. -	 * 0 - Default, -	 * 1 - From ASPM setting without low Mac Pwr, -	 * 2 - From ASPM setting with low Mac Pwr, -	 * 3 - Bus D3 -	 * set default to RTL8192CE:0 RTL8192SE:2 -	 */ -	rtlpci->const_hwsw_rfoff_d3 = 0; - -	/* -	 * This setting works for those device with -	 * backdoor ASPM setting such as EPHY setting. -	 * 0 - Not support ASPM, -	 * 1 - Support ASPM, -	 * 2 - According to chipset. -	 */ -	rtlpci->const_support_pciaspm = 1; - -	_rtl_pci_initialize_adapter_common(hw); -} -  static void _rtl_pci_io_handler_init(struct device *dev,  				     struct ieee80211_hw *hw)  { @@ -429,6 +441,90 @@ static void _rtl_pci_io_handler_release(struct ieee80211_hw *hw)  {  } +static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw, +		struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc, u8 tid) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +	u8 additionlen = FCS_LEN; +	struct sk_buff *next_skb; + +	/* here open is 4, wep/tkip is 8, aes is 12*/ +	if (info->control.hw_key) +		additionlen += info->control.hw_key->icv_len; + +	/* The most skb num is 6 */ +	tcb_desc->empkt_num = 0; +	spin_lock_bh(&rtlpriv->locks.waitq_lock); +	skb_queue_walk(&rtlpriv->mac80211.skb_waitq[tid], next_skb) { +		struct ieee80211_tx_info *next_info; + +		next_info = IEEE80211_SKB_CB(next_skb); +		if (next_info->flags & IEEE80211_TX_CTL_AMPDU) { +			tcb_desc->empkt_len[tcb_desc->empkt_num] = +				next_skb->len + additionlen; +			tcb_desc->empkt_num++; +		} else { +			break; +		} + +		if (skb_queue_is_last(&rtlpriv->mac80211.skb_waitq[tid], +				      next_skb)) +			break; + +		if (tcb_desc->empkt_num >= 5) +			break; +	} +	spin_unlock_bh(&rtlpriv->locks.waitq_lock); + +	return true; +} + +/* just for early mode now */ +static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct sk_buff *skb = NULL; +	struct ieee80211_tx_info *info = NULL; +	int tid; /* should be int */ + +	if (!rtlpriv->rtlhal.earlymode_enable) +		return; + +	/* we juse use em for BE/BK/VI/VO */ +	for (tid = 7; tid >= 0; tid--) { +		u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(hw, tid)]; +		struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; +		while (!mac->act_scanning && +		       rtlpriv->psc.rfpwr_state == ERFON) { +			struct rtl_tcb_desc tcb_desc; +			memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); + +			spin_lock_bh(&rtlpriv->locks.waitq_lock); +			if (!skb_queue_empty(&mac->skb_waitq[tid]) && +			   (ring->entries - skb_queue_len(&ring->queue) > 5)) { +				skb = skb_dequeue(&mac->skb_waitq[tid]); +			} else { +				spin_unlock_bh(&rtlpriv->locks.waitq_lock); +				break; +			} +			spin_unlock_bh(&rtlpriv->locks.waitq_lock); + +			/* Some macaddr can't do early mode. like +			 * multicast/broadcast/no_qos data */ +			info = IEEE80211_SKB_CB(skb); +			if (info->flags & IEEE80211_TX_CTL_AMPDU) +				_rtl_update_earlymode_info(hw, skb, +							   &tcb_desc, tid); + +			rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); +		} +	} +} + +  static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -440,6 +536,8 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)  		struct rtl_tx_desc *entry = &ring->desc[ring->idx];  		struct sk_buff *skb;  		struct ieee80211_tx_info *info; +		__le16 fc; +		u8 tid;  		u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true,  							  HW_DESC_OWN); @@ -460,6 +558,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)  						      HW_DESC_TXBUFF_ADDR),  				 skb->len, PCI_DMA_TODEVICE); +		/* remove early mode header */ +		if (rtlpriv->rtlhal.earlymode_enable) +			skb_pull(skb, EM_HDR_LEN); +  		RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,  			 ("new ring->idx:%d, "  			  "free: skb_queue_len:%d, free: seq:%x\n", @@ -467,6 +569,30 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)  			  skb_queue_len(&ring->queue),  			  *(u16 *) (skb->data + 22))); +		if (prio == TXCMD_QUEUE) { +			dev_kfree_skb(skb); +			goto tx_status_ok; + +		} + +		/* for sw LPS, just after NULL skb send out, we can +		 * sure AP kown we are sleeped, our we should not let +		 * rf to sleep*/ +		fc = rtl_get_fc(skb); +		if (ieee80211_is_nullfunc(fc)) { +			if (ieee80211_has_pm(fc)) { +				rtlpriv->mac80211.offchan_deley = true; +				rtlpriv->psc.state_inap = 1; +			} else { +				rtlpriv->psc.state_inap = 0; +			} +		} + +		/* update tid tx pkt num */ +		tid = rtl_get_tid(skb); +		if (tid <= 7) +			rtlpriv->link_info.tidtx_inperiod[tid]++; +  		info = IEEE80211_SKB_CB(skb);  		ieee80211_tx_info_clear_status(info); @@ -489,7 +615,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)  					skb_get_queue_mapping  					(skb));  		} - +tx_status_ok:  		skb = NULL;  	} @@ -561,23 +687,21 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  			 *skb_trim(skb, skb->len - 4);  			 */ -			hdr = (struct ieee80211_hdr *)(skb->data); -			fc = hdr->frame_control; +			hdr = rtl_get_hdr(skb); +			fc = rtl_get_fc(skb); -			if (!stats.crc) { +			if (!stats.crc || !stats.hwerror) {  				memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,  				       sizeof(rx_status)); -				if (is_broadcast_ether_addr(hdr->addr1)) +				if (is_broadcast_ether_addr(hdr->addr1)) {  					;/*TODO*/ -				else { -					if (is_multicast_ether_addr(hdr->addr1)) -						;/*TODO*/ -					else { -						unicast = true; -						rtlpriv->stats.rxbytesunicast += -						    skb->len; -					} +				} else if (is_multicast_ether_addr(hdr->addr1)) { +					;/*TODO*/ +				} else { +					unicast = true; +					rtlpriv->stats.rxbytesunicast += +					    skb->len;  				}  				rtl_is_special_data(hw, skb, false); @@ -591,28 +715,38 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  						    num_rx_inperiod++;  				} -				if (unlikely(!rtl_action_proc(hw, skb, -				    false))) { +				/* for sw lps */ +				rtl_swlps_beacon(hw, (void *)skb->data, +						 skb->len); +				rtl_recognize_peer(hw, (void *)skb->data, +						   skb->len); +				if ((rtlpriv->mac80211.opmode == +				     NL80211_IFTYPE_AP) && +				    (rtlpriv->rtlhal.current_bandtype == +				     BAND_ON_2_4G) && +				     (ieee80211_is_beacon(fc) || +				     ieee80211_is_probe_resp(fc))) {  					dev_kfree_skb_any(skb);  				} else { -					struct sk_buff *uskb = NULL; -					u8 *pdata; -					uskb = dev_alloc_skb(skb->len + 128); -					if (!uskb) { -						RT_TRACE(rtlpriv, -							(COMP_INTR | COMP_RECV), -							DBG_EMERG, -							("can't alloc rx skb\n")); -						goto done; -					} -					memcpy(IEEE80211_SKB_RXCB(uskb), -							&rx_status, -							sizeof(rx_status)); -					pdata = (u8 *)skb_put(uskb, skb->len); -					memcpy(pdata, skb->data, skb->len); -					dev_kfree_skb_any(skb); +					if (unlikely(!rtl_action_proc(hw, skb, +					    false))) { +						dev_kfree_skb_any(skb); +					} else { +						struct sk_buff *uskb = NULL; +						u8 *pdata; +						uskb = dev_alloc_skb(skb->len +								     + 128); +						memcpy(IEEE80211_SKB_RXCB(uskb), +						       &rx_status, +						       sizeof(rx_status)); +						pdata = (u8 *)skb_put(uskb, +							skb->len); +						memcpy(pdata, skb->data, +						       skb->len); +						dev_kfree_skb_any(skb); -					ieee80211_rx_irqsafe(hw, uskb); +						ieee80211_rx_irqsafe(hw, uskb); +					}  				}  			} else {  				dev_kfree_skb_any(skb); @@ -627,7 +761,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  			new_skb = dev_alloc_skb(rtlpci->rxbuffersize);  			if (unlikely(!new_skb)) {  				RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), -					 DBG_EMERG, +					 DBG_DMESG,  					 ("can't alloc skb for rx\n"));  				goto done;  			} @@ -645,7 +779,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  		}  done: -		bufferaddress = (u32)(*((dma_addr_t *) skb->cb)); +		bufferaddress = (*((dma_addr_t *)skb->cb));  		tmp_one = 1;  		rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,  					    HW_DESC_RXBUFF_ADDR, @@ -674,6 +808,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)  	struct ieee80211_hw *hw = dev_id;  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	unsigned long flags;  	u32 inta = 0;  	u32 intb = 0; @@ -760,23 +895,36 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)  		_rtl_pci_tx_isr(hw, VO_QUEUE);  	} +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) { +		if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) { +			rtlpriv->link_info.num_tx_inperiod++; + +			RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, +					("CMD TX OK interrupt!\n")); +			_rtl_pci_tx_isr(hw, TXCMD_QUEUE); +		} +	} +  	/*<2> Rx related */  	if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {  		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n")); -		tasklet_schedule(&rtlpriv->works.irq_tasklet); +		_rtl_pci_rx_interrupt(hw);  	}  	if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  			 ("rx descriptor unavailable!\n")); -		tasklet_schedule(&rtlpriv->works.irq_tasklet); +		_rtl_pci_rx_interrupt(hw);  	}  	if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n")); -		tasklet_schedule(&rtlpriv->works.irq_tasklet); +		_rtl_pci_rx_interrupt(hw);  	} +	if (rtlpriv->rtlhal.earlymode_enable) +		tasklet_schedule(&rtlpriv->works.irq_tasklet); +  	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);  	return IRQ_HANDLED; @@ -787,7 +935,7 @@ done:  static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)  { -	_rtl_pci_rx_interrupt(hw); +	_rtl_pci_tx_chk_waitq(hw);  }  static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) @@ -795,14 +943,15 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; +	struct rtl8192_tx_ring *ring = NULL;  	struct ieee80211_hdr *hdr = NULL;  	struct ieee80211_tx_info *info = NULL;  	struct sk_buff *pskb = NULL;  	struct rtl_tx_desc *pdesc = NULL; -	unsigned int queue_index; +	struct rtl_tcb_desc tcb_desc;  	u8 temp_one = 1; +	memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));  	ring = &rtlpci->tx_ring[BEACON_QUEUE];  	pskb = __skb_dequeue(&ring->queue);  	if (pskb) @@ -812,14 +961,11 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)  	pskb = ieee80211_beacon_get(hw, mac->vif);  	if (pskb == NULL)  		return; -	hdr = (struct ieee80211_hdr *)(pskb->data); +	hdr = rtl_get_hdr(pskb);  	info = IEEE80211_SKB_CB(pskb); - -	queue_index = BEACON_QUEUE; -  	pdesc = &ring->desc[0];  	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, -					info, pskb, queue_index); +		info, pskb, BEACON_QUEUE, &tcb_desc);  	__skb_queue_tail(&ring->queue, pskb); @@ -861,7 +1007,6 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));  	rtlpci->up_first_time = true;  	rtlpci->being_init_adapter = false; @@ -869,31 +1014,20 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,  	rtlhal->hw = hw;  	rtlpci->pdev = pdev; -	ppsc->inactiveps = false; -	ppsc->leisure_ps = true; -	ppsc->fwctrl_lps = true; -	ppsc->reg_fwctrl_lps = 3; -	ppsc->reg_max_lps_awakeintvl = 5; - -	if (ppsc->reg_fwctrl_lps == 1) -		ppsc->fwctrl_psmode = FW_PS_MIN_MODE; -	else if (ppsc->reg_fwctrl_lps == 2) -		ppsc->fwctrl_psmode = FW_PS_MAX_MODE; -	else if (ppsc->reg_fwctrl_lps == 3) -		ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; -  	/*Tx/Rx related var */  	_rtl_pci_init_trx_var(hw); -	 /*IBSS*/ mac->beacon_interval = 100; +	/*IBSS*/ mac->beacon_interval = 100; -	 /*AMPDU*/ mac->min_space_cfg = 0; +	/*AMPDU*/ +	mac->min_space_cfg = 0;  	mac->max_mss_density = 0;  	/*set sane AMPDU defaults */  	mac->current_ampdu_density = 7;  	mac->current_ampdu_factor = 3; -	 /*QOS*/ rtlpci->acm_method = eAcmWay2_SW; +	/*QOS*/ +	rtlpci->acm_method = eAcmWay2_SW;  	/*task */  	tasklet_init(&rtlpriv->works.irq_tasklet, @@ -934,7 +1068,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,  		 ("queue:%d, ring_addr:%p\n", prio, ring));  	for (i = 0; i < entries; i++) { -		nextdescaddress = (u32) dma + ((i + 1) % entries) * +		nextdescaddress = (u32) dma + +					      ((i + 1) % entries) *  					      sizeof(*ring);  		rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), @@ -999,7 +1134,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)  					   rtlpci->rxbuffersize,  					   PCI_DMA_FROMDEVICE); -			bufferaddress = (u32)(*((dma_addr_t *)skb->cb)); +			bufferaddress = (*((dma_addr_t *)skb->cb));  			rtlpriv->cfg->ops->set_desc((u8 *)entry, false,  						    HW_DESC_RXBUFF_ADDR,  						    (u8 *)&bufferaddress); @@ -1182,72 +1317,73 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)  	return 0;  } -static unsigned int _rtl_mac_to_hwqueue(__le16 fc, -		unsigned int mac80211_queue_index) +static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, +					struct sk_buff *skb)  { -	unsigned int hw_queue_index; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +	struct ieee80211_sta *sta = info->control.sta; +	struct rtl_sta_info *sta_entry = NULL; +	u8 tid = rtl_get_tid(skb); -	if (unlikely(ieee80211_is_beacon(fc))) { -		hw_queue_index = BEACON_QUEUE; -		goto out; -	} +	if (!sta) +		return false; +	sta_entry = (struct rtl_sta_info *)sta->drv_priv; -	if (ieee80211_is_mgmt(fc)) { -		hw_queue_index = MGNT_QUEUE; -		goto out; -	} +	if (!rtlpriv->rtlhal.earlymode_enable) +		return false; +	if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL) +		return false; +	if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE) +		return false; +	if (tid > 7) +		return false; -	switch (mac80211_queue_index) { -	case 0: -		hw_queue_index = VO_QUEUE; -		break; -	case 1: -		hw_queue_index = VI_QUEUE; -		break; -	case 2: -		hw_queue_index = BE_QUEUE;; -		break; -	case 3: -		hw_queue_index = BK_QUEUE; -		break; -	default: -		hw_queue_index = BE_QUEUE; -		RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n", -				  mac80211_queue_index)); -		break; -	} +	/* maybe every tid should be checked */ +	if (!rtlpriv->link_info.higher_busytxtraffic[tid]) +		return false; -out: -	return hw_queue_index; +	spin_lock_bh(&rtlpriv->locks.waitq_lock); +	skb_queue_tail(&rtlpriv->mac80211.skb_waitq[tid], skb); +	spin_unlock_bh(&rtlpriv->locks.waitq_lock); + +	return true;  } -static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, +		struct rtl_tcb_desc *ptcb_desc)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_sta_info *sta_entry = NULL;  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +	struct ieee80211_sta *sta = info->control.sta;  	struct rtl8192_tx_ring *ring;  	struct rtl_tx_desc *pdesc;  	u8 idx; -	unsigned int queue_index, hw_queue; +	u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb);  	unsigned long flags; -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); -	__le16 fc = hdr->frame_control; +	struct ieee80211_hdr *hdr = rtl_get_hdr(skb); +	__le16 fc = rtl_get_fc(skb);  	u8 *pda_addr = hdr->addr1;  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	/*ssn */ -	u8 *qc = NULL;  	u8 tid = 0;  	u16 seq_number = 0;  	u8 own;  	u8 temp_one = 1; -	if (ieee80211_is_mgmt(fc)) -		rtl_tx_mgmt_proc(hw, skb); -	rtl_action_proc(hw, skb, true); +	if (ieee80211_is_auth(fc)) { +		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); +		rtl_ips_nic_on(hw); +	} -	queue_index = skb_get_queue_mapping(skb); -	hw_queue = _rtl_mac_to_hwqueue(fc, queue_index); +	if (rtlpriv->psc.sw_ps_enabled) { +		if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && +			!ieee80211_has_pm(fc)) +			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); +	} + +	rtl_action_proc(hw, skb, true);  	if (is_multicast_ether_addr(pda_addr))  		rtlpriv->stats.txbytesmulticast += skb->len; @@ -1257,7 +1393,6 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)  		rtlpriv->stats.txbytesunicast += skb->len;  	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); -  	ring = &rtlpci->tx_ring[hw_queue];  	if (hw_queue != BEACON_QUEUE)  		idx = (ring->idx + skb_queue_len(&ring->queue)) % @@ -1280,43 +1415,30 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)  		return skb->len;  	} -	/* -	 *if(ieee80211_is_nullfunc(fc)) { -	 *      spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); -	 *      return 1; -	 *} -	 */ -  	if (ieee80211_is_data_qos(fc)) { -		qc = ieee80211_get_qos_ctl(hdr); -		tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; +		tid = rtl_get_tid(skb); +		if (sta) { +			sta_entry = (struct rtl_sta_info *)sta->drv_priv; +			seq_number = (le16_to_cpu(hdr->seq_ctrl) & +				      IEEE80211_SCTL_SEQ) >> 4; +			seq_number += 1; -		seq_number = mac->tids[tid].seq_number; -		seq_number &= IEEE80211_SCTL_SEQ; -		/* -		 *hdr->seq_ctrl = hdr->seq_ctrl & -		 *cpu_to_le16(IEEE80211_SCTL_FRAG); -		 *hdr->seq_ctrl |= cpu_to_le16(seq_number); -		 */ - -		seq_number += 1; +			if (!ieee80211_has_morefrags(hdr->frame_control)) +				sta_entry->tids[tid].seq_number = seq_number; +		}  	}  	if (ieee80211_is_data(fc))  		rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); -	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, -					info, skb, hw_queue); +	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, +			info, skb, hw_queue, ptcb_desc);  	__skb_queue_tail(&ring->queue, skb); -	rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, +	rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true,  				    HW_DESC_OWN, (u8 *)&temp_one); -	if (!ieee80211_has_morefrags(hdr->frame_control)) { -		if (qc) -			mac->tids[tid].seq_number = seq_number; -	}  	if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&  	    hw_queue != BEACON_QUEUE) { @@ -1338,6 +1460,35 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)  	return 0;  } +static void rtl_pci_flush(struct ieee80211_hw *hw, bool drop) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u16 i = 0; +	int queue_id; +	struct rtl8192_tx_ring *ring; + +	for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) { +		u32 queue_len; +		ring = &pcipriv->dev.tx_ring[queue_id]; +		queue_len = skb_queue_len(&ring->queue); +		if (queue_len == 0 || queue_id == BEACON_QUEUE || +			queue_id == TXCMD_QUEUE) { +			queue_id--; +			continue; +		} else { +			msleep(20); +			i++; +		} + +		/* we just wait 1s for all queues */ +		if (rtlpriv->psc.rfpwr_state == ERFOFF || +			is_hal_stop(rtlhal) || i >= 200) +			return; +	} +} +  static void rtl_pci_deinit(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1456,11 +1607,13 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,  	struct pci_dev *bridge_pdev = pdev->bus->self;  	u16 venderid;  	u16 deviceid; +	u8 revisionid;  	u16 irqline;  	u8 tmp;  	venderid = pdev->vendor;  	deviceid = pdev->device; +	pci_read_config_byte(pdev, 0x8, &revisionid);  	pci_read_config_word(pdev, 0x3C, &irqline);  	if (deviceid == RTL_PCI_8192_DID || @@ -1471,7 +1624,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,  	    deviceid == RTL_PCI_8173_DID ||  	    deviceid == RTL_PCI_8172_DID ||  	    deviceid == RTL_PCI_8171_DID) { -		switch (pdev->revision) { +		switch (revisionid) {  		case RTL_PCI_REVISION_ID_8192PCIE:  			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,  				 ("8192 PCI-E is found - " @@ -1500,6 +1653,12 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,  		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,  			 ("8192C PCI-E is found - "  			  "vid/did=%x/%x\n", venderid, deviceid)); +	} else if (deviceid == RTL_PCI_8192DE_DID || +		   deviceid == RTL_PCI_8192DE_DID2) { +		rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +			 ("8192D PCI-E is found - " +			  "vid/did=%x/%x\n", venderid, deviceid));  	} else {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  			 ("Err: Unknown device -" @@ -1508,6 +1667,25 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,  		rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;  	} +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) { +		if (revisionid == 0 || revisionid == 1) { +			if (revisionid == 0) { +				RT_TRACE(rtlpriv, COMP_INIT, +					 DBG_LOUD, ("Find 92DE MAC0.\n")); +				rtlhal->interfaceindex = 0; +			} else if (revisionid == 1) { +				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +					("Find 92DE MAC1.\n")); +				rtlhal->interfaceindex = 1; +			} +		} else { +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				("Unknown device - " +				"VendorID/DeviceID=%x/%x, Revision=%x\n", +				venderid, deviceid, revisionid)); +			rtlhal->interfaceindex = 0; +		} +	}  	/*find bus info */  	pcipriv->ndis_adapter.busnumber = pdev->bus->number;  	pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); @@ -1533,12 +1711,12 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,  		    PCI_SLOT(bridge_pdev->devfn);  		pcipriv->ndis_adapter.pcibridge_funcnum =  		    PCI_FUNC(bridge_pdev->devfn); -		pcipriv->ndis_adapter.pcibridge_pciehdr_offset = -		    pci_pcie_cap(bridge_pdev);  		pcipriv->ndis_adapter.pcicfg_addrport =  		    (pcipriv->ndis_adapter.pcibridge_busnum << 16) |  		    (pcipriv->ndis_adapter.pcibridge_devnum << 11) |  		    (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31); +		pcipriv->ndis_adapter.pcibridge_pciehdr_offset = +		    pci_pcie_cap(bridge_pdev);  		pcipriv->ndis_adapter.num4bytes =  		    (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; @@ -1621,6 +1799,11 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,  	pcipriv = (void *)rtlpriv->priv;  	pcipriv->dev.pdev = pdev; +	/* init cfg & intf_ops */ +	rtlpriv->rtlhal.interface = INTF_PCI; +	rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); +	rtlpriv->intf_ops = &rtl_pci_ops; +  	/*  	 *init dbgp flags before all  	 *other functions, because we will @@ -1638,13 +1821,14 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,  		return err;  	} -	pmem_start = pci_resource_start(pdev, 2); -	pmem_len = pci_resource_len(pdev, 2); -	pmem_flags = pci_resource_flags(pdev, 2); +	pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); +	pmem_len = pci_resource_len(pdev, rtlpriv->cfg->bar_id); +	pmem_flags = pci_resource_flags(pdev, rtlpriv->cfg->bar_id);  	/*shared mem start */  	rtlpriv->io.pci_mem_start = -			(unsigned long)pci_iomap(pdev, 2, pmem_len); +			(unsigned long)pci_iomap(pdev, +			rtlpriv->cfg->bar_id, pmem_len);  	if (rtlpriv->io.pci_mem_start == 0) {  		RT_ASSERT(false, ("Can't map PCI mem\n"));  		goto fail2; @@ -1663,11 +1847,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,  	pci_write_config_byte(pdev, 0x04, 0x06);  	pci_write_config_byte(pdev, 0x04, 0x07); -	/* init cfg & intf_ops */ -	rtlpriv->rtlhal.interface = INTF_PCI; -	rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); -	rtlpriv->intf_ops = &rtl_pci_ops; -  	/* find adapter */  	_rtl_pci_find_adapter(pdev, hw); @@ -1785,8 +1964,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev)  	rtl_pci_deinit(hw);  	rtl_deinit_core(hw); -	if (rtlpriv->cfg->ops->deinit_sw_leds) -		rtlpriv->cfg->ops->deinit_sw_leds(hw);  	_rtl_pci_io_handler_release(hw);  	rtlpriv->cfg->ops->deinit_sw_vars(hw); @@ -1801,6 +1978,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev)  	}  	pci_disable_device(pdev); + +	rtl_pci_disable_aspm(hw); +  	pci_set_drvdata(pdev, NULL);  	ieee80211_free_hw(hw); @@ -1824,10 +2004,15 @@ no need to call hw_disable here.  ****************************************/  int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state)  { +	struct ieee80211_hw *hw = pci_get_drvdata(pdev); +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtlpriv->cfg->ops->hw_suspend(hw); +	rtl_deinit_rfkill(hw); +  	pci_save_state(pdev);  	pci_disable_device(pdev);  	pci_set_power_state(pdev, PCI_D3hot); -  	return 0;  }  EXPORT_SYMBOL(rtl_pci_suspend); @@ -1835,6 +2020,8 @@ EXPORT_SYMBOL(rtl_pci_suspend);  int rtl_pci_resume(struct pci_dev *pdev)  {  	int ret; +	struct ieee80211_hw *hw = pci_get_drvdata(pdev); +	struct rtl_priv *rtlpriv = rtl_priv(hw);  	pci_set_power_state(pdev, PCI_D0);  	ret = pci_enable_device(pdev); @@ -1845,15 +2032,20 @@ int rtl_pci_resume(struct pci_dev *pdev)  	pci_restore_state(pdev); +	rtlpriv->cfg->ops->hw_resume(hw); +	rtl_init_rfkill(hw);  	return 0;  }  EXPORT_SYMBOL(rtl_pci_resume);  struct rtl_intf_ops rtl_pci_ops = { +	.read_efuse_byte = read_efuse_byte,  	.adapter_start = rtl_pci_start,  	.adapter_stop = rtl_pci_stop,  	.adapter_tx = rtl_pci_tx, +	.flush = rtl_pci_flush,  	.reset_trx_ring = rtl_pci_reset_trx_ring, +	.waitq_insert = rtl_pci_tx_chk_waitq_insert,  	.disable_aspm = rtl_pci_disable_aspm,  	.enable_aspm = rtl_pci_enable_aspm, diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index 12747b9c71e..671b1f5aa0c 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -102,8 +102,8 @@  #define RTL_PCI_8191CE_DID	0x8177	/*8192ce */  #define RTL_PCI_8188CE_DID	0x8176	/*8192ce */  #define RTL_PCI_8192CU_DID	0x8191	/*8192ce */ -#define RTL_PCI_8192DE_DID	0x092D	/*8192ce */ -#define RTL_PCI_8192DU_DID	0x092D	/*8192ce */ +#define RTL_PCI_8192DE_DID	0x8193	/*8192de */ +#define RTL_PCI_8192DE_DID2	0x002B	/*92DE*/  /*8192 support 16 pages of IO registers*/  #define RTL_MEM_MAPPED_IO_RANGE_8190PCI		0x1000 @@ -129,6 +129,11 @@ enum pci_bridge_vendor {  	PCI_BRIDGE_VENDOR_MAX,  }; +struct rtl_pci_capabilities_header { +	u8 capability_id; +	u8 next; +}; +  struct rtl_rx_desc {  	u32 dword[8];  } __packed; @@ -161,7 +166,9 @@ struct rtl_pci {  	bool driver_is_goingto_unload;  	bool up_first_time; +	bool first_init;  	bool being_init_adapter; +	bool init_ready;  	bool irq_enabled;  	/*Tx */ @@ -197,6 +204,9 @@ struct rtl_pci {  	/*QOS & EDCA */  	enum acm_method acm_method; + +	u16 shortretry_limit; +	u16 longretry_limit;  };  struct mp_adapter { @@ -227,6 +237,7 @@ struct rtl_pci_priv {  	struct rtl_pci dev;  	struct mp_adapter ndis_adapter;  	struct rtl_led_ctl ledctl; +	struct bt_coexist_info bt_coexist;  };  #define rtl_pcipriv(hw)		(((struct rtl_pci_priv *)(rtl_priv(hw))->priv)) diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index c8395fb0c05..2bb71195e97 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -36,7 +36,6 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	bool init_status = true;  	/*<1> reset trx ring */  	if (rtlhal->interface == INTF_PCI) @@ -49,7 +48,6 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)  	/*<2> Enable Adapter */  	rtlpriv->cfg->ops->hw_init(hw);  	RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); -	/*init_status = false; */  	/*<3> Enable Interrupt */  	rtlpriv->cfg->ops->enable_interrupt(hw); @@ -57,7 +55,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)  	/*<enable timer> */  	rtl_watch_dog_timer_callback((unsigned long)hw); -	return init_status; +	return true;  }  EXPORT_SYMBOL(rtl_ps_enable_nic); @@ -192,12 +190,13 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)  	ppsc->swrf_processing = true; -	if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) { +	if (ppsc->inactive_pwrstate == ERFOFF && +	    rtlhal->interface == INTF_PCI) {  		if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && -		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM) && +		    RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&  		    rtlhal->interface == INTF_PCI) {  			rtlpriv->intf_ops->disable_aspm(hw); -			RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); +			RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);  		}  	} @@ -206,9 +205,10 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)  	if (ppsc->inactive_pwrstate == ERFOFF &&  	    rtlhal->interface == INTF_PCI) { -		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { +		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && +			!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {  			rtlpriv->intf_ops->enable_aspm(hw); -			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); +			RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);  		}  	} @@ -232,6 +232,9 @@ void rtl_ips_nic_off_wq_callback(void *data)  		return;  	} +	if (mac->link_state > MAC80211_NOLINK) +		return; +  	if (is_hal_stop(rtlhal))  		return; @@ -283,10 +286,14 @@ void rtl_ips_nic_off(struct ieee80211_hw *hw)  void rtl_ips_nic_on(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));  	enum rf_pwrstate rtstate;  	unsigned long flags; +	if (mac->opmode != NL80211_IFTYPE_STATION) +		return; +  	spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);  	if (ppsc->inactiveps) { @@ -369,8 +376,7 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)  	 *   mode and set RPWM to turn RF on.  	 */ -	if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) && -	     ppsc->report_linked) { +	if ((ppsc->fwctrl_lps) && ppsc->report_linked) {  		bool fw_current_inps;  		if (ppsc->dot11_psmode == EACTIVE) {  			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, @@ -424,7 +430,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	unsigned long flag; -	if (!(ppsc->fwctrl_lps && ppsc->leisure_ps)) +	if (!ppsc->fwctrl_lps)  		return;  	if (rtlpriv->sec.being_setkey) @@ -445,17 +451,16 @@ void rtl_lps_enter(struct ieee80211_hw *hw)  	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); -	if (ppsc->leisure_ps) { -		/* Idle for a while if we connect to AP a while ago. */ -		if (mac->cnt_after_linked >= 2) { -			if (ppsc->dot11_psmode == EACTIVE) { -				RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +	/* Idle for a while if we connect to AP a while ago. */ +	if (mac->cnt_after_linked >= 2) { +		if (ppsc->dot11_psmode == EACTIVE) { +			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,  					("Enter 802.11 power save mode...\n")); -				rtl_lps_set_psmode(hw, EAUTOPS); -			} +			rtl_lps_set_psmode(hw, EAUTOPS);  		}  	} +  	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);  } @@ -469,17 +474,17 @@ void rtl_lps_leave(struct ieee80211_hw *hw)  	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); -	if (ppsc->fwctrl_lps && ppsc->leisure_ps) { +	if (ppsc->fwctrl_lps) {  		if (ppsc->dot11_psmode != EACTIVE) {  			/*FIX ME */  			rtlpriv->cfg->ops->enable_interrupt(hw);  			if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && -			    RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) && +			    RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&  			    rtlhal->interface == INTF_PCI) {  				rtlpriv->intf_ops->disable_aspm(hw); -				RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM); +				RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);  			}  			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, @@ -490,3 +495,214 @@ void rtl_lps_leave(struct ieee80211_hw *hw)  	}  	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);  } + +/* For sw LPS*/ +void rtl_swlps_beacon(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_tim_ie *tim_ie; +	u8 *tim; +	u8 tim_len; +	bool u_buffed; +	bool m_buffed; + +	if (mac->opmode != NL80211_IFTYPE_STATION) +		return; + +	if (!rtlpriv->psc.swctrl_lps) +		return; + +	if (rtlpriv->mac80211.link_state != MAC80211_LINKED) +		return; + +	if (!rtlpriv->psc.sw_ps_enabled) +		return; + +	if (rtlpriv->psc.fwctrl_lps) +		return; + +	if (likely(!(hw->conf.flags & IEEE80211_CONF_PS))) +		return; + +	/* check if this really is a beacon */ +	if (!ieee80211_is_beacon(hdr->frame_control)) +		return; + +	/* min. beacon length + FCS_LEN */ +	if (len <= 40 + FCS_LEN) +		return; + +	/* and only beacons from the associated BSSID, please */ +	if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid)) +		return; + +	rtlpriv->psc.last_beacon = jiffies; + +	tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); +	if (!tim) +		return; + +	if (tim[1] < sizeof(*tim_ie)) +		return; + +	tim_len = tim[1]; +	tim_ie = (struct ieee80211_tim_ie *) &tim[2]; + +	if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period)) +		rtlpriv->psc.dtim_counter = tim_ie->dtim_count; + +	/* Check whenever the PHY can be turned off again. */ + +	/* 1. What about buffered unicast traffic for our AID? */ +	u_buffed = ieee80211_check_tim(tim_ie, tim_len, +				       rtlpriv->mac80211.assoc_id); + +	/* 2. Maybe the AP wants to send multicast/broadcast data? */ +	m_buffed = tim_ie->bitmap_ctrl & 0x01; +	rtlpriv->psc.multi_buffered = m_buffed; + +	/* unicast will process by mac80211 through +	 * set ~IEEE80211_CONF_PS, So we just check +	 * multicast frames here */ +	if (!m_buffed) { +		/* back to low-power land. and delay is +		 * prevent null power save frame tx fail */ +		queue_delayed_work(rtlpriv->works.rtl_wq, +				&rtlpriv->works.ps_work, MSECS(5)); +	} else { +		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, " +				"m_buffered: %x\n", u_buffed, m_buffed)); +	} +} + +void rtl_swlps_rf_awake(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	unsigned long flag; + +	if (!rtlpriv->psc.swctrl_lps) +		return; +	if (mac->link_state != MAC80211_LINKED) +		return; + +	if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && +		RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { +		rtlpriv->intf_ops->disable_aspm(hw); +		RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); +	} + +	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); +	rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false); +	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); +} + +void rtl_swlps_rfon_wq_callback(void *data) +{ +	struct rtl_works *rtlworks = +	    container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq); +	struct ieee80211_hw *hw = rtlworks->hw; + +	rtl_swlps_rf_awake(hw); +} + +void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	unsigned long flag; +	u8 sleep_intv; + +	if (!rtlpriv->psc.sw_ps_enabled) +		return; + +	if ((rtlpriv->sec.being_setkey) || +	    (mac->opmode == NL80211_IFTYPE_ADHOC)) +		return; + +	/*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ +	if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5)) +		return; + +	if (rtlpriv->link_info.busytraffic) +		return; + +	spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); +	if (rtlpriv->psc.rfchange_inprogress) { +		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); +		return; +	} +	spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + +	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); +	rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false); +	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); + +	if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && +		!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { +		rtlpriv->intf_ops->enable_aspm(hw); +		RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); +	} + +	/* here is power save alg, when this beacon is DTIM +	 * we will set sleep time to dtim_period * n; +	 * when this beacon is not DTIM, we will set sleep +	 * time to sleep_intv = rtlpriv->psc.dtim_counter or +	 * MAX_SW_LPS_SLEEP_INTV(default set to 5) */ + +	if (rtlpriv->psc.dtim_counter == 0) { +		if (hw->conf.ps_dtim_period == 1) +			sleep_intv = hw->conf.ps_dtim_period * 2; +		else +			sleep_intv = hw->conf.ps_dtim_period; +	} else { +		sleep_intv = rtlpriv->psc.dtim_counter; +	} + +	if (sleep_intv > MAX_SW_LPS_SLEEP_INTV) +		sleep_intv = MAX_SW_LPS_SLEEP_INTV; + +	/* this print should always be dtim_conter = 0 & +	 * sleep  = dtim_period, that meaons, we should +	 * awake before every dtim */ +	RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, +		 ("dtim_counter:%x will sleep :%d" +		 " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv)); + +	/* we tested that 40ms is enough for sw & hw sw delay */ +	queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, +			MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40)); +} + + +void rtl_swlps_wq_callback(void *data) +{ +	struct rtl_works *rtlworks = container_of_dwork_rtl(data, +				     struct rtl_works, +				     ps_work); +	struct ieee80211_hw *hw = rtlworks->hw; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	bool ps = false; + +	ps = (hw->conf.flags & IEEE80211_CONF_PS); + +	/* we can sleep after ps null send ok */ +	if (rtlpriv->psc.state_inap) { +		rtl_swlps_rf_sleep(hw); + +		if (rtlpriv->psc.state && !ps) { +			rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies - +					rtlpriv->psc.last_action); +		} + +		if (ps) +			rtlpriv->psc.last_slept = jiffies; + +		rtlpriv->psc.last_action = jiffies; +		rtlpriv->psc.state = ps; +	} +} diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index ae56da801a2..e3bf8984037 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h @@ -30,6 +30,8 @@  #ifndef __REALTEK_RTL_PCI_PS_H__  #define __REALTEK_RTL_PCI_PS_H__ +#define MAX_SW_LPS_SLEEP_INTV	5 +  bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,  			 enum rf_pwrstate state_toset, u32 changesource,  			 bool protect_or_not); @@ -40,4 +42,11 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw);  void rtl_ips_nic_off_wq_callback(void *data);  void rtl_lps_enter(struct ieee80211_hw *hw);  void rtl_lps_leave(struct ieee80211_hw *hw); + +void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len); +void rtl_swlps_wq_callback(void *data); +void rtl_swlps_rfon_wq_callback(void *data); +void rtl_swlps_rf_awake(struct ieee80211_hw *hw); +void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); +  #endif diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 91634107434..30da68a7778 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -38,17 +38,14 @@   *CCK11M or OFDM_54M based on wireless mode.   */  static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, +				  struct ieee80211_sta *sta,  				  struct sk_buff *skb, bool not_data)  {  	struct rtl_mac *rtlmac = rtl_mac(rtlpriv); - -	/* -	 *mgt use 1M, although we have check it -	 *before this function use rate_control_send_low, -	 *we still check it here -	 */ -	if (not_data) -		return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_sta_info *sta_entry = NULL; +	u8 wireless_mode = 0;  	/*  	 *this rate is no use for true rate, firmware @@ -57,35 +54,78 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,  	 *2.in rtl_get_tcb_desc when we check rate is  	 *      1M we will not use FW rate but user rate.  	 */ -	if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) { -		return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M]; +	if (rtlmac->opmode == NL80211_IFTYPE_AP || +		rtlmac->opmode == NL80211_IFTYPE_ADHOC) { +		if (sta) { +			sta_entry = (struct rtl_sta_info *) sta->drv_priv; +			wireless_mode = sta_entry->wireless_mode; +		} else { +			return 0; +		}  	} else { -		if (rtlmac->mode == WIRELESS_MODE_B) -			return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]; -		else -			return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]; +		wireless_mode = rtlmac->mode; +	} + +	if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) || +			not_data) { +		return 0; +	} else { +		if (rtlhal->current_bandtype == BAND_ON_2_4G) { +			if (wireless_mode == WIRELESS_MODE_B) { +				return B_MODE_MAX_RIX; +			} else if (wireless_mode == WIRELESS_MODE_G) { +				return G_MODE_MAX_RIX; +			} else { +				if (get_rf_type(rtlphy) != RF_2T2R) +					return N_MODE_MCS7_RIX; +				else +					return N_MODE_MCS15_RIX; +			} +		} else { +			if (wireless_mode == WIRELESS_MODE_A) { +				return A_MODE_MAX_RIX; +			} else { +				if (get_rf_type(rtlphy) != RF_2T2R) +					return N_MODE_MCS7_RIX; +				else +					return N_MODE_MCS15_RIX; +			} +		}  	}  }  static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, +				    struct ieee80211_sta *sta,  				    struct ieee80211_tx_rate *rate,  				    struct ieee80211_tx_rate_control *txrc, -				    u8 tries, u8 rix, int rtsctsenable, +				    u8 tries, char rix, int rtsctsenable,  				    bool not_data)  {  	struct rtl_mac *mac = rtl_mac(rtlpriv); +	u8 sgi_20 = 0, sgi_40 = 0; +	if (sta) { +		sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; +		sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; +	}  	rate->count = tries; -	rate->idx = (rix > 0x2) ? rix : 0x2; +	rate->idx = rix >= 0x00 ? rix : 0x00;  	if (!not_data) {  		if (txrc->short_preamble)  			rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; -		if (mac->bw_40) -			rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; -		if (mac->sgi_20 || mac->sgi_40) +		if (mac->opmode == NL80211_IFTYPE_AP || +			mac->opmode == NL80211_IFTYPE_ADHOC) { +			if (sta && (sta->ht_cap.cap & +			    IEEE80211_HT_CAP_SUP_WIDTH_20_40)) +				rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; +		} else { +			if (mac->bw_40) +				rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; +		} +		if (sgi_20 || sgi_40)  			rate->flags |= IEEE80211_TX_RC_SHORT_GI; -		if (mac->ht_enable) +		if (sta && sta->ht_cap.ht_supported)  			rate->flags |= IEEE80211_TX_RC_MCS;  	}  } @@ -97,39 +137,39 @@ static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,  	struct sk_buff *skb = txrc->skb;  	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);  	struct ieee80211_tx_rate *rates = tx_info->control.rates; -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -	__le16 fc = hdr->frame_control; +	__le16 fc = rtl_get_fc(skb);  	u8 try_per_rate, i, rix;  	bool not_data = !ieee80211_is_data(fc);  	if (rate_control_send_low(sta, priv_sta, txrc))  		return; -	rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data); - +	rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);  	try_per_rate = 1; -	_rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc, +	_rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,  				try_per_rate, rix, 1, not_data);  	if (!not_data) {  		for (i = 1; i < 4; i++) -			_rtl_rc_rate_set_series(rtlpriv, &rates[i], +			_rtl_rc_rate_set_series(rtlpriv, sta, &rates[i],  						txrc, i, (rix - i), 1,  						not_data);  	}  } -static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid) +static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, +		struct rtl_sta_info *sta_entry, u16 tid)  {  	struct rtl_mac *mac = rtl_mac(rtlpriv);  	if (mac->act_scanning)  		return false; -	if (mac->cnt_after_linked < 3) +	if (mac->opmode == NL80211_IFTYPE_STATION && +		mac->cnt_after_linked < 3)  		return false; -	if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF) +	if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP)  		return true;  	return false; @@ -143,11 +183,9 @@ static void rtl_tx_status(void *ppriv,  {  	struct rtl_priv *rtlpriv = ppriv;  	struct rtl_mac *mac = rtl_mac(rtlpriv); -	struct ieee80211_hdr *hdr; -	__le16 fc; - -	hdr = (struct ieee80211_hdr *)skb->data; -	fc = hdr->frame_control; +	struct ieee80211_hdr *hdr = rtl_get_hdr(skb); +	__le16 fc = rtl_get_fc(skb); +	struct rtl_sta_info *sta_entry;  	if (!priv_sta || !ieee80211_is_data(fc))  		return; @@ -159,17 +197,21 @@ static void rtl_tx_status(void *ppriv,  	    || is_broadcast_ether_addr(ieee80211_get_DA(hdr)))  		return; -	/* Check if aggregation has to be enabled for this tid */ -	if (conf_is_ht(&mac->hw->conf) && -	    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { -		if (ieee80211_is_data_qos(fc)) { -			u8 *qc, tid; - -			qc = ieee80211_get_qos_ctl(hdr); -			tid = qc[0] & 0xf; - -			if (_rtl_tx_aggr_check(rtlpriv, tid)) -				ieee80211_start_tx_ba_session(sta, tid, 5000); +	if (sta) { +		/* Check if aggregation has to be enabled for this tid */ +		sta_entry = (struct rtl_sta_info *) sta->drv_priv; +		if ((sta->ht_cap.ht_supported == true) && +				!(skb->protocol == cpu_to_be16(ETH_P_PAE))) { +			if (ieee80211_is_data_qos(fc)) { +				u8 tid = rtl_get_tid(skb); +				if (_rtl_tx_aggr_check(rtlpriv, sta_entry, +				    tid)) { +					sta_entry->tids[tid].agg.agg_state = +							 RTL_AGG_PROGRESS; +					ieee80211_start_tx_ba_session(sta, +								 tid, 5000); +				} +			}  		}  	}  } @@ -178,43 +220,6 @@ static void rtl_rate_init(void *ppriv,  			  struct ieee80211_supported_band *sband,  			  struct ieee80211_sta *sta, void *priv_sta)  { -	struct rtl_priv *rtlpriv = ppriv; -	struct rtl_mac *mac = rtl_mac(rtlpriv); -	u8 is_ht = conf_is_ht(&mac->hw->conf); - -	if ((mac->opmode == NL80211_IFTYPE_STATION) || -	    (mac->opmode == NL80211_IFTYPE_MESH_POINT) || -	    (mac->opmode == NL80211_IFTYPE_ADHOC)) { - -		switch (sband->band) { -		case IEEE80211_BAND_2GHZ: -			rtlpriv->rate_priv->cur_ratetab_idx = -			    RATR_INX_WIRELESS_G; -			if (is_ht) -				rtlpriv->rate_priv->cur_ratetab_idx = -				    RATR_INX_WIRELESS_NGB; -			break; -		case IEEE80211_BAND_5GHZ: -			rtlpriv->rate_priv->cur_ratetab_idx = -			    RATR_INX_WIRELESS_A; -			if (is_ht) -				rtlpriv->rate_priv->cur_ratetab_idx = -				    RATR_INX_WIRELESS_NGB; -			break; -		default: -			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, -				 ("Invalid band\n")); -			rtlpriv->rate_priv->cur_ratetab_idx = -			    RATR_INX_WIRELESS_NGB; -			break; -		} - -		RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG, -			 ("Choosing rate table index: %d\n", -			  rtlpriv->rate_priv->cur_ratetab_idx)); - -	} -  }  static void rtl_rate_update(void *ppriv, @@ -223,49 +228,6 @@ static void rtl_rate_update(void *ppriv,  			    u32 changed,  			    enum nl80211_channel_type oper_chan_type)  { -	struct rtl_priv *rtlpriv = ppriv; -	struct rtl_mac *mac = rtl_mac(rtlpriv); -	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); -	bool oper_cw40 = false, oper_sgi40; -	bool local_cw40 = mac->bw_40; -	bool local_sgi40 = mac->sgi_40; -	u8 is_ht = conf_is_ht(&mac->hw->conf); - -	if (changed & IEEE80211_RC_HT_CHANGED) { -		if (mac->opmode != NL80211_IFTYPE_STATION) -			return; - -		if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS || -		    rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS) -			oper_cw40 = true; - -		oper_sgi40 = mac->sgi_40; - -		if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) { -			switch (sband->band) { -			case IEEE80211_BAND_2GHZ: -				rtlpriv->rate_priv->cur_ratetab_idx = -				    RATR_INX_WIRELESS_G; -				if (is_ht) -					rtlpriv->rate_priv->cur_ratetab_idx = -					    RATR_INX_WIRELESS_NGB; -				break; -			case IEEE80211_BAND_5GHZ: -				rtlpriv->rate_priv->cur_ratetab_idx = -				    RATR_INX_WIRELESS_A; -				if (is_ht) -					rtlpriv->rate_priv->cur_ratetab_idx = -					    RATR_INX_WIRELESS_NGB; -				break; -			default: -				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -					 ("Invalid band\n")); -				rtlpriv->rate_priv->cur_ratetab_idx = -				    RATR_INX_WIRELESS_NGB; -				break; -			} -		} -	}  }  static void *rtl_rate_alloc(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h index b4667c035f0..4afa2c20adc 100644 --- a/drivers/net/wireless/rtlwifi/rc.h +++ b/drivers/net/wireless/rtlwifi/rc.h @@ -30,8 +30,15 @@  #ifndef __RTL_RC_H__  #define __RTL_RC_H__ +#define B_MODE_MAX_RIX 3 +#define G_MODE_MAX_RIX 11 +#define A_MODE_MAX_RIX 7 + +/* in mac80211 mcs0-mcs15 is idx0-idx15*/ +#define N_MODE_MCS7_RIX 7 +#define N_MODE_MCS15_RIX 15 +  struct rtl_rate_priv { -	u8 cur_ratetab_idx;  	u8 ht_cap;  }; diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index d26f957981a..8f6718f163e 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -66,31 +66,83 @@ static struct country_code_to_enum_rd allCountries[] = {  	NL80211_RRF_PASSIVE_SCAN | \  	NL80211_RRF_NO_OFDM) +/* 5G chan 36 - chan 64*/ +#define RTL819x_5GHZ_5150_5350	\ +	REG_RULE(5150-10, 5350+10, 40, 0, 30, \ +	NL80211_RRF_PASSIVE_SCAN | \ +	NL80211_RRF_NO_IBSS) + +/* 5G chan 100 - chan 165*/ +#define RTL819x_5GHZ_5470_5850	\ +	REG_RULE(5470-10, 5850+10, 40, 0, 30, \ +	NL80211_RRF_PASSIVE_SCAN | \ +	NL80211_RRF_NO_IBSS) + +/* 5G chan 149 - chan 165*/ +#define RTL819x_5GHZ_5725_5850	\ +	REG_RULE(5725-10, 5850+10, 40, 0, 30, \ +	NL80211_RRF_PASSIVE_SCAN | \ +	NL80211_RRF_NO_IBSS) + +#define RTL819x_5GHZ_ALL	\ +	(RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) +  static const struct ieee80211_regdomain rtl_regdom_11 = {  	.n_reg_rules = 1,  	.alpha2 = "99",  	.reg_rules = {  		      RTL819x_2GHZ_CH01_11, -	} +		      } +}; + +static const struct ieee80211_regdomain rtl_regdom_12_13 = { +	.n_reg_rules = 2, +	.alpha2 = "99", +	.reg_rules = { +		      RTL819x_2GHZ_CH01_11, +			  RTL819x_2GHZ_CH12_13, +		      }  }; -static const struct ieee80211_regdomain rtl_regdom_global = { +static const struct ieee80211_regdomain rtl_regdom_no_midband = {  	.n_reg_rules = 3,  	.alpha2 = "99",  	.reg_rules = {  		      RTL819x_2GHZ_CH01_11, -		      RTL819x_2GHZ_CH12_13, -		      RTL819x_2GHZ_CH14, -	} +			  RTL819x_5GHZ_5150_5350, +			  RTL819x_5GHZ_5725_5850, +		      }  }; -static const struct ieee80211_regdomain rtl_regdom_world = { -	.n_reg_rules = 2, +static const struct ieee80211_regdomain rtl_regdom_60_64 = { +	.n_reg_rules = 3,  	.alpha2 = "99",  	.reg_rules = {  		      RTL819x_2GHZ_CH01_11, -		      RTL819x_2GHZ_CH12_13, -	} +			  RTL819x_2GHZ_CH12_13, +			  RTL819x_5GHZ_5725_5850, +		      } +}; + +static const struct ieee80211_regdomain rtl_regdom_14_60_64 = { +	.n_reg_rules = 4, +	.alpha2 = "99", +	.reg_rules = { +		      RTL819x_2GHZ_CH01_11, +			  RTL819x_2GHZ_CH12_13, +			  RTL819x_2GHZ_CH14, +			  RTL819x_5GHZ_5725_5850, +		      } +}; + +static const struct ieee80211_regdomain rtl_regdom_14 = { +	.n_reg_rules = 3, +	.alpha2 = "99", +	.reg_rules = { +		      RTL819x_2GHZ_CH01_11, +			  RTL819x_2GHZ_CH12_13, +			  RTL819x_2GHZ_CH14, +		      }  };  static bool _rtl_is_radar_freq(u16 center_freq) @@ -162,6 +214,8 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,  	u32 bandwidth = 0;  	int r; +	if (!wiphy->bands[IEEE80211_BAND_2GHZ]) +		return;  	sband = wiphy->bands[IEEE80211_BAND_2GHZ];  	/* @@ -292,25 +346,26 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(  {  	switch (reg->country_code) {  	case COUNTRY_CODE_FCC: +		return &rtl_regdom_no_midband;  	case COUNTRY_CODE_IC:  		return &rtl_regdom_11;  	case COUNTRY_CODE_ETSI: +	case COUNTRY_CODE_TELEC_NETGEAR: +		return &rtl_regdom_60_64;  	case COUNTRY_CODE_SPAIN:  	case COUNTRY_CODE_FRANCE:  	case COUNTRY_CODE_ISRAEL: -	case COUNTRY_CODE_TELEC_NETGEAR: -		return &rtl_regdom_world; +	case COUNTRY_CODE_WORLD_WIDE_13: +		return &rtl_regdom_12_13;  	case COUNTRY_CODE_MKK:  	case COUNTRY_CODE_MKK1:  	case COUNTRY_CODE_TELEC:  	case COUNTRY_CODE_MIC: -		return &rtl_regdom_global; +		return &rtl_regdom_14_60_64;  	case COUNTRY_CODE_GLOBAL_DOMAIN: -		return &rtl_regdom_global; -	case COUNTRY_CODE_WORLD_WIDE_13: -		return &rtl_regdom_world; +		return &rtl_regdom_14;  	default: -		return &rtl_regdom_world; +		return &rtl_regdom_no_midband;  	}  } @@ -323,9 +378,11 @@ static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,  	const struct ieee80211_regdomain *regd;  	wiphy->reg_notifier = reg_notifier; +  	wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;  	wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;  	wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; +  	regd = _rtl_regdomain_select(reg);  	wiphy_apply_custom_regulatory(wiphy, regd);  	_rtl_reg_apply_radar_flags(wiphy); @@ -355,8 +412,8 @@ int rtl_regd_init(struct ieee80211_hw *hw,  	if (wiphy == NULL || &rtlpriv->regd == NULL)  		return -EINVAL; -	/* force the channel plan to world wide 13 */ -	rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; +	/* init country_code from efuse channel plan */ +	rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan;  	RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,  		 (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", @@ -373,8 +430,8 @@ int rtl_regd_init(struct ieee80211_hw *hw,  	country = _rtl_regd_find_country(rtlpriv->regd.country_code);  	if (country) { -		rtlpriv->regd.alpha2[0] = country->isoName[0]; -		rtlpriv->regd.alpha2[1] = country->isoName[1]; +		rtlpriv->regd.alpha2[0] = country->iso_name[0]; +		rtlpriv->regd.alpha2[1] = country->iso_name[1];  	} else {  		rtlpriv->regd.alpha2[0] = '0';  		rtlpriv->regd.alpha2[1] = '0'; diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h index 4cdbc4ae76d..d23118938fa 100644 --- a/drivers/net/wireless/rtlwifi/regd.h +++ b/drivers/net/wireless/rtlwifi/regd.h @@ -32,7 +32,7 @@  struct country_code_to_enum_rd {  	u16 countrycode; -	const char *isoName; +	const char *iso_name;  };  enum country_code_type_t { diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index c228b9ee371..97183829b9b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -28,10 +28,26 @@   *****************************************************************************/  #include "dm_common.h" +#include "phy_common.h" +#include "../pci.h" +#include "../base.h"  struct dig_t dm_digtable;  static struct ps_t dm_pstable; +#define BT_RSSI_STATE_NORMAL_POWER	BIT_OFFSET_LEN_MASK_32(0, 1) +#define BT_RSSI_STATE_AMDPU_OFF		BIT_OFFSET_LEN_MASK_32(1, 1) +#define BT_RSSI_STATE_SPECIAL_LOW	BIT_OFFSET_LEN_MASK_32(2, 1) +#define BT_RSSI_STATE_BG_EDCA_LOW	BIT_OFFSET_LEN_MASK_32(3, 1) +#define BT_RSSI_STATE_TXPOWER_LOW	BIT_OFFSET_LEN_MASK_32(4, 1) + +#define RTLPRIV			(struct rtl_priv *) +#define GET_UNDECORATED_AVERAGE_RSSI(_priv)	\ +	((RTLPRIV(_priv))->mac80211.opmode == \ +			     NL80211_IFTYPE_ADHOC) ?	\ +	((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \ +	((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb) +  static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {  	0x7f8001fe,  	0x788001e2, @@ -304,7 +320,7 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)  static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)  { -	static u8 binitialized; /* initialized to false */ +	static u8 initialized; /* initialized to false */  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; @@ -315,11 +331,11 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)  	if ((multi_sta == false) || (dm_digtable.cursta_connectctate !=  				     DIG_STA_DISCONNECT)) { -		binitialized = false; +		initialized = false;  		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;  		return; -	} else if (binitialized == false) { -		binitialized = true; +	} else if (initialized == false) { +		initialized = true;  		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;  		dm_digtable.cur_igvalue = 0x20;  		rtl92c_dm_write_dig(hw); @@ -461,10 +477,7 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)  	if (mac->act_scanning == true)  		return; -	if ((mac->link_state > MAC80211_NOLINK) && -	    (mac->link_state < MAC80211_LINKED)) -		dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; -	else if (mac->link_state >= MAC80211_LINKED) +	if (mac->link_state >= MAC80211_LINKED)  		dm_digtable.cursta_connectctate = DIG_STA_CONNECT;  	else  		dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; @@ -562,23 +575,42 @@ EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo);  static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +  	static u64 last_txok_cnt;  	static u64 last_rxok_cnt; -	u64 cur_txok_cnt; -	u64 cur_rxok_cnt; +	static u32 last_bt_edca_ul; +	static u32 last_bt_edca_dl; +	u64 cur_txok_cnt = 0; +	u64 cur_rxok_cnt = 0;  	u32 edca_be_ul = 0x5ea42b;  	u32 edca_be_dl = 0x5ea42b; +	bool bt_change_edca = false; -	if (mac->opmode == NL80211_IFTYPE_ADHOC) -		goto dm_checkedcaturbo_exit; +	if ((last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) || +	    (last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) { +		rtlpriv->dm.current_turbo_edca = false; +		last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul; +		last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl; +	} + +	if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) { +		edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul; +		bt_change_edca = true; +	} + +	if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) { +		edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl; +		bt_change_edca = true; +	}  	if (mac->link_state != MAC80211_LINKED) {  		rtlpriv->dm.current_turbo_edca = false;  		return;  	} -	if (!mac->ht_enable) {	/*FIX MERGE */ +	if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {  		if (!(edca_be_ul & 0xffff0000))  			edca_be_ul |= 0x005e0000; @@ -586,10 +618,12 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)  			edca_be_dl |= 0x005e0000;  	} -	if ((!rtlpriv->dm.is_any_nonbepkts) && -	    (!rtlpriv->dm.disable_framebursting)) { +	if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && +	     (!rtlpriv->dm.disable_framebursting))) { +  		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;  		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; +  		if (cur_rxok_cnt > 4 * cur_txok_cnt) {  			if (!rtlpriv->dm.is_cur_rdlstate ||  			    !rtlpriv->dm.current_turbo_edca) { @@ -618,7 +652,6 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)  		}  	} -dm_checkedcaturbo_exit:  	rtlpriv->dm.is_any_nonbepkts = false;  	last_txok_cnt = rtlpriv->stats.txbytesunicast;  	last_rxok_cnt = rtlpriv->stats.rxbytesunicast; @@ -633,14 +666,14 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw  	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));  	u8 thermalvalue, delta, delta_lck, delta_iqk;  	long ele_a, ele_d, temp_cck, val_x, value32; -	long val_y, ele_c; +	long val_y, ele_c = 0;  	u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0;  	int i;  	bool is2t = IS_92C_SERIAL(rtlhal->version);  	u8 txpwr_level[2] = {0, 0};  	u8 ofdm_min_index = 6, rf; -	rtlpriv->dm.txpower_trackingInit = true; +	rtlpriv->dm.txpower_trackinginit = true;  	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,  		 ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); @@ -683,7 +716,6 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw  			for (i = 0; i < OFDM_TABLE_LENGTH; i++) {  				if (ele_d == (ofdmswing_table[i] &  				    MASKOFDM_D)) { -					ofdm_index_old[1] = (u8) i;  					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,  					   DBG_LOUD, @@ -1062,7 +1094,7 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	rtlpriv->dm.txpower_tracking = true; -	rtlpriv->dm.txpower_trackingInit = false; +	rtlpriv->dm.txpower_trackinginit = false;  	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,  		 ("pMgntInfo->txpower_tracking = %d\n", @@ -1132,6 +1164,7 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rate_adaptive *p_ra = &(rtlpriv->ra);  	u32 low_rssithresh_for_ra, high_rssithresh_for_ra; +	struct ieee80211_sta *sta = NULL;  	if (is_hal_stop(rtlhal)) {  		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, @@ -1145,8 +1178,8 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)  		return;  	} -	if (mac->link_state == MAC80211_LINKED) { - +	if (mac->link_state == MAC80211_LINKED && +	    mac->opmode == NL80211_IFTYPE_STATION) {  		switch (p_ra->pre_ratr_state) {  		case DM_RATR_STA_HIGH:  			high_rssithresh_for_ra = 50; @@ -1185,10 +1218,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)  				 ("PreState = %d, CurState = %d\n",  				  p_ra->pre_ratr_state, p_ra->ratr_state)); -			rtlpriv->cfg->ops->update_rate_mask(hw, +			rcu_read_lock(); +			sta = ieee80211_find_sta(mac->vif, mac->bssid); +			rtlpriv->cfg->ops->update_rate_tbl(hw, sta,  					p_ra->ratr_state);  			p_ra->pre_ratr_state = p_ra->ratr_state; +			rcu_read_unlock();  		}  	}  } @@ -1202,51 +1238,6 @@ static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)  	dm_pstable.rssi_val_min = 0;  } -static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_phy *rtlphy = &(rtlpriv->phy); - -	if (dm_pstable.rssi_val_min != 0) { -		if (dm_pstable.pre_ccastate == CCA_2R) { -			if (dm_pstable.rssi_val_min >= 35) -				dm_pstable.cur_ccasate = CCA_1R; -			else -				dm_pstable.cur_ccasate = CCA_2R; -		} else { -			if (dm_pstable.rssi_val_min <= 30) -				dm_pstable.cur_ccasate = CCA_2R; -			else -				dm_pstable.cur_ccasate = CCA_1R; -		} -	} else { -		dm_pstable.cur_ccasate = CCA_MAX; -	} - -	if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { -		if (dm_pstable.cur_ccasate == CCA_1R) { -			if (get_rf_type(rtlphy) == RF_2T2R) { -				rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, -					      MASKBYTE0, 0x13); -				rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); -			} else { -				rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, -					      MASKBYTE0, 0x23); -				rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); -			} -		} else { -			rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, -				      0x33); -			rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); -		} -		dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; -	} - -	RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", -					       (dm_pstable.cur_ccasate == -						0) ? "1RCCA" : "2RCCA")); -} -  void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)  {  	static u8 initialize; @@ -1352,7 +1343,9 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)  	}  	if (IS_92C_SERIAL(rtlhal->version)) -		rtl92c_dm_1r_cca(hw); +		;/* rtl92c_dm_1r_cca(hw); */ +	else +		rtl92c_dm_rf_saving(hw, false);  }  void rtl92c_dm_init(struct ieee80211_hw *hw) @@ -1369,6 +1362,84 @@ void rtl92c_dm_init(struct ieee80211_hw *hw)  }  EXPORT_SYMBOL(rtl92c_dm_init); +void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	long undecorated_smoothed_pwdb; + +	if (!rtlpriv->dm.dynamic_txpower_enable) +		return; + +	if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { +		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +		return; +	} + +	if ((mac->link_state < MAC80211_LINKED) && +	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { +		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, +			 ("Not connected to any\n")); + +		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + +		rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; +		return; +	} + +	if (mac->link_state >= MAC80211_LINKED) { +		if (mac->opmode == NL80211_IFTYPE_ADHOC) { +			undecorated_smoothed_pwdb = +			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; +			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +				 ("AP Client PWDB = 0x%lx\n", +				  undecorated_smoothed_pwdb)); +		} else { +			undecorated_smoothed_pwdb = +			    rtlpriv->dm.undecorated_smoothed_pwdb; +			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +				 ("STA Default Port PWDB = 0x%lx\n", +				  undecorated_smoothed_pwdb)); +		} +	} else { +		undecorated_smoothed_pwdb = +		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + +		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +			 ("AP Ext Port PWDB = 0x%lx\n", +			  undecorated_smoothed_pwdb)); +	} + +	if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { +		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; +		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); +	} else if ((undecorated_smoothed_pwdb < +		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && +		   (undecorated_smoothed_pwdb >= +		    TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + +		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; +		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); +	} else if (undecorated_smoothed_pwdb < +		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { +		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +			 ("TXHIGHPWRLEVEL_NORMAL\n")); +	} + +	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { +		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +			 ("PHY_SetTxPowerLevel8192S() Channel = %d\n", +			  rtlphy->current_channel)); +		rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); +	} + +	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} +  void rtl92c_dm_watchdog(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1388,11 +1459,321 @@ void rtl92c_dm_watchdog(struct ieee80211_hw *hw)  		rtl92c_dm_dig(hw);  		rtl92c_dm_false_alarm_counter_statistics(hw);  		rtl92c_dm_dynamic_bb_powersaving(hw); -		rtlpriv->cfg->ops->dm_dynamic_txpower(hw); +		rtl92c_dm_dynamic_txpower(hw);  		rtl92c_dm_check_txpower_tracking(hw);  		rtl92c_dm_refresh_rate_adaptive_mask(hw); +		rtl92c_dm_bt_coexist(hw);  		rtl92c_dm_check_edca_turbo(hw); -  	}  }  EXPORT_SYMBOL(rtl92c_dm_watchdog); + +u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); +	long undecorated_smoothed_pwdb; +	u8 curr_bt_rssi_state = 0x00; + +	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { +		undecorated_smoothed_pwdb = +				 GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); +	} else { +		if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0) +			undecorated_smoothed_pwdb = 100; +		else +			undecorated_smoothed_pwdb = +				rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; +	} + +	/* Check RSSI to determine HighPower/NormalPower state for +	 * BT coexistence. */ +	if (undecorated_smoothed_pwdb >= 67) +		curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER); +	else if (undecorated_smoothed_pwdb < 62) +		curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER; + +	/* Check RSSI to determine AMPDU setting for BT coexistence. */ +	if (undecorated_smoothed_pwdb >= 40) +		curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF); +	else if (undecorated_smoothed_pwdb <= 32) +		curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF; + +	/* Marked RSSI state. It will be used to determine BT coexistence +	 * setting later. */ +	if (undecorated_smoothed_pwdb < 35) +		curr_bt_rssi_state |=  BT_RSSI_STATE_SPECIAL_LOW; +	else +		curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); + +	/* Set Tx Power according to BT status. */ +	if (undecorated_smoothed_pwdb >= 30) +		curr_bt_rssi_state |=  BT_RSSI_STATE_TXPOWER_LOW; +	else if (undecorated_smoothed_pwdb < 25) +		curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); + +	/* Check BT state related to BT_Idle in B/G mode. */ +	if (undecorated_smoothed_pwdb < 15) +		curr_bt_rssi_state |=  BT_RSSI_STATE_BG_EDCA_LOW; +	else +		curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW); + +	if (curr_bt_rssi_state != rtlpcipriv->bt_coexist.bt_rssi_state) { +		rtlpcipriv->bt_coexist.bt_rssi_state = curr_bt_rssi_state; +		return true; +	} else { +		return false; +	} +} +EXPORT_SYMBOL(rtl92c_bt_rssi_state_change); + +static bool rtl92c_bt_state_change(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + +	u32 polling, ratio_tx, ratio_pri; +	u32 bt_tx, bt_pri; +	u8 bt_state; +	u8 cur_service_type; + +	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) +		return false; + +	bt_state = rtl_read_byte(rtlpriv, 0x4fd); +	bt_tx = rtl_read_dword(rtlpriv, 0x488); +	bt_tx = bt_tx & 0x00ffffff; +	bt_pri = rtl_read_dword(rtlpriv, 0x48c); +	bt_pri = bt_pri & 0x00ffffff; +	polling = rtl_read_dword(rtlpriv, 0x490); + +	if (bt_tx == 0xffffffff && bt_pri == 0xffffffff && +	    polling == 0xffffffff && bt_state == 0xff) +		return false; + +	bt_state &= BIT_OFFSET_LEN_MASK_32(0, 1); +	if (bt_state != rtlpcipriv->bt_coexist.bt_cur_state) { +		rtlpcipriv->bt_coexist.bt_cur_state = bt_state; + +		if (rtlpcipriv->bt_coexist.reg_bt_sco == 3) { +			rtlpcipriv->bt_coexist.bt_service = BT_IDLE; + +			bt_state = bt_state | +			  ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ? +			  0 : BIT_OFFSET_LEN_MASK_32(1, 1)) | +			  BIT_OFFSET_LEN_MASK_32(2, 1); +			rtl_write_byte(rtlpriv, 0x4fd, bt_state); +		} +		return true; +	} + +	ratio_tx = bt_tx * 1000 / polling; +	ratio_pri = bt_pri * 1000 / polling; +	rtlpcipriv->bt_coexist.ratio_tx = ratio_tx; +	rtlpcipriv->bt_coexist.ratio_pri = ratio_pri; + +	if (bt_state && rtlpcipriv->bt_coexist.reg_bt_sco == 3) { + +		if ((ratio_tx < 30)  && (ratio_pri < 30)) +			cur_service_type = BT_IDLE; +		else if ((ratio_pri > 110) && (ratio_pri < 250)) +			cur_service_type = BT_SCO; +		else if ((ratio_tx >= 200) && (ratio_pri >= 200)) +			cur_service_type = BT_BUSY; +		else if ((ratio_tx >= 350) && (ratio_tx < 500)) +			cur_service_type = BT_OTHERBUSY; +		else if (ratio_tx >= 500) +			cur_service_type = BT_PAN; +		else +			cur_service_type = BT_OTHER_ACTION; + +		if (cur_service_type != rtlpcipriv->bt_coexist.bt_service) { +			rtlpcipriv->bt_coexist.bt_service = cur_service_type; +			bt_state = bt_state | +			   ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ? +			   0 : BIT_OFFSET_LEN_MASK_32(1, 1)) | +			   ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) ? +			   0 : BIT_OFFSET_LEN_MASK_32(2, 1)); + +			/* Add interrupt migration when bt is not ini +			 * idle state (no traffic). */ +			if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { +				rtl_write_word(rtlpriv, 0x504, 0x0ccc); +				rtl_write_byte(rtlpriv, 0x506, 0x54); +				rtl_write_byte(rtlpriv, 0x507, 0x54); +			} else { +				rtl_write_byte(rtlpriv, 0x506, 0x00); +				rtl_write_byte(rtlpriv, 0x507, 0x00); +			} + +			rtl_write_byte(rtlpriv, 0x4fd, bt_state); +			return true; +		} +	} + +	return false; + +} + +static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	static bool media_connect; + +	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { +		media_connect = false; +	} else { +		if (!media_connect) { +			media_connect = true; +			return true; +		} +		media_connect = true; +	} + +	return false; +} + +static void rtl92c_bt_set_normal(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + + +	if (rtlpcipriv->bt_coexist.bt_service == BT_OTHERBUSY) { +		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72b; +		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72b; +	} else if (rtlpcipriv->bt_coexist.bt_service == BT_BUSY) { +		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82f; +		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82f; +	} else if (rtlpcipriv->bt_coexist.bt_service == BT_SCO) { +		if (rtlpcipriv->bt_coexist.ratio_tx > 160) { +			rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72f; +			rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72f; +		} else { +			rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea32b; +			rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea42b; +		} +	} else { +		rtlpcipriv->bt_coexist.bt_edca_ul = 0; +		rtlpcipriv->bt_coexist.bt_edca_dl = 0; +	} + +	if ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) && +	     (rtlpriv->mac80211.mode == WIRELESS_MODE_G || +	     (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) && +	     (rtlpcipriv->bt_coexist.bt_rssi_state & +	     BT_RSSI_STATE_BG_EDCA_LOW)) { +		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82b; +		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82b; +	} +} + +static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + + +	/* Only enable HW BT coexist when BT in "Busy" state. */ +	if (rtlpriv->mac80211.vendor == PEER_CISCO && +	    rtlpcipriv->bt_coexist.bt_service == BT_OTHER_ACTION) { +		rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); +	} else { +		if ((rtlpcipriv->bt_coexist.bt_service == BT_BUSY) && +		    (rtlpcipriv->bt_coexist.bt_rssi_state & +		     BT_RSSI_STATE_NORMAL_POWER)) { +			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); +		} else if ((rtlpcipriv->bt_coexist.bt_service == +			    BT_OTHER_ACTION) && (rtlpriv->mac80211.mode < +			    WIRELESS_MODE_N_24G) && +			    (rtlpcipriv->bt_coexist.bt_rssi_state & +			    BT_RSSI_STATE_SPECIAL_LOW)) { +			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); +		} else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) { +			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); +		} else { +			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); +		} +	} + +	if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) +		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100); +	else +		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0); + +	if (rtlpcipriv->bt_coexist.bt_rssi_state & +	    BT_RSSI_STATE_NORMAL_POWER) { +		rtl92c_bt_set_normal(hw); +	} else { +		rtlpcipriv->bt_coexist.bt_edca_ul = 0; +		rtlpcipriv->bt_coexist.bt_edca_dl = 0; +	} + +	if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { +		rtlpriv->cfg->ops->set_rfreg(hw, +				 RF90_PATH_A, +				 0x1e, +				 0xf0, 0xf); +	} else { +		rtlpriv->cfg->ops->set_rfreg(hw, +		     RF90_PATH_A, 0x1e, 0xf0, +		     rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); +	} + +	if (!rtlpriv->dm.dynamic_txpower_enable) { +		if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) { +			if (rtlpcipriv->bt_coexist.bt_rssi_state & +				BT_RSSI_STATE_TXPOWER_LOW) { +				rtlpriv->dm.dynamic_txhighpower_lvl = +							TXHIGHPWRLEVEL_BT2; +			} else { +				rtlpriv->dm.dynamic_txhighpower_lvl = +					TXHIGHPWRLEVEL_BT1; +			} +		} else { +			rtlpriv->dm.dynamic_txhighpower_lvl = +				TXHIGHPWRLEVEL_NORMAL; +		} +		rtl92c_phy_set_txpower_level(hw, +			rtlpriv->phy.current_channel); +	} +} + +static void rtl92c_check_bt_change(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + +	if (rtlpcipriv->bt_coexist.bt_cur_state) { +		if (rtlpcipriv->bt_coexist.bt_ant_isolation) +			rtl92c_bt_ant_isolation(hw); +	} else { +		rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00); +		rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0, +				rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); + +		rtlpcipriv->bt_coexist.bt_edca_ul = 0; +		rtlpcipriv->bt_coexist.bt_edca_dl = 0; +	} +} + +void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw) +{ +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + +	bool wifi_connect_change; +	bool bt_state_change; +	bool rssi_state_change; + +	if ((rtlpcipriv->bt_coexist.bt_coexistence) && +	     (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) { + +		wifi_connect_change = rtl92c_bt_wifi_connect_change(hw); +		bt_state_change = rtl92c_bt_state_change(hw); +		rssi_state_change = rtl92c_bt_rssi_state_change(hw); + +		if (wifi_connect_change || bt_state_change || rssi_state_change) +			rtl92c_check_bt_change(hw); +	} +} +EXPORT_SYMBOL(rtl92c_dm_bt_coexist); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h index b9cbb0a3c03..b9736d3e9a3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h @@ -200,5 +200,7 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);  void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);  void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);  void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); +void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); +void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index bc9d24134ac..50303e1adff 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -223,29 +223,15 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)  	u8 *pfwdata;  	u32 fwsize;  	enum version_8192c version = rtlhal->version; -	const struct firmware *firmware;  	printk(KERN_INFO "rtl8192c: Loading firmware file %s\n",  	       rtlpriv->cfg->fw_name); -	if (request_firmware(&firmware, rtlpriv->cfg->fw_name, -			    rtlpriv->io.dev)) { -		printk(KERN_ERR "rtl8192c: Firmware loading failed\n"); +	if (!rtlhal->pfirmware)  		return 1; -	} - -	if (firmware->size > 0x4000) { -		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -			 ("Firmware is too big!\n")); -		release_firmware(firmware); -		return 1; -	} - -	memcpy(rtlhal->pfirmware, firmware->data, firmware->size); -	fwsize = firmware->size; -	release_firmware(firmware);  	pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;  	pfwdata = (u8 *) rtlhal->pfirmware; +	fwsize = rtlhal->fwsize;  	if (IS_FW_HEADER_EXIST(pfwheader)) {  		RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, @@ -553,6 +539,39 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)  }  EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd); +static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, +				struct sk_buff *skb) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl8192_tx_ring *ring; +	struct rtl_tx_desc *pdesc; +	u8 own; +	unsigned long flags; +	struct sk_buff *pskb = NULL; + +	ring = &rtlpci->tx_ring[BEACON_QUEUE]; + +	pskb = __skb_dequeue(&ring->queue); +	if (pskb) +		kfree_skb(pskb); + +	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + +	pdesc = &ring->desc[0]; +	own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); + +	rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); + +	__skb_queue_tail(&ring->queue, skb); + +	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + +	rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); + +	return true; +} +  #define BEACON_PG		0 /*->1*/  #define PSPOLL_PG		2  #define NULL_PG			3 @@ -670,7 +689,7 @@ static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  }; -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -679,12 +698,12 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)  	u32 totalpacketlen;  	bool rtstatus;  	u8 u1RsvdPageLoc[3] = {0}; -	bool b_dlok = false; +	bool dlok = false;  	u8 *beacon; -	u8 *p_pspoll; +	u8 *pspoll;  	u8 *nullfunc; -	u8 *p_probersp; +	u8 *probersp;  	/*---------------------------------------------------------  				(1) beacon  	---------------------------------------------------------*/ @@ -695,10 +714,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)  	/*-------------------------------------------------------  				(2) ps-poll  	--------------------------------------------------------*/ -	p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; -	SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); -	SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); -	SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); +	pspoll = &reserved_page_packet[PSPOLL_PG * 128]; +	SET_80211_PS_POLL_AID(pspoll, (mac->assoc_id | 0xc000)); +	SET_80211_PS_POLL_BSSID(pspoll, mac->bssid); +	SET_80211_PS_POLL_TA(pspoll, mac->mac_addr);  	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); @@ -715,10 +734,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)  	/*---------------------------------------------------------  				(4) probe response  	----------------------------------------------------------*/ -	p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; -	SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); -	SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); -	SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); +	probersp = &reserved_page_packet[PROBERSP_PG * 128]; +	SET_80211_HDR_ADDRESS1(probersp, mac->bssid); +	SET_80211_HDR_ADDRESS2(probersp, mac->mac_addr); +	SET_80211_HDR_ADDRESS3(probersp, mac->bssid);  	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); @@ -736,12 +755,12 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)  	memcpy((u8 *) skb_put(skb, totalpacketlen),  	       &reserved_page_packet, totalpacketlen); -	rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb); +	rtstatus = _rtl92c_cmd_send_packet(hw, skb);  	if (rtstatus) -		b_dlok = true; +		dlok = true; -	if (b_dlok) { +	if (dlok) {  		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,  			 ("Set RSVD page location to Fw.\n"));  		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h index 3db33bd1466..3d5823c1262 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h @@ -27,8 +27,8 @@   *   *****************************************************************************/ -#ifndef __RTL92C__FW__H__ -#define __RTL92C__FW__H__ +#ifndef __RTL92C__FW__COMMON__H__ +#define __RTL92C__FW__COMMON__H__  #define FW_8192C_SIZE				0x3000  #define FW_8192C_START_ADDRESS			0x1000 diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index a7022827839..c5424cad43c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -78,27 +78,29 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,  	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"  					       " data(%#x)\n", regaddr, bitmask,  					       data)); +  }  EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);  u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, -					 enum radio_path rfpath, u32 offset) +				  enum radio_path rfpath, u32 offset)  {  	RT_ASSERT(false, ("deprecated!\n"));  	return 0; +  }  EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read);  void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, -					   enum radio_path rfpath, u32 offset, -					   u32 data) +				    enum radio_path rfpath, u32 offset, +				    u32 data)  {  	RT_ASSERT(false, ("deprecated!\n"));  }  EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);  u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, -				      enum radio_path rfpath, u32 offset) +			       enum radio_path rfpath, u32 offset)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -149,8 +151,8 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,  EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);  void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, -					enum radio_path rfpath, u32 offset, -					u32 data) +				 enum radio_path rfpath, u32 offset, +				 u32 data)  {  	u32 data_and_addr;  	u32 newoffset; @@ -197,6 +199,7 @@ static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)  	rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);  	rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);  } +  bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -241,13 +244,14 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)  	rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,  						RFPGA0_XA_HSSIPARAMETER2,  						0x200)); +  	return true;  }  EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile);  void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, -						   u32 regaddr, u32 bitmask, -						   u32 data) +					    u32 regaddr, u32 bitmask, +					    u32 data)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -317,61 +321,48 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,  	}  	if (regaddr == RTXAGC_B_RATE54_24) {  		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; -  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  			 ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",  			  rtlphy->pwrgroup_cnt,  			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]));  	} -  	if (regaddr == RTXAGC_B_CCK1_55_MCS32) {  		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; -  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  			 ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",  			  rtlphy->pwrgroup_cnt,  			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]));  	} -  	if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {  		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; -  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  			 ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",  			  rtlphy->pwrgroup_cnt,  			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]));  	} -  	if (regaddr == RTXAGC_B_MCS03_MCS00) {  		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; -  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  			 ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",  			  rtlphy->pwrgroup_cnt,  			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]));  	} -  	if (regaddr == RTXAGC_B_MCS07_MCS04) {  		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; -  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  			 ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",  			  rtlphy->pwrgroup_cnt,  			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]));  	} -  	if (regaddr == RTXAGC_B_MCS11_MCS08) {  		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; -  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  			 ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",  			  rtlphy->pwrgroup_cnt,  			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]));  	} -  	if (regaddr == RTXAGC_B_MCS15_MCS12) {  		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; -  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  			 ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",  			  rtlphy->pwrgroup_cnt, @@ -583,6 +574,7 @@ static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,  	rtlphy->cur_cck_txpwridx = cckpowerlevel[0];  	rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; +  }  void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) @@ -611,7 +603,6 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)  	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));  	u8 idx;  	u8 rf_path; -  	u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,  						      WIRELESS_MODE_B,  						      power_indbm); @@ -639,11 +630,6 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)  }  EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm); -void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) -{ -} -EXPORT_SYMBOL(rtl92c_phy_set_beacon_hw_reg); -  u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,  				enum wireless_mode wirelessmode,  				long power_indbm) @@ -741,9 +727,9 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,  	if (rtlphy->set_bwmode_inprogress)  		return;  	rtlphy->set_bwmode_inprogress = true; -	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) -		rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); -	else { +	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { +		rtlphy->set_bwmode_inprogress = false; +	} else {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  			 ("FALSE driver sleep or unload\n"));  		rtlphy->set_bwmode_inprogress = false; @@ -773,8 +759,9 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)  				mdelay(delay);  			else  				continue; -		} else +		} else {  			rtlphy->sw_chnl_inprogress = false; +		}  		break;  	} while (true);  	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); @@ -811,9 +798,32 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)  }  EXPORT_SYMBOL(rtl92c_phy_sw_chnl); -static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, -					     u8 channel, u8 *stage, u8 *step, -					     u32 *delay) +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, +					     u32 cmdtableidx, u32 cmdtablesz, +					     enum swchnlcmd_id cmdid, +					     u32 para1, u32 para2, u32 msdelay) +{ +	struct swchnlcmd *pcmd; + +	if (cmdtable == NULL) { +		RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); +		return false; +	} + +	if (cmdtableidx >= cmdtablesz) +		return false; + +	pcmd = cmdtable + cmdtableidx; +	pcmd->cmdid = cmdid; +	pcmd->para1 = para1; +	pcmd->para2 = para2; +	pcmd->msdelay = msdelay; +	return true; +} + +bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, +				      u8 channel, u8 *stage, u8 *step, +				      u32 *delay)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -917,29 +927,6 @@ static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,  	return false;  } -static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, -					     u32 cmdtableidx, u32 cmdtablesz, -					     enum swchnlcmd_id cmdid, -					     u32 para1, u32 para2, u32 msdelay) -{ -	struct swchnlcmd *pcmd; - -	if (cmdtable == NULL) { -		RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); -		return false; -	} - -	if (cmdtableidx >= cmdtablesz) -		return false; - -	pcmd = cmdtable + cmdtableidx; -	pcmd->cmdid = cmdid; -	pcmd->para1 = para1; -	pcmd->para2 = para2; -	pcmd->msdelay = msdelay; -	return true; -} -  bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)  {  	return true; @@ -1002,13 +989,13 @@ static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)  	reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);  	reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);  	reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); +  	if (!(reg_eac & BIT(31)) &&  	    (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&  	    (((reg_ebc & 0x03FF0000) >> 16) != 0x42))  		result |= 0x01;  	else  		return result; -  	if (!(reg_eac & BIT(30)) &&  	    (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&  	    (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) @@ -1023,9 +1010,9 @@ static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,  	u32 oldval_0, x, tx0_a, reg;  	long y, tx0_c; -	if (final_candidate == 0xFF) +	if (final_candidate == 0xFF) {  		return; -	else if (iqk_ok) { +	} else if (iqk_ok) {  		oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,  					  MASKDWORD) >> 22) & 0x3FF;  		x = result[final_candidate][0]; @@ -1063,9 +1050,9 @@ static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,  	u32 oldval_1, x, tx1_a, reg;  	long y, tx1_c; -	if (final_candidate == 0xFF) +	if (final_candidate == 0xFF) {  		return; -	else if (iqk_ok) { +	} else if (iqk_ok) {  		oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,  					  MASKDWORD) >> 22) & 0x3FF;  		x = result[final_candidate][4]; @@ -1282,6 +1269,7 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,  						   RFPGA0_XA_HSSIPARAMETER1,  						   BIT(8));  	} +  	if (!rtlphy->rfpi_enable)  		_rtl92c_phy_pi_mode_switch(hw, true);  	if (t == 0) { @@ -1317,9 +1305,10 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,  					0x3FF0000) >> 16;  			break;  		} else if (i == (retrycount - 1) && patha_ok == 0x01) +  			result[t][0] = (rtl_get_bbreg(hw, 0xe94,  						      MASKDWORD) & 0x3FF0000) >> -						      16; +			    16;  		result[t][1] =  		    (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; @@ -1375,8 +1364,7 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,  static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,  				     char delta, bool is2t)  { -	/* This routine is deliberately dummied out for later fixes */ -#if 0 +#if 0 /* This routine is deliberately dummied out for later fixes */  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy);  	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); @@ -1434,7 +1422,7 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,  		0x04db25a4, 0x0b1b25a4  	}; -	u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; +	const u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };  	u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; @@ -1463,13 +1451,15 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,  		0x00050006  	}; -	const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; +	u32 apk_result[PATH_NUM][APK_BB_REG_NUM];  	long bb_offset, delta_v, delta_offset;  	if (!is2t)  		pathbound = 1; +	return; +  	for (index = 0; index < PATH_NUM; index++) {  		apk_offset[index] = apk_normal_offset[index];  		apk_value[index] = apk_normal_value[index]; @@ -1730,8 +1720,7 @@ static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,  			       0x08));  	} - -	rtlphy->apk_done = true; +	rtlphy->b_apk_done = true;  #endif  } @@ -1758,6 +1747,7 @@ static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,  			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);  	} +  }  #undef IQK_ADDA_REG_NUM diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h index 53ffb098158..9a264c0d612 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h @@ -27,8 +27,8 @@   *   *****************************************************************************/ -#ifndef __RTL92C_PHY_H__ -#define __RTL92C_PHY_H__ +#ifndef __RTL92C_PHY_COMMON_H__ +#define __RTL92C_PHY_COMMON_H__  #define MAX_PRECMD_CNT			16  #define MAX_RFDEPENDCMD_CNT		16 @@ -39,6 +39,7 @@  #define RT_CANNOT_IO(hw)		false  #define HIGHPOWER_RADIOA_ARRAYLEN	22 +#define IQK_ADDA_REG_NUM		16  #define MAX_TOLERANCE			5  #define	IQK_DELAY_TIME			1 @@ -56,6 +57,7 @@  #define IQK_ADDA_REG_NUM		16  #define IQK_MAC_REG_NUM			4 +#define IQK_DELAY_TIME			1  #define RF90_PATH_MAX			2  #define CT_OFFSET_MAC_ADDR		0X16 @@ -77,6 +79,7 @@  #define RTL92C_MAX_PATH_NUM		2  #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER	255 +  enum swchnlcmd_id {  	CMDID_END,  	CMDID_SET_TXPOWEROWER_LEVEL, @@ -184,45 +187,41 @@ struct tx_power_struct {  	u32 mcs_original_offset[4][16];  }; -extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,  				   u32 regaddr, u32 bitmask); -extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,  				  u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,  				   enum radio_path rfpath, u32 regaddr,  				   u32 bitmask); -extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, -				  enum radio_path rfpath, u32 regaddr, -				  u32 bitmask, u32 data); -extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,  						 enum radio_path rfpath); -extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, +void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,  					 long *powerlevel); -extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, +void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,  					  long power_indbm); -extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, +void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,  					     u8 operation); -extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, +void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,  				   enum nl80211_channel_type ch_type); -extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); -extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, +void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,  					 u16 beaconinterval);  void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);  void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);  void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);  bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  					  enum radio_path rfpath); -extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,  					      u32 rfpath); -extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,  					  enum rf_pwrstate rfpwr_state);  void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);  void rtl92c_phy_set_io(struct ieee80211_hw *hw); @@ -235,12 +234,25 @@ u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,  				enum wireless_mode wirelessmode,  				long power_indbm);  void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); -static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, -					     u32 cmdtableidx, u32 cmdtablesz, -					     enum swchnlcmd_id cmdid, u32 para1, -					     u32 para2, u32 msdelay); -static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, -					     u8 channel, u8 *stage, u8 *step, -					     u32 *delay); +void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw); +bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, +				      u8 channel, u8 *stage, u8 *step, +				      u32 *delay); +u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw); +u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, +				  enum radio_path rfpath, u32 offset); +void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, +				    enum radio_path rfpath, u32 offset, +				    u32 data); +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, +			       enum radio_path rfpath, u32 offset); +void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, +				 enum radio_path rfpath, u32 offset, +				 u32 data); +bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); +void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, +					    u32 regaddr, u32 bitmask, +					    u32 data); +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 2f577c8828f..35ff7df41a1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -121,19 +121,6 @@  #define CHIP_92C			0x01  #define CHIP_88C			0x00 -/* Add vendor information into chip version definition. - * Add UMC B-Cut and RTL8723 chip info definition. - * - * BIT 7	Reserved - * BIT 6	UMC BCut - * BIT 5	Manufacturer(TSMC/UMC) - * BIT 4	TEST/NORMAL - * BIT 3	8723 Version - * BIT 2	8723? - * BIT 1	1T2R? - * BIT 0	88C/92C -*/ -  enum version_8192c {  	VERSION_A_CHIP_92C = 0x01,  	VERSION_A_CHIP_88C = 0x00, @@ -280,20 +267,6 @@ struct h2c_cmd_8192c {  	u8 *p_cmdbuffer;  }; -static inline u8 _rtl92c_get_chnl_group(u8 chnl) -{ -	u8 group = 0; - -	if (chnl < 3) -		group = 0; -	else if (chnl < 9) -		group = 1; -	else -		group = 2; - -	return group; -} -  /* NOTE: reference to rtl8192c_rates struct */  static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT,  				       u8 desc_rate, bool first_ampdu) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 7d76504df4d..2df33e53e15 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -29,10 +29,12 @@  #include "../wifi.h"  #include "../base.h" +#include "../pci.h"  #include "reg.h"  #include "def.h"  #include "phy.h"  #include "dm.h" +#include "../rtl8192c/fw_common.h"  void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)  { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 36302ebae4a..07dd9552e82 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h @@ -192,6 +192,7 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw);  void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);  void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);  void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); +void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);  void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 05477f465a7..4a56138eb33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -30,12 +30,14 @@  #include "../wifi.h"  #include "../efuse.h"  #include "../base.h" +#include "../regd.h"  #include "../cam.h"  #include "../ps.h"  #include "../pci.h"  #include "reg.h"  #include "def.h"  #include "phy.h" +#include "../rtl8192c/fw_common.h"  #include "dm.h"  #include "led.h"  #include "hw.h" @@ -137,15 +139,6 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		break;  		} -	case HW_VAR_MGT_FILTER: -		*((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); -		break; -	case HW_VAR_CTRL_FILTER: -		*((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); -		break; -	case HW_VAR_DATA_FILTER: -		*((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); -		break;  	default:  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 ("switch case not process\n")); @@ -156,6 +149,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -178,7 +172,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			rate_cfg |= 0x01;  			rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);  			rtl_write_byte(rtlpriv, REG_RRSR + 1, -				       (rate_cfg >> 8)&0xff); +				       (rate_cfg >> 8) & 0xff);  			while (rate_cfg > 0x1) {  				rate_cfg = (rate_cfg >> 1);  				rate_index++; @@ -276,13 +270,19 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			break;  		}  	case HW_VAR_AMPDU_FACTOR:{ -			u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; +			u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; +			u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97};  			u8 factor_toset;  			u8 *p_regtoset = NULL;  			u8 index = 0; -			p_regtoset = regtoset_normal; +			if ((rtlpcipriv->bt_coexist.bt_coexistence) && +			    (rtlpcipriv->bt_coexist.bt_coexist_type == +			    BT_CSR_BC4)) +				p_regtoset = regtoset_bt; +			else +				p_regtoset = regtoset_normal;  			factor_toset = *((u8 *) val);  			if (factor_toset <= 3) { @@ -317,45 +317,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		}  	case HW_VAR_AC_PARAM:{  			u8 e_aci = *((u8 *) val); -			u32 u4b_ac_param; -			u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); -			u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); -			u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); - -			u4b_ac_param = (u32) mac->ac[e_aci].aifs; -			u4b_ac_param |= ((u32)cw_min -					 & 0xF) << AC_PARAM_ECW_MIN_OFFSET; -			u4b_ac_param |= ((u32)cw_max & -					 0xF) << AC_PARAM_ECW_MAX_OFFSET; -			u4b_ac_param |= (u32)tx_op << AC_PARAM_TXOP_OFFSET; - -			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, -				 ("queue:%x, ac_param:%x\n", e_aci, -				  u4b_ac_param)); - -			switch (e_aci) { -			case AC1_BK: -				rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, -						u4b_ac_param); -				break; -			case AC0_BE: -				rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, -						u4b_ac_param); -				break; -			case AC2_VI: -				rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, -						u4b_ac_param); -				break; -			case AC3_VO: -				rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, -						u4b_ac_param); -				break; -			default: -				RT_ASSERT(false, -				  ("SetHwReg8185(): invalid aci: %d !\n", -				   e_aci)); -				break; -			} +			rtl92c_dm_init_edca_turbo(hw);  			if (rtlpci->acm_method != eAcmWay2_SW)  				rtlpriv->cfg->ops->set_hw_reg(hw, @@ -526,9 +488,6 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  	case HW_VAR_CORRECT_TSF:{  			u8 btype_ibss = ((u8 *) (val))[0]; -			/*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? -					1 : 0;*/ -  			if (btype_ibss == true)  				_rtl92ce_stop_tx_beacon(hw); @@ -537,7 +496,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			rtl_write_dword(rtlpriv, REG_TSFTR,  					(u32) (mac->tsf & 0xffffffff));  			rtl_write_dword(rtlpriv, REG_TSFTR + 4, -					(u32) ((mac->tsf >> 32)&0xffffffff)); +					(u32) ((mac->tsf >> 32) & 0xffffffff));  			_rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); @@ -547,15 +506,6 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			break;  		} -	case HW_VAR_MGT_FILTER: -		rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val); -		break; -	case HW_VAR_CTRL_FILTER: -		rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val); -		break; -	case HW_VAR_DATA_FILTER: -		rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val); -		break;  	default:  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "  							"not process\n")); @@ -679,12 +629,12 @@ static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw)  		rtl92ce_sw_led_on(hw, pLed0);  	else  		rtl92ce_sw_led_off(hw, pLed0); -  }  static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -693,9 +643,22 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)  	u16 retry;  	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); +	if (rtlpcipriv->bt_coexist.bt_coexistence) { +		u32 value32; +		value32 = rtl_read_dword(rtlpriv, REG_APS_FSMCO); +		value32 |= (SOP_ABG | SOP_AMB | XOP_BTCK); +		rtl_write_dword(rtlpriv, REG_APS_FSMCO, value32); +	}  	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);  	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); +	if (rtlpcipriv->bt_coexist.bt_coexistence) { +		u32 u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); + +		u4b_tmp &= (~0x00024800); +		rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp); +	} +  	bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0);  	udelay(2); @@ -726,6 +689,11 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)  	rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82);  	udelay(2); +	if (rtlpcipriv->bt_coexist.bt_coexistence) { +		bytetmp = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2) & 0xfd; +		rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, bytetmp); +	} +  	rtl_write_word(rtlpriv, REG_CR, 0x2ff);  	if (_rtl92ce_llt_table_init(hw) == false) @@ -793,6 +761,7 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)  {  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);  	u8 reg_bw_opmode;  	u32 reg_ratr, reg_prsr; @@ -824,7 +793,11 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)  	rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);  	rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); -	rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); +	if ((rtlpcipriv->bt_coexist.bt_coexistence) && +	    (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) +		rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431); +	else +		rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);  	rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); @@ -840,11 +813,20 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)  	rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);  	rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); -	rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - -	rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); +	if ((rtlpcipriv->bt_coexist.bt_coexistence) && +	    (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) { +		rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); +		rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402); +	} else { +		rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); +		rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); +	} -	rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); +	if ((rtlpcipriv->bt_coexist.bt_coexistence) && +	     (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) +		rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); +	else +		rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);  	rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); @@ -948,8 +930,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)  	}  	rtlhal->last_hmeboxnum = 0; -	rtl92ce_phy_mac_config(hw); -	rtl92ce_phy_bb_config(hw); +	rtl92c_phy_mac_config(hw); +	rtl92c_phy_bb_config(hw);  	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;  	rtl92c_phy_rf_config(hw);  	rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, @@ -962,15 +944,20 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)  	_rtl92ce_hw_configure(hw);  	rtl_cam_reset_all_entry(hw);  	rtl92ce_enable_hw_security_config(hw); +  	ppsc->rfpwr_state = ERFON; +  	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);  	_rtl92ce_enable_aspm_back_door(hw);  	rtlpriv->intf_ops->enable_aspm(hw); + +	rtl8192ce_bt_hw_init(hw); +  	if (ppsc->rfpwr_state == ERFON) {  		rtl92c_phy_set_rfpath_switch(hw, 1); -		if (iqk_initialized) +		if (iqk_initialized) {  			rtl92c_phy_iq_calibrate(hw, true); -		else { +		} else {  			rtl92c_phy_iq_calibrate(hw, false);  			iqk_initialized = true;  		} @@ -1128,75 +1115,62 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,  	return 0;  } -static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw, -				     enum nl80211_iftype type) +void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); -	u8 filterout_non_associated_bssid = false; -	switch (type) { -	case NL80211_IFTYPE_ADHOC: -	case NL80211_IFTYPE_STATION: -		filterout_non_associated_bssid = true; -		break; -	case NL80211_IFTYPE_UNSPECIFIED: -	case NL80211_IFTYPE_AP: -	default: -		break; -	} +	if (rtlpriv->psc.rfpwr_state != ERFON) +		return; -	if (filterout_non_associated_bssid == true) { +	if (check_bssid == true) {  		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,  					      (u8 *) (®_rcr));  		_rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); -	} else if (filterout_non_associated_bssid == false) { +	} else if (check_bssid == false) {  		reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));  		_rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0);  		rtlpriv->cfg->ops->set_hw_reg(hw,  					      HW_VAR_RCR, (u8 *) (®_rcr));  	} +  }  int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)  { +	struct rtl_priv *rtlpriv = rtl_priv(hw); +  	if (_rtl92ce_set_media_status(hw, type))  		return -EOPNOTSUPP; -	_rtl92ce_set_check_bssid(hw, type); + +	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { +		if (type != NL80211_IFTYPE_AP) +			rtl92ce_set_check_bssid(hw, true); +	} else { +		rtl92ce_set_check_bssid(hw, false); +	} +  	return 0;  } +/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */  void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	u32 u4b_ac_param; -	u16 cw_min = le16_to_cpu(mac->ac[aci].cw_min); -	u16 cw_max = le16_to_cpu(mac->ac[aci].cw_max); -	u16 tx_op = le16_to_cpu(mac->ac[aci].tx_op); -  	rtl92c_dm_init_edca_turbo(hw); -	u4b_ac_param = (u32) mac->ac[aci].aifs; -	u4b_ac_param |= (u32) ((cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET); -	u4b_ac_param |= (u32) ((cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET); -	u4b_ac_param |= (u32) (tx_op << AC_PARAM_TXOP_OFFSET); -	RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG, -		 ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n", -		  aci, u4b_ac_param, mac->ac[aci].aifs, cw_min, -		  cw_max, tx_op));  	switch (aci) {  	case AC1_BK: -		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); +		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);  		break;  	case AC0_BE: -		rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); +		/* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */  		break;  	case AC2_VI: -		rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param); +		rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);  		break;  	case AC3_VO: -		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); +		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);  		break;  	default:  		RT_ASSERT(false, ("invalid aci: %d !\n", aci)); @@ -1227,8 +1201,10 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)  static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	u8 u1b_tmp; +	u32 u4b_tmp;  	rtlpriv->intf_ops->enable_aspm(hw);  	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); @@ -1243,13 +1219,27 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)  	rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);  	rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000);  	u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); -	rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 | -			(u1b_tmp << 8)); +	if ((rtlpcipriv->bt_coexist.bt_coexistence) && +	     ((rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) || +	     (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC8))) { +		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00F30000 | +				(u1b_tmp << 8)); +	} else { +		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 | +				(u1b_tmp << 8)); +	}  	rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);  	rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);  	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);  	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); -	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); +	if (rtlpcipriv->bt_coexist.bt_coexistence) { +		u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); +		u4b_tmp |= 0x03824800; +		rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp); +	} else { +		rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); +	} +  	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);  	rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10);  } @@ -1327,6 +1317,7 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,  	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,  		 ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); +  	if (add_msr)  		rtlpci->irq_mask[0] |= add_msr;  	if (rm_msr) @@ -1582,7 +1573,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)  			 ("RTL819X Not boot from eeprom, check it !!"));  	} -	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), +	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),  		      hwinfo, HWSET_MAX_SIZE);  	eeprom_id = *((u16 *)&hwinfo[0]); @@ -1610,6 +1601,10 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)  					     rtlefuse->autoload_failflag,  					     hwinfo); +	rtl8192ce_read_bt_coexist_info_from_hwpg(hw, +						 rtlefuse->autoload_failflag, +						 hwinfo); +  	rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];  	rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];  	rtlefuse->txpwr_fromeprom = true; @@ -1618,6 +1613,9 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)  	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,  		 ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); +	/* set channel paln to world wide 13 */ +	rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; +  	if (rtlhal->oem_id == RT_CID_DEFAULT) {  		switch (rtlefuse->eeprom_oemid) {  		case EEPROM_CID_DEFAULT: @@ -1701,30 +1699,36 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)  	} else {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));  	} -  	_rtl92ce_hal_customized_behavior(hw);  } -void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) +static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw, +		struct ieee80211_sta *sta)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - -	u32 ratr_value = (u32) mac->basic_rates; -	u8 *mcsrate = mac->mcs; +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u32 ratr_value;  	u8 ratr_index = 0;  	u8 nmode = mac->ht_enable; -	u8 mimo_ps = 1; +	u8 mimo_ps = IEEE80211_SMPS_OFF;  	u16 shortgi_rate;  	u32 tmp_ratr_value;  	u8 curtxbw_40mhz = mac->bw_40; -	u8 curshortgi_40mhz = mac->sgi_40; -	u8 curshortgi_20mhz = mac->sgi_20; +	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? +			       1 : 0; +	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? +			       1 : 0;  	enum wireless_mode wirelessmode = mac->mode; -	ratr_value |= ((*(u16 *) (mcsrate))) << 12; - +	if (rtlhal->current_bandtype == BAND_ON_5G) +		ratr_value = sta->supp_rates[1] << 4; +	else +		ratr_value = sta->supp_rates[0]; +	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | +			sta->ht_cap.mcs.rx_mask[0] << 12);  	switch (wirelessmode) {  	case WIRELESS_MODE_B:  		if (ratr_value & 0x0000000c) @@ -1738,7 +1742,7 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)  	case WIRELESS_MODE_N_24G:  	case WIRELESS_MODE_N_5G:  		nmode = 1; -		if (mimo_ps == 0) { +		if (mimo_ps == IEEE80211_SMPS_STATIC) {  			ratr_value &= 0x0007F005;  		} else {  			u32 ratr_mask; @@ -1761,10 +1765,19 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)  		break;  	} -	ratr_value &= 0x0FFFFFFF; +	if ((rtlpcipriv->bt_coexist.bt_coexistence) && +	    (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) && +	    (rtlpcipriv->bt_coexist.bt_cur_state) && +	    (rtlpcipriv->bt_coexist.bt_ant_isolation) && +	    ((rtlpcipriv->bt_coexist.bt_service == BT_SCO) || +	    (rtlpcipriv->bt_coexist.bt_service == BT_BUSY))) +		ratr_value &= 0x0fffcfc0; +	else +		ratr_value &= 0x0FFFFFFF; -	if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || (!curtxbw_40mhz && -		       curshortgi_20mhz))) { +	if (nmode && ((curtxbw_40mhz && +			 curshortgi_40mhz) || (!curtxbw_40mhz && +					       curshortgi_20mhz))) {  		ratr_value |= 0x10000000;  		tmp_ratr_value = (ratr_value >> 12); @@ -1784,24 +1797,42 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)  		 ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));  } -void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) +static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, +		struct ieee80211_sta *sta, u8 rssi_level)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	u32 ratr_bitmap = (u32) mac->basic_rates; -	u8 *p_mcsrate = mac->mcs; +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_sta_info *sta_entry = NULL; +	u32 ratr_bitmap;  	u8 ratr_index; -	u8 curtxbw_40mhz = mac->bw_40; -	u8 curshortgi_40mhz = mac->sgi_40; -	u8 curshortgi_20mhz = mac->sgi_20; -	enum wireless_mode wirelessmode = mac->mode; +	u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) +				? 1 : 0; +	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? +				1 : 0; +	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? +				1 : 0; +	enum wireless_mode wirelessmode = 0;  	bool shortgi = false;  	u8 rate_mask[5];  	u8 macid = 0; -	u8 mimops = 1; +	u8 mimo_ps = IEEE80211_SMPS_OFF; -	ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); +	sta_entry = (struct rtl_sta_info *) sta->drv_priv; +	wirelessmode = sta_entry->wireless_mode; +	if (mac->opmode == NL80211_IFTYPE_STATION) +		curtxbw_40mhz = mac->bw_40; +	else if (mac->opmode == NL80211_IFTYPE_AP || +		mac->opmode == NL80211_IFTYPE_ADHOC) +		macid = sta->aid + 1; + +	if (rtlhal->current_bandtype == BAND_ON_5G) +		ratr_bitmap = sta->supp_rates[1] << 4; +	else +		ratr_bitmap = sta->supp_rates[0]; +	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | +			sta->ht_cap.mcs.rx_mask[0] << 12);  	switch (wirelessmode) {  	case WIRELESS_MODE_B:  		ratr_index = RATR_INX_WIRELESS_B; @@ -1828,7 +1859,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)  	case WIRELESS_MODE_N_5G:  		ratr_index = RATR_INX_WIRELESS_NGB; -		if (mimops == 0) { +		if (mimo_ps == IEEE80211_SMPS_STATIC) {  			if (rssi_level == 1)  				ratr_bitmap &= 0x00070000;  			else if (rssi_level == 2) @@ -1892,8 +1923,8 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)  	}  	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,  		 ("ratr_bitmap :%x\n", ratr_bitmap)); -	*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | -				       (ratr_index << 28); +	*(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | +				     (ratr_index << 28));  	rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;  	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "  						 "ratr_val:%x, %x:%x:%x:%x:%x\n", @@ -1902,6 +1933,20 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)  						 rate_mask[2], rate_mask[3],  						 rate_mask[4]));  	rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); + +	if (macid != 0) +		sta_entry->ratr_index = ratr_index; +} + +void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw, +		struct ieee80211_sta *sta, u8 rssi_level) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	if (rtlpriv->dm.useramask) +		rtl92ce_update_hal_rate_mask(hw, sta, rssi_level); +	else +		rtl92ce_update_hal_rate_table(hw, sta);  }  void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) @@ -1919,7 +1964,7 @@ void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw)  	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);  } -bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) +bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); @@ -1929,7 +1974,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)  	bool actuallyset = false;  	unsigned long flag; -	if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) +	if (rtlpci->being_init_adapter)  		return false;  	if (ppsc->swrf_processing) @@ -1946,12 +1991,6 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)  	cur_rfstate = ppsc->rfpwr_state; -	if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && -	    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { -		rtlpriv->intf_ops->disable_aspm(hw); -		RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); -	} -  	rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv,  		       REG_MAC_PINMUX_CFG)&~(BIT(3))); @@ -1976,38 +2015,13 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)  	}  	if (actuallyset) { -		if (e_rfpowerstate_toset == ERFON) { -			if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && -			    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { -				rtlpriv->intf_ops->disable_aspm(hw); -				RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); -			} -		} -  		spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);  		ppsc->rfchange_inprogress = false;  		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); - -		if (e_rfpowerstate_toset == ERFOFF) { -			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { -				rtlpriv->intf_ops->enable_aspm(hw); -				RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); -			} -		} - -	} else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { +	} else {  		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)  			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); -		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) { -			rtlpriv->intf_ops->enable_aspm(hw); -			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); -		} - -		spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); -		ppsc->rfchange_inprogress = false; -		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); -	} else {  		spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);  		ppsc->rfchange_inprogress = false;  		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); @@ -2086,15 +2100,31 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,  				macaddr = cam_const_broad;  				entry_id = key_index;  			} else { +				if (mac->opmode == NL80211_IFTYPE_AP) { +					entry_id = rtl_cam_get_free_entry(hw, +								 p_macaddr); +					if (entry_id >=  TOTAL_CAM_ENTRY) { +						RT_TRACE(rtlpriv, COMP_SEC, +						     DBG_EMERG, +						     ("Can not find free hw" +						     " security cam entry\n")); +						return; +					} +				} else { +					entry_id = CAM_PAIRWISE_KEY_POSITION; +				} +  				key_index = PAIRWISE_KEYIDX; -				entry_id = CAM_PAIRWISE_KEY_POSITION;  				is_pairwise = true;  			}  		}  		if (rtlpriv->sec.key_len[key_index] == 0) {  			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, -				 ("delete one entry\n")); +				 ("delete one entry, entry_id is %d\n", +				 entry_id)); +			if (mac->opmode == NL80211_IFTYPE_AP) +				rtl_cam_del_entry(hw, p_macaddr);  			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);  		} else {  			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, @@ -2146,3 +2176,132 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,  		}  	}  } + +static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw) +{ +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + +	rtlpcipriv->bt_coexist.bt_coexistence = +			rtlpcipriv->bt_coexist.eeprom_bt_coexist; +	rtlpcipriv->bt_coexist.bt_ant_num = +			rtlpcipriv->bt_coexist.eeprom_bt_ant_num; +	rtlpcipriv->bt_coexist.bt_coexist_type = +			rtlpcipriv->bt_coexist.eeprom_bt_type; + +	if (rtlpcipriv->bt_coexist.reg_bt_iso == 2) +		rtlpcipriv->bt_coexist.bt_ant_isolation = +			rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation; +	else +		rtlpcipriv->bt_coexist.bt_ant_isolation = +			rtlpcipriv->bt_coexist.reg_bt_iso; + +	rtlpcipriv->bt_coexist.bt_radio_shared_type = +			rtlpcipriv->bt_coexist.eeprom_bt_radio_shared; + +	if (rtlpcipriv->bt_coexist.bt_coexistence) { + +		if (rtlpcipriv->bt_coexist.reg_bt_sco == 1) +			rtlpcipriv->bt_coexist.bt_service = BT_OTHER_ACTION; +		else if (rtlpcipriv->bt_coexist.reg_bt_sco == 2) +			rtlpcipriv->bt_coexist.bt_service = BT_SCO; +		else if (rtlpcipriv->bt_coexist.reg_bt_sco == 4) +			rtlpcipriv->bt_coexist.bt_service = BT_BUSY; +		else if (rtlpcipriv->bt_coexist.reg_bt_sco == 5) +			rtlpcipriv->bt_coexist.bt_service = BT_OTHERBUSY; +		else +			rtlpcipriv->bt_coexist.bt_service = BT_IDLE; + +		rtlpcipriv->bt_coexist.bt_edca_ul = 0; +		rtlpcipriv->bt_coexist.bt_edca_dl = 0; +		rtlpcipriv->bt_coexist.bt_rssi_state = 0xff; +	} +} + +void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, +					      bool auto_load_fail, u8 *hwinfo) +{ +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); +	u8 value; + +	if (!auto_load_fail) { +		rtlpcipriv->bt_coexist.eeprom_bt_coexist = +					((hwinfo[RF_OPTION1] & 0xe0) >> 5); +		value = hwinfo[RF_OPTION4]; +		rtlpcipriv->bt_coexist.eeprom_bt_type = ((value & 0xe) >> 1); +		rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1); +		rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = +							 ((value & 0x10) >> 4); +		rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = +							 ((value & 0x20) >> 5); +	} else { +		rtlpcipriv->bt_coexist.eeprom_bt_coexist = 0; +		rtlpcipriv->bt_coexist.eeprom_bt_type = BT_2WIRE; +		rtlpcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; +		rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = 0; +		rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; +	} + +	rtl8192ce_bt_var_init(hw); +} + +void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw) +{ +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + +	/* 0:Low, 1:High, 2:From Efuse. */ +	rtlpcipriv->bt_coexist.reg_bt_iso = 2; +	/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ +	rtlpcipriv->bt_coexist.reg_bt_sco = 3; +	/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ +	rtlpcipriv->bt_coexist.reg_bt_sco = 0; +} + + +void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); + +	u8 u1_tmp; + +	if (rtlpcipriv->bt_coexist.bt_coexistence && +	    ((rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) || +	      rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC8)) { + +		if (rtlpcipriv->bt_coexist.bt_ant_isolation) +			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0); + +		u1_tmp = rtl_read_byte(rtlpriv, 0x4fd) & +			 BIT_OFFSET_LEN_MASK_32(0, 1); +		u1_tmp = u1_tmp | +			 ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ? +			 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) | +			 ((rtlpcipriv->bt_coexist.bt_service == BT_SCO) ? +			 0 : BIT_OFFSET_LEN_MASK_32(2, 1)); +		rtl_write_byte(rtlpriv, 0x4fd, u1_tmp); + +		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+4, 0xaaaa9aaa); +		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+8, 0xffbd0040); +		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+0xc, 0x40000010); + +		/* Config to 1T1R. */ +		if (rtlphy->rf_type == RF_1T1R) { +			u1_tmp = rtl_read_byte(rtlpriv, ROFDM0_TRXPATHENABLE); +			u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1)); +			rtl_write_byte(rtlpriv, ROFDM0_TRXPATHENABLE, u1_tmp); + +			u1_tmp = rtl_read_byte(rtlpriv, ROFDM1_TRXPATHENABLE); +			u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1)); +			rtl_write_byte(rtlpriv, ROFDM1_TRXPATHENABLE, u1_tmp); +		} +	} +} + +void rtl92ce_suspend(struct ieee80211_hw *hw) +{ +} + +void rtl92ce_resume(struct ieee80211_hw *hw) +{ +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h index a3dfdb63516..07dbe3e340a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h @@ -30,7 +30,18 @@  #ifndef __RTL92CE_HW_H__  #define __RTL92CE_HW_H__ -#define H2C_RA_MASK	6 +static inline u8 _rtl92c_get_chnl_group(u8 chnl) +{ +	u8 group; + +	if (chnl < 3) +		group = 0; +	else if (chnl < 9) +		group = 1; +	else +		group = 2; +	return group; +}  void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);  void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); @@ -41,28 +52,27 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw);  void rtl92ce_enable_interrupt(struct ieee80211_hw *hw);  void rtl92ce_disable_interrupt(struct ieee80211_hw *hw);  int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);  void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci);  void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw);  void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw);  void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,  				   u32 add_msr, u32 rm_msr);  void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw); -void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); +void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw, +				 struct ieee80211_sta *sta, u8 rssi_level);  void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);  bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);  void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);  void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,  		     u8 *p_macaddr, bool is_group, u8 enc_algo,  		     bool is_wepkey, bool clear_all); -bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); -void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); -void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); -int rtl92c_download_fw(struct ieee80211_hw *hw); -void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); -void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, -			 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer); -bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw); + +void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, +			bool autoload_fail, u8 *hwinfo); +void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw); +void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw); +void rtl92ce_suspend(struct ieee80211_hw *hw); +void rtl92ce_resume(struct ieee80211_hw *hw);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index d21b934b5c3..9dd1ed7b642 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -106,12 +106,11 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)  void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)  {  	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); -  	_rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);  	_rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);  } -void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, +static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,  				    enum led_ctl_mode ledaction)  {  	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); @@ -146,7 +145,7 @@ void rtl92ce_led_control(struct ieee80211_hw *hw,  	     ledaction == LED_CTL_POWER_ON)) {  		return;  	} -	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", +	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n",  				ledaction));  	_rtl92ce_sw_led_control(hw, ledaction);  } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 94332b3af5b..7dfccea2095 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h @@ -34,7 +34,5 @@ void rtl92ce_init_sw_leds(struct ieee80211_hw *hw);  void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);  void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);  void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); -void _rtl92ce_sw_led_control(struct ieee80211_hw *hw, -				    enum led_ctl_mode ledaction);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index d0541e8c601..73ae8a43184 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -38,7 +38,9 @@  #include "dm.h"  #include "table.h" -u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw, +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); + +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,  			    enum radio_path rfpath, u32 regaddr, u32 bitmask)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -73,9 +75,47 @@ u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw,  	return readback_value;  } +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	bool is92c = IS_92C_SERIAL(rtlhal->version); +	bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); + +	if (is92c) +		rtl_write_byte(rtlpriv, 0x14, 0x71); +	return rtstatus; +} + +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) +{ +	bool rtstatus = true; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u16 regval; +	u32 regvaldw; +	u8 reg_hwparafile = 1; + +	_rtl92c_phy_init_bb_rf_register_definition(hw); +	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); +	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, +		       regval | BIT(13) | BIT(0) | BIT(1)); +	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); +	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); +	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, +		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | +		       FEN_BB_GLB_RSTn | FEN_BBRSTB); +	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); +	regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); +	rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); +	if (reg_hwparafile == 1) +		rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); +	return rtstatus; +} +  void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, -			   enum radio_path rfpath, -			   u32 regaddr, u32 bitmask, u32 data) +			    enum radio_path rfpath, +			    u32 regaddr, u32 bitmask, u32 data)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -121,45 +161,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,  					       bitmask, data, rfpath));  } -bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	bool is92c = IS_92C_SERIAL(rtlhal->version); -	bool rtstatus = _rtl92ce_phy_config_mac_with_headerfile(hw); - -	if (is92c) -		rtl_write_byte(rtlpriv, 0x14, 0x71); -	return rtstatus; -} - -bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw) -{ -	bool rtstatus = true; -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	u16 regval; -	u32 regvaldw; -	u8 reg_hwparafile = 1; - -	_rtl92c_phy_init_bb_rf_register_definition(hw); -	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); -	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, -		       regval | BIT(13) | BIT(0) | BIT(1)); -	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); -	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); -	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); -	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, -		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | -		       FEN_BB_GLB_RSTn | FEN_BBRSTB); -	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); -	regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); -	rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); -	if (reg_hwparafile == 1) -		rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); -	return rtstatus; -} - -bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	u32 i; @@ -177,7 +179,7 @@ bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)  }  bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, -						  u8 configtype) +					    u8 configtype)  {  	int i;  	u32 *phy_regarray_table; @@ -236,7 +238,7 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,  }  bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, -						    u8 configtype) +					      u8 configtype)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	int i; @@ -274,7 +276,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,  	return true;  } -bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  					  enum radio_path rfpath)  { @@ -364,74 +366,6 @@ bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  	return true;  } -void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	struct rtl_phy *rtlphy = &(rtlpriv->phy); -	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	u8 reg_bw_opmode; -	u8 reg_prsr_rsc; - -	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, -		 ("Switch to %s bandwidth\n", -		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? -		  "20MHz" : "40MHz")) - -	    if (is_hal_stop(rtlhal)) -		return; - -	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); -	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); - -	switch (rtlphy->current_chan_bw) { -	case HT_CHANNEL_WIDTH_20: -		reg_bw_opmode |= BW_OPMODE_20MHZ; -		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); -		break; - -	case HT_CHANNEL_WIDTH_20_40: -		reg_bw_opmode &= ~BW_OPMODE_20MHZ; -		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - -		reg_prsr_rsc = -		    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); -		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); -		break; - -	default: -		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); -		break; -	} - -	switch (rtlphy->current_chan_bw) { -	case HT_CHANNEL_WIDTH_20: -		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); -		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); -		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); -		break; -	case HT_CHANNEL_WIDTH_20_40: -		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); -		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); -		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, -			      (mac->cur_40_prime_sc >> 1)); -		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); -		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); -		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), -			      (mac->cur_40_prime_sc == -			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); -		break; -	default: -		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); -		break; -	} -	rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); -	rtlphy->set_bwmode_inprogress = false; -	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); -} -  void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)  {  	u8 tmpreg; @@ -477,6 +411,36 @@ void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)  	}  } +static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ +	u32 u4b_tmp; +	u8 delay = 5; +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); +	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); +	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); +	u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); +	while (u4b_tmp != 0 && delay > 0) { +		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); +		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); +		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); +		u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); +		delay--; +	} +	if (delay == 0) { +		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); +		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); +		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); +		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, +			 ("Switch RF timeout !!!.\n")); +		return; +	} +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); +	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} +  static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,  					    enum rf_pwrstate rfpwr_state)  { @@ -523,33 +487,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,  			break;  		}  	case ERFOFF:{ -			for (queue_id = 0, i = 0; -			     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { -				ring = &pcipriv->dev.tx_ring[queue_id]; -				if (skb_queue_len(&ring->queue) == 0 || -				    queue_id == BEACON_QUEUE) { -					queue_id++; -					continue; -				} else { -					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, -						 ("eRf Off/Sleep: %d times " -						  "TcbBusyQueue[%d] " -						  "=%d before doze!\n", (i + 1), -						  queue_id, -						  skb_queue_len(&ring->queue))); -					udelay(10); -					i++; -				} -				if (i >= MAX_DOZE_WAITING_TIMES_9x) { -					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, -						 ("\nERFOFF: %d times " -						  "TcbBusyQueue[%d] = %d !\n", -						  MAX_DOZE_WAITING_TIMES_9x, -						  queue_id, -						  skb_queue_len(&ring->queue))); -					break; -				} -			}  			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {  				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,  					 ("IPS Set eRf nic disable\n")); @@ -581,6 +518,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,  						  "TcbBusyQueue[%d] =%d before "  						  "doze!\n", (i + 1), queue_id,  						  skb_queue_len(&ring->queue))); +  					udelay(10);  					i++;  				} @@ -599,7 +537,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,  				  jiffies_to_msecs(jiffies -  						   ppsc->last_awake_jiffies)));  			ppsc->last_sleep_jiffies = jiffies; -			_rtl92c_phy_set_rf_sleep(hw); +			_rtl92ce_phy_set_rf_sleep(hw);  			break;  		}  	default: @@ -614,10 +552,11 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,  	return bresult;  } -bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,  				   enum rf_pwrstate rfpwr_state)  {  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +  	bool bresult = false;  	if (rfpwr_state == ppsc->rfpwr_state) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index a37267e3fc2..ad580852cc7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -39,6 +39,7 @@  #define RT_CANNOT_IO(hw)		false  #define HIGHPOWER_RADIOA_ARRAYLEN	22 +#define IQK_ADDA_REG_NUM		16  #define MAX_TOLERANCE			5  #define	IQK_DELAY_TIME			1 @@ -56,6 +57,8 @@  #define IQK_ADDA_REG_NUM		16  #define IQK_MAC_REG_NUM			4 +#define IQK_DELAY_TIME			1 +  #define RF90_PATH_MAX			2  #define CT_OFFSET_MAC_ADDR		0X16 @@ -76,7 +79,7 @@  #define CT_OFFSET_CUSTOMER_ID		0x7F  #define RTL92C_MAX_PATH_NUM		2 -#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER	255 +  enum swchnlcmd_id {  	CMDID_END,  	CMDID_SET_TXPOWEROWER_LEVEL, @@ -184,43 +187,44 @@ struct tx_power_struct {  	u32 mcs_original_offset[4][16];  }; -extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,  				   u32 regaddr, u32 bitmask); -extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,  				  u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,  				   enum radio_path rfpath, u32 regaddr,  				   u32 bitmask);  extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, -				  enum radio_path rfpath, u32 regaddr, -				  u32 bitmask, u32 data); -extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); +				   enum radio_path rfpath, u32 regaddr, +				   u32 bitmask, u32 data); +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);  bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, +bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,  						 enum radio_path rfpath); -extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, +void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,  					 long *powerlevel); -extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, +void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,  					  long power_indbm); -extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, +void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,  					     u8 operation); -extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, +void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,  				   enum nl80211_channel_type ch_type); -extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); -extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, +void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,  					 u16 beaconinterval);  void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);  void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); +void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);  void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);  bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  					  enum radio_path rfpath); -extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,  					      u32 rfpath);  bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);  bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, @@ -237,9 +241,6 @@ u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask);  void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,  					enum radio_path rfpath, u32 offset,  					u32 data); -void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, -						   u32 regaddr, u32 bitmask, -						   u32 data);  void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,  					   enum radio_path rfpath, u32 offset,  					   u32 data); @@ -250,5 +251,11 @@ bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);  void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);  bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);  void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw); +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, +				   enum rf_pwrstate rfpwr_state); +bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, +					    u8 configtype); +bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, +					      u8 configtype);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index b0868a61384..598cecc63f4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -72,6 +72,7 @@  #define REG_GPIO_IO_SEL_2			0x0062  /* RTL8723 WIFI/BT/GPS Multi-Function control source. */  #define REG_MULTI_FUNC_CTRL			0x0068 +  #define REG_MCUFWDL				0x0080  #define REG_HMEBOX_EXT_0			0x0088 @@ -542,7 +543,7 @@  #define	IMR_OCPINT				BIT(1)  #define	IMR_WLANOFF				BIT(0) -#define	HWSET_MAX_SIZE				128 +#define EFUSE_REAL_CONTENT_LEN			512  #define	EEPROM_DEFAULT_TSSI			0x0  #define EEPROM_DEFAULT_TXPOWERDIFF		0x0 @@ -656,6 +657,7 @@  #define	STOPBE					BIT(1)  #define	STOPBK					BIT(0) +#define	RCR_APPFCS				BIT(31)  #define	RCR_APP_FCS				BIT(31)  #define	RCR_APP_MIC				BIT(30)  #define	RCR_APP_ICV				BIT(29) @@ -688,6 +690,7 @@  #define REG_USB_INFO				0xFE17  #define REG_USB_SPECIAL_OPTION			0xFE55 +  #define REG_USB_DMA_AGG_TO			0xFE5B  #define REG_USB_AGG_TO				0xFE5C  #define REG_USB_AGG_TH				0xFE5D @@ -775,7 +778,6 @@  #define	BOOT_FROM_EEPROM			BIT(4)  #define	EEPROM_EN				BIT(5) -#define	EEPROMSEL				BOOT_FROM_EEPROM  #define AFE_BGEN				BIT(0)  #define AFE_MBEN				BIT(1) @@ -901,28 +903,7 @@  #define BD_PKG_SEL				BIT(25)  #define BD_HCI_SEL				BIT(26)  #define TYPE_ID					BIT(27) - -/* REG_GPIO_OUTSTS (For RTL8723 only) */ -#define	EFS_HCI_SEL				(BIT(0)|BIT(1)) -#define	PAD_HCI_SEL				(BIT(2)|BIT(3)) -#define	HCI_SEL					(BIT(4)|BIT(5)) -#define	PKG_SEL_HCI				BIT(6) -#define	FEN_GPS					BIT(7) -#define	FEN_BT					BIT(8) -#define	FEN_WL					BIT(9) -#define	FEN_PCI					BIT(10) -#define	FEN_USB					BIT(11) -#define	BTRF_HWPDN_N				BIT(12) -#define	WLRF_HWPDN_N				BIT(13) -#define	PDN_BT_N				BIT(14) -#define	PDN_GPS_N				BIT(15) -#define	BT_CTL_HWPDN				BIT(16) -#define	GPS_CTL_HWPDN				BIT(17) -#define	PPHY_SUSB				BIT(20) -#define	UPHY_SUSB				BIT(21) -#define	PCI_SUSEN				BIT(22) -#define	USB_SUSEN				BIT(23) -#define	RF_RL_ID			(BIT(31) | BIT(30) | BIT(29) | BIT(28)) +#define	RF_RL_ID		(BIT(31) | BIT(30) | BIT(29) | BIT(28))  #define CHIP_VER_RTL_MASK			0xF000  #define CHIP_VER_RTL_SHIFT			12 @@ -1077,6 +1058,7 @@  #define _RARF_RC8(x)				(((x) & 0x1F) << 24)  #define AC_PARAM_TXOP_OFFSET			16 +#define AC_PARAM_TXOP_LIMIT_OFFSET		16  #define AC_PARAM_ECW_MAX_OFFSET			12  #define AC_PARAM_ECW_MIN_OFFSET			8  #define AC_PARAM_AIFS_OFFSET			0 @@ -1221,33 +1203,11 @@  #define EPROM_CMD_CONFIG			0x3  #define EPROM_CMD_LOAD				1 -#define	HWSET_MAX_SIZE_92S		HWSET_MAX_SIZE +#define	HWSET_MAX_SIZE_92S			HWSET_MAX_SIZE -#define	HAL_8192C_HW_GPIO_WPS_BIT		BIT(2) - -/* REG_MULTI_FUNC_CTRL(For RTL8723 Only) */ -/* Enable GPIO[9] as WiFi HW PDn source */  #define	WL_HWPDN_EN				BIT(0) -/* WiFi HW PDn polarity control */ -#define	WL_HWPDN_SL				BIT(1) -/* WiFi function enable */ -#define	WL_FUNC_EN				BIT(2) -/* Enable GPIO[9] as WiFi RF HW PDn source */ -#define	WL_HWROF_EN				BIT(3) -/* Enable GPIO[11] as BT HW PDn source */ -#define	BT_HWPDN_EN				BIT(16) -/* BT HW PDn polarity control */ -#define	BT_HWPDN_SL				BIT(17) -/* BT function enable */ -#define	BT_FUNC_EN				BIT(18) -/* Enable GPIO[11] as BT/GPS RF HW PDn source */ -#define	BT_HWROF_EN				BIT(19) -/* Enable GPIO[10] as GPS HW PDn source */ -#define	GPS_HWPDN_EN				BIT(20) -/* GPS HW PDn polarity control */ -#define	GPS_HWPDN_SL				BIT(21) -/* GPS function enable */ -#define	GPS_FUNC_EN				BIT(22) + +#define	HAL_8192C_HW_GPIO_WPS_BIT		BIT(2)  #define	RPMAC_RESET				0x100  #define	RPMAC_TXSTART				0x104 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index e301b12e281..90d0f2cf3b2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -34,9 +34,9 @@  #include "rf.h"  #include "dm.h" -static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); +static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw); -void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -62,7 +62,7 @@ void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)  }  void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, -				       u8 *ppowerlevel) +					u8 *ppowerlevel)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -128,8 +128,7 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,  	tmpval = tx_agc[RF90_PATH_A] >> 8; -	if (mac->mode == WIRELESS_MODE_B) -		tmpval = tmpval & 0xff00ffff; +	tmpval = tmpval & 0xff00ffff;  	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); @@ -440,16 +439,17 @@ bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw)  	else  		rtlphy->num_total_rfpath = 2; -	return _rtl92c_phy_rf6052_config_parafile(hw); +	return _rtl92ce_phy_rf6052_config_parafile(hw); +  } -static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy);  	u32 u4_regvalue = 0;  	u8 rfpath; -	bool rtstatus; +	bool rtstatus = true;  	struct bb_reg_def *pphyreg;  	for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { @@ -484,12 +484,12 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)  		switch (rfpath) {  		case RF90_PATH_A: -			rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw, -					(enum radio_path) rfpath); +			rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, +						(enum radio_path)rfpath);  			break;  		case RF90_PATH_B: -			rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw, -					(enum radio_path) rfpath); +			rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, +						(enum radio_path)rfpath);  			break;  		case RF90_PATH_C:  			break; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index 3aa520c1c17..39ff0368598 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -34,14 +34,11 @@  #define RF6052_MAX_REG			0x3F  #define RF6052_MAX_PATH			2 -extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, -					    u8 bandwidth); -extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, -					      u8 *ppowerlevel); -extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, -					       u8 *ppowerlevel, u8 channel); -bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); -bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, -					  enum radio_path rfpath); - +extern void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, +					     u8 bandwidth); +extern void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +					       u8 *ppowerlevel); +extern void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +						u8 *ppowerlevel, u8 channel); +extern bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index f4e2f3dccca..390bbb5ee11 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -42,10 +42,58 @@  #include "trx.h"  #include "led.h" +static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw) +{ +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + +	/*close ASPM for AMD defaultly */ +	rtlpci->const_amdpci_aspm = 0; + +	/* +	 * ASPM PS mode. +	 * 0 - Disable ASPM, +	 * 1 - Enable ASPM without Clock Req, +	 * 2 - Enable ASPM with Clock Req, +	 * 3 - Alwyas Enable ASPM with Clock Req, +	 * 4 - Always Enable ASPM without Clock Req. +	 * set defult to RTL8192CE:3 RTL8192E:2 +	 * */ +	rtlpci->const_pci_aspm = 3; + +	/*Setting for PCI-E device */ +	rtlpci->const_devicepci_aspm_setting = 0x03; + +	/*Setting for PCI-E bridge */ +	rtlpci->const_hostpci_aspm_setting = 0x02; + +	/* +	 * In Hw/Sw Radio Off situation. +	 * 0 - Default, +	 * 1 - From ASPM setting without low Mac Pwr, +	 * 2 - From ASPM setting with low Mac Pwr, +	 * 3 - Bus D3 +	 * set default to RTL8192CE:0 RTL8192SE:2 +	 */ +	rtlpci->const_hwsw_rfoff_d3 = 0; + +	/* +	 * This setting works for those device with +	 * backdoor ASPM setting such as EPHY setting. +	 * 0 - Not support ASPM, +	 * 1 - Support ASPM, +	 * 2 - According to chipset. +	 */ +	rtlpci->const_support_pciaspm = 1; +} +  int rtl92c_init_sw_vars(struct ieee80211_hw *hw)  { +	int err;  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	const struct firmware *firmware; + +	rtl8192ce_bt_reg_init(hw);  	rtlpriv->dm.dm_initialgain_enable = 1;  	rtlpriv->dm.dm_flag = 0; @@ -53,7 +101,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)  	rtlpriv->dm.thermalvalue = 0;  	rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); -	rtlpci->receive_config = (RCR_APP_FCS | +	/* compatible 5G band 88ce just 2.4G band & smsp */ +	rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; +	rtlpriv->rtlhal.bandset = BAND_ON_2_4G; +	rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + +	rtlpci->receive_config = (RCR_APPFCS |  				  RCR_AMF |  				  RCR_ADF |  				  RCR_APP_MIC | @@ -76,13 +129,49 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)  	rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); -	rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000); +	/* for LPS & IPS */ +	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; +	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; +	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; +	rtlpriv->psc.reg_fwctrl_lps = 3; +	rtlpriv->psc.reg_max_lps_awakeintvl = 5; +	/* for ASPM, you can close aspm through +	 * set const_support_pciaspm = 0 */ +	rtl92c_init_aspm_vars(hw); + +	if (rtlpriv->psc.reg_fwctrl_lps == 1) +		rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; +	else if (rtlpriv->psc.reg_fwctrl_lps == 2) +		rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; +	else if (rtlpriv->psc.reg_fwctrl_lps == 3) +		rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + +	/* for firmware buf */ +	rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);  	if (!rtlpriv->rtlhal.pfirmware) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 ("Can't alloc buffer for fw.\n"));  		return 1;  	} +	/* request fw */ +	err = request_firmware(&firmware, rtlpriv->cfg->fw_name, +			rtlpriv->io.dev); +	if (err) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 ("Failed to request firmware!\n")); +		return 1; +	} +	if (firmware->size > 0x4000) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 ("Firmware is too big!\n")); +		release_firmware(firmware); +		return 1; +	} +	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); +	rtlpriv->rtlhal.fwsize = firmware->size; +	release_firmware(firmware); +  	return 0;  } @@ -103,17 +192,19 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {  	.interrupt_recognized = rtl92ce_interrupt_recognized,  	.hw_init = rtl92ce_hw_init,  	.hw_disable = rtl92ce_card_disable, +	.hw_suspend = rtl92ce_suspend, +	.hw_resume = rtl92ce_resume,  	.enable_interrupt = rtl92ce_enable_interrupt,  	.disable_interrupt = rtl92ce_disable_interrupt,  	.set_network_type = rtl92ce_set_network_type, +	.set_chk_bssid = rtl92ce_set_check_bssid,  	.set_qos = rtl92ce_set_qos,  	.set_bcn_reg = rtl92ce_set_beacon_related_registers,  	.set_bcn_intv = rtl92ce_set_beacon_interval,  	.update_interrupt_mask = rtl92ce_update_interrupt_mask,  	.get_hw_reg = rtl92ce_get_hw_reg,  	.set_hw_reg = rtl92ce_set_hw_reg, -	.update_rate_table = rtl92ce_update_hal_rate_table, -	.update_rate_mask = rtl92ce_update_hal_rate_mask, +	.update_rate_tbl = rtl92ce_update_hal_rate_tbl,  	.fill_tx_desc = rtl92ce_tx_fill_desc,  	.fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc,  	.query_rx_desc = rtl92ce_rx_query_desc, @@ -123,7 +214,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {  	.switch_channel = rtl92c_phy_sw_chnl,  	.dm_watchdog = rtl92c_dm_watchdog,  	.scan_operation_backup = rtl92c_phy_scan_operation_backup, -	.set_rf_power_state = rtl92ce_phy_set_rf_power_state, +	.set_rf_power_state = rtl92c_phy_set_rf_power_state,  	.led_control = rtl92ce_led_control,  	.set_desc = rtl92ce_set_desc,  	.get_desc = rtl92ce_get_desc, @@ -133,24 +224,27 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {  	.init_sw_leds = rtl92ce_init_sw_leds,  	.get_bbreg = rtl92c_phy_query_bb_reg,  	.set_bbreg = rtl92c_phy_set_bb_reg, -	.get_rfreg = rtl92ce_phy_query_rf_reg,  	.set_rfreg = rtl92ce_phy_set_rf_reg, -	.cmd_send_packet = _rtl92c_cmd_send_packet, +	.get_rfreg = rtl92c_phy_query_rf_reg,  	.phy_rf6052_config = rtl92ce_phy_rf6052_config,  	.phy_rf6052_set_cck_txpower = rtl92ce_phy_rf6052_set_cck_txpower,  	.phy_rf6052_set_ofdm_txpower = rtl92ce_phy_rf6052_set_ofdm_txpower,  	.config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile,  	.config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile,  	.phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, -	.phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback,  	.dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower,  };  static struct rtl_mod_params rtl92ce_mod_params = { -	.sw_crypto = 0, +	.sw_crypto = false, +	.inactiveps = true, +	.swctrl_lps = false, +	.fwctrl_lps = true,  };  static struct rtl_hal_cfg rtl92ce_hal_cfg = { +	.bar_id = 2, +	.write_readback = true,  	.name = "rtl92c_pci",  	.fw_name = "rtlwifi/rtl8192cfw.bin",  	.ops = &rtl8192ce_hal_ops, @@ -174,6 +268,8 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = {  	.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,  	.maps[EFUSE_ANA8M] = EFUSE_ANA8M,  	.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, +	.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, +	.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,  	.maps[RWCAM] = REG_CAMCMD,  	.maps[WCAMI] = REG_CAMWRITE, @@ -238,7 +334,7 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = {  	.maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,  }; -static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = { +DEFINE_PCI_DEVICE_TABLE(rtl92ce_pci_ids) = {  	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)},  	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)},  	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)}, @@ -256,7 +352,13 @@ MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");  MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin");  module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); +module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444);  MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); +MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); +MODULE_PARM_DESC(fwlps, "using linked fw control power save " +		 "(default 1 is open)\n");  static struct pci_driver rtl92ce_driver = {  	.name = KBUILD_MODNAME, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index 36e657668c1..b7dc3263e43 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h @@ -33,19 +33,9 @@  int rtl92c_init_sw_vars(struct ieee80211_hw *hw);  void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw);  void rtl92c_init_var_map(struct ieee80211_hw *hw); -bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, -			     struct sk_buff *skb); -void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, -					u8 *ppowerlevel); -void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, -					 u8 *ppowerlevel, u8 channel);  bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, -						  u8 configtype); +					    u8 configtype);  bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, -						    u8 configtype); -void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); -u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw, -			    enum radio_path rfpath, u32 regaddr, u32 bitmask); -void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +					      u8 configtype);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index aa2b5815600..54b2bd53d36 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -36,42 +36,16 @@  #include "trx.h"  #include "led.h" -static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 fc, -							  unsigned int -							  skb_queue) +static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)  { -	enum rtl_desc_qsel qsel; +	__le16 fc = rtl_get_fc(skb); -	if (unlikely(ieee80211_is_beacon(fc))) { -		qsel = QSLT_BEACON; -		return qsel; -	} - -	if (ieee80211_is_mgmt(fc)) { -		qsel = QSLT_MGNT; -		return qsel; -	} +	if (unlikely(ieee80211_is_beacon(fc))) +		return QSLT_BEACON; +	if (ieee80211_is_mgmt(fc)) +		return QSLT_MGNT; -	switch (skb_queue) { -	case VO_QUEUE: -		qsel = QSLT_VO; -		break; -	case VI_QUEUE: -		qsel = QSLT_VI; -		break; -	case BE_QUEUE: -		qsel = QSLT_BE; -		break; -	case BK_QUEUE: -		qsel = QSLT_BK; -		break; -	default: -		qsel = QSLT_BE; -		RT_ASSERT(false, ("BE queue, skb_queue:%d," -				  " set qsel = 0x%X\n", skb_queue, QSLT_BE)); -		break; -	} -	return qsel; +	return skb->priority;  }  static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu) @@ -255,6 +229,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,  	u8 evm, pwdb_all, rf_rx_num = 0;  	u8 i, max_spatial_stream;  	u32 rssi, total_rssi = 0; +	bool in_powersavemode = false;  	bool is_cck_rate;  	is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); @@ -270,9 +245,13 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,  		u8 report, cck_highpwr;  		cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; -		cck_highpwr = (u8) rtl_get_bbreg(hw, -					 RFPGA0_XA_HSSIPARAMETER2, -					 BIT(9)); +		if (!in_powersavemode) +			cck_highpwr = (u8) rtl_get_bbreg(hw, +						 RFPGA0_XA_HSSIPARAMETER2, +						 BIT(9)); +		else +			cck_highpwr = false; +  		if (!cck_highpwr) {  			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;  			report = cck_buf->cck_agc_rpt & 0xc0; @@ -398,6 +377,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,  		if (rtlpriv->stats.ui_rssi.total_num++ >=  		    PHY_RSSI_SLID_WIN_MAX) { +  			rtlpriv->stats.ui_rssi.total_num =  			    PHY_RSSI_SLID_WIN_MAX;  			last_rssi = @@ -424,10 +404,6 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,  	if (!pstats->is_cck && pstats->packet_toself) {  		for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;  		     rfpath++) { - -			if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) -				continue; -  			if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {  				rtlpriv->stats.rx_rssi_percentage[rfpath] =  				    pstats->rx_mimo_signalstrength[rfpath]; @@ -723,7 +699,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,  void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,  			  struct ieee80211_tx_info *info, struct sk_buff *skb, -			  unsigned int queue_index) +			  u8 hw_queue, struct rtl_tcb_desc *tcb_desc)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -732,16 +708,9 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,  	bool defaultadapter = true;  	struct ieee80211_sta *sta;  	u8 *pdesc = (u8 *) pdesc_tx; -	struct rtl_tcb_desc tcb_desc; -	u8 *qc = ieee80211_get_qos_ctl(hdr); -	u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;  	u16 seq_number;  	__le16 fc = hdr->frame_control; -	u8 rate_flag = info->control.rates[0].flags; - -	enum rtl_desc_qsel fw_qsel = -	    _rtl92ce_map_hwqueue_to_fwqueue(fc, queue_index); - +	u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);  	bool firstseg = ((hdr->seq_ctrl &  			  cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); @@ -751,56 +720,68 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,  	dma_addr_t mapping = pci_map_single(rtlpci->pdev,  					    skb->data, skb->len,  					    PCI_DMA_TODEVICE); +	u8 bw_40 = 0; + +	rcu_read_lock(); +	sta = get_sta(hw, mac->vif, mac->bssid); +	if (mac->opmode == NL80211_IFTYPE_STATION) { +		bw_40 = mac->bw_40; +	} else if (mac->opmode == NL80211_IFTYPE_AP || +		mac->opmode == NL80211_IFTYPE_ADHOC) { +		if (sta) +			bw_40 = sta->ht_cap.cap & +				IEEE80211_HT_CAP_SUP_WIDTH_20_40; +	}  	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; -	rtl_get_tcb_desc(hw, info, skb, &tcb_desc); +	rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);  	CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); +	if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { +		firstseg = true; +		lastseg = true; +	}  	if (firstseg) {  		SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); -		SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); +		SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate); -		if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) +		if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)  			SET_TX_DESC_DATA_SHORTGI(pdesc, 1); -		if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && -		    info->flags & IEEE80211_TX_CTL_AMPDU) { +		if (info->flags & IEEE80211_TX_CTL_AMPDU) {  			SET_TX_DESC_AGG_BREAK(pdesc, 1);  			SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);  		}  		SET_TX_DESC_SEQ(pdesc, seq_number); -		SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable && -						!tcb_desc. +		SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable && +						!tcb_desc->  						cts_enable) ? 1 : 0));  		SET_TX_DESC_HW_RTS_ENABLE(pdesc, -					  ((tcb_desc.rts_enable -					    || tcb_desc.cts_enable) ? 1 : 0)); -		SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0)); -		SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0)); +					  ((tcb_desc->rts_enable +					    || tcb_desc->cts_enable) ? 1 : 0)); +		SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0)); +		SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0)); -		SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate); +		SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);  		SET_TX_DESC_RTS_BW(pdesc, 0); -		SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc); +		SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);  		SET_TX_DESC_RTS_SHORT(pdesc, -				      ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? -				      (tcb_desc.rts_use_shortpreamble ? 1 : 0) -				      : (tcb_desc.rts_use_shortgi ? 1 : 0))); +				      ((tcb_desc->rts_rate <= DESC92C_RATE54M) ? +				       (tcb_desc->rts_use_shortpreamble ? 1 : 0) +				       : (tcb_desc->rts_use_shortgi ? 1 : 0))); -		if (mac->bw_40) { -			if (tcb_desc.packet_bw) { +		if (bw_40) { +			if (tcb_desc->packet_bw) {  				SET_TX_DESC_DATA_BW(pdesc, 1);  				SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);  			} else {  				SET_TX_DESC_DATA_BW(pdesc, 0); - -				if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { -					SET_TX_DESC_TX_SUB_CARRIER(pdesc, -							mac->cur_40_prime_sc); -				} +				SET_TX_DESC_TX_SUB_CARRIER(pdesc, +						 mac->cur_40_prime_sc);  			}  		} else {  			SET_TX_DESC_DATA_BW(pdesc, 0); @@ -810,13 +791,10 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,  		SET_TX_DESC_LINIP(pdesc, 0);  		SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); -		rcu_read_lock(); -		sta = ieee80211_find_sta(mac->vif, mac->bssid);  		if (sta) {  			u8 ampdu_density = sta->ht_cap.ampdu_density;  			SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);  		} -		rcu_read_unlock();  		if (info->control.hw_key) {  			struct ieee80211_key_conf *keyconf = @@ -844,7 +822,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,  		SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);  		SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);  		SET_TX_DESC_DISABLE_FB(pdesc, 0); -		SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0); +		SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);  		if (ieee80211_is_data_qos(fc)) {  			if (mac->rdg_en) { @@ -855,24 +833,24 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,  			}  		}  	} +	rcu_read_unlock();  	SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));  	SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));  	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); -	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); +	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);  	if (rtlpriv->dm.useramask) { -		SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); -		SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); +		SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index); +		SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);  	} else { -		SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index); -		SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); +		SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index); +		SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);  	} -	if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && -	    ppsc->fwctrl_lps) { +	if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {  		SET_TX_DESC_HWSEQ_EN(pdesc, 1);  		SET_TX_DESC_PKT_ID(pdesc, 8); @@ -923,7 +901,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,  	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); -	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); +	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);  	SET_TX_DESC_RATE_ID(pdesc, 7);  	SET_TX_DESC_MACID(pdesc, 0); @@ -1021,7 +999,7 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)  	return ret;  } -void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) +void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	if (hw_queue == BEACON_QUEUE) { @@ -1032,35 +1010,3 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)  	}  } -bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, -			     struct sk_buff *skb) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); -	struct rtl8192_tx_ring *ring; -	struct rtl_tx_desc *pdesc; -	u8 own; -	unsigned long flags; -	struct sk_buff *pskb = NULL; - -	ring = &rtlpci->tx_ring[BEACON_QUEUE]; - -	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); - -	pskb = __skb_dequeue(&ring->queue); -	if (pskb) -		kfree_skb(pskb); - -	pdesc = &ring->desc[0]; -	own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); - -	rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); - -	__skb_queue_tail(&ring->queue, skb); - -	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); - -	rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); - -	return true; -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index b0b0b13dd0a..0f117713750 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -724,17 +724,16 @@ struct rx_desc_92c {  void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr,  			  u8 *pdesc, struct ieee80211_tx_info *info, -			  struct sk_buff *skb, unsigned int qsel); +			  struct sk_buff *skb, u8 hw_queue, +			  struct rtl_tcb_desc *ptcb_desc);  bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,  			   struct rtl_stats *stats,  			   struct ieee80211_rx_status *rx_status,  			   u8 *pdesc, struct sk_buff *skb);  void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);  u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name); -void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); +void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);  void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,  			     bool b_firstseg, bool b_lastseg,  			     struct sk_buff *skb); -bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); -  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index e43be254782..52e2af58c1e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -39,6 +39,7 @@  #include "mac.h"  #include "dm.h"  #include "hw.h" +#include "../rtl8192ce/hw.h"  #include "trx.h"  #include "led.h"  #include "table.h" @@ -605,10 +606,10 @@ void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw)  	if (!IS_NORMAL_CHIP(rtlhal->version))  		return;  	tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); -	rtlefuse->epromtype = (tmp_u1b & EEPROMSEL) ? +	rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ?  			       EEPROM_93C46 : EEPROM_BOOT_EFUSE;  	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n", -		 (tmp_u1b & EEPROMSEL) ? "EERROM" : "EFUSE")); +		 (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE"));  	rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true;  	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n",  		 (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!")); @@ -977,7 +978,7 @@ static void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APP_FCS | +	mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APPFCS |  		      RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL |  		      RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32);  	rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf); @@ -2182,7 +2183,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  	}  } -void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw) +void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, +				   struct ieee80211_sta *sta, +				   u8 rssi_level)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index 62af555bb61..32f85cba106 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h @@ -98,13 +98,14 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,  				   u32 add_msr, u32 rm_msr);  void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);  void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw); +void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, +				   struct ieee80211_sta *sta, +				   u8 rssi_level);  void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);  void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);  bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);  void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); -u8 _rtl92c_get_chnl_group(u8 chnl);  int rtl92c_download_fw(struct ieee80211_hw *hw);  void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);  void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index 4e020e654e6..9a3d0239e27 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -38,7 +38,7 @@  #include "table.h"  u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, -			    enum radio_path rfpath, u32 regaddr, u32 bitmask) +			     enum radio_path rfpath, u32 regaddr, u32 bitmask)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	u32 original_value, readback_value, bitshift; @@ -64,8 +64,8 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,  }  void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, -			   enum radio_path rfpath, -			   u32 regaddr, u32 bitmask, u32 data) +			    enum radio_path rfpath, +			    u32 regaddr, u32 bitmask, u32 data)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -163,7 +163,7 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)  }  bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, -						  u8 configtype) +					    u8 configtype)  {  	int i;  	u32 *phy_regarray_table; @@ -223,7 +223,7 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,  }  bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, -						    u8 configtype) +					      u8 configtype)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -459,7 +459,7 @@ void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)  	}  } -bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, +static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,  					    enum rf_pwrstate rfpwr_state)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -595,7 +595,7 @@ bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,  }  bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, -				   enum rf_pwrstate rfpwr_state) +				    enum rf_pwrstate rfpwr_state)  {  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));  	bool bresult = false; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h index 06299559ab6..ff81a61729d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h @@ -34,3 +34,17 @@ bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath);  void rtl92c_phy_set_io(struct ieee80211_hw *hw);  bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);  bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw); +u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, +			     enum radio_path rfpath, u32 regaddr, u32 bitmask); +void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, +			    enum radio_path rfpath, +			    u32 regaddr, u32 bitmask, u32 data); +bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw); +bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, +					      u8 configtype); +void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); +bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, +					    u8 configtype); +void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, +				    enum rf_pwrstate rfpwr_state); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 1c79c226f14..c7576ec4744 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -62,7 +62,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)  }  void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, -				       u8 *ppowerlevel) +					u8 *ppowerlevel)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -389,7 +389,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,  }  void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, -					u8 *ppowerlevel, u8 channel) +					 u8 *ppowerlevel, u8 channel)  {  	u32 writeVal[2], powerBase0[2], powerBase1[2];  	u8 index = 0; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index 86c2728cfa0..500a2094b6b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -43,5 +43,9 @@ extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,  bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw);  bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  					  enum radio_path rfpath); +void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +					u8 *ppowerlevel); +void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +					 u8 *ppowerlevel, u8 channel);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 71244a38d49..bee7c1480f6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -94,7 +94,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {  	.update_interrupt_mask = rtl92cu_update_interrupt_mask,  	.get_hw_reg = rtl92cu_get_hw_reg,  	.set_hw_reg = rtl92cu_set_hw_reg, -	.update_rate_table = rtl92cu_update_hal_rate_table, +	.update_rate_tbl = rtl92cu_update_hal_rate_table,  	.update_rate_mask = rtl92cu_update_hal_rate_mask,  	.fill_tx_desc = rtl92cu_tx_fill_desc,  	.fill_fake_txdesc = rtl92cu_fill_fake_txdesc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 3f0cb81c424..79c98f62175 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -498,14 +498,14 @@ static void _rtl_tx_desc_checksum(u8 *txdesc)  void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,  			  struct ieee80211_tx_info *info, struct sk_buff *skb, -			  unsigned int queue_index) +			  u8 queue_index, +			  struct rtl_tcb_desc *tcb_desc)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));  	bool defaultadapter = true; -	struct ieee80211_sta *sta; -	struct rtl_tcb_desc tcb_desc; +	struct ieee80211_sta *sta = info->control.sta = info->control.sta;  	u8 *qc = ieee80211_get_qos_ctl(hdr);  	u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;  	u16 seq_number; @@ -517,15 +517,15 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,  	u8 *txdesc;  	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; -	rtl_get_tcb_desc(hw, info, skb, &tcb_desc); +	rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);  	txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE);  	memset(txdesc, 0, RTL_TX_HEADER_SIZE);  	SET_TX_DESC_PKT_SIZE(txdesc, pktlen);  	SET_TX_DESC_LINIP(txdesc, 0);  	SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET);  	SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE); -	SET_TX_DESC_TX_RATE(txdesc, tcb_desc.hw_rate); -	if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) +	SET_TX_DESC_TX_RATE(txdesc, tcb_desc->hw_rate); +	if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)  		SET_TX_DESC_DATA_SHORTGI(txdesc, 1);  	if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&  		    info->flags & IEEE80211_TX_CTL_AMPDU) { @@ -535,21 +535,21 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,  		SET_TX_DESC_AGG_BREAK(txdesc, 1);  	}  	SET_TX_DESC_SEQ(txdesc, seq_number); -	SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable && -			       !tcb_desc.cts_enable) ? 1 : 0)); -	SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable || -				  tcb_desc.cts_enable) ? 1 : 0)); -	SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc.cts_enable) ? 1 : 0)); -	SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc.rts_stbc) ? 1 : 0)); -	SET_TX_DESC_RTS_RATE(txdesc, tcb_desc.rts_rate); +	SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable && +			       !tcb_desc->cts_enable) ? 1 : 0)); +	SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable || +				  tcb_desc->cts_enable) ? 1 : 0)); +	SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc->cts_enable) ? 1 : 0)); +	SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc->rts_stbc) ? 1 : 0)); +	SET_TX_DESC_RTS_RATE(txdesc, tcb_desc->rts_rate);  	SET_TX_DESC_RTS_BW(txdesc, 0); -	SET_TX_DESC_RTS_SC(txdesc, tcb_desc.rts_sc); +	SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc);  	SET_TX_DESC_RTS_SHORT(txdesc, -			      ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? -			       (tcb_desc.rts_use_shortpreamble ? 1 : 0) -			       : (tcb_desc.rts_use_shortgi ? 1 : 0))); +			      ((tcb_desc->rts_rate <= DESC92C_RATE54M) ? +			       (tcb_desc->rts_use_shortpreamble ? 1 : 0) +			       : (tcb_desc->rts_use_shortgi ? 1 : 0)));  	if (mac->bw_40) { -		if (tcb_desc.packet_bw) { +		if (tcb_desc->packet_bw) {  			SET_TX_DESC_DATA_BW(txdesc, 1);  			SET_TX_DESC_DATA_SC(txdesc, 3);  		} else { @@ -590,7 +590,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,  	SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F);  	SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF);  	SET_TX_DESC_DISABLE_FB(txdesc, 0); -	SET_TX_DESC_USE_RATE(txdesc, tcb_desc.use_driver_rate ? 1 : 0); +	SET_TX_DESC_USE_RATE(txdesc, tcb_desc->use_driver_rate ? 1 : 0);  	if (ieee80211_is_data_qos(fc)) {  		if (mac->rdg_en) {  			RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, @@ -600,11 +600,11 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,  		}  	}  	if (rtlpriv->dm.useramask) { -		SET_TX_DESC_RATE_ID(txdesc, tcb_desc.ratr_index); -		SET_TX_DESC_MACID(txdesc, tcb_desc.mac_id); +		SET_TX_DESC_RATE_ID(txdesc, tcb_desc->ratr_index); +		SET_TX_DESC_MACID(txdesc, tcb_desc->mac_id);  	} else { -		SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc.ratr_index); -		SET_TX_DESC_MACID(txdesc, tcb_desc.ratr_index); +		SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc->ratr_index); +		SET_TX_DESC_MACID(txdesc, tcb_desc->ratr_index);  	}  	if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&  	      ppsc->fwctrl_lps) { @@ -656,7 +656,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);  	__le16 fc = hdr->frame_control; -	memset(pdesc, 0, RTL_TX_HEADER_SIZE); +	memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE);  	if (firstseg)  		SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE);  	SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h index b396d46edbb..53de5f66e24 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h @@ -37,6 +37,8 @@  #define RTL92C_SIZE_MAX_RX_BUFFER		15360   /* 8192 */  #define RX_DRV_INFO_SIZE_UNIT			8 +#define RTL_AGG_ON				1 +  enum usb_rx_agg_mode {  	USB_RX_AGG_DISABLE,  	USB_RX_AGG_DMA, @@ -419,7 +421,8 @@ struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *,  void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,  			  struct ieee80211_tx_info *info, struct sk_buff *skb, -			  unsigned int queue_index); +			  u8 queue_index, +			  struct rtl_tcb_desc *tcb_desc);  void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,  			      u32 buffer_len, bool bIsPsPoll);  void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index f5d85735d64..a9367eba1ea 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -852,6 +852,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);  	struct rtl_tx_desc *pdesc = NULL; +	struct rtl_tcb_desc tcb_desc;  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);  	__le16 fc = hdr->frame_control;  	u8 *pda_addr = hdr->addr1; @@ -860,8 +861,17 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,  	u8 tid = 0;  	u16 seq_number = 0; -	if (ieee80211_is_mgmt(fc)) -		rtl_tx_mgmt_proc(hw, skb); +	if (ieee80211_is_auth(fc)) { +		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); +		rtl_ips_nic_on(hw); +	} + +	if (rtlpriv->psc.sw_ps_enabled) { +		if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && +		    !ieee80211_has_pm(fc)) +			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); +	} +  	rtl_action_proc(hw, skb, true);  	if (is_multicast_ether_addr(pda_addr))  		rtlpriv->stats.txbytesmulticast += skb->len; @@ -878,7 +888,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,  		seq_number <<= 4;  	}  	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb, -					hw_queue); +					hw_queue, &tcb_desc);  	if (!ieee80211_has_morefrags(hdr->frame_control)) {  		if (qc)  			mac->tids[tid].seq_number = seq_number; @@ -887,7 +897,8 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,  		rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);  } -static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb, +		      struct rtl_tcb_desc *dummy)  {  	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index abadfe918d3..d2a63fb3e1e 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h @@ -31,6 +31,8 @@  #include <linux/usb.h>  #include <linux/skbuff.h> +#define RTL_RX_DESC_SIZE		24 +  #define RTL_USB_DEVICE(vend, prod, cfg) \  	.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \  	.idVendor = (vend), \ diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 2713efe07ce..693395ee98f 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -68,6 +68,8 @@  #define QBSS_LOAD_SIZE				5  #define MAX_WMMELE_LENGTH			64 +#define TOTAL_CAM_ENTRY				32 +  /*slot time for 11g. */  #define RTL_SLOT_TIME_9				9  #define RTL_SLOT_TIME_20			20 @@ -94,8 +96,10 @@  #define	CHANNEL_GROUP_MAX_5G		9  #define CHANNEL_MAX_NUMBER_2G		14  #define AVG_THERMAL_NUM			8 +#define MAX_TID_COUNT			9  /* for early mode */ +#define FCS_LEN				4  #define EM_HDR_LEN			8  enum intf_type {  	INTF_PCI = 0, @@ -159,6 +163,8 @@ enum hardware_type {  (IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal))  #define	IS_HARDWARE_TYPE_8723(rtlhal)			\  (IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal)) +#define IS_HARDWARE_TYPE_8723U(rtlhal)			\ +	(rtlhal->hw_type == HARDWARE_TYPE_RTL8723U)  enum scan_operation_backup_opt {  	SCAN_OPT_BACKUP = 0, @@ -297,6 +303,9 @@ enum hw_variables {  	HW_VAR_DATA_FILTER,  }; +#define HWSET_MAX_SIZE				128 +#define EFUSE_MAX_SECTION			16 +  enum _RT_MEDIA_STATUS {  	RT_MEDIA_DISCONNECT = 0,  	RT_MEDIA_CONNECT = 1 @@ -843,6 +852,7 @@ struct rtl_phy {  	bool apk_done;  	u32 reg_rf3c[2];	/* pathA / pathB  */ +	/* bfsync */  	u8 framesync;  	u32 framesync_c34; @@ -852,6 +862,10 @@ struct rtl_phy {  };  #define MAX_TID_COUNT				9 +#define RTL_AGG_STOP				0 +#define RTL_AGG_PROGRESS			1 +#define RTL_AGG_START				2 +#define RTL_AGG_OPERATIONAL			3  #define RTL_AGG_OFF				0  #define RTL_AGG_ON				1  #define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA		2 @@ -871,6 +885,13 @@ struct rtl_tid_data {  	struct rtl_ht_agg agg;  }; +struct rtl_sta_info { +	u8 ratr_index; +	u8 wireless_mode; +	u8 mimo_ps; +	struct rtl_tid_data tids[MAX_TID_COUNT]; +} __packed; +  struct rtl_priv;  struct rtl_io {  	struct device *dev; @@ -894,6 +915,7 @@ struct rtl_io {  	u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr);  	int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len,  			    u8 *pdata); +  };  struct rtl_mac { @@ -916,6 +938,8 @@ struct rtl_mac {  	int n_channels;  	int n_bitrates; +	bool offchan_deley; +  	/*filters */  	u32 rx_conf;  	u16 rx_mgt_filter; @@ -1032,7 +1056,9 @@ struct rtl_security {  	enum rt_enc_alg pairwise_enc_algorithm;  	/*Encryption Algorithm for Brocast/Multicast */  	enum rt_enc_alg group_enc_algorithm; - +	/*Cam Entry Bitmap */ +	u32 hwsec_cam_bitmap; +	u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN];  	/*local Key buffer, indx 0 is for  	   pairwise key 1-4 is for agoup key. */  	u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN]; @@ -1053,7 +1079,7 @@ struct rtl_dm {  	bool current_turbo_edca;  	bool is_any_nonbepkts;	/*out dm */  	bool is_cur_rdlstate; -	bool txpower_trackingInit; +	bool txpower_trackinginit;  	bool disable_framebursting;  	bool cck_inch14;  	bool txpower_tracking; @@ -1079,7 +1105,6 @@ struct rtl_dm {  	bool disable_tx_int;  	char ofdm_index[2];  	char cck_index; -	u8 power_index_backup[6];  };  #define	EFUSE_MAX_LOGICAL_SIZE			256 @@ -1175,6 +1200,7 @@ struct rtl_ps_ctl {  	 * otherwise Offset[560h] = 0x00.  	 * */  	bool support_aspm; +  	bool support_backdoor;  	/*for LPS */ @@ -1201,7 +1227,6 @@ struct rtl_ps_ctl {  	/*just for PCIE ASPM */  	u8 const_amdpci_aspm; -  	bool pwrdown_mode;  	enum rf_pwrstate inactive_pwrstate; @@ -1282,6 +1307,10 @@ struct rt_link_detect {  	bool busytraffic;  	bool higher_busytraffic;  	bool higher_busyrxtraffic; + +	u32 tidtx_in4period[MAX_TID_COUNT][4]; +	u32 tidtx_inperiod[MAX_TID_COUNT]; +	bool higher_busytxtraffic[MAX_TID_COUNT];  };  struct rtl_tcb_desc { @@ -1344,13 +1373,15 @@ struct rtl_hal_ops {  				       u32 add_msr, u32 rm_msr);  	void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);  	void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val); -	void (*update_rate_table) (struct ieee80211_hw *hw); +	void (*update_rate_tbl) (struct ieee80211_hw *hw, +			      struct ieee80211_sta *sta, u8 rssi_level);  	void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level);  	void (*fill_tx_desc) (struct ieee80211_hw *hw,  			      struct ieee80211_hdr *hdr, u8 *pdesc_tx,  			      struct ieee80211_tx_info *info, -			      struct sk_buff *skb, unsigned int queue_index); -	void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 * pDesc, +			      struct sk_buff *skb, u8 hw_queue, +			      struct rtl_tcb_desc *ptcb_desc); +	void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 *pDesc,  				  u32 buffer_len, bool bIsPsPoll);  	void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc,  				 bool firstseg, bool lastseg, @@ -1370,10 +1401,10 @@ struct rtl_hal_ops {  			     enum led_ctl_mode ledaction);  	void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val);  	u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name); -	void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue); +	void (*tx_polling) (struct ieee80211_hw *hw, u8 hw_queue);  	void (*enable_hw_sec) (struct ieee80211_hw *hw);  	void (*set_key) (struct ieee80211_hw *hw, u32 key_index, -			 u8 *p_macaddr, bool is_group, u8 enc_algo, +			 u8 *macaddr, bool is_group, u8 enc_algo,  			 bool is_wepkey, bool clear_all);  	void (*init_sw_leds) (struct ieee80211_hw *hw);  	void (*deinit_sw_leds) (struct ieee80211_hw *hw); @@ -1384,6 +1415,7 @@ struct rtl_hal_ops {  			  u32 regaddr, u32 bitmask);  	void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath,  			   u32 regaddr, u32 bitmask, u32 data); +	void (*linked_set_reg) (struct ieee80211_hw *hw);  	bool (*phy_rf6052_config) (struct ieee80211_hw *hw);  	void (*phy_rf6052_set_cck_txpower) (struct ieee80211_hw *hw,  					    u8 *powerlevel); @@ -1404,7 +1436,9 @@ struct rtl_intf_ops {  	int (*adapter_start) (struct ieee80211_hw *hw);  	void (*adapter_stop) (struct ieee80211_hw *hw); -	int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb); +	int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb, +			struct rtl_tcb_desc *ptcb_desc); +	void (*flush)(struct ieee80211_hw *hw, bool drop);  	int (*reset_trx_ring) (struct ieee80211_hw *hw);  	bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); @@ -1418,6 +1452,15 @@ struct rtl_intf_ops {  struct rtl_mod_params {  	/* default: 0 = using hardware encryption */  	int sw_crypto; + +	/* default: 1 = using no linked power save */ +	bool inactiveps; + +	/* default: 1 = using linked sw power save */ +	bool swctrl_lps; + +	/* default: 1 = using linked fw power save */ +	bool fwctrl_lps;  };  struct rtl_hal_usbint_cfg { @@ -1445,6 +1488,7 @@ struct rtl_hal_usbint_cfg {  struct rtl_hal_cfg {  	u8 bar_id; +	bool write_readback;  	char *name;  	char *fw_name;  	struct rtl_hal_ops *ops; @@ -1469,7 +1513,6 @@ struct rtl_locks {  	spinlock_t rf_lock;  	spinlock_t lps_lock;  	spinlock_t waitq_lock; -	spinlock_t tx_urb_lock;  	/*Dual mac*/  	spinlock_t cck_and_rw_pagea_lock; @@ -1653,13 +1696,23 @@ struct bt_coexist_info {  #define EF4BYTE(_val)		\  	(le32_to_cpu(_val)) +/* Read data from memory */ +#define READEF1BYTE(_ptr)	\ +	EF1BYTE(*((u8 *)(_ptr)))  /* Read le16 data from memory and convert to host ordering */  #define READEF2BYTE(_ptr)	\  	EF2BYTE(*((u16 *)(_ptr))) +#define READEF4BYTE(_ptr)	\ +	EF4BYTE(*((u32 *)(_ptr))) +/* Write data to memory */ +#define WRITEEF1BYTE(_ptr, _val)	\ +	(*((u8 *)(_ptr))) = EF1BYTE(_val)  /* Write le16 data to memory in host ordering */  #define WRITEEF2BYTE(_ptr, _val)	\  	(*((u16 *)(_ptr))) = EF2BYTE(_val) +#define WRITEEF4BYTE(_ptr, _val)	\ +	(*((u16 *)(_ptr))) = EF2BYTE(_val)  /* Create a bit mask   * Examples: @@ -1698,6 +1751,25 @@ struct bt_coexist_info {  #define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \  	(EF1BYTE(*((u8 *)(__pstart)))) +/*Description: +Translate subfield (continuous bits in little-endian) of 4-byte +value to host byte ordering.*/ +#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ +	( \ +		(LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset))  & \ +		BIT_LEN_MASK_32(__bitlen) \ +	) +#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ +	( \ +		(LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ +		BIT_LEN_MASK_16(__bitlen) \ +	) +#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ +	( \ +		(LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ +		BIT_LEN_MASK_8(__bitlen) \ +	) +  /* Description:   * Mask subfield (continuous bits in little-endian) of 4-byte value   * and return the result in 4-byte value in host byte ordering. @@ -1721,6 +1793,18 @@ struct bt_coexist_info {  /* Description:   * Set subfield of little-endian 4-byte value to specified value.   */ +#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \ +	*((u32 *)(__pstart)) = EF4BYTE \ +	( \ +		LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \ +		((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \ +	); +#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \ +	*((u16 *)(__pstart)) = EF2BYTE \ +	( \ +		LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ +		((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ +	);  #define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \  	*((u8 *)(__pstart)) = EF1BYTE \  	( \ @@ -1728,12 +1812,16 @@ struct bt_coexist_info {  		((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \  	); +#define	N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \ +	(__value) : (((__value + __aligment - 1) / __aligment) * __aligment)) +  /****************************************  	mem access macro define end  ****************************************/  #define byte(x, n) ((x >> (8 * n)) & 0xff) +#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC)  #define RTL_WATCH_DOG_TIME	2000  #define MSECS(t)		msecs_to_jiffies(t)  #define WLAN_FC_GET_VERS(fc)	(le16_to_cpu(fc) & IEEE80211_FCTL_VERS) @@ -1768,6 +1856,15 @@ struct bt_coexist_info {  #define container_of_dwork_rtl(x, y, z) \  	container_of(container_of(x, struct delayed_work, work), y, z) +#define FILL_OCTET_STRING(_os, _octet, _len)	\ +		(_os).octet = (u8 *)(_octet);		\ +		(_os).length = (_len); + +#define CP_MACADDR(des, src)	\ +	((des)[0] = (src)[0], (des)[1] = (src)[1],\ +	(des)[2] = (src)[2], (des)[3] = (src)[3],\ +	(des)[4] = (src)[4], (des)[5] = (src)[5]) +  static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)  {  	return rtlpriv->io.read8_sync(rtlpriv, addr); @@ -1786,17 +1883,26 @@ static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr)  static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8)  {  	rtlpriv->io.write8_async(rtlpriv, addr, val8); + +	if (rtlpriv->cfg->write_readback) +		rtlpriv->io.read8_sync(rtlpriv, addr);  }  static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16)  {  	rtlpriv->io.write16_async(rtlpriv, addr, val16); + +	if (rtlpriv->cfg->write_readback) +		rtlpriv->io.read16_sync(rtlpriv, addr);  }  static inline void rtl_write_dword(struct rtl_priv *rtlpriv,  				   u32 addr, u32 val32)  {  	rtlpriv->io.write32_async(rtlpriv, addr, val32); + +	if (rtlpriv->cfg->write_readback) +		rtlpriv->io.read32_sync(rtlpriv, addr);  }  static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw, @@ -1855,4 +1961,31 @@ static inline u8 get_rf_type(struct rtl_phy *rtlphy)  	return rtlphy->rf_type;  } +static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb) +{ +	return (struct ieee80211_hdr *)(skb->data); +} + +static inline __le16 rtl_get_fc(struct sk_buff *skb) +{ +	return rtl_get_hdr(skb)->frame_control; +} + +static inline u16 rtl_get_tid_h(struct ieee80211_hdr *hdr) +{ +	return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; +} + +static inline u16 rtl_get_tid(struct sk_buff *skb) +{ +	return rtl_get_tid_h(rtl_get_hdr(skb)); +} + +static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, +					    struct ieee80211_vif *vif, +					    u8 *bssid) +{ +	return ieee80211_find_sta(vif, bssid); +} +  #endif  |