diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192ce/hw.c')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 99 | 
1 files changed, 73 insertions, 26 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 86d73b32d99..1b65db7fd65 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -896,7 +896,6 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)  	struct rtl_phy *rtlphy = &(rtlpriv->phy);  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); -	static bool iqk_initialized; /* initialized to false */  	bool rtstatus = true;  	bool is92c;  	int err; @@ -921,9 +920,28 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)  	rtlhal->last_hmeboxnum = 0;  	rtl92c_phy_mac_config(hw); +	/* because last function modify RCR, so we update +	 * rcr var here, or TP will unstable for receive_config +	 * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx +	 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/ +	rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); +	rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); +	rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);  	rtl92c_phy_bb_config(hw);  	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;  	rtl92c_phy_rf_config(hw); +	if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && +	    !IS_92C_SERIAL(rtlhal->version)) { +		rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); +		rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); +	} else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { +		rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); +		rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); +		rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); +		rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); +		rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); +		rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); +	}  	rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,  						 RF_CHNLBW, RFREG_OFFSET_MASK);  	rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, @@ -945,11 +963,11 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)  	if (ppsc->rfpwr_state == ERFON) {  		rtl92c_phy_set_rfpath_switch(hw, 1); -		if (iqk_initialized) { +		if (rtlphy->iqk_initialized) {  			rtl92c_phy_iq_calibrate(hw, true);  		} else {  			rtl92c_phy_iq_calibrate(hw, false); -			iqk_initialized = true; +			rtlphy->iqk_initialized = true;  		}  		rtl92c_dm_check_txpower_tracking(hw); @@ -1004,6 +1022,13 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)  				   ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) |  				   CHIP_VENDOR_UMC));  		} +		if (IS_92C_SERIAL(version)) { +			value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); +			version = (enum version_8192c)(version | +				   ((CHIP_BONDING_IDENTIFIER(value32) +				   == CHIP_BONDING_92C_1T2R) ? +				   RF_TYPE_1T2R : 0)); +		}  	}  	switch (version) { @@ -1019,12 +1044,30 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)  	case VERSION_A_CHIP_88C:  		versionid = "A_CHIP_88C";  		break; +	case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: +		versionid = "A_CUT_92C_1T2R"; +		break; +	case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: +		versionid = "A_CUT_92C"; +		break; +	case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: +		versionid = "A_CUT_88C"; +		break; +	case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: +		versionid = "B_CUT_92C_1T2R"; +		break; +	case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: +		versionid = "B_CUT_92C"; +		break; +	case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: +		versionid = "B_CUT_88C"; +		break;  	default:  		versionid = "Unknown. Bug?";  		break;  	} -	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +	RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,  		 "Chip Version ID: %s\n", versionid);  	switch (version & 0x3) { @@ -1197,6 +1240,7 @@ 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(rtlpriv);  	u8 u1b_tmp;  	u32 u4b_tmp; @@ -1225,7 +1269,8 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)  	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); +	if (!IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) +		rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);  	if (rtlpcipriv->bt_coexist.bt_coexistence) {  		u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);  		u4b_tmp |= 0x03824800; @@ -1254,6 +1299,9 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw)  		rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);  	RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);  	_rtl92ce_poweroff_adapter(hw); + +	/* after power off we should do iqk again */ +	rtlpriv->phy.iqk_initialized = false;  }  void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, @@ -1355,9 +1403,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,  			tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i];  		else  			tempval = EEPROM_DEFAULT_HT40_2SDIFF; -		rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = +		rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] =  		    (tempval & 0xf); -		rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = +		rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] =  		    ((tempval & 0xf0) >> 4);  	} @@ -1381,7 +1429,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,  				"RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",  				rf_path, i,  				rtlefuse-> -				eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); +				eprom_chnl_txpwr_ht40_2sdf[rf_path][i]);  	for (rf_path = 0; rf_path < 2; rf_path++) {  		for (i = 0; i < 14; i++) { @@ -1396,14 +1444,14 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,  			if ((rtlefuse->  			     eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -  			     rtlefuse-> -			     eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) +			     eprom_chnl_txpwr_ht40_2sdf[rf_path][index])  			    > 0) {  				rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =  				    rtlefuse->  				    eeprom_chnlarea_txpwr_ht40_1s[rf_path]  				    [index] -  				    rtlefuse-> -				    eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] +				    eprom_chnl_txpwr_ht40_2sdf[rf_path]  				    [index];  			} else {  				rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; @@ -1798,9 +1846,9 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,  	struct rtl_sta_info *sta_entry = NULL;  	u32 ratr_bitmap;  	u8 ratr_index; -	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) ? +	u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; +	u8 curshortgi_40mhz = curtxbw_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; @@ -1912,16 +1960,16 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,  			ratr_bitmap &= 0x0f0ff0ff;  		break;  	} +	sta_entry->ratr_index = ratr_index; +  	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,  		 "ratr_bitmap :%x\n", ratr_bitmap);  	*(u32 *)&rate_mask = (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", -		 ratr_index, ratr_bitmap, -		 rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], -		 rate_mask[4]); +		 "Rate_index:%x, ratr_val:%x, %5phC\n", +		 ratr_index, ratr_bitmap, rate_mask);  	rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);  	if (macid != 0) @@ -2176,7 +2224,7 @@ static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw)  	if (rtlpcipriv->bt_coexist.reg_bt_iso == 2)  		rtlpcipriv->bt_coexist.bt_ant_isolation = -			rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation; +			rtlpcipriv->bt_coexist.eeprom_bt_ant_isol;  	else  		rtlpcipriv->bt_coexist.bt_ant_isolation =  			rtlpcipriv->bt_coexist.reg_bt_iso; @@ -2207,23 +2255,22 @@ 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; +	u8 val;  	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); +		val = hwinfo[RF_OPTION4]; +		rtlpcipriv->bt_coexist.eeprom_bt_type = ((val & 0xe) >> 1); +		rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (val & 0x1); +		rtlpcipriv->bt_coexist.eeprom_bt_ant_isol = ((val & 0x10) >> 4);  		rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = -							 ((value & 0x20) >> 5); +							 ((val & 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_ant_isol = 0;  		rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED;  	}  |