aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2014-02-28 16:16:50 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-03-04 13:25:39 -0500
commita619d1abe20cc892ddd8f6f60345b24d43971fb4 (patch)
tree25643f37e962f1753f45fb3763313ba63cf94144
parent57d9d9630a6b3f289ae87b1fc00e83ae44636766 (diff)
rtlwifi: rtl8723be: Add new driver
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig19
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/Makefile20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/def.h248
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.c1325
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.h310
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/fw.c628
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/fw.h248
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.c2529
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.h64
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/led.c153
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/led.h35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/phy.c2175
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/phy.h217
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c106
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h305
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c140
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h95
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/reg.h2293
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/rf.c504
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.c385
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.h35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/table.c572
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/table.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/trx.c959
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/trx.h616
27 files changed, 14065 insertions, 3 deletions
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
index 9251e0d3685c..bf3cf124e4ea 100644
--- a/drivers/net/wireless/rtlwifi/Kconfig
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -5,7 +5,7 @@ menuconfig RTL_CARDS
5 ---help--- 5 ---help---
6 This option will enable support for the Realtek mac80211-based 6 This option will enable support for the Realtek mac80211-based
7 wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de, 7 wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de,
8 rtl8723ae, and rtl8188ae share some common code. 8 rtl8723ae, rtl8723be, and rtl8188ae share some common code.
9 9
10if RTL_CARDS 10if RTL_CARDS
11 11
@@ -56,6 +56,19 @@ config RTL8723AE
56 56
57 If you choose to build it as a module, it will be called rtl8723ae 57 If you choose to build it as a module, it will be called rtl8723ae
58 58
59config RTL8723BE
60 tristate "Realtek RTL8723BE PCIe Wireless Network Adapter"
61 depends on PCI
62 select RTLWIFI
63 select RTLWIFI_PCI
64 select RTL8723_COMMON
65 select RTLBTCOEXIST
66 ---help---
67 This is the driver for Realtek RTL8723BE 802.11n PCIe
68 wireless network adapters.
69
70 If you choose to build it as a module, it will be called rtl8723be
71
59config RTL8188EE 72config RTL8188EE
60 tristate "Realtek RTL8188EE Wireless Network Adapter" 73 tristate "Realtek RTL8188EE Wireless Network Adapter"
61 depends on PCI 74 depends on PCI
@@ -105,12 +118,12 @@ config RTL8192C_COMMON
105 118
106config RTL8723_COMMON 119config RTL8723_COMMON
107 tristate 120 tristate
108 depends on RTL8723AE 121 depends on RTL8723AE || RTL8723BE
109 default y 122 default y
110 123
111config RTLBTCOEXIST 124config RTLBTCOEXIST
112 tristate 125 tristate
113 depends on RTL8723AE 126 depends on RTL8723AE || RTL8723BE
114 default y 127 default y
115 128
116endif 129endif
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile
index d97d1b9d2427..bba36a06abcc 100644
--- a/drivers/net/wireless/rtlwifi/Makefile
+++ b/drivers/net/wireless/rtlwifi/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_RTL8192CU) += rtl8192cu/
24obj-$(CONFIG_RTL8192SE) += rtl8192se/ 24obj-$(CONFIG_RTL8192SE) += rtl8192se/
25obj-$(CONFIG_RTL8192DE) += rtl8192de/ 25obj-$(CONFIG_RTL8192DE) += rtl8192de/
26obj-$(CONFIG_RTL8723AE) += rtl8723ae/ 26obj-$(CONFIG_RTL8723AE) += rtl8723ae/
27obj-$(CONFIG_RTL8723BE) += rtl8723be/
27obj-$(CONFIG_RTL8188EE) += rtl8188ee/ 28obj-$(CONFIG_RTL8188EE) += rtl8188ee/
28obj-$(CONFIG_RTLBTCOEXIST) += btcoexist/ 29obj-$(CONFIG_RTLBTCOEXIST) += btcoexist/
29obj-$(CONFIG_RTL8723_COMMON) += rtl8723com/ 30obj-$(CONFIG_RTL8723_COMMON) += rtl8723com/
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/Makefile b/drivers/net/wireless/rtlwifi/rtl8723be/Makefile
new file mode 100644
index 000000000000..4a75aab0539a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/Makefile
@@ -0,0 +1,20 @@
1obj-m := rtl8723be.o
2
3
4rtl8723be-objs := \
5 dm.o \
6 fw.o \
7 hw.o \
8 led.o \
9 phy.o \
10 pwrseq.o \
11 pwrseqcmd.o \
12 rf.o \
13 sw.o \
14 table.o \
15 trx.o \
16
17
18obj-$(CONFIG_RTL8723BE) += rtl8723be.o
19
20ccflags-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 000000000000..3c30b74e983d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/def.h
@@ -0,0 +1,248 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_DEF_H__
27#define __RTL8723BE_DEF_H__
28
29#define HAL_RETRY_LIMIT_INFRA 48
30#define HAL_RETRY_LIMIT_AP_ADHOC 7
31
32#define RESET_DELAY_8185 20
33
34#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
35#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
36
37#define NUM_OF_FIRMWARE_QUEUE 10
38#define NUM_OF_PAGES_IN_FW 0x100
39#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
40#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
41#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
42#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
43#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
44#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
45#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
46#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
47#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
48#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
49
50#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
51#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
52#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
53#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
54#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
55
56#define MAX_LINES_HWCONFIG_TXT 1000
57#define MAX_BYTES_LINE_HWCONFIG_TXT 256
58
59#define SW_THREE_WIRE 0
60#define HW_THREE_WIRE 2
61
62#define BT_DEMO_BOARD 0
63#define BT_QA_BOARD 1
64#define BT_FPGA 2
65
66#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
67#define HAL_PRIME_CHNL_OFFSET_LOWER 1
68#define HAL_PRIME_CHNL_OFFSET_UPPER 2
69
70#define MAX_H2C_QUEUE_NUM 10
71
72#define RX_MPDU_QUEUE 0
73#define RX_CMD_QUEUE 1
74#define RX_MAX_QUEUE 2
75#define AC2QUEUEID(_AC) (_AC)
76
77#define C2H_RX_CMD_HDR_LEN 8
78#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
79 LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
80#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
81 LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
82#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
83 LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
84#define GET_C2H_CMD_CONTINUE(__prxhdr) \
85 LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
86#define GET_C2H_CMD_CONTENT(__prxhdr) \
87 ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
88
89#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
90 LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
91#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
92 LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
93#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
94 LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
95#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
96 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
97#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
98 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
99#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
100 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
101#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
102 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
103#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
104 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
105#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
106 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
107
108#define CHIP_BONDING_IDENTIFIER(_value) (((_value)>>22)&0x3)
109#define CHIP_BONDING_92C_1T2R 0x1
110
111#define CHIP_8723 BIT(0)
112#define CHIP_8723B (BIT(1) | BIT(2))
113#define NORMAL_CHIP BIT(3)
114#define RF_TYPE_1T1R (~(BIT(4) | BIT(5) | BIT(6)))
115#define RF_TYPE_1T2R BIT(4)
116#define RF_TYPE_2T2R BIT(5)
117#define CHIP_VENDOR_UMC BIT(7)
118#define B_CUT_VERSION BIT(12)
119#define C_CUT_VERSION BIT(13)
120#define D_CUT_VERSION ((BIT(12) | BIT(13)))
121#define E_CUT_VERSION BIT(14)
122#define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28))
123
124/* MASK */
125#define IC_TYPE_MASK (BIT(0) | BIT(1) | BIT(2))
126#define CHIP_TYPE_MASK BIT(3)
127#define RF_TYPE_MASK (BIT(4) | BIT(5) | BIT(6))
128#define MANUFACTUER_MASK BIT(7)
129#define ROM_VERSION_MASK (BIT(11) | BIT(10) | BIT(9) | BIT(8))
130#define CUT_VERSION_MASK (BIT(15) | BIT(14) | BIT(13) | BIT(12))
131
132/* Get element */
133#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK)
134#define GET_CVID_CHIP_TYPE(version) ((version) & CHIP_TYPE_MASK)
135#define GET_CVID_RF_TYPE(version) ((version) & RF_TYPE_MASK)
136#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK)
137#define GET_CVID_ROM_VERSION(version) ((version) & ROM_VERSION_MASK)
138#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK)
139
140#define IS_92C_SERIAL(version) ((IS_81XXC(version) && IS_2T2R(version)) ?\
141 true : false)
142#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0) ?\
143 true : false)
144#define IS_8723_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723) ?\
145 true : false)
146#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version)) ? false : true)
147#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)\
148 ? true : false)
149#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)\
150 ? true : false)
151enum rf_optype {
152 RF_OP_BY_SW_3WIRE = 0,
153 RF_OP_BY_FW,
154 RF_OP_MAX
155};
156
157enum rf_power_state {
158 RF_ON,
159 RF_OFF,
160 RF_SLEEP,
161 RF_SHUT_DOWN,
162};
163
164enum power_save_mode {
165 POWER_SAVE_MODE_ACTIVE,
166 POWER_SAVE_MODE_SAVE,
167};
168
169enum power_polocy_config {
170 POWERCFG_MAX_POWER_SAVINGS,
171 POWERCFG_GLOBAL_POWER_SAVINGS,
172 POWERCFG_LOCAL_POWER_SAVINGS,
173 POWERCFG_LENOVO,
174};
175
176enum interface_select_pci {
177 INTF_SEL1_MINICARD = 0,
178 INTF_SEL0_PCIE = 1,
179 INTF_SEL2_RSV = 2,
180 INTF_SEL3_RSV = 3,
181};
182
183enum rtl_desc_qsel {
184 QSLT_BK = 0x2,
185 QSLT_BE = 0x0,
186 QSLT_VI = 0x5,
187 QSLT_VO = 0x7,
188 QSLT_BEACON = 0x10,
189 QSLT_HIGH = 0x11,
190 QSLT_MGNT = 0x12,
191 QSLT_CMD = 0x13,
192};
193
194enum rtl_desc8723e_rate {
195 DESC92C_RATE1M = 0x00,
196 DESC92C_RATE2M = 0x01,
197 DESC92C_RATE5_5M = 0x02,
198 DESC92C_RATE11M = 0x03,
199
200 DESC92C_RATE6M = 0x04,
201 DESC92C_RATE9M = 0x05,
202 DESC92C_RATE12M = 0x06,
203 DESC92C_RATE18M = 0x07,
204 DESC92C_RATE24M = 0x08,
205 DESC92C_RATE36M = 0x09,
206 DESC92C_RATE48M = 0x0a,
207 DESC92C_RATE54M = 0x0b,
208
209 DESC92C_RATEMCS0 = 0x0c,
210 DESC92C_RATEMCS1 = 0x0d,
211 DESC92C_RATEMCS2 = 0x0e,
212 DESC92C_RATEMCS3 = 0x0f,
213 DESC92C_RATEMCS4 = 0x10,
214 DESC92C_RATEMCS5 = 0x11,
215 DESC92C_RATEMCS6 = 0x12,
216 DESC92C_RATEMCS7 = 0x13,
217 DESC92C_RATEMCS8 = 0x14,
218 DESC92C_RATEMCS9 = 0x15,
219 DESC92C_RATEMCS10 = 0x16,
220 DESC92C_RATEMCS11 = 0x17,
221 DESC92C_RATEMCS12 = 0x18,
222 DESC92C_RATEMCS13 = 0x19,
223 DESC92C_RATEMCS14 = 0x1a,
224 DESC92C_RATEMCS15 = 0x1b,
225 DESC92C_RATEMCS15_SG = 0x1c,
226 DESC92C_RATEMCS32 = 0x20,
227};
228
229enum rx_packet_type {
230 NORMAL_RX,
231 TX_REPORT1,
232 TX_REPORT2,
233 HIS_REPORT,
234};
235
236struct phy_sts_cck_8723e_t {
237 u8 adc_pwdb_X[4];
238 u8 sq_rpt;
239 u8 cck_agc_rpt;
240};
241
242struct h2c_cmd_8723e {
243 u8 element_id;
244 u32 cmd_len;
245 u8 *p_cmdbuffer;
246};
247
248#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
new file mode 100644
index 000000000000..736bfcb7938a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
@@ -0,0 +1,1325 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../base.h"
28#include "../pci.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "dm.h"
33#include "../rtl8723com/dm_common.h"
34#include "fw.h"
35#include "../rtl8723com/fw_common.h"
36#include "trx.h"
37#include "../btcoexist/rtl_btc.h"
38
39static const u32 ofdmswing_table[] = {
40 0x0b40002d, /* 0, -15.0dB */
41 0x0c000030, /* 1, -14.5dB */
42 0x0cc00033, /* 2, -14.0dB */
43 0x0d800036, /* 3, -13.5dB */
44 0x0e400039, /* 4, -13.0dB */
45 0x0f00003c, /* 5, -12.5dB */
46 0x10000040, /* 6, -12.0dB */
47 0x11000044, /* 7, -11.5dB */
48 0x12000048, /* 8, -11.0dB */
49 0x1300004c, /* 9, -10.5dB */
50 0x14400051, /* 10, -10.0dB */
51 0x15800056, /* 11, -9.5dB */
52 0x16c0005b, /* 12, -9.0dB */
53 0x18000060, /* 13, -8.5dB */
54 0x19800066, /* 14, -8.0dB */
55 0x1b00006c, /* 15, -7.5dB */
56 0x1c800072, /* 16, -7.0dB */
57 0x1e400079, /* 17, -6.5dB */
58 0x20000080, /* 18, -6.0dB */
59 0x22000088, /* 19, -5.5dB */
60 0x24000090, /* 20, -5.0dB */
61 0x26000098, /* 21, -4.5dB */
62 0x288000a2, /* 22, -4.0dB */
63 0x2ac000ab, /* 23, -3.5dB */
64 0x2d4000b5, /* 24, -3.0dB */
65 0x300000c0, /* 25, -2.5dB */
66 0x32c000cb, /* 26, -2.0dB */
67 0x35c000d7, /* 27, -1.5dB */
68 0x390000e4, /* 28, -1.0dB */
69 0x3c8000f2, /* 29, -0.5dB */
70 0x40000100, /* 30, +0dB */
71 0x43c0010f, /* 31, +0.5dB */
72 0x47c0011f, /* 32, +1.0dB */
73 0x4c000130, /* 33, +1.5dB */
74 0x50800142, /* 34, +2.0dB */
75 0x55400155, /* 35, +2.5dB */
76 0x5a400169, /* 36, +3.0dB */
77 0x5fc0017f, /* 37, +3.5dB */
78 0x65400195, /* 38, +4.0dB */
79 0x6b8001ae, /* 39, +4.5dB */
80 0x71c001c7, /* 40, +5.0dB */
81 0x788001e2, /* 41, +5.5dB */
82 0x7f8001fe /* 42, +6.0dB */
83};
84
85static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
86 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB */
87 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB */
88 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB */
89 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB */
90 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB */
91 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB */
92 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB */
93 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB */
94 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB */
95 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB */
96 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB */
97 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB */
98 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB */
99 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB */
100 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
101 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB */
102 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
103 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB */
104 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
105 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB */
106 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 20, -6.0dB */
107 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB */
108 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
109 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB */
110 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
111 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB */
112 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB */
113 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB */
114 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
115 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB */
116 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB */
117 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB */
118 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB */
119};
120
121static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
122 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB */
123 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB */
124 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB */
125 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB */
126 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB */
127 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 5, -13.5dB */
128 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB */
129 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB */
130 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB */
131 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB */
132 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB */
133 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 11, -10.5dB */
134 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB */
135 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB */
136 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 14, -9.0dB */
137 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB */
138 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
139 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB */
140 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
141 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
142 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
143 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB */
144 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
145 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 23, -4.5dB */
146 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
147 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
148 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
149 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 27, -2.5dB */
150 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
151 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 29, -1.5dB */
152 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
153 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
154 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */
155};
156
157static const u32 edca_setting_dl[PEER_MAX] = {
158 0xa44f, /* 0 UNKNOWN */
159 0x5ea44f, /* 1 REALTEK_90 */
160 0x5e4322, /* 2 REALTEK_92SE */
161 0x5ea42b, /* 3 BROAD */
162 0xa44f, /* 4 RAL */
163 0xa630, /* 5 ATH */
164 0x5ea630, /* 6 CISCO */
165 0x5ea42b, /* 7 MARVELL */
166};
167
168static const u32 edca_setting_ul[PEER_MAX] = {
169 0x5e4322, /* 0 UNKNOWN */
170 0xa44f, /* 1 REALTEK_90 */
171 0x5ea44f, /* 2 REALTEK_92SE */
172 0x5ea32b, /* 3 BROAD */
173 0x5ea422, /* 4 RAL */
174 0x5ea322, /* 5 ATH */
175 0x3ea430, /* 6 CISCO */
176 0x5ea44f, /* 7 MARV */
177};
178
179void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type,
180 u8 *pdirection, u32 *poutwrite_val)
181{
182 struct rtl_priv *rtlpriv = rtl_priv(hw);
183 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
184 u8 pwr_val = 0;
185 u8 ofdm_base = rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A];
186 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
187 u8 cck_base = rtldm->swing_idx_cck_base;
188 u8 cck_val = rtldm->swing_idx_cck;
189
190 if (type == 0) {
191 if (ofdm_val <= ofdm_base) {
192 *pdirection = 1;
193 pwr_val = ofdm_base - ofdm_val;
194 } else {
195 *pdirection = 2;
196 pwr_val = ofdm_val - ofdm_base;
197 }
198 } else if (type == 1) {
199 if (cck_val <= cck_base) {
200 *pdirection = 1;
201 pwr_val = cck_base - cck_val;
202 } else {
203 *pdirection = 2;
204 pwr_val = cck_val - cck_base;
205 }
206 }
207
208 if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
209 pwr_val = TXPWRTRACK_MAX_IDX;
210
211 *poutwrite_val = pwr_val | (pwr_val << 8) |
212 (pwr_val << 16) | (pwr_val << 24);
213}
214
215static void rtl8723be_dm_diginit(struct ieee80211_hw *hw)
216{
217 struct rtl_priv *rtlpriv = rtl_priv(hw);
218 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
219
220 dm_digtable->dig_enable_flag = true;
221 dm_digtable->cur_igvalue = rtl_get_bbreg(hw,
222 ROFDM0_XAAGCCORE1, 0x7f);
223 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
224 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
225 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
226 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
227 dm_digtable->rx_gain_max = DM_DIG_MAX;
228 dm_digtable->rx_gain_min = DM_DIG_MIN;
229 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
230 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
231 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
232 dm_digtable->pre_cck_cca_thres = 0xff;
233 dm_digtable->cur_cck_cca_thres = 0x83;
234 dm_digtable->forbidden_igi = DM_DIG_MIN;
235 dm_digtable->large_fa_hit = 0;
236 dm_digtable->recover_cnt = 0;
237 dm_digtable->dig_min_0 = DM_DIG_MIN;
238 dm_digtable->dig_min_1 = DM_DIG_MIN;
239 dm_digtable->media_connect_0 = false;
240 dm_digtable->media_connect_1 = false;
241 rtlpriv->dm.dm_initialgain_enable = true;
242 dm_digtable->bt30_cur_igi = 0x32;
243}
244
245void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
246{
247 struct rtl_priv *rtlpriv = rtl_priv(hw);
248 struct rate_adaptive *ra = &(rtlpriv->ra);
249
250 ra->ratr_state = DM_RATR_STA_INIT;
251 ra->pre_ratr_state = DM_RATR_STA_INIT;
252
253 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
254 rtlpriv->dm.useramask = true;
255 else
256 rtlpriv->dm.useramask = false;
257
258 ra->high_rssi_thresh_for_ra = 50;
259 ra->low_rssi_thresh_for_ra40m = 20;
260}
261
262static void rtl8723be_dm_init_txpower_tracking(struct ieee80211_hw *hw)
263{
264 struct rtl_priv *rtlpriv = rtl_priv(hw);
265
266 rtlpriv->dm.txpower_tracking = true;
267 rtlpriv->dm.txpower_track_control = true;
268 rtlpriv->dm.thermalvalue = 0;
269
270 rtlpriv->dm.ofdm_index[0] = 30;
271 rtlpriv->dm.cck_index = 20;
272
273 rtlpriv->dm.swing_idx_cck_base = rtlpriv->dm.cck_index;
274
275 rtlpriv->dm.swing_idx_ofdm_base[0] = rtlpriv->dm.ofdm_index[0];
276 rtlpriv->dm.delta_power_index[RF90_PATH_A] = 0;
277 rtlpriv->dm.delta_power_index_last[RF90_PATH_A] = 0;
278 rtlpriv->dm.power_index_offset[RF90_PATH_A] = 0;
279
280 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
281 " rtlpriv->dm.txpower_tracking = %d\n",
282 rtlpriv->dm.txpower_tracking);
283}
284
285static void rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
286{
287 struct rtl_priv *rtlpriv = rtl_priv(hw);
288
289 rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
290 rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, 0x800);
291 rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
292}
293
294void rtl8723be_dm_init(struct ieee80211_hw *hw)
295{
296 struct rtl_priv *rtlpriv = rtl_priv(hw);
297
298 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
299 rtl8723be_dm_diginit(hw);
300 rtl8723be_dm_init_rate_adaptive_mask(hw);
301 rtl8723_dm_init_edca_turbo(hw);
302 rtl8723_dm_init_dynamic_bb_powersaving(hw);
303 rtl8723_dm_init_dynamic_txpower(hw);
304 rtl8723be_dm_init_txpower_tracking(hw);
305 rtl8723be_dm_init_dynamic_atc_switch(hw);
306}
307
308static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw)
309{
310 struct rtl_priv *rtlpriv = rtl_priv(hw);
311 struct dig_t *rtl_dm_dig = &(rtlpriv->dm_digtable);
312 struct rtl_mac *mac = rtl_mac(rtlpriv);
313
314 /* Determine the minimum RSSI */
315 if ((mac->link_state < MAC80211_LINKED) &&
316 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
317 rtl_dm_dig->min_undec_pwdb_for_dm = 0;
318 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
319 "Not connected to any\n");
320 }
321 if (mac->link_state >= MAC80211_LINKED) {
322 if (mac->opmode == NL80211_IFTYPE_AP ||
323 mac->opmode == NL80211_IFTYPE_ADHOC) {
324 rtl_dm_dig->min_undec_pwdb_for_dm =
325 rtlpriv->dm.entry_min_undec_sm_pwdb;
326 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
327 "AP Client PWDB = 0x%lx\n",
328 rtlpriv->dm.entry_min_undec_sm_pwdb);
329 } else {
330 rtl_dm_dig->min_undec_pwdb_for_dm =
331 rtlpriv->dm.undec_sm_pwdb;
332 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
333 "STA Default Port PWDB = 0x%x\n",
334 rtl_dm_dig->min_undec_pwdb_for_dm);
335 }
336 } else {
337 rtl_dm_dig->min_undec_pwdb_for_dm =
338 rtlpriv->dm.entry_min_undec_sm_pwdb;
339 RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
340 "AP Ext Port or disconnet PWDB = 0x%x\n",
341 rtl_dm_dig->min_undec_pwdb_for_dm);
342 }
343 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
344 rtl_dm_dig->min_undec_pwdb_for_dm);
345}
346
347static void rtl8723be_dm_check_rssi_monitor(struct ieee80211_hw *hw)
348{
349 struct rtl_priv *rtlpriv = rtl_priv(hw);
350 struct rtl_sta_info *drv_priv;
351 u8 h2c_parameter[3] = { 0 };
352 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
353
354 /* AP & ADHOC & MESH */
355 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
356 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
357 if (drv_priv->rssi_stat.undec_sm_pwdb <
358 tmp_entry_min_pwdb)
359 tmp_entry_min_pwdb =
360 drv_priv->rssi_stat.undec_sm_pwdb;
361 if (drv_priv->rssi_stat.undec_sm_pwdb >
362 tmp_entry_max_pwdb)
363 tmp_entry_max_pwdb =
364 drv_priv->rssi_stat.undec_sm_pwdb;
365 }
366 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
367
368 /* If associated entry is found */
369 if (tmp_entry_max_pwdb != 0) {
370 rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb;
371 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
372 "EntryMaxPWDB = 0x%lx(%ld)\n",
373 tmp_entry_max_pwdb, tmp_entry_max_pwdb);
374 } else {
375 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
376 }
377 /* If associated entry is found */
378 if (tmp_entry_min_pwdb != 0xff) {
379 rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb;
380 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
381 "EntryMinPWDB = 0x%lx(%ld)\n",
382 tmp_entry_min_pwdb, tmp_entry_min_pwdb);
383 } else {
384 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
385 }
386 /* Indicate Rx signal strength to FW. */
387 if (rtlpriv->dm.useramask) {
388 h2c_parameter[2] = (u8) (rtlpriv->dm.undec_sm_pwdb & 0xFF);
389 h2c_parameter[1] = 0x20;
390 h2c_parameter[0] = 0;
391 rtl8723be_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);
392 } else {
393 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
394 }
395 rtl8723be_dm_find_minimum_rssi(hw);
396 rtlpriv->dm_digtable.rssi_val_min =
397 rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
398}
399
400void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
401{
402 struct rtl_priv *rtlpriv = rtl_priv(hw);
403
404 if (rtlpriv->dm_digtable.cur_igvalue != current_igi) {
405 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
406 if (rtlpriv->phy.rf_type != RF_1T1R)
407 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, current_igi);
408 }
409 rtlpriv->dm_digtable.pre_igvalue = rtlpriv->dm_digtable.cur_igvalue;
410 rtlpriv->dm_digtable.cur_igvalue = current_igi;
411}
412
413static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
414{
415 struct rtl_priv *rtlpriv = rtl_priv(hw);
416 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
417 struct dig_t *dm_digtable = &(rtlpriv->dm_digtable);
418 u8 dig_dynamic_min, dig_maxofmin;
419 bool firstconnect, firstdisconnect;
420 u8 dm_dig_max, dm_dig_min;
421 u8 current_igi = dm_digtable->cur_igvalue;
422 u8 offset;
423
424 /* AP, BT */
425 if (mac->act_scanning)
426 return;
427
428 dig_dynamic_min = dm_digtable->dig_min_0;
429 firstconnect = (mac->link_state >= MAC80211_LINKED) &&
430 !dm_digtable->media_connect_0;
431 firstdisconnect = (mac->link_state < MAC80211_LINKED) &&
432 dm_digtable->media_connect_0;
433
434 dm_dig_max = 0x5a;
435 dm_dig_min = DM_DIG_MIN;
436 dig_maxofmin = DM_DIG_MAX_AP;
437
438 if (mac->link_state >= MAC80211_LINKED) {
439 if ((dm_digtable->rssi_val_min + 10) > dm_dig_max)
440 dm_digtable->rx_gain_max = dm_dig_max;
441 else if ((dm_digtable->rssi_val_min + 10) < dm_dig_min)
442 dm_digtable->rx_gain_max = dm_dig_min;
443 else
444 dm_digtable->rx_gain_max =
445 dm_digtable->rssi_val_min + 10;
446
447 if (rtlpriv->dm.one_entry_only) {
448 offset = 12;
449 if (dm_digtable->rssi_val_min - offset < dm_dig_min)
450 dig_dynamic_min = dm_dig_min;
451 else if (dm_digtable->rssi_val_min - offset >
452 dig_maxofmin)
453 dig_dynamic_min = dig_maxofmin;
454 else
455 dig_dynamic_min =
456 dm_digtable->rssi_val_min - offset;
457 } else {
458 dig_dynamic_min = dm_dig_min;
459 }
460 } else {
461 dm_digtable->rx_gain_max = dm_dig_max;
462 dig_dynamic_min = dm_dig_min;
463 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
464 }
465
466 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
467 if (dm_digtable->large_fa_hit != 3)
468 dm_digtable->large_fa_hit++;
469 if (dm_digtable->forbidden_igi < current_igi) {
470 dm_digtable->forbidden_igi = current_igi;
471 dm_digtable->large_fa_hit = 1;
472 }
473
474 if (dm_digtable->large_fa_hit >= 3) {
475 if ((dm_digtable->forbidden_igi + 1) >
476 dm_digtable->rx_gain_max)
477 dm_digtable->rx_gain_min =
478 dm_digtable->rx_gain_max;
479 else
480 dm_digtable->rx_gain_min =
481 dm_digtable->forbidden_igi + 1;
482 dm_digtable->recover_cnt = 3600;
483 }
484 } else {
485 if (dm_digtable->recover_cnt != 0) {
486 dm_digtable->recover_cnt--;
487 } else {
488 if (dm_digtable->large_fa_hit < 3) {
489 if ((dm_digtable->forbidden_igi - 1) <
490 dig_dynamic_min) {
491 dm_digtable->forbidden_igi =
492 dig_dynamic_min;
493 dm_digtable->rx_gain_min =
494 dig_dynamic_min;
495 } else {
496 dm_digtable->forbidden_igi--;
497 dm_digtable->rx_gain_min =
498 dm_digtable->forbidden_igi + 1;
499 }
500 } else {
501 dm_digtable->large_fa_hit = 0;
502 }
503 }
504 }
505 if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max)
506 dm_digtable->rx_gain_min = dm_digtable->rx_gain_max;
507
508 if (mac->link_state >= MAC80211_LINKED) {
509 if (firstconnect) {
510 if (dm_digtable->rssi_val_min <= dig_maxofmin)
511 current_igi = dm_digtable->rssi_val_min;
512 else
513 current_igi = dig_maxofmin;
514
515 dm_digtable->large_fa_hit = 0;
516 } else {
517 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
518 current_igi += 4;
519 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
520 current_igi += 2;
521 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
522 current_igi -= 2;
523 }
524 } else {
525 if (firstdisconnect) {
526 current_igi = dm_digtable->rx_gain_min;
527 } else {
528 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
529 current_igi += 4;
530 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
531 current_igi += 2;
532 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
533 current_igi -= 2;
534 }
535 }
536
537 if (current_igi > dm_digtable->rx_gain_max)
538 current_igi = dm_digtable->rx_gain_max;
539 else if (current_igi < dm_digtable->rx_gain_min)
540 current_igi = dm_digtable->rx_gain_min;
541
542 rtl8723be_dm_write_dig(hw, current_igi);
543 dm_digtable->media_connect_0 =
544 ((mac->link_state >= MAC80211_LINKED) ? true : false);
545 dm_digtable->dig_min_0 = dig_dynamic_min;
546}
547
548static void rtl8723be_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
549{
550 u32 ret_value;
551 struct rtl_priv *rtlpriv = rtl_priv(hw);
552 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
553
554 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
555 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
556
557 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
558 falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff;
559 falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16;
560
561 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
562 falsealm_cnt->cnt_ofdm_cca = ret_value & 0xffff;
563 falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16;
564
565 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
566 falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff;
567 falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16;
568
569 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
570 falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff;
571
572 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
573 falsealm_cnt->cnt_rate_illegal +
574 falsealm_cnt->cnt_crc8_fail +
575 falsealm_cnt->cnt_mcs_fail +
576 falsealm_cnt->cnt_fast_fsync_fail +
577 falsealm_cnt->cnt_sb_search_fail;
578
579 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
580 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
581
582 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_RST_11N, MASKBYTE0);
583 falsealm_cnt->cnt_cck_fail = ret_value;
584
585 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
586 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
587
588 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
589 falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
590 ((ret_value & 0xff00) >> 8);
591
592 falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
593 falsealm_cnt->cnt_sb_search_fail +
594 falsealm_cnt->cnt_parity_fail +
595 falsealm_cnt->cnt_rate_illegal +
596 falsealm_cnt->cnt_crc8_fail +
597 falsealm_cnt->cnt_mcs_fail +
598 falsealm_cnt->cnt_cck_fail;
599
600 falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
601 falsealm_cnt->cnt_cck_cca;
602
603 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
604 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
605 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
606 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
607
608 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
609 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
610
611 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
612 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
613
614 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
615 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
616
617 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
618 "cnt_parity_fail = %d, cnt_rate_illegal = %d, "
619 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
620 falsealm_cnt->cnt_parity_fail,
621 falsealm_cnt->cnt_rate_illegal,
622 falsealm_cnt->cnt_crc8_fail,
623 falsealm_cnt->cnt_mcs_fail);
624
625 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
626 "cnt_ofdm_fail = %x, cnt_cck_fail = %x,"
627 " cnt_all = %x\n",
628 falsealm_cnt->cnt_ofdm_fail,
629 falsealm_cnt->cnt_cck_fail,
630 falsealm_cnt->cnt_all);
631}
632
633static void rtl8723be_dm_dynamic_txpower(struct ieee80211_hw *hw)
634{
635 /* 8723BE does not support ODM_BB_DYNAMIC_TXPWR*/
636 return;
637}
638
639static void rtl8723be_set_iqk_matrix(struct ieee80211_hw *hw, u8 ofdm_index,
640 u8 rfpath, long iqk_result_x,
641 long iqk_result_y)
642{
643 long ele_a = 0, ele_d, ele_c = 0, value32;
644
645 if (ofdm_index >= 43)
646 ofdm_index = 43 - 1;
647
648 ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000) >> 22;
649
650 if (iqk_result_x != 0) {
651 if ((iqk_result_x & 0x00000200) != 0)
652 iqk_result_x = iqk_result_x | 0xFFFFFC00;
653 ele_a = ((iqk_result_x * ele_d) >> 8) & 0x000003FF;
654
655 if ((iqk_result_y & 0x00000200) != 0)
656 iqk_result_y = iqk_result_y | 0xFFFFFC00;
657 ele_c = ((iqk_result_y * ele_d) >> 8) & 0x000003FF;
658
659 switch (rfpath) {
660 case RF90_PATH_A:
661 value32 = (ele_d << 22) |
662 ((ele_c & 0x3F) << 16) | ele_a;
663 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
664 value32);
665 value32 = (ele_c & 0x000003C0) >> 6;
666 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
667 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
668 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
669 value32);
670 break;
671 default:
672 break;
673 }
674 } else {
675 switch (rfpath) {
676 case RF90_PATH_A:
677 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
678 ofdmswing_table[ofdm_index]);
679 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
680 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00);
681 break;
682 default:
683 break;
684 }
685 }
686}
687
688static void rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw *hw,
689 enum pwr_track_control_method method,
690 u8 rfpath, u8 idx)
691{
692 struct rtl_priv *rtlpriv = rtl_priv(hw);
693 struct rtl_phy *rtlphy = &(rtlpriv->phy);
694 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
695 u8 swing_idx_ofdm_limit = 36;
696
697 if (method == TXAGC) {
698 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
699 } else if (method == BBSWING) {
700 if (rtldm->swing_idx_cck >= CCK_TABLE_SIZE)
701 rtldm->swing_idx_cck = CCK_TABLE_SIZE - 1;
702
703 if (!rtldm->cck_inch14) {
704 rtl_write_byte(rtlpriv, 0xa22,
705 cckswing_table_ch1ch13[rtldm->swing_idx_cck][0]);
706 rtl_write_byte(rtlpriv, 0xa23,
707 cckswing_table_ch1ch13[rtldm->swing_idx_cck][1]);
708 rtl_write_byte(rtlpriv, 0xa24,
709 cckswing_table_ch1ch13[rtldm->swing_idx_cck][2]);
710 rtl_write_byte(rtlpriv, 0xa25,
711 cckswing_table_ch1ch13[rtldm->swing_idx_cck][3]);
712 rtl_write_byte(rtlpriv, 0xa26,
713 cckswing_table_ch1ch13[rtldm->swing_idx_cck][4]);
714 rtl_write_byte(rtlpriv, 0xa27,
715 cckswing_table_ch1ch13[rtldm->swing_idx_cck][5]);
716 rtl_write_byte(rtlpriv, 0xa28,
717 cckswing_table_ch1ch13[rtldm->swing_idx_cck][6]);
718 rtl_write_byte(rtlpriv, 0xa29,
719 cckswing_table_ch1ch13[rtldm->swing_idx_cck][7]);
720 } else {
721 rtl_write_byte(rtlpriv, 0xa22,
722 cckswing_table_ch14[rtldm->swing_idx_cck][0]);
723 rtl_write_byte(rtlpriv, 0xa23,
724 cckswing_table_ch14[rtldm->swing_idx_cck][1]);
725 rtl_write_byte(rtlpriv, 0xa24,
726 cckswing_table_ch14[rtldm->swing_idx_cck][2]);
727 rtl_write_byte(rtlpriv, 0xa25,
728 cckswing_table_ch14[rtldm->swing_idx_cck][3]);
729 rtl_write_byte(rtlpriv, 0xa26,
730 cckswing_table_ch14[rtldm->swing_idx_cck][4]);
731 rtl_write_byte(rtlpriv, 0xa27,
732 cckswing_table_ch14[rtldm->swing_idx_cck][5]);
733 rtl_write_byte(rtlpriv, 0xa28,
734 cckswing_table_ch14[rtldm->swing_idx_cck][6]);
735 rtl_write_byte(rtlpriv, 0xa29,
736 cckswing_table_ch14[rtldm->swing_idx_cck][7]);
737 }
738
739 if (rfpath == RF90_PATH_A) {
740 if (rtldm->swing_idx_ofdm[RF90_PATH_A] <
741 swing_idx_ofdm_limit)
742 swing_idx_ofdm_limit =
743 rtldm->swing_idx_ofdm[RF90_PATH_A];
744
745 rtl8723be_set_iqk_matrix(hw,
746 rtldm->swing_idx_ofdm[rfpath], rfpath,
747 rtlphy->iqk_matrix[idx].value[0][0],
748 rtlphy->iqk_matrix[idx].value[0][1]);
749 } else if (rfpath == RF90_PATH_B) {
750 if (rtldm->swing_idx_ofdm[RF90_PATH_B] <
751 swing_idx_ofdm_limit)
752 swing_idx_ofdm_limit =
753 rtldm->swing_idx_ofdm[RF90_PATH_B];
754
755 rtl8723be_set_iqk_matrix(hw,
756 rtldm->swing_idx_ofdm[rfpath], rfpath,
757 rtlphy->iqk_matrix[idx].value[0][4],
758 rtlphy->iqk_matrix[idx].value[0][5]);
759 }
760 } else {
761 return;
762 }
763}
764
765static void txpwr_track_cb_therm(struct ieee80211_hw *hw)
766{
767 struct rtl_priv *rtlpriv = rtl_priv(hw);
768 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
769 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
770 u8 thermalvalue = 0, delta, delta_lck, delta_iqk;
771 u8 thermalvalue_avg_count = 0;
772 u32 thermalvalue_avg = 0;
773 int i = 0;
774
775 u8 ofdm_min_index = 6;
776 u8 index = 0;
777
778 char delta_swing_table_idx_tup_a[] = {
779 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
780 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10,
781 10, 11, 11, 12, 12, 13, 14, 15};
782 char delta_swing_table_idx_tdown_a[] = {
783 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
784 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9,
785 9, 10, 10, 11, 12, 13, 14, 15};
786
787 /*Initilization ( 7 steps in total)*/
788 rtlpriv->dm.txpower_trackinginit = true;
789 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
790 "rtl8723be_dm_txpower_tracking"
791 "_callback_thermalmeter\n");
792
793 thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xfc00);
794 if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 ||
795 rtlefuse->eeprom_thermalmeter == 0xFF)
796 return;
797 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
798 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
799 "eeprom_thermalmeter 0x%x\n",
800 thermalvalue, rtldm->thermalvalue,
801 rtlefuse->eeprom_thermalmeter);
802 /*3 Initialize ThermalValues of RFCalibrateInfo*/
803 if (!rtldm->thermalvalue) {
804 rtlpriv->dm.thermalvalue_lck = thermalvalue;
805 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
806 }
807
808 /*4 Calculate average thermal meter*/
809 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
810 rtldm->thermalvalue_avg_index++;
811 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8723BE)
812 rtldm->thermalvalue_avg_index = 0;
813
814 for (i = 0; i < AVG_THERMAL_NUM_8723BE; i++) {
815 if (rtldm->thermalvalue_avg[i]) {
816 thermalvalue_avg += rtldm->thermalvalue_avg[i];
817 thermalvalue_avg_count++;
818 }
819 }
820
821 if (thermalvalue_avg_count)
822 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
823
824 /* 5 Calculate delta, delta_LCK, delta_IQK.*/
825 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
826 (thermalvalue - rtlpriv->dm.thermalvalue) :
827 (rtlpriv->dm.thermalvalue - thermalvalue);
828 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
829 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
830 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
831 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
832 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
833 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
834
835 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
836 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
837 "eeprom_thermalmeter 0x%x delta 0x%x "
838 "delta_lck 0x%x delta_iqk 0x%x\n",
839 thermalvalue, rtlpriv->dm.thermalvalue,
840 rtlefuse->eeprom_thermalmeter, delta, delta_lck, delta_iqk);
841 /* 6 If necessary, do LCK.*/
842 if (delta_lck >= IQK_THRESHOLD) {
843 rtlpriv->dm.thermalvalue_lck = thermalvalue;
844 rtl8723be_phy_lc_calibrate(hw);
845 }
846
847 /* 7 If necessary, move the index of
848 * swing table to adjust Tx power.
849 */
850 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
851 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
852 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
853 (rtlefuse->eeprom_thermalmeter - thermalvalue);
854
855 if (delta >= TXSCALE_TABLE_SIZE)
856 delta = TXSCALE_TABLE_SIZE - 1;
857 /* 7.1 Get the final CCK_index and
858 * OFDM_index for each swing table.
859 */
860 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
861 rtldm->delta_power_index_last[RF90_PATH_A] =
862 rtldm->delta_power_index[RF90_PATH_A];
863 rtldm->delta_power_index[RF90_PATH_A] =
864 delta_swing_table_idx_tup_a[delta];
865 } else {
866 rtldm->delta_power_index_last[RF90_PATH_A] =
867 rtldm->delta_power_index[RF90_PATH_A];
868 rtldm->delta_power_index[RF90_PATH_A] =
869 -1 * delta_swing_table_idx_tdown_a[delta];
870 }
871
872 /* 7.2 Handle boundary conditions of index.*/
873 if (rtldm->delta_power_index[RF90_PATH_A] ==
874 rtldm->delta_power_index_last[RF90_PATH_A])
875 rtldm->power_index_offset[RF90_PATH_A] = 0;
876 else
877 rtldm->power_index_offset[RF90_PATH_A] =
878 rtldm->delta_power_index[RF90_PATH_A] -
879 rtldm->delta_power_index_last[RF90_PATH_A];
880
881 rtldm->ofdm_index[0] =
882 rtldm->swing_idx_ofdm_base[RF90_PATH_A] +
883 rtldm->power_index_offset[RF90_PATH_A];
884 rtldm->cck_index = rtldm->swing_idx_cck_base +
885 rtldm->power_index_offset[RF90_PATH_A];
886
887 rtldm->swing_idx_cck = rtldm->cck_index;
888 rtldm->swing_idx_ofdm[0] = rtldm->ofdm_index[0];
889
890 if (rtldm->ofdm_index[0] > OFDM_TABLE_SIZE - 1)
891 rtldm->ofdm_index[0] = OFDM_TABLE_SIZE - 1;
892 else if (rtldm->ofdm_index[0] < ofdm_min_index)
893 rtldm->ofdm_index[0] = ofdm_min_index;
894
895 if (rtldm->cck_index > CCK_TABLE_SIZE - 1)
896 rtldm->cck_index = CCK_TABLE_SIZE - 1;
897 else if (rtldm->cck_index < 0)
898 rtldm->cck_index = 0;
899 } else {
900 rtldm->power_index_offset[RF90_PATH_A] = 0;
901 }
902
903 if ((rtldm->power_index_offset[RF90_PATH_A] != 0) &&
904 (rtldm->txpower_track_control)) {
905 rtldm->done_txpower = true;
906 if (thermalvalue > rtlefuse->eeprom_thermalmeter)
907 rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
908 index);
909 else
910 rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
911 index);
912
913 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
914 rtldm->swing_idx_ofdm_base[RF90_PATH_A] =
915 rtldm->swing_idx_ofdm[0];
916 rtldm->thermalvalue = thermalvalue;
917 }
918
919 if (delta_iqk >= IQK_THRESHOLD) {
920 rtldm->thermalvalue_iqk = thermalvalue;
921 rtl8723be_phy_iq_calibrate(hw, false);
922 }
923
924 rtldm->txpowercount = 0;
925 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
926}
927
928void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw)
929{
930 struct rtl_priv *rtlpriv = rtl_priv(hw);
931 static u8 tm_trigger;
932
933 if (!rtlpriv->dm.txpower_tracking)
934 return;
935
936 if (!tm_trigger) {
937 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16),
938 0x03);
939 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
940 "Trigger 8723be Thermal Meter!!\n");
941 tm_trigger = 1;
942 return;
943 } else {
944 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
945 "Schedule TxPowerTracking !!\n");
946 txpwr_track_cb_therm(hw);
947 tm_trigger = 0;
948 }
949}
950
951static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
952{
953 struct rtl_priv *rtlpriv = rtl_priv(hw);
954 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
955 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
956 struct rate_adaptive *ra = &(rtlpriv->ra);
957 struct ieee80211_sta *sta = NULL;
958 u32 low_rssithresh_for_ra = ra->low2high_rssi_thresh_for_ra40m;
959 u32 high_rssithresh_for_ra = ra->high_rssi_thresh_for_ra;
960 u8 go_up_gap = 5;
961
962 if (is_hal_stop(rtlhal)) {
963 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
964 "driver is going to unload\n");
965 return;
966 }
967
968 if (!rtlpriv->dm.useramask) {
969 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
970 "driver does not control rate adaptive mask\n");
971 return;
972 }
973
974 if (mac->link_state == MAC80211_LINKED &&
975 mac->opmode == NL80211_IFTYPE_STATION) {
976 switch (ra->pre_ratr_state) {
977 case DM_RATR_STA_MIDDLE:
978 high_rssithresh_for_ra += go_up_gap;
979 break;
980 case DM_RATR_STA_LOW:
981 high_rssithresh_for_ra += go_up_gap;
982 low_rssithresh_for_ra += go_up_gap;
983 break;
984 default:
985 break;
986 }
987
988 if (rtlpriv->dm.undec_sm_pwdb >
989 (long)high_rssithresh_for_ra)
990 ra->ratr_state = DM_RATR_STA_HIGH;
991 else if (rtlpriv->dm.undec_sm_pwdb >
992 (long)low_rssithresh_for_ra)
993 ra->ratr_state = DM_RATR_STA_MIDDLE;
994 else
995 ra->ratr_state = DM_RATR_STA_LOW;
996
997 if (ra->pre_ratr_state != ra->ratr_state) {
998 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
999 "RSSI = %ld\n",
1000 rtlpriv->dm.undec_sm_pwdb);
1001 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1002 "RSSI_LEVEL = %d\n", ra->ratr_state);
1003 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1004 "PreState = %d, CurState = %d\n",
1005 ra->pre_ratr_state, ra->ratr_state);
1006
1007 rcu_read_lock();
1008 sta = rtl_find_sta(hw, mac->bssid);
1009 if (sta)
1010 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1011 ra->ratr_state);
1012 rcu_read_unlock();
1013
1014 ra->pre_ratr_state = ra->ratr_state;
1015 }
1016 }
1017}
1018
1019static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
1020{
1021 struct rtl_priv *rtlpriv = rtl_priv(hw);
1022
1023 if (rtlpriv->cfg->ops->get_btc_status()) {
1024 if (rtlpriv->btcoexist.btc_ops->btc_is_disable_edca_turbo(rtlpriv))
1025 return true;
1026 }
1027 if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
1028 return true;
1029
1030 return false;
1031}
1032
1033static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
1034{
1035 struct rtl_priv *rtlpriv = rtl_priv(hw);
1036 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1037 static u64 last_txok_cnt;
1038 static u64 last_rxok_cnt;
1039 u64 cur_txok_cnt = 0;
1040 u64 cur_rxok_cnt = 0;
1041 u32 edca_be_ul = 0x6ea42b;
1042 u32 edca_be_dl = 0x6ea42b;/*not sure*/
1043 u32 edca_be = 0x5ea42b;
1044 u32 iot_peer = 0;
1045 bool is_cur_rdlstate;
1046 bool last_is_cur_rdlstate = false;
1047 bool bias_on_rx = false;
1048 bool edca_turbo_on = false;
1049
1050 last_is_cur_rdlstate = rtlpriv->dm.is_cur_rdlstate;
1051
1052 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
1053 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
1054
1055 iot_peer = rtlpriv->mac80211.vendor;
1056 bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ?
1057 true : false;
1058 edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
1059 (!rtlpriv->dm.disable_framebursting)) ?
1060 true : false;
1061
1062 if ((iot_peer == PEER_CISCO) &&
1063 (mac->mode == WIRELESS_MODE_N_24G)) {
1064 edca_be_dl = edca_setting_dl[iot_peer];
1065 edca_be_ul = edca_setting_ul[iot_peer];
1066 }
1067 if (rtl8723be_dm_is_edca_turbo_disable(hw))
1068 goto exit;
1069
1070 if (edca_turbo_on) {
1071 if (bias_on_rx)
1072 is_cur_rdlstate = (cur_txok_cnt > cur_rxok_cnt * 4) ?
1073 false : true;
1074 else
1075 is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
1076 true : false;
1077
1078 edca_be = (is_cur_rdlstate) ? edca_be_dl : edca_be_ul;
1079 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be);
1080 rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate;
1081 rtlpriv->dm.current_turbo_edca = true;
1082 } else {
1083 if (rtlpriv->dm.current_turbo_edca) {
1084 u8 tmp = AC0_BE;
1085 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
1086 (u8 *)(&tmp));
1087 }
1088 rtlpriv->dm.current_turbo_edca = false;
1089 }
1090
1091exit:
1092 rtlpriv->dm.is_any_nonbepkts = false;
1093 last_txok_cnt = rtlpriv->stats.txbytesunicast;
1094 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
1095}
1096
1097static void rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
1098{
1099 struct rtl_priv *rtlpriv = rtl_priv(hw);
1100 u8 cur_cck_cca_thresh;
1101
1102 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1103 if (rtlpriv->dm_digtable.rssi_val_min > 25) {
1104 cur_cck_cca_thresh = 0xcd;
1105 } else if ((rtlpriv->dm_digtable.rssi_val_min <= 25) &&
1106 (rtlpriv->dm_digtable.rssi_val_min > 10)) {
1107 cur_cck_cca_thresh = 0x83;
1108 } else {
1109 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1110 cur_cck_cca_thresh = 0x83;
1111 else
1112 cur_cck_cca_thresh = 0x40;
1113 }
1114 } else {
1115 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1116 cur_cck_cca_thresh = 0x83;
1117 else
1118 cur_cck_cca_thresh = 0x40;
1119 }
1120
1121 if (rtlpriv->dm_digtable.cur_cck_cca_thres != cur_cck_cca_thresh)
1122 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
1123
1124 rtlpriv->dm_digtable.pre_cck_cca_thres = rtlpriv->dm_digtable.cur_cck_cca_thres;
1125 rtlpriv->dm_digtable.cur_cck_cca_thres = cur_cck_cca_thresh;
1126 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
1127 "CCK cca thresh hold =%x\n",
1128 rtlpriv->dm_digtable.cur_cck_cca_thres);
1129}
1130
1131static void rtl8723be_dm_dynamic_edcca(struct ieee80211_hw *hw)
1132{
1133 struct rtl_priv *rtlpriv = rtl_priv(hw);
1134 u8 reg_c50, reg_c58;
1135 bool fw_current_in_ps_mode = false;
1136
1137 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1138 (u8 *)(&fw_current_in_ps_mode));
1139 if (fw_current_in_ps_mode)
1140 return;
1141
1142 reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1143 reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1144
1145 if (reg_c50 > 0x28 && reg_c58 > 0x28) {
1146 if (!rtlpriv->rtlhal.pre_edcca_enable) {
1147 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
1148 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
1149 }
1150 } else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
1151 if (rtlpriv->rtlhal.pre_edcca_enable) {
1152 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
1153 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
1154 }
1155 }
1156}
1157
1158static void rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
1159{
1160 struct rtl_priv *rtlpriv = rtl_priv(hw);
1161 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1162 u8 crystal_cap;
1163 u32 packet_count;
1164 int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
1165 int cfo_ave_diff;
1166
1167 if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1168 if (rtldm->atc_status == ATC_STATUS_OFF) {
1169 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1170 ATC_STATUS_ON);
1171 rtldm->atc_status = ATC_STATUS_ON;
1172 }
1173 if (rtlpriv->cfg->ops->get_btc_status()) {
1174 if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) {
1175 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1176 "odm_DynamicATCSwitch(): Disable"
1177 " CFO tracking for BT!!\n");
1178 return;
1179 }
1180 }
1181
1182 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
1183 rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
1184 crystal_cap = rtldm->crystal_cap & 0x3f;
1185 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1186 (crystal_cap | (crystal_cap << 6)));
1187 }
1188 } else {
1189 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
1190 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
1191 packet_count = rtldm->packet_count;
1192
1193 if (packet_count == rtldm->packet_count_pre)
1194 return;
1195
1196 rtldm->packet_count_pre = packet_count;
1197
1198 if (rtlpriv->phy.rf_type == RF_1T1R)
1199 cfo_ave = cfo_khz_a;
1200 else
1201 cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
1202
1203 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
1204 (rtldm->cfo_ave_pre - cfo_ave) :
1205 (cfo_ave - rtldm->cfo_ave_pre);
1206
1207 if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) {
1208 rtldm->large_cfo_hit = 1;
1209 return;
1210 } else {
1211 rtldm->large_cfo_hit = 0;
1212 }
1213
1214 rtldm->cfo_ave_pre = cfo_ave;
1215
1216 if (cfo_ave >= -rtldm->cfo_threshold &&
1217 cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
1218 if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
1219 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
1220 rtldm->is_freeze = 1;
1221 } else {
1222 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
1223 }
1224 }
1225
1226 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
1227 adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 1) + 1;
1228 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
1229 rtlpriv->dm.crystal_cap > 0)
1230 adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 1) - 1;
1231
1232 if (adjust_xtal != 0) {
1233 rtldm->is_freeze = 0;
1234 rtldm->crystal_cap += adjust_xtal;
1235
1236 if (rtldm->crystal_cap > 0x3f)
1237 rtldm->crystal_cap = 0x3f;
1238 else if (rtldm->crystal_cap < 0)
1239 rtldm->crystal_cap = 0;
1240
1241 crystal_cap = rtldm->crystal_cap & 0x3f;
1242 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1243 (crystal_cap | (crystal_cap << 6)));
1244 }
1245
1246 if (cfo_ave < CFO_THRESHOLD_ATC &&
1247 cfo_ave > -CFO_THRESHOLD_ATC) {
1248 if (rtldm->atc_status == ATC_STATUS_ON) {
1249 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1250 ATC_STATUS_OFF);
1251 rtldm->atc_status = ATC_STATUS_OFF;
1252 }
1253 } else {
1254 if (rtldm->atc_status == ATC_STATUS_OFF) {
1255 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1256 ATC_STATUS_ON);
1257 rtldm->atc_status = ATC_STATUS_ON;
1258 }
1259 }
1260 }
1261}
1262
1263static void rtl8723be_dm_common_info_self_update(struct ieee80211_hw *hw)
1264{
1265 struct rtl_priv *rtlpriv = rtl_priv(hw);
1266 struct rtl_sta_info *drv_priv;
1267 u8 cnt = 0;
1268
1269 rtlpriv->dm.one_entry_only = false;
1270
1271 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
1272 rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1273 rtlpriv->dm.one_entry_only = true;
1274 return;
1275 }
1276
1277 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1278 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
1279 rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
1280 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1281 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1282 cnt++;
1283 }
1284 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1285
1286 if (cnt == 1)
1287 rtlpriv->dm.one_entry_only = true;
1288 }
1289}
1290
1291void rtl8723be_dm_watchdog(struct ieee80211_hw *hw)
1292{
1293 struct rtl_priv *rtlpriv = rtl_priv(hw);
1294 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1295 bool fw_current_inpsmode = false;
1296 bool fw_ps_awake = true;
1297
1298 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1299 (u8 *)(&fw_current_inpsmode));
1300
1301 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1302 (u8 *)(&fw_ps_awake));
1303
1304 if (ppsc->p2p_ps_info.p2p_ps_mode)
1305 fw_ps_awake = false;
1306
1307 if ((ppsc->rfpwr_state == ERFON) &&
1308 ((!fw_current_inpsmode) && fw_ps_awake) &&
1309 (!ppsc->rfchange_inprogress)) {
1310 rtl8723be_dm_common_info_self_update(hw);
1311 rtl8723be_dm_false_alarm_counter_statistics(hw);
1312 rtl8723be_dm_check_rssi_monitor(hw);
1313 rtl8723be_dm_dig(hw);
1314 rtl8723be_dm_dynamic_edcca(hw);
1315 rtl8723be_dm_cck_packet_detection_thresh(hw);
1316 rtl8723be_dm_refresh_rate_adaptive_mask(hw);
1317 rtl8723be_dm_check_edca_turbo(hw);
1318 rtl8723be_dm_dynamic_atc_switch(hw);
1319 rtl8723be_dm_check_txpower_tracking(hw);
1320 rtl8723be_dm_dynamic_txpower(hw);
1321 if (rtlpriv->cfg->ops->get_btc_status())
1322 rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv);
1323 }
1324 rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
1325}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.h b/drivers/net/wireless/rtlwifi/rtl8723be/dm.h
new file mode 100644
index 000000000000..c6c2f2a78a66
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.h
@@ -0,0 +1,310 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * Contact Information:
15 * wlanfae <wlanfae@realtek.com>
16 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
17 * Hsinchu 300, Taiwan.
18 *
19 * Larry Finger <Larry.Finger@lwfinger.net>
20 *
21 *****************************************************************************/
22
23#ifndef __RTL8723BE_DM_H__
24#define __RTL8723BE_DM_H__
25
26#define MAIN_ANT 0
27#define AUX_ANT 1
28#define MAIN_ANT_CG_TRX 1
29#define AUX_ANT_CG_TRX 0
30#define MAIN_ANT_CGCS_RX 0
31#define AUX_ANT_CGCS_RX 1
32
33#define TXSCALE_TABLE_SIZE 30
34
35/*RF REG LIST*/
36#define DM_REG_RF_MODE_11N 0x00
37#define DM_REG_RF_0B_11N 0x0B
38#define DM_REG_CHNBW_11N 0x18
39#define DM_REG_T_METER_11N 0x24
40#define DM_REG_RF_25_11N 0x25
41#define DM_REG_RF_26_11N 0x26
42#define DM_REG_RF_27_11N 0x27
43#define DM_REG_RF_2B_11N 0x2B
44#define DM_REG_RF_2C_11N 0x2C
45#define DM_REG_RXRF_A3_11N 0x3C
46#define DM_REG_T_METER_92D_11N 0x42
47#define DM_REG_T_METER_88E_11N 0x42
48
49/*BB REG LIST*/
50/*PAGE 8 */
51#define DM_REG_BB_CTRL_11N 0x800
52#define DM_REG_RF_PIN_11N 0x804
53#define DM_REG_PSD_CTRL_11N 0x808
54#define DM_REG_TX_ANT_CTRL_11N 0x80C
55#define DM_REG_BB_PWR_SAV5_11N 0x818
56#define DM_REG_CCK_RPT_FORMAT_11N 0x824
57#define DM_REG_RX_DEFUALT_A_11N 0x858
58#define DM_REG_RX_DEFUALT_B_11N 0x85A
59#define DM_REG_BB_PWR_SAV3_11N 0x85C
60#define DM_REG_ANTSEL_CTRL_11N 0x860
61#define DM_REG_RX_ANT_CTRL_11N 0x864
62#define DM_REG_PIN_CTRL_11N 0x870
63#define DM_REG_BB_PWR_SAV1_11N 0x874
64#define DM_REG_ANTSEL_PATH_11N 0x878
65#define DM_REG_BB_3WIRE_11N 0x88C
66#define DM_REG_SC_CNT_11N 0x8C4
67#define DM_REG_PSD_DATA_11N 0x8B4
68/*PAGE 9*/
69#define DM_REG_ANT_MAPPING1_11N 0x914
70#define DM_REG_ANT_MAPPING2_11N 0x918
71/*PAGE A*/
72#define DM_REG_CCK_ANTDIV_PARA1_11N 0xA00
73#define DM_REG_CCK_CCA_11N 0xA0A
74#define DM_REG_CCK_ANTDIV_PARA2_11N 0xA0C
75#define DM_REG_CCK_ANTDIV_PARA3_11N 0xA10
76#define DM_REG_CCK_ANTDIV_PARA4_11N 0xA14
77#define DM_REG_CCK_FILTER_PARA1_11N 0xA22
78#define DM_REG_CCK_FILTER_PARA2_11N 0xA23
79#define DM_REG_CCK_FILTER_PARA3_11N 0xA24
80#define DM_REG_CCK_FILTER_PARA4_11N 0xA25
81#define DM_REG_CCK_FILTER_PARA5_11N 0xA26
82#define DM_REG_CCK_FILTER_PARA6_11N 0xA27
83#define DM_REG_CCK_FILTER_PARA7_11N 0xA28
84#define DM_REG_CCK_FILTER_PARA8_11N 0xA29
85#define DM_REG_CCK_FA_RST_11N 0xA2C
86#define DM_REG_CCK_FA_MSB_11N 0xA58
87#define DM_REG_CCK_FA_LSB_11N 0xA5C
88#define DM_REG_CCK_CCA_CNT_11N 0xA60
89#define DM_REG_BB_PWR_SAV4_11N 0xA74
90/*PAGE B */
91#define DM_REG_LNA_SWITCH_11N 0xB2C
92#define DM_REG_PATH_SWITCH_11N 0xB30
93#define DM_REG_RSSI_CTRL_11N 0xB38
94#define DM_REG_CONFIG_ANTA_11N 0xB68
95#define DM_REG_RSSI_BT_11N 0xB9C
96/*PAGE C */
97#define DM_REG_OFDM_FA_HOLDC_11N 0xC00
98#define DM_REG_RX_PATH_11N 0xC04
99#define DM_REG_TRMUX_11N 0xC08
100#define DM_REG_OFDM_FA_RSTC_11N 0xC0C
101#define DM_REG_RXIQI_MATRIX_11N 0xC14
102#define DM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C
103#define DM_REG_IGI_A_11N 0xC50
104#define DM_REG_ANTDIV_PARA2_11N 0xC54
105#define DM_REG_IGI_B_11N 0xC58
106#define DM_REG_ANTDIV_PARA3_11N 0xC5C
107#define DM_REG_BB_PWR_SAV2_11N 0xC70
108#define DM_REG_RX_OFF_11N 0xC7C
109#define DM_REG_TXIQK_MATRIXA_11N 0xC80
110#define DM_REG_TXIQK_MATRIXB_11N 0xC88
111#define DM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94
112#define DM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C
113#define DM_REG_RXIQK_MATRIX_LSB_11N 0xCA0
114#define DM_REG_ANTDIV_PARA1_11N 0xCA4
115#define DM_REG_OFDM_FA_TYPE1_11N 0xCF0
116/*PAGE D */
117#define DM_REG_OFDM_FA_RSTD_11N 0xD00
118#define DM_REG_OFDM_FA_TYPE2_11N 0xDA0
119#define DM_REG_OFDM_FA_TYPE3_11N 0xDA4
120#define DM_REG_OFDM_FA_TYPE4_11N 0xDA8
121/*PAGE E */
122#define DM_REG_TXAGC_A_6_18_11N 0xE00
123#define DM_REG_TXAGC_A_24_54_11N 0xE04
124#define DM_REG_TXAGC_A_1_MCS32_11N 0xE08
125#define DM_REG_TXAGC_A_MCS0_3_11N 0xE10
126#define DM_REG_TXAGC_A_MCS4_7_11N 0xE14
127#define DM_REG_TXAGC_A_MCS8_11_11N 0xE18
128#define DM_REG_TXAGC_A_MCS12_15_11N 0xE1C
129#define DM_REG_FPGA0_IQK_11N 0xE28
130#define DM_REG_TXIQK_TONE_A_11N 0xE30
131#define DM_REG_RXIQK_TONE_A_11N 0xE34
132#define DM_REG_TXIQK_PI_A_11N 0xE38
133#define DM_REG_RXIQK_PI_A_11N 0xE3C
134#define DM_REG_TXIQK_11N 0xE40
135#define DM_REG_RXIQK_11N 0xE44
136#define DM_REG_IQK_AGC_PTS_11N 0xE48
137#define DM_REG_IQK_AGC_RSP_11N 0xE4C
138#define DM_REG_BLUETOOTH_11N 0xE6C
139#define DM_REG_RX_WAIT_CCA_11N 0xE70
140#define DM_REG_TX_CCK_RFON_11N 0xE74
141#define DM_REG_TX_CCK_BBON_11N 0xE78
142#define DM_REG_OFDM_RFON_11N 0xE7C
143#define DM_REG_OFDM_BBON_11N 0xE80
144#define DM_REG_TX2RX_11N 0xE84
145#define DM_REG_TX2TX_11N 0xE88
146#define DM_REG_RX_CCK_11N 0xE8C
147#define DM_REG_RX_OFDM_11N 0xED0
148#define DM_REG_RX_WAIT_RIFS_11N 0xED4
149#define DM_REG_RX2RX_11N 0xED8
150#define DM_REG_STANDBY_11N 0xEDC
151#define DM_REG_SLEEP_11N 0xEE0
152#define DM_REG_PMPD_ANAEN_11N 0xEEC
153
154/*MAC REG LIST*/
155#define DM_REG_BB_RST_11N 0x02
156#define DM_REG_ANTSEL_PIN_11N 0x4C
157#define DM_REG_EARLY_MODE_11N 0x4D0
158#define DM_REG_RSSI_MONITOR_11N 0x4FE
159#define DM_REG_EDCA_VO_11N 0x500
160#define DM_REG_EDCA_VI_11N 0x504
161#define DM_REG_EDCA_BE_11N 0x508
162#define DM_REG_EDCA_BK_11N 0x50C
163#define DM_REG_TXPAUSE_11N 0x522
164#define DM_REG_RESP_TX_11N 0x6D8
165#define DM_REG_ANT_TRAIN_PARA1_11N 0x7b0
166#define DM_REG_ANT_TRAIN_PARA2_11N 0x7b4
167
168/*DIG Related*/
169#define DM_BIT_IGI_11N 0x0000007F
170
171#define HAL_DM_DIG_DISABLE BIT(0)
172#define HAL_DM_HIPWR_DISABLE BIT(1)
173
174#define OFDM_TABLE_LENGTH 43
175#define CCK_TABLE_LENGTH 33
176
177#define OFDM_TABLE_SIZE 37
178#define CCK_TABLE_SIZE 33
179
180#define BW_AUTO_SWITCH_HIGH_LOW 25
181#define BW_AUTO_SWITCH_LOW_HIGH 30
182
183#define DM_DIG_THRESH_HIGH 40
184#define DM_DIG_THRESH_LOW 35
185
186#define DM_FALSEALARM_THRESH_LOW 400
187#define DM_FALSEALARM_THRESH_HIGH 1000
188
189#define DM_DIG_MAX 0x3e
190#define DM_DIG_MIN 0x1e
191
192#define DM_DIG_MAX_AP 0x32
193#define DM_DIG_MIN_AP 0x20
194
195#define DM_DIG_FA_UPPER 0x3e
196#define DM_DIG_FA_LOWER 0x1e
197#define DM_DIG_FA_TH0 0x200
198#define DM_DIG_FA_TH1 0x300
199#define DM_DIG_FA_TH2 0x400
200
201#define DM_DIG_BACKOFF_MAX 12
202#define DM_DIG_BACKOFF_MIN -4
203#define DM_DIG_BACKOFF_DEFAULT 10
204
205#define RXPATHSELECTION_DIFF_TH 18
206
207#define DM_RATR_STA_INIT 0
208#define DM_RATR_STA_HIGH 1
209#define DM_RATR_STA_MIDDLE 2
210#define DM_RATR_STA_LOW 3
211
212#define CTS2SELF_THVAL 30
213#define REGC38_TH 20
214
215#define TXHIGHPWRLEVEL_NORMAL 0
216#define TXHIGHPWRLEVEL_LEVEL1 1
217#define TXHIGHPWRLEVEL_LEVEL2 2
218#define TXHIGHPWRLEVEL_BT1 3
219#define TXHIGHPWRLEVEL_BT2 4
220
221#define DM_TYPE_BYFW 0
222#define DM_TYPE_BYDRIVER 1
223
224#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
225#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
226#define TXPWRTRACK_MAX_IDX 6
227
228/* Dynamic ATC switch */
229#define ATC_STATUS_OFF 0x0 /* enable */
230#define ATC_STATUS_ON 0x1 /* disable */
231#define CFO_THRESHOLD_XTAL 10 /* kHz */
232#define CFO_THRESHOLD_ATC 80 /* kHz */
233
234enum FAT_STATE {
235 FAT_NORMAL_STATE = 0,
236 FAT_TRAINING_STATE = 1,
237};
238
239enum tag_dynamic_init_gain_operation_type_definition {
240 DIG_TYPE_THRESH_HIGH = 0,
241 DIG_TYPE_THRESH_LOW = 1,
242 DIG_TYPE_BACKOFF = 2,
243 DIG_TYPE_RX_GAIN_MIN = 3,
244 DIG_TYPE_RX_GAIN_MAX = 4,
245 DIG_TYPE_ENABLE = 5,
246 DIG_TYPE_DISABLE = 6,
247 DIG_OP_TYPE_MAX
248};
249
250enum dm_1r_cca_e {
251 CCA_1R = 0,
252 CCA_2R = 1,
253 CCA_MAX = 2,
254};
255
256enum dm_rf_e {
257 RF_SAVE = 0,
258 RF_NORMAL = 1,
259 RF_MAX = 2,
260};
261
262enum dm_sw_ant_switch_e {
263 ANS_ANTENNA_B = 1,
264 ANS_ANTENNA_A = 2,
265 ANS_ANTENNA_MAX = 3,
266};
267
268enum dm_dig_ext_port_alg_e {
269 DIG_EXT_PORT_STAGE_0 = 0,
270 DIG_EXT_PORT_STAGE_1 = 1,
271 DIG_EXT_PORT_STAGE_2 = 2,
272 DIG_EXT_PORT_STAGE_3 = 3,
273 DIG_EXT_PORT_STAGE_MAX = 4,
274};
275
276enum dm_dig_connect_e {
277 DIG_STA_DISCONNECT = 0,
278 DIG_STA_CONNECT = 1,
279 DIG_STA_BEFORE_CONNECT = 2,
280 DIG_MULTISTA_DISCONNECT = 3,
281 DIG_MULTISTA_CONNECT = 4,
282 DIG_CONNECT_MAX
283};
284
285enum pwr_track_control_method {
286 BBSWING,
287 TXAGC
288};
289
290#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1)
291#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1)
292#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1)
293#define BT_RSSI_STATE_BG_EDCA_LOW BIT_OFFSET_LEN_MASK_32(3, 1)
294#define BT_RSSI_STATE_TXPOWER_LOW BIT_OFFSET_LEN_MASK_32(4, 1)
295
296void rtl8723be_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, u8 *pdesc,
297 u32 mac_id);
298void rtl8723be_dm_ant_sel_statistics(struct ieee80211_hw *hw, u8 antsel_tr_mux,
299 u32 mac_id, u32 rx_pwdb_all);
300void rtl8723be_dm_fast_antenna_trainning_callback(unsigned long data);
301void rtl8723be_dm_init(struct ieee80211_hw *hw);
302void rtl8723be_dm_watchdog(struct ieee80211_hw *hw);
303void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi);
304void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw);
305void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
306void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type,
307 u8 *pdirection, u32 *poutwrite_val);
308void rtl8723be_dm_init_edca_turbo(struct ieee80211_hw *hw);
309
310#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
new file mode 100644
index 000000000000..0f3522db5b37
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
@@ -0,0 +1,628 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
29#include "reg.h"
30#include "def.h"
31#include "fw.h"
32#include "../rtl8723com/fw_common.h"
33
34static bool _rtl8723be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
35 u8 boxnum)
36{
37 struct rtl_priv *rtlpriv = rtl_priv(hw);
38 u8 val_hmetfr;
39 bool result = false;
40
41 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
42 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
43 result = true;
44 return result;
45}
46
47static void _rtl8723be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
48 u32 cmd_len, u8 *p_cmdbuffer)
49{
50 struct rtl_priv *rtlpriv = rtl_priv(hw);
51 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
52 u8 boxnum;
53 u16 box_reg = 0, box_extreg = 0;
54 u8 u1b_tmp;
55 bool isfw_read = false;
56 u8 buf_index = 0;
57 bool bwrite_sucess = false;
58 u8 wait_h2c_limit = 100;
59 u8 wait_writeh2c_limit = 100;
60 u8 boxcontent[4], boxextcontent[4];
61 u32 h2c_waitcounter = 0;
62 unsigned long flag;
63 u8 idx;
64
65 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
66
67 while (true) {
68 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
69 if (rtlhal->h2c_setinprogress) {
70 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
71 "H2C set in progress! Wait to set.."
72 "element_id(%d).\n", element_id);
73
74 while (rtlhal->h2c_setinprogress) {
75 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
76 flag);
77 h2c_waitcounter++;
78 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
79 "Wait 100 us (%d times)...\n",
80 h2c_waitcounter);
81 udelay(100);
82
83 if (h2c_waitcounter > 1000)
84 return;
85 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
86 flag);
87 }
88 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
89 } else {
90 rtlhal->h2c_setinprogress = true;
91 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
92 break;
93 }
94 }
95 while (!bwrite_sucess) {
96 wait_writeh2c_limit--;
97 if (wait_writeh2c_limit == 0) {
98 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
99 "Write H2C fail because no trigger "
100 "for FW INT!\n");
101 break;
102 }
103 boxnum = rtlhal->last_hmeboxnum;
104 switch (boxnum) {
105 case 0:
106 box_reg = REG_HMEBOX_0;
107 box_extreg = REG_HMEBOX_EXT_0;
108 break;
109 case 1:
110 box_reg = REG_HMEBOX_1;
111 box_extreg = REG_HMEBOX_EXT_1;
112 break;
113 case 2:
114 box_reg = REG_HMEBOX_2;
115 box_extreg = REG_HMEBOX_EXT_2;
116 break;
117 case 3:
118 box_reg = REG_HMEBOX_3;
119 box_extreg = REG_HMEBOX_EXT_3;
120 break;
121 default:
122 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
123 "switch case not processed\n");
124 break;
125 }
126 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw, boxnum);
127 while (!isfw_read) {
128 wait_h2c_limit--;
129 if (wait_h2c_limit == 0) {
130 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
131 "Wating too long for FW read "
132 "clear HMEBox(%d)!\n", boxnum);
133 break;
134 }
135 udelay(10);
136
137 isfw_read = _rtl8723be_check_fw_read_last_h2c(hw,
138 boxnum);
139 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
140 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
141 "Wating for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
142 boxnum, u1b_tmp);
143 }
144 if (!isfw_read) {
145 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
146 "Write H2C register BOX[%d] fail!!!!! "
147 "Fw do not read.\n", boxnum);
148 break;
149 }
150 memset(boxcontent, 0, sizeof(boxcontent));
151 memset(boxextcontent, 0, sizeof(boxextcontent));
152 boxcontent[0] = element_id;
153 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
154 "Write element_id box_reg(%4x) = %2x\n",
155 box_reg, element_id);
156
157 switch (cmd_len) {
158 case 1:
159 case 2:
160 case 3:
161 /*boxcontent[0] &= ~(BIT(7));*/
162 memcpy((u8 *)(boxcontent) + 1,
163 p_cmdbuffer + buf_index, cmd_len);
164
165 for (idx = 0; idx < 4; idx++) {
166 rtl_write_byte(rtlpriv, box_reg + idx,
167 boxcontent[idx]);
168 }
169 break;
170 case 4:
171 case 5:
172 case 6:
173 case 7:
174 /*boxcontent[0] |= (BIT(7));*/
175 memcpy((u8 *)(boxextcontent),
176 p_cmdbuffer + buf_index+3, cmd_len-3);
177 memcpy((u8 *)(boxcontent) + 1,
178 p_cmdbuffer + buf_index, 3);
179
180 for (idx = 0; idx < 4; idx++) {
181 rtl_write_byte(rtlpriv, box_extreg + idx,
182 boxextcontent[idx]);
183 }
184 for (idx = 0; idx < 4; idx++) {
185 rtl_write_byte(rtlpriv, box_reg + idx,
186 boxcontent[idx]);
187 }
188 break;
189 default:
190 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
191 "switch case not process\n");
192 break;
193 }
194 bwrite_sucess = true;
195
196 rtlhal->last_hmeboxnum = boxnum + 1;
197 if (rtlhal->last_hmeboxnum == 4)
198 rtlhal->last_hmeboxnum = 0;
199
200 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
201 "pHalData->last_hmeboxnum = %d\n",
202 rtlhal->last_hmeboxnum);
203 }
204 if (!rtlpriv) {
205 pr_err("rtlpriv bad\n");
206 return;
207 }
208 if (!rtlhal) {
209 pr_err("rtlhal bad\n");
210 return;
211 }
212 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
213 rtlhal->h2c_setinprogress = false;
214 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
215
216 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
217}
218
219void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
220 u32 cmd_len, u8 *p_cmdbuffer)
221{
222 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
223 u32 tmp_cmdbuf[2];
224
225 if (!rtlhal->fw_ready) {
226 RT_ASSERT(false,
227 "return H2C cmd because of Fw download fail!!!\n");
228 return;
229 }
230 memset(tmp_cmdbuf, 0, 8);
231 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
232 _rtl8723be_fill_h2c_command(hw, element_id, cmd_len,
233 (u8 *)&tmp_cmdbuf);
234 return;
235}
236
237void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
238{
239 struct rtl_priv *rtlpriv = rtl_priv(hw);
240 u8 u1_h2c_set_pwrmode[H2C_8723BE_PWEMODE_LENGTH] = { 0 };
241 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
242 u8 rlbm, power_state = 0;
243 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
244
245 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
246 rlbm = 0;/*YJ, temp, 120316. FW now not support RLBM = 2.*/
247 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
248 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
249 (rtlpriv->mac80211.p2p) ?
250 ppsc->smart_ps : 1);
251 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
252 ppsc->reg_max_lps_awakeintvl);
253 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
254 if (mode == FW_PS_ACTIVE_MODE)
255 power_state |= FW_PWR_STATE_ACTIVE;
256 else
257 power_state |= FW_PWR_STATE_RF_OFF;
258 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
259
260 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
261 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
262 u1_h2c_set_pwrmode, H2C_8723BE_PWEMODE_LENGTH);
263 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_SETPWRMODE,
264 H2C_8723BE_PWEMODE_LENGTH,
265 u1_h2c_set_pwrmode);
266}
267
268static bool _rtl8723be_cmd_send_packet(struct ieee80211_hw *hw,
269 struct sk_buff *skb)
270{
271 struct rtl_priv *rtlpriv = rtl_priv(hw);
272 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
273 struct rtl8192_tx_ring *ring;
274 struct rtl_tx_desc *pdesc;
275 struct sk_buff *pskb = NULL;
276 u8 own;
277 unsigned long flags;
278
279 ring = &rtlpci->tx_ring[BEACON_QUEUE];
280
281 pskb = __skb_dequeue(&ring->queue);
282 if (pskb)
283 kfree_skb(pskb);
284
285 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
286
287 pdesc = &ring->desc[0];
288 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *)pdesc, true, HW_DESC_OWN);
289
290 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
291
292 __skb_queue_tail(&ring->queue, skb);
293
294 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
295
296 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
297
298 return true;
299}
300#define BEACON_PG 0 /* ->1 */
301#define PSPOLL_PG 2
302#define NULL_PG 3
303#define PROBERSP_PG 4 /* ->5 */
304
305#define TOTAL_RESERVED_PKT_LEN 768
306
307static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
308 /* page 0 beacon */
309 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
310 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
311 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
314 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
315 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
316 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
317 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
318 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
322 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
323 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
324 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
325
326 /* page 1 beacon */
327 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343
344 /* page 2 ps-poll */
345 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
346 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361
362 /* page 3 null */
363 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
364 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
365 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379
380 /* page 4 probe_resp */
381 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
382 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
383 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
384 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
385 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
386 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
387 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
388 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
389 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
390 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
391 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
395 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397
398 /* page 5 probe_resp */
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415};
416
417void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
418 bool dl_finished)
419{
420 struct rtl_priv *rtlpriv = rtl_priv(hw);
421 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
422 struct sk_buff *skb = NULL;
423
424 u32 totalpacketlen;
425 bool rtstatus;
426 u8 u1rsvdpageloc[5] = { 0 };
427 bool dlok = false;
428
429 u8 *beacon;
430 u8 *p_pspoll;
431 u8 *nullfunc;
432 u8 *p_probersp;
433 /*---------------------------------------------------------
434 * (1) beacon
435 *---------------------------------------------------------
436 */
437 beacon = &reserved_page_packet[BEACON_PG * 128];
438 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
439 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
440
441 /*-------------------------------------------------------
442 * (2) ps-poll
443 *-------------------------------------------------------
444 */
445 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
446 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
447 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
448 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
449
450 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
451
452 /*--------------------------------------------------------
453 * (3) null data
454 *--------------------------------------------------------
455 */
456 nullfunc = &reserved_page_packet[NULL_PG * 128];
457 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
458 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
459 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
460
461 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
462
463 /*---------------------------------------------------------
464 * (4) probe response
465 *---------------------------------------------------------
466 */
467 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
468 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
469 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
470 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
471
472 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
473
474 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
475
476 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
477 "rtl8723be_set_fw_rsvdpagepkt(): "
478 "HW_VAR_SET_TX_CMD: ALL\n",
479 &reserved_page_packet[0], totalpacketlen);
480 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
481 "rtl8723be_set_fw_rsvdpagepkt(): "
482 "HW_VAR_SET_TX_CMD: ALL\n", u1rsvdpageloc, 3);
483
484
485 skb = dev_alloc_skb(totalpacketlen);
486 memcpy((u8 *)skb_put(skb, totalpacketlen),
487 &reserved_page_packet, totalpacketlen);
488
489 rtstatus = _rtl8723be_cmd_send_packet(hw, skb);
490
491 if (rtstatus)
492 dlok = true;
493
494 if (dlok) {
495 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
496 "Set RSVD page location to Fw.\n");
497 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE:\n",
498 u1rsvdpageloc, 3);
499 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_RSVDPAGE,
500 sizeof(u1rsvdpageloc), u1rsvdpageloc);
501 } else {
502 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
503 "Set RSVD page location to Fw FAIL!!!!!!.\n");
504 }
505}
506
507/*Should check FW support p2p or not.*/
508static void rtl8723be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
509 u8 ctwindow)
510{
511 u8 u1_ctwindow_period[1] = {ctwindow};
512
513 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_P2P_PS_CTW_CMD, 1,
514 u1_ctwindow_period);
515}
516
517void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
518 u8 p2p_ps_state)
519{
520 struct rtl_priv *rtlpriv = rtl_priv(hw);
521 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
522 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
523 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
524 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
525 u8 i;
526 u16 ctwindow;
527 u32 start_time, tsf_low;
528
529 switch (p2p_ps_state) {
530 case P2P_PS_DISABLE:
531 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
532 memset(p2p_ps_offload, 0, sizeof(struct p2p_ps_offload_t));
533 break;
534 case P2P_PS_ENABLE:
535 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
536 /* update CTWindow value. */
537 if (p2pinfo->ctwindow > 0) {
538 p2p_ps_offload->ctwindow_en = 1;
539 ctwindow = p2pinfo->ctwindow;
540 rtl8723be_set_p2p_ctw_period_cmd(hw, ctwindow);
541 }
542 /* hw only support 2 set of NoA */
543 for (i = 0; i < p2pinfo->noa_num; i++) {
544 /* To control the register setting
545 * for which NOA
546 */
547 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
548 if (i == 0)
549 p2p_ps_offload->noa0_en = 1;
550 else
551 p2p_ps_offload->noa1_en = 1;
552
553 /* config P2P NoA Descriptor Register */
554 rtl_write_dword(rtlpriv, 0x5E0,
555 p2pinfo->noa_duration[i]);
556 rtl_write_dword(rtlpriv, 0x5E4,
557 p2pinfo->noa_interval[i]);
558
559 /*Get Current TSF value */
560 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
561
562 start_time = p2pinfo->noa_start_time[i];
563 if (p2pinfo->noa_count_type[i] != 1) {
564 while (start_time <= (tsf_low + (50 * 1024))) {
565 start_time += p2pinfo->noa_interval[i];
566 if (p2pinfo->noa_count_type[i] != 255)
567 p2pinfo->noa_count_type[i]--;
568 }
569 }
570 rtl_write_dword(rtlpriv, 0x5E8, start_time);
571 rtl_write_dword(rtlpriv, 0x5EC,
572 p2pinfo->noa_count_type[i]);
573 }
574 if ((p2pinfo->opp_ps == 1) ||
575 (p2pinfo->noa_num > 0)) {
576 /* rst p2p circuit */
577 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
578
579 p2p_ps_offload->offload_en = 1;
580
581 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
582 p2p_ps_offload->role = 1;
583 p2p_ps_offload->allstasleep = 0;
584 } else {
585 p2p_ps_offload->role = 0;
586 }
587 p2p_ps_offload->discovery = 0;
588 }
589 break;
590 case P2P_PS_SCAN:
591 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
592 p2p_ps_offload->discovery = 1;
593 break;
594 case P2P_PS_SCAN_DONE:
595 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
596 p2p_ps_offload->discovery = 0;
597 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
598 break;
599 default:
600 break;
601 }
602 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_P2P_PS_OFFLOAD, 1,
603 (u8 *)p2p_ps_offload);
604}
605
606void rtl8723be_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
607{
608 u8 u1_joinbssrpt_parm[1] = { 0 };
609
610 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
611
612 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_JOINBSSRPT, 1,
613 u1_joinbssrpt_parm);
614}
615
616void rtl8723be_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
617 u8 ap_offload_enable)
618{
619 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
620 u8 u1_apoffload_parm[H2C_8723BE_AP_OFFLOAD_LENGTH] = { 0 };
621
622 SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable);
623 SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->hiddenssid);
624 SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0);
625
626 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_AP_OFFLOAD,
627 H2C_8723BE_AP_OFFLOAD_LENGTH, u1_apoffload_parm);
628}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.h b/drivers/net/wireless/rtlwifi/rtl8723be/fw.h
new file mode 100644
index 000000000000..31eec281e446
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/fw.h
@@ -0,0 +1,248 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 * Larry Finger <Larry.Finger@lwfinger.net>
22 *
23 *****************************************************************************/
24
25#ifndef __RTL8723BE__FW__H__
26#define __RTL8723BE__FW__H__
27
28#define FW_8192C_SIZE 0x8000
29#define FW_8192C_START_ADDRESS 0x1000
30#define FW_8192C_END_ADDRESS 0x5FFF
31#define FW_8192C_PAGE_SIZE 4096
32#define FW_8192C_POLLING_DELAY 5
33#define FW_8192C_POLLING_TIMEOUT_COUNT 6000
34
35#define IS_FW_HEADER_EXIST(_pfwhdr) \
36 ((_pfwhdr->signature&0xFFF0) == 0x5300)
37#define USE_OLD_WOWLAN_DEBUG_FW 0
38
39#define H2C_8723BE_RSVDPAGE_LOC_LEN 5
40#define H2C_8723BE_PWEMODE_LENGTH 5
41#define H2C_8723BE_JOINBSSRPT_LENGTH 1
42#define H2C_8723BE_AP_OFFLOAD_LENGTH 3
43#define H2C_8723BE_WOWLAN_LENGTH 3
44#define H2C_8723BE_KEEP_ALIVE_CTRL_LENGTH 3
45#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
46#define H2C_8723BE_REMOTE_WAKE_CTRL_LEN 1
47#else
48#define H2C_8723BE_REMOTE_WAKE_CTRL_LEN 3
49#endif
50#define H2C_8723BE_AOAC_GLOBAL_INFO_LEN 2
51#define H2C_8723BE_AOAC_RSVDPAGE_LOC_LEN 7
52
53
54/* Fw PS state for RPWM.
55*BIT[2:0] = HW state
56*BIT[3] = Protocol PS state, 1: register active state , 0: register sleep state
57*BIT[4] = sub-state
58*/
59#define FW_PS_GO_ON BIT(0)
60#define FW_PS_TX_NULL BIT(1)
61#define FW_PS_RF_ON BIT(2)
62#define FW_PS_REGISTER_ACTIVE BIT(3)
63
64#define FW_PS_DPS BIT(0)
65#define FW_PS_LCLK (FW_PS_DPS)
66#define FW_PS_RF_OFF BIT(1)
67#define FW_PS_ALL_ON BIT(2)
68#define FW_PS_ST_ACTIVE BIT(3)
69#define FW_PS_ISR_ENABLE BIT(4)
70#define FW_PS_IMR_ENABLE BIT(5)
71
72
73#define FW_PS_ACK BIT(6)
74#define FW_PS_TOGGLE BIT(7)
75
76 /* 88E RPWM value*/
77 /* BIT[0] = 1: 32k, 0: 40M*/
78#define FW_PS_CLOCK_OFF BIT(0) /* 32k*/
79#define FW_PS_CLOCK_ON 0 /*40M*/
80
81#define FW_PS_STATE_MASK (0x0F)
82#define FW_PS_STATE_HW_MASK (0x07)
83/*ISR_ENABLE, IMR_ENABLE, and PS mode should be inherited.*/
84#define FW_PS_STATE_INT_MASK (0x3F)
85
86#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x))
87#define FW_PS_STATE_HW(x) (FW_PS_STATE_HW_MASK & (x))
88#define FW_PS_STATE_INT(x) (FW_PS_STATE_INT_MASK & (x))
89#define FW_PS_ISR_VAL(x) ((x) & 0x70)
90#define FW_PS_IMR_MASK(x) ((x) & 0xDF)
91#define FW_PS_KEEP_IMR(x) ((x) & 0x20)
92
93
94#define FW_PS_STATE_S0 (FW_PS_DPS)
95#define FW_PS_STATE_S1 (FW_PS_LCLK)
96#define FW_PS_STATE_S2 (FW_PS_RF_OFF)
97#define FW_PS_STATE_S3 (FW_PS_ALL_ON)
98#define FW_PS_STATE_S4 ((FW_PS_ST_ACTIVE) | (FW_PS_ALL_ON))
99
100/* ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))*/
101#define FW_PS_STATE_ALL_ON_88E (FW_PS_CLOCK_ON)
102/* (FW_PS_RF_ON)*/
103#define FW_PS_STATE_RF_ON_88E (FW_PS_CLOCK_ON)
104/* 0x0*/
105#define FW_PS_STATE_RF_OFF_88E (FW_PS_CLOCK_ON)
106/* (FW_PS_STATE_RF_OFF)*/
107#define FW_PS_STATE_RF_OFF_LOW_PWR_88E (FW_PS_CLOCK_OFF)
108
109#define FW_PS_STATE_ALL_ON_92C (FW_PS_STATE_S4)
110#define FW_PS_STATE_RF_ON_92C (FW_PS_STATE_S3)
111#define FW_PS_STATE_RF_OFF_92C (FW_PS_STATE_S2)
112#define FW_PS_STATE_RF_OFF_LOW_PWR_92C (FW_PS_STATE_S1)
113
114
115/* For 88E H2C PwrMode Cmd ID 5.*/
116#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
117#define FW_PWR_STATE_RF_OFF 0
118
119#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK)
120#define FW_PS_IS_CLK_ON(x) ((x) & (FW_PS_RF_OFF | FW_PS_ALL_ON))
121#define FW_PS_IS_RF_ON(x) ((x) & (FW_PS_ALL_ON))
122#define FW_PS_IS_ACTIVE(x) ((x) & (FW_PS_ST_ACTIVE))
123#define FW_PS_IS_CPWM_INT(x) ((x) & 0x40)
124
125#define FW_CLR_PS_STATE(x) ((x) = ((x) & (0xF0)))
126
127#define IS_IN_LOW_POWER_STATE_88E(fwpsstate) \
128 (FW_PS_STATE(fwpsstate) == FW_PS_CLOCK_OFF)
129
130#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE))
131#define FW_PWR_STATE_RF_OFF 0
132
133#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0))
134
135#define SET_88E_H2CCMD_WOWLAN_FUNC_ENABLE(__ph2ccmd, __val) \
136 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val)
137#define SET_88E_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__ph2ccmd, __val) \
138 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val)
139#define SET_88E_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__ph2ccmd, __val) \
140 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 2, 1, __val)
141#define SET_88E_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__ph2ccmd, __val) \
142 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 3, 1, __val)
143#define SET_88E_H2CCMD_WOWLAN_ALL_PKT_DROP(__ph2ccmd, __val) \
144 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 4, 1, __val)
145#define SET_88E_H2CCMD_WOWLAN_GPIO_ACTIVE(__ph2ccmd, __val) \
146 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 5, 1, __val)
147#define SET_88E_H2CCMD_WOWLAN_REKEY_WAKE_UP(__ph2ccmd, __val) \
148 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 6, 1, __val)
149#define SET_88E_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__ph2ccmd, __val) \
150 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 7, 1, __val)
151#define SET_88E_H2CCMD_WOWLAN_GPIONUM(__ph2ccmd, __val) \
152 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
153#define SET_88E_H2CCMD_WOWLAN_GPIO_DURATION(__ph2ccmd, __val) \
154 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
155
156
157#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
158 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
159#define SET_H2CCMD_PWRMODE_PARM_RLBM(__ph2ccmd, __val) \
160 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 4, __val)
161#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
162 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 4, 4, __val)
163#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__ph2ccmd, __val) \
164 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
165#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__ph2ccmd, __val) \
166 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val)
167#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__ph2ccmd, __val) \
168 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+4, 0, 8, __val)
169#define GET_88E_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd) \
170 LE_BITS_TO_1BYTE(__ph2ccmd, 0, 8)
171
172#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
173 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
174#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
175 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
176#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
177 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
178#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
179 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
180
181/* AP_OFFLOAD */
182#define SET_H2CCMD_AP_OFFLOAD_ON(__ph2ccmd, __val) \
183 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
184#define SET_H2CCMD_AP_OFFLOAD_HIDDEN(__ph2ccmd, __val) \
185 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
186#define SET_H2CCMD_AP_OFFLOAD_DENYANY(__ph2ccmd, __val) \
187 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
188#define SET_H2CCMD_AP_OFFLOAD_WAKEUP_EVT_RPT(__ph2ccmd, __val) \
189 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val)
190
191/* Keep Alive Control*/
192#define SET_88E_H2CCMD_KEEP_ALIVE_ENABLE(__ph2ccmd, __val) \
193 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val)
194#define SET_88E_H2CCMD_KEEP_ALIVE_ACCPEPT_USER_DEFINED(__ph2ccmd, __val)\
195 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val)
196#define SET_88E_H2CCMD_KEEP_ALIVE_PERIOD(__ph2ccmd, __val) \
197 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
198
199/*REMOTE_WAKE_CTRL */
200#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_EN(__ph2ccmd, __val) \
201 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val)
202#if (USE_OLD_WOWLAN_DEBUG_FW == 0)
203#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__ph2ccmd, __val)\
204 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val)
205#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__ph2ccmd, __val)\
206 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 2, 1, __val)
207#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__ph2ccmd, __val)\
208 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 3, 1, __val)
209#else
210#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_PAIRWISE_ENC_ALG(__ph2ccmd, __val)\
211 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
212#define SET_88E_H2CCMD_REMOTE_WAKE_CTRL_GROUP_ENC_ALG(__ph2ccmd, __val) \
213 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
214#endif
215
216/* GTK_OFFLOAD */
217#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__ph2ccmd, __val)\
218 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
219#define SET_88E_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__ph2ccmd, __val) \
220 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
221
222/* AOAC_RSVDPAGE_LOC */
223#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_REM_WAKE_CTRL_INFO(__ph2ccmd, __val)\
224 SET_BITS_TO_LE_1BYTE((__ph2ccmd), 0, 8, __val)
225#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__ph2ccmd, __val) \
226 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
227#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__ph2ccmd, __val) \
228 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
229#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__ph2ccmd, __val) \
230 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+3, 0, 8, __val)
231#define SET_88E_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__ph2ccmd, __val) \
232 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+4, 0, 8, __val)
233
234void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
235void rtl8723be_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
236 u8 ap_offload_enable);
237void rtl8723be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
238 u32 cmd_len, u8 *p_cmdbuffer);
239void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw);
240void rtl8723be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
241 bool dl_finished);
242void rtl8723be_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
243int rtl8723be_download_fw(struct ieee80211_hw *hw,
244 bool buse_wake_on_wlan_fw);
245void rtl8723be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw,
246 u8 p2p_ps_state);
247
248#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
new file mode 100644
index 000000000000..a500d266fae5
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
@@ -0,0 +1,2529 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../efuse.h"
28#include "../base.h"
29#include "../regd.h"
30#include "../cam.h"
31#include "../ps.h"
32#include "../pci.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "dm.h"
37#include "../rtl8723com/dm_common.h"
38#include "fw.h"
39#include "../rtl8723com/fw_common.h"
40#include "led.h"
41#include "hw.h"
42#include "pwrseqcmd.h"
43#include "pwrseq.h"
44#include "../btcoexist/rtl_btc.h"
45
46#define LLT_CONFIG 5
47
48static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
49{
50 struct rtl_priv *rtlpriv = rtl_priv(hw);
51 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
52 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
53
54 while (skb_queue_len(&ring->queue)) {
55 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
56 struct sk_buff *skb = __skb_dequeue(&ring->queue);
57
58 pci_unmap_single(rtlpci->pdev,
59 rtlpriv->cfg->ops->get_desc(
60 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
61 skb->len, PCI_DMA_TODEVICE);
62 kfree_skb(skb);
63 ring->idx = (ring->idx + 1) % ring->entries;
64 }
65}
66
67static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
68 u8 set_bits, u8 clear_bits)
69{
70 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
71 struct rtl_priv *rtlpriv = rtl_priv(hw);
72
73 rtlpci->reg_bcn_ctrl_val |= set_bits;
74 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
75
76 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
77}
78
79static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
80{
81 struct rtl_priv *rtlpriv = rtl_priv(hw);
82 u8 tmp1byte;
83
84 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
85 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
86 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
87 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
88 tmp1byte &= ~(BIT(0));
89 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
90}
91
92static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
93{
94 struct rtl_priv *rtlpriv = rtl_priv(hw);
95 u8 tmp1byte;
96
97 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
98 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
99 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
100 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
101 tmp1byte |= BIT(1);
102 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
103}
104
105static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
106{
107 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
108}
109
110static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
111{
112 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
113}
114
115static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
116 bool need_turn_off_ckk)
117{
118 struct rtl_priv *rtlpriv = rtl_priv(hw);
119 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
120 bool support_remote_wake_up;
121 u32 count = 0, isr_regaddr, content;
122 bool schedule_timer = need_turn_off_ckk;
123 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
124 (u8 *)(&support_remote_wake_up));
125
126 if (!rtlhal->fw_ready)
127 return;
128 if (!rtlpriv->psc.fw_current_inpsmode)
129 return;
130
131 while (1) {
132 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
133 if (rtlhal->fw_clk_change_in_progress) {
134 while (rtlhal->fw_clk_change_in_progress) {
135 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
136 count++;
137 udelay(100);
138 if (count > 1000)
139 return;
140 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
141 }
142 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
143 } else {
144 rtlhal->fw_clk_change_in_progress = false;
145 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
146 break;
147 }
148 }
149 if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
150 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
151 (u8 *)(&rpwm_val));
152 if (FW_PS_IS_ACK(rpwm_val)) {
153 isr_regaddr = REG_HISR;
154 content = rtl_read_dword(rtlpriv, isr_regaddr);
155 while (!(content & IMR_CPWM) && (count < 500)) {
156 udelay(50);
157 count++;
158 content = rtl_read_dword(rtlpriv, isr_regaddr);
159 }
160
161 if (content & IMR_CPWM) {
162 rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
163 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_88E;
164 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
165 "Receive CPWM INT!!! Set "
166 "pHalData->FwPSState = %X\n",
167 rtlhal->fw_ps_state);
168 }
169 }
170 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
171 rtlhal->fw_clk_change_in_progress = false;
172 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
173 if (schedule_timer) {
174 mod_timer(&rtlpriv->works.fw_clockoff_timer,
175 jiffies + MSECS(10));
176 }
177 } else {
178 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
179 rtlhal->fw_clk_change_in_progress = false;
180 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
181 }
182}
183
184static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
185{
186 struct rtl_priv *rtlpriv = rtl_priv(hw);
187 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
188 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
189 struct rtl8192_tx_ring *ring;
190 enum rf_pwrstate rtstate;
191 bool schedule_timer = false;
192 u8 queue;
193
194 if (!rtlhal->fw_ready)
195 return;
196 if (!rtlpriv->psc.fw_current_inpsmode)
197 return;
198 if (!rtlhal->allow_sw_to_change_hwclc)
199 return;
200 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
201 if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
202 return;
203
204 for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
205 ring = &rtlpci->tx_ring[queue];
206 if (skb_queue_len(&ring->queue)) {
207 schedule_timer = true;
208 break;
209 }
210 }
211 if (schedule_timer) {
212 mod_timer(&rtlpriv->works.fw_clockoff_timer,
213 jiffies + MSECS(10));
214 return;
215 }
216 if (FW_PS_STATE(rtlhal->fw_ps_state) !=
217 FW_PS_STATE_RF_OFF_LOW_PWR_88E) {
218 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
219 if (!rtlhal->fw_clk_change_in_progress) {
220 rtlhal->fw_clk_change_in_progress = true;
221 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
222 rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
223 rtl_write_word(rtlpriv, REG_HISR, 0x0100);
224 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
225 (u8 *)(&rpwm_val));
226 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
227 rtlhal->fw_clk_change_in_progress = false;
228 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
229 } else {
230 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
231 mod_timer(&rtlpriv->works.fw_clockoff_timer,
232 jiffies + MSECS(10));
233 }
234 }
235}
236
237static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
238{
239 u8 rpwm_val = 0;
240 rpwm_val |= (FW_PS_STATE_RF_OFF_88E | FW_PS_ACK);
241 _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
242}
243
244static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
245{
246 struct rtl_priv *rtlpriv = rtl_priv(hw);
247 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
248 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
249 bool fw_current_inps = false;
250 u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
251
252 if (ppsc->low_power_enable) {
253 rpwm_val = (FW_PS_STATE_ALL_ON_88E | FW_PS_ACK);/* RF on */
254 _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
255 rtlhal->allow_sw_to_change_hwclc = false;
256 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
257 (u8 *)(&fw_pwrmode));
258 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
259 (u8 *)(&fw_current_inps));
260 } else {
261 rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
262 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
263 (u8 *)(&rpwm_val));
264 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
265 (u8 *)(&fw_pwrmode));
266 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
267 (u8 *)(&fw_current_inps));
268 }
269}
270
271static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
272{
273 struct rtl_priv *rtlpriv = rtl_priv(hw);
274 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
275 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
276 bool fw_current_inps = true;
277 u8 rpwm_val;
278
279 if (ppsc->low_power_enable) {
280 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_88E; /* RF off */
281 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
282 (u8 *)(&fw_current_inps));
283 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
284 (u8 *)(&ppsc->fwctrl_psmode));
285 rtlhal->allow_sw_to_change_hwclc = true;
286 _rtl8723be_set_fw_clock_off(hw, rpwm_val);
287
288 } else {
289 rpwm_val = FW_PS_STATE_RF_OFF_88E; /* RF off */
290 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
291 (u8 *)(&fw_current_inps));
292 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
293 (u8 *)(&ppsc->fwctrl_psmode));
294 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
295 (u8 *)(&rpwm_val));
296 }
297}
298
299void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
300{
301 struct rtl_priv *rtlpriv = rtl_priv(hw);
302 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
303 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
304
305 switch (variable) {
306 case HW_VAR_RCR:
307 *((u32 *)(val)) = rtlpci->receive_config;
308 break;
309 case HW_VAR_RF_STATE:
310 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
311 break;
312 case HW_VAR_FWLPS_RF_ON: {
313 enum rf_pwrstate rfstate;
314 u32 val_rcr;
315
316 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
317 (u8 *)(&rfstate));
318 if (rfstate == ERFOFF) {
319 *((bool *)(val)) = true;
320 } else {
321 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
322 val_rcr &= 0x00070000;
323 if (val_rcr)
324 *((bool *)(val)) = false;
325 else
326 *((bool *)(val)) = true;
327 }
328 break; }
329 case HW_VAR_FW_PSMODE_STATUS:
330 *((bool *)(val)) = ppsc->fw_current_inpsmode;
331 break;
332 case HW_VAR_CORRECT_TSF: {
333 u64 tsf;
334 u32 *ptsf_low = (u32 *)&tsf;
335 u32 *ptsf_high = ((u32 *)&tsf) + 1;
336
337 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
338 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
339
340 *((u64 *)(val)) = tsf;
341
342 break; }
343 default:
344 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
345 "switch case not process %x\n", variable);
346 break;
347 }
348}
349
350void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
351{
352 struct rtl_priv *rtlpriv = rtl_priv(hw);
353 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
354 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
355 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
356 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
357 u8 idx;
358
359 switch (variable) {
360 case HW_VAR_ETHER_ADDR:
361 for (idx = 0; idx < ETH_ALEN; idx++)
362 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
363 break;
364 case HW_VAR_BASIC_RATE: {
365 u16 rate_cfg = ((u16 *)val)[0];
366 u8 rate_index = 0;
367 rate_cfg = rate_cfg & 0x15f;
368 rate_cfg |= 0x01;
369 rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
370 rtl_write_byte(rtlpriv, REG_RRSR + 1, (rate_cfg >> 8) & 0xff);
371 while (rate_cfg > 0x1) {
372 rate_cfg = (rate_cfg >> 1);
373 rate_index++;
374 }
375 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
376 break; }
377 case HW_VAR_BSSID:
378 for (idx = 0; idx < ETH_ALEN; idx++)
379 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
380 break;
381 case HW_VAR_SIFS:
382 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
383 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
384
385 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
386 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
387
388 if (!mac->ht_enable)
389 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
390 else
391 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
392 *((u16 *)val));
393 break;
394 case HW_VAR_SLOT_TIME: {
395 u8 e_aci;
396
397 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
398 "HW_VAR_SLOT_TIME %x\n", val[0]);
399
400 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
401
402 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
403 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
404 (u8 *)(&e_aci));
405 }
406 break; }
407 case HW_VAR_ACK_PREAMBLE: {
408 u8 reg_tmp;
409 u8 short_preamble = (bool) (*(u8 *)val);
410 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
411 if (short_preamble) {
412 reg_tmp |= 0x02;
413 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
414 } else {
415 reg_tmp &= 0xFD;
416 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
417 }
418 break; }
419 case HW_VAR_WPA_CONFIG:
420 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
421 break;
422 case HW_VAR_AMPDU_MIN_SPACE: {
423 u8 min_spacing_to_set;
424 u8 sec_min_space;
425
426 min_spacing_to_set = *((u8 *)val);
427 if (min_spacing_to_set <= 7) {
428 sec_min_space = 0;
429
430 if (min_spacing_to_set < sec_min_space)
431 min_spacing_to_set = sec_min_space;
432
433 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
434 min_spacing_to_set);
435
436 *val = min_spacing_to_set;
437
438 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
439 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
440 mac->min_space_cfg);
441
442 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
443 mac->min_space_cfg);
444 }
445 break; }
446 case HW_VAR_SHORTGI_DENSITY: {
447 u8 density_to_set;
448
449 density_to_set = *((u8 *)val);
450 mac->min_space_cfg |= (density_to_set << 3);
451
452 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
453 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
454 mac->min_space_cfg);
455
456 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
457 mac->min_space_cfg);
458 break; }
459 case HW_VAR_AMPDU_FACTOR: {
460 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
461 u8 factor_toset;
462 u8 *p_regtoset = NULL;
463 u8 index = 0;
464
465 p_regtoset = regtoset_normal;
466
467 factor_toset = *((u8 *)val);
468 if (factor_toset <= 3) {
469 factor_toset = (1 << (factor_toset + 2));
470 if (factor_toset > 0xf)
471 factor_toset = 0xf;
472
473 for (index = 0; index < 4; index++) {
474 if ((p_regtoset[index] & 0xf0) >
475 (factor_toset << 4))
476 p_regtoset[index] =
477 (p_regtoset[index] & 0x0f) |
478 (factor_toset << 4);
479
480 if ((p_regtoset[index] & 0x0f) > factor_toset)
481 p_regtoset[index] =
482 (p_regtoset[index] & 0xf0) |
483 (factor_toset);
484
485 rtl_write_byte(rtlpriv,
486 (REG_AGGLEN_LMT + index),
487 p_regtoset[index]);
488 }
489 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
490 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
491 factor_toset);
492 }
493 break; }
494 case HW_VAR_AC_PARAM: {
495 u8 e_aci = *((u8 *)val);
496 rtl8723_dm_init_edca_turbo(hw);
497
498 if (rtlpci->acm_method != EACMWAY2_SW)
499 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
500 (u8 *)(&e_aci));
501 break; }
502 case HW_VAR_ACM_CTRL: {
503 u8 e_aci = *((u8 *)val);
504 union aci_aifsn *p_aci_aifsn =
505 (union aci_aifsn *)(&(mac->ac[0].aifs));
506 u8 acm = p_aci_aifsn->f.acm;
507 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
508
509 acm_ctrl =
510 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
511
512 if (acm) {
513 switch (e_aci) {
514 case AC0_BE:
515 acm_ctrl |= ACMHW_BEQEN;
516 break;
517 case AC2_VI:
518 acm_ctrl |= ACMHW_VIQEN;
519 break;
520 case AC3_VO:
521 acm_ctrl |= ACMHW_VOQEN;
522 break;
523 default:
524 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
525 "HW_VAR_ACM_CTRL acm set "
526 "failed: eACI is %d\n", acm);
527 break;
528 }
529 } else {
530 switch (e_aci) {
531 case AC0_BE:
532 acm_ctrl &= (~ACMHW_BEQEN);
533 break;
534 case AC2_VI:
535 acm_ctrl &= (~ACMHW_VIQEN);
536 break;
537 case AC3_VO:
538 acm_ctrl &= (~ACMHW_BEQEN);
539 break;
540 default:
541 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
542 "switch case not process\n");
543 break;
544 }
545 }
546 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
547 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
548 "Write 0x%X\n", acm_ctrl);
549 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
550 break; }
551 case HW_VAR_RCR:
552 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
553 rtlpci->receive_config = ((u32 *)(val))[0];
554 break;
555 case HW_VAR_RETRY_LIMIT: {
556 u8 retry_limit = ((u8 *)(val))[0];
557
558 rtl_write_word(rtlpriv, REG_RL,
559 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
560 retry_limit << RETRY_LIMIT_LONG_SHIFT);
561 break; }
562 case HW_VAR_DUAL_TSF_RST:
563 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
564 break;
565 case HW_VAR_EFUSE_BYTES:
566 rtlefuse->efuse_usedbytes = *((u16 *)val);
567 break;
568 case HW_VAR_EFUSE_USAGE:
569 rtlefuse->efuse_usedpercentage = *((u8 *)val);
570 break;
571 case HW_VAR_IO_CMD:
572 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
573 break;
574 case HW_VAR_SET_RPWM: {
575 u8 rpwm_val;
576
577 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
578 udelay(1);
579
580 if (rpwm_val & BIT(7)) {
581 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
582 } else {
583 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
584 ((*(u8 *)val) | BIT(7)));
585 }
586 break; }
587 case HW_VAR_H2C_FW_PWRMODE:
588 rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
589 break;
590 case HW_VAR_FW_PSMODE_STATUS:
591 ppsc->fw_current_inpsmode = *((bool *)val);
592 break;
593 case HW_VAR_RESUME_CLK_ON:
594 _rtl8723be_set_fw_ps_rf_on(hw);
595 break;
596 case HW_VAR_FW_LPS_ACTION: {
597 bool enter_fwlps = *((bool *)val);
598
599 if (enter_fwlps)
600 _rtl8723be_fwlps_enter(hw);
601 else
602 _rtl8723be_fwlps_leave(hw);
603
604 break; }
605 case HW_VAR_H2C_FW_JOINBSSRPT: {
606 u8 mstatus = (*(u8 *)val);
607 u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
608 u8 count = 0, dlbcn_count = 0;
609 bool recover = false;
610
611 if (mstatus == RT_MEDIA_CONNECT) {
612 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
613
614 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
615 rtl_write_byte(rtlpriv, REG_CR + 1,
616 (tmp_regcr | BIT(0)));
617
618 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
619 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
620
621 tmp_reg422 = rtl_read_byte(rtlpriv,
622 REG_FWHW_TXQ_CTRL + 2);
623 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
624 tmp_reg422 & (~BIT(6)));
625 if (tmp_reg422 & BIT(6))
626 recover = true;
627
628 do {
629 bcnvalid_reg = rtl_read_byte(rtlpriv,
630 REG_TDECTRL + 2);
631 rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
632 (bcnvalid_reg | BIT(0)));
633 _rtl8723be_return_beacon_queue_skb(hw);
634
635 rtl8723be_set_fw_rsvdpagepkt(hw, 0);
636 bcnvalid_reg = rtl_read_byte(rtlpriv,
637 REG_TDECTRL + 2);
638 count = 0;
639 while (!(bcnvalid_reg & BIT(0)) && count < 20) {
640 count++;
641 udelay(10);
642 bcnvalid_reg = rtl_read_byte(rtlpriv,
643 REG_TDECTRL + 2);
644 }
645 dlbcn_count++;
646 } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
647
648 if (bcnvalid_reg & BIT(0))
649 rtl_write_byte(rtlpriv, REG_TDECTRL+2, BIT(0));
650
651 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
652 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
653
654 if (recover) {
655 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
656 tmp_reg422);
657 }
658 rtl_write_byte(rtlpriv, REG_CR + 1,
659 (tmp_regcr & ~(BIT(0))));
660 }
661 rtl8723be_set_fw_joinbss_report_cmd(hw, (*(u8 *)val));
662 break; }
663 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
664 rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
665 break;
666 case HW_VAR_AID: {
667 u16 u2btmp;
668 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
669 u2btmp &= 0xC000;
670 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
671 (u2btmp | mac->assoc_id));
672 break; }
673 case HW_VAR_CORRECT_TSF: {
674 u8 btype_ibss = ((u8 *)(val))[0];
675
676 if (btype_ibss)
677 _rtl8723be_stop_tx_beacon(hw);
678
679 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
680
681 rtl_write_dword(rtlpriv, REG_TSFTR,
682 (u32) (mac->tsf & 0xffffffff));
683 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
684 (u32) ((mac->tsf >> 32) & 0xffffffff));
685
686 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
687
688 if (btype_ibss)
689 _rtl8723be_resume_tx_beacon(hw);
690 break; }
691 case HW_VAR_KEEP_ALIVE: {
692 u8 array[2];
693 array[0] = 0xff;
694 array[1] = *((u8 *)val);
695 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL,
696 2, array);
697 break; }
698 default:
699 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
700 "switch case not process %x\n",
701 variable);
702 break;
703 }
704}
705
706static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
707{
708 struct rtl_priv *rtlpriv = rtl_priv(hw);
709 bool status = true;
710 int count = 0;
711 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
712 _LLT_OP(_LLT_WRITE_ACCESS);
713
714 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
715
716 do {
717 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
718 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
719 break;
720
721 if (count > POLLING_LLT_THRESHOLD) {
722 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
723 "Failed to polling write LLT done at "
724 "address %d!\n", address);
725 status = false;
726 break;
727 }
728 } while (++count);
729
730 return status;
731}
732
733static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
734{
735 struct rtl_priv *rtlpriv = rtl_priv(hw);
736 unsigned short i;
737 u8 txpktbuf_bndy;
738 u8 maxpage;
739 bool status;
740
741 maxpage = 255;
742 txpktbuf_bndy = 245;
743
744 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
745 (0x27FF0000 | txpktbuf_bndy));
746 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
747
748 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
749 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
750
751 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
752 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
753 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
754
755 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
756 status = _rtl8723be_llt_write(hw, i, i + 1);
757 if (!status)
758 return status;
759 }
760 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
761
762 if (!status)
763 return status;
764
765 for (i = txpktbuf_bndy; i < maxpage; i++) {
766 status = _rtl8723be_llt_write(hw, i, (i + 1));
767 if (!status)
768 return status;
769 }
770 status = _rtl8723be_llt_write(hw, maxpage, txpktbuf_bndy);
771 if (!status)
772 return status;
773
774 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
775 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
776
777 return true;
778}
779
780static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
781{
782 struct rtl_priv *rtlpriv = rtl_priv(hw);
783 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
784 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
785 struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0);
786
787 if (rtlpriv->rtlhal.up_first_time)
788 return;
789
790 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
791 rtl8723be_sw_led_on(hw, pled0);
792 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
793 rtl8723be_sw_led_on(hw, pled0);
794 else
795 rtl8723be_sw_led_off(hw, pled0);
796}
797
798static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
799{
800 struct rtl_priv *rtlpriv = rtl_priv(hw);
801 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
802
803 unsigned char bytetmp;
804 unsigned short wordtmp;
805 u16 retry = 0;
806 bool mac_func_enable;
807
808 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
809
810 /*Auto Power Down to CHIP-off State*/
811 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
812 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
813
814 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
815 if (bytetmp == 0xFF)
816 mac_func_enable = true;
817 else
818 mac_func_enable = false;
819
820 /* HW Power on sequence */
821 if (!rtlbe_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
822 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
823 RTL8723_NIC_ENABLE_FLOW)) {
824 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
825 "init MAC Fail as power on failure\n");
826 return false;
827 }
828 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
829 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
830
831 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
832 bytetmp = 0xff;
833 rtl_write_byte(rtlpriv, REG_CR, bytetmp);
834 mdelay(2);
835
836 bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
837 bytetmp |= 0x7f;
838 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
839 mdelay(2);
840
841 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
842 if (bytetmp & BIT(0)) {
843 bytetmp = rtl_read_byte(rtlpriv, 0x7c);
844 bytetmp |= BIT(6);
845 rtl_write_byte(rtlpriv, 0x7c, bytetmp);
846 }
847 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
848 bytetmp |= BIT(3);
849 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp);
850 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
851 bytetmp &= ~BIT(4);
852 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp);
853
854 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+3);
855 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+3, bytetmp | 0x77);
856
857 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
858
859 if (!mac_func_enable) {
860 if (!_rtl8723be_llt_table_init(hw))
861 return false;
862 }
863 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
864 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
865
866 /* Enable FW Beamformer Interrupt */
867 bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
868 rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
869
870 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
871 wordtmp &= 0xf;
872 wordtmp |= 0xF5B1;
873 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
874
875 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
876 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
877 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
878 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
879
880 rtl_write_byte(rtlpriv, 0x4d0, 0x0);
881
882 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
883 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
884 DMA_BIT_MASK(32));
885 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
886 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
887 DMA_BIT_MASK(32));
888 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
889 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
890 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
891 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
892 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
893 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
894 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
895 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
896 rtl_write_dword(rtlpriv, REG_HQ_DESA,
897 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
898 DMA_BIT_MASK(32));
899 rtl_write_dword(rtlpriv, REG_RX_DESA,
900 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
901 DMA_BIT_MASK(32));
902
903 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
904 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
905
906 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
907
908 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
909 rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6));
910
911 rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
912
913 do {
914 retry++;
915 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
916 } while ((retry < 200) && (bytetmp & BIT(7)));
917
918 _rtl8723be_gen_refresh_led_state(hw);
919
920 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
921
922 bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
923 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & ~BIT(2));
924
925 return true;
926}
927
928static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
929{
930 struct rtl_priv *rtlpriv = rtl_priv(hw);
931 u8 reg_bw_opmode;
932 u32 reg_ratr, reg_prsr;
933
934 reg_bw_opmode = BW_OPMODE_20MHZ;
935 reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
936 RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
937 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
938
939 rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
940 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
941}
942
943static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
944{
945 struct rtl_priv *rtlpriv = rtl_priv(hw);
946 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
947
948 rtl_write_byte(rtlpriv, 0x34b, 0x93);
949 rtl_write_word(rtlpriv, 0x350, 0x870c);
950 rtl_write_byte(rtlpriv, 0x352, 0x1);
951
952 if (ppsc->support_backdoor)
953 rtl_write_byte(rtlpriv, 0x349, 0x1b);
954 else
955 rtl_write_byte(rtlpriv, 0x349, 0x03);
956
957 rtl_write_word(rtlpriv, 0x350, 0x2718);
958 rtl_write_byte(rtlpriv, 0x352, 0x1);
959}
960
961void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
962{
963 struct rtl_priv *rtlpriv = rtl_priv(hw);
964 u8 sec_reg_value;
965
966 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
967 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
968 rtlpriv->sec.pairwise_enc_algorithm,
969 rtlpriv->sec.group_enc_algorithm);
970
971 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
972 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
973 "not open hw encryption\n");
974 return;
975 }
976 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
977
978 if (rtlpriv->sec.use_defaultkey) {
979 sec_reg_value |= SCR_TXUSEDK;
980 sec_reg_value |= SCR_RXUSEDK;
981 }
982 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
983
984 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
985
986 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "The SECR-value %x\n",
987 sec_reg_value);
988
989 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
990}
991
992int rtl8723be_hw_init(struct ieee80211_hw *hw)
993{
994 struct rtl_priv *rtlpriv = rtl_priv(hw);
995 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
996 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
997 struct rtl_phy *rtlphy = &(rtlpriv->phy);
998 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
999 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1000 bool rtstatus = true;
1001 int err;
1002 u8 tmp_u1b;
1003 unsigned long flags;
1004
1005 /* reenable interrupts to not interfere with other devices */
1006 local_save_flags(flags);
1007 local_irq_enable();
1008
1009 rtlpriv->rtlhal.being_init_adapter = true;
1010 rtlpriv->intf_ops->disable_aspm(hw);
1011 rtstatus = _rtl8723be_init_mac(hw);
1012 if (!rtstatus) {
1013 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
1014 err = 1;
1015 goto exit;
1016 }
1017 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
1018 tmp_u1b &= 0x7F;
1019 rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b);
1020
1021 err = rtl8723_download_fw(hw, true);
1022 if (err) {
1023 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1024 "Failed to download FW. Init HW without FW now..\n");
1025 err = 1;
1026 rtlhal->fw_ready = false;
1027 goto exit;
1028 } else {
1029 rtlhal->fw_ready = true;
1030 }
1031 rtlhal->last_hmeboxnum = 0;
1032 rtl8723be_phy_mac_config(hw);
1033 /* because last function modify RCR, so we update
1034 * rcr var here, or TP will unstable for receive_config
1035 * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
1036 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1037 */
1038 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1039 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1040 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1041
1042 rtl8723be_phy_bb_config(hw);
1043 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
1044 rtl8723be_phy_rf_config(hw);
1045
1046 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1047 RF_CHNLBW, RFREG_OFFSET_MASK);
1048 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1049 RF_CHNLBW, RFREG_OFFSET_MASK);
1050 rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1051 rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1052
1053 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
1054 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
1055 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
1056 _rtl8723be_hw_configure(hw);
1057 rtl_cam_reset_all_entry(hw);
1058 rtl8723be_enable_hw_security_config(hw);
1059
1060 ppsc->rfpwr_state = ERFON;
1061
1062 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1063 _rtl8723be_enable_aspm_back_door(hw);
1064 rtlpriv->intf_ops->enable_aspm(hw);
1065
1066 rtl8723be_bt_hw_init(hw);
1067
1068 rtl_set_bbreg(hw, 0x64, BIT(20), 0);
1069 rtl_set_bbreg(hw, 0x64, BIT(24), 0);
1070
1071 rtl_set_bbreg(hw, 0x40, BIT(4), 0);
1072 rtl_set_bbreg(hw, 0x40, BIT(3), 1);
1073
1074 rtl_set_bbreg(hw, 0x944, BIT(0)|BIT(1), 0x3);
1075 rtl_set_bbreg(hw, 0x930, 0xff, 0x77);
1076
1077 rtl_set_bbreg(hw, 0x38, BIT(11), 0x1);
1078
1079 rtl_set_bbreg(hw, 0xb2c, 0xffffffff, 0x80000000);
1080
1081 if (ppsc->rfpwr_state == ERFON) {
1082 rtl8723be_dm_check_txpower_tracking(hw);
1083 rtl8723be_phy_lc_calibrate(hw);
1084 }
1085 tmp_u1b = efuse_read_1byte(hw, 0x1FA);
1086 if (!(tmp_u1b & BIT(0))) {
1087 rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
1088 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n");
1089 }
1090 if (!(tmp_u1b & BIT(4))) {
1091 tmp_u1b = rtl_read_byte(rtlpriv, 0x16);
1092 tmp_u1b &= 0x0F;
1093 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
1094 udelay(10);
1095 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
1096 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
1097 }
1098 rtl8723be_dm_init(hw);
1099exit:
1100 local_irq_restore(flags);
1101 rtlpriv->rtlhal.being_init_adapter = false;
1102 return err;
1103}
1104
1105static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1106{
1107 struct rtl_priv *rtlpriv = rtl_priv(hw);
1108 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1109 enum version_8723e version = VERSION_UNKNOWN;
1110 u8 count = 0;
1111 u8 value8;
1112 u32 value32;
1113
1114 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0);
1115
1116 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 2);
1117 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 2, value8 | BIT(0));
1118
1119 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1120 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, value8 | BIT(0));
1121
1122 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1123 while (((value8 & BIT(0))) && (count++ < 100)) {
1124 udelay(10);
1125 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1126 }
1127 count = 0;
1128 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1129 while ((value8 == 0) && (count++ < 50)) {
1130 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1131 mdelay(1);
1132 }
1133 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1134 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
1135 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unkown chip version\n");
1136 else
1137 version = (enum version_8723e) VERSION_TEST_CHIP_1T1R_8723B;
1138
1139 rtlphy->rf_type = RF_1T1R;
1140
1141 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1142 if (value8 >= 0x02)
1143 version |= BIT(3);
1144 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1145 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
1146 "RF_2T2R" : "RF_1T1R");
1147
1148 return version;
1149}
1150
1151static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1152 enum nl80211_iftype type)
1153{
1154 struct rtl_priv *rtlpriv = rtl_priv(hw);
1155 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1156 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1157
1158 rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0);
1159 RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
1160 "clear 0x550 when set HW_VAR_MEDIA_STATUS\n");
1161
1162 if (type == NL80211_IFTYPE_UNSPECIFIED ||
1163 type == NL80211_IFTYPE_STATION) {
1164 _rtl8723be_stop_tx_beacon(hw);
1165 _rtl8723be_enable_bcn_sub_func(hw);
1166 } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) {
1167 _rtl8723be_resume_tx_beacon(hw);
1168 _rtl8723be_disable_bcn_sub_func(hw);
1169 } else {
1170 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1171 "Set HW_VAR_MEDIA_STATUS: "
1172 "No such media status(%x).\n", type);
1173 }
1174 switch (type) {
1175 case NL80211_IFTYPE_UNSPECIFIED:
1176 bt_msr |= MSR_NOLINK;
1177 ledaction = LED_CTL_LINK;
1178 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1179 "Set Network type to NO LINK!\n");
1180 break;
1181 case NL80211_IFTYPE_ADHOC:
1182 bt_msr |= MSR_ADHOC;
1183 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1184 "Set Network type to Ad Hoc!\n");
1185 break;
1186 case NL80211_IFTYPE_STATION:
1187 bt_msr |= MSR_INFRA;
1188 ledaction = LED_CTL_LINK;
1189 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1190 "Set Network type to STA!\n");
1191 break;
1192 case NL80211_IFTYPE_AP:
1193 bt_msr |= MSR_AP;
1194 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1195 "Set Network type to AP!\n");
1196 break;
1197 default:
1198 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1199 "Network type %d not support!\n", type);
1200 return 1;
1201 }
1202 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1203 rtlpriv->cfg->ops->led_control(hw, ledaction);
1204 if ((bt_msr & 0x03) == MSR_AP)
1205 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1206 else
1207 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1208 return 0;
1209}
1210
1211void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1212{
1213 struct rtl_priv *rtlpriv = rtl_priv(hw);
1214 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1215 u32 reg_rcr = rtlpci->receive_config;
1216
1217 if (rtlpriv->psc.rfpwr_state != ERFON)
1218 return;
1219
1220 if (check_bssid) {
1221 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1222 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1223 (u8 *)(&reg_rcr));
1224 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1225 } else if (!check_bssid) {
1226 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1227 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1228 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1229 (u8 *)(&reg_rcr));
1230 }
1231}
1232
1233int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1234 enum nl80211_iftype type)
1235{
1236 struct rtl_priv *rtlpriv = rtl_priv(hw);
1237
1238 if (_rtl8723be_set_media_status(hw, type))
1239 return -EOPNOTSUPP;
1240
1241 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1242 if (type != NL80211_IFTYPE_AP)
1243 rtl8723be_set_check_bssid(hw, true);
1244 } else {
1245 rtl8723be_set_check_bssid(hw, false);
1246 }
1247 return 0;
1248}
1249
1250/* don't set REG_EDCA_BE_PARAM here
1251 * because mac80211 will send pkt when scan
1252 */
1253void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1254{
1255 struct rtl_priv *rtlpriv = rtl_priv(hw);
1256 rtl8723_dm_init_edca_turbo(hw);
1257 switch (aci) {
1258 case AC1_BK:
1259 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1260 break;
1261 case AC0_BE:
1262 break;
1263 case AC2_VI:
1264 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1265 break;
1266 case AC3_VO:
1267 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1268 break;
1269 default:
1270 RT_ASSERT(false, "invalid aci: %d !\n", aci);
1271 break;
1272 }
1273}
1274
1275void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1276{
1277 struct rtl_priv *rtlpriv = rtl_priv(hw);
1278 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1279
1280 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1281 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1282 rtlpci->irq_enabled = true;
1283 /* there are some C2H CMDs have been sent
1284 * before system interrupt is enabled, e.g., C2H, CPWM.
1285 * So we need to clear all C2H events that FW has notified,
1286 * otherwise FW won't schedule any commands anymore.
1287 */
1288 rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0);
1289 /*enable system interrupt*/
1290 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1291}
1292
1293void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1294{
1295 struct rtl_priv *rtlpriv = rtl_priv(hw);
1296 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1297
1298 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1299 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1300 rtlpci->irq_enabled = false;
1301 synchronize_irq(rtlpci->pdev->irq);
1302}
1303
1304static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1305{
1306 struct rtl_priv *rtlpriv = rtl_priv(hw);
1307 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1308 u8 u1b_tmp;
1309
1310 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1311 /* 1. Run LPS WL RFOFF flow */
1312 rtlbe_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1313 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1314
1315 /* 2. 0x1F[7:0] = 0 */
1316 /* turn off RF */
1317 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1318 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1319 rtlhal->fw_ready)
1320 rtl8723be_firmware_selfreset(hw);
1321
1322 /* Reset MCU. Suggested by Filen. */
1323 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1324 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1325
1326 /* g. MCUFWDL 0x80[1:0]= 0 */
1327 /* reset MCU ready status */
1328 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1329
1330 /* HW card disable configuration. */
1331 rtlbe_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1332 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1333
1334 /* Reset MCU IO Wrapper */
1335 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1336 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
1337 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1338 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1339
1340 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1341 /* lock ISO/CLK/Power control register */
1342 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1343}
1344
1345void rtl8723be_card_disable(struct ieee80211_hw *hw)
1346{
1347 struct rtl_priv *rtlpriv = rtl_priv(hw);
1348 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1349 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1350 enum nl80211_iftype opmode;
1351
1352 mac->link_state = MAC80211_NOLINK;
1353 opmode = NL80211_IFTYPE_UNSPECIFIED;
1354 _rtl8723be_set_media_status(hw, opmode);
1355 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1356 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1357 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1358 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1359 _rtl8723be_poweroff_adapter(hw);
1360
1361 /* after power off we should do iqk again */
1362 rtlpriv->phy.iqk_initialized = false;
1363}
1364
1365void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1366 u32 *p_inta, u32 *p_intb)
1367{
1368 struct rtl_priv *rtlpriv = rtl_priv(hw);
1369 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1370
1371 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1372 rtl_write_dword(rtlpriv, ISR, *p_inta);
1373
1374 *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1375 rtlpci->irq_mask[1];
1376 rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1377}
1378
1379void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1380{
1381 struct rtl_priv *rtlpriv = rtl_priv(hw);
1382 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1383 u16 bcn_interval, atim_window;
1384
1385 bcn_interval = mac->beacon_interval;
1386 atim_window = 2; /*FIX MERGE */
1387 rtl8723be_disable_interrupt(hw);
1388 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1389 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1390 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1391 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1392 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1393 rtl_write_byte(rtlpriv, 0x606, 0x30);
1394 rtl8723be_enable_interrupt(hw);
1395}
1396
1397void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1398{
1399 struct rtl_priv *rtlpriv = rtl_priv(hw);
1400 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1401 u16 bcn_interval = mac->beacon_interval;
1402
1403 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1404 "beacon_interval:%d\n", bcn_interval);
1405 rtl8723be_disable_interrupt(hw);
1406 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1407 rtl8723be_enable_interrupt(hw);
1408}
1409
1410void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1411 u32 add_msr, u32 rm_msr)
1412{
1413 struct rtl_priv *rtlpriv = rtl_priv(hw);
1414 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1415
1416 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1417 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1418
1419 if (add_msr)
1420 rtlpci->irq_mask[0] |= add_msr;
1421 if (rm_msr)
1422 rtlpci->irq_mask[0] &= (~rm_msr);
1423 rtl8723be_disable_interrupt(hw);
1424 rtl8723be_enable_interrupt(hw);
1425}
1426
1427static u8 _rtl8723be_get_chnl_group(u8 chnl)
1428{
1429 u8 group;
1430
1431 if (chnl < 3)
1432 group = 0;
1433 else if (chnl < 9)
1434 group = 1;
1435 else
1436 group = 2;
1437 return group;
1438}
1439
1440static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1441 struct txpower_info_2g *pw2g,
1442 struct txpower_info_5g *pw5g,
1443 bool autoload_fail, u8 *hwinfo)
1444{
1445 struct rtl_priv *rtlpriv = rtl_priv(hw);
1446 u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1447
1448 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1449 "hal_ReadPowerValueFromPROM8723BE(): "
1450 "PROMContent[0x%x]= 0x%x\n",
1451 (addr + 1), hwinfo[addr + 1]);
1452 if (0xFF == hwinfo[addr + 1]) /*YJ, add, 120316*/
1453 autoload_fail = true;
1454
1455 if (autoload_fail) {
1456 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1457 "auto load fail : Use Default value!\n");
1458 for (path = 0; path < MAX_RF_PATH; path++) {
1459 /* 2.4G default value */
1460 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1461 pw2g->index_cck_base[path][group] = 0x2D;
1462 pw2g->index_bw40_base[path][group] = 0x2D;
1463 }
1464 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1465 if (cnt == 0) {
1466 pw2g->bw20_diff[path][0] = 0x02;
1467 pw2g->ofdm_diff[path][0] = 0x04;
1468 } else {
1469 pw2g->bw20_diff[path][cnt] = 0xFE;
1470 pw2g->bw40_diff[path][cnt] = 0xFE;
1471 pw2g->cck_diff[path][cnt] = 0xFE;
1472 pw2g->ofdm_diff[path][cnt] = 0xFE;
1473 }
1474 }
1475 }
1476 return;
1477 }
1478 for (path = 0; path < MAX_RF_PATH; path++) {
1479 /*2.4G default value*/
1480 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1481 pw2g->index_cck_base[path][group] = hwinfo[addr++];
1482 if (pw2g->index_cck_base[path][group] == 0xFF)
1483 pw2g->index_cck_base[path][group] = 0x2D;
1484 }
1485 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1486 pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1487 if (pw2g->index_bw40_base[path][group] == 0xFF)
1488 pw2g->index_bw40_base[path][group] = 0x2D;
1489 }
1490 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1491 if (cnt == 0) {
1492 pw2g->bw40_diff[path][cnt] = 0;
1493 if (hwinfo[addr] == 0xFF) {
1494 pw2g->bw20_diff[path][cnt] = 0x02;
1495 } else {
1496 pw2g->bw20_diff[path][cnt] =
1497 (hwinfo[addr] & 0xf0) >> 4;
1498 /*bit sign number to 8 bit sign number*/
1499 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1500 pw2g->bw20_diff[path][cnt] |= 0xF0;
1501 }
1502 if (hwinfo[addr] == 0xFF) {
1503 pw2g->ofdm_diff[path][cnt] = 0x04;
1504 } else {
1505 pw2g->ofdm_diff[path][cnt] =
1506 (hwinfo[addr] & 0x0f);
1507 /*bit sign number to 8 bit sign number*/
1508 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1509 pw2g->ofdm_diff[path][cnt] |=
1510 0xF0;
1511 }
1512 pw2g->cck_diff[path][cnt] = 0;
1513 addr++;
1514 } else {
1515 if (hwinfo[addr] == 0xFF) {
1516 pw2g->bw40_diff[path][cnt] = 0xFE;
1517 } else {
1518 pw2g->bw40_diff[path][cnt] =
1519 (hwinfo[addr] & 0xf0) >> 4;
1520 if (pw2g->bw40_diff[path][cnt] & BIT(3))
1521 pw2g->bw40_diff[path][cnt] |=
1522 0xF0;
1523 }
1524 if (hwinfo[addr] == 0xFF) {
1525 pw2g->bw20_diff[path][cnt] = 0xFE;
1526 } else {
1527 pw2g->bw20_diff[path][cnt] =
1528 (hwinfo[addr] & 0x0f);
1529 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1530 pw2g->bw20_diff[path][cnt] |=
1531 0xF0;
1532 }
1533 addr++;
1534
1535 if (hwinfo[addr] == 0xFF) {
1536 pw2g->ofdm_diff[path][cnt] = 0xFE;
1537 } else {
1538 pw2g->ofdm_diff[path][cnt] =
1539 (hwinfo[addr] & 0xf0) >> 4;
1540 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1541 pw2g->ofdm_diff[path][cnt] |=
1542 0xF0;
1543 }
1544 if (hwinfo[addr] == 0xFF) {
1545 pw2g->cck_diff[path][cnt] = 0xFE;
1546 } else {
1547 pw2g->cck_diff[path][cnt] =
1548 (hwinfo[addr] & 0x0f);
1549 if (pw2g->cck_diff[path][cnt] & BIT(3))
1550 pw2g->cck_diff[path][cnt] |=
1551 0xF0;
1552 }
1553 addr++;
1554 }
1555 }
1556 /*5G default value*/
1557 for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1558 pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1559 if (pw5g->index_bw40_base[path][group] == 0xFF)
1560 pw5g->index_bw40_base[path][group] = 0xFE;
1561 }
1562 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1563 if (cnt == 0) {
1564 pw5g->bw40_diff[path][cnt] = 0;
1565
1566 if (hwinfo[addr] == 0xFF) {
1567 pw5g->bw20_diff[path][cnt] = 0;
1568 } else {
1569 pw5g->bw20_diff[path][0] =
1570 (hwinfo[addr] & 0xf0) >> 4;
1571 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1572 pw5g->bw20_diff[path][cnt] |=
1573 0xF0;
1574 }
1575 if (hwinfo[addr] == 0xFF) {
1576 pw5g->ofdm_diff[path][cnt] = 0x04;
1577 } else {
1578 pw5g->ofdm_diff[path][0] =
1579 (hwinfo[addr] & 0x0f);
1580 if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1581 pw5g->ofdm_diff[path][cnt] |=
1582 0xF0;
1583 }
1584 addr++;
1585 } else {
1586 if (hwinfo[addr] == 0xFF) {
1587 pw5g->bw40_diff[path][cnt] = 0xFE;
1588 } else {
1589 pw5g->bw40_diff[path][cnt] =
1590 (hwinfo[addr] & 0xf0) >> 4;
1591 if (pw5g->bw40_diff[path][cnt] & BIT(3))
1592 pw5g->bw40_diff[path][cnt] |= 0xF0;
1593 }
1594 if (hwinfo[addr] == 0xFF) {
1595 pw5g->bw20_diff[path][cnt] = 0xFE;
1596 } else {
1597 pw5g->bw20_diff[path][cnt] =
1598 (hwinfo[addr] & 0x0f);
1599 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1600 pw5g->bw20_diff[path][cnt] |= 0xF0;
1601 }
1602 addr++;
1603 }
1604 }
1605 if (hwinfo[addr] == 0xFF) {
1606 pw5g->ofdm_diff[path][1] = 0xFE;
1607 pw5g->ofdm_diff[path][2] = 0xFE;
1608 } else {
1609 pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1610 pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1611 }
1612 addr++;
1613
1614 if (hwinfo[addr] == 0xFF)
1615 pw5g->ofdm_diff[path][3] = 0xFE;
1616 else
1617 pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1618 addr++;
1619
1620 for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1621 if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1622 pw5g->ofdm_diff[path][cnt] = 0xFE;
1623 else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1624 pw5g->ofdm_diff[path][cnt] |= 0xF0;
1625 }
1626 }
1627}
1628
1629static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1630 bool autoload_fail,
1631 u8 *hwinfo)
1632{
1633 struct rtl_priv *rtlpriv = rtl_priv(hw);
1634 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1635 struct txpower_info_2g pw2g;
1636 struct txpower_info_5g pw5g;
1637 u8 rf_path, index;
1638 u8 i;
1639
1640 _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1641 hwinfo);
1642
1643 for (rf_path = 0; rf_path < 2; rf_path++) {
1644 for (i = 0; i < 14; i++) {
1645 index = _rtl8723be_get_chnl_group(i+1);
1646
1647 rtlefuse->txpwrlevel_cck[rf_path][i] =
1648 pw2g.index_cck_base[rf_path][index];
1649 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1650 pw2g.index_bw40_base[rf_path][index];
1651 }
1652 for (i = 0; i < MAX_TX_COUNT; i++) {
1653 rtlefuse->txpwr_ht20diff[rf_path][i] =
1654 pw2g.bw20_diff[rf_path][i];
1655 rtlefuse->txpwr_ht40diff[rf_path][i] =
1656 pw2g.bw40_diff[rf_path][i];
1657 rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1658 pw2g.ofdm_diff[rf_path][i];
1659 }
1660 for (i = 0; i < 14; i++) {
1661 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1662 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = "
1663 "[0x%x / 0x%x ]\n", rf_path, i,
1664 rtlefuse->txpwrlevel_cck[rf_path][i],
1665 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1666 }
1667 }
1668 if (!autoload_fail)
1669 rtlefuse->eeprom_thermalmeter =
1670 hwinfo[EEPROM_THERMAL_METER_88E];
1671 else
1672 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1673
1674 if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
1675 rtlefuse->apk_thermalmeterignore = true;
1676 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1677 }
1678 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1679 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1680 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1681
1682 if (!autoload_fail) {
1683 rtlefuse->eeprom_regulatory =
1684 hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
1685 if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
1686 rtlefuse->eeprom_regulatory = 0;
1687 } else {
1688 rtlefuse->eeprom_regulatory = 0;
1689 }
1690 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1691 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1692}
1693
1694static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
1695 bool pseudo_test)
1696{
1697 struct rtl_priv *rtlpriv = rtl_priv(hw);
1698 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1699 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1700 u16 i, usvalue;
1701 u8 hwinfo[HWSET_MAX_SIZE];
1702 u16 eeprom_id;
1703 bool is_toshiba_smid1 = false;
1704 bool is_toshiba_smid2 = false;
1705 bool is_samsung_smid = false;
1706 bool is_lenovo_smid = false;
1707 u16 toshiba_smid1[] = {
1708 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
1709 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
1710 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
1711 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
1712 };
1713 u16 toshiba_smid2[] = {
1714 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
1715 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
1716 };
1717 u16 samsung_smid[] = {
1718 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
1719 0x8193, 0x9191, 0x9192, 0x9193
1720 };
1721 u16 lenovo_smid[] = {
1722 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
1723 };
1724
1725 if (pseudo_test) {
1726 /* needs to be added */
1727 return;
1728 }
1729 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
1730 rtl_efuse_shadow_map_update(hw);
1731
1732 memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
1733 HWSET_MAX_SIZE);
1734 } else if (rtlefuse->epromtype == EEPROM_93C46) {
1735 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1736 "RTL819X Not boot from eeprom, check it !!");
1737 }
1738 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
1739 hwinfo, HWSET_MAX_SIZE);
1740
1741 eeprom_id = *((u16 *)&hwinfo[0]);
1742 if (eeprom_id != RTL8723BE_EEPROM_ID) {
1743 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1744 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
1745 rtlefuse->autoload_failflag = true;
1746 } else {
1747 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1748 rtlefuse->autoload_failflag = false;
1749 }
1750 if (rtlefuse->autoload_failflag)
1751 return;
1752
1753 rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
1754 rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
1755 rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
1756 rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
1757 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1758 "EEPROMId = 0x%4x\n", eeprom_id);
1759 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1760 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1761 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1762 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1763 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1764 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1765 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1766 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1767
1768 for (i = 0; i < 6; i += 2) {
1769 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1770 *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
1771 }
1772 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "dev_addr: %pM\n",
1773 rtlefuse->dev_addr);
1774
1775 /*parse xtal*/
1776 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
1777 if (rtlefuse->crystalcap == 0xFF)
1778 rtlefuse->crystalcap = 0x20;
1779
1780 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
1781 hwinfo);
1782
1783 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
1784 rtlefuse->autoload_failflag,
1785 hwinfo);
1786
1787 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
1788 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1789 rtlefuse->txpwr_fromeprom = true;
1790 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
1791
1792 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1793 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
1794
1795 /* set channel plan to world wide 13 */
1796 rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
1797
1798 if (rtlhal->oem_id == RT_CID_DEFAULT) {
1799 /* Does this one have a Toshiba SMID from group 1? */
1800 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
1801 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
1802 is_toshiba_smid1 = true;
1803 break;
1804 }
1805 }
1806 /* Does this one have a Toshiba SMID from group 2? */
1807 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
1808 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
1809 is_toshiba_smid2 = true;
1810 break;
1811 }
1812 }
1813 /* Does this one have a Samsung SMID? */
1814 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
1815 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
1816 is_samsung_smid = true;
1817 break;
1818 }
1819 }
1820 /* Does this one have a Lenovo SMID? */
1821 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
1822 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
1823 is_lenovo_smid = true;
1824 break;
1825 }
1826 }
1827 switch (rtlefuse->eeprom_oemid) {
1828 case EEPROM_CID_DEFAULT:
1829 if (rtlefuse->eeprom_did == 0x8176) {
1830 if (rtlefuse->eeprom_svid == 0x10EC &&
1831 is_toshiba_smid1) {
1832 rtlhal->oem_id = RT_CID_TOSHIBA;
1833 } else if (rtlefuse->eeprom_svid == 0x1025) {
1834 rtlhal->oem_id = RT_CID_819X_ACER;
1835 } else if (rtlefuse->eeprom_svid == 0x10EC &&
1836 is_samsung_smid) {
1837 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
1838 } else if (rtlefuse->eeprom_svid == 0x10EC &&
1839 is_lenovo_smid) {
1840 rtlhal->oem_id = RT_CID_819X_LENOVO;
1841 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
1842 rtlefuse->eeprom_smid == 0x8197) ||
1843 (rtlefuse->eeprom_svid == 0x10EC &&
1844 rtlefuse->eeprom_smid == 0x9196)) {
1845 rtlhal->oem_id = RT_CID_819X_CLEVO;
1846 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
1847 rtlefuse->eeprom_smid == 0x8194) ||
1848 (rtlefuse->eeprom_svid == 0x1028 &&
1849 rtlefuse->eeprom_smid == 0x8198) ||
1850 (rtlefuse->eeprom_svid == 0x1028 &&
1851 rtlefuse->eeprom_smid == 0x9197) ||
1852 (rtlefuse->eeprom_svid == 0x1028 &&
1853 rtlefuse->eeprom_smid == 0x9198)) {
1854 rtlhal->oem_id = RT_CID_819X_DELL;
1855 } else if ((rtlefuse->eeprom_svid == 0x103C &&
1856 rtlefuse->eeprom_smid == 0x1629)) {
1857 rtlhal->oem_id = RT_CID_819X_HP;
1858 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
1859 rtlefuse->eeprom_smid == 0x2315)) {
1860 rtlhal->oem_id = RT_CID_819X_QMI;
1861 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
1862 rtlefuse->eeprom_smid == 0x8203)) {
1863 rtlhal->oem_id = RT_CID_819X_PRONETS;
1864 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
1865 rtlefuse->eeprom_smid == 0x84B5)) {
1866 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
1867 } else {
1868 rtlhal->oem_id = RT_CID_DEFAULT;
1869 }
1870 } else if (rtlefuse->eeprom_did == 0x8178) {
1871 if (rtlefuse->eeprom_svid == 0x10EC &&
1872 is_toshiba_smid2)
1873 rtlhal->oem_id = RT_CID_TOSHIBA;
1874 else if (rtlefuse->eeprom_svid == 0x1025)
1875 rtlhal->oem_id = RT_CID_819X_ACER;
1876 else if ((rtlefuse->eeprom_svid == 0x10EC &&
1877 rtlefuse->eeprom_smid == 0x8186))
1878 rtlhal->oem_id = RT_CID_819X_PRONETS;
1879 else if ((rtlefuse->eeprom_svid == 0x1043 &&
1880 rtlefuse->eeprom_smid == 0x84B6))
1881 rtlhal->oem_id =
1882 RT_CID_819X_EDIMAX_ASUS;
1883 else
1884 rtlhal->oem_id = RT_CID_DEFAULT;
1885 } else {
1886 rtlhal->oem_id = RT_CID_DEFAULT;
1887 }
1888 break;
1889 case EEPROM_CID_TOSHIBA:
1890 rtlhal->oem_id = RT_CID_TOSHIBA;
1891 break;
1892 case EEPROM_CID_CCX:
1893 rtlhal->oem_id = RT_CID_CCX;
1894 break;
1895 case EEPROM_CID_QMI:
1896 rtlhal->oem_id = RT_CID_819X_QMI;
1897 break;
1898 case EEPROM_CID_WHQL:
1899 break;
1900 default:
1901 rtlhal->oem_id = RT_CID_DEFAULT;
1902 break;
1903 }
1904 }
1905}
1906
1907static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
1908{
1909 struct rtl_priv *rtlpriv = rtl_priv(hw);
1910 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1911 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1912
1913 pcipriv->ledctl.led_opendrain = true;
1914 switch (rtlhal->oem_id) {
1915 case RT_CID_819X_HP:
1916 pcipriv->ledctl.led_opendrain = true;
1917 break;
1918 case RT_CID_819X_LENOVO:
1919 case RT_CID_DEFAULT:
1920 case RT_CID_TOSHIBA:
1921 case RT_CID_CCX:
1922 case RT_CID_819X_ACER:
1923 case RT_CID_WHQL:
1924 default:
1925 break;
1926 }
1927 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1928 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
1929}
1930
1931void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
1932{
1933 struct rtl_priv *rtlpriv = rtl_priv(hw);
1934 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1935 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1936 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1937 u8 tmp_u1b;
1938
1939 rtlhal->version = _rtl8723be_read_chip_version(hw);
1940 if (get_rf_type(rtlphy) == RF_1T1R)
1941 rtlpriv->dm.rfpath_rxenable[0] = true;
1942 else
1943 rtlpriv->dm.rfpath_rxenable[0] =
1944 rtlpriv->dm.rfpath_rxenable[1] = true;
1945 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
1946 rtlhal->version);
1947 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
1948 if (tmp_u1b & BIT(4)) {
1949 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
1950 rtlefuse->epromtype = EEPROM_93C46;
1951 } else {
1952 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
1953 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1954 }
1955 if (tmp_u1b & BIT(5)) {
1956 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1957 rtlefuse->autoload_failflag = false;
1958 _rtl8723be_read_adapter_info(hw, false);
1959 } else {
1960 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
1961 }
1962 _rtl8723be_hal_customized_behavior(hw);
1963}
1964
1965static void rtl8723be_update_hal_rate_table(struct ieee80211_hw *hw,
1966 struct ieee80211_sta *sta)
1967{
1968 struct rtl_priv *rtlpriv = rtl_priv(hw);
1969 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1970 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1971 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1972 u32 ratr_value;
1973 u8 ratr_index = 0;
1974 u8 nmode = mac->ht_enable;
1975 u8 mimo_ps = IEEE80211_SMPS_OFF;
1976 u16 shortgi_rate;
1977 u32 tmp_ratr_value;
1978 u8 curtxbw_40mhz = mac->bw_40;
1979 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1980 1 : 0;
1981 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1982 1 : 0;
1983 enum wireless_mode wirelessmode = mac->mode;
1984
1985 if (rtlhal->current_bandtype == BAND_ON_5G)
1986 ratr_value = sta->supp_rates[1] << 4;
1987 else
1988 ratr_value = sta->supp_rates[0];
1989 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1990 ratr_value = 0xfff;
1991 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1992 sta->ht_cap.mcs.rx_mask[0] << 12);
1993 switch (wirelessmode) {
1994 case WIRELESS_MODE_B:
1995 if (ratr_value & 0x0000000c)
1996 ratr_value &= 0x0000000d;
1997 else
1998 ratr_value &= 0x0000000f;
1999 break;
2000 case WIRELESS_MODE_G:
2001 ratr_value &= 0x00000FF5;
2002 break;
2003 case WIRELESS_MODE_N_24G:
2004 case WIRELESS_MODE_N_5G:
2005 nmode = 1;
2006 if (mimo_ps == IEEE80211_SMPS_STATIC) {
2007 ratr_value &= 0x0007F005;
2008 } else {
2009 u32 ratr_mask;
2010
2011 if (get_rf_type(rtlphy) == RF_1T2R ||
2012 get_rf_type(rtlphy) == RF_1T1R)
2013 ratr_mask = 0x000ff005;
2014 else
2015 ratr_mask = 0x0f0ff005;
2016 ratr_value &= ratr_mask;
2017 }
2018 break;
2019 default:
2020 if (rtlphy->rf_type == RF_1T2R)
2021 ratr_value &= 0x000ff0ff;
2022 else
2023 ratr_value &= 0x0f0ff0ff;
2024 break;
2025 }
2026 if ((rtlpriv->btcoexist.bt_coexistence) &&
2027 (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) &&
2028 (rtlpriv->btcoexist.bt_cur_state) &&
2029 (rtlpriv->btcoexist.bt_ant_isolation) &&
2030 ((rtlpriv->btcoexist.bt_service == BT_SCO) ||
2031 (rtlpriv->btcoexist.bt_service == BT_BUSY)))
2032 ratr_value &= 0x0fffcfc0;
2033 else
2034 ratr_value &= 0x0FFFFFFF;
2035
2036 if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
2037 (!curtxbw_40mhz && curshortgi_20mhz))) {
2038 ratr_value |= 0x10000000;
2039 tmp_ratr_value = (ratr_value >> 12);
2040
2041 for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2042 if ((1 << shortgi_rate) & tmp_ratr_value)
2043 break;
2044 }
2045 shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2046 (shortgi_rate << 4) | (shortgi_rate);
2047 }
2048 rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
2049
2050 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2051 "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0));
2052}
2053
2054static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2055 u8 rate_index)
2056{
2057 u8 ret = 0;
2058
2059 switch (rate_index) {
2060 case RATR_INX_WIRELESS_NGB:
2061 ret = 1;
2062 break;
2063 case RATR_INX_WIRELESS_N:
2064 case RATR_INX_WIRELESS_NG:
2065 ret = 5;
2066 break;
2067 case RATR_INX_WIRELESS_NB:
2068 ret = 3;
2069 break;
2070 case RATR_INX_WIRELESS_GB:
2071 ret = 6;
2072 break;
2073 case RATR_INX_WIRELESS_G:
2074 ret = 7;
2075 break;
2076 case RATR_INX_WIRELESS_B:
2077 ret = 8;
2078 break;
2079 default:
2080 ret = 0;
2081 break;
2082 }
2083 return ret;
2084}
2085
2086static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2087 struct ieee80211_sta *sta,
2088 u8 rssi_level)
2089{
2090 struct rtl_priv *rtlpriv = rtl_priv(hw);
2091 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2092 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2093 struct rtl_sta_info *sta_entry = NULL;
2094 u32 ratr_bitmap;
2095 u8 ratr_index;
2096 u8 curtxbw_40mhz = (sta->ht_cap.cap &
2097 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
2098 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2099 1 : 0;
2100 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2101 1 : 0;
2102 enum wireless_mode wirelessmode = 0;
2103 bool shortgi = false;
2104 u8 rate_mask[7];
2105 u8 macid = 0;
2106 u8 mimo_ps = IEEE80211_SMPS_OFF;
2107
2108 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2109 wirelessmode = sta_entry->wireless_mode;
2110 if (mac->opmode == NL80211_IFTYPE_STATION ||
2111 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2112 curtxbw_40mhz = mac->bw_40;
2113 else if (mac->opmode == NL80211_IFTYPE_AP ||
2114 mac->opmode == NL80211_IFTYPE_ADHOC)
2115 macid = sta->aid + 1;
2116
2117 ratr_bitmap = sta->supp_rates[0];
2118
2119 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2120 ratr_bitmap = 0xfff;
2121
2122 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2123 sta->ht_cap.mcs.rx_mask[0] << 12);
2124 switch (wirelessmode) {
2125 case WIRELESS_MODE_B:
2126 ratr_index = RATR_INX_WIRELESS_B;
2127 if (ratr_bitmap & 0x0000000c)
2128 ratr_bitmap &= 0x0000000d;
2129 else
2130 ratr_bitmap &= 0x0000000f;
2131 break;
2132 case WIRELESS_MODE_G:
2133 ratr_index = RATR_INX_WIRELESS_GB;
2134
2135 if (rssi_level == 1)
2136 ratr_bitmap &= 0x00000f00;
2137 else if (rssi_level == 2)
2138 ratr_bitmap &= 0x00000ff0;
2139 else
2140 ratr_bitmap &= 0x00000ff5;
2141 break;
2142 case WIRELESS_MODE_A:
2143 ratr_index = RATR_INX_WIRELESS_A;
2144 ratr_bitmap &= 0x00000ff0;
2145 break;
2146 case WIRELESS_MODE_N_24G:
2147 case WIRELESS_MODE_N_5G:
2148 ratr_index = RATR_INX_WIRELESS_NGB;
2149
2150 if (mimo_ps == IEEE80211_SMPS_STATIC ||
2151 mimo_ps == IEEE80211_SMPS_DYNAMIC) {
2152 if (rssi_level == 1)
2153 ratr_bitmap &= 0x00070000;
2154 else if (rssi_level == 2)
2155 ratr_bitmap &= 0x0007f000;
2156 else
2157 ratr_bitmap &= 0x0007f005;
2158 } else {
2159 if (rtlphy->rf_type == RF_1T1R) {
2160 if (curtxbw_40mhz) {
2161 if (rssi_level == 1)
2162 ratr_bitmap &= 0x000f0000;
2163 else if (rssi_level == 2)
2164 ratr_bitmap &= 0x000ff000;
2165 else
2166 ratr_bitmap &= 0x000ff015;
2167 } else {
2168 if (rssi_level == 1)
2169 ratr_bitmap &= 0x000f0000;
2170 else if (rssi_level == 2)
2171 ratr_bitmap &= 0x000ff000;
2172 else
2173 ratr_bitmap &= 0x000ff005;
2174 }
2175 } else {
2176 if (curtxbw_40mhz) {
2177 if (rssi_level == 1)
2178 ratr_bitmap &= 0x0f8f0000;
2179 else if (rssi_level == 2)
2180 ratr_bitmap &= 0x0f8ff000;
2181 else
2182 ratr_bitmap &= 0x0f8ff015;
2183 } else {
2184 if (rssi_level == 1)
2185 ratr_bitmap &= 0x0f8f0000;
2186 else if (rssi_level == 2)
2187 ratr_bitmap &= 0x0f8ff000;
2188 else
2189 ratr_bitmap &= 0x0f8ff005;
2190 }
2191 }
2192 }
2193 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2194 (!curtxbw_40mhz && curshortgi_20mhz)) {
2195 if (macid == 0)
2196 shortgi = true;
2197 else if (macid == 1)
2198 shortgi = false;
2199 }
2200 break;
2201 default:
2202 ratr_index = RATR_INX_WIRELESS_NGB;
2203
2204 if (rtlphy->rf_type == RF_1T2R)
2205 ratr_bitmap &= 0x000ff0ff;
2206 else
2207 ratr_bitmap &= 0x0f0ff0ff;
2208 break;
2209 }
2210 sta_entry->ratr_index = ratr_index;
2211
2212 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2213 "ratr_bitmap :%x\n", ratr_bitmap);
2214 *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
2215 (ratr_index << 28));
2216 rate_mask[0] = macid;
2217 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
2218 (shortgi ? 0x80 : 0x00);
2219 rate_mask[2] = curtxbw_40mhz;
2220 /* if (prox_priv->proxim_modeinfo->power_output > 0)
2221 * rate_mask[2] |= BIT(6);
2222 */
2223
2224 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2225 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2226 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2227 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2228
2229 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2230 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2231 ratr_index, ratr_bitmap,
2232 rate_mask[0], rate_mask[1],
2233 rate_mask[2], rate_mask[3],
2234 rate_mask[4], rate_mask[5],
2235 rate_mask[6]);
2236 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_RA_MASK, 7, rate_mask);
2237 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2238}
2239
2240void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2241 struct ieee80211_sta *sta,
2242 u8 rssi_level)
2243{
2244 struct rtl_priv *rtlpriv = rtl_priv(hw);
2245 if (rtlpriv->dm.useramask)
2246 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
2247 else
2248 rtl8723be_update_hal_rate_table(hw, sta);
2249}
2250
2251void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2252{
2253 struct rtl_priv *rtlpriv = rtl_priv(hw);
2254 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2255 u16 sifs_timer;
2256
2257 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
2258 (u8 *)&mac->slot_time);
2259 if (!mac->ht_enable)
2260 sifs_timer = 0x0a0a;
2261 else
2262 sifs_timer = 0x0e0e;
2263 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2264}
2265
2266bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2267{
2268 struct rtl_priv *rtlpriv = rtl_priv(hw);
2269 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2270 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2271 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2272 u8 u1tmp;
2273 bool actuallyset = false;
2274
2275 if (rtlpriv->rtlhal.being_init_adapter)
2276 return false;
2277
2278 if (ppsc->swrf_processing)
2279 return false;
2280
2281 spin_lock(&rtlpriv->locks.rf_ps_lock);
2282 if (ppsc->rfchange_inprogress) {
2283 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2284 return false;
2285 } else {
2286 ppsc->rfchange_inprogress = true;
2287 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2288 }
2289 cur_rfstate = ppsc->rfpwr_state;
2290
2291 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2292 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2293
2294 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2295
2296 if (rtlphy->polarity_ctl)
2297 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2298 else
2299 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2300
2301 if (ppsc->hwradiooff &&
2302 (e_rfpowerstate_toset == ERFON)) {
2303 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2304 "GPIOChangeRF - HW Radio ON, RF ON\n");
2305
2306 e_rfpowerstate_toset = ERFON;
2307 ppsc->hwradiooff = false;
2308 actuallyset = true;
2309 } else if (!ppsc->hwradiooff &&
2310 (e_rfpowerstate_toset == ERFOFF)) {
2311 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2312 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2313
2314 e_rfpowerstate_toset = ERFOFF;
2315 ppsc->hwradiooff = true;
2316 actuallyset = true;
2317 }
2318 if (actuallyset) {
2319 spin_lock(&rtlpriv->locks.rf_ps_lock);
2320 ppsc->rfchange_inprogress = false;
2321 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2322 } else {
2323 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2324 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2325
2326 spin_lock(&rtlpriv->locks.rf_ps_lock);
2327 ppsc->rfchange_inprogress = false;
2328 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2329 }
2330 *valid = 1;
2331 return !ppsc->hwradiooff;
2332}
2333
2334void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2335 u8 *p_macaddr, bool is_group, u8 enc_algo,
2336 bool is_wepkey, bool clear_all)
2337{
2338 struct rtl_priv *rtlpriv = rtl_priv(hw);
2339 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2340 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2341 u8 *macaddr = p_macaddr;
2342 u32 entry_id = 0;
2343 bool is_pairwise = false;
2344
2345 static u8 cam_const_addr[4][6] = {
2346 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2347 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2348 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2349 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2350 };
2351 static u8 cam_const_broad[] = {
2352 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2353 };
2354
2355 if (clear_all) {
2356 u8 idx = 0;
2357 u8 cam_offset = 0;
2358 u8 clear_number = 5;
2359
2360 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2361
2362 for (idx = 0; idx < clear_number; idx++) {
2363 rtl_cam_mark_invalid(hw, cam_offset + idx);
2364 rtl_cam_empty_entry(hw, cam_offset + idx);
2365
2366 if (idx < 5) {
2367 memset(rtlpriv->sec.key_buf[idx], 0,
2368 MAX_KEY_LEN);
2369 rtlpriv->sec.key_len[idx] = 0;
2370 }
2371 }
2372 } else {
2373 switch (enc_algo) {
2374 case WEP40_ENCRYPTION:
2375 enc_algo = CAM_WEP40;
2376 break;
2377 case WEP104_ENCRYPTION:
2378 enc_algo = CAM_WEP104;
2379 break;
2380 case TKIP_ENCRYPTION:
2381 enc_algo = CAM_TKIP;
2382 break;
2383 case AESCCMP_ENCRYPTION:
2384 enc_algo = CAM_AES;
2385 break;
2386 default:
2387 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2388 "switch case not process\n");
2389 enc_algo = CAM_TKIP;
2390 break;
2391 }
2392
2393 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2394 macaddr = cam_const_addr[key_index];
2395 entry_id = key_index;
2396 } else {
2397 if (is_group) {
2398 macaddr = cam_const_broad;
2399 entry_id = key_index;
2400 } else {
2401 if (mac->opmode == NL80211_IFTYPE_AP) {
2402 entry_id = rtl_cam_get_free_entry(hw,
2403 p_macaddr);
2404 if (entry_id >= TOTAL_CAM_ENTRY) {
2405 RT_TRACE(rtlpriv, COMP_SEC,
2406 DBG_EMERG,
2407 "Can not find free"
2408 " hw security cam "
2409 "entry\n");
2410 return;
2411 }
2412 } else {
2413 entry_id = CAM_PAIRWISE_KEY_POSITION;
2414 }
2415 key_index = PAIRWISE_KEYIDX;
2416 is_pairwise = true;
2417 }
2418 }
2419 if (rtlpriv->sec.key_len[key_index] == 0) {
2420 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2421 "delete one entry, entry_id is %d\n",
2422 entry_id);
2423 if (mac->opmode == NL80211_IFTYPE_AP)
2424 rtl_cam_del_entry(hw, p_macaddr);
2425 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2426 } else {
2427 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2428 "add one entry\n");
2429 if (is_pairwise) {
2430 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2431 "set Pairwise key\n");
2432
2433 rtl_cam_add_one_entry(hw, macaddr, key_index,
2434 entry_id, enc_algo,
2435 CAM_CONFIG_NO_USEDK,
2436 rtlpriv->sec.key_buf[key_index]);
2437 } else {
2438 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2439 "set group key\n");
2440
2441 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2442 rtl_cam_add_one_entry(hw,
2443 rtlefuse->dev_addr,
2444 PAIRWISE_KEYIDX,
2445 CAM_PAIRWISE_KEY_POSITION,
2446 enc_algo,
2447 CAM_CONFIG_NO_USEDK,
2448 rtlpriv->sec.key_buf
2449 [entry_id]);
2450 }
2451 rtl_cam_add_one_entry(hw, macaddr, key_index,
2452 entry_id, enc_algo,
2453 CAM_CONFIG_NO_USEDK,
2454 rtlpriv->sec.key_buf[entry_id]);
2455 }
2456 }
2457 }
2458}
2459
2460void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2461 bool auto_load_fail, u8 *hwinfo)
2462{
2463 struct rtl_priv *rtlpriv = rtl_priv(hw);
2464 u8 value;
2465 u32 tmpu_32;
2466
2467 if (!auto_load_fail) {
2468 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2469 if (tmpu_32 & BIT(18))
2470 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2471 else
2472 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2473 value = hwinfo[RF_OPTION4];
2474 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2475 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
2476 } else {
2477 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2478 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2479 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
2480 }
2481}
2482
2483void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2484{
2485 struct rtl_priv *rtlpriv = rtl_priv(hw);
2486
2487 /* 0:Low, 1:High, 2:From Efuse. */
2488 rtlpriv->btcoexist.reg_bt_iso = 2;
2489 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2490 rtlpriv->btcoexist.reg_bt_sco = 3;
2491 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2492 rtlpriv->btcoexist.reg_bt_sco = 0;
2493}
2494
2495void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2496{
2497 struct rtl_priv *rtlpriv = rtl_priv(hw);
2498
2499 if (rtlpriv->cfg->ops->get_btc_status())
2500 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
2501}
2502
2503void rtl8723be_suspend(struct ieee80211_hw *hw)
2504{
2505}
2506
2507void rtl8723be_resume(struct ieee80211_hw *hw)
2508{
2509}
2510
2511/* Turn on AAP (RCR:bit 0) for promicuous mode. */
2512void rtl8723be_allow_all_destaddr(struct ieee80211_hw *hw, bool allow_all_da,
2513 bool write_into_reg)
2514{
2515 struct rtl_priv *rtlpriv = rtl_priv(hw);
2516 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2517
2518 if (allow_all_da) /* Set BIT0 */
2519 rtlpci->receive_config |= RCR_AAP;
2520 else /* Clear BIT0 */
2521 rtlpci->receive_config &= ~RCR_AAP;
2522
2523 if (write_into_reg)
2524 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
2525
2526 RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
2527 "receive_config = 0x%08X, write_into_reg =%d\n",
2528 rtlpci->receive_config, write_into_reg);
2529}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.h b/drivers/net/wireless/rtlwifi/rtl8723be/hw.h
new file mode 100644
index 000000000000..b7449a9b57e4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.h
@@ -0,0 +1,64 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_HW_H__
27#define __RTL8723BE_HW_H__
28
29void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
30void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw);
31
32void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
33 u32 *p_inta, u32 *p_intb);
34int rtl8723be_hw_init(struct ieee80211_hw *hw);
35void rtl8723be_card_disable(struct ieee80211_hw *hw);
36void rtl8723be_enable_interrupt(struct ieee80211_hw *hw);
37void rtl8723be_disable_interrupt(struct ieee80211_hw *hw);
38int rtl8723be_set_network_type(struct ieee80211_hw *hw,
39 enum nl80211_iftype type);
40void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
41void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci);
42void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw);
43void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw);
44void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
45 u32 add_msr, u32 rm_msr);
46void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
47void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
48 struct ieee80211_sta *sta,
49 u8 rssi_level);
50void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw);
51bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
52void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw);
53void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
54 u8 *p_macaddr, bool is_group, u8 enc_algo,
55 bool is_wepkey, bool clear_all);
56void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
57 bool autoload_fail, u8 *hwinfo);
58void rtl8723be_bt_reg_init(struct ieee80211_hw *hw);
59void rtl8723be_bt_hw_init(struct ieee80211_hw *hw);
60void rtl8723be_suspend(struct ieee80211_hw *hw);
61void rtl8723be_resume(struct ieee80211_hw *hw);
62void rtl8723be_allow_all_destaddr(struct ieee80211_hw *hw, bool allow_all_da,
63 bool write_into_reg);
64#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/led.c b/drivers/net/wireless/rtlwifi/rtl8723be/led.c
new file mode 100644
index 000000000000..cb931a38dc48
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/led.c
@@ -0,0 +1,153 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "reg.h"
29#include "led.h"
30
31static void _rtl8723be_init_led(struct ieee80211_hw *hw, struct rtl_led *pled,
32 enum rtl_led_pin ledpin)
33{
34 pled->hw = hw;
35 pled->ledpin = ledpin;
36 pled->ledon = false;
37}
38
39void rtl8723be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
40{
41 u8 ledcfg;
42 struct rtl_priv *rtlpriv = rtl_priv(hw);
43
44 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
45 "LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin);
46
47 switch (pled->ledpin) {
48 case LED_PIN_GPIO0:
49 break;
50 case LED_PIN_LED0:
51 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
52 ledcfg &= ~BIT(6);
53 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5));
54 break;
55 case LED_PIN_LED1:
56 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
57 rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
58 break;
59 default:
60 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
61 "switch case not process\n");
62 break;
63 }
64 pled->ledon = true;
65}
66
67void rtl8723be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
68{
69 struct rtl_priv *rtlpriv = rtl_priv(hw);
70 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
71 u8 ledcfg;
72
73 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
74 "LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin);
75
76 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
77
78 switch (pled->ledpin) {
79 case LED_PIN_GPIO0:
80 break;
81 case LED_PIN_LED0:
82 ledcfg &= 0xf0;
83 if (pcipriv->ledctl.led_opendrain) {
84 ledcfg &= 0x90; /* Set to software control. */
85 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
86 ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
87 ledcfg &= 0xFE;
88 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
89 } else {
90 ledcfg &= ~BIT(6);
91 rtl_write_byte(rtlpriv, REG_LEDCFG2,
92 (ledcfg | BIT(3) | BIT(5)));
93 }
94 break;
95 case LED_PIN_LED1:
96 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
97 ledcfg &= 0x10; /* Set to software control. */
98 rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3));
99
100 break;
101 default:
102 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
103 "switch case not processed\n");
104 break;
105 }
106 pled->ledon = false;
107}
108
109void rtl8723be_init_sw_leds(struct ieee80211_hw *hw)
110{
111 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
112 _rtl8723be_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
113 _rtl8723be_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
114}
115
116static void _rtl8723be_sw_led_control(struct ieee80211_hw *hw,
117 enum led_ctl_mode ledaction)
118{
119 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
120 struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0);
121 switch (ledaction) {
122 case LED_CTL_POWER_ON:
123 case LED_CTL_LINK:
124 case LED_CTL_NO_LINK:
125 rtl8723be_sw_led_on(hw, pled0);
126 break;
127 case LED_CTL_POWER_OFF:
128 rtl8723be_sw_led_off(hw, pled0);
129 break;
130 default:
131 break;
132 }
133}
134
135void rtl8723be_led_control(struct ieee80211_hw *hw,
136 enum led_ctl_mode ledaction)
137{
138 struct rtl_priv *rtlpriv = rtl_priv(hw);
139 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
140
141 if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
142 (ledaction == LED_CTL_TX ||
143 ledaction == LED_CTL_RX ||
144 ledaction == LED_CTL_SITE_SURVEY ||
145 ledaction == LED_CTL_LINK ||
146 ledaction == LED_CTL_NO_LINK ||
147 ledaction == LED_CTL_START_TO_LINK ||
148 ledaction == LED_CTL_POWER_ON)) {
149 return;
150 }
151 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction);
152 _rtl8723be_sw_led_control(hw, ledaction);
153}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/led.h b/drivers/net/wireless/rtlwifi/rtl8723be/led.h
new file mode 100644
index 000000000000..c57de379ee8d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/led.h
@@ -0,0 +1,35 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_LED_H__
27#define __RTL8723BE_LED_H__
28
29void rtl8723be_init_sw_leds(struct ieee80211_hw *hw);
30void rtl8723be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
31void rtl8723be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
32void rtl8723be_led_control(struct ieee80211_hw *hw,
33 enum led_ctl_mode ledaction);
34
35#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
new file mode 100644
index 000000000000..ebc1e2788fca
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
@@ -0,0 +1,2175 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../ps.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "../rtl8723com/phy_common.h"
33#include "rf.h"
34#include "dm.h"
35#include "table.h"
36#include "trx.h"
37
38static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
39static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
40 u8 configtype);
41static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
42 u8 channel, u8 *stage,
43 u8 *step, u32 *delay);
44static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
45 u32 addr, u32 data);
46
47static bool _rtl8723be_check_condition(struct ieee80211_hw *hw,
48 const u32 condition)
49{
50 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
51 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
52 u32 _board = rtlefuse->board_type; /*need efuse define*/
53 u32 _interface = rtlhal->interface;
54 u32 _platform = 0x08;/*SupportPlatform */
55 u32 cond = condition;
56
57 if (condition == 0xCDCDCDCD)
58 return true;
59
60 cond = condition & 0xFF;
61 if ((_board & cond) == 0 && cond != 0x1F)
62 return false;
63
64 cond = condition & 0xFF00;
65 cond = cond >> 8;
66 if ((_interface & cond) == 0 && cond != 0x07)
67 return false;
68
69 cond = condition & 0xFF0000;
70 cond = cond >> 16;
71 if ((_platform & cond) == 0 && cond != 0x0F)
72 return false;
73 return true;
74}
75
76static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
77{
78 struct rtl_priv *rtlpriv = rtl_priv(hw);
79 u32 i;
80 u32 arraylength;
81 u32 *ptrarray;
82
83 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
84 arraylength = RTL8723BEMAC_1T_ARRAYLEN;
85 ptrarray = RTL8723BEMAC_1T_ARRAY;
86 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
87 "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength);
88 for (i = 0; i < arraylength; i = i + 2)
89 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
90 return true;
91}
92
93static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
94 u8 configtype)
95{
96 #define READ_NEXT_PAIR(v1, v2, i) \
97 do { \
98 i += 2; \
99 v1 = array_table[i];\
100 v2 = array_table[i+1]; \
101 } while (0)
102
103 int i;
104 u32 *array_table;
105 u16 arraylen;
106 struct rtl_priv *rtlpriv = rtl_priv(hw);
107 u32 v1 = 0, v2 = 0;
108
109 if (configtype == BASEBAND_CONFIG_PHY_REG) {
110 arraylen = RTL8723BEPHY_REG_1TARRAYLEN;
111 array_table = RTL8723BEPHY_REG_1TARRAY;
112
113 for (i = 0; i < arraylen; i = i + 2) {
114 v1 = array_table[i];
115 v2 = array_table[i+1];
116 if (v1 < 0xcdcdcdcd) {
117 _rtl8723be_config_bb_reg(hw, v1, v2);
118 } else {/*This line is the start line of branch.*/
119 if (!_rtl8723be_check_condition(hw, array_table[i])) {
120 /*Discard the following (offset, data) pairs*/
121 READ_NEXT_PAIR(v1, v2, i);
122 while (v2 != 0xDEAD &&
123 v2 != 0xCDEF &&
124 v2 != 0xCDCD &&
125 i < arraylen - 2) {
126 READ_NEXT_PAIR(v1, v2, i);
127 }
128 i -= 2; /* prevent from for-loop += 2*/
129 /* Configure matched pairs and
130 * skip to end of if-else.
131 */
132 } else {
133 READ_NEXT_PAIR(v1, v2, i);
134 while (v2 != 0xDEAD &&
135 v2 != 0xCDEF &&
136 v2 != 0xCDCD &&
137 i < arraylen - 2) {
138 _rtl8723be_config_bb_reg(hw,
139 v1, v2);
140 READ_NEXT_PAIR(v1, v2, i);
141 }
142
143 while (v2 != 0xDEAD && i < arraylen - 2)
144 READ_NEXT_PAIR(v1, v2, i);
145 }
146 }
147 }
148 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
149 arraylen = RTL8723BEAGCTAB_1TARRAYLEN;
150 array_table = RTL8723BEAGCTAB_1TARRAY;
151
152 for (i = 0; i < arraylen; i = i + 2) {
153 v1 = array_table[i];
154 v2 = array_table[i+1];
155 if (v1 < 0xCDCDCDCD) {
156 rtl_set_bbreg(hw, array_table[i],
157 MASKDWORD,
158 array_table[i + 1]);
159 udelay(1);
160 continue;
161 } else {/*This line is the start line of branch.*/
162 if (!_rtl8723be_check_condition(hw, array_table[i])) {
163 /* Discard the following
164 * (offset, data) pairs
165 */
166 READ_NEXT_PAIR(v1, v2, i);
167 while (v2 != 0xDEAD &&
168 v2 != 0xCDEF &&
169 v2 != 0xCDCD &&
170 i < arraylen - 2) {
171 READ_NEXT_PAIR(v1, v2, i);
172 }
173 i -= 2; /* prevent from for-loop += 2*/
174 /*Configure matched pairs and
175 *skip to end of if-else.
176 */
177 } else {
178 READ_NEXT_PAIR(v1, v2, i);
179 while (v2 != 0xDEAD &&
180 v2 != 0xCDEF &&
181 v2 != 0xCDCD &&
182 i < arraylen - 2) {
183 rtl_set_bbreg(hw, array_table[i],
184 MASKDWORD,
185 array_table[i + 1]);
186 udelay(1);
187 READ_NEXT_PAIR(v1, v2, i);
188 }
189
190 while (v2 != 0xDEAD && i < arraylen - 2)
191 READ_NEXT_PAIR(v1, v2, i);
192 }
193 }
194 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
195 "The agctab_array_table[0] is "
196 "%x Rtl818EEPHY_REGArray[1] is %x\n",
197 array_table[i], array_table[i + 1]);
198 }
199 }
200 return true;
201}
202
203static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
204{
205 u8 index = 0;
206
207 switch (regaddr) {
208 case RTXAGC_A_RATE18_06:
209 case RTXAGC_B_RATE18_06:
210 index = 0;
211 break;
212 case RTXAGC_A_RATE54_24:
213 case RTXAGC_B_RATE54_24:
214 index = 1;
215 break;
216 case RTXAGC_A_CCK1_MCS32:
217 case RTXAGC_B_CCK1_55_MCS32:
218 index = 2;
219 break;
220 case RTXAGC_B_CCK11_A_CCK2_11:
221 index = 3;
222 break;
223 case RTXAGC_A_MCS03_MCS00:
224 case RTXAGC_B_MCS03_MCS00:
225 index = 4;
226 break;
227 case RTXAGC_A_MCS07_MCS04:
228 case RTXAGC_B_MCS07_MCS04:
229 index = 5;
230 break;
231 case RTXAGC_A_MCS11_MCS08:
232 case RTXAGC_B_MCS11_MCS08:
233 index = 6;
234 break;
235 case RTXAGC_A_MCS15_MCS12:
236 case RTXAGC_B_MCS15_MCS12:
237 index = 7;
238 break;
239 default:
240 regaddr &= 0xFFF;
241 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
242 index = (u8) ((regaddr - 0xC20) / 4);
243 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
244 index = (u8) ((regaddr - 0xE20) / 4);
245 break;
246 };
247 return index;
248}
249
250u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
251 u32 regaddr, u32 bitmask)
252{
253 struct rtl_priv *rtlpriv = rtl_priv(hw);
254 u32 original_value, readback_value, bitshift;
255 unsigned long flags;
256
257 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
258 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
259 regaddr, rfpath, bitmask);
260
261 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
262
263 original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
264 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
265 readback_value = (original_value & bitmask) >> bitshift;
266
267 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
268
269 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
270 "regaddr(%#x), rfpath(%#x), "
271 "bitmask(%#x), original_value(%#x)\n",
272 regaddr, rfpath, bitmask, original_value);
273
274 return readback_value;
275}
276
277void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
278 u32 regaddr, u32 bitmask, u32 data)
279{
280 struct rtl_priv *rtlpriv = rtl_priv(hw);
281 u32 original_value, bitshift;
282 unsigned long flags;
283
284 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
285 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
286 regaddr, bitmask, data, path);
287
288 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
289
290 if (bitmask != RFREG_OFFSET_MASK) {
291 original_value = rtl8723_phy_rf_serial_read(hw, path,
292 regaddr);
293 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
294 data = ((original_value & (~bitmask)) |
295 (data << bitshift));
296 }
297
298 rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
299
300 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
301
302 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
303 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
304 regaddr, bitmask, data, path);
305}
306
307bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
308{
309 struct rtl_priv *rtlpriv = rtl_priv(hw);
310 bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
311
312 rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
313 return rtstatus;
314}
315
316bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
317{
318 bool rtstatus = true;
319 struct rtl_priv *rtlpriv = rtl_priv(hw);
320 u16 regval;
321 u8 reg_hwparafile = 1;
322 u32 tmp;
323 u8 crystalcap = rtlpriv->efuse.crystalcap;
324 rtl8723_phy_init_bb_rf_reg_def(hw);
325 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
326 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
327 regval | BIT(13) | BIT(0) | BIT(1));
328
329 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
330 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
331 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
332 FEN_BB_GLB_RSTN | FEN_BBRSTB);
333 tmp = rtl_read_dword(rtlpriv, 0x4c);
334 rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
335
336 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
337
338 if (reg_hwparafile == 1)
339 rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
340
341 crystalcap = crystalcap & 0x3F;
342 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
343 (crystalcap | crystalcap << 6));
344
345 return rtstatus;
346}
347
348bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
349{
350 return rtl8723be_phy_rf6052_config(hw);
351}
352
353static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
354 u32 data, enum radio_path rfpath,
355 u32 regaddr)
356{
357 if (addr == 0xfe || addr == 0xffe) {
358 mdelay(50);
359 } else {
360 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
361 udelay(1);
362 }
363}
364
365static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
366 u32 addr, u32 data)
367{
368 u32 content = 0x1000; /*RF Content: radio_a_txt*/
369 u32 maskforphyset = (u32)(content & 0xE000);
370
371 _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
372 addr | maskforphyset);
373}
374
375static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
376{
377 struct rtl_priv *rtlpriv = rtl_priv(hw);
378 struct rtl_phy *rtlphy = &(rtlpriv->phy);
379
380 u8 band, path, txnum, section;
381
382 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
383 for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
384 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
385 for (section = 0;
386 section < TX_PWR_BY_RATE_NUM_SECTION;
387 ++section)
388 rtlphy->tx_power_by_rate_offset[band]
389 [path][txnum][section] = 0;
390}
391
392static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
393 u32 addr, u32 data)
394{
395 if (addr == 0xfe) {
396 mdelay(50);
397 } else if (addr == 0xfd) {
398 mdelay(5);
399 } else if (addr == 0xfc) {
400 mdelay(1);
401 } else if (addr == 0xfb) {
402 udelay(50);
403 } else if (addr == 0xfa) {
404 udelay(5);
405 } else if (addr == 0xf9) {
406 udelay(1);
407 } else {
408 rtl_set_bbreg(hw, addr, MASKDWORD, data);
409 udelay(1);
410 }
411}
412
413static void phy_set_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band,
414 u8 path, u8 rate_section,
415 u8 txnum, u8 value)
416{
417 struct rtl_priv *rtlpriv = rtl_priv(hw);
418 struct rtl_phy *rtlphy = &(rtlpriv->phy);
419
420 if (path > RF90_PATH_D) {
421 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
422 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
423 path);
424 return;
425 }
426
427 if (band == BAND_ON_2_4G) {
428 switch (rate_section) {
429 case CCK:
430 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
431 break;
432 case OFDM:
433 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
434 break;
435 case HT_MCS0_MCS7:
436 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
437 break;
438 case HT_MCS8_MCS15:
439 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
440 break;
441 default:
442 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
443 "Invalid RateSection %d in Band 2.4G, Rf Path"
444 " %d, %dTx in PHY_SetTxPowerByRateBase()\n",
445 rate_section, path, txnum);
446 break;
447 };
448 } else {
449 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
450 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
451 band);
452 }
453}
454
455static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path,
456 u8 txnum, u8 rate_section)
457{
458 struct rtl_priv *rtlpriv = rtl_priv(hw);
459 struct rtl_phy *rtlphy = &(rtlpriv->phy);
460 u8 value = 0;
461 if (path > RF90_PATH_D) {
462 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
463 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
464 path);
465 return 0;
466 }
467
468 if (band == BAND_ON_2_4G) {
469 switch (rate_section) {
470 case CCK:
471 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
472 break;
473 case OFDM:
474 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
475 break;
476 case HT_MCS0_MCS7:
477 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
478 break;
479 case HT_MCS8_MCS15:
480 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
481 break;
482 default:
483 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
484 "Invalid RateSection %d in Band 2.4G, Rf Path"
485 " %d, %dTx in PHY_GetTxPowerByRateBase()\n",
486 rate_section, path, txnum);
487 break;
488 };
489 } else {
490 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
491 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
492 band);
493 }
494
495 return value;
496}
497
498static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
499{
500 struct rtl_priv *rtlpriv = rtl_priv(hw);
501 struct rtl_phy *rtlphy = &(rtlpriv->phy);
502 u16 raw_value = 0;
503 u8 base = 0, path = 0;
504
505 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
506 if (path == RF90_PATH_A) {
507 raw_value = (u16) (rtlphy->tx_power_by_rate_offset
508 [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
509 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
510 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, CCK,
511 RF_1TX, base);
512 } else if (path == RF90_PATH_B) {
513 raw_value = (u16) (rtlphy->tx_power_by_rate_offset
514 [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
515 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
516 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
517 CCK, RF_1TX, base);
518 }
519 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
520 [path][RF_1TX][1] >> 24) & 0xFF;
521 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
522 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX,
523 base);
524
525 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
526 [path][RF_1TX][5] >> 24) & 0xFF;
527 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
528 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7,
529 RF_1TX, base);
530
531 raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
532 [path][RF_2TX][7] >> 24) & 0xFF;
533 base = (raw_value >> 4) * 10 + (raw_value & 0xF);
534 phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
535 HT_MCS8_MCS15, RF_2TX, base);
536 }
537}
538
539static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val)
540{
541 char i = 0;
542 u8 temp_value = 0;
543 u32 temp_data = 0;
544
545 for (i = 3; i >= 0; --i) {
546 if (i >= start && i <= end) {
547 /* Get the exact value */
548 temp_value = (u8) (*data >> (i * 8)) & 0xF;
549 temp_value += ((u8) ((*data >> (i*8 + 4)) & 0xF)) * 10;
550
551 /* Change the value to a relative value */
552 temp_value = (temp_value > base_val) ?
553 temp_value - base_val :
554 base_val - temp_value;
555 } else {
556 temp_value = (u8) (*data >> (i * 8)) & 0xFF;
557 }
558 temp_data <<= 8;
559 temp_data |= temp_value;
560 }
561 *data = temp_data;
562}
563
564static void conv_dbm_to_rel(struct ieee80211_hw *hw)
565{
566 struct rtl_priv *rtlpriv = rtl_priv(hw);
567 struct rtl_phy *rtlphy = &(rtlpriv->phy);
568 u8 base = 0, rfpath = RF90_PATH_A;
569
570 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
571 RF_1TX, CCK);
572 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
573 [rfpath][RF_1TX][2]), 1, 1, base);
574 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
575 [rfpath][RF_1TX][3]), 1, 3, base);
576
577 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
578 RF_1TX, OFDM);
579 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
580 [rfpath][RF_1TX][0]), 0, 3, base);
581 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
582 [rfpath][RF_1TX][1]), 0, 3, base);
583
584 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
585 RF_1TX, HT_MCS0_MCS7);
586 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
587 [rfpath][RF_1TX][4]), 0, 3, base);
588 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
589 [rfpath][RF_1TX][5]), 0, 3, base);
590
591 base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
592 RF_2TX, HT_MCS8_MCS15);
593 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
594 [rfpath][RF_2TX][6]), 0, 3, base);
595
596 phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
597 [rfpath][RF_2TX][7]), 0, 3, base);
598
599 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
600 "<=== conv_dbm_to_rel()\n");
601}
602
603static void _rtl8723be_phy_txpower_by_rate_configuration(
604 struct ieee80211_hw *hw)
605{
606 _rtl8723be_phy_store_txpower_by_rate_base(hw);
607 conv_dbm_to_rel(hw);
608}
609
610static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
611{
612 struct rtl_priv *rtlpriv = rtl_priv(hw);
613 struct rtl_phy *rtlphy = &(rtlpriv->phy);
614 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
615 bool rtstatus;
616
617 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
618 BASEBAND_CONFIG_PHY_REG);
619 if (!rtstatus) {
620 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
621 return false;
622 }
623 _rtl8723be_phy_init_tx_power_by_rate(hw);
624 if (!rtlefuse->autoload_failflag) {
625 rtlphy->pwrgroup_cnt = 0;
626 rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
627 BASEBAND_CONFIG_PHY_REG);
628 }
629 _rtl8723be_phy_txpower_by_rate_configuration(hw);
630 if (!rtstatus) {
631 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
632 return false;
633 }
634 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
635 BASEBAND_CONFIG_AGC_TAB);
636 if (!rtstatus) {
637 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
638 return false;
639 }
640 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
641 RFPGA0_XA_HSSIPARAMETER2,
642 0x200));
643 return true;
644}
645
646static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
647 u32 band, u32 rfpath,
648 u32 txnum, u32 regaddr,
649 u32 bitmask, u32 data)
650{
651 struct rtl_priv *rtlpriv = rtl_priv(hw);
652 struct rtl_phy *rtlphy = &(rtlpriv->phy);
653 u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
654
655 if (band != BAND_ON_2_4G && band != BAND_ON_5G)
656 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
657 "Invalid Band %d\n", band);
658
659 if (rfpath > MAX_RF_PATH)
660 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
661 "Invalid RfPath %d\n", rfpath);
662
663 if (txnum > MAX_RF_PATH)
664 RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
665 "Invalid TxNum %d\n", txnum);
666
667 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
668 data;
669}
670
671static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
672 u8 configtype)
673{
674 struct rtl_priv *rtlpriv = rtl_priv(hw);
675 int i;
676 u32 *phy_regarray_table_pg;
677 u16 phy_regarray_pg_len;
678 u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
679
680 phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
681 phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
682
683 if (configtype == BASEBAND_CONFIG_PHY_REG) {
684 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
685 v1 = phy_regarray_table_pg[i];
686 v2 = phy_regarray_table_pg[i+1];
687 v3 = phy_regarray_table_pg[i+2];
688 v4 = phy_regarray_table_pg[i+3];
689 v5 = phy_regarray_table_pg[i+4];
690 v6 = phy_regarray_table_pg[i+5];
691
692 if (v1 < 0xcdcdcdcd) {
693 if (phy_regarray_table_pg[i] == 0xfe ||
694 phy_regarray_table_pg[i] == 0xffe)
695 mdelay(50);
696 else
697 _rtl8723be_store_tx_power_by_rate(hw,
698 v1, v2, v3, v4, v5, v6);
699 continue;
700 } else {
701 /*don't need the hw_body*/
702 if (!_rtl8723be_check_condition(hw,
703 phy_regarray_table_pg[i])) {
704 i += 2; /* skip the pair of expression*/
705 v1 = phy_regarray_table_pg[i];
706 v2 = phy_regarray_table_pg[i+1];
707 v3 = phy_regarray_table_pg[i+2];
708 while (v2 != 0xDEAD) {
709 i += 3;
710 v1 = phy_regarray_table_pg[i];
711 v2 = phy_regarray_table_pg[i+1];
712 v3 = phy_regarray_table_pg[i+2];
713 }
714 }
715 }
716 }
717 } else {
718 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
719 "configtype != BaseBand_Config_PHY_REG\n");
720 }
721 return true;
722}
723
724bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
725 enum radio_path rfpath)
726{
727 #define READ_NEXT_RF_PAIR(v1, v2, i) \
728 do { \
729 i += 2; \
730 v1 = radioa_array_table[i]; \
731 v2 = radioa_array_table[i+1]; \
732 } while (0)
733
734 int i;
735 bool rtstatus = true;
736 u32 *radioa_array_table;
737 u16 radioa_arraylen;
738 struct rtl_priv *rtlpriv = rtl_priv(hw);
739 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
740 u32 v1 = 0, v2 = 0;
741
742 radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
743 radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
744 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
745 "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
746 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
747 rtstatus = true;
748 switch (rfpath) {
749 case RF90_PATH_A:
750 for (i = 0; i < radioa_arraylen; i = i + 2) {
751 v1 = radioa_array_table[i];
752 v2 = radioa_array_table[i+1];
753 if (v1 < 0xcdcdcdcd) {
754 _rtl8723be_config_rf_radio_a(hw, v1, v2);
755 } else { /*This line is the start line of branch.*/
756 if (!_rtl8723be_check_condition(hw,
757 radioa_array_table[i])) {
758 /* Discard the following
759 * (offset, data) pairs
760 */
761 READ_NEXT_RF_PAIR(v1, v2, i);
762 while (v2 != 0xDEAD &&
763 v2 != 0xCDEF &&
764 v2 != 0xCDCD &&
765 i < radioa_arraylen - 2)
766 READ_NEXT_RF_PAIR(v1, v2, i);
767 i -= 2; /* prevent from for-loop += 2*/
768 } else {
769 /* Configure matched pairs
770 * and skip to end of if-else.
771 */
772 READ_NEXT_RF_PAIR(v1, v2, i);
773 while (v2 != 0xDEAD &&
774 v2 != 0xCDEF &&
775 v2 != 0xCDCD &&
776 i < radioa_arraylen - 2) {
777 _rtl8723be_config_rf_radio_a(hw,
778 v1, v2);
779 READ_NEXT_RF_PAIR(v1, v2, i);
780 }
781
782 while (v2 != 0xDEAD &&
783 i < radioa_arraylen - 2) {
784 READ_NEXT_RF_PAIR(v1, v2, i);
785 }
786 }
787 }
788 }
789
790 if (rtlhal->oem_id == RT_CID_819X_HP)
791 _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
792
793 break;
794 case RF90_PATH_B:
795 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
796 "switch case not process\n");
797 break;
798 case RF90_PATH_C:
799 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
800 "switch case not process\n");
801 break;
802 case RF90_PATH_D:
803 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
804 "switch case not process\n");
805 break;
806 }
807 return true;
808}
809
810void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
811{
812 struct rtl_priv *rtlpriv = rtl_priv(hw);
813 struct rtl_phy *rtlphy = &(rtlpriv->phy);
814
815 rtlphy->default_initialgain[0] =
816 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
817 rtlphy->default_initialgain[1] =
818 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
819 rtlphy->default_initialgain[2] =
820 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
821 rtlphy->default_initialgain[3] =
822 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
823
824 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
825 "Default initial gain (c50 = 0x%x, "
826 "c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n",
827 rtlphy->default_initialgain[0],
828 rtlphy->default_initialgain[1],
829 rtlphy->default_initialgain[2],
830 rtlphy->default_initialgain[3]);
831
832 rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
833 MASKBYTE0);
834 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
835 MASKDWORD);
836
837 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
838 "Default framesync (0x%x) = 0x%x\n",
839 ROFDM0_RXDETECTOR3, rtlphy->framesync);
840}
841
842void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
843{
844 struct rtl_priv *rtlpriv = rtl_priv(hw);
845 struct rtl_phy *rtlphy = &(rtlpriv->phy);
846 u8 txpwr_level;
847 long txpwr_dbm;
848
849 txpwr_level = rtlphy->cur_cck_txpwridx;
850 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
851 txpwr_level);
852 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
853 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
854 txpwr_dbm)
855 txpwr_dbm =
856 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
857 txpwr_level);
858 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
859 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
860 txpwr_level) > txpwr_dbm)
861 txpwr_dbm =
862 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
863 txpwr_level);
864 *powerlevel = txpwr_dbm;
865}
866
867static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
868 u8 rate)
869{
870 u8 rate_section = 0;
871
872 switch (rate) {
873 case DESC92C_RATE1M:
874 rate_section = 2;
875 break;
876 case DESC92C_RATE2M:
877 case DESC92C_RATE5_5M:
878 if (path == RF90_PATH_A)
879 rate_section = 3;
880 else if (path == RF90_PATH_B)
881 rate_section = 2;
882 break;
883 case DESC92C_RATE11M:
884 rate_section = 3;
885 break;
886 case DESC92C_RATE6M:
887 case DESC92C_RATE9M:
888 case DESC92C_RATE12M:
889 case DESC92C_RATE18M:
890 rate_section = 0;
891 break;
892 case DESC92C_RATE24M:
893 case DESC92C_RATE36M:
894 case DESC92C_RATE48M:
895 case DESC92C_RATE54M:
896 rate_section = 1;
897 break;
898 case DESC92C_RATEMCS0:
899 case DESC92C_RATEMCS1:
900 case DESC92C_RATEMCS2:
901 case DESC92C_RATEMCS3:
902 rate_section = 4;
903 break;
904 case DESC92C_RATEMCS4:
905 case DESC92C_RATEMCS5:
906 case DESC92C_RATEMCS6:
907 case DESC92C_RATEMCS7:
908 rate_section = 5;
909 break;
910 case DESC92C_RATEMCS8:
911 case DESC92C_RATEMCS9:
912 case DESC92C_RATEMCS10:
913 case DESC92C_RATEMCS11:
914 rate_section = 6;
915 break;
916 case DESC92C_RATEMCS12:
917 case DESC92C_RATEMCS13:
918 case DESC92C_RATEMCS14:
919 case DESC92C_RATEMCS15:
920 rate_section = 7;
921 break;
922 default:
923 RT_ASSERT(true, "Rate_Section is Illegal\n");
924 break;
925 }
926 return rate_section;
927}
928
929static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
930 enum band_type band,
931 enum radio_path rfpath, u8 rate)
932{
933 struct rtl_priv *rtlpriv = rtl_priv(hw);
934 struct rtl_phy *rtlphy = &(rtlpriv->phy);
935 u8 shift = 0, rate_section, tx_num;
936 char tx_pwr_diff = 0;
937
938 rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
939 rate);
940 tx_num = RF_TX_NUM_NONIMPLEMENT;
941
942 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
943 if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
944 tx_num = RF_2TX;
945 else
946 tx_num = RF_1TX;
947 }
948
949 switch (rate) {
950 case DESC92C_RATE6M:
951 case DESC92C_RATE24M:
952 case DESC92C_RATEMCS0:
953 case DESC92C_RATEMCS4:
954 case DESC92C_RATEMCS8:
955 case DESC92C_RATEMCS12:
956 shift = 0;
957 break;
958 case DESC92C_RATE1M:
959 case DESC92C_RATE2M:
960 case DESC92C_RATE9M:
961 case DESC92C_RATE36M:
962 case DESC92C_RATEMCS1:
963 case DESC92C_RATEMCS5:
964 case DESC92C_RATEMCS9:
965 case DESC92C_RATEMCS13:
966 shift = 8;
967 break;
968 case DESC92C_RATE5_5M:
969 case DESC92C_RATE12M:
970 case DESC92C_RATE48M:
971 case DESC92C_RATEMCS2:
972 case DESC92C_RATEMCS6:
973 case DESC92C_RATEMCS10:
974 case DESC92C_RATEMCS14:
975 shift = 16;
976 break;
977 case DESC92C_RATE11M:
978 case DESC92C_RATE18M:
979 case DESC92C_RATE54M:
980 case DESC92C_RATEMCS3:
981 case DESC92C_RATEMCS7:
982 case DESC92C_RATEMCS11:
983 case DESC92C_RATEMCS15:
984 shift = 24;
985 break;
986 default:
987 RT_ASSERT(true, "Rate_Section is Illegal\n");
988 break;
989 }
990 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
991 [rate_section] >> shift) & 0xff;
992
993 return tx_pwr_diff;
994}
995
996static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
997 u8 rate, u8 bandwidth, u8 channel)
998{
999 struct rtl_priv *rtlpriv = rtl_priv(hw);
1000 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1001 u8 index = (channel - 1);
1002 u8 txpower;
1003 u8 power_diff_byrate = 0;
1004
1005 if (channel > 14 || channel < 1) {
1006 index = 0;
1007 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1008 "Illegal channel!\n");
1009 }
1010 if (RTL8723E_RX_HAL_IS_CCK_RATE(rate))
1011 txpower = rtlefuse->txpwrlevel_cck[path][index];
1012 else if (DESC92C_RATE6M <= rate)
1013 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1014 else
1015 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1016 "invalid rate\n");
1017
1018 if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1019 !RTL8723E_RX_HAL_IS_CCK_RATE(rate))
1020 txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1021
1022 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1023 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1024 txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1025 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1026 txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1027 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1028 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1029 txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1030 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1031 txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1032 }
1033 if (rtlefuse->eeprom_regulatory != 2)
1034 power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1035 BAND_ON_2_4G,
1036 path, rate);
1037
1038 txpower += power_diff_byrate;
1039
1040 if (txpower > MAX_POWER_INDEX)
1041 txpower = MAX_POWER_INDEX;
1042
1043 return txpower;
1044}
1045
1046static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1047 u8 power_index, u8 path, u8 rate)
1048{
1049 struct rtl_priv *rtlpriv = rtl_priv(hw);
1050 if (path == RF90_PATH_A) {
1051 switch (rate) {
1052 case DESC92C_RATE1M:
1053 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1054 MASKBYTE1, power_index);
1055 break;
1056 case DESC92C_RATE2M:
1057 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1058 MASKBYTE1, power_index);
1059 break;
1060 case DESC92C_RATE5_5M:
1061 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1062 MASKBYTE2, power_index);
1063 break;
1064 case DESC92C_RATE11M:
1065 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1066 MASKBYTE3, power_index);
1067 break;
1068 case DESC92C_RATE6M:
1069 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1070 MASKBYTE0, power_index);
1071 break;
1072 case DESC92C_RATE9M:
1073 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1074 MASKBYTE1, power_index);
1075 break;
1076 case DESC92C_RATE12M:
1077 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1078 MASKBYTE2, power_index);
1079 break;
1080 case DESC92C_RATE18M:
1081 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1082 MASKBYTE3, power_index);
1083 break;
1084 case DESC92C_RATE24M:
1085 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1086 MASKBYTE0, power_index);
1087 break;
1088 case DESC92C_RATE36M:
1089 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1090 MASKBYTE1, power_index);
1091 break;
1092 case DESC92C_RATE48M:
1093 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1094 MASKBYTE2, power_index);
1095 break;
1096 case DESC92C_RATE54M:
1097 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1098 MASKBYTE3, power_index);
1099 break;
1100 case DESC92C_RATEMCS0:
1101 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1102 MASKBYTE0, power_index);
1103 break;
1104 case DESC92C_RATEMCS1:
1105 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1106 MASKBYTE1, power_index);
1107 break;
1108 case DESC92C_RATEMCS2:
1109 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1110 MASKBYTE2, power_index);
1111 break;
1112 case DESC92C_RATEMCS3:
1113 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1114 MASKBYTE3, power_index);
1115 break;
1116 case DESC92C_RATEMCS4:
1117 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1118 MASKBYTE0, power_index);
1119 break;
1120 case DESC92C_RATEMCS5:
1121 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1122 MASKBYTE1, power_index);
1123 break;
1124 case DESC92C_RATEMCS6:
1125 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1126 MASKBYTE2, power_index);
1127 break;
1128 case DESC92C_RATEMCS7:
1129 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1130 MASKBYTE3, power_index);
1131 break;
1132 case DESC92C_RATEMCS8:
1133 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1134 MASKBYTE0, power_index);
1135 break;
1136 case DESC92C_RATEMCS9:
1137 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1138 MASKBYTE1, power_index);
1139 break;
1140 case DESC92C_RATEMCS10:
1141 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1142 MASKBYTE2, power_index);
1143 break;
1144 case DESC92C_RATEMCS11:
1145 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1146 MASKBYTE3, power_index);
1147 break;
1148 default:
1149 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1150 "Invalid Rate!!\n");
1151 break;
1152 }
1153 } else {
1154 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1155 }
1156}
1157
1158void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1159{
1160 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1161 u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1162 DESC92C_RATE5_5M, DESC92C_RATE11M};
1163 u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1164 DESC92C_RATE12M, DESC92C_RATE18M,
1165 DESC92C_RATE24M, DESC92C_RATE36M,
1166 DESC92C_RATE48M, DESC92C_RATE54M};
1167 u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1168 DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1169 DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1170 DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1171 u8 i, size;
1172 u8 power_index;
1173
1174 if (!rtlefuse->txpwr_fromeprom)
1175 return;
1176
1177 size = sizeof(cck_rates) / sizeof(u8);
1178 for (i = 0; i < size; i++) {
1179 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1180 cck_rates[i],
1181 rtl_priv(hw)->phy.current_chan_bw,
1182 channel);
1183 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1184 cck_rates[i]);
1185 }
1186 size = sizeof(ofdm_rates) / sizeof(u8);
1187 for (i = 0; i < size; i++) {
1188 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1189 ofdm_rates[i],
1190 rtl_priv(hw)->phy.current_chan_bw,
1191 channel);
1192 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1193 ofdm_rates[i]);
1194 }
1195 size = sizeof(ht_rates_1t) / sizeof(u8);
1196 for (i = 0; i < size; i++) {
1197 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1198 ht_rates_1t[i],
1199 rtl_priv(hw)->phy.current_chan_bw,
1200 channel);
1201 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1202 ht_rates_1t[i]);
1203 }
1204}
1205
1206void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1207{
1208 struct rtl_priv *rtlpriv = rtl_priv(hw);
1209 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1210 enum io_type iotype;
1211
1212 if (!is_hal_stop(rtlhal)) {
1213 switch (operation) {
1214 case SCAN_OPT_BACKUP:
1215 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1216 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1217 (u8 *)&iotype);
1218 break;
1219 case SCAN_OPT_RESTORE:
1220 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1221 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1222 (u8 *)&iotype);
1223 break;
1224 default:
1225 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1226 "Unknown Scan Backup operation.\n");
1227 break;
1228 }
1229 }
1230}
1231
1232void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1233{
1234 struct rtl_priv *rtlpriv = rtl_priv(hw);
1235 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1236 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1237 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1238 u8 reg_bw_opmode;
1239 u8 reg_prsr_rsc;
1240
1241 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1242 "Switch to %s bandwidth\n",
1243 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1244 "20MHz" : "40MHz");
1245
1246 if (is_hal_stop(rtlhal)) {
1247 rtlphy->set_bwmode_inprogress = false;
1248 return;
1249 }
1250
1251 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1252 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1253
1254 switch (rtlphy->current_chan_bw) {
1255 case HT_CHANNEL_WIDTH_20:
1256 reg_bw_opmode |= BW_OPMODE_20MHZ;
1257 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1258 break;
1259 case HT_CHANNEL_WIDTH_20_40:
1260 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1261 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1262 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1263 (mac->cur_40_prime_sc << 5);
1264 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1265 break;
1266 default:
1267 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1268 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1269 break;
1270 }
1271
1272 switch (rtlphy->current_chan_bw) {
1273 case HT_CHANNEL_WIDTH_20:
1274 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1275 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1276 break;
1277 case HT_CHANNEL_WIDTH_20_40:
1278 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1279 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1280 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1281 (mac->cur_40_prime_sc >> 1));
1282 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1283 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1284 (mac->cur_40_prime_sc ==
1285 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1286 break;
1287 default:
1288 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1289 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1290 break;
1291 }
1292 rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1293 rtlphy->set_bwmode_inprogress = false;
1294 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1295}
1296
1297void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1298 enum nl80211_channel_type ch_type)
1299{
1300 struct rtl_priv *rtlpriv = rtl_priv(hw);
1301 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1302 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1303 u8 tmp_bw = rtlphy->current_chan_bw;
1304
1305 if (rtlphy->set_bwmode_inprogress)
1306 return;
1307 rtlphy->set_bwmode_inprogress = true;
1308 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1309 rtl8723be_phy_set_bw_mode_callback(hw);
1310 } else {
1311 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1312 "false driver sleep or unload\n");
1313 rtlphy->set_bwmode_inprogress = false;
1314 rtlphy->current_chan_bw = tmp_bw;
1315 }
1316}
1317
1318void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1319{
1320 struct rtl_priv *rtlpriv = rtl_priv(hw);
1321 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1322 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1323 u32 delay;
1324
1325 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1326 "switch to channel%d\n", rtlphy->current_channel);
1327 if (is_hal_stop(rtlhal))
1328 return;
1329 do {
1330 if (!rtlphy->sw_chnl_inprogress)
1331 break;
1332 if (!rtl8723be_phy_sw_chn_step_by_step(hw,
1333 rtlphy->current_channel,
1334 &rtlphy->sw_chnl_stage,
1335 &rtlphy->sw_chnl_step,
1336 &delay)) {
1337 if (delay > 0)
1338 mdelay(delay);
1339 else
1340 continue;
1341 } else {
1342 rtlphy->sw_chnl_inprogress = false;
1343 }
1344 break;
1345 } while (true);
1346 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1347}
1348
1349u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1350{
1351 struct rtl_priv *rtlpriv = rtl_priv(hw);
1352 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1353 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1354
1355 if (rtlphy->sw_chnl_inprogress)
1356 return 0;
1357 if (rtlphy->set_bwmode_inprogress)
1358 return 0;
1359 RT_ASSERT((rtlphy->current_channel <= 14),
1360 "WIRELESS_MODE_G but channel>14");
1361 rtlphy->sw_chnl_inprogress = true;
1362 rtlphy->sw_chnl_stage = 0;
1363 rtlphy->sw_chnl_step = 0;
1364 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1365 rtl8723be_phy_sw_chnl_callback(hw);
1366 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1367 "sw_chnl_inprogress false schdule "
1368 "workitem current channel %d\n",
1369 rtlphy->current_channel);
1370 rtlphy->sw_chnl_inprogress = false;
1371 } else {
1372 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1373 "sw_chnl_inprogress false driver sleep or"
1374 " unload\n");
1375 rtlphy->sw_chnl_inprogress = false;
1376 }
1377 return 1;
1378}
1379
1380static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
1381 u8 channel, u8 *stage,
1382 u8 *step, u32 *delay)
1383{
1384 struct rtl_priv *rtlpriv = rtl_priv(hw);
1385 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1386 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1387 u32 precommoncmdcnt;
1388 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1389 u32 postcommoncmdcnt;
1390 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1391 u32 rfdependcmdcnt;
1392 struct swchnlcmd *currentcmd = NULL;
1393 u8 rfpath;
1394 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1395
1396 precommoncmdcnt = 0;
1397 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1398 MAX_PRECMD_CNT,
1399 CMDID_SET_TXPOWEROWER_LEVEL,
1400 0, 0, 0);
1401 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1402 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1403 postcommoncmdcnt = 0;
1404 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1405 MAX_POSTCMD_CNT, CMDID_END,
1406 0, 0, 0);
1407 rfdependcmdcnt = 0;
1408
1409 RT_ASSERT((channel >= 1 && channel <= 14),
1410 "illegal channel for Zebra: %d\n", channel);
1411
1412 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1413 MAX_RFDEPENDCMD_CNT,
1414 CMDID_RF_WRITEREG,
1415 RF_CHNLBW, channel, 10);
1416
1417 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1418 MAX_RFDEPENDCMD_CNT,
1419 CMDID_END, 0, 0, 0);
1420
1421 do {
1422 switch (*stage) {
1423 case 0:
1424 currentcmd = &precommoncmd[*step];
1425 break;
1426 case 1:
1427 currentcmd = &rfdependcmd[*step];
1428 break;
1429 case 2:
1430 currentcmd = &postcommoncmd[*step];
1431 break;
1432 }
1433
1434 if (currentcmd->cmdid == CMDID_END) {
1435 if ((*stage) == 2) {
1436 return true;
1437 } else {
1438 (*stage)++;
1439 (*step) = 0;
1440 continue;
1441 }
1442 }
1443
1444 switch (currentcmd->cmdid) {
1445 case CMDID_SET_TXPOWEROWER_LEVEL:
1446 rtl8723be_phy_set_txpower_level(hw, channel);
1447 break;
1448 case CMDID_WRITEPORT_ULONG:
1449 rtl_write_dword(rtlpriv, currentcmd->para1,
1450 currentcmd->para2);
1451 break;
1452 case CMDID_WRITEPORT_USHORT:
1453 rtl_write_word(rtlpriv, currentcmd->para1,
1454 (u16) currentcmd->para2);
1455 break;
1456 case CMDID_WRITEPORT_UCHAR:
1457 rtl_write_byte(rtlpriv, currentcmd->para1,
1458 (u8) currentcmd->para2);
1459 break;
1460 case CMDID_RF_WRITEREG:
1461 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1462 rtlphy->rfreg_chnlval[rfpath] =
1463 ((rtlphy->rfreg_chnlval[rfpath] &
1464 0xfffffc00) | currentcmd->para2);
1465
1466 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1467 currentcmd->para1,
1468 RFREG_OFFSET_MASK,
1469 rtlphy->rfreg_chnlval[rfpath]);
1470 }
1471 break;
1472 default:
1473 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1474 "switch case not process\n");
1475 break;
1476 }
1477
1478 break;
1479 } while (true);
1480
1481 (*delay) = currentcmd->msdelay;
1482 (*step)++;
1483 return false;
1484}
1485
1486static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1487{
1488 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1489 u8 result = 0x00;
1490
1491 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
1492 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
1493 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
1494 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
1495
1496 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1497 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1498 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1499
1500 mdelay(IQK_DELAY_TIME);
1501
1502 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1503 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1504 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1505 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1506
1507 if (!(reg_eac & BIT(28)) &&
1508 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1509 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1510 result |= 0x01;
1511 return result;
1512}
1513
1514static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8],
1515 u8 c1, u8 c2)
1516{
1517 u32 i, j, diff, simularity_bitmap, bound;
1518 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1519
1520 u8 final_candidate[2] = { 0xFF, 0xFF };
1521 bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1522
1523 if (is2t)
1524 bound = 8;
1525 else
1526 bound = 4;
1527
1528 simularity_bitmap = 0;
1529
1530 for (i = 0; i < bound; i++) {
1531 diff = (result[c1][i] > result[c2][i]) ?
1532 (result[c1][i] - result[c2][i]) :
1533 (result[c2][i] - result[c1][i]);
1534
1535 if (diff > MAX_TOLERANCE) {
1536 if ((i == 2 || i == 6) && !simularity_bitmap) {
1537 if (result[c1][i] + result[c1][i + 1] == 0)
1538 final_candidate[(i / 4)] = c2;
1539 else if (result[c2][i] + result[c2][i + 1] == 0)
1540 final_candidate[(i / 4)] = c1;
1541 else
1542 simularity_bitmap |= (1 << i);
1543 } else {
1544 simularity_bitmap |= (1 << i);
1545 }
1546 }
1547 }
1548
1549 if (simularity_bitmap == 0) {
1550 for (i = 0; i < (bound / 4); i++) {
1551 if (final_candidate[i] != 0xFF) {
1552 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1553 result[3][j] =
1554 result[final_candidate[i]][j];
1555 bresult = false;
1556 }
1557 }
1558 return bresult;
1559 } else if (!(simularity_bitmap & 0x0F)) {
1560 for (i = 0; i < 4; i++)
1561 result[3][i] = result[c1][i];
1562 return false;
1563 } else if (!(simularity_bitmap & 0xF0) && is2t) {
1564 for (i = 4; i < 8; i++)
1565 result[3][i] = result[c1][i];
1566 return false;
1567 } else {
1568 return false;
1569 }
1570}
1571
1572static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
1573 long result[][8], u8 t, bool is2t)
1574{
1575 struct rtl_priv *rtlpriv = rtl_priv(hw);
1576 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1577 u32 i;
1578 u8 patha_ok;
1579 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1580 0x85c, 0xe6c, 0xe70, 0xe74,
1581 0xe78, 0xe7c, 0xe80, 0xe84,
1582 0xe88, 0xe8c, 0xed0, 0xed4,
1583 0xed8, 0xedc, 0xee0, 0xeec
1584 };
1585
1586 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1587 0x522, 0x550, 0x551, 0x040
1588 };
1589 u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1590 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
1591 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
1592 0x870, 0x860,
1593 0x864, 0x800
1594 };
1595 const u32 retrycount = 2;
1596 u32 path_sel_bb, path_sel_rf;
1597 u8 tmp_reg_c50, tmp_reg_c58;
1598
1599 tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
1600 tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
1601
1602 if (t == 0) {
1603 rtl8723_save_adda_registers(hw, adda_reg,
1604 rtlphy->adda_backup, 16);
1605 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1606 rtlphy->iqk_mac_backup);
1607 rtl8723_save_adda_registers(hw, iqk_bb_reg,
1608 rtlphy->iqk_bb_backup,
1609 IQK_BB_REG_NUM);
1610 }
1611 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1612 if (t == 0) {
1613 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1614 RFPGA0_XA_HSSIPARAMETER1,
1615 BIT(8));
1616 }
1617 if (!rtlphy->rfpi_enable)
1618 rtl8723_phy_pi_mode_switch(hw, true);
1619
1620 path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
1621 path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff);
1622
1623 /*BB Setting*/
1624 rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
1625 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1626 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1627 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1628
1629 rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
1630 rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
1631 rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
1632 rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
1633
1634 if (is2t)
1635 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASKDWORD, 0x10000);
1636 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1637 rtlphy->iqk_mac_backup);
1638 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1639
1640 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1641 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1642 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
1643 for (i = 0; i < retrycount; i++) {
1644 patha_ok = _rtl8723be_phy_path_a_iqk(hw, is2t);
1645 if (patha_ok == 0x01) {
1646 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1647 "Path A Tx IQK Success!!\n");
1648 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1649 0x3FF0000) >> 16;
1650 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1651 0x3FF0000) >> 16;
1652 break;
1653 }
1654 }
1655
1656 if (0 == patha_ok)
1657 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1658 "Path A IQK Success!!\n");
1659 if (is2t) {
1660 rtl8723_phy_path_a_standby(hw);
1661 rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1662 }
1663
1664 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1665
1666 if (t != 0) {
1667 if (!rtlphy->rfpi_enable)
1668 rtl8723_phy_pi_mode_switch(hw, false);
1669 rtl8723_phy_reload_adda_registers(hw, adda_reg,
1670 rtlphy->adda_backup, 16);
1671 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1672 rtlphy->iqk_mac_backup);
1673 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1674 rtlphy->iqk_bb_backup,
1675 IQK_BB_REG_NUM);
1676
1677 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
1678 rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);
1679
1680 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
1681 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
1682 if (is2t) {
1683 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
1684 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
1685 }
1686 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1687 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1688 }
1689 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
1690}
1691
1692static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1693{
1694 struct rtl_priv *rtlpriv = rtl_priv(hw);
1695 u8 tmpreg;
1696 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1697
1698 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1699
1700 if ((tmpreg & 0x70) != 0)
1701 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1702 else
1703 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1704
1705 if ((tmpreg & 0x70) != 0) {
1706 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1707
1708 if (is2t)
1709 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1710 MASK12BITS);
1711
1712 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1713 (rf_a_mode & 0x8FFFF) | 0x10000);
1714
1715 if (is2t)
1716 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1717 (rf_b_mode & 0x8FFFF) | 0x10000);
1718 }
1719 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1720
1721 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
1722 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
1723
1724 mdelay(100);
1725
1726 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
1727
1728 if ((tmpreg & 0x70) != 0) {
1729 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1730 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1731
1732 if (is2t)
1733 rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
1734 MASK12BITS, rf_b_mode);
1735 } else {
1736 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1737 }
1738 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1739}
1740
1741static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1742 bool bmain, bool is2t)
1743{
1744 struct rtl_priv *rtlpriv = rtl_priv(hw);
1745 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1746 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1747 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1748
1749 if (is_hal_stop(rtlhal)) {
1750 u8 u1btmp;
1751 u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
1752 rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
1753 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1754 }
1755 if (is2t) {
1756 if (bmain)
1757 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1758 BIT(5) | BIT(6), 0x1);
1759 else
1760 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1761 BIT(5) | BIT(6), 0x2);
1762 } else {
1763 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
1764 rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
1765
1766 /* We use the RF definition of MAIN and AUX,
1767 * left antenna and right antenna repectively.
1768 * Default output at AUX.
1769 */
1770 if (bmain) {
1771 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1772 BIT(14) | BIT(13) | BIT(12), 0);
1773 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1774 BIT(5) | BIT(4) | BIT(3), 0);
1775 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1776 rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 0);
1777 } else {
1778 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1779 BIT(14) | BIT(13) | BIT(12), 1);
1780 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1781 BIT(5) | BIT(4) | BIT(3), 1);
1782 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1783 rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 1);
1784 }
1785 }
1786}
1787
1788#undef IQK_ADDA_REG_NUM
1789#undef IQK_DELAY_TIME
1790
1791void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1792{
1793 struct rtl_priv *rtlpriv = rtl_priv(hw);
1794 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1795 long result[4][8];
1796 u8 i, final_candidate;
1797 bool patha_ok, pathb_ok;
1798 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1799 reg_ecc, reg_tmp = 0;
1800 bool is12simular, is13simular, is23simular;
1801 u32 iqk_bb_reg[9] = {
1802 ROFDM0_XARXIQIMBALANCE,
1803 ROFDM0_XBRXIQIMBALANCE,
1804 ROFDM0_ECCATHRESHOLD,
1805 ROFDM0_AGCRSSITABLE,
1806 ROFDM0_XATXIQIMBALANCE,
1807 ROFDM0_XBTXIQIMBALANCE,
1808 ROFDM0_XCTXAFE,
1809 ROFDM0_XDTXAFE,
1810 ROFDM0_RXIQEXTANTA
1811 };
1812
1813 if (recovery) {
1814 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1815 rtlphy->iqk_bb_backup, 9);
1816 return;
1817 }
1818
1819 for (i = 0; i < 8; i++) {
1820 result[0][i] = 0;
1821 result[1][i] = 0;
1822 result[2][i] = 0;
1823 result[3][i] = 0;
1824 }
1825 final_candidate = 0xff;
1826 patha_ok = false;
1827 pathb_ok = false;
1828 is12simular = false;
1829 is23simular = false;
1830 is13simular = false;
1831 for (i = 0; i < 3; i++) {
1832 if (get_rf_type(rtlphy) == RF_2T2R)
1833 _rtl8723be_phy_iq_calibrate(hw, result, i, true);
1834 else
1835 _rtl8723be_phy_iq_calibrate(hw, result, i, false);
1836 if (i == 1) {
1837 is12simular = phy_similarity_cmp(hw, result, 0, 1);
1838 if (is12simular) {
1839 final_candidate = 0;
1840 break;
1841 }
1842 }
1843 if (i == 2) {
1844 is13simular = phy_similarity_cmp(hw, result, 0, 2);
1845 if (is13simular) {
1846 final_candidate = 0;
1847 break;
1848 }
1849 is23simular = phy_similarity_cmp(hw, result, 1, 2);
1850 if (is23simular) {
1851 final_candidate = 1;
1852 } else {
1853 for (i = 0; i < 8; i++)
1854 reg_tmp += result[3][i];
1855
1856 if (reg_tmp != 0)
1857 final_candidate = 3;
1858 else
1859 final_candidate = 0xFF;
1860 }
1861 }
1862 }
1863 for (i = 0; i < 4; i++) {
1864 reg_e94 = result[i][0];
1865 reg_e9c = result[i][1];
1866 reg_ea4 = result[i][2];
1867 reg_eac = result[i][3];
1868 reg_eb4 = result[i][4];
1869 reg_ebc = result[i][5];
1870 reg_ec4 = result[i][6];
1871 reg_ecc = result[i][7];
1872 }
1873 if (final_candidate != 0xff) {
1874 reg_e94 = result[final_candidate][0];
1875 rtlphy->reg_e94 = reg_e94;
1876 reg_e9c = result[final_candidate][1];
1877 rtlphy->reg_e9c = reg_e9c;
1878 reg_ea4 = result[final_candidate][2];
1879 reg_eac = result[final_candidate][3];
1880 reg_eb4 = result[final_candidate][4];
1881 rtlphy->reg_eb4 = reg_eb4;
1882 reg_ebc = result[final_candidate][5];
1883 rtlphy->reg_ebc = reg_ebc;
1884 reg_ec4 = result[final_candidate][6];
1885 reg_ecc = result[final_candidate][7];
1886 patha_ok = true;
1887 pathb_ok = true;
1888 } else {
1889 rtlphy->reg_e94 = 0x100;
1890 rtlphy->reg_eb4 = 0x100;
1891 rtlphy->reg_e9c = 0x0;
1892 rtlphy->reg_ebc = 0x0;
1893 }
1894 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1895 rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1896 final_candidate,
1897 (reg_ea4 == 0));
1898 if (final_candidate != 0xFF) {
1899 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
1900 rtlphy->iqk_matrix[0].value[0][i] =
1901 result[final_candidate][i];
1902 rtlphy->iqk_matrix[0].iqk_done = true;
1903 }
1904 rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1905}
1906
1907void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
1908{
1909 struct rtl_priv *rtlpriv = rtl_priv(hw);
1910 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1911 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1912 u32 timeout = 2000, timecount = 0;
1913
1914 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
1915 udelay(50);
1916 timecount += 50;
1917 }
1918
1919 rtlphy->lck_inprogress = true;
1920 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1921 "LCK:Start!!! currentband %x delay %d ms\n",
1922 rtlhal->current_bandtype, timecount);
1923
1924 _rtl8723be_phy_lc_calibrate(hw, false);
1925
1926 rtlphy->lck_inprogress = false;
1927}
1928
1929void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
1930{
1931 struct rtl_priv *rtlpriv = rtl_priv(hw);
1932 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1933
1934 if (rtlphy->apk_done)
1935 return;
1936
1937 return;
1938}
1939
1940void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1941{
1942 _rtl8723be_phy_set_rfpath_switch(hw, bmain, false);
1943}
1944
1945static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
1946{
1947 struct rtl_priv *rtlpriv = rtl_priv(hw);
1948 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1949
1950 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1951 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1952 rtlphy->current_io_type, rtlphy->set_io_inprogress);
1953 switch (rtlphy->current_io_type) {
1954 case IO_CMD_RESUME_DM_BY_SCAN:
1955 rtlpriv->dm_digtable.cur_igvalue =
1956 rtlphy->initgain_backup.xaagccore1;
1957 /*rtl92c_dm_write_dig(hw);*/
1958 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
1959 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
1960 break;
1961 case IO_CMD_PAUSE_DM_BY_SCAN:
1962 rtlphy->initgain_backup.xaagccore1 =
1963 rtlpriv->dm_digtable.cur_igvalue;
1964 rtlpriv->dm_digtable.cur_igvalue = 0x17;
1965 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
1966 break;
1967 default:
1968 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1969 "switch case not process\n");
1970 break;
1971 }
1972 rtlphy->set_io_inprogress = false;
1973 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1974 "(%#x)\n", rtlphy->current_io_type);
1975}
1976
1977bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1978{
1979 struct rtl_priv *rtlpriv = rtl_priv(hw);
1980 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1981 bool postprocessing = false;
1982
1983 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1984 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1985 iotype, rtlphy->set_io_inprogress);
1986 do {
1987 switch (iotype) {
1988 case IO_CMD_RESUME_DM_BY_SCAN:
1989 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1990 "[IO CMD] Resume DM after scan.\n");
1991 postprocessing = true;
1992 break;
1993 case IO_CMD_PAUSE_DM_BY_SCAN:
1994 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1995 "[IO CMD] Pause DM before scan.\n");
1996 postprocessing = true;
1997 break;
1998 default:
1999 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2000 "switch case not process\n");
2001 break;
2002 }
2003 } while (false);
2004 if (postprocessing && !rtlphy->set_io_inprogress) {
2005 rtlphy->set_io_inprogress = true;
2006 rtlphy->current_io_type = iotype;
2007 } else {
2008 return false;
2009 }
2010 rtl8723be_phy_set_io(hw);
2011 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2012 return true;
2013}
2014
2015static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2016{
2017 struct rtl_priv *rtlpriv = rtl_priv(hw);
2018
2019 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2020 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2021 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2022 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2023 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2024}
2025
2026static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2027{
2028 struct rtl_priv *rtlpriv = rtl_priv(hw);
2029
2030 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2031 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2032 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2033 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2034}
2035
2036static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2037 enum rf_pwrstate rfpwr_state)
2038{
2039 struct rtl_priv *rtlpriv = rtl_priv(hw);
2040 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2041 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2042 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2043 bool bresult = true;
2044 u8 i, queue_id;
2045 struct rtl8192_tx_ring *ring = NULL;
2046
2047 switch (rfpwr_state) {
2048 case ERFON:
2049 if ((ppsc->rfpwr_state == ERFOFF) &&
2050 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2051 bool rtstatus;
2052 u32 initialize_count = 0;
2053 do {
2054 initialize_count++;
2055 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2056 "IPS Set eRf nic enable\n");
2057 rtstatus = rtl_ps_enable_nic(hw);
2058 } while (!rtstatus && (initialize_count < 10));
2059 RT_CLEAR_PS_LEVEL(ppsc,
2060 RT_RF_OFF_LEVL_HALT_NIC);
2061 } else {
2062 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2063 "Set ERFON sleeped:%d ms\n",
2064 jiffies_to_msecs(jiffies -
2065 ppsc->last_sleep_jiffies));
2066 ppsc->last_awake_jiffies = jiffies;
2067 rtl8723be_phy_set_rf_on(hw);
2068 }
2069 if (mac->link_state == MAC80211_LINKED)
2070 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2071 else
2072 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2073 break;
2074 case ERFOFF:
2075 for (queue_id = 0, i = 0;
2076 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2077 ring = &pcipriv->dev.tx_ring[queue_id];
2078 if (skb_queue_len(&ring->queue) == 0) {
2079 queue_id++;
2080 continue;
2081 } else {
2082 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2083 "eRf Off/Sleep: %d times "
2084 "TcbBusyQueue[%d] =%d before "
2085 "doze!\n", (i + 1), queue_id,
2086 skb_queue_len(&ring->queue));
2087
2088 udelay(10);
2089 i++;
2090 }
2091 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2092 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2093 "\n ERFSLEEP: %d times "
2094 "TcbBusyQueue[%d] = %d !\n",
2095 MAX_DOZE_WAITING_TIMES_9x,
2096 queue_id,
2097 skb_queue_len(&ring->queue));
2098 break;
2099 }
2100 }
2101
2102 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2103 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2104 "IPS Set eRf nic disable\n");
2105 rtl_ps_disable_nic(hw);
2106 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2107 } else {
2108 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2109 rtlpriv->cfg->ops->led_control(hw,
2110 LED_CTL_NO_LINK);
2111 } else {
2112 rtlpriv->cfg->ops->led_control(hw,
2113 LED_CTL_POWER_OFF);
2114 }
2115 }
2116 break;
2117 case ERFSLEEP:
2118 if (ppsc->rfpwr_state == ERFOFF)
2119 break;
2120 for (queue_id = 0, i = 0;
2121 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2122 ring = &pcipriv->dev.tx_ring[queue_id];
2123 if (skb_queue_len(&ring->queue) == 0) {
2124 queue_id++;
2125 continue;
2126 } else {
2127 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2128 "eRf Off/Sleep: %d times "
2129 "TcbBusyQueue[%d] =%d before "
2130 "doze!\n", (i + 1), queue_id,
2131 skb_queue_len(&ring->queue));
2132
2133 udelay(10);
2134 i++;
2135 }
2136 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2137 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2138 "\n ERFSLEEP: %d times "
2139 "TcbBusyQueue[%d] = %d !\n",
2140 MAX_DOZE_WAITING_TIMES_9x,
2141 queue_id,
2142 skb_queue_len(&ring->queue));
2143 break;
2144 }
2145 }
2146 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2147 "Set ERFSLEEP awaked:%d ms\n",
2148 jiffies_to_msecs(jiffies -
2149 ppsc->last_awake_jiffies));
2150 ppsc->last_sleep_jiffies = jiffies;
2151 _rtl8723be_phy_set_rf_sleep(hw);
2152 break;
2153 default:
2154 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2155 "switch case not process\n");
2156 bresult = false;
2157 break;
2158 }
2159 if (bresult)
2160 ppsc->rfpwr_state = rfpwr_state;
2161 return bresult;
2162}
2163
2164bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2165 enum rf_pwrstate rfpwr_state)
2166{
2167 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2168
2169 bool bresult = false;
2170
2171 if (rfpwr_state == ppsc->rfpwr_state)
2172 return bresult;
2173 bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2174 return bresult;
2175}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.h b/drivers/net/wireless/rtlwifi/rtl8723be/phy.h
new file mode 100644
index 000000000000..444ef95bb6af
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.h
@@ -0,0 +1,217 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_PHY_H__
27#define __RTL8723BE_PHY_H__
28
29/*It must always set to 4, otherwise read efuse table secquence will be wrong.*/
30#define MAX_TX_COUNT 4
31#define TX_1S 0
32#define TX_2S 1
33
34#define MAX_POWER_INDEX 0x3F
35
36#define MAX_PRECMD_CNT 16
37#define MAX_RFDEPENDCMD_CNT 16
38#define MAX_POSTCMD_CNT 16
39
40#define MAX_DOZE_WAITING_TIMES_9x 64
41
42#define RT_CANNOT_IO(hw) false
43#define HIGHPOWER_RADIOA_ARRAYLEN 22
44
45#define IQK_ADDA_REG_NUM 16
46#define IQK_BB_REG_NUM 9
47#define MAX_TOLERANCE 5
48#define IQK_DELAY_TIME 10
49#define index_mapping_NUM 15
50
51#define APK_BB_REG_NUM 5
52#define APK_AFE_REG_NUM 16
53#define APK_CURVE_REG_NUM 4
54#define PATH_NUM 1
55
56#define LOOP_LIMIT 5
57#define MAX_STALL_TIME 50
58#define ANTENNADIVERSITYVALUE 0x80
59#define MAX_TXPWR_IDX_NMODE_92S 63
60#define RESET_CNT_LIMIT 3
61
62#define IQK_ADDA_REG_NUM 16
63#define IQK_MAC_REG_NUM 4
64
65#define RF6052_MAX_PATH 2
66
67#define CT_OFFSET_MAC_ADDR 0X16
68
69#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
70#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
71#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66
72#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
73#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
74
75#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
76#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
77
78#define CT_OFFSET_CHANNEL_PLAH 0x75
79#define CT_OFFSET_THERMAL_METER 0x78
80#define CT_OFFSET_RF_OPTION 0x79
81#define CT_OFFSET_VERSION 0x7E
82#define CT_OFFSET_CUSTOMER_ID 0x7F
83
84#define RTL92C_MAX_PATH_NUM 2
85
86enum hw90_block_e {
87 HW90_BLOCK_MAC = 0,
88 HW90_BLOCK_PHY0 = 1,
89 HW90_BLOCK_PHY1 = 2,
90 HW90_BLOCK_RF = 3,
91 HW90_BLOCK_MAXIMUM = 4,
92};
93
94enum baseband_config_type {
95 BASEBAND_CONFIG_PHY_REG = 0,
96 BASEBAND_CONFIG_AGC_TAB = 1,
97};
98
99enum ra_offset_area {
100 RA_OFFSET_LEGACY_OFDM1,
101 RA_OFFSET_LEGACY_OFDM2,
102 RA_OFFSET_HT_OFDM1,
103 RA_OFFSET_HT_OFDM2,
104 RA_OFFSET_HT_OFDM3,
105 RA_OFFSET_HT_OFDM4,
106 RA_OFFSET_HT_CCK,
107};
108
109enum antenna_path {
110 ANTENNA_NONE,
111 ANTENNA_D,
112 ANTENNA_C,
113 ANTENNA_CD,
114 ANTENNA_B,
115 ANTENNA_BD,
116 ANTENNA_BC,
117 ANTENNA_BCD,
118 ANTENNA_A,
119 ANTENNA_AD,
120 ANTENNA_AC,
121 ANTENNA_ACD,
122 ANTENNA_AB,
123 ANTENNA_ABD,
124 ANTENNA_ABC,
125 ANTENNA_ABCD
126};
127
128struct r_antenna_select_ofdm {
129 u32 r_tx_antenna:4;
130 u32 r_ant_l:4;
131 u32 r_ant_non_ht:4;
132 u32 r_ant_ht1:4;
133 u32 r_ant_ht2:4;
134 u32 r_ant_ht_s1:4;
135 u32 r_ant_non_ht_s1:4;
136 u32 ofdm_txsc:2;
137 u32 reserved:2;
138};
139
140struct r_antenna_select_cck {
141 u8 r_cckrx_enable_2:2;
142 u8 r_cckrx_enable:2;
143 u8 r_ccktx_enable:4;
144};
145
146
147struct efuse_contents {
148 u8 mac_addr[ETH_ALEN];
149 u8 cck_tx_power_idx[6];
150 u8 ht40_1s_tx_power_idx[6];
151 u8 ht40_2s_tx_power_idx_diff[3];
152 u8 ht20_tx_power_idx_diff[3];
153 u8 ofdm_tx_power_idx_diff[3];
154 u8 ht40_max_power_offset[3];
155 u8 ht20_max_power_offset[3];
156 u8 channel_plan;
157 u8 thermal_meter;
158 u8 rf_option[5];
159 u8 version;
160 u8 oem_id;
161 u8 regulatory;
162};
163
164struct tx_power_struct {
165 u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
166 u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
167 u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
168 u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
169 u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
170 u8 legacy_ht_txpowerdiff;
171 u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
172 u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
173 u8 pwrgroup_cnt;
174 u32 mcs_original_offset[4][16];
175};
176
177enum _ANT_DIV_TYPE {
178 NO_ANTDIV = 0xFF,
179 CG_TRX_HW_ANTDIV = 0x01,
180 CGCS_RX_HW_ANTDIV = 0x02,
181 FIXED_HW_ANTDIV = 0x03,
182 CG_TRX_SMART_ANTDIV = 0x04,
183 CGCS_RX_SW_ANTDIV = 0x05,
184};
185
186u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw,
187 enum radio_path rfpath,
188 u32 regaddr, u32 bitmask);
189void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw,
190 enum radio_path rfpath,
191 u32 regaddr, u32 bitmask, u32 data);
192bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw);
193bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw);
194bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw);
195void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
196void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw,
197 long *powerlevel);
198void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw,
199 u8 channel);
200void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw,
201 u8 operation);
202void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
203void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
204 enum nl80211_channel_type ch_type);
205void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw);
206u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw);
207void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
208 bool b_recovery);
209void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
210void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw);
211void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
212bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
213 enum radio_path rfpath);
214bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
215bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
216 enum rf_pwrstate rfpwr_state);
217#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c
new file mode 100644
index 000000000000..b5167e73fecf
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c
@@ -0,0 +1,106 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "pwrseqcmd.h"
27#include "pwrseq.h"
28
29
30/* drivers should parse below arrays and do the corresponding actions */
31/*3 Power on Array*/
32struct wlan_pwr_cfg rtl8723B_power_on_flow[RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS +
33 RTL8723B_TRANS_END_STEPS] = {
34 RTL8723B_TRANS_CARDEMU_TO_ACT
35 RTL8723B_TRANS_END
36};
37
38/*3Radio off GPIO Array */
39struct wlan_pwr_cfg rtl8723B_radio_off_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS
40 + RTL8723B_TRANS_END_STEPS] = {
41 RTL8723B_TRANS_ACT_TO_CARDEMU
42 RTL8723B_TRANS_END
43};
44
45/*3Card Disable Array*/
46struct wlan_pwr_cfg rtl8723B_card_disable_flow
47 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
48 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
49 RTL8723B_TRANS_END_STEPS] = {
50 RTL8723B_TRANS_ACT_TO_CARDEMU
51 RTL8723B_TRANS_CARDEMU_TO_CARDDIS
52 RTL8723B_TRANS_END
53};
54
55/*3 Card Enable Array*/
56struct wlan_pwr_cfg rtl8723B_card_enable_flow
57 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
58 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
59 RTL8723B_TRANS_END_STEPS] = {
60 RTL8723B_TRANS_CARDDIS_TO_CARDEMU
61 RTL8723B_TRANS_CARDEMU_TO_ACT
62 RTL8723B_TRANS_END
63};
64
65/*3Suspend Array*/
66struct wlan_pwr_cfg rtl8723B_suspend_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
67 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS +
68 RTL8723B_TRANS_END_STEPS] = {
69 RTL8723B_TRANS_ACT_TO_CARDEMU
70 RTL8723B_TRANS_CARDEMU_TO_SUS
71 RTL8723B_TRANS_END
72};
73
74/*3 Resume Array*/
75struct wlan_pwr_cfg rtl8723B_resume_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
76 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS +
77 RTL8723B_TRANS_END_STEPS] = {
78 RTL8723B_TRANS_SUS_TO_CARDEMU
79 RTL8723B_TRANS_CARDEMU_TO_ACT
80 RTL8723B_TRANS_END
81};
82
83/*3HWPDN Array*/
84struct wlan_pwr_cfg rtl8723B_hwpdn_flow[RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
85 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
86 RTL8723B_TRANS_END_STEPS] = {
87 RTL8723B_TRANS_ACT_TO_CARDEMU
88 RTL8723B_TRANS_CARDEMU_TO_PDN
89 RTL8723B_TRANS_END
90};
91
92/*3 Enter LPS */
93struct wlan_pwr_cfg rtl8723B_enter_lps_flow[RTL8723B_TRANS_ACT_TO_LPS_STEPS +
94 RTL8723B_TRANS_END_STEPS] = {
95 /*FW behavior*/
96 RTL8723B_TRANS_ACT_TO_LPS
97 RTL8723B_TRANS_END
98};
99
100/*3 Leave LPS */
101struct wlan_pwr_cfg rtl8723B_leave_lps_flow[RTL8723B_TRANS_LPS_TO_ACT_STEPS +
102 RTL8723B_TRANS_END_STEPS] = {
103 /*FW behavior*/
104 RTL8723B_TRANS_LPS_TO_ACT
105 RTL8723B_TRANS_END
106};
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h
new file mode 100644
index 000000000000..960b408216df
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h
@@ -0,0 +1,305 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_PWRSEQ_H__
27#define __RTL8723BE_PWRSEQ_H__
28
29#include "pwrseqcmd.h"
30/* Check document WM-20130425-JackieLau-RTL8723B_Power_Architecture v05.vsd
31 * There are 6 HW Power States:
32 * 0: POFF--Power Off
33 * 1: PDN--Power Down
34 * 2: CARDEMU--Card Emulation
35 * 3: ACT--Active Mode
36 * 4: LPS--Low Power State
37 * 5: SUS--Suspend
38 *
39 * The transition from different states are defined below
40 * TRANS_CARDEMU_TO_ACT
41 * TRANS_ACT_TO_CARDEMU
42 * TRANS_CARDEMU_TO_SUS
43 * TRANS_SUS_TO_CARDEMU
44 * TRANS_CARDEMU_TO_PDN
45 * TRANS_ACT_TO_LPS
46 * TRANS_LPS_TO_ACT
47 *
48 * TRANS_END
49 */
50#define RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS 23
51#define RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS 15
52#define RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS 15
53#define RTL8723B_TRANS_SUS_TO_CARDEMU_STEPS 15
54#define RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS 15
55#define RTL8723B_TRANS_PDN_TO_CARDEMU_STEPS 15
56#define RTL8723B_TRANS_ACT_TO_LPS_STEPS 15
57#define RTL8723B_TRANS_LPS_TO_ACT_STEPS 15
58#define RTL8723B_TRANS_END_STEPS 1
59
60#define RTL8723B_TRANS_CARDEMU_TO_ACT \
61 {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
62 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
63 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
64 {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
65 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
66 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
67 {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
68 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
69 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS}, \
70 {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
71 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
72 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0}, \
73 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
74 PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)|BIT(2)), 0}, \
75 {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
76 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0) , 0}, \
77 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
78 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
79 {0x0075, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
80 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0) , BIT(0)}, \
81 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
82 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
83 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
84 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \
85 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
86 PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \
87 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
88 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
89 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
90 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0}, \
91 {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
92 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), BIT(6)}, \
93 {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
94 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
95 {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
96 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
97 {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
98 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
99 {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
100 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
101 {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
102 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
103 {0x0068, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\
104 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3), BIT(3)}, \
105 {0x0069, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
106 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), BIT(6)},
107
108#define RTL8723B_TRANS_ACT_TO_CARDEMU \
109 {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
110 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \
111 {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
112 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
113 {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
114 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
115 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
116 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
117 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
118 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, \
119 {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
120 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6), 0}, \
121 {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
122 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \
123 PWR_CMD_WRITE, BIT(5), BIT(5)}, \
124 {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
125 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \
126 PWR_CMD_WRITE, BIT(0), 0},
127
128#define RTL8723B_TRANS_CARDEMU_TO_SUS \
129 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
130 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4) | BIT(3), (BIT(4) | BIT(3))}, \
131 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
132 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, \
133 PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, \
134 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
135 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \
136 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
137 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, \
138 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
139 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)},\
140 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
141 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
142 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
143 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0},
144
145#define RTL8723B_TRANS_SUS_TO_CARDEMU \
146 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
147 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, \
148 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
149 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
150 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
151 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
152 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
153 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
154 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
155 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0},
156
157#define RTL8723B_TRANS_CARDEMU_TO_CARDDIS \
158 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
159 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, \
160 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
161 PWR_INTF_USB_MSK | PWR_INTF_SDIO_MSK, \
162 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, \
163 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
164 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, \
165 {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
166 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 1}, \
167 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
168 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \
169 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
170 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \
171 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
172 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0},
173
174#define RTL8723B_TRANS_CARDDIS_TO_CARDEMU \
175 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
176 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, \
177 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
178 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \
179 {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
180 PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \
181 {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
182 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
183 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
184 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \
185 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
186 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
187 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
188 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},
189
190#define RTL8723B_TRANS_CARDEMU_TO_PDN \
191 {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
192 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, \
193 {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \
194 PWR_INTF_SDIO_MSK | PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, \
195 PWR_CMD_WRITE, 0xFF, 0x20}, \
196 {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
197 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
198 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
199 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},
200
201#define RTL8723B_TRANS_PDN_TO_CARDEMU \
202 {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
203 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},
204
205#define RTL8723B_TRANS_ACT_TO_LPS \
206 {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
207 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
208 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
209 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
210 {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
211 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
212 {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
213 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
214 {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
215 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
216 {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
217 PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \
218 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
219 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \
220 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
221 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \
222 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
223 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
224 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
225 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03}, \
226 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
227 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \
228 {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
229 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00}, \
230 {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
231 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)},
232
233#define RTL8723B_TRANS_LPS_TO_ACT \
234 {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \
235 PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, \
236 {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \
237 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \
238 {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \
239 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \
240 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
241 PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \
242 {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
243 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \
244 {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
245 PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \
246 {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
247 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \
248 {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
249 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \
250 {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
251 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \
252 {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
253 PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1) | BIT(0), BIT(1) | BIT(0)}, \
254 {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \
255 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},
256
257#define RTL8723B_TRANS_END \
258 {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, 0, \
259 PWR_CMD_END, 0, 0},
260
261extern struct wlan_pwr_cfg rtl8723B_power_on_flow
262 [RTL8723B_TRANS_CARDEMU_TO_ACT_STEPS +
263 RTL8723B_TRANS_END_STEPS];
264extern struct wlan_pwr_cfg rtl8723B_radio_off_flow
265 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
266 RTL8723B_TRANS_END_STEPS];
267extern struct wlan_pwr_cfg rtl8723B_card_disable_flow
268 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
269 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
270 RTL8723B_TRANS_END_STEPS];
271extern struct wlan_pwr_cfg rtl8723B_card_enable_flow
272 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
273 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
274 RTL8723B_TRANS_END_STEPS];
275extern struct wlan_pwr_cfg rtl8723B_suspend_flow
276 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
277 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS +
278 RTL8723B_TRANS_END_STEPS];
279extern struct wlan_pwr_cfg rtl8723B_resume_flow
280 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
281 RTL8723B_TRANS_CARDEMU_TO_SUS_STEPS +
282 RTL8723B_TRANS_END_STEPS];
283extern struct wlan_pwr_cfg rtl8723B_hwpdn_flow
284 [RTL8723B_TRANS_ACT_TO_CARDEMU_STEPS +
285 RTL8723B_TRANS_CARDEMU_TO_PDN_STEPS +
286 RTL8723B_TRANS_END_STEPS];
287extern struct wlan_pwr_cfg rtl8723B_enter_lps_flow
288 [RTL8723B_TRANS_ACT_TO_LPS_STEPS +
289 RTL8723B_TRANS_END_STEPS];
290extern struct wlan_pwr_cfg rtl8723B_leave_lps_flow
291 [RTL8723B_TRANS_LPS_TO_ACT_STEPS +
292 RTL8723B_TRANS_END_STEPS];
293
294/* RTL8723 Power Configuration CMDs for PCIe interface */
295#define RTL8723_NIC_PWR_ON_FLOW rtl8723B_power_on_flow
296#define RTL8723_NIC_RF_OFF_FLOW rtl8723B_radio_off_flow
297#define RTL8723_NIC_DISABLE_FLOW rtl8723B_card_disable_flow
298#define RTL8723_NIC_ENABLE_FLOW rtl8723B_card_enable_flow
299#define RTL8723_NIC_SUSPEND_FLOW rtl8723B_suspend_flow
300#define RTL8723_NIC_RESUME_FLOW rtl8723B_resume_flow
301#define RTL8723_NIC_PDN_FLOW rtl8723B_hwpdn_flow
302#define RTL8723_NIC_LPS_ENTER_FLOW rtl8723B_enter_lps_flow
303#define RTL8723_NIC_LPS_LEAVE_FLOW rtl8723B_leave_lps_flow
304
305#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c
new file mode 100644
index 000000000000..e4a507a756fb
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c
@@ -0,0 +1,140 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "pwrseq.h"
27
28/* Description:
29 * This routine deal with the Power Configuration CMDs
30 * parsing for RTL8723/RTL8188E Series IC.
31 * Assumption:
32 * We should follow specific format which was released from HW SD.
33 *
34 * 2011.07.07, added by Roger.
35 */
36bool rtlbe_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
37 u8 fab_version, u8 interface_type,
38 struct wlan_pwr_cfg pwrcfgcmd[])
39
40{
41 struct wlan_pwr_cfg pwr_cfg_cmd = {0};
42 bool b_polling_bit = false;
43 u32 ary_idx = 0;
44 u8 value = 0;
45 u32 offset = 0;
46 u32 polling_count = 0;
47 u32 max_polling_cnt = 5000;
48
49 do {
50 pwr_cfg_cmd = pwrcfgcmd[ary_idx];
51 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
52 "rtlbe_hal_pwrseqcmdparsing(): "
53 "offset(%#x),cut_msk(%#x), fab_msk(%#x),"
54 "interface_msk(%#x), base(%#x), "
55 "cmd(%#x), msk(%#x), value(%#x)\n",
56 GET_PWR_CFG_OFFSET(pwr_cfg_cmd),
57 GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd),
58 GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd),
59 GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd),
60 GET_PWR_CFG_BASE(pwr_cfg_cmd),
61 GET_PWR_CFG_CMD(pwr_cfg_cmd),
62 GET_PWR_CFG_MASK(pwr_cfg_cmd),
63 GET_PWR_CFG_VALUE(pwr_cfg_cmd));
64
65 if ((GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd)&fab_version) &&
66 (GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd)&cut_version) &&
67 (GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd)&interface_type)) {
68 switch (GET_PWR_CFG_CMD(pwr_cfg_cmd)) {
69 case PWR_CMD_READ:
70 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
71 "rtlbe_hal_pwrseqcmdparsing(): "
72 "PWR_CMD_READ\n");
73 break;
74 case PWR_CMD_WRITE:
75 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
76 "rtlbe_hal_pwrseqcmdparsing(): "
77 "PWR_CMD_WRITE\n");
78 offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd);
79
80 /*Read the value from system register*/
81 value = rtl_read_byte(rtlpriv, offset);
82 value &= (~(GET_PWR_CFG_MASK(pwr_cfg_cmd)));
83 value = value | (GET_PWR_CFG_VALUE(pwr_cfg_cmd)
84 & GET_PWR_CFG_MASK(pwr_cfg_cmd));
85
86 /*Write the value back to sytem register*/
87 rtl_write_byte(rtlpriv, offset, value);
88 break;
89 case PWR_CMD_POLLING:
90 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
91 "rtlbe_hal_pwrseqcmdparsing(): "
92 "PWR_CMD_POLLING\n");
93 b_polling_bit = false;
94 offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd);
95
96 do {
97 value = rtl_read_byte(rtlpriv, offset);
98
99 value &= GET_PWR_CFG_MASK(pwr_cfg_cmd);
100 if (value ==
101 (GET_PWR_CFG_VALUE(pwr_cfg_cmd) &
102 GET_PWR_CFG_MASK(pwr_cfg_cmd)))
103 b_polling_bit = true;
104 else
105 udelay(10);
106
107 if (polling_count++ > max_polling_cnt)
108 return false;
109
110 } while (!b_polling_bit);
111 break;
112 case PWR_CMD_DELAY:
113 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
114 "rtlbe_hal_pwrseqcmdparsing(): "
115 "PWR_CMD_DELAY\n");
116 if (GET_PWR_CFG_VALUE(pwr_cfg_cmd) ==
117 PWRSEQ_DELAY_US)
118 udelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd));
119 else
120 mdelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd));
121 break;
122 case PWR_CMD_END:
123 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
124 "rtlbe_hal_pwrseqcmdparsing(): "
125 "PWR_CMD_END\n");
126 return true;
127 break;
128 default:
129 RT_ASSERT(false,
130 "rtlbe_hal_pwrseqcmdparsing(): "
131 "Unknown CMD!!\n");
132 break;
133 }
134 }
135
136 ary_idx++;
137 } while (1);
138
139 return true;
140}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h
new file mode 100644
index 000000000000..ce14a3b5cb71
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h
@@ -0,0 +1,95 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_PWRSEQCMD_H__
27#define __RTL8723BE_PWRSEQCMD_H__
28
29#include "../wifi.h"
30/*---------------------------------------------*/
31/*The value of cmd: 4 bits */
32/*---------------------------------------------*/
33#define PWR_CMD_READ 0x00
34#define PWR_CMD_WRITE 0x01
35#define PWR_CMD_POLLING 0x02
36#define PWR_CMD_DELAY 0x03
37#define PWR_CMD_END 0x04
38
39/* define the base address of each block */
40#define PWR_BASEADDR_MAC 0x00
41#define PWR_BASEADDR_USB 0x01
42#define PWR_BASEADDR_PCIE 0x02
43#define PWR_BASEADDR_SDIO 0x03
44
45#define PWR_INTF_SDIO_MSK BIT(0)
46#define PWR_INTF_USB_MSK BIT(1)
47#define PWR_INTF_PCI_MSK BIT(2)
48#define PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
49
50#define PWR_FAB_TSMC_MSK BIT(0)
51#define PWR_FAB_UMC_MSK BIT(1)
52#define PWR_FAB_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
53
54#define PWR_CUT_TESTCHIP_MSK BIT(0)
55#define PWR_CUT_A_MSK BIT(1)
56#define PWR_CUT_B_MSK BIT(2)
57#define PWR_CUT_C_MSK BIT(3)
58#define PWR_CUT_D_MSK BIT(4)
59#define PWR_CUT_E_MSK BIT(5)
60#define PWR_CUT_F_MSK BIT(6)
61#define PWR_CUT_G_MSK BIT(7)
62#define PWR_CUT_ALL_MSK 0xFF
63
64
65enum pwrseq_delay_unit {
66 PWRSEQ_DELAY_US,
67 PWRSEQ_DELAY_MS,
68};
69
70struct wlan_pwr_cfg {
71 u16 offset;
72 u8 cut_msk;
73 u8 fab_msk:4;
74 u8 interface_msk:4;
75 u8 base:4;
76 u8 cmd:4;
77 u8 msk;
78 u8 value;
79
80};
81
82#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset
83#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk
84#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk
85#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) __PWR_CMD.interface_msk
86#define GET_PWR_CFG_BASE(__PWR_CMD) __PWR_CMD.base
87#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd
88#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk
89#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value
90
91bool rtlbe_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
92 u8 fab_version, u8 interface_type,
93 struct wlan_pwr_cfg pwrcfgcmd[]);
94
95#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
new file mode 100644
index 000000000000..65221e678230
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
@@ -0,0 +1,2293 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_REG_H__
27#define __RTL8723BE_REG_H__
28
29#define TXPKT_BUF_SELECT 0x69
30#define RXPKT_BUF_SELECT 0xA5
31#define DISABLE_TRXPKT_BUF_ACCESS 0x0
32
33#define REG_SYS_ISO_CTRL 0x0000
34#define REG_SYS_FUNC_EN 0x0002
35#define REG_APS_FSMCO 0x0004
36#define REG_SYS_CLKR 0x0008
37#define REG_9346CR 0x000A
38#define REG_EE_VPD 0x000C
39#define REG_AFE_MISC 0x0010
40#define REG_SPS0_CTRL 0x0011
41#define REG_SPS_OCP_CFG 0x0018
42#define REG_RSV_CTRL 0x001C
43#define REG_RF_CTRL 0x001F
44#define REG_LDOA15_CTRL 0x0020
45#define REG_LDOV12D_CTRL 0x0021
46#define REG_LDOHCI12_CTRL 0x0022
47#define REG_LPLDO_CTRL 0x0023
48#define REG_AFE_XTAL_CTRL 0x0024
49/* 1.5v for 8188EE test chip, 1.4v for MP chip */
50#define REG_AFE_LDO_CTRL 0x0027
51#define REG_AFE_PLL_CTRL 0x0028
52#define REG_MAC_PHY_CTRL 0x002c
53#define REG_EFUSE_CTRL 0x0030
54#define REG_EFUSE_TEST 0x0034
55#define REG_PWR_DATA 0x0038
56#define REG_CAL_TIMER 0x003C
57#define REG_ACLK_MON 0x003E
58#define REG_GPIO_MUXCFG 0x0040
59#define REG_GPIO_IO_SEL 0x0042
60#define REG_MAC_PINMUX_CFG 0x0043
61#define REG_GPIO_PIN_CTRL 0x0044
62#define REG_GPIO_INTM 0x0048
63#define REG_LEDCFG0 0x004C
64#define REG_LEDCFG1 0x004D
65#define REG_LEDCFG2 0x004E
66#define REG_LEDCFG3 0x004F
67#define REG_FSIMR 0x0050
68#define REG_FSISR 0x0054
69#define REG_HSIMR 0x0058
70#define REG_HSISR 0x005c
71#define REG_GPIO_PIN_CTRL_2 0x0060
72#define REG_GPIO_IO_SEL_2 0x0062
73#define REG_MULTI_FUNC_CTRL 0x0068
74#define REG_GPIO_OUTPUT 0x006c
75#define REG_AFE_XTAL_CTRL_EXT 0x0078
76#define REG_XCK_OUT_CTRL 0x007c
77#define REG_MCUFWDL 0x0080
78#define REG_WOL_EVENT 0x0081
79#define REG_MCUTSTCFG 0x0084
80
81
82#define REG_HIMR 0x00B0
83#define REG_HISR 0x00B4
84#define REG_HIMRE 0x00B8
85#define REG_HISRE 0x00BC
86
87#define REG_EFUSE_ACCESS 0x00CF
88
89#define REG_BIST_SCAN 0x00D0
90#define REG_BIST_RPT 0x00D4
91#define REG_BIST_ROM_RPT 0x00D8
92#define REG_USB_SIE_INTF 0x00E0
93#define REG_PCIE_MIO_INTF 0x00E4
94#define REG_PCIE_MIO_INTD 0x00E8
95#define REG_HPON_FSM 0x00EC
96#define REG_SYS_CFG 0x00F0
97#define REG_GPIO_OUTSTS 0x00F4
98#define REG_SYS_CFG1 0x00F0
99#define REG_ROM_VERSION 0x00FD
100
101#define REG_CR 0x0100
102#define REG_PBP 0x0104
103#define REG_PKT_BUFF_ACCESS_CTRL 0x0106
104#define REG_TRXDMA_CTRL 0x010C
105#define REG_TRXFF_BNDY 0x0114
106#define REG_TRXFF_STATUS 0x0118
107#define REG_RXFF_PTR 0x011C
108
109#define REG_CPWM 0x012F
110#define REG_FWIMR 0x0130
111#define REG_FWISR 0x0134
112#define REG_PKTBUF_DBG_CTRL 0x0140
113#define REG_PKTBUF_DBG_DATA_L 0x0144
114#define REG_PKTBUF_DBG_DATA_H 0x0148
115#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL + 2)
116
117#define REG_TC0_CTRL 0x0150
118#define REG_TC1_CTRL 0x0154
119#define REG_TC2_CTRL 0x0158
120#define REG_TC3_CTRL 0x015C
121#define REG_TC4_CTRL 0x0160
122#define REG_TCUNIT_BASE 0x0164
123#define REG_MBIST_START 0x0174
124#define REG_MBIST_DONE 0x0178
125#define REG_MBIST_FAIL 0x017C
126#define REG_32K_CTRL 0x0194
127#define REG_C2HEVT_MSG_NORMAL 0x01A0
128#define REG_C2HEVT_CLEAR 0x01AF
129#define REG_C2HEVT_MSG_TEST 0x01B8
130#define REG_MCUTST_1 0x01c0
131#define REG_FMETHR 0x01C8
132#define REG_HMETFR 0x01CC
133#define REG_HMEBOX_0 0x01D0
134#define REG_HMEBOX_1 0x01D4
135#define REG_HMEBOX_2 0x01D8
136#define REG_HMEBOX_3 0x01DC
137
138#define REG_LLT_INIT 0x01E0
139#define REG_BB_ACCEESS_CTRL 0x01E8
140#define REG_BB_ACCESS_DATA 0x01EC
141
142#define REG_HMEBOX_EXT_0 0x01F0
143#define REG_HMEBOX_EXT_1 0x01F4
144#define REG_HMEBOX_EXT_2 0x01F8
145#define REG_HMEBOX_EXT_3 0x01FC
146
147#define REG_RQPN 0x0200
148#define REG_FIFOPAGE 0x0204
149#define REG_TDECTRL 0x0208
150#define REG_TXDMA_OFFSET_CHK 0x020C
151#define REG_TXDMA_STATUS 0x0210
152#define REG_RQPN_NPQ 0x0214
153
154#define REG_RXDMA_AGG_PG_TH 0x0280
155/* FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 */
156#define REG_FW_UPD_RDPTR 0x0284
157/* Control the RX DMA.*/
158#define REG_RXDMA_CONTROL 0x0286
159/* The number of packets in RXPKTBUF. */
160#define REG_RXPKT_NUM 0x0287
161
162#define REG_PCIE_CTRL_REG 0x0300
163#define REG_INT_MIG 0x0304
164#define REG_BCNQ_DESA 0x0308
165#define REG_HQ_DESA 0x0310
166#define REG_MGQ_DESA 0x0318
167#define REG_VOQ_DESA 0x0320
168#define REG_VIQ_DESA 0x0328
169#define REG_BEQ_DESA 0x0330
170#define REG_BKQ_DESA 0x0338
171#define REG_RX_DESA 0x0340
172
173#define REG_DBI 0x0348
174#define REG_MDIO 0x0354
175#define REG_DBG_SEL 0x0360
176#define REG_PCIE_HRPWM 0x0361
177#define REG_PCIE_HCPWM 0x0363
178#define REG_UART_CTRL 0x0364
179#define REG_WATCH_DOG 0x0368
180#define REG_UART_TX_DESA 0x0370
181#define REG_UART_RX_DESA 0x0378
182
183
184#define REG_HDAQ_DESA_NODEF 0x0000
185#define REG_CMDQ_DESA_NODEF 0x0000
186
187#define REG_VOQ_INFORMATION 0x0400
188#define REG_VIQ_INFORMATION 0x0404
189#define REG_BEQ_INFORMATION 0x0408
190#define REG_BKQ_INFORMATION 0x040C
191#define REG_MGQ_INFORMATION 0x0410
192#define REG_HGQ_INFORMATION 0x0414
193#define REG_BCNQ_INFORMATION 0x0418
194#define REG_TXPKT_EMPTY 0x041A
195
196
197#define REG_CPU_MGQ_INFORMATION 0x041C
198#define REG_FWHW_TXQ_CTRL 0x0420
199#define REG_HWSEQ_CTRL 0x0423
200#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
201#define REG_TXPKTBUF_MGQ_BDNY 0x0425
202#define REG_MULTI_BCNQ_EN 0x0426
203#define REG_MULTI_BCNQ_OFFSET 0x0427
204#define REG_SPEC_SIFS 0x0428
205#define REG_RL 0x042A
206#define REG_DARFRC 0x0430
207#define REG_RARFRC 0x0438
208#define REG_RRSR 0x0440
209#define REG_ARFR0 0x0444
210#define REG_ARFR1 0x0448
211#define REG_ARFR2 0x044C
212#define REG_ARFR3 0x0450
213#define REG_AMPDU_MAX_TIME 0x0456
214#define REG_AGGLEN_LMT 0x0458
215#define REG_AMPDU_MIN_SPACE 0x045C
216#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D
217#define REG_FAST_EDCA_CTRL 0x0460
218#define REG_RD_RESP_PKT_TH 0x0463
219#define REG_INIRTS_RATE_SEL 0x0480
220#define REG_INIDATA_RATE_SEL 0x0484
221#define REG_POWER_STATUS 0x04A4
222#define REG_POWER_STAGE1 0x04B4
223#define REG_POWER_STAGE2 0x04B8
224#define REG_PKT_LIFE_TIME 0x04C0
225#define REG_STBC_SETTING 0x04C4
226#define REG_PROT_MODE_CTRL 0x04C8
227#define REG_BAR_MODE_CTRL 0x04CC
228#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
229#define REG_EARLY_MODE_CONTROL 0x04D0
230#define REG_NQOS_SEQ 0x04DC
231#define REG_QOS_SEQ 0x04DE
232#define REG_NEED_CPU_HANDLE 0x04E0
233#define REG_PKT_LOSE_RPT 0x04E1
234#define REG_PTCL_ERR_STATUS 0x04E2
235#define REG_TX_RPT_CTRL 0x04EC
236#define REG_TX_RPT_TIME 0x04F0
237#define REG_DUMMY 0x04FC
238
239#define REG_EDCA_VO_PARAM 0x0500
240#define REG_EDCA_VI_PARAM 0x0504
241#define REG_EDCA_BE_PARAM 0x0508
242#define REG_EDCA_BK_PARAM 0x050C
243#define REG_BCNTCFG 0x0510
244#define REG_PIFS 0x0512
245#define REG_RDG_PIFS 0x0513
246#define REG_SIFS_CTX 0x0514
247#define REG_SIFS_TRX 0x0516
248#define REG_AGGR_BREAK_TIME 0x051A
249#define REG_SLOT 0x051B
250#define REG_TX_PTCL_CTRL 0x0520
251#define REG_TXPAUSE 0x0522
252#define REG_DIS_TXREQ_CLR 0x0523
253#define REG_RD_CTRL 0x0524
254#define REG_TBTT_PROHIBIT 0x0540
255#define REG_RD_NAV_NXT 0x0544
256#define REG_NAV_PROT_LEN 0x0546
257#define REG_BCN_CTRL 0x0550
258#define REG_USTIME_TSF 0x0551
259#define REG_MBID_NUM 0x0552
260#define REG_DUAL_TSF_RST 0x0553
261#define REG_BCN_INTERVAL 0x0554
262#define REG_MBSSID_BCN_SPACE 0x0554
263#define REG_DRVERLYINT 0x0558
264#define REG_BCNDMATIM 0x0559
265#define REG_ATIMWND 0x055A
266#define REG_BCN_MAX_ERR 0x055D
267#define REG_RXTSF_OFFSET_CCK 0x055E
268#define REG_RXTSF_OFFSET_OFDM 0x055F
269#define REG_TSFTR 0x0560
270#define REG_INIT_TSFTR 0x0564
271#define REG_SECONDARY_CCA_CTRL 0x0577
272#define REG_PSTIMER 0x0580
273#define REG_TIMER0 0x0584
274#define REG_TIMER1 0x0588
275#define REG_ACMHWCTRL 0x05C0
276#define REG_ACMRSTCTRL 0x05C1
277#define REG_ACMAVG 0x05C2
278#define REG_VO_ADMTIME 0x05C4
279#define REG_VI_ADMTIME 0x05C6
280#define REG_BE_ADMTIME 0x05C8
281#define REG_EDCA_RANDOM_GEN 0x05CC
282#define REG_SCH_TXCMD 0x05D0
283
284#define REG_APSD_CTRL 0x0600
285#define REG_BWOPMODE 0x0603
286#define REG_TCR 0x0604
287#define REG_RCR 0x0608
288#define REG_RX_PKT_LIMIT 0x060C
289#define REG_RX_DLK_TIME 0x060D
290#define REG_RX_DRVINFO_SZ 0x060F
291
292#define REG_MACID 0x0610
293#define REG_BSSID 0x0618
294#define REG_MAR 0x0620
295#define REG_MBIDCAMCFG 0x0628
296
297#define REG_USTIME_EDCA 0x0638
298#define REG_MAC_SPEC_SIFS 0x063A
299#define REG_RESP_SIFS_CCK 0x063C
300#define REG_RESP_SIFS_OFDM 0x063E
301#define REG_ACKTO 0x0640
302#define REG_CTS2TO 0x0641
303#define REG_EIFS 0x0642
304
305#define REG_NAV_CTRL 0x0650
306#define REG_BACAMCMD 0x0654
307#define REG_BACAMCONTENT 0x0658
308#define REG_LBDLY 0x0660
309#define REG_FWDLY 0x0661
310#define REG_RXERR_RPT 0x0664
311#define REG_TRXPTCL_CTL 0x0668
312
313#define REG_CAMCMD 0x0670
314#define REG_CAMWRITE 0x0674
315#define REG_CAMREAD 0x0678
316#define REG_CAMDBG 0x067C
317#define REG_SECCFG 0x0680
318
319#define REG_WOW_CTRL 0x0690
320#define REG_PSSTATUS 0x0691
321#define REG_PS_RX_INFO 0x0692
322#define REG_UAPSD_TID 0x0693
323#define REG_LPNAV_CTRL 0x0694
324#define REG_WKFMCAM_NUM 0x0698
325#define REG_WKFMCAM_RWD 0x069C
326#define REG_RXFLTMAP0 0x06A0
327#define REG_RXFLTMAP1 0x06A2
328#define REG_RXFLTMAP2 0x06A4
329#define REG_BCN_PSR_RPT 0x06A8
330#define REG_CALB32K_CTRL 0x06AC
331#define REG_PKT_MON_CTRL 0x06B4
332#define REG_BT_COEX_TABLE 0x06C0
333#define REG_WMAC_RESP_TXINFO 0x06D8
334
335#define REG_USB_INFO 0xFE17
336#define REG_USB_SPECIAL_OPTION 0xFE55
337#define REG_USB_DMA_AGG_TO 0xFE5B
338#define REG_USB_AGG_TO 0xFE5C
339#define REG_USB_AGG_TH 0xFE5D
340
341#define REG_TEST_USB_TXQS 0xFE48
342#define REG_TEST_SIE_VID 0xFE60
343#define REG_TEST_SIE_PID 0xFE62
344#define REG_TEST_SIE_OPTIONAL 0xFE64
345#define REG_TEST_SIE_CHIRP_K 0xFE65
346#define REG_TEST_SIE_PHY 0xFE66
347#define REG_TEST_SIE_MAC_ADDR 0xFE70
348#define REG_TEST_SIE_STRING 0xFE80
349
350#define REG_NORMAL_SIE_VID 0xFE60
351#define REG_NORMAL_SIE_PID 0xFE62
352#define REG_NORMAL_SIE_OPTIONAL 0xFE64
353#define REG_NORMAL_SIE_EP 0xFE65
354#define REG_NORMAL_SIE_PHY 0xFE68
355#define REG_NORMAL_SIE_MAC_ADDR 0xFE70
356#define REG_NORMAL_SIE_STRING 0xFE80
357
358#define CR9346 REG_9346CR
359#define MSR (REG_CR + 2)
360#define ISR REG_HISR
361#define TSFR REG_TSFTR
362
363#define MACIDR0 REG_MACID
364#define MACIDR4 (REG_MACID + 4)
365
366#define PBP REG_PBP
367
368#define IDR0 MACIDR0
369#define IDR4 MACIDR4
370
371#define UNUSED_REGISTER 0x1BF
372#define DCAM UNUSED_REGISTER
373#define PSR UNUSED_REGISTER
374#define BBADDR UNUSED_REGISTER
375#define PHYDATAR UNUSED_REGISTER
376
377#define INVALID_BBRF_VALUE 0x12345678
378
379#define MAX_MSS_DENSITY_2T 0x13
380#define MAX_MSS_DENSITY_1T 0x0A
381
382#define CMDEEPROM_EN BIT(5)
383#define CMDEEPROM_SEL BIT(4)
384#define CMD9346CR_9356SEL BIT(4)
385#define AUTOLOAD_EEPROM (CMDEEPROM_EN | CMDEEPROM_SEL)
386#define AUTOLOAD_EFUSE CMDEEPROM_EN
387
388#define GPIOSEL_GPIO 0
389#define GPIOSEL_ENBT BIT(5)
390
391#define GPIO_IN REG_GPIO_PIN_CTRL
392#define GPIO_OUT (REG_GPIO_PIN_CTRL + 1)
393#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL + 2)
394#define GPIO_MOD (REG_GPIO_PIN_CTRL + 3)
395
396/* 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) */
397#define HSIMR_GPIO12_0_INT_EN BIT(0)
398#define HSIMR_SPS_OCP_INT_EN BIT(5)
399#define HSIMR_RON_INT_EN BIT(6)
400#define HSIMR_PDN_INT_EN BIT(7)
401#define HSIMR_GPIO9_INT_EN BIT(25)
402
403/* 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) */
404
405#define HSISR_GPIO12_0_INT BIT(0)
406#define HSISR_SPS_OCP_INT BIT(5)
407#define HSISR_RON_INT_EN BIT(6)
408#define HSISR_PDNINT BIT(7)
409#define HSISR_GPIO9_INT BIT(25)
410
411#define MSR_NOLINK 0x00
412#define MSR_ADHOC 0x01
413#define MSR_INFRA 0x02
414#define MSR_AP 0x03
415
416#define RRSR_RSC_OFFSET 21
417#define RRSR_SHORT_OFFSET 23
418#define RRSR_RSC_BW_40M 0x600000
419#define RRSR_RSC_UPSUBCHNL 0x400000
420#define RRSR_RSC_LOWSUBCHNL 0x200000
421#define RRSR_SHORT 0x800000
422#define RRSR_1M BIT(0)
423#define RRSR_2M BIT(1)
424#define RRSR_5_5M BIT(2)
425#define RRSR_11M BIT(3)
426#define RRSR_6M BIT(4)
427#define RRSR_9M BIT(5)
428#define RRSR_12M BIT(6)
429#define RRSR_18M BIT(7)
430#define RRSR_24M BIT(8)
431#define RRSR_36M BIT(9)
432#define RRSR_48M BIT(10)
433#define RRSR_54M BIT(11)
434#define RRSR_MCS0 BIT(12)
435#define RRSR_MCS1 BIT(13)
436#define RRSR_MCS2 BIT(14)
437#define RRSR_MCS3 BIT(15)
438#define RRSR_MCS4 BIT(16)
439#define RRSR_MCS5 BIT(17)
440#define RRSR_MCS6 BIT(18)
441#define RRSR_MCS7 BIT(19)
442#define BRSR_ACKSHORTPMB BIT(23)
443
444#define RATR_1M 0x00000001
445#define RATR_2M 0x00000002
446#define RATR_55M 0x00000004
447#define RATR_11M 0x00000008
448#define RATR_6M 0x00000010
449#define RATR_9M 0x00000020
450#define RATR_12M 0x00000040
451#define RATR_18M 0x00000080
452#define RATR_24M 0x00000100
453#define RATR_36M 0x00000200
454#define RATR_48M 0x00000400
455#define RATR_54M 0x00000800
456#define RATR_MCS0 0x00001000
457#define RATR_MCS1 0x00002000
458#define RATR_MCS2 0x00004000
459#define RATR_MCS3 0x00008000
460#define RATR_MCS4 0x00010000
461#define RATR_MCS5 0x00020000
462#define RATR_MCS6 0x00040000
463#define RATR_MCS7 0x00080000
464#define RATR_MCS8 0x00100000
465#define RATR_MCS9 0x00200000
466#define RATR_MCS10 0x00400000
467#define RATR_MCS11 0x00800000
468#define RATR_MCS12 0x01000000
469#define RATR_MCS13 0x02000000
470#define RATR_MCS14 0x04000000
471#define RATR_MCS15 0x08000000
472
473#define RATE_1M BIT(0)
474#define RATE_2M BIT(1)
475#define RATE_5_5M BIT(2)
476#define RATE_11M BIT(3)
477#define RATE_6M BIT(4)
478#define RATE_9M BIT(5)
479#define RATE_12M BIT(6)
480#define RATE_18M BIT(7)
481#define RATE_24M BIT(8)
482#define RATE_36M BIT(9)
483#define RATE_48M BIT(10)
484#define RATE_54M BIT(11)
485#define RATE_MCS0 BIT(12)
486#define RATE_MCS1 BIT(13)
487#define RATE_MCS2 BIT(14)
488#define RATE_MCS3 BIT(15)
489#define RATE_MCS4 BIT(16)
490#define RATE_MCS5 BIT(17)
491#define RATE_MCS6 BIT(18)
492#define RATE_MCS7 BIT(19)
493#define RATE_MCS8 BIT(20)
494#define RATE_MCS9 BIT(21)
495#define RATE_MCS10 BIT(22)
496#define RATE_MCS11 BIT(23)
497#define RATE_MCS12 BIT(24)
498#define RATE_MCS13 BIT(25)
499#define RATE_MCS14 BIT(26)
500#define RATE_MCS15 BIT(27)
501
502#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
503#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\
504 RATR_24M | RATR_36M | RATR_48M | RATR_54M)
505#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\
506 RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\
507 RATR_MCS6 | RATR_MCS7)
508#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\
509 RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\
510 RATR_MCS14 | RATR_MCS15)
511
512#define BW_OPMODE_20MHZ BIT(2)
513#define BW_OPMODE_5G BIT(1)
514#define BW_OPMODE_11J BIT(0)
515
516#define CAM_VALID BIT(15)
517#define CAM_NOTVALID 0x0000
518#define CAM_USEDK BIT(5)
519
520#define CAM_NONE 0x0
521#define CAM_WEP40 0x01
522#define CAM_TKIP 0x02
523#define CAM_AES 0x04
524#define CAM_WEP104 0x05
525
526#define TOTAL_CAM_ENTRY 32
527#define HALF_CAM_ENTRY 16
528
529#define CAM_WRITE BIT(16)
530#define CAM_READ 0x00000000
531#define CAM_POLLINIG BIT(31)
532
533#define SCR_USEDK 0x01
534#define SCR_TXSEC_ENABLE 0x02
535#define SCR_RXSEC_ENABLE 0x04
536
537#define WOW_PMEN BIT(0)
538#define WOW_WOMEN BIT(1)
539#define WOW_MAGIC BIT(2)
540#define WOW_UWF BIT(3)
541
542/*********************************************
543* 8723BE IMR/ISR bits
544**********************************************/
545#define IMR_DISABLED 0x0
546/* IMR DW0(0x0060-0063) Bit 0-31 */
547#define IMR_TXCCK BIT(30) /* TXRPT interrupt when
548 * CCX bit of the packet is set
549 */
550#define IMR_PSTIMEOUT BIT(29) /* Power Save Time Out Interrupt */
551#define IMR_GTINT4 BIT(28) /* When GTIMER4 expires,
552 * this bit is set to 1
553 */
554#define IMR_GTINT3 BIT(27) /* When GTIMER3 expires,
555 * this bit is set to 1
556 */
557#define IMR_TBDER BIT(26) /* Transmit Beacon0 Error */
558#define IMR_TBDOK BIT(25) /* Transmit Beacon0 OK */
559#define IMR_TSF_BIT32_TOGGLE BIT(24) /* TSF Timer BIT32 toggle
560 * indication interrupt
561 */
562#define IMR_BCNDMAINT0 BIT(20) /* Beacon DMA Interrupt 0 */
563#define IMR_BCNDOK0 BIT(16) /* Beacon Queue DMA OK0 */
564#define IMR_HSISR_IND_ON_INT BIT(15) /* HSISR Indicator (HSIMR & HSISR is
565 * true, this bit is set to 1)
566 */
567#define IMR_BCNDMAINT_E BIT(14) /* Beacon DMA Interrupt
568 * Extension for Win7
569 */
570#define IMR_ATIMEND BIT(12) /* CTWidnow End or ATIM Window End */
571#define IMR_HISR1_IND_INT BIT(11) /* HISR1 Indicator (HISR1 & HIMR1 is
572 * true, this bit is set to 1)
573 */
574#define IMR_C2HCMD BIT(10) /* CPU to Host Command INT Status,
575 * Write 1 clear
576 */
577#define IMR_CPWM2 BIT(9) /* CPU power Mode exchange INT Status,
578 * Write 1 clear
579 */
580#define IMR_CPWM BIT(8) /* CPU power Mode exchange INT Status,
581 * Write 1 clear
582 */
583#define IMR_HIGHDOK BIT(7) /* High Queue DMA OK */
584#define IMR_MGNTDOK BIT(6) /* Management Queue DMA OK */
585#define IMR_BKDOK BIT(5) /* AC_BK DMA OK */
586#define IMR_BEDOK BIT(4) /* AC_BE DMA OK */
587#define IMR_VIDOK BIT(3) /* AC_VI DMA OK */
588#define IMR_VODOK BIT(2) /* AC_VO DMA OK */
589#define IMR_RDU BIT(1) /* Rx Descriptor Unavailable */
590#define IMR_ROK BIT(0) /* Receive DMA OK */
591
592/* IMR DW1(0x00B4-00B7) Bit 0-31 */
593#define IMR_BCNDMAINT7 BIT(27) /* Beacon DMA Interrupt 7 */
594#define IMR_BCNDMAINT6 BIT(26) /* Beacon DMA Interrupt 6 */
595#define IMR_BCNDMAINT5 BIT(25) /* Beacon DMA Interrupt 5 */
596#define IMR_BCNDMAINT4 BIT(24) /* Beacon DMA Interrupt 4 */
597#define IMR_BCNDMAINT3 BIT(23) /* Beacon DMA Interrupt 3 */
598#define IMR_BCNDMAINT2 BIT(22) /* Beacon DMA Interrupt 2 */
599#define IMR_BCNDMAINT1 BIT(21) /* Beacon DMA Interrupt 1 */
600#define IMR_BCNDOK7 BIT(20) /* Beacon Queue DMA OK Interrup 7 */
601#define IMR_BCNDOK6 BIT(19) /* Beacon Queue DMA OK Interrup 6 */
602#define IMR_BCNDOK5 BIT(18) /* Beacon Queue DMA OK Interrup 5 */
603#define IMR_BCNDOK4 BIT(17) /* Beacon Queue DMA OK Interrup 4 */
604#define IMR_BCNDOK3 BIT(16) /* Beacon Queue DMA OK Interrup 3 */
605#define IMR_BCNDOK2 BIT(15) /* Beacon Queue DMA OK Interrup 2 */
606#define IMR_BCNDOK1 BIT(14) /* Beacon Queue DMA OK Interrup 1 */
607#define IMR_ATIMEND_E BIT(13) /* ATIM Window End Extension for Win7 */
608#define IMR_TXERR BIT(11) /* Tx Error Flag Interrupt Status,
609 * write 1 clear.
610 */
611#define IMR_RXERR BIT(10) /* Rx Error Flag INT Status,
612 * Write 1 clear
613 */
614#define IMR_TXFOVW BIT(9) /* Transmit FIFO Overflow */
615#define IMR_RXFOVW BIT(8) /* Receive FIFO Overflow */
616
617#define HWSET_MAX_SIZE 512
618#define EFUSE_MAX_SECTION 64
619#define EFUSE_REAL_CONTENT_LEN 256
620#define EFUSE_OOB_PROTECT_BYTES 18 /* PG data exclude header,
621 * dummy 7 bytes frome CP test
622 * and reserved 1byte.
623 */
624
625#define EEPROM_DEFAULT_TSSI 0x0
626#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
627#define EEPROM_DEFAULT_CRYSTALCAP 0x5
628#define EEPROM_DEFAULT_BOARDTYPE 0x02
629#define EEPROM_DEFAULT_TXPOWER 0x1010
630#define EEPROM_DEFAULT_HT2T_TXPWR 0x10
631
632#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
633#define EEPROM_DEFAULT_THERMALMETER 0x18
634#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0
635#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5
636#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22
637#define EEPROM_DEFAULT_HT40_2SDIFF 0x0
638#define EEPROM_DEFAULT_HT20_DIFF 2
639#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
640#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0
641#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0
642
643#define RF_OPTION1 0x79
644#define RF_OPTION2 0x7A
645#define RF_OPTION3 0x7B
646#define RF_OPTION4 0xC3
647
648#define EEPROM_DEFAULT_PID 0x1234
649#define EEPROM_DEFAULT_VID 0x5678
650#define EEPROM_DEFAULT_CUSTOMERID 0xAB
651#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD
652#define EEPROM_DEFAULT_VERSION 0
653
654#define EEPROM_CHANNEL_PLAN_FCC 0x0
655#define EEPROM_CHANNEL_PLAN_IC 0x1
656#define EEPROM_CHANNEL_PLAN_ETSI 0x2
657#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
658#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
659#define EEPROM_CHANNEL_PLAN_MKK 0x5
660#define EEPROM_CHANNEL_PLAN_MKK1 0x6
661#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
662#define EEPROM_CHANNEL_PLAN_TELEC 0x8
663#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
664#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
665#define EEPROM_CHANNEL_PLAN_NCC 0xB
666#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
667
668#define EEPROM_CID_DEFAULT 0x0
669#define EEPROM_CID_TOSHIBA 0x4
670#define EEPROM_CID_CCX 0x10
671#define EEPROM_CID_QMI 0x0D
672#define EEPROM_CID_WHQL 0xFE
673
674#define RTL8723BE_EEPROM_ID 0x8129
675
676#define EEPROM_HPON 0x02
677#define EEPROM_CLK 0x06
678#define EEPROM_TESTR 0x08
679
680
681#define EEPROM_TXPOWERCCK 0x10
682#define EEPROM_TXPOWERHT40_1S 0x16
683#define EEPROM_TXPOWERHT20DIFF 0x1B
684#define EEPROM_TXPOWER_OFDMDIFF 0x1B
685
686
687
688#define EEPROM_TX_PWR_INX 0x10
689
690#define EEPROM_CHANNELPLAN 0xB8
691#define EEPROM_XTAL_8723BE 0xB9
692#define EEPROM_THERMAL_METER_88E 0xBA
693#define EEPROM_IQK_LCK_88E 0xBB
694
695#define EEPROM_RF_BOARD_OPTION_88E 0xC1
696#define EEPROM_RF_FEATURE_OPTION_88E 0xC2
697#define EEPROM_RF_BT_SETTING_88E 0xC3
698#define EEPROM_VERSION 0xC4
699#define EEPROM_CUSTOMER_ID 0xC5
700#define EEPROM_RF_ANTENNA_OPT_88E 0xC9
701
702#define EEPROM_MAC_ADDR 0xD0
703#define EEPROM_VID 0xD6
704#define EEPROM_DID 0xD8
705#define EEPROM_SVID 0xDA
706#define EEPROM_SMID 0xDC
707
708#define STOPBECON BIT(6)
709#define STOPHIGHT BIT(5)
710#define STOPMGT BIT(4)
711#define STOPVO BIT(3)
712#define STOPVI BIT(2)
713#define STOPBE BIT(1)
714#define STOPBK BIT(0)
715
716#define RCR_APPFCS BIT(31)
717#define RCR_APP_MIC BIT(30)
718#define RCR_APP_ICV BIT(29)
719#define RCR_APP_PHYST_RXFF BIT(28)
720#define RCR_APP_BA_SSN BIT(27)
721#define RCR_ENMBID BIT(24)
722#define RCR_LSIGEN BIT(23)
723#define RCR_MFBEN BIT(22)
724#define RCR_HTC_LOC_CTRL BIT(14)
725#define RCR_AMF BIT(13)
726#define RCR_ACF BIT(12)
727#define RCR_ADF BIT(11)
728#define RCR_AICV BIT(9)
729#define RCR_ACRC32 BIT(8)
730#define RCR_CBSSID_BCN BIT(7)
731#define RCR_CBSSID_DATA BIT(6)
732#define RCR_CBSSID RCR_CBSSID_DATA
733#define RCR_APWRMGT BIT(5)
734#define RCR_ADD3 BIT(4)
735#define RCR_AB BIT(3)
736#define RCR_AM BIT(2)
737#define RCR_APM BIT(1)
738#define RCR_AAP BIT(0)
739#define RCR_MXDMA_OFFSET 8
740#define RCR_FIFO_OFFSET 13
741
742#define RSV_CTRL 0x001C
743#define RD_CTRL 0x0524
744
745#define REG_USB_INFO 0xFE17
746#define REG_USB_SPECIAL_OPTION 0xFE55
747#define REG_USB_DMA_AGG_TO 0xFE5B
748#define REG_USB_AGG_TO 0xFE5C
749#define REG_USB_AGG_TH 0xFE5D
750
751#define REG_USB_VID 0xFE60
752#define REG_USB_PID 0xFE62
753#define REG_USB_OPTIONAL 0xFE64
754#define REG_USB_CHIRP_K 0xFE65
755#define REG_USB_PHY 0xFE66
756#define REG_USB_MAC_ADDR 0xFE70
757#define REG_USB_HRPWM 0xFE58
758#define REG_USB_HCPWM 0xFE57
759
760#define SW18_FPWM BIT(3)
761
762#define ISO_MD2PP BIT(0)
763#define ISO_UA2USB BIT(1)
764#define ISO_UD2CORE BIT(2)
765#define ISO_PA2PCIE BIT(3)
766#define ISO_PD2CORE BIT(4)
767#define ISO_IP2MAC BIT(5)
768#define ISO_DIOP BIT(6)
769#define ISO_DIOE BIT(7)
770#define ISO_EB2CORE BIT(8)
771#define ISO_DIOR BIT(9)
772
773#define PWC_EV25V BIT(14)
774#define PWC_EV12V BIT(15)
775
776#define FEN_BBRSTB BIT(0)
777#define FEN_BB_GLB_RSTN BIT(1)
778#define FEN_USBA BIT(2)
779#define FEN_UPLL BIT(3)
780#define FEN_USBD BIT(4)
781#define FEN_DIO_PCIE BIT(5)
782#define FEN_PCIEA BIT(6)
783#define FEN_PPLL BIT(7)
784#define FEN_PCIED BIT(8)
785#define FEN_DIOE BIT(9)
786#define FEN_CPUEN BIT(10)
787#define FEN_DCORE BIT(11)
788#define FEN_ELDR BIT(12)
789#define FEN_DIO_RF BIT(13)
790#define FEN_HWPDN BIT(14)
791#define FEN_MREGEN BIT(15)
792
793#define PFM_LDALL BIT(0)
794#define PFM_ALDN BIT(1)
795#define PFM_LDKP BIT(2)
796#define PFM_WOWL BIT(3)
797#define ENPDN BIT(4)
798#define PDN_PL BIT(5)
799#define APFM_ONMAC BIT(8)
800#define APFM_OFF BIT(9)
801#define APFM_RSM BIT(10)
802#define AFSM_HSUS BIT(11)
803#define AFSM_PCIE BIT(12)
804#define APDM_MAC BIT(13)
805#define APDM_HOST BIT(14)
806#define APDM_HPDN BIT(15)
807#define RDY_MACON BIT(16)
808#define SUS_HOST BIT(17)
809#define ROP_ALD BIT(20)
810#define ROP_PWR BIT(21)
811#define ROP_SPS BIT(22)
812#define SOP_MRST BIT(25)
813#define SOP_FUSE BIT(26)
814#define SOP_ABG BIT(27)
815#define SOP_AMB BIT(28)
816#define SOP_RCK BIT(29)
817#define SOP_A8M BIT(30)
818#define XOP_BTCK BIT(31)
819
820#define ANAD16V_EN BIT(0)
821#define ANA8M BIT(1)
822#define MACSLP BIT(4)
823#define LOADER_CLK_EN BIT(5)
824#define _80M_SSC_DIS BIT(7)
825#define _80M_SSC_EN_HO BIT(8)
826#define PHY_SSC_RSTB BIT(9)
827#define SEC_CLK_EN BIT(10)
828#define MAC_CLK_EN BIT(11)
829#define SYS_CLK_EN BIT(12)
830#define RING_CLK_EN BIT(13)
831
832#define BOOT_FROM_EEPROM BIT(4)
833#define EEPROM_EN BIT(5)
834
835#define AFE_BGEN BIT(0)
836#define AFE_MBEN BIT(1)
837#define MAC_ID_EN BIT(7)
838
839#define WLOCK_ALL BIT(0)
840#define WLOCK_00 BIT(1)
841#define WLOCK_04 BIT(2)
842#define WLOCK_08 BIT(3)
843#define WLOCK_40 BIT(4)
844#define R_DIS_PRST_0 BIT(5)
845#define R_DIS_PRST_1 BIT(6)
846#define LOCK_ALL_EN BIT(7)
847
848#define RF_EN BIT(0)
849#define RF_RSTB BIT(1)
850#define RF_SDMRSTB BIT(2)
851
852#define LDA15_EN BIT(0)
853#define LDA15_STBY BIT(1)
854#define LDA15_OBUF BIT(2)
855#define LDA15_REG_VOS BIT(3)
856#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
857
858#define LDV12_EN BIT(0)
859#define LDV12_SDBY BIT(1)
860#define LPLDO_HSM BIT(2)
861#define LPLDO_LSM_DIS BIT(3)
862#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
863
864#define XTAL_EN BIT(0)
865#define XTAL_BSEL BIT(1)
866#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
867#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
868#define XTAL_GATE_USB BIT(8)
869#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
870#define XTAL_GATE_AFE BIT(11)
871#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
872#define XTAL_RF_GATE BIT(14)
873#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
874#define XTAL_GATE_DIG BIT(17)
875#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
876#define XTAL_BT_GATE BIT(20)
877#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
878#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
879
880#define CKDLY_AFE BIT(26)
881#define CKDLY_USB BIT(27)
882#define CKDLY_DIG BIT(28)
883#define CKDLY_BT BIT(29)
884
885#define APLL_EN BIT(0)
886#define APLL_320_EN BIT(1)
887#define APLL_FREF_SEL BIT(2)
888#define APLL_EDGE_SEL BIT(3)
889#define APLL_WDOGB BIT(4)
890#define APLL_LPFEN BIT(5)
891
892#define APLL_REF_CLK_13MHZ 0x1
893#define APLL_REF_CLK_19_2MHZ 0x2
894#define APLL_REF_CLK_20MHZ 0x3
895#define APLL_REF_CLK_25MHZ 0x4
896#define APLL_REF_CLK_26MHZ 0x5
897#define APLL_REF_CLK_38_4MHZ 0x6
898#define APLL_REF_CLK_40MHZ 0x7
899
900#define APLL_320EN BIT(14)
901#define APLL_80EN BIT(15)
902#define APLL_1MEN BIT(24)
903
904#define ALD_EN BIT(18)
905#define EF_PD BIT(19)
906#define EF_FLAG BIT(31)
907
908#define EF_TRPT BIT(7)
909#define LDOE25_EN BIT(31)
910
911#define RSM_EN BIT(0)
912#define TIMER_EN BIT(4)
913
914#define TRSW0EN BIT(2)
915#define TRSW1EN BIT(3)
916#define EROM_EN BIT(4)
917#define ENBT BIT(5)
918#define ENUART BIT(8)
919#define UART_910 BIT(9)
920#define ENPMAC BIT(10)
921#define SIC_SWRST BIT(11)
922#define ENSIC BIT(12)
923#define SIC_23 BIT(13)
924#define ENHDP BIT(14)
925#define SIC_LBK BIT(15)
926
927#define LED0PL BIT(4)
928#define LED1PL BIT(12)
929#define LED0DIS BIT(7)
930
931#define MCUFWDL_EN BIT(0)
932#define MCUFWDL_RDY BIT(1)
933#define FWDL_CHKSUM_RPT BIT(2)
934#define MACINI_RDY BIT(3)
935#define BBINI_RDY BIT(4)
936#define RFINI_RDY BIT(5)
937#define WINTINI_RDY BIT(6)
938#define CPRST BIT(23)
939
940#define XCLK_VLD BIT(0)
941#define ACLK_VLD BIT(1)
942#define UCLK_VLD BIT(2)
943#define PCLK_VLD BIT(3)
944#define PCIRSTB BIT(4)
945#define V15_VLD BIT(5)
946#define TRP_B15V_EN BIT(7)
947#define SIC_IDLE BIT(8)
948#define BD_MAC2 BIT(9)
949#define BD_MAC1 BIT(10)
950#define IC_MACPHY_MODE BIT(11)
951#define VENDOR_ID BIT(19)
952#define PAD_HWPD_IDN BIT(22)
953#define TRP_VAUX_EN BIT(23)
954#define TRP_BT_EN BIT(24)
955#define BD_PKG_SEL BIT(25)
956#define BD_HCI_SEL BIT(26)
957#define TYPE_ID BIT(27)
958
959#define CHIP_VER_RTL_MASK 0xF000
960#define CHIP_VER_RTL_SHIFT 12
961
962#define REG_LBMODE (REG_CR + 3)
963
964#define HCI_TXDMA_EN BIT(0)
965#define HCI_RXDMA_EN BIT(1)
966#define TXDMA_EN BIT(2)
967#define RXDMA_EN BIT(3)
968#define PROTOCOL_EN BIT(4)
969#define SCHEDULE_EN BIT(5)
970#define MACTXEN BIT(6)
971#define MACRXEN BIT(7)
972#define ENSWBCN BIT(8)
973#define ENSEC BIT(9)
974
975#define _NETTYPE(x) (((x) & 0x3) << 16)
976#define MASK_NETTYPE 0x30000
977#define NT_NO_LINK 0x0
978#define NT_LINK_AD_HOC 0x1
979#define NT_LINK_AP 0x2
980#define NT_AS_AP 0x3
981
982#define _LBMODE(x) (((x) & 0xF) << 24)
983#define MASK_LBMODE 0xF000000
984#define LOOPBACK_NORMAL 0x0
985#define LOOPBACK_IMMEDIATELY 0xB
986#define LOOPBACK_MAC_DELAY 0x3
987#define LOOPBACK_PHY 0x1
988#define LOOPBACK_DMA 0x7
989
990#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
991#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
992#define _PSRX_MASK 0xF
993#define _PSTX_MASK 0xF0
994#define _PSRX(x) (x)
995#define _PSTX(x) ((x) << 4)
996
997#define PBP_64 0x0
998#define PBP_128 0x1
999#define PBP_256 0x2
1000#define PBP_512 0x3
1001#define PBP_1024 0x4
1002
1003#define RXDMA_ARBBW_EN BIT(0)
1004#define RXSHFT_EN BIT(1)
1005#define RXDMA_AGG_EN BIT(2)
1006#define QS_VO_QUEUE BIT(8)
1007#define QS_VI_QUEUE BIT(9)
1008#define QS_BE_QUEUE BIT(10)
1009#define QS_BK_QUEUE BIT(11)
1010#define QS_MANAGER_QUEUE BIT(12)
1011#define QS_HIGH_QUEUE BIT(13)
1012
1013#define HQSEL_VOQ BIT(0)
1014#define HQSEL_VIQ BIT(1)
1015#define HQSEL_BEQ BIT(2)
1016#define HQSEL_BKQ BIT(3)
1017#define HQSEL_MGTQ BIT(4)
1018#define HQSEL_HIQ BIT(5)
1019
1020#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14)
1021#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12)
1022#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10)
1023#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8)
1024#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6)
1025#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4)
1026
1027#define QUEUE_LOW 1
1028#define QUEUE_NORMAL 2
1029#define QUEUE_HIGH 3
1030
1031#define _LLT_NO_ACTIVE 0x0
1032#define _LLT_WRITE_ACCESS 0x1
1033#define _LLT_READ_ACCESS 0x2
1034
1035#define _LLT_INIT_DATA(x) ((x) & 0xFF)
1036#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
1037#define _LLT_OP(x) (((x) & 0x3) << 30)
1038#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
1039
1040#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
1041#define BB_WRITE_EN BIT(30)
1042#define BB_READ_EN BIT(31)
1043
1044#define _HPQ(x) ((x) & 0xFF)
1045#define _LPQ(x) (((x) & 0xFF) << 8)
1046#define _PUBQ(x) (((x) & 0xFF) << 16)
1047#define _NPQ(x) ((x) & 0xFF)
1048
1049#define HPQ_PUBLIC_DIS BIT(24)
1050#define LPQ_PUBLIC_DIS BIT(25)
1051#define LD_RQPN BIT(31)
1052
1053#define BCN_VALID BIT(16)
1054#define BCN_HEAD(x) (((x) & 0xFF) << 8)
1055#define BCN_HEAD_MASK 0xFF00
1056
1057#define BLK_DESC_NUM_SHIFT 4
1058#define BLK_DESC_NUM_MASK 0xF
1059
1060#define DROP_DATA_EN BIT(9)
1061
1062#define EN_AMPDU_RTY_NEW BIT(7)
1063
1064#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
1065
1066#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
1067#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
1068
1069#define RATE_REG_BITMAP_ALL 0xFFFFF
1070
1071#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
1072
1073#define _RRSR_RSC(x) (((x) & 0x3) << 21)
1074#define RRSR_RSC_RESERVED 0x0
1075#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
1076#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
1077#define RRSR_RSC_DUPLICATE_MODE 0x3
1078
1079#define USE_SHORT_G1 BIT(20)
1080
1081#define _AGGLMT_MCS0(x) ((x) & 0xF)
1082#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
1083#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
1084#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
1085#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
1086#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
1087#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
1088#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
1089
1090#define RETRY_LIMIT_SHORT_SHIFT 8
1091#define RETRY_LIMIT_LONG_SHIFT 0
1092
1093#define _DARF_RC1(x) ((x) & 0x1F)
1094#define _DARF_RC2(x) (((x) & 0x1F) << 8)
1095#define _DARF_RC3(x) (((x) & 0x1F) << 16)
1096#define _DARF_RC4(x) (((x) & 0x1F) << 24)
1097#define _DARF_RC5(x) ((x) & 0x1F)
1098#define _DARF_RC6(x) (((x) & 0x1F) << 8)
1099#define _DARF_RC7(x) (((x) & 0x1F) << 16)
1100#define _DARF_RC8(x) (((x) & 0x1F) << 24)
1101
1102#define _RARF_RC1(x) ((x) & 0x1F)
1103#define _RARF_RC2(x) (((x) & 0x1F) << 8)
1104#define _RARF_RC3(x) (((x) & 0x1F) << 16)
1105#define _RARF_RC4(x) (((x) & 0x1F) << 24)
1106#define _RARF_RC5(x) ((x) & 0x1F)
1107#define _RARF_RC6(x) (((x) & 0x1F) << 8)
1108#define _RARF_RC7(x) (((x) & 0x1F) << 16)
1109#define _RARF_RC8(x) (((x) & 0x1F) << 24)
1110
1111#define AC_PARAM_TXOP_LIMIT_OFFSET 16
1112#define AC_PARAM_ECW_MAX_OFFSET 12
1113#define AC_PARAM_ECW_MIN_OFFSET 8
1114#define AC_PARAM_AIFS_OFFSET 0
1115
1116#define _AIFS(x) (x)
1117#define _ECW_MAX_MIN(x) ((x) << 8)
1118#define _TXOP_LIMIT(x) ((x) << 16)
1119
1120#define _BCNIFS(x) ((x) & 0xFF)
1121#define _BCNECW(x) ((((x) & 0xF)) << 8)
1122
1123#define _LRL(x) ((x) & 0x3F)
1124#define _SRL(x) (((x) & 0x3F) << 8)
1125
1126#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
1127#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8)
1128
1129#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
1130#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8)
1131
1132#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
1133
1134#define DIS_EDCA_CNT_DWN BIT(11)
1135
1136#define EN_MBSSID BIT(1)
1137#define EN_TXBCN_RPT BIT(2)
1138#define EN_BCN_FUNCTION BIT(3)
1139
1140#define TSFTR_RST BIT(0)
1141#define TSFTR1_RST BIT(1)
1142
1143#define STOP_BCNQ BIT(6)
1144
1145#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
1146#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
1147
1148#define ACMHW_HWEN BIT(0)
1149#define ACMHW_BEQEN BIT(1)
1150#define ACMHW_VIQEN BIT(2)
1151#define ACMHW_VOQEN BIT(3)
1152#define ACMHW_BEQSTATUS BIT(4)
1153#define ACMHW_VIQSTATUS BIT(5)
1154#define ACMHW_VOQSTATUS BIT(6)
1155
1156#define APSDOFF BIT(6)
1157#define APSDOFF_STATUS BIT(7)
1158
1159#define BW_20MHZ BIT(2)
1160
1161#define RATE_BITMAP_ALL 0xFFFFF
1162
1163#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
1164
1165#define TSFRST BIT(0)
1166#define DIS_GCLK BIT(1)
1167#define PAD_SEL BIT(2)
1168#define PWR_ST BIT(6)
1169#define PWRBIT_OW_EN BIT(7)
1170#define ACRC BIT(8)
1171#define CFENDFORM BIT(9)
1172#define ICV BIT(10)
1173
1174#define AAP BIT(0)
1175#define APM BIT(1)
1176#define AM BIT(2)
1177#define AB BIT(3)
1178#define ADD3 BIT(4)
1179#define APWRMGT BIT(5)
1180#define CBSSID BIT(6)
1181#define CBSSID_DATA BIT(6)
1182#define CBSSID_BCN BIT(7)
1183#define ACRC32 BIT(8)
1184#define AICV BIT(9)
1185#define ADF BIT(11)
1186#define ACF BIT(12)
1187#define AMF BIT(13)
1188#define HTC_LOC_CTRL BIT(14)
1189#define UC_DATA_EN BIT(16)
1190#define BM_DATA_EN BIT(17)
1191#define MFBEN BIT(22)
1192#define LSIGEN BIT(23)
1193#define ENMBID BIT(24)
1194#define APP_BASSN BIT(27)
1195#define APP_PHYSTS BIT(28)
1196#define APP_ICV BIT(29)
1197#define APP_MIC BIT(30)
1198#define APP_FCS BIT(31)
1199
1200#define _MIN_SPACE(x) ((x) & 0x7)
1201#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
1202
1203#define RXERR_TYPE_OFDM_PPDU 0
1204#define RXERR_TYPE_OFDM_FALSE_ALARM 1
1205#define RXERR_TYPE_OFDM_MPDU_OK 2
1206#define RXERR_TYPE_OFDM_MPDU_FAIL 3
1207#define RXERR_TYPE_CCK_PPDU 4
1208#define RXERR_TYPE_CCK_FALSE_ALARM 5
1209#define RXERR_TYPE_CCK_MPDU_OK 6
1210#define RXERR_TYPE_CCK_MPDU_FAIL 7
1211#define RXERR_TYPE_HT_PPDU 8
1212#define RXERR_TYPE_HT_FALSE_ALARM 9
1213#define RXERR_TYPE_HT_MPDU_TOTAL 10
1214#define RXERR_TYPE_HT_MPDU_OK 11
1215#define RXERR_TYPE_HT_MPDU_FAIL 12
1216#define RXERR_TYPE_RX_FULL_DROP 15
1217
1218#define RXERR_COUNTER_MASK 0xFFFFF
1219#define RXERR_RPT_RST BIT(27)
1220#define _RXERR_RPT_SEL(type) ((type) << 28)
1221
1222#define SCR_TXUSEDK BIT(0)
1223#define SCR_RXUSEDK BIT(1)
1224#define SCR_TXENCENABLE BIT(2)
1225#define SCR_RXDECENABLE BIT(3)
1226#define SCR_SKBYA2 BIT(4)
1227#define SCR_NOSKMC BIT(5)
1228#define SCR_TXBCUSEDK BIT(6)
1229#define SCR_RXBCUSEDK BIT(7)
1230
1231#define XCLK_VLD BIT(0)
1232#define ACLK_VLD BIT(1)
1233#define UCLK_VLD BIT(2)
1234#define PCLK_VLD BIT(3)
1235#define PCIRSTB BIT(4)
1236#define V15_VLD BIT(5)
1237#define TRP_B15V_EN BIT(7)
1238#define SIC_IDLE BIT(8)
1239#define BD_MAC2 BIT(9)
1240#define BD_MAC1 BIT(10)
1241#define IC_MACPHY_MODE BIT(11)
1242#define BT_FUNC BIT(16)
1243#define VENDOR_ID BIT(19)
1244#define PAD_HWPD_IDN BIT(22)
1245#define TRP_VAUX_EN BIT(23)
1246#define TRP_BT_EN BIT(24)
1247#define BD_PKG_SEL BIT(25)
1248#define BD_HCI_SEL BIT(26)
1249#define TYPE_ID BIT(27)
1250
1251#define USB_IS_HIGH_SPEED 0
1252#define USB_IS_FULL_SPEED 1
1253#define USB_SPEED_MASK BIT(5)
1254
1255#define USB_NORMAL_SIE_EP_MASK 0xF
1256#define USB_NORMAL_SIE_EP_SHIFT 4
1257
1258#define USB_TEST_EP_MASK 0x30
1259#define USB_TEST_EP_SHIFT 4
1260
1261#define USB_AGG_EN BIT(3)
1262
1263#define MAC_ADDR_LEN 6
1264#define LAST_ENTRY_OF_TX_PKT_BUFFER 175/*255 88e*/
1265
1266#define POLLING_LLT_THRESHOLD 20
1267#define POLLING_READY_TIMEOUT_COUNT 3000
1268
1269#define MAX_MSS_DENSITY_2T 0x13
1270#define MAX_MSS_DENSITY_1T 0x0A
1271
1272#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
1273#define EPROM_CMD_CONFIG 0x3
1274#define EPROM_CMD_LOAD 1
1275
1276#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
1277
1278#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
1279
1280#define RPMAC_RESET 0x100
1281#define RPMAC_TXSTART 0x104
1282#define RPMAC_TXLEGACYSIG 0x108
1283#define RPMAC_TXHTSIG1 0x10c
1284#define RPMAC_TXHTSIG2 0x110
1285#define RPMAC_PHYDEBUG 0x114
1286#define RPMAC_TXPACKETNUM 0x118
1287#define RPMAC_TXIDLE 0x11c
1288#define RPMAC_TXMACHEADER0 0x120
1289#define RPMAC_TXMACHEADER1 0x124
1290#define RPMAC_TXMACHEADER2 0x128
1291#define RPMAC_TXMACHEADER3 0x12c
1292#define RPMAC_TXMACHEADER4 0x130
1293#define RPMAC_TXMACHEADER5 0x134
1294#define RPMAC_TXDADATYPE 0x138
1295#define RPMAC_TXRANDOMSEED 0x13c
1296#define RPMAC_CCKPLCPPREAMBLE 0x140
1297#define RPMAC_CCKPLCPHEADER 0x144
1298#define RPMAC_CCKCRC16 0x148
1299#define RPMAC_OFDMRXCRC32OK 0x170
1300#define RPMAC_OFDMRXCRC32ER 0x174
1301#define RPMAC_OFDMRXPARITYER 0x178
1302#define RPMAC_OFDMRXCRC8ER 0x17c
1303#define RPMAC_CCKCRXRC16ER 0x180
1304#define RPMAC_CCKCRXRC32ER 0x184
1305#define RPMAC_CCKCRXRC32OK 0x188
1306#define RPMAC_TXSTATUS 0x18c
1307
1308#define RFPGA0_RFMOD 0x800
1309
1310#define RFPGA0_TXINFO 0x804
1311#define RFPGA0_PSDFUNCTION 0x808
1312
1313#define RFPGA0_TXGAINSTAGE 0x80c
1314
1315#define RFPGA0_RFTIMING1 0x810
1316#define RFPGA0_RFTIMING2 0x814
1317
1318#define RFPGA0_XA_HSSIPARAMETER1 0x820
1319#define RFPGA0_XA_HSSIPARAMETER2 0x824
1320#define RFPGA0_XB_HSSIPARAMETER1 0x828
1321#define RFPGA0_XB_HSSIPARAMETER2 0x82c
1322
1323#define RFPGA0_XA_LSSIPARAMETER 0x840
1324#define RFPGA0_XB_LSSIPARAMETER 0x844
1325
1326#define RFPGA0_RFWAKEUPPARAMETER 0x850
1327#define RFPGA0_RFSLEEPUPPARAMETER 0x854
1328
1329#define RFPGA0_XAB_SWITCHCONTROL 0x858
1330#define RFPGA0_XCD_SWITCHCONTROL 0x85c
1331
1332#define RFPGA0_XA_RFINTERFACEOE 0x860
1333#define RFPGA0_XB_RFINTERFACEOE 0x864
1334
1335#define RFPGA0_XAB_RFINTERFACESW 0x870
1336#define RFPGA0_XCD_RFINTERFACESW 0x874
1337
1338#define RFPGA0_XAB_RFPARAMETER 0x878
1339#define RFPGA0_XCD_RFPARAMETER 0x87c
1340
1341#define RFPGA0_ANALOGPARAMETER1 0x880
1342#define RFPGA0_ANALOGPARAMETER2 0x884
1343#define RFPGA0_ANALOGPARAMETER3 0x888
1344#define RFPGA0_ANALOGPARAMETER4 0x88c
1345
1346#define RFPGA0_XA_LSSIREADBACK 0x8a0
1347#define RFPGA0_XB_LSSIREADBACK 0x8a4
1348#define RFPGA0_XC_LSSIREADBACK 0x8a8
1349#define RFPGA0_XD_LSSIREADBACK 0x8ac
1350
1351#define RFPGA0_PSDREPORT 0x8b4
1352#define TRANSCEIVEA_HSPI_READBACK 0x8b8
1353#define TRANSCEIVEB_HSPI_READBACK 0x8bc
1354#define REG_SC_CNT 0x8c4
1355#define RFPGA0_XAB_RFINTERFACERB 0x8e0
1356#define RFPGA0_XCD_RFINTERFACERB 0x8e4
1357
1358#define RFPGA1_RFMOD 0x900
1359
1360#define RFPGA1_TXBLOCK 0x904
1361#define RFPGA1_DEBUGSELECT 0x908
1362#define RFPGA1_TXINFO 0x90c
1363
1364#define RCCK0_SYSTEM 0xa00
1365
1366#define RCCK0_AFESETTING 0xa04
1367#define RCCK0_CCA 0xa08
1368
1369#define RCCK0_RXAGC1 0xa0c
1370#define RCCK0_RXAGC2 0xa10
1371
1372#define RCCK0_RXHP 0xa14
1373
1374#define RCCK0_DSPPARAMETER1 0xa18
1375#define RCCK0_DSPPARAMETER2 0xa1c
1376
1377#define RCCK0_TXFILTER1 0xa20
1378#define RCCK0_TXFILTER2 0xa24
1379#define RCCK0_DEBUGPORT 0xa28
1380#define RCCK0_FALSEALARMREPORT 0xa2c
1381#define RCCK0_TRSSIREPORT 0xa50
1382#define RCCK0_RXREPORT 0xa54
1383#define RCCK0_FACOUNTERLOWER 0xa5c
1384#define RCCK0_FACOUNTERUPPER 0xa58
1385#define RCCK0_CCA_CNT 0xa60
1386
1387
1388/* PageB(0xB00) */
1389#define RPDP_ANTA 0xb00
1390#define RPDP_ANTA_4 0xb04
1391#define RPDP_ANTA_8 0xb08
1392#define RPDP_ANTA_C 0xb0c
1393#define RPDP_ANTA_10 0xb10
1394#define RPDP_ANTA_14 0xb14
1395#define RPDP_ANTA_18 0xb18
1396#define RPDP_ANTA_1C 0xb1c
1397#define RPDP_ANTA_20 0xb20
1398#define RPDP_ANTA_24 0xb24
1399
1400#define RCONFIG_PMPD_ANTA 0xb28
1401#define CONFIG_RAM64X16 0xb2c
1402
1403#define RBNDA 0xb30
1404#define RHSSIPAR 0xb34
1405
1406#define RCONFIG_ANTA 0xb68
1407#define RCONFIG_ANTB 0xb6c
1408
1409#define RPDP_ANTB 0xb70
1410#define RPDP_ANTB_4 0xb74
1411#define RPDP_ANTB_8 0xb78
1412#define RPDP_ANTB_C 0xb7c
1413#define RPDP_ANTB_10 0xb80
1414#define RPDP_ANTB_14 0xb84
1415#define RPDP_ANTB_18 0xb88
1416#define RPDP_ANTB_1C 0xb8c
1417#define RPDP_ANTB_20 0xb90
1418#define RPDP_ANTB_24 0xb94
1419
1420#define RCONFIG_PMPD_ANTB 0xb98
1421
1422#define RBNDB 0xba0
1423
1424#define RAPK 0xbd8
1425#define RPM_RX0_ANTA 0xbdc
1426#define RPM_RX1_ANTA 0xbe0
1427#define RPM_RX2_ANTA 0xbe4
1428#define RPM_RX3_ANTA 0xbe8
1429#define RPM_RX0_ANTB 0xbec
1430#define RPM_RX1_ANTB 0xbf0
1431#define RPM_RX2_ANTB 0xbf4
1432#define RPM_RX3_ANTB 0xbf8
1433
1434/*Page C*/
1435#define ROFDM0_LSTF 0xc00
1436
1437#define ROFDM0_TRXPATHENABLE 0xc04
1438#define ROFDM0_TRMUXPAR 0xc08
1439#define ROFDM0_TRSWISOLATION 0xc0c
1440
1441#define ROFDM0_XARXAFE 0xc10
1442#define ROFDM0_XARXIQIMBALANCE 0xc14
1443#define ROFDM0_XBRXAFE 0xc18
1444#define ROFDM0_XBRXIQIMBALANCE 0xc1c
1445#define ROFDM0_XCRXAFE 0xc20
1446#define ROFDM0_XCRXIQIMBANLANCE 0xc24
1447#define ROFDM0_XDRXAFE 0xc28
1448#define ROFDM0_XDRXIQIMBALANCE 0xc2c
1449
1450#define ROFDM0_RXDETECTOR1 0xc30
1451#define ROFDM0_RXDETECTOR2 0xc34
1452#define ROFDM0_RXDETECTOR3 0xc38
1453#define ROFDM0_RXDETECTOR4 0xc3c
1454
1455#define ROFDM0_RXDSP 0xc40
1456#define ROFDM0_CFOANDDAGC 0xc44
1457#define ROFDM0_CCADROPTHRESHOLD 0xc48
1458#define ROFDM0_ECCATHRESHOLD 0xc4c
1459
1460#define ROFDM0_XAAGCCORE1 0xc50
1461#define ROFDM0_XAAGCCORE2 0xc54
1462#define ROFDM0_XBAGCCORE1 0xc58
1463#define ROFDM0_XBAGCCORE2 0xc5c
1464#define ROFDM0_XCAGCCORE1 0xc60
1465#define ROFDM0_XCAGCCORE2 0xc64
1466#define ROFDM0_XDAGCCORE1 0xc68
1467#define ROFDM0_XDAGCCORE2 0xc6c
1468
1469#define ROFDM0_AGCPARAMETER1 0xc70
1470#define ROFDM0_AGCPARAMETER2 0xc74
1471#define ROFDM0_AGCRSSITABLE 0xc78
1472#define ROFDM0_HTSTFAGC 0xc7c
1473
1474#define ROFDM0_XATXIQIMBALANCE 0xc80
1475#define ROFDM0_XATXAFE 0xc84
1476#define ROFDM0_XBTXIQIMBALANCE 0xc88
1477#define ROFDM0_XBTXAFE 0xc8c
1478#define ROFDM0_XCTXIQIMBALANCE 0xc90
1479#define ROFDM0_XCTXAFE 0xc94
1480#define ROFDM0_XDTXIQIMBALANCE 0xc98
1481#define ROFDM0_XDTXAFE 0xc9c
1482
1483#define ROFDM0_RXIQEXTANTA 0xca0
1484#define ROFDM0_TXCOEFF1 0xca4
1485#define ROFDM0_TXCOEFF2 0xca8
1486#define ROFDM0_TXCOEFF3 0xcac
1487#define ROFDM0_TXCOEFF4 0xcb0
1488#define ROFDM0_TXCOEFF5 0xcb4
1489#define ROFDM0_TXCOEFF6 0xcb8
1490
1491#define ROFDM0_RXHPPARAMETER 0xce0
1492#define ROFDM0_TXPSEUDONOISEWGT 0xce4
1493#define ROFDM0_FRAMESYNC 0xcf0
1494#define ROFDM0_DFSREPORT 0xcf4
1495
1496
1497#define ROFDM1_LSTF 0xd00
1498#define ROFDM1_TRXPATHENABLE 0xd04
1499
1500#define ROFDM1_CF0 0xd08
1501#define ROFDM1_CSI1 0xd10
1502#define ROFDM1_SBD 0xd14
1503#define ROFDM1_CSI2 0xd18
1504#define ROFDM1_CFOTRACKING 0xd2c
1505#define ROFDM1_TRXMESAURE1 0xd34
1506#define ROFDM1_INTFDET 0xd3c
1507#define ROFDM1_PSEUDONOISESTATEAB 0xd50
1508#define ROFDM1_PSEUDONOISESTATECD 0xd54
1509#define ROFDM1_RXPSEUDONOISEWGT 0xd58
1510
1511#define ROFDM_PHYCOUNTER1 0xda0
1512#define ROFDM_PHYCOUNTER2 0xda4
1513#define ROFDM_PHYCOUNTER3 0xda8
1514
1515#define ROFDM_SHORTCFOAB 0xdac
1516#define ROFDM_SHORTCFOCD 0xdb0
1517#define ROFDM_LONGCFOAB 0xdb4
1518#define ROFDM_LONGCFOCD 0xdb8
1519#define ROFDM_TAILCF0AB 0xdbc
1520#define ROFDM_TAILCF0CD 0xdc0
1521#define ROFDM_PWMEASURE1 0xdc4
1522#define ROFDM_PWMEASURE2 0xdc8
1523#define ROFDM_BWREPORT 0xdcc
1524#define ROFDM_AGCREPORT 0xdd0
1525#define ROFDM_RXSNR 0xdd4
1526#define ROFDM_RXEVMCSI 0xdd8
1527#define ROFDM_SIGREPORT 0xddc
1528
1529#define RTXAGC_A_RATE18_06 0xe00
1530#define RTXAGC_A_RATE54_24 0xe04
1531#define RTXAGC_A_CCK1_MCS32 0xe08
1532#define RTXAGC_A_MCS03_MCS00 0xe10
1533#define RTXAGC_A_MCS07_MCS04 0xe14
1534#define RTXAGC_A_MCS11_MCS08 0xe18
1535#define RTXAGC_A_MCS15_MCS12 0xe1c
1536
1537#define RTXAGC_B_RATE18_06 0x830
1538#define RTXAGC_B_RATE54_24 0x834
1539#define RTXAGC_B_CCK1_55_MCS32 0x838
1540#define RTXAGC_B_MCS03_MCS00 0x83c
1541#define RTXAGC_B_MCS07_MCS04 0x848
1542#define RTXAGC_B_MCS11_MCS08 0x84c
1543#define RTXAGC_B_MCS15_MCS12 0x868
1544#define RTXAGC_B_CCK11_A_CCK2_11 0x86c
1545
1546#define RFPGA0_IQK 0xe28
1547#define RTX_IQK_TONE_A 0xe30
1548#define RRX_IQK_TONE_A 0xe34
1549#define RTX_IQK_PI_A 0xe38
1550#define RRX_IQK_PI_A 0xe3c
1551
1552#define RTX_IQK 0xe40
1553#define RRX_IQK 0xe44
1554#define RIQK_AGC_PTS 0xe48
1555#define RIQK_AGC_RSP 0xe4c
1556#define RTX_IQK_TONE_B 0xe50
1557#define RRX_IQK_TONE_B 0xe54
1558#define RTX_IQK_PI_B 0xe58
1559#define RRX_IQK_PI_B 0xe5c
1560#define RIQK_AGC_CONT 0xe60
1561
1562#define RBLUE_TOOTH 0xe6c
1563#define RRX_WAIT_CCA 0xe70
1564#define RTX_CCK_RFON 0xe74
1565#define RTX_CCK_BBON 0xe78
1566#define RTX_OFDM_RFON 0xe7c
1567#define RTX_OFDM_BBON 0xe80
1568#define RTX_TO_RX 0xe84
1569#define RTX_TO_TX 0xe88
1570#define RRX_CCK 0xe8c
1571
1572#define RTX_POWER_BEFORE_IQK_A 0xe94
1573#define RTX_POWER_AFTER_IQK_A 0xe9c
1574
1575#define RRX_POWER_BEFORE_IQK_A 0xea0
1576#define RRX_POWER_BEFORE_IQK_A_2 0xea4
1577#define RRX_POWER_AFTER_IQK_A 0xea8
1578#define RRX_POWER_AFTER_IQK_A_2 0xeac
1579
1580#define RTX_POWER_BEFORE_IQK_B 0xeb4
1581#define RTX_POWER_AFTER_IQK_B 0xebc
1582
1583#define RRX_POWER_BEFORE_IQK_B 0xec0
1584#define RRX_POWER_BEFORE_IQK_B_2 0xec4
1585#define RRX_POWER_AFTER_IQK_B 0xec8
1586#define RRX_POWER_AFTER_IQK_B_2 0xecc
1587
1588#define RRX_OFDM 0xed0
1589#define RRX_WAIT_RIFS 0xed4
1590#define RRX_TO_RX 0xed8
1591#define RSTANDBY 0xedc
1592#define RSLEEP 0xee0
1593#define RPMPD_ANAEN 0xeec
1594
1595#define RZEBRA1_HSSIENABLE 0x0
1596#define RZEBRA1_TRXENABLE1 0x1
1597#define RZEBRA1_TRXENABLE2 0x2
1598#define RZEBRA1_AGC 0x4
1599#define RZEBRA1_CHARGEPUMP 0x5
1600#define RZEBRA1_CHANNEL 0x7
1601
1602#define RZEBRA1_TXGAIN 0x8
1603#define RZEBRA1_TXLPF 0x9
1604#define RZEBRA1_RXLPF 0xb
1605#define RZEBRA1_RXHPFCORNER 0xc
1606
1607#define RGLOBALCTRL 0
1608#define RRTL8256_TXLPF 19
1609#define RRTL8256_RXLPF 11
1610#define RRTL8258_TXLPF 0x11
1611#define RRTL8258_RXLPF 0x13
1612#define RRTL8258_RSSILPF 0xa
1613
1614#define RF_AC 0x00
1615
1616#define RF_IQADJ_G1 0x01
1617#define RF_IQADJ_G2 0x02
1618#define RF_POW_TRSW 0x05
1619
1620#define RF_GAIN_RX 0x06
1621#define RF_GAIN_TX 0x07
1622
1623#define RF_TXM_IDAC 0x08
1624#define RF_BS_IQGEN 0x0F
1625
1626#define RF_MODE1 0x10
1627#define RF_MODE2 0x11
1628
1629#define RF_RX_AGC_HP 0x12
1630#define RF_TX_AGC 0x13
1631#define RF_BIAS 0x14
1632#define RF_IPA 0x15
1633#define RF_POW_ABILITY 0x17
1634#define RF_MODE_AG 0x18
1635#define RRFCHANNEL 0x18
1636#define RF_CHNLBW 0x18
1637#define RF_TOP 0x19
1638
1639#define RF_RX_G1 0x1A
1640#define RF_RX_G2 0x1B
1641
1642#define RF_RX_BB2 0x1C
1643#define RF_RX_BB1 0x1D
1644
1645#define RF_RCK1 0x1E
1646#define RF_RCK2 0x1F
1647
1648#define RF_TX_G1 0x20
1649#define RF_TX_G2 0x21
1650#define RF_TX_G3 0x22
1651
1652#define RF_TX_BB1 0x23
1653#define RF_T_METER 0x42
1654
1655#define RF_SYN_G1 0x25
1656#define RF_SYN_G2 0x26
1657#define RF_SYN_G3 0x27
1658#define RF_SYN_G4 0x28
1659#define RF_SYN_G5 0x29
1660#define RF_SYN_G6 0x2A
1661#define RF_SYN_G7 0x2B
1662#define RF_SYN_G8 0x2C
1663
1664#define RF_RCK_OS 0x30
1665#define RF_TXPA_G1 0x31
1666#define RF_TXPA_G2 0x32
1667#define RF_TXPA_G3 0x33
1668
1669#define RF_TX_BIAS_A 0x35
1670#define RF_TX_BIAS_D 0x36
1671#define RF_LOBF_9 0x38
1672#define RF_RXRF_A3 0x3C
1673#define RF_TRSW 0x3F
1674
1675#define RF_TXRF_A2 0x41
1676#define RF_TXPA_G4 0x46
1677#define RF_TXPA_A4 0x4B
1678
1679#define RF_WE_LUT 0xEF
1680
1681#define BBBRESETB 0x100
1682#define BGLOBALRESETB 0x200
1683#define BOFDMTXSTART 0x4
1684#define BCCKTXSTART 0x8
1685#define BCRC32DEBUG 0x100
1686#define BPMACLOOPBACK 0x10
1687#define BTXLSIG 0xffffff
1688#define BOFDMTXRATE 0xf
1689#define BOFDMTXRESERVED 0x10
1690#define BOFDMTXLENGTH 0x1ffe0
1691#define BOFDMTXPARITY 0x20000
1692#define BTXHTSIG1 0xffffff
1693#define BTXHTMCSRATE 0x7f
1694#define BTXHTBW 0x80
1695#define BTXHTLENGTH 0xffff00
1696#define BTXHTSIG2 0xffffff
1697#define BTXHTSMOOTHING 0x1
1698#define BTXHTSOUNDING 0x2
1699#define BTXHTRESERVED 0x4
1700#define BTXHTAGGREATION 0x8
1701#define BTXHTSTBC 0x30
1702#define BTXHTADVANCECODING 0x40
1703#define BTXHTSHORTGI 0x80
1704#define BTXHTNUMBERHT_LTF 0x300
1705#define BTXHTCRC8 0x3fc00
1706#define BCOUNTERRESET 0x10000
1707#define BNUMOFOFDMTX 0xffff
1708#define BNUMOFCCKTX 0xffff0000
1709#define BTXIDLEINTERVAL 0xffff
1710#define BOFDMSERVICE 0xffff0000
1711#define BTXMACHEADER 0xffffffff
1712#define BTXDATAINIT 0xff
1713#define BTXHTMODE 0x100
1714#define BTXDATATYPE 0x30000
1715#define BTXRANDOMSEED 0xffffffff
1716#define BCCKTXPREAMBLE 0x1
1717#define BCCKTXSFD 0xffff0000
1718#define BCCKTXSIG 0xff
1719#define BCCKTXSERVICE 0xff00
1720#define BCCKLENGTHEXT 0x8000
1721#define BCCKTXLENGHT 0xffff0000
1722#define BCCKTXCRC16 0xffff
1723#define BCCKTXSTATUS 0x1
1724#define BOFDMTXSTATUS 0x2
1725#define IS_BB_REG_OFFSET_92S(_offset) \
1726 ((_offset >= 0x800) && (_offset <= 0xfff))
1727
1728#define BRFMOD 0x1
1729#define BJAPANMODE 0x2
1730#define BCCKTXSC 0x30
1731#define BCCKEN 0x1000000
1732#define BOFDMEN 0x2000000
1733
1734#define BOFDMRXADCPHASE 0x10000
1735#define BOFDMTXDACPHASE 0x40000
1736#define BXATXAGC 0x3f
1737
1738#define BXBTXAGC 0xf00
1739#define BXCTXAGC 0xf000
1740#define BXDTXAGC 0xf0000
1741
1742#define BPASTART 0xf0000000
1743#define BTRSTART 0x00f00000
1744#define BRFSTART 0x0000f000
1745#define BBBSTART 0x000000f0
1746#define BBBCCKSTART 0x0000000f
1747#define BPAEND 0xf
1748#define BTREND 0x0f000000
1749#define BRFEND 0x000f0000
1750#define BCCAMASK 0x000000f0
1751#define BR2RCCAMASK 0x00000f00
1752#define BHSSI_R2TDELAY 0xf8000000
1753#define BHSSI_T2RDELAY 0xf80000
1754#define BCONTXHSSI 0x400
1755#define BIGFROMCCK 0x200
1756#define BAGCADDRESS 0x3f
1757#define BRXHPTX 0x7000
1758#define BRXHP2RX 0x38000
1759#define BRXHPCCKINI 0xc0000
1760#define BAGCTXCODE 0xc00000
1761#define BAGCRXCODE 0x300000
1762
1763#define B3WIREDATALENGTH 0x800
1764#define B3WIREADDREAALENGTH 0x400
1765
1766#define B3WIRERFPOWERDOWN 0x1
1767#define B5GPAPEPOLARITY 0x40000000
1768#define B2GPAPEPOLARITY 0x80000000
1769#define BRFSW_TXDEFAULTANT 0x3
1770#define BRFSW_TXOPTIONANT 0x30
1771#define BRFSW_RXDEFAULTANT 0x300
1772#define BRFSW_RXOPTIONANT 0x3000
1773#define BRFSI_3WIREDATA 0x1
1774#define BRFSI_3WIRECLOCK 0x2
1775#define BRFSI_3WIRELOAD 0x4
1776#define BRFSI_3WIRERW 0x8
1777#define BRFSI_3WIRE 0xf
1778
1779#define BRFSI_RFENV 0x10
1780
1781#define BRFSI_TRSW 0x20
1782#define BRFSI_TRSWB 0x40
1783#define BRFSI_ANTSW 0x100
1784#define BRFSI_ANTSWB 0x200
1785#define BRFSI_PAPE 0x400
1786#define BRFSI_PAPE5G 0x800
1787#define BBANDSELECT 0x1
1788#define BHTSIG2_GI 0x80
1789#define BHTSIG2_SMOOTHING 0x01
1790#define BHTSIG2_SOUNDING 0x02
1791#define BHTSIG2_AGGREATON 0x08
1792#define BHTSIG2_STBC 0x30
1793#define BHTSIG2_ADVCODING 0x40
1794#define BHTSIG2_NUMOFHTLTF 0x300
1795#define BHTSIG2_CRC8 0x3fc
1796#define BHTSIG1_MCS 0x7f
1797#define BHTSIG1_BANDWIDTH 0x80
1798#define BHTSIG1_HTLENGTH 0xffff
1799#define BLSIG_RATE 0xf
1800#define BLSIG_RESERVED 0x10
1801#define BLSIG_LENGTH 0x1fffe
1802#define BLSIG_PARITY 0x20
1803#define BCCKRXPHASE 0x4
1804
1805#define BLSSIREADADDRESS 0x7f800000
1806#define BLSSIREADEDGE 0x80000000
1807
1808#define BLSSIREADBACKDATA 0xfffff
1809
1810#define BLSSIREADOKFLAG 0x1000
1811#define BCCKSAMPLERATE 0x8
1812#define BREGULATOR0STANDBY 0x1
1813#define BREGULATORPLLSTANDBY 0x2
1814#define BREGULATOR1STANDBY 0x4
1815#define BPLLPOWERUP 0x8
1816#define BDPLLPOWERUP 0x10
1817#define BDA10POWERUP 0x20
1818#define BAD7POWERUP 0x200
1819#define BDA6POWERUP 0x2000
1820#define BXTALPOWERUP 0x4000
1821#define B40MDCLKPOWERUP 0x8000
1822#define BDA6DEBUGMODE 0x20000
1823#define BDA6SWING 0x380000
1824
1825#define BADCLKPHASE 0x4000000
1826#define B80MCLKDELAY 0x18000000
1827#define BAFEWATCHDOGENABLE 0x20000000
1828
1829#define BXTALCAP01 0xc0000000
1830#define BXTALCAP23 0x3
1831#define BXTALCAP92X 0x0f000000
1832#define BXTALCAP 0x0f000000
1833
1834#define BINTDIFCLKENABLE 0x400
1835#define BEXTSIGCLKENABLE 0x800
1836#define BBANDGAP_MBIAS_POWERUP 0x10000
1837#define BAD11SH_GAIN 0xc0000
1838#define BAD11NPUT_RANGE 0x700000
1839#define BAD110P_CURRENT 0x3800000
1840#define BLPATH_LOOPBACK 0x4000000
1841#define BQPATH_LOOPBACK 0x8000000
1842#define BAFE_LOOPBACK 0x10000000
1843#define BDA10_SWING 0x7e0
1844#define BDA10_REVERSE 0x800
1845#define BDA_CLK_SOURCE 0x1000
1846#define BDA7INPUT_RANGE 0x6000
1847#define BDA7_GAIN 0x38000
1848#define BDA7OUTPUT_CM_MODE 0x40000
1849#define BDA7INPUT_CM_MODE 0x380000
1850#define BDA7CURRENT 0xc00000
1851#define BREGULATOR_ADJUST 0x7000000
1852#define BAD11POWERUP_ATTX 0x1
1853#define BDA10PS_ATTX 0x10
1854#define BAD11POWERUP_ATRX 0x100
1855#define BDA10PS_ATRX 0x1000
1856#define BCCKRX_AGC_FORMAT 0x200
1857#define BPSDFFT_SAMPLE_POINT 0xc000
1858#define BPSD_AVERAGE_NUM 0x3000
1859#define BIQPATH_CONTROL 0xc00
1860#define BPSD_FREQ 0x3ff
1861#define BPSD_ANTENNA_PATH 0x30
1862#define BPSD_IQ_SWITCH 0x40
1863#define BPSD_RX_TRIGGER 0x400000
1864#define BPSD_TX_TRIGGER 0x80000000
1865#define BPSD_SINE_TONE_SCALE 0x7f000000
1866#define BPSD_REPORT 0xffff
1867
1868#define BOFDM_TXSC 0x30000000
1869#define BCCK_TXON 0x1
1870#define BOFDM_TXON 0x2
1871#define BDEBUG_PAGE 0xfff
1872#define BDEBUG_ITEM 0xff
1873#define BANTL 0x10
1874#define BANT_NONHT 0x100
1875#define BANT_HT1 0x1000
1876#define BANT_HT2 0x10000
1877#define BANT_HT1S1 0x100000
1878#define BANT_NONHTS1 0x1000000
1879
1880#define BCCK_BBMODE 0x3
1881#define BCCK_TXPOWERSAVING 0x80
1882#define BCCK_RXPOWERSAVING 0x40
1883
1884#define BCCK_SIDEBAND 0x10
1885
1886#define BCCK_SCRAMBLE 0x8
1887#define BCCK_ANTDIVERSITY 0x8000
1888#define BCCK_CARRIER_RECOVERY 0x4000
1889#define BCCK_TXRATE 0x3000
1890#define BCCK_DCCANCEL 0x0800
1891#define BCCK_ISICANCEL 0x0400
1892#define BCCK_MATCH_FILTER 0x0200
1893#define BCCK_EQUALIZER 0x0100
1894#define BCCK_PREAMBLE_DETECT 0x800000
1895#define BCCK_FAST_FALSECCA 0x400000
1896#define BCCK_CH_ESTSTART 0x300000
1897#define BCCK_CCA_COUNT 0x080000
1898#define BCCK_CS_LIM 0x070000
1899#define BCCK_BIST_MODE 0x80000000
1900#define BCCK_CCAMASK 0x40000000
1901#define BCCK_TX_DAC_PHASE 0x4
1902#define BCCK_RX_ADC_PHASE 0x20000000
1903#define BCCKR_CP_MODE 0x0100
1904#define BCCK_TXDC_OFFSET 0xf0
1905#define BCCK_RXDC_OFFSET 0xf
1906#define BCCK_CCA_MODE 0xc000
1907#define BCCK_FALSECS_LIM 0x3f00
1908#define BCCK_CS_RATIO 0xc00000
1909#define BCCK_CORGBIT_SEL 0x300000
1910#define BCCK_PD_LIM 0x0f0000
1911#define BCCK_NEWCCA 0x80000000
1912#define BCCK_RXHP_OF_IG 0x8000
1913#define BCCK_RXIG 0x7f00
1914#define BCCK_LNA_POLARITY 0x800000
1915#define BCCK_RX1ST_BAIN 0x7f0000
1916#define BCCK_RF_EXTEND 0x20000000
1917#define BCCK_RXAGC_SATLEVEL 0x1f000000
1918#define BCCK_RXAGC_SATCOUNT 0xe0
1919#define BCCKRXRFSETTLE 0x1f
1920#define BCCK_FIXED_RXAGC 0x8000
1921#define BCCK_ANTENNA_POLARITY 0x2000
1922#define BCCK_TXFILTER_TYPE 0x0c00
1923#define BCCK_RXAGC_REPORTTYPE 0x0300
1924#define BCCK_RXDAGC_EN 0x80000000
1925#define BCCK_RXDAGC_PERIOD 0x20000000
1926#define BCCK_RXDAGC_SATLEVEL 0x1f000000
1927#define BCCK_TIMING_RECOVERY 0x800000
1928#define BCCK_TXC0 0x3f0000
1929#define BCCK_TXC1 0x3f000000
1930#define BCCK_TXC2 0x3f
1931#define BCCK_TXC3 0x3f00
1932#define BCCK_TXC4 0x3f0000
1933#define BCCK_TXC5 0x3f000000
1934#define BCCK_TXC6 0x3f
1935#define BCCK_TXC7 0x3f00
1936#define BCCK_DEBUGPORT 0xff0000
1937#define BCCK_DAC_DEBUG 0x0f000000
1938#define BCCK_FALSEALARM_ENABLE 0x8000
1939#define BCCK_FALSEALARM_READ 0x4000
1940#define BCCK_TRSSI 0x7f
1941#define BCCK_RXAGC_REPORT 0xfe
1942#define BCCK_RXREPORT_ANTSEL 0x80000000
1943#define BCCK_RXREPORT_MFOFF 0x40000000
1944#define BCCK_RXREPORT_SQLOSS 0x20000000
1945#define BCCK_RXREPORT_PKTLOSS 0x10000000
1946#define BCCK_RXREPORT_LOCKEDBIT 0x08000000
1947#define BCCK_RXREPORT_RATEERROR 0x04000000
1948#define BCCK_RXREPORT_RXRATE 0x03000000
1949#define BCCK_RXFA_COUNTER_LOWER 0xff
1950#define BCCK_RXFA_COUNTER_UPPER 0xff000000
1951#define BCCK_RXHPAGC_START 0xe000
1952#define BCCK_RXHPAGC_FINAL 0x1c00
1953#define BCCK_RXFALSEALARM_ENABLE 0x8000
1954#define BCCK_FACOUNTER_FREEZE 0x4000
1955#define BCCK_TXPATH_SEL 0x10000000
1956#define BCCK_DEFAULT_RXPATH 0xc000000
1957#define BCCK_OPTION_RXPATH 0x3000000
1958
1959#define BNUM_OFSTF 0x3
1960#define BSHIFT_L 0xc0
1961#define BGI_TH 0xc
1962#define BRXPATH_A 0x1
1963#define BRXPATH_B 0x2
1964#define BRXPATH_C 0x4
1965#define BRXPATH_D 0x8
1966#define BTXPATH_A 0x1
1967#define BTXPATH_B 0x2
1968#define BTXPATH_C 0x4
1969#define BTXPATH_D 0x8
1970#define BTRSSI_FREQ 0x200
1971#define BADC_BACKOFF 0x3000
1972#define BDFIR_BACKOFF 0xc000
1973#define BTRSSI_LATCH_PHASE 0x10000
1974#define BRX_LDC_OFFSET 0xff
1975#define BRX_QDC_OFFSET 0xff00
1976#define BRX_DFIR_MODE 0x1800000
1977#define BRX_DCNF_TYPE 0xe000000
1978#define BRXIQIMB_A 0x3ff
1979#define BRXIQIMB_B 0xfc00
1980#define BRXIQIMB_C 0x3f0000
1981#define BRXIQIMB_D 0xffc00000
1982#define BDC_DC_NOTCH 0x60000
1983#define BRXNB_NOTCH 0x1f000000
1984#define BPD_TH 0xf
1985#define BPD_TH_OPT2 0xc000
1986#define BPWED_TH 0x700
1987#define BIFMF_WIN_L 0x800
1988#define BPD_OPTION 0x1000
1989#define BMF_WIN_L 0xe000
1990#define BBW_SEARCH_L 0x30000
1991#define BWIN_ENH_L 0xc0000
1992#define BBW_TH 0x700000
1993#define BED_TH2 0x3800000
1994#define BBW_OPTION 0x4000000
1995#define BRADIO_TH 0x18000000
1996#define BWINDOW_L 0xe0000000
1997#define BSBD_OPTION 0x1
1998#define BFRAME_TH 0x1c
1999#define BFS_OPTION 0x60
2000#define BDC_SLOPE_CHECK 0x80
2001#define BFGUARD_COUNTER_DC_L 0xe00
2002#define BFRAME_WEIGHT_SHORT 0x7000
2003#define BSUB_TUNE 0xe00000
2004#define BFRAME_DC_LENGTH 0xe000000
2005#define BSBD_START_OFFSET 0x30000000
2006#define BFRAME_TH_2 0x7
2007#define BFRAME_GI2_TH 0x38
2008#define BGI2_SYNC_EN 0x40
2009#define BSARCH_SHORT_EARLY 0x300
2010#define BSARCH_SHORT_LATE 0xc00
2011#define BSARCH_GI2_LATE 0x70000
2012#define BCFOANTSUM 0x1
2013#define BCFOACC 0x2
2014#define BCFOSTARTOFFSET 0xc
2015#define BCFOLOOPBACK 0x70
2016#define BCFOSUMWEIGHT 0x80
2017#define BDAGCENABLE 0x10000
2018#define BTXIQIMB_A 0x3ff
2019#define BTXIQIMB_b 0xfc00
2020#define BTXIQIMB_C 0x3f0000
2021#define BTXIQIMB_D 0xffc00000
2022#define BTXIDCOFFSET 0xff
2023#define BTXIQDCOFFSET 0xff00
2024#define BTXDFIRMODE 0x10000
2025#define BTXPESUDO_NOISEON 0x4000000
2026#define BTXPESUDO_NOISE_A 0xff
2027#define BTXPESUDO_NOISE_B 0xff00
2028#define BTXPESUDO_NOISE_C 0xff0000
2029#define BTXPESUDO_NOISE_D 0xff000000
2030#define BCCA_DROPOPTION 0x20000
2031#define BCCA_DROPTHRES 0xfff00000
2032#define BEDCCA_H 0xf
2033#define BEDCCA_L 0xf0
2034#define BLAMBDA_ED 0x300
2035#define BRX_INITIALGAIN 0x7f
2036#define BRX_ANTDIV_EN 0x80
2037#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00
2038#define BRX_HIGHPOWER_FLOW 0x8000
2039#define BRX_AGC_FREEZE_THRES 0xc0000
2040#define BRX_FREEZESTEP_AGC1 0x300000
2041#define BRX_FREEZESTEP_AGC2 0xc00000
2042#define BRX_FREEZESTEP_AGC3 0x3000000
2043#define BRX_FREEZESTEP_AGC0 0xc000000
2044#define BRXRSSI_CMP_EN 0x10000000
2045#define BRXQUICK_AGCEN 0x20000000
2046#define BRXAGC_FREEZE_THRES_MODE 0x40000000
2047#define BRX_OVERFLOW_CHECKTYPE 0x80000000
2048#define BRX_AGCSHIFT 0x7f
2049#define BTRSW_TRI_ONLY 0x80
2050#define BPOWER_THRES 0x300
2051#define BRXAGC_EN 0x1
2052#define BRXAGC_TOGETHER_EN 0x2
2053#define BRXAGC_MIN 0x4
2054#define BRXHP_INI 0x7
2055#define BRXHP_TRLNA 0x70
2056#define BRXHP_RSSI 0x700
2057#define BRXHP_BBP1 0x7000
2058#define BRXHP_BBP2 0x70000
2059#define BRXHP_BBP3 0x700000
2060#define BRSSI_H 0x7f0000
2061#define BRSSI_GEN 0x7f000000
2062#define BRXSETTLE_TRSW 0x7
2063#define BRXSETTLE_LNA 0x38
2064#define BRXSETTLE_RSSI 0x1c0
2065#define BRXSETTLE_BBP 0xe00
2066#define BRXSETTLE_RXHP 0x7000
2067#define BRXSETTLE_ANTSW_RSSI 0x38000
2068#define BRXSETTLE_ANTSW 0xc0000
2069#define BRXPROCESS_TIME_DAGC 0x300000
2070#define BRXSETTLE_HSSI 0x400000
2071#define BRXPROCESS_TIME_BBPPW 0x800000
2072#define BRXANTENNA_POWER_SHIFT 0x3000000
2073#define BRSSI_TABLE_SELECT 0xc000000
2074#define BRXHP_FINAL 0x7000000
2075#define BRXHPSETTLE_BBP 0x7
2076#define BRXHTSETTLE_HSSI 0x8
2077#define BRXHTSETTLE_RXHP 0x70
2078#define BRXHTSETTLE_BBPPW 0x80
2079#define BRXHTSETTLE_IDLE 0x300
2080#define BRXHTSETTLE_RESERVED 0x1c00
2081#define BRXHT_RXHP_EN 0x8000
2082#define BRXAGC_FREEZE_THRES 0x30000
2083#define BRXAGC_TOGETHEREN 0x40000
2084#define BRXHTAGC_MIN 0x80000
2085#define BRXHTAGC_EN 0x100000
2086#define BRXHTDAGC_EN 0x200000
2087#define BRXHT_RXHP_BBP 0x1c00000
2088#define BRXHT_RXHP_FINAL 0xe0000000
2089#define BRXPW_RADIO_TH 0x3
2090#define BRXPW_RADIO_EN 0x4
2091#define BRXMF_HOLD 0x3800
2092#define BRXPD_DELAY_TH1 0x38
2093#define BRXPD_DELAY_TH2 0x1c0
2094#define BRXPD_DC_COUNT_MAX 0x600
2095#define BRXPD_DELAY_TH 0x8000
2096#define BRXPROCESS_DELAY 0xf0000
2097#define BRXSEARCHRANGE_GI2_EARLY 0x700000
2098#define BRXFRAME_FUARD_COUNTER_L 0x3800000
2099#define BRXSGI_GUARD_L 0xc000000
2100#define BRXSGI_SEARCH_L 0x30000000
2101#define BRXSGI_TH 0xc0000000
2102#define BDFSCNT0 0xff
2103#define BDFSCNT1 0xff00
2104#define BDFSFLAG 0xf0000
2105#define BMF_WEIGHT_SUM 0x300000
2106#define BMINIDX_TH 0x7f000000
2107#define BDAFORMAT 0x40000
2108#define BTXCH_EMU_ENABLE 0x01000000
2109#define BTRSW_ISOLATION_A 0x7f
2110#define BTRSW_ISOLATION_B 0x7f00
2111#define BTRSW_ISOLATION_C 0x7f0000
2112#define BTRSW_ISOLATION_D 0x7f000000
2113#define BEXT_LNA_GAIN 0x7c00
2114
2115#define BSTBC_EN 0x4
2116#define BANTENNA_MAPPING 0x10
2117#define BNSS 0x20
2118#define BCFO_ANTSUM_ID 0x200
2119#define BPHY_COUNTER_RESET 0x8000000
2120#define BCFO_REPORT_GET 0x4000000
2121#define BOFDM_CONTINUE_TX 0x10000000
2122#define BOFDM_SINGLE_CARRIER 0x20000000
2123#define BOFDM_SINGLE_TONE 0x40000000
2124#define BHT_DETECT 0x100
2125#define BCFOEN 0x10000
2126#define BCFOVALUE 0xfff00000
2127#define BSIGTONE_RE 0x3f
2128#define BSIGTONE_IM 0x7f00
2129#define BCOUNTER_CCA 0xffff
2130#define BCOUNTER_PARITYFAIL 0xffff0000
2131#define BCOUNTER_RATEILLEGAL 0xffff
2132#define BCOUNTER_CRC8FAIL 0xffff0000
2133#define BCOUNTER_MCSNOSUPPORT 0xffff
2134#define BCOUNTER_FASTSYNC 0xffff
2135#define BSHORTCFO 0xfff
2136#define BSHORTCFOT_LENGTH 12
2137#define BSHORTCFOF_LENGTH 11
2138#define BLONGCFO 0x7ff
2139#define BLONGCFOT_LENGTH 11
2140#define BLONGCFOF_LENGTH 11
2141#define BTAILCFO 0x1fff
2142#define BTAILCFOT_LENGTH 13
2143#define BTAILCFOF_LENGTH 12
2144#define BNOISE_EN_PWDB 0xffff
2145#define BCC_POWER_DB 0xffff0000
2146#define BMOISE_PWDB 0xffff
2147#define BPOWERMEAST_LENGTH 10
2148#define BPOWERMEASF_LENGTH 3
2149#define BRX_HT_BW 0x1
2150#define BRXSC 0x6
2151#define BRX_HT 0x8
2152#define BNB_INTF_DET_ON 0x1
2153#define BINTF_WIN_LEN_CFG 0x30
2154#define BNB_INTF_TH_CFG 0x1c0
2155#define BRFGAIN 0x3f
2156#define BTABLESEL 0x40
2157#define BTRSW 0x80
2158#define BRXSNR_A 0xff
2159#define BRXSNR_B 0xff00
2160#define BRXSNR_C 0xff0000
2161#define BRXSNR_D 0xff000000
2162#define BSNR_EVMT_LENGTH 8
2163#define BSNR_EVMF_LENGTH 1
2164#define BCSI1ST 0xff
2165#define BCSI2ND 0xff00
2166#define BRXEVM1ST 0xff0000
2167#define BRXEVM2ND 0xff000000
2168#define BSIGEVM 0xff
2169#define BPWDB 0xff00
2170#define BSGIEN 0x10000
2171
2172#define BSFACTOR_QMA1 0xf
2173#define BSFACTOR_QMA2 0xf0
2174#define BSFACTOR_QMA3 0xf00
2175#define BSFACTOR_QMA4 0xf000
2176#define BSFACTOR_QMA5 0xf0000
2177#define BSFACTOR_QMA6 0xf0000
2178#define BSFACTOR_QMA7 0xf00000
2179#define BSFACTOR_QMA8 0xf000000
2180#define BSFACTOR_QMA9 0xf0000000
2181#define BCSI_SCHEME 0x100000
2182
2183#define BNOISE_LVL_TOP_SET 0x3
2184#define BCHSMOOTH 0x4
2185#define BCHSMOOTH_CFG1 0x38
2186#define BCHSMOOTH_CFG2 0x1c0
2187#define BCHSMOOTH_CFG3 0xe00
2188#define BCHSMOOTH_CFG4 0x7000
2189#define BMRCMODE 0x800000
2190#define BTHEVMCFG 0x7000000
2191
2192#define BLOOP_FIT_TYPE 0x1
2193#define BUPD_CFO 0x40
2194#define BUPD_CFO_OFFDATA 0x80
2195#define BADV_UPD_CFO 0x100
2196#define BADV_TIME_CTRL 0x800
2197#define BUPD_CLKO 0x1000
2198#define BFC 0x6000
2199#define BTRACKING_MODE 0x8000
2200#define BPHCMP_ENABLE 0x10000
2201#define BUPD_CLKO_LTF 0x20000
2202#define BCOM_CH_CFO 0x40000
2203#define BCSI_ESTI_MODE 0x80000
2204#define BADV_UPD_EQZ 0x100000
2205#define BUCHCFG 0x7000000
2206#define BUPDEQZ 0x8000000
2207
2208#define BRX_PESUDO_NOISE_ON 0x20000000
2209#define BRX_PESUDO_NOISE_A 0xff
2210#define BRX_PESUDO_NOISE_B 0xff00
2211#define BRX_PESUDO_NOISE_C 0xff0000
2212#define BRX_PESUDO_NOISE_D 0xff000000
2213#define BRX_PESUDO_NOISESTATE_A 0xffff
2214#define BRX_PESUDO_NOISESTATE_B 0xffff0000
2215#define BRX_PESUDO_NOISESTATE_C 0xffff
2216#define BRX_PESUDO_NOISESTATE_D 0xffff0000
2217
2218#define BZEBRA1_HSSIENABLE 0x8
2219#define BZEBRA1_TRXCONTROL 0xc00
2220#define BZEBRA1_TRXGAINSETTING 0x07f
2221#define BZEBRA1_RXCOUNTER 0xc00
2222#define BZEBRA1_TXCHANGEPUMP 0x38
2223#define BZEBRA1_RXCHANGEPUMP 0x7
2224#define BZEBRA1_CHANNEL_NUM 0xf80
2225#define BZEBRA1_TXLPFBW 0x400
2226#define BZEBRA1_RXLPFBW 0x600
2227
2228#define BRTL8256REG_MODE_CTRL1 0x100
2229#define BRTL8256REG_MODE_CTRL0 0x40
2230#define BRTL8256REG_TXLPFBW 0x18
2231#define BRTL8256REG_RXLPFBW 0x600
2232
2233#define BRTL8258_TXLPFBW 0xc
2234#define BRTL8258_RXLPFBW 0xc00
2235#define BRTL8258_RSSILPFBW 0xc0
2236
2237#define BBYTE0 0x1
2238#define BBYTE1 0x2
2239#define BBYTE2 0x4
2240#define BBYTE3 0x8
2241#define BWORD0 0x3
2242#define BWORD1 0xc
2243#define BWORD 0xf
2244
2245#define MASKBYTE0 0xff
2246#define MASKBYTE1 0xff00
2247#define MASKBYTE2 0xff0000
2248#define MASKBYTE3 0xff000000
2249#define MASKHWORD 0xffff0000
2250#define MASKLWORD 0x0000ffff
2251#define MASKDWORD 0xffffffff
2252#define MASK12BITS 0xfff
2253#define MASKH4BITS 0xf0000000
2254#define MASKOFDM_D 0xffc00000
2255#define MASKCCK 0x3f3f3f3f
2256
2257#define MASK4BITS 0x0f
2258#define MASK20BITS 0xfffff
2259#define RFREG_OFFSET_MASK 0xfffff
2260
2261#define BENABLE 0x1
2262#define BDISABLE 0x0
2263
2264#define LEFT_ANTENNA 0x0
2265#define RIGHT_ANTENNA 0x1
2266
2267#define TCHECK_TXSTATUS 500
2268#define TUPDATE_RXCOUNTER 100
2269
2270#define REG_UN_used_register 0x01bf
2271
2272/* WOL bit information */
2273#define HAL92C_WOL_PTK_UPDATE_EVENT BIT(0)
2274#define HAL92C_WOL_GTK_UPDATE_EVENT BIT(1)
2275#define HAL92C_WOL_DISASSOC_EVENT BIT(2)
2276#define HAL92C_WOL_DEAUTH_EVENT BIT(3)
2277#define HAL92C_WOL_FW_DISCONNECT_EVENT BIT(4)
2278
2279#define WOL_REASON_PTK_UPDATE BIT(0)
2280#define WOL_REASON_GTK_UPDATE BIT(1)
2281#define WOL_REASON_DISASSOC BIT(2)
2282#define WOL_REASON_DEAUTH BIT(3)
2283#define WOL_REASON_FW_DISCONNECT BIT(4)
2284
2285/* 2 EFUSE_TEST (For RTL8723 partially) */
2286#define EFUSE_SEL(x) (((x) & 0x3) << 8)
2287#define EFUSE_SEL_MASK 0x300
2288#define EFUSE_WIFI_SEL_0 0x0
2289
2290#define WL_HWPDN_EN BIT(0) /* Enable GPIO[9] as WiFi HW PDn source*/
2291#define WL_HWPDN_SL BIT(1) /* WiFi HW PDn polarity control*/
2292
2293#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.c b/drivers/net/wireless/rtlwifi/rtl8723be/rf.c
new file mode 100644
index 000000000000..486294930a7b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/rf.c
@@ -0,0 +1,504 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "reg.h"
28#include "def.h"
29#include "phy.h"
30#include "rf.h"
31#include "dm.h"
32
33static bool _rtl8723be_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
34
35void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
36{
37 struct rtl_priv *rtlpriv = rtl_priv(hw);
38 struct rtl_phy *rtlphy = &(rtlpriv->phy);
39
40 switch (bandwidth) {
41 case HT_CHANNEL_WIDTH_20:
42 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
43 0xfffff3ff) | BIT(10) | BIT(11));
44 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
45 rtlphy->rfreg_chnlval[0]);
46 break;
47 case HT_CHANNEL_WIDTH_20_40:
48 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
49 0xfffff3ff) | BIT(10));
50 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
51 rtlphy->rfreg_chnlval[0]);
52 break;
53 default:
54 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
55 "unknown bandwidth: %#X\n", bandwidth);
56 break;
57 }
58}
59
60void rtl8723be_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
61 u8 *ppowerlevel)
62{
63 struct rtl_priv *rtlpriv = rtl_priv(hw);
64 struct rtl_phy *rtlphy = &(rtlpriv->phy);
65 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
66 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
67 u32 tx_agc[2] = {0, 0}, tmpval;
68 bool turbo_scanoff = false;
69 u8 idx1, idx2;
70 u8 *ptr;
71 u8 direction;
72 u32 pwrtrac_value;
73
74 if (rtlefuse->eeprom_regulatory != 0)
75 turbo_scanoff = true;
76
77 if (mac->act_scanning) {
78 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
79 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
80
81 if (turbo_scanoff) {
82 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
83 tx_agc[idx1] = ppowerlevel[idx1] |
84 (ppowerlevel[idx1] << 8) |
85 (ppowerlevel[idx1] << 16) |
86 (ppowerlevel[idx1] << 24);
87 }
88 }
89 } else {
90 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
91 tx_agc[idx1] = ppowerlevel[idx1] |
92 (ppowerlevel[idx1] << 8) |
93 (ppowerlevel[idx1] << 16) |
94 (ppowerlevel[idx1] << 24);
95 }
96 if (rtlefuse->eeprom_regulatory == 0) {
97 tmpval =
98 (rtlphy->mcs_offset[0][6]) +
99 (rtlphy->mcs_offset[0][7] << 8);
100 tx_agc[RF90_PATH_A] += tmpval;
101
102 tmpval = (rtlphy->mcs_offset[0][14]) +
103 (rtlphy->mcs_offset[0][15] <<
104 24);
105 tx_agc[RF90_PATH_B] += tmpval;
106 }
107 }
108 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
109 ptr = (u8 *)(&(tx_agc[idx1]));
110 for (idx2 = 0; idx2 < 4; idx2++) {
111 if (*ptr > RF6052_MAX_TX_PWR)
112 *ptr = RF6052_MAX_TX_PWR;
113 ptr++;
114 }
115 }
116 rtl8723be_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value);
117 if (direction == 1) {
118 tx_agc[0] += pwrtrac_value;
119 tx_agc[1] += pwrtrac_value;
120 } else if (direction == 2) {
121 tx_agc[0] -= pwrtrac_value;
122 tx_agc[1] -= pwrtrac_value;
123 }
124 tmpval = tx_agc[RF90_PATH_A] & 0xff;
125 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
126
127 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
128 "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
129 RTXAGC_A_CCK1_MCS32);
130
131 tmpval = tx_agc[RF90_PATH_A] >> 8;
132
133 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
134
135 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
136 "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
137 RTXAGC_B_CCK11_A_CCK2_11);
138
139 tmpval = tx_agc[RF90_PATH_B] >> 24;
140 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
141
142 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
143 "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
144 RTXAGC_B_CCK11_A_CCK2_11);
145
146 tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
147 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
148
149 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
150 "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
151 RTXAGC_B_CCK1_55_MCS32);
152}
153
154static void rtl8723be_phy_get_power_base(struct ieee80211_hw *hw,
155 u8 *ppowerlevel_ofdm,
156 u8 *ppowerlevel_bw20,
157 u8 *ppowerlevel_bw40,
158 u8 channel, u32 *ofdmbase,
159 u32 *mcsbase)
160{
161 struct rtl_priv *rtlpriv = rtl_priv(hw);
162 struct rtl_phy *rtlphy = &(rtlpriv->phy);
163 u32 powerbase0, powerbase1;
164 u8 i, powerlevel[2];
165
166 for (i = 0; i < 2; i++) {
167 powerbase0 = ppowerlevel_ofdm[i];
168
169 powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
170 (powerbase0 << 8) | powerbase0;
171 *(ofdmbase + i) = powerbase0;
172 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
173 " [OFDM power base index rf(%c) = 0x%x]\n",
174 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i));
175 }
176
177 for (i = 0; i < 2; i++) {
178 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20)
179 powerlevel[i] = ppowerlevel_bw20[i];
180 else
181 powerlevel[i] = ppowerlevel_bw40[i];
182 powerbase1 = powerlevel[i];
183 powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) |
184 (powerbase1 << 8) | powerbase1;
185
186 *(mcsbase + i) = powerbase1;
187
188 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
189 " [MCS power base index rf(%c) = 0x%x]\n",
190 ((i == 0) ? 'A' : 'B'), *(mcsbase + i));
191 }
192}
193
194static void txpwr_by_regulatory(struct ieee80211_hw *hw, u8 channel, u8 index,
195 u32 *powerbase0, u32 *powerbase1,
196 u32 *p_outwriteval)
197{
198 struct rtl_priv *rtlpriv = rtl_priv(hw);
199 struct rtl_phy *rtlphy = &(rtlpriv->phy);
200 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
201 u8 i, chnlgroup = 0, pwr_diff_limit[4];
202 u8 pwr_diff = 0, customer_pwr_diff;
203 u32 writeval, customer_limit, rf;
204
205 for (rf = 0; rf < 2; rf++) {
206 switch (rtlefuse->eeprom_regulatory) {
207 case 0:
208 chnlgroup = 0;
209
210 writeval =
211 rtlphy->mcs_offset[chnlgroup][index + (rf ? 8 : 0)]
212 + ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
213
214 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
215 "RTK better performance, "
216 "writeval(%c) = 0x%x\n",
217 ((rf == 0) ? 'A' : 'B'), writeval);
218 break;
219 case 1:
220 if (rtlphy->pwrgroup_cnt == 1) {
221 chnlgroup = 0;
222 } else {
223 if (channel < 3)
224 chnlgroup = 0;
225 else if (channel < 6)
226 chnlgroup = 1;
227 else if (channel < 9)
228 chnlgroup = 2;
229 else if (channel < 12)
230 chnlgroup = 3;
231 else if (channel < 14)
232 chnlgroup = 4;
233 else if (channel == 14)
234 chnlgroup = 5;
235 }
236 writeval = rtlphy->mcs_offset[chnlgroup]
237 [index + (rf ? 8 : 0)] + ((index < 2) ?
238 powerbase0[rf] :
239 powerbase1[rf]);
240
241 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
242 "Realtek regulatory, 20MHz, "
243 "writeval(%c) = 0x%x\n",
244 ((rf == 0) ? 'A' : 'B'), writeval);
245
246 break;
247 case 2:
248 writeval =
249 ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
250
251 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
252 "Better regulatory, "
253 "writeval(%c) = 0x%x\n",
254 ((rf == 0) ? 'A' : 'B'), writeval);
255 break;
256 case 3:
257 chnlgroup = 0;
258
259 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
260 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
261 "customer's limit, 40MHz "
262 "rf(%c) = 0x%x\n",
263 ((rf == 0) ? 'A' : 'B'),
264 rtlefuse->pwrgroup_ht40[rf]
265 [channel-1]);
266 } else {
267 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
268 "customer's limit, 20MHz "
269 "rf(%c) = 0x%x\n",
270 ((rf == 0) ? 'A' : 'B'),
271 rtlefuse->pwrgroup_ht20[rf]
272 [channel-1]);
273 }
274
275 if (index < 2)
276 pwr_diff =
277 rtlefuse->txpwr_legacyhtdiff[rf][channel-1];
278 else if (rtlphy->current_chan_bw ==
279 HT_CHANNEL_WIDTH_20)
280 pwr_diff =
281 rtlefuse->txpwr_ht20diff[rf][channel-1];
282
283 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
284 customer_pwr_diff =
285 rtlefuse->pwrgroup_ht40[rf][channel-1];
286 else
287 customer_pwr_diff =
288 rtlefuse->pwrgroup_ht20[rf][channel-1];
289
290 if (pwr_diff > customer_pwr_diff)
291 pwr_diff = 0;
292 else
293 pwr_diff = customer_pwr_diff - pwr_diff;
294
295 for (i = 0; i < 4; i++) {
296 pwr_diff_limit[i] =
297 (u8)((rtlphy->mcs_offset
298 [chnlgroup][index + (rf ? 8 : 0)] &
299 (0x7f << (i * 8))) >> (i * 8));
300
301 if (pwr_diff_limit[i] > pwr_diff)
302 pwr_diff_limit[i] = pwr_diff;
303 }
304
305 customer_limit = (pwr_diff_limit[3] << 24) |
306 (pwr_diff_limit[2] << 16) |
307 (pwr_diff_limit[1] << 8) |
308 (pwr_diff_limit[0]);
309
310 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
311 "Customer's limit rf(%c) = 0x%x\n",
312 ((rf == 0) ? 'A' : 'B'), customer_limit);
313
314 writeval = customer_limit + ((index < 2) ?
315 powerbase0[rf] :
316 powerbase1[rf]);
317
318 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
319 "Customer, writeval rf(%c)= 0x%x\n",
320 ((rf == 0) ? 'A' : 'B'), writeval);
321 break;
322 default:
323 chnlgroup = 0;
324 writeval =
325 rtlphy->mcs_offset[chnlgroup]
326 [index + (rf ? 8 : 0)]
327 + ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
328
329 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
330 "RTK better performance, writeval "
331 "rf(%c) = 0x%x\n",
332 ((rf == 0) ? 'A' : 'B'), writeval);
333 break;
334 }
335
336 if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
337 writeval = writeval - 0x06060606;
338 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
339 TXHIGHPWRLEVEL_BT2)
340 writeval = writeval - 0x0c0c0c0c;
341 *(p_outwriteval + rf) = writeval;
342 }
343}
344
345static void _rtl8723be_write_ofdm_power_reg(struct ieee80211_hw *hw,
346 u8 index, u32 *value)
347{
348 struct rtl_priv *rtlpriv = rtl_priv(hw);
349 u16 regoffset_a[6] = {
350 RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
351 RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
352 RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
353 };
354 u16 regoffset_b[6] = {
355 RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
356 RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
357 RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
358 };
359 u8 i, rf, pwr_val[4];
360 u32 writeval;
361 u16 regoffset;
362
363 for (rf = 0; rf < 2; rf++) {
364 writeval = value[rf];
365 for (i = 0; i < 4; i++) {
366 pwr_val[i] = (u8) ((writeval & (0x7f <<
367 (i * 8))) >> (i * 8));
368
369 if (pwr_val[i] > RF6052_MAX_TX_PWR)
370 pwr_val[i] = RF6052_MAX_TX_PWR;
371 }
372 writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
373 (pwr_val[1] << 8) | pwr_val[0];
374
375 if (rf == 0)
376 regoffset = regoffset_a[index];
377 else
378 regoffset = regoffset_b[index];
379 rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
380
381 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
382 "Set 0x%x = %08x\n", regoffset, writeval);
383 }
384}
385
386void rtl8723be_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
387 u8 *ppowerlevel_ofdm,
388 u8 *ppowerlevel_bw20,
389 u8 *ppowerlevel_bw40, u8 channel)
390{
391 u32 writeval[2], powerbase0[2], powerbase1[2];
392 u8 index;
393 u8 direction;
394 u32 pwrtrac_value;
395
396 rtl8723be_phy_get_power_base(hw, ppowerlevel_ofdm, ppowerlevel_bw20,
397 ppowerlevel_bw40, channel,
398 &powerbase0[0], &powerbase1[0]);
399
400 rtl8723be_dm_txpower_track_adjust(hw, 1, &direction, &pwrtrac_value);
401
402 for (index = 0; index < 6; index++) {
403 txpwr_by_regulatory(hw, channel, index, &powerbase0[0],
404 &powerbase1[0], &writeval[0]);
405 if (direction == 1) {
406 writeval[0] += pwrtrac_value;
407 writeval[1] += pwrtrac_value;
408 } else if (direction == 2) {
409 writeval[0] -= pwrtrac_value;
410 writeval[1] -= pwrtrac_value;
411 }
412 _rtl8723be_write_ofdm_power_reg(hw, index, &writeval[0]);
413 }
414}
415
416bool rtl8723be_phy_rf6052_config(struct ieee80211_hw *hw)
417{
418 struct rtl_priv *rtlpriv = rtl_priv(hw);
419 struct rtl_phy *rtlphy = &(rtlpriv->phy);
420
421 if (rtlphy->rf_type == RF_1T1R)
422 rtlphy->num_total_rfpath = 1;
423 else
424 rtlphy->num_total_rfpath = 2;
425
426 return _rtl8723be_phy_rf6052_config_parafile(hw);
427}
428
429static bool _rtl8723be_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
430{
431 struct rtl_priv *rtlpriv = rtl_priv(hw);
432 struct rtl_phy *rtlphy = &(rtlpriv->phy);
433 struct bb_reg_def *pphyreg;
434 u32 u4_regvalue = 0;
435 u8 rfpath;
436 bool rtstatus = true;
437
438 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
439 pphyreg = &rtlphy->phyreg_def[rfpath];
440
441 switch (rfpath) {
442 case RF90_PATH_A:
443 case RF90_PATH_C:
444 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
445 BRFSI_RFENV);
446 break;
447 case RF90_PATH_B:
448 case RF90_PATH_D:
449 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
450 BRFSI_RFENV << 16);
451 break;
452 }
453
454 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
455 udelay(1);
456
457 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
458 udelay(1);
459
460 rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
461 B3WIREADDREAALENGTH, 0x0);
462 udelay(1);
463
464 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
465 udelay(1);
466
467 switch (rfpath) {
468 case RF90_PATH_A:
469 rtstatus = rtl8723be_phy_config_rf_with_headerfile(hw,
470 (enum radio_path)rfpath);
471 break;
472 case RF90_PATH_B:
473 rtstatus = rtl8723be_phy_config_rf_with_headerfile(hw,
474 (enum radio_path)rfpath);
475 break;
476 case RF90_PATH_C:
477 break;
478 case RF90_PATH_D:
479 break;
480 }
481
482 switch (rfpath) {
483 case RF90_PATH_A:
484 case RF90_PATH_C:
485 rtl_set_bbreg(hw, pphyreg->rfintfs,
486 BRFSI_RFENV, u4_regvalue);
487 break;
488 case RF90_PATH_B:
489 case RF90_PATH_D:
490 rtl_set_bbreg(hw, pphyreg->rfintfs,
491 BRFSI_RFENV << 16, u4_regvalue);
492 break;
493 }
494
495 if (!rtstatus) {
496 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
497 "Radio[%d] Fail!!", rfpath);
498 return false;
499 }
500 }
501
502 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "\n");
503 return rtstatus;
504}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
new file mode 100644
index 000000000000..a6fea106ced4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
@@ -0,0 +1,43 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_RF_H__
27#define __RTL8723BE_RF_H__
28
29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31
32void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth);
34void rtl8723be_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
35 u8 *ppowerlevel);
36void rtl8723be_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
37 u8 *ppowerlevel_ofdm,
38 u8 *ppowerlevel_bw20,
39 u8 *ppowerlevel_bw40,
40 u8 channel);
41bool rtl8723be_phy_rf6052_config(struct ieee80211_hw *hw);
42
43#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
new file mode 100644
index 000000000000..7834ae577b52
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
@@ -0,0 +1,385 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../core.h"
28#include "../pci.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "../rtl8723com/phy_common.h"
33#include "dm.h"
34#include "hw.h"
35#include "fw.h"
36#include "../rtl8723com/fw_common.h"
37#include "sw.h"
38#include "trx.h"
39#include "led.h"
40#include "table.h"
41#include "../btcoexist/rtl_btc.h"
42
43#include <linux/vmalloc.h>
44#include <linux/module.h>
45
46static void rtl8723be_init_aspm_vars(struct ieee80211_hw *hw)
47{
48 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
49
50 /*close ASPM for AMD defaultly */
51 rtlpci->const_amdpci_aspm = 0;
52
53 /* ASPM PS mode.
54 * 0 - Disable ASPM,
55 * 1 - Enable ASPM without Clock Req,
56 * 2 - Enable ASPM with Clock Req,
57 * 3 - Alwyas Enable ASPM with Clock Req,
58 * 4 - Always Enable ASPM without Clock Req.
59 * set defult to RTL8192CE:3 RTL8192E:2
60 */
61 rtlpci->const_pci_aspm = 3;
62
63 /*Setting for PCI-E device */
64 rtlpci->const_devicepci_aspm_setting = 0x03;
65
66 /*Setting for PCI-E bridge */
67 rtlpci->const_hostpci_aspm_setting = 0x02;
68
69 /* In Hw/Sw Radio Off situation.
70 * 0 - Default,
71 * 1 - From ASPM setting without low Mac Pwr,
72 * 2 - From ASPM setting with low Mac Pwr,
73 * 3 - Bus D3
74 * set default to RTL8192CE:0 RTL8192SE:2
75 */
76 rtlpci->const_hwsw_rfoff_d3 = 0;
77
78 /* This setting works for those device with
79 * backdoor ASPM setting such as EPHY setting.
80 * 0 - Not support ASPM,
81 * 1 - Support ASPM,
82 * 2 - According to chipset.
83 */
84 rtlpci->const_support_pciaspm = 1;
85}
86
87int rtl8723be_init_sw_vars(struct ieee80211_hw *hw)
88{
89 int err = 0;
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
92 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
93
94 rtl8723be_bt_reg_init(hw);
95 rtlpci->msi_support = true;
96 rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
97
98 rtlpriv->dm.dm_initialgain_enable = 1;
99 rtlpriv->dm.dm_flag = 0;
100 rtlpriv->dm.disable_framebursting = 0;
101 rtlpriv->dm.thermalvalue = 0;
102 rtlpci->transmit_config = CFENDFORM | BIT(15) | BIT(24) | BIT(25);
103
104 mac->ht_enable = true;
105
106 /* compatible 5G band 88ce just 2.4G band & smsp */
107 rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
108 rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
109 rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
110
111 rtlpci->receive_config = (RCR_APPFCS |
112 RCR_APP_MIC |
113 RCR_APP_ICV |
114 RCR_APP_PHYST_RXFF |
115 RCR_HTC_LOC_CTRL |
116 RCR_AMF |
117 RCR_ACF |
118 RCR_ADF |
119 RCR_AICV |
120 RCR_AB |
121 RCR_AM |
122 RCR_APM |
123 0);
124
125 rtlpci->irq_mask[0] = (u32) (IMR_PSTIMEOUT |
126 IMR_HSISR_IND_ON_INT |
127 IMR_C2HCMD |
128 IMR_HIGHDOK |
129 IMR_MGNTDOK |
130 IMR_BKDOK |
131 IMR_BEDOK |
132 IMR_VIDOK |
133 IMR_VODOK |
134 IMR_RDU |
135 IMR_ROK |
136 0);
137
138 rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | 0);
139
140 /* for debug level */
141 rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
142 /* for LPS & IPS */
143 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
144 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
145 rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
146 rtlpriv->psc.reg_fwctrl_lps = 3;
147 rtlpriv->psc.reg_max_lps_awakeintvl = 5;
148 /* for ASPM, you can close aspm through
149 * set const_support_pciaspm = 0
150 */
151 rtl8723be_init_aspm_vars(hw);
152
153 if (rtlpriv->psc.reg_fwctrl_lps == 1)
154 rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
155 else if (rtlpriv->psc.reg_fwctrl_lps == 2)
156 rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
157 else if (rtlpriv->psc.reg_fwctrl_lps == 3)
158 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
159
160 /* for firmware buf */
161 rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
162 if (!rtlpriv->rtlhal.pfirmware) {
163 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
164 "Can't alloc buffer for fw.\n");
165 return 1;
166 }
167
168 rtlpriv->max_fw_size = 0x8000;
169 pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
170 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
171 rtlpriv->io.dev, GFP_KERNEL, hw,
172 rtl_fw_cb);
173 if (err) {
174 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
175 "Failed to request firmware!\n");
176 return 1;
177 }
178 return 0;
179}
180
181void rtl8723be_deinit_sw_vars(struct ieee80211_hw *hw)
182{
183 struct rtl_priv *rtlpriv = rtl_priv(hw);
184
185 if (rtlpriv->cfg->ops->get_btc_status())
186 rtlpriv->btcoexist.btc_ops->btc_halt_notify();
187 if (rtlpriv->rtlhal.pfirmware) {
188 vfree(rtlpriv->rtlhal.pfirmware);
189 rtlpriv->rtlhal.pfirmware = NULL;
190 }
191}
192
193/* get bt coexist status */
194bool rtl8723be_get_btc_status(void)
195{
196 return true;
197}
198
199static bool is_fw_header(struct rtl92c_firmware_header *hdr)
200{
201 return (hdr->signature & 0xfff0) == 0x5300;
202}
203
204static struct rtl_hal_ops rtl8723be_hal_ops = {
205 .init_sw_vars = rtl8723be_init_sw_vars,
206 .deinit_sw_vars = rtl8723be_deinit_sw_vars,
207 .read_eeprom_info = rtl8723be_read_eeprom_info,
208 .interrupt_recognized = rtl8723be_interrupt_recognized,
209 .hw_init = rtl8723be_hw_init,
210 .hw_disable = rtl8723be_card_disable,
211 .hw_suspend = rtl8723be_suspend,
212 .hw_resume = rtl8723be_resume,
213 .enable_interrupt = rtl8723be_enable_interrupt,
214 .disable_interrupt = rtl8723be_disable_interrupt,
215 .set_network_type = rtl8723be_set_network_type,
216 .set_chk_bssid = rtl8723be_set_check_bssid,
217 .set_qos = rtl8723be_set_qos,
218 .set_bcn_reg = rtl8723be_set_beacon_related_registers,
219 .set_bcn_intv = rtl8723be_set_beacon_interval,
220 .update_interrupt_mask = rtl8723be_update_interrupt_mask,
221 .get_hw_reg = rtl8723be_get_hw_reg,
222 .set_hw_reg = rtl8723be_set_hw_reg,
223 .update_rate_tbl = rtl8723be_update_hal_rate_tbl,
224 .fill_tx_desc = rtl8723be_tx_fill_desc,
225 .fill_tx_cmddesc = rtl8723be_tx_fill_cmddesc,
226 .query_rx_desc = rtl8723be_rx_query_desc,
227 .set_channel_access = rtl8723be_update_channel_access_setting,
228 .radio_onoff_checking = rtl8723be_gpio_radio_on_off_checking,
229 .set_bw_mode = rtl8723be_phy_set_bw_mode,
230 .switch_channel = rtl8723be_phy_sw_chnl,
231 .dm_watchdog = rtl8723be_dm_watchdog,
232 .scan_operation_backup = rtl8723be_phy_scan_operation_backup,
233 .set_rf_power_state = rtl8723be_phy_set_rf_power_state,
234 .led_control = rtl8723be_led_control,
235 .set_desc = rtl8723be_set_desc,
236 .get_desc = rtl8723be_get_desc,
237 .is_tx_desc_closed = rtl8723be_is_tx_desc_closed,
238 .tx_polling = rtl8723be_tx_polling,
239 .enable_hw_sec = rtl8723be_enable_hw_security_config,
240 .set_key = rtl8723be_set_key,
241 .init_sw_leds = rtl8723be_init_sw_leds,
242 .allow_all_destaddr = rtl8723be_allow_all_destaddr,
243 .get_bbreg = rtl8723_phy_query_bb_reg,
244 .set_bbreg = rtl8723_phy_set_bb_reg,
245 .get_rfreg = rtl8723be_phy_query_rf_reg,
246 .set_rfreg = rtl8723be_phy_set_rf_reg,
247 .fill_h2c_cmd = rtl8723be_fill_h2c_cmd,
248 .get_btc_status = rtl8723be_get_btc_status,
249 .is_fw_header = is_fw_header,
250};
251
252static struct rtl_mod_params rtl8723be_mod_params = {
253 .sw_crypto = false,
254 .inactiveps = true,
255 .swctrl_lps = false,
256 .fwctrl_lps = true,
257 .debug = DBG_EMERG,
258};
259
260static struct rtl_hal_cfg rtl8723be_hal_cfg = {
261 .bar_id = 2,
262 .write_readback = true,
263 .name = "rtl8723be_pci",
264 .fw_name = "rtlwifi/rtl8723befw.bin",
265 .ops = &rtl8723be_hal_ops,
266 .mod_params = &rtl8723be_mod_params,
267 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
268 .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
269 .maps[SYS_CLK] = REG_SYS_CLKR,
270 .maps[MAC_RCR_AM] = AM,
271 .maps[MAC_RCR_AB] = AB,
272 .maps[MAC_RCR_ACRC32] = ACRC32,
273 .maps[MAC_RCR_ACF] = ACF,
274 .maps[MAC_RCR_AAP] = AAP,
275
276 .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS,
277
278 .maps[EFUSE_TEST] = REG_EFUSE_TEST,
279 .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
280 .maps[EFUSE_CLK] = 0,
281 .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
282 .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
283 .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
284 .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
285 .maps[EFUSE_ANA8M] = ANA8M,
286 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
287 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
288 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
289 .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES,
290
291 .maps[RWCAM] = REG_CAMCMD,
292 .maps[WCAMI] = REG_CAMWRITE,
293 .maps[RCAMO] = REG_CAMREAD,
294 .maps[CAMDBG] = REG_CAMDBG,
295 .maps[SECR] = REG_SECCFG,
296 .maps[SEC_CAM_NONE] = CAM_NONE,
297 .maps[SEC_CAM_WEP40] = CAM_WEP40,
298 .maps[SEC_CAM_TKIP] = CAM_TKIP,
299 .maps[SEC_CAM_AES] = CAM_AES,
300 .maps[SEC_CAM_WEP104] = CAM_WEP104,
301
302 .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
303 .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
304 .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
305 .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
306 .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
307 .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
308 .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
309 .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
310 .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
311 .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
312 .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
313 .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
314 .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
315
316 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
317 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
318 .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0,
319 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
320 .maps[RTL_IMR_RDU] = IMR_RDU,
321 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
322 .maps[RTL_IMR_BDOK] = IMR_BCNDOK0,
323 .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
324 .maps[RTL_IMR_TBDER] = IMR_TBDER,
325 .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
326 .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
327 .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
328 .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
329 .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
330 .maps[RTL_IMR_VODOK] = IMR_VODOK,
331 .maps[RTL_IMR_ROK] = IMR_ROK,
332 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER),
333
334 .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
335 .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
336 .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
337 .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
338 .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
339 .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
340 .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
341 .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
342 .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
343 .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
344 .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
345 .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
346
347 .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
348 .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
349};
350
351static DEFINE_PCI_DEVICE_TABLE(rtl8723be_pci_id) = {
352 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xb723, rtl8723be_hal_cfg)},
353 {},
354};
355
356MODULE_DEVICE_TABLE(pci, rtl8723be_pci_id);
357
358MODULE_AUTHOR("PageHe <page_he@realsil.com.cn>");
359MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
360MODULE_LICENSE("GPL");
361MODULE_DESCRIPTION("Realtek 8723BE 802.11n PCI wireless");
362MODULE_FIRMWARE("rtlwifi/rtl8723befw.bin");
363
364module_param_named(swenc, rtl8723be_mod_params.sw_crypto, bool, 0444);
365module_param_named(debug, rtl8723be_mod_params.debug, int, 0444);
366module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444);
367module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444);
368module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444);
369MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
370MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
371MODULE_PARM_DESC(fwlps, "using linked fw control power save (default 1 is open)\n");
372MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
373
374static const SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
375
376static struct pci_driver rtl8723be_driver = {
377 .name = KBUILD_MODNAME,
378 .id_table = rtl8723be_pci_id,
379 .probe = rtl_pci_probe,
380 .remove = rtl_pci_disconnect,
381
382 .driver.pm = &rtlwifi_pm_ops,
383};
384
385module_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 000000000000..a7b25e769950
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.h
@@ -0,0 +1,35 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_SW_H__
27#define __RTL8723BE_SW_H__
28
29int rtl8723be_init_sw_vars(struct ieee80211_hw *hw);
30void rtl8723be_deinit_sw_vars(struct ieee80211_hw *hw);
31void rtl8723be_init_var_map(struct ieee80211_hw *hw);
32bool rtl8723be_get_btc_status(void);
33
34
35#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/table.c b/drivers/net/wireless/rtlwifi/rtl8723be/table.c
new file mode 100644
index 000000000000..4b283cde042e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/table.c
@@ -0,0 +1,572 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Created on 2010/ 5/18, 1:41
23 *
24 * Larry Finger <Larry.Finger@lwfinger.net>
25 *
26 *****************************************************************************/
27
28#include "table.h"
29u32 RTL8723BEPHY_REG_1TARRAY[] = {
30 0x800, 0x80040000,
31 0x804, 0x00000003,
32 0x808, 0x0000FC00,
33 0x80C, 0x0000000A,
34 0x810, 0x10001331,
35 0x814, 0x020C3D10,
36 0x818, 0x02200385,
37 0x81C, 0x00000000,
38 0x820, 0x01000100,
39 0x824, 0x00390204,
40 0x828, 0x00000000,
41 0x82C, 0x00000000,
42 0x830, 0x00000000,
43 0x834, 0x00000000,
44 0x838, 0x00000000,
45 0x83C, 0x00000000,
46 0x840, 0x00010000,
47 0x844, 0x00000000,
48 0x848, 0x00000000,
49 0x84C, 0x00000000,
50 0x850, 0x00000000,
51 0x854, 0x00000000,
52 0x858, 0x569A11A9,
53 0x85C, 0x01000014,
54 0x860, 0x66F60110,
55 0x864, 0x061F0649,
56 0x868, 0x00000000,
57 0x86C, 0x27272700,
58 0x870, 0x07000760,
59 0x874, 0x25004000,
60 0x878, 0x00000808,
61 0x87C, 0x00000000,
62 0x880, 0xB0000C1C,
63 0x884, 0x00000001,
64 0x888, 0x00000000,
65 0x88C, 0xCCC000C0,
66 0x890, 0x00000800,
67 0x894, 0xFFFFFFFE,
68 0x898, 0x40302010,
69 0x89C, 0x00706050,
70 0x900, 0x00000000,
71 0x904, 0x00000023,
72 0x908, 0x00000000,
73 0x90C, 0x81121111,
74 0x910, 0x00000002,
75 0x914, 0x00000201,
76 0x948, 0x00000000,
77 0xA00, 0x00D047C8,
78 0xA04, 0x80FF000C,
79 0xA08, 0x8C838300,
80 0xA0C, 0x2E7F120F,
81 0xA10, 0x9500BB78,
82 0xA14, 0x1114D028,
83 0xA18, 0x00881117,
84 0xA1C, 0x89140F00,
85 0xA20, 0x1A1B0000,
86 0xA24, 0x090E1317,
87 0xA28, 0x00000204,
88 0xA2C, 0x00D30000,
89 0xA70, 0x101FBF00,
90 0xA74, 0x00000007,
91 0xA78, 0x00000900,
92 0xA7C, 0x225B0606,
93 0xA80, 0x21806490,
94 0xB2C, 0x00000000,
95 0xC00, 0x48071D40,
96 0xC04, 0x03A05611,
97 0xC08, 0x000000E4,
98 0xC0C, 0x6C6C6C6C,
99 0xC10, 0x08800000,
100 0xC14, 0x40000100,
101 0xC18, 0x08800000,
102 0xC1C, 0x40000100,
103 0xC20, 0x00000000,
104 0xC24, 0x00000000,
105 0xC28, 0x00000000,
106 0xC2C, 0x00000000,
107 0xC30, 0x69E9AC44,
108 0xC34, 0x469652AF,
109 0xC38, 0x49795994,
110 0xC3C, 0x0A97971C,
111 0xC40, 0x1F7C403F,
112 0xC44, 0x000100B7,
113 0xC48, 0xEC020107,
114 0xC4C, 0x007F037F,
115 0xC50, 0x69553420,
116 0xC54, 0x43BC0094,
117 0xC58, 0x00023169,
118 0xC5C, 0x00250492,
119 0xC60, 0x00000000,
120 0xC64, 0x7112848B,
121 0xC68, 0x47C00BFF,
122 0xC6C, 0x00000036,
123 0xC70, 0x2C7F000D,
124 0xC74, 0x020610DB,
125 0xC78, 0x0000001F,
126 0xC7C, 0x00B91612,
127 0xC80, 0x390000E4,
128 0xC84, 0x20F60000,
129 0xC88, 0x40000100,
130 0xC8C, 0x20200000,
131 0xC90, 0x00020E1A,
132 0xC94, 0x00000000,
133 0xC98, 0x00020E1A,
134 0xC9C, 0x00007F7F,
135 0xCA0, 0x00000000,
136 0xCA4, 0x000300A0,
137 0xCA8, 0x00000000,
138 0xCAC, 0x00000000,
139 0xCB0, 0x00000000,
140 0xCB4, 0x00000000,
141 0xCB8, 0x00000000,
142 0xCBC, 0x28000000,
143 0xCC0, 0x00000000,
144 0xCC4, 0x00000000,
145 0xCC8, 0x00000000,
146 0xCCC, 0x00000000,
147 0xCD0, 0x00000000,
148 0xCD4, 0x00000000,
149 0xCD8, 0x64B22427,
150 0xCDC, 0x00766932,
151 0xCE0, 0x00222222,
152 0xCE4, 0x00000000,
153 0xCE8, 0x37644302,
154 0xCEC, 0x2F97D40C,
155 0xD00, 0x00000740,
156 0xD04, 0x40020401,
157 0xD08, 0x0000907F,
158 0xD0C, 0x20010201,
159 0xD10, 0xA0633333,
160 0xD14, 0x3333BC53,
161 0xD18, 0x7A8F5B6F,
162 0xD2C, 0xCC979975,
163 0xD30, 0x00000000,
164 0xD34, 0x80608000,
165 0xD38, 0x00000000,
166 0xD3C, 0x00127353,
167 0xD40, 0x00000000,
168 0xD44, 0x00000000,
169 0xD48, 0x00000000,
170 0xD4C, 0x00000000,
171 0xD50, 0x6437140A,
172 0xD54, 0x00000000,
173 0xD58, 0x00000282,
174 0xD5C, 0x30032064,
175 0xD60, 0x4653DE68,
176 0xD64, 0x04518A3C,
177 0xD68, 0x00002101,
178 0xD6C, 0x2A201C16,
179 0xD70, 0x1812362E,
180 0xD74, 0x322C2220,
181 0xD78, 0x000E3C24,
182 0xE00, 0x2D2D2D2D,
183 0xE04, 0x2D2D2D2D,
184 0xE08, 0x0390272D,
185 0xE10, 0x2D2D2D2D,
186 0xE14, 0x2D2D2D2D,
187 0xE18, 0x2D2D2D2D,
188 0xE1C, 0x2D2D2D2D,
189 0xE28, 0x00000000,
190 0xE30, 0x1000DC1F,
191 0xE34, 0x10008C1F,
192 0xE38, 0x02140102,
193 0xE3C, 0x681604C2,
194 0xE40, 0x01007C00,
195 0xE44, 0x01004800,
196 0xE48, 0xFB000000,
197 0xE4C, 0x000028D1,
198 0xE50, 0x1000DC1F,
199 0xE54, 0x10008C1F,
200 0xE58, 0x02140102,
201 0xE5C, 0x28160D05,
202 0xE60, 0x00000008,
203 0xE68, 0x001B2556,
204 0xE6C, 0x00C00096,
205 0xE70, 0x00C00096,
206 0xE74, 0x01000056,
207 0xE78, 0x01000014,
208 0xE7C, 0x01000056,
209 0xE80, 0x01000014,
210 0xE84, 0x00C00096,
211 0xE88, 0x01000056,
212 0xE8C, 0x00C00096,
213 0xED0, 0x00C00096,
214 0xED4, 0x00C00096,
215 0xED8, 0x00C00096,
216 0xEDC, 0x000000D6,
217 0xEE0, 0x000000D6,
218 0xEEC, 0x01C00016,
219 0xF14, 0x00000003,
220 0xF4C, 0x00000000,
221 0xF00, 0x00000300,
222 0x820, 0x01000100,
223 0x800, 0x83040000,
224};
225
226u32 RTL8723BEPHY_REG_ARRAY_PG[] = {
227 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00004000,
228 0, 0, 0, 0x0000086c, 0xffffff00, 0x34363800,
229 0, 0, 0, 0x00000e00, 0xffffffff, 0x42444646,
230 0, 0, 0, 0x00000e04, 0xffffffff, 0x30343840,
231 0, 0, 0, 0x00000e10, 0xffffffff, 0x38404244,
232 0, 0, 0, 0x00000e14, 0xffffffff, 0x26303436
233};
234
235u32 RTL8723BE_RADIOA_1TARRAY[] = {
236 0x000, 0x00010000,
237 0x0B0, 0x000DFFE0,
238 0x0FE, 0x00000000,
239 0x0FE, 0x00000000,
240 0x0FE, 0x00000000,
241 0x0B1, 0x00000018,
242 0x0FE, 0x00000000,
243 0x0FE, 0x00000000,
244 0x0FE, 0x00000000,
245 0x0B2, 0x00084C00,
246 0x0B5, 0x0000D2CC,
247 0x0B6, 0x000925AA,
248 0x0B7, 0x00000010,
249 0x0B8, 0x0000907F,
250 0x05C, 0x00000002,
251 0x07C, 0x00000002,
252 0x07E, 0x00000005,
253 0x08B, 0x0006FC00,
254 0x0B0, 0x000FF9F0,
255 0x01C, 0x000739D2,
256 0x01E, 0x00000000,
257 0x0DF, 0x00000780,
258 0x050, 0x00067435,
259 0x051, 0x0006B04E,
260 0x052, 0x000007D2,
261 0x053, 0x00000000,
262 0x054, 0x00050400,
263 0x055, 0x0004026E,
264 0x0DD, 0x0000004C,
265 0x070, 0x00067435,
266 0x071, 0x0006B04E,
267 0x072, 0x000007D2,
268 0x073, 0x00000000,
269 0x074, 0x00050400,
270 0x075, 0x0004026E,
271 0x0EF, 0x00000100,
272 0x034, 0x0000ADD7,
273 0x035, 0x00005C00,
274 0x034, 0x00009DD4,
275 0x035, 0x00005000,
276 0x034, 0x00008DD1,
277 0x035, 0x00004400,
278 0x034, 0x00007DCE,
279 0x035, 0x00003800,
280 0x034, 0x00006CD1,
281 0x035, 0x00004400,
282 0x034, 0x00005CCE,
283 0x035, 0x00003800,
284 0x034, 0x000048CE,
285 0x035, 0x00004400,
286 0x034, 0x000034CE,
287 0x035, 0x00003800,
288 0x034, 0x00002451,
289 0x035, 0x00004400,
290 0x034, 0x0000144E,
291 0x035, 0x00003800,
292 0x034, 0x00000051,
293 0x035, 0x00004400,
294 0x0EF, 0x00000000,
295 0x0EF, 0x00000100,
296 0x0ED, 0x00000010,
297 0x044, 0x0000ADD7,
298 0x044, 0x00009DD4,
299 0x044, 0x00008DD1,
300 0x044, 0x00007DCE,
301 0x044, 0x00006CC1,
302 0x044, 0x00005CCE,
303 0x044, 0x000044D1,
304 0x044, 0x000034CE,
305 0x044, 0x00002451,
306 0x044, 0x0000144E,
307 0x044, 0x00000051,
308 0x0EF, 0x00000000,
309 0x0ED, 0x00000000,
310 0x0EF, 0x00002000,
311 0x03B, 0x000380EF,
312 0x03B, 0x000302FE,
313 0x03B, 0x00028CE6,
314 0x03B, 0x000200BC,
315 0x03B, 0x000188A5,
316 0x03B, 0x00010FBC,
317 0x03B, 0x00008F71,
318 0x03B, 0x00000900,
319 0x0EF, 0x00000000,
320 0x0ED, 0x00000001,
321 0x040, 0x000380EF,
322 0x040, 0x000302FE,
323 0x040, 0x00028CE6,
324 0x040, 0x000200BC,
325 0x040, 0x000188A5,
326 0x040, 0x00010FBC,
327 0x040, 0x00008F71,
328 0x040, 0x00000900,
329 0x0ED, 0x00000000,
330 0x082, 0x00080000,
331 0x083, 0x00008000,
332 0x084, 0x00048D80,
333 0x085, 0x00068000,
334 0x0A2, 0x00080000,
335 0x0A3, 0x00008000,
336 0x0A4, 0x00048D80,
337 0x0A5, 0x00068000,
338 0x000, 0x00033D80,
339};
340
341u32 RTL8723BEMAC_1T_ARRAY[] = {
342 0x02F, 0x00000030,
343 0x035, 0x00000000,
344 0x428, 0x0000000A,
345 0x429, 0x00000010,
346 0x430, 0x00000000,
347 0x431, 0x00000000,
348 0x432, 0x00000000,
349 0x433, 0x00000001,
350 0x434, 0x00000004,
351 0x435, 0x00000005,
352 0x436, 0x00000007,
353 0x437, 0x00000008,
354 0x43C, 0x00000004,
355 0x43D, 0x00000005,
356 0x43E, 0x00000007,
357 0x43F, 0x00000008,
358 0x440, 0x0000005D,
359 0x441, 0x00000001,
360 0x442, 0x00000000,
361 0x444, 0x00000010,
362 0x445, 0x00000000,
363 0x446, 0x00000000,
364 0x447, 0x00000000,
365 0x448, 0x00000000,
366 0x449, 0x000000F0,
367 0x44A, 0x0000000F,
368 0x44B, 0x0000003E,
369 0x44C, 0x00000010,
370 0x44D, 0x00000000,
371 0x44E, 0x00000000,
372 0x44F, 0x00000000,
373 0x450, 0x00000000,
374 0x451, 0x000000F0,
375 0x452, 0x0000000F,
376 0x453, 0x00000000,
377 0x456, 0x0000005E,
378 0x460, 0x00000066,
379 0x461, 0x00000066,
380 0x4C8, 0x000000FF,
381 0x4C9, 0x00000008,
382 0x4CC, 0x000000FF,
383 0x4CD, 0x000000FF,
384 0x4CE, 0x00000001,
385 0x500, 0x00000026,
386 0x501, 0x000000A2,
387 0x502, 0x0000002F,
388 0x503, 0x00000000,
389 0x504, 0x00000028,
390 0x505, 0x000000A3,
391 0x506, 0x0000005E,
392 0x507, 0x00000000,
393 0x508, 0x0000002B,
394 0x509, 0x000000A4,
395 0x50A, 0x0000005E,
396 0x50B, 0x00000000,
397 0x50C, 0x0000004F,
398 0x50D, 0x000000A4,
399 0x50E, 0x00000000,
400 0x50F, 0x00000000,
401 0x512, 0x0000001C,
402 0x514, 0x0000000A,
403 0x516, 0x0000000A,
404 0x525, 0x0000004F,
405 0x550, 0x00000010,
406 0x551, 0x00000010,
407 0x559, 0x00000002,
408 0x55C, 0x00000050,
409 0x55D, 0x000000FF,
410 0x605, 0x00000030,
411 0x608, 0x0000000E,
412 0x609, 0x0000002A,
413 0x620, 0x000000FF,
414 0x621, 0x000000FF,
415 0x622, 0x000000FF,
416 0x623, 0x000000FF,
417 0x624, 0x000000FF,
418 0x625, 0x000000FF,
419 0x626, 0x000000FF,
420 0x627, 0x000000FF,
421 0x638, 0x00000050,
422 0x63C, 0x0000000A,
423 0x63D, 0x0000000A,
424 0x63E, 0x0000000E,
425 0x63F, 0x0000000E,
426 0x640, 0x00000040,
427 0x642, 0x00000040,
428 0x643, 0x00000000,
429 0x652, 0x000000C8,
430 0x66E, 0x00000005,
431 0x700, 0x00000021,
432 0x701, 0x00000043,
433 0x702, 0x00000065,
434 0x703, 0x00000087,
435 0x708, 0x00000021,
436 0x709, 0x00000043,
437 0x70A, 0x00000065,
438 0x70B, 0x00000087,
439};
440
441u32 RTL8723BEAGCTAB_1TARRAY[] = {
442 0xC78, 0xFD000001,
443 0xC78, 0xFC010001,
444 0xC78, 0xFB020001,
445 0xC78, 0xFA030001,
446 0xC78, 0xF9040001,
447 0xC78, 0xF8050001,
448 0xC78, 0xF7060001,
449 0xC78, 0xF6070001,
450 0xC78, 0xF5080001,
451 0xC78, 0xF4090001,
452 0xC78, 0xF30A0001,
453 0xC78, 0xF20B0001,
454 0xC78, 0xF10C0001,
455 0xC78, 0xF00D0001,
456 0xC78, 0xEF0E0001,
457 0xC78, 0xEE0F0001,
458 0xC78, 0xED100001,
459 0xC78, 0xEC110001,
460 0xC78, 0xEB120001,
461 0xC78, 0xEA130001,
462 0xC78, 0xE9140001,
463 0xC78, 0xE8150001,
464 0xC78, 0xE7160001,
465 0xC78, 0xAA170001,
466 0xC78, 0xA9180001,
467 0xC78, 0xA8190001,
468 0xC78, 0xA71A0001,
469 0xC78, 0xA61B0001,
470 0xC78, 0xA51C0001,
471 0xC78, 0xA41D0001,
472 0xC78, 0xA31E0001,
473 0xC78, 0x671F0001,
474 0xC78, 0x66200001,
475 0xC78, 0x65210001,
476 0xC78, 0x64220001,
477 0xC78, 0x63230001,
478 0xC78, 0x62240001,
479 0xC78, 0x61250001,
480 0xC78, 0x47260001,
481 0xC78, 0x46270001,
482 0xC78, 0x45280001,
483 0xC78, 0x44290001,
484 0xC78, 0x432A0001,
485 0xC78, 0x422B0001,
486 0xC78, 0x292C0001,
487 0xC78, 0x282D0001,
488 0xC78, 0x272E0001,
489 0xC78, 0x262F0001,
490 0xC78, 0x25300001,
491 0xC78, 0x24310001,
492 0xC78, 0x09320001,
493 0xC78, 0x08330001,
494 0xC78, 0x07340001,
495 0xC78, 0x06350001,
496 0xC78, 0x05360001,
497 0xC78, 0x04370001,
498 0xC78, 0x03380001,
499 0xC78, 0x02390001,
500 0xC78, 0x013A0001,
501 0xC78, 0x003B0001,
502 0xC78, 0x003C0001,
503 0xC78, 0x003D0001,
504 0xC78, 0x003E0001,
505 0xC78, 0x003F0001,
506 0xC78, 0xFC400001,
507 0xC78, 0xFB410001,
508 0xC78, 0xFA420001,
509 0xC78, 0xF9430001,
510 0xC78, 0xF8440001,
511 0xC78, 0xF7450001,
512 0xC78, 0xF6460001,
513 0xC78, 0xF5470001,
514 0xC78, 0xF4480001,
515 0xC78, 0xF3490001,
516 0xC78, 0xF24A0001,
517 0xC78, 0xF14B0001,
518 0xC78, 0xF04C0001,
519 0xC78, 0xEF4D0001,
520 0xC78, 0xEE4E0001,
521 0xC78, 0xED4F0001,
522 0xC78, 0xEC500001,
523 0xC78, 0xEB510001,
524 0xC78, 0xEA520001,
525 0xC78, 0xE9530001,
526 0xC78, 0xE8540001,
527 0xC78, 0xE7550001,
528 0xC78, 0xE6560001,
529 0xC78, 0xE5570001,
530 0xC78, 0xAA580001,
531 0xC78, 0xA9590001,
532 0xC78, 0xA85A0001,
533 0xC78, 0xA75B0001,
534 0xC78, 0xA65C0001,
535 0xC78, 0xA55D0001,
536 0xC78, 0xA45E0001,
537 0xC78, 0x675F0001,
538 0xC78, 0x66600001,
539 0xC78, 0x65610001,
540 0xC78, 0x64620001,
541 0xC78, 0x63630001,
542 0xC78, 0x62640001,
543 0xC78, 0x61650001,
544 0xC78, 0x47660001,
545 0xC78, 0x46670001,
546 0xC78, 0x45680001,
547 0xC78, 0x44690001,
548 0xC78, 0x436A0001,
549 0xC78, 0x426B0001,
550 0xC78, 0x296C0001,
551 0xC78, 0x286D0001,
552 0xC78, 0x276E0001,
553 0xC78, 0x266F0001,
554 0xC78, 0x25700001,
555 0xC78, 0x24710001,
556 0xC78, 0x09720001,
557 0xC78, 0x08730001,
558 0xC78, 0x07740001,
559 0xC78, 0x06750001,
560 0xC78, 0x05760001,
561 0xC78, 0x04770001,
562 0xC78, 0x03780001,
563 0xC78, 0x02790001,
564 0xC78, 0x017A0001,
565 0xC78, 0x007B0001,
566 0xC78, 0x007C0001,
567 0xC78, 0x007D0001,
568 0xC78, 0x007E0001,
569 0xC78, 0x007F0001,
570 0xC50, 0x69553422,
571 0xC50, 0x69553420,
572};
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/table.h b/drivers/net/wireless/rtlwifi/rtl8723be/table.h
new file mode 100644
index 000000000000..932760a84827
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/table.h
@@ -0,0 +1,43 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Created on 2010/ 5/18, 1:41
23 *
24 * Larry Finger <Larry.Finger@lwfinger.net>
25 *
26 *****************************************************************************/
27
28#ifndef __RTL8723BE_TABLE__H_
29#define __RTL8723BE_TABLE__H_
30
31#include <linux/types.h>
32#define RTL8723BEPHY_REG_1TARRAYLEN 388
33extern u32 RTL8723BEPHY_REG_1TARRAY[];
34#define RTL8723BEPHY_REG_ARRAY_PGLEN 36
35extern u32 RTL8723BEPHY_REG_ARRAY_PG[];
36#define RTL8723BE_RADIOA_1TARRAYLEN 206
37extern u32 RTL8723BE_RADIOA_1TARRAY[];
38#define RTL8723BEMAC_1T_ARRAYLEN 194
39extern u32 RTL8723BEMAC_1T_ARRAY[];
40#define RTL8723BEAGCTAB_1TARRAYLEN 260
41extern u32 RTL8723BEAGCTAB_1TARRAY[];
42
43#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
new file mode 100644
index 000000000000..7779531919fb
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
@@ -0,0 +1,959 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
29#include "../stats.h"
30#include "reg.h"
31#include "def.h"
32#include "phy.h"
33#include "trx.h"
34#include "led.h"
35#include "dm.h"
36#include "phy.h"
37
38static u8 _rtl8723be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
39{
40 __le16 fc = rtl_get_fc(skb);
41
42 if (unlikely(ieee80211_is_beacon(fc)))
43 return QSLT_BEACON;
44 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
45 return QSLT_MGNT;
46
47 return skb->priority;
48}
49
50/* mac80211's rate_idx is like this:
51 *
52 * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
53 *
54 * B/G rate:
55 * (rx_status->flag & RX_FLAG_HT) = 0,
56 * DESC92C_RATE1M-->DESC92C_RATE54M ==> idx is 0-->11,
57 *
58 * N rate:
59 * (rx_status->flag & RX_FLAG_HT) = 1,
60 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
61 *
62 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
63 * A rate:
64 * (rx_status->flag & RX_FLAG_HT) = 0,
65 * DESC92C_RATE6M-->DESC92C_RATE54M ==> idx is 0-->7,
66 *
67 * N rate:
68 * (rx_status->flag & RX_FLAG_HT) = 1,
69 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
70 */
71static int _rtl8723be_rate_mapping(struct ieee80211_hw *hw,
72 bool isht, u8 desc_rate)
73{
74 int rate_idx;
75
76 if (!isht) {
77 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
78 switch (desc_rate) {
79 case DESC92C_RATE1M:
80 rate_idx = 0;
81 break;
82 case DESC92C_RATE2M:
83 rate_idx = 1;
84 break;
85 case DESC92C_RATE5_5M:
86 rate_idx = 2;
87 break;
88 case DESC92C_RATE11M:
89 rate_idx = 3;
90 break;
91 case DESC92C_RATE6M:
92 rate_idx = 4;
93 break;
94 case DESC92C_RATE9M:
95 rate_idx = 5;
96 break;
97 case DESC92C_RATE12M:
98 rate_idx = 6;
99 break;
100 case DESC92C_RATE18M:
101 rate_idx = 7;
102 break;
103 case DESC92C_RATE24M:
104 rate_idx = 8;
105 break;
106 case DESC92C_RATE36M:
107 rate_idx = 9;
108 break;
109 case DESC92C_RATE48M:
110 rate_idx = 10;
111 break;
112 case DESC92C_RATE54M:
113 rate_idx = 11;
114 break;
115 default:
116 rate_idx = 0;
117 break;
118 }
119 } else {
120 switch (desc_rate) {
121 case DESC92C_RATE6M:
122 rate_idx = 0;
123 break;
124 case DESC92C_RATE9M:
125 rate_idx = 1;
126 break;
127 case DESC92C_RATE12M:
128 rate_idx = 2;
129 break;
130 case DESC92C_RATE18M:
131 rate_idx = 3;
132 break;
133 case DESC92C_RATE24M:
134 rate_idx = 4;
135 break;
136 case DESC92C_RATE36M:
137 rate_idx = 5;
138 break;
139 case DESC92C_RATE48M:
140 rate_idx = 6;
141 break;
142 case DESC92C_RATE54M:
143 rate_idx = 7;
144 break;
145 default:
146 rate_idx = 0;
147 break;
148 }
149 }
150 } else {
151 switch (desc_rate) {
152 case DESC92C_RATEMCS0:
153 rate_idx = 0;
154 break;
155 case DESC92C_RATEMCS1:
156 rate_idx = 1;
157 break;
158 case DESC92C_RATEMCS2:
159 rate_idx = 2;
160 break;
161 case DESC92C_RATEMCS3:
162 rate_idx = 3;
163 break;
164 case DESC92C_RATEMCS4:
165 rate_idx = 4;
166 break;
167 case DESC92C_RATEMCS5:
168 rate_idx = 5;
169 break;
170 case DESC92C_RATEMCS6:
171 rate_idx = 6;
172 break;
173 case DESC92C_RATEMCS7:
174 rate_idx = 7;
175 break;
176 case DESC92C_RATEMCS8:
177 rate_idx = 8;
178 break;
179 case DESC92C_RATEMCS9:
180 rate_idx = 9;
181 break;
182 case DESC92C_RATEMCS10:
183 rate_idx = 10;
184 break;
185 case DESC92C_RATEMCS11:
186 rate_idx = 11;
187 break;
188 case DESC92C_RATEMCS12:
189 rate_idx = 12;
190 break;
191 case DESC92C_RATEMCS13:
192 rate_idx = 13;
193 break;
194 case DESC92C_RATEMCS14:
195 rate_idx = 14;
196 break;
197 case DESC92C_RATEMCS15:
198 rate_idx = 15;
199 break;
200 default:
201 rate_idx = 0;
202 break;
203 }
204 }
205 return rate_idx;
206}
207
208static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw,
209 struct rtl_stats *pstatus, u8 *pdesc,
210 struct rx_fwinfo_8723be *p_drvinfo,
211 bool packet_match_bssid,
212 bool packet_toself,
213 bool packet_beacon)
214{
215 struct rtl_priv *rtlpriv = rtl_priv(hw);
216 struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
217 struct phy_sts_cck_8723e_t *cck_buf;
218 struct phy_status_rpt *p_phystrpt = (struct phy_status_rpt *)p_drvinfo;
219 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
220 char rx_pwr_all = 0, rx_pwr[4];
221 u8 rf_rx_num = 0, evm, pwdb_all;
222 u8 i, max_spatial_stream;
223 u32 rssi, total_rssi = 0;
224 bool is_cck = pstatus->is_cck;
225 u8 lan_idx, vga_idx;
226
227 /* Record it for next packet processing */
228 pstatus->packet_matchbssid = packet_match_bssid;
229 pstatus->packet_toself = packet_toself;
230 pstatus->packet_beacon = packet_beacon;
231 pstatus->rx_mimo_sig_qual[0] = -1;
232 pstatus->rx_mimo_sig_qual[1] = -1;
233
234 if (is_cck) {
235 u8 cck_highpwr;
236 u8 cck_agc_rpt;
237 /* CCK Driver info Structure is not the same as OFDM packet. */
238 cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo;
239 cck_agc_rpt = cck_buf->cck_agc_rpt;
240
241 /* (1)Hardware does not provide RSSI for CCK
242 * (2)PWDB, Average PWDB cacluated by
243 * hardware (for rate adaptive)
244 */
245 if (ppsc->rfpwr_state == ERFON)
246 cck_highpwr = (u8) rtl_get_bbreg(hw,
247 RFPGA0_XA_HSSIPARAMETER2,
248 BIT(9));
249 else
250 cck_highpwr = false;
251
252 lan_idx = ((cck_agc_rpt & 0xE0) >> 5);
253 vga_idx = (cck_agc_rpt & 0x1f);
254 switch (lan_idx) {
255 case 7:
256 if (vga_idx <= 27)/*VGA_idx = 27~2*/
257 rx_pwr_all = -100 + 2 * (27 - vga_idx);
258 else
259 rx_pwr_all = -100;
260 break;
261 case 6:/*VGA_idx = 2~0*/
262 rx_pwr_all = -48 + 2 * (2 - vga_idx);
263 break;
264 case 5:/*VGA_idx = 7~5*/
265 rx_pwr_all = -42 + 2 * (7 - vga_idx);
266 break;
267 case 4:/*VGA_idx = 7~4*/
268 rx_pwr_all = -36 + 2 * (7 - vga_idx);
269 break;
270 case 3:/*VGA_idx = 7~0*/
271 rx_pwr_all = -24 + 2 * (7 - vga_idx);
272 break;
273 case 2:
274 if (cck_highpwr)/*VGA_idx = 5~0*/
275 rx_pwr_all = -12 + 2 * (5 - vga_idx);
276 else
277 rx_pwr_all = -6 + 2 * (5 - vga_idx);
278 break;
279 case 1:
280 rx_pwr_all = 8 - 2 * vga_idx;
281 break;
282 case 0:
283 rx_pwr_all = 14 - 2 * vga_idx;
284 break;
285 default:
286 break;
287 }
288 rx_pwr_all += 6;
289 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
290 /* CCK gain is smaller than OFDM/MCS gain, */
291 /* so we add gain diff by experiences,
292 * the val is 6
293 */
294 pwdb_all += 6;
295 if (pwdb_all > 100)
296 pwdb_all = 100;
297 /* modify the offset to make the same gain index with OFDM. */
298 if (pwdb_all > 34 && pwdb_all <= 42)
299 pwdb_all -= 2;
300 else if (pwdb_all > 26 && pwdb_all <= 34)
301 pwdb_all -= 6;
302 else if (pwdb_all > 14 && pwdb_all <= 26)
303 pwdb_all -= 8;
304 else if (pwdb_all > 4 && pwdb_all <= 14)
305 pwdb_all -= 4;
306 if (!cck_highpwr) {
307 if (pwdb_all >= 80)
308 pwdb_all = ((pwdb_all - 80) << 1) +
309 ((pwdb_all - 80) >> 1) + 80;
310 else if ((pwdb_all <= 78) && (pwdb_all >= 20))
311 pwdb_all += 3;
312 if (pwdb_all > 100)
313 pwdb_all = 100;
314 }
315
316 pstatus->rx_pwdb_all = pwdb_all;
317 pstatus->recvsignalpower = rx_pwr_all;
318
319 /* (3) Get Signal Quality (EVM) */
320 if (packet_match_bssid) {
321 u8 sq;
322
323 if (pstatus->rx_pwdb_all > 40) {
324 sq = 100;
325 } else {
326 sq = cck_buf->sq_rpt;
327 if (sq > 64)
328 sq = 0;
329 else if (sq < 20)
330 sq = 100;
331 else
332 sq = ((64 - sq) * 100) / 44;
333 }
334
335 pstatus->signalquality = sq;
336 pstatus->rx_mimo_sig_qual[0] = sq;
337 pstatus->rx_mimo_sig_qual[1] = -1;
338 }
339 } else {
340 rtlpriv->dm.rfpath_rxenable[0] = true;
341 rtlpriv->dm.rfpath_rxenable[1] = true;
342
343 /* (1)Get RSSI for HT rate */
344 for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
345 /* we will judge RF RX path now. */
346 if (rtlpriv->dm.rfpath_rxenable[i])
347 rf_rx_num++;
348
349 rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f)*2) - 110;
350
351 /* Translate DBM to percentage. */
352 rssi = rtl_query_rxpwrpercentage(rx_pwr[i]);
353 total_rssi += rssi;
354
355 /* Get Rx snr value in DB */
356 rtlpriv->stats.rx_snr_db[i] =
357 (long)(p_drvinfo->rxsnr[i] / 2);
358
359 /* Record Signal Strength for next packet */
360 if (packet_match_bssid)
361 pstatus->rx_mimo_signalstrength[i] = (u8) rssi;
362 }
363
364 /* (2)PWDB, Avg cacluated by hardware (for rate adaptive) */
365 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
366
367 pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
368 pstatus->rx_pwdb_all = pwdb_all;
369 pstatus->rxpower = rx_pwr_all;
370 pstatus->recvsignalpower = rx_pwr_all;
371
372 /* (3)EVM of HT rate */
373 if (pstatus->is_ht && pstatus->rate >= DESC92C_RATEMCS8 &&
374 pstatus->rate <= DESC92C_RATEMCS15)
375 max_spatial_stream = 2;
376 else
377 max_spatial_stream = 1;
378
379 for (i = 0; i < max_spatial_stream; i++) {
380 evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]);
381
382 if (packet_match_bssid) {
383 /* Fill value in RFD, Get the first
384 * spatial stream only
385 */
386 if (i == 0)
387 pstatus->signalquality =
388 (u8) (evm & 0xff);
389 pstatus->rx_mimo_sig_qual[i] =
390 (u8) (evm & 0xff);
391 }
392 }
393 if (packet_match_bssid) {
394 for (i = RF90_PATH_A; i <= RF90_PATH_B; i++)
395 rtl_priv(hw)->dm.cfo_tail[i] =
396 (char)p_phystrpt->path_cfotail[i];
397
398 rtl_priv(hw)->dm.packet_count++;
399 if (rtl_priv(hw)->dm.packet_count == 0xffffffff)
400 rtl_priv(hw)->dm.packet_count = 0;
401 }
402 }
403
404 /* UI BSS List signal strength(in percentage),
405 * make it good looking, from 0~100.
406 */
407 if (is_cck)
408 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
409 pwdb_all));
410 else if (rf_rx_num != 0)
411 pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw,
412 total_rssi /= rf_rx_num));
413 /*HW antenna diversity*/
414 rtldm->fat_table.antsel_rx_keep_0 = p_phystrpt->ant_sel;
415 rtldm->fat_table.antsel_rx_keep_1 = p_phystrpt->ant_sel_b;
416 rtldm->fat_table.antsel_rx_keep_2 = p_phystrpt->antsel_rx_keep_2;
417}
418
419static void _rtl8723be_translate_rx_signal_stuff(struct ieee80211_hw *hw,
420 struct sk_buff *skb,
421 struct rtl_stats *pstatus,
422 u8 *pdesc,
423 struct rx_fwinfo_8723be *p_drvinfo)
424{
425 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
426 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
427 struct ieee80211_hdr *hdr;
428 u8 *tmp_buf;
429 u8 *praddr;
430 u8 *psaddr;
431 u16 fc, type;
432 bool packet_matchbssid, packet_toself, packet_beacon;
433
434 tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
435
436 hdr = (struct ieee80211_hdr *)tmp_buf;
437 fc = le16_to_cpu(hdr->frame_control);
438 type = WLAN_FC_GET_TYPE(hdr->frame_control);
439 praddr = hdr->addr1;
440 psaddr = ieee80211_get_SA(hdr);
441 memcpy(pstatus->psaddr, psaddr, ETH_ALEN);
442
443 packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
444 (!ether_addr_equal(mac->bssid, (fc & IEEE80211_FCTL_TODS) ?
445 hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
446 hdr->addr2 : hdr->addr3)) &&
447 (!pstatus->hwerror) &&
448 (!pstatus->crc) && (!pstatus->icv));
449
450 packet_toself = packet_matchbssid &&
451 (!ether_addr_equal(praddr, rtlefuse->dev_addr));
452
453 /* YP: packet_beacon is not initialized,
454 * this assignment is neccesary,
455 * otherwise it counld be true in this case
456 * the situation is much worse in Kernel 3.10
457 */
458 if (ieee80211_is_beacon(hdr->frame_control))
459 packet_beacon = true;
460 else
461 packet_beacon = false;
462
463 if (packet_beacon && packet_matchbssid)
464 rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++;
465
466 _rtl8723be_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo,
467 packet_matchbssid,
468 packet_toself,
469 packet_beacon);
470
471 rtl_process_phyinfo(hw, tmp_buf, pstatus);
472}
473
474static void _rtl8723be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
475 u8 *virtualaddress)
476{
477 u32 dwtmp = 0;
478 memset(virtualaddress, 0, 8);
479
480 SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
481 if (ptcb_desc->empkt_num == 1) {
482 dwtmp = ptcb_desc->empkt_len[0];
483 } else {
484 dwtmp = ptcb_desc->empkt_len[0];
485 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
486 dwtmp += ptcb_desc->empkt_len[1];
487 }
488 SET_EARLYMODE_LEN0(virtualaddress, dwtmp);
489
490 if (ptcb_desc->empkt_num <= 3) {
491 dwtmp = ptcb_desc->empkt_len[2];
492 } else {
493 dwtmp = ptcb_desc->empkt_len[2];
494 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
495 dwtmp += ptcb_desc->empkt_len[3];
496 }
497 SET_EARLYMODE_LEN1(virtualaddress, dwtmp);
498 if (ptcb_desc->empkt_num <= 5) {
499 dwtmp = ptcb_desc->empkt_len[4];
500 } else {
501 dwtmp = ptcb_desc->empkt_len[4];
502 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
503 dwtmp += ptcb_desc->empkt_len[5];
504 }
505 SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF);
506 SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4);
507 if (ptcb_desc->empkt_num <= 7) {
508 dwtmp = ptcb_desc->empkt_len[6];
509 } else {
510 dwtmp = ptcb_desc->empkt_len[6];
511 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
512 dwtmp += ptcb_desc->empkt_len[7];
513 }
514 SET_EARLYMODE_LEN3(virtualaddress, dwtmp);
515 if (ptcb_desc->empkt_num <= 9) {
516 dwtmp = ptcb_desc->empkt_len[8];
517 } else {
518 dwtmp = ptcb_desc->empkt_len[8];
519 dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4;
520 dwtmp += ptcb_desc->empkt_len[9];
521 }
522 SET_EARLYMODE_LEN4(virtualaddress, dwtmp);
523}
524
525bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw,
526 struct rtl_stats *status,
527 struct ieee80211_rx_status *rx_status,
528 u8 *pdesc, struct sk_buff *skb)
529{
530 struct rtl_priv *rtlpriv = rtl_priv(hw);
531 struct rx_fwinfo_8723be *p_drvinfo;
532 struct ieee80211_hdr *hdr;
533
534 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
535 status->packet_report_type = (u8)GET_RX_STATUS_DESC_RPT_SEL(pdesc);
536 if (status->packet_report_type == TX_REPORT2)
537 status->length = (u16) GET_RX_RPT2_DESC_PKT_LEN(pdesc);
538 else
539 status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
540 status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
541 RX_DRV_INFO_SIZE_UNIT;
542 status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
543 status->icv = (u16) GET_RX_DESC_ICV(pdesc);
544 status->crc = (u16) GET_RX_DESC_CRC32(pdesc);
545 status->hwerror = (status->crc | status->icv);
546 status->decrypted = !GET_RX_DESC_SWDEC(pdesc);
547 status->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
548 status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
549 status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
550 status->isfirst_ampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
551 if (status->packet_report_type == NORMAL_RX)
552 status->timestamp_low = GET_RX_DESC_TSFL(pdesc);
553 status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
554 status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
555
556 status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate);
557
558 status->macid = GET_RX_DESC_MACID(pdesc);
559 if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
560 status->wake_match = BIT(2);
561 else if (GET_RX_STATUS_DESC_MAGIC_MATCH(pdesc))
562 status->wake_match = BIT(1);
563 else if (GET_RX_STATUS_DESC_UNICAST_MATCH(pdesc))
564 status->wake_match = BIT(0);
565 else
566 status->wake_match = 0;
567 if (status->wake_match)
568 RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD,
569 "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n",
570 status->wake_match);
571 rx_status->freq = hw->conf.chandef.chan->center_freq;
572 rx_status->band = hw->conf.chandef.chan->band;
573
574
575 hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size +
576 status->rx_bufshift);
577
578 if (status->crc)
579 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
580
581 if (status->rx_is40Mhzpacket)
582 rx_status->flag |= RX_FLAG_40MHZ;
583
584 if (status->is_ht)
585 rx_status->flag |= RX_FLAG_HT;
586
587 rx_status->flag |= RX_FLAG_MACTIME_START;
588
589 /* hw will set status->decrypted true, if it finds the
590 * frame is open data frame or mgmt frame.
591 * So hw will not decryption robust managment frame
592 * for IEEE80211w but still set status->decrypted
593 * true, so here we should set it back to undecrypted
594 * for IEEE80211w frame, and mac80211 sw will help
595 * to decrypt it
596 */
597 if (status->decrypted) {
598 if (!hdr) {
599 WARN_ON_ONCE(true);
600 pr_err("decrypted is true but hdr NULL in skb %p\n",
601 rtl_get_hdr(skb));
602 return false;
603 }
604
605 if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
606 (ieee80211_has_protected(hdr->frame_control)))
607 rx_status->flag &= ~RX_FLAG_DECRYPTED;
608 else
609 rx_status->flag |= RX_FLAG_DECRYPTED;
610 }
611
612 /* rate_idx: index of data rate into band's
613 * supported rates or MCS index if HT rates
614 * are use (RX_FLAG_HT)
615 * Notice: this is diff with windows define
616 */
617 rx_status->rate_idx = _rtl8723be_rate_mapping(hw, status->is_ht,
618 status->rate);
619
620 rx_status->mactime = status->timestamp_low;
621 if (phystatus) {
622 p_drvinfo = (struct rx_fwinfo_8723be *)(skb->data +
623 status->rx_bufshift);
624
625 _rtl8723be_translate_rx_signal_stuff(hw, skb, status,
626 pdesc, p_drvinfo);
627 }
628
629 /*rx_status->qual = status->signal; */
630 rx_status->signal = status->recvsignalpower + 10;
631 if (status->packet_report_type == TX_REPORT2) {
632 status->macid_valid_entry[0] =
633 GET_RX_RPT2_DESC_MACID_VALID_1(pdesc);
634 status->macid_valid_entry[1] =
635 GET_RX_RPT2_DESC_MACID_VALID_2(pdesc);
636 }
637 return true;
638}
639
640void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
641 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
642 struct ieee80211_tx_info *info,
643 struct ieee80211_sta *sta, struct sk_buff *skb,
644 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
645{
646 struct rtl_priv *rtlpriv = rtl_priv(hw);
647 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
648 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
649 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
650 u8 *pdesc = (u8 *)pdesc_tx;
651 u16 seq_number;
652 __le16 fc = hdr->frame_control;
653 unsigned int buf_len = 0;
654 unsigned int skb_len = skb->len;
655 u8 fw_qsel = _rtl8723be_map_hwqueue_to_fwqueue(skb, hw_queue);
656 bool firstseg = ((hdr->seq_ctrl &
657 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
658 bool lastseg = ((hdr->frame_control &
659 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
660 dma_addr_t mapping;
661 u8 bw_40 = 0;
662 u8 short_gi = 0;
663
664 if (mac->opmode == NL80211_IFTYPE_STATION) {
665 bw_40 = mac->bw_40;
666 } else if (mac->opmode == NL80211_IFTYPE_AP ||
667 mac->opmode == NL80211_IFTYPE_ADHOC) {
668 if (sta)
669 bw_40 = sta->ht_cap.cap &
670 IEEE80211_HT_CAP_SUP_WIDTH_20_40;
671 }
672 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
673 rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
674 /* reserve 8 byte for AMPDU early mode */
675 if (rtlhal->earlymode_enable) {
676 skb_push(skb, EM_HDR_LEN);
677 memset(skb->data, 0, EM_HDR_LEN);
678 }
679 buf_len = skb->len;
680 mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
681 PCI_DMA_TODEVICE);
682 if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
683 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "DMA mapping error");
684 return;
685 }
686 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723be));
687 if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
688 firstseg = true;
689 lastseg = true;
690 }
691 if (firstseg) {
692 if (rtlhal->earlymode_enable) {
693 SET_TX_DESC_PKT_OFFSET(pdesc, 1);
694 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
695 EM_HDR_LEN);
696 if (ptcb_desc->empkt_num) {
697 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
698 "Insert 8 byte.pTcb->EMPktNum:%d\n",
699 ptcb_desc->empkt_num);
700 _rtl8723be_insert_emcontent(ptcb_desc,
701 (u8 *)(skb->data));
702 }
703 } else {
704 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
705 }
706
707 /* ptcb_desc->use_driver_rate = true; */
708 SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
709 if (ptcb_desc->hw_rate > DESC92C_RATEMCS0)
710 short_gi = (ptcb_desc->use_shortgi) ? 1 : 0;
711 else
712 short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0;
713
714 SET_TX_DESC_DATA_SHORTGI(pdesc, short_gi);
715
716 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
717 SET_TX_DESC_AGG_ENABLE(pdesc, 1);
718 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
719 }
720 SET_TX_DESC_SEQ(pdesc, seq_number);
721 SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
722 !ptcb_desc->cts_enable) ?
723 1 : 0));
724 SET_TX_DESC_HW_RTS_ENABLE(pdesc, 0);
725 SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ?
726 1 : 0));
727
728 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
729
730 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
731 SET_TX_DESC_RTS_SHORT(pdesc,
732 ((ptcb_desc->rts_rate <= DESC92C_RATE54M) ?
733 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
734 (ptcb_desc->rts_use_shortgi ? 1 : 0)));
735
736 if (ptcb_desc->btx_enable_sw_calc_duration)
737 SET_TX_DESC_NAV_USE_HDR(pdesc, 1);
738
739 if (bw_40) {
740 if (ptcb_desc->packet_bw) {
741 SET_TX_DESC_DATA_BW(pdesc, 1);
742 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
743 } else {
744 SET_TX_DESC_DATA_BW(pdesc, 0);
745 SET_TX_DESC_TX_SUB_CARRIER(pdesc, mac->cur_40_prime_sc);
746 }
747 } else {
748 SET_TX_DESC_DATA_BW(pdesc, 0);
749 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
750 }
751
752 SET_TX_DESC_LINIP(pdesc, 0);
753 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
754 if (sta) {
755 u8 ampdu_density = sta->ht_cap.ampdu_density;
756 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
757 }
758 if (info->control.hw_key) {
759 struct ieee80211_key_conf *keyconf =
760 info->control.hw_key;
761 switch (keyconf->cipher) {
762 case WLAN_CIPHER_SUITE_WEP40:
763 case WLAN_CIPHER_SUITE_WEP104:
764 case WLAN_CIPHER_SUITE_TKIP:
765 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
766 break;
767 case WLAN_CIPHER_SUITE_CCMP:
768 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
769 break;
770 default:
771 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
772 break;
773 }
774 }
775
776 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
777 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
778 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
779 SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
780 1 : 0);
781 SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
782
783 if (ieee80211_is_data_qos(fc)) {
784 if (mac->rdg_en) {
785 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
786 "Enable RDG function.\n");
787 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
788 SET_TX_DESC_HTC(pdesc, 1);
789 }
790 }
791 }
792
793 SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
794 SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
795 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
796 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
797 SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
798 SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
799
800 if (!ieee80211_is_data_qos(fc)) {
801 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
802 SET_TX_DESC_HWSEQ_SEL(pdesc, 0);
803 }
804 SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
805 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
806 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
807 SET_TX_DESC_BMC(pdesc, 1);
808 }
809 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
810}
811
812void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
813 bool b_firstseg, bool b_lastseg,
814 struct sk_buff *skb)
815{
816 struct rtl_priv *rtlpriv = rtl_priv(hw);
817 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
818 u8 fw_queue = QSLT_BEACON;
819
820 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
821 skb->data, skb->len,
822 PCI_DMA_TODEVICE);
823
824 if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
825 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
826 "DMA mapping error");
827 return;
828 }
829 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
830
831 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
832
833 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
834
835 SET_TX_DESC_SEQ(pdesc, 0);
836
837 SET_TX_DESC_LINIP(pdesc, 0);
838
839 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
840
841 SET_TX_DESC_FIRST_SEG(pdesc, 1);
842 SET_TX_DESC_LAST_SEG(pdesc, 1);
843
844 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
845
846 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
847
848 SET_TX_DESC_RATE_ID(pdesc, 0);
849 SET_TX_DESC_MACID(pdesc, 0);
850
851 SET_TX_DESC_OWN(pdesc, 1);
852
853 SET_TX_DESC_PKT_SIZE((u8 *)pdesc, (u16)(skb->len));
854
855 SET_TX_DESC_FIRST_SEG(pdesc, 1);
856 SET_TX_DESC_LAST_SEG(pdesc, 1);
857
858 SET_TX_DESC_USE_RATE(pdesc, 1);
859}
860
861void rtl8723be_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
862{
863 if (istx) {
864 switch (desc_name) {
865 case HW_DESC_OWN:
866 SET_TX_DESC_OWN(pdesc, 1);
867 break;
868 case HW_DESC_TX_NEXTDESC_ADDR:
869 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *)val);
870 break;
871 default:
872 RT_ASSERT(false, "ERR txdesc :%d not process\n",
873 desc_name);
874 break;
875 }
876 } else {
877 switch (desc_name) {
878 case HW_DESC_RXOWN:
879 SET_RX_DESC_OWN(pdesc, 1);
880 break;
881 case HW_DESC_RXBUFF_ADDR:
882 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *)val);
883 break;
884 case HW_DESC_RXPKT_LEN:
885 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *)val);
886 break;
887 case HW_DESC_RXERO:
888 SET_RX_DESC_EOR(pdesc, 1);
889 break;
890 default:
891 RT_ASSERT(false, "ERR rxdesc :%d not process\n",
892 desc_name);
893 break;
894 }
895 }
896}
897
898u32 rtl8723be_get_desc(u8 *pdesc, bool istx, u8 desc_name)
899{
900 u32 ret = 0;
901
902 if (istx) {
903 switch (desc_name) {
904 case HW_DESC_OWN:
905 ret = GET_TX_DESC_OWN(pdesc);
906 break;
907 case HW_DESC_TXBUFF_ADDR:
908 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc);
909 break;
910 default:
911 RT_ASSERT(false, "ERR txdesc :%d not process\n",
912 desc_name);
913 break;
914 }
915 } else {
916 switch (desc_name) {
917 case HW_DESC_OWN:
918 ret = GET_RX_DESC_OWN(pdesc);
919 break;
920 case HW_DESC_RXPKT_LEN:
921 ret = GET_RX_DESC_PKT_LEN(pdesc);
922 break;
923 default:
924 RT_ASSERT(false, "ERR rxdesc :%d not process\n",
925 desc_name);
926 break;
927 }
928 }
929 return ret;
930}
931
932bool rtl8723be_is_tx_desc_closed(struct ieee80211_hw *hw,
933 u8 hw_queue, u16 index)
934{
935 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
936 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
937 u8 *entry = (u8 *)(&ring->desc[ring->idx]);
938 u8 own = (u8) rtl8723be_get_desc(entry, true, HW_DESC_OWN);
939
940 /*beacon packet will only use the first
941 *descriptor by default, and the own may not
942 *be cleared by the hardware
943 */
944 if (own)
945 return false;
946 else
947 return true;
948}
949
950void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
951{
952 struct rtl_priv *rtlpriv = rtl_priv(hw);
953 if (hw_queue == BEACON_QUEUE) {
954 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
955 } else {
956 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
957 BIT(0) << (hw_queue));
958 }
959}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.h b/drivers/net/wireless/rtlwifi/rtl8723be/trx.h
new file mode 100644
index 000000000000..d375cf01c3dc
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.h
@@ -0,0 +1,616 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#ifndef __RTL8723BE_TRX_H__
27#define __RTL8723BE_TRX_H__
28
29#define TX_DESC_SIZE 40
30#define TX_DESC_AGGR_SUBFRAME_SIZE 32
31
32#define RX_DESC_SIZE 32
33#define RX_DRV_INFO_SIZE_UNIT 8
34
35#define TX_DESC_NEXT_DESC_OFFSET 40
36#define USB_HWDESC_HEADER_LEN 40
37#define CRCLENGTH 4
38
39#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
40 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
41#define SET_TX_DESC_OFFSET(__pdesc, __val) \
42 SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
43#define SET_TX_DESC_BMC(__pdesc, __val) \
44 SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
45#define SET_TX_DESC_HTC(__pdesc, __val) \
46 SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
47#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
48 SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
49#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
50 SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
51#define SET_TX_DESC_LINIP(__pdesc, __val) \
52 SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
53#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
54 SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
55#define SET_TX_DESC_GF(__pdesc, __val) \
56 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
57#define SET_TX_DESC_OWN(__pdesc, __val) \
58 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
59
60#define GET_TX_DESC_PKT_SIZE(__pdesc) \
61 LE_BITS_TO_4BYTE(__pdesc, 0, 16)
62#define GET_TX_DESC_OFFSET(__pdesc) \
63 LE_BITS_TO_4BYTE(__pdesc, 16, 8)
64#define GET_TX_DESC_BMC(__pdesc) \
65 LE_BITS_TO_4BYTE(__pdesc, 24, 1)
66#define GET_TX_DESC_HTC(__pdesc) \
67 LE_BITS_TO_4BYTE(__pdesc, 25, 1)
68#define GET_TX_DESC_LAST_SEG(__pdesc) \
69 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
70#define GET_TX_DESC_FIRST_SEG(__pdesc) \
71 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
72#define GET_TX_DESC_LINIP(__pdesc) \
73 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
74#define GET_TX_DESC_NO_ACM(__pdesc) \
75 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
76#define GET_TX_DESC_GF(__pdesc) \
77 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
78#define GET_TX_DESC_OWN(__pdesc) \
79 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
80
81#define SET_TX_DESC_MACID(__pdesc, __val) \
82 SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 7, __val)
83#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
84 SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
85#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
86 SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
87#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
88 SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
89#define SET_TX_DESC_PIFS(__pdesc, __val) \
90 SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
91#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
92 SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 5, __val)
93#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
94 SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
95#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
96 SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
97#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
98 SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 5, __val)
99
100
101#define SET_TX_DESC_PAID(__pdesc, __val) \
102 SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 9, __val)
103#define SET_TX_DESC_CCA_RTS(__pdesc, __val) \
104 SET_BITS_TO_LE_4BYTE(__pdesc+8, 10, 2, __val)
105#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
106 SET_BITS_TO_LE_4BYTE(__pdesc+8, 12, 1, __val)
107#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
108 SET_BITS_TO_LE_4BYTE(__pdesc+8, 13, 1, __val)
109#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
110 SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
111#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
112 SET_BITS_TO_LE_4BYTE(__pdesc+8, 16, 1, __val)
113#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
114 SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
115#define SET_TX_DESC_RAW(__pdesc, __val) \
116 SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
117#define SET_TX_DESC_SPE_RPT(__pdesc, __val) \
118 SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
119#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
120 SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
121#define SET_TX_DESC_BT_INT(__pdesc, __val) \
122 SET_BITS_TO_LE_4BYTE(__pdesc+8, 23, 1, __val)
123#define SET_TX_DESC_GID(__pdesc, __val) \
124 SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 6, __val)
125
126
127#define SET_TX_DESC_WHEADER_LEN(__pdesc, __val) \
128 SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 4, __val)
129#define SET_TX_DESC_CHK_EN(__pdesc, __val) \
130 SET_BITS_TO_LE_4BYTE(__pdesc+12, 4, 1, __val)
131#define SET_TX_DESC_EARLY_MODE(__pdesc, __val) \
132 SET_BITS_TO_LE_4BYTE(__pdesc+12, 5, 1, __val)
133#define SET_TX_DESC_HWSEQ_SEL(__pdesc, __val) \
134 SET_BITS_TO_LE_4BYTE(__pdesc+12, 6, 2, __val)
135#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
136 SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 1, __val)
137#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
138 SET_BITS_TO_LE_4BYTE(__pdesc+12, 9, 1, __val)
139#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
140 SET_BITS_TO_LE_4BYTE(__pdesc+12, 10, 1, __val)
141#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
142 SET_BITS_TO_LE_4BYTE(__pdesc+12, 11, 1, __val)
143#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
144 SET_BITS_TO_LE_4BYTE(__pdesc+12, 12, 1, __val)
145#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
146 SET_BITS_TO_LE_4BYTE(__pdesc+12, 13, 1, __val)
147#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
148 SET_BITS_TO_LE_4BYTE(__pdesc+12, 15, 1, __val)
149#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
150 SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 1, __val)
151#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
152 SET_BITS_TO_LE_4BYTE(__pdesc+12, 17, 5, __val)
153#define SET_TX_DESC_NDPA(__pdesc, __val) \
154 SET_BITS_TO_LE_4BYTE(__pdesc+12, 22, 2, __val)
155#define SET_TX_DESC_AMPDU_MAX_TIME(__pdesc, __val) \
156 SET_BITS_TO_LE_4BYTE(__pdesc+12, 24, 8, __val)
157
158
159#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
160 SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 7, __val)
161#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
162 SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 5, __val)
163#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
164 SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 4, __val)
165#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
166 SET_BITS_TO_LE_4BYTE(__pdesc+16, 17, 1, __val)
167#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
168 SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 6, __val)
169#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
170 SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 5, __val)
171
172
173#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
174 SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 4, __val)
175#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
176 SET_BITS_TO_LE_4BYTE(__pdesc+20, 4, 1, __val)
177#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
178 SET_BITS_TO_LE_4BYTE(__pdesc+20, 5, 2, __val)
179#define SET_TX_DESC_DATA_LDPC(__pdesc, __val) \
180 SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
181#define SET_TX_DESC_DATA_STBC(__pdesc, __val) \
182 SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 2, __val)
183#define SET_TX_DESC_CTROL_STBC(__pdesc, __val) \
184 SET_BITS_TO_LE_4BYTE(__pdesc+20, 10, 2, __val)
185#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
186 SET_BITS_TO_LE_4BYTE(__pdesc+20, 12, 1, __val)
187#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
188 SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
189
190
191#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
192 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
193
194#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
195 LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
196
197#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
198 SET_BITS_TO_LE_4BYTE(__pdesc+32, 15, 1, __val)
199
200#define SET_TX_DESC_SEQ(__pdesc, __val) \
201 SET_BITS_TO_LE_4BYTE(__pdesc+36, 12, 12, __val)
202
203#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
204 SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
205
206#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
207 LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
208
209
210#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
211 SET_BITS_TO_LE_4BYTE(__pdesc+48, 0, 32, __val)
212
213#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
214 LE_BITS_TO_4BYTE(__pdesc+48, 0, 32)
215
216#define GET_RX_DESC_PKT_LEN(__pdesc) \
217 LE_BITS_TO_4BYTE(__pdesc, 0, 14)
218#define GET_RX_DESC_CRC32(__pdesc) \
219 LE_BITS_TO_4BYTE(__pdesc, 14, 1)
220#define GET_RX_DESC_ICV(__pdesc) \
221 LE_BITS_TO_4BYTE(__pdesc, 15, 1)
222#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
223 LE_BITS_TO_4BYTE(__pdesc, 16, 4)
224#define GET_RX_DESC_SECURITY(__pdesc) \
225 LE_BITS_TO_4BYTE(__pdesc, 20, 3)
226#define GET_RX_DESC_QOS(__pdesc) \
227 LE_BITS_TO_4BYTE(__pdesc, 23, 1)
228#define GET_RX_DESC_SHIFT(__pdesc) \
229 LE_BITS_TO_4BYTE(__pdesc, 24, 2)
230#define GET_RX_DESC_PHYST(__pdesc) \
231 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
232#define GET_RX_DESC_SWDEC(__pdesc) \
233 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
234#define GET_RX_DESC_LS(__pdesc) \
235 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
236#define GET_RX_DESC_FS(__pdesc) \
237 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
238#define GET_RX_DESC_EOR(__pdesc) \
239 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
240#define GET_RX_DESC_OWN(__pdesc) \
241 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
242
243#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
244 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
245#define SET_RX_DESC_EOR(__pdesc, __val) \
246 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
247#define SET_RX_DESC_OWN(__pdesc, __val) \
248 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
249
250#define GET_RX_DESC_MACID(__pdesc) \
251 LE_BITS_TO_4BYTE(__pdesc+4, 0, 7)
252#define GET_RX_DESC_TID(__pdesc) \
253 LE_BITS_TO_4BYTE(__pdesc+4, 8, 4)
254#define GET_RX_DESC_AMSDU(__pdesc) \
255 LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
256#define GET_RX_STATUS_DESC_RXID_MATCH(__pdesc) \
257 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
258#define GET_RX_DESC_PAGGR(__pdesc) \
259 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
260#define GET_RX_DESC_A1_FIT(__pdesc) \
261 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
262#define GET_RX_DESC_CHKERR(__pdesc) \
263 LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
264#define GET_RX_DESC_IPVER(__pdesc) \
265 LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
266#define GET_RX_STATUS_DESC_IS_TCPUDP(__pdesc) \
267 LE_BITS_TO_4BYTE(__pdesc+4, 22, 1)
268#define GET_RX_STATUS_DESC_CHK_VLD(__pdesc) \
269 LE_BITS_TO_4BYTE(__pdesc+4, 23, 1)
270#define GET_RX_DESC_PAM(__pdesc) \
271 LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
272#define GET_RX_DESC_PWR(__pdesc) \
273 LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
274#define GET_RX_DESC_MD(__pdesc) \
275 LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
276#define GET_RX_DESC_MF(__pdesc) \
277 LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
278#define GET_RX_DESC_TYPE(__pdesc) \
279 LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
280#define GET_RX_DESC_MC(__pdesc) \
281 LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
282#define GET_RX_DESC_BC(__pdesc) \
283 LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
284
285
286#define GET_RX_DESC_SEQ(__pdesc) \
287 LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
288#define GET_RX_DESC_FRAG(__pdesc) \
289 LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
290#define GET_RX_STATUS_DESC_RX_IS_QOS(__pdesc) \
291 LE_BITS_TO_4BYTE(__pdesc+8, 16, 1)
292#define GET_RX_STATUS_DESC_WLANHD_IV_LEN(__pdesc) \
293 LE_BITS_TO_4BYTE(__pdesc+8, 18, 6)
294#define GET_RX_STATUS_DESC_RPT_SEL(__pdesc) \
295 LE_BITS_TO_4BYTE(__pdesc+8, 28, 1)
296
297
298#define GET_RX_DESC_RXMCS(__pdesc) \
299 LE_BITS_TO_4BYTE(__pdesc+12, 0, 7)
300#define GET_RX_DESC_RXHT(__pdesc) \
301 LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
302#define GET_RX_STATUS_DESC_RX_GF(__pdesc) \
303 LE_BITS_TO_4BYTE(__pdesc+12, 7, 1)
304#define GET_RX_DESC_HTC(__pdesc) \
305 LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
306#define GET_RX_STATUS_DESC_EOSP(__pdesc) \
307 LE_BITS_TO_4BYTE(__pdesc+12, 11, 1)
308#define GET_RX_STATUS_DESC_BSSID_FIT(__pdesc) \
309 LE_BITS_TO_4BYTE(__pdesc+12, 12, 2)
310
311#define GET_RX_STATUS_DESC_PATTERN_MATCH(__pdesc) \
312 LE_BITS_TO_4BYTE(__pdesc+12, 29, 1)
313#define GET_RX_STATUS_DESC_UNICAST_MATCH(__pdesc) \
314 LE_BITS_TO_4BYTE(__pdesc+12, 30, 1)
315#define GET_RX_STATUS_DESC_MAGIC_MATCH(__pdesc) \
316 LE_BITS_TO_4BYTE(__pdesc+12, 31, 1)
317
318#define GET_RX_DESC_SPLCP(__pdesc) \
319 LE_BITS_TO_4BYTE(__pdesc+16, 0, 1)
320#define GET_RX_STATUS_DESC_LDPC(__pdesc) \
321 LE_BITS_TO_4BYTE(__pdesc+16, 1, 1)
322#define GET_RX_STATUS_DESC_STBC(__pdesc) \
323 LE_BITS_TO_4BYTE(__pdesc+16, 2, 1)
324#define GET_RX_DESC_BW(__pdesc) \
325 LE_BITS_TO_4BYTE(__pdesc+16, 4, 2)
326
327#define GET_RX_DESC_TSFL(__pdesc) \
328 LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
329
330#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
331 LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
332#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
333 LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
334
335#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
336 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
337#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
338 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
339
340
341/* TX report 2 format in Rx desc*/
342
343#define GET_RX_RPT2_DESC_PKT_LEN(__rxstatusdesc) \
344 LE_BITS_TO_4BYTE(__rxstatusdesc, 0, 9)
345#define GET_RX_RPT2_DESC_MACID_VALID_1(__rxstatusdesc) \
346 LE_BITS_TO_4BYTE(__rxstatusdesc+16, 0, 32)
347#define GET_RX_RPT2_DESC_MACID_VALID_2(__rxstatusdesc) \
348 LE_BITS_TO_4BYTE(__rxstatusdesc+20, 0, 32)
349
350#define SET_EARLYMODE_PKTNUM(__paddr, __value) \
351 SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __value)
352#define SET_EARLYMODE_LEN0(__paddr, __value) \
353 SET_BITS_TO_LE_4BYTE(__paddr, 4, 12, __value)
354#define SET_EARLYMODE_LEN1(__paddr, __value) \
355 SET_BITS_TO_LE_4BYTE(__paddr, 16, 12, __value)
356#define SET_EARLYMODE_LEN2_1(__paddr, __value) \
357 SET_BITS_TO_LE_4BYTE(__paddr, 28, 4, __value)
358#define SET_EARLYMODE_LEN2_2(__paddr, __value) \
359 SET_BITS_TO_LE_4BYTE(__paddr+4, 0, 8, __value)
360#define SET_EARLYMODE_LEN3(__paddr, __value) \
361 SET_BITS_TO_LE_4BYTE(__paddr+4, 8, 12, __value)
362#define SET_EARLYMODE_LEN4(__paddr, __value) \
363 SET_BITS_TO_LE_4BYTE(__paddr+4, 20, 12, __value)
364
365#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
366do { \
367 if (_size > TX_DESC_NEXT_DESC_OFFSET) \
368 memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
369 else \
370 memset(__pdesc, 0, _size); \
371} while (0)
372
373struct phy_rx_agc_info_t {
374 #ifdef __LITTLE_ENDIAN
375 u8 gain:7, trsw:1;
376 #else
377 u8 trsw:1, gain:7;
378 #endif
379};
380struct phy_status_rpt {
381 struct phy_rx_agc_info_t path_agc[2];
382 u8 ch_corr[2];
383 u8 cck_sig_qual_ofdm_pwdb_all;
384 u8 cck_agc_rpt_ofdm_cfosho_a;
385 u8 cck_rpt_b_ofdm_cfosho_b;
386 u8 rsvd_1;/* ch_corr_msb; */
387 u8 noise_power_db_msb;
388 char path_cfotail[2];
389 u8 pcts_mask[2];
390 char stream_rxevm[2];
391 u8 path_rxsnr[2];
392 u8 noise_power_db_lsb;
393 u8 rsvd_2[3];
394 u8 stream_csi[2];
395 u8 stream_target_csi[2];
396 u8 sig_evm;
397 u8 rsvd_3;
398#ifdef __LITTLE_ENDIAN
399 u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
400 u8 sgi_en:1;
401 u8 rxsc:2;
402 u8 idle_long:1;
403 u8 r_ant_train_en:1;
404 u8 ant_sel_b:1;
405 u8 ant_sel:1;
406#else /* _BIG_ENDIAN_ */
407 u8 ant_sel:1;
408 u8 ant_sel_b:1;
409 u8 r_ant_train_en:1;
410 u8 idle_long:1;
411 u8 rxsc:2;
412 u8 sgi_en:1;
413 u8 antsel_rx_keep_2:1; /*ex_intf_flg:1;*/
414#endif
415} __packed;
416
417struct rx_fwinfo_8723be {
418 u8 gain_trsw[4];
419 u8 pwdb_all;
420 u8 cfosho[4];
421 u8 cfotail[4];
422 char rxevm[2];
423 char rxsnr[4];
424 u8 pdsnr[2];
425 u8 csi_current[2];
426 u8 csi_target[2];
427 u8 sigevm;
428 u8 max_ex_pwr;
429 u8 ex_intf_flag:1;
430 u8 sgi_en:1;
431 u8 rxsc:2;
432 u8 reserve:4;
433} __packed;
434
435struct tx_desc_8723be {
436 u32 pktsize:16;
437 u32 offset:8;
438 u32 bmc:1;
439 u32 htc:1;
440 u32 lastseg:1;
441 u32 firstseg:1;
442 u32 linip:1;
443 u32 noacm:1;
444 u32 gf:1;
445 u32 own:1;
446
447 u32 macid:6;
448 u32 rsvd0:2;
449 u32 queuesel:5;
450 u32 rd_nav_ext:1;
451 u32 lsig_txop_en:1;
452 u32 pifs:1;
453 u32 rateid:4;
454 u32 nav_usehdr:1;
455 u32 en_descid:1;
456 u32 sectype:2;
457 u32 pktoffset:8;
458
459 u32 rts_rc:6;
460 u32 data_rc:6;
461 u32 agg_en:1;
462 u32 rdg_en:1;
463 u32 bar_retryht:2;
464 u32 agg_break:1;
465 u32 morefrag:1;
466 u32 raw:1;
467 u32 ccx:1;
468 u32 ampdudensity:3;
469 u32 bt_int:1;
470 u32 ant_sela:1;
471 u32 ant_selb:1;
472 u32 txant_cck:2;
473 u32 txant_l:2;
474 u32 txant_ht:2;
475
476 u32 nextheadpage:8;
477 u32 tailpage:8;
478 u32 seq:12;
479 u32 cpu_handle:1;
480 u32 tag1:1;
481 u32 trigger_int:1;
482 u32 hwseq_en:1;
483
484 u32 rtsrate:5;
485 u32 apdcfe:1;
486 u32 qos:1;
487 u32 hwseq_ssn:1;
488 u32 userrate:1;
489 u32 dis_rtsfb:1;
490 u32 dis_datafb:1;
491 u32 cts2self:1;
492 u32 rts_en:1;
493 u32 hwrts_en:1;
494 u32 portid:1;
495 u32 pwr_status:3;
496 u32 waitdcts:1;
497 u32 cts2ap_en:1;
498 u32 txsc:2;
499 u32 stbc:2;
500 u32 txshort:1;
501 u32 txbw:1;
502 u32 rtsshort:1;
503 u32 rtsbw:1;
504 u32 rtssc:2;
505 u32 rtsstbc:2;
506
507 u32 txrate:6;
508 u32 shortgi:1;
509 u32 ccxt:1;
510 u32 txrate_fb_lmt:5;
511 u32 rtsrate_fb_lmt:4;
512 u32 retrylmt_en:1;
513 u32 txretrylmt:6;
514 u32 usb_txaggnum:8;
515
516 u32 txagca:5;
517 u32 txagcb:5;
518 u32 usemaxlen:1;
519 u32 maxaggnum:5;
520 u32 mcsg1maxlen:4;
521 u32 mcsg2maxlen:4;
522 u32 mcsg3maxlen:4;
523 u32 mcs7sgimaxlen:4;
524
525 u32 txbuffersize:16;
526 u32 sw_offset30:8;
527 u32 sw_offset31:4;
528 u32 rsvd1:1;
529 u32 antsel_c:1;
530 u32 null_0:1;
531 u32 null_1:1;
532
533 u32 txbuffaddr;
534 u32 txbufferaddr64;
535 u32 nextdescaddress;
536 u32 nextdescaddress64;
537
538 u32 reserve_pass_pcie_mm_limit[4];
539} __packed;
540
541struct rx_desc_8723be {
542 u32 length:14;
543 u32 crc32:1;
544 u32 icverror:1;
545 u32 drv_infosize:4;
546 u32 security:3;
547 u32 qos:1;
548 u32 shift:2;
549 u32 phystatus:1;
550 u32 swdec:1;
551 u32 lastseg:1;
552 u32 firstseg:1;
553 u32 eor:1;
554 u32 own:1;
555
556 u32 macid:6;
557 u32 tid:4;
558 u32 hwrsvd:5;
559 u32 paggr:1;
560 u32 faggr:1;
561 u32 a1_fit:4;
562 u32 a2_fit:4;
563 u32 pam:1;
564 u32 pwr:1;
565 u32 moredata:1;
566 u32 morefrag:1;
567 u32 type:2;
568 u32 mc:1;
569 u32 bc:1;
570
571 u32 seq:12;
572 u32 frag:4;
573 u32 nextpktlen:14;
574 u32 nextind:1;
575 u32 rsvd:1;
576
577 u32 rxmcs:6;
578 u32 rxht:1;
579 u32 amsdu:1;
580 u32 splcp:1;
581 u32 bandwidth:1;
582 u32 htc:1;
583 u32 tcpchk_rpt:1;
584 u32 ipcchk_rpt:1;
585 u32 tcpchk_valid:1;
586 u32 hwpcerr:1;
587 u32 hwpcind:1;
588 u32 iv0:16;
589
590 u32 iv1;
591
592 u32 tsfl;
593
594 u32 bufferaddress;
595 u32 bufferaddress64;
596
597} __packed;
598
599void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
600 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
601 struct ieee80211_tx_info *info,
602 struct ieee80211_sta *sta, struct sk_buff *skb,
603 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc);
604bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw,
605 struct rtl_stats *status,
606 struct ieee80211_rx_status *rx_status,
607 u8 *pdesc, struct sk_buff *skb);
608void rtl8723be_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
609u32 rtl8723be_get_desc(u8 *pdesc, bool istx, u8 desc_name);
610bool rtl8723be_is_tx_desc_closed(struct ieee80211_hw *hw,
611 u8 hw_queue, u16 index);
612void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
613void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
614 bool b_firstseg, bool b_lastseg,
615 struct sk_buff *skb);
616#endif