diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
134 files changed, 23051 insertions, 2760 deletions
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index c2ffce7a907..bf3cf124e4e 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -5,7 +5,7 @@ menuconfig RTL_CARDS  	---help---  	  This option will enable support for the Realtek mac80211-based  	  wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de, -	  rtl8723eu, and rtl8188eu share some common code. +	  rtl8723ae, rtl8723be, and rtl8188ae share some common code.  if RTL_CARDS @@ -48,12 +48,27 @@ config RTL8723AE  	depends on PCI  	select RTLWIFI  	select RTLWIFI_PCI +	select RTL8723_COMMON +	select RTLBTCOEXIST  	---help---  	This is the driver for Realtek RTL8723AE 802.11n PCIe  	wireless network adapters.  	If you choose to build it as a module, it will be called rtl8723ae +config RTL8723BE +	tristate "Realtek RTL8723BE PCIe Wireless Network Adapter" +	depends on PCI +	select RTLWIFI +	select RTLWIFI_PCI +	select RTL8723_COMMON +	select RTLBTCOEXIST +	---help--- +	This is the driver for Realtek RTL8723BE 802.11n PCIe +	wireless network adapters. + +	If you choose to build it as a module, it will be called rtl8723be +  config RTL8188EE  	tristate "Realtek RTL8188EE Wireless Network Adapter"  	depends on PCI @@ -101,4 +116,14 @@ config RTL8192C_COMMON  	depends on RTL8192CE || RTL8192CU  	default y +config RTL8723_COMMON +	tristate +	depends on RTL8723AE || RTL8723BE +	default y + +config RTLBTCOEXIST +	tristate +	depends on RTL8723AE || RTL8723BE +	default y +  endif diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index d56f023a4b9..bba36a06abc 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -24,6 +24,9 @@ obj-$(CONFIG_RTL8192CU)		+= rtl8192cu/  obj-$(CONFIG_RTL8192SE)		+= rtl8192se/  obj-$(CONFIG_RTL8192DE)		+= rtl8192de/  obj-$(CONFIG_RTL8723AE)		+= rtl8723ae/ +obj-$(CONFIG_RTL8723BE)		+= rtl8723be/  obj-$(CONFIG_RTL8188EE)		+= rtl8188ee/ +obj-$(CONFIG_RTLBTCOEXIST)	+= btcoexist/ +obj-$(CONFIG_RTL8723_COMMON)	+= rtl8723com/  ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 8bb4a9a01a1..93bb384eb00 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -37,6 +37,7 @@  #include <linux/ip.h>  #include <linux/module.h> +#include <linux/udp.h>  /*   *NOTICE!!!: This file will be very big, we should @@ -352,7 +353,6 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)  	/* TODO: Correct this value for our hw */  	/* TODO: define these hard code value */ -	hw->channel_change_time = 100;  	hw->max_listen_interval = 10;  	hw->max_rate_tries = 4;  	/* hw->max_rates = 1; */ @@ -1074,64 +1074,52 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)  	if (!ieee80211_is_data(fc))  		return false; +	ip = (const struct iphdr *)(skb->data + mac_hdr_len + +				    SNAP_SIZE + PROTOC_TYPE_SIZE); +	ether_type = be16_to_cpup((__be16 *) +				  (skb->data + mac_hdr_len + SNAP_SIZE)); -	ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + -			      SNAP_SIZE + PROTOC_TYPE_SIZE); -	ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); -	/*	ether_type = ntohs(ether_type); */ - -	if (ETH_P_IP == ether_type) { -		if (IPPROTO_UDP == ip->protocol) { -			struct udphdr *udp = (struct udphdr *)((u8 *) ip + -							       (ip->ihl << 2)); -			if (((((u8 *) udp)[1] == 68) && -			     (((u8 *) udp)[3] == 67)) || -			    ((((u8 *) udp)[1] == 67) && -			     (((u8 *) udp)[3] == 68))) { -				/* -				 * 68 : UDP BOOTP client -				 * 67 : UDP BOOTP server -				 */ -				RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), -					 DBG_DMESG, "dhcp %s !!\n", -					 is_tx ? "Tx" : "Rx"); - -				if (is_tx) { -					rtlpriv->enter_ps = false; -					schedule_work(&rtlpriv-> -						      works.lps_change_work); -					ppsc->last_delaylps_stamp_jiffies = -					    jiffies; -				} +	switch (ether_type) { +	case ETH_P_IP: { +		struct udphdr *udp; +		u16 src; +		u16 dst; -				return true; -			} -		} -	} else if (ETH_P_ARP == ether_type) { -		if (is_tx) { -			rtlpriv->enter_ps = false; -			schedule_work(&rtlpriv->works.lps_change_work); -			ppsc->last_delaylps_stamp_jiffies = jiffies; -		} +		if (ip->protocol != IPPROTO_UDP) +			return false; +		udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); +		src = be16_to_cpu(udp->source); +		dst = be16_to_cpu(udp->dest); + +		/* If this case involves port 68 (UDP BOOTP client) connecting +		 * with port 67 (UDP BOOTP server), then return true so that +		 * the lowest speed is used. +		 */ +		if (!((src == 68 && dst == 67) || (src == 67 && dst == 68))) +			return false; -		return true; -	} else if (ETH_P_PAE == ether_type) { +		RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, +			 "dhcp %s !!\n", is_tx ? "Tx" : "Rx"); +		break; +	} +	case ETH_P_ARP: +		break; +	case ETH_P_PAE:  		RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,  			 "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); - -		if (is_tx) { -			rtlpriv->enter_ps = false; -			schedule_work(&rtlpriv->works.lps_change_work); -			ppsc->last_delaylps_stamp_jiffies = jiffies; -		} - -		return true; -	} else if (ETH_P_IPV6 == ether_type) { -		/* IPv6 */ -		return true; +		break; +	case ETH_P_IPV6: +		/* TODO: Is this right? */ +		return false; +	default: +		return false;  	} - -	return false; +	if (is_tx) { +		rtlpriv->enter_ps = false; +		schedule_work(&rtlpriv->works.lps_change_work); +		ppsc->last_delaylps_stamp_jiffies = jiffies; +	} +	return true;  }  EXPORT_SYMBOL_GPL(rtl_is_special_data); @@ -1304,7 +1292,7 @@ void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)  		return;  	/* and only beacons from the associated BSSID, please */ -	if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) +	if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))  		return;  	rtlpriv->link_info.bcn_rx_inperiod++; @@ -1448,7 +1436,8 @@ void rtl_watchdog_wq_callback(void *data)  			/* if we can't recv beacon for 6s, we should  			 * reconnect this AP  			 */ -			if (rtlpriv->link_info.roam_times >= 3) { +			if ((rtlpriv->link_info.roam_times >= 3) && +			    !is_zero_ether_addr(rtlpriv->mac80211.bssid)) {  				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  					 "AP off, try to reconnect now\n");  				rtlpriv->link_info.roam_times = 0; @@ -1613,6 +1602,35 @@ err_free:  }  EXPORT_SYMBOL(rtl_send_smps_action); +void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	enum io_type iotype; + +	if (!is_hal_stop(rtlhal)) { +		switch (operation) { +		case SCAN_OPT_BACKUP: +			iotype = IO_CMD_PAUSE_DM_BY_SCAN; +			rtlpriv->cfg->ops->set_hw_reg(hw, +						      HW_VAR_IO_CMD, +						      (u8 *)&iotype); +			break; +		case SCAN_OPT_RESTORE: +			iotype = IO_CMD_RESUME_DM_BY_SCAN; +			rtlpriv->cfg->ops->set_hw_reg(hw, +						      HW_VAR_IO_CMD, +						      (u8 *)&iotype); +			break; +		default: +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "Unknown Scan Backup operation.\n"); +			break; +		} +	} +} +EXPORT_SYMBOL(rtl_phy_scan_operation_backup); +  /* There seem to be issues in mac80211 regarding when del ba frames can be   * received. As a work around, we make a fake del_ba if we receive a ba_req;   * however, rx_agg was opened to let mac80211 release some ba related @@ -1762,7 +1780,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)  		return;  	/* and only beacons from the associated BSSID, please */ -	if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) +	if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))  		return;  	if (rtl_find_221_ie(hw, data, len)) diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 0e5fe0902da..0cd07420777 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h @@ -114,7 +114,6 @@ void rtl_init_rfkill(struct ieee80211_hw *hw);  void rtl_deinit_rfkill(struct ieee80211_hw *hw);  void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); -void rtl_watch_dog_timer_callback(unsigned long data);  void rtl_deinit_deferred_work(struct ieee80211_hw *hw);  bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); @@ -153,5 +152,6 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw,  bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);  struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw,  				u8 *sa, u8 *bssid, u16 tid); +void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);  #endif diff --git a/drivers/net/wireless/rtlwifi/btcoexist/Makefile b/drivers/net/wireless/rtlwifi/btcoexist/Makefile new file mode 100644 index 00000000000..47ceecfcb7d --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/Makefile @@ -0,0 +1,7 @@ +btcoexist-objs :=	halbtc8723b2ant.o	\ +			halbtcoutsrc.o		\ +			rtl_btc.o + +obj-$(CONFIG_RTLBTCOEXIST) += btcoexist.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h new file mode 100644 index 00000000000..d76684eb24d --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h @@ -0,0 +1,75 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * 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	__HALBT_PRECOMP_H__ +#define __HALBT_PRECOMP_H__ +/************************************************************* + * include files + *************************************************************/ +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" + +#include "halbtcoutsrc.h" + +#include "halbtc8723b2ant.h" + +#define BIT0	0x00000001 +#define BIT1	0x00000002 +#define BIT2	0x00000004 +#define BIT3	0x00000008 +#define BIT4	0x00000010 +#define BIT5	0x00000020 +#define BIT6	0x00000040 +#define BIT7	0x00000080 +#define BIT8	0x00000100 +#define BIT9	0x00000200 +#define BIT10	0x00000400 +#define BIT11	0x00000800 +#define BIT12	0x00001000 +#define BIT13	0x00002000 +#define BIT14	0x00004000 +#define BIT15	0x00008000 +#define BIT16	0x00010000 +#define BIT17	0x00020000 +#define BIT18	0x00040000 +#define BIT19	0x00080000 +#define BIT20	0x00100000 +#define BIT21	0x00200000 +#define BIT22	0x00400000 +#define BIT23	0x00800000 +#define BIT24	0x01000000 +#define BIT25	0x02000000 +#define BIT26	0x04000000 +#define BIT27	0x08000000 +#define BIT28	0x10000000 +#define BIT29	0x20000000 +#define BIT30	0x40000000 +#define BIT31	0x80000000 + +#endif	/* __HALBT_PRECOMP_H__ */ diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c new file mode 100644 index 00000000000..d916ab9f3c3 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c @@ -0,0 +1,3698 @@ +/****************************************************************************** + * + * Copyright(c) 2012  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> + * + *****************************************************************************/ +/*************************************************************** + * Description: + * + * This file is for RTL8723B Co-exist mechanism + * + * History + * 2012/11/15 Cosa first check in. + * + **************************************************************/ +/************************************************************** + * include files + **************************************************************/ +#include "halbt_precomp.h" +/************************************************************** + * Global variables, these are static variables + **************************************************************/ +static struct coex_dm_8723b_2ant glcoex_dm_8723b_2ant; +static struct coex_dm_8723b_2ant *coex_dm = &glcoex_dm_8723b_2ant; +static struct coex_sta_8723b_2ant glcoex_sta_8723b_2ant; +static struct coex_sta_8723b_2ant *coex_sta = &glcoex_sta_8723b_2ant; + +static const char *const glbt_info_src_8723b_2ant[] = { +	"BT Info[wifi fw]", +	"BT Info[bt rsp]", +	"BT Info[bt auto report]", +}; + +static u32 glcoex_ver_date_8723b_2ant = 20130731; +static u32 glcoex_ver_8723b_2ant = 0x3b; + +/************************************************************** + * local function proto type if needed + **************************************************************/ +/************************************************************** + * local function start with btc8723b2ant_ + **************************************************************/ +static u8 btc8723b2ant_bt_rssi_state(u8 level_num, u8 rssi_thresh, +				     u8 rssi_thresh1) +{ +	s32 bt_rssi = 0; +	u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; + +	bt_rssi = coex_sta->bt_rssi; + +	if (level_num == 2) { +		if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || +		    (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { +			if (bt_rssi >= rssi_thresh + +				       BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				bt_rssi_state = BTC_RSSI_STATE_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to High\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at Low\n"); +			} +		} else { +			if (bt_rssi < rssi_thresh) { +				bt_rssi_state = BTC_RSSI_STATE_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to Low\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at High\n"); +			} +		} +	} else if (level_num == 3) { +		if (rssi_thresh > rssi_thresh1) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +				  "[BTCoex], BT Rssi thresh error!!\n"); +			return coex_sta->pre_bt_rssi_state; +		} + +		if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || +		    (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { +			if (bt_rssi >= rssi_thresh + +				       BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				bt_rssi_state = BTC_RSSI_STATE_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to Medium\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at Low\n"); +			} +		} else if ((coex_sta->pre_bt_rssi_state == +						BTC_RSSI_STATE_MEDIUM) || +			   (coex_sta->pre_bt_rssi_state == +						BTC_RSSI_STATE_STAY_MEDIUM)) { +			if (bt_rssi >= rssi_thresh1 + +				       BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				bt_rssi_state = BTC_RSSI_STATE_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to High\n"); +			} else if (bt_rssi < rssi_thresh) { +				bt_rssi_state = BTC_RSSI_STATE_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to Low\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at Medium\n"); +			} +		} else { +			if (bt_rssi < rssi_thresh1) { +				bt_rssi_state = BTC_RSSI_STATE_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "switch to Medium\n"); +			} else { +				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, +					  "[BTCoex], BT Rssi state " +					  "stay at High\n"); +			} +		} +	} + +	coex_sta->pre_bt_rssi_state = bt_rssi_state; + +	return bt_rssi_state; +} + +static u8 btc8723b2ant_wifi_rssi_state(struct btc_coexist *btcoexist, +				       u8 index, u8 level_num, +				       u8 rssi_thresh, u8 rssi_thresh1) +{ +	s32 wifi_rssi = 0; +	u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; + +	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); + +	if (level_num == 2) { +		if ((coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_LOW) || +		    (coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_STAY_LOW)) { +			if (wifi_rssi >= rssi_thresh + +					 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				wifi_rssi_state = BTC_RSSI_STATE_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to High\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at Low\n"); +			} +		} else { +			if (wifi_rssi < rssi_thresh) { +				wifi_rssi_state = BTC_RSSI_STATE_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to Low\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at High\n"); +			} +		} +	} else if (level_num == 3) { +		if (rssi_thresh > rssi_thresh1) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, +				  "[BTCoex], wifi RSSI thresh error!!\n"); +			return coex_sta->pre_wifi_rssi_state[index]; +		} + +		if ((coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_LOW) || +		    (coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_STAY_LOW)) { +			if (wifi_rssi >= rssi_thresh + +					BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to Medium\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at Low\n"); +			} +		} else if ((coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_MEDIUM) || +			   (coex_sta->pre_wifi_rssi_state[index] == +						BTC_RSSI_STATE_STAY_MEDIUM)) { +			if (wifi_rssi >= rssi_thresh1 + +					 BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT) { +				wifi_rssi_state = BTC_RSSI_STATE_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to High\n"); +			} else if (wifi_rssi < rssi_thresh) { +				wifi_rssi_state = BTC_RSSI_STATE_LOW; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to Low\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at Medium\n"); +			} +		} else { +			if (wifi_rssi < rssi_thresh1) { +				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "switch to Medium\n"); +			} else { +				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_WIFI_RSSI_STATE, +					  "[BTCoex], wifi RSSI state " +					  "stay at High\n"); +			} +		} +	} + +	coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; + +	return wifi_rssi_state; +} + +static void btc8723b2ant_monitor_bt_ctr(struct btc_coexist *btcoexist) +{ +	u32 reg_hp_txrx, reg_lp_txrx, u32tmp; +	u32 reg_hp_tx = 0, reg_hp_rx = 0; +	u32 reg_lp_tx = 0, reg_lp_rx = 0; + +	reg_hp_txrx = 0x770; +	reg_lp_txrx = 0x774; + +	u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); +	reg_hp_tx = u32tmp & MASKLWORD; +	reg_hp_rx = (u32tmp & MASKHWORD) >> 16; + +	u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); +	reg_lp_tx = u32tmp & MASKLWORD; +	reg_lp_rx = (u32tmp & MASKHWORD) >> 16; + +	coex_sta->high_priority_tx = reg_hp_tx; +	coex_sta->high_priority_rx = reg_hp_rx; +	coex_sta->low_priority_tx = reg_lp_tx; +	coex_sta->low_priority_rx = reg_lp_rx; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, +		  "[BTCoex], High Priority Tx/Rx(reg 0x%x)=0x%x(%d)/0x%x(%d)\n", +		  reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx); +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, +		  "[BTCoex], Low Priority Tx/Rx(reg 0x%x)=0x%x(%d)/0x%x(%d)\n", +		  reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx); + +	/* reset counter */ +	btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); +} + +static bool btc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) +{ +	static bool pre_wifi_busy; +	static bool pre_under_4way; +	static bool pre_bt_hs_on; +	bool wifi_busy = false, under_4way = false, bt_hs_on = false; +	bool wifi_connected = false; + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +			   &wifi_connected); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, +			   &under_4way); + +	if (wifi_connected) { +		if (wifi_busy != pre_wifi_busy) { +			pre_wifi_busy = wifi_busy; +			return true; +		} + +		if (under_4way != pre_under_4way) { +			pre_under_4way = under_4way; +			return true; +		} + +		if (bt_hs_on != pre_bt_hs_on) { +			pre_bt_hs_on = bt_hs_on; +			return true; +		} +	} + +	return false; +} + +static void btc8723b2ant_update_bt_link_info(struct btc_coexist *btcoexist) +{ +	/*struct btc_stack_info *stack_info = &btcoexist->stack_info;*/ +	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; +	bool bt_hs_on = false; + +#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) /* profile from bt patch */ +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + +	bt_link_info->bt_link_exist = coex_sta->bt_link_exist; +	bt_link_info->sco_exist = coex_sta->sco_exist; +	bt_link_info->a2dp_exist = coex_sta->a2dp_exist; +	bt_link_info->pan_exist = coex_sta->pan_exist; +	bt_link_info->hid_exist = coex_sta->hid_exist; + +	/* work around for HS mode. */ +	if (bt_hs_on) { +		bt_link_info->pan_exist = true; +		bt_link_info->bt_link_exist = true; +	} +#else	/* profile from bt stack */ +	bt_link_info->bt_link_exist = stack_info->bt_link_exist; +	bt_link_info->sco_exist = stack_info->sco_exist; +	bt_link_info->a2dp_exist = stack_info->a2dp_exist; +	bt_link_info->pan_exist = stack_info->pan_exist; +	bt_link_info->hid_exist = stack_info->hid_exist; + +	/*for win-8 stack HID report error*/ +	if (!stack_info->hid_exist) +		stack_info->hid_exist = coex_sta->hid_exist; +	/*sync  BTInfo with BT firmware and stack*/ +	/* when stack HID report error, here we use the info from bt fw.*/ +	if (!stack_info->bt_link_exist) +		stack_info->bt_link_exist = coex_sta->bt_link_exist; +#endif +	/* check if Sco only */ +	if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist && +	    !bt_link_info->pan_exist && !bt_link_info->hid_exist) +		bt_link_info->sco_only = true; +	else +		bt_link_info->sco_only = false; + +	/* check if A2dp only */ +	if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist && +	    !bt_link_info->pan_exist && !bt_link_info->hid_exist) +		bt_link_info->a2dp_only = true; +	else +		bt_link_info->a2dp_only = false; + +	/* check if Pan only */ +	if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && +	    bt_link_info->pan_exist && !bt_link_info->hid_exist) +		bt_link_info->pan_only = true; +	else +		bt_link_info->pan_only = false; + +	/* check if Hid only */ +	if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && +	    !bt_link_info->pan_exist && bt_link_info->hid_exist) +		bt_link_info->hid_only = true; +	else +		bt_link_info->hid_only = false; +} + +static u8 btc8723b2ant_action_algorithm(struct btc_coexist *btcoexist) +{ +	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; +	bool bt_hs_on = false; +	u8 algorithm = BT_8723B_2ANT_COEX_ALGO_UNDEFINED; +	u8 num_of_diff_profile = 0; + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); + +	if (!bt_link_info->bt_link_exist) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], No BT link exists!!!\n"); +		return algorithm; +	} + +	if (bt_link_info->sco_exist) +		num_of_diff_profile++; +	if (bt_link_info->hid_exist) +		num_of_diff_profile++; +	if (bt_link_info->pan_exist) +		num_of_diff_profile++; +	if (bt_link_info->a2dp_exist) +		num_of_diff_profile++; + +	if (num_of_diff_profile == 1) { +		if (bt_link_info->sco_exist) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], SCO only\n"); +			algorithm = BT_8723B_2ANT_COEX_ALGO_SCO; +		} else { +			if (bt_link_info->hid_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], HID only\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_HID; +			} else if (bt_link_info->a2dp_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], A2DP only\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_A2DP; +			} else if (bt_link_info->pan_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], PAN(HS) only\n"); +					algorithm = +						BT_8723B_2ANT_COEX_ALGO_PANHS; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], PAN(EDR) only\n"); +					algorithm = +						BT_8723B_2ANT_COEX_ALGO_PANEDR; +				} +			} +		} +	} else if (num_of_diff_profile == 2) { +		if (bt_link_info->sco_exist) { +			if (bt_link_info->hid_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], SCO + HID\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +			} else if (bt_link_info->a2dp_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], SCO + A2DP ==> SCO\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +			} else if (bt_link_info->pan_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + PAN(HS)\n"); +					algorithm = BT_8723B_2ANT_COEX_ALGO_SCO; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + PAN(EDR)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} +		} else { +			if (bt_link_info->hid_exist && +			    bt_link_info->a2dp_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], HID + A2DP\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_HID_A2DP; +			} else if (bt_link_info->hid_exist && +				   bt_link_info->pan_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], HID + PAN(HS)\n"); +					algorithm = BT_8723B_2ANT_COEX_ALGO_HID; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], HID + PAN(EDR)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} else if (bt_link_info->pan_exist && +				   bt_link_info->a2dp_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], A2DP + PAN(HS)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex],A2DP + PAN(EDR)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP; +				} +			} +		} +	} else if (num_of_diff_profile == 3) { +		if (bt_link_info->sco_exist) { +			if (bt_link_info->hid_exist && +			    bt_link_info->a2dp_exist) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], SCO + HID + A2DP" +					  " ==> HID\n"); +				algorithm = BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +			} else if (bt_link_info->hid_exist && +				   bt_link_info->pan_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + HID + " +						  "PAN(HS)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + HID + " +						  "PAN(EDR)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} else if (bt_link_info->pan_exist && +				   bt_link_info->a2dp_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + A2DP + " +						  "PAN(HS)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + A2DP + " +						  "PAN(EDR) ==> HID\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} +		} else { +			if (bt_link_info->hid_exist && +			    bt_link_info->pan_exist && +			    bt_link_info->a2dp_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], HID + A2DP + " +						  "PAN(HS)\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_HID_A2DP; +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], HID + A2DP + " +						  "PAN(EDR)\n"); +					algorithm = +					BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR; +				} +			} +		} +	} else if (num_of_diff_profile >= 3) { +		if (bt_link_info->sco_exist) { +			if (bt_link_info->hid_exist && +			    bt_link_info->pan_exist && +			    bt_link_info->a2dp_exist) { +				if (bt_hs_on) { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], Error!!! SCO + HID" +						  " + A2DP + PAN(HS)\n"); +				} else { +					BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +						  "[BTCoex], SCO + HID + A2DP +" +						  " PAN(EDR)==>PAN(EDR)+HID\n"); +					algorithm = +					    BT_8723B_2ANT_COEX_ALGO_PANEDR_HID; +				} +			} +		} +	} +	return algorithm; +} + +static bool btc8723b_need_dec_pwr(struct btc_coexist *btcoexist) +{ +	bool ret = false; +	bool bt_hs_on = false, wifi_connected = false; +	s32 bt_hs_rssi = 0; +	u8 bt_rssi_state; + +	if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on)) +		return false; +	if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +				&wifi_connected)) +		return false; +	if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi)) +		return false; + +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	if (wifi_connected) { +		if (bt_hs_on) { +			if (bt_hs_rssi > 37) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +					  "[BTCoex], Need to decrease bt " +					  "power for HS mode!!\n"); +				ret = true; +			} +		} else { +			if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +			    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +					  "[BTCoex], Need to decrease bt " +					  "power for Wifi is connected!!\n"); +				ret = true; +			} +		} +	} + +	return ret; +} + +static void btc8723b2ant_set_fw_dac_swing_level(struct btc_coexist *btcoexist, +						u8 dac_swing_lvl) +{ +	u8 h2c_parameter[1] = {0}; + +	/* There are several type of dacswing +	 * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 +	 */ +	h2c_parameter[0] = dac_swing_lvl; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], Set Dac Swing Level=0x%x\n", dac_swing_lvl); +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], FW write 0x64=0x%x\n", h2c_parameter[0]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter); +} + +static void btc8723b2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist, +					   bool dec_bt_pwr) +{ +	u8 h2c_parameter[1] = {0}; + +	h2c_parameter[0] = 0; + +	if (dec_bt_pwr) +		h2c_parameter[0] |= BIT1; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], decrease Bt Power : %s, FW write 0x62=0x%x\n", +		  (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter); +} + +static void btc8723b2ant_dec_bt_pwr(struct btc_coexist *btcoexist, +				    bool force_exec, bool dec_bt_pwr) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], %s Dec BT power = %s\n", +		  (force_exec ? "force to" : ""), (dec_bt_pwr ? "ON" : "OFF")); +	coex_dm->cur_dec_bt_pwr = dec_bt_pwr; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], bPreDecBtPwr=%d, bCurDecBtPwr=%d\n", +			  coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr); + +		if (coex_dm->pre_dec_bt_pwr == coex_dm->cur_dec_bt_pwr) +			return; +	} +	btc8723b2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr); + +	coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr; +} + +static void btc8723b2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist, +					  bool force_exec, u8 fw_dac_swing_lvl) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], %s set FW Dac Swing level = %d\n", +		  (force_exec ? "force to" : ""), fw_dac_swing_lvl); +	coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], preFwDacSwingLvl=%d, " +			  "curFwDacSwingLvl=%d\n", +			  coex_dm->pre_fw_dac_swing_lvl, +			  coex_dm->cur_fw_dac_swing_lvl); + +		if (coex_dm->pre_fw_dac_swing_lvl == +		   coex_dm->cur_fw_dac_swing_lvl) +			return; +	} + +	btc8723b2ant_set_fw_dac_swing_level(btcoexist, +					    coex_dm->cur_fw_dac_swing_lvl); +	coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl; +} + +static void btc8723b2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist, +						 bool rx_rf_shrink_on) +{ +	if (rx_rf_shrink_on) { +		/* Shrink RF Rx LPF corner */ +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Shrink RF Rx LPF corner!!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, +					  0xfffff, 0xffffc); +	} else { +		/* Resume RF Rx LPF corner */ +		/* After initialized, we can use coex_dm->btRf0x1eBackup */ +		if (btcoexist->initilized) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +				  "[BTCoex], Resume RF Rx LPF corner!!\n"); +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, +						  0xfffff, +						  coex_dm->bt_rf0x1e_backup); +		} +	} +} + +static void btc8723b2ant_rf_shrink(struct btc_coexist *btcoexist, +				   bool force_exec, bool rx_rf_shrink_on) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s turn Rx RF Shrink = %s\n", +		  (force_exec ? "force to" : ""), (rx_rf_shrink_on ? +		  "ON" : "OFF")); +	coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], bPreRfRxLpfShrink=%d, " +			  "bCurRfRxLpfShrink=%d\n", +			  coex_dm->pre_rf_rx_lpf_shrink, +			  coex_dm->cur_rf_rx_lpf_shrink); + +		if (coex_dm->pre_rf_rx_lpf_shrink == +		    coex_dm->cur_rf_rx_lpf_shrink) +			return; +	} +	btc8723b2ant_set_sw_rf_rx_lpf_corner(btcoexist, +					     coex_dm->cur_rf_rx_lpf_shrink); + +	coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink; +} + +static void btc8723b_set_penalty_txrate(struct btc_coexist *btcoexist, +					bool low_penalty_ra) +{ +	u8 h2c_parameter[6] = {0}; + +	h2c_parameter[0] = 0x6;	/* opCode, 0x6= Retry_Penalty*/ + +	if (low_penalty_ra) { +		h2c_parameter[1] |= BIT0; +		/*normal rate except MCS7/6/5, OFDM54/48/36*/ +		h2c_parameter[2] = 0x00; +		h2c_parameter[3] = 0xf7;  /*MCS7 or OFDM54*/ +		h2c_parameter[4] = 0xf8;  /*MCS6 or OFDM48*/ +		h2c_parameter[5] = 0xf9;  /*MCS5 or OFDM36*/ +	} + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], set WiFi Low-Penalty Retry: %s", +		  (low_penalty_ra ? "ON!!" : "OFF!!")); + +	btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); +} + +static void btc8723b2ant_low_penalty_ra(struct btc_coexist *btcoexist, +					bool force_exec, bool low_penalty_ra) +{ +	/*return; */ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s turn LowPenaltyRA = %s\n", +		  (force_exec ? "force to" : ""), (low_penalty_ra ? +		  "ON" : "OFF")); +	coex_dm->cur_low_penalty_ra = low_penalty_ra; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], bPreLowPenaltyRa=%d, " +			  "bCurLowPenaltyRa=%d\n", +			  coex_dm->pre_low_penalty_ra, +			  coex_dm->cur_low_penalty_ra); + +		if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) +			return; +	} +	btc8723b_set_penalty_txrate(btcoexist, coex_dm->cur_low_penalty_ra); + +	coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; +} + +static void btc8723b2ant_set_dac_swing_reg(struct btc_coexist *btcoexist, +					   u32 level) +{ +	u8 val = (u8) level; +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], Write SwDacSwing = 0x%x\n", level); +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val); +} + +static void btc8723b2ant_set_sw_fulltime_dac_swing(struct btc_coexist *btcoex, +						   bool sw_dac_swing_on, +						   u32 sw_dac_swing_lvl) +{ +	if (sw_dac_swing_on) +		btc8723b2ant_set_dac_swing_reg(btcoex, sw_dac_swing_lvl); +	else +		btc8723b2ant_set_dac_swing_reg(btcoex, 0x18); +} + + +static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, +				   bool force_exec, bool dac_swing_on, +				   u32 dac_swing_lvl) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s turn DacSwing=%s, dac_swing_lvl=0x%x\n", +		  (force_exec ? "force to" : ""), +		  (dac_swing_on ? "ON" : "OFF"), dac_swing_lvl); +	coex_dm->cur_dac_swing_on = dac_swing_on; +	coex_dm->cur_dac_swing_lvl = dac_swing_lvl; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl=0x%x," +			  " bCurDacSwingOn=%d, curDacSwingLvl=0x%x\n", +			  coex_dm->pre_dac_swing_on, coex_dm->pre_dac_swing_lvl, +			  coex_dm->cur_dac_swing_on, +			  coex_dm->cur_dac_swing_lvl); + +		if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) && +		    (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl)) +			return; +	} +	mdelay(30); +	btc8723b2ant_set_sw_fulltime_dac_swing(btcoexist, dac_swing_on, +					       dac_swing_lvl); + +	coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on; +	coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl; +} + +static void btc8723b2ant_set_agc_table(struct btc_coexist *btcoexist, +				       bool agc_table_en) +{ +	u8 rssi_adjust_val = 0; + +	/*  BB AGC Gain Table */ +	if (agc_table_en) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], BB Agc Table On!\n"); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6e1A0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6d1B0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6c1C0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6b1D0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x6a1E0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x691F0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x68200001); +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], BB Agc Table Off!\n"); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa91B0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa81C0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa71D0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa61E0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa51F0001); +		btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa4200001); +	} + + +	/* RF Gain */ +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); +	if (agc_table_en) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Agc Table On!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, +					  0xfffff, 0x38fff); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, +					  0xfffff, 0x38ffe); +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Agc Table Off!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, +					  0xfffff, 0x380c3); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, +					  0xfffff, 0x28ce6); +	} +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xed, 0xfffff, 0x1); + +	if (agc_table_en) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Agc Table On!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40, +					  0xfffff, 0x38fff); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40, +					  0xfffff, 0x38ffe); +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +			  "[BTCoex], Agc Table Off!\n"); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40, +					  0xfffff, 0x380c3); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x40, +					  0xfffff, 0x28ce6); +	} +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xed, 0xfffff, 0x0); + +	/* set rssiAdjustVal for wifi module. */ +	if (agc_table_en) +		rssi_adjust_val = 8; +	btcoexist->btc_set(btcoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, +			   &rssi_adjust_val); +} + +static void btc8723b2ant_agc_table(struct btc_coexist *btcoexist, +				   bool force_exec, bool agc_table_en) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s %s Agc Table\n", +		  (force_exec ? "force to" : ""), +		  (agc_table_en ? "Enable" : "Disable")); +	coex_dm->cur_agc_table_en = agc_table_en; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n", +			  coex_dm->pre_agc_table_en, coex_dm->cur_agc_table_en); + +		if (coex_dm->pre_agc_table_en == coex_dm->cur_agc_table_en) +			return; +	} +	btc8723b2ant_set_agc_table(btcoexist, agc_table_en); + +	coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en; +} + +static void btc8723b2ant_set_coex_table(struct btc_coexist *btcoexist, +					u32 val0x6c0, u32 val0x6c4, +					u32 val0x6c8, u8 val0x6cc) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0); +	btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4); +	btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8); +	btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, +		  "[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc); +	btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); +} + +static void btc8723b2ant_coex_table(struct btc_coexist *btcoexist, +				    bool force_exec, u32 val0x6c0, +				    u32 val0x6c4, u32 val0x6c8, +				    u8 val0x6cc) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, +		  "[BTCoex], %s write Coex Table 0x6c0=0x%x," +		  " 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n", +		  (force_exec ? "force to" : ""), val0x6c0, +		  val0x6c4, val0x6c8, val0x6cc); +	coex_dm->cur_val0x6c0 = val0x6c0; +	coex_dm->cur_val0x6c4 = val0x6c4; +	coex_dm->cur_val0x6c8 = val0x6c8; +	coex_dm->cur_val0x6cc = val0x6cc; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], preVal0x6c0=0x%x, " +			  "preVal0x6c4=0x%x, preVal0x6c8=0x%x, " +			  "preVal0x6cc=0x%x !!\n", +			  coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4, +			  coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc); +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, +			  "[BTCoex], curVal0x6c0=0x%x, " +			  "curVal0x6c4=0x%x, curVal0x6c8=0x%x, " +			  "curVal0x6cc=0x%x !!\n", +			  coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4, +			  coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc); + +		if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && +		    (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && +		    (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && +		    (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) +			return; +	} +	btc8723b2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, +				    val0x6c8, val0x6cc); + +	coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; +	coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; +	coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; +	coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; +} + +static void btc8723b_coex_tbl_type(struct btc_coexist *btcoexist, +				   bool force_exec, u8 type) +{ +	switch (type) { +	case 0: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555, +					0x55555555, 0xffff, 0x3); +		break; +	case 1: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55555555, +					0x5afa5afa, 0xffff, 0x3); +		break; +	case 2: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, +					0x5a5a5a5a, 0xffff, 0x3); +		break; +	case 3: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa, +					0xaaaaaaaa, 0xffff, 0x3); +		break; +	case 4: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0xffffffff, +					0xffffffff, 0xffff, 0x3); +		break; +	case 5: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x5fff5fff, +					0x5fff5fff, 0xffff, 0x3); +		break; +	case 6: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5a5a5a5a, 0xffff, 0x3); +		break; +	case 7: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5afa5afa, 0xffff, 0x3); +		break; +	case 8: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x5aea5aea, +					0x5aea5aea, 0xffff, 0x3); +		break; +	case 9: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5aea5aea, 0xffff, 0x3); +		break; +	case 10: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5aff5aff, 0xffff, 0x3); +		break; +	case 11: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5a5f5a5f, 0xffff, 0x3); +		break; +	case 12: +		btc8723b2ant_coex_table(btcoexist, force_exec, 0x55ff55ff, +					0x5f5f5f5f, 0xffff, 0x3); +		break; +	default: +		break; +	} +} + +static void btc8723b2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist, +						bool enable) +{ +	u8 h2c_parameter[1] = {0}; + +	if (enable) +		h2c_parameter[0] |= BIT0;/* function enable*/ + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], set FW for BT Ignore Wlan_Act, " +		  "FW write 0x63=0x%x\n", h2c_parameter[0]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); +} + +static void btc8723b2ant_ignore_wlan_act(struct btc_coexist *btcoexist, +					 bool force_exec, bool enable) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], %s turn Ignore WlanAct %s\n", +		  (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); +	coex_dm->cur_ignore_wlan_act = enable; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], bPreIgnoreWlanAct = %d, " +			  "bCurIgnoreWlanAct = %d!!\n", +			  coex_dm->pre_ignore_wlan_act, +			  coex_dm->cur_ignore_wlan_act); + +		if (coex_dm->pre_ignore_wlan_act == +		    coex_dm->cur_ignore_wlan_act) +			return; +	} +	btc8723b2ant_set_fw_ignore_wlan_act(btcoexist, enable); + +	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; +} + +static void btc8723b2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1, +					u8 byte2, u8 byte3, u8 byte4, u8 byte5) +{ +	u8 h2c_parameter[5]; + +	h2c_parameter[0] = byte1; +	h2c_parameter[1] = byte2; +	h2c_parameter[2] = byte3; +	h2c_parameter[3] = byte4; +	h2c_parameter[4] = byte5; + +	coex_dm->ps_tdma_para[0] = byte1; +	coex_dm->ps_tdma_para[1] = byte2; +	coex_dm->ps_tdma_para[2] = byte3; +	coex_dm->ps_tdma_para[3] = byte4; +	coex_dm->ps_tdma_para[4] = byte5; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n", +		  h2c_parameter[0], +		  h2c_parameter[1] << 24 | h2c_parameter[2] << 16 | +		  h2c_parameter[3] << 8 | h2c_parameter[4]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); +} + +static void btc8723b2ant_sw_mechanism1(struct btc_coexist *btcoexist, +				       bool shrink_rx_lpf, bool low_penalty_ra, +				       bool limited_dig, bool bt_lna_constrain) +{ +	btc8723b2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf); +	btc8723b2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); +} + +static void btc8723b2ant_sw_mechanism2(struct btc_coexist *btcoexist, +				       bool agc_table_shift, bool adc_backoff, +				       bool sw_dac_swing, u32 dac_swing_lvl) +{ +	btc8723b2ant_agc_table(btcoexist, NORMAL_EXEC, agc_table_shift); +	btc8723b2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing, +			       dac_swing_lvl); +} + +static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec, +			     bool turn_on, u8 type) +{ +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], %s turn %s PS TDMA, type=%d\n", +		  (force_exec ? "force to" : ""), +		  (turn_on ? "ON" : "OFF"), type); +	coex_dm->cur_ps_tdma_on = turn_on; +	coex_dm->cur_ps_tdma = type; + +	if (!force_exec) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n", +			  coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on); +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n", +			  coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma); + +		if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && +		    (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) +			return; +	} +	if (turn_on) { +		switch (type) { +		case 1: +		default: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0xe1, 0x90); +			break; +		case 2: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, +						    0x12, 0xe1, 0x90); +			break; +		case 3: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, +						    0x3, 0xf1, 0x90); +			break; +		case 4: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10, +						    0x03, 0xf1, 0x90); +			break; +		case 5: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0x60, 0x90); +			break; +		case 6: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, +						    0x12, 0x60, 0x90); +			break; +		case 7: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c, +						    0x3, 0x70, 0x90); +			break; +		case 8: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x10, +						    0x3, 0x70, 0x90); +			break; +		case 9: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0xe1, 0x90); +			break; +		case 10: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, +						    0x12, 0xe1, 0x90); +			break; +		case 11: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, +						    0xa, 0xe1, 0x90); +			break; +		case 12: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, +						    0x5, 0xe1, 0x90); +			break; +		case 13: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0x60, 0x90); +			break; +		case 14: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12, +						    0x12, 0x60, 0x90); +			break; +		case 15: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, +						    0xa, 0x60, 0x90); +			break; +		case 16: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, +						    0x5, 0x60, 0x90); +			break; +		case 17: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x2f, +						    0x2f, 0x60, 0x90); +			break; +		case 18: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5, +						    0x5, 0xe1, 0x90); +			break; +		case 19: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, +						    0x25, 0xe1, 0x90); +			break; +		case 20: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, +						    0x25, 0x60, 0x90); +			break; +		case 21: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, +						    0x03, 0x70, 0x90); +			break; +		case 71: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a, +						    0x1a, 0xe1, 0x90); +			break; +		} +	} else { +		/* disable PS tdma */ +		switch (type) { +		case 0: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, +						    0x40, 0x0); +			break; +		case 1: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, +						    0x48, 0x0); +			break; +		default: +			btc8723b2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, +						    0x40, 0x0); +			break; +		} +	} + +	/* update pre state */ +	coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; +	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; +} + +static void btc8723b2ant_coex_alloff(struct btc_coexist *btcoexist) +{ +	/* fw all off */ +	btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); +	btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	/* sw all off */ +	btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false); +	btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); + +	/* hw all off */ +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +} + +static void btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ +	/* force to reset coex mechanism*/ + +	btc8723b2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); +	btc8723b2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, false); + +	btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false); +	btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); +} + +static void btc8723b2ant_action_bt_inquiry(struct btc_coexist *btcoexist) +{ +	bool wifi_connected = false; +	bool low_pwr_disable = true; + +	btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, +			   &low_pwr_disable); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +			   &wifi_connected); + +	if (wifi_connected) { +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +	} else { +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +	} +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); +	btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, false); +	btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, 0x18); + +	coex_dm->need_recover_0x948 = true; +	coex_dm->backup_0x948 = btcoexist->btc_read_2byte(btcoexist, 0x948); + +	btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); +} + +static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist) +{ +	bool common = false, wifi_connected = false; +	bool wifi_busy = false; +	bool bt_hs_on = false, low_pwr_disable = false; + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +			   &wifi_connected); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); + +	if (!wifi_connected) { +		low_pwr_disable = false; +		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, +				   &low_pwr_disable); + +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], Wifi non-connected idle!!\n"); + +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, +					  0x0); +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +		btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +		btc8723b2ant_sw_mechanism1(btcoexist, false, false, false, +					   false); +		btc8723b2ant_sw_mechanism2(btcoexist, false, false, false, +					   0x18); + +		common = true; +	} else { +		if (BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE == +		    coex_dm->bt_status) { +			low_pwr_disable = false; +			btcoexist->btc_set(btcoexist, +					   BTC_SET_ACT_DISABLE_LOW_POWER, +					   &low_pwr_disable); + +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Wifi connected + " +				  "BT non connected-idle!!\n"); + +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, +						  0xfffff, 0x0); +			btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +			btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, +						      0xb); +			btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, +						false); + +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); + +			common = true; +		} else if (BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE == +			   coex_dm->bt_status) { +			low_pwr_disable = true; +			btcoexist->btc_set(btcoexist, +					   BTC_SET_ACT_DISABLE_LOW_POWER, +					   &low_pwr_disable); + +			if (bt_hs_on) +				return false; +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Wifi connected + " +				  "BT connected-idle!!\n"); + +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, +						  0xfffff, 0x0); +			btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); +			btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, +						      0xb); +			btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, +						false); + +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); + +			common = true; +		} else { +			low_pwr_disable = true; +			btcoexist->btc_set(btcoexist, +					   BTC_SET_ACT_DISABLE_LOW_POWER, +					   &low_pwr_disable); + +			if (wifi_busy) { +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], Wifi Connected-Busy + " +					  "BT Busy!!\n"); +				common = false; +			} else { +				if (bt_hs_on) +					return false; + +				BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +					  "[BTCoex], Wifi Connected-Idle + " +					  "BT Busy!!\n"); + +				btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, +							  0x1, 0xfffff, 0x0); +				btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, +						       7); +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 21); +				btc8723b2ant_fw_dac_swing_lvl(btcoexist, +							      NORMAL_EXEC, +							      0xb); +				if (btc8723b_need_dec_pwr(btcoexist)) +					btc8723b2ant_dec_bt_pwr(btcoexist, +								NORMAL_EXEC, +								true); +				else +					btc8723b2ant_dec_bt_pwr(btcoexist, +								NORMAL_EXEC, +								false); +				btc8723b2ant_sw_mechanism1(btcoexist, false, +							   false, false, +							   false); +				btc8723b2ant_sw_mechanism2(btcoexist, false, +							   false, false, +							   0x18); +				common = true; +			} +		} +	} + +	return common; +} + +static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause, +			  s32 result) +{ +	/* Set PS TDMA for max interval == 1 */ +	if (tx_pause) { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 1\n"); + +		if (coex_dm->cur_ps_tdma == 71) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 5); +			coex_dm->tdma_adj_type = 5; +		} else if (coex_dm->cur_ps_tdma == 1) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 5); +			coex_dm->tdma_adj_type = 5; +		} else if (coex_dm->cur_ps_tdma == 2) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 6); +			coex_dm->tdma_adj_type = 6; +		} else if (coex_dm->cur_ps_tdma == 3) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 4) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 8); +			coex_dm->tdma_adj_type = 8; +		} else if (coex_dm->cur_ps_tdma == 9) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 13); +			coex_dm->tdma_adj_type = 13; +		} else if (coex_dm->cur_ps_tdma == 10) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 14); +			coex_dm->tdma_adj_type = 14; +		} else if (coex_dm->cur_ps_tdma == 11) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 12) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +					     true, 16); +			coex_dm->tdma_adj_type = 16; +		} + +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 5) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 8); +				coex_dm->tdma_adj_type = 8; +			} else if (coex_dm->cur_ps_tdma == 13) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 16); +				coex_dm->tdma_adj_type = 16; +			} +		}  else if (result == 1) { +			if (coex_dm->cur_ps_tdma == 8) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 5); +				coex_dm->tdma_adj_type = 5; +			} else if (coex_dm->cur_ps_tdma == 16) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 13); +				coex_dm->tdma_adj_type = 13; +			} +		} +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 0\n"); +		if (coex_dm->cur_ps_tdma == 5) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 71); +			coex_dm->tdma_adj_type = 71; +		} else if (coex_dm->cur_ps_tdma == 6) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); +			coex_dm->tdma_adj_type = 2; +		} else if (coex_dm->cur_ps_tdma == 7) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +		} else if (coex_dm->cur_ps_tdma == 8) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); +			coex_dm->tdma_adj_type = 4; +		} else if (coex_dm->cur_ps_tdma == 13) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); +			coex_dm->tdma_adj_type = 9; +		} else if (coex_dm->cur_ps_tdma == 14) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); +			coex_dm->tdma_adj_type = 10; +		} else if (coex_dm->cur_ps_tdma == 15) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +		} else if (coex_dm->cur_ps_tdma == 16) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); +			coex_dm->tdma_adj_type = 12; +		} + +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 71) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 1); +				coex_dm->tdma_adj_type = 1; +			} else if (coex_dm->cur_ps_tdma == 1) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 2); +				coex_dm->tdma_adj_type = 2; +			} else if (coex_dm->cur_ps_tdma == 2) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +			} else if (coex_dm->cur_ps_tdma == 3) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 4); +				coex_dm->tdma_adj_type = 4; +			} else if (coex_dm->cur_ps_tdma == 9) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 10); +				coex_dm->tdma_adj_type = 10; +			} else if (coex_dm->cur_ps_tdma == 10) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +			} else if (coex_dm->cur_ps_tdma == 11) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 12); +				coex_dm->tdma_adj_type = 12; +			} +		}  else if (result == 1) { +			int tmp = coex_dm->cur_ps_tdma; +			switch (tmp) { +			case 4: +			case 3: +			case 2: +			case 12: +			case 11: +			case 10: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, tmp - 1); +				coex_dm->tdma_adj_type = tmp - 1; +				break; +			case 1: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 71); +				coex_dm->tdma_adj_type = 71; +				break; +			} +		} +	} +} + +static void set_tdma_int2(struct btc_coexist *btcoexist, bool tx_pause, +			  s32 result) +{ +	/* Set PS TDMA for max interval == 2 */ +	if (tx_pause) { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 1\n"); +		if (coex_dm->cur_ps_tdma == 1) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6); +			coex_dm->tdma_adj_type = 6; +		} else if (coex_dm->cur_ps_tdma == 2) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6); +			coex_dm->tdma_adj_type = 6; +		} else if (coex_dm->cur_ps_tdma == 3) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 4) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); +			coex_dm->tdma_adj_type = 8; +		} else if (coex_dm->cur_ps_tdma == 9) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); +			coex_dm->tdma_adj_type = 14; +		} else if (coex_dm->cur_ps_tdma == 10) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); +			coex_dm->tdma_adj_type = 14; +		} else if (coex_dm->cur_ps_tdma == 11) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 12) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 16); +			coex_dm->tdma_adj_type = 16; +		} +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 5) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 8); +				coex_dm->tdma_adj_type = 8; +			} else if (coex_dm->cur_ps_tdma == 13) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 16); +				coex_dm->tdma_adj_type = 16; +			} +		}  else if (result == 1) { +			if (coex_dm->cur_ps_tdma == 8) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 6); +				coex_dm->tdma_adj_type = 6; +			} else if (coex_dm->cur_ps_tdma == 16) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 14); +				coex_dm->tdma_adj_type = 14; +			} +		} +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 0\n"); +		if (coex_dm->cur_ps_tdma == 5) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); +			coex_dm->tdma_adj_type = 2; +		} else if (coex_dm->cur_ps_tdma == 6) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); +			coex_dm->tdma_adj_type = 2; +		} else if (coex_dm->cur_ps_tdma == 7) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +		} else if (coex_dm->cur_ps_tdma == 8) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); +			coex_dm->tdma_adj_type = 4; +		} else if (coex_dm->cur_ps_tdma == 13) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); +			coex_dm->tdma_adj_type = 10; +		} else if (coex_dm->cur_ps_tdma == 14) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); +			coex_dm->tdma_adj_type = 10; +		} else if (coex_dm->cur_ps_tdma == 15) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +		} else if (coex_dm->cur_ps_tdma == 16) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); +			coex_dm->tdma_adj_type = 12; +		} +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 1) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 2); +				coex_dm->tdma_adj_type = 2; +			} else if (coex_dm->cur_ps_tdma == 2) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +			} else if (coex_dm->cur_ps_tdma == 3) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 4); +				coex_dm->tdma_adj_type = 4; +			} else if (coex_dm->cur_ps_tdma == 9) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 10); +				coex_dm->tdma_adj_type = 10; +			} else if (coex_dm->cur_ps_tdma == 10) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +			} else if (coex_dm->cur_ps_tdma == 11) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 12); +				coex_dm->tdma_adj_type = 12; +			} +		} else if (result == 1) { +			if (coex_dm->cur_ps_tdma == 4) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +			} else if (coex_dm->cur_ps_tdma == 3) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 2); +				coex_dm->tdma_adj_type = 2; +			} else if (coex_dm->cur_ps_tdma == 2) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 2); +				coex_dm->tdma_adj_type = 2; +			} else if (coex_dm->cur_ps_tdma == 12) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +			} else if (coex_dm->cur_ps_tdma == 11) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 10); +				coex_dm->tdma_adj_type = 10; +			} else if (coex_dm->cur_ps_tdma == 10) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 10); +				coex_dm->tdma_adj_type = 10; +			} +		} +	} +} + +static void set_tdma_int3(struct btc_coexist *btcoexist, bool tx_pause, +			  s32 result) +{ +	/* Set PS TDMA for max interval == 3 */ +	if (tx_pause) { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 1\n"); +		if (coex_dm->cur_ps_tdma == 1) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 2) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 3) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 7); +			coex_dm->tdma_adj_type = 7; +		} else if (coex_dm->cur_ps_tdma == 4) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); +			coex_dm->tdma_adj_type = 8; +		} else if (coex_dm->cur_ps_tdma == 9) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 10) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 11) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); +			coex_dm->tdma_adj_type = 15; +		} else if (coex_dm->cur_ps_tdma == 12) { +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 16); +			coex_dm->tdma_adj_type = 16; +		} +		if (result == -1) { +			if (coex_dm->cur_ps_tdma == 5) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 8); +				coex_dm->tdma_adj_type = 8; +			} else if (coex_dm->cur_ps_tdma == 13) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 16); +				coex_dm->tdma_adj_type = 16; +			} +		}  else if (result == 1) { +			if (coex_dm->cur_ps_tdma == 8) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 7) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 6) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 7); +				coex_dm->tdma_adj_type = 7; +			} else if (coex_dm->cur_ps_tdma == 16) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 15) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} else if (coex_dm->cur_ps_tdma == 14) { +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 15); +				coex_dm->tdma_adj_type = 15; +			} +		} +	} else { +		BTC_PRINT(BTC_MSG_ALGORITHM, +			  ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], TxPause = 0\n"); +		switch (coex_dm->cur_ps_tdma) { +		case 5: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +			break; +		case 6: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +			break; +		case 7: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); +			coex_dm->tdma_adj_type = 3; +			break; +		case 8: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); +			coex_dm->tdma_adj_type = 4; +			break; +		case 13: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +			break; +		case 14: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +			break; +		case 15: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); +			coex_dm->tdma_adj_type = 11; +			break; +		case 16: +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); +			coex_dm->tdma_adj_type = 12; +			break; +		} +		if (result == -1) { +			switch (coex_dm->cur_ps_tdma) { +			case 1: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 2: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 3: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 4); +				coex_dm->tdma_adj_type = 4; +				break; +			case 9: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +				break; +			case 10: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +				break; +			case 11: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 12); +				coex_dm->tdma_adj_type = 12; +				break; +			} +		} else if (result == 1) { +			switch (coex_dm->cur_ps_tdma) { +			case 4: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 3: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 2: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 3); +				coex_dm->tdma_adj_type = 3; +				break; +			case 12: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +				break; +			case 11: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +				break; +			case 10: +				btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, +						     true, 11); +				coex_dm->tdma_adj_type = 11; +			} +		} +	} +} + +static void btc8723b2ant_tdma_duration_adjust(struct btc_coexist *btcoexist, +					  bool sco_hid, bool tx_pause, +					  u8 max_interval) +{ +	static s32 up, dn, m, n, wait_count; +	/*0: no change, +1: increase WiFi duration, -1: decrease WiFi duration*/ +	s32 result; +	u8 retry_count = 0; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, +		  "[BTCoex], TdmaDurationAdjust()\n"); + +	if (!coex_dm->auto_tdma_adjust) { +		coex_dm->auto_tdma_adjust = true; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], first run TdmaDurationAdjust()!!\n"); +		if (sco_hid) { +			if (tx_pause) { +				if (max_interval == 1) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 13); +					coex_dm->tdma_adj_type = 13; +				} else if (max_interval == 2) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 14); +					coex_dm->tdma_adj_type = 14; +				} else if (max_interval == 3) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 15); +					coex_dm->tdma_adj_type = 15; +				} else { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 15); +					coex_dm->tdma_adj_type = 15; +				} +			} else { +				if (max_interval == 1) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 9); +					coex_dm->tdma_adj_type = 9; +				} else if (max_interval == 2) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 10); +					coex_dm->tdma_adj_type = 10; +				} else if (max_interval == 3) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 11); +					coex_dm->tdma_adj_type = 11; +				} else { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 11); +					coex_dm->tdma_adj_type = 11; +				} +			} +		} else { +			if (tx_pause) { +				if (max_interval == 1) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 5); +					coex_dm->tdma_adj_type = 5; +				} else if (max_interval == 2) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 6); +					coex_dm->tdma_adj_type = 6; +				} else if (max_interval == 3) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 7); +					coex_dm->tdma_adj_type = 7; +				} else { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 7); +					coex_dm->tdma_adj_type = 7; +				} +			} else { +				if (max_interval == 1) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 1); +					coex_dm->tdma_adj_type = 1; +				} else if (max_interval == 2) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 2); +					coex_dm->tdma_adj_type = 2; +				} else if (max_interval == 3) { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 3); +					coex_dm->tdma_adj_type = 3; +				} else { +					btc8723b2ant_ps_tdma(btcoexist, +							     NORMAL_EXEC, +							     true, 3); +					coex_dm->tdma_adj_type = 3; +				} +			} +		} + +		up = 0; +		dn = 0; +		m = 1; +		n = 3; +		result = 0; +		wait_count = 0; +	} else { +		/*accquire the BT TRx retry count from BT_Info byte2*/ +		retry_count = coex_sta->bt_retry_cnt; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], retry_count = %d\n", retry_count); +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_count=%d\n", +			  up, dn, m, n, wait_count); +		result = 0; +		wait_count++; +		 /* no retry in the last 2-second duration*/ +		if (retry_count == 0) { +			up++; +			dn--; + +			if (dn <= 0) +				dn = 0; + +			if (up >= n) { +				wait_count = 0; +				n = 3; +				up = 0; +				dn = 0; +				result = 1; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_TRACE_FW_DETAIL, +					  "[BTCoex], Increase wifi " +					  "duration!!\n"); +			} /* <=3 retry in the last 2-second duration*/ +		} else if (retry_count <= 3) { +			up--; +			dn++; + +			if (up <= 0) +				up = 0; + +			if (dn == 2) { +				if (wait_count <= 2) +					m++; +				else +					m = 1; + +				if (m >= 20) +					m = 20; + +				n = 3 * m; +				up = 0; +				dn = 0; +				wait_count = 0; +				result = -1; +				BTC_PRINT(BTC_MSG_ALGORITHM, +					  ALGO_TRACE_FW_DETAIL, +					  "[BTCoex], Decrease wifi duration " +					  "for retry_counter<3!!\n"); +			} +		} else { +			if (wait_count == 1) +				m++; +			else +				m = 1; + +			if (m >= 20) +				m = 20; + +			n = 3 * m; +			up = 0; +			dn = 0; +			wait_count = 0; +			result = -1; +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +				  "[BTCoex], Decrease wifi duration " +				  "for retry_counter>3!!\n"); +		} + +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], max Interval = %d\n", max_interval); +		if (max_interval == 1) +			set_tdma_int1(btcoexist, tx_pause, result); +		else if (max_interval == 2) +			set_tdma_int2(btcoexist, tx_pause, result); +		else if (max_interval == 3) +			set_tdma_int3(btcoexist, tx_pause, result); +	} + +	/*if current PsTdma not match with the recorded one (when scan, dhcp..), +	 *then we have to adjust it back to the previous recorded one. +	 */ +	if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) { +		bool scan = false, link = false, roam = false; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +			  "[BTCoex], PsTdma type dismatch!!!, " +			  "curPsTdma=%d, recordPsTdma=%d\n", +			  coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type); + +		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); +		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); +		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); + +		if (!scan && !link && !roam) +			btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, +					     coex_dm->tdma_adj_type); +		else +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, +				  "[BTCoex], roaming/link/scan is under" +				  " progress, will adjust next time!!!\n"); +	} +} + +/* SCO only or SCO+PAN(HS) */ +static void btc8723b2ant_action_sco(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	/*for SCO quality at 11b/g mode*/ +	if (BTC_WIFI_BW_LEGACY == wifi_bw) +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 2); +	else  /*for SCO quality & wifi performance balance at 11n mode*/ +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 8); + +	/*for voice quality */ +	btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   true, 0x4); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   true, 0x4); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   true, 0x4); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   true, 0x4); +		} +	} +} + +static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	if (BTC_WIFI_BW_LEGACY == wifi_bw) /*/for HID at 11b/g mode*/ +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); +	else  /*for HID quality & wifi performance balance at 11n mode*/ +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 9); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); +	else +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/ +static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_tdma_duration_adjust(btcoexist, false, +						  false, 1); +	else +		btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 1); + +	/* sw mechanism */ +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 2); + +	/* sw mechanism */ +	btcoexist->btc_get(btcoexist, +		BTC_GET_U4_WIFI_BW, &wifi_bw); +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 10); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1); +	else +		btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); + +	/* sw mechanism */ +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +/*PAN(HS) only*/ +static void btc8723b2ant_action_pan_hs(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +/*PAN(EDR)+A2DP*/ +static void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 12); +		if (BTC_WIFI_BW_HT40 == wifi_bw) +			btc8723b2ant_tdma_duration_adjust(btcoexist, false, +							  true, 3); +		else +			btc8723b2ant_tdma_duration_adjust(btcoexist, false, +							  false, 3); +	} else { +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); +		btc8723b2ant_tdma_duration_adjust(btcoexist, false, true, 3); +	} + +	/* sw mechanism	*/ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, false, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +		if (BTC_WIFI_BW_HT40 == wifi_bw) { +			btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, +						      3); +			btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 11); +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, +						  0xfffff, 0x780); +		} else { +			btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, +						      6); +			btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); +			btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, +						  0xfffff, 0x0); +		} +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2); +	} else { +		btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); +		btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 11); +		btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, +					  0x0); +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2); +	} + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +/* HID+A2DP+PAN(EDR) */ +static void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +						       0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +		if (BTC_WIFI_BW_HT40 == wifi_bw) +			btc8723b2ant_tdma_duration_adjust(btcoexist, true, +							  true, 2); +		else +			btc8723b2ant_tdma_duration_adjust(btcoexist, true, +							  false, 3); +	} else { +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 3); +	} + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist) +{ +	u8 wifi_rssi_state, bt_rssi_state; +	u32 wifi_bw; + +	wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, +							  0, 2, 15, 0); +	bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); + +	btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); + +	btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); + +	if (btc8723b_need_dec_pwr(btcoexist)) +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); +	else +		btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); + +	btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 7); + +	if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || +	    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, false, 2); +	else +		btc8723b2ant_tdma_duration_adjust(btcoexist, true, true, 2); + +	/* sw mechanism */ +	if (BTC_WIFI_BW_HT40 == wifi_bw) { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, true, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} else { +		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || +		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, true, false, +						   false, 0x18); +		} else { +			btc8723b2ant_sw_mechanism1(btcoexist, false, true, +						   false, false); +			btc8723b2ant_sw_mechanism2(btcoexist, false, false, +						   false, 0x18); +		} +	} +} + +static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) +{ +	u8 algorithm = 0; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +		  "[BTCoex], RunCoexistMechanism()===>\n"); + +	if (btcoexist->manual_control) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], RunCoexistMechanism(), " +			  "return for Manual CTRL <===\n"); +		return; +	} + +	if (coex_sta->under_ips) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], wifi is under IPS !!!\n"); +		return; +	} + +	algorithm = btc8723b2ant_action_algorithm(btcoexist); +	if (coex_sta->c2h_bt_inquiry_page && +	    (BT_8723B_2ANT_COEX_ALGO_PANHS != algorithm)) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BT is under inquiry/page scan !!\n"); +		btc8723b2ant_action_bt_inquiry(btcoexist); +		return; +	} else { +		if (coex_dm->need_recover_0x948) { +			coex_dm->need_recover_0x948 = false; +			btcoexist->btc_write_2byte(btcoexist, 0x948, +						   coex_dm->backup_0x948); +		} +	} + +	coex_dm->cur_algorithm = algorithm; +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, "[BTCoex], Algorithm = %d\n", +		  coex_dm->cur_algorithm); + +	if (btc8723b2ant_is_common_action(btcoexist)) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], Action 2-Ant common.\n"); +		coex_dm->auto_tdma_adjust = false; +	} else { +		if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], preAlgorithm=%d, " +				  "curAlgorithm=%d\n", coex_dm->pre_algorithm, +				  coex_dm->cur_algorithm); +			coex_dm->auto_tdma_adjust = false; +		} +		switch (coex_dm->cur_algorithm) { +		case BT_8723B_2ANT_COEX_ALGO_SCO: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, algorithm = SCO.\n"); +			btc8723b2ant_action_sco(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_HID: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, algorithm = HID.\n"); +			btc8723b2ant_action_hid(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_A2DP: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = A2DP.\n"); +			btc8723b2ant_action_a2dp(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = A2DP+PAN(HS).\n"); +			btc8723b2ant_action_a2dp_pan_hs(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_PANEDR: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = PAN(EDR).\n"); +			btc8723b2ant_action_pan_edr(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_PANHS: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = HS mode.\n"); +			btc8723b2ant_action_pan_hs(btcoexist); +				break; +		case BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = PAN+A2DP.\n"); +			btc8723b2ant_action_pan_edr_a2dp(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_PANEDR_HID: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = PAN(EDR)+HID.\n"); +			btc8723b2ant_action_pan_edr_hid(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = HID+A2DP+PAN.\n"); +			btc8723b2ant_action_hid_a2dp_pan_edr(btcoexist); +			break; +		case BT_8723B_2ANT_COEX_ALGO_HID_A2DP: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = HID+A2DP.\n"); +			btc8723b2ant_action_hid_a2dp(btcoexist); +			break; +		default: +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], Action 2-Ant, " +				  "algorithm = coexist All Off!!\n"); +			btc8723b2ant_coex_alloff(btcoexist); +			break; +		} +		coex_dm->pre_algorithm = coex_dm->cur_algorithm; +	} +} + + + +/********************************************************************* + *  work around function start with wa_btc8723b2ant_ + *********************************************************************/ +/********************************************************************* + *  extern function start with EXbtc8723b2ant_ + *********************************************************************/ +void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist) +{ +	struct btc_board_info *board_info = &btcoexist->board_info; +	u32 u32tmp = 0, fw_ver; +	u8 u8tmp = 0; +	u8 h2c_parameter[2] = {0}; + + +	BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +		  "[BTCoex], 2Ant Init HW Config!!\n"); + +	/* backup rf 0x1e value */ +	coex_dm->bt_rf0x1e_backup = btcoexist->btc_get_rf_reg(btcoexist, +							      BTC_RF_A, 0x1e, +							      0xfffff); + +	/* 0x4c[23]=0, 0x4c[24]=1  Antenna control by WL/BT */ +	u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); +	u32tmp &= ~BIT23; +	u32tmp |= BIT24; +	btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); + +	btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff); +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3); +	btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77); +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1); + +	/* Antenna switch control parameter */ +	/* btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555);*/ + +	/*Force GNT_BT to low*/ +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0); +	btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); + +	/* 0x790[5:0]=0x5 */ +	u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); +	u8tmp &= 0xc0; +	u8tmp |= 0x5; +	btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); + + +	/*Antenna config	*/ +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); + + /*ext switch for fw ver < 0xc */ +	if (fw_ver < 0xc00) { +		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { +			btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, +							   0x3, 0x1); +			/*Main Ant to  BT for IPS case 0x4c[23]=1*/ +			btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, +							   0x1); + +			/*tell firmware "no antenna inverse"*/ +			h2c_parameter[0] = 0; +			h2c_parameter[1] = 1;  /* ext switch type */ +			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, +						h2c_parameter); +		} else { +			btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, +							   0x3, 0x2); +			/*Aux Ant to  BT for IPS case 0x4c[23]=1*/ +			btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, +							   0x0); + +			/*tell firmware "antenna inverse"*/ +			h2c_parameter[0] = 1; +			h2c_parameter[1] = 1;  /*ext switch type*/ +			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, +						h2c_parameter); +		} +	} else { +		/*ext switch always at s1 (if exist) */ +		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, 0x3, 0x1); +		/*Main Ant to  BT for IPS case 0x4c[23]=1*/ +		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, 0x1); + +		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { +			/*tell firmware "no antenna inverse"*/ +			h2c_parameter[0] = 0; +			h2c_parameter[1] = 0;  /*ext switch type*/ +			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, +						h2c_parameter); +		} else { +			/*tell firmware "antenna inverse"*/ +			h2c_parameter[0] = 1; +			h2c_parameter[1] = 0;  /*ext switch type*/ +			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, +						h2c_parameter); +		} +	} + +	/* PTA parameter */ +	btc8723b_coex_tbl_type(btcoexist, FORCE_EXEC, 0); + +	/* Enable counter statistics */ +	/*0x76e[3] =1, WLAN_Act control by PTA*/ +	btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); +	btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); +	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); +} + +void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) +{ +	BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +		  "[BTCoex], Coex Mechanism Init!!\n"); +	btc8723b2ant_init_coex_dm(btcoexist); +} + +void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) +{ +	struct btc_board_info *board_info = &btcoexist->board_info; +	struct btc_stack_info *stack_info = &btcoexist->stack_info; +	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; +	u8 *cli_buf = btcoexist->cli_buf; +	u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0; +	u32 u32tmp[4]; +	bool roam = false, scan = false; +	bool link = false, wifi_under_5g = false; +	bool bt_hs_on = false, wifi_busy = false; +	s32 wifi_rssi = 0, bt_hs_rssi = 0; +	u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck; +	u8 wifi_dot11_chnl, wifi_hs_chnl; +	u32 fw_ver = 0, bt_patch_ver = 0; + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n ============[BT Coexist info]============"); +	CL_PRINTF(cli_buf); + +	if (btcoexist->manual_control) { +		CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +			   "\r\n ==========[Under Manual Control]============"); +		CL_PRINTF(cli_buf); +		CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +			   "\r\n =========================================="); +		CL_PRINTF(cli_buf); +	} + +	if (!board_info->bt_exist) { +		CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!"); +		CL_PRINTF(cli_buf); +		return; +	} + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", +		   "Ant PG number/ Ant mechanism:", +		   board_info->pg_ant_num, board_info->btdm_ant_num); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", +		   "BT stack/ hci ext ver", +		   ((stack_info->profile_notified) ? "Yes" : "No"), +		   stack_info->hci_version); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", +		   "CoexVer/ FwVer/ PatchVer", +		   glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, +		   fw_ver, bt_patch_ver, bt_patch_ver); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); +	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, +			   &wifi_dot11_chnl); +	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", +		   "Dot11 channel / HsChnl(HsMode)", +		   wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", +		   "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0], +		   coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); +	btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", +		   "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", +		   "Wifi link/ roam/ scan", link, roam, scan); +	CL_PRINTF(cli_buf); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); +	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, +			   &wifi_traffic_dir); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", +		   "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), +		   ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : +		   (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), +		   ((!wifi_busy) ? "idle" : +		   ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? +		   "uplink" : "downlink"))); +	CL_PRINTF(cli_buf); + +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", +		   "SCO/HID/PAN/A2DP", +		   bt_link_info->sco_exist, bt_link_info->hid_exist, +		   bt_link_info->pan_exist, bt_link_info->a2dp_exist); +	CL_PRINTF(cli_buf); +	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO); + +	bt_info_ext = coex_sta->bt_info_ext; +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", +		   "BT Info A2DP rate", +		   (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); +	CL_PRINTF(cli_buf); + +	for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) { +		if (coex_sta->bt_info_c2h_cnt[i]) { +			CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +				   "\r\n %-35s = %02x %02x %02x " +				   "%02x %02x %02x %02x(%d)", +				   glbt_info_src_8723b_2ant[i], +				   coex_sta->bt_info_c2h[i][0], +				   coex_sta->bt_info_c2h[i][1], +				   coex_sta->bt_info_c2h[i][2], +				   coex_sta->bt_info_c2h[i][3], +				   coex_sta->bt_info_c2h[i][4], +				   coex_sta->bt_info_c2h[i][5], +				   coex_sta->bt_info_c2h[i][6], +				   coex_sta->bt_info_c2h_cnt[i]); +			CL_PRINTF(cli_buf); +		} +	} + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s", +		   "PS state, IPS/LPS", +		   ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), +		   ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); +	CL_PRINTF(cli_buf); +	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); + +	/* Sw mechanism	*/ +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s", "============[Sw mechanism]============"); +	CL_PRINTF(cli_buf); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", +		   "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink, +		   coex_dm->cur_low_penalty_ra, coex_dm->limited_dig); +	CL_PRINTF(cli_buf); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", +		   "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", +		   coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, +		   coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); +	CL_PRINTF(cli_buf); + +	/* Fw mechanism	*/ +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", +		   "============[Fw mechanism]============"); +	CL_PRINTF(cli_buf); + +	ps_tdma_case = coex_dm->cur_ps_tdma; +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", +		   "PS TDMA", coex_dm->ps_tdma_para[0], +		   coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], +		   coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], +		   ps_tdma_case, coex_dm->auto_tdma_adjust); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", +		   "DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr, +		   coex_dm->cur_ignore_wlan_act); +	CL_PRINTF(cli_buf); + +	/* Hw setting */ +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", +		   "============[Hw setting]============"); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", +		   "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup); +	CL_PRINTF(cli_buf); + +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", +		   "0x778/0x880[29:25]", u8tmp[0], +		   (u32tmp[0]&0x3e000000) >> 25); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); +	u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", +		   "0x948/ 0x67[5] / 0x765", +		   u32tmp[0], ((u8tmp[0]&0x20) >> 5), u8tmp[1]); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); +	u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); +	u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", +		   "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", +		   u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3); +	CL_PRINTF(cli_buf); + + +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); +	u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); +	u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", +		   "0x38[11]/0x40/0x4c[24:23]/0x64[0]", +		   ((u8tmp[0] & 0x8)>>3), u8tmp[1], +		   ((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", +		   "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", +		   "0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); +	u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); +	u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8); +	u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0); + +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); +	u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); + +	fa_ofdm = ((u32tmp[0]&0xffff0000) >> 16) + +		  ((u32tmp[1]&0xffff0000) >> 16) + +		   (u32tmp[1] & 0xffff) + +		   (u32tmp[2] & 0xffff) + +		  ((u32tmp[3]&0xffff0000) >> 16) + +		   (u32tmp[3] & 0xffff); +	fa_cck = (u8tmp[0] << 8) + u8tmp[1]; + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", +		   "OFDM-CCA/OFDM-FA/CCK-FA", +		   u32tmp[0]&0xffff, fa_ofdm, fa_cck); +	CL_PRINTF(cli_buf); + +	u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); +	u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); +	u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); +	u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, +		   "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", +		   "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", +		   u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]); +	CL_PRINTF(cli_buf); + +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", +		   "0x770(high-pri rx/tx)", +		   coex_sta->high_priority_rx, coex_sta->high_priority_tx); +	CL_PRINTF(cli_buf); +	CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", +		   "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, +		   coex_sta->low_priority_tx); +	CL_PRINTF(cli_buf); +#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) +	btc8723b2ant_monitor_bt_ctr(btcoexist); +#endif +	btcoexist->btc_disp_dbg_msg(btcoexist, +	BTC_DBG_DISP_COEX_STATISTICS); +} + + +void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ +	if (BTC_IPS_ENTER == type) { +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], IPS ENTER notify\n"); +		coex_sta->under_ips = true; +		btc8723b2ant_coex_alloff(btcoexist); +	} else if (BTC_IPS_LEAVE == type) { +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], IPS LEAVE notify\n"); +		coex_sta->under_ips = false; +	} +} + +void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ +	if (BTC_LPS_ENABLE == type) { +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], LPS ENABLE notify\n"); +		coex_sta->under_lps = true; +	} else if (BTC_LPS_DISABLE == type) { +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], LPS DISABLE notify\n"); +		coex_sta->under_lps = false; +	} +} + +void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ +	if (BTC_SCAN_START == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], SCAN START notify\n"); +	else if (BTC_SCAN_FINISH == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], SCAN FINISH notify\n"); +} + +void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) +{ +	if (BTC_ASSOCIATE_START == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], CONNECT START notify\n"); +	else if (BTC_ASSOCIATE_FINISH == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], CONNECT FINISH notify\n"); +} + +void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, +					    u8 type) +{ +	u8 h2c_parameter[3] = {0}; +	u32 wifi_bw; +	u8 wifi_central_chnl; + +	if (BTC_MEDIA_CONNECT == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], MEDIA connect notify\n"); +	else +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], MEDIA disconnect notify\n"); + +	/* only 2.4G we need to inform bt the chnl mask */ +	btcoexist->btc_get(btcoexist, +		BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl); +	if ((BTC_MEDIA_CONNECT == type) && +	    (wifi_central_chnl <= 14)) { +		h2c_parameter[0] = 0x1; +		h2c_parameter[1] = wifi_central_chnl; +		btcoexist->btc_get(btcoexist, +			BTC_GET_U4_WIFI_BW, &wifi_bw); +		if (BTC_WIFI_BW_HT40 == wifi_bw) +			h2c_parameter[2] = 0x30; +		else +			h2c_parameter[2] = 0x20; +	} + +	coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; +	coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; +	coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, +		  "[BTCoex], FW write 0x66=0x%x\n", +		  h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | +		  h2c_parameter[2]); + +	btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); +} + +void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, +					      u8 type) +{ +	if (type == BTC_PACKET_DHCP) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex], DHCP Packet notify\n"); +} + +void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, +				       u8 *tmpbuf, u8 length) +{ +	u8 bt_info = 0; +	u8 i, rsp_source = 0; +	bool bt_busy = false, limited_dig = false; +	bool wifi_connected = false; + +	coex_sta->c2h_bt_info_req_sent = false; + +	rsp_source = tmpbuf[0]&0xf; +	if (rsp_source >= BT_INFO_SRC_8723B_2ANT_MAX) +		rsp_source = BT_INFO_SRC_8723B_2ANT_WIFI_FW; +	coex_sta->bt_info_c2h_cnt[rsp_source]++; + +	BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +		  "[BTCoex], Bt info[%d], length=%d, hex data=[", +		  rsp_source, length); +	for (i = 0; i < length; i++) { +		coex_sta->bt_info_c2h[rsp_source][i] = tmpbuf[i]; +		if (i == 1) +			bt_info = tmpbuf[i]; +		if (i == length-1) +			BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +				  "0x%02x]\n", tmpbuf[i]); +		else +			BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +				  "0x%02x, ", tmpbuf[i]); +	} + +	if (btcoexist->manual_control) { +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), " +			  "return for Manual CTRL<===\n"); +		return; +	} + +	if (BT_INFO_SRC_8723B_2ANT_WIFI_FW != rsp_source) { +		coex_sta->bt_retry_cnt =	/* [3:0]*/ +			coex_sta->bt_info_c2h[rsp_source][2] & 0xf; + +		coex_sta->bt_rssi = +			coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; + +		coex_sta->bt_info_ext = +			coex_sta->bt_info_c2h[rsp_source][4]; + +		/* Here we need to resend some wifi info to BT +		 * because bt is reset and loss of the info. +		 */ +		if ((coex_sta->bt_info_ext & BIT1)) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], BT ext info bit1 check," +				  " send wifi BW&Chnl to BT!!\n"); +			btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, +					   &wifi_connected); +			if (wifi_connected) +				btc8723b_med_stat_notify(btcoexist, +							 BTC_MEDIA_CONNECT); +			else +				btc8723b_med_stat_notify(btcoexist, +							 BTC_MEDIA_DISCONNECT); +		} + +		if ((coex_sta->bt_info_ext & BIT3)) { +			BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +				  "[BTCoex], BT ext info bit3 check, " +				  "set BT NOT to ignore Wlan active!!\n"); +			btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, +						     false); +		} else { +			/* BT already NOT ignore Wlan active, do nothing here.*/ +		} +#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 0) +		if ((coex_sta->bt_info_ext & BIT4)) { +			/* BT auto report already enabled, do nothing*/ +		} else { +			btc8723b2ant_bt_auto_report(btcoexist, FORCE_EXEC, +						    true); +		} +#endif +	} + +	/* check BIT2 first ==> check if bt is under inquiry or page scan*/ +	if (bt_info & BT_INFO_8723B_2ANT_B_INQ_PAGE) +		coex_sta->c2h_bt_inquiry_page = true; +	else +		coex_sta->c2h_bt_inquiry_page = false; + +	/* set link exist status*/ +	if (!(bt_info & BT_INFO_8723B_2ANT_B_CONNECTION)) { +		coex_sta->bt_link_exist = false; +		coex_sta->pan_exist = false; +		coex_sta->a2dp_exist = false; +		coex_sta->hid_exist = false; +		coex_sta->sco_exist = false; +	} else { /*  connection exists */ +		coex_sta->bt_link_exist = true; +		if (bt_info & BT_INFO_8723B_2ANT_B_FTP) +			coex_sta->pan_exist = true; +		else +			coex_sta->pan_exist = false; +		if (bt_info & BT_INFO_8723B_2ANT_B_A2DP) +			coex_sta->a2dp_exist = true; +		else +			coex_sta->a2dp_exist = false; +		if (bt_info & BT_INFO_8723B_2ANT_B_HID) +			coex_sta->hid_exist = true; +		else +			coex_sta->hid_exist = false; +		if (bt_info & BT_INFO_8723B_2ANT_B_SCO_ESCO) +			coex_sta->sco_exist = true; +		else +			coex_sta->sco_exist = false; +	} + +	btc8723b2ant_update_bt_link_info(btcoexist); + +	if (!(bt_info & BT_INFO_8723B_2ANT_B_CONNECTION)) { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), " +			  "BT Non-Connected idle!!!\n"); +	/* connection exists but no busy */ +	} else if (bt_info == BT_INFO_8723B_2ANT_B_CONNECTION) { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); +	} else if ((bt_info & BT_INFO_8723B_2ANT_B_SCO_ESCO) || +		   (bt_info & BT_INFO_8723B_2ANT_B_SCO_BUSY)) { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_SCO_BUSY; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); +	} else if (bt_info & BT_INFO_8723B_2ANT_B_ACL_BUSY) { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_ACL_BUSY; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); +	} else { +		coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_MAX; +		BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +			  "[BTCoex], BtInfoNotify(), " +			  "BT Non-Defined state!!!\n"); +	} + +	if ((BT_8723B_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || +	    (BT_8723B_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || +	    (BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) { +		bt_busy = true; +		limited_dig = true; +	} else { +		bt_busy = false; +		limited_dig = false; +	} + +	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); + +	coex_dm->limited_dig = limited_dig; +	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig); + +	btc8723b2ant_run_coexist_mechanism(btcoexist); +} + +void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist, +					       u8 type) +{ +	if (BTC_STACK_OP_INQ_PAGE_PAIR_START == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex],StackOP Inquiry/page/pair start notify\n"); +	else if (BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type) +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, +			  "[BTCoex],StackOP Inquiry/page/pair finish notify\n"); +} + +void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist) +{ +	BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n"); + +	btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); +	btc8723b_med_stat_notify(btcoexist, BTC_MEDIA_DISCONNECT); +} + +void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist) +{ +	struct btc_board_info *board_info = &btcoexist->board_info; +	struct btc_stack_info *stack_info = &btcoexist->stack_info; +	static u8 dis_ver_info_cnt; +	u32 fw_ver = 0, bt_patch_ver = 0; + +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +		  "[BTCoex], ==========================" +		  "Periodical===========================\n"); + +	if (dis_ver_info_cnt <= 5) { +		dis_ver_info_cnt += 1; +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], ****************************" +			  "************************************\n"); +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], Ant PG Num/ Ant Mech/ " +			  "Ant Pos = %d/ %d/ %d\n", board_info->pg_ant_num, +			  board_info->btdm_ant_num, board_info->btdm_ant_pos); +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], BT stack/ hci ext ver = %s / %d\n", +			  ((stack_info->profile_notified) ? "Yes" : "No"), +			  stack_info->hci_version); +		btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, +				   &bt_patch_ver); +		btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], CoexVer/ FwVer/ PatchVer = " +			  "%d_%x/ 0x%x/ 0x%x(%d)\n", +			  glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, +			  fw_ver, bt_patch_ver, bt_patch_ver); +		BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, +			  "[BTCoex], *****************************" +			  "***********************************\n"); +	} + +#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 0) +	btc8723b2ant_query_bt_info(btcoexist); +	btc8723b2ant_monitor_bt_ctr(btcoexist); +	btc8723b2ant_monitor_bt_enable_disable(btcoexist); +#else +	if (btc8723b2ant_is_wifi_status_changed(btcoexist) || +	    coex_dm->auto_tdma_adjust) +		btc8723b2ant_run_coexist_mechanism(btcoexist); +#endif +} diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h new file mode 100644 index 00000000000..e0ad8e545f8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h @@ -0,0 +1,173 @@ +/****************************************************************************** + * + * Copyright(c) 2012  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 _HAL8723B_2_ANT +#define _HAL8723B_2_ANT + +/************************************************************************ + * The following is for 8723B 2Ant BT Co-exist definition + ************************************************************************/ +#define	BT_AUTO_REPORT_ONLY_8723B_2ANT			1 + +#define	BT_INFO_8723B_2ANT_B_FTP			BIT7 +#define	BT_INFO_8723B_2ANT_B_A2DP			BIT6 +#define	BT_INFO_8723B_2ANT_B_HID			BIT5 +#define	BT_INFO_8723B_2ANT_B_SCO_BUSY			BIT4 +#define	BT_INFO_8723B_2ANT_B_ACL_BUSY			BIT3 +#define	BT_INFO_8723B_2ANT_B_INQ_PAGE			BIT2 +#define	BT_INFO_8723B_2ANT_B_SCO_ESCO			BIT1 +#define	BT_INFO_8723B_2ANT_B_CONNECTION			BIT0 + +#define BTC_RSSI_COEX_THRESH_TOL_8723B_2ANT		2 + +enum BT_INFO_SRC_8723B_2ANT { +	BT_INFO_SRC_8723B_2ANT_WIFI_FW			= 0x0, +	BT_INFO_SRC_8723B_2ANT_BT_RSP			= 0x1, +	BT_INFO_SRC_8723B_2ANT_BT_ACTIVE_SEND		= 0x2, +	BT_INFO_SRC_8723B_2ANT_MAX +}; + +enum BT_8723B_2ANT_BT_STATUS { +	BT_8723B_2ANT_BT_STATUS_NON_CONNECTED_IDLE	= 0x0, +	BT_8723B_2ANT_BT_STATUS_CONNECTED_IDLE		= 0x1, +	BT_8723B_2ANT_BT_STATUS_INQ_PAGE		= 0x2, +	BT_8723B_2ANT_BT_STATUS_ACL_BUSY		= 0x3, +	BT_8723B_2ANT_BT_STATUS_SCO_BUSY		= 0x4, +	BT_8723B_2ANT_BT_STATUS_ACL_SCO_BUSY		= 0x5, +	BT_8723B_2ANT_BT_STATUS_MAX +}; + +enum BT_8723B_2ANT_COEX_ALGO { +	BT_8723B_2ANT_COEX_ALGO_UNDEFINED		= 0x0, +	BT_8723B_2ANT_COEX_ALGO_SCO			= 0x1, +	BT_8723B_2ANT_COEX_ALGO_HID			= 0x2, +	BT_8723B_2ANT_COEX_ALGO_A2DP			= 0x3, +	BT_8723B_2ANT_COEX_ALGO_A2DP_PANHS		= 0x4, +	BT_8723B_2ANT_COEX_ALGO_PANEDR			= 0x5, +	BT_8723B_2ANT_COEX_ALGO_PANHS			= 0x6, +	BT_8723B_2ANT_COEX_ALGO_PANEDR_A2DP		= 0x7, +	BT_8723B_2ANT_COEX_ALGO_PANEDR_HID		= 0x8, +	BT_8723B_2ANT_COEX_ALGO_HID_A2DP_PANEDR		= 0x9, +	BT_8723B_2ANT_COEX_ALGO_HID_A2DP		= 0xa, +	BT_8723B_2ANT_COEX_ALGO_MAX			= 0xb, +}; + +struct coex_dm_8723b_2ant { +	/* fw mechanism */ +	bool pre_dec_bt_pwr; +	bool cur_dec_bt_pwr; +	u8 pre_fw_dac_swing_lvl; +	u8 cur_fw_dac_swing_lvl; +	bool cur_ignore_wlan_act; +	bool pre_ignore_wlan_act; +	u8 pre_ps_tdma; +	u8 cur_ps_tdma; +	u8 ps_tdma_para[5]; +	u8 tdma_adj_type; +	bool reset_tdma_adjust; +	bool auto_tdma_adjust; +	bool pre_ps_tdma_on; +	bool cur_ps_tdma_on; +	bool pre_bt_auto_report; +	bool cur_bt_auto_report; + +	/* sw mechanism */ +	bool pre_rf_rx_lpf_shrink; +	bool cur_rf_rx_lpf_shrink; +	u32 bt_rf0x1e_backup; +	bool pre_low_penalty_ra; +	bool cur_low_penalty_ra; +	bool pre_dac_swing_on; +	u32 pre_dac_swing_lvl; +	bool cur_dac_swing_on; +	u32 cur_dac_swing_lvl; +	bool pre_adc_back_off; +	bool cur_adc_back_off; +	bool pre_agc_table_en; +	bool cur_agc_table_en; +	u32 pre_val0x6c0; +	u32 cur_val0x6c0; +	u32 pre_val0x6c4; +	u32 cur_val0x6c4; +	u32 pre_val0x6c8; +	u32 cur_val0x6c8; +	u8 pre_val0x6cc; +	u8 cur_val0x6cc; +	bool limited_dig; + +	/* algorithm related */ +	u8 pre_algorithm; +	u8 cur_algorithm; +	u8 bt_status; +	u8 wifi_chnl_info[3]; + +	bool need_recover_0x948; +	u16 backup_0x948; +}; + +struct coex_sta_8723b_2ant { +	bool bt_link_exist; +	bool sco_exist; +	bool a2dp_exist; +	bool hid_exist; +	bool pan_exist; + +	bool under_lps; +	bool under_ips; +	u32 high_priority_tx; +	u32 high_priority_rx; +	u32 low_priority_tx; +	u32 low_priority_rx; +	u8 bt_rssi; +	u8 pre_bt_rssi_state; +	u8 pre_wifi_rssi_state[4]; +	bool c2h_bt_info_req_sent; +	u8 bt_info_c2h[BT_INFO_SRC_8723B_2ANT_MAX][10]; +	u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_2ANT_MAX]; +	bool c2h_bt_inquiry_page; +	u8 bt_retry_cnt; +	u8 bt_info_ext; +}; + +/********************************************************************* + * The following is interface which will notify coex module. + *********************************************************************/ +void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist); +void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist); +void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type); +void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type); +void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type); +void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type); +void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, u8 type); +void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, +					      u8 type); +void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, +				       u8 *tmpbuf, u8 length); +void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist, +					       u8 type); +void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist); +void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist); +void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist); + +#endif diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c new file mode 100644 index 00000000000..33da3dfcfa4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c @@ -0,0 +1,1001 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved. + * + * 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 "halbt_precomp.h" + +/*********************************************** + *		Global variables + ***********************************************/ + +struct btc_coexist gl_bt_coexist; + +u32 btc_dbg_type[BTC_MSG_MAX]; +static u8 btc_dbg_buf[100]; + +/*************************************************** + *		Debug related function + ***************************************************/ +static bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist) +{ +	if (!btcoexist->binded || NULL == btcoexist->adapter) +		return false; + +	return true; +} + +static bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv) +{ +	if (rtlpriv->link_info.busytraffic) +		return true; +	else +		return false; +} + +static void halbtc_dbg_init(void) +{ +	u8 i; + +	for (i = 0; i < BTC_MSG_MAX; i++) +		btc_dbg_type[i] = 0; + +	btc_dbg_type[BTC_MSG_INTERFACE] = +/*			INTF_INIT				| */ +/*			INTF_NOTIFY				| */ +			0; + +	btc_dbg_type[BTC_MSG_ALGORITHM] = +/*			ALGO_BT_RSSI_STATE			| */ +/*			ALGO_WIFI_RSSI_STATE			| */ +/*			ALGO_BT_MONITOR				| */ +/*			ALGO_TRACE				| */ +/*			ALGO_TRACE_FW				| */ +/*			ALGO_TRACE_FW_DETAIL			| */ +/*			ALGO_TRACE_FW_EXEC			| */ +/*			ALGO_TRACE_SW				| */ +/*			ALGO_TRACE_SW_DETAIL			| */ +/*			ALGO_TRACE_SW_EXEC			| */ +			0; +} + +static bool halbtc_is_bt40(struct rtl_priv *adapter) +{ +	struct rtl_priv *rtlpriv = adapter; +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	bool is_ht40 = true; +	enum ht_channel_width bw = rtlphy->current_chan_bw; + +	if (bw == HT_CHANNEL_WIDTH_20) +		is_ht40 = false; +	else if (bw == HT_CHANNEL_WIDTH_20_40) +		is_ht40 = true; + +	return is_ht40; +} + +static bool halbtc_legacy(struct rtl_priv *adapter) +{ +	struct rtl_priv *rtlpriv = adapter; +	struct rtl_mac *mac = rtl_mac(rtlpriv); + +	bool is_legacy = false; + +	if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_B)) +		is_legacy = true; + +	return is_legacy; +} + +bool halbtc_is_wifi_uplink(struct rtl_priv *adapter) +{ +	struct rtl_priv *rtlpriv = adapter; + +	if (rtlpriv->link_info.tx_busy_traffic) +		return true; +	else +		return false; +} + +static u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = +		(struct rtl_priv *)btcoexist->adapter; +	u32 wifi_bw = BTC_WIFI_BW_HT20; + +	if (halbtc_is_bt40(rtlpriv)) { +		wifi_bw = BTC_WIFI_BW_HT40; +	} else { +		if (halbtc_legacy(rtlpriv)) +			wifi_bw = BTC_WIFI_BW_LEGACY; +		else +			wifi_bw = BTC_WIFI_BW_HT20; +	} +	return wifi_bw; +} + +static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_phy	*rtlphy = &(rtlpriv->phy); +	u8 chnl = 1; + +	if (rtlphy->current_channel != 0) +		chnl = rtlphy->current_channel; +	BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, +		  "static halbtc_get_wifi_central_chnl:%d\n", chnl); +	return chnl; +} + +static void halbtc_leave_lps(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv; +	struct rtl_ps_ctl *ppsc; +	bool ap_enable = false; + +	rtlpriv = btcoexist->adapter; +	ppsc = rtl_psc(rtlpriv); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, +			   &ap_enable); + +	if (ap_enable) { +		pr_info("halbtc_leave_lps()<--dont leave lps under AP mode\n"); +		return; +	} + +	btcoexist->bt_info.bt_ctrl_lps = true; +	btcoexist->bt_info.bt_lps_on = false; +} + +static void halbtc_enter_lps(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv; +	struct rtl_ps_ctl *ppsc; +	bool ap_enable = false; + +	rtlpriv = btcoexist->adapter; +	ppsc = rtl_psc(rtlpriv); + +	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, +			   &ap_enable); + +	if (ap_enable) { +		pr_info("halbtc_enter_lps()<--dont enter lps under AP mode\n"); +		return; +	} + +	btcoexist->bt_info.bt_ctrl_lps = true; +	btcoexist->bt_info.bt_lps_on = false; +} + +static void halbtc_normal_lps(struct btc_coexist *btcoexist) +{ +	if (btcoexist->bt_info.bt_ctrl_lps) { +		btcoexist->bt_info.bt_lps_on = false; +		btcoexist->bt_info.bt_ctrl_lps = false; +	} +} + +static void halbtc_leave_low_power(void) +{ +} + +static void halbtc_nomal_low_power(void) +{ +} + +static void halbtc_disable_low_power(void) +{ +} + +static void halbtc_aggregation_check(void) +{ +} + +static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist) +{ +	return 0; +} + +static s32 halbtc_get_wifi_rssi(struct rtl_priv *adapter) +{ +	struct rtl_priv *rtlpriv = adapter; +	s32	undec_sm_pwdb = 0; + +	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) +		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; +	else /* associated entry pwdb */ +		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; +	return undec_sm_pwdb; +} + +static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist; +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_mac *mac = rtl_mac(rtlpriv); +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	bool *bool_tmp = (bool *)out_buf; +	int *s32_tmp = (int *)out_buf; +	u32 *u32_tmp = (u32 *)out_buf; +	u8 *u8_tmp = (u8 *)out_buf; +	bool tmp = false; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return false; + +	switch (get_type) { +	case BTC_GET_BL_HS_OPERATION: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_HS_CONNECTING: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_CONNECTED: +		if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) +			tmp = true; +		*bool_tmp = tmp; +		break; +	case BTC_GET_BL_WIFI_BUSY: +		if (halbtc_is_wifi_busy(rtlpriv)) +			*bool_tmp = true; +		else +			*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_SCAN: +		if (mac->act_scanning) +			*bool_tmp = true; +		else +			*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_LINK: +		if (mac->link_state == MAC80211_LINKING) +			*bool_tmp = true; +		else +			*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_ROAM:	/*TODO*/ +		if (mac->link_state == MAC80211_LINKING) +			*bool_tmp = true; +		else +			*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_4_WAY_PROGRESS:	/*TODO*/ +			*bool_tmp = false; + +		break; +	case BTC_GET_BL_WIFI_UNDER_5G: +		*bool_tmp = false; /*TODO*/ + +	case BTC_GET_BL_WIFI_DHCP:	/*TODO*/ +		break; +	case BTC_GET_BL_WIFI_SOFTAP_IDLE: +		*bool_tmp = true; +		break; +	case BTC_GET_BL_WIFI_SOFTAP_LINKING: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_IN_EARLY_SUSPEND: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_AP_MODE_ENABLE: +		*bool_tmp = false; +		break; +	case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION: +		if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm) +			*bool_tmp = false; +		else +			*bool_tmp = true; +		break; +	case BTC_GET_BL_WIFI_UNDER_B_MODE: +		*bool_tmp = false; /*TODO*/ +		break; +	case BTC_GET_BL_EXT_SWITCH: +		*bool_tmp = false; +		break; +	case BTC_GET_S4_WIFI_RSSI: +		*s32_tmp = halbtc_get_wifi_rssi(rtlpriv); +		break; +	case BTC_GET_S4_HS_RSSI:	/*TODO*/ +		*s32_tmp = halbtc_get_wifi_rssi(rtlpriv); +		break; +	case BTC_GET_U4_WIFI_BW: +		*u32_tmp = halbtc_get_wifi_bw(btcoexist); +		break; +	case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION: +		if (halbtc_is_wifi_uplink(rtlpriv)) +			*u32_tmp = BTC_WIFI_TRAFFIC_TX; +		else +			*u32_tmp = BTC_WIFI_TRAFFIC_RX; +		break; +	case BTC_GET_U4_WIFI_FW_VER: +		*u32_tmp = rtlhal->fw_version; +		break; +	case BTC_GET_U4_BT_PATCH_VER: +		*u32_tmp = halbtc_get_bt_patch_version(btcoexist); +		break; +	case BTC_GET_U1_WIFI_DOT11_CHNL: +		*u8_tmp = rtlphy->current_channel; +		break; +	case BTC_GET_U1_WIFI_CENTRAL_CHNL: +		*u8_tmp = halbtc_get_wifi_central_chnl(btcoexist); +		break; +	case BTC_GET_U1_WIFI_HS_CHNL: +		*u8_tmp = 1;/*BT_OperateChnl(rtlpriv);*/ +		break; +	case BTC_GET_U1_MAC_PHY_MODE: +		*u8_tmp = BTC_MP_UNKNOWN; +		break; + +		/************* 1Ant **************/ +	case BTC_GET_U1_LPS_MODE: +		*u8_tmp = btcoexist->pwr_mode_val[0]; +		break; + +	default: +		break; +	} + +	return true; +} + +static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist; +	bool *bool_tmp = (bool *)in_buf; +	u8 *u8_tmp = (u8 *)in_buf; +	u32 *u32_tmp = (u32 *)in_buf; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return false; + +	switch (set_type) { +	/* set some bool type variables. */ +	case BTC_SET_BL_BT_DISABLE: +		btcoexist->bt_info.bt_disabled = *bool_tmp; +		break; +	case BTC_SET_BL_BT_TRAFFIC_BUSY: +		btcoexist->bt_info.bt_busy = *bool_tmp; +		break; +	case BTC_SET_BL_BT_LIMITED_DIG: +		btcoexist->bt_info.limited_dig = *bool_tmp; +		break; +	case BTC_SET_BL_FORCE_TO_ROAM: +		btcoexist->bt_info.force_to_roam = *bool_tmp; +		break; +	case BTC_SET_BL_TO_REJ_AP_AGG_PKT: +		btcoexist->bt_info.reject_agg_pkt = *bool_tmp; +		break; +	case BTC_SET_BL_BT_CTRL_AGG_SIZE: +		btcoexist->bt_info.b_bt_ctrl_buf_size = *bool_tmp; +		break; +	case BTC_SET_BL_INC_SCAN_DEV_NUM: +		btcoexist->bt_info.increase_scan_dev_num = *bool_tmp; +		break; +		/* set some u1Byte type variables. */ +	case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON: +		btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp; +		break; +	case BTC_SET_U1_AGG_BUF_SIZE: +		btcoexist->bt_info.agg_buf_size = *u8_tmp; +		break; +		/* the following are some action which will be triggered */ +	case BTC_SET_ACT_GET_BT_RSSI: +		/*BTHCI_SendGetBtRssiEvent(rtlpriv);*/ +		break; +	case BTC_SET_ACT_AGGREGATE_CTRL: +		halbtc_aggregation_check(); +		break; + +		/* 1Ant */ +	case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE: +		btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp; +		break; +	case BTC_SET_UI_SCAN_SIG_COMPENSATION: +	/*	rtlpriv->mlmepriv.scan_compensation = *u8_tmp;  */ +		break; +	case BTC_SET_U1_1ANT_LPS: +		btcoexist->bt_info.lps_1ant = *u8_tmp; +		break; +	case BTC_SET_U1_1ANT_RPWM: +		btcoexist->bt_info.rpwm_1ant = *u8_tmp; +		break; +	/* the following are some action which will be triggered  */ +	case BTC_SET_ACT_LEAVE_LPS: +		halbtc_leave_lps(btcoexist); +		break; +	case BTC_SET_ACT_ENTER_LPS: +		halbtc_enter_lps(btcoexist); +		break; +	case BTC_SET_ACT_NORMAL_LPS: +		halbtc_normal_lps(btcoexist); +		break; +	case BTC_SET_ACT_DISABLE_LOW_POWER: +		halbtc_disable_low_power(); +		break; +	case BTC_SET_ACT_UPDATE_ra_mask: +		btcoexist->bt_info.ra_mask = *u32_tmp; +		break; +	case BTC_SET_ACT_SEND_MIMO_PS: +		break; +	case BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT: +		btcoexist->bt_info.force_exec_pwr_cmd_cnt++; +		break; +	case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/ +		break; +	case BTC_SET_ACT_CTRL_BT_COEX: +		break; +	default: +		break; +	} + +	return true; +} + +static void halbtc_display_coex_statistics(struct btc_coexist *btcoexist) +{ +} + +static void halbtc_display_bt_link_info(struct btc_coexist *btcoexist) +{ +} + +static void halbtc_display_bt_fw_info(struct btc_coexist *btcoexist) +{ +} + +static void halbtc_display_fw_pwr_mode_cmd(struct btc_coexist *btcoexist) +{ +} + +/************************************************************ + *		IO related function + ************************************************************/ +static u8 halbtc_read_1byte(void *bt_context, u32 reg_addr) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return	rtl_read_byte(rtlpriv, reg_addr); +} + +static u16 halbtc_read_2byte(void *bt_context, u32 reg_addr) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return	rtl_read_word(rtlpriv, reg_addr); +} + +static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return	rtl_read_dword(rtlpriv, reg_addr); +} + +static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u8 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_write_byte(rtlpriv, reg_addr, data); +} + +static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr, +				       u32 bit_mask, u8 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	u8 original_value, bit_shift = 0; +	u8 i; + +	if (bit_mask != MASKDWORD) {/*if not "double word" write*/ +		original_value = rtl_read_byte(rtlpriv, reg_addr); +		for (i = 0; i <= 7; i++) { +			if ((bit_mask>>i) & 0x1) +				break; +		} +		bit_shift = i; +		data = (original_value & (~bit_mask)) | +			((data << bit_shift) & bit_mask); +	} +	rtl_write_byte(rtlpriv, reg_addr, data); +} + +static void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_write_word(rtlpriv, reg_addr, data); +} + +static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data) +{ +	struct btc_coexist *btcoexist = +		(struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_write_dword(rtlpriv, reg_addr, data); +} + +static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask, +			     u32 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data); +} + +static u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask); +} + +static void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr, +			     u32 bit_mask, u32 data) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data); +} + +static u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr, +			    u32 bit_mask) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask); +} + +static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id, +				u32 cmd_len, u8 *cmd_buf) +{ +	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; +	struct rtl_priv *rtlpriv = btcoexist->adapter; + +	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id, +					cmd_len, cmd_buf); +} + +static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type) +{ +	struct btc_coexist *btcoexist =	(struct btc_coexist *)bt_context; +	switch (disp_type) { +	case BTC_DBG_DISP_COEX_STATISTICS: +		halbtc_display_coex_statistics(btcoexist); +		break; +	case BTC_DBG_DISP_BT_LINK_INFO: +		halbtc_display_bt_link_info(btcoexist); +		break; +	case BTC_DBG_DISP_BT_FW_VER: +		halbtc_display_bt_fw_info(btcoexist); +		break; +	case BTC_DBG_DISP_FW_PWR_MODE_CMD: +		halbtc_display_fw_pwr_mode_cmd(btcoexist); +		break; +	default: +		break; +	} +} + +/***************************************************************** + *         Extern functions called by other module + *****************************************************************/ +bool exhalbtc_initlize_variables(struct rtl_priv *adapter) +{ +	struct btc_coexist *btcoexist = &gl_bt_coexist; + +	btcoexist->statistics.cnt_bind++; + +	halbtc_dbg_init(); + +	if (btcoexist->binded) +		return false; +	else +		btcoexist->binded = true; + +	btcoexist->chip_interface = BTC_INTF_UNKNOWN; + +	if (NULL == btcoexist->adapter) +		btcoexist->adapter = adapter; + +	btcoexist->stack_info.profile_notified = false; + +	btcoexist->btc_read_1byte = halbtc_read_1byte; +	btcoexist->btc_write_1byte = halbtc_write_1byte; +	btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte; +	btcoexist->btc_read_2byte = halbtc_read_2byte; +	btcoexist->btc_write_2byte = halbtc_write_2byte; +	btcoexist->btc_read_4byte = halbtc_read_4byte; +	btcoexist->btc_write_4byte = halbtc_write_4byte; + +	btcoexist->btc_set_bb_reg = halbtc_set_bbreg; +	btcoexist->btc_get_bb_reg = halbtc_get_bbreg; + +	btcoexist->btc_set_rf_reg = halbtc_set_rfreg; +	btcoexist->btc_get_rf_reg = halbtc_get_rfreg; + +	btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd; +	btcoexist->btc_disp_dbg_msg = halbtc_display_dbg_msg; + +	btcoexist->btc_get = halbtc_get; +	btcoexist->btc_set = halbtc_set; + +	btcoexist->cli_buf = &btc_dbg_buf[0]; + +	btcoexist->bt_info.b_bt_ctrl_buf_size = false; +	btcoexist->bt_info.agg_buf_size = 5; + +	btcoexist->bt_info.increase_scan_dev_num = false; +	return true; +} + +void exhalbtc_init_hw_config(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->statistics.cnt_init_hw_config++; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_init_hwconfig(btcoexist); +} + +void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->statistics.cnt_init_coex_dm++; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_init_coex_dm(btcoexist); + +	btcoexist->initilized = true; +} + +void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 ips_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_ips_notify++; +	if (btcoexist->manual_control) +		return; + +	if (ERFOFF == type) +		ips_type = BTC_IPS_ENTER; +	else +		ips_type = BTC_IPS_LEAVE; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_ips_notify(btcoexist, ips_type); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 lps_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_lps_notify++; +	if (btcoexist->manual_control) +		return; + +	if (EACTIVE == type) +		lps_type = BTC_LPS_DISABLE; +	else +		lps_type = BTC_LPS_ENABLE; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_lps_notify(btcoexist, lps_type); +} + +void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 scan_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_scan_notify++; +	if (btcoexist->manual_control) +		return; + +	if (type) +		scan_type = BTC_SCAN_START; +	else +		scan_type = BTC_SCAN_FINISH; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_scan_notify(btcoexist, scan_type); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 asso_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_connect_notify++; +	if (btcoexist->manual_control) +		return; + +	if (action) +		asso_type = BTC_ASSOCIATE_START; +	else +		asso_type = BTC_ASSOCIATE_FINISH; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_connect_notify(btcoexist, asso_type); +} + +void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, +				 enum _RT_MEDIA_STATUS media_status) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 status; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_media_status_notify++; +	if (btcoexist->manual_control) +		return; + +	if (RT_MEDIA_CONNECT == media_status) +		status = BTC_MEDIA_CONNECT; +	else +		status = BTC_MEDIA_DISCONNECT; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		btc8723b_med_stat_notify(btcoexist, status); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 packet_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_special_packet_notify++; +	if (btcoexist->manual_control) +		return; + +	packet_type = BTC_PACKET_DHCP; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_special_packet_notify(btcoexist, +							 packet_type); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, +			     u8 *tmp_buf, u8 length) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_bt_info_notify++; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length); +} + +void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 stack_op_type; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_stack_operation_notify++; +	if (btcoexist->manual_control) +		return; + +	stack_op_type = BTC_STACK_OP_NONE; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_stack_operation_notify(btcoexist, +							  stack_op_type); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_halt_notify(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_halt_notify(btcoexist); +} + +void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) +{ +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +} + +void exhalbtc_periodical(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_periodical++; + +	halbtc_leave_low_power(); + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_periodical(btcoexist); + +	halbtc_nomal_low_power(); +} + +void exhalbtc_dbg_control(struct btc_coexist *btcoexist, +			  u8 code, u8 len, u8 *data) +{ +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; +	btcoexist->statistics.cnt_dbg_ctrl++; +} + +void exhalbtc_stack_update_profile_info(void) +{ +} + +void exhalbtc_update_min_bt_rssi(char bt_rssi) +{ +	struct btc_coexist *btcoexist = &gl_bt_coexist; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->stack_info.min_bt_rssi = bt_rssi; +} + +void exhalbtc_set_hci_version(u16 hci_version) +{ +	struct btc_coexist *btcoexist = &gl_bt_coexist; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->stack_info.hci_version = hci_version; +} + +void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version) +{ +	struct btc_coexist *btcoexist = &gl_bt_coexist; + +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	btcoexist->bt_info.bt_real_fw_ver = bt_patch_version; +	btcoexist->bt_info.bt_hci_ver = bt_hci_version; +} + +void exhalbtc_set_bt_exist(bool bt_exist) +{ +	gl_bt_coexist.board_info.bt_exist = bt_exist; +} + +void exhalbtc_set_chip_type(u8 chip_type) +{ +	switch (chip_type) { +	default: +	case BT_2WIRE: +	case BT_ISSC_3WIRE: +	case BT_ACCEL: +	case BT_RTL8756: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_UNDEF; +		break; +	case BT_CSR_BC4: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC4; +		break; +	case BT_CSR_BC8: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC8; +		break; +	case BT_RTL8723A: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723A; +		break; +	case BT_RTL8821A: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8821; +		break; +	case BT_RTL8723B: +		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723B; +		break; +	} +} + +void exhalbtc_set_ant_num(u8 type, u8 ant_num) +{ +	if (BT_COEX_ANT_TYPE_PG == type) { +		gl_bt_coexist.board_info.pg_ant_num = ant_num; +		gl_bt_coexist.board_info.btdm_ant_num = ant_num; +	} else if (BT_COEX_ANT_TYPE_ANTDIV == type) { +		gl_bt_coexist.board_info.btdm_ant_num = ant_num; +	} +} + +void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist) +{ +	struct rtl_priv *rtlpriv = btcoexist->adapter; +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	if (!halbtc_is_bt_coexist_available(btcoexist)) +		return; + +	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) +		ex_halbtc8723b2ant_display_coex_info(btcoexist); +} diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h new file mode 100644 index 00000000000..871fc3c6d55 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h @@ -0,0 +1,559 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012  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	__HALBTC_OUT_SRC_H__ +#define __HALBTC_OUT_SRC_H__ + +#include	"../wifi.h" + +#define		NORMAL_EXEC				false +#define		FORCE_EXEC				true + +#define		BTC_RF_A				RF90_PATH_A +#define		BTC_RF_B				RF90_PATH_B +#define		BTC_RF_C				RF90_PATH_C +#define		BTC_RF_D				RF90_PATH_D + +#define		BTC_SMSP				SINGLEMAC_SINGLEPHY +#define		BTC_DMDP				DUALMAC_DUALPHY +#define		BTC_DMSP				DUALMAC_SINGLEPHY +#define		BTC_MP_UNKNOWN				0xff + +#define		IN +#define		OUT + +#define		BT_TMP_BUF_SIZE				100 + +#define		BT_COEX_ANT_TYPE_PG			0 +#define		BT_COEX_ANT_TYPE_ANTDIV			1 +#define		BT_COEX_ANT_TYPE_DETECTED		2 + +#define		BTC_MIMO_PS_STATIC			0 +#define		BTC_MIMO_PS_DYNAMIC			1 + +#define		BTC_RATE_DISABLE			0 +#define		BTC_RATE_ENABLE				1 + +#define		BTC_ANT_PATH_WIFI			0 +#define		BTC_ANT_PATH_BT				1 +#define		BTC_ANT_PATH_PTA			2 + +enum btc_chip_interface { +	BTC_INTF_UNKNOWN	= 0, +	BTC_INTF_PCI		= 1, +	BTC_INTF_USB		= 2, +	BTC_INTF_SDIO		= 3, +	BTC_INTF_GSPI		= 4, +	BTC_INTF_MAX +}; + +enum BTC_CHIP_TYPE { +	BTC_CHIP_UNDEF		= 0, +	BTC_CHIP_CSR_BC4	= 1, +	BTC_CHIP_CSR_BC8	= 2, +	BTC_CHIP_RTL8723A	= 3, +	BTC_CHIP_RTL8821	= 4, +	BTC_CHIP_RTL8723B	= 5, +	BTC_CHIP_MAX +}; + +enum BTC_MSG_TYPE { +	BTC_MSG_INTERFACE	= 0x0, +	BTC_MSG_ALGORITHM	= 0x1, +	BTC_MSG_MAX +}; +extern u32 btc_dbg_type[]; + +/* following is for BTC_MSG_INTERFACE */ +#define		INTF_INIT				BIT0 +#define		INTF_NOTIFY				BIT2 + +/* following is for BTC_ALGORITHM */ +#define		ALGO_BT_RSSI_STATE			BIT0 +#define		ALGO_WIFI_RSSI_STATE			BIT1 +#define		ALGO_BT_MONITOR				BIT2 +#define		ALGO_TRACE				BIT3 +#define		ALGO_TRACE_FW				BIT4 +#define		ALGO_TRACE_FW_DETAIL			BIT5 +#define		ALGO_TRACE_FW_EXEC			BIT6 +#define		ALGO_TRACE_SW				BIT7 +#define		ALGO_TRACE_SW_DETAIL			BIT8 +#define		ALGO_TRACE_SW_EXEC			BIT9 + +#define		BT_COEX_ANT_TYPE_PG			0 +#define		BT_COEX_ANT_TYPE_ANTDIV			1 +#define		BT_COEX_ANT_TYPE_DETECTED		2 +#define		BTC_MIMO_PS_STATIC			0 +#define		BTC_MIMO_PS_DYNAMIC			1 +#define		BTC_RATE_DISABLE			0 +#define		BTC_RATE_ENABLE				1 +#define		BTC_ANT_PATH_WIFI			0 +#define		BTC_ANT_PATH_BT				1 +#define		BTC_ANT_PATH_PTA			2 + + +#define	CL_SPRINTF	snprintf +#define	CL_PRINTF	printk + +#define	BTC_PRINT(dbgtype, dbgflag, printstr, ...)		\ +	do {							\ +		if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\ +			printk(printstr, ##__VA_ARGS__);	\ +		}						\ +	} while (0) + +#define	BTC_PRINT_F(dbgtype, dbgflag, printstr, ...)		\ +	do {							\ +		if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\ +			pr_info("%s: ", __func__);	\ +			printk(printstr, ##__VA_ARGS__);	\ +		}						\ +	} while (0) + +#define	BTC_PRINT_ADDR(dbgtype, dbgflag, printstr, _ptr)	\ +	do {							\ +		if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {	\ +			int __i;				\ +			u8 *__ptr = (u8 *)_ptr;			\ +			printk printstr;			\ +			for (__i = 0; __i < 6; __i++)		\ +				printk("%02X%s", __ptr[__i], (__i == 5) ? \ +				       "" : "-");		\ +			pr_info("\n");				\ +		}						\ +	} while (0) + +#define BTC_PRINT_DATA(dbgtype, dbgflag, _titlestring, _hexdata, _hexdatalen) \ +	do {								\ +		if (unlikely(btc_dbg_type[dbgtype] & dbgflag))	{	\ +			int __i;					\ +			u8 *__ptr = (u8 *)_hexdata;			\ +			printk(_titlestring);				\ +			for (__i = 0; __i < (int)_hexdatalen; __i++) {	\ +				printk("%02X%s", __ptr[__i], (((__i + 1) % 4) \ +							== 0) ? "  " : " ");\ +				if (((__i + 1) % 16) == 0)		\ +					printk("\n");			\ +			}						\ +			pr_debug("\n");					\ +		}							\ +	} while (0) + +#define BTC_ANT_PATH_WIFI	0 +#define BTC_ANT_PATH_BT		1 +#define BTC_ANT_PATH_PTA	2 + +enum btc_power_save_type { +	BTC_PS_WIFI_NATIVE = 0, +	BTC_PS_LPS_ON = 1, +	BTC_PS_LPS_OFF = 2, +	BTC_PS_LPS_MAX +}; + +struct btc_board_info { +	/* The following is some board information */ +	u8 bt_chip_type; +	u8 pg_ant_num;	/* pg ant number */ +	u8 btdm_ant_num;	/* ant number for btdm */ +	u8 btdm_ant_pos; +	bool bt_exist; +}; + +enum btc_dbg_opcode { +	BTC_DBG_SET_COEX_NORMAL = 0x0, +	BTC_DBG_SET_COEX_WIFI_ONLY = 0x1, +	BTC_DBG_SET_COEX_BT_ONLY = 0x2, +	BTC_DBG_MAX +}; + +enum btc_rssi_state { +	BTC_RSSI_STATE_HIGH = 0x0, +	BTC_RSSI_STATE_MEDIUM = 0x1, +	BTC_RSSI_STATE_LOW = 0x2, +	BTC_RSSI_STATE_STAY_HIGH = 0x3, +	BTC_RSSI_STATE_STAY_MEDIUM = 0x4, +	BTC_RSSI_STATE_STAY_LOW = 0x5, +	BTC_RSSI_MAX +}; + +enum btc_wifi_role { +	BTC_ROLE_STATION = 0x0, +	BTC_ROLE_AP = 0x1, +	BTC_ROLE_IBSS = 0x2, +	BTC_ROLE_HS_MODE = 0x3, +	BTC_ROLE_MAX +}; + +enum btc_wifi_bw_mode { +	BTC_WIFI_BW_LEGACY = 0x0, +	BTC_WIFI_BW_HT20 = 0x1, +	BTC_WIFI_BW_HT40 = 0x2, +	BTC_WIFI_BW_MAX +}; + +enum btc_wifi_traffic_dir { +	BTC_WIFI_TRAFFIC_TX = 0x0, +	BTC_WIFI_TRAFFIC_RX = 0x1, +	BTC_WIFI_TRAFFIC_MAX +}; + +enum btc_wifi_pnp { +	BTC_WIFI_PNP_WAKE_UP = 0x0, +	BTC_WIFI_PNP_SLEEP = 0x1, +	BTC_WIFI_PNP_MAX +}; + + +enum btc_get_type { +	/* type bool */ +	BTC_GET_BL_HS_OPERATION, +	BTC_GET_BL_HS_CONNECTING, +	BTC_GET_BL_WIFI_CONNECTED, +	BTC_GET_BL_WIFI_BUSY, +	BTC_GET_BL_WIFI_SCAN, +	BTC_GET_BL_WIFI_LINK, +	BTC_GET_BL_WIFI_DHCP, +	BTC_GET_BL_WIFI_SOFTAP_IDLE, +	BTC_GET_BL_WIFI_SOFTAP_LINKING, +	BTC_GET_BL_WIFI_IN_EARLY_SUSPEND, +	BTC_GET_BL_WIFI_ROAM, +	BTC_GET_BL_WIFI_4_WAY_PROGRESS, +	BTC_GET_BL_WIFI_UNDER_5G, +	BTC_GET_BL_WIFI_AP_MODE_ENABLE, +	BTC_GET_BL_WIFI_ENABLE_ENCRYPTION, +	BTC_GET_BL_WIFI_UNDER_B_MODE, +	BTC_GET_BL_EXT_SWITCH, + +	/* type s4Byte */ +	BTC_GET_S4_WIFI_RSSI, +	BTC_GET_S4_HS_RSSI, + +	/* type u32 */ +	BTC_GET_U4_WIFI_BW, +	BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, +	BTC_GET_U4_WIFI_FW_VER, +	BTC_GET_U4_BT_PATCH_VER, + +	/* type u1Byte */ +	BTC_GET_U1_WIFI_DOT11_CHNL, +	BTC_GET_U1_WIFI_CENTRAL_CHNL, +	BTC_GET_U1_WIFI_HS_CHNL, +	BTC_GET_U1_MAC_PHY_MODE, + +	/* for 1Ant */ +	BTC_GET_U1_LPS_MODE, +	BTC_GET_BL_BT_SCO_BUSY, + +	/* for test mode */ +	BTC_GET_DRIVER_TEST_CFG, +	BTC_GET_MAX +}; + + +enum btc_set_type { +	/* type bool */ +	BTC_SET_BL_BT_DISABLE, +	BTC_SET_BL_BT_TRAFFIC_BUSY, +	BTC_SET_BL_BT_LIMITED_DIG, +	BTC_SET_BL_FORCE_TO_ROAM, +	BTC_SET_BL_TO_REJ_AP_AGG_PKT, +	BTC_SET_BL_BT_CTRL_AGG_SIZE, +	BTC_SET_BL_INC_SCAN_DEV_NUM, + +	/* type u1Byte */ +	BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, +	BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, +	BTC_SET_UI_SCAN_SIG_COMPENSATION, +	BTC_SET_U1_AGG_BUF_SIZE, + +	/* type trigger some action */ +	BTC_SET_ACT_GET_BT_RSSI, +	BTC_SET_ACT_AGGREGATE_CTRL, + +	/********* for 1Ant **********/ +	/* type bool */ +	BTC_SET_BL_BT_SCO_BUSY, +	/* type u1Byte */ +	BTC_SET_U1_1ANT_LPS, +	BTC_SET_U1_1ANT_RPWM, +	/* type trigger some action */ +	BTC_SET_ACT_LEAVE_LPS, +	BTC_SET_ACT_ENTER_LPS, +	BTC_SET_ACT_NORMAL_LPS, +	BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT, +	BTC_SET_ACT_DISABLE_LOW_POWER, +	BTC_SET_ACT_UPDATE_ra_mask, +	BTC_SET_ACT_SEND_MIMO_PS, +	/* BT Coex related */ +	BTC_SET_ACT_CTRL_BT_INFO, +	BTC_SET_ACT_CTRL_BT_COEX, +	/***************************/ +	BTC_SET_MAX +}; + +enum btc_dbg_disp_type { +	BTC_DBG_DISP_COEX_STATISTICS = 0x0, +	BTC_DBG_DISP_BT_LINK_INFO = 0x1, +	BTC_DBG_DISP_BT_FW_VER = 0x2, +	BTC_DBG_DISP_FW_PWR_MODE_CMD = 0x3, +	BTC_DBG_DISP_MAX +}; + +enum btc_notify_type_ips { +	BTC_IPS_LEAVE = 0x0, +	BTC_IPS_ENTER = 0x1, +	BTC_IPS_MAX +}; + +enum btc_notify_type_lps { +	BTC_LPS_DISABLE = 0x0, +	BTC_LPS_ENABLE = 0x1, +	BTC_LPS_MAX +}; + +enum btc_notify_type_scan { +	BTC_SCAN_FINISH = 0x0, +	BTC_SCAN_START = 0x1, +	BTC_SCAN_MAX +}; + +enum btc_notify_type_associate { +	BTC_ASSOCIATE_FINISH = 0x0, +	BTC_ASSOCIATE_START = 0x1, +	BTC_ASSOCIATE_MAX +}; + +enum btc_notify_type_media_status { +	BTC_MEDIA_DISCONNECT = 0x0, +	BTC_MEDIA_CONNECT = 0x1, +	BTC_MEDIA_MAX +}; + +enum btc_notify_type_special_packet { +	BTC_PACKET_UNKNOWN = 0x0, +	BTC_PACKET_DHCP = 0x1, +	BTC_PACKET_ARP = 0x2, +	BTC_PACKET_EAPOL = 0x3, +	BTC_PACKET_MAX +}; + +enum btc_notify_type_stack_operation { +	BTC_STACK_OP_NONE = 0x0, +	BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1, +	BTC_STACK_OP_INQ_PAGE_PAIR_FINISH = 0x2, +	BTC_STACK_OP_MAX +}; + + +typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr); + +typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr); + +typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr); + +typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u8 data); + +typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr, +				   u32 bit_mask, u8 data1b); + +typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data); + +typedef void (*bfp_btc_w4)(void *btc_context, u32 reg_addr, u32 data); + +typedef void (*bfp_btc_wr_1byte_bit_mask)(void *btc_context, u32 reg_addr, +					  u8 bit_mask, u8 data); + +typedef void (*bfp_btc_set_bb_reg)(void *btc_context, u32 reg_addr, +				   u32 bit_mask, u32 data); + +typedef u32 (*bfp_btc_get_bb_reg)(void *btc_context, u32 reg_addr, +				  u32 bit_mask); + +typedef void (*bfp_btc_set_rf_reg)(void *btc_context, u8 rf_path, u32 reg_addr, +				   u32 bit_mask, u32 data); + +typedef u32 (*bfp_btc_get_rf_reg)(void *btc_context, u8 rf_path, +				  u32 reg_addr, u32 bit_mask); + +typedef void (*bfp_btc_fill_h2c)(void *btc_context, u8 element_id, +				 u32 cmd_len, u8 *cmd_buffer); + +typedef	bool (*bfp_btc_get)(void *btcoexist, u8 get_type, void *out_buf); + +typedef	bool (*bfp_btc_set)(void *btcoexist, u8 set_type, void *in_buf); + +typedef void (*bfp_btc_disp_dbg_msg)(void *btcoexist, u8 disp_type); + +struct btc_bt_info { +	bool bt_disabled; +	u8 rssi_adjust_for_agc_table_on; +	u8 rssi_adjust_for_1ant_coex_type; +	bool bt_busy; +	u8 agg_buf_size; +	bool limited_dig; +	bool reject_agg_pkt; +	bool b_bt_ctrl_buf_size; +	bool increase_scan_dev_num; +	u16 bt_hci_ver; +	u16 bt_real_fw_ver; +	u8 bt_fw_ver; + +	/* the following is for 1Ant solution */ +	bool bt_ctrl_lps; +	bool bt_pwr_save_mode; +	bool bt_lps_on; +	bool force_to_roam; +	u8 force_exec_pwr_cmd_cnt; +	u8 lps_1ant; +	u8 rpwm_1ant; +	u32 ra_mask; +}; + +struct btc_stack_info { +	bool profile_notified; +	u16 hci_version;	/* stack hci version */ +	u8 num_of_link; +	bool bt_link_exist; +	bool sco_exist; +	bool acl_exist; +	bool a2dp_exist; +	bool hid_exist; +	u8 num_of_hid; +	bool pan_exist; +	bool unknown_acl_exist; +	char min_bt_rssi; +}; + +struct btc_statistics { +	u32 cnt_bind; +	u32 cnt_init_hw_config; +	u32 cnt_init_coex_dm; +	u32 cnt_ips_notify; +	u32 cnt_lps_notify; +	u32 cnt_scan_notify; +	u32 cnt_connect_notify; +	u32 cnt_media_status_notify; +	u32 cnt_special_packet_notify; +	u32 cnt_bt_info_notify; +	u32 cnt_periodical; +	u32 cnt_stack_operation_notify; +	u32 cnt_dbg_ctrl; +}; + +struct btc_bt_link_info { +	bool bt_link_exist; +	bool sco_exist; +	bool sco_only; +	bool a2dp_exist; +	bool a2dp_only; +	bool hid_exist; +	bool hid_only; +	bool pan_exist; +	bool pan_only; +}; + +enum btc_antenna_pos { +	BTC_ANTENNA_AT_MAIN_PORT = 0x1, +	BTC_ANTENNA_AT_AUX_PORT = 0x2, +}; + +struct btc_coexist { +	/* make sure only one adapter can bind the data context  */ +	bool binded; +	/* default adapter */ +	void *adapter; +	struct btc_board_info board_info; +	/* some bt info referenced by non-bt module */ +	struct btc_bt_info bt_info; +	struct btc_stack_info stack_info; +	enum btc_chip_interface	chip_interface; +	struct btc_bt_link_info bt_link_info; + +	bool initilized; +	bool stop_coex_dm; +	bool manual_control; +	u8 *cli_buf; +	struct btc_statistics statistics; +	u8 pwr_mode_val[10]; + +	/* function pointers - io related */ +	bfp_btc_r1 btc_read_1byte; +	bfp_btc_w1 btc_write_1byte; +	bfp_btc_w1_bit_mak btc_write_1byte_bitmask; +	bfp_btc_r2 btc_read_2byte; +	bfp_btc_w2 btc_write_2byte; +	bfp_btc_r4 btc_read_4byte; +	bfp_btc_w4 btc_write_4byte; + +	bfp_btc_set_bb_reg btc_set_bb_reg; +	bfp_btc_get_bb_reg btc_get_bb_reg; + + +	bfp_btc_set_rf_reg btc_set_rf_reg; +	bfp_btc_get_rf_reg btc_get_rf_reg; + +	bfp_btc_fill_h2c btc_fill_h2c; + +	bfp_btc_disp_dbg_msg btc_disp_dbg_msg; + +	bfp_btc_get btc_get; +	bfp_btc_set btc_set; +}; + +bool halbtc_is_wifi_uplink(struct rtl_priv *adapter); + +extern struct btc_coexist gl_bt_coexist; + +bool exhalbtc_initlize_variables(struct rtl_priv *adapter); +void exhalbtc_init_hw_config(struct btc_coexist *btcoexist); +void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist); +void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action); +void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, +				 enum _RT_MEDIA_STATUS media_status); +void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type); +void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf, +			     u8 length); +void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type); +void exhalbtc_halt_notify(struct btc_coexist *btcoexist); +void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); +void exhalbtc_periodical(struct btc_coexist *btcoexist); +void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len, +			  u8 *data); +void exhalbtc_stack_update_profile_info(void); +void exhalbtc_set_hci_version(u16 hci_version); +void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version); +void exhalbtc_update_min_bt_rssi(char bt_rssi); +void exhalbtc_set_bt_exist(bool bt_exist); +void exhalbtc_set_chip_type(u8 chip_type); +void exhalbtc_set_ant_num(u8 type, u8 ant_num); +void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist); +void exhalbtc_signal_compensation(struct btc_coexist *btcoexist, +				  u8 *rssi_wifi, u8 *rssi_bt); +void exhalbtc_lps_leave(struct btc_coexist *btcoexist); +void exhalbtc_low_wifi_traffic_notify(struct btc_coexist *btcoexist); + +#endif diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c new file mode 100644 index 00000000000..0ab94fe4cbb --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c @@ -0,0 +1,218 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2013  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 "rtl_btc.h" +#include "halbt_precomp.h" + +#include <linux/vmalloc.h> +#include <linux/module.h> + +static struct rtl_btc_ops rtl_btc_operation = { +	.btc_init_variables = rtl_btc_init_variables, +	.btc_init_hal_vars = rtl_btc_init_hal_vars, +	.btc_init_hw_config = rtl_btc_init_hw_config, +	.btc_ips_notify = rtl_btc_ips_notify, +	.btc_scan_notify = rtl_btc_scan_notify, +	.btc_connect_notify = rtl_btc_connect_notify, +	.btc_mediastatus_notify = rtl_btc_mediastatus_notify, +	.btc_periodical = rtl_btc_periodical, +	.btc_halt_notify = rtl_btc_halt_notify, +	.btc_btinfo_notify = rtl_btc_btinfo_notify, +	.btc_is_limited_dig = rtl_btc_is_limited_dig, +	.btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo, +	.btc_is_bt_disabled = rtl_btc_is_bt_disabled, +}; + +void rtl_btc_init_variables(struct rtl_priv *rtlpriv) +{ +	exhalbtc_initlize_variables(rtlpriv); +} + +void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv) +{ +	u8 ant_num; +	u8 bt_exist; +	u8 bt_type; + +	ant_num = rtl_get_hwpg_ant_num(rtlpriv); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +		 "%s, antNum is %d\n", __func__, ant_num); + +	bt_exist = rtl_get_hwpg_bt_exist(rtlpriv); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +		 "%s, bt_exist is %d\n", __func__, bt_exist); +	exhalbtc_set_bt_exist(bt_exist); + +	bt_type = rtl_get_hwpg_bt_type(rtlpriv); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%s, bt_type is %d\n", +		 __func__, bt_type); +	exhalbtc_set_chip_type(bt_type); + +	exhalbtc_set_ant_num(BT_COEX_ANT_TYPE_PG, ant_num); +} + +void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv) +{ +	exhalbtc_init_hw_config(&gl_bt_coexist); +	exhalbtc_init_coex_dm(&gl_bt_coexist); +} + +void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type) +{ +	exhalbtc_ips_notify(&gl_bt_coexist, type); +} + +void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype) +{ +	exhalbtc_scan_notify(&gl_bt_coexist, scantype); +} + +void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action) +{ +	exhalbtc_connect_notify(&gl_bt_coexist, action); +} + +void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, +				enum _RT_MEDIA_STATUS mstatus) +{ +	exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus); +} + +void rtl_btc_periodical(struct rtl_priv *rtlpriv) +{ +	exhalbtc_periodical(&gl_bt_coexist); +} + +void rtl_btc_halt_notify(void) +{ +	exhalbtc_halt_notify(&gl_bt_coexist); +} + +void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmp_buf, u8 length) +{ +	exhalbtc_bt_info_notify(&gl_bt_coexist, tmp_buf, length); +} + +bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv) +{ +	return gl_bt_coexist.bt_info.limited_dig; +} + +bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv) +{ +	bool bt_change_edca = false; +	u32 cur_edca_val; +	u32 edca_bt_hs_uplink = 0x5ea42b, edca_bt_hs_downlink = 0x5ea42b; +	u32 edca_hs; +	u32 edca_addr = 0x504; + +	cur_edca_val = rtl_read_dword(rtlpriv, edca_addr); +	if (halbtc_is_wifi_uplink(rtlpriv)) { +		if (cur_edca_val != edca_bt_hs_uplink) { +			edca_hs = edca_bt_hs_uplink; +			bt_change_edca = true; +		} +	} else { +		if (cur_edca_val != edca_bt_hs_downlink) { +			edca_hs = edca_bt_hs_downlink; +			bt_change_edca = true; +		} +	} + +	if (bt_change_edca) +		rtl_write_dword(rtlpriv, edca_addr, edca_hs); + +	return true; +} + +bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv) +{ +	if (gl_bt_coexist.bt_info.bt_disabled) +		return true; +	else +		return false; +} + +struct rtl_btc_ops *rtl_btc_get_ops_pointer(void) +{ +	return &rtl_btc_operation; +} +EXPORT_SYMBOL(rtl_btc_get_ops_pointer); + +u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) +{ +	u8 num; + +	if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2) +		num = 2; +	else +		num = 1; + +	return num; +} + +enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	enum _RT_MEDIA_STATUS    m_status = RT_MEDIA_DISCONNECT; + +	u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; + +	if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) +		m_status = RT_MEDIA_CONNECT; + +	return m_status; +} + +u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv) +{ +	return rtlpriv->btcoexist.btc_info.btcoexist; +} + +u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv) +{ +	return rtlpriv->btcoexist.btc_info.bt_type; +} + +MODULE_AUTHOR("Page He	<page_he@realsil.com.cn>"); +MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>"); +MODULE_AUTHOR("Larry Finger	<Larry.FInger@lwfinger.net>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); + +static int __init rtl_btcoexist_module_init(void) +{ +	return 0; +} + +static void __exit rtl_btcoexist_module_exit(void) +{ +	return; +} + +module_init(rtl_btcoexist_module_init); +module_exit(rtl_btcoexist_module_exit); diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h new file mode 100644 index 00000000000..805b22cc8fc --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010  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 __RTL_BTC_H__ +#define __RTL_BTC_H__ + +#include "halbt_precomp.h" + +void rtl_btc_init_variables(struct rtl_priv *rtlpriv); +void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv); +void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv); +void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type); +void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype); +void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action); +void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, +				enum _RT_MEDIA_STATUS mstatus); +void rtl_btc_periodical(struct rtl_priv *rtlpriv); +void rtl_btc_halt_notify(void); +void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length); +bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv); +bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); +bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); + +struct rtl_btc_ops *rtl_btc_get_ops_pointer(void); + +u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv); +u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv); +u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv); +enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 0e510f73041..0276153c72c 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -295,7 +295,7 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)  	/* Does STA already exist? */  	for (i = 4; i < TOTAL_CAM_ENTRY; i++) {  		addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; -		if (memcmp(addr, sta_addr, ETH_ALEN) == 0) +		if (ether_addr_equal_unaligned(addr, sta_addr))  			return i;  	}  	/* Get a free CAM entry. */ @@ -335,7 +335,7 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)  		addr = rtlpriv->sec.hwsec_cam_sta_addr[i];  		bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i;  		if (((bitmap & BIT(0)) == BIT(0)) && -		    (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { +		    (ether_addr_equal_unaligned(addr, sta_addr))) {  			/* Remove from HW Security CAM */  			eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]);  			rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h index 35e00086a52..0105e6c1901 100644 --- a/drivers/net/wireless/rtlwifi/cam.h +++ b/drivers/net/wireless/rtlwifi/cam.h @@ -41,12 +41,12 @@  #define	CAM_CONFIG_USEDK				1  #define	CAM_CONFIG_NO_USEDK				0 -extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); -extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, -			u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, -			u32 ul_default_key, u8 *key_content); +void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); +u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, +			 u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, +			 u32 ul_default_key, u8 *key_content);  int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, -			u32 ul_key_id); +			     u32 ul_key_id);  void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);  void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);  void rtl_cam_reset_sec_info(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 733b7ce7f0e..b1ed6d0796f 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -36,6 +36,66 @@  #include <linux/export.h> +void rtl_addr_delay(u32 addr) +{ +	if (addr == 0xfe) +		mdelay(50); +	else if (addr == 0xfd) +		mdelay(5); +	else if (addr == 0xfc) +		mdelay(1); +	else if (addr == 0xfb) +		udelay(50); +	else if (addr == 0xfa) +		udelay(5); +	else if (addr == 0xf9) +		udelay(1); +} +EXPORT_SYMBOL(rtl_addr_delay); + +void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, +		     u32 mask, u32 data) +{ +	if (addr == 0xfe) { +		mdelay(50); +	} else if (addr == 0xfd) { +		mdelay(5); +	} else if (addr == 0xfc) { +		mdelay(1); +	} else if (addr == 0xfb) { +		udelay(50); +	} else if (addr == 0xfa) { +		udelay(5); +	} else if (addr == 0xf9) { +		udelay(1); +	} else { +		rtl_set_rfreg(hw, rfpath, addr, mask, data); +		udelay(1); +	} +} +EXPORT_SYMBOL(rtl_rfreg_delay); + +void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data) +{ +	if (addr == 0xfe) { +		mdelay(50); +	} else if (addr == 0xfd) { +		mdelay(5); +	} else if (addr == 0xfc) { +		mdelay(1); +	} else if (addr == 0xfb) { +		udelay(50); +	} else if (addr == 0xfa) { +		udelay(5); +	} else if (addr == 0xf9) { +		udelay(1); +	} else { +		rtl_set_bbreg(hw, addr, MASKDWORD, data); +		udelay(1); +	} +} +EXPORT_SYMBOL(rtl_bb_delay); +  void rtl_fw_cb(const struct firmware *firmware, void *context)  {  	struct ieee80211_hw *hw = context; @@ -46,10 +106,20 @@ void rtl_fw_cb(const struct firmware *firmware, void *context)  			 "Firmware callback routine entered!\n");  	complete(&rtlpriv->firmware_loading_complete);  	if (!firmware) { +		if (rtlpriv->cfg->alt_fw_name) { +			err = request_firmware(&firmware, +					       rtlpriv->cfg->alt_fw_name, +					       rtlpriv->io.dev); +			pr_info("Loading alternative firmware %s\n", +				rtlpriv->cfg->alt_fw_name); +			if (!err) +				goto found_alt; +		}  		pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);  		rtlpriv->max_fw_size = 0;  		return;  	} +found_alt:  	if (firmware->size > rtlpriv->max_fw_size) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 "Firmware is too big!\n"); @@ -115,7 +185,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw)  	mutex_lock(&rtlpriv->locks.conf_mutex);  	mac->link_state = MAC80211_NOLINK; -	memset(mac->bssid, 0, 6); +	memset(mac->bssid, 0, ETH_ALEN);  	mac->vendor = PEER_UNKNOWN;  	/*reset sec info */ @@ -184,6 +254,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,  					rtlpriv->cfg->maps  					[RTL_IBSS_INT_MASKS]);  		} +		mac->link_state = MAC80211_LINKED;  		break;  	case NL80211_IFTYPE_ADHOC:  		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, @@ -280,7 +351,7 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw,  	mac->p2p = 0;  	mac->vif = NULL;  	mac->link_state = MAC80211_NOLINK; -	memset(mac->bssid, 0, 6); +	memset(mac->bssid, 0, ETH_ALEN);  	mac->vendor = PEER_UNKNOWN;  	mac->opmode = NL80211_IFTYPE_UNSPECIFIED;  	rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); @@ -464,20 +535,40 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	u32 rx_conf;  	*new_flags &= RTL_SUPPORTED_FILTERS;  	if (!changed_flags)  		return; +	/* if ssid not set to hw don't check bssid +	 * here just used for linked scanning, & linked +	 * and nolink check bssid is set in set network_type */ +	if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) && +		(mac->link_state >= MAC80211_LINKED)) { +		if (mac->opmode != NL80211_IFTYPE_AP && +		    mac->opmode != NL80211_IFTYPE_MESH_POINT) { +			if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { +				rtlpriv->cfg->ops->set_chk_bssid(hw, false); +			} else { +				rtlpriv->cfg->ops->set_chk_bssid(hw, true); +			} +		} +	} + +	/* must be called after set_chk_bssid since that function modifies the +	 * RCR register too. */ +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(&rx_conf)); +  	/*TODO: we disable broadcase now, so enable here */  	if (changed_flags & FIF_ALLMULTI) {  		if (*new_flags & FIF_ALLMULTI) { -			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | +			rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |  			    rtlpriv->cfg->maps[MAC_RCR_AB];  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 "Enable receive multicast frame\n");  		} else { -			mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | +			rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |  					  rtlpriv->cfg->maps[MAC_RCR_AB]);  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 "Disable receive multicast frame\n"); @@ -486,39 +577,25 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,  	if (changed_flags & FIF_FCSFAIL) {  		if (*new_flags & FIF_FCSFAIL) { -			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; +			rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 "Enable receive FCS error frame\n");  		} else { -			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; +			rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 "Disable receive FCS error frame\n");  		}  	} -	/* if ssid not set to hw don't check bssid -	 * here just used for linked scanning, & linked -	 * and nolink check bssid is set in set network_type */ -	if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) && -		(mac->link_state >= MAC80211_LINKED)) { -		if (mac->opmode != NL80211_IFTYPE_AP && -		    mac->opmode != NL80211_IFTYPE_MESH_POINT) { -			if (*new_flags & FIF_BCN_PRBRESP_PROMISC) { -				rtlpriv->cfg->ops->set_chk_bssid(hw, false); -			} else { -				rtlpriv->cfg->ops->set_chk_bssid(hw, true); -			} -		} -	}  	if (changed_flags & FIF_CONTROL) {  		if (*new_flags & FIF_CONTROL) { -			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; +			rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 "Enable receive control frame\n");  		} else { -			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; +			rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 "Disable receive control frame\n");  		} @@ -526,15 +603,17 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,  	if (changed_flags & FIF_OTHER_BSS) {  		if (*new_flags & FIF_OTHER_BSS) { -			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; +			rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 "Enable receive other BSS's frame\n");  		} else { -			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; +			rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];  			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,  				 "Disable receive other BSS's frame\n");  		}  	} + +	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&rx_conf));  }  static int rtl_op_sta_add(struct ieee80211_hw *hw,  			 struct ieee80211_vif *vif, @@ -721,12 +800,17 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  			mac->link_state = MAC80211_LINKED;  			mac->cnt_after_linked = 0;  			mac->assoc_id = bss_conf->aid; -			memcpy(mac->bssid, bss_conf->bssid, 6); +			memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN);  			if (rtlpriv->cfg->ops->linked_set_reg)  				rtlpriv->cfg->ops->linked_set_reg(hw);  			rcu_read_lock();  			sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); +			if (!sta) { +				pr_err("ieee80211_find_sta returned NULL\n"); +				rcu_read_unlock(); +				goto out; +			}  			if (vif->type == NL80211_IFTYPE_STATION && sta)  				rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); @@ -750,7 +834,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  			if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)  				rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);  			mac->link_state = MAC80211_NOLINK; -			memset(mac->bssid, 0, 6); +			memset(mac->bssid, 0, ETH_ALEN);  			mac->vendor = PEER_UNKNOWN;  			if (rtlpriv->dm.supp_phymode_switch) { @@ -826,7 +910,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  			 bss_conf->bssid);  		mac->vendor = PEER_UNKNOWN; -		memcpy(mac->bssid, bss_conf->bssid, 6); +		memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN);  		rtlpriv->cfg->ops->set_network_type(hw, vif->type);  		rcu_read_lock(); @@ -881,7 +965,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  			mac->basic_rates = basic_rates;  			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, -					(u8 *) (&basic_rates)); +					(u8 *)(&basic_rates));  		}  		rcu_read_unlock();  	} @@ -895,6 +979,11 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,  		if (bss_conf->assoc) {  			if (ppsc->fwctrl_lps) {  				u8 mstatus = RT_MEDIA_CONNECT; +				u8 keep_alive = 10; +				rtlpriv->cfg->ops->set_hw_reg(hw, +						 HW_VAR_KEEP_ALIVE, +						 &keep_alive); +  				rtlpriv->cfg->ops->set_hw_reg(hw,  						      HW_VAR_H2C_FW_JOINBSSRPT,  						      &mstatus); @@ -1298,7 +1387,8 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)   * before switch channel or power save, or tx buffer packet   * maybe send after offchannel or rf sleep, this may cause   * dis-association by AP */ -static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) +static void rtl_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +			 u32 queues, bool drop)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 2fe46a1b4f1..027e75374dc 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -41,5 +41,9 @@  extern const struct ieee80211_ops rtl_ops;  void rtl_fw_cb(const struct firmware *firmware, void *context); +void rtl_addr_delay(u32 addr); +void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, +		     u32 mask, u32 data); +void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);  #endif diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 838a1ed3f19..2ffc7298f68 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -262,9 +262,9 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)  			    sizeof(u8), GFP_ATOMIC);  	if (!efuse_tbl)  		return; -	efuse_word = kmalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC); +	efuse_word = kzalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC);  	if (!efuse_word) -		goto done; +		goto out;  	for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {  		efuse_word[i] = kmalloc(efuse_max_section * sizeof(u16),  					GFP_ATOMIC); @@ -378,6 +378,7 @@ done:  	for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++)  		kfree(efuse_word[i]);  	kfree(efuse_word); +out:  	kfree(efuse_tbl);  } @@ -1203,20 +1204,18 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)  static u16 efuse_get_current_size(struct ieee80211_hw *hw)  { -	int continual = true;  	u16 efuse_addr = 0;  	u8 hworden;  	u8 efuse_data, word_cnts; -	while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) -	       && (efuse_addr < EFUSE_MAX_SIZE)) { -		if (efuse_data != 0xFF) { -			hworden = efuse_data & 0x0F; -			word_cnts = efuse_calculate_word_cnts(hworden); -			efuse_addr = efuse_addr + (word_cnts * 2) + 1; -		} else { -			continual = false; -		} +	while (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && +	       efuse_addr < EFUSE_MAX_SIZE) { +		if (efuse_data == 0xFF) +			break; + +		hworden = efuse_data & 0x0F; +		word_cnts = efuse_calculate_word_cnts(hworden); +		efuse_addr = efuse_addr + (word_cnts * 2) + 1;  	}  	return efuse_addr; diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 395a326acfb..1663b3afd41 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -104,20 +104,19 @@ struct efuse_priv {  	u8 tx_power_g[14];  }; -extern void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); -extern void efuse_initialize(struct ieee80211_hw *hw); -extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); -extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); -extern void read_efuse(struct ieee80211_hw *hw, u16 _offset, -		       u16 _size_byte, u8 *pbuf); -extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, -			      u16 offset, u32 *value); -extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, -			       u16 offset, u32 value); -extern bool efuse_shadow_update(struct ieee80211_hw *hw); -extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw); -extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); -extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); -extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); +void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); +void efuse_initialize(struct ieee80211_hw *hw); +u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); +void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); +void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf); +void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, u16 offset, +		       u32 *value); +void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, +			u32 value); +bool efuse_shadow_update(struct ieee80211_hw *hw); +bool efuse_shadow_update_chk(struct ieee80211_hw *hw); +void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); +void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); +void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);  #endif diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 703f839af6c..dae55257f0e 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -688,8 +688,6 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,  		rtlpriv->stats.rxbytesunicast += skb->len;  	} -	rtl_is_special_data(hw, skb, false); -  	if (ieee80211_is_data(fc)) {  		rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); @@ -736,11 +734,12 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)  	struct rtl_stats stats = {  		.signal = 0, -		.noise = -98,  		.rate = 0,  	};  	int index = rtlpci->rx_ring[rx_queue_idx].idx; +	if (rtlpci->driver_is_goingto_unload) +		return;  	/*RX NORMAL PKT */  	while (count--) {  		/*rx descriptor */ @@ -812,19 +811,19 @@ done:  		if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))  			return;  		tmp_one = 1; -		rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, +		rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false,  					    HW_DESC_RXBUFF_ADDR,  					    (u8 *)&bufferaddress); -		rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, +		rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false,  					    HW_DESC_RXPKT_LEN,  					    (u8 *)&rtlpci->rxbuffersize);  		if (index == rtlpci->rxringcount - 1) -			rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, +			rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false,  						    HW_DESC_RXERO,  						    &tmp_one); -		rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, +		rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, false, HW_DESC_RXOWN,  					    &tmp_one);  		index = (index + 1) % rtlpci->rxringcount; @@ -984,6 +983,8 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)  	struct sk_buff *pskb = NULL;  	struct rtl_tx_desc *pdesc = NULL;  	struct rtl_tcb_desc tcb_desc; +	/*This is for new trx flow*/ +	struct rtl_tx_buffer_desc *pbuffer_desc = NULL;  	u8 temp_one = 1;  	memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); @@ -1005,11 +1006,12 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)  	info = IEEE80211_SKB_CB(pskb);  	pdesc = &ring->desc[0];  	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, -		info, NULL, pskb, BEACON_QUEUE, &tcb_desc); +					(u8 *)pbuffer_desc, info, NULL, pskb, +					BEACON_QUEUE, &tcb_desc);  	__skb_queue_tail(&ring->queue, pskb); -	rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN, +	rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN,  				    &temp_one);  	return; @@ -1067,7 +1069,7 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,  	mac->current_ampdu_factor = 3;  	/*QOS*/ -	rtlpci->acm_method = eAcmWay2_SW; +	rtlpci->acm_method = EACMWAY2_SW;  	/*task */  	tasklet_init(&rtlpriv->works.irq_tasklet, @@ -1114,7 +1116,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,  					      ((i + 1) % entries) *  					      sizeof(*ring); -		rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), +		rtlpriv->cfg->ops->set_desc(hw, (u8 *)&(ring[i]),  					    true, HW_DESC_TX_NEXTDESC_ADDR,  					    (u8 *)&nextdescaddress);  	} @@ -1189,19 +1191,19 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)  				dev_kfree_skb_any(skb);  				return 1;  			} -			rtlpriv->cfg->ops->set_desc((u8 *)entry, false, +			rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,  						    HW_DESC_RXBUFF_ADDR,  						    (u8 *)&bufferaddress); -			rtlpriv->cfg->ops->set_desc((u8 *)entry, false, +			rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,  						    HW_DESC_RXPKT_LEN,  						    (u8 *)&rtlpci->  						    rxbuffersize); -			rtlpriv->cfg->ops->set_desc((u8 *) entry, false, +			rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,  						    HW_DESC_RXOWN,  						    &tmp_one);  		} -		rtlpriv->cfg->ops->set_desc((u8 *) entry, false, +		rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,  					    HW_DESC_RXERO, &tmp_one);  	}  	return 0; @@ -1332,7 +1334,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)  			for (i = 0; i < rtlpci->rxringcount; i++) {  				entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; -				rtlpriv->cfg->ops->set_desc((u8 *) entry, +				rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry,  							    false,  							    HW_DESC_RXOWN,  							    &tmp_one); @@ -1425,6 +1427,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);  	struct rtl8192_tx_ring *ring;  	struct rtl_tx_desc *pdesc; +	struct rtl_tx_buffer_desc *ptx_bd_desc = NULL;  	u8 idx;  	u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb);  	unsigned long flags; @@ -1465,17 +1468,22 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,  		idx = 0;  	pdesc = &ring->desc[idx]; -	own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, -			true, HW_DESC_OWN); +	if (rtlpriv->use_new_trx_flow) { +		ptx_bd_desc = &ring->buffer_desc[idx]; +	} else { +		own = (u8) rtlpriv->cfg->ops->get_desc((u8 *)pdesc, +				true, HW_DESC_OWN); -	if ((own == 1) && (hw_queue != BEACON_QUEUE)) { -		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, -			 "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", -			 hw_queue, ring->idx, idx, -			 skb_queue_len(&ring->queue)); +		if ((own == 1) && (hw_queue != BEACON_QUEUE)) { +			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +				 "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", +				 hw_queue, ring->idx, idx, +				 skb_queue_len(&ring->queue)); -		spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); -		return skb->len; +			spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, +					       flags); +			return skb->len; +		}  	}  	if (ieee80211_is_data_qos(fc)) { @@ -1495,17 +1503,20 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,  		rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);  	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, -			info, sta, skb, hw_queue, ptcb_desc); +			(u8 *)ptx_bd_desc, info, sta, skb, hw_queue, ptcb_desc);  	__skb_queue_tail(&ring->queue, skb); -	rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true, -				    HW_DESC_OWN, &temp_one); - +	if (rtlpriv->use_new_trx_flow) { +		rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, +					    HW_DESC_OWN, &hw_queue); +	} else { +		rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, +					    HW_DESC_OWN, &temp_one); +	}  	if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&  	    hw_queue != BEACON_QUEUE) { -  		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,  			 "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n",  			 hw_queue, ring->idx, idx, @@ -1637,6 +1648,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)  	 */  	set_hal_stop(rtlhal); +	rtlpci->driver_is_goingto_unload = true;  	rtlpriv->cfg->ops->disable_interrupt(hw);  	cancel_work_sync(&rtlpriv->works.lps_change_work); @@ -1654,7 +1666,6 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)  	ppsc->rfchange_inprogress = true;  	spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags); -	rtlpci->driver_is_goingto_unload = true;  	rtlpriv->cfg->ops->hw_disable(hw);  	/* some things are not needed if firmware not available */  	if (!rtlpriv->max_fw_size) @@ -1842,6 +1853,65 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,  	return true;  } +static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); +	int ret; + +	ret = pci_enable_msi(rtlpci->pdev); +	if (ret < 0) +		return ret; + +	ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, +			  IRQF_SHARED, KBUILD_MODNAME, hw); +	if (ret < 0) { +		pci_disable_msi(rtlpci->pdev); +		return ret; +	} + +	rtlpci->using_msi = true; + +	RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG, +		 "MSI Interrupt Mode!\n"); +	return 0; +} + +static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); +	int ret; + +	ret = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, +			  IRQF_SHARED, KBUILD_MODNAME, hw); +	if (ret < 0) +		return ret; + +	rtlpci->using_msi = false; +	RT_TRACE(rtlpriv, COMP_INIT|COMP_INTR, DBG_DMESG, +		 "Pin-based Interrupt Mode!\n"); +	return 0; +} + +static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw) +{ +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); +	int ret; + +	if (rtlpci->msi_support) { +		ret = rtl_pci_intr_mode_msi(hw); +		if (ret < 0) +			ret = rtl_pci_intr_mode_legacy(hw); +	} else { +		ret = rtl_pci_intr_mode_legacy(hw); +	} +	return ret; +} +  int rtl_pci_probe(struct pci_dev *pdev,  			    const struct pci_device_id *id)  { @@ -1984,8 +2054,7 @@ int rtl_pci_probe(struct pci_dev *pdev,  	}  	rtlpci = rtl_pcidev(pcipriv); -	err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, -			  IRQF_SHARED, KBUILD_MODNAME, hw); +	err = rtl_pci_intr_mode_decide(hw);  	if (err) {  		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,  			 "%s: failed to register IRQ handler\n", @@ -2009,7 +2078,6 @@ fail2:  fail1:  	if (hw)  		ieee80211_free_hw(hw); -	pci_set_drvdata(pdev, NULL);  	pci_disable_device(pdev);  	return err; @@ -2054,6 +2122,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev)  		rtlpci->irq_alloc = 0;  	} +	if (rtlpci->using_msi) +		pci_disable_msi(rtlpci->pdev); +  	list_del(&rtlpriv->list);  	if (rtlpriv->io.pci_mem_start != 0) {  		pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); @@ -2064,8 +2135,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev)  	rtl_pci_disable_aspm(hw); -	pci_set_drvdata(pdev, NULL); -  	ieee80211_free_hw(hw);  }  EXPORT_SYMBOL(rtl_pci_disconnect); diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index d3262ec45d2..90174a814a6 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -137,12 +137,22 @@ struct rtl_tx_cmd_desc {  	u32 dword[16];  } __packed; +/* In new TRX flow, Buffer_desc is new concept + * But TX wifi info == TX descriptor in old flow + * RX wifi info == RX descriptor in old flow + */ +struct rtl_tx_buffer_desc { +	u32 dword[8]; /*seg = 4*/ +} __packed; +  struct rtl8192_tx_ring {  	struct rtl_tx_desc *desc;  	dma_addr_t dma;  	unsigned int idx;  	unsigned int entries;  	struct sk_buff_head queue; +	/*add for new trx flow*/ +	struct rtl_tx_buffer_desc *buffer_desc; /*tx buffer descriptor*/  };  struct rtl8192_rx_ring { @@ -199,6 +209,10 @@ struct rtl_pci {  	u16 shortretry_limit;  	u16 longretry_limit; + +	/* MSI support */ +	bool msi_support; +	bool using_msi;  };  struct mp_adapter { diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 0d81f766fd0..50504942ded 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -32,6 +32,106 @@  #include "base.h"  #include "ps.h" +/*	Description: + *		This routine deals with the Power Configuration CMD + *		 parsing for RTL8723/RTL8188E Series IC. + *	Assumption: + *		We should follow specific format that was released from HW SD. + */ +bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, +			      u8 faversion, u8 interface_type, +			      struct wlan_pwr_cfg pwrcfgcmd[]) +{ +	struct wlan_pwr_cfg cfg_cmd = {0}; +	bool polling_bit = false; +	u32 ary_idx = 0; +	u8 value = 0; +	u32 offset = 0; +	u32 polling_count = 0; +	u32 max_polling_cnt = 5000; + +	do { +		cfg_cmd = pwrcfgcmd[ary_idx]; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +			"rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x)," +			"interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", +			GET_PWR_CFG_OFFSET(cfg_cmd), +					   GET_PWR_CFG_CUT_MASK(cfg_cmd), +			GET_PWR_CFG_FAB_MASK(cfg_cmd), +					     GET_PWR_CFG_INTF_MASK(cfg_cmd), +			GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), +			GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); + +		if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) && +		    (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) && +		    (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) { +			switch (GET_PWR_CFG_CMD(cfg_cmd)) { +			case PWR_CMD_READ: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"); +				break; +			case PWR_CMD_WRITE: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n"); +				offset = GET_PWR_CFG_OFFSET(cfg_cmd); + +				/*Read the value from system register*/ +				value = rtl_read_byte(rtlpriv, offset); +				value &= (~(GET_PWR_CFG_MASK(cfg_cmd))); +				value |= (GET_PWR_CFG_VALUE(cfg_cmd) & +					  GET_PWR_CFG_MASK(cfg_cmd)); + +				/*Write the value back to sytem register*/ +				rtl_write_byte(rtlpriv, offset, value); +				break; +			case PWR_CMD_POLLING: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"); +				polling_bit = false; +				offset = GET_PWR_CFG_OFFSET(cfg_cmd); + +				do { +					value = rtl_read_byte(rtlpriv, offset); + +					value &= GET_PWR_CFG_MASK(cfg_cmd); +					if (value == +					    (GET_PWR_CFG_VALUE(cfg_cmd) +					    & GET_PWR_CFG_MASK(cfg_cmd))) +						polling_bit = true; +					else +						udelay(10); + +					if (polling_count++ > max_polling_cnt) +						return false; +				} while (!polling_bit); +				break; +			case PWR_CMD_DELAY: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					"rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n"); +				if (GET_PWR_CFG_VALUE(cfg_cmd) == +				    PWRSEQ_DELAY_US) +					udelay(GET_PWR_CFG_OFFSET(cfg_cmd)); +				else +					mdelay(GET_PWR_CFG_OFFSET(cfg_cmd)); +				break; +			case PWR_CMD_END: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					 "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n"); +				return true; +			default: +				RT_ASSERT(false, +					 "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n"); +				break; +			} + +		} +		ary_idx++; +	} while (1); + +	return true; +} +EXPORT_SYMBOL(rtl_hal_pwrseqcmdparsing); +  bool rtl_ps_enable_nic(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -48,7 +148,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)  	/*<2> Enable Adapter */  	if (rtlpriv->cfg->ops->hw_init(hw)) -		return 1; +		return false;  	RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);  	/*<3> Enable Interrupt */ @@ -478,7 +578,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)  		return;  	/* and only beacons from the associated BSSID, please */ -	if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) +	if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))  		return;  	rtlpriv->psc.last_beacon = jiffies; @@ -659,7 +759,7 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data,  			   unsigned int len)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct ieee80211_mgmt *mgmt = (void *)data; +	struct ieee80211_mgmt *mgmt = data;  	struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);  	u8 *pos, *end, *ie;  	u16 noa_len; @@ -758,7 +858,7 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data,  			      unsigned int len)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct ieee80211_mgmt *mgmt = (void *)data; +	struct ieee80211_mgmt *mgmt = data;  	struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info);  	u8 noa_num, index, i, noa_index = 0;  	u8 *pos, *end, *ie; @@ -850,9 +950,8 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  	switch (p2p_ps_state) {  	case P2P_PS_DISABLE:  		p2pinfo->p2p_ps_state = p2p_ps_state; -		rtlpriv->cfg->ops->set_hw_reg(hw, -				 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, -				 (u8 *)(&p2p_ps_state)); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, +					      &p2p_ps_state);  		p2pinfo->noa_index = 0;  		p2pinfo->ctwindow = 0; @@ -864,7 +963,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  				rtlps->smart_ps = 2;  				rtlpriv->cfg->ops->set_hw_reg(hw,  					 HW_VAR_H2C_FW_PWRMODE, -					 (u8 *)(&rtlps->pwr_mode)); +					 &rtlps->pwr_mode);  			}  		}  		break; @@ -877,12 +976,12 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  					rtlps->smart_ps = 0;  					rtlpriv->cfg->ops->set_hw_reg(hw,  						 HW_VAR_H2C_FW_PWRMODE, -						 (u8 *)(&rtlps->pwr_mode)); +						 &rtlps->pwr_mode);  				}  			}  			rtlpriv->cfg->ops->set_hw_reg(hw,  				 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, -				 (u8 *)(&p2p_ps_state)); +				 &p2p_ps_state);  		}  		break;  	case P2P_PS_SCAN: @@ -892,7 +991,7 @@ void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  			p2pinfo->p2p_ps_state = p2p_ps_state;  			rtlpriv->cfg->ops->set_hw_reg(hw,  				 HW_VAR_H2C_FW_P2P_PS_OFFLOAD, -				 (u8 *)(&p2p_ps_state)); +				 &p2p_ps_state);  		}  		break;  	default: @@ -912,7 +1011,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	struct ieee80211_hdr *hdr = (void *)data; +	struct ieee80211_hdr *hdr = data;  	if (!mac->p2p)  		return; @@ -923,7 +1022,7 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)  		return;  	/* and only beacons from the associated BSSID, please */ -	if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid)) +	if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid))  		return;  	/* check if this really is a beacon */ diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index 88bd76ea88f..3bd41f95897 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h @@ -32,6 +32,66 @@  #define MAX_SW_LPS_SLEEP_INTV	5 +/*--------------------------------------------- + * 3 The value of cmd: 4 bits + *--------------------------------------------- + */ +#define    PWR_CMD_READ		0x00 +#define    PWR_CMD_WRITE	0x01 +#define    PWR_CMD_POLLING	0x02 +#define    PWR_CMD_DELAY	0x03 +#define    PWR_CMD_END		0x04 + +/* define the base address of each block */ +#define	PWR_BASEADDR_MAC	0x00 +#define	PWR_BASEADDR_USB	0x01 +#define	PWR_BASEADDR_PCIE	0x02 +#define	PWR_BASEADDR_SDIO	0x03 + +#define	PWR_FAB_ALL_MSK		(BIT(0)|BIT(1)|BIT(2)|BIT(3)) +#define	PWR_CUT_TESTCHIP_MSK	BIT(0) +#define	PWR_CUT_A_MSK		BIT(1) +#define	PWR_CUT_B_MSK		BIT(2) +#define	PWR_CUT_C_MSK		BIT(3) +#define	PWR_CUT_D_MSK		BIT(4) +#define	PWR_CUT_E_MSK		BIT(5) +#define	PWR_CUT_F_MSK		BIT(6) +#define	PWR_CUT_G_MSK		BIT(7) +#define	PWR_CUT_ALL_MSK		0xFF +#define PWR_INTF_SDIO_MSK	BIT(0) +#define PWR_INTF_USB_MSK	BIT(1) +#define PWR_INTF_PCI_MSK	BIT(2) +#define PWR_INTF_ALL_MSK	(BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +enum pwrseq_delay_unit { +	PWRSEQ_DELAY_US, +	PWRSEQ_DELAY_MS, +}; + +struct wlan_pwr_cfg { +	u16 offset; +	u8 cut_msk; +	u8 fab_msk:4; +	u8 interface_msk:4; +	u8 base:4; +	u8 cmd:4; +	u8 msk; +	u8 value; +}; + +#define	GET_PWR_CFG_OFFSET(__PWR_CMD)	(__PWR_CMD.offset) +#define	GET_PWR_CFG_CUT_MASK(__PWR_CMD)	(__PWR_CMD.cut_msk) +#define	GET_PWR_CFG_FAB_MASK(__PWR_CMD)	(__PWR_CMD.fab_msk) +#define	GET_PWR_CFG_INTF_MASK(__PWR_CMD)	(__PWR_CMD.interface_msk) +#define	GET_PWR_CFG_BASE(__PWR_CMD)	(__PWR_CMD.base) +#define	GET_PWR_CFG_CMD(__PWR_CMD)	(__PWR_CMD.cmd) +#define	GET_PWR_CFG_MASK(__PWR_CMD)	(__PWR_CMD.msk) +#define	GET_PWR_CFG_VALUE(__PWR_CMD)	(__PWR_CMD.value) + +bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, +			      u8 fab_version, u8 interface_type, +			      struct wlan_pwr_cfg pwrcfgcmd[]); +  bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,  			 enum rf_pwrstate state_toset, u32 changesource);  bool rtl_ps_enable_nic(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index a98acefb8c0..ee28a1a3d01 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -260,8 +260,7 @@ static void rtl_rate_free_sta(void *rtlpriv,  	kfree(rate_priv);  } -static struct rate_control_ops rtl_rate_ops = { -	.module = NULL, +static const struct rate_control_ops rtl_rate_ops = {  	.name = "rtl_rc",  	.alloc = rtl_rate_alloc,  	.free = rtl_rate_free, diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index d7d0d4948b0..a4eb9b27143 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -59,30 +59,26 @@ static struct country_code_to_enum_rd allCountries[] = {   */  #define RTL819x_2GHZ_CH12_13	\  	REG_RULE(2467-10, 2472+10, 40, 0, 20,\ -	NL80211_RRF_PASSIVE_SCAN) +		 NL80211_RRF_NO_IR)  #define RTL819x_2GHZ_CH14	\  	REG_RULE(2484-10, 2484+10, 40, 0, 20, \ -	NL80211_RRF_PASSIVE_SCAN | \ -	NL80211_RRF_NO_OFDM) +		 NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM)  /* 5G chan 36 - chan 64*/  #define RTL819x_5GHZ_5150_5350	\  	REG_RULE(5150-10, 5350+10, 40, 0, 30, \ -	NL80211_RRF_PASSIVE_SCAN | \ -	NL80211_RRF_NO_IBSS) +		 NL80211_RRF_NO_IR)  /* 5G chan 100 - chan 165*/  #define RTL819x_5GHZ_5470_5850	\  	REG_RULE(5470-10, 5850+10, 40, 0, 30, \ -	NL80211_RRF_PASSIVE_SCAN | \ -	NL80211_RRF_NO_IBSS) +		 NL80211_RRF_NO_IR)  /* 5G chan 149 - chan 165*/  #define RTL819x_5GHZ_5725_5850	\  	REG_RULE(5725-10, 5850+10, 40, 0, 30, \ -	NL80211_RRF_PASSIVE_SCAN | \ -	NL80211_RRF_NO_IBSS) +		 NL80211_RRF_NO_IR)  #define RTL819x_5GHZ_ALL	\  	(RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) @@ -172,7 +168,8 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,  			    (ch->flags & IEEE80211_CHAN_RADAR))  				continue;  			if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { -				reg_rule = freq_reg_info(wiphy, ch->center_freq); +				reg_rule = freq_reg_info(wiphy, +							 MHZ_TO_KHZ(ch->center_freq));  				if (IS_ERR(reg_rule))  					continue; @@ -185,16 +182,11 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,  				 *regulatory_hint().  				 */ -				if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) -					ch->flags &= ~IEEE80211_CHAN_NO_IBSS; -				if (!(reg_rule-> -				     flags & NL80211_RRF_PASSIVE_SCAN)) -					ch->flags &= -					    ~IEEE80211_CHAN_PASSIVE_SCAN; +				if (!(reg_rule->flags & NL80211_RRF_NO_IR)) +					ch->flags &= ~IEEE80211_CHAN_NO_IR;  			} else {  				if (ch->beacon_found) -					ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | -						  IEEE80211_CHAN_PASSIVE_SCAN); +					ch->flags &= ~IEEE80211_CHAN_NO_IR;  			}  		}  	} @@ -219,11 +211,11 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,  	 */  	if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {  		ch = &sband->channels[11];	/* CH 12 */ -		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) -			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; +		if (ch->flags & IEEE80211_CHAN_NO_IR) +			ch->flags &= ~IEEE80211_CHAN_NO_IR;  		ch = &sband->channels[12];	/* CH 13 */ -		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) -			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; +		if (ch->flags & IEEE80211_CHAN_NO_IR) +			ch->flags &= ~IEEE80211_CHAN_NO_IR;  		return;  	} @@ -235,19 +227,19 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,  	 */  	ch = &sband->channels[11];	/* CH 12 */ -	reg_rule = freq_reg_info(wiphy, ch->center_freq); +	reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));  	if (!IS_ERR(reg_rule)) { -		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) -			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) -				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; +		if (!(reg_rule->flags & NL80211_RRF_NO_IR)) +			if (ch->flags & IEEE80211_CHAN_NO_IR) +				ch->flags &= ~IEEE80211_CHAN_NO_IR;  	}  	ch = &sband->channels[12];	/* CH 13 */ -	reg_rule = freq_reg_info(wiphy, ch->center_freq); +	reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));  	if (!IS_ERR(reg_rule)) { -		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) -			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) -				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; +		if (!(reg_rule->flags & NL80211_RRF_NO_IR)) +			if (ch->flags & IEEE80211_CHAN_NO_IR) +				ch->flags &= ~IEEE80211_CHAN_NO_IR;  	}  } @@ -284,8 +276,7 @@ static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)  		 */  		if (!(ch->flags & IEEE80211_CHAN_DISABLED))  			ch->flags |= IEEE80211_CHAN_RADAR | -			    IEEE80211_CHAN_NO_IBSS | -			    IEEE80211_CHAN_PASSIVE_SCAN; +				     IEEE80211_CHAN_NO_IR;  	}  } @@ -354,9 +345,9 @@ static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,  	wiphy->reg_notifier = reg_notifier; -	wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; -	wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; -	wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; +	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; +	wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; +	wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;  	regd = _rtl_regdomain_select(reg);  	wiphy_apply_custom_regulatory(wiphy, regd); diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile b/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile index 5b194e97f4b..a85419a3765 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/Makefile @@ -5,7 +5,6 @@ rtl8188ee-objs :=		\  		led.o		\  		phy.o		\  		pwrseq.o	\ -		pwrseqcmd.o	\  		rf.o		\  		sw.o		\  		table.o		\ diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c index 21a5cf06067..f8daa61cf1c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c @@ -235,7 +235,7 @@ void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,  	u8 pwr_val = 0;  	u8 cck_base = rtldm->swing_idx_cck_base;  	u8 cck_val = rtldm->swing_idx_cck; -	u8 ofdm_base = rtldm->swing_idx_ofdm_base; +	u8 ofdm_base = rtldm->swing_idx_ofdm_base[0];  	u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];  	if (type == 0) { @@ -726,7 +726,7 @@ static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw)  	static u64 last_rx;  	long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff; -	if (rtlhal->oem_id == RT_CID_819x_HP) { +	if (rtlhal->oem_id == RT_CID_819X_HP) {  		u64 cur_txok_cnt = 0;  		u64 cur_rxok_cnt = 0;  		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok; @@ -851,9 +851,8 @@ static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)  	} else {  		if (rtlpriv->dm.current_turbo_edca) {  			u8 tmp = AC0_BE; -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_AC_PARAM, -						      (u8 *)(&tmp)); +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, +						      &tmp);  			rtlpriv->dm.current_turbo_edca = false;  		}  	} @@ -912,7 +911,7 @@ static void rtl88e_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_old[0] = (u8) i; -			rtldm->swing_idx_ofdm_base = (u8)i; +			rtldm->swing_idx_ofdm_base[0] = (u8)i;  			RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,  				 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",  				 ROFDM0_XATXIQIMBAL, @@ -1078,7 +1077,7 @@ static void rtl88e_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw  				rtldm->swing_flag_ofdm = true;  			} -			if (rtldm->swing_idx_cck != rtldm->swing_idx_cck) { +			if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {  				rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;  				rtldm->swing_flag_cck = true;  			} diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c index 557bc5b8327..4f9376ad473 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/fw.c @@ -119,7 +119,7 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw,  			     enum version_8188e version, u8 *buffer, u32 size)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	u8 *buf_ptr = (u8 *)buffer; +	u8 *buf_ptr = buffer;  	u32 page_no, remain;  	u32 page, offset; @@ -213,7 +213,7 @@ int rtl88e_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)  		return 1;  	pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; -	pfwdata = (u8 *)rtlhal->pfirmware; +	pfwdata = rtlhal->pfirmware;  	fwsize = rtlhal->fwsize;  	RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,  		 "normal Firmware SIZE %d\n", fwsize); diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c index b68cae3024f..b14cf5a10f4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c @@ -41,7 +41,6 @@  #include "fw.h"  #include "led.h"  #include "hw.h" -#include "pwrseqcmd.h"  #include "pwrseq.h"  #define LLT_CONFIG		5 @@ -143,12 +142,12 @@ static void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw,  		} else {  			rtlhal->fw_clk_change_in_progress = false;  			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +			break;  		}  	}  	if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) { -		rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, -					      (u8 *)(&rpwm_val)); +		rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);  		if (FW_PS_IS_ACK(rpwm_val)) {  			isr_regaddr = REG_HISR;  			content = rtl_read_dword(rtlpriv, isr_regaddr); @@ -225,7 +224,7 @@ static void _rtl88ee_set_fw_clock_off(struct ieee80211_hw *hw,  			rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);  			rtl_write_word(rtlpriv, REG_HISR, 0x0100);  			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, -						      (u8 *)(&rpwm_val)); +						      &rpwm_val);  			spin_lock_bh(&rtlpriv->locks.fw_ps_lock);  			rtlhal->fw_clk_change_in_progress = false;  			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); @@ -273,15 +272,14 @@ static void _rtl88ee_fwlps_leave(struct ieee80211_hw *hw)  		_rtl88ee_set_fw_clock_on(hw, rpwm_val, false);  		rtlhal->allow_sw_to_change_hwclc = false;  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, -					      (u8 *)(&fw_pwrmode)); +					      &fw_pwrmode);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,  					      (u8 *)(&fw_current_inps));  	} else {  		rpwm_val = FW_PS_STATE_ALL_ON_88E;	/* RF on */ -		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, -					      (u8 *)(&rpwm_val)); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, -					      (u8 *)(&fw_pwrmode)); +					      &fw_pwrmode);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,  					      (u8 *)(&fw_current_inps));  	} @@ -300,7 +298,7 @@ static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw)  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,  					      (u8 *)(&fw_current_inps));  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, -					      (u8 *)(&ppsc->fwctrl_psmode)); +					      &ppsc->fwctrl_psmode);  		rtlhal->allow_sw_to_change_hwclc = true;  		_rtl88ee_set_fw_clock_off(hw, rpwm_val);  	} else { @@ -308,9 +306,8 @@ static void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw)  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,  					      (u8 *)(&fw_current_inps));  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, -					      (u8 *)(&ppsc->fwctrl_psmode)); -		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, -					      (u8 *)(&rpwm_val)); +					      &ppsc->fwctrl_psmode); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);  	}  } @@ -419,12 +416,12 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		for (e_aci = 0; e_aci < AC_MAX; e_aci++) {  			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, -						      (u8 *)(&e_aci)); +						      &e_aci);  		}  		break; }  	case HW_VAR_ACK_PREAMBLE:{  		u8 reg_tmp; -		u8 short_preamble = (bool) (*(u8 *)val); +		u8 short_preamble = (bool)*val;  		reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2);  		if (short_preamble) {  			reg_tmp |= 0x02; @@ -435,13 +432,13 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		}  		break; }  	case HW_VAR_WPA_CONFIG: -		rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); +		rtl_write_byte(rtlpriv, REG_SECCFG, *val);  		break;  	case HW_VAR_AMPDU_MIN_SPACE:{  		u8 min_spacing_to_set;  		u8 sec_min_space; -		min_spacing_to_set = *((u8 *)val); +		min_spacing_to_set = *val;  		if (min_spacing_to_set <= 7) {  			sec_min_space = 0; @@ -464,7 +461,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  	case HW_VAR_SHORTGI_DENSITY:{  		u8 density_to_set; -		density_to_set = *((u8 *)val); +		density_to_set = *val;  		mac->min_space_cfg |= (density_to_set << 3);  		RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, @@ -482,7 +479,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		reg = regtoset_normal; -		factor = *((u8 *)val); +		factor = *val;  		if (factor <= 3) {  			factor = (1 << (factor + 2));  			if (factor > 0xf) @@ -505,15 +502,15 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		}  		break; }  	case HW_VAR_AC_PARAM:{ -		u8 e_aci = *((u8 *)val); +		u8 e_aci = *val;  		rtl88e_dm_init_edca_turbo(hw); -		if (rtlpci->acm_method != eAcmWay2_SW) +		if (rtlpci->acm_method != EACMWAY2_SW)  			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, -						      (u8 *)(&e_aci)); +						      &e_aci);  		break; }  	case HW_VAR_ACM_CTRL:{ -		u8 e_aci = *((u8 *)val); +		u8 e_aci = *val;  		union aci_aifsn *p_aci_aifsn =  		    (union aci_aifsn *)(&(mac->ac[0].aifs));  		u8 acm = p_aci_aifsn->f.acm; @@ -566,7 +563,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		rtlpci->receive_config = ((u32 *)(val))[0];  		break;  	case HW_VAR_RETRY_LIMIT:{ -		u8 retry_limit = ((u8 *)(val))[0]; +		u8 retry_limit = *val;  		rtl_write_word(rtlpriv, REG_RL,  			       retry_limit << RETRY_LIMIT_SHORT_SHIFT | @@ -579,7 +576,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		rtlefuse->efuse_usedbytes = *((u16 *)val);  		break;  	case HW_VAR_EFUSE_USAGE: -		rtlefuse->efuse_usedpercentage = *((u8 *)val); +		rtlefuse->efuse_usedpercentage = *val;  		break;  	case HW_VAR_IO_CMD:  		rtl88e_phy_set_io_cmd(hw, (*(enum io_type *)val)); @@ -591,15 +588,13 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		udelay(1);  		if (rpwm_val & BIT(7)) { -			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, -				       (*(u8 *)val)); +			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);  		} else { -			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, -				       ((*(u8 *)val) | BIT(7))); +			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));  		}  		break; }  	case HW_VAR_H2C_FW_PWRMODE: -		rtl88e_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); +		rtl88e_set_fw_pwrmode_cmd(hw, *val);  		break;  	case HW_VAR_FW_PSMODE_STATUS:  		ppsc->fw_current_inpsmode = *((bool *)val); @@ -616,7 +611,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			_rtl88ee_fwlps_leave(hw);  		 break; }  	case HW_VAR_H2C_FW_JOINBSSRPT:{ -		u8 mstatus = (*(u8 *)val); +		u8 mstatus = *val;  		u8 tmp, tmp_reg422, uval;  		u8 count = 0, dlbcn_count = 0;  		bool recover = false; @@ -667,10 +662,10 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			}  			rtl_write_byte(rtlpriv, REG_CR + 1, (tmp & ~(BIT(0))));  		} -		rtl88e_set_fw_joinbss_report_cmd(hw, (*(u8 *)val)); +		rtl88e_set_fw_joinbss_report_cmd(hw, *val);  		break; }  	case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: -		rtl88e_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); +		rtl88e_set_p2p_ps_offload_cmd(hw, *val);  		break;  	case HW_VAR_AID:{  		u16 u2btmp; @@ -680,7 +675,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			       mac->assoc_id));  		break; }  	case HW_VAR_CORRECT_TSF:{ -		u8 btype_ibss = ((u8 *)(val))[0]; +		u8 btype_ibss = *val;  		if (btype_ibss == true)  			_rtl88ee_stop_tx_beacon(hw); @@ -814,11 +809,11 @@ static bool _rtl88ee_init_mac(struct ieee80211_hw *hw)  	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);  	/* HW Power on sequence */ -	if (!rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, -					PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, -					Rtl8188E_NIC_ENABLE_FLOW)) { +	if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, +				      PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, +				      Rtl8188E_NIC_ENABLE_FLOW)) {  		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, -			 "init MAC Fail as rtl88_hal_pwrseqcmdparsing\n"); +			 "init MAC Fail as rtl_hal_pwrseqcmdparsing\n");  		return false;  	} @@ -1024,9 +1019,20 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)  	bool rtstatus = true;  	int err = 0;  	u8 tmp_u1b, u1byte; +	unsigned long flags;  	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Rtl8188EE hw init\n");  	rtlpriv->rtlhal.being_init_adapter = true; +	/* As this function can take a very long time (up to 350 ms) +	 * and can be called with irqs disabled, reenable the irqs +	 * to let the other devices continue being serviced. +	 * +	 * It is safe doing so since our own interrupts will only be enabled +	 * in a subsequent step. +	 */ +	local_save_flags(flags); +	local_irq_enable(); +  	rtlpriv->intf_ops->disable_aspm(hw);  	tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1); @@ -1042,7 +1048,7 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)  	if (rtstatus != true) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");  		err = 1; -		return err; +		goto exit;  	}  	err = rtl88e_download_fw(hw, false); @@ -1050,8 +1056,7 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  			 "Failed to download FW. Init HW without FW now..\n");  		err = 1; -		rtlhal->fw_ready = false; -		return err; +		goto exit;  	} else {  		rtlhal->fw_ready = true;  	} @@ -1096,7 +1101,7 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)  	if (ppsc->rfpwr_state == ERFON) {  		if ((rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) ||  		    ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) && -		    (rtlhal->oem_id == RT_CID_819x_HP))) { +		    (rtlhal->oem_id == RT_CID_819X_HP))) {  			rtl88e_phy_set_rfpath_switch(hw, true);  			rtlpriv->dm.fat_table.rx_idle_ant = MAIN_ANT;  		} else { @@ -1134,10 +1139,12 @@ int rtl88ee_hw_init(struct ieee80211_hw *hw)  	}  	rtl_write_byte(rtlpriv, REG_NAV_CTRL+2,  ((30000+127)/128));  	rtl88e_dm_init(hw); +exit: +	local_irq_restore(flags);  	rtlpriv->rtlhal.being_init_adapter = false;  	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "end of Rtl8188EE hw init %x\n",  		 err); -	return 0; +	return err;  }  static enum version_8188e _rtl88ee_read_chip_version(struct ieee80211_hw *hw) @@ -1234,12 +1241,13 @@ static int _rtl88ee_set_media_status(struct ieee80211_hw *hw,  void rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); -	u32 reg_rcr = rtlpci->receive_config; +	u32 reg_rcr;  	if (rtlpriv->psc.rfpwr_state != ERFON)  		return; +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); +  	if (check_bssid == true) {  		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, @@ -1344,9 +1352,9 @@ static void _rtl88ee_poweroff_adapter(struct ieee80211_hw *hw)  	}  	rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0xFF); -	rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, -				   PWR_INTF_PCI_MSK, -				   Rtl8188E_NIC_LPS_ENTER_FLOW); +	rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, +				 PWR_INTF_PCI_MSK, +				 Rtl8188E_NIC_LPS_ENTER_FLOW);  	rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); @@ -1360,8 +1368,8 @@ static void _rtl88ee_poweroff_adapter(struct ieee80211_hw *hw)  	u1b_tmp = rtl_read_byte(rtlpriv, REG_32K_CTRL);  	rtl_write_byte(rtlpriv, REG_32K_CTRL, (u1b_tmp & (~BIT(0)))); -	rtl88_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, -				   PWR_INTF_PCI_MSK, Rtl8188E_NIC_DISABLE_FLOW); +	rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, +				 PWR_INTF_PCI_MSK, Rtl8188E_NIC_DISABLE_FLOW);  	u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);  	rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(3)))); @@ -1815,7 +1823,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)  	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,  		 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);  	/*customer ID*/ -	rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; +	rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];  	if (rtlefuse->eeprom_oemid == 0xFF)  		rtlefuse->eeprom_oemid = 0; @@ -1832,7 +1840,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)  	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,  		 "dev_addr: %pM\n", rtlefuse->dev_addr);  	/*channel plan */ -	rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; +	rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];  	/* set channel paln to world wide 13 */  	rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;  	/*tx power*/ @@ -1844,7 +1852,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)  						 rtlefuse->autoload_failflag,  						 hwinfo);  	/*board type*/ -	rtlefuse->board_type = (((*(u8 *)&hwinfo[jj]) & 0xE0) >> 5); +	rtlefuse->board_type = (hwinfo[jj] & 0xE0) >> 5;  	/*Wake on wlan*/  	rtlefuse->wowlan_enable = ((hwinfo[kk] & 0x40) >> 6);  	/*parse xtal*/ @@ -1871,15 +1879,15 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)  		case EEPROM_CID_DEFAULT:  			if (rtlefuse->eeprom_did == 0x8179) {  				if (rtlefuse->eeprom_svid == 0x1025) { -					rtlhal->oem_id = RT_CID_819x_Acer; +					rtlhal->oem_id = RT_CID_819X_ACER;  				} else if ((rtlefuse->eeprom_svid == 0x10EC &&  					    rtlefuse->eeprom_smid == 0x0179) ||  					    (rtlefuse->eeprom_svid == 0x17AA &&  					    rtlefuse->eeprom_smid == 0x0179)) { -					rtlhal->oem_id = RT_CID_819x_Lenovo; +					rtlhal->oem_id = RT_CID_819X_LENOVO;  				} else if (rtlefuse->eeprom_svid == 0x103c &&  					 rtlefuse->eeprom_smid == 0x197d) { -					rtlhal->oem_id = RT_CID_819x_HP; +					rtlhal->oem_id = RT_CID_819X_HP;  				} else {  					rtlhal->oem_id = RT_CID_DEFAULT;  				} @@ -1891,7 +1899,7 @@ static void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)  			rtlhal->oem_id = RT_CID_TOSHIBA;  			break;  		case EEPROM_CID_QMI: -			rtlhal->oem_id = RT_CID_819x_QMI; +			rtlhal->oem_id = RT_CID_819X_QMI;  			break;  		case EEPROM_CID_WHQL:  		default: @@ -1910,14 +1918,14 @@ static void _rtl88ee_hal_customized_behavior(struct ieee80211_hw *hw)  	pcipriv->ledctl.led_opendrain = true;  	switch (rtlhal->oem_id) { -	case RT_CID_819x_HP: +	case RT_CID_819X_HP:  		pcipriv->ledctl.led_opendrain = true;  		break; -	case RT_CID_819x_Lenovo: +	case RT_CID_819X_LENOVO:  	case RT_CID_DEFAULT:  	case RT_CID_TOSHIBA:  	case RT_CID_CCX: -	case RT_CID_819x_Acer: +	case RT_CID_819X_ACER:  	case RT_CID_WHQL:  	default:  		break; @@ -2210,8 +2218,7 @@ void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw)  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	u16 sifs_timer; -	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, -				      (u8 *)&mac->slot_time); +	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);  	if (!mac->ht_enable)  		sifs_timer = 0x0a0a;  	else @@ -2508,23 +2515,3 @@ void rtl88ee_suspend(struct ieee80211_hw *hw)  void rtl88ee_resume(struct ieee80211_hw *hw)  {  } - -/* Turn on AAP (RCR:bit 0) for promicuous mode. */ -void rtl88ee_allow_all_destaddr(struct ieee80211_hw *hw, -				bool allow_all_da, bool write_into_reg) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - -	if (allow_all_da) /* Set BIT0 */ -		rtlpci->receive_config |= RCR_AAP; -	 else /* Clear BIT0 */ -		rtlpci->receive_config &= ~RCR_AAP; - -	if (write_into_reg) -		rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - -	RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, -		 "receive_config = 0x%08X, write_into_reg =%d\n", -		 rtlpci->receive_config, write_into_reg); -} diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h index b4460a41bd0..1850fde881b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.h @@ -61,8 +61,6 @@ void rtl8188ee_bt_reg_init(struct ieee80211_hw *hw);  void rtl8188ee_bt_hw_init(struct ieee80211_hw *hw);  void rtl88ee_suspend(struct ieee80211_hw *hw);  void rtl88ee_resume(struct ieee80211_hw *hw); -void rtl88ee_allow_all_destaddr(struct ieee80211_hw *hw, -				bool allow_all_da, bool write_into_reg);  void rtl88ee_fw_clk_off_timer_callback(unsigned long data);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c index e655c047322..1cd6c16d597 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c @@ -29,6 +29,7 @@  #include "../wifi.h"  #include "../pci.h" +#include "../core.h"  #include "../ps.h"  #include "reg.h"  #include "def.h" @@ -151,18 +152,7 @@ static bool config_bb_with_pgheader(struct ieee80211_hw *hw,  			v2 = table_pg[i + 1];  			if (v1 < 0xcdcdcdcd) { -				if (table_pg[i] == 0xfe) -					mdelay(50); -				else if (table_pg[i] == 0xfd) -					mdelay(5); -				else if (table_pg[i] == 0xfc) -					mdelay(1); -				else if (table_pg[i] == 0xfb) -					udelay(50); -				else if (table_pg[i] == 0xfa) -					udelay(5); -				else if (table_pg[i] == 0xf9) -					udelay(1); +				rtl_addr_delay(table_pg[i]);  				store_pwrindex_offset(hw, table_pg[i],  						      table_pg[i + 1], @@ -672,24 +662,9 @@ static void _rtl8188e_config_rf_reg(struct ieee80211_hw *hw,  				    u32 addr, u32 data, enum radio_path rfpath,  				    u32 regaddr)  { -	if (addr == 0xffe) { -		mdelay(50); -	} else if (addr == 0xfd) { -		mdelay(5); -	} else if (addr == 0xfc) { -		mdelay(1); -	} else if (addr == 0xfb) { -		udelay(50); -	} else if (addr == 0xfa) { -		udelay(5); -	} else if (addr == 0xf9) { -		udelay(1); -	} else { -		rtl_set_rfreg(hw, rfpath, regaddr, -			      RFREG_OFFSET_MASK, -			      data); -		udelay(1); -	} +	rtl_rfreg_delay(hw, rfpath, regaddr, +			RFREG_OFFSET_MASK, +			data);  }  static void rtl88_config_s(struct ieee80211_hw *hw, @@ -702,28 +677,6 @@ static void rtl88_config_s(struct ieee80211_hw *hw,  				addr | maskforphyset);  } -static void _rtl8188e_config_bb_reg(struct ieee80211_hw *hw, -				    u32 addr, u32 data) -{ -	if (addr == 0xfe) { -		mdelay(50); -	} else if (addr == 0xfd) { -		mdelay(5); -	} else if (addr == 0xfc) { -		mdelay(1); -	} else if (addr == 0xfb) { -		udelay(50); -	} else if (addr == 0xfa) { -		udelay(5); -	} else if (addr == 0xf9) { -		udelay(1); -	} else { -		rtl_set_bbreg(hw, addr, MASKDWORD, data); -		udelay(1); -	} -} - -  #define NEXT_PAIR(v1, v2, i)				\  	do {						\  		i += 2; v1 = array_table[i];		\ @@ -795,7 +748,7 @@ static void set_baseband_phy_config(struct ieee80211_hw *hw)  		v1 = array_table[i];  		v2 = array_table[i + 1];  		if (v1 < 0xcdcdcdcd) { -			_rtl8188e_config_bb_reg(hw, v1, v2); +			rtl_bb_delay(hw, v1, v2);  		} else {/*This line is the start line of branch.*/  			if (!check_cond(hw, array_table[i])) {  				/*Discard the following (offset, data) pairs*/ @@ -811,7 +764,7 @@ static void set_baseband_phy_config(struct ieee80211_hw *hw)  				while (v2 != 0xDEAD &&  				       v2 != 0xCDEF &&  				       v2 != 0xCDCD && i < arraylen - 2) { -					_rtl8188e_config_bb_reg(hw, v1, v2); +					rtl_bb_delay(hw, v1, v2);  					NEXT_PAIR(v1, v2, i);  				} @@ -1002,7 +955,7 @@ bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  			}  		} -		if (rtlhal->oem_id == RT_CID_819x_HP) +		if (rtlhal->oem_id == RT_CID_819X_HP)  			rtl88_config_s(hw, 0x52, 0x7E4BD);  		break; @@ -1136,34 +1089,6 @@ void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)  					   &bw40_pwr[0], channel);  } -void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	enum io_type iotype; - -	if (!is_hal_stop(rtlhal)) { -		switch (operation) { -		case SCAN_OPT_BACKUP: -			iotype = IO_CMD_PAUSE_DM_BY_SCAN; -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_IO_CMD, -						      (u8 *)&iotype); -			break; -		case SCAN_OPT_RESTORE: -			iotype = IO_CMD_RESUME_DM_BY_SCAN; -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_IO_CMD, -						      (u8 *)&iotype); -			break; -		default: -			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -				 "Unknown Scan Backup operation.\n"); -			break; -		} -	} -} -  void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h index f1acd6d27e4..89f0f1ef146 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h @@ -200,37 +200,35 @@ enum _ANT_DIV_TYPE {  	CGCS_RX_SW_ANTDIV		= 0x05,  }; -extern u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, -				   u32 regaddr, u32 bitmask); -extern void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, -				  u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, -				   enum radio_path rfpath, u32 regaddr, -				   u32 bitmask); -extern void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, -				  enum radio_path rfpath, u32 regaddr, -				  u32 bitmask, u32 data); -extern bool rtl88e_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl88e_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl88e_phy_rf_config(struct ieee80211_hw *hw); -extern void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, -					 long *powerlevel); -extern void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -extern void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, -					     u8 operation); -extern void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, -				   enum nl80211_channel_type ch_type); -extern void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, +			    u32 regaddr, u32 bitmask); +void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, +			   u32 regaddr, u32 bitmask, u32 data); +u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, +			    enum radio_path rfpath, u32 regaddr, +			    u32 bitmask); +void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, +			   enum radio_path rfpath, u32 regaddr, +			   u32 bitmask, u32 data); +bool rtl88e_phy_mac_config(struct ieee80211_hw *hw); +bool rtl88e_phy_bb_config(struct ieee80211_hw *hw); +bool rtl88e_phy_rf_config(struct ieee80211_hw *hw); +void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, +				  long *powerlevel); +void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, +			    enum nl80211_channel_type ch_type); +void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);  void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw);  void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);  bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  					  enum radio_path rfpath);  bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, -					  enum rf_pwrstate rfpwr_state); +bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, +				   enum rf_pwrstate rfpwr_state);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h index 028ec6dd52b..32e135ab9a6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h @@ -30,7 +30,6 @@  #ifndef __RTL8723E_PWRSEQ_H__  #define __RTL8723E_PWRSEQ_H__ -#include "pwrseqcmd.h"  /*  	Check document WM-20110607-Paul-RTL8188E_Power_Architecture-R02.vsd  	There are 6 HW Power States: diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h index d849abf7d94..7af85cfa8f8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h @@ -2215,22 +2215,6 @@  #define	BWORD1					0xc  #define	BWORD					0xf -#define	MASKBYTE0				0xff -#define	MASKBYTE1				0xff00 -#define	MASKBYTE2				0xff0000 -#define	MASKBYTE3				0xff000000 -#define	MASKHWORD				0xffff0000 -#define	MASKLWORD				0x0000ffff -#define	MASKDWORD				0xffffffff -#define	MASK12BITS				0xfff -#define	MASKH4BITS				0xf0000000 -#define MASKOFDM_D				0xffc00000 -#define	MASKCCK					0x3f3f3f3f - -#define	MASK4BITS				0x0f -#define	MASK20BITS				0xfffff -#define RFREG_OFFSET_MASK			0xfffff -  #define	BENABLE					0x1  #define	BDISABLE				0x0 diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c index c254693a1e6..842d69349a3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c @@ -30,6 +30,7 @@  #include "../wifi.h"  #include "../core.h"  #include "../pci.h" +#include "../base.h"  #include "reg.h"  #include "def.h"  #include "phy.h" @@ -92,6 +93,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw)  	u8 tid;  	rtl8188ee_bt_reg_init(hw); +	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;  	rtlpriv->dm.dm_initialgain_enable = 1;  	rtlpriv->dm.dm_flag = 0; @@ -244,7 +246,7 @@ static struct rtl_hal_ops rtl8188ee_hal_ops = {  	.set_bw_mode = rtl88e_phy_set_bw_mode,  	.switch_channel = rtl88e_phy_sw_chnl,  	.dm_watchdog = rtl88e_dm_watchdog, -	.scan_operation_backup = rtl88e_phy_scan_operation_backup, +	.scan_operation_backup = rtl_phy_scan_operation_backup,  	.set_rf_power_state = rtl88e_phy_set_rf_power_state,  	.led_control = rtl88ee_led_control,  	.set_desc = rtl88ee_set_desc, @@ -253,7 +255,6 @@ static struct rtl_hal_ops rtl8188ee_hal_ops = {  	.enable_hw_sec = rtl88ee_enable_hw_security_config,  	.set_key = rtl88ee_set_key,  	.init_sw_leds = rtl88ee_init_sw_leds, -	.allow_all_destaddr = rtl88ee_allow_all_destaddr,  	.get_bbreg = rtl88e_phy_query_bb_reg,  	.set_bbreg = rtl88e_phy_set_bb_reg,  	.get_rfreg = rtl88e_phy_query_rf_reg, @@ -265,6 +266,7 @@ static struct rtl_mod_params rtl88ee_mod_params = {  	.inactiveps = true,  	.swctrl_lps = false,  	.fwctrl_lps = true, +	.msi_support = false,  	.debug = DBG_EMERG,  }; @@ -381,10 +383,12 @@ module_param_named(debug, rtl88ee_mod_params.debug, int, 0444);  module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444);  module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444);  module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl88ee_mod_params.msi_support, bool, 0444);  MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");  MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");  MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");  MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");  MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");  static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c index 68685a89825..5b4c225396f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c @@ -293,7 +293,7 @@ static void _rtl88ee_translate_rx_signal_stuff(struct ieee80211_hw *hw,  	u8 *psaddr;  	__le16 fc;  	u16 type, ufc; -	bool match_bssid, packet_toself, packet_beacon, addr; +	bool match_bssid, packet_toself, packet_beacon = false, addr;  	tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; @@ -452,7 +452,7 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,  			/* During testing, hdr was NULL */  			return false;  		} -		if ((ieee80211_is_robust_mgmt_frame(hdr)) && +		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&  		    (ieee80211_has_protected(hdr->frame_control)))  			rx_status->flag &= ~RX_FLAG_DECRYPTED;  		else @@ -478,7 +478,6 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,  	/*rx_status->qual = status->signal; */  	rx_status->signal = status->recvsignalpower + 10; -	/*rx_status->noise = -status->noise; */  	if (status->packet_report_type == TX_REPORT2) {  		status->macid_valid_entry[0] =  			 GET_RX_RPT2_DESC_MACID_VALID_1(pdesc); @@ -490,16 +489,15 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,  void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx, -			  struct ieee80211_tx_info *info, -			  struct ieee80211_sta *sta, -			  struct sk_buff *skb, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info, +			  struct ieee80211_sta *sta, struct sk_buff *skb,  			  u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); -	u8 *pdesc = (u8 *)pdesc_tx; +	u8 *pdesc = pdesc_tx;  	u16 seq_number;  	__le16 fc = hdr->frame_control;  	unsigned int buf_len = 0; @@ -718,7 +716,7 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,  	SET_TX_DESC_OWN(pdesc, 1); -	SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len)); +	SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));  	SET_TX_DESC_FIRST_SEG(pdesc, 1);  	SET_TX_DESC_LAST_SEG(pdesc, 1); @@ -735,7 +733,8 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,  		      pdesc, TX_DESC_SIZE);  } -void rtl88ee_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) +void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +		      u8 desc_name, u8 *val)  {  	if (istx == true) {  		switch (desc_name) { diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h index 21ca33a7c77..8c2609412d2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.h @@ -777,15 +777,15 @@ struct rx_desc_88e {  void rtl88ee_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx, -			  struct ieee80211_tx_info *info, -			  struct ieee80211_sta *sta, -			  struct sk_buff *skb, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info, +			  struct ieee80211_sta *sta, struct sk_buff *skb,  			  u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);  bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,  			   struct rtl_stats *status,  			   struct ieee80211_rx_status *rx_status,  			   u8 *pdesc, struct sk_buff *skb); -void rtl88ee_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); +void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +		      u8 desc_name, u8 *val);  u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name);  void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);  void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index d2d57a27a7c..eb78fd8607f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -158,6 +158,42 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {  	{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}  }; +static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + +void dm_restorepowerindex(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8	index; + +	for (index = 0; index < 6; index++) +		rtl_write_byte(rtlpriv, power_index_reg[index], +			       rtlpriv->dm.powerindex_backup[index]); +} +EXPORT_SYMBOL_GPL(dm_restorepowerindex); + +void dm_writepowerindex(struct ieee80211_hw *hw, u8 value) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 index; + +	for (index = 0; index < 6; index++) +		rtl_write_byte(rtlpriv, power_index_reg[index], value); +} +EXPORT_SYMBOL_GPL(dm_writepowerindex); + +void dm_savepowerindex(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 index; +	u8 tmp; + +	for (index = 0; index < 6; index++) { +		tmp = rtl_read_byte(rtlpriv, power_index_reg[index]); +		rtlpriv->dm.powerindex_backup[index] = tmp; +	} +} +EXPORT_SYMBOL_GPL(dm_savepowerindex); +  static void rtl92c_dm_diginit(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -180,7 +216,12 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw)  	dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;  	dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;  	dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; -	dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; +	dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LowRssi; + +	dm_digtable->forbidden_igi = DM_DIG_MIN; +	dm_digtable->large_fa_hit = 0; +	dm_digtable->recover_cnt = 0; +	dm_digtable->dig_dynamic_min  = 0x25;  }  static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) @@ -206,7 +247,9 @@ static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)  		rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;  	} -	return (u8) rssi_val_min; +	if (rssi_val_min > 100) +		rssi_val_min = 100; +	return (u8)rssi_val_min;  }  static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) @@ -224,9 +267,17 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)  	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);  	falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + +	 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD); +	falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff); +	falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16); +  	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + -	    falsealm_cnt->cnt_rate_illegal + -	    falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; +				      falsealm_cnt->cnt_rate_illegal + +				      falsealm_cnt->cnt_crc8_fail + +				      falsealm_cnt->cnt_mcs_fail + +				      falsealm_cnt->cnt_fast_fsync_fail + +				      falsealm_cnt->cnt_sb_search_fail;  	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);  	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); @@ -271,12 +322,14 @@ static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)  		value_igi++;  	else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)  		value_igi += 2; +  	if (value_igi > DM_DIG_FA_UPPER)  		value_igi = DM_DIG_FA_UPPER;  	else if (value_igi < DM_DIG_FA_LOWER)  		value_igi = DM_DIG_FA_LOWER; +  	if (rtlpriv->falsealm_cnt.cnt_all > 10000) -		value_igi = 0x32; +		value_igi = DM_DIG_FA_UPPER;  	dm_digtable->cur_igvalue = value_igi;  	rtl92c_dm_write_dig(hw); @@ -286,32 +339,80 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct dig_t *digtable = &rtlpriv->dm_digtable; +	u32 isbt; + +	/* modify DIG lower bound, deal with abnorally large false alarm */ +	if (rtlpriv->falsealm_cnt.cnt_all > 10000) { +		digtable->large_fa_hit++; +		if (digtable->forbidden_igi < digtable->cur_igvalue) { +			digtable->forbidden_igi = digtable->cur_igvalue; +			digtable->large_fa_hit = 1; +		} -	if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) { -		if ((digtable->back_val - 2) < digtable->back_range_min) -			digtable->back_val = digtable->back_range_min; -		else -			digtable->back_val -= 2; -	} else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) { -		if ((digtable->back_val + 2) > digtable->back_range_max) -			digtable->back_val = digtable->back_range_max; -		else -			digtable->back_val += 2; +		if (digtable->large_fa_hit >= 3) { +			if ((digtable->forbidden_igi + 1) > +			    digtable->rx_gain_max) +				digtable->rx_gain_min = digtable->rx_gain_max; +			else +				digtable->rx_gain_min = (digtable->forbidden_igi + 1); +			digtable->recover_cnt = 3600; /* 3600=2hr */ +		} +	} else { +		/* Recovery mechanism for IGI lower bound */ +		if (digtable->recover_cnt != 0) { +			digtable->recover_cnt--; +		} else { +			if (digtable->large_fa_hit == 0) { +				if ((digtable->forbidden_igi-1) < DM_DIG_MIN) { +					digtable->forbidden_igi = DM_DIG_MIN; +					digtable->rx_gain_min = DM_DIG_MIN; +				} else { +					digtable->forbidden_igi--; +					digtable->rx_gain_min = digtable->forbidden_igi + 1; +				} +			} else if (digtable->large_fa_hit == 3) { +				digtable->large_fa_hit = 0; +			} +		} +	} +	if (rtlpriv->falsealm_cnt.cnt_all < 250) { +		isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01; + +		if (!isbt) { +			if (rtlpriv->falsealm_cnt.cnt_all > +			    digtable->fa_lowthresh) { +				if ((digtable->back_val - 2) < +				   digtable->back_range_min) +					digtable->back_val = digtable->back_range_min; +				else +					digtable->back_val -= 2; +			} else if (rtlpriv->falsealm_cnt.cnt_all < +				   digtable->fa_lowthresh) { +				if ((digtable->back_val + 2) > +				    digtable->back_range_max) +					digtable->back_val = digtable->back_range_max; +				else +					digtable->back_val += 2; +			} +		} else { +			digtable->back_val = DM_DIG_BACKOFF_DEFAULT; +		} +	} else { +		/* Adjust initial gain by false alarm */ +		if (rtlpriv->falsealm_cnt.cnt_all > 1000) +			digtable->cur_igvalue = digtable->pre_igvalue + 2; +		else if (rtlpriv->falsealm_cnt.cnt_all > 750) +			digtable->cur_igvalue = digtable->pre_igvalue + 1; +		else if (rtlpriv->falsealm_cnt.cnt_all < 500) +			digtable->cur_igvalue = digtable->pre_igvalue - 1;  	} -	if ((digtable->rssi_val_min + 10 - digtable->back_val) > -	    digtable->rx_gain_max) +	/* Check initial gain by upper/lower bound */ +	if (digtable->cur_igvalue > digtable->rx_gain_max)  		digtable->cur_igvalue = digtable->rx_gain_max; -	else if ((digtable->rssi_val_min + 10 - -		  digtable->back_val) < digtable->rx_gain_min) -		digtable->cur_igvalue = digtable->rx_gain_min; -	else -		digtable->cur_igvalue = digtable->rssi_val_min + 10 - -		    digtable->back_val; -	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, -		 "rssi_val_min = %x back_val %x\n", -		 digtable->rssi_val_min, digtable->back_val); +	if (digtable->cur_igvalue < digtable->rx_gain_min) +		digtable->cur_igvalue = digtable->rx_gain_min;  	rtl92c_dm_write_dig(hw);  } @@ -329,7 +430,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)  		multi_sta = true;  	if (!multi_sta || -	    dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { +	    dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) {  		initialized = false;  		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;  		return; @@ -375,7 +476,6 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)  	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,  		 "presta_cstate = %x, cursta_cstate = %x\n",  		 dm_digtable->presta_cstate, dm_digtable->cursta_cstate); -  	if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||  	    dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||  	    dm_digtable->cursta_cstate == DIG_STA_CONNECT) { @@ -383,6 +483,8 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)  		if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {  			dm_digtable->rssi_val_min =  			    rtl92c_dm_initial_gain_min_pwdb(hw); +			if (dm_digtable->rssi_val_min > 100) +				dm_digtable->rssi_val_min = 100;  			rtl92c_dm_ctrl_initgain_by_rssi(hw);  		}  	} else { @@ -398,11 +500,12 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)  static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;  	if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {  		dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); +		if (dm_digtable->rssi_val_min > 100) +			dm_digtable->rssi_val_min = 100;  		if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {  			if (dm_digtable->rssi_val_min <= 25) @@ -424,48 +527,14 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)  	}  	if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { -		if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { -			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) -				dm_digtable->cur_cck_fa_state = -				    CCK_FA_STAGE_High; -			else -				dm_digtable->cur_cck_fa_state = CCK_FA_STAGE_Low; - -			if (dm_digtable->pre_cck_fa_state != -			    dm_digtable->cur_cck_fa_state) { -				if (dm_digtable->cur_cck_fa_state == -				    CCK_FA_STAGE_Low) -					rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, -						      0x83); -				else -					rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, -						      0xcd); - -				dm_digtable->pre_cck_fa_state = -				    dm_digtable->cur_cck_fa_state; -			} - -			rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); - -			if (IS_92C_SERIAL(rtlhal->version)) -				rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, -					      MASKBYTE2, 0xd7); -		} else { +		if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) || +		    (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX)) +			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83); +		else  			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); -			rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); -			if (IS_92C_SERIAL(rtlhal->version)) -				rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, -					      MASKBYTE2, 0xd3); -		}  		dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;  	} - -	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n", -		 dm_digtable->cur_cck_pd_state); - -	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n", -		 IS_92C_SERIAL(rtlhal->version));  }  static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) @@ -482,6 +551,8 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)  	else  		dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; +	dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; +  	rtl92c_dm_initial_gain_sta(hw);  	rtl92c_dm_initial_gain_multi_sta(hw);  	rtl92c_dm_cck_packet_detection_thresh(hw); @@ -493,23 +564,26 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)  static void rtl92c_dm_dig(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;  	if (rtlpriv->dm.dm_initialgain_enable == false)  		return; -	if (dm_digtable->dig_enable_flag == false) +	if (!(rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG))  		return;  	rtl92c_dm_ctrl_initgain_by_twoport(hw); -  }  static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	rtlpriv->dm.dynamic_txpower_enable = false; - +	if (rtlpriv->rtlhal.interface == INTF_USB && +	    rtlpriv->rtlhal.board_type & 0x1) { +		dm_savepowerindex(hw); +		rtlpriv->dm.dynamic_txpower_enable = true; +	} else { +		rtlpriv->dm.dynamic_txpower_enable = false; +	}  	rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;  	rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;  } @@ -524,9 +598,14 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)  		 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,  		 dm_digtable->back_val); -	dm_digtable->cur_igvalue += 2; -	if (dm_digtable->cur_igvalue > 0x3f) -		dm_digtable->cur_igvalue = 0x3f; +	if (rtlpriv->rtlhal.interface == INTF_USB && +	    !dm_digtable->dig_enable_flag) { +		dm_digtable->pre_igvalue = 0x17; +		return; +	} +	dm_digtable->cur_igvalue -= 1; +	if (dm_digtable->cur_igvalue < DM_DIG_MIN) +		dm_digtable->cur_igvalue = DM_DIG_MIN;  	if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {  		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, @@ -536,34 +615,47 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)  		dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;  	} +	RT_TRACE(rtlpriv, COMP_DIG, DBG_WARNING, +		 "dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", +		 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, +		 dm_digtable->rssi_val_min, dm_digtable->back_val, +		 dm_digtable->rx_gain_max, dm_digtable->rx_gain_min, +		 dm_digtable->large_fa_hit, dm_digtable->forbidden_igi);  }  EXPORT_SYMBOL(rtl92c_dm_write_dig);  static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; -	u8 h2c_parameter[3] = { 0 }; +	if (mac->link_state != MAC80211_LINKED) +		return; -	return; +	if (mac->opmode == NL80211_IFTYPE_ADHOC || +	    mac->opmode == NL80211_IFTYPE_AP) { +		/* TODO: Handle ADHOC and AP Mode */ +	} -	if (tmpentry_max_pwdb != 0) { +	if (tmpentry_max_pwdb != 0)  		rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb; -	} else { +	else  		rtlpriv->dm.entry_max_undec_sm_pwdb = 0; -	} -	if (tmpentry_min_pwdb != 0xff) { +	if (tmpentry_min_pwdb != 0xff)  		rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb; -	} else { +	else  		rtlpriv->dm.entry_min_undec_sm_pwdb = 0; -	} -	h2c_parameter[2] = (u8) (rtlpriv->dm.undec_sm_pwdb & 0xFF); -	h2c_parameter[0] = 0; - -	rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); +/* TODO: + *	if (mac->opmode == NL80211_IFTYPE_STATION) { + *		if (rtlpriv->rtlhal.fw_ready) { + *			u32 param = (u32)(rtlpriv->dm.undec_sm_pwdb << 16); + *			rtl8192c_set_rssi_cmd(hw, param); + *		} + *	} + */  }  void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) @@ -673,7 +765,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw  	s8 cck_index = 0;  	int i;  	bool is2t = IS_92C_SERIAL(rtlhal->version); -	s8 txpwr_level[2] = {0, 0}; +	s8 txpwr_level[3] = {0, 0, 0};  	u8 ofdm_min_index = 6, rf;  	rtlpriv->dm.txpower_trackinginit = true; @@ -773,6 +865,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw  				rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];  			rtlpriv->dm.cck_index = cck_index_old;  		} +		/* Handle USB High PA boards */  		delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?  		    (thermalvalue - rtlpriv->dm.thermalvalue) : @@ -1163,22 +1256,22 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct ps_t *dm_pstable = &rtlpriv->dm_pstable; -	static u8 initialize; -	static u32 reg_874, reg_c70, reg_85c, reg_a74; -	if (initialize == 0) { -		reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, -					 MASKDWORD) & 0x1CC000) >> 14; +	if (!rtlpriv->reg_init) { +		rtlpriv->reg_874 = (rtl_get_bbreg(hw, +						  RFPGA0_XCD_RFINTERFACESW, +						  MASKDWORD) & 0x1CC000) >> 14; -		reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, -					 MASKDWORD) & BIT(3)) >> 3; +		rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, +				    MASKDWORD) & BIT(3)) >> 3; -		reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, -					 MASKDWORD) & 0xFF000000) >> 24; +		rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, +				    MASKDWORD) & 0xFF000000) >> 24; -		reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; +		rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & +				    0xF000) >> 12; -		initialize = 1; +		rtlpriv->reg_init = true;  	}  	if (!bforce_in_normal) { @@ -1215,12 +1308,12 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)  			rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);  		} else {  			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, -				      0x1CC000, reg_874); +				      0x1CC000, rtlpriv->reg_874);  			rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), -				      reg_c70); +				      rtlpriv->reg_c70);  			rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, -				      reg_85c); -			rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); +				      rtlpriv->reg_85c); +			rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);  			rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);  		} @@ -1236,6 +1329,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	/* Determine the minimum RSSI */  	if (((mac->link_state == MAC80211_NOLINK)) &&  	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {  		dm_pstable->rssi_val_min = 0; @@ -1264,6 +1358,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)  			 dm_pstable->rssi_val_min);  	} +	/* Power Saving for 92C */  	if (IS_92C_SERIAL(rtlhal->version))  		;/* rtl92c_dm_1r_cca(hw); */  	else @@ -1275,12 +1370,23 @@ void rtl92c_dm_init(struct ieee80211_hw *hw)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; +	rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG; +	rtlpriv->dm.undec_sm_pwdb = -1; +	rtlpriv->dm.undec_sm_cck = -1; +	rtlpriv->dm.dm_initialgain_enable = true;  	rtl92c_dm_diginit(hw); + +	rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE;  	rtl92c_dm_init_dynamic_txpower(hw); +  	rtl92c_dm_init_edca_turbo(hw);  	rtl92c_dm_init_rate_adaptive_mask(hw); +	rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS;  	rtl92c_dm_initialize_txpower_tracking(hw);  	rtl92c_dm_init_dynamic_bb_powersaving(hw); + +	rtlpriv->dm.ofdm_pkt_cnt = 0; +	rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT;  }  EXPORT_SYMBOL(rtl92c_dm_init); @@ -1331,7 +1437,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)  	}  	if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { -		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; +		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2;  		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,  			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");  	} else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && @@ -1351,8 +1457,16 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)  			 "PHY_SetTxPowerLevel8192S() Channel = %d\n",  			 rtlphy->current_channel);  		rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); +		if (rtlpriv->dm.dynamic_txhighpower_lvl == +		    TXHIGHPWRLEVEL_NORMAL) +			dm_restorepowerindex(hw); +		else if (rtlpriv->dm.dynamic_txhighpower_lvl == +			 TXHIGHPWRLEVEL_LEVEL1) +			dm_writepowerindex(hw, 0x14); +		else if (rtlpriv->dm.dynamic_txhighpower_lvl == +			 TXHIGHPWRLEVEL_LEVEL2) +			dm_writepowerindex(hw, 0x10);  	} -  	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;  } @@ -1423,12 +1537,6 @@ u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)  	else  		curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); -	/* Set Tx Power according to BT status. */ -	if (undec_sm_pwdb >= 30) -		curr_bt_rssi_state |=  BT_RSSI_STATE_TXPOWER_LOW; -	else if (undec_sm_pwdb < 25) -		curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); -  	/* Check BT state related to BT_Idle in B/G mode. */  	if (undec_sm_pwdb < 15)  		curr_bt_rssi_state |=  BT_RSSI_STATE_BG_EDCA_LOW; diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h index 518e208c018..4f232a06363 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h @@ -91,6 +91,17 @@  #define TX_POWER_NEAR_FIELD_THRESH_LVL2		74  #define TX_POWER_NEAR_FIELD_THRESH_LVL1		67 +#define DYNAMIC_FUNC_DISABLE			0x0 +#define DYNAMIC_FUNC_DIG			BIT(0) +#define DYNAMIC_FUNC_HP				BIT(1) +#define DYNAMIC_FUNC_SS				BIT(2) /*Tx Power Tracking*/ +#define DYNAMIC_FUNC_BT				BIT(3) +#define DYNAMIC_FUNC_ANT_DIV			BIT(4) + +#define	RSSI_CCK				0 +#define	RSSI_OFDM				1 +#define	RSSI_DEFAULT				2 +  struct swat_t {  	u8 failure_cnt;  	u8 try_flag; @@ -167,5 +178,8 @@ 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); +void dm_savepowerindex(struct ieee80211_hw *hw); +void dm_writepowerindex(struct ieee80211_hw *hw, u8 value); +void dm_restorepowerindex(struct ieee80211_hw *hw);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 246e5352f2e..9e32ac8a442 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -592,36 +592,6 @@ long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,  }  EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm); -void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	enum io_type iotype; - -	if (!is_hal_stop(rtlhal)) { -		switch (operation) { -		case SCAN_OPT_BACKUP: -			iotype = IO_CMD_PAUSE_DM_BY_SCAN; -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_IO_CMD, -						      (u8 *)&iotype); - -			break; -		case SCAN_OPT_RESTORE: -			iotype = IO_CMD_RESUME_DM_BY_SCAN; -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_IO_CMD, -						      (u8 *)&iotype); -			break; -		default: -			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -				 "Unknown Scan Backup operation\n"); -			break; -		} -	} -} -EXPORT_SYMBOL(rtl92c_phy_scan_operation_backup); -  void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,  			    enum nl80211_channel_type ch_type)  { @@ -1177,6 +1147,12 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,  		0x522, 0x550, 0x551, 0x040  	}; +	u32 iqk_bb_reg_92C[9] = { +		0xc04, 0xc08, 0x874, 0xb68, +		0xb6c, 0x870, 0x860, 0x864, +		0x800 +	}; +  	const u32 retrycount = 2;  	if (t == 0) { @@ -1187,6 +1163,8 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,  						rtlphy->adda_backup, 16);  		_rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,  					       rtlphy->iqk_mac_backup); +		_rtl92c_phy_save_adda_registers(hw, iqk_bb_reg_92C, +						rtlphy->iqk_bb_backup, 9);  	}  	_rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);  	if (t == 0) { @@ -1197,14 +1175,18 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,  	if (!rtlphy->rfpi_enable)  		_rtl92c_phy_pi_mode_switch(hw, true); -	if (t == 0) { -		rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); -		rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); -		rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); -	} + +	rtl_set_bbreg(hw, 0x800, BIT(24), 0x0); +  	rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);  	rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);  	rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + +	rtl_set_bbreg(hw, 0x870, BIT(10), 0x1); +	rtl_set_bbreg(hw, 0x870, BIT(26), 0x1); +	rtl_set_bbreg(hw, 0x860, BIT(10), 0x0); +	rtl_set_bbreg(hw, 0x864, BIT(10), 0x0); +  	if (is2t) {  		rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);  		rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); @@ -1269,13 +1251,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,  					0x3FF0000) >> 16;  		}  	} -	rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); -	rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); -	rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); +  	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); -	rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); -	if (is2t) -		rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); +  	if (t != 0) {  		if (!rtlphy->rfpi_enable)  			_rtl92c_phy_pi_mode_switch(hw, false); @@ -1283,6 +1261,15 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,  						  rtlphy->adda_backup, 16);  		_rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,  						 rtlphy->iqk_mac_backup); +		_rtl92c_phy_reload_adda_registers(hw, iqk_bb_reg_92C, +						  rtlphy->iqk_bb_backup, 9); + +		rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); +		if (is2t) +			rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); + +		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); +		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);  	}  } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h index cec10d69649..e79dabe9ba1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h @@ -39,9 +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  #define	APK_BB_REG_NUM			5  #define	APK_AFE_REG_NUM			16 @@ -205,8 +203,6 @@ void rtl92c_phy_get_txpower_level(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); -void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, -					     u8 operation);  void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,  				   enum nl80211_channel_type ch_type);  void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 3cfa1bb0f47..fa24de43ce7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -152,8 +152,6 @@ enum version_8192c {  #define IS_VENDOR_UMC_A_CUT(version)	((IS_CHIP_VENDOR_UMC(version)) ? \  	((GET_CVID_CUT_VERSION(version)) ? false : true) : false)  #define IS_CHIP_VER_B(version)  ((version & CHIP_VER_B) ? true : false) -#define IS_VENDOR_UMC_A_CUT(version)	((IS_CHIP_VENDOR_UMC(version)) ? \ -	((GET_CVID_CUT_VERSION(version)) ? false : true) : false)  #define IS_92C_SERIAL(version)  ((version & CHIP_92C_BITMASK) ? true : false)  #define IS_CHIP_VENDOR_UMC(version)		\  	((version & CHIP_VENDOR_UMC) ? true : false) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index a82b30a1996..cdecb0fd4d8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -319,7 +319,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			u8 e_aci = *(val);  			rtl92c_dm_init_edca_turbo(hw); -			if (rtlpci->acm_method != eAcmWay2_SW) +			if (rtlpci->acm_method != EACMWAY2_SW)  				rtlpriv->cfg->ops->set_hw_reg(hw,  							      HW_VAR_ACM_CTRL,  							      (&e_aci)); @@ -476,7 +476,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			break;  		}  	case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: -		rtl92c_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); +		rtl92c_set_p2p_ps_offload_cmd(hw, *val);  		break;  	case HW_VAR_AID:{  			u16 u2btmp; @@ -521,30 +521,32 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  						(u8 *)(&fw_current_inps));  				rtlpriv->cfg->ops->set_hw_reg(hw,  						HW_VAR_H2C_FW_PWRMODE, -						(u8 *)(&ppsc->fwctrl_psmode)); +						&ppsc->fwctrl_psmode);  				rtlpriv->cfg->ops->set_hw_reg(hw, -						HW_VAR_SET_RPWM, -						(u8 *)(&rpwm_val)); +							      HW_VAR_SET_RPWM, +							      &rpwm_val);  			} else {  				rpwm_val = 0x0C;	/* RF on */  				fw_pwrmode = FW_PS_ACTIVE_MODE;  				fw_current_inps = false;  				rtlpriv->cfg->ops->set_hw_reg(hw, -						HW_VAR_SET_RPWM, -						(u8 *)(&rpwm_val)); +							      HW_VAR_SET_RPWM, +							      &rpwm_val);  				rtlpriv->cfg->ops->set_hw_reg(hw,  						HW_VAR_H2C_FW_PWRMODE, -						(u8 *)(&fw_pwrmode)); +						&fw_pwrmode);  				rtlpriv->cfg->ops->set_hw_reg(hw,  						HW_VAR_FW_PSMODE_STATUS,  						(u8 *)(&fw_current_inps));  			}  		break; } +	case HW_VAR_KEEP_ALIVE: +		break;  	default:  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -			 "switch case not processed\n"); +			 "switch case %d not processed\n", variable);  		break;  	}  } @@ -937,14 +939,26 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)  	bool is92c;  	int err;  	u8 tmp_u1b; +	unsigned long flags;  	rtlpci->being_init_adapter = true; + +	/* Since this function can take a very long time (up to 350 ms) +	 * and can be called with irqs disabled, reenable the irqs +	 * to let the other devices continue being serviced. +	 * +	 * It is safe doing so since our own interrupts will only be enabled +	 * in a subsequent step. +	 */ +	local_save_flags(flags); +	local_irq_enable(); +  	rtlpriv->intf_ops->disable_aspm(hw);  	rtstatus = _rtl92ce_init_mac(hw);  	if (!rtstatus) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");  		err = 1; -		return err; +		goto exit;  	}  	err = rtl92c_download_fw(hw); @@ -952,7 +966,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  			 "Failed to download FW. Init HW without FW now..\n");  		err = 1; -		return err; +		goto exit;  	}  	rtlhal->last_hmeboxnum = 0; @@ -1032,6 +1046,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");  	}  	rtl92c_dm_init(hw); +exit: +	local_irq_restore(flags);  	rtlpci->being_init_adapter = false;  	return err;  } @@ -1200,11 +1216,13 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,  void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); +	u32 reg_rcr;  	if (rtlpriv->psc.rfpwr_state != ERFON)  		return; +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); +  	if (check_bssid) {  		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, @@ -1720,7 +1738,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)  			if (rtlefuse->eeprom_did == 0x8176) {  				if ((rtlefuse->eeprom_svid == 0x103C &&  				     rtlefuse->eeprom_smid == 0x1629)) -					rtlhal->oem_id = RT_CID_819x_HP; +					rtlhal->oem_id = RT_CID_819X_HP;  				else  					rtlhal->oem_id = RT_CID_DEFAULT;  			} else { @@ -1731,7 +1749,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)  			rtlhal->oem_id = RT_CID_TOSHIBA;  			break;  		case EEPROM_CID_QMI: -			rtlhal->oem_id = RT_CID_819x_QMI; +			rtlhal->oem_id = RT_CID_819X_QMI;  			break;  		case EEPROM_CID_WHQL:  		default: @@ -1750,14 +1768,14 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw)  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	switch (rtlhal->oem_id) { -	case RT_CID_819x_HP: +	case RT_CID_819X_HP:  		pcipriv->ledctl.led_opendrain = true;  		break; -	case RT_CID_819x_Lenovo: +	case RT_CID_819X_LENOVO:  	case RT_CID_DEFAULT:  	case RT_CID_TOSHIBA:  	case RT_CID_CCX: -	case RT_CID_819x_Acer: +	case RT_CID_819X_ACER:  	case RT_CID_WHQL:  	default:  		break; @@ -2405,24 +2423,3 @@ void rtl92ce_suspend(struct ieee80211_hw *hw)  void rtl92ce_resume(struct ieee80211_hw *hw)  {  } - -/* Turn on AAP (RCR:bit 0) for promicuous mode. */ -void rtl92ce_allow_all_destaddr(struct ieee80211_hw *hw, -	bool allow_all_da, bool write_into_reg) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - -	if (allow_all_da) {/* Set BIT0 */ -		rtlpci->receive_config |= RCR_AAP; -	} else {/* Clear BIT0 */ -		rtlpci->receive_config &= ~RCR_AAP; -	} - -	if (write_into_reg) -		rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - -	RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, -		 "receive_config=0x%08X, write_into_reg=%d\n", -		 rtlpci->receive_config, write_into_reg); -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h index 2d063b0c776..5533070f266 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h @@ -76,7 +76,5 @@ void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw);  void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw);  void rtl92ce_suspend(struct ieee80211_hw *hw);  void rtl92ce_resume(struct ieee80211_hw *hw); -void rtl92ce_allow_all_destaddr(struct ieee80211_hw *hw, -				bool allow_all_da, bool write_into_reg);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 73262ca3864..98b22303c84 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -30,6 +30,7 @@  #include "../wifi.h"  #include "../pci.h"  #include "../ps.h" +#include "../core.h"  #include "reg.h"  #include "def.h"  #include "hw.h" @@ -198,18 +199,7 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,  	}  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_reg_arraylen; i = i + 2) { -			if (phy_regarray_table[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray_table[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray_table[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray_table[i] == 0xfb) -				udelay(50); -			else if (phy_regarray_table[i] == 0xfa) -				udelay(5); -			else if (phy_regarray_table[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_regarray_table[i]);  			rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,  				      phy_regarray_table[i + 1]);  			udelay(1); @@ -245,18 +235,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_regarray_pg_len; i = i + 3) { -			if (phy_regarray_table_pg[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray_table_pg[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray_table_pg[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray_table_pg[i] == 0xfb) -				udelay(50); -			else if (phy_regarray_table_pg[i] == 0xfa) -				udelay(5); -			else if (phy_regarray_table_pg[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_regarray_table_pg[i]);  			_rtl92c_store_pwrIndex_diffrate_offset(hw,  					       phy_regarray_table_pg[i], @@ -305,46 +284,16 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  	switch (rfpath) {  	case RF90_PATH_A:  		for (i = 0; i < radioa_arraylen; i = i + 2) { -			if (radioa_array_table[i] == 0xfe) -				mdelay(50); -			else if (radioa_array_table[i] == 0xfd) -				mdelay(5); -			else if (radioa_array_table[i] == 0xfc) -				mdelay(1); -			else if (radioa_array_table[i] == 0xfb) -				udelay(50); -			else if (radioa_array_table[i] == 0xfa) -				udelay(5); -			else if (radioa_array_table[i] == 0xf9) -				udelay(1); -			else { -				rtl_set_rfreg(hw, rfpath, radioa_array_table[i], -					      RFREG_OFFSET_MASK, -					      radioa_array_table[i + 1]); -				udelay(1); -			} +			rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], +					RFREG_OFFSET_MASK, +					radioa_array_table[i + 1]);  		}  		break;  	case RF90_PATH_B:  		for (i = 0; i < radiob_arraylen; i = i + 2) { -			if (radiob_array_table[i] == 0xfe) { -				mdelay(50); -			} else if (radiob_array_table[i] == 0xfd) -				mdelay(5); -			else if (radiob_array_table[i] == 0xfc) -				mdelay(1); -			else if (radiob_array_table[i] == 0xfb) -				udelay(50); -			else if (radiob_array_table[i] == 0xfa) -				udelay(5); -			else if (radiob_array_table[i] == 0xf9) -				udelay(1); -			else { -				rtl_set_rfreg(hw, rfpath, radiob_array_table[i], -					      RFREG_OFFSET_MASK, -					      radiob_array_table[i + 1]); -				udelay(1); -			} +			rtl_rfreg_delay(hw, rfpath, radiob_array_table[i], +					RFREG_OFFSET_MASK, +					radiob_array_table[i + 1]);  		}  		break;  	case RF90_PATH_C: @@ -355,6 +304,8 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 "switch case not processed\n");  		break; +	default: +		break;  	}  	return true;  } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index d5e3b704f93..94486cca400 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -39,9 +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  #define	APK_BB_REG_NUM			5  #define	APK_AFE_REG_NUM			16 @@ -188,36 +186,29 @@ struct tx_power_struct {  };  bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); -u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, -				   u32 regaddr, u32 bitmask); -void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, -				  u32 regaddr, u32 bitmask, u32 data); -u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, -				   enum radio_path rfpath, u32 regaddr, -				   u32 bitmask); -extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, -				   enum radio_path rfpath, u32 regaddr, -				   u32 bitmask, u32 data); +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, +			   u32 data); +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, +			    u32 regaddr, u32 bitmask); +void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, +			    u32 regaddr, u32 bitmask, u32 data);  bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);  bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw);  bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);  bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, -						 enum radio_path rfpath); +					  enum radio_path rfpath);  void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, -					 long *powerlevel); +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel);  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); -void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, -					     u8 operation);  void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, -				   enum nl80211_channel_type ch_type); +			    enum nl80211_channel_type ch_type);  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_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval);  void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);  void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);  void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); @@ -225,28 +216,25 @@ 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);  bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, -					      u32 rfpath); -bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +				       u32 rfpath);  bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, -					  enum rf_pwrstate rfpwr_state); +				    enum rf_pwrstate rfpwr_state);  void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);  bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);  void rtl92c_phy_set_io(struct ieee80211_hw *hw);  void rtl92c_bb_block_on(struct ieee80211_hw *hw); -u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, -				      enum radio_path rfpath, u32 offset); +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, +			       u32 offset);  u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, -					 enum radio_path rfpath, u32 offset); +				  enum radio_path rfpath, u32 offset);  u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask);  void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, -					enum radio_path rfpath, u32 offset, -					u32 data); +				 enum radio_path rfpath, u32 offset, u32 data);  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);  void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, -						   u32 regaddr, u32 bitmask, -						   u32 data); +					    u32 regaddr, u32 bitmask, u32 data);  bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);  void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);  bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index bd4aef74c05..ed703a1b3b7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -560,7 +560,6 @@  #define	EEPROM_DEFAULT_TXPOWERLEVEL		0x22  #define	EEPROM_DEFAULT_HT40_2SDIFF		0x0  #define EEPROM_DEFAULT_HT20_DIFF		2 -#define	EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF	0x3  #define EEPROM_DEFAULT_HT40_PWRMAXOFFSET	0  #define EEPROM_DEFAULT_HT20_PWRMAXOFFSET	0 @@ -639,17 +638,8 @@  #define	EEPROM_TXPWR_GROUP			0x6F -#define EEPROM_TSSI_A				0x76 -#define EEPROM_TSSI_B				0x77 -#define EEPROM_THERMAL_METER			0x78 -  #define EEPROM_CHANNELPLAN			0x75 -#define RF_OPTION1				0x79 -#define RF_OPTION2				0x7A -#define RF_OPTION3				0x7B -#define RF_OPTION4				0x7C -  #define	STOPBECON				BIT(6)  #define	STOPHIGHT				BIT(5)  #define	STOPMGT					BIT(4) @@ -689,13 +679,6 @@  #define RSV_CTRL				0x001C  #define RD_CTRL					0x0524 -#define REG_USB_INFO				0xFE17 -#define REG_USB_SPECIAL_OPTION			0xFE55 - -#define REG_USB_DMA_AGG_TO			0xFE5B -#define REG_USB_AGG_TO				0xFE5C -#define REG_USB_AGG_TH				0xFE5D -  #define REG_USB_VID				0xFE60  #define REG_USB_PID				0xFE62  #define REG_USB_OPTIONAL			0xFE64 @@ -1196,9 +1179,6 @@  #define POLLING_LLT_THRESHOLD			20  #define POLLING_READY_TIMEOUT_COUNT		1000 -#define	MAX_MSS_DENSITY_2T			0x13 -#define	MAX_MSS_DENSITY_1T			0x0A -  #define EPROM_CMD_OPERATING_MODE_MASK	((1<<7)|(1<<6))  #define EPROM_CMD_CONFIG			0x3  #define EPROM_CMD_LOAD				1 @@ -2064,22 +2044,6 @@  #define	BWORD1					0xc  #define	BWORD					0xf -#define	MASKBYTE0				0xff -#define	MASKBYTE1				0xff00 -#define	MASKBYTE2				0xff0000 -#define	MASKBYTE3				0xff000000 -#define	MASKHWORD				0xffff0000 -#define	MASKLWORD				0x0000ffff -#define	MASKDWORD				0xffffffff -#define	MASK12BITS				0xfff -#define	MASKH4BITS				0xf0000000 -#define MASKOFDM_D				0xffc00000 -#define	MASKCCK					0x3f3f3f3f - -#define	MASK4BITS				0x0f -#define	MASK20BITS				0xfffff -#define RFREG_OFFSET_MASK			0xfffff -  #define	BENABLE					0x1  #define	BDISABLE				0x0 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index 6c8d56efcea..d8fe68b389d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -34,11 +34,10 @@  #define RF6052_MAX_REG			0x3F  #define RF6052_MAX_PATH			2 -extern void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, -					     u8 bandwidth); -extern void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, -					       u8 *ppowerlevel); -extern void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, -						u8 *ppowerlevel, u8 channel); -extern bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); +void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +					u8 *ppowerlevel); +void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +					 u8 *ppowerlevel, u8 channel); +bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 14203561b6e..12f21f4073e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -30,6 +30,7 @@  #include "../wifi.h"  #include "../core.h"  #include "../pci.h" +#include "../base.h"  #include "reg.h"  #include "def.h"  #include "phy.h" @@ -219,7 +220,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {  	.set_bw_mode = rtl92c_phy_set_bw_mode,  	.switch_channel = rtl92c_phy_sw_chnl,  	.dm_watchdog = rtl92c_dm_watchdog, -	.scan_operation_backup = rtl92c_phy_scan_operation_backup, +	.scan_operation_backup = rtl_phy_scan_operation_backup,  	.set_rf_power_state = rtl92c_phy_set_rf_power_state,  	.led_control = rtl92ce_led_control,  	.set_desc = rtl92ce_set_desc, @@ -228,7 +229,6 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {  	.enable_hw_sec = rtl92ce_enable_hw_security_config,  	.set_key = rtl92ce_set_key,  	.init_sw_leds = rtl92ce_init_sw_leds, -	.allow_all_destaddr = rtl92ce_allow_all_destaddr,  	.get_bbreg = rtl92c_phy_query_bb_reg,  	.set_bbreg = rtl92c_phy_set_bb_reg,  	.set_rfreg = rtl92ce_phy_set_rf_reg, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 6ad23b413eb..8f04817cb7e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -393,7 +393,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,  			/* In testing, hdr was NULL here */  			return false;  		} -		if ((ieee80211_is_robust_mgmt_frame(hdr)) && +		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&  		    (ieee80211_has_protected(hdr->frame_control)))  			rx_status->flag &= ~RX_FLAG_DECRYPTED;  		else @@ -420,14 +420,13 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,  	/*rx_status->qual = stats->signal; */  	rx_status->signal = stats->recvsignalpower + 10; -	/*rx_status->noise = -stats->noise; */  	return true;  }  void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx, -			  struct ieee80211_tx_info *info, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			  struct ieee80211_sta *sta,  			  struct sk_buff *skb,  			  u8 hw_queue, struct rtl_tcb_desc *tcb_desc) @@ -667,7 +666,8 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,  		      "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);  } -void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) +void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +		      u8 desc_name, u8 *val)  {  	if (istx) {  		switch (desc_name) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index a7cdd514cb2..9a39ec4204d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -711,8 +711,8 @@ struct rx_desc_92c {  } __packed;  void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, -			  struct ieee80211_hdr *hdr, -			  u8 *pdesc, struct ieee80211_tx_info *info, +			  struct ieee80211_hdr *hdr, u8 *pdesc, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			  struct ieee80211_sta *sta,  			  struct sk_buff *skb, u8 hw_queue,  			  struct rtl_tcb_desc *ptcb_desc); @@ -720,7 +720,8 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,  			   struct rtl_stats *stats,  			   struct ieee80211_rx_status *rx_status,  			   u8 *pdesc, struct sk_buff *skb); -void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); +void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +		      u8 desc_name, u8 *val);  u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);  void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);  void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index 16a0b9e59ac..c16209a336e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -101,6 +101,15 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)  			 "PHY_SetTxPowerLevel8192S() Channel = %d\n",  			 rtlphy->current_channel);  		rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); +		if (rtlpriv->dm.dynamic_txhighpower_lvl == +		    TXHIGHPWRLEVEL_NORMAL) +			dm_restorepowerindex(hw); +		else if (rtlpriv->dm.dynamic_txhighpower_lvl == +			 TXHIGHPWRLEVEL_LEVEL1) +			dm_writepowerindex(hw, 0x14); +		else if (rtlpriv->dm.dynamic_txhighpower_lvl == +			 TXHIGHPWRLEVEL_LEVEL2) +			dm_writepowerindex(hw, 0x10);  	}  	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h index d947e7d350b..fafa6bac2a3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h @@ -30,3 +30,6 @@  #include "../rtl8192ce/dm.h"  void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw); +void dm_savepowerindex(struct ieee80211_hw *hw); +void dm_writepowerindex(struct ieee80211_hw *hw, u8 value); +void dm_restorepowerindex(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 189ba124a8c..a903c2671b4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -394,7 +394,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)  			if (rtlefuse->eeprom_did == 0x8176) {  				if ((rtlefuse->eeprom_svid == 0x103C &&  				     rtlefuse->eeprom_smid == 0x1629)) -					rtlhal->oem_id = RT_CID_819x_HP; +					rtlhal->oem_id = RT_CID_819X_HP;  				else  					rtlhal->oem_id = RT_CID_DEFAULT;  			} else { @@ -405,7 +405,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)  			rtlhal->oem_id = RT_CID_TOSHIBA;  			break;  		case EEPROM_CID_QMI: -			rtlhal->oem_id = RT_CID_819x_QMI; +			rtlhal->oem_id = RT_CID_819X_QMI;  			break;  		case EEPROM_CID_WHQL:  		default: @@ -423,14 +423,14 @@ static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw)  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	switch (rtlhal->oem_id) { -	case RT_CID_819x_HP: +	case RT_CID_819X_HP:  		usb_priv->ledctl.led_opendrain = true;  		break; -	case RT_CID_819x_Lenovo: +	case RT_CID_819X_LENOVO:  	case RT_CID_DEFAULT:  	case RT_CID_TOSHIBA:  	case RT_CID_CCX: -	case RT_CID_819x_Acer: +	case RT_CID_819X_ACER:  	case RT_CID_WHQL:  	default:  		break; @@ -511,7 +511,7 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)  			pr_info("MAC auto ON okay!\n");  			break;  		} -		if (pollingCount++ > 100) { +		if (pollingCount++ > 1000) {  			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,  				 "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n");  			return -ENODEV; @@ -985,19 +985,30 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));  	int err = 0;  	static bool iqk_initialized; +	unsigned long flags; + +	/* As this function can take a very long time (up to 350 ms) +	 * and can be called with irqs disabled, reenable the irqs +	 * to let the other devices continue being serviced. +	 * +	 * It is safe doing so since our own interrupts will only be enabled +	 * in a subsequent step. +	 */ +	local_save_flags(flags); +	local_irq_enable();  	rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU;  	err = _rtl92cu_init_mac(hw);  	if (err) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n"); -		return err; +		goto exit;  	}  	err = rtl92c_download_fw(hw);  	if (err) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  			 "Failed to download FW. Init HW without FW now..\n");  		err = 1; -		return err; +		goto exit;  	}  	rtlhal->last_hmeboxnum = 0; /* h2c */  	_rtl92cu_phy_param_tab_init(hw); @@ -1022,7 +1033,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)  	if (ppsc->rfpwr_state == ERFON) {  		rtl92c_phy_set_rfpath_switch(hw, 1);  		if (iqk_initialized) { -			rtl92c_phy_iq_calibrate(hw, false); +			rtl92c_phy_iq_calibrate(hw, true);  		} else {  			rtl92c_phy_iq_calibrate(hw, false);  			iqk_initialized = true; @@ -1034,6 +1045,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)  	_InitPABias(hw);  	_update_mac_setting(hw);  	rtl92c_dm_init(hw); +exit: +	local_irq_restore(flags);  	return err;  } @@ -1379,11 +1392,13 @@ void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); -	u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); +	u32 reg_rcr;  	if (rtlpriv->psc.rfpwr_state != ERFON)  		return; +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); +  	if (check_bssid) {  		u8 tmp;  		if (IS_NORMAL_CHIP(rtlhal->version)) { @@ -1795,7 +1810,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  					  e_aci);  				break;  			} -			if (rtlusb->acm_method != eAcmWay2_SW) +			if (rtlusb->acm_method != EACMWAY2_SW)  				rtlpriv->cfg->ops->set_hw_reg(hw,  					 HW_VAR_ACM_CTRL, &e_aci);  			break; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index da4f587199e..e26312fb435 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -32,6 +32,7 @@  #include "../usb.h"  #include "../ps.h"  #include "../cam.h" +#include "../stats.h"  #include "reg.h"  #include "def.h"  #include "phy.h" @@ -738,16 +739,6 @@ static u8 _rtl92c_evm_db_to_percentage(char value)  	return ret_val;  } -static long _rtl92c_translate_todbm(struct ieee80211_hw *hw, -				     u8 signal_strength_index) -{ -	long signal_power; - -	signal_power = (long)((signal_strength_index + 1) >> 1); -	signal_power -= 95; -	return signal_power; -} -  static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw,  		long currsig)  { @@ -778,7 +769,7 @@ static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw,  static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,  				      struct rtl_stats *pstats, -				      struct rx_desc_92c *pdesc, +				      struct rx_desc_92c *p_desc,  				      struct rx_fwinfo_92c *p_drvinfo,  				      bool packet_match_bssid,  				      bool packet_toself, @@ -793,11 +784,11 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,  	u32 rssi, total_rssi = 0;  	bool in_powersavemode = false;  	bool is_cck_rate; +	u8 *pdesc = (u8 *)p_desc; -	is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); +	is_cck_rate = RX_HAL_IS_CCK_RATE(p_desc);  	pstats->packet_matchbssid = packet_match_bssid;  	pstats->packet_toself = packet_toself; -	pstats->is_cck = is_cck_rate;  	pstats->packet_beacon = packet_beacon;  	pstats->is_cck = is_cck_rate;  	pstats->RX_SIGQ[0] = -1; @@ -913,180 +904,6 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,  			  (hw, total_rssi /= rf_rx_num));  } -static void _rtl92c_process_ui_rssi(struct ieee80211_hw *hw, -		struct rtl_stats *pstats) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_phy *rtlphy = &(rtlpriv->phy); -	u8 rfpath; -	u32 last_rssi, tmpval; - -	if (pstats->packet_toself || pstats->packet_beacon) { -		rtlpriv->stats.rssi_calculate_cnt++; -		if (rtlpriv->stats.ui_rssi.total_num++ >= -		    PHY_RSSI_SLID_WIN_MAX) { -			rtlpriv->stats.ui_rssi.total_num = -			    PHY_RSSI_SLID_WIN_MAX; -			last_rssi = -			    rtlpriv->stats.ui_rssi.elements[rtlpriv-> -							   stats.ui_rssi.index]; -			rtlpriv->stats.ui_rssi.total_val -= last_rssi; -		} -		rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; -		rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi. -					index++] = pstats->signalstrength; -		if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) -			rtlpriv->stats.ui_rssi.index = 0; -		tmpval = rtlpriv->stats.ui_rssi.total_val / -		    rtlpriv->stats.ui_rssi.total_num; -		rtlpriv->stats.signal_strength = -		    _rtl92c_translate_todbm(hw, (u8) tmpval); -		pstats->rssi = rtlpriv->stats.signal_strength; -	} -	if (!pstats->is_cck && pstats->packet_toself) { -		for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; -		     rfpath++) { -			if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) -				continue; -			if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { -				rtlpriv->stats.rx_rssi_percentage[rfpath] = -				    pstats->rx_mimo_signalstrength[rfpath]; -			} -			if (pstats->rx_mimo_signalstrength[rfpath] > -			    rtlpriv->stats.rx_rssi_percentage[rfpath]) { -				rtlpriv->stats.rx_rssi_percentage[rfpath] = -				    ((rtlpriv->stats. -				      rx_rssi_percentage[rfpath] * -				      (RX_SMOOTH_FACTOR - 1)) + -				     (pstats->rx_mimo_signalstrength[rfpath])) / -				    (RX_SMOOTH_FACTOR); - -				rtlpriv->stats.rx_rssi_percentage[rfpath] = -				    rtlpriv->stats.rx_rssi_percentage[rfpath] + -				    1; -			} else { -				rtlpriv->stats.rx_rssi_percentage[rfpath] = -				    ((rtlpriv->stats. -				      rx_rssi_percentage[rfpath] * -				      (RX_SMOOTH_FACTOR - 1)) + -				     (pstats->rx_mimo_signalstrength[rfpath])) / -				    (RX_SMOOTH_FACTOR); -			} -		} -	} -} - -static void _rtl92c_update_rxsignalstatistics(struct ieee80211_hw *hw, -					       struct rtl_stats *pstats) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	int weighting = 0; - -	if (rtlpriv->stats.recv_signal_power == 0) -		rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; -	if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) -		weighting = 5; -	else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) -		weighting = (-5); -	rtlpriv->stats.recv_signal_power = -	    (rtlpriv->stats.recv_signal_power * 5 + -	     pstats->recvsignalpower + weighting) / 6; -} - -static void _rtl92c_process_pwdb(struct ieee80211_hw *hw, -		struct rtl_stats *pstats) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); -	long undec_sm_pwdb = 0; - -	if (mac->opmode == NL80211_IFTYPE_ADHOC) { -		return; -	} else { -		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; -	} -	if (pstats->packet_toself || pstats->packet_beacon) { -		if (undec_sm_pwdb < 0) -			undec_sm_pwdb = pstats->rx_pwdb_all; -		if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { -			undec_sm_pwdb = (((undec_sm_pwdb) * -			      (RX_SMOOTH_FACTOR - 1)) + -			     (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); -			undec_sm_pwdb += 1; -		} else { -			undec_sm_pwdb = (((undec_sm_pwdb) * -			      (RX_SMOOTH_FACTOR - 1)) + -			     (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); -		} -		rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; -		_rtl92c_update_rxsignalstatistics(hw, pstats); -	} -} - -static void _rtl92c_process_LINK_Q(struct ieee80211_hw *hw, -					     struct rtl_stats *pstats) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	u32 last_evm = 0, n_stream, tmpval; - -	if (pstats->signalquality != 0) { -		if (pstats->packet_toself || pstats->packet_beacon) { -			if (rtlpriv->stats.LINK_Q.total_num++ >= -			    PHY_LINKQUALITY_SLID_WIN_MAX) { -				rtlpriv->stats.LINK_Q.total_num = -				    PHY_LINKQUALITY_SLID_WIN_MAX; -				last_evm = -				    rtlpriv->stats.LINK_Q.elements -				    [rtlpriv->stats.LINK_Q.index]; -				rtlpriv->stats.LINK_Q.total_val -= -				    last_evm; -			} -			rtlpriv->stats.LINK_Q.total_val += -			    pstats->signalquality; -			rtlpriv->stats.LINK_Q.elements -			   [rtlpriv->stats.LINK_Q.index++] = -			    pstats->signalquality; -			if (rtlpriv->stats.LINK_Q.index >= -			    PHY_LINKQUALITY_SLID_WIN_MAX) -				rtlpriv->stats.LINK_Q.index = 0; -			tmpval = rtlpriv->stats.LINK_Q.total_val / -			    rtlpriv->stats.LINK_Q.total_num; -			rtlpriv->stats.signal_quality = tmpval; -			rtlpriv->stats.last_sigstrength_inpercent = tmpval; -			for (n_stream = 0; n_stream < 2; -			     n_stream++) { -				if (pstats->RX_SIGQ[n_stream] != -1) { -					if (!rtlpriv->stats.RX_EVM[n_stream]) { -						rtlpriv->stats.RX_EVM[n_stream] -						 = pstats->RX_SIGQ[n_stream]; -					} -					rtlpriv->stats.RX_EVM[n_stream] = -					    ((rtlpriv->stats.RX_EVM -					    [n_stream] * -					    (RX_SMOOTH_FACTOR - 1)) + -					    (pstats->RX_SIGQ -					    [n_stream] * 1)) / -					    (RX_SMOOTH_FACTOR); -				} -			} -		} -	} else { -		; -	} -} - -static void _rtl92c_process_phyinfo(struct ieee80211_hw *hw, -				     u8 *buffer, -				     struct rtl_stats *pcurrent_stats) -{ -	if (!pcurrent_stats->packet_matchbssid && -	    !pcurrent_stats->packet_beacon) -		return; -	_rtl92c_process_ui_rssi(hw, pcurrent_stats); -	_rtl92c_process_pwdb(hw, pcurrent_stats); -	_rtl92c_process_LINK_Q(hw, pcurrent_stats); -} -  void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,  					       struct sk_buff *skb,  					       struct rtl_stats *pstats, @@ -1123,5 +940,5 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,  	_rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,  				   packet_matchbssid, packet_toself,  				   packet_beacon); -	_rtl92c_process_phyinfo(hw, tmp_buf, pstats); +	rtl_process_phyinfo(hw, tmp_buf, pstats);  } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index 34e56308301..9831ff1128c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -30,6 +30,7 @@  #include "../wifi.h"  #include "../pci.h"  #include "../ps.h" +#include "../core.h"  #include "reg.h"  #include "def.h"  #include "phy.h" @@ -120,6 +121,7 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));  	u16 regval; +	u32 regval32;  	u8 b_reg_hwparafile = 1;  	_rtl92c_phy_init_bb_rf_register_definition(hw); @@ -135,8 +137,11 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)  	} else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) {  		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |  			       FEN_BB_GLB_RSTn | FEN_BBRSTB); -		rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);  	} +	regval32 = rtl_read_dword(rtlpriv, 0x87c); +	rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31))); +	if (IS_HARDWARE_TYPE_8192CU(rtlhal)) +		rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);  	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);  	if (b_reg_hwparafile == 1)  		rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); @@ -184,18 +189,7 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,  	}  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_reg_arraylen; i = i + 2) { -			if (phy_regarray_table[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray_table[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray_table[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray_table[i] == 0xfb) -				udelay(50); -			else if (phy_regarray_table[i] == 0xfa) -				udelay(5); -			else if (phy_regarray_table[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_regarray_table[i]);  			rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,  				      phy_regarray_table[i + 1]);  			udelay(1); @@ -232,18 +226,7 @@ bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,  	phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata;  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_regarray_pg_len; i = i + 3) { -			if (phy_regarray_table_pg[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray_table_pg[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray_table_pg[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray_table_pg[i] == 0xfb) -				udelay(50); -			else if (phy_regarray_table_pg[i] == 0xfa) -				udelay(5); -			else if (phy_regarray_table_pg[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_regarray_table_pg[i]);  			_rtl92c_store_pwrIndex_diffrate_offset(hw,  						  phy_regarray_table_pg[i],  						  phy_regarray_table_pg[i + 1], @@ -290,46 +273,16 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  	switch (rfpath) {  	case RF90_PATH_A:  		for (i = 0; i < radioa_arraylen; i = i + 2) { -			if (radioa_array_table[i] == 0xfe) -				mdelay(50); -			else if (radioa_array_table[i] == 0xfd) -				mdelay(5); -			else if (radioa_array_table[i] == 0xfc) -				mdelay(1); -			else if (radioa_array_table[i] == 0xfb) -				udelay(50); -			else if (radioa_array_table[i] == 0xfa) -				udelay(5); -			else if (radioa_array_table[i] == 0xf9) -				udelay(1); -			else { -				rtl_set_rfreg(hw, rfpath, radioa_array_table[i], -					      RFREG_OFFSET_MASK, -					      radioa_array_table[i + 1]); -				udelay(1); -			} +			rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], +					RFREG_OFFSET_MASK, +					radioa_array_table[i + 1]);  		}  		break;  	case RF90_PATH_B:  		for (i = 0; i < radiob_arraylen; i = i + 2) { -			if (radiob_array_table[i] == 0xfe) { -				mdelay(50); -			} else if (radiob_array_table[i] == 0xfd) -				mdelay(5); -			else if (radiob_array_table[i] == 0xfc) -				mdelay(1); -			else if (radiob_array_table[i] == 0xfb) -				udelay(50); -			else if (radiob_array_table[i] == 0xfa) -				udelay(5); -			else if (radiob_array_table[i] == 0xf9) -				udelay(1); -			else { -				rtl_set_rfreg(hw, rfpath, radiob_array_table[i], -					      RFREG_OFFSET_MASK, -					      radiob_array_table[i + 1]); -				udelay(1); -			} +			rtl_rfreg_delay(hw, rfpath, radiob_array_table[i], +					RFREG_OFFSET_MASK, +					radiob_array_table[i + 1]);  		}  		break;  	case RF90_PATH_C: @@ -340,6 +293,8 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,  			 "switch case not processed\n");  		break; +	default: +		break;  	}  	return true;  } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 2119313a737..b878d56d2f4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -85,17 +85,15 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,  	if (mac->act_scanning) {  		tx_agc[RF90_PATH_A] = 0x3f3f3f3f;  		tx_agc[RF90_PATH_B] = 0x3f3f3f3f; -		if (turbo_scanoff) { -			for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { -				tx_agc[idx1] = ppowerlevel[idx1] | -				    (ppowerlevel[idx1] << 8) | -				    (ppowerlevel[idx1] << 16) | -				    (ppowerlevel[idx1] << 24); -				if (rtlhal->interface == INTF_USB) { -					if (tx_agc[idx1] > 0x20 && -					    rtlefuse->external_pa) -						tx_agc[idx1] = 0x20; -				} +		for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { +			tx_agc[idx1] = ppowerlevel[idx1] | +			    (ppowerlevel[idx1] << 8) | +			    (ppowerlevel[idx1] << 16) | +			    (ppowerlevel[idx1] << 24); +			if (rtlhal->interface == INTF_USB) { +				if (tx_agc[idx1] > 0x20 && +				    rtlefuse->external_pa) +					tx_agc[idx1] = 0x20;  			}  		}  	} else { @@ -107,7 +105,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,  			   TXHIGHPWRLEVEL_LEVEL2) {  			tx_agc[RF90_PATH_A] = 0x00000000;  			tx_agc[RF90_PATH_B] = 0x00000000; -		} else{ +		} else {  			for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {  				tx_agc[idx1] = ppowerlevel[idx1] |  				    (ppowerlevel[idx1] << 8) | @@ -373,7 +371,12 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,  			    regoffset == RTXAGC_B_MCS07_MCS04)  				regoffset = 0xc98;  			for (i = 0; i < 3; i++) { -				writeVal = (writeVal > 6) ? (writeVal - 6) : 0; +				if (i != 2) +					writeVal = (writeVal > 8) ? +						   (writeVal - 8) : 0; +				else +					writeVal = (writeVal > 6) ? +						   (writeVal - 6) : 0;  				rtl_write_byte(rtlpriv, (u32)(regoffset + i),  					      (u8)writeVal);  			} diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index 090fd33a158..11b439d6b67 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -34,15 +34,14 @@  #define RF6052_MAX_REG			0x3F  #define RF6052_MAX_PATH			2 -extern void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, -					    u8 bandwidth); -extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, -					      u8 *ppowerlevel); -extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, -					       u8 *ppowerlevel, u8 channel); +void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +				       u8 *ppowerlevel); +void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +					u8 *ppowerlevel, u8 channel);  bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw);  bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, -					  enum radio_path rfpath); +					   enum radio_path rfpath);  void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,  					u8 *ppowerlevel);  void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 2bd59852621..361435f8608 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -31,6 +31,7 @@  #include "../core.h"  #include "../usb.h"  #include "../efuse.h" +#include "../base.h"  #include "reg.h"  #include "def.h"  #include "phy.h" @@ -49,6 +50,9 @@ MODULE_AUTHOR("Larry Finger	<Larry.Finger@lwfinger.net>");  MODULE_LICENSE("GPL");  MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");  MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin");  static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)  { @@ -68,14 +72,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)  			 "Can't alloc buffer for fw\n");  		return 1;  	} - +	if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) && +	    !IS_92C_SERIAL(rtlpriv->rtlhal.version)) { +		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_A.bin"; +	} else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlpriv->rtlhal.version)) { +		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_B.bin"; +	} else { +		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_TMSC.bin"; +	} +	/* provide name of alternative file */ +	rtlpriv->cfg->alt_fw_name = "rtlwifi/rtl8192cufw.bin";  	pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);  	rtlpriv->max_fw_size = 0x4000;  	err = request_firmware_nowait(THIS_MODULE, 1,  				      rtlpriv->cfg->fw_name, rtlpriv->io.dev,  				      GFP_KERNEL, hw, rtl_fw_cb); - -  	return err;  } @@ -117,7 +128,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {  	.set_bw_mode = rtl92c_phy_set_bw_mode,  	.switch_channel = rtl92c_phy_sw_chnl,  	.dm_watchdog = rtl92c_dm_watchdog, -	.scan_operation_backup = rtl92c_phy_scan_operation_backup, +	.scan_operation_backup = rtl_phy_scan_operation_backup,  	.set_rf_power_state = rtl92cu_phy_set_rf_power_state,  	.led_control = rtl92cu_led_control,  	.enable_hw_sec = rtl92cu_enable_hw_security_config, @@ -306,6 +317,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {  	{RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/  	{RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/  	{RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ +	{RTL_USB_DEVICE(0x0df6, 0x0077, rtl92cu_hal_cfg)}, /*Sitecom-WLA2100V2*/  	{RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/  	{RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/  	/* HP - Lite-On ,8188CUS Slim Combo */ @@ -383,9 +395,6 @@ static struct usb_driver rtl8192cu_driver = {  	/* .resume = rtl_usb_resume, */  	/* .reset_resume = rtl8192c_resume, */  #endif /* CONFIG_PM */ -#ifdef CONFIG_AUTOSUSPEND -	.supports_autosuspend = 1, -#endif  	.disable_hub_initiated_lpm = 1,  }; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c index 966be519edb..7903c154de0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c @@ -36,7 +36,7 @@ u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = {  	0x804, 0x00000003,  	0x808, 0x0000fc00,  	0x80c, 0x0000000a, -	0x810, 0x10005388, +	0x810, 0x10000330,  	0x814, 0x020c3d10,  	0x818, 0x02200385,  	0x81c, 0x00000000, @@ -110,22 +110,22 @@ u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = {  	0xc44, 0x000100b7,  	0xc48, 0xec020107,  	0xc4c, 0x007f037f, -	0xc50, 0x6954341e, +	0xc50, 0x69543420,  	0xc54, 0x43bc0094, -	0xc58, 0x6954341e, +	0xc58, 0x69543420,  	0xc5c, 0x433c0094,  	0xc60, 0x00000000,  	0xc64, 0x5116848b,  	0xc68, 0x47c00bff,  	0xc6c, 0x00000036,  	0xc70, 0x2c7f000d, -	0xc74, 0x0186115b, +	0xc74, 0x2186115b,  	0xc78, 0x0000001f,  	0xc7c, 0x00b99612,  	0xc80, 0x40000100,  	0xc84, 0x20f60000,  	0xc88, 0x40000100, -	0xc8c, 0x20200000, +	0xc8c, 0xa0e40000,  	0xc90, 0x00121820,  	0xc94, 0x00000000,  	0xc98, 0x00121820, @@ -226,7 +226,7 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {  	0x804, 0x00000001,  	0x808, 0x0000fc00,  	0x80c, 0x0000000a, -	0x810, 0x10005388, +	0x810, 0x10000330,  	0x814, 0x020c3d10,  	0x818, 0x02200385,  	0x81c, 0x00000000, @@ -300,9 +300,9 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {  	0xc44, 0x000100b7,  	0xc48, 0xec020107,  	0xc4c, 0x007f037f, -	0xc50, 0x6954341e, +	0xc50, 0x69543420,  	0xc54, 0x43bc0094, -	0xc58, 0x6954341e, +	0xc58, 0x69543420,  	0xc5c, 0x433c0094,  	0xc60, 0x00000000,  	0xc64, 0x5116848b, @@ -340,7 +340,7 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {  	0xce4, 0x00000000,  	0xce8, 0x37644302,  	0xcec, 0x2f97d40c, -	0xd00, 0x00080740, +	0xd00, 0x00000740,  	0xd04, 0x00020401,  	0xd08, 0x0000907f,  	0xd0c, 0x20010201, @@ -633,17 +633,17 @@ u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH] = {  	0x012, 0x00071000,  	0x012, 0x000b0000,  	0x012, 0x000fc000, -	0x013, 0x000287af, +	0x013, 0x000287b3,  	0x013, 0x000244b7,  	0x013, 0x000204ab,  	0x013, 0x0001c49f,  	0x013, 0x00018493, -	0x013, 0x00014297, -	0x013, 0x00010295, -	0x013, 0x0000c298, -	0x013, 0x0000819c, -	0x013, 0x000040a8, -	0x013, 0x0000001c, +	0x013, 0x0001429b, +	0x013, 0x00010299, +	0x013, 0x0000c29c, +	0x013, 0x000081a0, +	0x013, 0x000040ac, +	0x013, 0x00000020,  	0x014, 0x0001944c,  	0x014, 0x00059444,  	0x014, 0x0009944c, @@ -932,10 +932,10 @@ u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH] = {  	0x608, 0x0000000e,  	0x609, 0x0000002a,  	0x652, 0x00000020, -	0x63c, 0x0000000a, -	0x63d, 0x0000000e, -	0x63e, 0x0000000a, -	0x63f, 0x0000000e, +	0x63c, 0x00000008, +	0x63d, 0x00000008, +	0x63e, 0x0000000c, +	0x63f, 0x0000000c,  	0x66e, 0x00000005,  	0x700, 0x00000021,  	0x701, 0x00000043, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 763cf1defab..035e0dc3922 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -303,10 +303,10 @@ out:  bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,  			   struct rtl_stats *stats,  			   struct ieee80211_rx_status *rx_status, -			   u8 *p_desc, struct sk_buff *skb) +			   u8 *pdesc, struct sk_buff *skb)  {  	struct rx_fwinfo_92c *p_drvinfo; -	struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; +	struct rx_desc_92c *p_desc = (struct rx_desc_92c *)pdesc;  	u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc);  	stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); @@ -343,13 +343,13 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,  					(bool)GET_RX_DESC_PAGGR(pdesc));  	rx_status->mactime = GET_RX_DESC_TSFL(pdesc);  	if (phystatus) { -		p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); -		rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, +		p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + +						     stats->rx_bufshift); +		rtl92c_translate_rx_signal_stuff(hw, skb, stats, p_desc,  						 p_drvinfo);  	}  	/*rx_status->qual = stats->signal; */ -	rx_status->signal = stats->rssi + 10; -	/*rx_status->noise = -stats->noise; */ +	rx_status->signal = stats->recvsignalpower + 10;  	return true;  } @@ -364,7 +364,6 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)  	u8 *rxdesc;  	struct rtl_stats stats = {  		.signal = 0, -		.noise = -98,  		.rate = 0,  	};  	struct rx_fwinfo_92c *p_drvinfo; @@ -496,7 +495,7 @@ static void _rtl_tx_desc_checksum(u8 *txdesc)  void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx, -			  struct ieee80211_tx_info *info, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			  struct ieee80211_sta *sta,  			  struct sk_buff *skb,  			  u8 queue_index, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h index 725c53accc5..fd8051dcd98 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h @@ -420,7 +420,7 @@ struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *,  					   struct sk_buff_head *);  void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx, -			  struct ieee80211_tx_info *info, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			  struct ieee80211_sta *sta,  			  struct sk_buff *skb,  			  u8 queue_index, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index f700f7a614b..304c443b89b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -194,15 +194,15 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)  	rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); /* hold page C counter */  	rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); /*hold page D counter */ -	ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, BMASKDWORD); +	ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);  	falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);  	falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16); -	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, BMASKDWORD); +	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);  	falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); -	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, BMASKDWORD); +	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);  	falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);  	falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); -	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, BMASKDWORD); +	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);  	falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);  	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +  				      falsealm_cnt->cnt_rate_illegal + @@ -214,9 +214,9 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)  	if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) {  		/* hold cck counter */  		rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); -		ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, BMASKBYTE0); +		ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);  		falsealm_cnt->cnt_cck_fail = ret_value; -		ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, BMASKBYTE3); +		ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);  		falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;  		rtl92d_release_cckandrw_pagea_ctl(hw, &flag);  	} else { @@ -331,11 +331,11 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)  	if (de_digtable->pre_cck_pd_state != de_digtable->cur_cck_pd_state) {  		if (de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {  			rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); -			rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0x83); +			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);  			rtl92d_release_cckandrw_pagea_ctl(hw, &flag);  		} else {  			rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); -			rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0xcd); +			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);  			rtl92d_release_cckandrw_pagea_ctl(hw, &flag);  		}  		de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state; @@ -722,7 +722,7 @@ static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw)  	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,  		 "===> Rx Gain %x\n", u4tmp);  	for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++) -		rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK, +		rtl_set_rfreg(hw, i, 0x3C, RFREG_OFFSET_MASK,  			      (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp);  } @@ -737,7 +737,7 @@ static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg,  	/* Query CCK default setting From 0xa24 */  	rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);  	temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, -				 BMASKDWORD) & BMASKCCK; +				 MASKDWORD) & MASKCCK;  	rtl92d_release_cckandrw_pagea_ctl(hw, &flag);  	for (i = 0; i < CCK_TABLE_LENGTH; i++) {  		if (rtlpriv->dm.cck_inch14) { @@ -840,9 +840,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(  	bool internal_pa = false;  	long ele_a = 0, ele_d, temp_cck, val_x, value32;  	long val_y, ele_c = 0; -	u8 ofdm_index[2]; +	u8 ofdm_index[3];  	s8 cck_index = 0; -	u8 ofdm_index_old[2] = {0, 0}; +	u8 ofdm_index_old[3] = {0, 0, 0};  	s8 cck_index_old = 0;  	u8 index;  	int i; @@ -896,9 +896,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(  		rf = 1;  	if (thermalvalue) {  		ele_d = rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, -				      BMASKDWORD) & BMASKOFDM_D; +				      MASKDWORD) & MASKOFDM_D;  		for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) { -			if (ele_d == (ofdmswing_table[i] & BMASKOFDM_D)) { +			if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {  				ofdm_index_old[0] = (u8) i;  				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, @@ -910,10 +910,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(  		}  		if (is2t) {  			ele_d = rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, -					      BMASKDWORD) & BMASKOFDM_D; +					      MASKDWORD) & MASKOFDM_D;  			for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {  				if (ele_d == -				    (ofdmswing_table[i] & BMASKOFDM_D)) { +				    (ofdmswing_table[i] & MASKOFDM_D)) {  					ofdm_index_old[1] = (u8) i;  					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,  						 DBG_LOUD, @@ -1091,10 +1091,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(  				value32 = (ele_d << 22) | ((ele_c & 0x3F) <<  					  16) | ele_a;  				rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, -					      BMASKDWORD, value32); +					      MASKDWORD, value32);  				value32 = (ele_c & 0x000003C0) >> 6; -				rtl_set_bbreg(hw, ROFDM0_XCTxAFE, BMASKH4BITS, +				rtl_set_bbreg(hw, ROFDM0_XCTxAFE, MASKH4BITS,  					      value32);  				value32 = ((val_x * ele_d) >> 7) & 0x01; @@ -1103,10 +1103,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(  			} else {  				rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, -					      BMASKDWORD, +					      MASKDWORD,  					      ofdmswing_table  					      [(u8)ofdm_index[0]]); -				rtl_set_bbreg(hw, ROFDM0_XCTxAFE, BMASKH4BITS, +				rtl_set_bbreg(hw, ROFDM0_XCTxAFE, MASKH4BITS,  					      0x00);  				rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,  					      BIT(24), 0x00); @@ -1118,6 +1118,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(  				 val_x, val_y, ele_a, ele_c, ele_d,  				 val_x, val_y); +			if (cck_index >= CCK_TABLE_SIZE) +				cck_index = CCK_TABLE_SIZE - 1; +			if (cck_index < 0) +				cck_index = 0;  			if (rtlhal->current_bandtype == BAND_ON_2_4G) {  				/* Adjust CCK according to IQK result */  				if (!rtlpriv->dm.cck_inch14) { @@ -1200,21 +1204,21 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(  						  ele_a;  					rtl_set_bbreg(hw,  						      ROFDM0_XBTxIQIMBALANCE, -						      BMASKDWORD, value32); +						      MASKDWORD, value32);  					value32 = (ele_c & 0x000003C0) >> 6;  					rtl_set_bbreg(hw, ROFDM0_XDTxAFE, -						      BMASKH4BITS, value32); +						      MASKH4BITS, value32);  					value32 = ((val_x * ele_d) >> 7) & 0x01;  					rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,  						      BIT(28), value32);  				} else {  					rtl_set_bbreg(hw,  						      ROFDM0_XBTxIQIMBALANCE, -						      BMASKDWORD, +						      MASKDWORD,  						      ofdmswing_table  						      [(u8) ofdm_index[1]]);  					rtl_set_bbreg(hw, ROFDM0_XDTxAFE, -						      BMASKH4BITS, 0x00); +						      MASKH4BITS, 0x00);  					rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,  						      BIT(28), 0x00);  				} @@ -1225,10 +1229,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(  			}  			RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,  				 "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n", -				 rtl_get_bbreg(hw, 0xc80, BMASKDWORD), -				 rtl_get_bbreg(hw, 0xc94, BMASKDWORD), +				 rtl_get_bbreg(hw, 0xc80, MASKDWORD), +				 rtl_get_bbreg(hw, 0xc94, MASKDWORD),  				 rtl_get_rfreg(hw, RF90_PATH_A, 0x24, -					       BRFREGOFFSETMASK)); +					       RFREG_OFFSET_MASK));  		}  		if ((delta_iqk > rtlefuse->delta_iqk) &&  		    (rtlefuse->delta_iqk != 0)) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 7dd8f6de055..2b08671004a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -318,7 +318,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  	case HW_VAR_AC_PARAM: {  		u8 e_aci = *val;  		rtl92d_dm_init_edca_turbo(hw); -		if (rtlpci->acm_method != eAcmWay2_SW) +		if (rtlpci->acm_method != EACMWAY2_SW)  			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,  						      &e_aci);  		break; @@ -985,9 +985,9 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)  	/* set default value after initialize RF,  */  	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);  	rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, -			RF_CHNLBW, BRFREGOFFSETMASK); +			RF_CHNLBW, RFREG_OFFSET_MASK);  	rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, -			RF_CHNLBW, BRFREGOFFSETMASK); +			RF_CHNLBW, RFREG_OFFSET_MASK);  	/*---- Set CCK and OFDM Block "ON"----*/  	if (rtlhal->current_bandtype == BAND_ON_2_4G) @@ -1035,7 +1035,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)  				tmp_rega = rtl_get_rfreg(hw,  						  (enum radio_path)RF90_PATH_A, -						  0x2a, BMASKDWORD); +						  0x2a, MASKDWORD);  				if (((tmp_rega & BIT(11)) == BIT(11)))  					break; @@ -1138,11 +1138,13 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,  void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); -	u32 reg_rcr = rtlpci->receive_config; +	u32 reg_rcr;  	if (rtlpriv->psc.rfpwr_state != ERFON)  		return; + +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); +  	if (check_bssid) {  		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); @@ -1194,25 +1196,7 @@ void rtl92d_linked_set_reg(struct ieee80211_hw *hw)   * mac80211 will send pkt when scan */  void rtl92de_set_qos(struct ieee80211_hw *hw, int aci)  { -	struct rtl_priv *rtlpriv = rtl_priv(hw);  	rtl92d_dm_init_edca_turbo(hw); -	return; -	switch (aci) { -	case AC1_BK: -		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); -		break; -	case AC0_BE: -		break; -	case AC2_VI: -		rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); -		break; -	case AC3_VO: -		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); -		break; -	default: -		RT_ASSERT(false, "invalid aci: %d !\n", aci); -		break; -	}  }  void rtl92de_enable_interrupt(struct ieee80211_hw *hw) @@ -1350,13 +1334,13 @@ void rtl92de_card_disable(struct ieee80211_hw *hw)  	/* c. ========RF OFF sequence==========  */  	/* 0x88c[23:20] = 0xf. */  	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); -	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); +	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);  	/* APSD_CTRL 0x600[7:0] = 0x40 */  	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);  	/* Close antenna 0,0xc04,0xd04 */ -	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0); +	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0);  	rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0);  	/*  SYS_FUNC_EN 0x02[7:0] = 0xE2   reset BB state machine */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h index 7c9f7a2f1e4..1bc7b1a96d4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h @@ -55,10 +55,9 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,  		     u8 *p_macaddr, bool is_group, u8 enc_algo,  		     bool is_wepkey, bool clear_all); -extern void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, -				    u32 value, u8 direct); -extern u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, -				  u8 direct); +void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, u32 value, +			     u8 direct); +u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct);  void rtl92de_suspend(struct ieee80211_hw *hw);  void rtl92de_resume(struct ieee80211_hw *hw);  void rtl92d_linked_set_reg(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 840bac5fa2f..3d1f0dd4e52 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -30,6 +30,7 @@  #include "../wifi.h"  #include "../pci.h"  #include "../ps.h" +#include "../core.h"  #include "reg.h"  #include "def.h"  #include "phy.h" @@ -242,7 +243,7 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,  	else if (rtlhal->during_mac0init_radiob)  		/* mac0 use phy1 write radio_b. */  		dbi_direct = BIT(3) | BIT(2); -	if (bitmask != BMASKDWORD) { +	if (bitmask != MASKDWORD) {  		if (rtlhal->during_mac1init_radioa ||  		    rtlhal->during_mac0init_radiob)  			originalvalue = rtl92de_read_dword_dbi(hw, @@ -275,20 +276,20 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,  	u32 retvalue;  	newoffset = offset; -	tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD); +	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, BMASKDWORD); +		tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);  	tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |  		(newoffset << 23) | BLSSIREADEDGE; -	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD, +	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,  		tmplong & (~BLSSIREADEDGE));  	udelay(10); -	rtl_set_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD, tmplong2); +	rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);  	udelay(50);  	udelay(50); -	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD, +	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,  		tmplong | BLSSIREADEDGE);  	udelay(10);  	if (rfpath == RF90_PATH_A) @@ -321,7 +322,7 @@ static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw,  	newoffset = offset;  	/* T65 RF */  	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; -	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr); +	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);  } @@ -362,7 +363,7 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,  		return;  	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);  	if (rtlphy->rf_mode != RF_OP_BY_FW) { -		if (bitmask != BRFREGOFFSETMASK) { +		if (bitmask != RFREG_OFFSET_MASK) {  			original_value = _rtl92d_phy_rf_serial_read(hw,  				rfpath, regaddr);  			bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); @@ -567,19 +568,8 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,  		 " ===> phy:Rtl819XPHY_REG_Array_PG\n");  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_reg_arraylen; i = i + 2) { -			if (phy_regarray_table[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray_table[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray_table[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray_table[i] == 0xfb) -				udelay(50); -			else if (phy_regarray_table[i] == 0xfa) -				udelay(5); -			else if (phy_regarray_table[i] == 0xf9) -				udelay(1); -			rtl_set_bbreg(hw, phy_regarray_table[i], BMASKDWORD, +			rtl_addr_delay(phy_regarray_table[i]); +			rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,  				      phy_regarray_table[i + 1]);  			udelay(1);  			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, @@ -591,7 +581,7 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,  		if (rtlhal->interfaceindex == 0) {  			for (i = 0; i < agctab_arraylen; i = i + 2) {  				rtl_set_bbreg(hw, agctab_array_table[i], -					BMASKDWORD, +					MASKDWORD,  					agctab_array_table[i + 1]);  				/* Add 1us delay between BB/RF register  				 * setting. */ @@ -607,7 +597,7 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,  			if (rtlhal->current_bandtype == BAND_ON_2_4G) {  				for (i = 0; i < agctab_arraylen; i = i + 2) {  					rtl_set_bbreg(hw, agctab_array_table[i], -						BMASKDWORD, +						MASKDWORD,  						agctab_array_table[i + 1]);  					/* Add 1us delay between BB/RF register  					 * setting. */ @@ -623,7 +613,7 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,  				for (i = 0; i < agctab_5garraylen; i = i + 2) {  					rtl_set_bbreg(hw,  						agctab_5garray_table[i], -						BMASKDWORD, +						MASKDWORD,  						agctab_5garray_table[i + 1]);  					/* Add 1us delay between BB/RF registeri  					 * setting. */ @@ -705,18 +695,7 @@ static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,  	phy_regarray_table_pg = rtl8192de_phy_reg_array_pg;  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_regarray_pg_len; i = i + 3) { -			if (phy_regarray_table_pg[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray_table_pg[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray_table_pg[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray_table_pg[i] == 0xfb) -				udelay(50); -			else if (phy_regarray_table_pg[i] == 0xfa) -				udelay(5); -			else if (phy_regarray_table_pg[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_regarray_table_pg[i]);  			_rtl92d_store_pwrindex_diffrate_offset(hw,  				phy_regarray_table_pg[i],  				phy_regarray_table_pg[i + 1], @@ -843,54 +822,16 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  	switch (rfpath) {  	case RF90_PATH_A:  		for (i = 0; i < radioa_arraylen; i = i + 2) { -			if (radioa_array_table[i] == 0xfe) { -				mdelay(50); -			} else if (radioa_array_table[i] == 0xfd) { -				/* delay_ms(5); */ -				mdelay(5); -			} else if (radioa_array_table[i] == 0xfc) { -				/* delay_ms(1); */ -				mdelay(1); -			} else if (radioa_array_table[i] == 0xfb) { -				udelay(50); -			} else if (radioa_array_table[i] == 0xfa) { -				udelay(5); -			} else if (radioa_array_table[i] == 0xf9) { -				udelay(1); -			} else { -				rtl_set_rfreg(hw, rfpath, radioa_array_table[i], -					      BRFREGOFFSETMASK, -					      radioa_array_table[i + 1]); -				/*  Add 1us delay between BB/RF register set. */ -				udelay(1); -			} +			rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], +					RFREG_OFFSET_MASK, +					radioa_array_table[i + 1]);  		}  		break;  	case RF90_PATH_B:  		for (i = 0; i < radiob_arraylen; i = i + 2) { -			if (radiob_array_table[i] == 0xfe) { -				/* Delay specific ms. Only RF configuration -				 * requires delay. */ -				mdelay(50); -			} else if (radiob_array_table[i] == 0xfd) { -				/* delay_ms(5); */ -				mdelay(5); -			} else if (radiob_array_table[i] == 0xfc) { -				/* delay_ms(1); */ -				mdelay(1); -			} else if (radiob_array_table[i] == 0xfb) { -				udelay(50); -			} else if (radiob_array_table[i] == 0xfa) { -				udelay(5); -			} else if (radiob_array_table[i] == 0xf9) { -				udelay(1); -			} else { -				rtl_set_rfreg(hw, rfpath, radiob_array_table[i], -					      BRFREGOFFSETMASK, -					      radiob_array_table[i + 1]); -				/*  Add 1us delay between BB/RF register set. */ -				udelay(1); -			} +			rtl_rfreg_delay(hw, rfpath, radiob_array_table[i], +					RFREG_OFFSET_MASK, +					radiob_array_table[i + 1]);  		}  		break;  	case RF90_PATH_C: @@ -911,13 +852,13 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)  	struct rtl_phy *rtlphy = &(rtlpriv->phy);  	rtlphy->default_initialgain[0] = -	    (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, BMASKBYTE0); +	    (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);  	rtlphy->default_initialgain[1] = -	    (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, BMASKBYTE0); +	    (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);  	rtlphy->default_initialgain[2] = -	    (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, BMASKBYTE0); +	    (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);  	rtlphy->default_initialgain[3] = -	    (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0); +	    (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);  	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",  		 rtlphy->default_initialgain[0], @@ -925,9 +866,9 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)  		 rtlphy->default_initialgain[2],  		 rtlphy->default_initialgain[3]);  	rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, -					      BMASKBYTE0); +					      MASKBYTE0);  	rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, -					      BMASKDWORD); +					      MASKDWORD);  	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,  		 "Default framesync (0x%x) = 0x%x\n",  		 ROFDM0_RXDETECTOR3, rtlphy->framesync); @@ -1022,34 +963,6 @@ void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)  	rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);  } -void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	enum io_type iotype; - -	if (!is_hal_stop(rtlhal)) { -		switch (operation) { -		case SCAN_OPT_BACKUP: -			rtlhal->current_bandtypebackup = -						 rtlhal->current_bandtype; -			iotype = IO_CMD_PAUSE_DM_BY_SCAN; -			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, -						      (u8 *)&iotype); -			break; -		case SCAN_OPT_RESTORE: -			iotype = IO_CMD_RESUME_DM_BY_SCAN; -			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, -						      (u8 *)&iotype); -			break; -		default: -			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -				 "Unknown Scan Backup operation\n"); -			break; -		} -	} -} -  void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,  			    enum nl80211_channel_type ch_type)  { @@ -1134,7 +1047,7 @@ static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw)  {  	rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0);  	rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0); -	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x00); +	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x00);  	rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0);  } @@ -1196,7 +1109,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,  {  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	u32 imr_num = MAX_RF_IMR_INDEX; -	u32 rfmask = BRFREGOFFSETMASK; +	u32 rfmask = RFREG_OFFSET_MASK;  	u8 group, i;  	unsigned long flag = 0; @@ -1239,7 +1152,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,  			for (i = 0; i < imr_num; i++) {  				rtl_set_rfreg(hw, (enum radio_path)rfpath,  					      rf_reg_for_5g_swchnl_normal[i], -					      BRFREGOFFSETMASK, +					      RFREG_OFFSET_MASK,  					      rf_imr_param_normal[0][0][i]);  			}  			rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, @@ -1357,7 +1270,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)  			if (i == 0 && (rtlhal->macphymode == DUALMAC_DUALPHY)) {  				rtl_set_rfreg(hw, (enum radio_path)path,  					      rf_reg_for_c_cut_5g[i], -					      BRFREGOFFSETMASK, 0xE439D); +					      RFREG_OFFSET_MASK, 0xE439D);  			} else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) {  				u4tmp2 = (rf_reg_pram_c_5g[index][i] &  				     0x7FF) | (u4tmp << 11); @@ -1365,11 +1278,11 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)  					u4tmp2 &= ~(BIT(7) | BIT(6));  				rtl_set_rfreg(hw, (enum radio_path)path,  					      rf_reg_for_c_cut_5g[i], -					      BRFREGOFFSETMASK, u4tmp2); +					      RFREG_OFFSET_MASK, u4tmp2);  			} else {  				rtl_set_rfreg(hw, (enum radio_path)path,  					      rf_reg_for_c_cut_5g[i], -					      BRFREGOFFSETMASK, +					      RFREG_OFFSET_MASK,  					      rf_reg_pram_c_5g[index][i]);  			}  			RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, @@ -1379,7 +1292,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)  				 path, index,  				 rtl_get_rfreg(hw, (enum radio_path)path,  					       rf_reg_for_c_cut_5g[i], -					       BRFREGOFFSETMASK)); +					       RFREG_OFFSET_MASK));  		}  		if (need_pwr_down)  			_rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); @@ -1409,7 +1322,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)  				     i++) {  					rtl_set_rfreg(hw, rfpath,  						rf_for_c_cut_5g_internal_pa[i], -						BRFREGOFFSETMASK, +						RFREG_OFFSET_MASK,  						rf_pram_c_5g_int_pa[index][i]);  					RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,  						 "offset 0x%x value 0x%x path %d index %d\n", @@ -1450,13 +1363,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)  			if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7)  				rtl_set_rfreg(hw, (enum radio_path)path,  					rf_reg_for_c_cut_2g[i], -					BRFREGOFFSETMASK, +					RFREG_OFFSET_MASK,  					(rf_reg_param_for_c_cut_2g[index][i] |  					BIT(17)));  			else  				rtl_set_rfreg(hw, (enum radio_path)path,  					      rf_reg_for_c_cut_2g[i], -					      BRFREGOFFSETMASK, +					      RFREG_OFFSET_MASK,  					      rf_reg_param_for_c_cut_2g  					      [index][i]);  			RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, @@ -1466,14 +1379,14 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)  				 rf_reg_mask_for_c_cut_2g[i], path, index,  				 rtl_get_rfreg(hw, (enum radio_path)path,  					       rf_reg_for_c_cut_2g[i], -					       BRFREGOFFSETMASK)); +					       RFREG_OFFSET_MASK));  		}  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  			"cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",  			rf_syn_g4_for_c_cut_2g | (u4tmp << 11));  		rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4, -			      BRFREGOFFSETMASK, +			      RFREG_OFFSET_MASK,  			      rf_syn_g4_for_c_cut_2g | (u4tmp << 11));  		if (need_pwr_down)  			_rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); @@ -1521,41 +1434,41 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)  	/* path-A IQK setting */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");  	if (rtlhal->interfaceindex == 0) { -		rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f); -		rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f); +		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); +		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);  	} else { -		rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c22); -		rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c22); +		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c22); +		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c22);  	} -	rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140102); -	rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x28160206); +	rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); +	rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160206);  	/* path-B IQK setting */  	if (configpathb) { -		rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x10008c22); -		rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x10008c22); -		rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140102); -		rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206); +		rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); +		rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); +		rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); +		rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160206);  	}  	/* LO calibration setting */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n"); -	rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); +	rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);  	/* One shot, path A LOK & IQK */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "One shot, path A LOK & IQK!\n"); -	rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); -	rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); +	rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); +	rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);  	/* delay x ms */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  		"Delay %d ms for One shot, path A LOK & IQK\n",  		IQK_DELAY_TIME);  	mdelay(IQK_DELAY_TIME);  	/* Check failed */ -	regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); +	regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac); -	rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); +	rege94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe94 = 0x%x\n", rege94); -	rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); +	rege9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe9c = 0x%x\n", rege9c); -	regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); +	regea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xea4 = 0x%x\n", regea4);  	if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) &&  	    (((rege9c & 0x03FF0000) >> 16) != 0x42)) @@ -1591,42 +1504,42 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK!\n");  	/* path-A IQK setting */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n"); -	rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); -	rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); -	rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307); -	rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68160960); +	rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x18008c1f); +	rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x18008c1f); +	rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140307); +	rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x68160960);  	/* path-B IQK setting */  	if (configpathb) { -		rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f); -		rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f); -		rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82110000); -		rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000); +		rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x18008c2f); +		rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x18008c2f); +		rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82110000); +		rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x68110000);  	}  	/* LO calibration setting */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n"); -	rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); +	rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);  	/* path-A PA on */ -	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60); -	rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, 0x66e60e30); +	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x07000f60); +	rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD, 0x66e60e30);  	for (i = 0; i < retrycount; i++) {  		/* One shot, path A LOK & IQK */  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  			"One shot, path A LOK & IQK!\n"); -		rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); -		rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); +		rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); +		rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);  		/* delay x ms */  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  			"Delay %d ms for One shot, path A LOK & IQK.\n",  			IQK_DELAY_TIME);  		mdelay(IQK_DELAY_TIME * 10);  		/* Check failed */ -		regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); +		regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac); -		rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); +		rege94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe94 = 0x%x\n", rege94); -		rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); +		rege9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe9c = 0x%x\n", rege9c); -		regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); +		regea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xea4 = 0x%x\n", regea4);  		if (!(regeac & TxOKBit) &&  		     (((rege94 & 0x03FF0000) >> 16) != 0x142)) { @@ -1648,9 +1561,9 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,  		}  	}  	/* path A PA off */ -	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, +	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD,  		      rtlphy->iqk_bb_backup[0]); -	rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, +	rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, MASKDWORD,  		      rtlphy->iqk_bb_backup[1]);  	return result;  } @@ -1665,22 +1578,22 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B IQK!\n");  	/* One shot, path B LOK & IQK */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "One shot, path A LOK & IQK!\n"); -	rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002); -	rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000); +	rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); +	rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);  	/* delay x ms  */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  		"Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME);  	mdelay(IQK_DELAY_TIME);  	/* Check failed */ -	regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); +	regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac); -	regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); +	regeb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeb4 = 0x%x\n", regeb4); -	regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); +	regebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xebc = 0x%x\n", regebc); -	regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); +	regec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xec4 = 0x%x\n", regec4); -	regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); +	regecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xecc = 0x%x\n", regecc);  	if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&  	    (((regebc & 0x03FF0000) >> 16) != 0x42)) @@ -1708,31 +1621,31 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B IQK!\n");  	/* path-A IQK setting */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n"); -	rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); -	rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); -	rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000); -	rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68110000); +	rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x18008c1f); +	rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x18008c1f); +	rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82110000); +	rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x68110000);  	/* path-B IQK setting */ -	rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f); -	rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f); -	rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140307); -	rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960); +	rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x18008c2f); +	rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x18008c2f); +	rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140307); +	rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x68160960);  	/* LO calibration setting */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n"); -	rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); +	rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);  	/* path-B PA on */ -	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x0f600700); -	rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, 0x061f0d30); +	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD, 0x0f600700); +	rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD, 0x061f0d30);  	for (i = 0; i < retrycount; i++) {  		/* One shot, path B LOK & IQK */  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  			"One shot, path A LOK & IQK!\n"); -		rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000); -		rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); +		rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xfa000000); +		rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);  		/* delay x ms */  		RTPRINT(rtlpriv, FINIT, INIT_IQK, @@ -1740,15 +1653,15 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)  		mdelay(IQK_DELAY_TIME * 10);  		/* Check failed */ -		regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); +		regeac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac); -		regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); +		regeb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeb4 = 0x%x\n", regeb4); -		regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); +		regebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xebc = 0x%x\n", regebc); -		regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); +		regec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xec4 = 0x%x\n", regec4); -		regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); +		regecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xecc = 0x%x\n", regecc);  		if (!(regeac & BIT(31)) &&  		    (((regeb4 & 0x03FF0000) >> 16) != 0x142)) @@ -1766,9 +1679,9 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)  	}  	/* path B PA off */ -	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, +	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, MASKDWORD,  		      rtlphy->iqk_bb_backup[0]); -	rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, +	rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, MASKDWORD,  		      rtlphy->iqk_bb_backup[2]);  	return result;  } @@ -1782,7 +1695,7 @@ static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw,  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Save ADDA parameters.\n");  	for (i = 0; i < regnum; i++) -		adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD); +		adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], MASKDWORD);  }  static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw, @@ -1807,7 +1720,7 @@ static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw,  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  		"Reload ADDA power saving parameters !\n");  	for (i = 0; i < regnum; i++) -		rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]); +		rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, adda_backup[i]);  }  static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw, @@ -1835,7 +1748,7 @@ static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,  		pathon = rtlpriv->rtlhal.interfaceindex == 0 ?  		    0x04db25a4 : 0x0b1b25a4;  	for (i = 0; i < IQK_ADDA_REG_NUM; i++) -		rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, pathon); +		rtl_set_bbreg(hw, adda_reg[i], MASKDWORD, pathon);  }  static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, @@ -1858,9 +1771,9 @@ static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw)  	struct rtl_priv *rtlpriv = rtl_priv(hw);  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A standby mode!\n"); -	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0); -	rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000); -	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); +	rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD, 0x00010000); +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);  }  static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode) @@ -1871,8 +1784,8 @@ static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  		"BB Switch to %s mode!\n", pi_mode ? "PI" : "SI");  	mode = pi_mode ? 0x01000100 : 0x01000000; -	rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode); -	rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode); +	rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); +	rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);  }  static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], @@ -1903,7 +1816,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK for 2.4G :Start!!!\n");  	if (t == 0) { -		bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); +		bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "==>0x%08x\n", bbvalue);  		RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",  			is2t ? "2T2R" : "1T1R"); @@ -1926,40 +1839,40 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],  		_rtl92d_phy_pimode_switch(hw, true);  	rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); -	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600); -	rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4); -	rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22204000); +	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600); +	rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4); +	rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22204000);  	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);  	if (is2t) { -		rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, +		rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, MASKDWORD,  			      0x00010000); -		rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, BMASKDWORD, +		rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, MASKDWORD,  			      0x00010000);  	}  	/* MAC settings */  	_rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,  					    rtlphy->iqk_mac_backup);  	/* Page B init */ -	rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000); +	rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);  	if (is2t) -		rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); +		rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000);  	/* IQ calibration setting */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK setting!\n"); -	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); -	rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00); -	rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +	rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); +	rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);  	for (i = 0; i < retrycount; i++) {  		patha_ok = _rtl92d_phy_patha_iqk(hw, is2t);  		if (patha_ok == 0x03) {  			RTPRINT(rtlpriv, FINIT, INIT_IQK,  				"Path A IQK Success!!\n"); -			result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & +			result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &  					0x3FF0000) >> 16; -			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & +			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &  					0x3FF0000) >> 16; -			result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) & +			result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &  					0x3FF0000) >> 16; -			result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) & +			result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &  					0x3FF0000) >> 16;  			break;  		} else if (i == (retrycount - 1) && patha_ok == 0x01) { @@ -1967,9 +1880,9 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],  			RTPRINT(rtlpriv, FINIT, INIT_IQK,  				"Path A IQK Only  Tx Success!!\n"); -			result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & +			result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &  					0x3FF0000) >> 16; -			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & +			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &  					0x3FF0000) >> 16;  		}  	} @@ -1985,22 +1898,22 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],  				RTPRINT(rtlpriv, FINIT, INIT_IQK,  					"Path B IQK Success!!\n");  				result[t][4] = (rtl_get_bbreg(hw, 0xeb4, -					       BMASKDWORD) & 0x3FF0000) >> 16; +					       MASKDWORD) & 0x3FF0000) >> 16;  				result[t][5] = (rtl_get_bbreg(hw, 0xebc, -					       BMASKDWORD) & 0x3FF0000) >> 16; +					       MASKDWORD) & 0x3FF0000) >> 16;  				result[t][6] = (rtl_get_bbreg(hw, 0xec4, -					       BMASKDWORD) & 0x3FF0000) >> 16; +					       MASKDWORD) & 0x3FF0000) >> 16;  				result[t][7] = (rtl_get_bbreg(hw, 0xecc, -					       BMASKDWORD) & 0x3FF0000) >> 16; +					       MASKDWORD) & 0x3FF0000) >> 16;  				break;  			} else if (i == (retrycount - 1) && pathb_ok == 0x01) {  				/* Tx IQK OK */  				RTPRINT(rtlpriv, FINIT, INIT_IQK,  					"Path B Only Tx IQK Success!!\n");  				result[t][4] = (rtl_get_bbreg(hw, 0xeb4, -					       BMASKDWORD) & 0x3FF0000) >> 16; +					       MASKDWORD) & 0x3FF0000) >> 16;  				result[t][5] = (rtl_get_bbreg(hw, 0xebc, -					       BMASKDWORD) & 0x3FF0000) >> 16; +					       MASKDWORD) & 0x3FF0000) >> 16;  			}  		}  		if (0x00 == pathb_ok) @@ -2012,7 +1925,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  		"IQK:Back to BB mode, load original value!\n"); -	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);  	if (t != 0) {  		/* Switch back BB to SI mode after finish IQ Calibration. */  		if (!rtlphy->rfpi_enable) @@ -2032,8 +1945,8 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],  							  rtlphy->iqk_bb_backup,  							  IQK_BB_REG_NUM - 1);  		/* load 0xe30 IQC default value */ -		rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00); -		rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00); +		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); +		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);  	}  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "<==\n");  } @@ -2070,7 +1983,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK for 5G NORMAL:Start!!!\n");  	mdelay(IQK_DELAY_TIME * 20);  	if (t == 0) { -		bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); +		bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, MASKDWORD);  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "==>0x%08x\n", bbvalue);  		RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",  			is2t ? "2T2R" : "1T1R"); @@ -2100,38 +2013,38 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,  	if (!rtlphy->rfpi_enable)  		_rtl92d_phy_pimode_switch(hw, true);  	rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); -	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600); -	rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4); -	rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22208000); +	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600); +	rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4); +	rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208000);  	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);  	/* Page B init */ -	rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000); +	rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);  	if (is2t) -		rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); +		rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000);  	/* IQ calibration setting  */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK setting!\n"); -	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); -	rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00); -	rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +	rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x10007c00); +	rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);  	patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t);  	if (patha_ok == 0x03) {  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK Success!!\n"); -		result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & +		result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &  				0x3FF0000) >> 16; -		result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & +		result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &  				0x3FF0000) >> 16; -		result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) & +		result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &  				0x3FF0000) >> 16; -		result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) & +		result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &  				0x3FF0000) >> 16;  	} else if (patha_ok == 0x01) {	/* Tx IQK OK */  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  			"Path A IQK Only  Tx Success!!\n"); -		result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & +		result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &  				0x3FF0000) >> 16; -		result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & +		result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &  				0x3FF0000) >> 16;  	} else {  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK Fail!!\n"); @@ -2144,20 +2057,20 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,  		if (pathb_ok == 0x03) {  			RTPRINT(rtlpriv, FINIT, INIT_IQK,  				"Path B IQK Success!!\n"); -			result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & +			result[t][4] = (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &  			     0x3FF0000) >> 16; -			result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & +			result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &  			     0x3FF0000) >> 16; -			result[t][6] = (rtl_get_bbreg(hw, 0xec4, BMASKDWORD) & +			result[t][6] = (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &  			     0x3FF0000) >> 16; -			result[t][7] = (rtl_get_bbreg(hw, 0xecc, BMASKDWORD) & +			result[t][7] = (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &  			     0x3FF0000) >> 16;  		} else if (pathb_ok == 0x01) { /* Tx IQK OK */  			RTPRINT(rtlpriv, FINIT, INIT_IQK,  				"Path B Only Tx IQK Success!!\n"); -			result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & +			result[t][4] = (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &  			     0x3FF0000) >> 16; -			result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & +			result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &  			     0x3FF0000) >> 16;  		} else {  			RTPRINT(rtlpriv, FINIT, INIT_IQK, @@ -2168,7 +2081,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,  	/* Back to BB mode, load original value */  	RTPRINT(rtlpriv, FINIT, INIT_IQK,  		"IQK:Back to BB mode, load original value!\n"); -	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);  	if (t != 0) {  		if (is2t)  			_rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg, @@ -2268,7 +2181,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,  		return;  	} else if (iqk_ok) {  		oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, -			BMASKDWORD) >> 22) & 0x3FF;	/* OFDM0_D */ +			MASKDWORD) >> 22) & 0x3FF;	/* OFDM0_D */  		val_x = result[final_candidate][0];  		if ((val_x & 0x00000200) != 0)  			val_x = val_x | 0xFFFFFC00; @@ -2299,7 +2212,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,  				      ((val_y * oldval_0 >> 7) & 0x1));  		RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n",  			rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, -				      BMASKDWORD)); +				      MASKDWORD));  		if (txonly) {  			RTPRINT(rtlpriv, FINIT, INIT_IQK,  "only Tx OK\n");  			return; @@ -2327,7 +2240,7 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,  		return;  	} else if (iqk_ok) {  		oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, -					  BMASKDWORD) >> 22) & 0x3FF; +					  MASKDWORD) >> 22) & 0x3FF;  		val_x = result[final_candidate][4];  		if ((val_x & 0x00000200) != 0)  			val_x = val_x | 0xFFFFFC00; @@ -2685,7 +2598,7 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)  		rf_mode[index] = rtl_read_byte(rtlpriv, offset);  		/* 2. Set RF mode = standby mode */  		rtl_set_rfreg(hw, (enum radio_path)index, RF_AC, -			      BRFREGOFFSETMASK, 0x010000); +			      RFREG_OFFSET_MASK, 0x010000);  		if (rtlpci->init_ready) {  			/* switch CV-curve control by LC-calibration */  			rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7, @@ -2695,16 +2608,16 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)  				      0x08000, 0x01);  		}  		u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6, -				  BRFREGOFFSETMASK); +				  RFREG_OFFSET_MASK);  		while ((!(u4tmp & BIT(11))) && timecount <= timeout) {  			mdelay(50);  			timecount += 50;  			u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, -					      RF_SYN_G6, BRFREGOFFSETMASK); +					      RF_SYN_G6, RFREG_OFFSET_MASK);  		}  		RTPRINT(rtlpriv, FINIT, INIT_IQK,  			"PHY_LCK finish delay for %d ms=2\n", timecount); -		u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK); +		u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, RFREG_OFFSET_MASK);  		if (index == 0 && rtlhal->interfaceindex == 0) {  			RTPRINT(rtlpriv, FINIT, INIT_IQK,  				"path-A / 5G LCK\n"); @@ -2724,9 +2637,9 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)  				      0x7f, i);  			rtl_set_rfreg(hw, (enum radio_path)index, 0x4D, -				BRFREGOFFSETMASK, 0x0); +				RFREG_OFFSET_MASK, 0x0);  			readval = rtl_get_rfreg(hw, (enum radio_path)index, -					  0x4F, BRFREGOFFSETMASK); +					  0x4F, RFREG_OFFSET_MASK);  			curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5;  			/* reg 0x4f [4:0] */  			/* reg 0x50 [19:10] */ @@ -2940,7 +2853,7 @@ static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,  				}  				rtl_set_rfreg(hw, (enum radio_path)rfpath,  					      currentcmd->para1, -					      BRFREGOFFSETMASK, +					      RFREG_OFFSET_MASK,  					      rtlphy->rfreg_chnlval[rfpath]);  				_rtl92d_phy_reload_imr_setting(hw, channel,  							       rfpath); @@ -2988,7 +2901,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)  	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&  	    rtlhal->bandset == BAND_ON_BOTH) {  		ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER, -					  BMASKDWORD); +					  MASKDWORD);  		if (rtlphy->current_channel > 14 && !(ret_value & BIT(0)))  			rtl92d_phy_switch_wirelessband(hw, BAND_ON_5G);  		else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0))) @@ -3140,7 +3053,7 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)  	/* a.   TXPAUSE 0x522[7:0] = 0xFF  Pause MAC TX queue  */  	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);  	/* b.   RF path 0 offset 0x00 = 0x00  disable RF  */ -	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); +	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);  	/* c.   APSD_CTRL 0x600[7:0] = 0x40 */  	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);  	/* d. APSD_CTRL 0x600[7:0] = 0x00 @@ -3148,12 +3061,12 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)  	 * RF path 0 offset 0x00 = 0x00  	 * APSD_CTRL 0x600[7:0] = 0x40  	 * */ -	u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK); +	u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);  	while (u4btmp != 0 && delay > 0) {  		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); -		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00); +		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);  		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); -		u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK); +		u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);  		delay--;  	}  	if (delay == 0) { @@ -3496,9 +3409,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)  		/* 5G LAN ON */  		rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa);  		/* TX BB gain shift*1,Just for testchip,0xc80,0xc88 */ -		rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, +		rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, MASKDWORD,  			      0x40000100); -		rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, +		rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, MASKDWORD,  			      0x40000100);  		if (rtlhal->macphymode == DUALMAC_DUALPHY) {  			rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, @@ -3552,16 +3465,16 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)  		rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0);  		/* TX BB gain shift,Just for testchip,0xc80,0xc88 */  		if (rtlefuse->internal_pa_5g[0]) -			rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, +			rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, MASKDWORD,  				      0x2d4000b5);  		else -			rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD, +			rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, MASKDWORD,  				      0x20000080);  		if (rtlefuse->internal_pa_5g[1]) -			rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, +			rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, MASKDWORD,  				      0x2d4000b5);  		else -			rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD, +			rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, MASKDWORD,  				      0x20000080);  		if (rtlhal->macphymode == DUALMAC_DUALPHY) {  			rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, @@ -3588,8 +3501,8 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)  		}  	}  	/* update IQK related settings */ -	rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, BMASKDWORD, 0x40000100); -	rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, BMASKDWORD, 0x40000100); +	rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, MASKDWORD, 0x40000100); +	rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, MASKDWORD, 0x40000100);  	rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, 0x00);  	rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) |  		      BIT(26) | BIT(24), 0x00); @@ -3618,7 +3531,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)  	/* DMDP */  	if (rtlphy->rf_type == RF_1T1R) {  		/* Use antenna 0,0xc04,0xd04 */ -		rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x11); +		rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x11);  		rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1);  		/* enable ad/da clock1 for dual-phy reg0x888 */ @@ -3640,7 +3553,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)  	} else {  		/* Single PHY */  		/* Use antenna 0 & 1,0xc04,0xd04 */ -		rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x33); +		rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x33);  		rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3);  		/* disable ad/da clock1,0x888 */  		rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0); @@ -3648,9 +3561,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)  	for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;  	     rfpath++) {  		rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath, -						RF_CHNLBW, BRFREGOFFSETMASK); +						RF_CHNLBW, RFREG_OFFSET_MASK);  		rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C, -			BRFREGOFFSETMASK); +			RFREG_OFFSET_MASK);  	}  	for (i = 0; i < 2; i++)  		RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n", diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h index f074952bf25..48d5c6835b6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h @@ -39,9 +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  #define	APK_BB_REG_NUM				5  #define	APK_AFE_REG_NUM				16 @@ -127,34 +125,32 @@ static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,  			*flag);  } -extern u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, -				   u32 regaddr, u32 bitmask); -extern void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, -				  u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, -				   enum radio_path rfpath, u32 regaddr, -				   u32 bitmask); -extern void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, -				  enum radio_path rfpath, u32 regaddr, -				  u32 bitmask, u32 data); -extern bool rtl92d_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl92d_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl92d_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, -						 enum radio_path rfpath); -extern void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -extern void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, -					     u8 operation); -extern void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, -				   enum nl80211_channel_type ch_type); -extern u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw); +u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, +			    u32 regaddr, u32 bitmask); +void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, +			   u32 regaddr, u32 bitmask, u32 data); +u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, +			    enum radio_path rfpath, u32 regaddr, +			    u32 bitmask); +void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, +			   enum radio_path rfpath, u32 regaddr, +			   u32 bitmask, u32 data); +bool rtl92d_phy_mac_config(struct ieee80211_hw *hw); +bool rtl92d_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92d_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, +					  enum radio_path rfpath); +void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, +			    enum nl80211_channel_type ch_type); +u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw);  bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  					  enum rf_content content,  					  enum radio_path rfpath);  bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, -					  enum rf_pwrstate rfpwr_state); +bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, +				   enum rf_pwrstate rfpwr_state);  void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw);  void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw); @@ -173,6 +169,5 @@ void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,  				       unsigned long *flag);  u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl);  void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel); -void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h index b7498c5bafc..7f29b8d765b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h @@ -1295,18 +1295,4 @@  #define	BWORD1					0xc  #define	BDWORD					0xf -#define	BMASKBYTE0				0xff -#define	BMASKBYTE1				0xff00 -#define	BMASKBYTE2				0xff0000 -#define	BMASKBYTE3				0xff000000 -#define	BMASKHWORD				0xffff0000 -#define	BMASKLWORD				0x0000ffff -#define	BMASKDWORD				0xffffffff -#define	BMASK12BITS				0xfff -#define	BMASKH4BITS				0xf0000000 -#define BMASKOFDM_D				0xffc00000 -#define	BMASKCCK				0x3f3f3f3f - -#define BRFREGOFFSETMASK			0xfffff -  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index 20144e0b414..6a6ac540d5b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -125,7 +125,7 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,  	}  	tmpval = tx_agc[RF90_PATH_A] & 0xff; -	rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval); +	rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);  	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,  		"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",  		tmpval, RTXAGC_A_CCK1_MCS32); @@ -135,7 +135,7 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,  		"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",  		tmpval, RTXAGC_B_CCK11_A_CCK2_11);  	tmpval = tx_agc[RF90_PATH_B] >> 24; -	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval); +	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);  	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,  		"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",  		tmpval, RTXAGC_B_CCK11_A_CCK2_11); @@ -360,7 +360,7 @@ static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,  			regoffset = regoffset_a[index];  		else  			regoffset = regoffset_b[index]; -		rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval); +		rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);  		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,  			"Set 0x%x = %08x\n", regoffset, writeval);  		if (((get_rf_type(rtlphy) == RF_2T2R) && diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h index 0fe1a48593e..7303d12c266 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h @@ -30,15 +30,13 @@  #ifndef __RTL92D_RF_H__  #define __RTL92D_RF_H__ -extern void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, -					    u8 bandwidth); -extern void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, -					      u8 *ppowerlevel); -extern void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, -					       u8 *ppowerlevel, u8 channel); -extern bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw); -extern bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); -extern void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, -					    bool bmac0); +void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +				       u8 *ppowerlevel); +void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +					u8 *ppowerlevel, u8 channel); +bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw); +bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); +void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index c18c04bf0c1..edab5a5351b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -30,6 +30,7 @@  #include "../wifi.h"  #include "../core.h"  #include "../pci.h" +#include "../base.h"  #include "reg.h"  #include "def.h"  #include "phy.h" @@ -236,7 +237,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = {  	.set_bw_mode = rtl92d_phy_set_bw_mode,  	.switch_channel = rtl92d_phy_sw_chnl,  	.dm_watchdog = rtl92d_dm_watchdog, -	.scan_operation_backup = rtl92d_phy_scan_operation_backup, +	.scan_operation_backup = rtl_phy_scan_operation_backup,  	.set_rf_power_state = rtl92d_phy_set_rf_power_state,  	.led_control = rtl92de_led_control,  	.set_desc = rtl92de_set_desc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index b8ec718a0fa..99c2ab5dfce 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -525,8 +525,7 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,	struct rtl_stats *stats,  						   p_drvinfo);  	}  	/*rx_status->qual = stats->signal; */ -	rx_status->signal = stats->rssi + 10; -	/*rx_status->noise = -stats->noise; */ +	rx_status->signal = stats->recvsignalpower + 10;  	return true;  } @@ -546,7 +545,7 @@ static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,  void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,  			  struct ieee80211_hdr *hdr, u8 *pdesc_tx, -			  struct ieee80211_tx_info *info, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			  struct ieee80211_sta *sta,  			  struct sk_buff *skb,  			  u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) @@ -787,7 +786,8 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,  	SET_TX_DESC_OWN(pdesc, 1);  } -void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) +void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +		      u8 desc_name, u8 *val)  {  	if (istx) {  		switch (desc_name) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h index c1b5dfb79d5..fb5cf0634e8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h @@ -728,8 +728,8 @@ struct rx_desc_92d {  } __packed;  void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, -			  struct ieee80211_hdr *hdr, -			  u8 *pdesc, struct ieee80211_tx_info *info, +			  struct ieee80211_hdr *hdr, u8 *pdesc, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			  struct ieee80211_sta *sta,  			  struct sk_buff *skb, u8 hw_queue,  			  struct rtl_tcb_desc *ptcb_desc); @@ -737,7 +737,8 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,  			   struct rtl_stats *stats,  			   struct ieee80211_rx_status *rx_status,  			   u8 *pdesc, struct sk_buff *skb); -void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); +void rtl92de_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +		      u8 desc_name, u8 *val);  u32 rtl92de_get_desc(u8 *pdesc, bool istx, u8 desc_name);  void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);  void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 4f461786a7e..1c7101bcd79 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -251,7 +251,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			u8 e_aci = *val;  			rtl92s_dm_init_edca_turbo(hw); -			if (rtlpci->acm_method != eAcmWay2_SW) +			if (rtlpci->acm_method != EACMWAY2_SW)  				rtlpriv->cfg->ops->set_hw_reg(hw,  						 HW_VAR_ACM_CTRL,  						 &e_aci); @@ -413,20 +413,18 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  					(u8 *)(&fw_current_inps));  			rtlpriv->cfg->ops->set_hw_reg(hw,  					HW_VAR_H2C_FW_PWRMODE, -					(u8 *)(&ppsc->fwctrl_psmode)); +					&ppsc->fwctrl_psmode); -			rtlpriv->cfg->ops->set_hw_reg(hw, -					HW_VAR_SET_RPWM, -					(u8 *)(&rpwm_val)); +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, +						      &rpwm_val);  		} else {  			rpwm_val = 0x0C;	/* RF on */  			fw_pwrmode = FW_PS_ACTIVE_MODE;  			fw_current_inps = false;  			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, -					(u8 *)(&rpwm_val)); -			rtlpriv->cfg->ops->set_hw_reg(hw, -					HW_VAR_H2C_FW_PWRMODE, -					(u8 *)(&fw_pwrmode)); +						      &rpwm_val); +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, +						      &fw_pwrmode);  			rtlpriv->cfg->ops->set_hw_reg(hw,  					HW_VAR_FW_PSMODE_STATUS, @@ -955,7 +953,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));  	u8 tmp_byte = 0; - +	unsigned long flags;  	bool rtstatus = true;  	u8 tmp_u1b;  	int err = false; @@ -967,6 +965,16 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)  	rtlpci->being_init_adapter = true; +	/* As this function can take a very long time (up to 350 ms) +	 * and can be called with irqs disabled, reenable the irqs +	 * to let the other devices continue being serviced. +	 * +	 * It is safe doing so since our own interrupts will only be enabled +	 * in a subsequent step. +	 */ +	local_save_flags(flags); +	local_irq_enable(); +  	rtlpriv->intf_ops->disable_aspm(hw);  	/* 1. MAC Initialize */ @@ -984,7 +992,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  			 "Failed to download FW. Init HW without FW now... "  			 "Please copy FW into /lib/firmware/rtlwifi\n"); -		return 1; +		err = 1; +		goto exit;  	}  	/* After FW download, we have to reset MAC register */ @@ -997,7 +1006,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)  	/* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */  	if (!rtl92s_phy_mac_config(hw)) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n"); -		return rtstatus; +		err = rtstatus; +		goto exit;  	}  	/* because last function modify RCR, so we update @@ -1016,7 +1026,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)  	/* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */  	if (!rtl92s_phy_bb_config(hw)) {  		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n"); -		return rtstatus; +		err = rtstatus; +		goto exit;  	}  	/* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */ @@ -1033,7 +1044,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)  	if (!rtl92s_phy_rf_config(hw)) {  		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); -		return rtstatus; +		err = rtstatus; +		goto exit;  	}  	/* After read predefined TXT, we must set BB/MAC/RF @@ -1122,8 +1134,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)  	rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);  	rtl92s_dm_init(hw); +exit: +	local_irq_restore(flags);  	rtlpci->being_init_adapter = false; -  	return err;  } @@ -1135,12 +1148,13 @@ void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr)  void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); -	u32 reg_rcr = rtlpci->receive_config; +	u32 reg_rcr;  	if (rtlpriv->psc.rfpwr_state != ERFON)  		return; +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); +  	if (check_bssid) {  		reg_rcr |= (RCR_CBSSID);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); @@ -2530,23 +2544,3 @@ void rtl92se_resume(struct ieee80211_hw *hw)  		pci_write_config_dword(rtlpci->pdev, 0x40,  			val & 0xffff00ff);  } - -/* Turn on AAP (RCR:bit 0) for promicuous mode. */ -void rtl92se_allow_all_destaddr(struct ieee80211_hw *hw, -				bool allow_all_da, bool write_into_reg) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - -	if (allow_all_da) /* Set BIT0 */ -		rtlpci->receive_config |= RCR_AAP; -	else /* Clear BIT0 */ -		rtlpci->receive_config &= ~RCR_AAP; - -	if (write_into_reg) -		rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config); - -	RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, -		 "receive_config=0x%08X, write_into_reg=%d\n", -		 rtlpci->receive_config, write_into_reg); -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h index da48aa8cbe6..4cacee10f31 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h @@ -74,7 +74,5 @@ void rtl92se_set_key(struct ieee80211_hw *hw,  		     u8 enc_algo, bool is_wepkey, bool clear_all);  void rtl92se_suspend(struct ieee80211_hw *hw);  void rtl92se_resume(struct ieee80211_hw *hw); -void rtl92se_allow_all_destaddr(struct ieee80211_hw *hw, -				bool allow_all_da, bool write_into_reg);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 9c092e6eb3f..77c5b5f3524 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -30,6 +30,7 @@  #include "../wifi.h"  #include "../pci.h"  #include "../ps.h" +#include "../core.h"  #include "reg.h"  #include "def.h"  #include "phy.h" @@ -833,18 +834,7 @@ static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_reg_len; i = i + 2) { -			if (phy_reg_table[i] == 0xfe) -				mdelay(50); -			else if (phy_reg_table[i] == 0xfd) -				mdelay(5); -			else if (phy_reg_table[i] == 0xfc) -				mdelay(1); -			else if (phy_reg_table[i] == 0xfb) -				udelay(50); -			else if (phy_reg_table[i] == 0xfa) -				udelay(5); -			else if (phy_reg_table[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_reg_table[i]);  			/* Add delay for ECS T20 & LG malow platform, */  			udelay(1); @@ -886,18 +876,7 @@ static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) { -			if (phy_regarray2xtxr_table[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray2xtxr_table[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray2xtxr_table[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray2xtxr_table[i] == 0xfb) -				udelay(50); -			else if (phy_regarray2xtxr_table[i] == 0xfa) -				udelay(5); -			else if (phy_regarray2xtxr_table[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_regarray2xtxr_table[i]);  			rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],  				phy_regarray2xtxr_table[i + 1], @@ -920,18 +899,7 @@ static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_pg_len; i = i + 3) { -			if (phy_table_pg[i] == 0xfe) -				mdelay(50); -			else if (phy_table_pg[i] == 0xfd) -				mdelay(5); -			else if (phy_table_pg[i] == 0xfc) -				mdelay(1); -			else if (phy_table_pg[i] == 0xfb) -				udelay(50); -			else if (phy_table_pg[i] == 0xfa) -				udelay(5); -			else if (phy_table_pg[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_table_pg[i]);  			_rtl92s_store_pwrindex_diffrate_offset(hw,  					phy_table_pg[i], @@ -1034,28 +1002,9 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)  	switch (rfpath) {  	case RF90_PATH_A:  		for (i = 0; i < radio_a_tblen; i = i + 2) { -			if (radio_a_table[i] == 0xfe) -				/* Delay specific ms. Only RF configuration -				 * requires delay. */ -				mdelay(50); -			else if (radio_a_table[i] == 0xfd) -				mdelay(5); -			else if (radio_a_table[i] == 0xfc) -				mdelay(1); -			else if (radio_a_table[i] == 0xfb) -				udelay(50); -			else if (radio_a_table[i] == 0xfa) -				udelay(5); -			else if (radio_a_table[i] == 0xf9) -				udelay(1); -			else -				rtl92s_phy_set_rf_reg(hw, rfpath, -						      radio_a_table[i], -						      MASK20BITS, -						      radio_a_table[i + 1]); +			rtl_rfreg_delay(hw, rfpath, radio_a_table[i], +					MASK20BITS, radio_a_table[i + 1]); -			/* Add delay for ECS T20 & LG malow platform */ -			udelay(1);  		}  		/* PA Bias current for inferiority IC */ @@ -1063,28 +1012,8 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)  		break;  	case RF90_PATH_B:  		for (i = 0; i < radio_b_tblen; i = i + 2) { -			if (radio_b_table[i] == 0xfe) -				/* Delay specific ms. Only RF configuration -				 * requires delay.*/ -				mdelay(50); -			else if (radio_b_table[i] == 0xfd) -				mdelay(5); -			else if (radio_b_table[i] == 0xfc) -				mdelay(1); -			else if (radio_b_table[i] == 0xfb) -				udelay(50); -			else if (radio_b_table[i] == 0xfa) -				udelay(5); -			else if (radio_b_table[i] == 0xf9) -				udelay(1); -			else -				rtl92s_phy_set_rf_reg(hw, rfpath, -						      radio_b_table[i], -						      MASK20BITS, -						      radio_b_table[i + 1]); - -			/* Add delay for ECS T20 & LG malow platform */ -			udelay(1); +			rtl_rfreg_delay(hw, rfpath, radio_b_table[i], +					MASK20BITS, radio_b_table[i + 1]);  		}  		break;  	case RF90_PATH_C: diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h index 84d1181795b..e13043479b7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h @@ -425,14 +425,9 @@  #define	EXT_IMEM_CODE_DONE			BIT(2)  #define	IMEM_CHK_RPT				BIT(1)  #define	IMEM_CODE_DONE				BIT(0) -#define	IMEM_CODE_DONE				BIT(0) -#define	IMEM_CHK_RPT				BIT(1)  #define	EMEM_CODE_DONE				BIT(2)  #define	EMEM_CHK_RPT				BIT(3) -#define	DMEM_CODE_DONE				BIT(4)  #define	IMEM_RDY				BIT(5) -#define	BASECHG					BIT(6) -#define	FWRDY					BIT(7)  #define	LOAD_FW_READY				(IMEM_CODE_DONE | \  						IMEM_CHK_RPT | \  						EMEM_CODE_DONE | \ @@ -1170,16 +1165,4 @@  #define	BTX_AGCRATECCK				0x7f00 -#define	MASKBYTE0				0xff -#define	MASKBYTE1				0xff00 -#define	MASKBYTE2				0xff0000 -#define	MASKBYTE3				0xff000000 -#define	MASKHWORD				0xffff0000 -#define	MASKLWORD				0x0000ffff -#define	MASKDWORD				0xffffffff - -#define	MAKS12BITS				0xfffff -#define	MASK20BITS				0xfffff -#define RFREG_OFFSET_MASK			0xfffff -  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 5061f1db3f0..78a81c1e390 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -52,7 +52,7 @@ static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,  	/* We only care about the path A for legacy. */  	if (rtlefuse->eeprom_version < 2) {  		pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf); -	} else if (rtlefuse->eeprom_version >= 2) { +	} else {  		legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff  						[RF90_PATH_A][chnl - 1]; @@ -265,7 +265,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,  				    rtlefuse->pwrgroup_ht40  				    [RF90_PATH_A][chnl - 1]) {  					pwrdiff_limit[i] = -					  rtlefuse->pwrgroup_ht20 +					  rtlefuse->pwrgroup_ht40  					  [RF90_PATH_A][chnl - 1];  				}  			} else { diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 2e8e6f8d2d5..1bff2a0f760 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -290,7 +290,6 @@ static struct rtl_hal_ops rtl8192se_hal_ops = {  	.enable_hw_sec = rtl92se_enable_hw_security_config,  	.set_key = rtl92se_set_key,  	.init_sw_leds = rtl92se_init_sw_leds, -	.allow_all_destaddr = rtl92se_allow_all_destaddr,  	.get_bbreg = rtl92s_phy_query_bb_reg,  	.set_bbreg = rtl92s_phy_set_bb_reg,  	.get_rfreg = rtl92s_phy_query_rf_reg, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index c7095118de6..2b3c78baa9f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -49,6 +49,12 @@ static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb,	u8 skb_queue)  	if (ieee80211_is_nullfunc(fc))  		return QSLT_HIGH; +	/* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use +	 * queue V0 at priority 7; however, the RTL8192SE appears to have +	 * that queue at priority 6 +	 */ +	if (skb->priority == 7) +		return QSLT_VO;  	return skb->priority;  } @@ -310,7 +316,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,  			/* during testing, hdr was NULL here */  			return false;  		} -		if ((ieee80211_is_robust_mgmt_frame(hdr)) && +		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&  			(ieee80211_has_protected(hdr->frame_control)))  			rx_status->flag &= ~RX_FLAG_DECRYPTED;  		else @@ -329,15 +335,14 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,  	}  	/*rx_status->qual = stats->signal; */ -	rx_status->signal = stats->rssi + 10; -	/*rx_status->noise = -stats->noise; */ +	rx_status->signal = stats->recvsignalpower + 10;  	return true;  }  void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,  		struct ieee80211_hdr *hdr, u8 *pdesc_tx, -		struct ieee80211_tx_info *info, +		u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  		struct ieee80211_sta *sta,  		struct sk_buff *skb,  		u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) @@ -574,7 +579,8 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,  	}  } -void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) +void rtl92se_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +		      u8 desc_name, u8 *val)  {  	if (istx) {  		switch (desc_name) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h index 64dd66f287c..5a13f17e3b4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h @@ -29,8 +29,9 @@  #ifndef __REALTEK_PCI92SE_TRX_H__  #define __REALTEK_PCI92SE_TRX_H__ -void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, -			  u8 *pdesc, struct ieee80211_tx_info *info, +void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, +			  struct ieee80211_hdr *hdr, u8 *pdesc, +			  u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			  struct ieee80211_sta *sta,  			  struct sk_buff *skb, u8 hw_queue,  			  struct rtl_tcb_desc *ptcb_desc); @@ -39,7 +40,8 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool firstseg,  bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,  			   struct ieee80211_rx_status *rx_status, u8 *pdesc,  			   struct sk_buff *skb); -void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); +void rtl92se_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +		      u8 desc_name, u8 *val);  u32 rtl92se_get_desc(u8 *pdesc, bool istx, u8 desc_name);  void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile index 4ed731f09b1..9c34a85fdb8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile @@ -10,7 +10,6 @@ rtl8723ae-objs :=		\  		led.o		\  		phy.o		\  		pwrseq.o	\ -		pwrseqcmd.o	\  		rf.o		\  		sw.o		\  		table.o		\ diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h index 8c110356dff..debe261a7ee 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h @@ -46,11 +46,6 @@  #define E_CUT_VERSION			BIT(14)  #define	RF_RL_ID			(BIT(31)|BIT(30)|BIT(29)|BIT(28)) -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, -};  /* MASK */  #define IC_TYPE_MASK			(BIT(0)|BIT(1)|BIT(2)) diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c index a36eee28f9e..25cc83058b0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c @@ -35,6 +35,7 @@  #include "def.h"  #include "phy.h"  #include "dm.h" +#include "../rtl8723com/dm_common.h"  #include "fw.h"  #include "hal_btc.h" @@ -483,16 +484,6 @@ static void rtl8723ae_dm_dig(struct ieee80211_hw *hw)  	rtl8723ae_dm_ctrl_initgain_by_twoport(hw);  } -static void rtl8723ae_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; -} -  static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -585,19 +576,6 @@ void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw)  	}  } -static void rtl8723ae_dm_pwdmonitor(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_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; -} -  static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -669,9 +647,8 @@ static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw)  	} else {  		if (rtlpriv->dm.current_turbo_edca) {  			u8 tmp = AC0_BE; -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_AC_PARAM, -						      (u8 *) (&tmp)); +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, +						      &tmp);  			rtlpriv->dm.current_turbo_edca = false;  		}  	} @@ -778,17 +755,6 @@ static void rtl8723ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)  	}  } -static void rtl8723ae_dm_init_dynamic_bpowersaving(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; -} -  void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -905,11 +871,11 @@ void rtl8723ae_dm_init(struct ieee80211_hw *hw)  	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;  	rtl8723ae_dm_diginit(hw); -	rtl8723ae_dm_init_dynamic_txpower(hw); -	rtl8723ae_dm_init_edca_turbo(hw); +	rtl8723_dm_init_dynamic_txpower(hw); +	rtl8723_dm_init_edca_turbo(hw);  	rtl8723ae_dm_init_rate_adaptive_mask(hw);  	rtl8723ae_dm_initialize_txpower_tracking(hw); -	rtl8723ae_dm_init_dynamic_bpowersaving(hw); +	rtl8723_dm_init_dynamic_bb_powersaving(hw);  }  void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw) @@ -930,7 +896,6 @@ void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw)  	if ((ppsc->rfpwr_state == ERFON) &&  	    ((!fw_current_inpsmode) && fw_ps_awake) &&  	    (!ppsc->rfchange_inprogress)) { -		rtl8723ae_dm_pwdmonitor(hw);  		rtl8723ae_dm_dig(hw);  		rtl8723ae_dm_false_alarm_counter_statistics(hw);  		rtl8723ae_dm_dynamic_bpowersaving(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h index a372b020445..d253bb53d03 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h @@ -147,7 +147,6 @@ enum dm_dig_connect_e {  void rtl8723ae_dm_init(struct ieee80211_hw *hw);  void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw);  void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw); -void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw);  void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);  void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);  void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c index ba1502b172a..728b7563ad3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c @@ -34,199 +34,7 @@  #include "reg.h"  #include "def.h"  #include "fw.h" - -static void _rtl8723ae_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); -	} -} - -static void _rtl8723ae_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)); -		} -	} -} - -static void _rtl8723ae_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); -	_rtl8723ae_fw_block_write(hw, buffer, size); -} - -static void _rtl8723ae_write_fw(struct ieee80211_hw *hw, -				enum version_8723e version, u8 *buffer, -				u32 size) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	u8 *bufferPtr = (u8 *) buffer; -	u32 page_nums, remain_size; -	u32 page, offset; - -	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); - -	page_nums = size / FW_8192C_PAGE_SIZE; -	remain_size = size % FW_8192C_PAGE_SIZE; - -	if (page_nums > 6) { -		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -			 "Page numbers should not be greater then 6\n"); -	} - -	for (page = 0; page < page_nums; page++) { -		offset = page * FW_8192C_PAGE_SIZE; -		_rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset), -					 FW_8192C_PAGE_SIZE); -	} - -	if (remain_size) { -		offset = page_nums * FW_8192C_PAGE_SIZE; -		page = page_nums; -		_rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset), -					 remain_size); -	} - -	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n"); -} - -static int _rtl8723ae_fw_free_to_go(struct ieee80211_hw *hw) -{ -	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 faill ! 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); -	value32 |= MCUFWDL_RDY; -	value32 &= ~WINTINI_RDY; -	rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); - -	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; -		} - -		mdelay(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; -} - -int rtl8723ae_download_fw(struct ieee80211_hw *hw) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	struct rtl8723ae_firmware_header *pfwheader; -	u8 *pfwdata; -	u32 fwsize; -	int err; -	enum version_8723e version = rtlhal->version; - -	if (!rtlhal->pfirmware) -		return 1; - -	pfwheader = (struct rtl8723ae_firmware_header *)rtlhal->pfirmware; -	pfwdata = (u8 *) rtlhal->pfirmware; -	fwsize = rtlhal->fwsize; - -	if (IS_FW_HEADER_EXIST(pfwheader)) { -		RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, -			 "Firmware Version(%d), Signature(%#x),Size(%d)\n", -			 pfwheader->version, pfwheader->signature, -			 (int)sizeof(struct rtl8723ae_firmware_header)); - -		pfwdata = pfwdata + sizeof(struct rtl8723ae_firmware_header); -		fwsize = fwsize - sizeof(struct rtl8723ae_firmware_header); -	} - -	if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) { -		rtl8723ae_firmware_selfreset(hw); -		rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); -	} -	_rtl8723ae_enable_fw_download(hw, true); -	_rtl8723ae_write_fw(hw, version, pfwdata, fwsize); -	_rtl8723ae_enable_fw_download(hw, false); - -	err = _rtl8723ae_fw_free_to_go(hw); -	if (err) { -		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -			 "Firmware is not ready to run!\n"); -	} else { -		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, -			 "Firmware is ready to run!\n"); -	} -	return 0; -} +#include "../rtl8723com/fw_common.h"  static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)  { @@ -463,50 +271,6 @@ void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw,  	return;  } -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))); -	} -} - -void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	u8 u1_h2c_set_pwrmode[3] = { 0 }; -	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - -	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); - -	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); -	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, -					 (rtlpriv->mac80211.p2p) ? -					 ppsc->smart_ps : 1); -	SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, -					      ppsc->reg_max_lps_awakeintvl); - -	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, -		      "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", -		      u1_h2c_set_pwrmode, 3); -	rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); - -} -  static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw,  				       struct sk_buff *skb)  { @@ -812,7 +576,6 @@ void rtl8723ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  			rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));  			p2p_ps_offload->offload_en = 1; -  			if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {  				p2p_ps_offload->role = 1;  				p2p_ps_offload->allstasleep = 0; @@ -836,3 +599,24 @@ void rtl8723ae_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)  	}  	rtl8723ae_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);  } + +void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 u1_h2c_set_pwrmode[3] = { 0 }; +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + +	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); + +	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); +	SET_H2CCMD_PWRMODE_PARM_SMART_PS_23A(u1_h2c_set_pwrmode, +					     (rtlpriv->mac80211.p2p) ? +					     ppsc->smart_ps : 1); +	SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, +					      ppsc->reg_max_lps_awakeintvl); + +	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, +		      "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", +		      u1_h2c_set_pwrmode, 3); +	rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h index ed3b795e698..d355b85dd9f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h @@ -34,7 +34,7 @@  #define FW_8192C_END_ADDRESS			0x3FFF  #define FW_8192C_PAGE_SIZE			4096  #define FW_8192C_POLLING_DELAY			5 -#define FW_8192C_POLLING_TIMEOUT_COUNT		1000 +#define FW_8192C_POLLING_TIMEOUT_COUNT		6000  #define BEACON_PG				0  #define PSPOLL_PG				2 @@ -65,21 +65,9 @@ struct rtl8723ae_firmware_header {  	u32 rsvd5;  }; -enum rtl8192c_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 -}; -  #define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val)			\  	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val)		\ +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS_23A(__ph2ccmd, __val)		\  	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)  #define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val)	\  	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) @@ -92,10 +80,8 @@ enum rtl8192c_h2c_cmd {  #define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val)		\  	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) -int rtl8723ae_download_fw(struct ieee80211_hw *hw);  void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,  			    u32 cmd_len, u8 *p_cmdbuffer); -void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);  void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);  void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);  void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c index 3d092e4b0b7..5b4a714f3c8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c @@ -31,6 +31,7 @@  #include "../pci.h"  #include "dm.h"  #include "fw.h" +#include "../rtl8723com/fw_common.h"  #include "phy.h"  #include "reg.h"  #include "hal_btc.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c index 68c28340f79..5d534df8d90 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c @@ -30,7 +30,9 @@  #include "hal_btc.h"  #include "../pci.h"  #include "phy.h" +#include "../rtl8723com/phy_common.h"  #include "fw.h" +#include "../rtl8723com/fw_common.h"  #include "reg.h"  #include "def.h" @@ -391,13 +393,13 @@ static void rtl8723ae_dm_bt_set_sw_full_time_dac_swing(struct ieee80211_hw *hw,  	if (sw_dac_swing_on) {  		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,  			 "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl); -		rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, -					 sw_dac_swing_lvl); +		rtl8723_phy_set_bb_reg(hw, 0x880, 0xff000000, +				       sw_dac_swing_lvl);  		rtlpcipriv->bt_coexist.sw_coexist_all_off = false;  	} else {  		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,  			 "[BTCoex], SwDacSwing Off!\n"); -		rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0); +		rtl8723_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0);  	}  } diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c index c333dfd116b..87f69166a7e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c @@ -38,10 +38,11 @@  #include "def.h"  #include "phy.h"  #include "dm.h" +#include "../rtl8723com/dm_common.h"  #include "fw.h" +#include "../rtl8723com/fw_common.h"  #include "led.h"  #include "hw.h" -#include "pwrseqcmd.h"  #include "pwrseq.h"  #include "btc.h" @@ -206,14 +207,13 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		rtl_write_byte(rtlpriv, REG_SLOT, val[0]);  		for (e_aci = 0; e_aci < AC_MAX; e_aci++) { -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_AC_PARAM, -						      (u8 *) (&e_aci)); +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, +						      &e_aci);  		}  		break; }  	case HW_VAR_ACK_PREAMBLE:{  		u8 reg_tmp; -		u8 short_preamble = (bool) (*(u8 *) val); +		u8 short_preamble = (bool)*val;  		reg_tmp = (mac->cur_40_prime_sc) << 5;  		if (short_preamble)  			reg_tmp |= 0x80; @@ -224,7 +224,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		u8 min_spacing_to_set;  		u8 sec_min_space; -		min_spacing_to_set = *((u8 *) val); +		min_spacing_to_set = *val;  		if (min_spacing_to_set <= 7) {  			sec_min_space = 0; @@ -248,7 +248,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  	case HW_VAR_SHORTGI_DENSITY:{  		u8 density_to_set; -		density_to_set = *((u8 *) val); +		density_to_set = *val;  		mac->min_space_cfg |= (density_to_set << 3);  		RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, @@ -272,7 +272,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		else  			p_regtoset = regtoset_normal; -		factor_toset = *((u8 *) val); +		factor_toset = *val;  		if (factor_toset <= 3) {  			factor_toset = (1 << (factor_toset + 2));  			if (factor_toset > 0xf) @@ -303,16 +303,15 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		}  		break; }  	case HW_VAR_AC_PARAM:{ -		u8 e_aci = *((u8 *) val); -		rtl8723ae_dm_init_edca_turbo(hw); +		u8 e_aci = *val; +		rtl8723_dm_init_edca_turbo(hw); -		if (rtlpci->acm_method != eAcmWay2_SW) -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_ACM_CTRL, -						      (u8 *) (&e_aci)); +		if (rtlpci->acm_method != EACMWAY2_SW) +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, +						      &e_aci);  		break; }  	case HW_VAR_ACM_CTRL:{ -		u8 e_aci = *((u8 *) val); +		u8 e_aci = *val;  		union aci_aifsn *p_aci_aifsn =  		    (union aci_aifsn *)(&(mac->ac[0].aifs));  		u8 acm = p_aci_aifsn->f.acm; @@ -365,7 +364,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		rtlpci->receive_config = ((u32 *) (val))[0];  		break;  	case HW_VAR_RETRY_LIMIT:{ -		u8 retry_limit = ((u8 *) (val))[0]; +		u8 retry_limit = *val;  		rtl_write_word(rtlpriv, REG_RL,  			       retry_limit << RETRY_LIMIT_SHORT_SHIFT | @@ -378,13 +377,13 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		rtlefuse->efuse_usedbytes = *((u16 *) val);  		break;  	case HW_VAR_EFUSE_USAGE: -		rtlefuse->efuse_usedpercentage = *((u8 *) val); +		rtlefuse->efuse_usedpercentage = *val;  		break;  	case HW_VAR_IO_CMD:  		rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val));  		break;  	case HW_VAR_WPA_CONFIG: -		rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); +		rtl_write_byte(rtlpriv, REG_SECCFG, *val);  		break;  	case HW_VAR_SET_RPWM:{  		u8 rpwm_val; @@ -393,27 +392,25 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  		udelay(1);  		if (rpwm_val & BIT(7)) { -			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, -				       (*(u8 *) val)); +			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);  		} else { -			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, -				       ((*(u8 *) val) | BIT(7))); +			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));  		}  		break; }  	case HW_VAR_H2C_FW_PWRMODE:{ -		u8 psmode = (*(u8 *) val); +		u8 psmode = *val;  		if (psmode != FW_PS_ACTIVE_MODE)  			rtl8723ae_dm_rf_saving(hw, true); -		rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); +		rtl8723ae_set_fw_pwrmode_cmd(hw, *val);  		break; }  	case HW_VAR_FW_PSMODE_STATUS:  		ppsc->fw_current_inpsmode = *((bool *) val);  		break;  	case HW_VAR_H2C_FW_JOINBSSRPT:{ -		u8 mstatus = (*(u8 *) val); +		u8 mstatus = *val;  		u8 tmp_regcr, tmp_reg422;  		bool recover = false; @@ -446,11 +443,11 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  			rtl_write_byte(rtlpriv, REG_CR + 1,  				       (tmp_regcr & ~(BIT(0))));  		} -		rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); +		rtl8723ae_set_fw_joinbss_report_cmd(hw, *val);  		break; }  	case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: -		rtl8723ae_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); +		rtl8723ae_set_p2p_ps_offload_cmd(hw, *val);  		break;  	case HW_VAR_AID:{  		u16 u2btmp; @@ -460,7 +457,7 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  				mac->assoc_id));  		break; }  	case HW_VAR_CORRECT_TSF:{ -		u8 btype_ibss = ((u8 *) (val))[0]; +		u8 btype_ibss = *val;  		if (btype_ibss == true)  			_rtl8723ae_stop_tx_beacon(hw); @@ -490,20 +487,18 @@ void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)  					(u8 *)(&fw_current_inps));  			rtlpriv->cfg->ops->set_hw_reg(hw,  					HW_VAR_H2C_FW_PWRMODE, -					(u8 *)(&ppsc->fwctrl_psmode)); +					&ppsc->fwctrl_psmode); -			rtlpriv->cfg->ops->set_hw_reg(hw, -					HW_VAR_SET_RPWM, -					(u8 *)(&rpwm_val)); +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, +						      &rpwm_val);  		} else {  			rpwm_val = 0x0C;	/* RF on */  			fw_pwrmode = FW_PS_ACTIVE_MODE;  			fw_current_inps = false;  			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, -					(u8 *)(&rpwm_val)); -			rtlpriv->cfg->ops->set_hw_reg(hw, -					HW_VAR_H2C_FW_PWRMODE, -					(u8 *)(&fw_pwrmode)); +						      &rpwm_val); +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, +						      &fw_pwrmode);  			rtlpriv->cfg->ops->set_hw_reg(hw,  					HW_VAR_FW_PSMODE_STATUS, @@ -880,23 +875,33 @@ int rtl8723ae_hw_init(struct ieee80211_hw *hw)  	bool rtstatus = true;  	int err;  	u8 tmp_u1b; +	unsigned long flags;  	rtlpriv->rtlhal.being_init_adapter = true; +	/* As this function can take a very long time (up to 350 ms) +	 * and can be called with irqs disabled, reenable the irqs +	 * to let the other devices continue being serviced. +	 * +	 * It is safe doing so since our own interrupts will only be enabled +	 * in a subsequent step. +	 */ +	local_save_flags(flags); +	local_irq_enable(); +  	rtlpriv->intf_ops->disable_aspm(hw);  	rtstatus = _rtl8712e_init_mac(hw);  	if (rtstatus != true) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");  		err = 1; -		return err; +		goto exit;  	} -	err = rtl8723ae_download_fw(hw); +	err = rtl8723_download_fw(hw, false);  	if (err) {  		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,  			 "Failed to download FW. Init HW without FW now..\n");  		err = 1; -		rtlhal->fw_ready = false; -		return err; +		goto exit;  	} else {  		rtlhal->fw_ready = true;  	} @@ -971,6 +976,8 @@ int rtl8723ae_hw_init(struct ieee80211_hw *hw)  		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");  	}  	rtl8723ae_dm_init(hw); +exit: +	local_irq_restore(flags);  	rtlpriv->rtlhal.being_init_adapter = false;  	return err;  } @@ -1112,12 +1119,13 @@ static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw,  void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); -	u32 reg_rcr = rtlpci->receive_config; +	u32 reg_rcr;  	if (rtlpriv->psc.rfpwr_state != ERFON)  		return; +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); +  	if (check_bssid == true) {  		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);  		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, @@ -1153,7 +1161,7 @@ void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); -	rtl8723ae_dm_init_edca_turbo(hw); +	rtl8723_dm_init_edca_turbo(hw);  	switch (aci) {  	case AC1_BK:  		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); @@ -1614,10 +1622,10 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,  	rtl8723ae_read_bt_coexist_info_from_hwpg(hw,  			rtlefuse->autoload_failflag, hwinfo); -	rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; +	rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];  	rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];  	rtlefuse->txpwr_fromeprom = true; -	rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; +	rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];  	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,  		 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); @@ -1655,7 +1663,7 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,  				    CHK_SVID_SMID(0x10EC, 0x9185))  					rtlhal->oem_id = RT_CID_TOSHIBA;  				else if (rtlefuse->eeprom_svid == 0x1025) -					rtlhal->oem_id = RT_CID_819x_Acer; +					rtlhal->oem_id = RT_CID_819X_ACER;  				else if (CHK_SVID_SMID(0x10EC, 0x6191) ||  					 CHK_SVID_SMID(0x10EC, 0x6192) ||  					 CHK_SVID_SMID(0x10EC, 0x6193) || @@ -1665,7 +1673,7 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,  					 CHK_SVID_SMID(0x10EC, 0x8191) ||  					 CHK_SVID_SMID(0x10EC, 0x8192) ||  					 CHK_SVID_SMID(0x10EC, 0x8193)) -					rtlhal->oem_id = RT_CID_819x_SAMSUNG; +					rtlhal->oem_id = RT_CID_819X_SAMSUNG;  				else if (CHK_SVID_SMID(0x10EC, 0x8195) ||  					 CHK_SVID_SMID(0x10EC, 0x9195) ||  					 CHK_SVID_SMID(0x10EC, 0x7194) || @@ -1673,24 +1681,24 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,  					 CHK_SVID_SMID(0x10EC, 0x8201) ||  					 CHK_SVID_SMID(0x10EC, 0x8202) ||  					 CHK_SVID_SMID(0x10EC, 0x9200)) -					rtlhal->oem_id = RT_CID_819x_Lenovo; +					rtlhal->oem_id = RT_CID_819X_LENOVO;  				else if (CHK_SVID_SMID(0x10EC, 0x8197) ||  					 CHK_SVID_SMID(0x10EC, 0x9196)) -					rtlhal->oem_id = RT_CID_819x_CLEVO; +					rtlhal->oem_id = RT_CID_819X_CLEVO;  				else if (CHK_SVID_SMID(0x1028, 0x8194) ||  					 CHK_SVID_SMID(0x1028, 0x8198) ||  					 CHK_SVID_SMID(0x1028, 0x9197) ||  					 CHK_SVID_SMID(0x1028, 0x9198)) -					rtlhal->oem_id = RT_CID_819x_DELL; +					rtlhal->oem_id = RT_CID_819X_DELL;  				else if (CHK_SVID_SMID(0x103C, 0x1629)) -					rtlhal->oem_id = RT_CID_819x_HP; +					rtlhal->oem_id = RT_CID_819X_HP;  				else if (CHK_SVID_SMID(0x1A32, 0x2315)) -					rtlhal->oem_id = RT_CID_819x_QMI; +					rtlhal->oem_id = RT_CID_819X_QMI;  				else if (CHK_SVID_SMID(0x10EC, 0x8203)) -					rtlhal->oem_id = RT_CID_819x_PRONETS; +					rtlhal->oem_id = RT_CID_819X_PRONETS;  				else if (CHK_SVID_SMID(0x1043, 0x84B5))  					rtlhal->oem_id = -						 RT_CID_819x_Edimax_ASUS; +						 RT_CID_819X_EDIMAX_ASUS;  				else  					rtlhal->oem_id = RT_CID_DEFAULT;  			} else if (rtlefuse->eeprom_did == 0x8178) { @@ -1712,12 +1720,12 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,  				    CHK_SVID_SMID(0x10EC, 0x9185))  					rtlhal->oem_id = RT_CID_TOSHIBA;  				else if (rtlefuse->eeprom_svid == 0x1025) -					rtlhal->oem_id = RT_CID_819x_Acer; +					rtlhal->oem_id = RT_CID_819X_ACER;  				else if (CHK_SVID_SMID(0x10EC, 0x8186)) -					rtlhal->oem_id = RT_CID_819x_PRONETS; +					rtlhal->oem_id = RT_CID_819X_PRONETS;  				else if (CHK_SVID_SMID(0x1043, 0x8486))  					rtlhal->oem_id = -						     RT_CID_819x_Edimax_ASUS; +						     RT_CID_819X_EDIMAX_ASUS;  				else  					rtlhal->oem_id = RT_CID_DEFAULT;  			} else { @@ -1731,7 +1739,7 @@ static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw,  			rtlhal->oem_id = RT_CID_CCX;  			break;  		case EEPROM_CID_QMI: -			rtlhal->oem_id = RT_CID_819x_QMI; +			rtlhal->oem_id = RT_CID_819X_QMI;  			break;  		case EEPROM_CID_WHQL:  				break; @@ -2037,8 +2045,7 @@ void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw)  	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));  	u16 sifs_timer; -	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, -				      (u8 *)&mac->slot_time); +	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);  	if (!mac->ht_enable)  		sifs_timer = 0x0a0a;  	else @@ -2376,24 +2383,3 @@ void rtl8723ae_suspend(struct ieee80211_hw *hw)  void rtl8723ae_resume(struct ieee80211_hw *hw)  {  } - -/* Turn on AAP (RCR:bit 0) for promicuous mode. */ -void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw, -	bool allow_all_da, bool write_into_reg) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - -	if (allow_all_da) /* Set BIT0 */ -		rtlpci->receive_config |= RCR_AAP; -	else /* Clear BIT0 */ -		rtlpci->receive_config &= ~RCR_AAP; - -	if (write_into_reg) -		rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - - -	RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, -		 "receive_config=0x%08X, write_into_reg=%d\n", -		 rtlpci->receive_config, write_into_reg); -} diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h index 6fa24f79b1d..d3bc39fb27a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h @@ -67,7 +67,5 @@ void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw);  void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw);  void rtl8723ae_suspend(struct ieee80211_hw *hw);  void rtl8723ae_resume(struct ieee80211_hw *hw); -void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw, -				  bool allow_all_da, bool write_into_reg);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c index eafbb18dd48..3ea78afdec7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c @@ -30,12 +30,14 @@  #include "../wifi.h"  #include "../pci.h"  #include "../ps.h" +#include "../core.h"  #include "reg.h"  #include "def.h"  #include "phy.h"  #include "rf.h"  #include "dm.h"  #include "table.h" +#include "../rtl8723com/phy_common.h"  /* static forward definitions */  static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, @@ -43,72 +45,17 @@ static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,  static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,  				    enum radio_path rfpath,  				    u32 offset, u32 data); -static u32 _phy_rf_serial_read(struct ieee80211_hw *hw, -			       enum radio_path rfpath, u32 offset); -static void _phy_rf_serial_write(struct ieee80211_hw *hw, -				 enum radio_path rfpath, u32 offset, u32 data); -static u32 _phy_calculate_bit_shift(u32 bitmask);  static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw);  static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw);  static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype);  static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype); -static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw); -static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, -				      u32 cmdtableidx, u32 cmdtablesz, -				      enum swchnlcmd_id cmdid, -				      u32 para1, u32 para2, -				      u32 msdelay);  static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,  				      u8 *stage, u8 *step, u32 *delay);  static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,  				enum wireless_mode wirelessmode,  				long power_indbm); -static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, -				  enum wireless_mode wirelessmode, u8 txpwridx);  static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw); -u32 rtl8723ae_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 = _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; -} - -void rtl8723ae_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 = _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); -} -  u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,  			       enum radio_path rfpath, u32 regaddr, u32 bitmask)  { @@ -124,11 +71,11 @@ u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,  	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);  	if (rtlphy->rf_mode != RF_OP_BY_FW) -		original_value = _phy_rf_serial_read(hw, rfpath, regaddr); +		original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);  	else  		original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr); -	bitshift = _phy_calculate_bit_shift(bitmask); +	bitshift = rtl8723_phy_calculate_bit_shift(bitmask);  	readback_value = (original_value & bitmask) >> bitshift;  	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); @@ -157,19 +104,19 @@ void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,  	if (rtlphy->rf_mode != RF_OP_BY_FW) {  		if (bitmask != RFREG_OFFSET_MASK) { -			original_value = _phy_rf_serial_read(hw, rfpath, -							     regaddr); -			bitshift = _phy_calculate_bit_shift(bitmask); +			original_value = rtl8723_phy_rf_serial_read(hw, rfpath, +								    regaddr); +			bitshift = rtl8723_phy_calculate_bit_shift(bitmask);  			data = ((original_value & (~bitmask)) |  			       (data << bitshift));  		} -		_phy_rf_serial_write(hw, rfpath, regaddr, data); +		rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data);  	} else {  		if (bitmask != RFREG_OFFSET_MASK) {  			original_value = _phy_fw_rf_serial_read(hw, rfpath,  								regaddr); -			bitshift = _phy_calculate_bit_shift(bitmask); +			bitshift = rtl8723_phy_calculate_bit_shift(bitmask);  			data = ((original_value & (~bitmask)) |  			       (data << bitshift));  		} @@ -197,87 +144,6 @@ static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,  	RT_ASSERT(false, "deprecated!\n");  } -static u32 _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 &= 0x3f; -	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(1); -	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, -		      tmplong | BLSSIREADEDGE); -	mdelay(1); -	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; -} - -static void _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 &= 0x3f; -	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); -} - -static u32 _phy_calculate_bit_shift(u32 bitmask) -{ -	u32 i; - -	for (i = 0; i <= 31; i++) { -		if (((bitmask >> i) & 0x1) == 1) -			break; -	} -	return i; -} -  static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw)  {  	rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); @@ -307,7 +173,7 @@ bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw)  	u8 tmpu1b;  	u8 reg_hwparafile = 1; -	_phy_init_bb_rf_reg_def(hw); +	rtl8723_phy_init_bb_rf_reg_def(hw);  	/* 1. 0x28[1] = 1 */  	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL); @@ -412,18 +278,7 @@ static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype)  	phy_regarray_table = RTL8723EPHY_REG_1TARRAY;  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_reg_arraylen; i = i + 2) { -			if (phy_regarray_table[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray_table[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray_table[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray_table[i] == 0xfb) -				udelay(50); -			else if (phy_regarray_table[i] == 0xfa) -				udelay(5); -			else if (phy_regarray_table[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_regarray_table[i]);  			rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,  				      phy_regarray_table[i + 1]);  			udelay(1); @@ -585,18 +440,7 @@ static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype)  	if (configtype == BASEBAND_CONFIG_PHY_REG) {  		for (i = 0; i < phy_regarray_pg_len; i = i + 3) { -			if (phy_regarray_table_pg[i] == 0xfe) -				mdelay(50); -			else if (phy_regarray_table_pg[i] == 0xfd) -				mdelay(5); -			else if (phy_regarray_table_pg[i] == 0xfc) -				mdelay(1); -			else if (phy_regarray_table_pg[i] == 0xfb) -				udelay(50); -			else if (phy_regarray_table_pg[i] == 0xfa) -				udelay(5); -			else if (phy_regarray_table_pg[i] == 0xf9) -				udelay(1); +			rtl_addr_delay(phy_regarray_table_pg[i]);  			_st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i],  					      phy_regarray_table_pg[i + 1], @@ -623,24 +467,9 @@ bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  	switch (rfpath) {  	case RF90_PATH_A:  		for (i = 0; i < radioa_arraylen; i = i + 2) { -			if (radioa_array_table[i] == 0xfe) -				mdelay(50); -			else if (radioa_array_table[i] == 0xfd) -				mdelay(5); -			else if (radioa_array_table[i] == 0xfc) -				mdelay(1); -			else if (radioa_array_table[i] == 0xfb) -				udelay(50); -			else if (radioa_array_table[i] == 0xfa) -				udelay(5); -			else if (radioa_array_table[i] == 0xf9) -				udelay(1); -			else { -				rtl_set_rfreg(hw, rfpath, radioa_array_table[i], -					      RFREG_OFFSET_MASK, -					      radioa_array_table[i + 1]); -				udelay(1); -			} +			rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], +					RFREG_OFFSET_MASK, +					radioa_array_table[i + 1]);  		}  		break;  	case RF90_PATH_B: @@ -690,92 +519,6 @@ void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)  		 ROFDM0_RXDETECTOR3, rtlphy->framesync);  } -static void _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; -} -  void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -785,17 +528,17 @@ void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)  	long txpwr_dbm;  	txpwr_level = rtlphy->cur_cck_txpwridx; -	txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level); +	txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level);  	txpwr_level = rtlphy->cur_ofdm24g_txpwridx +  	    rtlefuse->legacy_ht_txpowerdiff; -	if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm) -		txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, +	if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm) +		txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,  						  txpwr_level);  	txpwr_level = rtlphy->cur_ofdm24g_txpwridx; -	if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) > +	if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) >  	    txpwr_dbm) -		txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, -						  txpwr_level); +		txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, +							 txpwr_level);  	*powerlevel = txpwr_dbm;  } @@ -912,57 +655,6 @@ static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,  	return txpwridx;  } -static long _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: -		offset = -8; -		break; -	default: -		offset = -8; -		break; -	} -	pwrout_dbm = txpwridx / 2 + offset; -	return pwrout_dbm; -} - -void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ -	struct rtl_priv *rtlpriv = rtl_priv(hw); -	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); -	enum io_type iotype; - -	if (!is_hal_stop(rtlhal)) { -		switch (operation) { -		case SCAN_OPT_BACKUP: -			iotype = IO_CMD_PAUSE_DM_BY_SCAN; -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_IO_CMD, -						      (u8 *)&iotype); - -			break; -		case SCAN_OPT_RESTORE: -			iotype = IO_CMD_RESUME_DM_BY_SCAN; -			rtlpriv->cfg->ops->set_hw_reg(hw, -						      HW_VAR_IO_CMD, -						      (u8 *)&iotype); -			break; -		default: -			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, -				 "Unknown Scan Backup operation.\n"); -			break; -		} -	} -} -  void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)  {  	struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1146,26 +838,26 @@ static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,  	u8 num_total_rfpath = rtlphy->num_total_rfpath;  	precommoncmdcnt = 0; -	_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, -				  MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, -				  0, 0, 0); -	_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, -				  MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); +	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, +					 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, +					 0, 0, 0); +	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, +					 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);  	postcommoncmdcnt = 0; -	_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, -				  MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); +	rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, +					 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);  	rfdependcmdcnt = 0;  	RT_ASSERT((channel >= 1 && channel <= 14),  		  "illegal channel for Zebra: %d\n", channel); -	_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, -				  MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, +	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, +					 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,  				  RF_CHNLBW, channel, 10); -	_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, -				  MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); +	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, +					 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);  	do {  		switch (*stage) { @@ -1233,29 +925,6 @@ static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,  	return false;  } -static bool _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; -} -  static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)  {  	u32 reg_eac, reg_e94, reg_e9c, reg_ea4; @@ -1326,136 +995,6 @@ static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw)  	return result;  } -static void 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); -	} -} - -static void phy_save_adda_regs(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); -} - -static void phy_save_mac_regs(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]); -} - -static void phy_reload_adda_regs(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]); -} - -static void phy_reload_mac_regs(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]); -} - -static void _rtl8723ae_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 (false == 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); -} - -static void _rtl8723ae_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)))); -} - -static void _rtl8723ae_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); -} - -static void _rtl8723ae_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); -} -  static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8],  				u8 c1, u8 c2)  { @@ -1527,10 +1066,12 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,  	const u32 retrycount = 2;  	if (t == 0) { -		phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); -		phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); +		rtl8723_save_adda_registers(hw, adda_reg, rtlphy->adda_backup, +					    16); +		rtl8723_phy_save_mac_registers(hw, iqk_mac_reg, +					       rtlphy->iqk_mac_backup);  	} -	_rtl8723ae_phy_path_adda_on(hw, adda_reg, true, is2t); +	rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);  	if (t == 0) {  		rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,  						 RFPGA0_XA_HSSIPARAMETER1, @@ -1538,7 +1079,7 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,  	}  	if (!rtlphy->rfpi_enable) -		_rtl8723ae_phy_pi_mode_switch(hw, true); +		rtl8723_phy_pi_mode_switch(hw, true);  	if (t == 0) {  		rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);  		rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); @@ -1551,7 +1092,7 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,  		rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);  		rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);  	} -	_rtl8723ae_phy_mac_setting_calibration(hw, iqk_mac_reg, +	rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,  					    rtlphy->iqk_mac_backup);  	rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);  	if (is2t) @@ -1581,8 +1122,8 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,  	}  	if (is2t) { -		_rtl8723ae_phy_path_a_standby(hw); -		_rtl8723ae_phy_path_adda_on(hw, adda_reg, false, is2t); +		rtl8723_phy_path_a_standby(hw); +		rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);  		for (i = 0; i < retrycount; i++) {  			pathb_ok = _rtl8723ae_phy_path_b_iqk(hw);  			if (pathb_ok == 0x03) { @@ -1617,9 +1158,11 @@ static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,  		rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);  	if (t != 0) {  		if (!rtlphy->rfpi_enable) -			_rtl8723ae_phy_pi_mode_switch(hw, false); -		phy_reload_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); -		phy_reload_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); +			rtl8723_phy_pi_mode_switch(hw, false); +		rtl8723_phy_reload_adda_registers(hw, adda_reg, +						  rtlphy->adda_backup, 16); +		rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg, +						 rtlphy->iqk_mac_backup);  	}  } @@ -1720,7 +1263,8 @@ void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)  	};  	if (recovery) { -		phy_reload_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); +		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg, +						  rtlphy->iqk_bb_backup, 10);  		return;  	}  	if (start_conttx || singletone) @@ -1785,9 +1329,10 @@ void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)  		rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;  	}  	if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ -		phy_path_a_fill_iqk_matrix(hw, patha_ok, result, -					   final_candidate, (reg_ea4 == 0)); -	phy_save_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); +		rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result, +						   final_candidate, +						   (reg_ea4 == 0)); +	rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);  }  void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h index e7a59eba351..cd43139ed33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h @@ -76,23 +76,6 @@  #define RTL92C_MAX_PATH_NUM			2 -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; -}; -  enum hw90_block_e {  	HW90_BLOCK_MAC = 0,  	HW90_BLOCK_PHY0 = 1, @@ -183,42 +166,36 @@ struct tx_power_struct {  	u32 mcs_original_offset[4][16];  }; -extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, -				      u32 regaddr, u32 bitmask); -extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, -				     u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, -				      enum radio_path rfpath, u32 regaddr, -				      u32 bitmask); -extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, -				     enum radio_path rfpath, u32 regaddr, -				     u32 bitmask, u32 data); -extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, -						 enum radio_path rfpath); -extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, -					    long *powerlevel); -extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, -					    u8 channel); -extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, -					     long power_indbm); -extern void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, -						u8 operation); -extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, -				      enum nl80211_channel_type ch_type); -extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); +u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, +			       enum radio_path rfpath, u32 regaddr, +			       u32 bitmask); +void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, +			      enum radio_path rfpath, u32 regaddr, +			      u32 bitmask, u32 data); +bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); +bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); +bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); +bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, +					  enum radio_path rfpath); +void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, +				     long *powerlevel); +void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, +				     u8 channel); +bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, +				      long power_indbm); +void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, +			       enum nl80211_channel_type ch_type); +void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);  void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw);  void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);  bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,  					     enum radio_path rfpath);  bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, -					     enum rf_pwrstate rfpwr_state); +bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, +				      enum rf_pwrstate rfpwr_state);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h index 7a46f9fdf55..a418acb4d0c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h @@ -30,7 +30,6 @@  #ifndef __RTL8723E_PWRSEQ_H__  #define __RTL8723E_PWRSEQ_H__ -#include "pwrseqcmd.h"  /*  	Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd  	There are 6 HW Power States: diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h index 199da366c6d..64376b38708 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h @@ -2059,22 +2059,6 @@  #define	BWORD1					0xc  #define	BWORD					0xf -#define	MASKBYTE0				0xff -#define	MASKBYTE1				0xff00 -#define	MASKBYTE2				0xff0000 -#define	MASKBYTE3				0xff000000 -#define	MASKHWORD				0xffff0000 -#define	MASKLWORD				0x0000ffff -#define	MASKDWORD				0xffffffff -#define	MASK12BITS				0xfff -#define	MASKH4BITS				0xf0000000 -#define MASKOFDM_D				0xffc00000 -#define	MASKCCK					0x3f3f3f3f - -#define	MASK4BITS				0x0f -#define	MASK20BITS				0xfffff -#define RFREG_OFFSET_MASK			0xfffff -  #define	BENABLE					0x1  #define	BDISABLE				0x0 diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h index d0f9dd79abe..57f1933ee66 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h @@ -32,12 +32,11 @@  #define RF6052_MAX_TX_PWR		0x3F -extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, -					    u8 bandwidth); -extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, -					      u8 *ppowerlevel); -extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, -					       u8 *ppowerlevel, u8 channel); -extern bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw); +void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); +void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +					  u8 *ppowerlevel); +void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +					   u8 *ppowerlevel, u8 channel); +bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw);  #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c index d9ee2efffe5..73cba1eec8c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c @@ -33,11 +33,15 @@  #include "../core.h"  #include "../pci.h" +#include "../base.h"  #include "reg.h"  #include "def.h"  #include "phy.h" +#include "../rtl8723com/phy_common.h"  #include "dm.h"  #include "hw.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h"  #include "sw.h"  #include "trx.h"  #include "led.h" @@ -192,6 +196,11 @@ void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw)  	}  } +static bool is_fw_header(struct rtl92c_firmware_header *hdr) +{ +	return (hdr->signature & 0xfff0) == 0x2300; +} +  static struct rtl_hal_ops rtl8723ae_hal_ops = {  	.init_sw_vars = rtl8723ae_init_sw_vars,  	.deinit_sw_vars = rtl8723ae_deinit_sw_vars, @@ -220,7 +229,7 @@ static struct rtl_hal_ops rtl8723ae_hal_ops = {  	.set_bw_mode = rtl8723ae_phy_set_bw_mode,  	.switch_channel = rtl8723ae_phy_sw_chnl,  	.dm_watchdog = rtl8723ae_dm_watchdog, -	.scan_operation_backup = rtl8723ae_phy_scan_operation_backup, +	.scan_operation_backup = rtl_phy_scan_operation_backup,  	.set_rf_power_state = rtl8723ae_phy_set_rf_power_state,  	.led_control = rtl8723ae_led_control,  	.set_desc = rtl8723ae_set_desc, @@ -229,14 +238,14 @@ static struct rtl_hal_ops rtl8723ae_hal_ops = {  	.enable_hw_sec = rtl8723ae_enable_hw_security_config,  	.set_key = rtl8723ae_set_key,  	.init_sw_leds = rtl8723ae_init_sw_leds, -	.allow_all_destaddr = rtl8723ae_allow_all_destaddr, -	.get_bbreg = rtl8723ae_phy_query_bb_reg, -	.set_bbreg = rtl8723ae_phy_set_bb_reg, +	.get_bbreg = rtl8723_phy_query_bb_reg, +	.set_bbreg = rtl8723_phy_set_bb_reg,  	.get_rfreg = rtl8723ae_phy_query_rf_reg,  	.set_rfreg = rtl8723ae_phy_set_rf_reg,  	.c2h_command_handle = rtl_8723e_c2h_command_handle,  	.bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify,  	.bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps, +	.is_fw_header = is_fw_header,  };  static struct rtl_mod_params rtl8723ae_mod_params = { diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c index bcd82a1020a..10b7577b6ae 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c @@ -334,7 +334,7 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,  			/* during testing, hdr could be NULL here */  			return false;  		} -		if ((ieee80211_is_robust_mgmt_frame(hdr)) && +		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&  			(ieee80211_has_protected(hdr->frame_control)))  			rx_status->flag &= ~RX_FLAG_DECRYPTED;  		else @@ -359,14 +359,13 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,  	/*rx_status->qual = status->signal; */  	rx_status->signal = status->recvsignalpower + 10; -	/*rx_status->noise = -status->noise; */  	return true;  }  void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,  			    struct ieee80211_hdr *hdr, u8 *pdesc_tx, -			    struct ieee80211_tx_info *info, +			    u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			    struct ieee80211_sta *sta,  			    struct sk_buff *skb, u8 hw_queue,  			    struct rtl_tcb_desc *ptcdesc) @@ -376,7 +375,7 @@ void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,  	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));  	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));  	bool defaultadapter = true; -	u8 *pdesc = (u8 *) pdesc_tx; +	u8 *pdesc = pdesc_tx;  	u16 seq_number;  	__le16 fc = hdr->frame_control;  	u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue); @@ -578,7 +577,7 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,  	SET_TX_DESC_OWN(pdesc, 1); -	SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); +	SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));  	SET_TX_DESC_FIRST_SEG(pdesc, 1);  	SET_TX_DESC_LAST_SEG(pdesc, 1); @@ -598,7 +597,8 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,  		      pdesc, TX_DESC_SIZE);  } -void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) +void rtl8723ae_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +			u8 desc_name, u8 *val)  {  	if (istx == true) {  		switch (desc_name) { diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h index ad05b54bc0f..4380b7d3a91 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h @@ -521,12 +521,6 @@ do {							\  		memset(__pdesc, 0, _size);		\  } while (0) -#define RTL8723E_RX_HAL_IS_CCK_RATE(rxmcs)		\ -	((rxmcs) == DESC92_RATE1M ||			\ -	 (rxmcs) == DESC92_RATE2M ||			\ -	 (rxmcs) == DESC92_RATE5_5M ||			\ -	 (rxmcs) == DESC92_RATE11M) -  struct rx_fwinfo_8723e {  	u8 gain_trsw[4];  	u8 pwdb_all; @@ -706,8 +700,8 @@ struct rx_desc_8723e {  } __packed;  void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, -			    struct ieee80211_hdr *hdr, u8 *pdesc_tx, -			    struct ieee80211_tx_info *info, +			    struct ieee80211_hdr *hdr, u8 *pdesc, +			    u8 *pbd_desc_tx, struct ieee80211_tx_info *info,  			    struct ieee80211_sta *sta,  			    struct sk_buff *skb, u8 hw_queue,  			    struct rtl_tcb_desc *ptcb_desc); @@ -715,7 +709,8 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw,  			     struct rtl_stats *status,  			     struct ieee80211_rx_status *rx_status,  			     u8 *pdesc, struct sk_buff *skb); -void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); +void rtl8723ae_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +			u8 desc_name, u8 *val);  u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name);  void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);  void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/Makefile b/drivers/net/wireless/rtlwifi/rtl8723be/Makefile new file mode 100644 index 00000000000..59e416abd93 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/Makefile @@ -0,0 +1,19 @@ +obj-m := rtl8723be.o + + +rtl8723be-objs :=		\ +		dm.o		\ +		fw.o		\ +		hw.o		\ +		led.o		\ +		phy.o		\ +		pwrseq.o	\ +		rf.o		\ +		sw.o		\ +		table.o		\ +		trx.o		\ + + +obj-$(CONFIG_RTL8723BE) += rtl8723be.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/def.h b/drivers/net/wireless/rtlwifi/rtl8723be/def.h new file mode 100644 index 00000000000..3c30b74e983 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/def.h @@ -0,0 +1,248 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_DEF_H__ +#define __RTL8723BE_DEF_H__ + +#define HAL_RETRY_LIMIT_INFRA				48 +#define HAL_RETRY_LIMIT_AP_ADHOC			7 + +#define RESET_DELAY_8185				20 + +#define RT_IBSS_INT_MASKS	(IMR_BCNINT | IMR_TBDOK | IMR_TBDER) +#define RT_AC_INT_MASKS		(IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) + +#define NUM_OF_FIRMWARE_QUEUE			10 +#define NUM_OF_PAGES_IN_FW			0x100 +#define NUM_OF_PAGE_IN_FW_QUEUE_BK		0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE		0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI		0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO		0x07 +#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA		0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_CMD		0x0 +#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT		0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH		0x02 +#define NUM_OF_PAGE_IN_FW_QUEUE_BCN		0x2 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB		0xA1 + +#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM		0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM		0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM		0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM		0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM		0x00 + +#define MAX_LINES_HWCONFIG_TXT			1000 +#define MAX_BYTES_LINE_HWCONFIG_TXT		256 + +#define SW_THREE_WIRE				0 +#define HW_THREE_WIRE				2 + +#define BT_DEMO_BOARD				0 +#define BT_QA_BOARD				1 +#define BT_FPGA					2 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE		0 +#define HAL_PRIME_CHNL_OFFSET_LOWER		1 +#define HAL_PRIME_CHNL_OFFSET_UPPER		2 + +#define MAX_H2C_QUEUE_NUM			10 + +#define RX_MPDU_QUEUE				0 +#define RX_CMD_QUEUE				1 +#define RX_MAX_QUEUE				2 +#define AC2QUEUEID(_AC)				(_AC) + +#define	C2H_RX_CMD_HDR_LEN			8 +#define	GET_C2H_CMD_CMD_LEN(__prxhdr)		\ +	LE_BITS_TO_4BYTE((__prxhdr), 0, 16) +#define	GET_C2H_CMD_ELEMENT_ID(__prxhdr)	\ +	LE_BITS_TO_4BYTE((__prxhdr), 16, 8) +#define	GET_C2H_CMD_CMD_SEQ(__prxhdr)		\ +	LE_BITS_TO_4BYTE((__prxhdr), 24, 7) +#define	GET_C2H_CMD_CONTINUE(__prxhdr)		\ +	LE_BITS_TO_4BYTE((__prxhdr), 31, 1) +#define	GET_C2H_CMD_CONTENT(__prxhdr)		\ +	((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN) + +#define	GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8) +#define	GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8) +#define	GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16) +#define	GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5) +#define	GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1) +#define	GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5) +#define	GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1) +#define	GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4) +#define	GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr)	\ +	LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) + +#define CHIP_BONDING_IDENTIFIER(_value)	(((_value)>>22)&0x3) +#define	CHIP_BONDING_92C_1T2R		0x1 + +#define CHIP_8723			BIT(0) +#define CHIP_8723B			(BIT(1) | BIT(2)) +#define NORMAL_CHIP			BIT(3) +#define RF_TYPE_1T1R			(~(BIT(4) | BIT(5) | BIT(6))) +#define RF_TYPE_1T2R			BIT(4) +#define RF_TYPE_2T2R			BIT(5) +#define CHIP_VENDOR_UMC			BIT(7) +#define B_CUT_VERSION			BIT(12) +#define C_CUT_VERSION			BIT(13) +#define D_CUT_VERSION			((BIT(12) | BIT(13))) +#define E_CUT_VERSION			BIT(14) +#define	RF_RL_ID			(BIT(31) | BIT(30) | BIT(29) | BIT(28)) + +/* MASK */ +#define IC_TYPE_MASK			(BIT(0) | BIT(1) | BIT(2)) +#define CHIP_TYPE_MASK			BIT(3) +#define RF_TYPE_MASK			(BIT(4) | BIT(5) | BIT(6)) +#define MANUFACTUER_MASK		BIT(7) +#define ROM_VERSION_MASK		(BIT(11) | BIT(10) | BIT(9) | BIT(8)) +#define CUT_VERSION_MASK		(BIT(15) | BIT(14) | BIT(13) | BIT(12)) + +/* Get element */ +#define GET_CVID_IC_TYPE(version)	((version) & IC_TYPE_MASK) +#define GET_CVID_CHIP_TYPE(version)	((version) & CHIP_TYPE_MASK) +#define GET_CVID_RF_TYPE(version)	((version) & RF_TYPE_MASK) +#define GET_CVID_MANUFACTUER(version)	((version) & MANUFACTUER_MASK) +#define GET_CVID_ROM_VERSION(version)	((version) & ROM_VERSION_MASK) +#define GET_CVID_CUT_VERSION(version)	((version) & CUT_VERSION_MASK) + +#define IS_92C_SERIAL(version)   ((IS_81XXC(version) && IS_2T2R(version)) ?\ +								true : false) +#define IS_81XXC(version)	((GET_CVID_IC_TYPE(version) == 0) ?\ +							true : false) +#define IS_8723_SERIES(version)	((GET_CVID_IC_TYPE(version) == CHIP_8723) ?\ +							true : false) +#define IS_1T1R(version)	((GET_CVID_RF_TYPE(version)) ? false : true) +#define IS_1T2R(version)	((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)\ +							? true : false) +#define IS_2T2R(version)	((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)\ +							? true : false) +enum rf_optype { +	RF_OP_BY_SW_3WIRE = 0, +	RF_OP_BY_FW, +	RF_OP_MAX +}; + +enum rf_power_state { +	RF_ON, +	RF_OFF, +	RF_SLEEP, +	RF_SHUT_DOWN, +}; + +enum power_save_mode { +	POWER_SAVE_MODE_ACTIVE, +	POWER_SAVE_MODE_SAVE, +}; + +enum power_polocy_config { +	POWERCFG_MAX_POWER_SAVINGS, +	POWERCFG_GLOBAL_POWER_SAVINGS, +	POWERCFG_LOCAL_POWER_SAVINGS, +	POWERCFG_LENOVO, +}; + +enum interface_select_pci { +	INTF_SEL1_MINICARD = 0, +	INTF_SEL0_PCIE = 1, +	INTF_SEL2_RSV = 2, +	INTF_SEL3_RSV = 3, +}; + +enum rtl_desc_qsel { +	QSLT_BK = 0x2, +	QSLT_BE = 0x0, +	QSLT_VI = 0x5, +	QSLT_VO = 0x7, +	QSLT_BEACON = 0x10, +	QSLT_HIGH = 0x11, +	QSLT_MGNT = 0x12, +	QSLT_CMD = 0x13, +}; + +enum rtl_desc8723e_rate { +	DESC92C_RATE1M = 0x00, +	DESC92C_RATE2M = 0x01, +	DESC92C_RATE5_5M = 0x02, +	DESC92C_RATE11M = 0x03, + +	DESC92C_RATE6M = 0x04, +	DESC92C_RATE9M = 0x05, +	DESC92C_RATE12M = 0x06, +	DESC92C_RATE18M = 0x07, +	DESC92C_RATE24M = 0x08, +	DESC92C_RATE36M = 0x09, +	DESC92C_RATE48M = 0x0a, +	DESC92C_RATE54M = 0x0b, + +	DESC92C_RATEMCS0 = 0x0c, +	DESC92C_RATEMCS1 = 0x0d, +	DESC92C_RATEMCS2 = 0x0e, +	DESC92C_RATEMCS3 = 0x0f, +	DESC92C_RATEMCS4 = 0x10, +	DESC92C_RATEMCS5 = 0x11, +	DESC92C_RATEMCS6 = 0x12, +	DESC92C_RATEMCS7 = 0x13, +	DESC92C_RATEMCS8 = 0x14, +	DESC92C_RATEMCS9 = 0x15, +	DESC92C_RATEMCS10 = 0x16, +	DESC92C_RATEMCS11 = 0x17, +	DESC92C_RATEMCS12 = 0x18, +	DESC92C_RATEMCS13 = 0x19, +	DESC92C_RATEMCS14 = 0x1a, +	DESC92C_RATEMCS15 = 0x1b, +	DESC92C_RATEMCS15_SG = 0x1c, +	DESC92C_RATEMCS32 = 0x20, +}; + +enum rx_packet_type { +	NORMAL_RX, +	TX_REPORT1, +	TX_REPORT2, +	HIS_REPORT, +}; + +struct phy_sts_cck_8723e_t { +	u8 adc_pwdb_X[4]; +	u8 sq_rpt; +	u8 cck_agc_rpt; +}; + +struct h2c_cmd_8723e { +	u8 element_id; +	u32 cmd_len; +	u8 *p_cmdbuffer; +}; + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c new file mode 100644 index 00000000000..13d53a1df78 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c @@ -0,0 +1,1325 @@ +/****************************************************************************** + * + * 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 "../base.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "../rtl8723com/dm_common.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" +#include "trx.h" +#include "../btcoexist/rtl_btc.h" + +static const u32 ofdmswing_table[] = { +	0x0b40002d, /* 0,  -15.0dB */ +	0x0c000030, /* 1,  -14.5dB */ +	0x0cc00033, /* 2,  -14.0dB */ +	0x0d800036, /* 3,  -13.5dB */ +	0x0e400039, /* 4,  -13.0dB */ +	0x0f00003c, /* 5,  -12.5dB */ +	0x10000040, /* 6,  -12.0dB */ +	0x11000044, /* 7,  -11.5dB */ +	0x12000048, /* 8,  -11.0dB */ +	0x1300004c, /* 9,  -10.5dB */ +	0x14400051, /* 10, -10.0dB */ +	0x15800056, /* 11, -9.5dB */ +	0x16c0005b, /* 12, -9.0dB */ +	0x18000060, /* 13, -8.5dB */ +	0x19800066, /* 14, -8.0dB */ +	0x1b00006c, /* 15, -7.5dB */ +	0x1c800072, /* 16, -7.0dB */ +	0x1e400079, /* 17, -6.5dB */ +	0x20000080, /* 18, -6.0dB */ +	0x22000088, /* 19, -5.5dB */ +	0x24000090, /* 20, -5.0dB */ +	0x26000098, /* 21, -4.5dB */ +	0x288000a2, /* 22, -4.0dB */ +	0x2ac000ab, /* 23, -3.5dB */ +	0x2d4000b5, /* 24, -3.0dB */ +	0x300000c0, /* 25, -2.5dB */ +	0x32c000cb, /* 26, -2.0dB */ +	0x35c000d7, /* 27, -1.5dB */ +	0x390000e4, /* 28, -1.0dB */ +	0x3c8000f2, /* 29, -0.5dB */ +	0x40000100, /* 30, +0dB */ +	0x43c0010f, /* 31, +0.5dB */ +	0x47c0011f, /* 32, +1.0dB */ +	0x4c000130, /* 33, +1.5dB */ +	0x50800142, /* 34, +2.0dB */ +	0x55400155, /* 35, +2.5dB */ +	0x5a400169, /* 36, +3.0dB */ +	0x5fc0017f, /* 37, +3.5dB */ +	0x65400195, /* 38, +4.0dB */ +	0x6b8001ae, /* 39, +4.5dB */ +	0x71c001c7, /* 40, +5.0dB */ +	0x788001e2, /* 41, +5.5dB */ +	0x7f8001fe  /* 42, +6.0dB */ +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { +	{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /*  0, -16.0dB */ +	{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /*  1, -15.5dB */ +	{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /*  2, -15.0dB */ +	{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /*  3, -14.5dB */ +	{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /*  4, -14.0dB */ +	{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /*  5, -13.5dB */ +	{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /*  6, -13.0dB */ +	{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /*  7, -12.5dB */ +	{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /*  8, -12.0dB */ +	{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /*  9, -11.5dB */ +	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB */ +	{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB */ +	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB */ +	{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB */ +	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */ +	{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB */ +	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ +	{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB */ +	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */ +	{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB */ +	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 20, -6.0dB */ +	{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB */ +	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */ +	{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB */ +	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */ +	{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB */ +	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB */ +	{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB */ +	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */ +	{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB */ +	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB */ +	{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB */ +	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}  /* 32, +0dB */ +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { +	{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /*  0, -16.0dB */ +	{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  1, -15.5dB */ +	{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  2, -15.0dB */ +	{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  3, -14.5dB */ +	{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  4, -14.0dB */ +	{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  5, -13.5dB */ +	{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  6, -13.0dB */ +	{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  7, -12.5dB */ +	{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /*  8, -12.0dB */ +	{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /*  9, -11.5dB */ +	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB */ +	{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 11, -10.5dB */ +	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB */ +	{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB */ +	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 14, -9.0dB */ +	{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB */ +	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ +	{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB */ +	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */ +	{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */ +	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */ +	{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB */ +	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */ +	{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 23, -4.5dB */ +	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */ +	{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */ +	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */ +	{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 27, -2.5dB */ +	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */ +	{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 29, -1.5dB */ +	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */ +	{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */ +	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}  /* 32, +0dB */ +}; + +static const u32 edca_setting_dl[PEER_MAX] = { +	0xa44f,		/* 0 UNKNOWN */ +	0x5ea44f,	/* 1 REALTEK_90 */ +	0x5e4322,	/* 2 REALTEK_92SE */ +	0x5ea42b,	/* 3 BROAD */ +	0xa44f,		/* 4 RAL */ +	0xa630,		/* 5 ATH */ +	0x5ea630,	/* 6 CISCO */ +	0x5ea42b,	/* 7 MARVELL */ +}; + +static const u32 edca_setting_ul[PEER_MAX] = { +	0x5e4322,	/* 0 UNKNOWN */ +	0xa44f,		/* 1 REALTEK_90 */ +	0x5ea44f,	/* 2 REALTEK_92SE */ +	0x5ea32b,	/* 3 BROAD */ +	0x5ea422,	/* 4 RAL */ +	0x5ea322,	/* 5 ATH */ +	0x3ea430,	/* 6 CISCO */ +	0x5ea44f,	/* 7 MARV */ +}; + +void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type, +				       u8 *pdirection, u32 *poutwrite_val) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); +	u8 pwr_val = 0; +	u8 ofdm_base = rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A]; +	u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A]; +	u8 cck_base = rtldm->swing_idx_cck_base; +	u8 cck_val = rtldm->swing_idx_cck; + +	if (type == 0) { +		if (ofdm_val <= ofdm_base) { +			*pdirection = 1; +			pwr_val = ofdm_base - ofdm_val; +		} else { +			*pdirection = 2; +			pwr_val = ofdm_val - ofdm_base; +		} +	} else if (type == 1) { +		if (cck_val <= cck_base) { +			*pdirection = 1; +			pwr_val = cck_base - cck_val; +		} else { +			*pdirection = 2; +			pwr_val = cck_val - cck_base; +		} +	} + +	if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1)) +		pwr_val = TXPWRTRACK_MAX_IDX; + +	*poutwrite_val = pwr_val | (pwr_val << 8) | +			(pwr_val << 16) | (pwr_val << 24); +} + +static void rtl8723be_dm_diginit(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + +	dm_digtable->dig_enable_flag = true; +	dm_digtable->cur_igvalue = rtl_get_bbreg(hw, +		ROFDM0_XAAGCCORE1, 0x7f); +	dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; +	dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; +	dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; +	dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; +	dm_digtable->rx_gain_max = DM_DIG_MAX; +	dm_digtable->rx_gain_min = DM_DIG_MIN; +	dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; +	dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; +	dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; +	dm_digtable->pre_cck_cca_thres = 0xff; +	dm_digtable->cur_cck_cca_thres = 0x83; +	dm_digtable->forbidden_igi = DM_DIG_MIN; +	dm_digtable->large_fa_hit = 0; +	dm_digtable->recover_cnt = 0; +	dm_digtable->dig_min_0 = DM_DIG_MIN; +	dm_digtable->dig_min_1 = DM_DIG_MIN; +	dm_digtable->media_connect_0 = false; +	dm_digtable->media_connect_1 = false; +	rtlpriv->dm.dm_initialgain_enable = true; +	dm_digtable->bt30_cur_igi = 0x32; +} + +void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rate_adaptive *ra = &(rtlpriv->ra); + +	ra->ratr_state = DM_RATR_STA_INIT; +	ra->pre_ratr_state = DM_RATR_STA_INIT; + +	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) +		rtlpriv->dm.useramask = true; +	else +		rtlpriv->dm.useramask = false; + +	ra->high_rssi_thresh_for_ra = 50; +	ra->low_rssi_thresh_for_ra40m = 20; +} + +static void rtl8723be_dm_init_txpower_tracking(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtlpriv->dm.txpower_tracking = true; +	rtlpriv->dm.txpower_track_control = true; +	rtlpriv->dm.thermalvalue = 0; + +	rtlpriv->dm.ofdm_index[0] = 30; +	rtlpriv->dm.cck_index = 20; + +	rtlpriv->dm.swing_idx_cck_base = rtlpriv->dm.cck_index; + +	rtlpriv->dm.swing_idx_ofdm_base[0] = rtlpriv->dm.ofdm_index[0]; +	rtlpriv->dm.delta_power_index[RF90_PATH_A] = 0; +	rtlpriv->dm.delta_power_index_last[RF90_PATH_A] = 0; +	rtlpriv->dm.power_index_offset[RF90_PATH_A] = 0; + +	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +		 "  rtlpriv->dm.txpower_tracking = %d\n", +		 rtlpriv->dm.txpower_tracking); +} + +static void rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap; +	rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, 0x800); +	rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL; +} + +void rtl8723be_dm_init(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; +	rtl8723be_dm_diginit(hw); +	rtl8723be_dm_init_rate_adaptive_mask(hw); +	rtl8723_dm_init_edca_turbo(hw); +	rtl8723_dm_init_dynamic_bb_powersaving(hw); +	rtl8723_dm_init_dynamic_txpower(hw); +	rtl8723be_dm_init_txpower_tracking(hw); +	rtl8723be_dm_init_dynamic_atc_switch(hw); +} + +static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct dig_t *rtl_dm_dig = &(rtlpriv->dm_digtable); +	struct rtl_mac *mac = rtl_mac(rtlpriv); + +	/* Determine the minimum RSSI  */ +	if ((mac->link_state < MAC80211_LINKED) && +	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { +		rtl_dm_dig->min_undec_pwdb_for_dm = 0; +		RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, +			 "Not connected to any\n"); +	} +	if (mac->link_state >= MAC80211_LINKED) { +		if (mac->opmode == NL80211_IFTYPE_AP || +		    mac->opmode == NL80211_IFTYPE_ADHOC) { +			rtl_dm_dig->min_undec_pwdb_for_dm = +			    rtlpriv->dm.entry_min_undec_sm_pwdb; +			RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, +				 "AP Client PWDB = 0x%lx\n", +				 rtlpriv->dm.entry_min_undec_sm_pwdb); +		} else { +			rtl_dm_dig->min_undec_pwdb_for_dm = +			    rtlpriv->dm.undec_sm_pwdb; +			RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, +				 "STA Default Port PWDB = 0x%x\n", +				 rtl_dm_dig->min_undec_pwdb_for_dm); +		} +	} else { +		rtl_dm_dig->min_undec_pwdb_for_dm = +				rtlpriv->dm.entry_min_undec_sm_pwdb; +		RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, +			 "AP Ext Port or disconnet PWDB = 0x%x\n", +			 rtl_dm_dig->min_undec_pwdb_for_dm); +	} +	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", +		 rtl_dm_dig->min_undec_pwdb_for_dm); +} + +static void rtl8723be_dm_check_rssi_monitor(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_sta_info *drv_priv; +	u8 h2c_parameter[3] = { 0 }; +	long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff; + +	/* AP & ADHOC & MESH */ +	spin_lock_bh(&rtlpriv->locks.entry_list_lock); +	list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { +		if (drv_priv->rssi_stat.undec_sm_pwdb < +						tmp_entry_min_pwdb) +			tmp_entry_min_pwdb = +				drv_priv->rssi_stat.undec_sm_pwdb; +		if (drv_priv->rssi_stat.undec_sm_pwdb > +						tmp_entry_max_pwdb) +			tmp_entry_max_pwdb = +				drv_priv->rssi_stat.undec_sm_pwdb; +	} +	spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + +	/* If associated entry is found */ +	if (tmp_entry_max_pwdb != 0) { +		rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb; +		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +			 "EntryMaxPWDB = 0x%lx(%ld)\n", +			 tmp_entry_max_pwdb, tmp_entry_max_pwdb); +	} else { +		rtlpriv->dm.entry_max_undec_sm_pwdb = 0; +	} +	/* If associated entry is found */ +	if (tmp_entry_min_pwdb != 0xff) { +		rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb; +		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +			 "EntryMinPWDB = 0x%lx(%ld)\n", +			 tmp_entry_min_pwdb, tmp_entry_min_pwdb); +	} else { +		rtlpriv->dm.entry_min_undec_sm_pwdb = 0; +	} +	/* Indicate Rx signal strength to FW. */ +	if (rtlpriv->dm.useramask) { +		h2c_parameter[2] = (u8) (rtlpriv->dm.undec_sm_pwdb & 0xFF); +		h2c_parameter[1] = 0x20; +		h2c_parameter[0] = 0; +		rtl8723be_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); +	} else { +		rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb); +	} +	rtl8723be_dm_find_minimum_rssi(hw); +	rtlpriv->dm_digtable.rssi_val_min = +		rtlpriv->dm_digtable.min_undec_pwdb_for_dm; +} + +void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	if (rtlpriv->dm_digtable.cur_igvalue != current_igi) { +		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi); +		if (rtlpriv->phy.rf_type != RF_1T1R) +			rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, current_igi); +	} +	rtlpriv->dm_digtable.pre_igvalue = rtlpriv->dm_digtable.cur_igvalue; +	rtlpriv->dm_digtable.cur_igvalue = current_igi; +} + +static void rtl8723be_dm_dig(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct dig_t *dm_digtable = &(rtlpriv->dm_digtable); +	u8 dig_dynamic_min, dig_maxofmin; +	bool firstconnect, firstdisconnect; +	u8 dm_dig_max, dm_dig_min; +	u8 current_igi = dm_digtable->cur_igvalue; +	u8 offset; + +	/* AP, BT */ +	if (mac->act_scanning) +		return; + +	dig_dynamic_min = dm_digtable->dig_min_0; +	firstconnect = (mac->link_state >= MAC80211_LINKED) && +			!dm_digtable->media_connect_0; +	firstdisconnect = (mac->link_state < MAC80211_LINKED) && +			   dm_digtable->media_connect_0; + +	dm_dig_max = 0x5a; +	dm_dig_min = DM_DIG_MIN; +	dig_maxofmin = DM_DIG_MAX_AP; + +	if (mac->link_state >= MAC80211_LINKED) { +		if ((dm_digtable->rssi_val_min + 10) > dm_dig_max) +			dm_digtable->rx_gain_max = dm_dig_max; +		else if ((dm_digtable->rssi_val_min + 10) < dm_dig_min) +			dm_digtable->rx_gain_max = dm_dig_min; +		else +			dm_digtable->rx_gain_max = +				dm_digtable->rssi_val_min + 10; + +		if (rtlpriv->dm.one_entry_only) { +			offset = 12; +			if (dm_digtable->rssi_val_min - offset < dm_dig_min) +				dig_dynamic_min = dm_dig_min; +			else if (dm_digtable->rssi_val_min - offset > +							dig_maxofmin) +				dig_dynamic_min = dig_maxofmin; +			else +				dig_dynamic_min = +					dm_digtable->rssi_val_min - offset; +		} else { +			dig_dynamic_min = dm_dig_min; +		} +	} else { +		dm_digtable->rx_gain_max = dm_dig_max; +		dig_dynamic_min = dm_dig_min; +		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n"); +	} + +	if (rtlpriv->falsealm_cnt.cnt_all > 10000) { +		if (dm_digtable->large_fa_hit != 3) +			dm_digtable->large_fa_hit++; +		if (dm_digtable->forbidden_igi < current_igi) { +			dm_digtable->forbidden_igi = current_igi; +			dm_digtable->large_fa_hit = 1; +		} + +		if (dm_digtable->large_fa_hit >= 3) { +			if ((dm_digtable->forbidden_igi + 1) > +			     dm_digtable->rx_gain_max) +				dm_digtable->rx_gain_min = +						dm_digtable->rx_gain_max; +			else +				dm_digtable->rx_gain_min = +						dm_digtable->forbidden_igi + 1; +			dm_digtable->recover_cnt = 3600; +		} +	} else { +		if (dm_digtable->recover_cnt != 0) { +			dm_digtable->recover_cnt--; +		} else { +			if (dm_digtable->large_fa_hit < 3) { +				if ((dm_digtable->forbidden_igi - 1) < +				     dig_dynamic_min) { +					dm_digtable->forbidden_igi = +							dig_dynamic_min; +					dm_digtable->rx_gain_min = +							dig_dynamic_min; +				} else { +					dm_digtable->forbidden_igi--; +					dm_digtable->rx_gain_min = +						dm_digtable->forbidden_igi + 1; +				} +			} else { +				dm_digtable->large_fa_hit = 0; +			} +		} +	} +	if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max) +		dm_digtable->rx_gain_min = dm_digtable->rx_gain_max; + +	if (mac->link_state >= MAC80211_LINKED) { +		if (firstconnect) { +			if (dm_digtable->rssi_val_min <= dig_maxofmin) +				current_igi = dm_digtable->rssi_val_min; +			else +				current_igi = dig_maxofmin; + +			dm_digtable->large_fa_hit = 0; +		} else { +			if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) +				current_igi += 4; +			else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) +				current_igi += 2; +			else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) +				current_igi -= 2; +		} +	} else { +		if (firstdisconnect) { +			current_igi = dm_digtable->rx_gain_min; +		} else { +			if (rtlpriv->falsealm_cnt.cnt_all > 10000) +				current_igi += 4; +			else if (rtlpriv->falsealm_cnt.cnt_all > 8000) +				current_igi += 2; +			else if (rtlpriv->falsealm_cnt.cnt_all < 500) +				current_igi -= 2; +		} +	} + +	if (current_igi > dm_digtable->rx_gain_max) +		current_igi = dm_digtable->rx_gain_max; +	else if (current_igi < dm_digtable->rx_gain_min) +		current_igi = dm_digtable->rx_gain_min; + +	rtl8723be_dm_write_dig(hw, current_igi); +	dm_digtable->media_connect_0 = +		((mac->link_state >= MAC80211_LINKED) ? true : false); +	dm_digtable->dig_min_0 = dig_dynamic_min; +} + +static void rtl8723be_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ +	u32 ret_value; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + +	rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); +	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); + +	ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD); +	falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff; +	falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16; + +	ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD); +	falsealm_cnt->cnt_ofdm_cca = ret_value & 0xffff; +	falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16; + +	ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD); +	falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff; +	falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16; + +	ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD); +	falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff; + +	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + +				      falsealm_cnt->cnt_rate_illegal + +				      falsealm_cnt->cnt_crc8_fail + +				      falsealm_cnt->cnt_mcs_fail + +				      falsealm_cnt->cnt_fast_fsync_fail + +				      falsealm_cnt->cnt_sb_search_fail; + +	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1); +	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1); + +	ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_RST_11N, MASKBYTE0); +	falsealm_cnt->cnt_cck_fail = ret_value; + +	ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3); +	falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + +	ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD); +	falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) | +				    ((ret_value & 0xff00) >> 8); + +	falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail + +				falsealm_cnt->cnt_sb_search_fail + +				falsealm_cnt->cnt_parity_fail + +				falsealm_cnt->cnt_rate_illegal + +				falsealm_cnt->cnt_crc8_fail + +				falsealm_cnt->cnt_mcs_fail + +				falsealm_cnt->cnt_cck_fail; + +	falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca + +				    falsealm_cnt->cnt_cck_cca; + +	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1); +	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0); +	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1); +	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0); + +	rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); +	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); + +	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0); +	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2); + +	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0); +	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2); + +	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, +		 "cnt_parity_fail = %d, cnt_rate_illegal = %d, " +		 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", +		 falsealm_cnt->cnt_parity_fail, +		 falsealm_cnt->cnt_rate_illegal, +		 falsealm_cnt->cnt_crc8_fail, +		 falsealm_cnt->cnt_mcs_fail); + +	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, +		 "cnt_ofdm_fail = %x, cnt_cck_fail = %x," +		 " cnt_all = %x\n", +		 falsealm_cnt->cnt_ofdm_fail, +		 falsealm_cnt->cnt_cck_fail, +		 falsealm_cnt->cnt_all); +} + +static void rtl8723be_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ +	/* 8723BE does not support ODM_BB_DYNAMIC_TXPWR*/ +	return; +} + +static void rtl8723be_set_iqk_matrix(struct ieee80211_hw *hw, u8 ofdm_index, +				     u8 rfpath, long iqk_result_x, +				     long iqk_result_y) +{ +	long ele_a = 0, ele_d, ele_c = 0, value32; + +	if (ofdm_index >= 43) +		ofdm_index = 43 - 1; + +	ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000) >> 22; + +	if (iqk_result_x != 0) { +		if ((iqk_result_x & 0x00000200) != 0) +			iqk_result_x = iqk_result_x | 0xFFFFFC00; +		ele_a = ((iqk_result_x * ele_d) >> 8) & 0x000003FF; + +		if ((iqk_result_y & 0x00000200) != 0) +			iqk_result_y = iqk_result_y | 0xFFFFFC00; +		ele_c = ((iqk_result_y * ele_d) >> 8) & 0x000003FF; + +		switch (rfpath) { +		case RF90_PATH_A: +			value32 = (ele_d << 22) | +				((ele_c & 0x3F) << 16) | ele_a; +			rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, +				      value32); +			value32 = (ele_c & 0x000003C0) >> 6; +			rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32); +			value32 = ((iqk_result_x * ele_d) >> 7) & 0x01; +			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), +				      value32); +			break; +		default: +			break; +		} +	} else { +		switch (rfpath) { +		case RF90_PATH_A: +			rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD, +				      ofdmswing_table[ofdm_index]); +			rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00); +			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00); +			break; +		default: +			break; +		} +	} +} + +static void rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw *hw, +					enum pwr_track_control_method method, +					u8 rfpath, u8 idx) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); +	u8 swing_idx_ofdm_limit = 36; + +	if (method == TXAGC) { +		rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel); +	} else if (method == BBSWING) { +		if (rtldm->swing_idx_cck >= CCK_TABLE_SIZE) +			rtldm->swing_idx_cck = CCK_TABLE_SIZE - 1; + +		if (!rtldm->cck_inch14) { +			rtl_write_byte(rtlpriv, 0xa22, +			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][0]); +			rtl_write_byte(rtlpriv, 0xa23, +			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][1]); +			rtl_write_byte(rtlpriv, 0xa24, +			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][2]); +			rtl_write_byte(rtlpriv, 0xa25, +			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][3]); +			rtl_write_byte(rtlpriv, 0xa26, +			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][4]); +			rtl_write_byte(rtlpriv, 0xa27, +			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][5]); +			rtl_write_byte(rtlpriv, 0xa28, +			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][6]); +			rtl_write_byte(rtlpriv, 0xa29, +			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][7]); +		} else { +			rtl_write_byte(rtlpriv, 0xa22, +			    cckswing_table_ch14[rtldm->swing_idx_cck][0]); +			rtl_write_byte(rtlpriv, 0xa23, +			    cckswing_table_ch14[rtldm->swing_idx_cck][1]); +			rtl_write_byte(rtlpriv, 0xa24, +			    cckswing_table_ch14[rtldm->swing_idx_cck][2]); +			rtl_write_byte(rtlpriv, 0xa25, +			    cckswing_table_ch14[rtldm->swing_idx_cck][3]); +			rtl_write_byte(rtlpriv, 0xa26, +			    cckswing_table_ch14[rtldm->swing_idx_cck][4]); +			rtl_write_byte(rtlpriv, 0xa27, +			    cckswing_table_ch14[rtldm->swing_idx_cck][5]); +			rtl_write_byte(rtlpriv, 0xa28, +			    cckswing_table_ch14[rtldm->swing_idx_cck][6]); +			rtl_write_byte(rtlpriv, 0xa29, +			    cckswing_table_ch14[rtldm->swing_idx_cck][7]); +		} + +		if (rfpath == RF90_PATH_A) { +			if (rtldm->swing_idx_ofdm[RF90_PATH_A] < +			    swing_idx_ofdm_limit) +				swing_idx_ofdm_limit = +					rtldm->swing_idx_ofdm[RF90_PATH_A]; + +			rtl8723be_set_iqk_matrix(hw, +				rtldm->swing_idx_ofdm[rfpath], rfpath, +				rtlphy->iqk_matrix[idx].value[0][0], +				rtlphy->iqk_matrix[idx].value[0][1]); +		} else if (rfpath == RF90_PATH_B) { +			if (rtldm->swing_idx_ofdm[RF90_PATH_B] < +			    swing_idx_ofdm_limit) +				swing_idx_ofdm_limit = +					rtldm->swing_idx_ofdm[RF90_PATH_B]; + +			rtl8723be_set_iqk_matrix(hw, +				rtldm->swing_idx_ofdm[rfpath], rfpath, +				rtlphy->iqk_matrix[idx].value[0][4], +				rtlphy->iqk_matrix[idx].value[0][5]); +		} +	} else { +		return; +	} +} + +static void txpwr_track_cb_therm(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw)); +	u8 thermalvalue = 0, delta, delta_lck, delta_iqk; +	u8 thermalvalue_avg_count = 0; +	u32 thermalvalue_avg = 0; +	int i = 0; + +	u8 ofdm_min_index = 6; +	u8 index = 0; + +	char delta_swing_table_idx_tup_a[] = { +		0, 0, 1, 2, 2, 2, 3, 3, 3, 4,  5, +		5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, +		10, 11, 11, 12, 12, 13, 14, 15}; +	char delta_swing_table_idx_tdown_a[] = { +		0, 0, 1, 2, 2, 2, 3, 3, 3, 4,  5, +		5, 6, 6, 6, 6, 7, 7, 7, 8, 8,  9, +		9, 10, 10, 11, 12, 13, 14, 15}; + +	/*Initilization ( 7 steps in total)*/ +	rtlpriv->dm.txpower_trackinginit = true; +	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +		 "rtl8723be_dm_txpower_tracking" +		 "_callback_thermalmeter\n"); + +	thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xfc00); +	if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 || +	    rtlefuse->eeprom_thermalmeter == 0xFF) +		return; +	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +		 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x " +		 "eeprom_thermalmeter 0x%x\n", +		 thermalvalue, rtldm->thermalvalue, +		 rtlefuse->eeprom_thermalmeter); +	/*3 Initialize ThermalValues of RFCalibrateInfo*/ +	if (!rtldm->thermalvalue) { +		rtlpriv->dm.thermalvalue_lck = thermalvalue; +		rtlpriv->dm.thermalvalue_iqk = thermalvalue; +	} + +	/*4 Calculate average thermal meter*/ +	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue; +	rtldm->thermalvalue_avg_index++; +	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8723BE) +		rtldm->thermalvalue_avg_index = 0; + +	for (i = 0; i < AVG_THERMAL_NUM_8723BE; i++) { +		if (rtldm->thermalvalue_avg[i]) { +			thermalvalue_avg += rtldm->thermalvalue_avg[i]; +			thermalvalue_avg_count++; +		} +	} + +	if (thermalvalue_avg_count) +		thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count); + +	/* 5 Calculate delta, delta_LCK, delta_IQK.*/ +	delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? +		(thermalvalue - rtlpriv->dm.thermalvalue) : +		(rtlpriv->dm.thermalvalue - thermalvalue); +	delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? +		    (thermalvalue - rtlpriv->dm.thermalvalue_lck) : +		    (rtlpriv->dm.thermalvalue_lck - thermalvalue); +	delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? +		    (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : +		    (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + +	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +		 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x " +		 "eeprom_thermalmeter 0x%x delta 0x%x " +		 "delta_lck 0x%x delta_iqk 0x%x\n", +		 thermalvalue, rtlpriv->dm.thermalvalue, +		 rtlefuse->eeprom_thermalmeter, delta, delta_lck, delta_iqk); +	/* 6 If necessary, do LCK.*/ +	if (delta_lck >= IQK_THRESHOLD) { +		rtlpriv->dm.thermalvalue_lck = thermalvalue; +		rtl8723be_phy_lc_calibrate(hw); +	} + +	/* 7 If necessary, move the index of +	 * swing table to adjust Tx power. +	 */ +	if (delta > 0 && rtlpriv->dm.txpower_track_control) { +		delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ? +			(thermalvalue - rtlefuse->eeprom_thermalmeter) : +			(rtlefuse->eeprom_thermalmeter - thermalvalue); + +		if (delta >= TXSCALE_TABLE_SIZE) +			delta = TXSCALE_TABLE_SIZE - 1; +		/* 7.1 Get the final CCK_index and +		 * OFDM_index for each swing table. +		 */ +		if (thermalvalue > rtlefuse->eeprom_thermalmeter) { +			rtldm->delta_power_index_last[RF90_PATH_A] = +					rtldm->delta_power_index[RF90_PATH_A]; +			rtldm->delta_power_index[RF90_PATH_A] = +					delta_swing_table_idx_tup_a[delta]; +		} else { +			rtldm->delta_power_index_last[RF90_PATH_A] = +					rtldm->delta_power_index[RF90_PATH_A]; +			rtldm->delta_power_index[RF90_PATH_A] = +				-1 * delta_swing_table_idx_tdown_a[delta]; +		} + +		/* 7.2 Handle boundary conditions of index.*/ +		if (rtldm->delta_power_index[RF90_PATH_A] == +		    rtldm->delta_power_index_last[RF90_PATH_A]) +			rtldm->power_index_offset[RF90_PATH_A] = 0; +		else +			rtldm->power_index_offset[RF90_PATH_A] = +				rtldm->delta_power_index[RF90_PATH_A] - +				rtldm->delta_power_index_last[RF90_PATH_A]; + +		rtldm->ofdm_index[0] = +			rtldm->swing_idx_ofdm_base[RF90_PATH_A] + +			rtldm->power_index_offset[RF90_PATH_A]; +		rtldm->cck_index = rtldm->swing_idx_cck_base + +				   rtldm->power_index_offset[RF90_PATH_A]; + +		rtldm->swing_idx_cck = rtldm->cck_index; +		rtldm->swing_idx_ofdm[0] = rtldm->ofdm_index[0]; + +		if (rtldm->ofdm_index[0] > OFDM_TABLE_SIZE - 1) +			rtldm->ofdm_index[0] = OFDM_TABLE_SIZE - 1; +		else if (rtldm->ofdm_index[0] < ofdm_min_index) +			rtldm->ofdm_index[0] = ofdm_min_index; + +		if (rtldm->cck_index > CCK_TABLE_SIZE - 1) +			rtldm->cck_index = CCK_TABLE_SIZE - 1; +		else if (rtldm->cck_index < 0) +			rtldm->cck_index = 0; +	} else { +		rtldm->power_index_offset[RF90_PATH_A] = 0; +	} + +	if ((rtldm->power_index_offset[RF90_PATH_A] != 0) && +	    (rtldm->txpower_track_control)) { +		rtldm->done_txpower = true; +		if (thermalvalue > rtlefuse->eeprom_thermalmeter) +			rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0, +							      index); +		else +			rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0, +							      index); + +		rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; +		rtldm->swing_idx_ofdm_base[RF90_PATH_A] = +						rtldm->swing_idx_ofdm[0]; +		rtldm->thermalvalue = thermalvalue; +	} + +	if (delta_iqk >= IQK_THRESHOLD) { +		rtldm->thermalvalue_iqk = thermalvalue; +		rtl8723be_phy_iq_calibrate(hw, false); +	} + +	rtldm->txpowercount = 0; +	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n"); +} + +void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	static u8 tm_trigger; + +	if (!rtlpriv->dm.txpower_tracking) +		return; + +	if (!tm_trigger) { +		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16), +			      0x03); +		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +			 "Trigger 8723be Thermal Meter!!\n"); +		tm_trigger = 1; +		return; +	} else { +		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +			 "Schedule TxPowerTracking !!\n"); +		txpwr_track_cb_therm(hw); +		tm_trigger = 0; +	} +} + +static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rate_adaptive *ra = &(rtlpriv->ra); +	struct ieee80211_sta *sta = NULL; +	u32 low_rssithresh_for_ra = ra->low2high_rssi_thresh_for_ra40m; +	u32 high_rssithresh_for_ra = ra->high_rssi_thresh_for_ra; +	u8 go_up_gap = 5; + +	if (is_hal_stop(rtlhal)) { +		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, +			 "driver is going to unload\n"); +		return; +	} + +	if (!rtlpriv->dm.useramask) { +		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, +			 "driver does not control rate adaptive mask\n"); +		return; +	} + +	if (mac->link_state == MAC80211_LINKED && +	    mac->opmode == NL80211_IFTYPE_STATION) { +		switch (ra->pre_ratr_state) { +		case DM_RATR_STA_MIDDLE: +			high_rssithresh_for_ra += go_up_gap; +			break; +		case DM_RATR_STA_LOW: +			high_rssithresh_for_ra += go_up_gap; +			low_rssithresh_for_ra += go_up_gap; +			break; +		default: +			break; +		} + +		if (rtlpriv->dm.undec_sm_pwdb > +		    (long)high_rssithresh_for_ra) +			ra->ratr_state = DM_RATR_STA_HIGH; +		else if (rtlpriv->dm.undec_sm_pwdb > +			 (long)low_rssithresh_for_ra) +			ra->ratr_state = DM_RATR_STA_MIDDLE; +		else +			ra->ratr_state = DM_RATR_STA_LOW; + +		if (ra->pre_ratr_state != ra->ratr_state) { +			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, +				 "RSSI = %ld\n", +				 rtlpriv->dm.undec_sm_pwdb); +			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, +				 "RSSI_LEVEL = %d\n", ra->ratr_state); +			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, +				 "PreState = %d, CurState = %d\n", +				 ra->pre_ratr_state, ra->ratr_state); + +			rcu_read_lock(); +			sta = rtl_find_sta(hw, mac->bssid); +			if (sta) +				rtlpriv->cfg->ops->update_rate_tbl(hw, sta, +							   ra->ratr_state); +			rcu_read_unlock(); + +			ra->pre_ratr_state = ra->ratr_state; +		} +	} +} + +static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	if (rtlpriv->cfg->ops->get_btc_status()) { +		if (rtlpriv->btcoexist.btc_ops->btc_is_disable_edca_turbo(rtlpriv)) +			return true; +	} +	if (rtlpriv->mac80211.mode == WIRELESS_MODE_B) +		return true; + +	return false; +} + +static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	static u64 last_txok_cnt; +	static u64 last_rxok_cnt; +	u64 cur_txok_cnt = 0; +	u64 cur_rxok_cnt = 0; +	u32 edca_be_ul = 0x6ea42b; +	u32 edca_be_dl = 0x6ea42b;/*not sure*/ +	u32 edca_be = 0x5ea42b; +	u32 iot_peer = 0; +	bool is_cur_rdlstate; +	bool last_is_cur_rdlstate = false; +	bool bias_on_rx = false; +	bool edca_turbo_on = false; + +	last_is_cur_rdlstate = rtlpriv->dm.is_cur_rdlstate; + +	cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; +	cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + +	iot_peer = rtlpriv->mac80211.vendor; +	bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ? +		     true : false; +	edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && +			 (!rtlpriv->dm.disable_framebursting)) ? +			 true : false; + +	if ((iot_peer == PEER_CISCO) && +	    (mac->mode == WIRELESS_MODE_N_24G)) { +		edca_be_dl = edca_setting_dl[iot_peer]; +		edca_be_ul = edca_setting_ul[iot_peer]; +	} +	if (rtl8723be_dm_is_edca_turbo_disable(hw)) +		goto exit; + +	if (edca_turbo_on) { +		if (bias_on_rx) +			is_cur_rdlstate = (cur_txok_cnt > cur_rxok_cnt * 4) ? +					  false : true; +		else +			is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ? +					  true : false; + +		edca_be = (is_cur_rdlstate) ? edca_be_dl : edca_be_ul; +		rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be); +		rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate; +		rtlpriv->dm.current_turbo_edca = true; +	} else { +		if (rtlpriv->dm.current_turbo_edca) { +			u8 tmp = AC0_BE; +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, +						      &tmp); +		} +		rtlpriv->dm.current_turbo_edca = false; +	} + +exit: +	rtlpriv->dm.is_any_nonbepkts = false; +	last_txok_cnt = rtlpriv->stats.txbytesunicast; +	last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 cur_cck_cca_thresh; + +	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { +		if (rtlpriv->dm_digtable.rssi_val_min > 25) { +			cur_cck_cca_thresh = 0xcd; +		} else if ((rtlpriv->dm_digtable.rssi_val_min <= 25) && +			   (rtlpriv->dm_digtable.rssi_val_min > 10)) { +			cur_cck_cca_thresh = 0x83; +		} else { +			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) +				cur_cck_cca_thresh = 0x83; +			else +				cur_cck_cca_thresh = 0x40; +		} +	} else { +		if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) +			cur_cck_cca_thresh = 0x83; +		else +			cur_cck_cca_thresh = 0x40; +	} + +	if (rtlpriv->dm_digtable.cur_cck_cca_thres != cur_cck_cca_thresh) +		rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh); + +	rtlpriv->dm_digtable.pre_cck_cca_thres = rtlpriv->dm_digtable.cur_cck_cca_thres; +	rtlpriv->dm_digtable.cur_cck_cca_thres = cur_cck_cca_thresh; +	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, +		 "CCK cca thresh hold =%x\n", +		 rtlpriv->dm_digtable.cur_cck_cca_thres); +} + +static void rtl8723be_dm_dynamic_edcca(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 reg_c50, reg_c58; +	bool fw_current_in_ps_mode = false; + +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, +				      (u8 *)(&fw_current_in_ps_mode)); +	if (fw_current_in_ps_mode) +		return; + +	reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); +	reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + +	if (reg_c50 > 0x28 && reg_c58 > 0x28) { +		if (!rtlpriv->rtlhal.pre_edcca_enable) { +			rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03); +			rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00); +		} +	} else if (reg_c50 < 0x25 && reg_c58 < 0x25) { +		if (rtlpriv->rtlhal.pre_edcca_enable) { +			rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f); +			rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f); +		} +	} +} + +static void rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); +	u8 crystal_cap; +	u32 packet_count; +	int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0; +	int cfo_ave_diff; + +	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { +		if (rtldm->atc_status == ATC_STATUS_OFF) { +			rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), +				      ATC_STATUS_ON); +			rtldm->atc_status = ATC_STATUS_ON; +		} +		if (rtlpriv->cfg->ops->get_btc_status()) { +			if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) { +				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, +					 "odm_DynamicATCSwitch(): Disable" +					 " CFO tracking for BT!!\n"); +				return; +			} +		} + +		if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) { +			rtldm->crystal_cap = rtlpriv->efuse.crystalcap; +			crystal_cap = rtldm->crystal_cap & 0x3f; +			rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, +				      (crystal_cap | (crystal_cap << 6))); +		} +	} else { +		cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280; +		cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280; +		packet_count = rtldm->packet_count; + +		if (packet_count == rtldm->packet_count_pre) +			return; + +		rtldm->packet_count_pre = packet_count; + +		if (rtlpriv->phy.rf_type == RF_1T1R) +			cfo_ave = cfo_khz_a; +		else +			cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1; + +		cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ? +			       (rtldm->cfo_ave_pre - cfo_ave) : +			       (cfo_ave - rtldm->cfo_ave_pre); + +		if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) { +			rtldm->large_cfo_hit = 1; +			return; +		} else { +			rtldm->large_cfo_hit = 0; +		} + +		rtldm->cfo_ave_pre = cfo_ave; + +		if (cfo_ave >= -rtldm->cfo_threshold && +		    cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) { +			if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) { +				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10; +				rtldm->is_freeze = 1; +			} else { +				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL; +			} +		} + +		if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f) +			adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 1) + 1; +		else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && +					rtlpriv->dm.crystal_cap > 0) +			adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 1) - 1; + +		if (adjust_xtal != 0) { +			rtldm->is_freeze = 0; +			rtldm->crystal_cap += adjust_xtal; + +			if (rtldm->crystal_cap > 0x3f) +				rtldm->crystal_cap = 0x3f; +			else if (rtldm->crystal_cap < 0) +				rtldm->crystal_cap = 0; + +			crystal_cap = rtldm->crystal_cap & 0x3f; +			rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, +				      (crystal_cap | (crystal_cap << 6))); +		} + +		if (cfo_ave < CFO_THRESHOLD_ATC && +		    cfo_ave > -CFO_THRESHOLD_ATC) { +			if (rtldm->atc_status == ATC_STATUS_ON) { +				rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), +					      ATC_STATUS_OFF); +				rtldm->atc_status = ATC_STATUS_OFF; +			} +		} else { +			if (rtldm->atc_status == ATC_STATUS_OFF) { +				rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), +					      ATC_STATUS_ON); +				rtldm->atc_status = ATC_STATUS_ON; +			} +		} +	} +} + +static void rtl8723be_dm_common_info_self_update(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_sta_info *drv_priv; +	u8 cnt = 0; + +	rtlpriv->dm.one_entry_only = false; + +	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && +	    rtlpriv->mac80211.link_state >= MAC80211_LINKED) { +		rtlpriv->dm.one_entry_only = true; +		return; +	} + +	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || +	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC || +	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) { +		spin_lock_bh(&rtlpriv->locks.entry_list_lock); +		list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { +			cnt++; +		} +		spin_unlock_bh(&rtlpriv->locks.entry_list_lock); + +		if (cnt == 1) +			rtlpriv->dm.one_entry_only = true; +	} +} + +void rtl8723be_dm_watchdog(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	bool fw_current_inpsmode = false; +	bool fw_ps_awake = true; + +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, +				      (u8 *)(&fw_current_inpsmode)); + +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, +				      (u8 *)(&fw_ps_awake)); + +	if (ppsc->p2p_ps_info.p2p_ps_mode) +		fw_ps_awake = false; + +	if ((ppsc->rfpwr_state == ERFON) && +	    ((!fw_current_inpsmode) && fw_ps_awake) && +	    (!ppsc->rfchange_inprogress)) { +		rtl8723be_dm_common_info_self_update(hw); +		rtl8723be_dm_false_alarm_counter_statistics(hw); +		rtl8723be_dm_check_rssi_monitor(hw); +		rtl8723be_dm_dig(hw); +		rtl8723be_dm_dynamic_edcca(hw); +		rtl8723be_dm_cck_packet_detection_thresh(hw); +		rtl8723be_dm_refresh_rate_adaptive_mask(hw); +		rtl8723be_dm_check_edca_turbo(hw); +		rtl8723be_dm_dynamic_atc_switch(hw); +		rtl8723be_dm_check_txpower_tracking(hw); +		rtl8723be_dm_dynamic_txpower(hw); +		if (rtlpriv->cfg->ops->get_btc_status()) +			rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv); +	} +	rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.h b/drivers/net/wireless/rtlwifi/rtl8723be/dm.h new file mode 100644 index 00000000000..c6c2f2a78a6 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.h @@ -0,0 +1,310 @@ +/****************************************************************************** + * + * 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. + * + * 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	__RTL8723BE_DM_H__ +#define __RTL8723BE_DM_H__ + +#define	MAIN_ANT		0 +#define	AUX_ANT			1 +#define	MAIN_ANT_CG_TRX		1 +#define	AUX_ANT_CG_TRX		0 +#define	MAIN_ANT_CGCS_RX	0 +#define	AUX_ANT_CGCS_RX		1 + +#define	TXSCALE_TABLE_SIZE	30 + +/*RF REG LIST*/ +#define	DM_REG_RF_MODE_11N			0x00 +#define	DM_REG_RF_0B_11N			0x0B +#define	DM_REG_CHNBW_11N			0x18 +#define	DM_REG_T_METER_11N			0x24 +#define	DM_REG_RF_25_11N			0x25 +#define	DM_REG_RF_26_11N			0x26 +#define	DM_REG_RF_27_11N			0x27 +#define	DM_REG_RF_2B_11N			0x2B +#define	DM_REG_RF_2C_11N			0x2C +#define	DM_REG_RXRF_A3_11N			0x3C +#define	DM_REG_T_METER_92D_11N			0x42 +#define	DM_REG_T_METER_88E_11N			0x42 + +/*BB REG LIST*/ +/*PAGE 8 */ +#define	DM_REG_BB_CTRL_11N			0x800 +#define	DM_REG_RF_PIN_11N			0x804 +#define	DM_REG_PSD_CTRL_11N			0x808 +#define	DM_REG_TX_ANT_CTRL_11N			0x80C +#define	DM_REG_BB_PWR_SAV5_11N			0x818 +#define	DM_REG_CCK_RPT_FORMAT_11N		0x824 +#define	DM_REG_RX_DEFUALT_A_11N			0x858 +#define	DM_REG_RX_DEFUALT_B_11N			0x85A +#define	DM_REG_BB_PWR_SAV3_11N			0x85C +#define	DM_REG_ANTSEL_CTRL_11N			0x860 +#define	DM_REG_RX_ANT_CTRL_11N			0x864 +#define	DM_REG_PIN_CTRL_11N			0x870 +#define	DM_REG_BB_PWR_SAV1_11N			0x874 +#define	DM_REG_ANTSEL_PATH_11N			0x878 +#define	DM_REG_BB_3WIRE_11N			0x88C +#define	DM_REG_SC_CNT_11N			0x8C4 +#define	DM_REG_PSD_DATA_11N			0x8B4 +/*PAGE 9*/ +#define	DM_REG_ANT_MAPPING1_11N			0x914 +#define	DM_REG_ANT_MAPPING2_11N			0x918 +/*PAGE A*/ +#define	DM_REG_CCK_ANTDIV_PARA1_11N		0xA00 +#define	DM_REG_CCK_CCA_11N			0xA0A +#define	DM_REG_CCK_ANTDIV_PARA2_11N		0xA0C +#define	DM_REG_CCK_ANTDIV_PARA3_11N		0xA10 +#define	DM_REG_CCK_ANTDIV_PARA4_11N		0xA14 +#define	DM_REG_CCK_FILTER_PARA1_11N		0xA22 +#define	DM_REG_CCK_FILTER_PARA2_11N		0xA23 +#define	DM_REG_CCK_FILTER_PARA3_11N		0xA24 +#define	DM_REG_CCK_FILTER_PARA4_11N		0xA25 +#define	DM_REG_CCK_FILTER_PARA5_11N		0xA26 +#define	DM_REG_CCK_FILTER_PARA6_11N		0xA27 +#define	DM_REG_CCK_FILTER_PARA7_11N		0xA28 +#define	DM_REG_CCK_FILTER_PARA8_11N		0xA29 +#define	DM_REG_CCK_FA_RST_11N			0xA2C +#define	DM_REG_CCK_FA_MSB_11N			0xA58 +#define	DM_REG_CCK_FA_LSB_11N			0xA5C +#define	DM_REG_CCK_CCA_CNT_11N			0xA60 +#define	DM_REG_BB_PWR_SAV4_11N			0xA74 +/*PAGE B */ +#define	DM_REG_LNA_SWITCH_11N			0xB2C +#define	DM_REG_PATH_SWITCH_11N			0xB30 +#define	DM_REG_RSSI_CTRL_11N			0xB38 +#define	DM_REG_CONFIG_ANTA_11N			0xB68 +#define	DM_REG_RSSI_BT_11N			0xB9C +/*PAGE C */ +#define	DM_REG_OFDM_FA_HOLDC_11N		0xC00 +#define	DM_REG_RX_PATH_11N			0xC04 +#define	DM_REG_TRMUX_11N			0xC08 +#define	DM_REG_OFDM_FA_RSTC_11N			0xC0C +#define	DM_REG_RXIQI_MATRIX_11N			0xC14 +#define	DM_REG_TXIQK_MATRIX_LSB1_11N		0xC4C +#define	DM_REG_IGI_A_11N			0xC50 +#define	DM_REG_ANTDIV_PARA2_11N			0xC54 +#define	DM_REG_IGI_B_11N			0xC58 +#define	DM_REG_ANTDIV_PARA3_11N			0xC5C +#define	DM_REG_BB_PWR_SAV2_11N			0xC70 +#define	DM_REG_RX_OFF_11N			0xC7C +#define	DM_REG_TXIQK_MATRIXA_11N		0xC80 +#define	DM_REG_TXIQK_MATRIXB_11N		0xC88 +#define	DM_REG_TXIQK_MATRIXA_LSB2_11N		0xC94 +#define	DM_REG_TXIQK_MATRIXB_LSB2_11N		0xC9C +#define	DM_REG_RXIQK_MATRIX_LSB_11N		0xCA0 +#define	DM_REG_ANTDIV_PARA1_11N			0xCA4 +#define	DM_REG_OFDM_FA_TYPE1_11N		0xCF0 +/*PAGE D */ +#define	DM_REG_OFDM_FA_RSTD_11N			0xD00 +#define	DM_REG_OFDM_FA_TYPE2_11N		0xDA0 +#define	DM_REG_OFDM_FA_TYPE3_11N		0xDA4 +#define	DM_REG_OFDM_FA_TYPE4_11N		0xDA8 +/*PAGE E */ +#define	DM_REG_TXAGC_A_6_18_11N			0xE00 +#define	DM_REG_TXAGC_A_24_54_11N		0xE04 +#define	DM_REG_TXAGC_A_1_MCS32_11N		0xE08 +#define	DM_REG_TXAGC_A_MCS0_3_11N		0xE10 +#define	DM_REG_TXAGC_A_MCS4_7_11N		0xE14 +#define	DM_REG_TXAGC_A_MCS8_11_11N		0xE18 +#define	DM_REG_TXAGC_A_MCS12_15_11N		0xE1C +#define	DM_REG_FPGA0_IQK_11N			0xE28 +#define	DM_REG_TXIQK_TONE_A_11N			0xE30 +#define	DM_REG_RXIQK_TONE_A_11N			0xE34 +#define	DM_REG_TXIQK_PI_A_11N			0xE38 +#define	DM_REG_RXIQK_PI_A_11N			0xE3C +#define	DM_REG_TXIQK_11N			0xE40 +#define	DM_REG_RXIQK_11N			0xE44 +#define	DM_REG_IQK_AGC_PTS_11N			0xE48 +#define	DM_REG_IQK_AGC_RSP_11N			0xE4C +#define	DM_REG_BLUETOOTH_11N			0xE6C +#define	DM_REG_RX_WAIT_CCA_11N			0xE70 +#define	DM_REG_TX_CCK_RFON_11N			0xE74 +#define	DM_REG_TX_CCK_BBON_11N			0xE78 +#define	DM_REG_OFDM_RFON_11N			0xE7C +#define	DM_REG_OFDM_BBON_11N			0xE80 +#define DM_REG_TX2RX_11N			0xE84 +#define	DM_REG_TX2TX_11N			0xE88 +#define	DM_REG_RX_CCK_11N			0xE8C +#define	DM_REG_RX_OFDM_11N			0xED0 +#define	DM_REG_RX_WAIT_RIFS_11N			0xED4 +#define	DM_REG_RX2RX_11N			0xED8 +#define	DM_REG_STANDBY_11N			0xEDC +#define	DM_REG_SLEEP_11N			0xEE0 +#define	DM_REG_PMPD_ANAEN_11N			0xEEC + +/*MAC REG LIST*/ +#define	DM_REG_BB_RST_11N			0x02 +#define	DM_REG_ANTSEL_PIN_11N			0x4C +#define	DM_REG_EARLY_MODE_11N			0x4D0 +#define	DM_REG_RSSI_MONITOR_11N			0x4FE +#define	DM_REG_EDCA_VO_11N			0x500 +#define	DM_REG_EDCA_VI_11N			0x504 +#define	DM_REG_EDCA_BE_11N			0x508 +#define	DM_REG_EDCA_BK_11N			0x50C +#define	DM_REG_TXPAUSE_11N			0x522 +#define	DM_REG_RESP_TX_11N			0x6D8 +#define	DM_REG_ANT_TRAIN_PARA1_11N		0x7b0 +#define	DM_REG_ANT_TRAIN_PARA2_11N		0x7b4 + +/*DIG Related*/ +#define	DM_BIT_IGI_11N				0x0000007F + +#define HAL_DM_DIG_DISABLE			BIT(0) +#define HAL_DM_HIPWR_DISABLE			BIT(1) + +#define OFDM_TABLE_LENGTH			43 +#define CCK_TABLE_LENGTH			33 + +#define OFDM_TABLE_SIZE				37 +#define CCK_TABLE_SIZE				33 + +#define BW_AUTO_SWITCH_HIGH_LOW			25 +#define BW_AUTO_SWITCH_LOW_HIGH			30 + +#define DM_DIG_THRESH_HIGH			40 +#define DM_DIG_THRESH_LOW			35 + +#define DM_FALSEALARM_THRESH_LOW		400 +#define DM_FALSEALARM_THRESH_HIGH		1000 + +#define DM_DIG_MAX				0x3e +#define DM_DIG_MIN				0x1e + +#define DM_DIG_MAX_AP				0x32 +#define DM_DIG_MIN_AP				0x20 + +#define DM_DIG_FA_UPPER				0x3e +#define DM_DIG_FA_LOWER				0x1e +#define DM_DIG_FA_TH0				0x200 +#define DM_DIG_FA_TH1				0x300 +#define DM_DIG_FA_TH2				0x400 + +#define DM_DIG_BACKOFF_MAX			12 +#define DM_DIG_BACKOFF_MIN			-4 +#define DM_DIG_BACKOFF_DEFAULT			10 + +#define RXPATHSELECTION_DIFF_TH			18 + +#define DM_RATR_STA_INIT			0 +#define DM_RATR_STA_HIGH			1 +#define DM_RATR_STA_MIDDLE			2 +#define DM_RATR_STA_LOW				3 + +#define CTS2SELF_THVAL				30 +#define REGC38_TH				20 + +#define TXHIGHPWRLEVEL_NORMAL			0 +#define TXHIGHPWRLEVEL_LEVEL1			1 +#define TXHIGHPWRLEVEL_LEVEL2			2 +#define TXHIGHPWRLEVEL_BT1			3 +#define TXHIGHPWRLEVEL_BT2			4 + +#define DM_TYPE_BYFW				0 +#define DM_TYPE_BYDRIVER			1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2		74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1		67 +#define TXPWRTRACK_MAX_IDX			6 + +/* Dynamic ATC switch */ +#define ATC_STATUS_OFF				0x0 /* enable */ +#define	ATC_STATUS_ON				0x1 /* disable */ +#define	CFO_THRESHOLD_XTAL			10 /* kHz */ +#define	CFO_THRESHOLD_ATC			80 /* kHz */ + +enum FAT_STATE { +	FAT_NORMAL_STATE	= 0, +	FAT_TRAINING_STATE	= 1, +}; + +enum tag_dynamic_init_gain_operation_type_definition { +	DIG_TYPE_THRESH_HIGH	= 0, +	DIG_TYPE_THRESH_LOW	= 1, +	DIG_TYPE_BACKOFF	= 2, +	DIG_TYPE_RX_GAIN_MIN	= 3, +	DIG_TYPE_RX_GAIN_MAX	= 4, +	DIG_TYPE_ENABLE		= 5, +	DIG_TYPE_DISABLE	= 6, +	DIG_OP_TYPE_MAX +}; + +enum dm_1r_cca_e { +	CCA_1R		= 0, +	CCA_2R		= 1, +	CCA_MAX		= 2, +}; + +enum dm_rf_e { +	RF_SAVE		= 0, +	RF_NORMAL	= 1, +	RF_MAX		= 2, +}; + +enum dm_sw_ant_switch_e { +	ANS_ANTENNA_B	= 1, +	ANS_ANTENNA_A	= 2, +	ANS_ANTENNA_MAX	= 3, +}; + +enum dm_dig_ext_port_alg_e { +	DIG_EXT_PORT_STAGE_0	= 0, +	DIG_EXT_PORT_STAGE_1	= 1, +	DIG_EXT_PORT_STAGE_2	= 2, +	DIG_EXT_PORT_STAGE_3	= 3, +	DIG_EXT_PORT_STAGE_MAX	= 4, +}; + +enum dm_dig_connect_e { +	DIG_STA_DISCONNECT	= 0, +	DIG_STA_CONNECT		= 1, +	DIG_STA_BEFORE_CONNECT	= 2, +	DIG_MULTISTA_DISCONNECT	= 3, +	DIG_MULTISTA_CONNECT	= 4, +	DIG_CONNECT_MAX +}; + +enum pwr_track_control_method { +	BBSWING, +	TXAGC +}; + +#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) + +void rtl8723be_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, u8 *pdesc, +					u32 mac_id); +void rtl8723be_dm_ant_sel_statistics(struct ieee80211_hw *hw, u8 antsel_tr_mux, +				     u32 mac_id, u32 rx_pwdb_all); +void rtl8723be_dm_fast_antenna_trainning_callback(unsigned long data); +void rtl8723be_dm_init(struct ieee80211_hw *hw); +void rtl8723be_dm_watchdog(struct ieee80211_hw *hw); +void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi); +void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type, +				       u8 *pdirection, u32 *poutwrite_val); +void rtl8723be_dm_init_edca_turbo(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c new file mode 100644 index 00000000000..f856be6fc13 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c @@ -0,0 +1,620 @@ +/****************************************************************************** + * + * 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 "reg.h" +#include "def.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" + +static bool _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw *hw, +					      u8 boxnum) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 val_hmetfr; +	bool result = false; + +	val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); +	if (((val_hmetfr >> boxnum) & BIT(0)) == 0) +		result = true; +	return result; +} + +static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, +					u32 cmd_len, u8 *p_cmdbuffer) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u8 boxnum; +	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_limit = 100; +	u8 wait_writeh2c_limit = 100; +	u8 boxcontent[4], boxextcontent[4]; +	u32 h2c_waitcounter = 0; +	unsigned long flag; +	u8 idx; + +	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); + +	while (true) { +		spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); +		if (rtlhal->h2c_setinprogress) { +			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, +				 "H2C set in progress! Wait to set.." +				 "element_id(%d).\n", element_id); + +			while (rtlhal->h2c_setinprogress) { +				spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, +						       flag); +				h2c_waitcounter++; +				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, +					 "Wait 100 us (%d times)...\n", +					 h2c_waitcounter); +				udelay(100); + +				if (h2c_waitcounter > 1000) +					return; +				spin_lock_irqsave(&rtlpriv->locks.h2c_lock, +						  flag); +			} +			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); +		} else { +			rtlhal->h2c_setinprogress = true; +			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); +			break; +		} +	} +	while (!bwrite_sucess) { +		wait_writeh2c_limit--; +		if (wait_writeh2c_limit == 0) { +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "Write H2C fail because no trigger " +				 "for FW INT!\n"); +			break; +		} +		boxnum = rtlhal->last_hmeboxnum; +		switch (boxnum) { +		case 0: +			box_reg = REG_HMEBOX_0; +			box_extreg = REG_HMEBOX_EXT_0; +			break; +		case 1: +			box_reg = REG_HMEBOX_1; +			box_extreg = REG_HMEBOX_EXT_1; +			break; +		case 2: +			box_reg = REG_HMEBOX_2; +			box_extreg = REG_HMEBOX_EXT_2; +			break; +		case 3: +			box_reg = REG_HMEBOX_3; +			box_extreg = REG_HMEBOX_EXT_3; +			break; +		default: +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "switch case not processed\n"); +			break; +		} +		isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum); +		while (!isfw_read) { +			wait_h2c_limit--; +			if (wait_h2c_limit == 0) { +				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, +					 "Wating too long for FW read " +					 "clear HMEBox(%d)!\n", boxnum); +				break; +			} +			udelay(10); + +			isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, +								boxnum); +			u1b_tmp = rtl_read_byte(rtlpriv, 0x130); +			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, +				 "Wating for FW read clear HMEBox(%d)!!! 0x130 = %2x\n", +				 boxnum, u1b_tmp); +		} +		if (!isfw_read) { +			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, +				 "Write H2C register BOX[%d] fail!!!!! " +				 "Fw do not read.\n", boxnum); +			break; +		} +		memset(boxcontent, 0, sizeof(boxcontent)); +		memset(boxextcontent, 0, sizeof(boxextcontent)); +		boxcontent[0] = element_id; +		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, +			 "Write element_id box_reg(%4x) = %2x\n", +			 box_reg, element_id); + +		switch (cmd_len) { +		case 1: +		case 2: +		case 3: +			/*boxcontent[0] &= ~(BIT(7));*/ +			memcpy((u8 *)(boxcontent) + 1, +			       p_cmdbuffer + buf_index, cmd_len); + +			for (idx = 0; idx < 4; idx++) { +				rtl_write_byte(rtlpriv, box_reg + idx, +					       boxcontent[idx]); +			} +			break; +		case 4: +		case 5: +		case 6: +		case 7: +			/*boxcontent[0] |= (BIT(7));*/ +			memcpy((u8 *)(boxextcontent), +			       p_cmdbuffer + buf_index+3, cmd_len-3); +			memcpy((u8 *)(boxcontent) + 1, +			       p_cmdbuffer + buf_index, 3); + +			for (idx = 0; idx < 4; idx++) { +				rtl_write_byte(rtlpriv, box_extreg + idx, +					       boxextcontent[idx]); +			} +			for (idx = 0; idx < 4; idx++) { +				rtl_write_byte(rtlpriv, box_reg + idx, +					       boxcontent[idx]); +			} +			break; +		default: +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "switch case not process\n"); +			break; +		} +		bwrite_sucess = true; + +		rtlhal->last_hmeboxnum = boxnum + 1; +		if (rtlhal->last_hmeboxnum == 4) +			rtlhal->last_hmeboxnum = 0; + +		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, +			 "pHalData->last_hmeboxnum  = %d\n", +			 rtlhal->last_hmeboxnum); +	} +	spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); +	rtlhal->h2c_setinprogress = false; +	spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + +	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, +			    u32 cmd_len, u8 *p_cmdbuffer) +{ +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u32 tmp_cmdbuf[2]; + +	if (!rtlhal->fw_ready) { +		RT_ASSERT(false, +			  "return H2C cmd because of Fw download fail!!!\n"); +		return; +	} +	memset(tmp_cmdbuf, 0, 8); +	memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); +	_rtl8723be_fill_h2c_command(hw, element_id, cmd_len, +				    (u8 *)&tmp_cmdbuf); +	return; +} + +void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 u1_h2c_set_pwrmode[H2C_8723BE_PWEMODE_LENGTH] = { 0 }; +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	u8 rlbm, power_state = 0; +	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); + +	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); +	rlbm = 0;/*YJ, temp, 120316. FW now not support RLBM = 2.*/ +	SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm); +	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, +					 (rtlpriv->mac80211.p2p) ? +					 ppsc->smart_ps : 1); +	SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, +					       ppsc->reg_max_lps_awakeintvl); +	SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0); +	if (mode == FW_PS_ACTIVE_MODE) +		power_state |= FW_PWR_STATE_ACTIVE; +	else +		power_state |= FW_PWR_STATE_RF_OFF; +	SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state); + +	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, +		      "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n", +		      u1_h2c_set_pwrmode, H2C_8723BE_PWEMODE_LENGTH); +	rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_SETPWRMODE, +			       H2C_8723BE_PWEMODE_LENGTH, +			       u1_h2c_set_pwrmode); +} + +static bool _rtl8723be_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; +} +#define BEACON_PG		0 /* ->1 */ +#define PSPOLL_PG		2 +#define NULL_PG			3 +#define PROBERSP_PG		4 /* ->5 */ + +#define TOTAL_RESERVED_PKT_LEN	768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { +	/* page 0 beacon */ +	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +	0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, +	0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65, +	0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B, +	0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06, +	0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32, +	0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, +	0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C, +	0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50, +	0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, +	0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00, + +	/* page 1 beacon */ +	0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +	/* page 2  ps-poll */ +	0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B, +	0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +	/* page 3  null */ +	0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B, +	0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, +	0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +	/* page 4  probe_resp */ +	0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, +	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, +	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, +	0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, +	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, +	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, +	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, +	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, +	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, +	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, +	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, +	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +	/* page 5  probe_resp */ +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl8723be_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)); +	struct sk_buff *skb = NULL; + +	u32 totalpacketlen; +	bool rtstatus; +	u8 u1rsvdpageloc[5] = { 0 }; +	bool dlok = false; + +	u8 *beacon; +	u8 *p_pspoll; +	u8 *nullfunc; +	u8 *p_probersp; +	/*--------------------------------------------------------- +	 *			(1) beacon +	 *--------------------------------------------------------- +	 */ +	beacon = &reserved_page_packet[BEACON_PG * 128]; +	SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); +	SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + +	/*------------------------------------------------------- +	 *			(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); + +	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG); + +	/*-------------------------------------------------------- +	 *			(3) null data +	 *-------------------------------------------------------- +	 */ +	nullfunc = &reserved_page_packet[NULL_PG * 128]; +	SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); +	SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); +	SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + +	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG); + +	/*--------------------------------------------------------- +	 *			(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); + +	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG); + +	totalpacketlen = TOTAL_RESERVED_PKT_LEN; + +	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, +		      "rtl8723be_set_fw_rsvdpagepkt(): " +		      "HW_VAR_SET_TX_CMD: ALL\n", +		      &reserved_page_packet[0], totalpacketlen); +	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, +		      "rtl8723be_set_fw_rsvdpagepkt(): " +		      "HW_VAR_SET_TX_CMD: ALL\n", u1rsvdpageloc, 3); + + +	skb = dev_alloc_skb(totalpacketlen); +	memcpy((u8 *)skb_put(skb, totalpacketlen), +	       &reserved_page_packet, totalpacketlen); + +	rtstatus = _rtl8723be_cmd_send_packet(hw, skb); + +	if (rtstatus) +		dlok = true; + +	if (dlok) { +		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +			 "Set RSVD page location to Fw.\n"); +		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n", +			      u1rsvdpageloc, 3); +		rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_RSVDPAGE, +				       sizeof(u1rsvdpageloc), u1rsvdpageloc); +	} else { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +			 "Set RSVD page location to Fw FAIL!!!!!!.\n"); +	} +} + +/*Should check FW support p2p or not.*/ +static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, +					     u8 ctwindow) +{ +	u8 u1_ctwindow_period[1] = {ctwindow}; + +	rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_P2P_PS_CTW_CMD, 1, +			       u1_ctwindow_period); +} + +void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, +				      u8 p2p_ps_state) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info); +	struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; +	u8 i; +	u16 ctwindow; +	u32 start_time, tsf_low; + +	switch (p2p_ps_state) { +	case P2P_PS_DISABLE: +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); +		memset(p2p_ps_offload, 0, sizeof(struct p2p_ps_offload_t)); +		break; +	case P2P_PS_ENABLE: +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); +		/* update CTWindow value. */ +		if (p2pinfo->ctwindow > 0) { +			p2p_ps_offload->ctwindow_en = 1; +			ctwindow = p2pinfo->ctwindow; +			rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow); +		} +		/* hw only support 2 set of NoA */ +		for (i = 0; i < p2pinfo->noa_num; i++) { +			/* To control the register setting +			 * for which NOA +			 */ +			rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); +			if (i == 0) +				p2p_ps_offload->noa0_en = 1; +			else +				p2p_ps_offload->noa1_en = 1; + +			/* config P2P NoA Descriptor Register */ +			rtl_write_dword(rtlpriv, 0x5E0, +					p2pinfo->noa_duration[i]); +			rtl_write_dword(rtlpriv, 0x5E4, +					p2pinfo->noa_interval[i]); + +			/*Get Current TSF value */ +			tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + +			start_time = p2pinfo->noa_start_time[i]; +			if (p2pinfo->noa_count_type[i] != 1) { +				while (start_time <= (tsf_low + (50 * 1024))) { +					start_time += p2pinfo->noa_interval[i]; +					if (p2pinfo->noa_count_type[i] != 255) +						p2pinfo->noa_count_type[i]--; +				} +			} +			rtl_write_dword(rtlpriv, 0x5E8, start_time); +			rtl_write_dword(rtlpriv, 0x5EC, +					p2pinfo->noa_count_type[i]); +		} +		if ((p2pinfo->opp_ps == 1) || +		    (p2pinfo->noa_num > 0)) { +			/* rst p2p circuit */ +			rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4)); + +			p2p_ps_offload->offload_en = 1; + +			if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { +				p2p_ps_offload->role = 1; +				p2p_ps_offload->allstasleep = 0; +			} else { +				p2p_ps_offload->role = 0; +			} +			p2p_ps_offload->discovery = 0; +		} +		break; +	case P2P_PS_SCAN: +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); +		p2p_ps_offload->discovery = 1; +		break; +	case P2P_PS_SCAN_DONE: +		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); +		p2p_ps_offload->discovery = 0; +		p2pinfo->p2p_ps_state = P2P_PS_ENABLE; +		break; +	default: +		break; +	} +	rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_P2P_PS_OFFLOAD, 1, +			       (u8 *)p2p_ps_offload); +} + +void rtl8723be_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ +	u8 u1_joinbssrpt_parm[1] = { 0 }; + +	SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); + +	rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_JOINBSSRPT, 1, +			       u1_joinbssrpt_parm); +} + +void rtl8723be_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw, +				      u8 ap_offload_enable) +{ +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	u8 u1_apoffload_parm[H2C_8723BE_AP_OFFLOAD_LENGTH] = { 0 }; + +	SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable); +	SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->hiddenssid); +	SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0); + +	rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_AP_OFFLOAD, +			       H2C_8723BE_AP_OFFLOAD_LENGTH, u1_apoffload_parm); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.h b/drivers/net/wireless/rtlwifi/rtl8723be/fw.h new file mode 100644 index 00000000000..31eec281e44 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/fw.h @@ -0,0 +1,248 @@ +/****************************************************************************** + * + * 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 __RTL8723BE__FW__H__ +#define __RTL8723BE__FW__H__ + +#define FW_8192C_SIZE				0x8000 +#define FW_8192C_START_ADDRESS			0x1000 +#define FW_8192C_END_ADDRESS			0x5FFF +#define FW_8192C_PAGE_SIZE			4096 +#define FW_8192C_POLLING_DELAY			5 +#define FW_8192C_POLLING_TIMEOUT_COUNT		6000 + +#define IS_FW_HEADER_EXIST(_pfwhdr)	\ +	((_pfwhdr->signature&0xFFF0) == 0x5300) +#define USE_OLD_WOWLAN_DEBUG_FW			0 + +#define H2C_8723BE_RSVDPAGE_LOC_LEN		5 +#define H2C_8723BE_PWEMODE_LENGTH		5 +#define H2C_8723BE_JOINBSSRPT_LENGTH		1 +#define H2C_8723BE_AP_OFFLOAD_LENGTH		3 +#define H2C_8723BE_WOWLAN_LENGTH		3 +#define H2C_8723BE_KEEP_ALIVE_CTRL_LENGTH	3 +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) +#define H2C_8723BE_REMOTE_WAKE_CTRL_LEN		1 +#else +#define H2C_8723BE_REMOTE_WAKE_CTRL_LEN		3 +#endif +#define H2C_8723BE_AOAC_GLOBAL_INFO_LEN		2 +#define H2C_8723BE_AOAC_RSVDPAGE_LOC_LEN	7 + + +/* Fw PS state for RPWM. +*BIT[2:0] = HW state +*BIT[3] = Protocol PS state, 1: register active state , 0: register sleep state +*BIT[4] = sub-state +*/ +#define	FW_PS_GO_ON		BIT(0) +#define	FW_PS_TX_NULL		BIT(1) +#define	FW_PS_RF_ON		BIT(2) +#define	FW_PS_REGISTER_ACTIVE	BIT(3) + +#define	FW_PS_DPS		BIT(0) +#define	FW_PS_LCLK		(FW_PS_DPS) +#define	FW_PS_RF_OFF		BIT(1) +#define	FW_PS_ALL_ON		BIT(2) +#define	FW_PS_ST_ACTIVE	BIT(3) +#define	FW_PS_ISR_ENABLE	BIT(4) +#define	FW_PS_IMR_ENABLE	BIT(5) + + +#define	FW_PS_ACK		BIT(6) +#define	FW_PS_TOGGLE		BIT(7) + + /* 88E RPWM value*/ + /* BIT[0] = 1: 32k, 0: 40M*/ +#define	FW_PS_CLOCK_OFF		BIT(0)		/* 32k*/ +#define	FW_PS_CLOCK_ON		0		/*40M*/ + +#define	FW_PS_STATE_MASK	(0x0F) +#define	FW_PS_STATE_HW_MASK	(0x07) +/*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/ +#define	FW_PS_STATE_INT_MASK	(0x3F) + +#define	FW_PS_STATE(x)	(FW_PS_STATE_MASK & (x)) +#define	FW_PS_STATE_HW(x)	(FW_PS_STATE_HW_MASK & (x)) +#define	FW_PS_STATE_INT(x)	(FW_PS_STATE_INT_MASK & (x)) +#define	FW_PS_ISR_VAL(x)	((x) & 0x70) +#define	FW_PS_IMR_MASK(x)	((x) & 0xDF) +#define	FW_PS_KEEP_IMR(x)	((x) & 0x20) + + +#define	FW_PS_STATE_S0		(FW_PS_DPS) +#define	FW_PS_STATE_S1		(FW_PS_LCLK) +#define	FW_PS_STATE_S2		(FW_PS_RF_OFF) +#define	FW_PS_STATE_S3		(FW_PS_ALL_ON) +#define	FW_PS_STATE_S4		((FW_PS_ST_ACTIVE) | (FW_PS_ALL_ON)) + +/* ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))*/ +#define	FW_PS_STATE_ALL_ON_88E	(FW_PS_CLOCK_ON) +/* (FW_PS_RF_ON)*/ +#define	FW_PS_STATE_RF_ON_88E	(FW_PS_CLOCK_ON) +/* 0x0*/ +#define	FW_PS_STATE_RF_OFF_88E	(FW_PS_CLOCK_ON) +/* (FW_PS_STATE_RF_OFF)*/ +#define	FW_PS_STATE_RF_OFF_LOW_PWR_88E	(FW_PS_CLOCK_OFF) + +#define	FW_PS_STATE_ALL_ON_92C	(FW_PS_STATE_S4) +#define	FW_PS_STATE_RF_ON_92C		(FW_PS_STATE_S3) +#define	FW_PS_STATE_RF_OFF_92C	(FW_PS_STATE_S2) +#define	FW_PS_STATE_RF_OFF_LOW_PWR_92C	(FW_PS_STATE_S1) + + +/* For 88E H2C PwrMode Cmd ID 5.*/ +#define	FW_PWR_STATE_ACTIVE	((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define	FW_PWR_STATE_RF_OFF	0 + +#define	FW_PS_IS_ACK(x)	((x) & FW_PS_ACK) +#define	FW_PS_IS_CLK_ON(x)	((x) & (FW_PS_RF_OFF | FW_PS_ALL_ON)) +#define	FW_PS_IS_RF_ON(x)	((x) & (FW_PS_ALL_ON)) +#define	FW_PS_IS_ACTIVE(x)	((x) & (FW_PS_ST_ACTIVE)) +#define	FW_PS_IS_CPWM_INT(x)	((x) & 0x40) + +#define	FW_CLR_PS_STATE(x)	((x) = ((x) & (0xF0))) + +#define	IS_IN_LOW_POWER_STATE_88E(fwpsstate)		\ +			(FW_PS_STATE(fwpsstate) == FW_PS_CLOCK_OFF) + +#define	FW_PWR_STATE_ACTIVE	((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define	FW_PWR_STATE_RF_OFF	0 + +#define pagenum_128(_len)	(u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + +#define SET_88E_H2CCMD_WOWLAN_FUNC_ENABLE(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val) +#define SET_88E_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val) +#define SET_88E_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 2, 1, __val) +#define SET_88E_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 3, 1, __val) +#define SET_88E_H2CCMD_WOWLAN_ALL_PKT_DROP(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 4, 1, __val) +#define SET_88E_H2CCMD_WOWLAN_GPIO_ACTIVE(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 5, 1, __val) +#define SET_88E_H2CCMD_WOWLAN_REKEY_WAKE_UP(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 6, 1, __val) +#define SET_88E_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 7, 1, __val) +#define SET_88E_H2CCMD_WOWLAN_GPIONUM(__ph2ccmd, __val)			\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_88E_H2CCMD_WOWLAN_GPIO_DURATION(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) + + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val)			\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_RLBM(__ph2ccmd, __val)			\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 4, __val) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 4, 4, __val) +#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+4, 0, 8, __val) +#define GET_88E_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd)			\ +	LE_BITS_TO_1BYTE(__ph2ccmd, 0, 8) + +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) + +/* AP_OFFLOAD */ +#define SET_H2CCMD_AP_OFFLOAD_ON(__ph2ccmd, __val)			\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_AP_OFFLOAD_HIDDEN(__ph2ccmd, __val)			\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_H2CCMD_AP_OFFLOAD_DENYANY(__ph2ccmd, __val)			\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) +#define SET_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val) + +/* Keep Alive Control*/ +#define SET_88E_H2CCMD_KEEP_ALIVE_ENABLE(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val) +#define SET_88E_H2CCMD_KEEP_ALIVE_ACCPEPT_USER_DEFINED(__ph2ccmd, __val)\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val) +#define SET_88E_H2CCMD_KEEP_ALIVE_PERIOD(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) + +/*REMOTE_WAKE_CTRL */ +#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_EN(__ph2ccmd, __val)		\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val) +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) +#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__ph2ccmd, __val)\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val) +#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__ph2ccmd, __val)\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 2, 1, __val) +#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__ph2ccmd, __val)\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 3, 1, __val) +#else +#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_PAIRWISE_ENC_ALG(__ph2ccmd, __val)\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GROUP_ENC_ALG(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) +#endif + +/* GTK_OFFLOAD */ +#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__ph2ccmd, __val)\ +	SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) + +/* AOAC_RSVDPAGE_LOC */ +#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_REM_WAKE_CTRL_INFO(__ph2ccmd, __val)\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd), 0, 8, __val) +#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) +#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val) +#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__ph2ccmd, __val)	\ +	SET_BITS_TO_LE_1BYTE((__ph2ccmd)+4, 0, 8, __val) + +void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl8723be_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw, +				      u8 ap_offload_enable); +void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, +			    u32 cmd_len, u8 *p_cmdbuffer); +void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw); +void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, +				  bool dl_finished); +void rtl8723be_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); +int rtl8723be_download_fw(struct ieee80211_hw *hw, +			  bool buse_wake_on_wlan_fw); +void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, +				      u8 p2p_ps_state); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c new file mode 100644 index 00000000000..3d555495b45 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c @@ -0,0 +1,2503 @@ +/****************************************************************************** + * + * 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 "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "../rtl8723com/dm_common.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" +#include "led.h" +#include "hw.h" +#include "pwrseq.h" +#include "../btcoexist/rtl_btc.h" + +#define LLT_CONFIG	5 + +static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + +	while (skb_queue_len(&ring->queue)) { +		struct rtl_tx_desc *entry = &ring->desc[ring->idx]; +		struct sk_buff *skb = __skb_dequeue(&ring->queue); + +		pci_unmap_single(rtlpci->pdev, +				 rtlpriv->cfg->ops->get_desc( +				 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR), +				 skb->len, PCI_DMA_TODEVICE); +		kfree_skb(skb); +		ring->idx = (ring->idx + 1) % ring->entries; +	} +} + +static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw, +					u8 set_bits, u8 clear_bits) +{ +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtlpci->reg_bcn_ctrl_val |= set_bits; +	rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + +	rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 tmp1byte; + +	tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); +	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); +	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); +	tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); +	tmp1byte &= ~(BIT(0)); +	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 tmp1byte; + +	tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); +	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); +	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); +	tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); +	tmp1byte |= BIT(1); +	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); +} + +static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ +	_rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ +	_rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val, +				       bool need_turn_off_ckk) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	bool support_remote_wake_up; +	u32 count = 0, isr_regaddr, content; +	bool schedule_timer = need_turn_off_ckk; +	rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, +				      (u8 *)(&support_remote_wake_up)); + +	if (!rtlhal->fw_ready) +		return; +	if (!rtlpriv->psc.fw_current_inpsmode) +		return; + +	while (1) { +		spin_lock_bh(&rtlpriv->locks.fw_ps_lock); +		if (rtlhal->fw_clk_change_in_progress) { +			while (rtlhal->fw_clk_change_in_progress) { +				spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +				count++; +				udelay(100); +				if (count > 1000) +					return; +				spin_lock_bh(&rtlpriv->locks.fw_ps_lock); +			} +			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +		} else { +			rtlhal->fw_clk_change_in_progress = false; +			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +			break; +		} +	} +	if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) { +		rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, +					      &rpwm_val); +		if (FW_PS_IS_ACK(rpwm_val)) { +			isr_regaddr = REG_HISR; +			content = rtl_read_dword(rtlpriv, isr_regaddr); +			while (!(content & IMR_CPWM) && (count < 500)) { +				udelay(50); +				count++; +				content = rtl_read_dword(rtlpriv, isr_regaddr); +			} + +			if (content & IMR_CPWM) { +				rtl_write_word(rtlpriv, isr_regaddr, 0x0100); +				rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_88E; +				RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +					 "Receive CPWM INT!!! Set " +					 "pHalData->FwPSState = %X\n", +					 rtlhal->fw_ps_state); +			} +		} +		spin_lock_bh(&rtlpriv->locks.fw_ps_lock); +		rtlhal->fw_clk_change_in_progress = false; +		spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +		if (schedule_timer) { +			mod_timer(&rtlpriv->works.fw_clockoff_timer, +				  jiffies + MSECS(10)); +		} +	} else  { +		spin_lock_bh(&rtlpriv->locks.fw_ps_lock); +		rtlhal->fw_clk_change_in_progress = false; +		spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +	} +} + +static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl8192_tx_ring *ring; +	enum rf_pwrstate rtstate; +	bool schedule_timer = false; +	u8 queue; + +	if (!rtlhal->fw_ready) +		return; +	if (!rtlpriv->psc.fw_current_inpsmode) +		return; +	if (!rtlhal->allow_sw_to_change_hwclc) +		return; +	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate)); +	if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF) +		return; + +	for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) { +		ring = &rtlpci->tx_ring[queue]; +		if (skb_queue_len(&ring->queue)) { +			schedule_timer = true; +			break; +		} +	} +	if (schedule_timer) { +		mod_timer(&rtlpriv->works.fw_clockoff_timer, +			  jiffies + MSECS(10)); +		return; +	} +	if (FW_PS_STATE(rtlhal->fw_ps_state) != +	    FW_PS_STATE_RF_OFF_LOW_PWR_88E) { +		spin_lock_bh(&rtlpriv->locks.fw_ps_lock); +		if (!rtlhal->fw_clk_change_in_progress) { +			rtlhal->fw_clk_change_in_progress = true; +			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +			rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); +			rtl_write_word(rtlpriv, REG_HISR, 0x0100); +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, +						      &rpwm_val); +			spin_lock_bh(&rtlpriv->locks.fw_ps_lock); +			rtlhal->fw_clk_change_in_progress = false; +			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +		} else { +			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); +			mod_timer(&rtlpriv->works.fw_clockoff_timer, +				  jiffies + MSECS(10)); +		} +	} +} + +static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw) +{ +	u8 rpwm_val = 0; +	rpwm_val |= (FW_PS_STATE_RF_OFF_88E | FW_PS_ACK); +	_rtl8723be_set_fw_clock_on(hw, rpwm_val, true); +} + +static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	bool fw_current_inps = false; +	u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE; + +	if (ppsc->low_power_enable) { +		rpwm_val = (FW_PS_STATE_ALL_ON_88E | FW_PS_ACK);/* RF on */ +		_rtl8723be_set_fw_clock_on(hw, rpwm_val, false); +		rtlhal->allow_sw_to_change_hwclc = false; +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, +					      &fw_pwrmode); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, +					      (u8 *)(&fw_current_inps)); +	} else { +		rpwm_val = FW_PS_STATE_ALL_ON_88E;	/* RF on */ +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, +					      &fw_pwrmode); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, +					      (u8 *)(&fw_current_inps)); +	} +} + +static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	bool fw_current_inps = true; +	u8 rpwm_val; + +	if (ppsc->low_power_enable) { +		rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_88E;	/* RF off */ +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, +					      (u8 *)(&fw_current_inps)); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, +					      &ppsc->fwctrl_psmode); +		rtlhal->allow_sw_to_change_hwclc = true; +		_rtl8723be_set_fw_clock_off(hw, rpwm_val); + +	} else { +		rpwm_val = FW_PS_STATE_RF_OFF_88E;	/* RF off */ +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, +					      (u8 *)(&fw_current_inps)); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, +					      &ppsc->fwctrl_psmode); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val); +	} +} + +void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + +	switch (variable) { +	case HW_VAR_RCR: +		*((u32 *)(val)) = rtlpci->receive_config; +		break; +	case HW_VAR_RF_STATE: +		*((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; +		break; +	case HW_VAR_FWLPS_RF_ON: { +		enum rf_pwrstate rfstate; +		u32 val_rcr; + +		rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, +					      (u8 *)(&rfstate)); +		if (rfstate == ERFOFF) { +			*((bool *)(val)) = true; +		} else { +			val_rcr = rtl_read_dword(rtlpriv, REG_RCR); +			val_rcr &= 0x00070000; +			if (val_rcr) +				*((bool *)(val)) = false; +			else +				*((bool *)(val)) = true; +		} +		break; } +	case HW_VAR_FW_PSMODE_STATUS: +		*((bool *)(val)) = ppsc->fw_current_inpsmode; +		break; +	case HW_VAR_CORRECT_TSF: { +		u64 tsf; +		u32 *ptsf_low = (u32 *)&tsf; +		u32 *ptsf_high = ((u32 *)&tsf) + 1; + +		*ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); +		*ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + +		*((u64 *)(val)) = tsf; + +		break; } +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not process %x\n", variable); +		break; +	} +} + +void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	u8 idx; + +	switch (variable) { +	case HW_VAR_ETHER_ADDR: +		for (idx = 0; idx < ETH_ALEN; idx++) +			rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]); +		break; +	case HW_VAR_BASIC_RATE: { +		u16 rate_cfg = ((u16 *)val)[0]; +		u8 rate_index = 0; +		rate_cfg = rate_cfg & 0x15f; +		rate_cfg |= 0x01; +		rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); +		rtl_write_byte(rtlpriv, REG_RRSR + 1, (rate_cfg >> 8) & 0xff); +		while (rate_cfg > 0x1) { +			rate_cfg = (rate_cfg >> 1); +			rate_index++; +		} +		rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index); +		break; } +	case HW_VAR_BSSID: +		for (idx = 0; idx < ETH_ALEN; idx++) +			rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]); +		break; +	case HW_VAR_SIFS: +		rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); +		rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); + +		rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); +		rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + +		if (!mac->ht_enable) +			rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e); +		else +			rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, +				       *((u16 *)val)); +		break; +	case HW_VAR_SLOT_TIME: { +		u8 e_aci; + +		RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, +			 "HW_VAR_SLOT_TIME %x\n", val[0]); + +		rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + +		for (e_aci = 0; e_aci < AC_MAX; e_aci++) { +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, +						      &e_aci); +		} +		break; } +	case HW_VAR_ACK_PREAMBLE: { +		u8 reg_tmp; +		u8 short_preamble = (bool)*val; +		reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2); +		if (short_preamble) { +			reg_tmp |= 0x02; +			rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp); +		} else { +			reg_tmp &= 0xFD; +			rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp); +		} +		break; } +	case HW_VAR_WPA_CONFIG: +		rtl_write_byte(rtlpriv, REG_SECCFG, *val); +		break; +	case HW_VAR_AMPDU_MIN_SPACE: { +		u8 min_spacing_to_set; +		u8 sec_min_space; + +		min_spacing_to_set = *val; +		if (min_spacing_to_set <= 7) { +			sec_min_space = 0; + +			if (min_spacing_to_set < sec_min_space) +				min_spacing_to_set = sec_min_space; + +			mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) | +					      min_spacing_to_set); + +			*val = min_spacing_to_set; + +			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, +				 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", +				 mac->min_space_cfg); + +			rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, +				       mac->min_space_cfg); +		} +		break; } +	case HW_VAR_SHORTGI_DENSITY: { +		u8 density_to_set; + +		density_to_set = *val; +		mac->min_space_cfg |= (density_to_set << 3); + +		RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, +			 "Set HW_VAR_SHORTGI_DENSITY: %#x\n", +			 mac->min_space_cfg); + +		rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, +			       mac->min_space_cfg); +		break; } +	case HW_VAR_AMPDU_FACTOR: { +		u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; +		u8 factor_toset; +		u8 *p_regtoset = NULL; +		u8 index = 0; + +		p_regtoset = regtoset_normal; + +		factor_toset = *val; +		if (factor_toset <= 3) { +			factor_toset = (1 << (factor_toset + 2)); +			if (factor_toset > 0xf) +				factor_toset = 0xf; + +			for (index = 0; index < 4; index++) { +				if ((p_regtoset[index] & 0xf0) > +				    (factor_toset << 4)) +					p_regtoset[index] = +						(p_regtoset[index] & 0x0f) | +						(factor_toset << 4); + +				if ((p_regtoset[index] & 0x0f) > factor_toset) +					p_regtoset[index] = +						(p_regtoset[index] & 0xf0) | +						(factor_toset); + +				rtl_write_byte(rtlpriv, +					       (REG_AGGLEN_LMT + index), +					       p_regtoset[index]); +			} +			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, +				 "Set HW_VAR_AMPDU_FACTOR: %#x\n", +				 factor_toset); +		} +		break; } +	case HW_VAR_AC_PARAM: { +		u8 e_aci = *val; +		rtl8723_dm_init_edca_turbo(hw); + +		if (rtlpci->acm_method != EACMWAY2_SW) +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, +						      &e_aci); +		break; } +	case HW_VAR_ACM_CTRL: { +		u8 e_aci = *val; +		union aci_aifsn *p_aci_aifsn = +				(union aci_aifsn *)(&(mac->ac[0].aifs)); +		u8 acm = p_aci_aifsn->f.acm; +		u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + +		acm_ctrl = +		    acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + +		if (acm) { +			switch (e_aci) { +			case AC0_BE: +				acm_ctrl |= ACMHW_BEQEN; +				break; +			case AC2_VI: +				acm_ctrl |= ACMHW_VIQEN; +				break; +			case AC3_VO: +				acm_ctrl |= ACMHW_VOQEN; +				break; +			default: +				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +					 "HW_VAR_ACM_CTRL acm set " +					  "failed: eACI is %d\n", acm); +				break; +			} +		} else { +			switch (e_aci) { +			case AC0_BE: +				acm_ctrl &= (~ACMHW_BEQEN); +				break; +			case AC2_VI: +				acm_ctrl &= (~ACMHW_VIQEN); +				break; +			case AC3_VO: +				acm_ctrl &= (~ACMHW_BEQEN); +				break; +			default: +				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +					 "switch case not process\n"); +				break; +			} +		} +		RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, +			 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " +			 "Write 0x%X\n", acm_ctrl); +		rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); +		break; } +	case HW_VAR_RCR: +		rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]); +		rtlpci->receive_config = ((u32 *)(val))[0]; +		break; +	case HW_VAR_RETRY_LIMIT: { +		u8 retry_limit = *val; + +		rtl_write_word(rtlpriv, REG_RL, +			       retry_limit << RETRY_LIMIT_SHORT_SHIFT | +			       retry_limit << RETRY_LIMIT_LONG_SHIFT); +		break; } +	case HW_VAR_DUAL_TSF_RST: +		rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); +		break; +	case HW_VAR_EFUSE_BYTES: +		rtlefuse->efuse_usedbytes = *((u16 *)val); +		break; +	case HW_VAR_EFUSE_USAGE: +		rtlefuse->efuse_usedpercentage = *val; +		break; +	case HW_VAR_IO_CMD: +		rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val)); +		break; +	case HW_VAR_SET_RPWM: { +		u8 rpwm_val; + +		rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); +		udelay(1); + +		if (rpwm_val & BIT(7)) { +			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val); +		} else { +			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7)); +		} +		break; } +	case HW_VAR_H2C_FW_PWRMODE: +		rtl8723be_set_fw_pwrmode_cmd(hw, *val); +		break; +	case HW_VAR_FW_PSMODE_STATUS: +		ppsc->fw_current_inpsmode = *((bool *)val); +		break; +	case HW_VAR_RESUME_CLK_ON: +		_rtl8723be_set_fw_ps_rf_on(hw); +		break; +	case HW_VAR_FW_LPS_ACTION: { +		bool enter_fwlps = *((bool *)val); + +		if (enter_fwlps) +			_rtl8723be_fwlps_enter(hw); +		else +			_rtl8723be_fwlps_leave(hw); + +		break; } +	case HW_VAR_H2C_FW_JOINBSSRPT: { +		u8 mstatus = *val; +		u8 tmp_regcr, tmp_reg422, bcnvalid_reg; +		u8 count = 0, dlbcn_count = 0; +		bool recover = false; + +		if (mstatus == RT_MEDIA_CONNECT) { +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); + +			tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); +			rtl_write_byte(rtlpriv, REG_CR + 1, +				       (tmp_regcr | BIT(0))); + +			_rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3)); +			_rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0); + +			tmp_reg422 = rtl_read_byte(rtlpriv, +						   REG_FWHW_TXQ_CTRL + 2); +			rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, +				       tmp_reg422 & (~BIT(6))); +			if (tmp_reg422 & BIT(6)) +				recover = true; + +			do { +				bcnvalid_reg = rtl_read_byte(rtlpriv, +							     REG_TDECTRL + 2); +				rtl_write_byte(rtlpriv, REG_TDECTRL + 2, +					       (bcnvalid_reg | BIT(0))); +				_rtl8723be_return_beacon_queue_skb(hw); + +				rtl8723be_set_fw_rsvdpagepkt(hw, 0); +				bcnvalid_reg = rtl_read_byte(rtlpriv, +							     REG_TDECTRL + 2); +				count = 0; +				while (!(bcnvalid_reg & BIT(0)) && count < 20) { +					count++; +					udelay(10); +					bcnvalid_reg = rtl_read_byte(rtlpriv, +							       REG_TDECTRL + 2); +				} +				dlbcn_count++; +			} while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5); + +			if (bcnvalid_reg & BIT(0)) +				rtl_write_byte(rtlpriv, REG_TDECTRL+2, BIT(0)); + +			_rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0); +			_rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4)); + +			if (recover) { +				rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, +					       tmp_reg422); +			} +			rtl_write_byte(rtlpriv, REG_CR + 1, +				       (tmp_regcr & ~(BIT(0)))); +		} +		rtl8723be_set_fw_joinbss_report_cmd(hw, *val); +		break; } +	case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: +		rtl8723be_set_p2p_ps_offload_cmd(hw, *val); +		break; +	case HW_VAR_AID: { +		u16 u2btmp; +		u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); +		u2btmp &= 0xC000; +		rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, +			       (u2btmp | mac->assoc_id)); +		break; } +	case HW_VAR_CORRECT_TSF: { +		u8 btype_ibss = *val; + +		if (btype_ibss) +			_rtl8723be_stop_tx_beacon(hw); + +		_rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3)); + +		rtl_write_dword(rtlpriv, REG_TSFTR, +				(u32) (mac->tsf & 0xffffffff)); +		rtl_write_dword(rtlpriv, REG_TSFTR + 4, +				(u32) ((mac->tsf >> 32) & 0xffffffff)); + +		_rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0); + +		if (btype_ibss) +			_rtl8723be_resume_tx_beacon(hw); +		break; } +	case HW_VAR_KEEP_ALIVE: { +		u8 array[2]; +		array[0] = 0xff; +		array[1] = *val; +		rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL, +				       2, array); +		break; } +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not process %x\n", +			 variable); +		break; +	} +} + +static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	bool status = true; +	int count = 0; +	u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | +		    _LLT_OP(_LLT_WRITE_ACCESS); + +	rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + +	do { +		value = rtl_read_dword(rtlpriv, REG_LLT_INIT); +		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) +			break; + +		if (count > POLLING_LLT_THRESHOLD) { +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "Failed to polling write LLT done at " +				  "address %d!\n", address); +			status = false; +			break; +		} +	} while (++count); + +	return status; +} + +static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	unsigned short i; +	u8 txpktbuf_bndy; +	u8 maxpage; +	bool status; + +	maxpage = 255; +	txpktbuf_bndy = 245; + +	rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, +			(0x27FF0000 | txpktbuf_bndy)); +	rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); + +	rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); +	rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + +	rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); +	rtl_write_byte(rtlpriv, REG_PBP, 0x31); +	rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); + +	for (i = 0; i < (txpktbuf_bndy - 1); i++) { +		status = _rtl8723be_llt_write(hw, i, i + 1); +		if (!status) +			return status; +	} +	status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); + +	if (!status) +		return status; + +	for (i = txpktbuf_bndy; i < maxpage; i++) { +		status = _rtl8723be_llt_write(hw, i, (i + 1)); +		if (!status) +			return status; +	} +	status = _rtl8723be_llt_write(hw, maxpage, txpktbuf_bndy); +	if (!status) +		return status; + +	rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808); +	rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00); + +	return true; +} + +static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0); + +	if (rtlpriv->rtlhal.up_first_time) +		return; + +	if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) +		rtl8723be_sw_led_on(hw, pled0); +	else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) +		rtl8723be_sw_led_on(hw, pled0); +	else +		rtl8723be_sw_led_off(hw, pled0); +} + +static bool _rtl8723be_init_mac(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + +	unsigned char bytetmp; +	unsigned short wordtmp; +	u16 retry = 0; +	bool mac_func_enable; + +	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); + +	/*Auto Power Down to CHIP-off State*/ +	bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7)); +	rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); + +	bytetmp = rtl_read_byte(rtlpriv, REG_CR); +	if (bytetmp == 0xFF) +		mac_func_enable = true; +	else +		mac_func_enable = false; + +	/* HW Power on sequence */ +	if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, +				      PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, +				      RTL8723_NIC_ENABLE_FLOW)) { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 "init MAC Fail as power on failure\n"); +		return false; +	} +	bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4); +	rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp); + +	bytetmp = rtl_read_byte(rtlpriv, REG_CR); +	bytetmp = 0xff; +	rtl_write_byte(rtlpriv, REG_CR, bytetmp); +	mdelay(2); + +	bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL); +	bytetmp |= 0x7f; +	rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp); +	mdelay(2); + +	bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3); +	if (bytetmp & BIT(0)) { +		bytetmp = rtl_read_byte(rtlpriv, 0x7c); +		bytetmp |= BIT(6); +		rtl_write_byte(rtlpriv, 0x7c, bytetmp); +	} +	bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR); +	bytetmp |= BIT(3); +	rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp); +	bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1); +	bytetmp &= ~BIT(4); +	rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp); + +	bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+3); +	rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+3, bytetmp | 0x77); + +	rtl_write_word(rtlpriv, REG_CR, 0x2ff); + +	if (!mac_func_enable) { +		if (!_rtl8723be_llt_table_init(hw)) +			return false; +	} +	rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); +	rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff); + +	/* Enable FW Beamformer Interrupt */ +	bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3); +	rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6)); + +	wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); +	wordtmp &= 0xf; +	wordtmp |= 0xF5B1; +	rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); + +	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); +	rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); +	rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF); +	rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); + +	rtl_write_byte(rtlpriv, 0x4d0, 0x0); + +	rtl_write_dword(rtlpriv, REG_BCNQ_DESA, +			((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & +			DMA_BIT_MASK(32)); +	rtl_write_dword(rtlpriv, REG_MGQ_DESA, +			(u64) rtlpci->tx_ring[MGNT_QUEUE].dma & +			DMA_BIT_MASK(32)); +	rtl_write_dword(rtlpriv, REG_VOQ_DESA, +			(u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); +	rtl_write_dword(rtlpriv, REG_VIQ_DESA, +			(u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); +	rtl_write_dword(rtlpriv, REG_BEQ_DESA, +			(u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); +	rtl_write_dword(rtlpriv, REG_BKQ_DESA, +			(u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); +	rtl_write_dword(rtlpriv, REG_HQ_DESA, +			(u64) rtlpci->tx_ring[HIGH_QUEUE].dma & +			DMA_BIT_MASK(32)); +	rtl_write_dword(rtlpriv, REG_RX_DESA, +			(u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & +			DMA_BIT_MASK(32)); + +	bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3); +	rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77); + +	rtl_write_dword(rtlpriv, REG_INT_MIG, 0); + +	bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); +	rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); + +	rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3); + +	do { +		retry++; +		bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); +	} while ((retry < 200) && (bytetmp & BIT(7))); + +	_rtl8723be_gen_refresh_led_state(hw); + +	rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); + +	bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); +	rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & ~BIT(2)); + +	return true; +} + +static void _rtl8723be_hw_configure(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 reg_bw_opmode; +	u32 reg_ratr, reg_prsr; + +	reg_bw_opmode = BW_OPMODE_20MHZ; +	reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | +		   RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; +	reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + +	rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); +	rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); +} + +static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + +	rtl_write_byte(rtlpriv, 0x34b, 0x93); +	rtl_write_word(rtlpriv, 0x350, 0x870c); +	rtl_write_byte(rtlpriv, 0x352, 0x1); + +	if (ppsc->support_backdoor) +		rtl_write_byte(rtlpriv, 0x349, 0x1b); +	else +		rtl_write_byte(rtlpriv, 0x349, 0x03); + +	rtl_write_word(rtlpriv, 0x350, 0x2718); +	rtl_write_byte(rtlpriv, 0x352, 0x1); +} + +void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 sec_reg_value; + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +		 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", +		 rtlpriv->sec.pairwise_enc_algorithm, +		 rtlpriv->sec.group_enc_algorithm); + +	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { +		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +			 "not open hw encryption\n"); +		return; +	} +	sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; + +	if (rtlpriv->sec.use_defaultkey) { +		sec_reg_value |= SCR_TXUSEDK; +		sec_reg_value |= SCR_RXUSEDK; +	} +	sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + +	rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + +	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "The SECR-value %x\n", +		 sec_reg_value); + +	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +int rtl8723be_hw_init(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	bool rtstatus = true; +	int err; +	u8 tmp_u1b; +	unsigned long flags; + +	/* reenable interrupts to not interfere with other devices */ +	local_save_flags(flags); +	local_irq_enable(); + +	rtlpriv->rtlhal.being_init_adapter = true; +	rtlpriv->intf_ops->disable_aspm(hw); +	rtstatus = _rtl8723be_init_mac(hw); +	if (!rtstatus) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); +		err = 1; +		goto exit; +	} +	tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG); +	tmp_u1b &= 0x7F; +	rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b); + +	err = rtl8723_download_fw(hw, true); +	if (err) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +			 "Failed to download FW. Init HW without FW now..\n"); +		err = 1; +		rtlhal->fw_ready = false; +		goto exit; +	} else { +		rtlhal->fw_ready = true; +	} +	rtlhal->last_hmeboxnum = 0; +	rtl8723be_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); + +	rtl8723be_phy_bb_config(hw); +	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; +	rtl8723be_phy_rf_config(hw); + +	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, +						 RF_CHNLBW, RFREG_OFFSET_MASK); +	rtlphy->rfreg_chnlval[0] &= 0xFFF03FF; +	rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11)); + +	rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); +	rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); +	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); +	_rtl8723be_hw_configure(hw); +	rtl_cam_reset_all_entry(hw); +	rtl8723be_enable_hw_security_config(hw); + +	ppsc->rfpwr_state = ERFON; + +	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); +	_rtl8723be_enable_aspm_back_door(hw); +	rtlpriv->intf_ops->enable_aspm(hw); + +	rtl8723be_bt_hw_init(hw); + +	rtl_set_bbreg(hw, 0x64, BIT(20), 0); +	rtl_set_bbreg(hw, 0x64, BIT(24), 0); + +	rtl_set_bbreg(hw, 0x40, BIT(4), 0); +	rtl_set_bbreg(hw, 0x40, BIT(3), 1); + +	rtl_set_bbreg(hw, 0x944, BIT(0)|BIT(1), 0x3); +	rtl_set_bbreg(hw, 0x930, 0xff, 0x77); + +	rtl_set_bbreg(hw, 0x38, BIT(11), 0x1); + +	rtl_set_bbreg(hw, 0xb2c, 0xffffffff, 0x80000000); + +	if (ppsc->rfpwr_state == ERFON) { +		rtl8723be_dm_check_txpower_tracking(hw); +		rtl8723be_phy_lc_calibrate(hw); +	} +	tmp_u1b = efuse_read_1byte(hw, 0x1FA); +	if (!(tmp_u1b & BIT(0))) { +		rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); +	} +	if (!(tmp_u1b & BIT(4))) { +		tmp_u1b = rtl_read_byte(rtlpriv, 0x16); +		tmp_u1b &= 0x0F; +		rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); +		udelay(10); +		rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); +	} +	rtl8723be_dm_init(hw); +exit: +	local_irq_restore(flags); +	rtlpriv->rtlhal.being_init_adapter = false; +	return err; +} + +static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	enum version_8723e version = VERSION_UNKNOWN; +	u8 count = 0; +	u8 value8; +	u32 value32; + +	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0); + +	value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 2); +	rtl_write_byte(rtlpriv, REG_APS_FSMCO + 2, value8 | BIT(0)); + +	value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); +	rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, value8 | BIT(0)); + +	value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); +	while (((value8 & BIT(0))) && (count++ < 100)) { +		udelay(10); +		value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); +	} +	count = 0; +	value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION); +	while ((value8 == 0) && (count++ < 50)) { +		value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION); +		mdelay(1); +	} +	value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1); +	if ((value32 & (CHIP_8723B)) != CHIP_8723B) +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unkown chip version\n"); +	else +		version = (enum version_8723e) VERSION_TEST_CHIP_1T1R_8723B; + +		rtlphy->rf_type = RF_1T1R; + +	value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION); +	if (value8 >= 0x02) +		version |= BIT(3); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? +		 "RF_2T2R" : "RF_1T1R"); + +	return version; +} + +static int _rtl8723be_set_media_status(struct ieee80211_hw *hw, +				       enum nl80211_iftype type) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; +	enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + +	rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0); +	RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD, +		 "clear 0x550 when set HW_VAR_MEDIA_STATUS\n"); + +	if (type == NL80211_IFTYPE_UNSPECIFIED || +	    type == NL80211_IFTYPE_STATION) { +		_rtl8723be_stop_tx_beacon(hw); +		_rtl8723be_enable_bcn_sub_func(hw); +	} else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { +		_rtl8723be_resume_tx_beacon(hw); +		_rtl8723be_disable_bcn_sub_func(hw); +	} else { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +			 "Set HW_VAR_MEDIA_STATUS: " +			 "No such media status(%x).\n", type); +	} +	switch (type) { +	case NL80211_IFTYPE_UNSPECIFIED: +		bt_msr |= MSR_NOLINK; +		ledaction = LED_CTL_LINK; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +			 "Set Network type to NO LINK!\n"); +		break; +	case NL80211_IFTYPE_ADHOC: +		bt_msr |= MSR_ADHOC; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +			 "Set Network type to Ad Hoc!\n"); +		break; +	case NL80211_IFTYPE_STATION: +		bt_msr |= MSR_INFRA; +		ledaction = LED_CTL_LINK; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +			 "Set Network type to STA!\n"); +		break; +	case NL80211_IFTYPE_AP: +		bt_msr |= MSR_AP; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +			 "Set Network type to AP!\n"); +		break; +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "Network type %d not support!\n", type); +		return 1; +	} +	rtl_write_byte(rtlpriv, (MSR), bt_msr); +	rtlpriv->cfg->ops->led_control(hw, ledaction); +	if ((bt_msr & 0x03) == MSR_AP) +		rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); +	else +		rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); +	return 0; +} + +void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	u32 reg_rcr = rtlpci->receive_config; + +	if (rtlpriv->psc.rfpwr_state != ERFON) +		return; + +	if (check_bssid) { +		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, +					      (u8 *)(®_rcr)); +		_rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4)); +	} else if (!check_bssid) { +		reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); +		_rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0); +		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, +					      (u8 *)(®_rcr)); +	} +} + +int rtl8723be_set_network_type(struct ieee80211_hw *hw, +			       enum nl80211_iftype type) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	if (_rtl8723be_set_media_status(hw, type)) +		return -EOPNOTSUPP; + +	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { +		if (type != NL80211_IFTYPE_AP) +			rtl8723be_set_check_bssid(hw, true); +	} else { +		rtl8723be_set_check_bssid(hw, false); +	} +	return 0; +} + +/* don't set REG_EDCA_BE_PARAM here + * because mac80211 will send pkt when scan + */ +void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	rtl8723_dm_init_edca_turbo(hw); +	switch (aci) { +	case AC1_BK: +		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); +		break; +	case AC0_BE: +		break; +	case AC2_VI: +		rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); +		break; +	case AC3_VO: +		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); +		break; +	default: +		RT_ASSERT(false, "invalid aci: %d !\n", aci); +		break; +	} +} + +void rtl8723be_enable_interrupt(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + +	rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); +	rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); +	rtlpci->irq_enabled = true; +	/* there are some C2H CMDs have been sent +	 * before system interrupt is enabled, e.g., C2H, CPWM. +	 * So we need to clear all C2H events that FW has notified, +	 * otherwise FW won't schedule any commands anymore. +	 */ +	rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0); +	/*enable system interrupt*/ +	rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF); +} + +void rtl8723be_disable_interrupt(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + +	rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED); +	rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED); +	rtlpci->irq_enabled = false; +	synchronize_irq(rtlpci->pdev->irq); +} + +static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u8 u1b_tmp; + +	/* Combo (PCIe + USB) Card and PCIe-MF Card */ +	/* 1. Run LPS WL RFOFF flow */ +	rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, +				 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW); + +	/* 2. 0x1F[7:0] = 0 */ +	/* turn off RF */ +	rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); +	if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && +	    rtlhal->fw_ready) +		rtl8723be_firmware_selfreset(hw); + +	/* Reset MCU. Suggested by Filen. */ +	u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); + +	/* g.	MCUFWDL 0x80[1:0]= 0	 */ +	/* reset MCU ready status */ +	rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); + +	/* HW card disable configuration. */ +	rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, +				 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW); + +	/* Reset MCU IO Wrapper */ +	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_RSV_CTRL + 1); +	rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0)); + +	/* 7. RSV_CTRL 0x1C[7:0] = 0x0E */ +	/* lock ISO/CLK/Power control register */ +	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); +} + +void rtl8723be_card_disable(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	enum nl80211_iftype opmode; + +	mac->link_state = MAC80211_NOLINK; +	opmode = NL80211_IFTYPE_UNSPECIFIED; +	_rtl8723be_set_media_status(hw, opmode); +	if (rtlpriv->rtlhal.driver_is_goingto_unload || +	    ppsc->rfoff_reason > RF_CHANGE_BY_PS) +		rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); +	RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); +	_rtl8723be_poweroff_adapter(hw); + +	/* after power off we should do iqk again */ +	rtlpriv->phy.iqk_initialized = false; +} + +void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw, +				    u32 *p_inta, u32 *p_intb) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + +	*p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; +	rtl_write_dword(rtlpriv, ISR, *p_inta); + +	*p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & +					rtlpci->irq_mask[1]; +	rtl_write_dword(rtlpriv, REG_HISRE, *p_intb); +} + +void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	u16 bcn_interval, atim_window; + +	bcn_interval = mac->beacon_interval; +	atim_window = 2;	/*FIX MERGE */ +	rtl8723be_disable_interrupt(hw); +	rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); +	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); +	rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); +	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); +	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); +	rtl_write_byte(rtlpriv, 0x606, 0x30); +	rtl8723be_enable_interrupt(hw); +} + +void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	u16 bcn_interval = mac->beacon_interval; + +	RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, +		 "beacon_interval:%d\n", bcn_interval); +	rtl8723be_disable_interrupt(hw); +	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); +	rtl8723be_enable_interrupt(hw); +} + +void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw, +				   u32 add_msr, u32 rm_msr) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + +	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, +		 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); + +	if (add_msr) +		rtlpci->irq_mask[0] |= add_msr; +	if (rm_msr) +		rtlpci->irq_mask[0] &= (~rm_msr); +	rtl8723be_disable_interrupt(hw); +	rtl8723be_enable_interrupt(hw); +} + +static u8 _rtl8723be_get_chnl_group(u8 chnl) +{ +	u8 group; + +	if (chnl < 3) +		group = 0; +	else if (chnl < 9) +		group = 1; +	else +		group = 2; +	return group; +} + +static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw, +					struct txpower_info_2g *pw2g, +					struct txpower_info_5g *pw5g, +					bool autoload_fail, u8 *hwinfo) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0; + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "hal_ReadPowerValueFromPROM8723BE(): " +		 "PROMContent[0x%x]= 0x%x\n", +		 (addr + 1), hwinfo[addr + 1]); +	if (0xFF == hwinfo[addr + 1])  /*YJ, add, 120316*/ +		autoload_fail = true; + +	if (autoload_fail) { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 "auto load fail : Use Default value!\n"); +		for (path = 0; path < MAX_RF_PATH; path++) { +			/* 2.4G default value */ +			for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { +				pw2g->index_cck_base[path][group] = 0x2D; +				pw2g->index_bw40_base[path][group] = 0x2D; +			} +			for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) { +				if (cnt == 0) { +					pw2g->bw20_diff[path][0] = 0x02; +					pw2g->ofdm_diff[path][0] = 0x04; +				} else { +					pw2g->bw20_diff[path][cnt] = 0xFE; +					pw2g->bw40_diff[path][cnt] = 0xFE; +					pw2g->cck_diff[path][cnt] = 0xFE; +					pw2g->ofdm_diff[path][cnt] = 0xFE; +				} +			} +		} +		return; +	} +	for (path = 0; path < MAX_RF_PATH; path++) { +		/*2.4G default value*/ +		for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { +			pw2g->index_cck_base[path][group] = hwinfo[addr++]; +			if (pw2g->index_cck_base[path][group] == 0xFF) +				pw2g->index_cck_base[path][group] = 0x2D; +		} +		for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) { +			pw2g->index_bw40_base[path][group] = hwinfo[addr++]; +			if (pw2g->index_bw40_base[path][group] == 0xFF) +				pw2g->index_bw40_base[path][group] = 0x2D; +		} +		for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) { +			if (cnt == 0) { +				pw2g->bw40_diff[path][cnt] = 0; +				if (hwinfo[addr] == 0xFF) { +					pw2g->bw20_diff[path][cnt] = 0x02; +				} else { +					pw2g->bw20_diff[path][cnt] = +						(hwinfo[addr] & 0xf0) >> 4; +					/*bit sign number to 8 bit sign number*/ +					if (pw2g->bw20_diff[path][cnt] & BIT(3)) +						pw2g->bw20_diff[path][cnt] |= 0xF0; +				} +				if (hwinfo[addr] == 0xFF) { +					pw2g->ofdm_diff[path][cnt] = 0x04; +				} else { +					pw2g->ofdm_diff[path][cnt] = +							(hwinfo[addr] & 0x0f); +					/*bit sign number to 8 bit sign number*/ +					if (pw2g->ofdm_diff[path][cnt] & BIT(3)) +						pw2g->ofdm_diff[path][cnt] |= +									  0xF0; +				} +				pw2g->cck_diff[path][cnt] = 0; +				addr++; +			} else { +				if (hwinfo[addr] == 0xFF) { +					pw2g->bw40_diff[path][cnt] = 0xFE; +				} else { +					pw2g->bw40_diff[path][cnt] = +						(hwinfo[addr] & 0xf0) >> 4; +					if (pw2g->bw40_diff[path][cnt] & BIT(3)) +						pw2g->bw40_diff[path][cnt] |= +									  0xF0; +				} +				if (hwinfo[addr] == 0xFF) { +					pw2g->bw20_diff[path][cnt] = 0xFE; +				} else { +					pw2g->bw20_diff[path][cnt] = +							(hwinfo[addr] & 0x0f); +					if (pw2g->bw20_diff[path][cnt] & BIT(3)) +						pw2g->bw20_diff[path][cnt] |= +									  0xF0; +				} +				addr++; + +				if (hwinfo[addr] == 0xFF) { +					pw2g->ofdm_diff[path][cnt] = 0xFE; +				} else { +					pw2g->ofdm_diff[path][cnt] = +						(hwinfo[addr] & 0xf0) >> 4; +					if (pw2g->ofdm_diff[path][cnt] & BIT(3)) +						pw2g->ofdm_diff[path][cnt] |= +									  0xF0; +				} +				if (hwinfo[addr] == 0xFF) { +					pw2g->cck_diff[path][cnt] = 0xFE; +				} else { +					pw2g->cck_diff[path][cnt] = +							(hwinfo[addr] & 0x0f); +					if (pw2g->cck_diff[path][cnt] & BIT(3)) +						pw2g->cck_diff[path][cnt] |= +									 0xF0; +				} +				addr++; +			} +		} +		/*5G default value*/ +		for (group = 0; group < MAX_CHNL_GROUP_5G; group++) { +			pw5g->index_bw40_base[path][group] = hwinfo[addr++]; +			if (pw5g->index_bw40_base[path][group] == 0xFF) +				pw5g->index_bw40_base[path][group] = 0xFE; +		} +		for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) { +			if (cnt == 0) { +				pw5g->bw40_diff[path][cnt] = 0; + +				if (hwinfo[addr] == 0xFF) { +					pw5g->bw20_diff[path][cnt] = 0; +				} else { +					pw5g->bw20_diff[path][0] = +						(hwinfo[addr] & 0xf0) >> 4; +					if (pw5g->bw20_diff[path][cnt] & BIT(3)) +						pw5g->bw20_diff[path][cnt] |= +									  0xF0; +				} +				if (hwinfo[addr] == 0xFF) { +					pw5g->ofdm_diff[path][cnt] = 0x04; +				} else { +					pw5g->ofdm_diff[path][0] = +							(hwinfo[addr] & 0x0f); +					if (pw5g->ofdm_diff[path][cnt] & BIT(3)) +						pw5g->ofdm_diff[path][cnt] |= +									  0xF0; +				} +				addr++; +			} else { +				if (hwinfo[addr] == 0xFF) { +					pw5g->bw40_diff[path][cnt] = 0xFE; +				} else { +					pw5g->bw40_diff[path][cnt] = +						(hwinfo[addr] & 0xf0) >> 4; +					if (pw5g->bw40_diff[path][cnt] & BIT(3)) +						pw5g->bw40_diff[path][cnt] |= 0xF0; +				} +				if (hwinfo[addr] == 0xFF) { +					pw5g->bw20_diff[path][cnt] = 0xFE; +				} else { +					pw5g->bw20_diff[path][cnt] = +							(hwinfo[addr] & 0x0f); +					if (pw5g->bw20_diff[path][cnt] & BIT(3)) +						pw5g->bw20_diff[path][cnt] |= 0xF0; +				} +				addr++; +			} +		} +		if (hwinfo[addr] == 0xFF) { +			pw5g->ofdm_diff[path][1] = 0xFE; +			pw5g->ofdm_diff[path][2] = 0xFE; +		} else { +			pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4; +			pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f); +		} +		addr++; + +		if (hwinfo[addr] == 0xFF) +			pw5g->ofdm_diff[path][3] = 0xFE; +		else +			pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f); +		addr++; + +		for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) { +			if (pw5g->ofdm_diff[path][cnt] == 0xFF) +				pw5g->ofdm_diff[path][cnt] = 0xFE; +			else if (pw5g->ofdm_diff[path][cnt] & BIT(3)) +				pw5g->ofdm_diff[path][cnt] |= 0xF0; +		} +	} +} + +static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, +						   bool autoload_fail, +						   u8 *hwinfo) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	struct txpower_info_2g pw2g; +	struct txpower_info_5g pw5g; +	u8 rf_path, index; +	u8 i; + +	_rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail, +					     hwinfo); + +	for (rf_path = 0; rf_path < 2; rf_path++) { +		for (i = 0; i < 14; i++) { +			index = _rtl8723be_get_chnl_group(i+1); + +			rtlefuse->txpwrlevel_cck[rf_path][i] = +					pw2g.index_cck_base[rf_path][index]; +			rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = +					pw2g.index_bw40_base[rf_path][index]; +		} +		for (i = 0; i < MAX_TX_COUNT; i++) { +			rtlefuse->txpwr_ht20diff[rf_path][i] = +						pw2g.bw20_diff[rf_path][i]; +			rtlefuse->txpwr_ht40diff[rf_path][i] = +						pw2g.bw40_diff[rf_path][i]; +			rtlefuse->txpwr_legacyhtdiff[rf_path][i] = +						pw2g.ofdm_diff[rf_path][i]; +		} +		for (i = 0; i < 14; i++) { +			RTPRINT(rtlpriv, FINIT, INIT_EEPROM, +				"RF(%d)-Ch(%d) [CCK / HT40_1S ] = " +				"[0x%x / 0x%x ]\n", rf_path, i, +				rtlefuse->txpwrlevel_cck[rf_path][i], +				rtlefuse->txpwrlevel_ht40_1s[rf_path][i]); +		} +	} +	if (!autoload_fail) +		rtlefuse->eeprom_thermalmeter = +					hwinfo[EEPROM_THERMAL_METER_88E]; +	else +		rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + +	if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) { +		rtlefuse->apk_thermalmeterignore = true; +		rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; +	} +	rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; +	RTPRINT(rtlpriv, FINIT, INIT_EEPROM, +		"thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); + +	if (!autoload_fail) { +		rtlefuse->eeprom_regulatory = +			hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/ +		if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF) +			rtlefuse->eeprom_regulatory = 0; +	} else { +		rtlefuse->eeprom_regulatory = 0; +	} +	RTPRINT(rtlpriv, FINIT, INIT_EEPROM, +		"eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); +} + +static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw, +					 bool pseudo_test) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u16 i, usvalue; +	u8 hwinfo[HWSET_MAX_SIZE]; +	u16 eeprom_id; +	bool is_toshiba_smid1 = false; +	bool is_toshiba_smid2 = false; +	bool is_samsung_smid = false; +	bool is_lenovo_smid = false; +	u16 toshiba_smid1[] = { +		0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180, +		0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180, +		0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185, +		0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185 +	}; +	u16 toshiba_smid2[] = { +		0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181, +		0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185 +	}; +	u16 samsung_smid[] = { +		0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192, +		0x8193, 0x9191, 0x9192, 0x9193 +	}; +	u16 lenovo_smid[] = { +		0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200 +	}; + +	if (pseudo_test) { +		/* needs to be added */ +		return; +	} +	if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { +		rtl_efuse_shadow_map_update(hw); + +		memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], +		       HWSET_MAX_SIZE); +	} else if (rtlefuse->epromtype == EEPROM_93C46) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "RTL819X Not boot from eeprom, check it !!"); +	} +	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), +		      hwinfo, HWSET_MAX_SIZE); + +	eeprom_id = *((u16 *)&hwinfo[0]); +	if (eeprom_id != RTL8723BE_EEPROM_ID) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +			 "EEPROM ID(%#x) is invalid!!\n", eeprom_id); +		rtlefuse->autoload_failflag = true; +	} else { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); +		rtlefuse->autoload_failflag = false; +	} +	if (rtlefuse->autoload_failflag) +		return; + +	rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; +	rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; +	rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; +	rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "EEPROMId = 0x%4x\n", eeprom_id); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); + +	for (i = 0; i < 6; i += 2) { +		usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; +		*((u16 *)(&rtlefuse->dev_addr[i])) = usvalue; +	} +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "dev_addr: %pM\n", +		 rtlefuse->dev_addr); + +	/*parse xtal*/ +	rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE]; +	if (rtlefuse->crystalcap == 0xFF) +		rtlefuse->crystalcap = 0x20; + +	_rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, +					       hwinfo); + +	rtl8723be_read_bt_coexist_info_from_hwpg(hw, +						 rtlefuse->autoload_failflag, +						 hwinfo); + +	rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; +	rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; +	rtlefuse->txpwr_fromeprom = true; +	rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID]; + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); + +	/* set channel plan to world wide 13 */ +	rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; + +	if (rtlhal->oem_id == RT_CID_DEFAULT) { +		/* Does this one have a Toshiba SMID from group 1? */ +		for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) { +			if (rtlefuse->eeprom_smid == toshiba_smid1[i]) { +				is_toshiba_smid1 = true; +				break; +			} +		} +		/* Does this one have a Toshiba SMID from group 2? */ +		for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) { +			if (rtlefuse->eeprom_smid == toshiba_smid2[i]) { +				is_toshiba_smid2 = true; +				break; +			} +		} +		/* Does this one have a Samsung SMID? */ +		for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) { +			if (rtlefuse->eeprom_smid == samsung_smid[i]) { +				is_samsung_smid = true; +				break; +			} +		} +		/* Does this one have a Lenovo SMID? */ +		for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) { +			if (rtlefuse->eeprom_smid == lenovo_smid[i]) { +				is_lenovo_smid = true; +				break; +			} +		} +		switch (rtlefuse->eeprom_oemid) { +		case EEPROM_CID_DEFAULT: +			if (rtlefuse->eeprom_did == 0x8176) { +				if (rtlefuse->eeprom_svid == 0x10EC && +				    is_toshiba_smid1) { +					rtlhal->oem_id = RT_CID_TOSHIBA; +				} else if (rtlefuse->eeprom_svid == 0x1025) { +					rtlhal->oem_id = RT_CID_819X_ACER; +				} else if (rtlefuse->eeprom_svid == 0x10EC && +					   is_samsung_smid) { +					rtlhal->oem_id = RT_CID_819X_SAMSUNG; +				} else if (rtlefuse->eeprom_svid == 0x10EC && +					   is_lenovo_smid) { +					rtlhal->oem_id = RT_CID_819X_LENOVO; +				} else if ((rtlefuse->eeprom_svid == 0x10EC && +					    rtlefuse->eeprom_smid == 0x8197) || +					   (rtlefuse->eeprom_svid == 0x10EC && +					    rtlefuse->eeprom_smid == 0x9196)) { +					rtlhal->oem_id = RT_CID_819X_CLEVO; +				} else if ((rtlefuse->eeprom_svid == 0x1028 && +					    rtlefuse->eeprom_smid == 0x8194) || +					   (rtlefuse->eeprom_svid == 0x1028 && +					    rtlefuse->eeprom_smid == 0x8198) || +					   (rtlefuse->eeprom_svid == 0x1028 && +					    rtlefuse->eeprom_smid == 0x9197) || +					   (rtlefuse->eeprom_svid == 0x1028 && +					    rtlefuse->eeprom_smid == 0x9198)) { +					rtlhal->oem_id = RT_CID_819X_DELL; +				} else if ((rtlefuse->eeprom_svid == 0x103C && +					    rtlefuse->eeprom_smid == 0x1629)) { +					rtlhal->oem_id = RT_CID_819X_HP; +				} else if ((rtlefuse->eeprom_svid == 0x1A32 && +					   rtlefuse->eeprom_smid == 0x2315)) { +					rtlhal->oem_id = RT_CID_819X_QMI; +				} else if ((rtlefuse->eeprom_svid == 0x10EC && +					   rtlefuse->eeprom_smid == 0x8203)) { +					rtlhal->oem_id = RT_CID_819X_PRONETS; +				} else if ((rtlefuse->eeprom_svid == 0x1043 && +					   rtlefuse->eeprom_smid == 0x84B5)) { +					rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS; +				} else { +					rtlhal->oem_id = RT_CID_DEFAULT; +				} +			} else if (rtlefuse->eeprom_did == 0x8178) { +				if (rtlefuse->eeprom_svid == 0x10EC && +				    is_toshiba_smid2) +					rtlhal->oem_id = RT_CID_TOSHIBA; +				else if (rtlefuse->eeprom_svid == 0x1025) +					rtlhal->oem_id = RT_CID_819X_ACER; +				else if ((rtlefuse->eeprom_svid == 0x10EC && +					  rtlefuse->eeprom_smid == 0x8186)) +					rtlhal->oem_id = RT_CID_819X_PRONETS; +				else if ((rtlefuse->eeprom_svid == 0x1043 && +					  rtlefuse->eeprom_smid == 0x84B6)) +					rtlhal->oem_id = +							RT_CID_819X_EDIMAX_ASUS; +				else +					rtlhal->oem_id = RT_CID_DEFAULT; +			} else { +					rtlhal->oem_id = RT_CID_DEFAULT; +			} +			break; +		case EEPROM_CID_TOSHIBA: +			rtlhal->oem_id = RT_CID_TOSHIBA; +			break; +		case EEPROM_CID_CCX: +			rtlhal->oem_id = RT_CID_CCX; +			break; +		case EEPROM_CID_QMI: +			rtlhal->oem_id = RT_CID_819X_QMI; +			break; +		case EEPROM_CID_WHQL: +			break; +		default: +			rtlhal->oem_id = RT_CID_DEFAULT; +			break; +		} +	} +} + +static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + +	pcipriv->ledctl.led_opendrain = true; +	switch (rtlhal->oem_id) { +	case RT_CID_819X_HP: +		pcipriv->ledctl.led_opendrain = true; +		break; +	case RT_CID_819X_LENOVO: +	case RT_CID_DEFAULT: +	case RT_CID_TOSHIBA: +	case RT_CID_CCX: +	case RT_CID_819X_ACER: +	case RT_CID_WHQL: +	default: +		break; +	} +	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, +		 "RT Customized ID: 0x%02X\n", rtlhal->oem_id); +} + +void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u8 tmp_u1b; + +	rtlhal->version = _rtl8723be_read_chip_version(hw); +	if (get_rf_type(rtlphy) == RF_1T1R) +		rtlpriv->dm.rfpath_rxenable[0] = true; +	else +		rtlpriv->dm.rfpath_rxenable[0] = +		    rtlpriv->dm.rfpath_rxenable[1] = true; +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", +		 rtlhal->version); +	tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); +	if (tmp_u1b & BIT(4)) { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); +		rtlefuse->epromtype = EEPROM_93C46; +	} else { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); +		rtlefuse->epromtype = EEPROM_BOOT_EFUSE; +	} +	if (tmp_u1b & BIT(5)) { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); +		rtlefuse->autoload_failflag = false; +		_rtl8723be_read_adapter_info(hw, false); +	} else { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); +	} +	_rtl8723be_hal_customized_behavior(hw); +} + +static void rtl8723be_update_hal_rate_table(struct ieee80211_hw *hw, +					    struct ieee80211_sta *sta) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u32 ratr_value; +	u8 ratr_index = 0; +	u8 nmode = mac->ht_enable; +	u8 mimo_ps = IEEE80211_SMPS_OFF; +	u16 shortgi_rate; +	u32 tmp_ratr_value; +	u8 curtxbw_40mhz = mac->bw_40; +	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? +			       1 : 0; +	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? +			       1 : 0; +	enum wireless_mode wirelessmode = mac->mode; + +	if (rtlhal->current_bandtype == BAND_ON_5G) +		ratr_value = sta->supp_rates[1] << 4; +	else +		ratr_value = sta->supp_rates[0]; +	if (mac->opmode == NL80211_IFTYPE_ADHOC) +		ratr_value = 0xfff; +	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | +		       sta->ht_cap.mcs.rx_mask[0] << 12); +	switch (wirelessmode) { +	case WIRELESS_MODE_B: +		if (ratr_value & 0x0000000c) +			ratr_value &= 0x0000000d; +		else +			ratr_value &= 0x0000000f; +		break; +	case WIRELESS_MODE_G: +		ratr_value &= 0x00000FF5; +		break; +	case WIRELESS_MODE_N_24G: +	case WIRELESS_MODE_N_5G: +		nmode = 1; +		if (mimo_ps == IEEE80211_SMPS_STATIC) { +			ratr_value &= 0x0007F005; +		} else { +			u32 ratr_mask; + +			if (get_rf_type(rtlphy) == RF_1T2R || +			    get_rf_type(rtlphy) == RF_1T1R) +				ratr_mask = 0x000ff005; +			else +				ratr_mask = 0x0f0ff005; +			ratr_value &= ratr_mask; +		} +		break; +	default: +		if (rtlphy->rf_type == RF_1T2R) +			ratr_value &= 0x000ff0ff; +		else +			ratr_value &= 0x0f0ff0ff; +		break; +	} +	if ((rtlpriv->btcoexist.bt_coexistence) && +	    (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) && +	    (rtlpriv->btcoexist.bt_cur_state) && +	    (rtlpriv->btcoexist.bt_ant_isolation) && +	    ((rtlpriv->btcoexist.bt_service == BT_SCO) || +	     (rtlpriv->btcoexist.bt_service == BT_BUSY))) +		ratr_value &= 0x0fffcfc0; +	else +		ratr_value &= 0x0FFFFFFF; + +	if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || +		      (!curtxbw_40mhz && curshortgi_20mhz))) { +		ratr_value |= 0x10000000; +		tmp_ratr_value = (ratr_value >> 12); + +		for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { +			if ((1 << shortgi_rate) & tmp_ratr_value) +				break; +		} +		shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | +			       (shortgi_rate << 4) | (shortgi_rate); +	} +	rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + +	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, +		 "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); +} + +static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, +					  u8 rate_index) +{ +	u8 ret = 0; + +	switch (rate_index) { +	case RATR_INX_WIRELESS_NGB: +		ret = 1; +		break; +	case RATR_INX_WIRELESS_N: +	case RATR_INX_WIRELESS_NG: +		ret = 5; +		break; +	case RATR_INX_WIRELESS_NB: +		ret = 3; +		break; +	case RATR_INX_WIRELESS_GB: +		ret = 6; +		break; +	case RATR_INX_WIRELESS_G: +		ret = 7; +		break; +	case RATR_INX_WIRELESS_B: +		ret = 8; +		break; +	default: +		ret = 0; +		break; +	} +	return ret; +} + +static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw, +					   struct ieee80211_sta *sta, +					   u8 rssi_level) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	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) ? +			       1 : 0; +	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? +			       1 : 0; +	enum wireless_mode wirelessmode = 0; +	bool shortgi = false; +	u8 rate_mask[7]; +	u8 macid = 0; +	u8 mimo_ps = IEEE80211_SMPS_OFF; + +	sta_entry = (struct rtl_sta_info *)sta->drv_priv; +	wirelessmode = sta_entry->wireless_mode; +	if (mac->opmode == NL80211_IFTYPE_STATION || +	    mac->opmode == NL80211_IFTYPE_MESH_POINT) +		curtxbw_40mhz = mac->bw_40; +	else if (mac->opmode == NL80211_IFTYPE_AP || +		 mac->opmode == NL80211_IFTYPE_ADHOC) +		macid = sta->aid + 1; + +	ratr_bitmap = sta->supp_rates[0]; + +	if (mac->opmode == NL80211_IFTYPE_ADHOC) +		ratr_bitmap = 0xfff; + +	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | +			sta->ht_cap.mcs.rx_mask[0] << 12); +	switch (wirelessmode) { +	case WIRELESS_MODE_B: +		ratr_index = RATR_INX_WIRELESS_B; +		if (ratr_bitmap & 0x0000000c) +			ratr_bitmap &= 0x0000000d; +		else +			ratr_bitmap &= 0x0000000f; +		break; +	case WIRELESS_MODE_G: +		ratr_index = RATR_INX_WIRELESS_GB; + +		if (rssi_level == 1) +			ratr_bitmap &= 0x00000f00; +		else if (rssi_level == 2) +			ratr_bitmap &= 0x00000ff0; +		else +			ratr_bitmap &= 0x00000ff5; +		break; +	case WIRELESS_MODE_A: +		ratr_index = RATR_INX_WIRELESS_A; +		ratr_bitmap &= 0x00000ff0; +		break; +	case WIRELESS_MODE_N_24G: +	case WIRELESS_MODE_N_5G: +		ratr_index = RATR_INX_WIRELESS_NGB; + +		if (mimo_ps == IEEE80211_SMPS_STATIC  || +		    mimo_ps == IEEE80211_SMPS_DYNAMIC) { +			if (rssi_level == 1) +				ratr_bitmap &= 0x00070000; +			else if (rssi_level == 2) +				ratr_bitmap &= 0x0007f000; +			else +				ratr_bitmap &= 0x0007f005; +		} else { +			if (rtlphy->rf_type == RF_1T1R) { +				if (curtxbw_40mhz) { +					if (rssi_level == 1) +						ratr_bitmap &= 0x000f0000; +					else if (rssi_level == 2) +						ratr_bitmap &= 0x000ff000; +					else +						ratr_bitmap &= 0x000ff015; +				} else { +					if (rssi_level == 1) +						ratr_bitmap &= 0x000f0000; +					else if (rssi_level == 2) +						ratr_bitmap &= 0x000ff000; +					else +						ratr_bitmap &= 0x000ff005; +				} +			} else { +				if (curtxbw_40mhz) { +					if (rssi_level == 1) +						ratr_bitmap &= 0x0f8f0000; +					else if (rssi_level == 2) +						ratr_bitmap &= 0x0f8ff000; +					else +						ratr_bitmap &= 0x0f8ff015; +				} else { +					if (rssi_level == 1) +						ratr_bitmap &= 0x0f8f0000; +					else if (rssi_level == 2) +						ratr_bitmap &= 0x0f8ff000; +					else +						ratr_bitmap &= 0x0f8ff005; +				} +			} +		} +		if ((curtxbw_40mhz && curshortgi_40mhz) || +		    (!curtxbw_40mhz && curshortgi_20mhz)) { +			if (macid == 0) +				shortgi = true; +			else if (macid == 1) +				shortgi = false; +		} +		break; +	default: +		ratr_index = RATR_INX_WIRELESS_NGB; + +		if (rtlphy->rf_type == RF_1T2R) +			ratr_bitmap &= 0x000ff0ff; +		else +			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[0] = macid; +	rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) | +						       (shortgi ? 0x80 : 0x00); +	rate_mask[2] = curtxbw_40mhz; +	/* if (prox_priv->proxim_modeinfo->power_output > 0) +	 *	rate_mask[2] |= BIT(6); +	 */ + +	rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff); +	rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8); +	rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16); +	rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24); + +	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, +		 "Rate_index:%x, ratr_val:%x, %x:%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_mask[5], +		 rate_mask[6]); +	rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_RA_MASK, 7, rate_mask); +	_rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0); +} + +void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw, +				   struct ieee80211_sta *sta, +				   u8 rssi_level) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	if (rtlpriv->dm.useramask) +		rtl8723be_update_hal_rate_mask(hw, sta, rssi_level); +	else +		rtl8723be_update_hal_rate_table(hw, sta); +} + +void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	u16 sifs_timer; + +	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time); +	if (!mac->ht_enable) +		sifs_timer = 0x0a0a; +	else +		sifs_timer = 0x0e0e; +	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; +	u8 u1tmp; +	bool actuallyset = false; + +	if (rtlpriv->rtlhal.being_init_adapter) +		return false; + +	if (ppsc->swrf_processing) +		return false; + +	spin_lock(&rtlpriv->locks.rf_ps_lock); +	if (ppsc->rfchange_inprogress) { +		spin_unlock(&rtlpriv->locks.rf_ps_lock); +		return false; +	} else { +		ppsc->rfchange_inprogress = true; +		spin_unlock(&rtlpriv->locks.rf_ps_lock); +	} +	cur_rfstate = ppsc->rfpwr_state; + +	rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2, +		       rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1))); + +	u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2); + +	if (rtlphy->polarity_ctl) +		e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON; +	else +		e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF; + +	if (ppsc->hwradiooff && +	    (e_rfpowerstate_toset == ERFON)) { +		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, +			 "GPIOChangeRF  - HW Radio ON, RF ON\n"); + +		e_rfpowerstate_toset = ERFON; +		ppsc->hwradiooff = false; +		actuallyset = true; +	} else if (!ppsc->hwradiooff && +		   (e_rfpowerstate_toset == ERFOFF)) { +		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, +			 "GPIOChangeRF  - HW Radio OFF, RF OFF\n"); + +		e_rfpowerstate_toset = ERFOFF; +		ppsc->hwradiooff = true; +		actuallyset = true; +	} +	if (actuallyset) { +		spin_lock(&rtlpriv->locks.rf_ps_lock); +		ppsc->rfchange_inprogress = false; +		spin_unlock(&rtlpriv->locks.rf_ps_lock); +	} else { +		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) +			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + +		spin_lock(&rtlpriv->locks.rf_ps_lock); +		ppsc->rfchange_inprogress = false; +		spin_unlock(&rtlpriv->locks.rf_ps_lock); +	} +	*valid = 1; +	return !ppsc->hwradiooff; +} + +void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index, +		       u8 *p_macaddr, bool is_group, u8 enc_algo, +		       bool is_wepkey, bool clear_all) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	u8 *macaddr = p_macaddr; +	u32 entry_id = 0; +	bool is_pairwise = false; + +	static u8 cam_const_addr[4][6] = { +		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +		{0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, +		{0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, +		{0x00, 0x00, 0x00, 0x00, 0x00, 0x03} +	}; +	static u8 cam_const_broad[] = { +		0xff, 0xff, 0xff, 0xff, 0xff, 0xff +	}; + +	if (clear_all) { +		u8 idx = 0; +		u8 cam_offset = 0; +		u8 clear_number = 5; + +		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + +		for (idx = 0; idx < clear_number; idx++) { +			rtl_cam_mark_invalid(hw, cam_offset + idx); +			rtl_cam_empty_entry(hw, cam_offset + idx); + +			if (idx < 5) { +				memset(rtlpriv->sec.key_buf[idx], 0, +				       MAX_KEY_LEN); +				rtlpriv->sec.key_len[idx] = 0; +			} +		} +	} else { +		switch (enc_algo) { +		case WEP40_ENCRYPTION: +			enc_algo = CAM_WEP40; +			break; +		case WEP104_ENCRYPTION: +			enc_algo = CAM_WEP104; +			break; +		case TKIP_ENCRYPTION: +			enc_algo = CAM_TKIP; +			break; +		case AESCCMP_ENCRYPTION: +			enc_algo = CAM_AES; +			break; +		default: +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "switch case not process\n"); +			enc_algo = CAM_TKIP; +			break; +		} + +		if (is_wepkey || rtlpriv->sec.use_defaultkey) { +			macaddr = cam_const_addr[key_index]; +			entry_id = key_index; +		} else { +			if (is_group) { +				macaddr = cam_const_broad; +				entry_id = key_index; +			} else { +				if (mac->opmode == NL80211_IFTYPE_AP) { +					entry_id = rtl_cam_get_free_entry(hw, +								p_macaddr); +					if (entry_id >=  TOTAL_CAM_ENTRY) { +						RT_TRACE(rtlpriv, COMP_SEC, +							 DBG_EMERG, +							 "Can not find free" +							 " hw security cam " +							 "entry\n"); +						return; +					} +				} else { +					entry_id = CAM_PAIRWISE_KEY_POSITION; +				} +				key_index = PAIRWISE_KEYIDX; +				is_pairwise = true; +			} +		} +		if (rtlpriv->sec.key_len[key_index] == 0) { +			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +				 "delete one entry, entry_id is %d\n", +				 entry_id); +			if (mac->opmode == NL80211_IFTYPE_AP) +				rtl_cam_del_entry(hw, p_macaddr); +			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); +		} else { +			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +				 "add one entry\n"); +			if (is_pairwise) { +				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +					 "set Pairwise key\n"); + +				rtl_cam_add_one_entry(hw, macaddr, key_index, +						      entry_id, enc_algo, +						      CAM_CONFIG_NO_USEDK, +						      rtlpriv->sec.key_buf[key_index]); +			} else { +				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, +					 "set group key\n"); + +				if (mac->opmode == NL80211_IFTYPE_ADHOC) { +					rtl_cam_add_one_entry(hw, +						rtlefuse->dev_addr, +						PAIRWISE_KEYIDX, +						CAM_PAIRWISE_KEY_POSITION, +						enc_algo, +						CAM_CONFIG_NO_USEDK, +						rtlpriv->sec.key_buf +						[entry_id]); +				} +				rtl_cam_add_one_entry(hw, macaddr, key_index, +						      entry_id, enc_algo, +						      CAM_CONFIG_NO_USEDK, +						      rtlpriv->sec.key_buf[entry_id]); +			} +		} +	} +} + +void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, +					      bool auto_load_fail, u8 *hwinfo) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 value; +	u32 tmpu_32; + +	if (!auto_load_fail) { +		tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); +		if (tmpu_32 & BIT(18)) +			rtlpriv->btcoexist.btc_info.btcoexist = 1; +		else +			rtlpriv->btcoexist.btc_info.btcoexist = 0; +		value = hwinfo[RF_OPTION4]; +		rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; +		rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1); +	} else { +		rtlpriv->btcoexist.btc_info.btcoexist = 0; +		rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B; +		rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; +	} +} + +void rtl8723be_bt_reg_init(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	/* 0:Low, 1:High, 2:From Efuse. */ +	rtlpriv->btcoexist.reg_bt_iso = 2; +	/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ +	rtlpriv->btcoexist.reg_bt_sco = 3; +	/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ +	rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl8723be_bt_hw_init(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	if (rtlpriv->cfg->ops->get_btc_status()) +		rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv); +} + +void rtl8723be_suspend(struct ieee80211_hw *hw) +{ +} + +void rtl8723be_resume(struct ieee80211_hw *hw) +{ +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.h b/drivers/net/wireless/rtlwifi/rtl8723be/hw.h new file mode 100644 index 00000000000..64c7551af6b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_HW_H__ +#define __RTL8723BE_HW_H__ + +void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw); + +void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw, +				    u32 *p_inta, u32 *p_intb); +int rtl8723be_hw_init(struct ieee80211_hw *hw); +void rtl8723be_card_disable(struct ieee80211_hw *hw); +void rtl8723be_enable_interrupt(struct ieee80211_hw *hw); +void rtl8723be_disable_interrupt(struct ieee80211_hw *hw); +int rtl8723be_set_network_type(struct ieee80211_hw *hw, +			       enum nl80211_iftype type); +void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci); +void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw); +void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw, +				     u32 add_msr, u32 rm_msr); +void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw, +				   struct ieee80211_sta *sta, +				   u8 rssi_level); +void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index, +		       u8 *p_macaddr, bool is_group, u8 enc_algo, +		       bool is_wepkey, bool clear_all); +void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, +					      bool autoload_fail, u8 *hwinfo); +void rtl8723be_bt_reg_init(struct ieee80211_hw *hw); +void rtl8723be_bt_hw_init(struct ieee80211_hw *hw); +void rtl8723be_suspend(struct ieee80211_hw *hw); +void rtl8723be_resume(struct ieee80211_hw *hw); +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/led.c b/drivers/net/wireless/rtlwifi/rtl8723be/led.c new file mode 100644 index 00000000000..cb931a38dc4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/led.c @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * 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 "reg.h" +#include "led.h" + +static void _rtl8723be_init_led(struct ieee80211_hw *hw,  struct rtl_led *pled, +				enum rtl_led_pin ledpin) +{ +	pled->hw = hw; +	pled->ledpin = ledpin; +	pled->ledon = false; +} + +void rtl8723be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) +{ +	u8 ledcfg; +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, +		 "LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin); + +	switch (pled->ledpin) { +	case LED_PIN_GPIO0: +		break; +	case LED_PIN_LED0: +		ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); +		ledcfg &= ~BIT(6); +		rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5)); +		break; +	case LED_PIN_LED1: +		ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); +		rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10); +		break; +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not process\n"); +		break; +	} +	pled->ledon = true; +} + +void rtl8723be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	u8 ledcfg; + +	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, +		 "LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin); + +	ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + +	switch (pled->ledpin) { +	case LED_PIN_GPIO0: +		break; +	case LED_PIN_LED0: +		ledcfg &= 0xf0; +		if (pcipriv->ledctl.led_opendrain) { +			ledcfg &= 0x90; /* Set to software control. */ +			rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3))); +			ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG); +			ledcfg &= 0xFE; +			rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg); +		} else { +			ledcfg &= ~BIT(6); +			rtl_write_byte(rtlpriv, REG_LEDCFG2, +				       (ledcfg | BIT(3) | BIT(5))); +		} +		break; +	case LED_PIN_LED1: +		ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1); +		ledcfg &= 0x10; /* Set to software control. */ +		rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3)); + +		break; +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not processed\n"); +		break; +	} +	pled->ledon = false; +} + +void rtl8723be_init_sw_leds(struct ieee80211_hw *hw) +{ +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	_rtl8723be_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); +	_rtl8723be_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); +} + +static void _rtl8723be_sw_led_control(struct ieee80211_hw *hw, +				      enum led_ctl_mode ledaction) +{ +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0); +	switch (ledaction) { +	case LED_CTL_POWER_ON: +	case LED_CTL_LINK: +	case LED_CTL_NO_LINK: +		rtl8723be_sw_led_on(hw, pled0); +		break; +	case LED_CTL_POWER_OFF: +		rtl8723be_sw_led_off(hw, pled0); +		break; +	default: +		break; +	} +} + +void rtl8723be_led_control(struct ieee80211_hw *hw, +			   enum led_ctl_mode ledaction) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + +	if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && +	    (ledaction == LED_CTL_TX || +	     ledaction == LED_CTL_RX || +	     ledaction == LED_CTL_SITE_SURVEY || +	     ledaction == LED_CTL_LINK || +	     ledaction == LED_CTL_NO_LINK || +	     ledaction == LED_CTL_START_TO_LINK || +	     ledaction == LED_CTL_POWER_ON)) { +		return; +	} +	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); +	_rtl8723be_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/led.h b/drivers/net/wireless/rtlwifi/rtl8723be/led.h new file mode 100644 index 00000000000..c57de379ee8 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/led.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_LED_H__ +#define __RTL8723BE_LED_H__ + +void rtl8723be_init_sw_leds(struct ieee80211_hw *hw); +void rtl8723be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl8723be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl8723be_led_control(struct ieee80211_hw *hw, +			   enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c new file mode 100644 index 00000000000..1575ef9ece9 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c @@ -0,0 +1,2156 @@ +/****************************************************************************** + * + * 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 "../ps.h" +#include "../core.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8723com/phy_common.h" +#include "rf.h" +#include "dm.h" +#include "table.h" +#include "trx.h" + +static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw); +static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, +						       u8 configtype); +static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, +					      u8 channel, u8 *stage, +					      u8 *step, u32 *delay); +static bool _rtl8723be_check_condition(struct ieee80211_hw *hw, +				       const u32  condition) +{ +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	u32 _board = rtlefuse->board_type; /*need efuse define*/ +	u32 _interface = rtlhal->interface; +	u32 _platform = 0x08;/*SupportPlatform */ +	u32 cond = condition; + +	if (condition == 0xCDCDCDCD) +		return true; + +	cond = condition & 0xFF; +	if ((_board & cond) == 0 && cond != 0x1F) +		return false; + +	cond = condition & 0xFF00; +	cond = cond >> 8; +	if ((_interface & cond) == 0 && cond != 0x07) +		return false; + +	cond = condition & 0xFF0000; +	cond = cond >> 16; +	if ((_platform & cond) == 0 && cond != 0x0F) +		return false; +	return true; +} + +static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 i; +	u32 arraylength; +	u32 *ptrarray; + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n"); +	arraylength = RTL8723BEMAC_1T_ARRAYLEN; +	ptrarray = RTL8723BEMAC_1T_ARRAY; +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength); +	for (i = 0; i < arraylength; i = i + 2) +		rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); +	return true; +} + +static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, +						     u8 configtype) +{ +	#define READ_NEXT_PAIR(v1, v2, i) \ +		do { \ +			i += 2; \ +			v1 = array_table[i];\ +			v2 = array_table[i+1]; \ +		} while (0) + +	int i; +	u32 *array_table; +	u16 arraylen; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 v1 = 0, v2 = 0; + +	if (configtype == BASEBAND_CONFIG_PHY_REG) { +		arraylen = RTL8723BEPHY_REG_1TARRAYLEN; +		array_table = RTL8723BEPHY_REG_1TARRAY; + +		for (i = 0; i < arraylen; i = i + 2) { +			v1 = array_table[i]; +			v2 = array_table[i+1]; +			if (v1 < 0xcdcdcdcd) { +				rtl_bb_delay(hw, v1, v2); +			} else {/*This line is the start line of branch.*/ +				if (!_rtl8723be_check_condition(hw, array_table[i])) { +					/*Discard the following (offset, data) pairs*/ +					READ_NEXT_PAIR(v1, v2, i); +					while (v2 != 0xDEAD && +					       v2 != 0xCDEF && +					       v2 != 0xCDCD && +					       i < arraylen - 2) { +						READ_NEXT_PAIR(v1, v2, i); +					} +					i -= 2; /* prevent from for-loop += 2*/ +				/* Configure matched pairs and +				 * skip to end of if-else. +				 */ +				} else { +					READ_NEXT_PAIR(v1, v2, i); +					while (v2 != 0xDEAD && +					       v2 != 0xCDEF && +					       v2 != 0xCDCD && +					       i < arraylen - 2) { +						rtl_bb_delay(hw, +								    v1, v2); +						READ_NEXT_PAIR(v1, v2, i); +					} + +					while (v2 != 0xDEAD && i < arraylen - 2) +						READ_NEXT_PAIR(v1, v2, i); +				} +			} +		} +	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) { +		arraylen = RTL8723BEAGCTAB_1TARRAYLEN; +		array_table = RTL8723BEAGCTAB_1TARRAY; + +		for (i = 0; i < arraylen; i = i + 2) { +			v1 = array_table[i]; +			v2 = array_table[i+1]; +			if (v1 < 0xCDCDCDCD) { +				rtl_set_bbreg(hw, array_table[i], +					      MASKDWORD, +					      array_table[i + 1]); +				udelay(1); +				continue; +			} else {/*This line is the start line of branch.*/ +				if (!_rtl8723be_check_condition(hw, array_table[i])) { +					/* Discard the following +					 * (offset, data) pairs +					 */ +					READ_NEXT_PAIR(v1, v2, i); +					while (v2 != 0xDEAD && +					       v2 != 0xCDEF && +					       v2 != 0xCDCD && +					       i < arraylen - 2) { +						READ_NEXT_PAIR(v1, v2, i); +					} +					i -= 2; /* prevent from for-loop += 2*/ +				/*Configure matched pairs and +				 *skip to end of if-else. +				 */ +				} else { +					READ_NEXT_PAIR(v1, v2, i); +					while (v2 != 0xDEAD && +					       v2 != 0xCDEF && +					       v2 != 0xCDCD && +					       i < arraylen - 2) { +						rtl_set_bbreg(hw, array_table[i], +							      MASKDWORD, +							      array_table[i + 1]); +						udelay(1); +						READ_NEXT_PAIR(v1, v2, i); +					} + +					while (v2 != 0xDEAD && i < arraylen - 2) +						READ_NEXT_PAIR(v1, v2, i); +				} +			} +			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +				 "The agctab_array_table[0] is " +				  "%x Rtl818EEPHY_REGArray[1] is %x\n", +				  array_table[i], array_table[i + 1]); +		} +	} +	return true; +} + +static u8 _rtl8723be_get_rate_section_index(u32 regaddr) +{ +	u8 index = 0; + +	switch (regaddr) { +	case RTXAGC_A_RATE18_06: +	case RTXAGC_B_RATE18_06: +		index = 0; +		break; +	case RTXAGC_A_RATE54_24: +	case RTXAGC_B_RATE54_24: +		index = 1; +		break; +	case RTXAGC_A_CCK1_MCS32: +	case RTXAGC_B_CCK1_55_MCS32: +		index = 2; +		break; +	case RTXAGC_B_CCK11_A_CCK2_11: +		index = 3; +		break; +	case RTXAGC_A_MCS03_MCS00: +	case RTXAGC_B_MCS03_MCS00: +		index = 4; +		break; +	case RTXAGC_A_MCS07_MCS04: +	case RTXAGC_B_MCS07_MCS04: +		index = 5; +		break; +	case RTXAGC_A_MCS11_MCS08: +	case RTXAGC_B_MCS11_MCS08: +		index = 6; +		break; +	case RTXAGC_A_MCS15_MCS12: +	case RTXAGC_B_MCS15_MCS12: +		index = 7; +		break; +	default: +		regaddr &= 0xFFF; +		if (regaddr >= 0xC20 && regaddr <= 0xC4C) +			index = (u8) ((regaddr - 0xC20) / 4); +		else if (regaddr >= 0xE20 && regaddr <= 0xE4C) +			index = (u8) ((regaddr - 0xE20) / 4); +		break; +	}; +	return index; +} + +u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, +			       u32 regaddr, u32 bitmask) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 original_value, readback_value, bitshift; +	unsigned long flags; + +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", +		  regaddr, rfpath, bitmask); + +	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + +	original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr); +	bitshift = rtl8723_phy_calculate_bit_shift(bitmask); +	readback_value = (original_value & bitmask) >> bitshift; + +	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "regaddr(%#x), rfpath(%#x), " +		  "bitmask(%#x), original_value(%#x)\n", +		  regaddr, rfpath, bitmask, original_value); + +	return readback_value; +} + +void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path, +			      u32 regaddr, u32 bitmask, u32 data) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u32 original_value, bitshift; +	unsigned long flags; + +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", +		  regaddr, bitmask, data, path); + +	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + +	if (bitmask != RFREG_OFFSET_MASK) { +			original_value = rtl8723_phy_rf_serial_read(hw, path, +								    regaddr); +			bitshift = rtl8723_phy_calculate_bit_shift(bitmask); +			data = ((original_value & (~bitmask)) | +				(data << bitshift)); +		} + +	rtl8723_phy_rf_serial_write(hw, path, regaddr, data); + +	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + +	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, +		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", +		  regaddr, bitmask, data, path); +} + +bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw); + +	rtl_write_byte(rtlpriv, 0x04CA, 0x0B); +	return rtstatus; +} + +bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw) +{ +	bool rtstatus = true; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u16 regval; +	u8 reg_hwparafile = 1; +	u32 tmp; +	u8 crystalcap = rtlpriv->efuse.crystalcap; +	rtl8723_phy_init_bb_rf_reg_def(hw); +	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); +	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, +		       regval | BIT(13) | BIT(0) | BIT(1)); + +	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, +		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | +		       FEN_BB_GLB_RSTN | FEN_BBRSTB); +	tmp = rtl_read_dword(rtlpriv, 0x4c); +	rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23)); + +	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + +	if (reg_hwparafile == 1) +		rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw); + +	crystalcap = crystalcap & 0x3F; +	rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, +		      (crystalcap | crystalcap << 6)); + +	return rtstatus; +} + +bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw) +{ +	return rtl8723be_phy_rf6052_config(hw); +} + +static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr, +				     u32 data, enum radio_path rfpath, +				     u32 regaddr) +{ +	if (addr == 0xfe || addr == 0xffe) { +		mdelay(50); +	} else { +		rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data); +		udelay(1); +	} +} + +static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw, +					 u32 addr, u32 data) +{ +	u32 content = 0x1000; /*RF Content: radio_a_txt*/ +	u32 maskforphyset = (u32)(content & 0xE000); + +	_rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A, +				 addr | maskforphyset); +} + +static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); + +	u8 band, path, txnum, section; + +	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) +		for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path) +			for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) +				for (section = 0; +				     section < TX_PWR_BY_RATE_NUM_SECTION; +				     ++section) +					rtlphy->tx_power_by_rate_offset[band] +						[path][txnum][section] = 0; +} + +static void phy_set_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, +				       u8 path, u8 rate_section, +				       u8 txnum, u8 value) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); + +	if (path > RF90_PATH_D) { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", +			  path); +		return; +	} + +	if (band == BAND_ON_2_4G) { +		switch (rate_section) { +		case CCK: +			rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value; +			break; +		case OFDM: +			rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value; +			break; +		case HT_MCS0_MCS7: +			rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value; +			break; +		case HT_MCS8_MCS15: +			rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value; +			break; +		default: +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				 "Invalid RateSection %d in Band 2.4G, Rf Path" +				  " %d, %dTx in PHY_SetTxPowerByRateBase()\n", +				  rate_section, path, txnum); +			break; +		}; +	} else { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", +			  band); +	} +} + +static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path, +				     u8 txnum, u8 rate_section) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u8 value = 0; +	if (path > RF90_PATH_D) { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n", +			  path); +		return 0; +	} + +	if (band == BAND_ON_2_4G) { +		switch (rate_section) { +		case CCK: +			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0]; +			break; +		case OFDM: +			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1]; +			break; +		case HT_MCS0_MCS7: +			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2]; +			break; +		case HT_MCS8_MCS15: +			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3]; +			break; +		default: +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				 "Invalid RateSection %d in Band 2.4G, Rf Path" +				  " %d, %dTx in PHY_GetTxPowerByRateBase()\n", +				  rate_section, path, txnum); +			break; +		}; +	} else { +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", +			  band); +	} + +	return value; +} + +static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u16 raw_value = 0; +	u8 base = 0, path = 0; + +	for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { +		if (path == RF90_PATH_A) { +			raw_value = (u16) (rtlphy->tx_power_by_rate_offset +				[BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF; +			base = (raw_value >> 4) * 10 + (raw_value & 0xF); +			phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, CCK, +						   RF_1TX, base); +		} else if (path == RF90_PATH_B) { +			raw_value = (u16) (rtlphy->tx_power_by_rate_offset +				[BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF; +			base = (raw_value >> 4) * 10 + (raw_value & 0xF); +			phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, +						   CCK, RF_1TX, base); +		} +		raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +					  [path][RF_1TX][1] >> 24) & 0xFF; +		base = (raw_value >> 4) * 10 + (raw_value & 0xF); +		phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, +					   base); + +		raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +					  [path][RF_1TX][5] >> 24) & 0xFF; +		base = (raw_value >> 4) * 10 + (raw_value & 0xF); +		phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, +					   RF_1TX, base); + +		raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +					  [path][RF_2TX][7] >> 24) & 0xFF; +		base = (raw_value >> 4) * 10 + (raw_value & 0xF); +		phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, +					   HT_MCS8_MCS15, RF_2TX, base); +	} +} + +static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val) +{ +	char i = 0; +	u8 temp_value = 0; +	u32 temp_data = 0; + +	for (i = 3; i >= 0; --i) { +		if (i >= start && i <= end) { +			/* Get the exact value */ +			temp_value = (u8) (*data >> (i * 8)) & 0xF; +			temp_value += ((u8) ((*data >> (i*8 + 4)) & 0xF)) * 10; + +			/* Change the value to a relative value */ +			temp_value = (temp_value > base_val) ? +				     temp_value - base_val : +				     base_val - temp_value; +		} else { +			temp_value = (u8) (*data >> (i * 8)) & 0xFF; +		} +		temp_data <<= 8; +		temp_data |= temp_value; +	} +	*data = temp_data; +} + +static void conv_dbm_to_rel(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u8 base = 0, rfpath = RF90_PATH_A; + +	base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath, +					  RF_1TX, CCK); +	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +			    [rfpath][RF_1TX][2]), 1, 1, base); +	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +			    [rfpath][RF_1TX][3]), 1, 3, base); + +	base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath, +					  RF_1TX, OFDM); +	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +			    [rfpath][RF_1TX][0]), 0, 3, base); +	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +			    [rfpath][RF_1TX][1]), 0, 3, base); + +	base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath, +					  RF_1TX, HT_MCS0_MCS7); +	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +			    [rfpath][RF_1TX][4]), 0, 3, base); +	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +			    [rfpath][RF_1TX][5]), 0, 3, base); + +	base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath, +					  RF_2TX, HT_MCS8_MCS15); +	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +			    [rfpath][RF_2TX][6]), 0, 3, base); + +	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] +			    [rfpath][RF_2TX][7]), 0, 3, base); + +	RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, +		 "<=== conv_dbm_to_rel()\n"); +} + +static void _rtl8723be_phy_txpower_by_rate_configuration( +							struct ieee80211_hw *hw) +{ +	_rtl8723be_phy_store_txpower_by_rate_base(hw); +	conv_dbm_to_rel(hw); +} + +static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	bool rtstatus; + +	rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw, +						BASEBAND_CONFIG_PHY_REG); +	if (!rtstatus) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!"); +		return false; +	} +	_rtl8723be_phy_init_tx_power_by_rate(hw); +	if (!rtlefuse->autoload_failflag) { +		rtlphy->pwrgroup_cnt = 0; +		rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw, +						BASEBAND_CONFIG_PHY_REG); +	} +	_rtl8723be_phy_txpower_by_rate_configuration(hw); +	if (!rtstatus) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!"); +		return false; +	} +	rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw, +						BASEBAND_CONFIG_AGC_TAB); +	if (!rtstatus) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); +		return false; +	} +	rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, +						       RFPGA0_XA_HSSIPARAMETER2, +						       0x200)); +	return true; +} + +static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw, +					      u32 band, u32 rfpath, +					      u32 txnum, u32 regaddr, +					      u32 bitmask, u32 data) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u8 rate_section = _rtl8723be_get_rate_section_index(regaddr); + +	if (band != BAND_ON_2_4G && band != BAND_ON_5G) { +		RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR, +			 "Invalid Band %d\n", band); +		return; +	} + +	if (rfpath > TX_PWR_BY_RATE_NUM_RF) { +		RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR, +			 "Invalid RfPath %d\n", rfpath); +		return; +	} +	if (txnum > TX_PWR_BY_RATE_NUM_RF) { +		RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR, +			 "Invalid TxNum %d\n", txnum); +		return; +	} +	rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = +									data; +} + +static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, +						       u8 configtype) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	int i; +	u32 *phy_regarray_table_pg; +	u16 phy_regarray_pg_len; +	u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0; + +	phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN; +	phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG; + +	if (configtype == BASEBAND_CONFIG_PHY_REG) { +		for (i = 0; i < phy_regarray_pg_len; i = i + 6) { +			v1 = phy_regarray_table_pg[i]; +			v2 = phy_regarray_table_pg[i+1]; +			v3 = phy_regarray_table_pg[i+2]; +			v4 = phy_regarray_table_pg[i+3]; +			v5 = phy_regarray_table_pg[i+4]; +			v6 = phy_regarray_table_pg[i+5]; + +			if (v1 < 0xcdcdcdcd) { +				if (phy_regarray_table_pg[i] == 0xfe || +				    phy_regarray_table_pg[i] == 0xffe) +					mdelay(50); +				else +					_rtl8723be_store_tx_power_by_rate(hw, +							v1, v2, v3, v4, v5, v6); +				continue; +			} else { +				/*don't need the hw_body*/ +				if (!_rtl8723be_check_condition(hw, +						phy_regarray_table_pg[i])) { +					i += 2; /* skip the pair of expression*/ +					v1 = phy_regarray_table_pg[i]; +					v2 = phy_regarray_table_pg[i+1]; +					v3 = phy_regarray_table_pg[i+2]; +					while (v2 != 0xDEAD) { +						i += 3; +						v1 = phy_regarray_table_pg[i]; +						v2 = phy_regarray_table_pg[i+1]; +						v3 = phy_regarray_table_pg[i+2]; +					} +				} +			} +		} +	} else { +		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, +			 "configtype != BaseBand_Config_PHY_REG\n"); +	} +	return true; +} + +bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, +					     enum radio_path rfpath) +{ +	#define READ_NEXT_RF_PAIR(v1, v2, i) \ +		do { \ +			i += 2; \ +			v1 = radioa_array_table[i]; \ +			v2 = radioa_array_table[i+1]; \ +		} while (0) + +	int i; +	bool rtstatus = true; +	u32 *radioa_array_table; +	u16 radioa_arraylen; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u32 v1 = 0, v2 = 0; + +	radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN; +	radioa_array_table = RTL8723BE_RADIOA_1TARRAY; +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); +	rtstatus = true; +	switch (rfpath) { +	case RF90_PATH_A: +		for (i = 0; i < radioa_arraylen; i = i + 2) { +			v1 = radioa_array_table[i]; +			v2 = radioa_array_table[i+1]; +			if (v1 < 0xcdcdcdcd) { +				_rtl8723be_config_rf_radio_a(hw, v1, v2); +			} else { /*This line is the start line of branch.*/ +				if (!_rtl8723be_check_condition(hw, +						radioa_array_table[i])) { +					/* Discard the following +					 * (offset, data) pairs +					 */ +					READ_NEXT_RF_PAIR(v1, v2, i); +					while (v2 != 0xDEAD && +					       v2 != 0xCDEF && +					       v2 != 0xCDCD && +					       i < radioa_arraylen - 2) +						READ_NEXT_RF_PAIR(v1, v2, i); +					i -= 2; /* prevent from for-loop += 2*/ +				} else { +					/* Configure matched pairs +					 * and skip to end of if-else. +					 */ +					READ_NEXT_RF_PAIR(v1, v2, i); +					while (v2 != 0xDEAD && +					       v2 != 0xCDEF && +					       v2 != 0xCDCD && +					       i < radioa_arraylen - 2) { +						_rtl8723be_config_rf_radio_a(hw, +									v1, v2); +						READ_NEXT_RF_PAIR(v1, v2, i); +					} + +					while (v2 != 0xDEAD && +					       i < radioa_arraylen - 2) { +						READ_NEXT_RF_PAIR(v1, v2, i); +					} +				} +			} +		} + +		if (rtlhal->oem_id == RT_CID_819X_HP) +			_rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD); + +		break; +	case RF90_PATH_B: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not process\n"); +		break; +	case RF90_PATH_C: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not process\n"); +		break; +	case RF90_PATH_D: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not process\n"); +		break; +	} +	return true; +} + +void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); + +	rtlphy->default_initialgain[0] = +	    (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); +	rtlphy->default_initialgain[1] = +	    (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); +	rtlphy->default_initialgain[2] = +	    (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); +	rtlphy->default_initialgain[3] = +	    (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +		 "Default initial gain (c50 = 0x%x, " +		  "c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n", +		  rtlphy->default_initialgain[0], +		  rtlphy->default_initialgain[1], +		  rtlphy->default_initialgain[2], +		  rtlphy->default_initialgain[3]); + +	rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, +					       MASKBYTE0); +	rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, +					      MASKDWORD); + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +		 "Default framesync (0x%x) = 0x%x\n", +		  ROFDM0_RXDETECTOR3, rtlphy->framesync); +} + +void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u8 txpwr_level; +	long txpwr_dbm; + +	txpwr_level = rtlphy->cur_cck_txpwridx; +	txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, +						 txpwr_level); +	txpwr_level = rtlphy->cur_ofdm24g_txpwridx; +	if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > +	    txpwr_dbm) +		txpwr_dbm = +		    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, +						 txpwr_level); +	txpwr_level = rtlphy->cur_ofdm24g_txpwridx; +	if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, +					 txpwr_level) > txpwr_dbm) +		txpwr_dbm = +		    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, +						 txpwr_level); +	*powerlevel = txpwr_dbm; +} + +static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path, +							  u8 rate) +{ +	u8 rate_section = 0; + +	switch (rate) { +	case DESC92C_RATE1M: +		rate_section = 2; +		break; +	case DESC92C_RATE2M: +	case DESC92C_RATE5_5M: +		if (path == RF90_PATH_A) +			rate_section = 3; +		else if (path == RF90_PATH_B) +			rate_section = 2; +		break; +	case DESC92C_RATE11M: +		rate_section = 3; +		break; +	case DESC92C_RATE6M: +	case DESC92C_RATE9M: +	case DESC92C_RATE12M: +	case DESC92C_RATE18M: +		rate_section = 0; +		break; +	case DESC92C_RATE24M: +	case DESC92C_RATE36M: +	case DESC92C_RATE48M: +	case DESC92C_RATE54M: +		rate_section = 1; +		break; +	case DESC92C_RATEMCS0: +	case DESC92C_RATEMCS1: +	case DESC92C_RATEMCS2: +	case DESC92C_RATEMCS3: +		rate_section = 4; +		break; +	case DESC92C_RATEMCS4: +	case DESC92C_RATEMCS5: +	case DESC92C_RATEMCS6: +	case DESC92C_RATEMCS7: +		rate_section = 5; +		break; +	case DESC92C_RATEMCS8: +	case DESC92C_RATEMCS9: +	case DESC92C_RATEMCS10: +	case DESC92C_RATEMCS11: +		rate_section = 6; +		break; +	case DESC92C_RATEMCS12: +	case DESC92C_RATEMCS13: +	case DESC92C_RATEMCS14: +	case DESC92C_RATEMCS15: +		rate_section = 7; +		break; +	default: +		RT_ASSERT(true, "Rate_Section is Illegal\n"); +		break; +	} +	return rate_section; +} + +static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw, +					 enum band_type band, +					 enum radio_path rfpath, u8 rate) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u8 shift = 0, rate_section, tx_num; +	char tx_pwr_diff = 0; + +	rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath, +								       rate); +	tx_num = RF_TX_NUM_NONIMPLEMENT; + +	if (tx_num == RF_TX_NUM_NONIMPLEMENT) { +		if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15) +			tx_num = RF_2TX; +		else +			tx_num = RF_1TX; +	} + +	switch (rate) { +	case DESC92C_RATE6M: +	case DESC92C_RATE24M: +	case DESC92C_RATEMCS0: +	case DESC92C_RATEMCS4: +	case DESC92C_RATEMCS8: +	case DESC92C_RATEMCS12: +		shift = 0; +		break; +	case DESC92C_RATE1M: +	case DESC92C_RATE2M: +	case DESC92C_RATE9M: +	case DESC92C_RATE36M: +	case DESC92C_RATEMCS1: +	case DESC92C_RATEMCS5: +	case DESC92C_RATEMCS9: +	case DESC92C_RATEMCS13: +		shift = 8; +		break; +	case DESC92C_RATE5_5M: +	case DESC92C_RATE12M: +	case DESC92C_RATE48M: +	case DESC92C_RATEMCS2: +	case DESC92C_RATEMCS6: +	case DESC92C_RATEMCS10: +	case DESC92C_RATEMCS14: +		shift = 16; +		break; +	case DESC92C_RATE11M: +	case DESC92C_RATE18M: +	case DESC92C_RATE54M: +	case DESC92C_RATEMCS3: +	case DESC92C_RATEMCS7: +	case DESC92C_RATEMCS11: +	case DESC92C_RATEMCS15: +		shift = 24; +		break; +	default: +		RT_ASSERT(true, "Rate_Section is Illegal\n"); +		break; +	} +	tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num] +					  [rate_section] >> shift) & 0xff; + +	return	tx_pwr_diff; +} + +static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path, +				       u8 rate, u8 bandwidth, u8 channel) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	u8 index = (channel - 1); +	u8 txpower; +	u8 power_diff_byrate = 0; + +	if (channel > 14 || channel < 1) { +		index = 0; +		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +			 "Illegal channel!\n"); +	} +	if (RTL8723E_RX_HAL_IS_CCK_RATE(rate)) +		txpower = rtlefuse->txpwrlevel_cck[path][index]; +	else if (DESC92C_RATE6M <= rate) +		txpower = rtlefuse->txpwrlevel_ht40_1s[path][index]; +	else +		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, +			 "invalid rate\n"); + +	if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M && +	    !RTL8723E_RX_HAL_IS_CCK_RATE(rate)) +		txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S]; + +	if (bandwidth == HT_CHANNEL_WIDTH_20) { +		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) +			txpower += rtlefuse->txpwr_ht20diff[0][TX_1S]; +		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) +			txpower += rtlefuse->txpwr_ht20diff[0][TX_2S]; +	} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { +		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) +			txpower += rtlefuse->txpwr_ht40diff[0][TX_1S]; +		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) +			txpower += rtlefuse->txpwr_ht40diff[0][TX_2S]; +	} +	if (rtlefuse->eeprom_regulatory != 2) +		power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw, +								   BAND_ON_2_4G, +								   path, rate); + +	txpower += power_diff_byrate; + +	if (txpower > MAX_POWER_INDEX) +		txpower = MAX_POWER_INDEX; + +	return txpower; +} + +static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, +					     u8 power_index, u8 path, u8 rate) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	if (path == RF90_PATH_A) { +		switch (rate) { +		case DESC92C_RATE1M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32, +					       MASKBYTE1, power_index); +			break; +		case DESC92C_RATE2M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, +					       MASKBYTE1, power_index); +			break; +		case DESC92C_RATE5_5M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, +					       MASKBYTE2, power_index); +			break; +		case DESC92C_RATE11M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, +					       MASKBYTE3, power_index); +			break; +		case DESC92C_RATE6M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, +					       MASKBYTE0, power_index); +			break; +		case DESC92C_RATE9M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, +					       MASKBYTE1, power_index); +			break; +		case DESC92C_RATE12M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, +					       MASKBYTE2, power_index); +			break; +		case DESC92C_RATE18M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, +					       MASKBYTE3, power_index); +			break; +		case DESC92C_RATE24M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, +					       MASKBYTE0, power_index); +			break; +		case DESC92C_RATE36M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, +					       MASKBYTE1, power_index); +			break; +		case DESC92C_RATE48M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, +					       MASKBYTE2, power_index); +			break; +		case DESC92C_RATE54M: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, +					       MASKBYTE3, power_index); +			break; +		case DESC92C_RATEMCS0: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, +					       MASKBYTE0, power_index); +			break; +		case DESC92C_RATEMCS1: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, +					       MASKBYTE1, power_index); +			break; +		case DESC92C_RATEMCS2: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, +					       MASKBYTE2, power_index); +			break; +		case DESC92C_RATEMCS3: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, +					       MASKBYTE3, power_index); +			break; +		case DESC92C_RATEMCS4: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, +					       MASKBYTE0, power_index); +			break; +		case DESC92C_RATEMCS5: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, +					       MASKBYTE1, power_index); +			break; +		case DESC92C_RATEMCS6: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, +					       MASKBYTE2, power_index); +			break; +		case DESC92C_RATEMCS7: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, +					       MASKBYTE3, power_index); +			break; +		case DESC92C_RATEMCS8: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, +					       MASKBYTE0, power_index); +			break; +		case DESC92C_RATEMCS9: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, +					       MASKBYTE1, power_index); +			break; +		case DESC92C_RATEMCS10: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, +					       MASKBYTE2, power_index); +			break; +		case DESC92C_RATEMCS11: +			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, +					       MASKBYTE3, power_index); +			break; +		default: +			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, +				 "Invalid Rate!!\n"); +			break; +		} +	} else { +		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n"); +	} +} + +void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	u8 cck_rates[]  = {DESC92C_RATE1M, DESC92C_RATE2M, +			   DESC92C_RATE5_5M, DESC92C_RATE11M}; +	u8 ofdm_rates[]  = {DESC92C_RATE6M, DESC92C_RATE9M, +			    DESC92C_RATE12M, DESC92C_RATE18M, +			    DESC92C_RATE24M, DESC92C_RATE36M, +			    DESC92C_RATE48M, DESC92C_RATE54M}; +	u8 ht_rates_1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1, +			     DESC92C_RATEMCS2, DESC92C_RATEMCS3, +			     DESC92C_RATEMCS4, DESC92C_RATEMCS5, +			     DESC92C_RATEMCS6, DESC92C_RATEMCS7}; +	u8 i, size; +	u8 power_index; + +	if (!rtlefuse->txpwr_fromeprom) +		return; + +	size = sizeof(cck_rates) / sizeof(u8); +	for (i = 0; i < size; i++) { +		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, +					cck_rates[i], +					rtl_priv(hw)->phy.current_chan_bw, +					channel); +		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, +						 cck_rates[i]); +	} +	size = sizeof(ofdm_rates) / sizeof(u8); +	for (i = 0; i < size; i++) { +		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, +					ofdm_rates[i], +					rtl_priv(hw)->phy.current_chan_bw, +					channel); +		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, +						 ofdm_rates[i]); +	} +	size = sizeof(ht_rates_1t) / sizeof(u8); +	for (i = 0; i < size; i++) { +		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, +					ht_rates_1t[i], +					rtl_priv(hw)->phy.current_chan_bw, +					channel); +		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, +						 ht_rates_1t[i]); +	} +} + +void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	enum io_type iotype; + +	if (!is_hal_stop(rtlhal)) { +		switch (operation) { +		case SCAN_OPT_BACKUP: +			iotype = IO_CMD_PAUSE_DM_BY_SCAN; +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, +						      (u8 *)&iotype); +			break; +		case SCAN_OPT_RESTORE: +			iotype = IO_CMD_RESUME_DM_BY_SCAN; +			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, +						      (u8 *)&iotype); +			break; +		default: +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "Unknown Scan Backup operation.\n"); +			break; +		} +	} +} + +void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	u8 reg_bw_opmode; +	u8 reg_prsr_rsc; + +	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, +		 "Switch to %s bandwidth\n", +		 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? +		 "20MHz" : "40MHz"); + +	if (is_hal_stop(rtlhal)) { +		rtlphy->set_bwmode_inprogress = false; +		return; +	} + +	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); +	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + +	switch (rtlphy->current_chan_bw) { +	case HT_CHANNEL_WIDTH_20: +		reg_bw_opmode |= BW_OPMODE_20MHZ; +		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); +		break; +	case HT_CHANNEL_WIDTH_20_40: +		reg_bw_opmode &= ~BW_OPMODE_20MHZ; +		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); +		reg_prsr_rsc = (reg_prsr_rsc & 0x90) | +			       (mac->cur_40_prime_sc << 5); +		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); +		break; +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); +		break; +	} + +	switch (rtlphy->current_chan_bw) { +	case HT_CHANNEL_WIDTH_20: +		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); +		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); +		break; +	case HT_CHANNEL_WIDTH_20_40: +		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); +		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); +		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, +			      (mac->cur_40_prime_sc >> 1)); +		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); +		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), +			      (mac->cur_40_prime_sc == +			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); +		break; +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); +		break; +	} +	rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); +	rtlphy->set_bwmode_inprogress = false; +	RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); +} + +void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw, +			    enum nl80211_channel_type ch_type) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	u8 tmp_bw = rtlphy->current_chan_bw; + +	if (rtlphy->set_bwmode_inprogress) +		return; +	rtlphy->set_bwmode_inprogress = true; +	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { +		rtl8723be_phy_set_bw_mode_callback(hw); +	} else { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +			 "false driver sleep or unload\n"); +		rtlphy->set_bwmode_inprogress = false; +		rtlphy->current_chan_bw = tmp_bw; +	} +} + +void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u32 delay; + +	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, +		 "switch to channel%d\n", rtlphy->current_channel); +	if (is_hal_stop(rtlhal)) +		return; +	do { +		if (!rtlphy->sw_chnl_inprogress) +			break; +		if (!rtl8723be_phy_sw_chn_step_by_step(hw, +						       rtlphy->current_channel, +						       &rtlphy->sw_chnl_stage, +						       &rtlphy->sw_chnl_step, +						       &delay)) { +			if (delay > 0) +				mdelay(delay); +			else +				continue; +		} else { +			rtlphy->sw_chnl_inprogress = false; +		} +		break; +	} while (true); +	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); +} + +u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + +	if (rtlphy->sw_chnl_inprogress) +		return 0; +	if (rtlphy->set_bwmode_inprogress) +		return 0; +	RT_ASSERT((rtlphy->current_channel <= 14), +		  "WIRELESS_MODE_G but channel>14"); +	rtlphy->sw_chnl_inprogress = true; +	rtlphy->sw_chnl_stage = 0; +	rtlphy->sw_chnl_step = 0; +	if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { +		rtl8723be_phy_sw_chnl_callback(hw); +		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, +			 "sw_chnl_inprogress false schdule " +			  "workitem current channel %d\n", +			  rtlphy->current_channel); +		rtlphy->sw_chnl_inprogress = false; +	} else { +		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, +			 "sw_chnl_inprogress false driver sleep or" +			  " unload\n"); +		rtlphy->sw_chnl_inprogress = false; +	} +	return 1; +} + +static bool rtl8723be_phy_sw_chn_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); +	struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; +	u32 precommoncmdcnt; +	struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; +	u32 postcommoncmdcnt; +	struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; +	u32 rfdependcmdcnt; +	struct swchnlcmd *currentcmd = NULL; +	u8 rfpath; +	u8 num_total_rfpath = rtlphy->num_total_rfpath; + +	precommoncmdcnt = 0; +	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, +					 MAX_PRECMD_CNT, +					 CMDID_SET_TXPOWEROWER_LEVEL, +					 0, 0, 0); +	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, +					 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); +	postcommoncmdcnt = 0; +	rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, +					 MAX_POSTCMD_CNT, CMDID_END, +					 0, 0, 0); +	rfdependcmdcnt = 0; + +	RT_ASSERT((channel >= 1 && channel <= 14), +		  "illegal channel for Zebra: %d\n", channel); + +	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, +					 MAX_RFDEPENDCMD_CNT, +					 CMDID_RF_WRITEREG, +					 RF_CHNLBW, channel, 10); + +	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, +					 MAX_RFDEPENDCMD_CNT, +					 CMDID_END, 0, 0, 0); + +	do { +		switch (*stage) { +		case 0: +			currentcmd = &precommoncmd[*step]; +			break; +		case 1: +			currentcmd = &rfdependcmd[*step]; +			break; +		case 2: +			currentcmd = &postcommoncmd[*step]; +			break; +		} + +		if (currentcmd->cmdid == CMDID_END) { +			if ((*stage) == 2) { +				return true; +			} else { +				(*stage)++; +				(*step) = 0; +				continue; +			} +		} + +		switch (currentcmd->cmdid) { +		case CMDID_SET_TXPOWEROWER_LEVEL: +			rtl8723be_phy_set_txpower_level(hw, channel); +			break; +		case CMDID_WRITEPORT_ULONG: +			rtl_write_dword(rtlpriv, currentcmd->para1, +					currentcmd->para2); +			break; +		case CMDID_WRITEPORT_USHORT: +			rtl_write_word(rtlpriv, currentcmd->para1, +				       (u16) currentcmd->para2); +			break; +		case CMDID_WRITEPORT_UCHAR: +			rtl_write_byte(rtlpriv, currentcmd->para1, +				       (u8) currentcmd->para2); +			break; +		case CMDID_RF_WRITEREG: +			for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { +				rtlphy->rfreg_chnlval[rfpath] = +				    ((rtlphy->rfreg_chnlval[rfpath] & +				      0xfffffc00) | currentcmd->para2); + +				rtl_set_rfreg(hw, (enum radio_path)rfpath, +					      currentcmd->para1, +					      RFREG_OFFSET_MASK, +					      rtlphy->rfreg_chnlval[rfpath]); +			} +			break; +		default: +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "switch case not process\n"); +			break; +		} + +		break; +	} while (true); + +	(*delay) = currentcmd->msdelay; +	(*step)++; +	return false; +} + +static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ +	u32 reg_eac, reg_e94, reg_e9c, reg_ea4; +	u8 result = 0x00; + +	rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c); +	rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c); +	rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a); +	rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000); + +	rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911); +	rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); +	rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + +	mdelay(IQK_DELAY_TIME); + +	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); +	reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); +	reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); +	reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); + +	if (!(reg_eac & BIT(28)) && +	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && +	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) +		result |= 0x01; +	return result; +} + +static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8], +			       u8 c1, u8 c2) +{ +	u32 i, j, diff, simularity_bitmap, bound; +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + +	u8 final_candidate[2] = { 0xFF, 0xFF }; +	bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); + +	if (is2t) +		bound = 8; +	else +		bound = 4; + +	simularity_bitmap = 0; + +	for (i = 0; i < bound; i++) { +		diff = (result[c1][i] > result[c2][i]) ? +		    (result[c1][i] - result[c2][i]) : +		    (result[c2][i] - result[c1][i]); + +		if (diff > MAX_TOLERANCE) { +			if ((i == 2 || i == 6) && !simularity_bitmap) { +				if (result[c1][i] + result[c1][i + 1] == 0) +					final_candidate[(i / 4)] = c2; +				else if (result[c2][i] + result[c2][i + 1] == 0) +					final_candidate[(i / 4)] = c1; +				else +					simularity_bitmap |= (1 << i); +			} else { +				simularity_bitmap |= (1 << i); +			} +		} +	} + +	if (simularity_bitmap == 0) { +		for (i = 0; i < (bound / 4); i++) { +			if (final_candidate[i] != 0xFF) { +				for (j = i * 4; j < (i + 1) * 4 - 2; j++) +					result[3][j] = +						result[final_candidate[i]][j]; +				bresult = false; +			} +		} +		return bresult; +	} else if (!(simularity_bitmap & 0x0F)) { +		for (i = 0; i < 4; i++) +			result[3][i] = result[c1][i]; +		return false; +	} else if (!(simularity_bitmap & 0xF0) && is2t) { +		for (i = 4; i < 8; i++) +			result[3][i] = result[c1][i]; +		return false; +	} else { +		return false; +	} +} + +static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, +					long result[][8], u8 t, bool is2t) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u32 i; +	u8 patha_ok; +	u32 adda_reg[IQK_ADDA_REG_NUM] = { +		0x85c, 0xe6c, 0xe70, 0xe74, +		0xe78, 0xe7c, 0xe80, 0xe84, +		0xe88, 0xe8c, 0xed0, 0xed4, +		0xed8, 0xedc, 0xee0, 0xeec +	}; + +	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { +		0x522, 0x550, 0x551, 0x040 +	}; +	u32 iqk_bb_reg[IQK_BB_REG_NUM] = { +		ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, +		RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c, +		0x870, 0x860, +		0x864, 0x800 +	}; +	const u32 retrycount = 2; +	u32 path_sel_bb, path_sel_rf; +	u8 tmp_reg_c50, tmp_reg_c58; + +	tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0); +	tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0); + +	if (t == 0) { +		rtl8723_save_adda_registers(hw, adda_reg, +					    rtlphy->adda_backup, 16); +		rtl8723_phy_save_mac_registers(hw, iqk_mac_reg, +					       rtlphy->iqk_mac_backup); +		rtl8723_save_adda_registers(hw, iqk_bb_reg, +					    rtlphy->iqk_bb_backup, +					    IQK_BB_REG_NUM); +	} +	rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t); +	if (t == 0) { +		rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, +						RFPGA0_XA_HSSIPARAMETER1, +						BIT(8)); +	} +	if (!rtlphy->rfpi_enable) +		rtl8723_phy_pi_mode_switch(hw, true); + +	path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD); +	path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); + +	/*BB Setting*/ +	rtl_set_bbreg(hw, 0x800, BIT(24), 0x00); +	rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); +	rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); +	rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + +	rtl_set_bbreg(hw, 0x870, BIT(10), 0x01); +	rtl_set_bbreg(hw, 0x870, BIT(26), 0x01); +	rtl_set_bbreg(hw, 0x860, BIT(10), 0x00); +	rtl_set_bbreg(hw, 0x864, BIT(10), 0x00); + +	if (is2t) +		rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASKDWORD, 0x10000); +	rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg, +					    rtlphy->iqk_mac_backup); +	rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000); + +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +	rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); +	rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800); +	for (i = 0; i < retrycount; i++) { +		patha_ok = _rtl8723be_phy_path_a_iqk(hw, is2t); +		if (patha_ok == 0x01) { +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				 "Path A Tx IQK Success!!\n"); +			result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & +					0x3FF0000) >> 16; +			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & +					0x3FF0000) >> 16; +			break; +		} +	} + +	if (0 == patha_ok) +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 "Path A IQK Success!!\n"); +	if (is2t) { +		rtl8723_phy_path_a_standby(hw); +		rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t); +	} + +	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + +	if (t != 0) { +		if (!rtlphy->rfpi_enable) +			rtl8723_phy_pi_mode_switch(hw, false); +		rtl8723_phy_reload_adda_registers(hw, adda_reg, +						  rtlphy->adda_backup, 16); +		rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg, +						 rtlphy->iqk_mac_backup); +		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg, +						  rtlphy->iqk_bb_backup, +						  IQK_BB_REG_NUM); + +		rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb); +		rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf); + +		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50); +		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50); +		if (is2t) { +			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50); +			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58); +		} +		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); +		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00); +	} +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n"); +} + +static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u8 tmpreg; +	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + +	tmpreg = rtl_read_byte(rtlpriv, 0xd03); + +	if ((tmpreg & 0x70) != 0) +		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); +	else +		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + +	if ((tmpreg & 0x70) != 0) { +		rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + +		if (is2t) +			rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, +						  MASK12BITS); + +		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, +			      (rf_a_mode & 0x8FFFF) | 0x10000); + +		if (is2t) +			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, +				      (rf_b_mode & 0x8FFFF) | 0x10000); +	} +	lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + +	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0); +	rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a); + +	mdelay(100); + +	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0); + +	if ((tmpreg & 0x70) != 0) { +		rtl_write_byte(rtlpriv, 0xd03, tmpreg); +		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + +		if (is2t) +			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, +				      MASK12BITS, rf_b_mode); +	} else { +		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +	} +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); +} + +static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, +					     bool bmain, bool is2t) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); + +	if (is_hal_stop(rtlhal)) { +		u8 u1btmp; +		u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0); +		rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7)); +		rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); +	} +	if (is2t) { +		if (bmain) +			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, +				      BIT(5) | BIT(6), 0x1); +		else +			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, +				      BIT(5) | BIT(6), 0x2); +	} else { +		rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0); +		rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201); + +		/* We use the RF definition of MAIN and AUX, +		 * left antenna and right antenna repectively. +		 * Default output at AUX. +		 */ +		if (bmain) { +			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, +				      BIT(14) | BIT(13) | BIT(12), 0); +			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, +				      BIT(5) | BIT(4) | BIT(3), 0); +			if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) +				rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 0); +		} else { +			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, +				      BIT(14) | BIT(13) | BIT(12), 1); +			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, +				      BIT(5) | BIT(4) | BIT(3), 1); +			if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) +				rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 1); +		} +	} +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	long result[4][8]; +	u8 i, final_candidate; +	bool patha_ok, pathb_ok; +	long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, +	    reg_ecc, reg_tmp = 0; +	bool is12simular, is13simular, is23simular; +	u32 iqk_bb_reg[9] = { +		ROFDM0_XARXIQIMBALANCE, +		ROFDM0_XBRXIQIMBALANCE, +		ROFDM0_ECCATHRESHOLD, +		ROFDM0_AGCRSSITABLE, +		ROFDM0_XATXIQIMBALANCE, +		ROFDM0_XBTXIQIMBALANCE, +		ROFDM0_XCTXAFE, +		ROFDM0_XDTXAFE, +		ROFDM0_RXIQEXTANTA +	}; + +	if (recovery) { +		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg, +						  rtlphy->iqk_bb_backup, 9); +		return; +	} + +	for (i = 0; i < 8; i++) { +		result[0][i] = 0; +		result[1][i] = 0; +		result[2][i] = 0; +		result[3][i] = 0; +	} +	final_candidate = 0xff; +	patha_ok = false; +	pathb_ok = false; +	is12simular = false; +	is23simular = false; +	is13simular = false; +	for (i = 0; i < 3; i++) { +		if (get_rf_type(rtlphy) == RF_2T2R) +			_rtl8723be_phy_iq_calibrate(hw, result, i, true); +		else +			_rtl8723be_phy_iq_calibrate(hw, result, i, false); +		if (i == 1) { +			is12simular = phy_similarity_cmp(hw, result, 0, 1); +			if (is12simular) { +				final_candidate = 0; +				break; +			} +		} +		if (i == 2) { +			is13simular = phy_similarity_cmp(hw, result, 0, 2); +			if (is13simular) { +				final_candidate = 0; +				break; +			} +			is23simular = phy_similarity_cmp(hw, result, 1, 2); +			if (is23simular) { +				final_candidate = 1; +			} else { +				for (i = 0; i < 8; i++) +					reg_tmp += result[3][i]; + +				if (reg_tmp != 0) +					final_candidate = 3; +				else +					final_candidate = 0xFF; +			} +		} +	} +	for (i = 0; i < 4; i++) { +		reg_e94 = result[i][0]; +		reg_e9c = result[i][1]; +		reg_ea4 = result[i][2]; +		reg_eac = result[i][3]; +		reg_eb4 = result[i][4]; +		reg_ebc = result[i][5]; +		reg_ec4 = result[i][6]; +		reg_ecc = result[i][7]; +	} +	if (final_candidate != 0xff) { +		reg_e94 = result[final_candidate][0]; +		rtlphy->reg_e94 = reg_e94; +		reg_e9c = result[final_candidate][1]; +		rtlphy->reg_e9c = reg_e9c; +		reg_ea4 = result[final_candidate][2]; +		reg_eac = result[final_candidate][3]; +		reg_eb4 = result[final_candidate][4]; +		rtlphy->reg_eb4 = reg_eb4; +		reg_ebc = result[final_candidate][5]; +		rtlphy->reg_ebc = reg_ebc; +		reg_ec4 = result[final_candidate][6]; +		reg_ecc = result[final_candidate][7]; +		patha_ok = true; +		pathb_ok = true; +	} else { +		rtlphy->reg_e94 = 0x100; +		rtlphy->reg_eb4 = 0x100; +		rtlphy->reg_e9c = 0x0; +		rtlphy->reg_ebc = 0x0; +	} +	if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ +		rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result, +						   final_candidate, +						   (reg_ea4 == 0)); +	if (final_candidate != 0xFF) { +		for (i = 0; i < IQK_MATRIX_REG_NUM; i++) +			rtlphy->iqk_matrix[0].value[0][i] = +						result[final_candidate][i]; +		rtlphy->iqk_matrix[0].iqk_done = true; +	} +	rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9); +} + +void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); +	u32 timeout = 2000, timecount = 0; + +	while (rtlpriv->mac80211.act_scanning && timecount < timeout) { +		udelay(50); +		timecount += 50; +	} + +	rtlphy->lck_inprogress = true; +	RTPRINT(rtlpriv, FINIT, INIT_EEPROM, +		"LCK:Start!!! currentband %x delay %d ms\n", +		rtlhal->current_bandtype, timecount); + +	_rtl8723be_phy_lc_calibrate(hw, false); + +	rtlphy->lck_inprogress = false; +} + +void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); + +	if (rtlphy->apk_done) +		return; + +	return; +} + +void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ +	_rtl8723be_phy_set_rfpath_switch(hw, bmain, false); +} + +static void rtl8723be_phy_set_io(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); + +	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, +		 "--->Cmd(%#x), set_io_inprogress(%d)\n", +		  rtlphy->current_io_type, rtlphy->set_io_inprogress); +	switch (rtlphy->current_io_type) { +	case IO_CMD_RESUME_DM_BY_SCAN: +		rtlpriv->dm_digtable.cur_igvalue = +				 rtlphy->initgain_backup.xaagccore1; +		/*rtl92c_dm_write_dig(hw);*/ +		rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel); +		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83); +		break; +	case IO_CMD_PAUSE_DM_BY_SCAN: +		rtlphy->initgain_backup.xaagccore1 = +				 rtlpriv->dm_digtable.cur_igvalue; +		rtlpriv->dm_digtable.cur_igvalue = 0x17; +		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40); +		break; +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not process\n"); +		break; +	} +	rtlphy->set_io_inprogress = false; +	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, +		 "(%#x)\n", rtlphy->current_io_type); +} + +bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	bool postprocessing = false; + +	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, +		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n", +		  iotype, rtlphy->set_io_inprogress); +	do { +		switch (iotype) { +		case IO_CMD_RESUME_DM_BY_SCAN: +			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, +				 "[IO CMD] Resume DM after scan.\n"); +			postprocessing = true; +			break; +		case IO_CMD_PAUSE_DM_BY_SCAN: +			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, +				 "[IO CMD] Pause DM before scan.\n"); +			postprocessing = true; +			break; +		default: +			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +				 "switch case not process\n"); +			break; +		} +	} while (false); +	if (postprocessing && !rtlphy->set_io_inprogress) { +		rtlphy->set_io_inprogress = true; +		rtlphy->current_io_type = iotype; +	} else { +		return false; +	} +	rtl8723be_phy_set_io(hw); +	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); +	return true; +} + +static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); +	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); +	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); +	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); +	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} + +static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, +					      enum rf_pwrstate rfpwr_state) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); +	bool bresult = true; +	u8 i, queue_id; +	struct rtl8192_tx_ring *ring = NULL; + +	switch (rfpwr_state) { +	case ERFON: +		if ((ppsc->rfpwr_state == ERFOFF) && +		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { +			bool rtstatus; +			u32 initialize_count = 0; +			do { +				initialize_count++; +				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, +					 "IPS Set eRf nic enable\n"); +				rtstatus = rtl_ps_enable_nic(hw); +			} while (!rtstatus && (initialize_count < 10)); +				RT_CLEAR_PS_LEVEL(ppsc, +						  RT_RF_OFF_LEVL_HALT_NIC); +		} else { +			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, +				 "Set ERFON sleeped:%d ms\n", +				  jiffies_to_msecs(jiffies - +						   ppsc->last_sleep_jiffies)); +			ppsc->last_awake_jiffies = jiffies; +			rtl8723be_phy_set_rf_on(hw); +		} +		if (mac->link_state == MAC80211_LINKED) +			rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); +		else +			rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); +		break; +	case ERFOFF: +		for (queue_id = 0, i = 0; +		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { +			ring = &pcipriv->dev.tx_ring[queue_id]; +			if (skb_queue_len(&ring->queue) == 0) { +				queue_id++; +				continue; +			} else { +				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +					 "eRf Off/Sleep: %d times " +					  "TcbBusyQueue[%d] =%d before " +					  "doze!\n", (i + 1), queue_id, +					  skb_queue_len(&ring->queue)); + +				udelay(10); +				i++; +			} +			if (i >= MAX_DOZE_WAITING_TIMES_9x) { +				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +					 "\n ERFSLEEP: %d times " +					  "TcbBusyQueue[%d] = %d !\n", +					  MAX_DOZE_WAITING_TIMES_9x, +					  queue_id, +					  skb_queue_len(&ring->queue)); +				break; +			} +		} + +		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { +			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, +				 "IPS Set eRf nic disable\n"); +			rtl_ps_disable_nic(hw); +			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); +		} else { +			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { +				rtlpriv->cfg->ops->led_control(hw, +							       LED_CTL_NO_LINK); +			} else { +				rtlpriv->cfg->ops->led_control(hw, +							     LED_CTL_POWER_OFF); +			} +		} +		break; +	case ERFSLEEP: +		if (ppsc->rfpwr_state == ERFOFF) +			break; +		for (queue_id = 0, i = 0; +		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { +			ring = &pcipriv->dev.tx_ring[queue_id]; +			if (skb_queue_len(&ring->queue) == 0) { +				queue_id++; +				continue; +			} else { +				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +					 "eRf Off/Sleep: %d times " +					  "TcbBusyQueue[%d] =%d before " +					  "doze!\n", (i + 1), queue_id, +					  skb_queue_len(&ring->queue)); + +				udelay(10); +				i++; +			} +			if (i >= MAX_DOZE_WAITING_TIMES_9x) { +				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, +					 "\n ERFSLEEP: %d times " +					  "TcbBusyQueue[%d] = %d !\n", +					  MAX_DOZE_WAITING_TIMES_9x, +					  queue_id, +					  skb_queue_len(&ring->queue)); +				break; +			} +		} +		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, +			 "Set ERFSLEEP awaked:%d ms\n", +			  jiffies_to_msecs(jiffies - +					   ppsc->last_awake_jiffies)); +		ppsc->last_sleep_jiffies = jiffies; +		_rtl8723be_phy_set_rf_sleep(hw); +		break; +	default: +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "switch case not process\n"); +		bresult = false; +		break; +	} +	if (bresult) +		ppsc->rfpwr_state = rfpwr_state; +	return bresult; +} + +bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, +				      enum rf_pwrstate rfpwr_state) +{ +	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + +	bool bresult = false; + +	if (rfpwr_state == ppsc->rfpwr_state) +		return bresult; +	bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state); +	return bresult; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.h b/drivers/net/wireless/rtlwifi/rtl8723be/phy.h new file mode 100644 index 00000000000..444ef95bb6a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.h @@ -0,0 +1,217 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_PHY_H__ +#define __RTL8723BE_PHY_H__ + +/*It must always set to 4, otherwise read efuse table secquence will be wrong.*/ +#define MAX_TX_COUNT		4 +#define	TX_1S			0 +#define	TX_2S			1 + +#define	MAX_POWER_INDEX		0x3F + +#define MAX_PRECMD_CNT			16 +#define MAX_RFDEPENDCMD_CNT		16 +#define MAX_POSTCMD_CNT		16 + +#define MAX_DOZE_WAITING_TIMES_9x	64 + +#define RT_CANNOT_IO(hw)		false +#define HIGHPOWER_RADIOA_ARRAYLEN	22 + +#define IQK_ADDA_REG_NUM		16 +#define IQK_BB_REG_NUM			9 +#define MAX_TOLERANCE			5 +#define	IQK_DELAY_TIME			10 +#define	index_mapping_NUM		15 + +#define	APK_BB_REG_NUM			5 +#define	APK_AFE_REG_NUM			16 +#define	APK_CURVE_REG_NUM		4 +#define	PATH_NUM			1 + +#define LOOP_LIMIT			5 +#define MAX_STALL_TIME			50 +#define ANTENNADIVERSITYVALUE		0x80 +#define MAX_TXPWR_IDX_NMODE_92S		63 +#define RESET_CNT_LIMIT			3 + +#define IQK_ADDA_REG_NUM		16 +#define IQK_MAC_REG_NUM			4 + +#define RF6052_MAX_PATH			2 + +#define CT_OFFSET_MAC_ADDR		0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX		0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX		0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF	0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF		0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF		0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET		0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET		0x72 + +#define CT_OFFSET_CHANNEL_PLAH			0x75 +#define CT_OFFSET_THERMAL_METER			0x78 +#define CT_OFFSET_RF_OPTION			0x79 +#define CT_OFFSET_VERSION			0x7E +#define CT_OFFSET_CUSTOMER_ID			0x7F + +#define RTL92C_MAX_PATH_NUM			2 + +enum hw90_block_e { +	HW90_BLOCK_MAC = 0, +	HW90_BLOCK_PHY0 = 1, +	HW90_BLOCK_PHY1 = 2, +	HW90_BLOCK_RF = 3, +	HW90_BLOCK_MAXIMUM = 4, +}; + +enum baseband_config_type { +	BASEBAND_CONFIG_PHY_REG = 0, +	BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ra_offset_area { +	RA_OFFSET_LEGACY_OFDM1, +	RA_OFFSET_LEGACY_OFDM2, +	RA_OFFSET_HT_OFDM1, +	RA_OFFSET_HT_OFDM2, +	RA_OFFSET_HT_OFDM3, +	RA_OFFSET_HT_OFDM4, +	RA_OFFSET_HT_CCK, +}; + +enum antenna_path { +	ANTENNA_NONE, +	ANTENNA_D, +	ANTENNA_C, +	ANTENNA_CD, +	ANTENNA_B, +	ANTENNA_BD, +	ANTENNA_BC, +	ANTENNA_BCD, +	ANTENNA_A, +	ANTENNA_AD, +	ANTENNA_AC, +	ANTENNA_ACD, +	ANTENNA_AB, +	ANTENNA_ABD, +	ANTENNA_ABC, +	ANTENNA_ABCD +}; + +struct r_antenna_select_ofdm { +	u32 r_tx_antenna:4; +	u32 r_ant_l:4; +	u32 r_ant_non_ht:4; +	u32 r_ant_ht1:4; +	u32 r_ant_ht2:4; +	u32 r_ant_ht_s1:4; +	u32 r_ant_non_ht_s1:4; +	u32 ofdm_txsc:2; +	u32 reserved:2; +}; + +struct r_antenna_select_cck { +	u8 r_cckrx_enable_2:2; +	u8 r_cckrx_enable:2; +	u8 r_ccktx_enable:4; +}; + + +struct efuse_contents { +	u8 mac_addr[ETH_ALEN]; +	u8 cck_tx_power_idx[6]; +	u8 ht40_1s_tx_power_idx[6]; +	u8 ht40_2s_tx_power_idx_diff[3]; +	u8 ht20_tx_power_idx_diff[3]; +	u8 ofdm_tx_power_idx_diff[3]; +	u8 ht40_max_power_offset[3]; +	u8 ht20_max_power_offset[3]; +	u8 channel_plan; +	u8 thermal_meter; +	u8 rf_option[5]; +	u8 version; +	u8 oem_id; +	u8 regulatory; +}; + +struct tx_power_struct { +	u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; +	u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; +	u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; +	u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; +	u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; +	u8 legacy_ht_txpowerdiff; +	u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; +	u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; +	u8 pwrgroup_cnt; +	u32 mcs_original_offset[4][16]; +}; + +enum _ANT_DIV_TYPE { +	NO_ANTDIV				= 0xFF, +	CG_TRX_HW_ANTDIV		= 0x01, +	CGCS_RX_HW_ANTDIV		= 0x02, +	FIXED_HW_ANTDIV         = 0x03, +	CG_TRX_SMART_ANTDIV		= 0x04, +	CGCS_RX_SW_ANTDIV		= 0x05, +}; + +u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, +			       enum radio_path rfpath, +			       u32 regaddr, u32 bitmask); +void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, +			      enum radio_path rfpath, +			      u32 regaddr, u32 bitmask, u32 data); +bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw); +bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw); +bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw); +void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, +				     long *powerlevel); +void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, +				     u8 channel); +void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, +					 u8 operation); +void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw, +			       enum nl80211_channel_type ch_type); +void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw); +u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, +				bool b_recovery); +void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); +void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, +					     enum radio_path rfpath); +bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, +				      enum rf_pwrstate rfpwr_state); +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c new file mode 100644 index 00000000000..b5167e73fec --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c @@ -0,0 +1,106 @@ +/****************************************************************************** + * + * 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 "pwrseqcmd.h" +#include "pwrseq.h" + + +/* drivers should parse below arrays and do the corresponding actions */ +/*3 Power on  Array*/ +struct wlan_pwr_cfg rtl8723B_power_on_flow[RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS + +					   RTL8723B_TRANS_END_STEPS] = { +	RTL8723B_TRANS_CARDEMU_TO_ACT +	RTL8723B_TRANS_END +}; + +/*3Radio off GPIO Array */ +struct wlan_pwr_cfg rtl8723B_radio_off_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +					    + RTL8723B_TRANS_END_STEPS] = { +	RTL8723B_TRANS_ACT_TO_CARDEMU +	RTL8723B_TRANS_END +}; + +/*3Card Disable Array*/ +struct wlan_pwr_cfg rtl8723B_card_disable_flow +				[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +				 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + +				 RTL8723B_TRANS_END_STEPS] = { +	RTL8723B_TRANS_ACT_TO_CARDEMU +	RTL8723B_TRANS_CARDEMU_TO_CARDDIS +	RTL8723B_TRANS_END +}; + +/*3 Card Enable Array*/ +struct wlan_pwr_cfg rtl8723B_card_enable_flow +				[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +				 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + +				 RTL8723B_TRANS_END_STEPS] = { +	RTL8723B_TRANS_CARDDIS_TO_CARDEMU +	RTL8723B_TRANS_CARDEMU_TO_ACT +	RTL8723B_TRANS_END +}; + +/*3Suspend Array*/ +struct wlan_pwr_cfg rtl8723B_suspend_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +					  RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS + +					  RTL8723B_TRANS_END_STEPS] = { +	RTL8723B_TRANS_ACT_TO_CARDEMU +	RTL8723B_TRANS_CARDEMU_TO_SUS +	RTL8723B_TRANS_END +}; + +/*3 Resume Array*/ +struct wlan_pwr_cfg rtl8723B_resume_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +					 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS + +					 RTL8723B_TRANS_END_STEPS] = { +	RTL8723B_TRANS_SUS_TO_CARDEMU +	RTL8723B_TRANS_CARDEMU_TO_ACT +	RTL8723B_TRANS_END +}; + +/*3HWPDN Array*/ +struct wlan_pwr_cfg rtl8723B_hwpdn_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +					RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + +					RTL8723B_TRANS_END_STEPS] = { +	RTL8723B_TRANS_ACT_TO_CARDEMU +	RTL8723B_TRANS_CARDEMU_TO_PDN +	RTL8723B_TRANS_END +}; + +/*3 Enter LPS */ +struct wlan_pwr_cfg rtl8723B_enter_lps_flow[RTL8723B_TRANS_ACT_TO_LPS_STEPS + +					    RTL8723B_TRANS_END_STEPS] = { +	/*FW behavior*/ +	RTL8723B_TRANS_ACT_TO_LPS +	RTL8723B_TRANS_END +}; + +/*3 Leave LPS */ +struct wlan_pwr_cfg rtl8723B_leave_lps_flow[RTL8723B_TRANS_LPS_TO_ACT_STEPS + +					    RTL8723B_TRANS_END_STEPS] = { +	/*FW behavior*/ +	RTL8723B_TRANS_LPS_TO_ACT +	RTL8723B_TRANS_END +}; diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h new file mode 100644 index 00000000000..a62f43ed8d3 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h @@ -0,0 +1,304 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_PWRSEQ_H__ +#define __RTL8723BE_PWRSEQ_H__ + +/*	Check document WM-20130425-JackieLau-RTL8723B_Power_Architecture v05.vsd + *	There are 6 HW Power States: + *	0: POFF--Power Off + *	1: PDN--Power Down + *	2: CARDEMU--Card Emulation + *	3: ACT--Active Mode + *	4: LPS--Low Power State + *	5: SUS--Suspend + * + *	The transition from different states are defined below + *	TRANS_CARDEMU_TO_ACT + *	TRANS_ACT_TO_CARDEMU + *	TRANS_CARDEMU_TO_SUS + *	TRANS_SUS_TO_CARDEMU + *	TRANS_CARDEMU_TO_PDN + *	TRANS_ACT_TO_LPS + *	TRANS_LPS_TO_ACT + * + *	TRANS_END + */ +#define	RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS	23 +#define	RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS	15 +#define	RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS	15 +#define	RTL8723B_TRANS_SUS_TO_CARDEMU_STEPS	15 +#define	RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS	15 +#define	RTL8723B_TRANS_PDN_TO_CARDEMU_STEPS	15 +#define	RTL8723B_TRANS_ACT_TO_LPS_STEPS		15 +#define	RTL8723B_TRANS_LPS_TO_ACT_STEPS		15 +#define	RTL8723B_TRANS_END_STEPS		1 + +#define RTL8723B_TRANS_CARDEMU_TO_ACT					\ +	{0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK,				\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},		\ +	{0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK,				\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0},			\ +	{0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK,				\ +	 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},		\ +	{0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK,				\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0},			\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)|BIT(2)), 0},	\ +	{0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0) , 0},			\ +	{0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)},		\ +	{0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0) , BIT(0)},		\ +	{0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},		\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},			\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0},		\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},		\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0},			\ +	{0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), BIT(6)},		\ +	{0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)},		\ +	{0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)},		\ +	{0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},			\ +	{0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},		\ +	{0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)},		\ +	{0x0068, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3), BIT(3)},		\ +	{0x0069, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), BIT(6)}, + +#define RTL8723B_TRANS_ACT_TO_CARDEMU					\ +	{0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},			\ +	{0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},			\ +	{0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},			\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)},		\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0},			\ +	{0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), 0},			\ +	{0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC,	\ +	 PWR_CMD_WRITE, BIT(5), BIT(5)},				\ +	{0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC,	\ +	 PWR_CMD_WRITE, BIT(0), 0}, + +#define RTL8723B_TRANS_CARDEMU_TO_SUS					\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4) | BIT(3), (BIT(4) | BIT(3))}, \ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC,	\ +	 PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)},			\ +	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)},		\ +	{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20},			\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)},\ +	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)},		\ +	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, + +#define RTL8723B_TRANS_SUS_TO_CARDEMU					\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0},		\ +	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0},			\ +	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)},		\ +	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0},			\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, + +#define RTL8723B_TRANS_CARDEMU_TO_CARDDIS				\ +	{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20},			\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK,				\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},	\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)},		\ +	{0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 1},			\ +	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)},		\ +	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)},		\ +	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, + +#define RTL8723B_TRANS_CARDDIS_TO_CARDEMU				\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0},		\ +	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0},			\ +	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)},		\ +	{0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},			\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0},		\ +	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0},			\ +	{0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, + +#define RTL8723B_TRANS_CARDEMU_TO_PDN					\ +	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)},		\ +	{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,			\ +	 PWR_INTF_SDIO_MSK | PWR_INTF_USB_MSK, PWR_BASEADDR_MAC,	\ +	 PWR_CMD_WRITE, 0xFF, 0x20},					\ +	{0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},			\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)}, + +#define RTL8723B_TRANS_PDN_TO_CARDEMU					\ +	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, + +#define RTL8723B_TRANS_ACT_TO_LPS					\ +	{0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},			\ +	{0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},			\ +	{0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},			\ +	{0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},			\ +	{0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},			\ +	{0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},			\ +	{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},			\ +	{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},		\ +	{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},			\ +	{0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03},			\ +	{0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},			\ +	{0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},			\ +	{0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)}, + +#define RTL8723B_TRANS_LPS_TO_ACT					\ +	{0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,	\ +	 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84},		\ +	{0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84},			\ +	{0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84},			\ +	{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS},		\ +	{0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0},			\ +	{0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0},		\ +	{0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0},		\ +	{0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)},		\ +	{0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},			\ +	{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1) | BIT(0), BIT(1) | BIT(0)}, \ +	{0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,	\ +	 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, + +#define RTL8723B_TRANS_END						\ +	{0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, 0,	\ +	 PWR_CMD_END, 0, 0}, + +extern struct wlan_pwr_cfg rtl8723B_power_on_flow +				[RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS + +				 RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_radio_off_flow +				[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +				 RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_card_disable_flow +				[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +				 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + +				 RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_card_enable_flow +				[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +				 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + +				 RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_suspend_flow +				[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +				 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS + +				 RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_resume_flow +				[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +				 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS + +				 RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_hwpdn_flow +				[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS + +				 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS + +				 RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_enter_lps_flow +				[RTL8723B_TRANS_ACT_TO_LPS_STEPS + +				 RTL8723B_TRANS_END_STEPS]; +extern struct wlan_pwr_cfg rtl8723B_leave_lps_flow +				[RTL8723B_TRANS_LPS_TO_ACT_STEPS + +				 RTL8723B_TRANS_END_STEPS]; + +/* RTL8723 Power Configuration CMDs for PCIe interface */ +#define RTL8723_NIC_PWR_ON_FLOW		rtl8723B_power_on_flow +#define RTL8723_NIC_RF_OFF_FLOW		rtl8723B_radio_off_flow +#define RTL8723_NIC_DISABLE_FLOW	rtl8723B_card_disable_flow +#define RTL8723_NIC_ENABLE_FLOW		rtl8723B_card_enable_flow +#define RTL8723_NIC_SUSPEND_FLOW	rtl8723B_suspend_flow +#define RTL8723_NIC_RESUME_FLOW		rtl8723B_resume_flow +#define RTL8723_NIC_PDN_FLOW		rtl8723B_hwpdn_flow +#define RTL8723_NIC_LPS_ENTER_FLOW	rtl8723B_enter_lps_flow +#define RTL8723_NIC_LPS_LEAVE_FLOW	rtl8723B_leave_lps_flow + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c new file mode 100644 index 00000000000..e4a507a756f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * 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 "pwrseq.h" + +/*	Description: + *		This routine deal with the Power Configuration CMDs + *		 parsing for RTL8723/RTL8188E Series IC. + *	Assumption: + *		We should follow specific format which was released from HW SD. + * + *	2011.07.07, added by Roger. + */ +bool rtlbe_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, +				 u8 fab_version, u8 interface_type, +				 struct wlan_pwr_cfg pwrcfgcmd[]) + +{ +	struct wlan_pwr_cfg pwr_cfg_cmd = {0}; +	bool b_polling_bit = false; +	u32 ary_idx = 0; +	u8 value = 0; +	u32 offset = 0; +	u32 polling_count = 0; +	u32 max_polling_cnt = 5000; + +	do { +		pwr_cfg_cmd = pwrcfgcmd[ary_idx]; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +			 "rtlbe_hal_pwrseqcmdparsing(): " +			 "offset(%#x),cut_msk(%#x), fab_msk(%#x)," +			 "interface_msk(%#x), base(%#x), " +			 "cmd(%#x), msk(%#x), value(%#x)\n", +			 GET_PWR_CFG_OFFSET(pwr_cfg_cmd), +			 GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd), +			 GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd), +			 GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd), +			 GET_PWR_CFG_BASE(pwr_cfg_cmd), +			 GET_PWR_CFG_CMD(pwr_cfg_cmd), +			 GET_PWR_CFG_MASK(pwr_cfg_cmd), +			 GET_PWR_CFG_VALUE(pwr_cfg_cmd)); + +		if ((GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd)&fab_version) && +		    (GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd)&cut_version) && +		    (GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd)&interface_type)) { +			switch (GET_PWR_CFG_CMD(pwr_cfg_cmd)) { +			case PWR_CMD_READ: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					 "rtlbe_hal_pwrseqcmdparsing(): " +					  "PWR_CMD_READ\n"); +				break; +			case PWR_CMD_WRITE: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					 "rtlbe_hal_pwrseqcmdparsing(): " +					  "PWR_CMD_WRITE\n"); +				offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd); + +				/*Read the value from system register*/ +				value = rtl_read_byte(rtlpriv, offset); +				value &= (~(GET_PWR_CFG_MASK(pwr_cfg_cmd))); +				value = value | (GET_PWR_CFG_VALUE(pwr_cfg_cmd) +					& GET_PWR_CFG_MASK(pwr_cfg_cmd)); + +				/*Write the value back to sytem register*/ +				rtl_write_byte(rtlpriv, offset, value); +				break; +			case PWR_CMD_POLLING: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					 "rtlbe_hal_pwrseqcmdparsing(): " +					  "PWR_CMD_POLLING\n"); +				b_polling_bit = false; +				offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd); + +				do { +					value = rtl_read_byte(rtlpriv, offset); + +					value &= GET_PWR_CFG_MASK(pwr_cfg_cmd); +					if (value == +					    (GET_PWR_CFG_VALUE(pwr_cfg_cmd) & +					     GET_PWR_CFG_MASK(pwr_cfg_cmd))) +						b_polling_bit = true; +					else +						udelay(10); + +					if (polling_count++ > max_polling_cnt) +						return false; + +				} while (!b_polling_bit); +				break; +			case PWR_CMD_DELAY: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					 "rtlbe_hal_pwrseqcmdparsing(): " +					 "PWR_CMD_DELAY\n"); +				if (GET_PWR_CFG_VALUE(pwr_cfg_cmd) == +				    PWRSEQ_DELAY_US) +					udelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd)); +				else +					mdelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd)); +				break; +			case PWR_CMD_END: +				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +					 "rtlbe_hal_pwrseqcmdparsing(): " +					 "PWR_CMD_END\n"); +				return true; +				break; +			default: +				RT_ASSERT(false, +					  "rtlbe_hal_pwrseqcmdparsing(): " +					  "Unknown CMD!!\n"); +				break; +			} +		} + +		ary_idx++; +	} while (1); + +	return true; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h new file mode 100644 index 00000000000..ce14a3b5cb7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_PWRSEQCMD_H__ +#define __RTL8723BE_PWRSEQCMD_H__ + +#include "../wifi.h" +/*---------------------------------------------*/ +/*The value of cmd: 4 bits */ +/*---------------------------------------------*/ +#define PWR_CMD_READ		0x00 +#define PWR_CMD_WRITE		0x01 +#define PWR_CMD_POLLING		0x02 +#define PWR_CMD_DELAY		0x03 +#define PWR_CMD_END		0x04 + +/* define the base address of each block */ +#define PWR_BASEADDR_MAC	0x00 +#define PWR_BASEADDR_USB	0x01 +#define PWR_BASEADDR_PCIE	0x02 +#define PWR_BASEADDR_SDIO	0x03 + +#define	PWR_INTF_SDIO_MSK	BIT(0) +#define	PWR_INTF_USB_MSK	BIT(1) +#define	PWR_INTF_PCI_MSK	BIT(2) +#define	PWR_INTF_ALL_MSK	(BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#define	PWR_FAB_TSMC_MSK	BIT(0) +#define	PWR_FAB_UMC_MSK		BIT(1) +#define	PWR_FAB_ALL_MSK		(BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#define	PWR_CUT_TESTCHIP_MSK	BIT(0) +#define	PWR_CUT_A_MSK		BIT(1) +#define	PWR_CUT_B_MSK		BIT(2) +#define	PWR_CUT_C_MSK		BIT(3) +#define	PWR_CUT_D_MSK		BIT(4) +#define	PWR_CUT_E_MSK		BIT(5) +#define	PWR_CUT_F_MSK		BIT(6) +#define	PWR_CUT_G_MSK		BIT(7) +#define	PWR_CUT_ALL_MSK		0xFF + + +enum pwrseq_delay_unit { +	PWRSEQ_DELAY_US, +	PWRSEQ_DELAY_MS, +}; + +struct wlan_pwr_cfg { +	u16 offset; +	u8 cut_msk; +	u8 fab_msk:4; +	u8 interface_msk:4; +	u8 base:4; +	u8 cmd:4; +	u8 msk; +	u8 value; + +}; + +#define	GET_PWR_CFG_OFFSET(__PWR_CMD)	__PWR_CMD.offset +#define	GET_PWR_CFG_CUT_MASK(__PWR_CMD)	__PWR_CMD.cut_msk +#define	GET_PWR_CFG_FAB_MASK(__PWR_CMD)	__PWR_CMD.fab_msk +#define	GET_PWR_CFG_INTF_MASK(__PWR_CMD)	__PWR_CMD.interface_msk +#define	GET_PWR_CFG_BASE(__PWR_CMD)	__PWR_CMD.base +#define	GET_PWR_CFG_CMD(__PWR_CMD)	__PWR_CMD.cmd +#define	GET_PWR_CFG_MASK(__PWR_CMD)	__PWR_CMD.msk +#define	GET_PWR_CFG_VALUE(__PWR_CMD)	__PWR_CMD.value + +bool rtlbe_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, +				 u8 fab_version, u8 interface_type, +				 struct wlan_pwr_cfg pwrcfgcmd[]); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h new file mode 100644 index 00000000000..4c653fab879 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h @@ -0,0 +1,2277 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_REG_H__ +#define __RTL8723BE_REG_H__ + +#define TXPKT_BUF_SELECT			0x69 +#define RXPKT_BUF_SELECT			0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS		0x0 + +#define REG_SYS_ISO_CTRL			0x0000 +#define REG_SYS_FUNC_EN				0x0002 +#define REG_APS_FSMCO				0x0004 +#define REG_SYS_CLKR				0x0008 +#define REG_9346CR				0x000A +#define REG_EE_VPD				0x000C +#define REG_AFE_MISC				0x0010 +#define REG_SPS0_CTRL				0x0011 +#define REG_SPS_OCP_CFG				0x0018 +#define REG_RSV_CTRL				0x001C +#define REG_RF_CTRL				0x001F +#define REG_LDOA15_CTRL				0x0020 +#define REG_LDOV12D_CTRL			0x0021 +#define REG_LDOHCI12_CTRL			0x0022 +#define REG_LPLDO_CTRL				0x0023 +#define REG_AFE_XTAL_CTRL			0x0024 +/* 1.5v for 8188EE test chip, 1.4v for MP chip */ +#define REG_AFE_LDO_CTRL			0x0027 +#define REG_AFE_PLL_CTRL			0x0028 +#define REG_MAC_PHY_CTRL			0x002c +#define REG_EFUSE_CTRL				0x0030 +#define REG_EFUSE_TEST				0x0034 +#define REG_PWR_DATA				0x0038 +#define REG_CAL_TIMER				0x003C +#define REG_ACLK_MON				0x003E +#define REG_GPIO_MUXCFG				0x0040 +#define REG_GPIO_IO_SEL				0x0042 +#define REG_MAC_PINMUX_CFG			0x0043 +#define REG_GPIO_PIN_CTRL			0x0044 +#define REG_GPIO_INTM				0x0048 +#define REG_LEDCFG0				0x004C +#define REG_LEDCFG1				0x004D +#define REG_LEDCFG2				0x004E +#define REG_LEDCFG3				0x004F +#define REG_FSIMR				0x0050 +#define REG_FSISR				0x0054 +#define REG_HSIMR				0x0058 +#define REG_HSISR				0x005c +#define REG_GPIO_PIN_CTRL_2			0x0060 +#define REG_GPIO_IO_SEL_2			0x0062 +#define REG_MULTI_FUNC_CTRL			0x0068 +#define REG_GPIO_OUTPUT				0x006c +#define REG_AFE_XTAL_CTRL_EXT			0x0078 +#define REG_XCK_OUT_CTRL			0x007c +#define REG_MCUFWDL				0x0080 +#define REG_WOL_EVENT				0x0081 +#define REG_MCUTSTCFG				0x0084 + + +#define REG_HIMR				0x00B0 +#define REG_HISR				0x00B4 +#define REG_HIMRE				0x00B8 +#define REG_HISRE				0x00BC + +#define REG_EFUSE_ACCESS			0x00CF + +#define REG_BIST_SCAN				0x00D0 +#define REG_BIST_RPT				0x00D4 +#define REG_BIST_ROM_RPT			0x00D8 +#define REG_USB_SIE_INTF			0x00E0 +#define REG_PCIE_MIO_INTF			0x00E4 +#define REG_PCIE_MIO_INTD			0x00E8 +#define REG_HPON_FSM				0x00EC +#define REG_SYS_CFG				0x00F0 +#define REG_GPIO_OUTSTS				0x00F4 +#define REG_SYS_CFG1				0x00F0 +#define REG_ROM_VERSION				0x00FD + +#define REG_CR					0x0100 +#define REG_PBP					0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL		0x0106 +#define REG_TRXDMA_CTRL				0x010C +#define REG_TRXFF_BNDY				0x0114 +#define REG_TRXFF_STATUS			0x0118 +#define REG_RXFF_PTR				0x011C + +#define REG_CPWM				0x012F +#define REG_FWIMR				0x0130 +#define REG_FWISR				0x0134 +#define REG_PKTBUF_DBG_CTRL			0x0140 +#define REG_PKTBUF_DBG_DATA_L			0x0144 +#define REG_PKTBUF_DBG_DATA_H			0x0148 +#define REG_RXPKTBUF_CTRL			(REG_PKTBUF_DBG_CTRL + 2) + +#define REG_TC0_CTRL				0x0150 +#define REG_TC1_CTRL				0x0154 +#define REG_TC2_CTRL				0x0158 +#define REG_TC3_CTRL				0x015C +#define REG_TC4_CTRL				0x0160 +#define REG_TCUNIT_BASE				0x0164 +#define REG_MBIST_START				0x0174 +#define REG_MBIST_DONE				0x0178 +#define REG_MBIST_FAIL				0x017C +#define REG_32K_CTRL				0x0194 +#define REG_C2HEVT_MSG_NORMAL			0x01A0 +#define REG_C2HEVT_CLEAR			0x01AF +#define REG_C2HEVT_MSG_TEST			0x01B8 +#define REG_MCUTST_1				0x01c0 +#define REG_FMETHR				0x01C8 +#define REG_HMETFR				0x01CC +#define REG_HMEBOX_0				0x01D0 +#define REG_HMEBOX_1				0x01D4 +#define REG_HMEBOX_2				0x01D8 +#define REG_HMEBOX_3				0x01DC + +#define REG_LLT_INIT				0x01E0 +#define REG_BB_ACCEESS_CTRL			0x01E8 +#define REG_BB_ACCESS_DATA			0x01EC + +#define REG_HMEBOX_EXT_0			0x01F0 +#define REG_HMEBOX_EXT_1			0x01F4 +#define REG_HMEBOX_EXT_2			0x01F8 +#define REG_HMEBOX_EXT_3			0x01FC + +#define REG_RQPN				0x0200 +#define REG_FIFOPAGE				0x0204 +#define REG_TDECTRL				0x0208 +#define REG_TXDMA_OFFSET_CHK			0x020C +#define REG_TXDMA_STATUS			0x0210 +#define REG_RQPN_NPQ				0x0214 + +#define REG_RXDMA_AGG_PG_TH			0x0280 +/* FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 */ +#define REG_FW_UPD_RDPTR			0x0284 +/* Control the RX DMA.*/ +#define REG_RXDMA_CONTROL			0x0286 +/* The number of packets in RXPKTBUF.	*/ +#define REG_RXPKT_NUM				0x0287 + +#define	REG_PCIE_CTRL_REG			0x0300 +#define	REG_INT_MIG				0x0304 +#define	REG_BCNQ_DESA				0x0308 +#define	REG_HQ_DESA				0x0310 +#define	REG_MGQ_DESA				0x0318 +#define	REG_VOQ_DESA				0x0320 +#define	REG_VIQ_DESA				0x0328 +#define	REG_BEQ_DESA				0x0330 +#define	REG_BKQ_DESA				0x0338 +#define	REG_RX_DESA				0x0340 + +#define	REG_DBI					0x0348 +#define	REG_MDIO				0x0354 +#define	REG_DBG_SEL				0x0360 +#define	REG_PCIE_HRPWM				0x0361 +#define	REG_PCIE_HCPWM				0x0363 +#define	REG_UART_CTRL				0x0364 +#define	REG_WATCH_DOG				0x0368 +#define	REG_UART_TX_DESA			0x0370 +#define	REG_UART_RX_DESA			0x0378 + + +#define	REG_HDAQ_DESA_NODEF			0x0000 +#define	REG_CMDQ_DESA_NODEF			0x0000 + +#define REG_VOQ_INFORMATION			0x0400 +#define REG_VIQ_INFORMATION			0x0404 +#define REG_BEQ_INFORMATION			0x0408 +#define REG_BKQ_INFORMATION			0x040C +#define REG_MGQ_INFORMATION			0x0410 +#define REG_HGQ_INFORMATION			0x0414 +#define REG_BCNQ_INFORMATION			0x0418 +#define REG_TXPKT_EMPTY				0x041A + + +#define REG_CPU_MGQ_INFORMATION			0x041C +#define REG_FWHW_TXQ_CTRL			0x0420 +#define REG_HWSEQ_CTRL				0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY			0x0424 +#define REG_TXPKTBUF_MGQ_BDNY			0x0425 +#define REG_MULTI_BCNQ_EN			0x0426 +#define REG_MULTI_BCNQ_OFFSET			0x0427 +#define REG_SPEC_SIFS				0x0428 +#define REG_RL					0x042A +#define REG_DARFRC				0x0430 +#define REG_RARFRC				0x0438 +#define REG_RRSR				0x0440 +#define REG_ARFR0				0x0444 +#define REG_ARFR1				0x0448 +#define REG_ARFR2				0x044C +#define REG_ARFR3				0x0450 +#define REG_AMPDU_MAX_TIME			0x0456 +#define REG_AGGLEN_LMT				0x0458 +#define REG_AMPDU_MIN_SPACE			0x045C +#define REG_TXPKTBUF_WMAC_LBK_BF_HD		0x045D +#define REG_FAST_EDCA_CTRL			0x0460 +#define REG_RD_RESP_PKT_TH			0x0463 +#define REG_INIRTS_RATE_SEL			0x0480 +#define REG_INIDATA_RATE_SEL			0x0484 +#define REG_POWER_STATUS			0x04A4 +#define REG_POWER_STAGE1			0x04B4 +#define REG_POWER_STAGE2			0x04B8 +#define REG_PKT_LIFE_TIME			0x04C0 +#define REG_STBC_SETTING			0x04C4 +#define REG_PROT_MODE_CTRL			0x04C8 +#define REG_BAR_MODE_CTRL			0x04CC +#define REG_RA_TRY_RATE_AGG_LMT			0x04CF +#define REG_EARLY_MODE_CONTROL			0x04D0 +#define REG_NQOS_SEQ				0x04DC +#define REG_QOS_SEQ				0x04DE +#define REG_NEED_CPU_HANDLE			0x04E0 +#define REG_PKT_LOSE_RPT			0x04E1 +#define REG_PTCL_ERR_STATUS			0x04E2 +#define REG_TX_RPT_CTRL				0x04EC +#define REG_TX_RPT_TIME				0x04F0 +#define REG_DUMMY				0x04FC + +#define REG_EDCA_VO_PARAM			0x0500 +#define REG_EDCA_VI_PARAM			0x0504 +#define REG_EDCA_BE_PARAM			0x0508 +#define REG_EDCA_BK_PARAM			0x050C +#define REG_BCNTCFG				0x0510 +#define REG_PIFS				0x0512 +#define REG_RDG_PIFS				0x0513 +#define REG_SIFS_CTX				0x0514 +#define REG_SIFS_TRX				0x0516 +#define REG_AGGR_BREAK_TIME			0x051A +#define REG_SLOT				0x051B +#define REG_TX_PTCL_CTRL			0x0520 +#define REG_TXPAUSE				0x0522 +#define REG_DIS_TXREQ_CLR			0x0523 +#define REG_RD_CTRL				0x0524 +#define REG_TBTT_PROHIBIT			0x0540 +#define REG_RD_NAV_NXT				0x0544 +#define REG_NAV_PROT_LEN			0x0546 +#define REG_BCN_CTRL				0x0550 +#define REG_USTIME_TSF				0x0551 +#define REG_MBID_NUM				0x0552 +#define REG_DUAL_TSF_RST			0x0553 +#define REG_BCN_INTERVAL			0x0554 +#define REG_MBSSID_BCN_SPACE			0x0554 +#define REG_DRVERLYINT				0x0558 +#define REG_BCNDMATIM				0x0559 +#define REG_ATIMWND				0x055A +#define REG_BCN_MAX_ERR				0x055D +#define REG_RXTSF_OFFSET_CCK			0x055E +#define REG_RXTSF_OFFSET_OFDM			0x055F +#define REG_TSFTR				0x0560 +#define REG_INIT_TSFTR				0x0564 +#define REG_SECONDARY_CCA_CTRL			0x0577 +#define REG_PSTIMER				0x0580 +#define REG_TIMER0				0x0584 +#define REG_TIMER1				0x0588 +#define REG_ACMHWCTRL				0x05C0 +#define REG_ACMRSTCTRL				0x05C1 +#define REG_ACMAVG				0x05C2 +#define REG_VO_ADMTIME				0x05C4 +#define REG_VI_ADMTIME				0x05C6 +#define REG_BE_ADMTIME				0x05C8 +#define REG_EDCA_RANDOM_GEN			0x05CC +#define REG_SCH_TXCMD				0x05D0 + +#define REG_APSD_CTRL				0x0600 +#define REG_BWOPMODE				0x0603 +#define REG_TCR					0x0604 +#define REG_RCR					0x0608 +#define REG_RX_PKT_LIMIT			0x060C +#define REG_RX_DLK_TIME				0x060D +#define REG_RX_DRVINFO_SZ			0x060F + +#define REG_MACID				0x0610 +#define REG_BSSID				0x0618 +#define REG_MAR					0x0620 +#define REG_MBIDCAMCFG				0x0628 + +#define REG_USTIME_EDCA				0x0638 +#define REG_MAC_SPEC_SIFS			0x063A +#define REG_RESP_SIFS_CCK			0x063C +#define REG_RESP_SIFS_OFDM			0x063E +#define REG_ACKTO				0x0640 +#define REG_CTS2TO				0x0641 +#define REG_EIFS				0x0642 + +#define REG_NAV_CTRL				0x0650 +#define REG_BACAMCMD				0x0654 +#define REG_BACAMCONTENT			0x0658 +#define REG_LBDLY				0x0660 +#define REG_FWDLY				0x0661 +#define REG_RXERR_RPT				0x0664 +#define REG_TRXPTCL_CTL				0x0668 + +#define REG_CAMCMD				0x0670 +#define REG_CAMWRITE				0x0674 +#define REG_CAMREAD				0x0678 +#define REG_CAMDBG				0x067C +#define REG_SECCFG				0x0680 + +#define REG_WOW_CTRL				0x0690 +#define REG_PSSTATUS				0x0691 +#define REG_PS_RX_INFO				0x0692 +#define REG_UAPSD_TID				0x0693 +#define REG_LPNAV_CTRL				0x0694 +#define REG_WKFMCAM_NUM				0x0698 +#define REG_WKFMCAM_RWD				0x069C +#define REG_RXFLTMAP0				0x06A0 +#define REG_RXFLTMAP1				0x06A2 +#define REG_RXFLTMAP2				0x06A4 +#define REG_BCN_PSR_RPT				0x06A8 +#define REG_CALB32K_CTRL			0x06AC +#define REG_PKT_MON_CTRL			0x06B4 +#define REG_BT_COEX_TABLE			0x06C0 +#define REG_WMAC_RESP_TXINFO			0x06D8 + +#define REG_USB_INFO				0xFE17 +#define REG_USB_SPECIAL_OPTION			0xFE55 +#define REG_USB_DMA_AGG_TO			0xFE5B +#define REG_USB_AGG_TO				0xFE5C +#define REG_USB_AGG_TH				0xFE5D + +#define REG_TEST_USB_TXQS			0xFE48 +#define REG_TEST_SIE_VID			0xFE60 +#define REG_TEST_SIE_PID			0xFE62 +#define REG_TEST_SIE_OPTIONAL			0xFE64 +#define REG_TEST_SIE_CHIRP_K			0xFE65 +#define REG_TEST_SIE_PHY			0xFE66 +#define REG_TEST_SIE_MAC_ADDR			0xFE70 +#define REG_TEST_SIE_STRING			0xFE80 + +#define REG_NORMAL_SIE_VID			0xFE60 +#define REG_NORMAL_SIE_PID			0xFE62 +#define REG_NORMAL_SIE_OPTIONAL			0xFE64 +#define REG_NORMAL_SIE_EP			0xFE65 +#define REG_NORMAL_SIE_PHY			0xFE68 +#define REG_NORMAL_SIE_MAC_ADDR			0xFE70 +#define REG_NORMAL_SIE_STRING			0xFE80 + +#define	CR9346					REG_9346CR +#define	MSR					(REG_CR + 2) +#define	ISR					REG_HISR +#define	TSFR					REG_TSFTR + +#define	MACIDR0					REG_MACID +#define	MACIDR4					(REG_MACID + 4) + +#define PBP					REG_PBP + +#define	IDR0					MACIDR0 +#define	IDR4					MACIDR4 + +#define	UNUSED_REGISTER				0x1BF +#define	DCAM					UNUSED_REGISTER +#define	PSR					UNUSED_REGISTER +#define BBADDR					UNUSED_REGISTER +#define	PHYDATAR				UNUSED_REGISTER + +#define	INVALID_BBRF_VALUE			0x12345678 + +#define	MAX_MSS_DENSITY_2T			0x13 +#define	MAX_MSS_DENSITY_1T			0x0A + +#define	CMDEEPROM_EN				BIT(5) +#define	CMDEEPROM_SEL				BIT(4) +#define	CMD9346CR_9356SEL			BIT(4) +#define	AUTOLOAD_EEPROM				(CMDEEPROM_EN | CMDEEPROM_SEL) +#define	AUTOLOAD_EFUSE				CMDEEPROM_EN + +#define	GPIOSEL_GPIO				0 +#define	GPIOSEL_ENBT				BIT(5) + +#define	GPIO_IN					REG_GPIO_PIN_CTRL +#define	GPIO_OUT				(REG_GPIO_PIN_CTRL + 1) +#define	GPIO_IO_SEL				(REG_GPIO_PIN_CTRL + 2) +#define	GPIO_MOD				(REG_GPIO_PIN_CTRL + 3) + +/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */ +#define	HSIMR_GPIO12_0_INT_EN			BIT(0) +#define	HSIMR_SPS_OCP_INT_EN			BIT(5) +#define	HSIMR_RON_INT_EN			BIT(6) +#define	HSIMR_PDN_INT_EN			BIT(7) +#define	HSIMR_GPIO9_INT_EN			BIT(25) + +/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */ + +#define	HSISR_GPIO12_0_INT			BIT(0) +#define	HSISR_SPS_OCP_INT			BIT(5) +#define	HSISR_RON_INT_EN			BIT(6) +#define	HSISR_PDNINT				BIT(7) +#define	HSISR_GPIO9_INT				BIT(25) + +#define	MSR_NOLINK				0x00 +#define	MSR_ADHOC				0x01 +#define	MSR_INFRA				0x02 +#define	MSR_AP					0x03 + +#define	RRSR_RSC_OFFSET				21 +#define	RRSR_SHORT_OFFSET			23 +#define	RRSR_RSC_BW_40M				0x600000 +#define	RRSR_RSC_UPSUBCHNL			0x400000 +#define	RRSR_RSC_LOWSUBCHNL			0x200000 +#define	RRSR_SHORT				0x800000 +#define	RRSR_1M					BIT(0) +#define	RRSR_2M					BIT(1) +#define	RRSR_5_5M				BIT(2) +#define	RRSR_11M				BIT(3) +#define	RRSR_6M					BIT(4) +#define	RRSR_9M					BIT(5) +#define	RRSR_12M				BIT(6) +#define	RRSR_18M				BIT(7) +#define	RRSR_24M				BIT(8) +#define	RRSR_36M				BIT(9) +#define	RRSR_48M				BIT(10) +#define	RRSR_54M				BIT(11) +#define	RRSR_MCS0				BIT(12) +#define	RRSR_MCS1				BIT(13) +#define	RRSR_MCS2				BIT(14) +#define	RRSR_MCS3				BIT(15) +#define	RRSR_MCS4				BIT(16) +#define	RRSR_MCS5				BIT(17) +#define	RRSR_MCS6				BIT(18) +#define	RRSR_MCS7				BIT(19) +#define	BRSR_ACKSHORTPMB			BIT(23) + +#define	RATR_1M					0x00000001 +#define	RATR_2M					0x00000002 +#define	RATR_55M				0x00000004 +#define	RATR_11M				0x00000008 +#define	RATR_6M					0x00000010 +#define	RATR_9M					0x00000020 +#define	RATR_12M				0x00000040 +#define	RATR_18M				0x00000080 +#define	RATR_24M				0x00000100 +#define	RATR_36M				0x00000200 +#define	RATR_48M				0x00000400 +#define	RATR_54M				0x00000800 +#define	RATR_MCS0				0x00001000 +#define	RATR_MCS1				0x00002000 +#define	RATR_MCS2				0x00004000 +#define	RATR_MCS3				0x00008000 +#define	RATR_MCS4				0x00010000 +#define	RATR_MCS5				0x00020000 +#define	RATR_MCS6				0x00040000 +#define	RATR_MCS7				0x00080000 +#define	RATR_MCS8				0x00100000 +#define	RATR_MCS9				0x00200000 +#define	RATR_MCS10				0x00400000 +#define	RATR_MCS11				0x00800000 +#define	RATR_MCS12				0x01000000 +#define	RATR_MCS13				0x02000000 +#define	RATR_MCS14				0x04000000 +#define	RATR_MCS15				0x08000000 + +#define RATE_1M					BIT(0) +#define RATE_2M					BIT(1) +#define RATE_5_5M				BIT(2) +#define RATE_11M				BIT(3) +#define RATE_6M					BIT(4) +#define RATE_9M					BIT(5) +#define RATE_12M				BIT(6) +#define RATE_18M				BIT(7) +#define RATE_24M				BIT(8) +#define RATE_36M				BIT(9) +#define RATE_48M				BIT(10) +#define RATE_54M				BIT(11) +#define RATE_MCS0				BIT(12) +#define RATE_MCS1				BIT(13) +#define RATE_MCS2				BIT(14) +#define RATE_MCS3				BIT(15) +#define RATE_MCS4				BIT(16) +#define RATE_MCS5				BIT(17) +#define RATE_MCS6				BIT(18) +#define RATE_MCS7				BIT(19) +#define RATE_MCS8				BIT(20) +#define RATE_MCS9				BIT(21) +#define RATE_MCS10				BIT(22) +#define RATE_MCS11				BIT(23) +#define RATE_MCS12				BIT(24) +#define RATE_MCS13				BIT(25) +#define RATE_MCS14				BIT(26) +#define RATE_MCS15				BIT(27) + +#define	RATE_ALL_CCK		(RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define	RATE_ALL_OFDM_AG	(RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ +				 RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define	RATE_ALL_OFDM_1SS	(RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ +				 RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ +				 RATR_MCS6 | RATR_MCS7) +#define	RATE_ALL_OFDM_2SS	(RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ +				 RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ +				 RATR_MCS14 | RATR_MCS15) + +#define	BW_OPMODE_20MHZ				BIT(2) +#define	BW_OPMODE_5G				BIT(1) +#define	BW_OPMODE_11J				BIT(0) + +#define	CAM_VALID				BIT(15) +#define	CAM_NOTVALID				0x0000 +#define	CAM_USEDK				BIT(5) + +#define	CAM_NONE				0x0 +#define	CAM_WEP40				0x01 +#define	CAM_TKIP				0x02 +#define	CAM_AES					0x04 +#define	CAM_WEP104				0x05 + +#define	TOTAL_CAM_ENTRY				32 +#define	HALF_CAM_ENTRY				16 + +#define	CAM_WRITE				BIT(16) +#define	CAM_READ				0x00000000 +#define	CAM_POLLINIG				BIT(31) + +#define	SCR_USEDK				0x01 +#define	SCR_TXSEC_ENABLE			0x02 +#define	SCR_RXSEC_ENABLE			0x04 + +#define	WOW_PMEN				BIT(0) +#define	WOW_WOMEN				BIT(1) +#define	WOW_MAGIC				BIT(2) +#define	WOW_UWF					BIT(3) + +/********************************************* +*       8723BE IMR/ISR bits +**********************************************/ +#define	IMR_DISABLED				0x0 +/* IMR DW0(0x0060-0063) Bit 0-31 */ +#define	IMR_TXCCK		BIT(30)	/* TXRPT interrupt when +					 * CCX bit of the packet is set +					 */ +#define	IMR_PSTIMEOUT		BIT(29)	/* Power Save Time Out Interrupt */ +#define	IMR_GTINT4		BIT(28)	/* When GTIMER4 expires, +					 * this bit is set to 1 +					 */ +#define	IMR_GTINT3		BIT(27)	/* When GTIMER3 expires, +					 * this bit is set to 1 +					 */ +#define	IMR_TBDER		BIT(26)	/* Transmit Beacon0 Error */ +#define	IMR_TBDOK		BIT(25)	/* Transmit Beacon0 OK */ +#define	IMR_TSF_BIT32_TOGGLE	BIT(24)	/* TSF Timer BIT32 toggle +					 * indication interrupt +					 */ +#define	IMR_BCNDMAINT0		BIT(20)	/* Beacon DMA Interrupt 0 */ +#define	IMR_BCNDOK0		BIT(16)	/* Beacon Queue DMA OK0 */ +#define	IMR_HSISR_IND_ON_INT	BIT(15)	/* HSISR Indicator (HSIMR & HSISR is +					 * true, this bit is set to 1) +					 */ +#define	IMR_BCNDMAINT_E		BIT(14)	/* Beacon DMA Interrupt +					 * Extension for Win7 +					 */ +#define	IMR_ATIMEND		BIT(12)	/* CTWidnow End or ATIM Window End */ +#define	IMR_HISR1_IND_INT	BIT(11)	/* HISR1 Indicator (HISR1 & HIMR1 is +					 * true, this bit is set to 1) +					 */ +#define	IMR_C2HCMD		BIT(10)	/* CPU to Host Command INT Status, +					 * Write 1 clear +					 */ +#define	IMR_CPWM2		BIT(9)	/* CPU power Mode exchange INT Status, +					 * Write 1 clear +					 */ +#define	IMR_CPWM		BIT(8)	/* CPU power Mode exchange INT Status, +					 * Write 1 clear +					 */ +#define	IMR_HIGHDOK		BIT(7)	/* High Queue DMA OK */ +#define	IMR_MGNTDOK		BIT(6)	/* Management Queue DMA OK */ +#define	IMR_BKDOK		BIT(5)	/* AC_BK DMA OK	*/ +#define	IMR_BEDOK		BIT(4)	/* AC_BE DMA OK	*/ +#define	IMR_VIDOK		BIT(3)	/* AC_VI DMA OK	*/ +#define	IMR_VODOK		BIT(2)	/* AC_VO DMA OK	*/ +#define	IMR_RDU			BIT(1)	/* Rx Descriptor Unavailable */ +#define	IMR_ROK			BIT(0)	/* Receive DMA OK */ + +/* IMR DW1(0x00B4-00B7) Bit 0-31 */ +#define	IMR_BCNDMAINT7		BIT(27)	/* Beacon DMA Interrupt 7 */ +#define	IMR_BCNDMAINT6		BIT(26)	/* Beacon DMA Interrupt 6 */ +#define	IMR_BCNDMAINT5		BIT(25)	/* Beacon DMA Interrupt 5 */ +#define	IMR_BCNDMAINT4		BIT(24)	/* Beacon DMA Interrupt 4 */ +#define	IMR_BCNDMAINT3		BIT(23)	/* Beacon DMA Interrupt 3 */ +#define	IMR_BCNDMAINT2		BIT(22)	/* Beacon DMA Interrupt 2 */ +#define	IMR_BCNDMAINT1		BIT(21)	/* Beacon DMA Interrupt 1 */ +#define	IMR_BCNDOK7		BIT(20)	/* Beacon Queue DMA OK Interrup 7 */ +#define	IMR_BCNDOK6		BIT(19)	/* Beacon Queue DMA OK Interrup 6 */ +#define	IMR_BCNDOK5		BIT(18)	/* Beacon Queue DMA OK Interrup 5 */ +#define	IMR_BCNDOK4		BIT(17)	/* Beacon Queue DMA OK Interrup 4 */ +#define	IMR_BCNDOK3		BIT(16)	/* Beacon Queue DMA OK Interrup 3 */ +#define	IMR_BCNDOK2		BIT(15)	/* Beacon Queue DMA OK Interrup 2 */ +#define	IMR_BCNDOK1		BIT(14)	/* Beacon Queue DMA OK Interrup 1 */ +#define	IMR_ATIMEND_E		BIT(13)	/* ATIM Window End Extension for Win7 */ +#define	IMR_TXERR		BIT(11)	/* Tx Error Flag Interrupt Status, +					 * write 1 clear. +					 */ +#define	IMR_RXERR		BIT(10)	/* Rx Error Flag INT Status, +					 * Write 1 clear +					 */ +#define	IMR_TXFOVW		BIT(9)	/* Transmit FIFO Overflow */ +#define	IMR_RXFOVW		BIT(8)	/* Receive FIFO Overflow */ + +#define	HWSET_MAX_SIZE			512 +#define EFUSE_MAX_SECTION		64 +#define EFUSE_REAL_CONTENT_LEN		256 +#define EFUSE_OOB_PROTECT_BYTES		18 /* PG data exclude header, +					    * dummy 7 bytes frome CP test +					    * and reserved 1byte. +					    */ + +#define	EEPROM_DEFAULT_TSSI			0x0 +#define EEPROM_DEFAULT_TXPOWERDIFF		0x0 +#define EEPROM_DEFAULT_CRYSTALCAP		0x5 +#define EEPROM_DEFAULT_BOARDTYPE		0x02 +#define EEPROM_DEFAULT_TXPOWER			0x1010 +#define	EEPROM_DEFAULT_HT2T_TXPWR		0x10 + +#define	EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF	0x3 +#define	EEPROM_DEFAULT_THERMALMETER		0x18 +#define	EEPROM_DEFAULT_ANTTXPOWERDIFF		0x0 +#define	EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP	0x5 +#define	EEPROM_DEFAULT_TXPOWERLEVEL		0x22 +#define	EEPROM_DEFAULT_HT40_2SDIFF		0x0 +#define EEPROM_DEFAULT_HT20_DIFF		2 +#define	EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF	0x3 +#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET	0 +#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET	0 + +#define RF_OPTION1				0x79 +#define RF_OPTION2				0x7A +#define RF_OPTION3				0x7B +#define RF_OPTION4				0xC3 + +#define EEPROM_DEFAULT_PID			0x1234 +#define EEPROM_DEFAULT_VID			0x5678 +#define EEPROM_DEFAULT_CUSTOMERID		0xAB +#define EEPROM_DEFAULT_SUBCUSTOMERID		0xCD +#define EEPROM_DEFAULT_VERSION			0 + +#define	EEPROM_CHANNEL_PLAN_FCC			0x0 +#define	EEPROM_CHANNEL_PLAN_IC			0x1 +#define	EEPROM_CHANNEL_PLAN_ETSI		0x2 +#define	EEPROM_CHANNEL_PLAN_SPAIN		0x3 +#define	EEPROM_CHANNEL_PLAN_FRANCE		0x4 +#define	EEPROM_CHANNEL_PLAN_MKK			0x5 +#define	EEPROM_CHANNEL_PLAN_MKK1		0x6 +#define	EEPROM_CHANNEL_PLAN_ISRAEL		0x7 +#define	EEPROM_CHANNEL_PLAN_TELEC		0x8 +#define	EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN	0x9 +#define	EEPROM_CHANNEL_PLAN_WORLD_WIDE_13	0xA +#define	EEPROM_CHANNEL_PLAN_NCC			0xB +#define	EEPROM_CHANNEL_PLAN_BY_HW_MASK		0x80 + +#define EEPROM_CID_DEFAULT			0x0 +#define EEPROM_CID_TOSHIBA			0x4 +#define	EEPROM_CID_CCX				0x10 +#define	EEPROM_CID_QMI				0x0D +#define EEPROM_CID_WHQL				0xFE + +#define	RTL8723BE_EEPROM_ID			0x8129 + +#define EEPROM_HPON				0x02 +#define EEPROM_CLK				0x06 +#define EEPROM_TESTR				0x08 + + +#define EEPROM_TXPOWERCCK			0x10 +#define	EEPROM_TXPOWERHT40_1S			0x16 +#define EEPROM_TXPOWERHT20DIFF			0x1B +#define EEPROM_TXPOWER_OFDMDIFF			0x1B + + + +#define	EEPROM_TX_PWR_INX			0x10 + +#define	EEPROM_CHANNELPLAN			0xB8 +#define	EEPROM_XTAL_8723BE			0xB9 +#define	EEPROM_THERMAL_METER_88E		0xBA +#define	EEPROM_IQK_LCK_88E			0xBB + +#define	EEPROM_RF_BOARD_OPTION_88E		0xC1 +#define	EEPROM_RF_FEATURE_OPTION_88E		0xC2 +#define	EEPROM_RF_BT_SETTING_88E		0xC3 +#define	EEPROM_VERSION				0xC4 +#define	EEPROM_CUSTOMER_ID			0xC5 +#define	EEPROM_RF_ANTENNA_OPT_88E		0xC9 + +#define	EEPROM_MAC_ADDR				0xD0 +#define EEPROM_VID				0xD6 +#define EEPROM_DID				0xD8 +#define EEPROM_SVID				0xDA +#define EEPROM_SMID				0xDC + +#define	STOPBECON				BIT(6) +#define	STOPHIGHT				BIT(5) +#define	STOPMGT					BIT(4) +#define	STOPVO					BIT(3) +#define	STOPVI					BIT(2) +#define	STOPBE					BIT(1) +#define	STOPBK					BIT(0) + +#define	RCR_APPFCS				BIT(31) +#define	RCR_APP_MIC				BIT(30) +#define	RCR_APP_ICV				BIT(29) +#define	RCR_APP_PHYST_RXFF			BIT(28) +#define	RCR_APP_BA_SSN				BIT(27) +#define	RCR_ENMBID				BIT(24) +#define	RCR_LSIGEN				BIT(23) +#define	RCR_MFBEN				BIT(22) +#define	RCR_HTC_LOC_CTRL			BIT(14) +#define	RCR_AMF					BIT(13) +#define	RCR_ACF					BIT(12) +#define	RCR_ADF					BIT(11) +#define	RCR_AICV				BIT(9) +#define	RCR_ACRC32				BIT(8) +#define	RCR_CBSSID_BCN				BIT(7) +#define	RCR_CBSSID_DATA				BIT(6) +#define	RCR_CBSSID				RCR_CBSSID_DATA +#define	RCR_APWRMGT				BIT(5) +#define	RCR_ADD3				BIT(4) +#define	RCR_AB					BIT(3) +#define	RCR_AM					BIT(2) +#define	RCR_APM					BIT(1) +#define	RCR_AAP					BIT(0) +#define	RCR_MXDMA_OFFSET			8 +#define	RCR_FIFO_OFFSET				13 + +#define RSV_CTRL				0x001C +#define RD_CTRL					0x0524 + +#define REG_USB_INFO				0xFE17 +#define REG_USB_SPECIAL_OPTION			0xFE55 +#define REG_USB_DMA_AGG_TO			0xFE5B +#define REG_USB_AGG_TO				0xFE5C +#define REG_USB_AGG_TH				0xFE5D + +#define REG_USB_VID				0xFE60 +#define REG_USB_PID				0xFE62 +#define REG_USB_OPTIONAL			0xFE64 +#define REG_USB_CHIRP_K				0xFE65 +#define REG_USB_PHY				0xFE66 +#define REG_USB_MAC_ADDR			0xFE70 +#define REG_USB_HRPWM				0xFE58 +#define REG_USB_HCPWM				0xFE57 + +#define SW18_FPWM				BIT(3) + +#define ISO_MD2PP				BIT(0) +#define ISO_UA2USB				BIT(1) +#define ISO_UD2CORE				BIT(2) +#define ISO_PA2PCIE				BIT(3) +#define ISO_PD2CORE				BIT(4) +#define ISO_IP2MAC				BIT(5) +#define ISO_DIOP				BIT(6) +#define ISO_DIOE				BIT(7) +#define ISO_EB2CORE				BIT(8) +#define ISO_DIOR				BIT(9) + +#define PWC_EV25V				BIT(14) +#define PWC_EV12V				BIT(15) + +#define FEN_BBRSTB				BIT(0) +#define FEN_BB_GLB_RSTN				BIT(1) +#define FEN_USBA				BIT(2) +#define FEN_UPLL				BIT(3) +#define FEN_USBD				BIT(4) +#define FEN_DIO_PCIE				BIT(5) +#define FEN_PCIEA				BIT(6) +#define FEN_PPLL				BIT(7) +#define FEN_PCIED				BIT(8) +#define FEN_DIOE				BIT(9) +#define FEN_CPUEN				BIT(10) +#define FEN_DCORE				BIT(11) +#define FEN_ELDR				BIT(12) +#define FEN_DIO_RF				BIT(13) +#define FEN_HWPDN				BIT(14) +#define FEN_MREGEN				BIT(15) + +#define PFM_LDALL				BIT(0) +#define PFM_ALDN				BIT(1) +#define PFM_LDKP				BIT(2) +#define PFM_WOWL				BIT(3) +#define ENPDN					BIT(4) +#define PDN_PL					BIT(5) +#define APFM_ONMAC				BIT(8) +#define APFM_OFF				BIT(9) +#define APFM_RSM				BIT(10) +#define AFSM_HSUS				BIT(11) +#define AFSM_PCIE				BIT(12) +#define APDM_MAC				BIT(13) +#define APDM_HOST				BIT(14) +#define APDM_HPDN				BIT(15) +#define RDY_MACON				BIT(16) +#define SUS_HOST				BIT(17) +#define ROP_ALD					BIT(20) +#define ROP_PWR					BIT(21) +#define ROP_SPS					BIT(22) +#define SOP_MRST				BIT(25) +#define SOP_FUSE				BIT(26) +#define SOP_ABG					BIT(27) +#define SOP_AMB					BIT(28) +#define SOP_RCK					BIT(29) +#define SOP_A8M					BIT(30) +#define XOP_BTCK				BIT(31) + +#define ANAD16V_EN				BIT(0) +#define ANA8M					BIT(1) +#define MACSLP					BIT(4) +#define LOADER_CLK_EN				BIT(5) +#define _80M_SSC_DIS				BIT(7) +#define _80M_SSC_EN_HO				BIT(8) +#define PHY_SSC_RSTB				BIT(9) +#define SEC_CLK_EN				BIT(10) +#define MAC_CLK_EN				BIT(11) +#define SYS_CLK_EN				BIT(12) +#define RING_CLK_EN				BIT(13) + +#define	BOOT_FROM_EEPROM			BIT(4) +#define	EEPROM_EN				BIT(5) + +#define AFE_BGEN				BIT(0) +#define AFE_MBEN				BIT(1) +#define MAC_ID_EN				BIT(7) + +#define WLOCK_ALL				BIT(0) +#define WLOCK_00				BIT(1) +#define WLOCK_04				BIT(2) +#define WLOCK_08				BIT(3) +#define WLOCK_40				BIT(4) +#define R_DIS_PRST_0				BIT(5) +#define R_DIS_PRST_1				BIT(6) +#define LOCK_ALL_EN				BIT(7) + +#define RF_EN					BIT(0) +#define RF_RSTB					BIT(1) +#define RF_SDMRSTB				BIT(2) + +#define LDA15_EN				BIT(0) +#define LDA15_STBY				BIT(1) +#define LDA15_OBUF				BIT(2) +#define LDA15_REG_VOS				BIT(3) +#define _LDA15_VOADJ(x)				(((x) & 0x7) << 4) + +#define LDV12_EN				BIT(0) +#define LDV12_SDBY				BIT(1) +#define LPLDO_HSM				BIT(2) +#define LPLDO_LSM_DIS				BIT(3) +#define _LDV12_VADJ(x)				(((x) & 0xF) << 4) + +#define XTAL_EN					BIT(0) +#define XTAL_BSEL				BIT(1) +#define _XTAL_BOSC(x)				(((x) & 0x3) << 2) +#define _XTAL_CADJ(x)				(((x) & 0xF) << 4) +#define XTAL_GATE_USB				BIT(8) +#define _XTAL_USB_DRV(x)			(((x) & 0x3) << 9) +#define XTAL_GATE_AFE				BIT(11) +#define _XTAL_AFE_DRV(x)			(((x) & 0x3) << 12) +#define XTAL_RF_GATE				BIT(14) +#define _XTAL_RF_DRV(x)				(((x) & 0x3) << 15) +#define XTAL_GATE_DIG				BIT(17) +#define _XTAL_DIG_DRV(x)			(((x) & 0x3) << 18) +#define XTAL_BT_GATE				BIT(20) +#define _XTAL_BT_DRV(x)				(((x) & 0x3) << 21) +#define _XTAL_GPIO(x)				(((x) & 0x7) << 23) + +#define CKDLY_AFE				BIT(26) +#define CKDLY_USB				BIT(27) +#define CKDLY_DIG				BIT(28) +#define CKDLY_BT				BIT(29) + +#define APLL_EN					BIT(0) +#define APLL_320_EN				BIT(1) +#define APLL_FREF_SEL				BIT(2) +#define APLL_EDGE_SEL				BIT(3) +#define APLL_WDOGB				BIT(4) +#define APLL_LPFEN				BIT(5) + +#define APLL_REF_CLK_13MHZ			0x1 +#define APLL_REF_CLK_19_2MHZ			0x2 +#define APLL_REF_CLK_20MHZ			0x3 +#define APLL_REF_CLK_25MHZ			0x4 +#define APLL_REF_CLK_26MHZ			0x5 +#define APLL_REF_CLK_38_4MHZ			0x6 +#define APLL_REF_CLK_40MHZ			0x7 + +#define APLL_320EN				BIT(14) +#define APLL_80EN				BIT(15) +#define APLL_1MEN				BIT(24) + +#define ALD_EN					BIT(18) +#define EF_PD					BIT(19) +#define EF_FLAG					BIT(31) + +#define EF_TRPT					BIT(7) +#define LDOE25_EN				BIT(31) + +#define RSM_EN					BIT(0) +#define TIMER_EN				BIT(4) + +#define TRSW0EN					BIT(2) +#define TRSW1EN					BIT(3) +#define EROM_EN					BIT(4) +#define ENBT					BIT(5) +#define ENUART					BIT(8) +#define UART_910				BIT(9) +#define ENPMAC					BIT(10) +#define SIC_SWRST				BIT(11) +#define ENSIC					BIT(12) +#define SIC_23					BIT(13) +#define ENHDP					BIT(14) +#define SIC_LBK					BIT(15) + +#define LED0PL					BIT(4) +#define LED1PL					BIT(12) +#define LED0DIS					BIT(7) + +#define MCUFWDL_EN				BIT(0) +#define MCUFWDL_RDY				BIT(1) +#define FWDL_CHKSUM_RPT				BIT(2) +#define MACINI_RDY				BIT(3) +#define BBINI_RDY				BIT(4) +#define RFINI_RDY				BIT(5) +#define WINTINI_RDY				BIT(6) +#define CPRST					BIT(23) + +#define XCLK_VLD				BIT(0) +#define ACLK_VLD				BIT(1) +#define UCLK_VLD				BIT(2) +#define PCLK_VLD				BIT(3) +#define PCIRSTB					BIT(4) +#define V15_VLD					BIT(5) +#define TRP_B15V_EN				BIT(7) +#define SIC_IDLE				BIT(8) +#define BD_MAC2					BIT(9) +#define BD_MAC1					BIT(10) +#define IC_MACPHY_MODE				BIT(11) +#define VENDOR_ID				BIT(19) +#define PAD_HWPD_IDN				BIT(22) +#define TRP_VAUX_EN				BIT(23) +#define TRP_BT_EN				BIT(24) +#define BD_PKG_SEL				BIT(25) +#define BD_HCI_SEL				BIT(26) +#define TYPE_ID					BIT(27) + +#define CHIP_VER_RTL_MASK			0xF000 +#define CHIP_VER_RTL_SHIFT			12 + +#define REG_LBMODE				(REG_CR + 3) + +#define HCI_TXDMA_EN				BIT(0) +#define HCI_RXDMA_EN				BIT(1) +#define TXDMA_EN				BIT(2) +#define RXDMA_EN				BIT(3) +#define PROTOCOL_EN				BIT(4) +#define SCHEDULE_EN				BIT(5) +#define MACTXEN					BIT(6) +#define MACRXEN					BIT(7) +#define ENSWBCN					BIT(8) +#define ENSEC					BIT(9) + +#define _NETTYPE(x)				(((x) & 0x3) << 16) +#define MASK_NETTYPE				0x30000 +#define NT_NO_LINK				0x0 +#define NT_LINK_AD_HOC				0x1 +#define NT_LINK_AP				0x2 +#define NT_AS_AP				0x3 + +#define _LBMODE(x)				(((x) & 0xF) << 24) +#define MASK_LBMODE				0xF000000 +#define LOOPBACK_NORMAL				0x0 +#define LOOPBACK_IMMEDIATELY			0xB +#define LOOPBACK_MAC_DELAY			0x3 +#define LOOPBACK_PHY				0x1 +#define LOOPBACK_DMA				0x7 + +#define GET_RX_PAGE_SIZE(value)			((value) & 0xF) +#define GET_TX_PAGE_SIZE(value)			(((value) & 0xF0) >> 4) +#define _PSRX_MASK				0xF +#define _PSTX_MASK				0xF0 +#define _PSRX(x)				(x) +#define _PSTX(x)				((x) << 4) + +#define PBP_64					0x0 +#define PBP_128					0x1 +#define PBP_256					0x2 +#define PBP_512					0x3 +#define PBP_1024				0x4 + +#define RXDMA_ARBBW_EN				BIT(0) +#define RXSHFT_EN				BIT(1) +#define RXDMA_AGG_EN				BIT(2) +#define QS_VO_QUEUE				BIT(8) +#define QS_VI_QUEUE				BIT(9) +#define QS_BE_QUEUE				BIT(10) +#define QS_BK_QUEUE				BIT(11) +#define QS_MANAGER_QUEUE			BIT(12) +#define QS_HIGH_QUEUE				BIT(13) + +#define HQSEL_VOQ				BIT(0) +#define HQSEL_VIQ				BIT(1) +#define HQSEL_BEQ				BIT(2) +#define HQSEL_BKQ				BIT(3) +#define HQSEL_MGTQ				BIT(4) +#define HQSEL_HIQ				BIT(5) + +#define _TXDMA_HIQ_MAP(x)			(((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x)			(((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x)			(((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x)			(((x)&0x3) << 8) +#define _TXDMA_VIQ_MAP(x)			(((x)&0x3) << 6) +#define _TXDMA_VOQ_MAP(x)			(((x)&0x3) << 4) + +#define QUEUE_LOW				1 +#define QUEUE_NORMAL				2 +#define QUEUE_HIGH				3 + +#define _LLT_NO_ACTIVE				0x0 +#define _LLT_WRITE_ACCESS			0x1 +#define _LLT_READ_ACCESS			0x2 + +#define _LLT_INIT_DATA(x)			((x) & 0xFF) +#define _LLT_INIT_ADDR(x)			(((x) & 0xFF) << 8) +#define _LLT_OP(x)				(((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x)			(((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK			(BIT(31) | BIT(30)) +#define BB_WRITE_EN				BIT(30) +#define BB_READ_EN				BIT(31) + +#define _HPQ(x)					((x) & 0xFF) +#define _LPQ(x)					(((x) & 0xFF) << 8) +#define _PUBQ(x)				(((x) & 0xFF) << 16) +#define _NPQ(x)					((x) & 0xFF) + +#define HPQ_PUBLIC_DIS				BIT(24) +#define LPQ_PUBLIC_DIS				BIT(25) +#define LD_RQPN					BIT(31) + +#define BCN_VALID				BIT(16) +#define BCN_HEAD(x)				(((x) & 0xFF) << 8) +#define	BCN_HEAD_MASK				0xFF00 + +#define BLK_DESC_NUM_SHIFT			4 +#define BLK_DESC_NUM_MASK			0xF + +#define DROP_DATA_EN				BIT(9) + +#define EN_AMPDU_RTY_NEW			BIT(7) + +#define _INIRTSMCS_SEL(x)			((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x)			((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x)			(((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL			0xFFFFF + +#define _RRSC_BITMAP(x)				((x) & 0xFFFFF) + +#define _RRSR_RSC(x)				(((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED			0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL		0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL		0x2 +#define RRSR_RSC_DUPLICATE_MODE			0x3 + +#define USE_SHORT_G1				BIT(20) + +#define _AGGLMT_MCS0(x)				((x) & 0xF) +#define _AGGLMT_MCS1(x)				(((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x)				(((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x)				(((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x)				(((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x)				(((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x)				(((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x)				(((x) & 0xF) << 28) + +#define	RETRY_LIMIT_SHORT_SHIFT			8 +#define	RETRY_LIMIT_LONG_SHIFT			0 + +#define _DARF_RC1(x)				((x) & 0x1F) +#define _DARF_RC2(x)				(((x) & 0x1F) << 8) +#define _DARF_RC3(x)				(((x) & 0x1F) << 16) +#define _DARF_RC4(x)				(((x) & 0x1F) << 24) +#define _DARF_RC5(x)				((x) & 0x1F) +#define _DARF_RC6(x)				(((x) & 0x1F) << 8) +#define _DARF_RC7(x)				(((x) & 0x1F) << 16) +#define _DARF_RC8(x)				(((x) & 0x1F) << 24) + +#define _RARF_RC1(x)				((x) & 0x1F) +#define _RARF_RC2(x)				(((x) & 0x1F) << 8) +#define _RARF_RC3(x)				(((x) & 0x1F) << 16) +#define _RARF_RC4(x)				(((x) & 0x1F) << 24) +#define _RARF_RC5(x)				((x) & 0x1F) +#define _RARF_RC6(x)				(((x) & 0x1F) << 8) +#define _RARF_RC7(x)				(((x) & 0x1F) << 16) +#define _RARF_RC8(x)				(((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET		16 +#define AC_PARAM_ECW_MAX_OFFSET			12 +#define AC_PARAM_ECW_MIN_OFFSET			8 +#define AC_PARAM_AIFS_OFFSET			0 + +#define _AIFS(x)				(x) +#define _ECW_MAX_MIN(x)				((x) << 8) +#define _TXOP_LIMIT(x)				((x) << 16) + +#define _BCNIFS(x)				((x) & 0xFF) +#define _BCNECW(x)				((((x) & 0xF)) << 8) + +#define _LRL(x)					((x) & 0x3F) +#define _SRL(x)					(((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x)			((x) & 0xFF) +#define _SIFS_CCK_TRX(x)			(((x) & 0xFF) << 8) + +#define _SIFS_OFDM_CTX(x)			((x) & 0xFF) +#define _SIFS_OFDM_TRX(x)			(((x) & 0xFF) << 8) + +#define _TBTT_PROHIBIT_HOLD(x)			(((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN			BIT(11) + +#define EN_MBSSID				BIT(1) +#define EN_TXBCN_RPT				BIT(2) +#define	EN_BCN_FUNCTION				BIT(3) + +#define TSFTR_RST				BIT(0) +#define TSFTR1_RST				BIT(1) + +#define STOP_BCNQ				BIT(6) + +#define	DIS_TSF_UDT0_NORMAL_CHIP		BIT(4) +#define	DIS_TSF_UDT0_TEST_CHIP			BIT(5) + +#define	ACMHW_HWEN				BIT(0) +#define	ACMHW_BEQEN				BIT(1) +#define	ACMHW_VIQEN				BIT(2) +#define	ACMHW_VOQEN				BIT(3) +#define	ACMHW_BEQSTATUS				BIT(4) +#define	ACMHW_VIQSTATUS				BIT(5) +#define	ACMHW_VOQSTATUS				BIT(6) + +#define APSDOFF					BIT(6) +#define APSDOFF_STATUS				BIT(7) + +#define BW_20MHZ				BIT(2) + +#define RATE_BITMAP_ALL				0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M			0xFFFF1 + +#define TSFRST					BIT(0) +#define DIS_GCLK				BIT(1) +#define PAD_SEL					BIT(2) +#define PWR_ST					BIT(6) +#define PWRBIT_OW_EN				BIT(7) +#define ACRC					BIT(8) +#define CFENDFORM				BIT(9) +#define ICV					BIT(10) + +#define AAP					BIT(0) +#define APM					BIT(1) +#define AM					BIT(2) +#define AB					BIT(3) +#define ADD3					BIT(4) +#define APWRMGT					BIT(5) +#define CBSSID					BIT(6) +#define CBSSID_DATA				BIT(6) +#define CBSSID_BCN				BIT(7) +#define ACRC32					BIT(8) +#define AICV					BIT(9) +#define ADF					BIT(11) +#define ACF					BIT(12) +#define AMF					BIT(13) +#define HTC_LOC_CTRL				BIT(14) +#define UC_DATA_EN				BIT(16) +#define BM_DATA_EN				BIT(17) +#define MFBEN					BIT(22) +#define LSIGEN					BIT(23) +#define ENMBID					BIT(24) +#define APP_BASSN				BIT(27) +#define APP_PHYSTS				BIT(28) +#define APP_ICV					BIT(29) +#define APP_MIC					BIT(30) +#define APP_FCS					BIT(31) + +#define _MIN_SPACE(x)			((x) & 0x7) +#define _SHORT_GI_PADDING(x)		(((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU		0 +#define RXERR_TYPE_OFDM_FALSE_ALARM	1 +#define	RXERR_TYPE_OFDM_MPDU_OK		2 +#define RXERR_TYPE_OFDM_MPDU_FAIL	3 +#define RXERR_TYPE_CCK_PPDU		4 +#define RXERR_TYPE_CCK_FALSE_ALARM	5 +#define RXERR_TYPE_CCK_MPDU_OK		6 +#define RXERR_TYPE_CCK_MPDU_FAIL	7 +#define RXERR_TYPE_HT_PPDU		8 +#define RXERR_TYPE_HT_FALSE_ALARM	9 +#define RXERR_TYPE_HT_MPDU_TOTAL	10 +#define RXERR_TYPE_HT_MPDU_OK		11 +#define RXERR_TYPE_HT_MPDU_FAIL		12 +#define RXERR_TYPE_RX_FULL_DROP		15 + +#define RXERR_COUNTER_MASK		0xFFFFF +#define RXERR_RPT_RST			BIT(27) +#define _RXERR_RPT_SEL(type)		((type) << 28) + +#define	SCR_TXUSEDK			BIT(0) +#define	SCR_RXUSEDK			BIT(1) +#define	SCR_TXENCENABLE			BIT(2) +#define	SCR_RXDECENABLE			BIT(3) +#define	SCR_SKBYA2			BIT(4) +#define	SCR_NOSKMC			BIT(5) +#define SCR_TXBCUSEDK			BIT(6) +#define SCR_RXBCUSEDK			BIT(7) + +#define XCLK_VLD			BIT(0) +#define ACLK_VLD			BIT(1) +#define UCLK_VLD			BIT(2) +#define PCLK_VLD			BIT(3) +#define PCIRSTB				BIT(4) +#define V15_VLD				BIT(5) +#define TRP_B15V_EN			BIT(7) +#define SIC_IDLE			BIT(8) +#define BD_MAC2				BIT(9) +#define BD_MAC1				BIT(10) +#define IC_MACPHY_MODE			BIT(11) +#define BT_FUNC				BIT(16) +#define VENDOR_ID			BIT(19) +#define PAD_HWPD_IDN			BIT(22) +#define TRP_VAUX_EN			BIT(23) +#define TRP_BT_EN			BIT(24) +#define BD_PKG_SEL			BIT(25) +#define BD_HCI_SEL			BIT(26) +#define TYPE_ID				BIT(27) + +#define USB_IS_HIGH_SPEED		0 +#define USB_IS_FULL_SPEED		1 +#define USB_SPEED_MASK			BIT(5) + +#define USB_NORMAL_SIE_EP_MASK		0xF +#define USB_NORMAL_SIE_EP_SHIFT		4 + +#define USB_TEST_EP_MASK		0x30 +#define USB_TEST_EP_SHIFT		4 + +#define USB_AGG_EN			BIT(3) + +#define MAC_ADDR_LEN			6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER	175/*255    88e*/ + +#define POLLING_LLT_THRESHOLD		20 +#define POLLING_READY_TIMEOUT_COUNT	3000 + +#define	MAX_MSS_DENSITY_2T		0x13 +#define	MAX_MSS_DENSITY_1T		0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK	((1<<7)|(1<<6)) +#define EPROM_CMD_CONFIG		0x3 +#define EPROM_CMD_LOAD			1 + +#define	HWSET_MAX_SIZE_92S		HWSET_MAX_SIZE + +#define	HAL_8192C_HW_GPIO_WPS_BIT	BIT(2) + +#define	RPMAC_RESET			0x100 +#define	RPMAC_TXSTART			0x104 +#define	RPMAC_TXLEGACYSIG		0x108 +#define	RPMAC_TXHTSIG1			0x10c +#define	RPMAC_TXHTSIG2			0x110 +#define	RPMAC_PHYDEBUG			0x114 +#define	RPMAC_TXPACKETNUM		0x118 +#define	RPMAC_TXIDLE			0x11c +#define	RPMAC_TXMACHEADER0		0x120 +#define	RPMAC_TXMACHEADER1		0x124 +#define	RPMAC_TXMACHEADER2		0x128 +#define	RPMAC_TXMACHEADER3		0x12c +#define	RPMAC_TXMACHEADER4		0x130 +#define	RPMAC_TXMACHEADER5		0x134 +#define	RPMAC_TXDADATYPE		0x138 +#define	RPMAC_TXRANDOMSEED		0x13c +#define	RPMAC_CCKPLCPPREAMBLE		0x140 +#define	RPMAC_CCKPLCPHEADER		0x144 +#define	RPMAC_CCKCRC16			0x148 +#define	RPMAC_OFDMRXCRC32OK		0x170 +#define	RPMAC_OFDMRXCRC32ER		0x174 +#define	RPMAC_OFDMRXPARITYER		0x178 +#define	RPMAC_OFDMRXCRC8ER		0x17c +#define	RPMAC_CCKCRXRC16ER		0x180 +#define	RPMAC_CCKCRXRC32ER		0x184 +#define	RPMAC_CCKCRXRC32OK		0x188 +#define	RPMAC_TXSTATUS			0x18c + +#define	RFPGA0_RFMOD			0x800 + +#define	RFPGA0_TXINFO			0x804 +#define	RFPGA0_PSDFUNCTION		0x808 + +#define	RFPGA0_TXGAINSTAGE		0x80c + +#define	RFPGA0_RFTIMING1		0x810 +#define	RFPGA0_RFTIMING2		0x814 + +#define	RFPGA0_XA_HSSIPARAMETER1	0x820 +#define	RFPGA0_XA_HSSIPARAMETER2	0x824 +#define	RFPGA0_XB_HSSIPARAMETER1	0x828 +#define	RFPGA0_XB_HSSIPARAMETER2	0x82c + +#define	RFPGA0_XA_LSSIPARAMETER		0x840 +#define	RFPGA0_XB_LSSIPARAMETER		0x844 + +#define	RFPGA0_RFWAKEUPPARAMETER	0x850 +#define	RFPGA0_RFSLEEPUPPARAMETER	0x854 + +#define	RFPGA0_XAB_SWITCHCONTROL	0x858 +#define	RFPGA0_XCD_SWITCHCONTROL	0x85c + +#define	RFPGA0_XA_RFINTERFACEOE		0x860 +#define	RFPGA0_XB_RFINTERFACEOE		0x864 + +#define	RFPGA0_XAB_RFINTERFACESW	0x870 +#define	RFPGA0_XCD_RFINTERFACESW	0x874 + +#define	RFPGA0_XAB_RFPARAMETER		0x878 +#define	RFPGA0_XCD_RFPARAMETER		0x87c + +#define	RFPGA0_ANALOGPARAMETER1		0x880 +#define	RFPGA0_ANALOGPARAMETER2		0x884 +#define	RFPGA0_ANALOGPARAMETER3		0x888 +#define	RFPGA0_ANALOGPARAMETER4		0x88c + +#define	RFPGA0_XA_LSSIREADBACK		0x8a0 +#define	RFPGA0_XB_LSSIREADBACK		0x8a4 +#define	RFPGA0_XC_LSSIREADBACK		0x8a8 +#define	RFPGA0_XD_LSSIREADBACK		0x8ac + +#define	RFPGA0_PSDREPORT		0x8b4 +#define	TRANSCEIVEA_HSPI_READBACK	0x8b8 +#define	TRANSCEIVEB_HSPI_READBACK	0x8bc +#define	REG_SC_CNT			0x8c4 +#define	RFPGA0_XAB_RFINTERFACERB	0x8e0 +#define	RFPGA0_XCD_RFINTERFACERB	0x8e4 + +#define	RFPGA1_RFMOD			0x900 + +#define	RFPGA1_TXBLOCK			0x904 +#define	RFPGA1_DEBUGSELECT		0x908 +#define	RFPGA1_TXINFO			0x90c + +#define	RCCK0_SYSTEM			0xa00 + +#define	RCCK0_AFESETTING		0xa04 +#define	RCCK0_CCA			0xa08 + +#define	RCCK0_RXAGC1			0xa0c +#define	RCCK0_RXAGC2			0xa10 + +#define	RCCK0_RXHP			0xa14 + +#define	RCCK0_DSPPARAMETER1		0xa18 +#define	RCCK0_DSPPARAMETER2		0xa1c + +#define	RCCK0_TXFILTER1			0xa20 +#define	RCCK0_TXFILTER2			0xa24 +#define	RCCK0_DEBUGPORT			0xa28 +#define	RCCK0_FALSEALARMREPORT		0xa2c +#define	RCCK0_TRSSIREPORT		0xa50 +#define	RCCK0_RXREPORT			0xa54 +#define	RCCK0_FACOUNTERLOWER		0xa5c +#define	RCCK0_FACOUNTERUPPER		0xa58 +#define	RCCK0_CCA_CNT			0xa60 + + +/* PageB(0xB00) */ +#define	RPDP_ANTA			0xb00 +#define	RPDP_ANTA_4			0xb04 +#define	RPDP_ANTA_8			0xb08 +#define	RPDP_ANTA_C			0xb0c +#define	RPDP_ANTA_10			0xb10 +#define	RPDP_ANTA_14			0xb14 +#define	RPDP_ANTA_18			0xb18 +#define	RPDP_ANTA_1C			0xb1c +#define	RPDP_ANTA_20			0xb20 +#define	RPDP_ANTA_24			0xb24 + +#define	RCONFIG_PMPD_ANTA		0xb28 +#define	CONFIG_RAM64X16			0xb2c + +#define	RBNDA				0xb30 +#define	RHSSIPAR			0xb34 + +#define	RCONFIG_ANTA			0xb68 +#define	RCONFIG_ANTB			0xb6c + +#define	RPDP_ANTB			0xb70 +#define	RPDP_ANTB_4			0xb74 +#define	RPDP_ANTB_8			0xb78 +#define	RPDP_ANTB_C			0xb7c +#define	RPDP_ANTB_10			0xb80 +#define	RPDP_ANTB_14			0xb84 +#define	RPDP_ANTB_18			0xb88 +#define	RPDP_ANTB_1C			0xb8c +#define	RPDP_ANTB_20			0xb90 +#define	RPDP_ANTB_24			0xb94 + +#define	RCONFIG_PMPD_ANTB		0xb98 + +#define	RBNDB				0xba0 + +#define	RAPK				0xbd8 +#define	RPM_RX0_ANTA			0xbdc +#define	RPM_RX1_ANTA			0xbe0 +#define	RPM_RX2_ANTA			0xbe4 +#define	RPM_RX3_ANTA			0xbe8 +#define	RPM_RX0_ANTB			0xbec +#define	RPM_RX1_ANTB			0xbf0 +#define	RPM_RX2_ANTB			0xbf4 +#define	RPM_RX3_ANTB			0xbf8 + +/*Page C*/ +#define	ROFDM0_LSTF			0xc00 + +#define	ROFDM0_TRXPATHENABLE		0xc04 +#define	ROFDM0_TRMUXPAR			0xc08 +#define	ROFDM0_TRSWISOLATION		0xc0c + +#define	ROFDM0_XARXAFE			0xc10 +#define	ROFDM0_XARXIQIMBALANCE		0xc14 +#define	ROFDM0_XBRXAFE			0xc18 +#define	ROFDM0_XBRXIQIMBALANCE		0xc1c +#define	ROFDM0_XCRXAFE			0xc20 +#define	ROFDM0_XCRXIQIMBANLANCE		0xc24 +#define	ROFDM0_XDRXAFE			0xc28 +#define	ROFDM0_XDRXIQIMBALANCE		0xc2c + +#define	ROFDM0_RXDETECTOR1		0xc30 +#define	ROFDM0_RXDETECTOR2		0xc34 +#define	ROFDM0_RXDETECTOR3		0xc38 +#define	ROFDM0_RXDETECTOR4		0xc3c + +#define	ROFDM0_RXDSP			0xc40 +#define	ROFDM0_CFOANDDAGC		0xc44 +#define	ROFDM0_CCADROPTHRESHOLD		0xc48 +#define	ROFDM0_ECCATHRESHOLD		0xc4c + +#define	ROFDM0_XAAGCCORE1		0xc50 +#define	ROFDM0_XAAGCCORE2		0xc54 +#define	ROFDM0_XBAGCCORE1		0xc58 +#define	ROFDM0_XBAGCCORE2		0xc5c +#define	ROFDM0_XCAGCCORE1		0xc60 +#define	ROFDM0_XCAGCCORE2		0xc64 +#define	ROFDM0_XDAGCCORE1		0xc68 +#define	ROFDM0_XDAGCCORE2		0xc6c + +#define	ROFDM0_AGCPARAMETER1		0xc70 +#define	ROFDM0_AGCPARAMETER2		0xc74 +#define	ROFDM0_AGCRSSITABLE		0xc78 +#define	ROFDM0_HTSTFAGC			0xc7c + +#define	ROFDM0_XATXIQIMBALANCE		0xc80 +#define	ROFDM0_XATXAFE			0xc84 +#define	ROFDM0_XBTXIQIMBALANCE		0xc88 +#define	ROFDM0_XBTXAFE			0xc8c +#define	ROFDM0_XCTXIQIMBALANCE		0xc90 +#define	ROFDM0_XCTXAFE			0xc94 +#define	ROFDM0_XDTXIQIMBALANCE		0xc98 +#define	ROFDM0_XDTXAFE			0xc9c + +#define ROFDM0_RXIQEXTANTA		0xca0 +#define	ROFDM0_TXCOEFF1			0xca4 +#define	ROFDM0_TXCOEFF2			0xca8 +#define	ROFDM0_TXCOEFF3			0xcac +#define	ROFDM0_TXCOEFF4			0xcb0 +#define	ROFDM0_TXCOEFF5			0xcb4 +#define	ROFDM0_TXCOEFF6			0xcb8 + +#define	ROFDM0_RXHPPARAMETER		0xce0 +#define	ROFDM0_TXPSEUDONOISEWGT		0xce4 +#define	ROFDM0_FRAMESYNC		0xcf0 +#define	ROFDM0_DFSREPORT		0xcf4 + + +#define	ROFDM1_LSTF			0xd00 +#define	ROFDM1_TRXPATHENABLE		0xd04 + +#define	ROFDM1_CF0			0xd08 +#define	ROFDM1_CSI1			0xd10 +#define	ROFDM1_SBD			0xd14 +#define	ROFDM1_CSI2			0xd18 +#define	ROFDM1_CFOTRACKING		0xd2c +#define	ROFDM1_TRXMESAURE1		0xd34 +#define	ROFDM1_INTFDET			0xd3c +#define	ROFDM1_PSEUDONOISESTATEAB	0xd50 +#define	ROFDM1_PSEUDONOISESTATECD	0xd54 +#define	ROFDM1_RXPSEUDONOISEWGT		0xd58 + +#define	ROFDM_PHYCOUNTER1		0xda0 +#define	ROFDM_PHYCOUNTER2		0xda4 +#define	ROFDM_PHYCOUNTER3		0xda8 + +#define	ROFDM_SHORTCFOAB		0xdac +#define	ROFDM_SHORTCFOCD		0xdb0 +#define	ROFDM_LONGCFOAB			0xdb4 +#define	ROFDM_LONGCFOCD			0xdb8 +#define	ROFDM_TAILCF0AB			0xdbc +#define	ROFDM_TAILCF0CD			0xdc0 +#define	ROFDM_PWMEASURE1		0xdc4 +#define	ROFDM_PWMEASURE2		0xdc8 +#define	ROFDM_BWREPORT			0xdcc +#define	ROFDM_AGCREPORT			0xdd0 +#define	ROFDM_RXSNR			0xdd4 +#define	ROFDM_RXEVMCSI			0xdd8 +#define	ROFDM_SIGREPORT			0xddc + +#define	RTXAGC_A_RATE18_06		0xe00 +#define	RTXAGC_A_RATE54_24		0xe04 +#define	RTXAGC_A_CCK1_MCS32		0xe08 +#define	RTXAGC_A_MCS03_MCS00		0xe10 +#define	RTXAGC_A_MCS07_MCS04		0xe14 +#define	RTXAGC_A_MCS11_MCS08		0xe18 +#define	RTXAGC_A_MCS15_MCS12		0xe1c + +#define	RTXAGC_B_RATE18_06		0x830 +#define	RTXAGC_B_RATE54_24		0x834 +#define	RTXAGC_B_CCK1_55_MCS32		0x838 +#define	RTXAGC_B_MCS03_MCS00		0x83c +#define	RTXAGC_B_MCS07_MCS04		0x848 +#define	RTXAGC_B_MCS11_MCS08		0x84c +#define	RTXAGC_B_MCS15_MCS12		0x868 +#define	RTXAGC_B_CCK11_A_CCK2_11	0x86c + +#define	RFPGA0_IQK			0xe28 +#define	RTX_IQK_TONE_A			0xe30 +#define	RRX_IQK_TONE_A			0xe34 +#define	RTX_IQK_PI_A			0xe38 +#define	RRX_IQK_PI_A			0xe3c + +#define	RTX_IQK				0xe40 +#define	RRX_IQK				0xe44 +#define	RIQK_AGC_PTS			0xe48 +#define	RIQK_AGC_RSP			0xe4c +#define	RTX_IQK_TONE_B			0xe50 +#define	RRX_IQK_TONE_B			0xe54 +#define	RTX_IQK_PI_B			0xe58 +#define	RRX_IQK_PI_B			0xe5c +#define	RIQK_AGC_CONT			0xe60 + +#define	RBLUE_TOOTH			0xe6c +#define	RRX_WAIT_CCA			0xe70 +#define	RTX_CCK_RFON			0xe74 +#define	RTX_CCK_BBON			0xe78 +#define	RTX_OFDM_RFON			0xe7c +#define	RTX_OFDM_BBON			0xe80 +#define	RTX_TO_RX			0xe84 +#define	RTX_TO_TX			0xe88 +#define	RRX_CCK				0xe8c + +#define	RTX_POWER_BEFORE_IQK_A		0xe94 +#define	RTX_POWER_AFTER_IQK_A		0xe9c + +#define	RRX_POWER_BEFORE_IQK_A		0xea0 +#define	RRX_POWER_BEFORE_IQK_A_2	0xea4 +#define	RRX_POWER_AFTER_IQK_A		0xea8 +#define	RRX_POWER_AFTER_IQK_A_2		0xeac + +#define	RTX_POWER_BEFORE_IQK_B		0xeb4 +#define	RTX_POWER_AFTER_IQK_B		0xebc + +#define	RRX_POWER_BEFORE_IQK_B		0xec0 +#define	RRX_POWER_BEFORE_IQK_B_2	0xec4 +#define	RRX_POWER_AFTER_IQK_B		0xec8 +#define	RRX_POWER_AFTER_IQK_B_2		0xecc + +#define	RRX_OFDM			0xed0 +#define	RRX_WAIT_RIFS			0xed4 +#define	RRX_TO_RX			0xed8 +#define	RSTANDBY			0xedc +#define	RSLEEP				0xee0 +#define	RPMPD_ANAEN			0xeec + +#define	RZEBRA1_HSSIENABLE		0x0 +#define	RZEBRA1_TRXENABLE1		0x1 +#define	RZEBRA1_TRXENABLE2		0x2 +#define	RZEBRA1_AGC			0x4 +#define	RZEBRA1_CHARGEPUMP		0x5 +#define	RZEBRA1_CHANNEL			0x7 + +#define	RZEBRA1_TXGAIN			0x8 +#define	RZEBRA1_TXLPF			0x9 +#define	RZEBRA1_RXLPF			0xb +#define	RZEBRA1_RXHPFCORNER		0xc + +#define	RGLOBALCTRL			0 +#define	RRTL8256_TXLPF			19 +#define	RRTL8256_RXLPF			11 +#define	RRTL8258_TXLPF			0x11 +#define	RRTL8258_RXLPF			0x13 +#define	RRTL8258_RSSILPF		0xa + +#define	RF_AC				0x00 + +#define	RF_IQADJ_G1			0x01 +#define	RF_IQADJ_G2			0x02 +#define	RF_POW_TRSW			0x05 + +#define	RF_GAIN_RX			0x06 +#define	RF_GAIN_TX			0x07 + +#define	RF_TXM_IDAC			0x08 +#define	RF_BS_IQGEN			0x0F + +#define	RF_MODE1			0x10 +#define	RF_MODE2			0x11 + +#define	RF_RX_AGC_HP			0x12 +#define	RF_TX_AGC			0x13 +#define	RF_BIAS				0x14 +#define	RF_IPA				0x15 +#define	RF_POW_ABILITY			0x17 +#define	RF_MODE_AG			0x18 +#define	RRFCHANNEL			0x18 +#define	RF_CHNLBW			0x18 +#define	RF_TOP				0x19 + +#define	RF_RX_G1			0x1A +#define	RF_RX_G2			0x1B + +#define	RF_RX_BB2			0x1C +#define	RF_RX_BB1			0x1D + +#define	RF_RCK1				0x1E +#define	RF_RCK2				0x1F + +#define	RF_TX_G1			0x20 +#define	RF_TX_G2			0x21 +#define	RF_TX_G3			0x22 + +#define	RF_TX_BB1			0x23 +#define	RF_T_METER			0x42 + +#define	RF_SYN_G1			0x25 +#define	RF_SYN_G2			0x26 +#define	RF_SYN_G3			0x27 +#define	RF_SYN_G4			0x28 +#define	RF_SYN_G5			0x29 +#define	RF_SYN_G6			0x2A +#define	RF_SYN_G7			0x2B +#define	RF_SYN_G8			0x2C + +#define	RF_RCK_OS			0x30 +#define	RF_TXPA_G1			0x31 +#define	RF_TXPA_G2			0x32 +#define	RF_TXPA_G3			0x33 + +#define	RF_TX_BIAS_A			0x35 +#define	RF_TX_BIAS_D			0x36 +#define	RF_LOBF_9			0x38 +#define	RF_RXRF_A3			0x3C +#define	RF_TRSW				0x3F + +#define	RF_TXRF_A2			0x41 +#define	RF_TXPA_G4			0x46 +#define	RF_TXPA_A4			0x4B + +#define	RF_WE_LUT			0xEF + +#define	BBBRESETB			0x100 +#define	BGLOBALRESETB			0x200 +#define	BOFDMTXSTART			0x4 +#define	BCCKTXSTART			0x8 +#define	BCRC32DEBUG			0x100 +#define	BPMACLOOPBACK			0x10 +#define	BTXLSIG				0xffffff +#define	BOFDMTXRATE			0xf +#define	BOFDMTXRESERVED			0x10 +#define	BOFDMTXLENGTH			0x1ffe0 +#define	BOFDMTXPARITY			0x20000 +#define	BTXHTSIG1			0xffffff +#define	BTXHTMCSRATE			0x7f +#define	BTXHTBW				0x80 +#define	BTXHTLENGTH			0xffff00 +#define	BTXHTSIG2			0xffffff +#define	BTXHTSMOOTHING			0x1 +#define	BTXHTSOUNDING			0x2 +#define	BTXHTRESERVED			0x4 +#define	BTXHTAGGREATION			0x8 +#define	BTXHTSTBC			0x30 +#define	BTXHTADVANCECODING		0x40 +#define	BTXHTSHORTGI			0x80 +#define	BTXHTNUMBERHT_LTF		0x300 +#define	BTXHTCRC8			0x3fc00 +#define	BCOUNTERRESET			0x10000 +#define	BNUMOFOFDMTX			0xffff +#define	BNUMOFCCKTX			0xffff0000 +#define	BTXIDLEINTERVAL			0xffff +#define	BOFDMSERVICE			0xffff0000 +#define	BTXMACHEADER			0xffffffff +#define	BTXDATAINIT			0xff +#define	BTXHTMODE			0x100 +#define	BTXDATATYPE			0x30000 +#define	BTXRANDOMSEED			0xffffffff +#define	BCCKTXPREAMBLE			0x1 +#define	BCCKTXSFD			0xffff0000 +#define	BCCKTXSIG			0xff +#define	BCCKTXSERVICE			0xff00 +#define	BCCKLENGTHEXT			0x8000 +#define	BCCKTXLENGHT			0xffff0000 +#define	BCCKTXCRC16			0xffff +#define	BCCKTXSTATUS			0x1 +#define	BOFDMTXSTATUS			0x2 +#define IS_BB_REG_OFFSET_92S(_offset)	\ +	((_offset >= 0x800) && (_offset <= 0xfff)) + +#define	BRFMOD				0x1 +#define	BJAPANMODE			0x2 +#define	BCCKTXSC			0x30 +#define	BCCKEN				0x1000000 +#define	BOFDMEN				0x2000000 + +#define	BOFDMRXADCPHASE			0x10000 +#define	BOFDMTXDACPHASE			0x40000 +#define	BXATXAGC			0x3f + +#define	BXBTXAGC			0xf00 +#define	BXCTXAGC			0xf000 +#define	BXDTXAGC			0xf0000 + +#define	BPASTART			0xf0000000 +#define	BTRSTART			0x00f00000 +#define	BRFSTART			0x0000f000 +#define	BBBSTART			0x000000f0 +#define	BBBCCKSTART			0x0000000f +#define	BPAEND				0xf +#define	BTREND				0x0f000000 +#define	BRFEND				0x000f0000 +#define	BCCAMASK			0x000000f0 +#define	BR2RCCAMASK			0x00000f00 +#define	BHSSI_R2TDELAY			0xf8000000 +#define	BHSSI_T2RDELAY			0xf80000 +#define	BCONTXHSSI			0x400 +#define	BIGFROMCCK			0x200 +#define	BAGCADDRESS			0x3f +#define	BRXHPTX				0x7000 +#define	BRXHP2RX			0x38000 +#define	BRXHPCCKINI			0xc0000 +#define	BAGCTXCODE			0xc00000 +#define	BAGCRXCODE			0x300000 + +#define	B3WIREDATALENGTH		0x800 +#define	B3WIREADDREAALENGTH		0x400 + +#define	B3WIRERFPOWERDOWN		0x1 +#define	B5GPAPEPOLARITY			0x40000000 +#define	B2GPAPEPOLARITY			0x80000000 +#define	BRFSW_TXDEFAULTANT		0x3 +#define	BRFSW_TXOPTIONANT		0x30 +#define	BRFSW_RXDEFAULTANT		0x300 +#define	BRFSW_RXOPTIONANT		0x3000 +#define	BRFSI_3WIREDATA			0x1 +#define	BRFSI_3WIRECLOCK		0x2 +#define	BRFSI_3WIRELOAD			0x4 +#define	BRFSI_3WIRERW			0x8 +#define	BRFSI_3WIRE			0xf + +#define	BRFSI_RFENV			0x10 + +#define	BRFSI_TRSW			0x20 +#define	BRFSI_TRSWB			0x40 +#define	BRFSI_ANTSW			0x100 +#define	BRFSI_ANTSWB			0x200 +#define	BRFSI_PAPE			0x400 +#define	BRFSI_PAPE5G			0x800 +#define	BBANDSELECT			0x1 +#define	BHTSIG2_GI			0x80 +#define	BHTSIG2_SMOOTHING		0x01 +#define	BHTSIG2_SOUNDING		0x02 +#define	BHTSIG2_AGGREATON		0x08 +#define	BHTSIG2_STBC			0x30 +#define	BHTSIG2_ADVCODING		0x40 +#define	BHTSIG2_NUMOFHTLTF		0x300 +#define	BHTSIG2_CRC8			0x3fc +#define	BHTSIG1_MCS			0x7f +#define	BHTSIG1_BANDWIDTH		0x80 +#define	BHTSIG1_HTLENGTH		0xffff +#define	BLSIG_RATE			0xf +#define	BLSIG_RESERVED			0x10 +#define	BLSIG_LENGTH			0x1fffe +#define	BLSIG_PARITY			0x20 +#define	BCCKRXPHASE			0x4 + +#define	BLSSIREADADDRESS		0x7f800000 +#define	BLSSIREADEDGE			0x80000000 + +#define	BLSSIREADBACKDATA		0xfffff + +#define	BLSSIREADOKFLAG			0x1000 +#define	BCCKSAMPLERATE			0x8 +#define	BREGULATOR0STANDBY		0x1 +#define	BREGULATORPLLSTANDBY		0x2 +#define	BREGULATOR1STANDBY		0x4 +#define	BPLLPOWERUP			0x8 +#define	BDPLLPOWERUP			0x10 +#define	BDA10POWERUP			0x20 +#define	BAD7POWERUP			0x200 +#define	BDA6POWERUP			0x2000 +#define	BXTALPOWERUP			0x4000 +#define	B40MDCLKPOWERUP			0x8000 +#define	BDA6DEBUGMODE			0x20000 +#define	BDA6SWING			0x380000 + +#define	BADCLKPHASE			0x4000000 +#define	B80MCLKDELAY	0x18000000 +#define	BAFEWATCHDOGENABLE	0x20000000 + +#define	BXTALCAP01	0xc0000000 +#define	BXTALCAP23	0x3 +#define	BXTALCAP92X			0x0f000000 +#define BXTALCAP	0x0f000000 + +#define	BINTDIFCLKENABLE		0x400 +#define	BEXTSIGCLKENABLE		0x800 +#define	BBANDGAP_MBIAS_POWERUP		0x10000 +#define	BAD11SH_GAIN			0xc0000 +#define	BAD11NPUT_RANGE			0x700000 +#define	BAD110P_CURRENT			0x3800000 +#define	BLPATH_LOOPBACK			0x4000000 +#define	BQPATH_LOOPBACK			0x8000000 +#define	BAFE_LOOPBACK			0x10000000 +#define	BDA10_SWING			0x7e0 +#define	BDA10_REVERSE			0x800 +#define	BDA_CLK_SOURCE			0x1000 +#define	BDA7INPUT_RANGE			0x6000 +#define	BDA7_GAIN			0x38000 +#define	BDA7OUTPUT_CM_MODE		0x40000 +#define	BDA7INPUT_CM_MODE		0x380000 +#define	BDA7CURRENT			0xc00000 +#define	BREGULATOR_ADJUST		0x7000000 +#define	BAD11POWERUP_ATTX		0x1 +#define	BDA10PS_ATTX			0x10 +#define	BAD11POWERUP_ATRX		0x100 +#define	BDA10PS_ATRX			0x1000 +#define	BCCKRX_AGC_FORMAT		0x200 +#define	BPSDFFT_SAMPLE_POINT		0xc000 +#define	BPSD_AVERAGE_NUM		0x3000 +#define	BIQPATH_CONTROL	0xc00 +#define	BPSD_FREQ			0x3ff +#define	BPSD_ANTENNA_PATH		0x30 +#define	BPSD_IQ_SWITCH			0x40 +#define	BPSD_RX_TRIGGER			0x400000 +#define	BPSD_TX_TRIGGER			0x80000000 +#define	BPSD_SINE_TONE_SCALE		0x7f000000 +#define	BPSD_REPORT			0xffff + +#define	BOFDM_TXSC			0x30000000 +#define	BCCK_TXON			0x1 +#define	BOFDM_TXON			0x2 +#define	BDEBUG_PAGE			0xfff +#define	BDEBUG_ITEM			0xff +#define	BANTL				0x10 +#define	BANT_NONHT			0x100 +#define	BANT_HT1			0x1000 +#define	BANT_HT2			0x10000 +#define	BANT_HT1S1			0x100000 +#define	BANT_NONHTS1			0x1000000 + +#define	BCCK_BBMODE			0x3 +#define	BCCK_TXPOWERSAVING		0x80 +#define	BCCK_RXPOWERSAVING		0x40 + +#define	BCCK_SIDEBAND			0x10 + +#define	BCCK_SCRAMBLE			0x8 +#define	BCCK_ANTDIVERSITY		0x8000 +#define	BCCK_CARRIER_RECOVERY		0x4000 +#define	BCCK_TXRATE			0x3000 +#define	BCCK_DCCANCEL			0x0800 +#define	BCCK_ISICANCEL			0x0400 +#define	BCCK_MATCH_FILTER		0x0200 +#define	BCCK_EQUALIZER			0x0100 +#define	BCCK_PREAMBLE_DETECT		0x800000 +#define	BCCK_FAST_FALSECCA		0x400000 +#define	BCCK_CH_ESTSTART		0x300000 +#define	BCCK_CCA_COUNT			0x080000 +#define	BCCK_CS_LIM			0x070000 +#define	BCCK_BIST_MODE			0x80000000 +#define	BCCK_CCAMASK			0x40000000 +#define	BCCK_TX_DAC_PHASE		0x4 +#define	BCCK_RX_ADC_PHASE		0x20000000 +#define	BCCKR_CP_MODE			0x0100 +#define	BCCK_TXDC_OFFSET		0xf0 +#define	BCCK_RXDC_OFFSET		0xf +#define	BCCK_CCA_MODE			0xc000 +#define	BCCK_FALSECS_LIM		0x3f00 +#define	BCCK_CS_RATIO			0xc00000 +#define	BCCK_CORGBIT_SEL		0x300000 +#define	BCCK_PD_LIM			0x0f0000 +#define	BCCK_NEWCCA			0x80000000 +#define	BCCK_RXHP_OF_IG			0x8000 +#define	BCCK_RXIG			0x7f00 +#define	BCCK_LNA_POLARITY		0x800000 +#define	BCCK_RX1ST_BAIN			0x7f0000 +#define	BCCK_RF_EXTEND			0x20000000 +#define	BCCK_RXAGC_SATLEVEL		0x1f000000 +#define	BCCK_RXAGC_SATCOUNT		0xe0 +#define	BCCKRXRFSETTLE			0x1f +#define	BCCK_FIXED_RXAGC		0x8000 +#define	BCCK_ANTENNA_POLARITY		0x2000 +#define	BCCK_TXFILTER_TYPE		0x0c00 +#define	BCCK_RXAGC_REPORTTYPE		0x0300 +#define	BCCK_RXDAGC_EN			0x80000000 +#define	BCCK_RXDAGC_PERIOD		0x20000000 +#define	BCCK_RXDAGC_SATLEVEL		0x1f000000 +#define	BCCK_TIMING_RECOVERY		0x800000 +#define	BCCK_TXC0			0x3f0000 +#define	BCCK_TXC1			0x3f000000 +#define	BCCK_TXC2			0x3f +#define	BCCK_TXC3			0x3f00 +#define	BCCK_TXC4			0x3f0000 +#define	BCCK_TXC5			0x3f000000 +#define	BCCK_TXC6			0x3f +#define	BCCK_TXC7			0x3f00 +#define	BCCK_DEBUGPORT			0xff0000 +#define	BCCK_DAC_DEBUG			0x0f000000 +#define	BCCK_FALSEALARM_ENABLE		0x8000 +#define	BCCK_FALSEALARM_READ		0x4000 +#define	BCCK_TRSSI			0x7f +#define	BCCK_RXAGC_REPORT		0xfe +#define	BCCK_RXREPORT_ANTSEL		0x80000000 +#define	BCCK_RXREPORT_MFOFF		0x40000000 +#define	BCCK_RXREPORT_SQLOSS		0x20000000 +#define	BCCK_RXREPORT_PKTLOSS		0x10000000 +#define	BCCK_RXREPORT_LOCKEDBIT		0x08000000 +#define	BCCK_RXREPORT_RATEERROR		0x04000000 +#define	BCCK_RXREPORT_RXRATE		0x03000000 +#define	BCCK_RXFA_COUNTER_LOWER		0xff +#define	BCCK_RXFA_COUNTER_UPPER		0xff000000 +#define	BCCK_RXHPAGC_START		0xe000 +#define	BCCK_RXHPAGC_FINAL		0x1c00 +#define	BCCK_RXFALSEALARM_ENABLE	0x8000 +#define	BCCK_FACOUNTER_FREEZE		0x4000 +#define	BCCK_TXPATH_SEL			0x10000000 +#define	BCCK_DEFAULT_RXPATH		0xc000000 +#define	BCCK_OPTION_RXPATH		0x3000000 + +#define	BNUM_OFSTF	0x3 +#define	BSHIFT_L	0xc0 +#define	BGI_TH	0xc +#define	BRXPATH_A	0x1 +#define	BRXPATH_B	0x2 +#define	BRXPATH_C	0x4 +#define	BRXPATH_D	0x8 +#define	BTXPATH_A	0x1 +#define	BTXPATH_B	0x2 +#define	BTXPATH_C	0x4 +#define	BTXPATH_D	0x8 +#define	BTRSSI_FREQ	0x200 +#define	BADC_BACKOFF	0x3000 +#define	BDFIR_BACKOFF	0xc000 +#define	BTRSSI_LATCH_PHASE	0x10000 +#define	BRX_LDC_OFFSET	0xff +#define	BRX_QDC_OFFSET	0xff00 +#define	BRX_DFIR_MODE	0x1800000 +#define	BRX_DCNF_TYPE	0xe000000 +#define	BRXIQIMB_A	0x3ff +#define	BRXIQIMB_B	0xfc00 +#define	BRXIQIMB_C	0x3f0000 +#define	BRXIQIMB_D	0xffc00000 +#define	BDC_DC_NOTCH	0x60000 +#define	BRXNB_NOTCH	0x1f000000 +#define	BPD_TH	0xf +#define	BPD_TH_OPT2	0xc000 +#define	BPWED_TH	0x700 +#define	BIFMF_WIN_L	0x800 +#define	BPD_OPTION	0x1000 +#define	BMF_WIN_L	0xe000 +#define	BBW_SEARCH_L	0x30000 +#define	BWIN_ENH_L	0xc0000 +#define	BBW_TH	0x700000 +#define	BED_TH2	0x3800000 +#define	BBW_OPTION	0x4000000 +#define	BRADIO_TH	0x18000000 +#define	BWINDOW_L	0xe0000000 +#define	BSBD_OPTION	0x1 +#define	BFRAME_TH	0x1c +#define	BFS_OPTION	0x60 +#define	BDC_SLOPE_CHECK	0x80 +#define	BFGUARD_COUNTER_DC_L	0xe00 +#define	BFRAME_WEIGHT_SHORT	0x7000 +#define	BSUB_TUNE	0xe00000 +#define	BFRAME_DC_LENGTH	0xe000000 +#define	BSBD_START_OFFSET	0x30000000 +#define	BFRAME_TH_2	0x7 +#define	BFRAME_GI2_TH	0x38 +#define	BGI2_SYNC_EN	0x40 +#define	BSARCH_SHORT_EARLY	0x300 +#define	BSARCH_SHORT_LATE	0xc00 +#define	BSARCH_GI2_LATE	0x70000 +#define	BCFOANTSUM	0x1 +#define	BCFOACC	0x2 +#define	BCFOSTARTOFFSET	0xc +#define	BCFOLOOPBACK	0x70 +#define	BCFOSUMWEIGHT	0x80 +#define	BDAGCENABLE	0x10000 +#define	BTXIQIMB_A	0x3ff +#define	BTXIQIMB_b	0xfc00 +#define	BTXIQIMB_C	0x3f0000 +#define	BTXIQIMB_D	0xffc00000 +#define	BTXIDCOFFSET	0xff +#define	BTXIQDCOFFSET	0xff00 +#define	BTXDFIRMODE	0x10000 +#define	BTXPESUDO_NOISEON	0x4000000 +#define	BTXPESUDO_NOISE_A	0xff +#define	BTXPESUDO_NOISE_B	0xff00 +#define	BTXPESUDO_NOISE_C	0xff0000 +#define	BTXPESUDO_NOISE_D	0xff000000 +#define	BCCA_DROPOPTION	0x20000 +#define	BCCA_DROPTHRES	0xfff00000 +#define	BEDCCA_H	0xf +#define	BEDCCA_L	0xf0 +#define	BLAMBDA_ED	0x300 +#define	BRX_INITIALGAIN	0x7f +#define	BRX_ANTDIV_EN	0x80 +#define	BRX_AGC_ADDRESS_FOR_LNA		0x7f00 +#define	BRX_HIGHPOWER_FLOW	0x8000 +#define	BRX_AGC_FREEZE_THRES		0xc0000 +#define	BRX_FREEZESTEP_AGC1	0x300000 +#define	BRX_FREEZESTEP_AGC2	0xc00000 +#define	BRX_FREEZESTEP_AGC3	0x3000000 +#define	BRX_FREEZESTEP_AGC0	0xc000000 +#define	BRXRSSI_CMP_EN	0x10000000 +#define	BRXQUICK_AGCEN	0x20000000 +#define	BRXAGC_FREEZE_THRES_MODE	0x40000000 +#define	BRX_OVERFLOW_CHECKTYPE	0x80000000 +#define	BRX_AGCSHIFT	0x7f +#define	BTRSW_TRI_ONLY	0x80 +#define	BPOWER_THRES	0x300 +#define	BRXAGC_EN	0x1 +#define	BRXAGC_TOGETHER_EN	0x2 +#define	BRXAGC_MIN	0x4 +#define	BRXHP_INI	0x7 +#define	BRXHP_TRLNA	0x70 +#define	BRXHP_RSSI	0x700 +#define	BRXHP_BBP1	0x7000 +#define	BRXHP_BBP2	0x70000 +#define	BRXHP_BBP3	0x700000 +#define	BRSSI_H	0x7f0000 +#define	BRSSI_GEN	0x7f000000 +#define	BRXSETTLE_TRSW	0x7 +#define	BRXSETTLE_LNA	0x38 +#define	BRXSETTLE_RSSI	0x1c0 +#define	BRXSETTLE_BBP	0xe00 +#define	BRXSETTLE_RXHP	0x7000 +#define	BRXSETTLE_ANTSW_RSSI	0x38000 +#define	BRXSETTLE_ANTSW	0xc0000 +#define	BRXPROCESS_TIME_DAGC	0x300000 +#define	BRXSETTLE_HSSI	0x400000 +#define	BRXPROCESS_TIME_BBPPW	0x800000 +#define	BRXANTENNA_POWER_SHIFT	0x3000000 +#define	BRSSI_TABLE_SELECT	0xc000000 +#define	BRXHP_FINAL	0x7000000 +#define	BRXHPSETTLE_BBP	0x7 +#define	BRXHTSETTLE_HSSI	0x8 +#define	BRXHTSETTLE_RXHP	0x70 +#define	BRXHTSETTLE_BBPPW	0x80 +#define	BRXHTSETTLE_IDLE	0x300 +#define	BRXHTSETTLE_RESERVED	0x1c00 +#define	BRXHT_RXHP_EN	0x8000 +#define	BRXAGC_FREEZE_THRES	0x30000 +#define	BRXAGC_TOGETHEREN	0x40000 +#define	BRXHTAGC_MIN	0x80000 +#define	BRXHTAGC_EN	0x100000 +#define	BRXHTDAGC_EN	0x200000 +#define	BRXHT_RXHP_BBP	0x1c00000 +#define	BRXHT_RXHP_FINAL	0xe0000000 +#define	BRXPW_RADIO_TH	0x3 +#define	BRXPW_RADIO_EN	0x4 +#define	BRXMF_HOLD	0x3800 +#define	BRXPD_DELAY_TH1	0x38 +#define	BRXPD_DELAY_TH2	0x1c0 +#define	BRXPD_DC_COUNT_MAX	0x600 +#define	BRXPD_DELAY_TH	0x8000 +#define	BRXPROCESS_DELAY	0xf0000 +#define	BRXSEARCHRANGE_GI2_EARLY	0x700000 +#define	BRXFRAME_FUARD_COUNTER_L	0x3800000 +#define	BRXSGI_GUARD_L	0xc000000 +#define	BRXSGI_SEARCH_L	0x30000000 +#define	BRXSGI_TH	0xc0000000 +#define	BDFSCNT0	0xff +#define	BDFSCNT1	0xff00 +#define	BDFSFLAG	0xf0000 +#define	BMF_WEIGHT_SUM	0x300000 +#define	BMINIDX_TH	0x7f000000 +#define	BDAFORMAT	0x40000 +#define	BTXCH_EMU_ENABLE	0x01000000 +#define	BTRSW_ISOLATION_A	0x7f +#define	BTRSW_ISOLATION_B	0x7f00 +#define	BTRSW_ISOLATION_C	0x7f0000 +#define	BTRSW_ISOLATION_D	0x7f000000 +#define	BEXT_LNA_GAIN	0x7c00 + +#define	BSTBC_EN	0x4 +#define	BANTENNA_MAPPING	0x10 +#define	BNSS	0x20 +#define	BCFO_ANTSUM_ID			0x200 +#define	BPHY_COUNTER_RESET	0x8000000 +#define	BCFO_REPORT_GET	0x4000000 +#define	BOFDM_CONTINUE_TX	0x10000000 +#define	BOFDM_SINGLE_CARRIER	0x20000000 +#define	BOFDM_SINGLE_TONE	0x40000000 +#define	BHT_DETECT	0x100 +#define	BCFOEN	0x10000 +#define	BCFOVALUE	0xfff00000 +#define	BSIGTONE_RE	0x3f +#define	BSIGTONE_IM	0x7f00 +#define	BCOUNTER_CCA	0xffff +#define	BCOUNTER_PARITYFAIL	0xffff0000 +#define	BCOUNTER_RATEILLEGAL	0xffff +#define	BCOUNTER_CRC8FAIL	0xffff0000 +#define	BCOUNTER_MCSNOSUPPORT	0xffff +#define	BCOUNTER_FASTSYNC	0xffff +#define	BSHORTCFO	0xfff +#define	BSHORTCFOT_LENGTH	12 +#define	BSHORTCFOF_LENGTH	11 +#define	BLONGCFO	0x7ff +#define	BLONGCFOT_LENGTH	11 +#define	BLONGCFOF_LENGTH	11 +#define	BTAILCFO	0x1fff +#define	BTAILCFOT_LENGTH	13 +#define	BTAILCFOF_LENGTH	12 +#define	BNOISE_EN_PWDB	0xffff +#define	BCC_POWER_DB	0xffff0000 +#define	BMOISE_PWDB	0xffff +#define	BPOWERMEAST_LENGTH	10 +#define	BPOWERMEASF_LENGTH	3 +#define	BRX_HT_BW	0x1 +#define	BRXSC	0x6 +#define	BRX_HT	0x8 +#define	BNB_INTF_DET_ON	0x1 +#define	BINTF_WIN_LEN_CFG	0x30 +#define	BNB_INTF_TH_CFG	0x1c0 +#define	BRFGAIN	0x3f +#define	BTABLESEL	0x40 +#define	BTRSW	0x80 +#define	BRXSNR_A	0xff +#define	BRXSNR_B	0xff00 +#define	BRXSNR_C	0xff0000 +#define	BRXSNR_D	0xff000000 +#define	BSNR_EVMT_LENGTH	8 +#define	BSNR_EVMF_LENGTH	1 +#define	BCSI1ST	0xff +#define	BCSI2ND	0xff00 +#define	BRXEVM1ST	0xff0000 +#define	BRXEVM2ND	0xff000000 +#define	BSIGEVM	0xff +#define	BPWDB	0xff00 +#define	BSGIEN	0x10000 + +#define	BSFACTOR_QMA1	0xf +#define	BSFACTOR_QMA2	0xf0 +#define	BSFACTOR_QMA3	0xf00 +#define	BSFACTOR_QMA4	0xf000 +#define	BSFACTOR_QMA5	0xf0000 +#define	BSFACTOR_QMA6	0xf0000 +#define	BSFACTOR_QMA7	0xf00000 +#define	BSFACTOR_QMA8	0xf000000 +#define	BSFACTOR_QMA9	0xf0000000 +#define	BCSI_SCHEME	0x100000 + +#define	BNOISE_LVL_TOP_SET		0x3 +#define	BCHSMOOTH	0x4 +#define	BCHSMOOTH_CFG1	0x38 +#define	BCHSMOOTH_CFG2	0x1c0 +#define	BCHSMOOTH_CFG3	0xe00 +#define	BCHSMOOTH_CFG4	0x7000 +#define	BMRCMODE	0x800000 +#define	BTHEVMCFG	0x7000000 + +#define	BLOOP_FIT_TYPE	0x1 +#define	BUPD_CFO	0x40 +#define	BUPD_CFO_OFFDATA	0x80 +#define	BADV_UPD_CFO	0x100 +#define	BADV_TIME_CTRL	0x800 +#define	BUPD_CLKO	0x1000 +#define	BFC	0x6000 +#define	BTRACKING_MODE	0x8000 +#define	BPHCMP_ENABLE	0x10000 +#define	BUPD_CLKO_LTF	0x20000 +#define	BCOM_CH_CFO	0x40000 +#define	BCSI_ESTI_MODE	0x80000 +#define	BADV_UPD_EQZ	0x100000 +#define	BUCHCFG	0x7000000 +#define	BUPDEQZ	0x8000000 + +#define	BRX_PESUDO_NOISE_ON		0x20000000 +#define	BRX_PESUDO_NOISE_A	0xff +#define	BRX_PESUDO_NOISE_B	0xff00 +#define	BRX_PESUDO_NOISE_C	0xff0000 +#define	BRX_PESUDO_NOISE_D	0xff000000 +#define	BRX_PESUDO_NOISESTATE_A		0xffff +#define	BRX_PESUDO_NOISESTATE_B		0xffff0000 +#define	BRX_PESUDO_NOISESTATE_C		0xffff +#define	BRX_PESUDO_NOISESTATE_D		0xffff0000 + +#define	BZEBRA1_HSSIENABLE	0x8 +#define	BZEBRA1_TRXCONTROL	0xc00 +#define	BZEBRA1_TRXGAINSETTING	0x07f +#define	BZEBRA1_RXCOUNTER	0xc00 +#define	BZEBRA1_TXCHANGEPUMP	0x38 +#define	BZEBRA1_RXCHANGEPUMP	0x7 +#define	BZEBRA1_CHANNEL_NUM	0xf80 +#define	BZEBRA1_TXLPFBW	0x400 +#define	BZEBRA1_RXLPFBW	0x600 + +#define	BRTL8256REG_MODE_CTRL1		0x100 +#define	BRTL8256REG_MODE_CTRL0		0x40 +#define	BRTL8256REG_TXLPFBW		0x18 +#define	BRTL8256REG_RXLPFBW		0x600 + +#define	BRTL8258_TXLPFBW	0xc +#define	BRTL8258_RXLPFBW	0xc00 +#define	BRTL8258_RSSILPFBW	0xc0 + +#define	BBYTE0	0x1 +#define	BBYTE1	0x2 +#define	BBYTE2	0x4 +#define	BBYTE3	0x8 +#define	BWORD0	0x3 +#define	BWORD1	0xc +#define	BWORD	0xf + +#define	BENABLE	0x1 +#define	BDISABLE	0x0 + +#define	LEFT_ANTENNA	0x0 +#define	RIGHT_ANTENNA	0x1 + +#define	TCHECK_TXSTATUS	500 +#define	TUPDATE_RXCOUNTER	100 + +#define	REG_UN_used_register		0x01bf + +/* WOL bit information */ +#define	HAL92C_WOL_PTK_UPDATE_EVENT	BIT(0) +#define	HAL92C_WOL_GTK_UPDATE_EVENT	BIT(1) +#define	HAL92C_WOL_DISASSOC_EVENT	BIT(2) +#define	HAL92C_WOL_DEAUTH_EVENT		BIT(3) +#define	HAL92C_WOL_FW_DISCONNECT_EVENT	BIT(4) + +#define		WOL_REASON_PTK_UPDATE		BIT(0) +#define		WOL_REASON_GTK_UPDATE		BIT(1) +#define		WOL_REASON_DISASSOC		BIT(2) +#define		WOL_REASON_DEAUTH		BIT(3) +#define		WOL_REASON_FW_DISCONNECT	BIT(4) + +/* 2 EFUSE_TEST (For RTL8723 partially) */ +#define EFUSE_SEL(x)				(((x) & 0x3) << 8) +#define EFUSE_SEL_MASK				0x300 +#define EFUSE_WIFI_SEL_0			0x0 + +#define	WL_HWPDN_EN	BIT(0)	/* Enable GPIO[9] as WiFi HW PDn source*/ +#define	WL_HWPDN_SL	BIT(1)	/* WiFi HW PDn polarity control*/ + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.c b/drivers/net/wireless/rtlwifi/rtl8723be/rf.c new file mode 100644 index 00000000000..486294930a7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/rf.c @@ -0,0 +1,504 @@ +/****************************************************************************** + * + * 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 "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl8723be_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); + +	switch (bandwidth) { +	case HT_CHANNEL_WIDTH_20: +		rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & +					     0xfffff3ff) | BIT(10) | BIT(11)); +		rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, +			      rtlphy->rfreg_chnlval[0]); +		break; +	case HT_CHANNEL_WIDTH_20_40: +		rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & +					     0xfffff3ff) | BIT(10)); +		rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, +			      rtlphy->rfreg_chnlval[0]); +		break; +	default: +		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, +			 "unknown bandwidth: %#X\n", bandwidth); +		break; +	} +} + +void rtl8723be_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +					  u8 *ppowerlevel) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	u32 tx_agc[2] = {0, 0}, tmpval; +	bool turbo_scanoff = false; +	u8 idx1, idx2; +	u8 *ptr; +	u8 direction; +	u32 pwrtrac_value; + +	if (rtlefuse->eeprom_regulatory != 0) +		turbo_scanoff = true; + +	if (mac->act_scanning) { +		tx_agc[RF90_PATH_A] = 0x3f3f3f3f; +		tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + +		if (turbo_scanoff) { +			for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { +				tx_agc[idx1] = ppowerlevel[idx1] | +					       (ppowerlevel[idx1] << 8) | +					       (ppowerlevel[idx1] << 16) | +					       (ppowerlevel[idx1] << 24); +			} +		} +	} else { +		for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { +			tx_agc[idx1] = ppowerlevel[idx1] | +				       (ppowerlevel[idx1] << 8) | +				       (ppowerlevel[idx1] << 16) | +				       (ppowerlevel[idx1] << 24); +		} +		if (rtlefuse->eeprom_regulatory == 0) { +			tmpval = +			    (rtlphy->mcs_offset[0][6]) + +			    (rtlphy->mcs_offset[0][7] << 8); +			tx_agc[RF90_PATH_A] += tmpval; + +			tmpval = (rtlphy->mcs_offset[0][14]) + +				 (rtlphy->mcs_offset[0][15] << +				  24); +			tx_agc[RF90_PATH_B] += tmpval; +		} +	} +	for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { +		ptr = (u8 *)(&(tx_agc[idx1])); +		for (idx2 = 0; idx2 < 4; idx2++) { +			if (*ptr > RF6052_MAX_TX_PWR) +				*ptr = RF6052_MAX_TX_PWR; +			ptr++; +		} +	} +	rtl8723be_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value); +	if (direction == 1) { +		tx_agc[0] += pwrtrac_value; +		tx_agc[1] += pwrtrac_value; +	} else if (direction == 2) { +		tx_agc[0] -= pwrtrac_value; +		tx_agc[1] -= pwrtrac_value; +	} +	tmpval = tx_agc[RF90_PATH_A] & 0xff; +	rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, +		 RTXAGC_A_CCK1_MCS32); + +	tmpval = tx_agc[RF90_PATH_A] >> 8; + +	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, +		 RTXAGC_B_CCK11_A_CCK2_11); + +	tmpval = tx_agc[RF90_PATH_B] >> 24; +	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, +		 RTXAGC_B_CCK11_A_CCK2_11); + +	tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; +	rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +		 "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, +		 RTXAGC_B_CCK1_55_MCS32); +} + +static void rtl8723be_phy_get_power_base(struct ieee80211_hw *hw, +					 u8 *ppowerlevel_ofdm, +					 u8 *ppowerlevel_bw20, +					 u8 *ppowerlevel_bw40, +					 u8 channel, u32 *ofdmbase, +					 u32 *mcsbase) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	u32 powerbase0, powerbase1; +	u8 i, powerlevel[2]; + +	for (i = 0; i < 2; i++) { +		powerbase0 = ppowerlevel_ofdm[i]; + +		powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) | +		    (powerbase0 << 8) | powerbase0; +		*(ofdmbase + i) = powerbase0; +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 " [OFDM power base index rf(%c) = 0x%x]\n", +			 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)); +	} + +	for (i = 0; i < 2; i++) { +		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) +			powerlevel[i] = ppowerlevel_bw20[i]; +		else +			powerlevel[i] = ppowerlevel_bw40[i]; +		powerbase1 = powerlevel[i]; +		powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) | +			     (powerbase1 << 8) | powerbase1; + +		*(mcsbase + i) = powerbase1; + +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			" [MCS power base index rf(%c) = 0x%x]\n", +			((i == 0) ? 'A' : 'B'), *(mcsbase + i)); +	} +} + +static void txpwr_by_regulatory(struct ieee80211_hw *hw, u8 channel, u8 index, +				u32 *powerbase0, u32 *powerbase1, +				u32 *p_outwriteval) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	u8 i, chnlgroup = 0, pwr_diff_limit[4]; +	u8 pwr_diff = 0, customer_pwr_diff; +	u32 writeval, customer_limit, rf; + +	for (rf = 0; rf < 2; rf++) { +		switch (rtlefuse->eeprom_regulatory) { +		case 0: +			chnlgroup = 0; + +			writeval = +			    rtlphy->mcs_offset[chnlgroup][index + (rf ? 8 : 0)] +			    + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				 "RTK better performance, " +				 "writeval(%c) = 0x%x\n", +				 ((rf == 0) ? 'A' : 'B'), writeval); +			break; +		case 1: +			if (rtlphy->pwrgroup_cnt == 1) { +				chnlgroup = 0; +			} else { +				if (channel < 3) +					chnlgroup = 0; +				else if (channel < 6) +					chnlgroup = 1; +				else if (channel < 9) +					chnlgroup = 2; +				else if (channel < 12) +					chnlgroup = 3; +				else if (channel < 14) +					chnlgroup = 4; +				else if (channel == 14) +					chnlgroup = 5; +			} +			writeval = rtlphy->mcs_offset[chnlgroup] +			    [index + (rf ? 8 : 0)] + ((index < 2) ? +						      powerbase0[rf] : +						      powerbase1[rf]); + +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				 "Realtek regulatory, 20MHz, " +				 "writeval(%c) = 0x%x\n", +				 ((rf == 0) ? 'A' : 'B'), writeval); + +			break; +		case 2: +			writeval = +			    ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				 "Better regulatory, " +				 "writeval(%c) = 0x%x\n", +				 ((rf == 0) ? 'A' : 'B'), writeval); +			break; +		case 3: +			chnlgroup = 0; + +			if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { +				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +					 "customer's limit, 40MHz " +					 "rf(%c) = 0x%x\n", +					 ((rf == 0) ? 'A' : 'B'), +					 rtlefuse->pwrgroup_ht40[rf] +					 [channel-1]); +			} else { +				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +					 "customer's limit, 20MHz " +					 "rf(%c) = 0x%x\n", +					 ((rf == 0) ? 'A' : 'B'), +					 rtlefuse->pwrgroup_ht20[rf] +					 [channel-1]); +			} + +			if (index < 2) +				pwr_diff = +				    rtlefuse->txpwr_legacyhtdiff[rf][channel-1]; +			else if (rtlphy->current_chan_bw == +				 HT_CHANNEL_WIDTH_20) +				pwr_diff = +				    rtlefuse->txpwr_ht20diff[rf][channel-1]; + +			if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) +				customer_pwr_diff = +					rtlefuse->pwrgroup_ht40[rf][channel-1]; +			else +				customer_pwr_diff = +					rtlefuse->pwrgroup_ht20[rf][channel-1]; + +			if (pwr_diff > customer_pwr_diff) +				pwr_diff = 0; +			else +				pwr_diff = customer_pwr_diff - pwr_diff; + +			for (i = 0; i < 4; i++) { +				pwr_diff_limit[i] = +				    (u8)((rtlphy->mcs_offset +					  [chnlgroup][index + (rf ? 8 : 0)] & +					  (0x7f << (i * 8))) >> (i * 8)); + +					if (pwr_diff_limit[i] > pwr_diff) +						pwr_diff_limit[i] = pwr_diff; +			} + +			customer_limit = (pwr_diff_limit[3] << 24) | +					 (pwr_diff_limit[2] << 16) | +					 (pwr_diff_limit[1] << 8) | +					 (pwr_diff_limit[0]); + +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				"Customer's limit rf(%c) = 0x%x\n", +				((rf == 0) ? 'A' : 'B'), customer_limit); + +			writeval = customer_limit + ((index < 2) ? +						      powerbase0[rf] : +						      powerbase1[rf]); + +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				 "Customer, writeval rf(%c)= 0x%x\n", +				 ((rf == 0) ? 'A' : 'B'), writeval); +			break; +		default: +			chnlgroup = 0; +			writeval = +			    rtlphy->mcs_offset[chnlgroup] +			    [index + (rf ? 8 : 0)] +			    + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); + +			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +				 "RTK better performance, writeval " +				 "rf(%c) = 0x%x\n", +				 ((rf == 0) ? 'A' : 'B'), writeval); +			break; +		} + +		if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) +			writeval = writeval - 0x06060606; +		else if (rtlpriv->dm.dynamic_txhighpower_lvl == +			 TXHIGHPWRLEVEL_BT2) +			writeval = writeval - 0x0c0c0c0c; +		*(p_outwriteval + rf) = writeval; +	} +} + +static void _rtl8723be_write_ofdm_power_reg(struct ieee80211_hw *hw, +					 u8 index, u32 *value) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	u16 regoffset_a[6] = { +		RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, +		RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, +		RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 +	}; +	u16 regoffset_b[6] = { +		RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, +		RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, +		RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 +	}; +	u8 i, rf, pwr_val[4]; +	u32 writeval; +	u16 regoffset; + +	for (rf = 0; rf < 2; rf++) { +		writeval = value[rf]; +		for (i = 0; i < 4; i++) { +			pwr_val[i] = (u8) ((writeval & (0x7f << +							(i * 8))) >> (i * 8)); + +			if (pwr_val[i] > RF6052_MAX_TX_PWR) +				pwr_val[i] = RF6052_MAX_TX_PWR; +		} +		writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) | +		    (pwr_val[1] << 8) | pwr_val[0]; + +		if (rf == 0) +			regoffset = regoffset_a[index]; +		else +			regoffset = regoffset_b[index]; +		rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval); + +		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, +			 "Set 0x%x = %08x\n", regoffset, writeval); +	} +} + +void rtl8723be_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +					   u8 *ppowerlevel_ofdm, +					   u8 *ppowerlevel_bw20, +					   u8 *ppowerlevel_bw40, u8 channel) +{ +	u32 writeval[2], powerbase0[2], powerbase1[2]; +	u8 index; +	u8 direction; +	u32 pwrtrac_value; + +	rtl8723be_phy_get_power_base(hw, ppowerlevel_ofdm, ppowerlevel_bw20, +				     ppowerlevel_bw40, channel, +				     &powerbase0[0], &powerbase1[0]); + +	rtl8723be_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value); + +	for (index = 0; index < 6; index++) { +		txpwr_by_regulatory(hw, channel, index, &powerbase0[0], +				    &powerbase1[0], &writeval[0]); +		if (direction == 1) { +			writeval[0] += pwrtrac_value; +			writeval[1] += pwrtrac_value; +		} else if (direction == 2) { +			writeval[0] -= pwrtrac_value; +			writeval[1] -= pwrtrac_value; +		} +		_rtl8723be_write_ofdm_power_reg(hw, index, &writeval[0]); +	} +} + +bool rtl8723be_phy_rf6052_config(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); + +	if (rtlphy->rf_type == RF_1T1R) +		rtlphy->num_total_rfpath = 1; +	else +		rtlphy->num_total_rfpath = 2; + +	return _rtl8723be_phy_rf6052_config_parafile(hw); +} + +static bool _rtl8723be_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_phy *rtlphy = &(rtlpriv->phy); +	struct bb_reg_def *pphyreg; +	u32 u4_regvalue = 0; +	u8 rfpath; +	bool rtstatus = true; + +	for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { +		pphyreg = &rtlphy->phyreg_def[rfpath]; + +		switch (rfpath) { +		case RF90_PATH_A: +		case RF90_PATH_C: +			u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, +						    BRFSI_RFENV); +			break; +		case RF90_PATH_B: +		case RF90_PATH_D: +			u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, +						    BRFSI_RFENV << 16); +			break; +		} + +		rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); +		udelay(1); + +		rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); +		udelay(1); + +		rtl_set_bbreg(hw, pphyreg->rfhssi_para2, +			      B3WIREADDREAALENGTH, 0x0); +		udelay(1); + +		rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); +		udelay(1); + +		switch (rfpath) { +		case RF90_PATH_A: +			rtstatus = rtl8723be_phy_config_rf_with_headerfile(hw, +						      (enum radio_path)rfpath); +			break; +		case RF90_PATH_B: +			rtstatus = rtl8723be_phy_config_rf_with_headerfile(hw, +						      (enum radio_path)rfpath); +			break; +		case RF90_PATH_C: +			break; +		case RF90_PATH_D: +			break; +		} + +		switch (rfpath) { +		case RF90_PATH_A: +		case RF90_PATH_C: +			rtl_set_bbreg(hw, pphyreg->rfintfs, +				      BRFSI_RFENV, u4_regvalue); +			break; +		case RF90_PATH_B: +		case RF90_PATH_D: +			rtl_set_bbreg(hw, pphyreg->rfintfs, +				      BRFSI_RFENV << 16, u4_regvalue); +			break; +		} + +		if (!rtstatus) { +			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, +				 "Radio[%d] Fail!!", rfpath); +			return false; +		} +	} + +	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); +	return rtstatus; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h new file mode 100644 index 00000000000..a6fea106ced --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_RF_H__ +#define __RTL8723BE_RF_H__ + +#define RF6052_MAX_TX_PWR		0x3F +#define RF6052_MAX_REG			0x3F + +void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, +					u8 bandwidth); +void rtl8723be_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +					  u8 *ppowerlevel); +void rtl8723be_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +					   u8 *ppowerlevel_ofdm, +					   u8 *ppowerlevel_bw20, +					   u8 *ppowerlevel_bw40, +					   u8 channel); +bool rtl8723be_phy_rf6052_config(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c new file mode 100644 index 00000000000..ff12bf41644 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c @@ -0,0 +1,387 @@ +/****************************************************************************** + * + * 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 "../core.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "../rtl8723com/phy_common.h" +#include "dm.h" +#include "hw.h" +#include "fw.h" +#include "../rtl8723com/fw_common.h" +#include "sw.h" +#include "trx.h" +#include "led.h" +#include "table.h" +#include "../btcoexist/rtl_btc.h" + +#include <linux/vmalloc.h> +#include <linux/module.h> + +static void rtl8723be_init_aspm_vars(struct ieee80211_hw *hw) +{ +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + +	/*close ASPM for AMD defaultly */ +	rtlpci->const_amdpci_aspm = 0; + +	/* ASPM PS mode. +	 * 0 - Disable ASPM, +	 * 1 - Enable ASPM without Clock Req, +	 * 2 - Enable ASPM with Clock Req, +	 * 3 - Alwyas Enable ASPM with Clock Req, +	 * 4 - Always Enable ASPM without Clock Req. +	 * set defult to RTL8192CE:3 RTL8192E:2 +	 */ +	rtlpci->const_pci_aspm = 3; + +	/*Setting for PCI-E device */ +	rtlpci->const_devicepci_aspm_setting = 0x03; + +	/*Setting for PCI-E bridge */ +	rtlpci->const_hostpci_aspm_setting = 0x02; + +	/* In Hw/Sw Radio Off situation. +	 * 0 - Default, +	 * 1 - From ASPM setting without low Mac Pwr, +	 * 2 - From ASPM setting with low Mac Pwr, +	 * 3 - Bus D3 +	 * set default to RTL8192CE:0 RTL8192SE:2 +	 */ +	rtlpci->const_hwsw_rfoff_d3 = 0; + +	/* This setting works for those device with +	 * backdoor ASPM setting such as EPHY setting. +	 * 0 - Not support ASPM, +	 * 1 - Support ASPM, +	 * 2 - According to chipset. +	 */ +	rtlpci->const_support_pciaspm = 1; +} + +int rtl8723be_init_sw_vars(struct ieee80211_hw *hw) +{ +	int err = 0; +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + +	rtl8723be_bt_reg_init(hw); +	rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; +	rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); + +	rtlpriv->dm.dm_initialgain_enable = 1; +	rtlpriv->dm.dm_flag = 0; +	rtlpriv->dm.disable_framebursting = 0; +	rtlpriv->dm.thermalvalue = 0; +	rtlpci->transmit_config = CFENDFORM | BIT(15) | BIT(24) | BIT(25); + +	mac->ht_enable = true; + +	/* compatible 5G band 88ce just 2.4G band & smsp */ +	rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; +	rtlpriv->rtlhal.bandset = BAND_ON_2_4G; +	rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + +	rtlpci->receive_config = (RCR_APPFCS		| +				  RCR_APP_MIC		| +				  RCR_APP_ICV		| +				  RCR_APP_PHYST_RXFF	| +				  RCR_HTC_LOC_CTRL	| +				  RCR_AMF		| +				  RCR_ACF		| +				  RCR_ADF		| +				  RCR_AICV		| +				  RCR_AB		| +				  RCR_AM		| +				  RCR_APM		| +				  0); + +	rtlpci->irq_mask[0] = (u32) (IMR_PSTIMEOUT	| +				     IMR_HSISR_IND_ON_INT	| +				     IMR_C2HCMD		| +				     IMR_HIGHDOK	| +				     IMR_MGNTDOK	| +				     IMR_BKDOK		| +				     IMR_BEDOK		| +				     IMR_VIDOK		| +				     IMR_VODOK		| +				     IMR_RDU		| +				     IMR_ROK		| +				     0); + +	rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | 0); + +	/* for debug level */ +	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; +	/* for LPS & IPS */ +	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; +	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; +	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; +	rtlpriv->psc.reg_fwctrl_lps = 3; +	rtlpriv->psc.reg_max_lps_awakeintvl = 5; +	/* for ASPM, you can close aspm through +	 * set const_support_pciaspm = 0 +	 */ +	rtl8723be_init_aspm_vars(hw); + +	if (rtlpriv->psc.reg_fwctrl_lps == 1) +		rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; +	else if (rtlpriv->psc.reg_fwctrl_lps == 2) +		rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; +	else if (rtlpriv->psc.reg_fwctrl_lps == 3) +		rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + +	/* for firmware buf */ +	rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); +	if (!rtlpriv->rtlhal.pfirmware) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "Can't alloc buffer for fw.\n"); +		return 1; +	} + +	rtlpriv->max_fw_size = 0x8000; +	pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); +	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, +				      rtlpriv->io.dev, GFP_KERNEL, hw, +				      rtl_fw_cb); +	if (err) { +		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, +			 "Failed to request firmware!\n"); +		return 1; +	} +	return 0; +} + +void rtl8723be_deinit_sw_vars(struct ieee80211_hw *hw) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); + +	if (rtlpriv->cfg->ops->get_btc_status()) +		rtlpriv->btcoexist.btc_ops->btc_halt_notify(); +	if (rtlpriv->rtlhal.pfirmware) { +		vfree(rtlpriv->rtlhal.pfirmware); +		rtlpriv->rtlhal.pfirmware = NULL; +	} +} + +/* get bt coexist status */ +bool rtl8723be_get_btc_status(void) +{ +	return true; +} + +static bool is_fw_header(struct rtl92c_firmware_header *hdr) +{ +	return (hdr->signature & 0xfff0) == 0x5300; +} + +static struct rtl_hal_ops rtl8723be_hal_ops = { +	.init_sw_vars = rtl8723be_init_sw_vars, +	.deinit_sw_vars = rtl8723be_deinit_sw_vars, +	.read_eeprom_info = rtl8723be_read_eeprom_info, +	.interrupt_recognized = rtl8723be_interrupt_recognized, +	.hw_init = rtl8723be_hw_init, +	.hw_disable = rtl8723be_card_disable, +	.hw_suspend = rtl8723be_suspend, +	.hw_resume = rtl8723be_resume, +	.enable_interrupt = rtl8723be_enable_interrupt, +	.disable_interrupt = rtl8723be_disable_interrupt, +	.set_network_type = rtl8723be_set_network_type, +	.set_chk_bssid = rtl8723be_set_check_bssid, +	.set_qos = rtl8723be_set_qos, +	.set_bcn_reg = rtl8723be_set_beacon_related_registers, +	.set_bcn_intv = rtl8723be_set_beacon_interval, +	.update_interrupt_mask = rtl8723be_update_interrupt_mask, +	.get_hw_reg = rtl8723be_get_hw_reg, +	.set_hw_reg = rtl8723be_set_hw_reg, +	.update_rate_tbl = rtl8723be_update_hal_rate_tbl, +	.fill_tx_desc = rtl8723be_tx_fill_desc, +	.fill_tx_cmddesc = rtl8723be_tx_fill_cmddesc, +	.query_rx_desc = rtl8723be_rx_query_desc, +	.set_channel_access = rtl8723be_update_channel_access_setting, +	.radio_onoff_checking = rtl8723be_gpio_radio_on_off_checking, +	.set_bw_mode = rtl8723be_phy_set_bw_mode, +	.switch_channel = rtl8723be_phy_sw_chnl, +	.dm_watchdog = rtl8723be_dm_watchdog, +	.scan_operation_backup = rtl8723be_phy_scan_operation_backup, +	.set_rf_power_state = rtl8723be_phy_set_rf_power_state, +	.led_control = rtl8723be_led_control, +	.set_desc = rtl8723be_set_desc, +	.get_desc = rtl8723be_get_desc, +	.is_tx_desc_closed = rtl8723be_is_tx_desc_closed, +	.tx_polling = rtl8723be_tx_polling, +	.enable_hw_sec = rtl8723be_enable_hw_security_config, +	.set_key = rtl8723be_set_key, +	.init_sw_leds = rtl8723be_init_sw_leds, +	.get_bbreg = rtl8723_phy_query_bb_reg, +	.set_bbreg = rtl8723_phy_set_bb_reg, +	.get_rfreg = rtl8723be_phy_query_rf_reg, +	.set_rfreg = rtl8723be_phy_set_rf_reg, +	.fill_h2c_cmd = rtl8723be_fill_h2c_cmd, +	.get_btc_status = rtl8723be_get_btc_status, +	.is_fw_header = is_fw_header, +}; + +static struct rtl_mod_params rtl8723be_mod_params = { +	.sw_crypto = false, +	.inactiveps = true, +	.swctrl_lps = false, +	.fwctrl_lps = true, +	.msi_support = false, +	.debug = DBG_EMERG, +}; + +static struct rtl_hal_cfg rtl8723be_hal_cfg = { +	.bar_id = 2, +	.write_readback = true, +	.name = "rtl8723be_pci", +	.fw_name = "rtlwifi/rtl8723befw.bin", +	.ops = &rtl8723be_hal_ops, +	.mod_params = &rtl8723be_mod_params, +	.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, +	.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, +	.maps[SYS_CLK] = REG_SYS_CLKR, +	.maps[MAC_RCR_AM] = AM, +	.maps[MAC_RCR_AB] = AB, +	.maps[MAC_RCR_ACRC32] = ACRC32, +	.maps[MAC_RCR_ACF] = ACF, +	.maps[MAC_RCR_AAP] = AAP, + +	.maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS, + +	.maps[EFUSE_TEST] = REG_EFUSE_TEST, +	.maps[EFUSE_CTRL] = REG_EFUSE_CTRL, +	.maps[EFUSE_CLK] = 0, +	.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, +	.maps[EFUSE_PWC_EV12V] = PWC_EV12V, +	.maps[EFUSE_FEN_ELDR] = FEN_ELDR, +	.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, +	.maps[EFUSE_ANA8M] = ANA8M, +	.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, +	.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, +	.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, +	.maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + +	.maps[RWCAM] = REG_CAMCMD, +	.maps[WCAMI] = REG_CAMWRITE, +	.maps[RCAMO] = REG_CAMREAD, +	.maps[CAMDBG] = REG_CAMDBG, +	.maps[SECR] = REG_SECCFG, +	.maps[SEC_CAM_NONE] = CAM_NONE, +	.maps[SEC_CAM_WEP40] = CAM_WEP40, +	.maps[SEC_CAM_TKIP] = CAM_TKIP, +	.maps[SEC_CAM_AES] = CAM_AES, +	.maps[SEC_CAM_WEP104] = CAM_WEP104, + +	.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, +	.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, +	.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, +	.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, +	.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, +	.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, +	.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, +	.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, +	.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, +	.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, +	.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, +	.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, +	.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + +	.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, +	.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, +	.maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0, +	.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, +	.maps[RTL_IMR_RDU] = IMR_RDU, +	.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, +	.maps[RTL_IMR_BDOK] = IMR_BCNDOK0, +	.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, +	.maps[RTL_IMR_TBDER] = IMR_TBDER, +	.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, +	.maps[RTL_IMR_TBDOK] = IMR_TBDOK, +	.maps[RTL_IMR_BKDOK] = IMR_BKDOK, +	.maps[RTL_IMR_BEDOK] = IMR_BEDOK, +	.maps[RTL_IMR_VIDOK] = IMR_VIDOK, +	.maps[RTL_IMR_VODOK] = IMR_VODOK, +	.maps[RTL_IMR_ROK] = IMR_ROK, +	.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER), + +	.maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, +	.maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, +	.maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, +	.maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, +	.maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, +	.maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, +	.maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, +	.maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, +	.maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, +	.maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, +	.maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, +	.maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, + +	.maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, +	.maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, +}; + +static DEFINE_PCI_DEVICE_TABLE(rtl8723be_pci_id) = { +	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb723, rtl8723be_hal_cfg)}, +	{}, +}; + +MODULE_DEVICE_TABLE(pci, rtl8723be_pci_id); + +MODULE_AUTHOR("PageHe	<page_he@realsil.com.cn>"); +MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8723BE 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8723befw.bin"); + +module_param_named(swenc, rtl8723be_mod_params.sw_crypto, bool, 0444); +module_param_named(debug, rtl8723be_mod_params.debug, int, 0444); +module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl8723be_mod_params.msi_support, bool, 0444); +MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); +MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); +MODULE_PARM_DESC(fwlps, "using linked fw control power save (default 1 is open)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n"); +MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl8723be_driver = { +	.name = KBUILD_MODNAME, +	.id_table = rtl8723be_pci_id, +	.probe = rtl_pci_probe, +	.remove = rtl_pci_disconnect, + +	.driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl8723be_driver); diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.h b/drivers/net/wireless/rtlwifi/rtl8723be/sw.h new file mode 100644 index 00000000000..a7b25e76995 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_SW_H__ +#define __RTL8723BE_SW_H__ + +int rtl8723be_init_sw_vars(struct ieee80211_hw *hw); +void rtl8723be_deinit_sw_vars(struct ieee80211_hw *hw); +void rtl8723be_init_var_map(struct ieee80211_hw *hw); +bool rtl8723be_get_btc_status(void); + + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/table.c b/drivers/net/wireless/rtlwifi/rtl8723be/table.c new file mode 100644 index 00000000000..4b283cde042 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/table.c @@ -0,0 +1,572 @@ +/****************************************************************************** + * + * 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. + * + * Created on  2010/ 5/18,  1:41 + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#include "table.h" +u32 RTL8723BEPHY_REG_1TARRAY[] = { +	0x800, 0x80040000, +	0x804, 0x00000003, +	0x808, 0x0000FC00, +	0x80C, 0x0000000A, +	0x810, 0x10001331, +	0x814, 0x020C3D10, +	0x818, 0x02200385, +	0x81C, 0x00000000, +	0x820, 0x01000100, +	0x824, 0x00390204, +	0x828, 0x00000000, +	0x82C, 0x00000000, +	0x830, 0x00000000, +	0x834, 0x00000000, +	0x838, 0x00000000, +	0x83C, 0x00000000, +	0x840, 0x00010000, +	0x844, 0x00000000, +	0x848, 0x00000000, +	0x84C, 0x00000000, +	0x850, 0x00000000, +	0x854, 0x00000000, +	0x858, 0x569A11A9, +	0x85C, 0x01000014, +	0x860, 0x66F60110, +	0x864, 0x061F0649, +	0x868, 0x00000000, +	0x86C, 0x27272700, +	0x870, 0x07000760, +	0x874, 0x25004000, +	0x878, 0x00000808, +	0x87C, 0x00000000, +	0x880, 0xB0000C1C, +	0x884, 0x00000001, +	0x888, 0x00000000, +	0x88C, 0xCCC000C0, +	0x890, 0x00000800, +	0x894, 0xFFFFFFFE, +	0x898, 0x40302010, +	0x89C, 0x00706050, +	0x900, 0x00000000, +	0x904, 0x00000023, +	0x908, 0x00000000, +	0x90C, 0x81121111, +	0x910, 0x00000002, +	0x914, 0x00000201, +	0x948, 0x00000000, +	0xA00, 0x00D047C8, +	0xA04, 0x80FF000C, +	0xA08, 0x8C838300, +	0xA0C, 0x2E7F120F, +	0xA10, 0x9500BB78, +	0xA14, 0x1114D028, +	0xA18, 0x00881117, +	0xA1C, 0x89140F00, +	0xA20, 0x1A1B0000, +	0xA24, 0x090E1317, +	0xA28, 0x00000204, +	0xA2C, 0x00D30000, +	0xA70, 0x101FBF00, +	0xA74, 0x00000007, +	0xA78, 0x00000900, +	0xA7C, 0x225B0606, +	0xA80, 0x21806490, +	0xB2C, 0x00000000, +	0xC00, 0x48071D40, +	0xC04, 0x03A05611, +	0xC08, 0x000000E4, +	0xC0C, 0x6C6C6C6C, +	0xC10, 0x08800000, +	0xC14, 0x40000100, +	0xC18, 0x08800000, +	0xC1C, 0x40000100, +	0xC20, 0x00000000, +	0xC24, 0x00000000, +	0xC28, 0x00000000, +	0xC2C, 0x00000000, +	0xC30, 0x69E9AC44, +	0xC34, 0x469652AF, +	0xC38, 0x49795994, +	0xC3C, 0x0A97971C, +	0xC40, 0x1F7C403F, +	0xC44, 0x000100B7, +	0xC48, 0xEC020107, +	0xC4C, 0x007F037F, +	0xC50, 0x69553420, +	0xC54, 0x43BC0094, +	0xC58, 0x00023169, +	0xC5C, 0x00250492, +	0xC60, 0x00000000, +	0xC64, 0x7112848B, +	0xC68, 0x47C00BFF, +	0xC6C, 0x00000036, +	0xC70, 0x2C7F000D, +	0xC74, 0x020610DB, +	0xC78, 0x0000001F, +	0xC7C, 0x00B91612, +	0xC80, 0x390000E4, +	0xC84, 0x20F60000, +	0xC88, 0x40000100, +	0xC8C, 0x20200000, +	0xC90, 0x00020E1A, +	0xC94, 0x00000000, +	0xC98, 0x00020E1A, +	0xC9C, 0x00007F7F, +	0xCA0, 0x00000000, +	0xCA4, 0x000300A0, +	0xCA8, 0x00000000, +	0xCAC, 0x00000000, +	0xCB0, 0x00000000, +	0xCB4, 0x00000000, +	0xCB8, 0x00000000, +	0xCBC, 0x28000000, +	0xCC0, 0x00000000, +	0xCC4, 0x00000000, +	0xCC8, 0x00000000, +	0xCCC, 0x00000000, +	0xCD0, 0x00000000, +	0xCD4, 0x00000000, +	0xCD8, 0x64B22427, +	0xCDC, 0x00766932, +	0xCE0, 0x00222222, +	0xCE4, 0x00000000, +	0xCE8, 0x37644302, +	0xCEC, 0x2F97D40C, +	0xD00, 0x00000740, +	0xD04, 0x40020401, +	0xD08, 0x0000907F, +	0xD0C, 0x20010201, +	0xD10, 0xA0633333, +	0xD14, 0x3333BC53, +	0xD18, 0x7A8F5B6F, +	0xD2C, 0xCC979975, +	0xD30, 0x00000000, +	0xD34, 0x80608000, +	0xD38, 0x00000000, +	0xD3C, 0x00127353, +	0xD40, 0x00000000, +	0xD44, 0x00000000, +	0xD48, 0x00000000, +	0xD4C, 0x00000000, +	0xD50, 0x6437140A, +	0xD54, 0x00000000, +	0xD58, 0x00000282, +	0xD5C, 0x30032064, +	0xD60, 0x4653DE68, +	0xD64, 0x04518A3C, +	0xD68, 0x00002101, +	0xD6C, 0x2A201C16, +	0xD70, 0x1812362E, +	0xD74, 0x322C2220, +	0xD78, 0x000E3C24, +	0xE00, 0x2D2D2D2D, +	0xE04, 0x2D2D2D2D, +	0xE08, 0x0390272D, +	0xE10, 0x2D2D2D2D, +	0xE14, 0x2D2D2D2D, +	0xE18, 0x2D2D2D2D, +	0xE1C, 0x2D2D2D2D, +	0xE28, 0x00000000, +	0xE30, 0x1000DC1F, +	0xE34, 0x10008C1F, +	0xE38, 0x02140102, +	0xE3C, 0x681604C2, +	0xE40, 0x01007C00, +	0xE44, 0x01004800, +	0xE48, 0xFB000000, +	0xE4C, 0x000028D1, +	0xE50, 0x1000DC1F, +	0xE54, 0x10008C1F, +	0xE58, 0x02140102, +	0xE5C, 0x28160D05, +	0xE60, 0x00000008, +	0xE68, 0x001B2556, +	0xE6C, 0x00C00096, +	0xE70, 0x00C00096, +	0xE74, 0x01000056, +	0xE78, 0x01000014, +	0xE7C, 0x01000056, +	0xE80, 0x01000014, +	0xE84, 0x00C00096, +	0xE88, 0x01000056, +	0xE8C, 0x00C00096, +	0xED0, 0x00C00096, +	0xED4, 0x00C00096, +	0xED8, 0x00C00096, +	0xEDC, 0x000000D6, +	0xEE0, 0x000000D6, +	0xEEC, 0x01C00016, +	0xF14, 0x00000003, +	0xF4C, 0x00000000, +	0xF00, 0x00000300, +	0x820, 0x01000100, +	0x800, 0x83040000, +}; + +u32 RTL8723BEPHY_REG_ARRAY_PG[] = { +	0, 0, 0, 0x00000e08, 0x0000ff00, 0x00004000, +	0, 0, 0, 0x0000086c, 0xffffff00, 0x34363800, +	0, 0, 0, 0x00000e00, 0xffffffff, 0x42444646, +	0, 0, 0, 0x00000e04, 0xffffffff, 0x30343840, +	0, 0, 0, 0x00000e10, 0xffffffff, 0x38404244, +	0, 0, 0, 0x00000e14, 0xffffffff, 0x26303436 +}; + +u32 RTL8723BE_RADIOA_1TARRAY[] = { +	0x000, 0x00010000, +	0x0B0, 0x000DFFE0, +	0x0FE, 0x00000000, +	0x0FE, 0x00000000, +	0x0FE, 0x00000000, +	0x0B1, 0x00000018, +	0x0FE, 0x00000000, +	0x0FE, 0x00000000, +	0x0FE, 0x00000000, +	0x0B2, 0x00084C00, +	0x0B5, 0x0000D2CC, +	0x0B6, 0x000925AA, +	0x0B7, 0x00000010, +	0x0B8, 0x0000907F, +	0x05C, 0x00000002, +	0x07C, 0x00000002, +	0x07E, 0x00000005, +	0x08B, 0x0006FC00, +	0x0B0, 0x000FF9F0, +	0x01C, 0x000739D2, +	0x01E, 0x00000000, +	0x0DF, 0x00000780, +	0x050, 0x00067435, +	0x051, 0x0006B04E, +	0x052, 0x000007D2, +	0x053, 0x00000000, +	0x054, 0x00050400, +	0x055, 0x0004026E, +	0x0DD, 0x0000004C, +	0x070, 0x00067435, +	0x071, 0x0006B04E, +	0x072, 0x000007D2, +	0x073, 0x00000000, +	0x074, 0x00050400, +	0x075, 0x0004026E, +	0x0EF, 0x00000100, +	0x034, 0x0000ADD7, +	0x035, 0x00005C00, +	0x034, 0x00009DD4, +	0x035, 0x00005000, +	0x034, 0x00008DD1, +	0x035, 0x00004400, +	0x034, 0x00007DCE, +	0x035, 0x00003800, +	0x034, 0x00006CD1, +	0x035, 0x00004400, +	0x034, 0x00005CCE, +	0x035, 0x00003800, +	0x034, 0x000048CE, +	0x035, 0x00004400, +	0x034, 0x000034CE, +	0x035, 0x00003800, +	0x034, 0x00002451, +	0x035, 0x00004400, +	0x034, 0x0000144E, +	0x035, 0x00003800, +	0x034, 0x00000051, +	0x035, 0x00004400, +	0x0EF, 0x00000000, +	0x0EF, 0x00000100, +	0x0ED, 0x00000010, +	0x044, 0x0000ADD7, +	0x044, 0x00009DD4, +	0x044, 0x00008DD1, +	0x044, 0x00007DCE, +	0x044, 0x00006CC1, +	0x044, 0x00005CCE, +	0x044, 0x000044D1, +	0x044, 0x000034CE, +	0x044, 0x00002451, +	0x044, 0x0000144E, +	0x044, 0x00000051, +	0x0EF, 0x00000000, +	0x0ED, 0x00000000, +	0x0EF, 0x00002000, +	0x03B, 0x000380EF, +	0x03B, 0x000302FE, +	0x03B, 0x00028CE6, +	0x03B, 0x000200BC, +	0x03B, 0x000188A5, +	0x03B, 0x00010FBC, +	0x03B, 0x00008F71, +	0x03B, 0x00000900, +	0x0EF, 0x00000000, +	0x0ED, 0x00000001, +	0x040, 0x000380EF, +	0x040, 0x000302FE, +	0x040, 0x00028CE6, +	0x040, 0x000200BC, +	0x040, 0x000188A5, +	0x040, 0x00010FBC, +	0x040, 0x00008F71, +	0x040, 0x00000900, +	0x0ED, 0x00000000, +	0x082, 0x00080000, +	0x083, 0x00008000, +	0x084, 0x00048D80, +	0x085, 0x00068000, +	0x0A2, 0x00080000, +	0x0A3, 0x00008000, +	0x0A4, 0x00048D80, +	0x0A5, 0x00068000, +	0x000, 0x00033D80, +}; + +u32 RTL8723BEMAC_1T_ARRAY[] = { +	0x02F, 0x00000030, +	0x035, 0x00000000, +	0x428, 0x0000000A, +	0x429, 0x00000010, +	0x430, 0x00000000, +	0x431, 0x00000000, +	0x432, 0x00000000, +	0x433, 0x00000001, +	0x434, 0x00000004, +	0x435, 0x00000005, +	0x436, 0x00000007, +	0x437, 0x00000008, +	0x43C, 0x00000004, +	0x43D, 0x00000005, +	0x43E, 0x00000007, +	0x43F, 0x00000008, +	0x440, 0x0000005D, +	0x441, 0x00000001, +	0x442, 0x00000000, +	0x444, 0x00000010, +	0x445, 0x00000000, +	0x446, 0x00000000, +	0x447, 0x00000000, +	0x448, 0x00000000, +	0x449, 0x000000F0, +	0x44A, 0x0000000F, +	0x44B, 0x0000003E, +	0x44C, 0x00000010, +	0x44D, 0x00000000, +	0x44E, 0x00000000, +	0x44F, 0x00000000, +	0x450, 0x00000000, +	0x451, 0x000000F0, +	0x452, 0x0000000F, +	0x453, 0x00000000, +	0x456, 0x0000005E, +	0x460, 0x00000066, +	0x461, 0x00000066, +	0x4C8, 0x000000FF, +	0x4C9, 0x00000008, +	0x4CC, 0x000000FF, +	0x4CD, 0x000000FF, +	0x4CE, 0x00000001, +	0x500, 0x00000026, +	0x501, 0x000000A2, +	0x502, 0x0000002F, +	0x503, 0x00000000, +	0x504, 0x00000028, +	0x505, 0x000000A3, +	0x506, 0x0000005E, +	0x507, 0x00000000, +	0x508, 0x0000002B, +	0x509, 0x000000A4, +	0x50A, 0x0000005E, +	0x50B, 0x00000000, +	0x50C, 0x0000004F, +	0x50D, 0x000000A4, +	0x50E, 0x00000000, +	0x50F, 0x00000000, +	0x512, 0x0000001C, +	0x514, 0x0000000A, +	0x516, 0x0000000A, +	0x525, 0x0000004F, +	0x550, 0x00000010, +	0x551, 0x00000010, +	0x559, 0x00000002, +	0x55C, 0x00000050, +	0x55D, 0x000000FF, +	0x605, 0x00000030, +	0x608, 0x0000000E, +	0x609, 0x0000002A, +	0x620, 0x000000FF, +	0x621, 0x000000FF, +	0x622, 0x000000FF, +	0x623, 0x000000FF, +	0x624, 0x000000FF, +	0x625, 0x000000FF, +	0x626, 0x000000FF, +	0x627, 0x000000FF, +	0x638, 0x00000050, +	0x63C, 0x0000000A, +	0x63D, 0x0000000A, +	0x63E, 0x0000000E, +	0x63F, 0x0000000E, +	0x640, 0x00000040, +	0x642, 0x00000040, +	0x643, 0x00000000, +	0x652, 0x000000C8, +	0x66E, 0x00000005, +	0x700, 0x00000021, +	0x701, 0x00000043, +	0x702, 0x00000065, +	0x703, 0x00000087, +	0x708, 0x00000021, +	0x709, 0x00000043, +	0x70A, 0x00000065, +	0x70B, 0x00000087, +}; + +u32 RTL8723BEAGCTAB_1TARRAY[] = { +	0xC78, 0xFD000001, +	0xC78, 0xFC010001, +	0xC78, 0xFB020001, +	0xC78, 0xFA030001, +	0xC78, 0xF9040001, +	0xC78, 0xF8050001, +	0xC78, 0xF7060001, +	0xC78, 0xF6070001, +	0xC78, 0xF5080001, +	0xC78, 0xF4090001, +	0xC78, 0xF30A0001, +	0xC78, 0xF20B0001, +	0xC78, 0xF10C0001, +	0xC78, 0xF00D0001, +	0xC78, 0xEF0E0001, +	0xC78, 0xEE0F0001, +	0xC78, 0xED100001, +	0xC78, 0xEC110001, +	0xC78, 0xEB120001, +	0xC78, 0xEA130001, +	0xC78, 0xE9140001, +	0xC78, 0xE8150001, +	0xC78, 0xE7160001, +	0xC78, 0xAA170001, +	0xC78, 0xA9180001, +	0xC78, 0xA8190001, +	0xC78, 0xA71A0001, +	0xC78, 0xA61B0001, +	0xC78, 0xA51C0001, +	0xC78, 0xA41D0001, +	0xC78, 0xA31E0001, +	0xC78, 0x671F0001, +	0xC78, 0x66200001, +	0xC78, 0x65210001, +	0xC78, 0x64220001, +	0xC78, 0x63230001, +	0xC78, 0x62240001, +	0xC78, 0x61250001, +	0xC78, 0x47260001, +	0xC78, 0x46270001, +	0xC78, 0x45280001, +	0xC78, 0x44290001, +	0xC78, 0x432A0001, +	0xC78, 0x422B0001, +	0xC78, 0x292C0001, +	0xC78, 0x282D0001, +	0xC78, 0x272E0001, +	0xC78, 0x262F0001, +	0xC78, 0x25300001, +	0xC78, 0x24310001, +	0xC78, 0x09320001, +	0xC78, 0x08330001, +	0xC78, 0x07340001, +	0xC78, 0x06350001, +	0xC78, 0x05360001, +	0xC78, 0x04370001, +	0xC78, 0x03380001, +	0xC78, 0x02390001, +	0xC78, 0x013A0001, +	0xC78, 0x003B0001, +	0xC78, 0x003C0001, +	0xC78, 0x003D0001, +	0xC78, 0x003E0001, +	0xC78, 0x003F0001, +	0xC78, 0xFC400001, +	0xC78, 0xFB410001, +	0xC78, 0xFA420001, +	0xC78, 0xF9430001, +	0xC78, 0xF8440001, +	0xC78, 0xF7450001, +	0xC78, 0xF6460001, +	0xC78, 0xF5470001, +	0xC78, 0xF4480001, +	0xC78, 0xF3490001, +	0xC78, 0xF24A0001, +	0xC78, 0xF14B0001, +	0xC78, 0xF04C0001, +	0xC78, 0xEF4D0001, +	0xC78, 0xEE4E0001, +	0xC78, 0xED4F0001, +	0xC78, 0xEC500001, +	0xC78, 0xEB510001, +	0xC78, 0xEA520001, +	0xC78, 0xE9530001, +	0xC78, 0xE8540001, +	0xC78, 0xE7550001, +	0xC78, 0xE6560001, +	0xC78, 0xE5570001, +	0xC78, 0xAA580001, +	0xC78, 0xA9590001, +	0xC78, 0xA85A0001, +	0xC78, 0xA75B0001, +	0xC78, 0xA65C0001, +	0xC78, 0xA55D0001, +	0xC78, 0xA45E0001, +	0xC78, 0x675F0001, +	0xC78, 0x66600001, +	0xC78, 0x65610001, +	0xC78, 0x64620001, +	0xC78, 0x63630001, +	0xC78, 0x62640001, +	0xC78, 0x61650001, +	0xC78, 0x47660001, +	0xC78, 0x46670001, +	0xC78, 0x45680001, +	0xC78, 0x44690001, +	0xC78, 0x436A0001, +	0xC78, 0x426B0001, +	0xC78, 0x296C0001, +	0xC78, 0x286D0001, +	0xC78, 0x276E0001, +	0xC78, 0x266F0001, +	0xC78, 0x25700001, +	0xC78, 0x24710001, +	0xC78, 0x09720001, +	0xC78, 0x08730001, +	0xC78, 0x07740001, +	0xC78, 0x06750001, +	0xC78, 0x05760001, +	0xC78, 0x04770001, +	0xC78, 0x03780001, +	0xC78, 0x02790001, +	0xC78, 0x017A0001, +	0xC78, 0x007B0001, +	0xC78, 0x007C0001, +	0xC78, 0x007D0001, +	0xC78, 0x007E0001, +	0xC78, 0x007F0001, +	0xC50, 0x69553422, +	0xC50, 0x69553420, +}; diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/table.h b/drivers/net/wireless/rtlwifi/rtl8723be/table.h new file mode 100644 index 00000000000..932760a8482 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/table.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * + * 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. + * + * Created on  2010/ 5/18,  1:41 + * + * Larry Finger <Larry.Finger@lwfinger.net> + * + *****************************************************************************/ + +#ifndef __RTL8723BE_TABLE__H_ +#define __RTL8723BE_TABLE__H_ + +#include <linux/types.h> +#define  RTL8723BEPHY_REG_1TARRAYLEN	388 +extern u32 RTL8723BEPHY_REG_1TARRAY[]; +#define RTL8723BEPHY_REG_ARRAY_PGLEN	36 +extern u32 RTL8723BEPHY_REG_ARRAY_PG[]; +#define	RTL8723BE_RADIOA_1TARRAYLEN	206 +extern u32 RTL8723BE_RADIOA_1TARRAY[]; +#define RTL8723BEMAC_1T_ARRAYLEN	194 +extern u32 RTL8723BEMAC_1T_ARRAY[]; +#define RTL8723BEAGCTAB_1TARRAYLEN	260 +extern u32 RTL8723BEAGCTAB_1TARRAY[]; + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c new file mode 100644 index 00000000000..969eaea5edd --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c @@ -0,0 +1,959 @@ +/****************************************************************************** + * + * 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 "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" +#include "dm.h" + +static u8 _rtl8723be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ +	__le16 fc = rtl_get_fc(skb); + +	if (unlikely(ieee80211_is_beacon(fc))) +		return QSLT_BEACON; +	if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) +		return QSLT_MGNT; + +	return skb->priority; +} + +/* mac80211's rate_idx is like this: + * + * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ + * + * B/G rate: + * (rx_status->flag & RX_FLAG_HT) = 0, + * DESC92C_RATE1M-->DESC92C_RATE54M ==> idx is 0-->11, + * + * N rate: + * (rx_status->flag & RX_FLAG_HT) = 1, + * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15 + * + * 5G band:rx_status->band == IEEE80211_BAND_5GHZ + * A rate: + * (rx_status->flag & RX_FLAG_HT) = 0, + * DESC92C_RATE6M-->DESC92C_RATE54M ==> idx is 0-->7, + * + * N rate: + * (rx_status->flag & RX_FLAG_HT) = 1, + * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15 + */ +static int _rtl8723be_rate_mapping(struct ieee80211_hw *hw, +				   bool isht, u8 desc_rate) +{ +	int rate_idx; + +	if (!isht) { +		if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) { +			switch (desc_rate) { +			case DESC92C_RATE1M: +				rate_idx = 0; +				break; +			case DESC92C_RATE2M: +				rate_idx = 1; +				break; +			case DESC92C_RATE5_5M: +				rate_idx = 2; +				break; +			case DESC92C_RATE11M: +				rate_idx = 3; +				break; +			case DESC92C_RATE6M: +				rate_idx = 4; +				break; +			case DESC92C_RATE9M: +				rate_idx = 5; +				break; +			case DESC92C_RATE12M: +				rate_idx = 6; +				break; +			case DESC92C_RATE18M: +				rate_idx = 7; +				break; +			case DESC92C_RATE24M: +				rate_idx = 8; +				break; +			case DESC92C_RATE36M: +				rate_idx = 9; +				break; +			case DESC92C_RATE48M: +				rate_idx = 10; +				break; +			case DESC92C_RATE54M: +				rate_idx = 11; +				break; +			default: +				rate_idx = 0; +				break; +			} +		} else { +			switch (desc_rate) { +			case DESC92C_RATE6M: +				rate_idx = 0; +				break; +			case DESC92C_RATE9M: +				rate_idx = 1; +				break; +			case DESC92C_RATE12M: +				rate_idx = 2; +				break; +			case DESC92C_RATE18M: +				rate_idx = 3; +				break; +			case DESC92C_RATE24M: +				rate_idx = 4; +				break; +			case DESC92C_RATE36M: +				rate_idx = 5; +				break; +			case DESC92C_RATE48M: +				rate_idx = 6; +				break; +			case DESC92C_RATE54M: +				rate_idx = 7; +				break; +			default: +				rate_idx = 0; +				break; +			} +		} +	} else { +		switch (desc_rate) { +		case DESC92C_RATEMCS0: +			rate_idx = 0; +			break; +		case DESC92C_RATEMCS1: +			rate_idx = 1; +			break; +		case DESC92C_RATEMCS2: +			rate_idx = 2; +			break; +		case DESC92C_RATEMCS3: +			rate_idx = 3; +			break; +		case DESC92C_RATEMCS4: +			rate_idx = 4; +			break; +		case DESC92C_RATEMCS5: +			rate_idx = 5; +			break; +		case DESC92C_RATEMCS6: +			rate_idx = 6; +			break; +		case DESC92C_RATEMCS7: +			rate_idx = 7; +			break; +		case DESC92C_RATEMCS8: +			rate_idx = 8; +			break; +		case DESC92C_RATEMCS9: +			rate_idx = 9; +			break; +		case DESC92C_RATEMCS10: +			rate_idx = 10; +			break; +		case DESC92C_RATEMCS11: +			rate_idx = 11; +			break; +		case DESC92C_RATEMCS12: +			rate_idx = 12; +			break; +		case DESC92C_RATEMCS13: +			rate_idx = 13; +			break; +		case DESC92C_RATEMCS14: +			rate_idx = 14; +			break; +		case DESC92C_RATEMCS15: +			rate_idx = 15; +			break; +		default: +			rate_idx = 0; +			break; +		} +	} +	return rate_idx; +} + +static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw, +					 struct rtl_stats *pstatus, u8 *pdesc, +					 struct rx_fwinfo_8723be *p_drvinfo, +					 bool packet_match_bssid, +					 bool packet_toself, +					 bool packet_beacon) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); +	struct phy_sts_cck_8723e_t *cck_buf; +	struct phy_status_rpt *p_phystrpt = (struct phy_status_rpt *)p_drvinfo; +	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); +	char rx_pwr_all = 0, rx_pwr[4]; +	u8 rf_rx_num = 0, evm, pwdb_all; +	u8 i, max_spatial_stream; +	u32 rssi, total_rssi = 0; +	bool is_cck = pstatus->is_cck; +	u8 lan_idx, vga_idx; + +	/* Record it for next packet processing */ +	pstatus->packet_matchbssid = packet_match_bssid; +	pstatus->packet_toself = packet_toself; +	pstatus->packet_beacon = packet_beacon; +	pstatus->rx_mimo_sig_qual[0] = -1; +	pstatus->rx_mimo_sig_qual[1] = -1; + +	if (is_cck) { +		u8 cck_highpwr; +		u8 cck_agc_rpt; +		/* CCK Driver info Structure is not the same as OFDM packet. */ +		cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo; +		cck_agc_rpt = cck_buf->cck_agc_rpt; + +		/* (1)Hardware does not provide RSSI for CCK +		 * (2)PWDB, Average PWDB cacluated by +		 * hardware (for rate adaptive) +		 */ +		if (ppsc->rfpwr_state == ERFON) +			cck_highpwr = (u8) rtl_get_bbreg(hw, +						       RFPGA0_XA_HSSIPARAMETER2, +						       BIT(9)); +		else +			cck_highpwr = false; + +		lan_idx = ((cck_agc_rpt & 0xE0) >> 5); +		vga_idx = (cck_agc_rpt & 0x1f); +		switch (lan_idx) { +		case 7: +			if (vga_idx <= 27)/*VGA_idx = 27~2*/ +				rx_pwr_all = -100 + 2 * (27 - vga_idx); +			else +				rx_pwr_all = -100; +			break; +		case 6:/*VGA_idx = 2~0*/ +			rx_pwr_all = -48 + 2 * (2 - vga_idx); +			break; +		case 5:/*VGA_idx = 7~5*/ +			rx_pwr_all = -42 + 2 * (7 - vga_idx); +			break; +		case 4:/*VGA_idx = 7~4*/ +			rx_pwr_all = -36 + 2 * (7 - vga_idx); +			break; +		case 3:/*VGA_idx = 7~0*/ +			rx_pwr_all = -24 + 2 * (7 - vga_idx); +			break; +		case 2: +			if (cck_highpwr)/*VGA_idx = 5~0*/ +				rx_pwr_all = -12 + 2 * (5 - vga_idx); +			else +				rx_pwr_all = -6 + 2 * (5 - vga_idx); +			break; +		case 1: +			rx_pwr_all = 8 - 2 * vga_idx; +			break; +		case 0: +			rx_pwr_all = 14 - 2 * vga_idx; +			break; +		default: +			break; +		} +		rx_pwr_all += 6; +		pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); +		/* CCK gain is smaller than OFDM/MCS gain,  */ +		/* so we add gain diff by experiences, +		 * the val is 6 +		 */ +		pwdb_all += 6; +		if (pwdb_all > 100) +			pwdb_all = 100; +		/* modify the offset to make the same gain index with OFDM. */ +		if (pwdb_all > 34 && pwdb_all <= 42) +			pwdb_all -= 2; +		else if (pwdb_all > 26 && pwdb_all <= 34) +			pwdb_all -= 6; +		else if (pwdb_all > 14 && pwdb_all <= 26) +			pwdb_all -= 8; +		else if (pwdb_all > 4 && pwdb_all <= 14) +			pwdb_all -= 4; +		if (!cck_highpwr) { +			if (pwdb_all >= 80) +				pwdb_all = ((pwdb_all - 80) << 1) + +					   ((pwdb_all - 80) >> 1) + 80; +			else if ((pwdb_all <= 78) && (pwdb_all >= 20)) +				pwdb_all += 3; +			if (pwdb_all > 100) +				pwdb_all = 100; +		} + +		pstatus->rx_pwdb_all = pwdb_all; +		pstatus->recvsignalpower = rx_pwr_all; + +		/* (3) Get Signal Quality (EVM) */ +		if (packet_match_bssid) { +			u8 sq; + +			if (pstatus->rx_pwdb_all > 40) { +				sq = 100; +			} else { +				sq = cck_buf->sq_rpt; +				if (sq > 64) +					sq = 0; +				else if (sq < 20) +					sq = 100; +				else +					sq = ((64 - sq) * 100) / 44; +			} + +			pstatus->signalquality = sq; +			pstatus->rx_mimo_sig_qual[0] = sq; +			pstatus->rx_mimo_sig_qual[1] = -1; +		} +	} else { +		rtlpriv->dm.rfpath_rxenable[0] = true; +		rtlpriv->dm.rfpath_rxenable[1] = true; + +		/* (1)Get RSSI for HT rate */ +		for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { +			/* we will judge RF RX path now. */ +			if (rtlpriv->dm.rfpath_rxenable[i]) +				rf_rx_num++; + +			rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f)*2) - 110; + +			/* Translate DBM to percentage. */ +			rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); +			total_rssi += rssi; + +			/* Get Rx snr value in DB */ +			rtlpriv->stats.rx_snr_db[i] = +					(long)(p_drvinfo->rxsnr[i] / 2); + +			/* Record Signal Strength for next packet */ +			if (packet_match_bssid) +				pstatus->rx_mimo_signalstrength[i] = (u8) rssi; +		} + +		/* (2)PWDB, Avg cacluated by hardware (for rate adaptive) */ +		rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + +		pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); +		pstatus->rx_pwdb_all = pwdb_all; +		pstatus->rxpower = rx_pwr_all; +		pstatus->recvsignalpower = rx_pwr_all; + +		/* (3)EVM of HT rate */ +		if (pstatus->is_ht && pstatus->rate >= DESC92C_RATEMCS8 && +		    pstatus->rate <= DESC92C_RATEMCS15) +			max_spatial_stream = 2; +		else +			max_spatial_stream = 1; + +		for (i = 0; i < max_spatial_stream; i++) { +			evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); + +			if (packet_match_bssid) { +				/* Fill value in RFD, Get the first +				 * spatial stream only +				 */ +				if (i == 0) +					pstatus->signalquality = +							(u8) (evm & 0xff); +				pstatus->rx_mimo_sig_qual[i] = +							(u8) (evm & 0xff); +			} +		} +		if (packet_match_bssid) { +			for (i = RF90_PATH_A; i <= RF90_PATH_B; i++) +				rtl_priv(hw)->dm.cfo_tail[i] = +					(char)p_phystrpt->path_cfotail[i]; + +			rtl_priv(hw)->dm.packet_count++; +			if (rtl_priv(hw)->dm.packet_count == 0xffffffff) +				rtl_priv(hw)->dm.packet_count = 0; +		} +	} + +	/* UI BSS List signal strength(in percentage), +	 * make it good looking, from 0~100. +	 */ +	if (is_cck) +		pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, +								pwdb_all)); +	else if (rf_rx_num != 0) +		pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, +						total_rssi /= rf_rx_num)); +	/*HW antenna diversity*/ +	rtldm->fat_table.antsel_rx_keep_0 = p_phystrpt->ant_sel; +	rtldm->fat_table.antsel_rx_keep_1 = p_phystrpt->ant_sel_b; +	rtldm->fat_table.antsel_rx_keep_2 = p_phystrpt->antsel_rx_keep_2; +} + +static void _rtl8723be_translate_rx_signal_stuff(struct ieee80211_hw *hw, +					struct sk_buff *skb, +					struct rtl_stats *pstatus, +					u8 *pdesc, +					struct rx_fwinfo_8723be *p_drvinfo) +{ +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); +	struct ieee80211_hdr *hdr; +	u8 *tmp_buf; +	u8 *praddr; +	u8 *psaddr; +	u16 fc, type; +	bool packet_matchbssid, packet_toself, packet_beacon; + +	tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; + +	hdr = (struct ieee80211_hdr *)tmp_buf; +	fc = le16_to_cpu(hdr->frame_control); +	type = WLAN_FC_GET_TYPE(hdr->frame_control); +	praddr = hdr->addr1; +	psaddr = ieee80211_get_SA(hdr); +	memcpy(pstatus->psaddr, psaddr, ETH_ALEN); + +	packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && +	     (!ether_addr_equal(mac->bssid, (fc & IEEE80211_FCTL_TODS) ? +				hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? +				hdr->addr2 : hdr->addr3)) && +				(!pstatus->hwerror) && +				(!pstatus->crc) && (!pstatus->icv)); + +	packet_toself = packet_matchbssid && +	    (!ether_addr_equal(praddr, rtlefuse->dev_addr)); + +	/* YP: packet_beacon is not initialized, +	 * this assignment is neccesary, +	 * otherwise it counld be true in this case +	 * the situation is much worse in Kernel 3.10 +	 */ +	if (ieee80211_is_beacon(hdr->frame_control)) +		packet_beacon = true; +	else +		packet_beacon = false; + +	if (packet_beacon && packet_matchbssid) +		rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++; + +	_rtl8723be_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, +				     packet_matchbssid, +				     packet_toself, +				     packet_beacon); + +	rtl_process_phyinfo(hw, tmp_buf, pstatus); +} + +static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, +					u8 *virtualaddress) +{ +	u32 dwtmp = 0; +	memset(virtualaddress, 0, 8); + +	SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num); +	if (ptcb_desc->empkt_num == 1) { +		dwtmp = ptcb_desc->empkt_len[0]; +	} else { +		dwtmp = ptcb_desc->empkt_len[0]; +		dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; +		dwtmp += ptcb_desc->empkt_len[1]; +	} +	SET_EARLYMODE_LEN0(virtualaddress, dwtmp); + +	if (ptcb_desc->empkt_num <= 3) { +		dwtmp = ptcb_desc->empkt_len[2]; +	} else { +		dwtmp = ptcb_desc->empkt_len[2]; +		dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; +		dwtmp += ptcb_desc->empkt_len[3]; +	} +	SET_EARLYMODE_LEN1(virtualaddress, dwtmp); +	if (ptcb_desc->empkt_num <= 5) { +		dwtmp = ptcb_desc->empkt_len[4]; +	} else { +		dwtmp = ptcb_desc->empkt_len[4]; +		dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; +		dwtmp += ptcb_desc->empkt_len[5]; +	} +	SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF); +	SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4); +	if (ptcb_desc->empkt_num <= 7) { +		dwtmp = ptcb_desc->empkt_len[6]; +	} else { +		dwtmp = ptcb_desc->empkt_len[6]; +		dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; +		dwtmp += ptcb_desc->empkt_len[7]; +	} +	SET_EARLYMODE_LEN3(virtualaddress, dwtmp); +	if (ptcb_desc->empkt_num <= 9) { +		dwtmp = ptcb_desc->empkt_len[8]; +	} else { +		dwtmp = ptcb_desc->empkt_len[8]; +		dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; +		dwtmp += ptcb_desc->empkt_len[9]; +	} +	SET_EARLYMODE_LEN4(virtualaddress, dwtmp); +} + +bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw, +			     struct rtl_stats *status, +			     struct ieee80211_rx_status *rx_status, +			     u8 *pdesc, struct sk_buff *skb) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rx_fwinfo_8723be *p_drvinfo; +	struct ieee80211_hdr *hdr; + +	u32 phystatus = GET_RX_DESC_PHYST(pdesc); +	status->packet_report_type = (u8)GET_RX_STATUS_DESC_RPT_SEL(pdesc); +	if (status->packet_report_type == TX_REPORT2) +		status->length = (u16) GET_RX_RPT2_DESC_PKT_LEN(pdesc); +	else +		status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); +	status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * +				  RX_DRV_INFO_SIZE_UNIT; +	status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); +	status->icv = (u16) GET_RX_DESC_ICV(pdesc); +	status->crc = (u16) GET_RX_DESC_CRC32(pdesc); +	status->hwerror = (status->crc | status->icv); +	status->decrypted = !GET_RX_DESC_SWDEC(pdesc); +	status->rate = (u8) GET_RX_DESC_RXMCS(pdesc); +	status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); +	status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); +	status->isfirst_ampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); +	if (status->packet_report_type == NORMAL_RX) +		status->timestamp_low = GET_RX_DESC_TSFL(pdesc); +	status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); +	status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc); + +	status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate); + +	status->macid = GET_RX_DESC_MACID(pdesc); +	if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc)) +		status->wake_match = BIT(2); +	else if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc)) +		status->wake_match = BIT(1); +	else if (GET_RX_STATUS_DESC_UNICAST_MATCH(pdesc)) +		status->wake_match = BIT(0); +	else +		status->wake_match = 0; +	if (status->wake_match) +		RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, +			 "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n", +			 status->wake_match); +	rx_status->freq = hw->conf.chandef.chan->center_freq; +	rx_status->band = hw->conf.chandef.chan->band; + + +	hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size + +				       status->rx_bufshift); + +	if (status->crc) +		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + +	if (status->rx_is40Mhzpacket) +		rx_status->flag |= RX_FLAG_40MHZ; + +	if (status->is_ht) +		rx_status->flag |= RX_FLAG_HT; + +	rx_status->flag |= RX_FLAG_MACTIME_START; + +	/* hw will set status->decrypted true, if it finds the +	 * frame is open data frame or mgmt frame. +	 * So hw will not decryption robust managment frame +	 * for IEEE80211w but still set status->decrypted +	 * true, so here we should set it back to undecrypted +	 * for IEEE80211w frame, and mac80211 sw will help +	 * to decrypt it +	 */ +	if (status->decrypted) { +		if (!hdr) { +			WARN_ON_ONCE(true); +			pr_err("decrypted is true but hdr NULL in skb %p\n", +			       rtl_get_hdr(skb)); +			return false; +		} + +		if ((_ieee80211_is_robust_mgmt_frame(hdr)) && +		    (ieee80211_has_protected(hdr->frame_control))) +			rx_status->flag &= ~RX_FLAG_DECRYPTED; +		else +			rx_status->flag |= RX_FLAG_DECRYPTED; +	} + +	/* rate_idx: index of data rate into band's +	 * supported rates or MCS index if HT rates +	 * are use (RX_FLAG_HT) +	 * Notice: this is diff with windows define +	 */ +	rx_status->rate_idx = _rtl8723be_rate_mapping(hw, status->is_ht, +						      status->rate); + +	rx_status->mactime = status->timestamp_low; +	if (phystatus) { +		p_drvinfo = (struct rx_fwinfo_8723be *)(skb->data + +							status->rx_bufshift); + +		_rtl8723be_translate_rx_signal_stuff(hw, skb, status, +						     pdesc, p_drvinfo); +	} + +	/*rx_status->qual = status->signal; */ +	rx_status->signal = status->recvsignalpower + 10; +	if (status->packet_report_type == TX_REPORT2) { +		status->macid_valid_entry[0] = +			 GET_RX_RPT2_DESC_MACID_VALID_1(pdesc); +		status->macid_valid_entry[1] = +			 GET_RX_RPT2_DESC_MACID_VALID_2(pdesc); +	} +	return true; +} + +void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw, +			    struct ieee80211_hdr *hdr, u8 *pdesc_tx, +			    u8 *pbd_desc_tx, struct ieee80211_tx_info *info, +			    struct ieee80211_sta *sta, struct sk_buff *skb, +			    u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl_hal *rtlhal = rtl_hal(rtlpriv); +	u8 *pdesc = pdesc_tx; +	u16 seq_number; +	__le16 fc = hdr->frame_control; +	unsigned int buf_len = 0; +	unsigned int skb_len = skb->len; +	u8 fw_qsel = _rtl8723be_map_hwqueue_to_fwqueue(skb, hw_queue); +	bool firstseg = ((hdr->seq_ctrl & +			  cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); +	bool lastseg = ((hdr->frame_control & +			 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); +	dma_addr_t mapping; +	u8 bw_40 = 0; +	u8 short_gi = 0; + +	if (mac->opmode == NL80211_IFTYPE_STATION) { +		bw_40 = mac->bw_40; +	} else if (mac->opmode == NL80211_IFTYPE_AP || +		mac->opmode == NL80211_IFTYPE_ADHOC) { +		if (sta) +			bw_40 = sta->ht_cap.cap & +				IEEE80211_HT_CAP_SUP_WIDTH_20_40; +	} +	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; +	rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); +	/* reserve 8 byte for AMPDU early mode */ +	if (rtlhal->earlymode_enable) { +		skb_push(skb, EM_HDR_LEN); +		memset(skb->data, 0, EM_HDR_LEN); +	} +	buf_len = skb->len; +	mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, +				 PCI_DMA_TODEVICE); +	if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { +		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "DMA mapping error"); +		return; +	} +	CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723be)); +	if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { +		firstseg = true; +		lastseg = true; +	} +	if (firstseg) { +		if (rtlhal->earlymode_enable) { +			SET_TX_DESC_PKT_OFFSET(pdesc, 1); +			SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN + +					   EM_HDR_LEN); +			if (ptcb_desc->empkt_num) { +				RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, +					 "Insert 8 byte.pTcb->EMPktNum:%d\n", +					  ptcb_desc->empkt_num); +				_rtl8723be_insert_emcontent(ptcb_desc, +							    (u8 *)(skb->data)); +			} +		} else { +			SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); +		} + +		/* ptcb_desc->use_driver_rate = true; */ +		SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate); +		if (ptcb_desc->hw_rate > DESC92C_RATEMCS0) +			short_gi = (ptcb_desc->use_shortgi) ? 1 : 0; +		else +			short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0; + +		SET_TX_DESC_DATA_SHORTGI(pdesc, short_gi); + +		if (info->flags & IEEE80211_TX_CTL_AMPDU) { +			SET_TX_DESC_AGG_ENABLE(pdesc, 1); +			SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); +		} +		SET_TX_DESC_SEQ(pdesc, seq_number); +		SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable && +						!ptcb_desc->cts_enable) ? +						1 : 0)); +		SET_TX_DESC_HW_RTS_ENABLE(pdesc, 0); +		SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? +					      1 : 0)); + +		SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate); + +		SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); +		SET_TX_DESC_RTS_SHORT(pdesc, +			((ptcb_desc->rts_rate <= DESC92C_RATE54M) ? +			 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : +			 (ptcb_desc->rts_use_shortgi ? 1 : 0))); + +		if (ptcb_desc->btx_enable_sw_calc_duration) +			SET_TX_DESC_NAV_USE_HDR(pdesc, 1); + +		if (bw_40) { +			if (ptcb_desc->packet_bw) { +				SET_TX_DESC_DATA_BW(pdesc, 1); +				SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); +			} else { +				SET_TX_DESC_DATA_BW(pdesc, 0); +				SET_TX_DESC_TX_SUB_CARRIER(pdesc, mac->cur_40_prime_sc); +			} +		} else { +			SET_TX_DESC_DATA_BW(pdesc, 0); +			SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); +		} + +		SET_TX_DESC_LINIP(pdesc, 0); +		SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len); +		if (sta) { +			u8 ampdu_density = sta->ht_cap.ampdu_density; +			SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); +		} +		if (info->control.hw_key) { +			struct ieee80211_key_conf *keyconf = +						info->control.hw_key; +			switch (keyconf->cipher) { +			case WLAN_CIPHER_SUITE_WEP40: +			case WLAN_CIPHER_SUITE_WEP104: +			case WLAN_CIPHER_SUITE_TKIP: +				SET_TX_DESC_SEC_TYPE(pdesc, 0x1); +				break; +			case WLAN_CIPHER_SUITE_CCMP: +				SET_TX_DESC_SEC_TYPE(pdesc, 0x3); +				break; +			default: +				SET_TX_DESC_SEC_TYPE(pdesc, 0x0); +				break; +			} +		} + +		SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); +		SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); +		SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); +		SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ? +				       1 : 0); +		SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + +		if (ieee80211_is_data_qos(fc)) { +			if (mac->rdg_en) { +				RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, +					 "Enable RDG function.\n"); +				SET_TX_DESC_RDG_ENABLE(pdesc, 1); +				SET_TX_DESC_HTC(pdesc, 1); +			} +		} +	} + +	SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); +	SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); +	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len); +	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); +	SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index); +	SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id); + +	if (!ieee80211_is_data_qos(fc))  { +		SET_TX_DESC_HWSEQ_EN(pdesc, 1); +		SET_TX_DESC_HWSEQ_SEL(pdesc, 0); +	} +	SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); +	if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || +	    is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { +		SET_TX_DESC_BMC(pdesc, 1); +	} +	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); +} + +void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, +			       bool b_firstseg, bool b_lastseg, +			       struct sk_buff *skb) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	u8 fw_queue = QSLT_BEACON; + +	dma_addr_t mapping = pci_map_single(rtlpci->pdev, +					    skb->data, skb->len, +					    PCI_DMA_TODEVICE); + +	if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { +		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, +			 "DMA mapping error"); +		return; +	} +	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); + +	SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + +	SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); + +	SET_TX_DESC_SEQ(pdesc, 0); + +	SET_TX_DESC_LINIP(pdesc, 0); + +	SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); + +	SET_TX_DESC_FIRST_SEG(pdesc, 1); +	SET_TX_DESC_LAST_SEG(pdesc, 1); + +	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); + +	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); + +	SET_TX_DESC_RATE_ID(pdesc, 0); +	SET_TX_DESC_MACID(pdesc, 0); + +	SET_TX_DESC_OWN(pdesc, 1); + +	SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len)); + +	SET_TX_DESC_FIRST_SEG(pdesc, 1); +	SET_TX_DESC_LAST_SEG(pdesc, 1); + +	SET_TX_DESC_USE_RATE(pdesc, 1); +} + +void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +			u8 desc_name, u8 *val) +{ +	if (istx) { +		switch (desc_name) { +		case HW_DESC_OWN: +			SET_TX_DESC_OWN(pdesc, 1); +			break; +		case HW_DESC_TX_NEXTDESC_ADDR: +			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *)val); +			break; +		default: +			RT_ASSERT(false, "ERR txdesc :%d not process\n", +				  desc_name); +			break; +		} +	} else { +		switch (desc_name) { +		case HW_DESC_RXOWN: +			SET_RX_DESC_OWN(pdesc, 1); +			break; +		case HW_DESC_RXBUFF_ADDR: +			SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *)val); +			break; +		case HW_DESC_RXPKT_LEN: +			SET_RX_DESC_PKT_LEN(pdesc, *(u32 *)val); +			break; +		case HW_DESC_RXERO: +			SET_RX_DESC_EOR(pdesc, 1); +			break; +		default: +			RT_ASSERT(false, "ERR rxdesc :%d not process\n", +				  desc_name); +			break; +		} +	} +} + +u32 rtl8723be_get_desc(u8 *pdesc, bool istx, u8 desc_name) +{ +	u32 ret = 0; + +	if (istx) { +		switch (desc_name) { +		case HW_DESC_OWN: +			ret = GET_TX_DESC_OWN(pdesc); +			break; +		case HW_DESC_TXBUFF_ADDR: +			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc); +			break; +		default: +			RT_ASSERT(false, "ERR txdesc :%d not process\n", +				  desc_name); +			break; +		} +	} else { +		switch (desc_name) { +		case HW_DESC_OWN: +			ret = GET_RX_DESC_OWN(pdesc); +			break; +		case HW_DESC_RXPKT_LEN: +			ret = GET_RX_DESC_PKT_LEN(pdesc); +			break; +		default: +			RT_ASSERT(false, "ERR rxdesc :%d not process\n", +				  desc_name); +			break; +		} +	} +	return ret; +} + +bool rtl8723be_is_tx_desc_closed(struct ieee80211_hw *hw, +				 u8 hw_queue, u16 index) +{ +	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); +	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; +	u8 *entry = (u8 *)(&ring->desc[ring->idx]); +	u8 own = (u8) rtl8723be_get_desc(entry, true, HW_DESC_OWN); + +	/*beacon packet will only use the first +	 *descriptor by default, and the own may not +	 *be cleared by the hardware +	 */ +	if (own) +		return false; +	else +		return true; +} + +void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ +	struct rtl_priv *rtlpriv = rtl_priv(hw); +	if (hw_queue == BEACON_QUEUE) { +		rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); +	} else { +		rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, +			       BIT(0) << (hw_queue)); +	} +} diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.h b/drivers/net/wireless/rtlwifi/rtl8723be/trx.h new file mode 100644 index 00000000000..102f33dcc98 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.h @@ -0,0 +1,617 @@ +/****************************************************************************** + * + * 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 __RTL8723BE_TRX_H__ +#define __RTL8723BE_TRX_H__ + +#define TX_DESC_SIZE				40 +#define TX_DESC_AGGR_SUBFRAME_SIZE		32 + +#define RX_DESC_SIZE				32 +#define RX_DRV_INFO_SIZE_UNIT			8 + +#define	TX_DESC_NEXT_DESC_OFFSET		40 +#define USB_HWDESC_HEADER_LEN			40 +#define CRCLENGTH				4 + +#define SET_TX_DESC_PKT_SIZE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) +#define SET_TX_DESC_OFFSET(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) +#define SET_TX_DESC_BMC(__pdesc, __val)			\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) +#define SET_TX_DESC_HTC(__pdesc, __val)			\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) +#define SET_TX_DESC_LAST_SEG(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) +#define SET_TX_DESC_FIRST_SEG(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) +#define SET_TX_DESC_LINIP(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) +#define SET_TX_DESC_NO_ACM(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) +#define SET_TX_DESC_GF(__pdesc, __val)			\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) +#define SET_TX_DESC_OWN(__pdesc, __val)			\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + +#define GET_TX_DESC_PKT_SIZE(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 0, 16) +#define GET_TX_DESC_OFFSET(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 16, 8) +#define GET_TX_DESC_BMC(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 24, 1) +#define GET_TX_DESC_HTC(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 25, 1) +#define GET_TX_DESC_LAST_SEG(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 26, 1) +#define GET_TX_DESC_FIRST_SEG(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 27, 1) +#define GET_TX_DESC_LINIP(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 28, 1) +#define GET_TX_DESC_NO_ACM(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 29, 1) +#define GET_TX_DESC_GF(__pdesc)				\ +	LE_BITS_TO_4BYTE(__pdesc, 30, 1) +#define GET_TX_DESC_OWN(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 31, 1) + +#define SET_TX_DESC_MACID(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 7, __val) +#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) +#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) +#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) +#define SET_TX_DESC_PIFS(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) +#define SET_TX_DESC_RATE_ID(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 5, __val) +#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) +#define SET_TX_DESC_SEC_TYPE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) +#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 5, __val) + + +#define SET_TX_DESC_PAID(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 9, __val) +#define SET_TX_DESC_CCA_RTS(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 10, 2, __val) +#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 12, 1, __val) +#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 13, 1, __val) +#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) +#define SET_TX_DESC_AGG_BREAK(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 16, 1, __val) +#define SET_TX_DESC_MORE_FRAG(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) +#define SET_TX_DESC_RAW(__pdesc, __val)			\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) +#define SET_TX_DESC_SPE_RPT(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) +#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) +#define SET_TX_DESC_BT_INT(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 23, 1, __val) +#define SET_TX_DESC_GID(__pdesc, __val)			\ +	SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 6, __val) + + +#define SET_TX_DESC_WHEADER_LEN(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 4, __val) +#define SET_TX_DESC_CHK_EN(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 4, 1, __val) +#define SET_TX_DESC_EARLY_MODE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 5, 1, __val) +#define SET_TX_DESC_HWSEQ_SEL(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 6, 2, __val) +#define SET_TX_DESC_USE_RATE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 1, __val) +#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 9, 1, __val) +#define SET_TX_DESC_DISABLE_FB(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 10, 1, __val) +#define SET_TX_DESC_CTS2SELF(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 11, 1, __val) +#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 12, 1, __val) +#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 13, 1, __val) +#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 15, 1, __val) +#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 1, __val) +#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 17, 5, __val) +#define SET_TX_DESC_NDPA(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 22, 2, __val) +#define SET_TX_DESC_AMPDU_MAX_TIME(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+12, 24, 8, __val) + + +#define SET_TX_DESC_TX_RATE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 7, __val) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 5, __val) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 4, __val) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+16, 17, 1, __val) +#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 6, __val) +#define SET_TX_DESC_RTS_RATE(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 5, __val) + + +#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 4, __val) +#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+20, 4, 1, __val) +#define SET_TX_DESC_DATA_BW(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+20, 5, 2, __val) +#define SET_TX_DESC_DATA_LDPC(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) +#define SET_TX_DESC_DATA_STBC(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 2, __val) +#define SET_TX_DESC_CTROL_STBC(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+20, 10, 2, __val) +#define SET_TX_DESC_RTS_SHORT(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+20, 12, 1, __val) +#define SET_TX_DESC_RTS_SC(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) + + +#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) + +#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) + +#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+32, 15, 1, __val) + +#define SET_TX_DESC_SEQ(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+36, 12, 12, __val) + +#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) + +#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) + + +#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+48, 0, 32, __val) + +#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+48, 0, 32) + +#define GET_RX_DESC_PKT_LEN(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 0, 14) +#define GET_RX_DESC_CRC32(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 14, 1) +#define GET_RX_DESC_ICV(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 15, 1) +#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc, 16, 4) +#define GET_RX_DESC_SECURITY(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 20, 3) +#define GET_RX_DESC_QOS(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 23, 1) +#define GET_RX_DESC_SHIFT(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 24, 2) +#define GET_RX_DESC_PHYST(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 26, 1) +#define GET_RX_DESC_SWDEC(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 27, 1) +#define GET_RX_DESC_LS(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 28, 1) +#define GET_RX_DESC_FS(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 29, 1) +#define GET_RX_DESC_EOR(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 30, 1) +#define GET_RX_DESC_OWN(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc, 31, 1) + +#define SET_RX_DESC_PKT_LEN(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) +#define SET_RX_DESC_EOR(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) +#define SET_RX_DESC_OWN(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + +#define GET_RX_DESC_MACID(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 0, 7) +#define GET_RX_DESC_TID(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 8, 4) +#define GET_RX_DESC_AMSDU(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) +#define GET_RX_DESC_PAGGR(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) +#define GET_RX_DESC_A1_FIT(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) +#define GET_RX_DESC_CHKERR(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) +#define GET_RX_DESC_IPVER(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) +#define GET_RX_STATUS_DESC_IS_TCPUDP(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+4, 22, 1) +#define GET_RX_STATUS_DESC_CHK_VLD(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+4, 23, 1) +#define GET_RX_DESC_PAM(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) +#define GET_RX_DESC_PWR(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) +#define GET_RX_DESC_MD(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) +#define GET_RX_DESC_MF(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) +#define GET_RX_DESC_TYPE(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) +#define GET_RX_DESC_MC(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) +#define GET_RX_DESC_BC(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) + + +#define GET_RX_DESC_SEQ(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) +#define GET_RX_DESC_FRAG(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) +#define GET_RX_STATUS_DESC_RX_IS_QOS(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+8, 16, 1) +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN(__pdesc)	\ +	LE_BITS_TO_4BYTE(__pdesc+8, 18, 6) +#define GET_RX_STATUS_DESC_RPT_SEL(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+8, 28, 1) + + +#define GET_RX_DESC_RXMCS(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+12, 0, 7) +#define GET_RX_DESC_RXHT(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) +#define GET_RX_STATUS_DESC_RX_GF(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+12, 7, 1) +#define GET_RX_DESC_HTC(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+12, 12, 2) + +#define GET_RX_STATUS_DESC_PATTERN_MATCH(__pdesc)	\ +	LE_BITS_TO_4BYTE(__pdesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_MATCH(__pdesc)	\ +	LE_BITS_TO_4BYTE(__pdesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_MATCH(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+12, 31, 1) + +#define GET_RX_DESC_SPLCP(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+16, 0, 1) +#define GET_RX_STATUS_DESC_LDPC(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+16, 1, 1) +#define GET_RX_STATUS_DESC_STBC(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+16, 2, 1) +#define GET_RX_DESC_BW(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+16, 4, 2) + +#define GET_RX_DESC_TSFL(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) + +#define GET_RX_DESC_BUFF_ADDR(__pdesc)			\ +	LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) +#define GET_RX_DESC_BUFF_ADDR64(__pdesc)		\ +	LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) + +#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val)		\ +	SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) +#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val)	\ +	SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) + + +/* TX report 2 format in Rx desc*/ + +#define GET_RX_RPT2_DESC_PKT_LEN(__rxstatusdesc)	\ +	LE_BITS_TO_4BYTE(__rxstatusdesc, 0, 9) +#define GET_RX_RPT2_DESC_MACID_VALID_1(__rxstatusdesc)	\ +	LE_BITS_TO_4BYTE(__rxstatusdesc+16, 0, 32) +#define GET_RX_RPT2_DESC_MACID_VALID_2(__rxstatusdesc)	\ +	LE_BITS_TO_4BYTE(__rxstatusdesc+20, 0, 32) + +#define SET_EARLYMODE_PKTNUM(__paddr, __value)		\ +	SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __value) +#define SET_EARLYMODE_LEN0(__paddr, __value)		\ +	SET_BITS_TO_LE_4BYTE(__paddr, 4, 12, __value) +#define SET_EARLYMODE_LEN1(__paddr, __value)		\ +	SET_BITS_TO_LE_4BYTE(__paddr, 16, 12, __value) +#define SET_EARLYMODE_LEN2_1(__paddr, __value)		\ +	SET_BITS_TO_LE_4BYTE(__paddr, 28, 4, __value) +#define SET_EARLYMODE_LEN2_2(__paddr, __value)		\ +	SET_BITS_TO_LE_4BYTE(__paddr+4, 0, 8, __value) +#define SET_EARLYMODE_LEN3(__paddr, __value)		\ +	SET_BITS_TO_LE_4BYTE(__paddr+4, 8, 12, __value) +#define SET_EARLYMODE_LEN4(__paddr, __value)		\ +	SET_BITS_TO_LE_4BYTE(__paddr+4, 20, 12, __value) + +#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size)		\ +do {								\ +	if (_size > TX_DESC_NEXT_DESC_OFFSET)			\ +		memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET);	\ +	else							\ +		memset(__pdesc, 0, _size);			\ +} while (0) + +struct phy_rx_agc_info_t { +	#ifdef __LITTLE_ENDIAN +		u8 gain:7, trsw:1; +	#else +		u8 trsw:1, gain:7; +	#endif +}; +struct phy_status_rpt { +	struct phy_rx_agc_info_t path_agc[2]; +	u8 ch_corr[2]; +	u8 cck_sig_qual_ofdm_pwdb_all; +	u8 cck_agc_rpt_ofdm_cfosho_a; +	u8 cck_rpt_b_ofdm_cfosho_b; +	u8 rsvd_1;/* ch_corr_msb; */ +	u8 noise_power_db_msb; +	char path_cfotail[2]; +	u8 pcts_mask[2]; +	char stream_rxevm[2]; +	u8 path_rxsnr[2]; +	u8 noise_power_db_lsb; +	u8 rsvd_2[3]; +	u8 stream_csi[2]; +	u8 stream_target_csi[2]; +	u8 sig_evm; +	u8 rsvd_3; +#ifdef __LITTLE_ENDIAN +	u8 antsel_rx_keep_2:1;	/*ex_intf_flg:1;*/ +	u8 sgi_en:1; +	u8 rxsc:2; +	u8 idle_long:1; +	u8 r_ant_train_en:1; +	u8 ant_sel_b:1; +	u8 ant_sel:1; +#else	/* _BIG_ENDIAN_	*/ +	u8 ant_sel:1; +	u8 ant_sel_b:1; +	u8 r_ant_train_en:1; +	u8 idle_long:1; +	u8 rxsc:2; +	u8 sgi_en:1; +	u8 antsel_rx_keep_2:1;	/*ex_intf_flg:1;*/ +#endif +} __packed; + +struct rx_fwinfo_8723be { +	u8 gain_trsw[4]; +	u8 pwdb_all; +	u8 cfosho[4]; +	u8 cfotail[4]; +	char rxevm[2]; +	char rxsnr[4]; +	u8 pdsnr[2]; +	u8 csi_current[2]; +	u8 csi_target[2]; +	u8 sigevm; +	u8 max_ex_pwr; +	u8 ex_intf_flag:1; +	u8 sgi_en:1; +	u8 rxsc:2; +	u8 reserve:4; +} __packed; + +struct tx_desc_8723be { +	u32 pktsize:16; +	u32 offset:8; +	u32 bmc:1; +	u32 htc:1; +	u32 lastseg:1; +	u32 firstseg:1; +	u32 linip:1; +	u32 noacm:1; +	u32 gf:1; +	u32 own:1; + +	u32 macid:6; +	u32 rsvd0:2; +	u32 queuesel:5; +	u32 rd_nav_ext:1; +	u32 lsig_txop_en:1; +	u32 pifs:1; +	u32 rateid:4; +	u32 nav_usehdr:1; +	u32 en_descid:1; +	u32 sectype:2; +	u32 pktoffset:8; + +	u32 rts_rc:6; +	u32 data_rc:6; +	u32 agg_en:1; +	u32 rdg_en:1; +	u32 bar_retryht:2; +	u32 agg_break:1; +	u32 morefrag:1; +	u32 raw:1; +	u32 ccx:1; +	u32 ampdudensity:3; +	u32 bt_int:1; +	u32 ant_sela:1; +	u32 ant_selb:1; +	u32 txant_cck:2; +	u32 txant_l:2; +	u32 txant_ht:2; + +	u32 nextheadpage:8; +	u32 tailpage:8; +	u32 seq:12; +	u32 cpu_handle:1; +	u32 tag1:1; +	u32 trigger_int:1; +	u32 hwseq_en:1; + +	u32 rtsrate:5; +	u32 apdcfe:1; +	u32 qos:1; +	u32 hwseq_ssn:1; +	u32 userrate:1; +	u32 dis_rtsfb:1; +	u32 dis_datafb:1; +	u32 cts2self:1; +	u32 rts_en:1; +	u32 hwrts_en:1; +	u32 portid:1; +	u32 pwr_status:3; +	u32 waitdcts:1; +	u32 cts2ap_en:1; +	u32 txsc:2; +	u32 stbc:2; +	u32 txshort:1; +	u32 txbw:1; +	u32 rtsshort:1; +	u32 rtsbw:1; +	u32 rtssc:2; +	u32 rtsstbc:2; + +	u32 txrate:6; +	u32 shortgi:1; +	u32 ccxt:1; +	u32 txrate_fb_lmt:5; +	u32 rtsrate_fb_lmt:4; +	u32 retrylmt_en:1; +	u32 txretrylmt:6; +	u32 usb_txaggnum:8; + +	u32 txagca:5; +	u32 txagcb:5; +	u32 usemaxlen:1; +	u32 maxaggnum:5; +	u32 mcsg1maxlen:4; +	u32 mcsg2maxlen:4; +	u32 mcsg3maxlen:4; +	u32 mcs7sgimaxlen:4; + +	u32 txbuffersize:16; +	u32 sw_offset30:8; +	u32 sw_offset31:4; +	u32 rsvd1:1; +	u32 antsel_c:1; +	u32 null_0:1; +	u32 null_1:1; + +	u32 txbuffaddr; +	u32 txbufferaddr64; +	u32 nextdescaddress; +	u32 nextdescaddress64; + +	u32 reserve_pass_pcie_mm_limit[4]; +} __packed; + +struct rx_desc_8723be { +	u32 length:14; +	u32 crc32:1; +	u32 icverror:1; +	u32 drv_infosize:4; +	u32 security:3; +	u32 qos:1; +	u32 shift:2; +	u32 phystatus:1; +	u32 swdec:1; +	u32 lastseg:1; +	u32 firstseg:1; +	u32 eor:1; +	u32 own:1; + +	u32 macid:6; +	u32 tid:4; +	u32 hwrsvd:5; +	u32 paggr:1; +	u32 faggr:1; +	u32 a1_fit:4; +	u32 a2_fit:4; +	u32 pam:1; +	u32 pwr:1; +	u32 moredata:1; +	u32 morefrag:1; +	u32 type:2; +	u32 mc:1; +	u32 bc:1; + +	u32 seq:12; +	u32 frag:4; +	u32 nextpktlen:14; +	u32 nextind:1; +	u32 rsvd:1; + +	u32 rxmcs:6; +	u32 rxht:1; +	u32 amsdu:1; +	u32 splcp:1; +	u32 bandwidth:1; +	u32 htc:1; +	u32 tcpchk_rpt:1; +	u32 ipcchk_rpt:1; +	u32 tcpchk_valid:1; +	u32 hwpcerr:1; +	u32 hwpcind:1; +	u32 iv0:16; + +	u32 iv1; + +	u32 tsfl; + +	u32 bufferaddress; +	u32 bufferaddress64; + +} __packed; + +void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw, +			    struct ieee80211_hdr *hdr, u8 *pdesc, +			    u8 *pbd_desc_tx, struct ieee80211_tx_info *info, +			    struct ieee80211_sta *sta, struct sk_buff *skb, +			    u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); +bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw, +			     struct rtl_stats *status, +			     struct ieee80211_rx_status *rx_status, +			     u8 *pdesc, struct sk_buff *skb); +void rtl8723be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +			u8 desc_name, u8 *val); +u32 rtl8723be_get_desc(u8 *pdesc, bool istx, u8 desc_name); +bool rtl8723be_is_tx_desc_closed(struct ieee80211_hw *hw, +				 u8 hw_queue, u16 index); +void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, +			       bool b_firstseg, bool b_lastseg, +			       struct sk_buff *skb); +#endif 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 diff --git a/drivers/net/wireless/rtlwifi/stats.c b/drivers/net/wireless/rtlwifi/stats.c index 8ed31744a05..4f083fc1d36 100644 --- a/drivers/net/wireless/rtlwifi/stats.c +++ b/drivers/net/wireless/rtlwifi/stats.c @@ -176,6 +176,7 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)  	struct rtl_sta_info *drv_priv = NULL;  	struct ieee80211_sta *sta = NULL;  	long undec_sm_pwdb; +	long undec_sm_cck;  	rcu_read_lock();  	if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) @@ -185,12 +186,16 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)  	if (sta) {  		drv_priv = (struct rtl_sta_info *) sta->drv_priv;  		undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; +		undec_sm_cck = drv_priv->rssi_stat.undec_sm_cck;  	} else {  		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; +		undec_sm_cck = rtlpriv->dm.undec_sm_cck;  	}  	if (undec_sm_pwdb < 0)  		undec_sm_pwdb = pstatus->rx_pwdb_all; +	if (undec_sm_cck < 0) +		undec_sm_cck = pstatus->rx_pwdb_all;  	if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) {  		undec_sm_pwdb = (((undec_sm_pwdb) *  		      (RX_SMOOTH_FACTOR - 1)) + @@ -200,6 +205,15 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)  		undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) +  		     (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);  	} +	if (pstatus->rx_pwdb_all > (u32) undec_sm_cck) { +		undec_sm_cck = (((undec_sm_pwdb) * +		      (RX_SMOOTH_FACTOR - 1)) + +		     (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); +		undec_sm_cck = undec_sm_cck + 1; +	} else { +		undec_sm_pwdb = (((undec_sm_cck) * (RX_SMOOTH_FACTOR - 1)) + +		     (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); +	}  	if (sta) {  		drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index e56778cac9b..0398d3ea15b 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -410,7 +410,7 @@ static void rtl_usb_init_sw(struct ieee80211_hw *hw)  	mac->current_ampdu_factor = 3;  	/* QOS */ -	rtlusb->acm_method = eAcmWay2_SW; +	rtlusb->acm_method = EACMWAY2_SW;  	/* IRQ */  	/* HIMR - turn all on */ @@ -455,7 +455,6 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw,  	struct ieee80211_rx_status rx_status = {0};  	struct rtl_stats stats = {  		.signal = 0, -		.noise = -98,  		.rate = 0,  	}; @@ -476,14 +475,14 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw,  			rtlpriv->stats.rxbytesunicast +=  skb->len;  		} -		rtl_is_special_data(hw, skb, false); -  		if (ieee80211_is_data(fc)) {  			rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);  			if (unicast)  				rtlpriv->link_info.num_rx_inperiod++;  		} +		/* static bcn for roaming */ +		rtl_beacon_statistic(hw, skb);  	}  } @@ -498,7 +497,6 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,  	struct ieee80211_rx_status rx_status = {0};  	struct rtl_stats stats = {  		.signal = 0, -		.noise = -98,  		.rate = 0,  	}; @@ -519,8 +517,6 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,  			rtlpriv->stats.rxbytesunicast +=  skb->len;  		} -		rtl_is_special_data(hw, skb, false); -  		if (ieee80211_is_data(fc)) {  			rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); @@ -555,7 +551,7 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)  	}  } -#define __RX_SKB_MAX_QUEUED	32 +#define __RX_SKB_MAX_QUEUED	64  static void _rtl_rx_work(unsigned long param)  { @@ -582,12 +578,15 @@ static void _rtl_rx_work(unsigned long param)  static unsigned int _rtl_rx_get_padding(struct ieee80211_hdr *hdr,  					unsigned int len)  { +#if NET_IP_ALIGN != 0  	unsigned int padding = 0; +#endif  	/* make function no-op when possible */  	if (NET_IP_ALIGN == 0 || len < sizeof(*hdr))  		return 0; +#if NET_IP_ALIGN != 0  	/* alignment calculation as in lbtf_rx() / carl9170_rx_copy_data() */  	/* TODO: deduplicate common code, define helper function instead? */ @@ -608,6 +607,7 @@ static unsigned int _rtl_rx_get_padding(struct ieee80211_hdr *hdr,  		padding ^= NET_IP_ALIGN;  	return padding; +#endif  }  #define __RADIO_TAP_SIZE_RSV	32 @@ -994,7 +994,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw,  		seq_number += 1;  		seq_number <<= 4;  	} -	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, sta, skb, +	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, NULL, info, sta, skb,  					hw_queue, &tcb_desc);  	if (!ieee80211_has_morefrags(hdr->frame_control)) {  		if (qc) diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 703258742d2..407a7936d36 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -41,6 +41,38 @@  #include <linux/completion.h>  #include "debug.h" +#define	MASKBYTE0				0xff +#define	MASKBYTE1				0xff00 +#define	MASKBYTE2				0xff0000 +#define	MASKBYTE3				0xff000000 +#define	MASKHWORD				0xffff0000 +#define	MASKLWORD				0x0000ffff +#define	MASKDWORD				0xffffffff +#define	MASK12BITS				0xfff +#define	MASKH4BITS				0xf0000000 +#define MASKOFDM_D				0xffc00000 +#define	MASKCCK					0x3f3f3f3f + +#define	MASK4BITS				0x0f +#define	MASK20BITS				0xfffff +#define RFREG_OFFSET_MASK			0xfffff + +#define	MASKBYTE0				0xff +#define	MASKBYTE1				0xff00 +#define	MASKBYTE2				0xff0000 +#define	MASKBYTE3				0xff000000 +#define	MASKHWORD				0xffff0000 +#define	MASKLWORD				0x0000ffff +#define	MASKDWORD				0xffffffff +#define	MASK12BITS				0xfff +#define	MASKH4BITS				0xf0000000 +#define MASKOFDM_D				0xffc00000 +#define	MASKCCK					0x3f3f3f3f + +#define	MASK4BITS				0x0f +#define	MASK20BITS				0xfffff +#define RFREG_OFFSET_MASK			0xfffff +  #define RF_CHANGE_BY_INIT			0  #define RF_CHANGE_BY_IPS			BIT(28)  #define RF_CHANGE_BY_PS				BIT(29) @@ -49,6 +81,7 @@  #define IQK_ADDA_REG_NUM			16  #define IQK_MAC_REG_NUM				4 +#define IQK_THRESHOLD				8  #define MAX_KEY_LEN				61  #define KEY_BUF_SIZE				5 @@ -77,11 +110,7 @@  #define RTL_SLOT_TIME_9				9  #define RTL_SLOT_TIME_20			20 -/*related with tcp/ip. */ -/*if_ehther.h*/ -#define ETH_P_PAE		0x888E	/*Port Access Entity (IEEE 802.1X) */ -#define ETH_P_IP		0x0800	/*Internet Protocol packet */ -#define ETH_P_ARP		0x0806	/*Address Resolution packet */ +/*related to tcp/ip. */  #define SNAP_SIZE		6  #define PROTOC_TYPE_SIZE	2 @@ -90,7 +119,18 @@  #define MAC80211_4ADDR_LEN			30  #define CHANNEL_MAX_NUMBER	(14 + 24 + 21)	/* 14 is the max channel no */ +#define CHANNEL_MAX_NUMBER_2G		14 +#define CHANNEL_MAX_NUMBER_5G		54 /* Please refer to +					    *"phy_GetChnlGroup8812A" and +					    * "Hal_ReadTxPowerInfo8812A" +					    */ +#define CHANNEL_MAX_NUMBER_5G_80M	7  #define CHANNEL_GROUP_MAX	(3 + 9)	/*  ch1~3, 4~9, 10~14 = three groups */ +#define CHANNEL_MAX_NUMBER_5G		54 /* Please refer to +					    *"phy_GetChnlGroup8812A" and +					    * "Hal_ReadTxPowerInfo8812A" +					    */ +#define CHANNEL_MAX_NUMBER_5G_80M	7  #define MAX_PG_GROUP			13  #define	CHANNEL_GROUP_MAX_2G		3  #define	CHANNEL_GROUP_IDX_5GL		3 @@ -100,6 +140,7 @@  #define CHANNEL_MAX_NUMBER_2G		14  #define AVG_THERMAL_NUM			8  #define AVG_THERMAL_NUM_88E		4 +#define AVG_THERMAL_NUM_8723BE		4  #define MAX_TID_COUNT			9  /* for early mode */ @@ -111,6 +152,24 @@  #define	MAX_CHNL_GROUP_24G		6  #define	MAX_CHNL_GROUP_5G		14 +#define TX_PWR_BY_RATE_NUM_BAND		2 +#define TX_PWR_BY_RATE_NUM_RF		4 +#define TX_PWR_BY_RATE_NUM_SECTION	12 +#define MAX_BASE_NUM_IN_PHY_REG_PG_24G  6 +#define MAX_BASE_NUM_IN_PHY_REG_PG_5G	5 + +#define RTL8192EE_SEG_NUM		1 /* 0:2 seg, 1: 4 seg, 2: 8 seg */ + +#define DEL_SW_IDX_SZ		30 +#define BAND_NUM			3 + +enum rf_tx_num { +	RF_1TX = 0, +	RF_2TX, +	RF_MAX_TX_NUM, +	RF_TX_NUM_NONIMPLEMENT, +}; +  struct txpower_info_2g {  	u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];  	u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; @@ -119,6 +178,8 @@ struct txpower_info_2g {  	u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];  	u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];  	u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; +	u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT]; +	u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT];  };  struct txpower_info_5g { @@ -127,6 +188,17 @@ struct txpower_info_5g {  	u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT];  	u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT];  	u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; +	u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT]; +	u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT]; +}; + +enum rate_section { +	CCK = 0, +	OFDM, +	HT_MCS0_MCS7, +	HT_MCS8_MCS15, +	VHT_1SSMCS0_1SSMCS9, +	VHT_2SSMCS0_2SSMCS9,  };  enum intf_type { @@ -162,7 +234,10 @@ enum hardware_type {  	HARDWARE_TYPE_RTL8192DU,  	HARDWARE_TYPE_RTL8723AE,  	HARDWARE_TYPE_RTL8723U, +	HARDWARE_TYPE_RTL8723BE,  	HARDWARE_TYPE_RTL8188EE, +	HARDWARE_TYPE_RTL8821AE, +	HARDWARE_TYPE_RTL8812AE,  	/* keep it last */  	HARDWARE_TYPE_NUM @@ -192,8 +267,6 @@ enum hardware_type {  (IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal))  #define	IS_HARDWARE_TYPE_8723(rtlhal)			\  (IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal)) -#define IS_HARDWARE_TYPE_8723U(rtlhal)			\ -	(rtlhal->hw_type == HARDWARE_TYPE_RTL8723U)  #define RX_HAL_IS_CCK_RATE(_pdesc)\  	(_pdesc->rxmcs == DESC92_RATE1M ||		\ @@ -201,8 +274,16 @@ enum hardware_type {  	 _pdesc->rxmcs == DESC92_RATE5_5M ||		\  	 _pdesc->rxmcs == DESC92_RATE11M) +#define RTL8723E_RX_HAL_IS_CCK_RATE(rxmcs)		\ +	((rxmcs) == DESC92_RATE1M ||			\ +	 (rxmcs) == DESC92_RATE2M ||			\ +	 (rxmcs) == DESC92_RATE5_5M ||			\ +	 (rxmcs) == DESC92_RATE11M) +  enum scan_operation_backup_opt {  	SCAN_OPT_BACKUP = 0, +	SCAN_OPT_BACKUP_BAND0 = 0, +	SCAN_OPT_BACKUP_BAND1,  	SCAN_OPT_RESTORE,  	SCAN_OPT_MAX  }; @@ -237,7 +318,9 @@ struct bb_reg_def {  enum io_type {  	IO_CMD_PAUSE_DM_BY_SCAN = 0, -	IO_CMD_RESUME_DM_BY_SCAN = 1, +	IO_CMD_PAUSE_BAND0_DM_BY_SCAN = 0, +	IO_CMD_PAUSE_BAND1_DM_BY_SCAN = 1, +	IO_CMD_RESUME_DM_BY_SCAN = 2,  };  enum hw_variables { @@ -304,6 +387,7 @@ enum hw_variables {  	HW_VAR_SET_RPWM,  	HW_VAR_H2C_FW_PWRMODE,  	HW_VAR_H2C_FW_JOINBSSRPT, +	HW_VAR_H2C_FW_MEDIASTATUSRPT,  	HW_VAR_H2C_FW_P2P_PS_OFFLOAD,  	HW_VAR_FW_PSMODE_STATUS,  	HW_VAR_RESUME_CLK_ON, @@ -336,6 +420,8 @@ enum hw_variables {  	HAL_DEF_WOWLAN,  	HW_VAR_MRC, +	HW_VAR_KEEP_ALIVE, +	HW_VAR_NAV_UPPER,  	HW_VAR_MGT_FILTER,  	HW_VAR_CTRL_FILTER, @@ -354,34 +440,34 @@ enum rt_oem_id {  	RT_CID_8187_HW_LED = 3,  	RT_CID_8187_NETGEAR = 4,  	RT_CID_WHQL = 5, -	RT_CID_819x_CAMEO = 6, -	RT_CID_819x_RUNTOP = 7, -	RT_CID_819x_Senao = 8, +	RT_CID_819X_CAMEO = 6, +	RT_CID_819X_RUNTOP = 7, +	RT_CID_819X_SENAO = 8,  	RT_CID_TOSHIBA = 9, -	RT_CID_819x_Netcore = 10, -	RT_CID_Nettronix = 11, +	RT_CID_819X_NETCORE = 10, +	RT_CID_NETTRONIX = 11,  	RT_CID_DLINK = 12,  	RT_CID_PRONET = 13,  	RT_CID_COREGA = 14, -	RT_CID_819x_ALPHA = 15, -	RT_CID_819x_Sitecom = 16, +	RT_CID_819X_ALPHA = 15, +	RT_CID_819X_SITECOM = 16,  	RT_CID_CCX = 17, -	RT_CID_819x_Lenovo = 18, -	RT_CID_819x_QMI = 19, -	RT_CID_819x_Edimax_Belkin = 20, -	RT_CID_819x_Sercomm_Belkin = 21, -	RT_CID_819x_CAMEO1 = 22, -	RT_CID_819x_MSI = 23, -	RT_CID_819x_Acer = 24, -	RT_CID_819x_HP = 27, -	RT_CID_819x_CLEVO = 28, -	RT_CID_819x_Arcadyan_Belkin = 29, -	RT_CID_819x_SAMSUNG = 30, -	RT_CID_819x_WNC_COREGA = 31, -	RT_CID_819x_Foxcoon = 32, -	RT_CID_819x_DELL = 33, -	RT_CID_819x_PRONETS = 34, -	RT_CID_819x_Edimax_ASUS = 35, +	RT_CID_819X_LENOVO = 18, +	RT_CID_819X_QMI = 19, +	RT_CID_819X_EDIMAX_BELKIN = 20, +	RT_CID_819X_SERCOMM_BELKIN = 21, +	RT_CID_819X_CAMEO1 = 22, +	RT_CID_819X_MSI = 23, +	RT_CID_819X_ACER = 24, +	RT_CID_819X_HP = 27, +	RT_CID_819X_CLEVO = 28, +	RT_CID_819X_ARCADYAN_BELKIN = 29, +	RT_CID_819X_SAMSUNG = 30, +	RT_CID_819X_WNC_COREGA = 31, +	RT_CID_819X_FOXCOON = 32, +	RT_CID_819X_DELL = 33, +	RT_CID_819X_PRONETS = 34, +	RT_CID_819X_EDIMAX_ASUS = 35,  	RT_CID_NETGEAR = 36,  	RT_CID_PLANEX = 37,  	RT_CID_CC_C = 38, @@ -395,6 +481,7 @@ enum hw_descs {  	HW_DESC_RXBUFF_ADDR,  	HW_DESC_RXPKT_LEN,  	HW_DESC_RXERO, +	HW_DESC_RX_PREPARE,  };  enum prime_sc { @@ -413,6 +500,7 @@ enum rf_type {  enum ht_channel_width {  	HT_CHANNEL_WIDTH_20 = 0,  	HT_CHANNEL_WIDTH_20_40 = 1, +	HT_CHANNEL_WIDTH_80 = 2,  };  /* Ref: 802.11i sepc D10.0 7.3.2.25.1 @@ -477,6 +565,9 @@ enum rtl_var_map {  	MAC_RCR_ACRC32,  	MAC_RCR_ACF,  	MAC_RCR_AAP, +	MAC_HIMR, +	MAC_HIMRE, +	MAC_HSISR,  	/*efuse map */  	EFUSE_TEST, @@ -614,7 +705,7 @@ enum rtl_led_pin {  enum acm_method {  	eAcmWay0_SwAndHw = 0,  	eAcmWay1_HW = 1, -	eAcmWay2_SW = 2, +	EACMWAY2_SW = 2,  };  enum macphy_mode { @@ -651,7 +742,9 @@ enum wireless_mode {  	WIRELESS_MODE_G = 0x04,  	WIRELESS_MODE_AUTO = 0x08,  	WIRELESS_MODE_N_24G = 0x10, -	WIRELESS_MODE_N_5G = 0x20 +	WIRELESS_MODE_N_5G = 0x20, +	WIRELESS_MODE_AC_5G = 0x40, +	WIRELESS_MODE_AC_24G  = 0x80  };  #define IS_WIRELESS_MODE_A(wirelessmode)	\ @@ -675,6 +768,8 @@ enum ratr_table_mode {  	RATR_INX_WIRELESS_B = 6,  	RATR_INX_WIRELESS_MC = 7,  	RATR_INX_WIRELESS_A = 8, +	RATR_INX_WIRELESS_AC_5N = 8, +	RATR_INX_WIRELESS_AC_24N = 9,  };  enum rtl_link_state { @@ -809,8 +904,12 @@ struct wireless_stats {  	long signal_strength;  	u8 rx_rssi_percentage[4]; +	u8 rx_evm_dbm[4];  	u8 rx_evm_percentage[2]; +	u16 rx_cfo_short[4]; +	u16 rx_cfo_tail[4]; +  	struct rt_smooth_data ui_rssi;  	struct rt_smooth_data ui_link_quality;  }; @@ -823,9 +922,9 @@ struct rate_adaptive {  	u32 high_rssi_thresh_for_ra;  	u32 high2low_rssi_thresh_for_ra;  	u8 low2high_rssi_thresh_for_ra40m; -	u32 low_rssi_thresh_for_ra40M; +	u32 low_rssi_thresh_for_ra40m;  	u8 low2high_rssi_thresh_for_ra20m; -	u32 low_rssi_thresh_for_ra20M; +	u32 low_rssi_thresh_for_ra20m;  	u32 upper_rssi_threshold_ratr;  	u32 middleupper_rssi_threshold_ratr;  	u32 middle_rssi_threshold_ratr; @@ -839,6 +938,10 @@ struct rate_adaptive {  	u32 ping_rssi_thresh_for_ra;  	u32 last_ratr;  	u8 pre_ratr_state; +	u8 ldpc_thres; +	bool use_ldpc; +	bool lower_rts_rate; +	bool is_special_data;  };  struct regd_pair_mapping { @@ -847,6 +950,16 @@ struct regd_pair_mapping {  	u16 reg_2ghz_ctl;  }; +struct dynamic_primary_cca { +	u8 pricca_flag; +	u8 intf_flag; +	u8 intf_type; +	u8 dup_rts_flag; +	u8 monitor_flag; +	u8 ch_offset; +	u8 mf_state; +}; +  struct rtl_regulatory {  	char alpha2[2];  	u16 country_code; @@ -982,16 +1095,29 @@ struct rtl_phy {  	u32 iqk_bb_backup[10];  	bool iqk_initialized; +	bool rfpath_rx_enable[MAX_RF_PATH]; +	u8 reg_837;  	/* Dual mac */  	bool need_iqk;  	struct iqk_matrix_regs iqk_matrix[IQK_MATRIX_SETTINGS_NUM];  	bool rfpi_enable; +	bool iqk_in_progress;  	u8 pwrgroup_cnt;  	u8 cck_high_power;  	/* MAX_PG_GROUP groups of pwr diff by rates */  	u32 mcs_offset[MAX_PG_GROUP][16]; +	u32 tx_power_by_rate_offset[TX_PWR_BY_RATE_NUM_BAND] +				   [TX_PWR_BY_RATE_NUM_RF] +				   [TX_PWR_BY_RATE_NUM_RF] +				   [TX_PWR_BY_RATE_NUM_SECTION]; +	u8 txpwr_by_rate_base_24g[TX_PWR_BY_RATE_NUM_RF] +				 [TX_PWR_BY_RATE_NUM_RF] +				 [MAX_BASE_NUM_IN_PHY_REG_PG_24G]; +	u8 txpwr_by_rate_base_5g[TX_PWR_BY_RATE_NUM_RF] +				[TX_PWR_BY_RATE_NUM_RF] +				[MAX_BASE_NUM_IN_PHY_REG_PG_5G];  	u8 default_initialgain[4];  	/* the current Tx power level */ @@ -1004,6 +1130,7 @@ struct rtl_phy {  	bool apk_done;  	u32 reg_rf3c[2];	/* pathA / pathB  */ +	u32 backup_rf_0x1a;/*92ee*/  	/* bfsync */  	u8 framesync;  	u32 framesync_c34; @@ -1012,6 +1139,7 @@ struct rtl_phy {  	struct phy_parameters hwparam_tables[MAX_TAB];  	u16 rf_pathmap; +	u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/  	enum rt_polarity_ctl polarity_ctl;  }; @@ -1039,6 +1167,7 @@ struct rtl_ht_agg {  struct rssi_sta {  	long undec_sm_pwdb; +	long undec_sm_cck;  };  struct rtl_tid_data { @@ -1138,6 +1267,7 @@ struct rtl_mac {  	u8 use_cts_protect;  	u8 cur_40_prime_sc;  	u8 cur_40_prime_sc_bk; +	u8 cur_80_prime_sc;  	u64 tsf;  	u8 retry_short;  	u8 retry_long; @@ -1218,6 +1348,7 @@ struct rtl_hal {  	bool being_init_adapter;  	bool bbrf_ready;  	bool mac_func_enable; +	bool pre_edcca_enable;  	struct bt_coexist_8723 hal_coex_8723;  	enum intf_type interface; @@ -1239,6 +1370,7 @@ struct rtl_hal {  	/*Reserve page start offset except beacon in TxQ. */  	u8 fw_rsvdpage_startoffset;  	u8 h2c_txcmd_seq; +	u8 current_ra_rate;  	/* FW Cmd IO related */  	u16 fwcmd_iomap; @@ -1278,6 +1410,9 @@ struct rtl_hal {  	bool disable_amsdu_8k;  	bool master_of_dmsp;  	bool slave_of_dmsp; + +	u16 rx_tag;/*for 92ee*/ +	u8 rts_en;  };  struct rtl_security { @@ -1326,11 +1461,23 @@ struct fast_ant_training {  	bool	becomelinked;  }; +struct dm_phy_dbg_info { +	char rx_snrdb[4]; +	u64 num_qry_phy_status; +	u64 num_qry_phy_status_cck; +	u64 num_qry_phy_status_ofdm; +	u16 num_qry_beacon_pkt; +	u16 num_non_be_pkt; +	s32 rx_evm[4]; +}; +  struct rtl_dm {  	/*PHY status for Dynamic Management */  	long entry_min_undec_sm_pwdb; +	long undec_sm_cck;  	long undec_sm_pwdb;	/*out dm */  	long entry_max_undec_sm_pwdb; +	s32 ofdm_pkt_cnt;  	bool dm_initialgain_enable;  	bool dynamic_txpower_enable;  	bool current_turbo_edca; @@ -1345,6 +1492,7 @@ struct rtl_dm {  	bool inform_fw_driverctrldm;  	bool current_mrc_switch;  	u8 txpowercount; +	u8 powerindex_backup[6];  	u8 thermalvalue_rxgain;  	u8 thermalvalue_iqk; @@ -1356,33 +1504,90 @@ struct rtl_dm {  	bool done_txpower;  	u8 dynamic_txhighpower_lvl;	/*Tx high power level */  	u8 dm_flag;		/*Indicate each dynamic mechanism's status. */ +	u8 dm_flag_tmp;  	u8 dm_type; +	u8 dm_rssi_sel;  	u8 txpower_track_control;  	bool interrupt_migration;  	bool disable_tx_int; -	char ofdm_index[2]; +	char ofdm_index[MAX_RF_PATH]; +	u8 default_ofdm_index; +	u8 default_cck_index;  	char cck_index; -	char delta_power_index; -	char delta_power_index_last; -	char power_index_offset; +	char delta_power_index[MAX_RF_PATH]; +	char delta_power_index_last[MAX_RF_PATH]; +	char power_index_offset[MAX_RF_PATH]; +	char absolute_ofdm_swing_idx[MAX_RF_PATH]; +	char remnant_ofdm_swing_idx[MAX_RF_PATH]; +	char remnant_cck_idx; +	bool modify_txagc_flag_path_a; +	bool modify_txagc_flag_path_b; + +	bool one_entry_only; +	struct dm_phy_dbg_info dbginfo; + +	/* Dynamic ATC switch */ +	bool atc_status; +	bool large_cfo_hit; +	bool is_freeze; +	int cfo_tail[2]; +	int cfo_ave_pre; +	int crystal_cap; +	u8 cfo_threshold; +	u32 packet_count; +	u32 packet_count_pre; +	u8 tx_rate;  	/*88e tx power tracking*/ -	u8	swing_idx_ofdm[2]; +	u8	swing_idx_ofdm[MAX_RF_PATH];  	u8	swing_idx_ofdm_cur; -	u8	swing_idx_ofdm_base; +	u8	swing_idx_ofdm_base[MAX_RF_PATH];  	bool	swing_flag_ofdm;  	u8	swing_idx_cck;  	u8	swing_idx_cck_cur;  	u8	swing_idx_cck_base;  	bool	swing_flag_cck; +	char	swing_diff_2g; +	char	swing_diff_5g; + +	u8 delta_swing_table_idx_24gccka_p[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24gccka_n[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24gcckb_p[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24gcckb_n[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24ga_p[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24ga_n[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24gb_p[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24gb_n[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_5ga_p[BAND_NUM][DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_5ga_n[BAND_NUM][DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_5gb_p[BAND_NUM][DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_5gb_n[BAND_NUM][DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24ga_p_8188e[DEL_SW_IDX_SZ]; +	u8 delta_swing_table_idx_24ga_n_8188e[DEL_SW_IDX_SZ]; +  	/* DMSP */  	bool supp_phymode_switch; +	/* DulMac */  	struct fast_ant_training fat_table; + +	u8	resp_tx_path; +	u8	path_sel; +	u32	patha_sum; +	u32	pathb_sum; +	u32	patha_cnt; +	u32	pathb_cnt; + +	u8 pre_channel; +	u8 *p_channel; +	u8 linked_interval; + +	u64 last_tx_ok_cnt; +	u64 last_rx_ok_cnt;  }; -#define	EFUSE_MAX_LOGICAL_SIZE			256 +#define	EFUSE_MAX_LOGICAL_SIZE			512  struct rtl_efuse {  	bool autoLoad_ok; @@ -1422,12 +1627,9 @@ struct rtl_efuse {  	u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */  	u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX];  	u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; -	u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G]; -	u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX]; -	u8 eprom_chnl_txpwr_ht40_2sdf[2][CHANNEL_GROUP_MAX]; -	u8 txpwrlevel_cck[2][CHANNEL_MAX_NUMBER_2G]; -	u8 txpwrlevel_ht40_1s[2][CHANNEL_MAX_NUMBER];	/*For HT 40MHZ pwr */ -	u8 txpwrlevel_ht40_2s[2][CHANNEL_MAX_NUMBER];	/*For HT 40MHZ pwr */ +	u8 eeprom_chnlarea_txpwr_cck[MAX_RF_PATH][CHANNEL_GROUP_MAX_2G]; +	u8 eeprom_chnlarea_txpwr_ht40_1s[MAX_RF_PATH][CHANNEL_GROUP_MAX]; +	u8 eprom_chnl_txpwr_ht40_2sdf[MAX_RF_PATH][CHANNEL_GROUP_MAX];  	u8 internal_pa_5g[2];	/* pathA / pathB */  	u8 eeprom_c9; @@ -1438,9 +1640,38 @@ struct rtl_efuse {  	u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER];  	u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER]; -	char txpwr_ht20diff[2][CHANNEL_MAX_NUMBER]; /*HT 20<->40 Pwr diff */ -	/*For HT<->legacy pwr diff*/ -	u8 txpwr_legacyhtdiff[2][CHANNEL_MAX_NUMBER]; +	u8 txpwrlevel_cck[MAX_RF_PATH][CHANNEL_MAX_NUMBER_2G]; +	/*For HT 40MHZ pwr */ +	u8 txpwrlevel_ht40_1s[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; +	/*For HT 40MHZ pwr */ +	u8 txpwrlevel_ht40_2s[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + +	/*--------------------------------------------------------* +	 * 8192CE\8192SE\8192DE\8723AE use the following 4 arrays, +	 * other ICs (8188EE\8723BE\8192EE\8812AE...) +	 * define new arrays in Windows code. +	 * BUT, in linux code, we use the same array for all ICs. +	 * +	 * The Correspondance relation between two arrays is: +	 * txpwr_cckdiff[][] == CCK_24G_Diff[][] +	 * txpwr_ht20diff[][] == BW20_24G_Diff[][] +	 * txpwr_ht40diff[][] == BW40_24G_Diff[][] +	 * txpwr_legacyhtdiff[][] == OFDM_24G_Diff[][] +	 * +	 * Sizes of these arrays are decided by the larger ones. +	 */ +	char txpwr_cckdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; +	char txpwr_ht20diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; +	char txpwr_ht40diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; +	char txpwr_legacyhtdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + +	u8 txpwr_5g_bw40base[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; +	u8 txpwr_5g_bw80base[MAX_RF_PATH][CHANNEL_MAX_NUMBER_5G_80M]; +	char txpwr_5g_ofdmdiff[MAX_RF_PATH][MAX_TX_COUNT]; +	char txpwr_5g_bw20diff[MAX_RF_PATH][MAX_TX_COUNT]; +	char txpwr_5g_bw40diff[MAX_RF_PATH][MAX_TX_COUNT]; +	char txpwr_5g_bw80diff[MAX_RF_PATH][MAX_TX_COUNT]; +  	u8 txpwr_safetyflag;			/* Band edge enable flag */  	u16 eeprom_txpowerdiff;  	u8 legacy_httxpowerdiff;	/* Legacy to HT rate power diff */ @@ -1571,7 +1802,9 @@ struct rtl_stats {  	bool rx_is40Mhzpacket;  	u32 rx_pwdb_all;  	u8 rx_mimo_signalstrength[4];	/*in 0~100 index */ -	s8 rx_mimo_sig_qual[2]; +	s8 rx_mimo_sig_qual[4]; +	u8 rx_pwr[4]; /* per-path's pwdb */ +	u8 rx_snr[4]; /* per-path's SNR */  	bool packet_matchbssid;  	bool is_cck;  	bool is_ht; @@ -1644,6 +1877,8 @@ struct rtl_tcb_desc {  	bool btx_enable_sw_calc_duration;  }; +struct rtl92c_firmware_header; +  struct rtl_hal_ops {  	int (*init_sw_vars) (struct ieee80211_hw *hw);  	void (*deinit_sw_vars) (struct ieee80211_hw *hw); @@ -1673,9 +1908,17 @@ struct rtl_hal_ops {  	void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);  	void (*update_rate_tbl) (struct ieee80211_hw *hw,  			      struct ieee80211_sta *sta, u8 rssi_level); +	void (*pre_fill_tx_bd_desc)(struct ieee80211_hw *hw, u8 *tx_bd_desc, +				    u8 *desc, u8 queue_index, +				    struct sk_buff *skb, dma_addr_t addr);  	void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level); +	u16 (*rx_desc_buff_remained_cnt)(struct ieee80211_hw *hw, +					 u8 queue_index); +	void (*rx_check_dma_ok)(struct ieee80211_hw *hw, u8 *header_desc, +				u8 queue_index);  	void (*fill_tx_desc) (struct ieee80211_hw *hw,  			      struct ieee80211_hdr *hdr, u8 *pdesc_tx, +			      u8 *pbd_desc_tx,  			      struct ieee80211_tx_info *info,  			      struct ieee80211_sta *sta,  			      struct sk_buff *skb, u8 hw_queue, @@ -1698,8 +1941,11 @@ struct rtl_hal_ops {  				    enum rf_pwrstate rfpwr_state);  	void (*led_control) (struct ieee80211_hw *hw,  			     enum led_ctl_mode ledaction); -	void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val); +	void (*set_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx, +			 u8 desc_name, u8 *val);  	u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name); +	bool (*is_tx_desc_closed) (struct ieee80211_hw *hw, +				   u8 hw_queue, u16 index);  	void (*tx_polling) (struct ieee80211_hw *hw, u8 hw_queue);  	void (*enable_hw_sec) (struct ieee80211_hw *hw);  	void (*set_key) (struct ieee80211_hw *hw, u32 key_index, @@ -1714,8 +1960,6 @@ struct rtl_hal_ops {  			  u32 regaddr, u32 bitmask);  	void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath,  			   u32 regaddr, u32 bitmask, u32 data); -	void (*allow_all_destaddr)(struct ieee80211_hw *hw, -		bool allow_all_da, bool write_into_reg);  	void (*linked_set_reg) (struct ieee80211_hw *hw);  	void (*chk_switch_dmdp) (struct ieee80211_hw *hw);  	void (*dualmac_easy_concurrent) (struct ieee80211_hw *hw); @@ -1738,6 +1982,10 @@ struct rtl_hal_ops {  	void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);  	void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,  			      u32 cmd_len, u8 *p_cmdbuffer); +	bool (*get_btc_status) (void); +	bool (*is_fw_header) (struct rtl92c_firmware_header *hdr); +	u32 (*rx_command_packet)(struct ieee80211_hw *hw, +				 struct rtl_stats status, struct sk_buff *skb);  };  struct rtl_intf_ops { @@ -1780,6 +2028,10 @@ struct rtl_mod_params {  	/* default: 1 = using linked fw power save */  	bool fwctrl_lps; + +	/* default: 0 = not using MSI interrupts mode */ +	/* submodules should set their own defalut value */ +	bool msi_support;  };  struct rtl_hal_usbint_cfg { @@ -1810,6 +2062,7 @@ struct rtl_hal_cfg {  	bool write_readback;  	char *name;  	char *fw_name; +	char *alt_fw_name;  	struct rtl_hal_ops *ops;  	struct rtl_mod_params *mod_params;  	struct rtl_hal_usbint_cfg *usb_interface_cfg; @@ -1846,6 +2099,8 @@ struct rtl_locks {  	/*Easy concurrent*/  	spinlock_t check_sendpkt_lock; + +	spinlock_t iqk_lock;  };  struct rtl_works { @@ -1914,6 +2169,7 @@ struct ps_t {  	u8 cur_ccasate;  	u8 pre_rfstate;  	u8 cur_rfstate; +	u8 initialize;  	long rssi_val_min;  }; @@ -1938,6 +2194,7 @@ struct dig_t {  	u8 cursta_cstate;  	u8 presta_cstate;  	u8 curmultista_cstate; +	u8 stop_dig;  	char back_val;  	char back_range_max;  	char back_range_min; @@ -1954,6 +2211,8 @@ struct dig_t {  	u8 pre_ccastate;  	u8 cur_ccasate;  	u8 large_fa_hit; +	u8 dig_dynamic_min; +	u8 dig_dynamic_min_1;  	u8 forbidden_igi;  	u8 dig_state;  	u8 dig_highpwrstate; @@ -1970,6 +2229,7 @@ struct dig_t {  	char backoffval_range_min;  	u8 dig_min_0;  	u8 dig_min_1; +	u8 bt30_cur_igi;  	bool media_connect_0;  	bool media_connect_1; @@ -1984,6 +2244,96 @@ struct rtl_global_var {  	spinlock_t glb_list_lock;  }; +struct rtl_btc_info { +	u8 bt_type; +	u8 btcoexist; +	u8 ant_num; +}; + +struct bt_coexist_info { +	struct rtl_btc_ops *btc_ops; +	struct rtl_btc_info btc_info; +	/* EEPROM BT info. */ +	u8 eeprom_bt_coexist; +	u8 eeprom_bt_type; +	u8 eeprom_bt_ant_num; +	u8 eeprom_bt_ant_isol; +	u8 eeprom_bt_radio_shared; + +	u8 bt_coexistence; +	u8 bt_ant_num; +	u8 bt_coexist_type; +	u8 bt_state; +	u8 bt_cur_state;	/* 0:on, 1:off */ +	u8 bt_ant_isolation;	/* 0:good, 1:bad */ +	u8 bt_pape_ctrl;	/* 0:SW, 1:SW/HW dynamic */ +	u8 bt_service; +	u8 bt_radio_shared_type; +	u8 bt_rfreg_origin_1e; +	u8 bt_rfreg_origin_1f; +	u8 bt_rssi_state; +	u32 ratio_tx; +	u32 ratio_pri; +	u32 bt_edca_ul; +	u32 bt_edca_dl; + +	bool init_set; +	bool bt_busy_traffic; +	bool bt_traffic_mode_set; +	bool bt_non_traffic_mode_set; + +	bool fw_coexist_all_off; +	bool sw_coexist_all_off; +	bool hw_coexist_all_off; +	u32 cstate; +	u32 previous_state; +	u32 cstate_h; +	u32 previous_state_h; + +	u8 bt_pre_rssi_state; +	u8 bt_pre_rssi_state1; + +	u8 reg_bt_iso; +	u8 reg_bt_sco; +	bool balance_on; +	u8 bt_active_zero_cnt; +	bool cur_bt_disabled; +	bool pre_bt_disabled; + +	u8 bt_profile_case; +	u8 bt_profile_action; +	bool bt_busy; +	bool hold_for_bt_operation; +	u8 lps_counter; +}; + +struct rtl_btc_ops { +	void (*btc_init_variables) (struct rtl_priv *rtlpriv); +	void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv); +	void (*btc_init_hw_config) (struct rtl_priv *rtlpriv); +	void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type); +	void (*btc_scan_notify) (struct rtl_priv *rtlpriv, u8 scantype); +	void (*btc_connect_notify) (struct rtl_priv *rtlpriv, u8 action); +	void (*btc_mediastatus_notify) (struct rtl_priv *rtlpriv, +					enum _RT_MEDIA_STATUS mstatus); +	void (*btc_periodical) (struct rtl_priv *rtlpriv); +	void (*btc_halt_notify) (void); +	void (*btc_btinfo_notify) (struct rtl_priv *rtlpriv, +				   u8 *tmp_buf, u8 length); +	bool (*btc_is_limited_dig) (struct rtl_priv *rtlpriv); +	bool (*btc_is_disable_edca_turbo) (struct rtl_priv *rtlpriv); +	bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv); +}; + +struct proxim { +	bool proxim_on; + +	void *proximity_priv; +	int (*proxim_rx)(struct ieee80211_hw *hw, struct rtl_stats *status, +			 struct sk_buff *skb); +	u8  (*proxim_get_var)(struct ieee80211_hw *hw, u8 type); +}; +  struct rtl_priv {  	struct ieee80211_hw *hw;  	struct completion firmware_loading_complete; @@ -2006,6 +2356,7 @@ struct rtl_priv {  	struct rtl_ps_ctl psc;  	struct rate_adaptive ra; +	struct dynamic_primary_cca primarycca;  	struct wireless_stats stats;  	struct rt_link_detect link_info;  	struct false_alarm_statistics falsealm_cnt; @@ -2034,25 +2385,32 @@ struct rtl_priv {  	struct dig_t dm_digtable;  	struct ps_t dm_pstable; -	/* section shared by individual drivers */ -	union { -		struct {	/* data buffer pointer for USB reads */ -			__le32 *usb_data; -			int usb_data_index; -			bool initialized; -		}; -		struct {	/* section for 8723ae */ -			bool reg_init;	/* true if regs saved */ -			u32 reg_874; -			u32 reg_c70; -			u32 reg_85c; -			u32 reg_a74; -			bool bt_operation_on; -		}; -	}; +	u32 reg_874; +	u32 reg_c70; +	u32 reg_85c; +	u32 reg_a74; +	bool reg_init;	/* true if regs saved */ +	bool bt_operation_on; +	__le32 *usb_data; +	int usb_data_index; +	bool initialized;  	bool enter_ps;	/* true when entering PS */  	u8 rate_mask[5]; +	/* intel Proximity, should be alloc mem +	 * in intel Proximity module and can only +	 * be used in intel Proximity mode +	 */ +	struct proxim proximity; + +	/*for bt coexist use*/ +	struct bt_coexist_info btcoexist; + +	/* separate 92ee from other ICs, +	 * 92ee use new trx flow. +	 */ +	bool use_new_trx_flow; +  	/*This must be the last item so  	   that it points to the data allocated  	   beyond  this structure like: @@ -2084,6 +2442,15 @@ enum bt_co_type {  	BT_CSR_BC8 = 4,  	BT_RTL8756 = 5,  	BT_RTL8723A = 6, +	BT_RTL8821A = 7, +	BT_RTL8723B = 8, +	BT_RTL8192E = 9, +	BT_RTL8812A = 11, +}; + +enum bt_total_ant_num { +	ANT_TOTAL_X2 = 0, +	ANT_TOTAL_X1 = 1  };  enum bt_cur_state { @@ -2109,62 +2476,6 @@ enum bt_radio_shared {  	BT_RADIO_INDIVIDUAL = 1,  }; -struct bt_coexist_info { - -	/* EEPROM BT info. */ -	u8 eeprom_bt_coexist; -	u8 eeprom_bt_type; -	u8 eeprom_bt_ant_num; -	u8 eeprom_bt_ant_isol; -	u8 eeprom_bt_radio_shared; - -	u8 bt_coexistence; -	u8 bt_ant_num; -	u8 bt_coexist_type; -	u8 bt_state; -	u8 bt_cur_state;	/* 0:on, 1:off */ -	u8 bt_ant_isolation;	/* 0:good, 1:bad */ -	u8 bt_pape_ctrl;	/* 0:SW, 1:SW/HW dynamic */ -	u8 bt_service; -	u8 bt_radio_shared_type; -	u8 bt_rfreg_origin_1e; -	u8 bt_rfreg_origin_1f; -	u8 bt_rssi_state; -	u32 ratio_tx; -	u32 ratio_pri; -	u32 bt_edca_ul; -	u32 bt_edca_dl; - -	bool init_set; -	bool bt_busy_traffic; -	bool bt_traffic_mode_set; -	bool bt_non_traffic_mode_set; - -	bool fw_coexist_all_off; -	bool sw_coexist_all_off; -	bool hw_coexist_all_off; -	u32 cstate; -	u32 previous_state; -	u32 cstate_h; -	u32 previous_state_h; - -	u8 bt_pre_rssi_state; -	u8 bt_pre_rssi_state1; - -	u8 reg_bt_iso; -	u8 reg_bt_sco; -	bool balance_on; -	u8 bt_active_zero_cnt; -	bool cur_bt_disabled; -	bool pre_bt_disabled; - -	u8 bt_profile_case; -	u8 bt_profile_action; -	bool bt_busy; -	bool hold_for_bt_operation; -	u8 lps_counter; -}; -  /****************************************  	mem access macro define start  | 
