diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8723com')
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723com/Makefile | 9 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c | 65 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h | 33 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c | 329 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h | 126 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723com/main.c | 33 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c | 434 | ||||
| -rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h | 89 | 
8 files changed, 1118 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/Makefile b/drivers/net/wireless/rtlwifi/rtl8723com/Makefile new file mode 100644 index 00000000000..345a68adcf3 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723com/Makefile @@ -0,0 +1,9 @@ +rtl8723-common-objs :=		\ +		main.o		\ +		dm_common.o	\ +		fw_common.o	\ +		phy_common.o + +obj-$(CONFIG_RTL8723_COMMON) += rtl8723-common.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c new file mode 100644 index 00000000000..4e254b72bf4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2014  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#include "../wifi.h" +#include "dm_common.h" +#include "../rtl8723ae/dm.h" +#include <linux/module.h> + +/* These routines are common to RTL8723AE and RTL8723bE */ + +void rtl8723_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtlpriv->dm.dynamic_txpower_enable = false; + +	rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; +	rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} +EXPORT_SYMBOL_GPL(rtl8723_dm_init_dynamic_txpower); + +void rtl8723_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtlpriv->dm.current_turbo_edca = false; +	rtlpriv->dm.is_any_nonbepkts = false; +	rtlpriv->dm.is_cur_rdlstate = false; +} +EXPORT_SYMBOL_GPL(rtl8723_dm_init_edca_turbo); + +void rtl8723_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtlpriv->dm_pstable.pre_ccastate = CCA_MAX; +	rtlpriv->dm_pstable.cur_ccasate = CCA_MAX; +	rtlpriv->dm_pstable.pre_rfstate = RF_MAX; +	rtlpriv->dm_pstable.cur_rfstate = RF_MAX; +	rtlpriv->dm_pstable.rssi_val_min = 0; +	rtlpriv->dm_pstable.initialize = 0; +} +EXPORT_SYMBOL_GPL(rtl8723_dm_init_dynamic_bb_powersaving); diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h new file mode 100644 index 00000000000..5c1b94ce2f8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2014  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#ifndef __DM_COMMON_H__ +#define __DM_COMMON_H__ + +void rtl8723_dm_init_dynamic_txpower(struct ieee80211_hw *hw); +void rtl8723_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl8723_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c new file mode 100644 index 00000000000..540278ff462 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c @@ -0,0 +1,329 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2014  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "fw_common.h" +#include <linux/module.h> + +void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 tmp; + +	if (enable) { +		tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); +		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04); + +		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); +		rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + +		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); +		rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); +	} else { +		tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); +		rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + +		rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); +	} +} +EXPORT_SYMBOL_GPL(rtl8723_enable_fw_download); + +void rtl8723_fw_block_write(struct ieee80211_hw *hw, +			    const u8 *buffer, u32 size) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 blocksize = sizeof(u32); +	u8 *bufferptr = (u8 *)buffer; +	u32 *pu4byteptr = (u32 *)buffer; +	u32 i, offset, blockcount, remainsize; + +	blockcount = size / blocksize; +	remainsize = size % blocksize; + +	for (i = 0; i < blockcount; i++) { +		offset = i * blocksize; +		rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), +				*(pu4byteptr + i)); +	} +	if (remainsize) { +		offset = blockcount * blocksize; +		bufferptr += offset; +		for (i = 0; i < remainsize; i++) { +			rtl_write_byte(rtlpriv, +				       (FW_8192C_START_ADDRESS + offset + i), +				       *(bufferptr + i)); +		} +	} +} +EXPORT_SYMBOL_GPL(rtl8723_fw_block_write); + +void rtl8723_fw_page_write(struct ieee80211_hw *hw, +			   u32 page, const u8 *buffer, u32 size) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 value8; +	u8 u8page = (u8) (page & 0x07); + +	value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; + +	rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); +	rtl8723_fw_block_write(hw, buffer, size); +} +EXPORT_SYMBOL_GPL(rtl8723_fw_page_write); + +static void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen) +{ +	u32 fwlen = *pfwlen; +	u8 remain = (u8) (fwlen % 4); + +	remain = (remain == 0) ? 0 : (4 - remain); + +	while (remain > 0) { +		pfwbuf[fwlen] = 0; +		fwlen++; +		remain--; +	} +	*pfwlen = fwlen; +} + +void rtl8723_write_fw(struct ieee80211_hw *hw, +		      enum version_8723e version, +		      u8 *buffer, u32 size) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 *bufferptr = buffer; +	u32 pagenums, remainsize; +	u32 page, offset; + +	RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size); + +	rtl8723_fill_dummy(bufferptr, &size); + +	pagenums = size / FW_8192C_PAGE_SIZE; +	remainsize = size % FW_8192C_PAGE_SIZE; + +	if (pagenums > 8) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "Page numbers should not greater then 8\n"); +	} +	for (page = 0; page < pagenums; page++) { +		offset = page * FW_8192C_PAGE_SIZE; +		rtl8723_fw_page_write(hw, page, (bufferptr + offset), +				      FW_8192C_PAGE_SIZE); +	} +	if (remainsize) { +		offset = pagenums * FW_8192C_PAGE_SIZE; +		page = pagenums; +		rtl8723_fw_page_write(hw, page, (bufferptr + offset), +				      remainsize); +	} +} +EXPORT_SYMBOL_GPL(rtl8723_write_fw); + +void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw) +{ +	u8 u1tmp; +	u8 delay = 100; +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); +	u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + +	while (u1tmp & BIT(2)) { +		delay--; +		if (delay == 0) +			break; +		udelay(50); +		u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); +	} +	if (delay == 0) { +		u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); +		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2))); +	} +} +EXPORT_SYMBOL_GPL(rtl8723ae_firmware_selfreset); + +void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw) +{ +	u8 u1b_tmp; +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); +	rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); + +	u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); +	udelay(50); + +	u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); +	rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0))); + +	u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2))); + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "  _8051Reset8723be(): 8051 reset success .\n"); +} +EXPORT_SYMBOL_GPL(rtl8723be_firmware_selfreset); + +int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	int err = -EIO; +	u32 counter = 0; +	u32 value32; + +	do { +		value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); +	} while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && +		 (!(value32 & FWDL_CHKSUM_RPT))); + +	if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "chksum report fail ! REG_MCUFWDL:0x%08x .\n", +			 value32); +		goto exit; +	} +	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, +		 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32); + +	value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL) | MCUFWDL_RDY; +	value32 &= ~WINTINI_RDY; +	rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + +	if (is_8723be) +		rtl8723be_firmware_selfreset(hw); +	counter = 0; + +	do { +		value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); +		if (value32 & WINTINI_RDY) { +			RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, +				 "Polling FW ready success!! " +				 "REG_MCUFWDL:0x%08x .\n", +				 value32); +			err = 0; +			goto exit; +		} +		udelay(FW_8192C_POLLING_DELAY); + +	} while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); + +	RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +		 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", +		 value32); + +exit: +	return err; +} +EXPORT_SYMBOL_GPL(rtl8723_fw_free_to_go); + +int rtl8723_download_fw(struct ieee80211_hw *hw, +			bool is_8723be) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl92c_firmware_header *pfwheader; +	u8 *pfwdata; +	u32 fwsize; +	int err; +	enum version_8723e version = rtlhal->version; + +	if (!rtlhal->pfirmware) +		return 1; + +	pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; +	pfwdata = rtlhal->pfirmware; +	fwsize = rtlhal->fwsize; +	RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, +		 "normal Firmware SIZE %d\n", fwsize); + +	if (rtlpriv->cfg->ops->is_fw_header(pfwheader)) { +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, +			 "Firmware Version(%d), Signature(%#x), Size(%d)\n", +			 pfwheader->version, pfwheader->signature, +			 (int)sizeof(struct rtl92c_firmware_header)); + +		pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); +		fwsize = fwsize - sizeof(struct rtl92c_firmware_header); +	} +	if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) { +		rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); +		if (is_8723be) +			rtl8723be_firmware_selfreset(hw); +		else +			rtl8723ae_firmware_selfreset(hw); +	} +	rtl8723_enable_fw_download(hw, true); +	rtl8723_write_fw(hw, version, pfwdata, fwsize); +	rtl8723_enable_fw_download(hw, false); + +	err = rtl8723_fw_free_to_go(hw, is_8723be); +	if (err) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "Firmware is not ready to run!\n"); +	} else { +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, +			 "Firmware is ready to run!\n"); +	} +	return 0; +} +EXPORT_SYMBOL_GPL(rtl8723_download_fw); + +bool rtl8723_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; +	struct sk_buff *pskb = NULL; +	u8 own; +	unsigned long flags; + +	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; +} +EXPORT_SYMBOL_GPL(rtl8723_cmd_send_packet); diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h new file mode 100644 index 00000000000..cf1cc5804d0 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h @@ -0,0 +1,126 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2014  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#ifndef __FW_COMMON_H__ +#define __FW_COMMON_H__ + +#define REG_SYS_FUNC_EN				0x0002 +#define REG_MCUFWDL				0x0080 +#define FW_8192C_START_ADDRESS			0x1000 +#define FW_8192C_PAGE_SIZE			4096 +#define FW_8192C_POLLING_TIMEOUT_COUNT		6000 +#define FW_8192C_POLLING_DELAY			5 + +#define MCUFWDL_RDY				BIT(1) +#define FWDL_CHKSUM_RPT				BIT(2) +#define WINTINI_RDY				BIT(6) + +#define REG_RSV_CTRL				0x001C +#define REG_HMETFR				0x01CC + +enum version_8723e { +	VERSION_TEST_UMC_CHIP_8723 = 0x0081, +	VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089, +	VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089, +	VERSION_TEST_CHIP_1T1R_8723B = 0x0106, +	VERSION_NORMAL_SMIC_CHIP_1T1R_8723B = 0x010E, +	VERSION_UNKNOWN = 0xFF, +}; + +enum rtl8723ae_h2c_cmd { +	H2C_AP_OFFLOAD = 0, +	H2C_SETPWRMODE = 1, +	H2C_JOINBSSRPT = 2, +	H2C_RSVDPAGE = 3, +	H2C_RSSI_REPORT = 4, +	H2C_P2P_PS_CTW_CMD = 5, +	H2C_P2P_PS_OFFLOAD = 6, +	H2C_RA_MASK = 7, +	MAX_H2CCMD +}; + +enum rtl8723be_cmd { +	H2C_8723BE_RSVDPAGE = 0, +	H2C_8723BE_JOINBSSRPT = 1, +	H2C_8723BE_SCAN = 2, +	H2C_8723BE_KEEP_ALIVE_CTRL = 3, +	H2C_8723BE_DISCONNECT_DECISION = 4, +	H2C_8723BE_INIT_OFFLOAD = 6, +	H2C_8723BE_AP_OFFLOAD = 8, +	H2C_8723BE_BCN_RSVDPAGE = 9, +	H2C_8723BE_PROBERSP_RSVDPAGE = 10, + +	H2C_8723BE_SETPWRMODE = 0x20, +	H2C_8723BE_PS_TUNING_PARA = 0x21, +	H2C_8723BE_PS_TUNING_PARA2 = 0x22, +	H2C_8723BE_PS_LPS_PARA = 0x23, +	H2C_8723BE_P2P_PS_OFFLOAD = 0x24, + +	H2C_8723BE_WO_WLAN = 0x80, +	H2C_8723BE_REMOTE_WAKE_CTRL = 0x81, +	H2C_8723BE_AOAC_GLOBAL_INFO = 0x82, +	H2C_8723BE_AOAC_RSVDPAGE = 0x83, +	H2C_8723BE_RSSI_REPORT = 0x42, +	H2C_8723BE_RA_MASK = 0x40, +	H2C_8723BE_SELECTIVE_SUSPEND_ROF_CMD, +	H2C_8723BE_P2P_PS_MODE, +	H2C_8723BE_PSD_RESULT, +	/*Not defined CTW CMD for P2P yet*/ +	H2C_8723BE_P2P_PS_CTW_CMD, +	MAX_8723BE_H2CCMD +}; + +struct rtl92c_firmware_header { +	u16 signature; +	u8 category; +	u8 function; +	u16 version; +	u8 subversion; +	u8 rsvd1; +	u8 month; +	u8 date; +	u8 hour; +	u8 minute; +	u16 ramcodesize; +	u16 rsvd2; +	u32 svnindex; +	u32 rsvd3; +	u32 rsvd4; +	u32 rsvd5; +}; + +void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw); +void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw); +void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable); +void rtl8723_fw_block_write(struct ieee80211_hw *hw, +			    const u8 *buffer, u32 size); +void rtl8723_fw_page_write(struct ieee80211_hw *hw, +			   u32 page, const u8 *buffer, u32 size); +void rtl8723_write_fw(struct ieee80211_hw *hw, +		      enum version_8723e version, +		      u8 *buffer, u32 size); +int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be); +int rtl8723_download_fw(struct ieee80211_hw *hw, bool is_8723be); +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/main.c b/drivers/net/wireless/rtlwifi/rtl8723com/main.c new file mode 100644 index 00000000000..9014a94fac6 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723com/main.c @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2014  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#include "../wifi.h" +#include <linux/module.h> + + +MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>"); +MODULE_AUTHOR("Larry Finger	<Larry.Finger@lwfinger.net>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek RTL8723AE/RTL8723BE 802.11n PCI wireless common routines"); diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c new file mode 100644 index 00000000000..d73b659bd2b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c @@ -0,0 +1,434 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2014  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#include "../wifi.h" +#include "phy_common.h" +#include "../rtl8723ae/reg.h" +#include <linux/module.h> + +/* These routines are common to RTL8723AE and RTL8723bE */ + +u32 rtl8723_phy_query_bb_reg(struct ieee80211_hw *hw, +			     u32 regaddr, u32 bitmask) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 returnvalue, originalvalue, bitshift; + +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); +	originalvalue = rtl_read_dword(rtlpriv, regaddr); +	bitshift = rtl8723_phy_calculate_bit_shift(bitmask); +	returnvalue = (originalvalue & bitmask) >> bitshift; + +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "BBR MASK = 0x%x Addr[0x%x]= 0x%x\n", +		  bitmask, regaddr, originalvalue); + +	return returnvalue; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_query_bb_reg); + +void rtl8723_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, +			      u32 bitmask, u32 data) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 originalvalue, bitshift; + +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "regaddr(%#x), bitmask(%#x), data(%#x)\n", +		  regaddr, bitmask, data); + +	if (bitmask != MASKDWORD) { +		originalvalue = rtl_read_dword(rtlpriv, regaddr); +		bitshift = rtl8723_phy_calculate_bit_shift(bitmask); +		data = ((originalvalue & (~bitmask)) | (data << bitshift)); +	} + +	rtl_write_dword(rtlpriv, regaddr, data); + +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "regaddr(%#x), bitmask(%#x), data(%#x)\n", +		  regaddr, bitmask, data); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_set_bb_reg); + +u32 rtl8723_phy_calculate_bit_shift(u32 bitmask) +{ +	u32 i; + +	for (i = 0; i <= 31; i++) { +		if (((bitmask >> i) & 0x1) == 1) +			break; +	} +	return i; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_calculate_bit_shift); + +u32 rtl8723_phy_rf_serial_read(struct ieee80211_hw *hw, +			       enum radio_path rfpath, u32 offset) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; +	u32 newoffset; +	u32 tmplong, tmplong2; +	u8 rfpi_enable = 0; +	u32 retvalue; + +	offset &= 0xff; +	newoffset = offset; +	if (RT_CANNOT_IO(hw)) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); +		return 0xFFFFFFFF; +	} +	tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); +	if (rfpath == RF90_PATH_A) +		tmplong2 = tmplong; +	else +		tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); +	tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | +		   (newoffset << 23) | BLSSIREADEDGE; +	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, +		      tmplong & (~BLSSIREADEDGE)); +	mdelay(1); +	rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); +	mdelay(2); +	if (rfpath == RF90_PATH_A) +		rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, +						 BIT(8)); +	else if (rfpath == RF90_PATH_B) +		rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, +						 BIT(8)); +	if (rfpi_enable) +		retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, +					 BLSSIREADBACKDATA); +	else +		retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, +					 BLSSIREADBACKDATA); +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "RFR-%d Addr[0x%x]= 0x%x\n", +		  rfpath, pphyreg->rf_rb, retvalue); +	return retvalue; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_read); + +void rtl8723_phy_rf_serial_write(struct ieee80211_hw *hw, +				 enum radio_path rfpath, +				 u32 offset, u32 data) +{ +	u32 data_and_addr; +	u32 newoffset; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + +	if (RT_CANNOT_IO(hw)) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); +		return; +	} +	offset &= 0xff; +	newoffset = offset; +	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; +	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "RFW-%d Addr[0x%x]= 0x%x\n", rfpath, +		   pphyreg->rf3wire_offset, data_and_addr); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_write); + +long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, +				  enum wireless_mode wirelessmode, +				  u8 txpwridx) +{ +	long offset; +	long pwrout_dbm; + +	switch (wirelessmode) { +	case WIRELESS_MODE_B: +		offset = -7; +		break; +	case WIRELESS_MODE_G: +	case WIRELESS_MODE_N_24G: +	default: +		offset = -8; +		break; +	} +	pwrout_dbm = txpwridx / 2 + offset; +	return pwrout_dbm; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_txpwr_idx_to_dbm); + +void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); + +	rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; +	rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; +	rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; +	rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + +	rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; +	rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; +	rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; +	rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + +	rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; +	rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + +	rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; +	rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + +	rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = +			    RFPGA0_XA_LSSIPARAMETER; +	rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = +			    RFPGA0_XB_LSSIPARAMETER; + +	rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; +	rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; +	rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; +	rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; + +	rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; +	rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; +	rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; +	rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + +	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; +	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + +	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; +	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + +	rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; +	rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; +	rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; +	rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + +	rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; +	rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; +	rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; +	rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + +	rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; +	rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; +	rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; +	rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + +	rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; +	rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; +	rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; +	rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + +	rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; +	rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; +	rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; +	rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + +	rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; +	rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; +	rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; +	rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + +	rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; +	rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; +	rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; +	rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; + +	rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; +	rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; +	rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; +	rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + +	rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; +	rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_init_bb_rf_reg_def); + +bool rtl8723_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; +} +EXPORT_SYMBOL_GPL(rtl8723_phy_set_sw_chnl_cmdarray); + +void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, +					bool iqk_ok, +					long result[][8], +					u8 final_candidate, +					bool btxonly) +{ +	u32 oldval_0, x, tx0_a, reg; +	long y, tx0_c; + +	if (final_candidate == 0xFF) { +		return; +	} else if (iqk_ok) { +		oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, +					  MASKDWORD) >> 22) & 0x3FF; +		x = result[final_candidate][0]; +		if ((x & 0x00000200) != 0) +			x = x | 0xFFFFFC00; +		tx0_a = (x * oldval_0) >> 8; +		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); +		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), +			      ((x * oldval_0 >> 7) & 0x1)); +		y = result[final_candidate][1]; +		if ((y & 0x00000200) != 0) +			y = y | 0xFFFFFC00; +		tx0_c = (y * oldval_0) >> 8; +		rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, +			      ((tx0_c & 0x3C0) >> 6)); +		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, +			      (tx0_c & 0x3F)); +		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), +			      ((y * oldval_0 >> 7) & 0x1)); +		if (btxonly) +			return; +		reg = result[final_candidate][2]; +		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); +		reg = result[final_candidate][3] & 0x3F; +		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); +		reg = (result[final_candidate][3] >> 6) & 0xF; +		rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); +	} +} +EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_fill_iqk_matrix); + +void rtl8723_save_adda_registers(struct ieee80211_hw *hw, u32 *addareg, +				 u32 *addabackup, u32 registernum) +{ +	u32 i; + +	for (i = 0; i < registernum; i++) +		addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); +} +EXPORT_SYMBOL_GPL(rtl8723_save_adda_registers); + +void rtl8723_phy_save_mac_registers(struct ieee80211_hw *hw, +				    u32 *macreg, u32 *macbackup) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 i; + +	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) +		macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); +	macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_save_mac_registers); + +void rtl8723_phy_reload_adda_registers(struct ieee80211_hw *hw, +				       u32 *addareg, u32 *addabackup, +				       u32 regiesternum) +{ +	u32 i; + +	for (i = 0; i < regiesternum; i++) +		rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_reload_adda_registers); + +void rtl8723_phy_reload_mac_registers(struct ieee80211_hw *hw, +				      u32 *macreg, u32 *macbackup) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 i; + +	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) +		rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); +	rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_reload_mac_registers); + +void rtl8723_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg, +			      bool is_patha_on, bool is2t) +{ +	u32 pathon; +	u32 i; + +	pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; +	if (!is2t) { +		pathon = 0x0bdb25a0; +		rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); +	} else { +		rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon); +	} + +	for (i = 1; i < IQK_ADDA_REG_NUM; i++) +		rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_path_adda_on); + +void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw *hw, +					 u32 *macreg, u32 *macbackup) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 i = 0; + +	rtl_write_byte(rtlpriv, macreg[i], 0x3F); + +	for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) +		rtl_write_byte(rtlpriv, macreg[i], +			       (u8) (macbackup[i] & (~BIT(3)))); +	rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_mac_setting_calibration); + +void rtl8723_phy_path_a_standby(struct ieee80211_hw *hw) +{ +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); +	rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_standby); + +void rtl8723_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ +	u32 mode; + +	mode = pi_mode ? 0x01000100 : 0x01000000; +	rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); +	rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); +} +EXPORT_SYMBOL_GPL(rtl8723_phy_pi_mode_switch); diff --git a/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h new file mode 100644 index 00000000000..83b891a9adb --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2014  Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#ifndef __PHY_COMMON__ +#define __PHY_COMMON__ + +#define RT_CANNOT_IO(hw)			false + +enum swchnlcmd_id { +	CMDID_END, +	CMDID_SET_TXPOWEROWER_LEVEL, +	CMDID_BBREGWRITE10, +	CMDID_WRITEPORT_ULONG, +	CMDID_WRITEPORT_USHORT, +	CMDID_WRITEPORT_UCHAR, +	CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { +	enum swchnlcmd_id cmdid; +	u32 para1; +	u32 para2; +	u32 msdelay; +}; + +u32 rtl8723_phy_query_bb_reg(struct ieee80211_hw *hw, +			     u32 regaddr, u32 bitmask); +void rtl8723_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, +			      u32 bitmask, u32 data); +u32 rtl8723_phy_calculate_bit_shift(u32 bitmask); +u32 rtl8723_phy_rf_serial_read(struct ieee80211_hw *hw, +			       enum radio_path rfpath, u32 offset); +void rtl8723_phy_rf_serial_write(struct ieee80211_hw *hw, +				 enum radio_path rfpath, +				 u32 offset, u32 data); +long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, +				  enum wireless_mode wirelessmode, +				  u8 txpwridx); +void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw *hw); +bool rtl8723_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, +				      u32 cmdtableidx, +				      u32 cmdtablesz, +				      enum swchnlcmd_id cmdid, +				      u32 para1, u32 para2, +				      u32 msdelay); +void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, +					bool iqk_ok, +					long result[][8], +					u8 final_candidate, +					bool btxonly); +void rtl8723_save_adda_registers(struct ieee80211_hw *hw, u32 *addareg, +				 u32 *addabackup, u32 registernum); +void rtl8723_phy_save_mac_registers(struct ieee80211_hw *hw, +				    u32 *macreg, u32 *macbackup); +void rtl8723_phy_reload_adda_registers(struct ieee80211_hw *hw, +				       u32 *addareg, u32 *addabackup, +				       u32 regiesternum); +void rtl8723_phy_reload_mac_registers(struct ieee80211_hw *hw, +				      u32 *macreg, u32 *macbackup); +void rtl8723_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg, +			      bool is_patha_on, bool is2t); +void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw *hw, +					 u32 *macreg, u32 *macbackup); +void rtl8723_phy_path_a_standby(struct ieee80211_hw *hw); +void rtl8723_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode); + +#endif  | 
