diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192c')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 525 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 115 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 128 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | 76 | 
6 files changed, 623 insertions, 227 deletions
| diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index bb023274414c..97183829b9be 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; -	u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; +	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 b9cbb0a3c03f..b9736d3e9a39 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 28a6ce3bc239..50303e1adff1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -171,7 +171,6 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,  static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	int err = -EIO;  	u32 counter = 0;  	u32 value32; @@ -184,7 +183,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",  			  value32)); -		goto exit; +		return -EIO;  	}  	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, @@ -204,8 +203,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)  				 ("Polling FW ready success!!"  				 " REG_MCUFWDL:0x%08x .\n",  				 value32)); -			err = 0; -			goto exit; +			return 0;  		}  		mdelay(FW_8192C_POLLING_DELAY); @@ -214,9 +212,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)  	RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  		 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); - -exit: -	return err; +	return -EIO;  }  int rtl92c_download_fw(struct ieee80211_hw *hw) @@ -226,32 +222,16 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)  	struct rtl92c_firmware_header *pfwheader;  	u8 *pfwdata;  	u32 fwsize; -	int err;  	enum version_8192c version = rtlhal->version; -	const struct firmware *firmware; -	printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n", +	printk(KERN_INFO "rtl8192c: Loading firmware file %s\n",  	       rtlpriv->cfg->fw_name); -	err = request_firmware(&firmware, rtlpriv->cfg->fw_name, -			       rtlpriv->io.dev); -	if (err) { -		printk(KERN_ERR "rtl8192cu: Firmware loading failed\n"); -		return 1; -	} - -	if (firmware->size > 0x4000) { -		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -			 ("Firmware is too big!\n")); -		release_firmware(firmware); +	if (!rtlhal->pfirmware)  		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, @@ -267,8 +247,7 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)  	_rtl92c_write_fw(hw, version, pfwdata, fwsize);  	_rtl92c_enable_fw_download(hw, false); -	err = _rtl92c_fw_free_to_go(hw); -	if (err) { +	if (_rtl92c_fw_free_to_go(hw)) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 ("Firmware is not ready to run!\n"));  	} else { @@ -300,10 +279,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	u8 boxnum; -	u16 box_reg, box_extreg; +	u16 box_reg = 0, box_extreg = 0;  	u8 u1b_tmp;  	bool isfw_read = false; -	u8 buf_index = 0;  	bool bwrite_sucess = false;  	u8 wait_h2c_limmit = 100;  	u8 wait_writeh2c_limmit = 100; @@ -414,7 +392,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,  		case 1:  			boxcontent[0] &= ~(BIT(7));  			memcpy((u8 *) (boxcontent) + 1, -			       p_cmdbuffer + buf_index, 1); +			       p_cmdbuffer, 1);  			for (idx = 0; idx < 4; idx++) {  				rtl_write_byte(rtlpriv, box_reg + idx, @@ -424,7 +402,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,  		case 2:  			boxcontent[0] &= ~(BIT(7));  			memcpy((u8 *) (boxcontent) + 1, -			       p_cmdbuffer + buf_index, 2); +			       p_cmdbuffer, 2);  			for (idx = 0; idx < 4; idx++) {  				rtl_write_byte(rtlpriv, box_reg + idx, @@ -434,7 +412,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,  		case 3:  			boxcontent[0] &= ~(BIT(7));  			memcpy((u8 *) (boxcontent) + 1, -			       p_cmdbuffer + buf_index, 3); +			       p_cmdbuffer, 3);  			for (idx = 0; idx < 4; idx++) {  				rtl_write_byte(rtlpriv, box_reg + idx, @@ -444,9 +422,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,  		case 4:  			boxcontent[0] |= (BIT(7));  			memcpy((u8 *) (boxextcontent), -			       p_cmdbuffer + buf_index, 2); +			       p_cmdbuffer, 2);  			memcpy((u8 *) (boxcontent) + 1, -			       p_cmdbuffer + buf_index + 2, 2); +			       p_cmdbuffer + 2, 2);  			for (idx = 0; idx < 2; idx++) {  				rtl_write_byte(rtlpriv, box_extreg + idx, @@ -461,9 +439,9 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,  		case 5:  			boxcontent[0] |= (BIT(7));  			memcpy((u8 *) (boxextcontent), -			       p_cmdbuffer + buf_index, 2); +			       p_cmdbuffer, 2);  			memcpy((u8 *) (boxcontent) + 1, -			       p_cmdbuffer + buf_index + 2, 3); +			       p_cmdbuffer + 2, 3);  			for (idx = 0; idx < 2; idx++) {  				rtl_write_byte(rtlpriv, box_extreg + idx, @@ -561,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 @@ -678,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)); @@ -687,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  	---------------------------------------------------------*/ @@ -703,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); @@ -723,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); @@ -744,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 3db33bd14666..3d5823c12621 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 a70228278398..c5424cad43cb 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 53ffb0981586..9a264c0d6127 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 |