Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bd899e7 authored by Larry Finger's avatar Larry Finger Committed by John W. Linville
Browse files

rtlwifi: rtl8192c: rtl8192ce: Add support for B-CUT version of RTL8188CE



Realtek devices with designation RTL8188CE-VL have the so-called B-cut
of the wireless chip. This patch adds the special programming needed by
these devices. In addition, a variable that was static has been moved into
the private data area as it is now needed in two different routines. This
change also fixes a minor bug that would be present if a system had more
than one RTL81{88,92}CE devices. Other drivers in the rtlwifi family had
already made this change, thus the variable already exists in the private
data structure.

Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Cc: Anisse Astier <anisse@astier.eu>
Cc: Li Chaoming <chaoming_li@realsil.com.cn>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent ab3d59d2
Loading
Loading
Loading
Loading
+21 −0
Original line number Original line Diff line number Diff line
@@ -724,6 +724,26 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
}
}
EXPORT_SYMBOL(rtl92c_phy_sw_chnl);
EXPORT_SYMBOL(rtl92c_phy_sw_chnl);


static void _rtl92c_phy_sw_rf_setting(struct ieee80211_hw *hw, u8 channel)
{
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));

	if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
		if (channel == 6 && rtlphy->current_chan_bw ==
		    HT_CHANNEL_WIDTH_20)
			rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
				      0x00255);
		else{
			u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A,
					    RF_RX_G1, RFREG_OFFSET_MASK);
			rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
				      backupRF0x1A);
		}
	}
}

static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
					     u32 cmdtableidx, u32 cmdtablesz,
					     u32 cmdtableidx, u32 cmdtablesz,
					     enum swchnlcmd_id cmdid,
					     enum swchnlcmd_id cmdid,
@@ -837,6 +857,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
					      currentcmd->para1,
					      currentcmd->para1,
					      RFREG_OFFSET_MASK,
					      RFREG_OFFSET_MASK,
					      rtlphy->rfreg_chnlval[rfpath]);
					      rtlphy->rfreg_chnlval[rfpath]);
			_rtl92c_phy_sw_rf_setting(hw, channel);
			}
			}
			break;
			break;
		default:
		default:
+3 −0
Original line number Original line Diff line number Diff line
@@ -116,6 +116,9 @@
	LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
	LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)


#define CHIP_VER_B			BIT(4)
#define CHIP_VER_B			BIT(4)
#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3)
#define CHIP_BONDING_92C_1T2R		0x1
#define RF_TYPE_1T2R			BIT(1)
#define CHIP_92C_BITMASK		BIT(0)
#define CHIP_92C_BITMASK		BIT(0)
#define CHIP_UNKNOWN			BIT(7)
#define CHIP_UNKNOWN			BIT(7)
#define CHIP_92C_1T2R			0x03
#define CHIP_92C_1T2R			0x03
+55 −5
Original line number Original line Diff line number Diff line
@@ -896,7 +896,6 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_phy *rtlphy = &(rtlpriv->phy);
	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
	static bool iqk_initialized; /* initialized to false */
	bool rtstatus = true;
	bool rtstatus = true;
	bool is92c;
	bool is92c;
	int err;
	int err;
@@ -921,9 +920,28 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)


	rtlhal->last_hmeboxnum = 0;
	rtlhal->last_hmeboxnum = 0;
	rtl92c_phy_mac_config(hw);
	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);
	rtl92c_phy_bb_config(hw);
	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
	rtl92c_phy_rf_config(hw);
	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,
	rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
						 RF_CHNLBW, RFREG_OFFSET_MASK);
						 RF_CHNLBW, RFREG_OFFSET_MASK);
	rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
	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) {
	if (ppsc->rfpwr_state == ERFON) {
		rtl92c_phy_set_rfpath_switch(hw, 1);
		rtl92c_phy_set_rfpath_switch(hw, 1);
		if (iqk_initialized) {
		if (rtlphy->iqk_initialized) {
			rtl92c_phy_iq_calibrate(hw, true);
			rtl92c_phy_iq_calibrate(hw, true);
		} else {
		} else {
			rtl92c_phy_iq_calibrate(hw, false);
			rtl92c_phy_iq_calibrate(hw, false);
			iqk_initialized = true;
			rtlphy->iqk_initialized = true;
		}
		}


		rtl92c_dm_check_txpower_tracking(hw);
		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_B_CUT : CHIP_UNKNOWN) |
				   CHIP_VENDOR_UMC));
				   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) {
	switch (version) {
@@ -1019,12 +1044,30 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
	case VERSION_A_CHIP_88C:
	case VERSION_A_CHIP_88C:
		versionid = "A_CHIP_88C";
		versionid = "A_CHIP_88C";
		break;
		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:
	default:
		versionid = "Unknown. Bug?";
		versionid = "Unknown. Bug?";
		break;
		break;
	}
	}


	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
	RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
		 "Chip Version ID: %s\n", versionid);
		 "Chip Version ID: %s\n", versionid);


	switch (version & 0x3) {
	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_priv *rtlpriv = rtl_priv(hw);
	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
	u8 u1b_tmp;
	u8 u1b_tmp;
	u32 u4b_tmp;
	u32 u4b_tmp;


@@ -1225,6 +1269,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
	rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
	rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
	rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
	rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
	if (!IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
		rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
		rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
	if (rtlpcipriv->bt_coexist.bt_coexistence) {
	if (rtlpcipriv->bt_coexist.bt_coexistence) {
		u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);
		u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);
@@ -1254,6 +1299,9 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw)
		rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
		rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
	RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
	RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
	_rtl92ce_poweroff_adapter(hw);
	_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,
void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
@@ -1912,6 +1960,8 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
			ratr_bitmap &= 0x0f0ff0ff;
			ratr_bitmap &= 0x0f0ff0ff;
		break;
		break;
	}
	}
	sta_entry->ratr_index = ratr_index;

	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
		 "ratr_bitmap :%x\n", ratr_bitmap);
		 "ratr_bitmap :%x\n", ratr_bitmap);
	*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
	*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
+2 −0
Original line number Original line Diff line number Diff line
@@ -82,6 +82,8 @@ bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)


	if (is92c)
	if (is92c)
		rtl_write_byte(rtlpriv, 0x14, 0x71);
		rtl_write_byte(rtlpriv, 0x14, 0x71);
	else
		rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
	return rtstatus;
	return rtstatus;
}
}


+2 −4
Original line number Original line Diff line number Diff line
@@ -162,12 +162,10 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)


	/* request fw */
	/* request fw */
	if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
	if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
	    !IS_92C_SERIAL(rtlhal->version)) {
	    !IS_92C_SERIAL(rtlhal->version))
		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
	} else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
	else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
		pr_info("****** This B_CUT device may not work with kernels 3.6 and earlier\n");
	}


	rtlpriv->max_fw_size = 0x4000;
	rtlpriv->max_fw_size = 0x4000;
	pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
	pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
Loading