diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
100 files changed, 22371 insertions, 1800 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/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..b6722de64a3 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c @@ -0,0 +1,1011 @@ +/****************************************************************************** + * + * 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; + +#if (defined(CONFIG_PCI_HCI)) + btcoexist->chip_interface = BTC_INTF_PCI; +#elif (defined(CONFIG_USB_HCI)) + btcoexist->chip_interface = BTC_INTF_USB; +#elif (defined(CONFIG_SDIO_HCI)) + btcoexist->chip_interface = BTC_INTF_SDIO; +#elif (defined(CONFIG_GSPI_HCI)) + btcoexist->chip_interface = BTC_INTF_GSPI; +#else + btcoexist->chip_interface = BTC_INTF_UNKNOWN; +#endif + + 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/core.c b/drivers/net/wireless/rtlwifi/core.c index 2d337a0c3df..4ec424f2667 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; @@ -475,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"); @@ -497,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"); } @@ -537,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, @@ -738,6 +806,11 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, 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); @@ -892,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(); } @@ -906,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); 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/pci.c b/drivers/net/wireless/rtlwifi/pci.c index d7aa165fe67..dae55257f0e 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -811,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; @@ -983,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)); @@ -1004,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; @@ -1066,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, @@ -1113,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); } @@ -1188,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; @@ -1331,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); @@ -1424,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; @@ -1464,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)) { @@ -1494,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, @@ -1841,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) { @@ -1983,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", @@ -2052,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); 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 d1c0191a195..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); @@ -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; 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/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 a6184b6e1d5..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, 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 e06971be7df..94cd9df9838 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 @@ -148,8 +147,7 @@ static void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw, } 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); @@ -226,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); @@ -274,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)); } @@ -301,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 { @@ -309,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); } } @@ -420,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; @@ -436,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; @@ -465,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, @@ -483,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) @@ -506,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; @@ -567,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 | @@ -580,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)); @@ -592,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); @@ -617,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; @@ -668,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; @@ -681,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); @@ -815,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; } @@ -1025,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); @@ -1043,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); @@ -1051,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; } @@ -1097,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 { @@ -1135,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) @@ -1235,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, @@ -1345,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); @@ -1361,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)))); @@ -1816,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; @@ -1833,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*/ @@ -1845,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*/ @@ -1872,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; } @@ -1892,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: @@ -1911,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; @@ -2211,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 diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c index d67f9c731cc..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; 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 347af1e4f43..1b4101bf997 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c @@ -93,6 +93,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw) u8 tid; rtl8188ee_bt_reg_init(hw); + rtlpci->msi_support = true; rtlpriv->dm.dm_initialgain_enable = 1; rtlpriv->dm.dm_flag = 0; diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c index aece6c9cccf..06ef47cd620 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c @@ -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 @@ -489,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; @@ -717,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); @@ -734,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/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 2eb0b38384d..55adf043aef 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; } } @@ -1214,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, @@ -1734,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 { @@ -1745,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: @@ -1764,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; 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/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index 8922ecb47ad..ed703a1b3b7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -2044,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/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 52abf0a862f..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 @@ -426,7 +426,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, 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) @@ -666,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/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 468bf73cc88..68b5c7e92cf 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; @@ -985,6 +985,17 @@ 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); @@ -997,7 +1008,7 @@ int rtl92cu_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; /* h2c */ _rtl92cu_phy_param_tab_init(hw); @@ -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/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index 0c09240eadc..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" @@ -188,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); @@ -236,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], @@ -294,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: @@ -344,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/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 1bc21ccfa71..035e0dc3922 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -495,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 7908e1c8581..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) { @@ -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); @@ -1204,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); } @@ -1229,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 c4a7db9135d..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)); @@ -1332,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/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 13196cc4b1d..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); @@ -1106,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); } @@ -1168,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; @@ -1211,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, @@ -1329,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); @@ -1337,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, @@ -1351,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); @@ -1381,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", @@ -1422,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, @@ -1438,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); @@ -1493,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)) @@ -1563,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)) { @@ -1620,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; } @@ -1637,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)) @@ -1680,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, @@ -1712,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)) @@ -1738,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; } @@ -1754,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, @@ -1779,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, @@ -1807,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, @@ -1830,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) @@ -1843,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], @@ -1875,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"); @@ -1898,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) { @@ -1939,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; } } @@ -1957,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) @@ -1984,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) @@ -2004,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"); } @@ -2042,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"); @@ -2072,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"); @@ -2116,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, @@ -2140,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, @@ -2240,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; @@ -2271,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; @@ -2299,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; @@ -2657,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, @@ -2667,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"); @@ -2696,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] */ @@ -2912,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); @@ -2960,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))) @@ -3112,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 @@ -3120,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) { @@ -3468,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, @@ -3524,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, @@ -3560,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); @@ -3590,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 */ @@ -3612,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); @@ -3620,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/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/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 0eb0f4ae592..99c2ab5dfce 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -545,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) @@ -786,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..9098558d916 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)); 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 c81c8359194..e13043479b7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h @@ -1165,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 92d38ab3c60..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]; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 27efbcdac6a..36b48be8329 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -310,7 +310,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 @@ -336,7 +336,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, 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) @@ -573,7 +573,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..48fee1be78c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c @@ -31,6 +31,8 @@ #include "../pci.h" #include "dm.h" #include "fw.h" +#include "../rtl8723com/fw_common.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..65c9e80e1f7 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c index 5d318a85eda..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,28 +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_set_bw_mode_callback(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1117,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) { @@ -1204,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; @@ -1297,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) { @@ -1498,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, @@ -1509,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); @@ -1522,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) @@ -1552,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) { @@ -1588,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); } } @@ -1691,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) @@ -1756,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 007ebdbbe10..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,10 +166,6 @@ struct tx_power_struct { u32 mcs_original_offset[4][16]; }; -u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask); 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/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c index 62b204faf77..1087a3bd07f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c @@ -37,8 +37,11 @@ #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" @@ -193,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, @@ -231,13 +239,14 @@ static struct rtl_hal_ops rtl8723ae_hal_ops = { .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 50b7be3f3a6..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 @@ -365,7 +365,7 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, 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) @@ -375,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); @@ -577,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); @@ -597,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..0fdf0909321 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c @@ -0,0 +1,2523 @@ +/****************************************************************************** + * + * 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) +{ +} + +/* Turn on AAP (RCR:bit 0) for promicuous mode. */ +void rtl8723be_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/rtl8723be/hw.h b/drivers/net/wireless/rtlwifi/rtl8723be/hw.h new file mode 100644 index 00000000000..b7449a9b57e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * 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); +void rtl8723be_allow_all_destaddr(struct ieee80211_hw *hw, bool allow_all_da, + bool write_into_reg); +#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..b4577ebc4bb --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c @@ -0,0 +1,384 @@ +/****************************************************************************** + * + * 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 = true; + 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, + .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_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(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..e0a0d8c8fed --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c @@ -0,0 +1,960 @@ +/****************************************************************************** + * + * 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" +#include "phy.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/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 4933f02ce1d..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 */ @@ -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 8c647391bed..6965afdf572 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 @@ -86,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 @@ -96,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 */ @@ -107,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]; @@ -115,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 { @@ -123,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 { @@ -158,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 @@ -195,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 }; @@ -231,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 { @@ -298,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, @@ -330,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, @@ -348,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, @@ -389,6 +481,7 @@ enum hw_descs { HW_DESC_RXBUFF_ADDR, HW_DESC_RXPKT_LEN, HW_DESC_RXERO, + HW_DESC_RX_PREPARE, }; enum prime_sc { @@ -407,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 @@ -471,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, @@ -608,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 { @@ -645,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) \ @@ -669,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 { @@ -803,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; }; @@ -817,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; @@ -833,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 { @@ -841,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; @@ -976,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 */ @@ -998,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; @@ -1006,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; }; @@ -1133,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; @@ -1213,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; @@ -1234,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; @@ -1273,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 { @@ -1321,6 +1461,16 @@ 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; @@ -1360,29 +1510,84 @@ struct rtl_dm { 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, @@ -1738,6 +1984,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 { @@ -1847,6 +2097,8 @@ struct rtl_locks { /*Easy concurrent*/ spinlock_t check_sendpkt_lock; + + spinlock_t iqk_lock; }; struct rtl_works { @@ -1915,6 +2167,7 @@ struct ps_t { u8 cur_ccasate; u8 pre_rfstate; u8 cur_rfstate; + u8 initialize; long rssi_val_min; }; @@ -1939,6 +2192,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; @@ -1956,6 +2210,7 @@ struct dig_t { 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; @@ -1972,6 +2227,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; @@ -1986,6 +2242,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; @@ -2008,6 +2354,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; @@ -2048,6 +2395,20 @@ struct rtl_priv { 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: @@ -2079,6 +2440,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 { @@ -2104,62 +2474,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 |