diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192se')
21 files changed, 11097 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/Makefile b/drivers/net/wireless/rtlwifi/rtl8192se/Makefile new file mode 100644 index 000000000000..b7eb13819cbc --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/Makefile | |||
@@ -0,0 +1,15 @@ | |||
1 | rtl8192se-objs := \ | ||
2 | dm.o \ | ||
3 | fw.o \ | ||
4 | hw.o \ | ||
5 | led.o \ | ||
6 | phy.o \ | ||
7 | rf.o \ | ||
8 | sw.o \ | ||
9 | table.o \ | ||
10 | trx.o | ||
11 | |||
12 | obj-$(CONFIG_RTL8192SE) += rtl8192se.o | ||
13 | |||
14 | ccflags-y += -D__CHECK_ENDIAN__ | ||
15 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h new file mode 100644 index 000000000000..69828f2b3fab --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h | |||
@@ -0,0 +1,598 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __REALTEK_92S_DEF_H__ | ||
30 | #define __REALTEK_92S_DEF_H__ | ||
31 | |||
32 | #define RX_MPDU_QUEUE 0 | ||
33 | #define RX_CMD_QUEUE 1 | ||
34 | #define RX_MAX_QUEUE 2 | ||
35 | |||
36 | #define DESC92S_RATE1M 0x00 | ||
37 | #define DESC92S_RATE2M 0x01 | ||
38 | #define DESC92S_RATE5_5M 0x02 | ||
39 | #define DESC92S_RATE11M 0x03 | ||
40 | #define DESC92S_RATE6M 0x04 | ||
41 | #define DESC92S_RATE9M 0x05 | ||
42 | #define DESC92S_RATE12M 0x06 | ||
43 | #define DESC92S_RATE18M 0x07 | ||
44 | #define DESC92S_RATE24M 0x08 | ||
45 | #define DESC92S_RATE36M 0x09 | ||
46 | #define DESC92S_RATE48M 0x0a | ||
47 | #define DESC92S_RATE54M 0x0b | ||
48 | #define DESC92S_RATEMCS0 0x0c | ||
49 | #define DESC92S_RATEMCS1 0x0d | ||
50 | #define DESC92S_RATEMCS2 0x0e | ||
51 | #define DESC92S_RATEMCS3 0x0f | ||
52 | #define DESC92S_RATEMCS4 0x10 | ||
53 | #define DESC92S_RATEMCS5 0x11 | ||
54 | #define DESC92S_RATEMCS6 0x12 | ||
55 | #define DESC92S_RATEMCS7 0x13 | ||
56 | #define DESC92S_RATEMCS8 0x14 | ||
57 | #define DESC92S_RATEMCS9 0x15 | ||
58 | #define DESC92S_RATEMCS10 0x16 | ||
59 | #define DESC92S_RATEMCS11 0x17 | ||
60 | #define DESC92S_RATEMCS12 0x18 | ||
61 | #define DESC92S_RATEMCS13 0x19 | ||
62 | #define DESC92S_RATEMCS14 0x1a | ||
63 | #define DESC92S_RATEMCS15 0x1b | ||
64 | #define DESC92S_RATEMCS15_SG 0x1c | ||
65 | #define DESC92S_RATEMCS32 0x20 | ||
66 | |||
67 | #define SHORT_SLOT_TIME 9 | ||
68 | #define NON_SHORT_SLOT_TIME 20 | ||
69 | |||
70 | /* Rx smooth factor */ | ||
71 | #define RX_SMOOTH_FACTOR 20 | ||
72 | |||
73 | /* Queue Select Value in TxDesc */ | ||
74 | #define QSLT_BK 0x2 | ||
75 | #define QSLT_BE 0x0 | ||
76 | #define QSLT_VI 0x5 | ||
77 | #define QSLT_VO 0x6 | ||
78 | #define QSLT_BEACON 0x10 | ||
79 | #define QSLT_HIGH 0x11 | ||
80 | #define QSLT_MGNT 0x12 | ||
81 | #define QSLT_CMD 0x13 | ||
82 | |||
83 | #define PHY_RSSI_SLID_WIN_MAX 100 | ||
84 | #define PHY_LINKQUALITY_SLID_WIN_MAX 20 | ||
85 | #define PHY_BEACON_RSSI_SLID_WIN_MAX 10 | ||
86 | |||
87 | /* Tx Desc */ | ||
88 | #define TX_DESC_SIZE_RTL8192S (16 * 4) | ||
89 | #define TX_CMDDESC_SIZE_RTL8192S (16 * 4) | ||
90 | |||
91 | /* Define a macro that takes a le32 word, converts it to host ordering, | ||
92 | * right shifts by a specified count, creates a mask of the specified | ||
93 | * bit count, and extracts that number of bits. | ||
94 | */ | ||
95 | |||
96 | #define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \ | ||
97 | ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \ | ||
98 | BIT_LEN_MASK_32(__mask)) | ||
99 | |||
100 | /* Define a macro that clears a bit field in an le32 word and | ||
101 | * sets the specified value into that bit field. The resulting | ||
102 | * value remains in le32 ordering; however, it is properly converted | ||
103 | * to host ordering for the clear and set operations before conversion | ||
104 | * back to le32. | ||
105 | */ | ||
106 | |||
107 | #define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \ | ||
108 | (*(__le32 *)(__pdesc) = \ | ||
109 | (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \ | ||
110 | (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \ | ||
111 | (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift))))); | ||
112 | |||
113 | /* macros to read/write various fields in RX or TX descriptors */ | ||
114 | |||
115 | /* Dword 0 */ | ||
116 | #define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ | ||
117 | SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val) | ||
118 | #define SET_TX_DESC_OFFSET(__pdesc, __val) \ | ||
119 | SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val) | ||
120 | #define SET_TX_DESC_TYPE(__pdesc, __val) \ | ||
121 | SET_BITS_OFFSET_LE(__pdesc, 24, 2, __val) | ||
122 | #define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ | ||
123 | SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val) | ||
124 | #define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ | ||
125 | SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val) | ||
126 | #define SET_TX_DESC_LINIP(__pdesc, __val) \ | ||
127 | SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val) | ||
128 | #define SET_TX_DESC_AMSDU(__pdesc, __val) \ | ||
129 | SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val) | ||
130 | #define SET_TX_DESC_GREEN_FIELD(__pdesc, __val) \ | ||
131 | SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val) | ||
132 | #define SET_TX_DESC_OWN(__pdesc, __val) \ | ||
133 | SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val) | ||
134 | |||
135 | #define GET_TX_DESC_OWN(__pdesc) \ | ||
136 | SHIFT_AND_MASK_LE(__pdesc, 31, 1) | ||
137 | |||
138 | /* Dword 1 */ | ||
139 | #define SET_TX_DESC_MACID(__pdesc, __val) \ | ||
140 | SET_BITS_OFFSET_LE(__pdesc + 4, 0, 5, __val) | ||
141 | #define SET_TX_DESC_MORE_DATA(__pdesc, __val) \ | ||
142 | SET_BITS_OFFSET_LE(__pdesc + 4, 5, 1, __val) | ||
143 | #define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ | ||
144 | SET_BITS_OFFSET_LE(__pdesc + 4, 6, 1, __val) | ||
145 | #define SET_TX_DESC_PIFS(__pdesc, __val) \ | ||
146 | SET_BITS_OFFSET_LE(__pdesc + 4, 7, 1, __val) | ||
147 | #define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ | ||
148 | SET_BITS_OFFSET_LE(__pdesc + 4, 8, 5, __val) | ||
149 | #define SET_TX_DESC_ACK_POLICY(__pdesc, __val) \ | ||
150 | SET_BITS_OFFSET_LE(__pdesc + 4, 13, 2, __val) | ||
151 | #define SET_TX_DESC_NO_ACM(__pdesc, __val) \ | ||
152 | SET_BITS_OFFSET_LE(__pdesc + 4, 15, 1, __val) | ||
153 | #define SET_TX_DESC_NON_QOS(__pdesc, __val) \ | ||
154 | SET_BITS_OFFSET_LE(__pdesc + 4, 16, 1, __val) | ||
155 | #define SET_TX_DESC_KEY_ID(__pdesc, __val) \ | ||
156 | SET_BITS_OFFSET_LE(__pdesc + 4, 17, 2, __val) | ||
157 | #define SET_TX_DESC_OUI(__pdesc, __val) \ | ||
158 | SET_BITS_OFFSET_LE(__pdesc + 4, 19, 1, __val) | ||
159 | #define SET_TX_DESC_PKT_TYPE(__pdesc, __val) \ | ||
160 | SET_BITS_OFFSET_LE(__pdesc + 4, 20, 1, __val) | ||
161 | #define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ | ||
162 | SET_BITS_OFFSET_LE(__pdesc + 4, 21, 1, __val) | ||
163 | #define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ | ||
164 | SET_BITS_OFFSET_LE(__pdesc + 4, 22, 2, __val) | ||
165 | #define SET_TX_DESC_WDS(__pdesc, __val) \ | ||
166 | SET_BITS_OFFSET_LE(__pdesc + 4, 24, 1, __val) | ||
167 | #define SET_TX_DESC_HTC(__pdesc, __val) \ | ||
168 | SET_BITS_OFFSET_LE(__pdesc + 4, 25, 1, __val) | ||
169 | #define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ | ||
170 | SET_BITS_OFFSET_LE(__pdesc + 4, 26, 5, __val) | ||
171 | #define SET_TX_DESC_HWPC(__pdesc, __val) \ | ||
172 | SET_BITS_OFFSET_LE(__pdesc + 4, 27, 1, __val) | ||
173 | |||
174 | /* Dword 2 */ | ||
175 | #define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ | ||
176 | SET_BITS_OFFSET_LE(__pdesc + 8, 0, 6, __val) | ||
177 | #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ | ||
178 | SET_BITS_OFFSET_LE(__pdesc + 8, 6, 1, __val) | ||
179 | #define SET_TX_DESC_TSFL(__pdesc, __val) \ | ||
180 | SET_BITS_OFFSET_LE(__pdesc + 8, 7, 5, __val) | ||
181 | #define SET_TX_DESC_RTS_RETRY_COUNT(__pdesc, __val) \ | ||
182 | SET_BITS_OFFSET_LE(__pdesc + 8, 12, 6, __val) | ||
183 | #define SET_TX_DESC_DATA_RETRY_COUNT(__pdesc, __val) \ | ||
184 | SET_BITS_OFFSET_LE(__pdesc + 8, 18, 6, __val) | ||
185 | #define SET_TX_DESC_RSVD_MACID(__pdesc, __val) \ | ||
186 | SET_BITS_OFFSET_LE(((__pdesc) + 8), 24, 5, __val) | ||
187 | #define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \ | ||
188 | SET_BITS_OFFSET_LE(__pdesc + 8, 29, 1, __val) | ||
189 | #define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ | ||
190 | SET_BITS_OFFSET_LE(__pdesc + 8, 30, 1, __val) | ||
191 | #define SET_TX_DESC_OWN_MAC(__pdesc, __val) \ | ||
192 | SET_BITS_OFFSET_LE(__pdesc + 8, 31, 1, __val) | ||
193 | |||
194 | /* Dword 3 */ | ||
195 | #define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ | ||
196 | SET_BITS_OFFSET_LE(__pdesc + 12, 0, 8, __val) | ||
197 | #define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ | ||
198 | SET_BITS_OFFSET_LE(__pdesc + 12, 8, 8, __val) | ||
199 | #define SET_TX_DESC_SEQ(__pdesc, __val) \ | ||
200 | SET_BITS_OFFSET_LE(__pdesc + 12, 16, 12, __val) | ||
201 | #define SET_TX_DESC_FRAG(__pdesc, __val) \ | ||
202 | SET_BITS_OFFSET_LE(__pdesc + 12, 28, 4, __val) | ||
203 | |||
204 | /* Dword 4 */ | ||
205 | #define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ | ||
206 | SET_BITS_OFFSET_LE(__pdesc + 16, 0, 6, __val) | ||
207 | #define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ | ||
208 | SET_BITS_OFFSET_LE(__pdesc + 16, 6, 1, __val) | ||
209 | #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ | ||
210 | SET_BITS_OFFSET_LE(__pdesc + 16, 7, 4, __val) | ||
211 | #define SET_TX_DESC_CTS_ENABLE(__pdesc, __val) \ | ||
212 | SET_BITS_OFFSET_LE(__pdesc + 16, 11, 1, __val) | ||
213 | #define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ | ||
214 | SET_BITS_OFFSET_LE(__pdesc + 16, 12, 1, __val) | ||
215 | #define SET_TX_DESC_RA_BRSR_ID(__pdesc, __val) \ | ||
216 | SET_BITS_OFFSET_LE(__pdesc + 16, 13, 3, __val) | ||
217 | #define SET_TX_DESC_TXHT(__pdesc, __val) \ | ||
218 | SET_BITS_OFFSET_LE(__pdesc + 16, 16, 1, __val) | ||
219 | #define SET_TX_DESC_TX_SHORT(__pdesc, __val) \ | ||
220 | SET_BITS_OFFSET_LE(__pdesc + 16, 17, 1, __val) | ||
221 | #define SET_TX_DESC_TX_BANDWIDTH(__pdesc, __val) \ | ||
222 | SET_BITS_OFFSET_LE(__pdesc + 16, 18, 1, __val) | ||
223 | #define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ | ||
224 | SET_BITS_OFFSET_LE(__pdesc + 16, 19, 2, __val) | ||
225 | #define SET_TX_DESC_TX_STBC(__pdesc, __val) \ | ||
226 | SET_BITS_OFFSET_LE(__pdesc + 16, 21, 2, __val) | ||
227 | #define SET_TX_DESC_TX_REVERSE_DIRECTION(__pdesc, __val) \ | ||
228 | SET_BITS_OFFSET_LE(__pdesc + 16, 23, 1, __val) | ||
229 | #define SET_TX_DESC_RTS_HT(__pdesc, __val) \ | ||
230 | SET_BITS_OFFSET_LE(__pdesc + 16, 24, 1, __val) | ||
231 | #define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ | ||
232 | SET_BITS_OFFSET_LE(__pdesc + 16, 25, 1, __val) | ||
233 | #define SET_TX_DESC_RTS_BANDWIDTH(__pdesc, __val) \ | ||
234 | SET_BITS_OFFSET_LE(__pdesc + 16, 26, 1, __val) | ||
235 | #define SET_TX_DESC_RTS_SUB_CARRIER(__pdesc, __val) \ | ||
236 | SET_BITS_OFFSET_LE(__pdesc + 16, 27, 2, __val) | ||
237 | #define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ | ||
238 | SET_BITS_OFFSET_LE(__pdesc + 16, 29, 2, __val) | ||
239 | #define SET_TX_DESC_USER_RATE(__pdesc, __val) \ | ||
240 | SET_BITS_OFFSET_LE(__pdesc + 16, 31, 1, __val) | ||
241 | |||
242 | /* Dword 5 */ | ||
243 | #define SET_TX_DESC_PACKET_ID(__pdesc, __val) \ | ||
244 | SET_BITS_OFFSET_LE(__pdesc + 20, 0, 9, __val) | ||
245 | #define SET_TX_DESC_TX_RATE(__pdesc, __val) \ | ||
246 | SET_BITS_OFFSET_LE(__pdesc + 20, 9, 6, __val) | ||
247 | #define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ | ||
248 | SET_BITS_OFFSET_LE(__pdesc + 20, 15, 1, __val) | ||
249 | #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ | ||
250 | SET_BITS_OFFSET_LE(__pdesc + 20, 16, 5, __val) | ||
251 | #define SET_TX_DESC_TX_AGC(__pdesc, __val) \ | ||
252 | SET_BITS_OFFSET_LE(__pdesc + 20, 21, 11, __val) | ||
253 | |||
254 | /* Dword 6 */ | ||
255 | #define SET_TX_DESC_IP_CHECK_SUM(__pdesc, __val) \ | ||
256 | SET_BITS_OFFSET_LE(__pdesc + 24, 0, 16, __val) | ||
257 | #define SET_TX_DESC_TCP_CHECK_SUM(__pdesc, __val) \ | ||
258 | SET_BITS_OFFSET_LE(__pdesc + 24, 16, 16, __val) | ||
259 | |||
260 | /* Dword 7 */ | ||
261 | #define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ | ||
262 | SET_BITS_OFFSET_LE(__pdesc + 28, 0, 16, __val) | ||
263 | #define SET_TX_DESC_IP_HEADER_OFFSET(__pdesc, __val) \ | ||
264 | SET_BITS_OFFSET_LE(__pdesc + 28, 16, 8, __val) | ||
265 | #define SET_TX_DESC_TCP_ENABLE(__pdesc, __val) \ | ||
266 | SET_BITS_OFFSET_LE(__pdesc + 28, 31, 1, __val) | ||
267 | |||
268 | /* Dword 8 */ | ||
269 | #define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ | ||
270 | SET_BITS_OFFSET_LE(__pdesc + 32, 0, 32, __val) | ||
271 | #define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ | ||
272 | SHIFT_AND_MASK_LE(__pdesc + 32, 0, 32) | ||
273 | |||
274 | /* Dword 9 */ | ||
275 | #define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ | ||
276 | SET_BITS_OFFSET_LE(__pdesc + 36, 0, 32, __val) | ||
277 | |||
278 | /* Because the PCI Tx descriptors are chaied at the | ||
279 | * initialization and all the NextDescAddresses in | ||
280 | * these descriptors cannot not be cleared (,or | ||
281 | * driver/HW cannot find the next descriptor), the | ||
282 | * offset 36 (NextDescAddresses) is reserved when | ||
283 | * the desc is cleared. */ | ||
284 | #define TX_DESC_NEXT_DESC_OFFSET 36 | ||
285 | #define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ | ||
286 | do { \ | ||
287 | if (_size > TX_DESC_NEXT_DESC_OFFSET) \ | ||
288 | memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ | ||
289 | else \ | ||
290 | memset(__pdesc, 0, _size); \ | ||
291 | } while (0); | ||
292 | |||
293 | /* Rx Desc */ | ||
294 | #define RX_STATUS_DESC_SIZE 24 | ||
295 | #define RX_DRV_INFO_SIZE_UNIT 8 | ||
296 | |||
297 | /* DWORD 0 */ | ||
298 | #define SET_RX_STATUS_DESC_PKT_LEN(__pdesc, __val) \ | ||
299 | SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val) | ||
300 | #define SET_RX_STATUS_DESC_CRC32(__pdesc, __val) \ | ||
301 | SET_BITS_OFFSET_LE(__pdesc, 14, 1, __val) | ||
302 | #define SET_RX_STATUS_DESC_ICV(__pdesc, __val) \ | ||
303 | SET_BITS_OFFSET_LE(__pdesc, 15, 1, __val) | ||
304 | #define SET_RX_STATUS_DESC_DRVINFO_SIZE(__pdesc, __val) \ | ||
305 | SET_BITS_OFFSET_LE(__pdesc, 16, 4, __val) | ||
306 | #define SET_RX_STATUS_DESC_SECURITY(__pdesc, __val) \ | ||
307 | SET_BITS_OFFSET_LE(__pdesc, 20, 3, __val) | ||
308 | #define SET_RX_STATUS_DESC_QOS(__pdesc, __val) \ | ||
309 | SET_BITS_OFFSET_LE(__pdesc, 23, 1, __val) | ||
310 | #define SET_RX_STATUS_DESC_SHIFT(__pdesc, __val) \ | ||
311 | SET_BITS_OFFSET_LE(__pdesc, 24, 2, __val) | ||
312 | #define SET_RX_STATUS_DESC_PHY_STATUS(__pdesc, __val) \ | ||
313 | SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val) | ||
314 | #define SET_RX_STATUS_DESC_SWDEC(__pdesc, __val) \ | ||
315 | SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val) | ||
316 | #define SET_RX_STATUS_DESC_LAST_SEG(__pdesc, __val) \ | ||
317 | SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val) | ||
318 | #define SET_RX_STATUS_DESC_FIRST_SEG(__pdesc, __val) \ | ||
319 | SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val) | ||
320 | #define SET_RX_STATUS_DESC_EOR(__pdesc, __val) \ | ||
321 | SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val) | ||
322 | #define SET_RX_STATUS_DESC_OWN(__pdesc, __val) \ | ||
323 | SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val) | ||
324 | |||
325 | #define GET_RX_STATUS_DESC_PKT_LEN(__pdesc) \ | ||
326 | SHIFT_AND_MASK_LE(__pdesc, 0, 14) | ||
327 | #define GET_RX_STATUS_DESC_CRC32(__pdesc) \ | ||
328 | SHIFT_AND_MASK_LE(__pdesc, 14, 1) | ||
329 | #define GET_RX_STATUS_DESC_ICV(__pdesc) \ | ||
330 | SHIFT_AND_MASK_LE(__pdesc, 15, 1) | ||
331 | #define GET_RX_STATUS_DESC_DRVINFO_SIZE(__pdesc) \ | ||
332 | SHIFT_AND_MASK_LE(__pdesc, 16, 4) | ||
333 | #define GET_RX_STATUS_DESC_SECURITY(__pdesc) \ | ||
334 | SHIFT_AND_MASK_LE(__pdesc, 20, 3) | ||
335 | #define GET_RX_STATUS_DESC_QOS(__pdesc) \ | ||
336 | SHIFT_AND_MASK_LE(__pdesc, 23, 1) | ||
337 | #define GET_RX_STATUS_DESC_SHIFT(__pdesc) \ | ||
338 | SHIFT_AND_MASK_LE(__pdesc, 24, 2) | ||
339 | #define GET_RX_STATUS_DESC_PHY_STATUS(__pdesc) \ | ||
340 | SHIFT_AND_MASK_LE(__pdesc, 26, 1) | ||
341 | #define GET_RX_STATUS_DESC_SWDEC(__pdesc) \ | ||
342 | SHIFT_AND_MASK_LE(__pdesc, 27, 1) | ||
343 | #define GET_RX_STATUS_DESC_LAST_SEG(__pdesc) \ | ||
344 | SHIFT_AND_MASK_LE(__pdesc, 28, 1) | ||
345 | #define GET_RX_STATUS_DESC_FIRST_SEG(__pdesc) \ | ||
346 | SHIFT_AND_MASK_LE(__pdesc, 29, 1) | ||
347 | #define GET_RX_STATUS_DESC_EOR(__pdesc) \ | ||
348 | SHIFT_AND_MASK_LE(__pdesc, 30, 1) | ||
349 | #define GET_RX_STATUS_DESC_OWN(__pdesc) \ | ||
350 | SHIFT_AND_MASK_LE(__pdesc, 31, 1) | ||
351 | |||
352 | /* DWORD 1 */ | ||
353 | #define SET_RX_STATUS_DESC_MACID(__pdesc, __val) \ | ||
354 | SET_BITS_OFFSET_LE(__pdesc + 4, 0, 5, __val) | ||
355 | #define SET_RX_STATUS_DESC_TID(__pdesc, __val) \ | ||
356 | SET_BITS_OFFSET_LE(__pdesc + 4, 5, 4, __val) | ||
357 | #define SET_RX_STATUS_DESC_PAGGR(__pdesc, __val) \ | ||
358 | SET_BITS_OFFSET_LE(__pdesc + 4, 14, 1, __val) | ||
359 | #define SET_RX_STATUS_DESC_FAGGR(__pdesc, __val) \ | ||
360 | SET_BITS_OFFSET_LE(__pdesc + 4, 15, 1, __val) | ||
361 | #define SET_RX_STATUS_DESC_A1_FIT(__pdesc, __val) \ | ||
362 | SET_BITS_OFFSET_LE(__pdesc + 4, 16, 4, __val) | ||
363 | #define SET_RX_STATUS_DESC_A2_FIT(__pdesc, __val) \ | ||
364 | SET_BITS_OFFSET_LE(__pdesc + 4, 20, 4, __val) | ||
365 | #define SET_RX_STATUS_DESC_PAM(__pdesc, __val) \ | ||
366 | SET_BITS_OFFSET_LE(__pdesc + 4, 24, 1, __val) | ||
367 | #define SET_RX_STATUS_DESC_PWR(__pdesc, __val) \ | ||
368 | SET_BITS_OFFSET_LE(__pdesc + 4, 25, 1, __val) | ||
369 | #define SET_RX_STATUS_DESC_MOREDATA(__pdesc, __val) \ | ||
370 | SET_BITS_OFFSET_LE(__pdesc + 4, 26, 1, __val) | ||
371 | #define SET_RX_STATUS_DESC_MOREFRAG(__pdesc, __val) \ | ||
372 | SET_BITS_OFFSET_LE(__pdesc + 4, 27, 1, __val) | ||
373 | #define SET_RX_STATUS_DESC_TYPE(__pdesc, __val) \ | ||
374 | SET_BITS_OFFSET_LE(__pdesc + 4, 28, 2, __val) | ||
375 | #define SET_RX_STATUS_DESC_MC(__pdesc, __val) \ | ||
376 | SET_BITS_OFFSET_LE(__pdesc + 4, 30, 1, __val) | ||
377 | #define SET_RX_STATUS_DESC_BC(__pdesc, __val) \ | ||
378 | SET_BITS_OFFSET_LE(__pdesc + 4, 31, 1, __val) | ||
379 | |||
380 | #define GET_RX_STATUS_DEC_MACID(__pdesc) \ | ||
381 | SHIFT_AND_MASK_LE(__pdesc + 4, 0, 5) | ||
382 | #define GET_RX_STATUS_DESC_TID(__pdesc) \ | ||
383 | SHIFT_AND_MASK_LE(__pdesc + 4, 5, 4) | ||
384 | #define GET_RX_STATUS_DESC_PAGGR(__pdesc) \ | ||
385 | SHIFT_AND_MASK_LE(__pdesc + 4, 14, 1) | ||
386 | #define GET_RX_STATUS_DESC_FAGGR(__pdesc) \ | ||
387 | SHIFT_AND_MASK_LE(__pdesc + 4, 15, 1) | ||
388 | #define GET_RX_STATUS_DESC_A1_FIT(__pdesc) \ | ||
389 | SHIFT_AND_MASK_LE(__pdesc + 4, 16, 4) | ||
390 | #define GET_RX_STATUS_DESC_A2_FIT(__pdesc) \ | ||
391 | SHIFT_AND_MASK_LE(__pdesc + 4, 20, 4) | ||
392 | #define GET_RX_STATUS_DESC_PAM(__pdesc) \ | ||
393 | SHIFT_AND_MASK_LE(__pdesc + 4, 24, 1) | ||
394 | #define GET_RX_STATUS_DESC_PWR(__pdesc) \ | ||
395 | SHIFT_AND_MASK_LE(__pdesc + 4, 25, 1) | ||
396 | #define GET_RX_STATUS_DESC_MORE_DATA(__pdesc) \ | ||
397 | SHIFT_AND_MASK_LE(__pdesc + 4, 26, 1) | ||
398 | #define GET_RX_STATUS_DESC_MORE_FRAG(__pdesc) \ | ||
399 | SHIFT_AND_MASK_LE(__pdesc + 4, 27, 1) | ||
400 | #define GET_RX_STATUS_DESC_TYPE(__pdesc) \ | ||
401 | SHIFT_AND_MASK_LE(__pdesc + 4, 28, 2) | ||
402 | #define GET_RX_STATUS_DESC_MC(__pdesc) \ | ||
403 | SHIFT_AND_MASK_LE(__pdesc + 4, 30, 1) | ||
404 | #define GET_RX_STATUS_DESC_BC(__pdesc) \ | ||
405 | SHIFT_AND_MASK_LE(__pdesc + 4, 31, 1) | ||
406 | |||
407 | /* DWORD 2 */ | ||
408 | #define SET_RX_STATUS_DESC_SEQ(__pdesc, __val) \ | ||
409 | SET_BITS_OFFSET_LE(__pdesc + 8, 0, 12, __val) | ||
410 | #define SET_RX_STATUS_DESC_FRAG(__pdesc, __val) \ | ||
411 | SET_BITS_OFFSET_LE(__pdesc + 8, 12, 4, __val) | ||
412 | #define SET_RX_STATUS_DESC_NEXT_PKTLEN(__pdesc, __val) \ | ||
413 | SET_BITS_OFFSET_LE(__pdesc + 8, 16, 8, __val) | ||
414 | #define SET_RX_STATUS_DESC_NEXT_IND(__pdesc, __val) \ | ||
415 | SET_BITS_OFFSET_LE(__pdesc + 8, 30, 1, __val) | ||
416 | |||
417 | #define GET_RX_STATUS_DESC_SEQ(__pdesc) \ | ||
418 | SHIFT_AND_MASK_LE(__pdesc + 8, 0, 12) | ||
419 | #define GET_RX_STATUS_DESC_FRAG(__pdesc) \ | ||
420 | SHIFT_AND_MASK_LE(__pdesc + 8, 12, 4) | ||
421 | #define GET_RX_STATUS_DESC_NEXT_PKTLEN(__pdesc) \ | ||
422 | SHIFT_AND_MASK_LE(__pdesc + 8, 16, 8) | ||
423 | #define GET_RX_STATUS_DESC_NEXT_IND(__pdesc) \ | ||
424 | SHIFT_AND_MASK_LE(__pdesc + 8, 30, 1) | ||
425 | |||
426 | /* DWORD 3 */ | ||
427 | #define SET_RX_STATUS_DESC_RX_MCS(__pdesc, __val) \ | ||
428 | SET_BITS_OFFSET_LE(__pdesc + 12, 0, 6, __val) | ||
429 | #define SET_RX_STATUS_DESC_RX_HT(__pdesc, __val) \ | ||
430 | SET_BITS_OFFSET_LE(__pdesc + 12, 6, 1, __val) | ||
431 | #define SET_RX_STATUS_DESC_AMSDU(__pdesc, __val) \ | ||
432 | SET_BITS_OFFSET_LE(__pdesc + 12, 7, 1, __val) | ||
433 | #define SET_RX_STATUS_DESC_SPLCP(__pdesc, __val) \ | ||
434 | SET_BITS_OFFSET_LE(__pdesc + 12, 8, 1, __val) | ||
435 | #define SET_RX_STATUS_DESC_BW(__pdesc, __val) \ | ||
436 | SET_BITS_OFFSET_LE(__pdesc + 12, 9, 1, __val) | ||
437 | #define SET_RX_STATUS_DESC_HTC(__pdesc, __val) \ | ||
438 | SET_BITS_OFFSET_LE(__pdesc + 12, 10, 1, __val) | ||
439 | #define SET_RX_STATUS_DESC_TCP_CHK_RPT(__pdesc, __val) \ | ||
440 | SET_BITS_OFFSET_LE(__pdesc + 12, 11, 1, __val) | ||
441 | #define SET_RX_STATUS_DESC_IP_CHK_RPT(__pdesc, __val) \ | ||
442 | SET_BITS_OFFSET_LE(__pdesc + 12, 12, 1, __val) | ||
443 | #define SET_RX_STATUS_DESC_TCP_CHK_VALID(__pdesc, __val) \ | ||
444 | SET_BITS_OFFSET_LE(__pdesc + 12, 13, 1, __val) | ||
445 | #define SET_RX_STATUS_DESC_HWPC_ERR(__pdesc, __val) \ | ||
446 | SET_BITS_OFFSET_LE(__pdesc + 12, 14, 1, __val) | ||
447 | #define SET_RX_STATUS_DESC_HWPC_IND(__pdesc, __val) \ | ||
448 | SET_BITS_OFFSET_LE(__pdesc + 12, 15, 1, __val) | ||
449 | #define SET_RX_STATUS_DESC_IV0(__pdesc, __val) \ | ||
450 | SET_BITS_OFFSET_LE(__pdesc + 12, 16, 16, __val) | ||
451 | |||
452 | #define GET_RX_STATUS_DESC_RX_MCS(__pdesc) \ | ||
453 | SHIFT_AND_MASK_LE(__pdesc + 12, 0, 6) | ||
454 | #define GET_RX_STATUS_DESC_RX_HT(__pdesc) \ | ||
455 | SHIFT_AND_MASK_LE(__pdesc + 12, 6, 1) | ||
456 | #define GET_RX_STATUS_DESC_AMSDU(__pdesc) \ | ||
457 | SHIFT_AND_MASK_LE(__pdesc + 12, 7, 1) | ||
458 | #define GET_RX_STATUS_DESC_SPLCP(__pdesc) \ | ||
459 | SHIFT_AND_MASK_LE(__pdesc + 12, 8, 1) | ||
460 | #define GET_RX_STATUS_DESC_BW(__pdesc) \ | ||
461 | SHIFT_AND_MASK_LE(__pdesc + 12, 9, 1) | ||
462 | #define GET_RX_STATUS_DESC_HTC(__pdesc) \ | ||
463 | SHIFT_AND_MASK_LE(__pdesc + 12, 10, 1) | ||
464 | #define GET_RX_STATUS_DESC_TCP_CHK_RPT(__pdesc) \ | ||
465 | SHIFT_AND_MASK_LE(__pdesc + 12, 11, 1) | ||
466 | #define GET_RX_STATUS_DESC_IP_CHK_RPT(__pdesc) \ | ||
467 | SHIFT_AND_MASK_LE(__pdesc + 12, 12, 1) | ||
468 | #define GET_RX_STATUS_DESC_TCP_CHK_VALID(__pdesc) \ | ||
469 | SHIFT_AND_MASK_LE(__pdesc + 12, 13, 1) | ||
470 | #define GET_RX_STATUS_DESC_HWPC_ERR(__pdesc) \ | ||
471 | SHIFT_AND_MASK_LE(__pdesc + 12, 14, 1) | ||
472 | #define GET_RX_STATUS_DESC_HWPC_IND(__pdesc) \ | ||
473 | SHIFT_AND_MASK_LE(__pdesc + 12, 15, 1) | ||
474 | #define GET_RX_STATUS_DESC_IV0(__pdesc) \ | ||
475 | SHIFT_AND_MASK_LE(__pdesc + 12, 16, 16) | ||
476 | |||
477 | /* DWORD 4 */ | ||
478 | #define SET_RX_STATUS_DESC_IV1(__pdesc, __val) \ | ||
479 | SET_BITS_OFFSET_LE(__pdesc + 16, 0, 32, __val) | ||
480 | #define GET_RX_STATUS_DESC_IV1(__pdesc) \ | ||
481 | SHIFT_AND_MASK_LE(__pdesc + 16, 0, 32) | ||
482 | |||
483 | /* DWORD 5 */ | ||
484 | #define SET_RX_STATUS_DESC_TSFL(__pdesc, __val) \ | ||
485 | SET_BITS_OFFSET_LE(__pdesc + 20, 0, 32, __val) | ||
486 | #define GET_RX_STATUS_DESC_TSFL(__pdesc) \ | ||
487 | SHIFT_AND_MASK_LE(__pdesc + 20, 0, 32) | ||
488 | |||
489 | /* DWORD 6 */ | ||
490 | #define SET_RX_STATUS__DESC_BUFF_ADDR(__pdesc, __val) \ | ||
491 | SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val) | ||
492 | |||
493 | #define RX_HAL_IS_CCK_RATE(_pdesc)\ | ||
494 | (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE1M || \ | ||
495 | GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE2M || \ | ||
496 | GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE5_5M ||\ | ||
497 | GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE11M) | ||
498 | |||
499 | enum rf_optype { | ||
500 | RF_OP_BY_SW_3WIRE = 0, | ||
501 | RF_OP_BY_FW, | ||
502 | RF_OP_MAX | ||
503 | }; | ||
504 | |||
505 | enum ic_inferiority { | ||
506 | IC_INFERIORITY_A = 0, | ||
507 | IC_INFERIORITY_B = 1, | ||
508 | }; | ||
509 | |||
510 | enum fwcmd_iotype { | ||
511 | /* For DIG DM */ | ||
512 | FW_CMD_DIG_ENABLE = 0, | ||
513 | FW_CMD_DIG_DISABLE = 1, | ||
514 | FW_CMD_DIG_HALT = 2, | ||
515 | FW_CMD_DIG_RESUME = 3, | ||
516 | /* For High Power DM */ | ||
517 | FW_CMD_HIGH_PWR_ENABLE = 4, | ||
518 | FW_CMD_HIGH_PWR_DISABLE = 5, | ||
519 | /* For Rate adaptive DM */ | ||
520 | FW_CMD_RA_RESET = 6, | ||
521 | FW_CMD_RA_ACTIVE = 7, | ||
522 | FW_CMD_RA_REFRESH_N = 8, | ||
523 | FW_CMD_RA_REFRESH_BG = 9, | ||
524 | FW_CMD_RA_INIT = 10, | ||
525 | /* For FW supported IQK */ | ||
526 | FW_CMD_IQK_INIT = 11, | ||
527 | /* Tx power tracking switch, | ||
528 | * MP driver only */ | ||
529 | FW_CMD_TXPWR_TRACK_ENABLE = 12, | ||
530 | /* Tx power tracking switch, | ||
531 | * MP driver only */ | ||
532 | FW_CMD_TXPWR_TRACK_DISABLE = 13, | ||
533 | /* Tx power tracking with thermal | ||
534 | * indication, for Normal driver */ | ||
535 | FW_CMD_TXPWR_TRACK_THERMAL = 14, | ||
536 | FW_CMD_PAUSE_DM_BY_SCAN = 15, | ||
537 | FW_CMD_RESUME_DM_BY_SCAN = 16, | ||
538 | FW_CMD_RA_REFRESH_N_COMB = 17, | ||
539 | FW_CMD_RA_REFRESH_BG_COMB = 18, | ||
540 | FW_CMD_ANTENNA_SW_ENABLE = 19, | ||
541 | FW_CMD_ANTENNA_SW_DISABLE = 20, | ||
542 | /* Tx Status report for CCX from FW */ | ||
543 | FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21, | ||
544 | /* Indifate firmware that driver | ||
545 | * enters LPS, For PS-Poll issue */ | ||
546 | FW_CMD_LPS_ENTER = 22, | ||
547 | /* Indicate firmware that driver | ||
548 | * leave LPS*/ | ||
549 | FW_CMD_LPS_LEAVE = 23, | ||
550 | /* Set DIG mode to signal strength */ | ||
551 | FW_CMD_DIG_MODE_SS = 24, | ||
552 | /* Set DIG mode to false alarm. */ | ||
553 | FW_CMD_DIG_MODE_FA = 25, | ||
554 | FW_CMD_ADD_A2_ENTRY = 26, | ||
555 | FW_CMD_CTRL_DM_BY_DRIVER = 27, | ||
556 | FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28, | ||
557 | FW_CMD_PAPE_CONTROL = 29, | ||
558 | FW_CMD_IQK_ENABLE = 30, | ||
559 | }; | ||
560 | |||
561 | /* | ||
562 | * Driver info contain PHY status | ||
563 | * and other variabel size info | ||
564 | * PHY Status content as below | ||
565 | */ | ||
566 | struct rx_fwinfo { | ||
567 | /* DWORD 0 */ | ||
568 | u8 gain_trsw[4]; | ||
569 | /* DWORD 1 */ | ||
570 | u8 pwdb_all; | ||
571 | u8 cfosho[4]; | ||
572 | /* DWORD 2 */ | ||
573 | u8 cfotail[4]; | ||
574 | /* DWORD 3 */ | ||
575 | s8 rxevm[2]; | ||
576 | s8 rxsnr[4]; | ||
577 | /* DWORD 4 */ | ||
578 | u8 pdsnr[2]; | ||
579 | /* DWORD 5 */ | ||
580 | u8 csi_current[2]; | ||
581 | u8 csi_target[2]; | ||
582 | /* DWORD 6 */ | ||
583 | u8 sigevm; | ||
584 | u8 max_ex_pwr; | ||
585 | u8 ex_intf_flag:1; | ||
586 | u8 sgi_en:1; | ||
587 | u8 rxsc:2; | ||
588 | u8 reserve:4; | ||
589 | }; | ||
590 | |||
591 | struct phy_sts_cck_8192s_t { | ||
592 | u8 adc_pwdb_x[4]; | ||
593 | u8 sq_rpt; | ||
594 | u8 cck_agc_rpt; | ||
595 | }; | ||
596 | |||
597 | #endif | ||
598 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c new file mode 100644 index 000000000000..da86db86fa4a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c | |||
@@ -0,0 +1,733 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../base.h" | ||
32 | #include "reg.h" | ||
33 | #include "def.h" | ||
34 | #include "phy.h" | ||
35 | #include "dm.h" | ||
36 | #include "fw.h" | ||
37 | |||
38 | struct dig_t digtable; | ||
39 | static const u32 edca_setting_dl[PEER_MAX] = { | ||
40 | 0xa44f, /* 0 UNKNOWN */ | ||
41 | 0x5ea44f, /* 1 REALTEK_90 */ | ||
42 | 0x5ea44f, /* 2 REALTEK_92SE */ | ||
43 | 0xa630, /* 3 BROAD */ | ||
44 | 0xa44f, /* 4 RAL */ | ||
45 | 0xa630, /* 5 ATH */ | ||
46 | 0xa630, /* 6 CISCO */ | ||
47 | 0xa42b, /* 7 MARV */ | ||
48 | }; | ||
49 | |||
50 | static const u32 edca_setting_dl_gmode[PEER_MAX] = { | ||
51 | 0x4322, /* 0 UNKNOWN */ | ||
52 | 0xa44f, /* 1 REALTEK_90 */ | ||
53 | 0x5ea44f, /* 2 REALTEK_92SE */ | ||
54 | 0xa42b, /* 3 BROAD */ | ||
55 | 0x5e4322, /* 4 RAL */ | ||
56 | 0x4322, /* 5 ATH */ | ||
57 | 0xa430, /* 6 CISCO */ | ||
58 | 0x5ea44f, /* 7 MARV */ | ||
59 | }; | ||
60 | |||
61 | static const u32 edca_setting_ul[PEER_MAX] = { | ||
62 | 0x5e4322, /* 0 UNKNOWN */ | ||
63 | 0xa44f, /* 1 REALTEK_90 */ | ||
64 | 0x5ea44f, /* 2 REALTEK_92SE */ | ||
65 | 0x5ea322, /* 3 BROAD */ | ||
66 | 0x5ea422, /* 4 RAL */ | ||
67 | 0x5ea322, /* 5 ATH */ | ||
68 | 0x3ea44f, /* 6 CISCO */ | ||
69 | 0x5ea44f, /* 7 MARV */ | ||
70 | }; | ||
71 | |||
72 | static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw) | ||
73 | { | ||
74 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
75 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
76 | |||
77 | static u64 last_txok_cnt; | ||
78 | static u64 last_rxok_cnt; | ||
79 | u64 cur_txok_cnt = 0; | ||
80 | u64 cur_rxok_cnt = 0; | ||
81 | |||
82 | u32 edca_be_ul = edca_setting_ul[mac->vendor]; | ||
83 | u32 edca_be_dl = edca_setting_dl[mac->vendor]; | ||
84 | u32 edca_gmode = edca_setting_dl_gmode[mac->vendor]; | ||
85 | |||
86 | if (mac->link_state != MAC80211_LINKED) { | ||
87 | rtlpriv->dm.current_turbo_edca = false; | ||
88 | goto dm_checkedcaturbo_exit; | ||
89 | } | ||
90 | |||
91 | if ((!rtlpriv->dm.is_any_nonbepkts) && | ||
92 | (!rtlpriv->dm.disable_framebursting)) { | ||
93 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; | ||
94 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; | ||
95 | |||
96 | if (rtlpriv->phy.rf_type == RF_1T2R) { | ||
97 | if (cur_txok_cnt > 4 * cur_rxok_cnt) { | ||
98 | /* Uplink TP is present. */ | ||
99 | if (rtlpriv->dm.is_cur_rdlstate || | ||
100 | !rtlpriv->dm.current_turbo_edca) { | ||
101 | rtl_write_dword(rtlpriv, EDCAPARA_BE, | ||
102 | edca_be_ul); | ||
103 | rtlpriv->dm.is_cur_rdlstate = false; | ||
104 | } | ||
105 | } else {/* Balance TP is present. */ | ||
106 | if (!rtlpriv->dm.is_cur_rdlstate || | ||
107 | !rtlpriv->dm.current_turbo_edca) { | ||
108 | if (mac->mode == WIRELESS_MODE_G || | ||
109 | mac->mode == WIRELESS_MODE_B) | ||
110 | rtl_write_dword(rtlpriv, | ||
111 | EDCAPARA_BE, | ||
112 | edca_gmode); | ||
113 | else | ||
114 | rtl_write_dword(rtlpriv, | ||
115 | EDCAPARA_BE, | ||
116 | edca_be_dl); | ||
117 | rtlpriv->dm.is_cur_rdlstate = true; | ||
118 | } | ||
119 | } | ||
120 | rtlpriv->dm.current_turbo_edca = true; | ||
121 | } else { | ||
122 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { | ||
123 | if (!rtlpriv->dm.is_cur_rdlstate || | ||
124 | !rtlpriv->dm.current_turbo_edca) { | ||
125 | if (mac->mode == WIRELESS_MODE_G || | ||
126 | mac->mode == WIRELESS_MODE_B) | ||
127 | rtl_write_dword(rtlpriv, | ||
128 | EDCAPARA_BE, | ||
129 | edca_gmode); | ||
130 | else | ||
131 | rtl_write_dword(rtlpriv, | ||
132 | EDCAPARA_BE, | ||
133 | edca_be_dl); | ||
134 | rtlpriv->dm.is_cur_rdlstate = true; | ||
135 | } | ||
136 | } else { | ||
137 | if (rtlpriv->dm.is_cur_rdlstate || | ||
138 | !rtlpriv->dm.current_turbo_edca) { | ||
139 | rtl_write_dword(rtlpriv, EDCAPARA_BE, | ||
140 | edca_be_ul); | ||
141 | rtlpriv->dm.is_cur_rdlstate = false; | ||
142 | } | ||
143 | } | ||
144 | rtlpriv->dm.current_turbo_edca = true; | ||
145 | } | ||
146 | } else { | ||
147 | if (rtlpriv->dm.current_turbo_edca) { | ||
148 | u8 tmp = AC0_BE; | ||
149 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, | ||
150 | (u8 *)(&tmp)); | ||
151 | rtlpriv->dm.current_turbo_edca = false; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | dm_checkedcaturbo_exit: | ||
156 | rtlpriv->dm.is_any_nonbepkts = false; | ||
157 | last_txok_cnt = rtlpriv->stats.txbytesunicast; | ||
158 | last_rxok_cnt = rtlpriv->stats.rxbytesunicast; | ||
159 | } | ||
160 | |||
161 | static void _rtl92s_dm_txpowertracking_callback_thermalmeter( | ||
162 | struct ieee80211_hw *hw) | ||
163 | { | ||
164 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
165 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
166 | u8 thermalvalue = 0; | ||
167 | |||
168 | rtlpriv->dm.txpower_trackinginit = true; | ||
169 | |||
170 | thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); | ||
171 | |||
172 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
173 | ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " | ||
174 | "eeprom_thermalmeter 0x%x\n", thermalvalue, | ||
175 | rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter)); | ||
176 | |||
177 | if (thermalvalue) { | ||
178 | rtlpriv->dm.thermalvalue = thermalvalue; | ||
179 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL); | ||
180 | } | ||
181 | |||
182 | rtlpriv->dm.txpowercount = 0; | ||
183 | } | ||
184 | |||
185 | static void _rtl92s_dm_check_txpowertracking_thermalmeter( | ||
186 | struct ieee80211_hw *hw) | ||
187 | { | ||
188 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
189 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
190 | static u8 tm_trigger; | ||
191 | u8 tx_power_checkcnt = 5; | ||
192 | |||
193 | /* 2T2R TP issue */ | ||
194 | if (rtlphy->rf_type == RF_2T2R) | ||
195 | return; | ||
196 | |||
197 | if (!rtlpriv->dm.txpower_tracking) | ||
198 | return; | ||
199 | |||
200 | if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) { | ||
201 | rtlpriv->dm.txpowercount++; | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | if (!tm_trigger) { | ||
206 | rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, | ||
207 | RFREG_OFFSET_MASK, 0x60); | ||
208 | tm_trigger = 1; | ||
209 | } else { | ||
210 | _rtl92s_dm_txpowertracking_callback_thermalmeter(hw); | ||
211 | tm_trigger = 0; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) | ||
216 | { | ||
217 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
218 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
219 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
220 | struct rate_adaptive *ra = &(rtlpriv->ra); | ||
221 | |||
222 | u32 low_rssi_thresh = 0; | ||
223 | u32 middle_rssi_thresh = 0; | ||
224 | u32 high_rssi_thresh = 0; | ||
225 | u8 rssi_level; | ||
226 | struct ieee80211_sta *sta = NULL; | ||
227 | |||
228 | if (is_hal_stop(rtlhal)) | ||
229 | return; | ||
230 | |||
231 | if (!rtlpriv->dm.useramask) | ||
232 | return; | ||
233 | |||
234 | if (!rtlpriv->dm.inform_fw_driverctrldm) { | ||
235 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER); | ||
236 | rtlpriv->dm.inform_fw_driverctrldm = true; | ||
237 | } | ||
238 | |||
239 | rcu_read_lock(); | ||
240 | if (mac->opmode == NL80211_IFTYPE_STATION) | ||
241 | sta = get_sta(hw, mac->vif, mac->bssid); | ||
242 | if ((mac->link_state == MAC80211_LINKED) && | ||
243 | (mac->opmode == NL80211_IFTYPE_STATION)) { | ||
244 | switch (ra->pre_ratr_state) { | ||
245 | case DM_RATR_STA_HIGH: | ||
246 | high_rssi_thresh = 40; | ||
247 | middle_rssi_thresh = 30; | ||
248 | low_rssi_thresh = 20; | ||
249 | break; | ||
250 | case DM_RATR_STA_MIDDLE: | ||
251 | high_rssi_thresh = 44; | ||
252 | middle_rssi_thresh = 30; | ||
253 | low_rssi_thresh = 20; | ||
254 | break; | ||
255 | case DM_RATR_STA_LOW: | ||
256 | high_rssi_thresh = 44; | ||
257 | middle_rssi_thresh = 34; | ||
258 | low_rssi_thresh = 20; | ||
259 | break; | ||
260 | case DM_RATR_STA_ULTRALOW: | ||
261 | high_rssi_thresh = 44; | ||
262 | middle_rssi_thresh = 34; | ||
263 | low_rssi_thresh = 24; | ||
264 | break; | ||
265 | default: | ||
266 | high_rssi_thresh = 44; | ||
267 | middle_rssi_thresh = 34; | ||
268 | low_rssi_thresh = 24; | ||
269 | break; | ||
270 | } | ||
271 | |||
272 | if (rtlpriv->dm.undecorated_smoothed_pwdb > | ||
273 | (long)high_rssi_thresh) { | ||
274 | ra->ratr_state = DM_RATR_STA_HIGH; | ||
275 | rssi_level = 1; | ||
276 | } else if (rtlpriv->dm.undecorated_smoothed_pwdb > | ||
277 | (long)middle_rssi_thresh) { | ||
278 | ra->ratr_state = DM_RATR_STA_LOW; | ||
279 | rssi_level = 3; | ||
280 | } else if (rtlpriv->dm.undecorated_smoothed_pwdb > | ||
281 | (long)low_rssi_thresh) { | ||
282 | ra->ratr_state = DM_RATR_STA_LOW; | ||
283 | rssi_level = 5; | ||
284 | } else { | ||
285 | ra->ratr_state = DM_RATR_STA_ULTRALOW; | ||
286 | rssi_level = 6; | ||
287 | } | ||
288 | |||
289 | if (ra->pre_ratr_state != ra->ratr_state) { | ||
290 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld " | ||
291 | "RSSI_LEVEL = %d PreState = %d, CurState = %d\n", | ||
292 | rtlpriv->dm.undecorated_smoothed_pwdb, | ||
293 | ra->ratr_state, | ||
294 | ra->pre_ratr_state, ra->ratr_state)); | ||
295 | |||
296 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, | ||
297 | ra->ratr_state); | ||
298 | ra->pre_ratr_state = ra->ratr_state; | ||
299 | } | ||
300 | } | ||
301 | rcu_read_unlock(); | ||
302 | } | ||
303 | |||
304 | static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw) | ||
305 | { | ||
306 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
307 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
308 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
309 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
310 | bool current_mrc; | ||
311 | bool enable_mrc = true; | ||
312 | long tmpentry_maxpwdb = 0; | ||
313 | u8 rssi_a = 0; | ||
314 | u8 rssi_b = 0; | ||
315 | |||
316 | if (is_hal_stop(rtlhal)) | ||
317 | return; | ||
318 | |||
319 | if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R)) | ||
320 | return; | ||
321 | |||
322 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(¤t_mrc)); | ||
323 | |||
324 | if (mac->link_state >= MAC80211_LINKED) { | ||
325 | if (rtlpriv->dm.undecorated_smoothed_pwdb > tmpentry_maxpwdb) { | ||
326 | rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A]; | ||
327 | rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B]; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | /* MRC settings would NOT affect TP on Wireless B mode. */ | ||
332 | if (mac->mode != WIRELESS_MODE_B) { | ||
333 | if ((rssi_a == 0) && (rssi_b == 0)) { | ||
334 | enable_mrc = true; | ||
335 | } else if (rssi_b > 30) { | ||
336 | /* Turn on B-Path */ | ||
337 | enable_mrc = true; | ||
338 | } else if (rssi_b < 5) { | ||
339 | /* Turn off B-path */ | ||
340 | enable_mrc = false; | ||
341 | /* Take care of RSSI differentiation. */ | ||
342 | } else if (rssi_a > 15 && (rssi_a >= rssi_b)) { | ||
343 | if ((rssi_a - rssi_b) > 15) | ||
344 | /* Turn off B-path */ | ||
345 | enable_mrc = false; | ||
346 | else if ((rssi_a - rssi_b) < 10) | ||
347 | /* Turn on B-Path */ | ||
348 | enable_mrc = true; | ||
349 | else | ||
350 | enable_mrc = current_mrc; | ||
351 | } else { | ||
352 | /* Turn on B-Path */ | ||
353 | enable_mrc = true; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | /* Update MRC settings if needed. */ | ||
358 | if (enable_mrc != current_mrc) | ||
359 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, | ||
360 | (u8 *)&enable_mrc); | ||
361 | |||
362 | } | ||
363 | |||
364 | void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw) | ||
365 | { | ||
366 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
367 | |||
368 | rtlpriv->dm.current_turbo_edca = false; | ||
369 | rtlpriv->dm.is_any_nonbepkts = false; | ||
370 | rtlpriv->dm.is_cur_rdlstate = false; | ||
371 | } | ||
372 | |||
373 | static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) | ||
374 | { | ||
375 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
376 | struct rate_adaptive *ra = &(rtlpriv->ra); | ||
377 | |||
378 | ra->ratr_state = DM_RATR_STA_MAX; | ||
379 | ra->pre_ratr_state = DM_RATR_STA_MAX; | ||
380 | |||
381 | if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) | ||
382 | rtlpriv->dm.useramask = true; | ||
383 | else | ||
384 | rtlpriv->dm.useramask = false; | ||
385 | |||
386 | rtlpriv->dm.useramask = false; | ||
387 | rtlpriv->dm.inform_fw_driverctrldm = false; | ||
388 | } | ||
389 | |||
390 | static void _rtl92s_dm_init_txpowertracking_thermalmeter( | ||
391 | struct ieee80211_hw *hw) | ||
392 | { | ||
393 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
394 | |||
395 | rtlpriv->dm.txpower_tracking = true; | ||
396 | rtlpriv->dm.txpowercount = 0; | ||
397 | rtlpriv->dm.txpower_trackinginit = false; | ||
398 | } | ||
399 | |||
400 | static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) | ||
401 | { | ||
402 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
403 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); | ||
404 | u32 ret_value; | ||
405 | |||
406 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); | ||
407 | falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); | ||
408 | |||
409 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); | ||
410 | falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); | ||
411 | falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); | ||
412 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); | ||
413 | falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); | ||
414 | |||
415 | falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + | ||
416 | falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail + | ||
417 | falsealm_cnt->cnt_mcs_fail; | ||
418 | |||
419 | /* read CCK false alarm */ | ||
420 | ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD); | ||
421 | falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff); | ||
422 | falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + | ||
423 | falsealm_cnt->cnt_cck_fail; | ||
424 | } | ||
425 | |||
426 | static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw) | ||
427 | { | ||
428 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
429 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); | ||
430 | |||
431 | if (falsealm_cnt->cnt_all > digtable.fa_highthresh) { | ||
432 | if ((digtable.backoff_val - 6) < | ||
433 | digtable.backoffval_range_min) | ||
434 | digtable.backoff_val = digtable.backoffval_range_min; | ||
435 | else | ||
436 | digtable.backoff_val -= 6; | ||
437 | } else if (falsealm_cnt->cnt_all < digtable.fa_lowthresh) { | ||
438 | if ((digtable.backoff_val + 6) > | ||
439 | digtable.backoffval_range_max) | ||
440 | digtable.backoff_val = | ||
441 | digtable.backoffval_range_max; | ||
442 | else | ||
443 | digtable.backoff_val += 6; | ||
444 | } | ||
445 | } | ||
446 | |||
447 | static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) | ||
448 | { | ||
449 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
450 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); | ||
451 | static u8 initialized, force_write; | ||
452 | u8 initial_gain = 0; | ||
453 | |||
454 | if ((digtable.pre_sta_connectstate == digtable.cur_sta_connectstate) || | ||
455 | (digtable.cur_sta_connectstate == DIG_STA_BEFORE_CONNECT)) { | ||
456 | if (digtable.cur_sta_connectstate == DIG_STA_BEFORE_CONNECT) { | ||
457 | if (rtlpriv->psc.rfpwr_state != ERFON) | ||
458 | return; | ||
459 | |||
460 | if (digtable.backoff_enable_flag == true) | ||
461 | rtl92s_backoff_enable_flag(hw); | ||
462 | else | ||
463 | digtable.backoff_val = DM_DIG_BACKOFF; | ||
464 | |||
465 | if ((digtable.rssi_val + 10 - digtable.backoff_val) > | ||
466 | digtable.rx_gain_range_max) | ||
467 | digtable.cur_igvalue = | ||
468 | digtable.rx_gain_range_max; | ||
469 | else if ((digtable.rssi_val + 10 - digtable.backoff_val) | ||
470 | < digtable.rx_gain_range_min) | ||
471 | digtable.cur_igvalue = | ||
472 | digtable.rx_gain_range_min; | ||
473 | else | ||
474 | digtable.cur_igvalue = digtable.rssi_val + 10 - | ||
475 | digtable.backoff_val; | ||
476 | |||
477 | if (falsealm_cnt->cnt_all > 10000) | ||
478 | digtable.cur_igvalue = | ||
479 | (digtable.cur_igvalue > 0x33) ? | ||
480 | digtable.cur_igvalue : 0x33; | ||
481 | |||
482 | if (falsealm_cnt->cnt_all > 16000) | ||
483 | digtable.cur_igvalue = | ||
484 | digtable.rx_gain_range_max; | ||
485 | /* connected -> connected or disconnected -> disconnected */ | ||
486 | } else { | ||
487 | /* Firmware control DIG, do nothing in driver dm */ | ||
488 | return; | ||
489 | } | ||
490 | /* disconnected -> connected or connected -> | ||
491 | * disconnected or beforeconnect->(dis)connected */ | ||
492 | } else { | ||
493 | /* Enable FW DIG */ | ||
494 | digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
495 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE); | ||
496 | |||
497 | digtable.backoff_val = DM_DIG_BACKOFF; | ||
498 | digtable.cur_igvalue = rtlpriv->phy.default_initialgain[0]; | ||
499 | digtable.pre_igvalue = 0; | ||
500 | return; | ||
501 | } | ||
502 | |||
503 | /* Forced writing to prevent from fw-dig overwriting. */ | ||
504 | if (digtable.pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, | ||
505 | MASKBYTE0)) | ||
506 | force_write = 1; | ||
507 | |||
508 | if ((digtable.pre_igvalue != digtable.cur_igvalue) || | ||
509 | !initialized || force_write) { | ||
510 | /* Disable FW DIG */ | ||
511 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE); | ||
512 | |||
513 | initial_gain = (u8)digtable.cur_igvalue; | ||
514 | |||
515 | /* Set initial gain. */ | ||
516 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain); | ||
517 | rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain); | ||
518 | digtable.pre_igvalue = digtable.cur_igvalue; | ||
519 | initialized = 1; | ||
520 | force_write = 0; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) | ||
525 | { | ||
526 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
527 | |||
528 | if (rtlpriv->mac80211.act_scanning) | ||
529 | return; | ||
530 | |||
531 | /* Decide the current status and if modify initial gain or not */ | ||
532 | if (rtlpriv->mac80211.link_state >= MAC80211_LINKED || | ||
533 | rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) | ||
534 | digtable.cur_sta_connectstate = DIG_STA_CONNECT; | ||
535 | else | ||
536 | digtable.cur_sta_connectstate = DIG_STA_DISCONNECT; | ||
537 | |||
538 | digtable.rssi_val = rtlpriv->dm.undecorated_smoothed_pwdb; | ||
539 | |||
540 | /* Change dig mode to rssi */ | ||
541 | if (digtable.cur_sta_connectstate != DIG_STA_DISCONNECT) { | ||
542 | if (digtable.dig_twoport_algorithm == | ||
543 | DIG_TWO_PORT_ALGO_FALSE_ALARM) { | ||
544 | digtable.dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; | ||
545 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS); | ||
546 | } | ||
547 | } | ||
548 | |||
549 | _rtl92s_dm_false_alarm_counter_statistics(hw); | ||
550 | _rtl92s_dm_initial_gain_sta_beforeconnect(hw); | ||
551 | |||
552 | digtable.pre_sta_connectstate = digtable.cur_sta_connectstate; | ||
553 | } | ||
554 | |||
555 | static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw) | ||
556 | { | ||
557 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
558 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
559 | |||
560 | /* 2T2R TP issue */ | ||
561 | if (rtlphy->rf_type == RF_2T2R) | ||
562 | return; | ||
563 | |||
564 | if (!rtlpriv->dm.dm_initialgain_enable) | ||
565 | return; | ||
566 | |||
567 | if (digtable.dig_enable_flag == false) | ||
568 | return; | ||
569 | |||
570 | _rtl92s_dm_ctrl_initgain_bytwoport(hw); | ||
571 | } | ||
572 | |||
573 | static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) | ||
574 | { | ||
575 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
576 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
577 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
578 | long undecorated_smoothed_pwdb; | ||
579 | long txpwr_threshold_lv1, txpwr_threshold_lv2; | ||
580 | |||
581 | /* 2T2R TP issue */ | ||
582 | if (rtlphy->rf_type == RF_2T2R) | ||
583 | return; | ||
584 | |||
585 | if (!rtlpriv->dm.dynamic_txpower_enable || | ||
586 | rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { | ||
587 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; | ||
588 | return; | ||
589 | } | ||
590 | |||
591 | if ((mac->link_state < MAC80211_LINKED) && | ||
592 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | ||
593 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
594 | ("Not connected to any\n")); | ||
595 | |||
596 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; | ||
597 | |||
598 | rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL; | ||
599 | return; | ||
600 | } | ||
601 | |||
602 | if (mac->link_state >= MAC80211_LINKED) { | ||
603 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
604 | undecorated_smoothed_pwdb = | ||
605 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
606 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
607 | ("AP Client PWDB = 0x%lx\n", | ||
608 | undecorated_smoothed_pwdb)); | ||
609 | } else { | ||
610 | undecorated_smoothed_pwdb = | ||
611 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
612 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
613 | ("STA Default Port PWDB = 0x%lx\n", | ||
614 | undecorated_smoothed_pwdb)); | ||
615 | } | ||
616 | } else { | ||
617 | undecorated_smoothed_pwdb = | ||
618 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
619 | |||
620 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
621 | ("AP Ext Port PWDB = 0x%lx\n", | ||
622 | undecorated_smoothed_pwdb)); | ||
623 | } | ||
624 | |||
625 | txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; | ||
626 | txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1; | ||
627 | |||
628 | if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1) | ||
629 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; | ||
630 | else if (undecorated_smoothed_pwdb >= txpwr_threshold_lv2) | ||
631 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2; | ||
632 | else if ((undecorated_smoothed_pwdb < (txpwr_threshold_lv2 - 3)) && | ||
633 | (undecorated_smoothed_pwdb >= txpwr_threshold_lv1)) | ||
634 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1; | ||
635 | else if (undecorated_smoothed_pwdb < (txpwr_threshold_lv1 - 3)) | ||
636 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; | ||
637 | |||
638 | if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) | ||
639 | rtl92s_phy_set_txpower(hw, rtlphy->current_channel); | ||
640 | |||
641 | rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; | ||
642 | } | ||
643 | |||
644 | static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw) | ||
645 | { | ||
646 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
647 | |||
648 | /* Disable DIG scheme now.*/ | ||
649 | digtable.dig_enable_flag = true; | ||
650 | digtable.backoff_enable_flag = true; | ||
651 | |||
652 | if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) && | ||
653 | (hal_get_firmwareversion(rtlpriv) >= 0x3c)) | ||
654 | digtable.dig_algorithm = DIG_ALGO_BY_TOW_PORT; | ||
655 | else | ||
656 | digtable.dig_algorithm = | ||
657 | DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM; | ||
658 | |||
659 | digtable.dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; | ||
660 | digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
661 | /* off=by real rssi value, on=by digtable.rssi_val for new dig */ | ||
662 | digtable.dig_dbgmode = DM_DBG_OFF; | ||
663 | digtable.dig_slgorithm_switch = 0; | ||
664 | |||
665 | /* 2007/10/04 MH Define init gain threshol. */ | ||
666 | digtable.dig_state = DM_STA_DIG_MAX; | ||
667 | digtable.dig_highpwrstate = DM_STA_DIG_MAX; | ||
668 | |||
669 | digtable.cur_sta_connectstate = DIG_STA_DISCONNECT; | ||
670 | digtable.pre_sta_connectstate = DIG_STA_DISCONNECT; | ||
671 | digtable.cur_ap_connectstate = DIG_AP_DISCONNECT; | ||
672 | digtable.pre_ap_connectstate = DIG_AP_DISCONNECT; | ||
673 | |||
674 | digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; | ||
675 | digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; | ||
676 | |||
677 | digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; | ||
678 | digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; | ||
679 | |||
680 | digtable.rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; | ||
681 | digtable.rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; | ||
682 | |||
683 | /* for dig debug rssi value */ | ||
684 | digtable.rssi_val = 50; | ||
685 | digtable.backoff_val = DM_DIG_BACKOFF; | ||
686 | digtable.rx_gain_range_max = DM_DIG_MAX; | ||
687 | |||
688 | digtable.rx_gain_range_min = DM_DIG_MIN; | ||
689 | |||
690 | digtable.backoffval_range_max = DM_DIG_BACKOFF_MAX; | ||
691 | digtable.backoffval_range_min = DM_DIG_BACKOFF_MIN; | ||
692 | } | ||
693 | |||
694 | static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw) | ||
695 | { | ||
696 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
697 | |||
698 | if ((hal_get_firmwareversion(rtlpriv) >= 60) && | ||
699 | (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)) | ||
700 | rtlpriv->dm.dynamic_txpower_enable = true; | ||
701 | else | ||
702 | rtlpriv->dm.dynamic_txpower_enable = false; | ||
703 | |||
704 | rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL; | ||
705 | rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; | ||
706 | } | ||
707 | |||
708 | void rtl92s_dm_init(struct ieee80211_hw *hw) | ||
709 | { | ||
710 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
711 | |||
712 | rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; | ||
713 | rtlpriv->dm.undecorated_smoothed_pwdb = -1; | ||
714 | |||
715 | _rtl92s_dm_init_dynamic_txpower(hw); | ||
716 | rtl92s_dm_init_edca_turbo(hw); | ||
717 | _rtl92s_dm_init_rate_adaptive_mask(hw); | ||
718 | _rtl92s_dm_init_txpowertracking_thermalmeter(hw); | ||
719 | _rtl92s_dm_init_dig(hw); | ||
720 | |||
721 | rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE); | ||
722 | } | ||
723 | |||
724 | void rtl92s_dm_watchdog(struct ieee80211_hw *hw) | ||
725 | { | ||
726 | _rtl92s_dm_check_edca_turbo(hw); | ||
727 | _rtl92s_dm_check_txpowertracking_thermalmeter(hw); | ||
728 | _rtl92s_dm_ctrl_initgain_byrssi(hw); | ||
729 | _rtl92s_dm_dynamic_txpower(hw); | ||
730 | _rtl92s_dm_refresh_rateadaptive_mask(hw); | ||
731 | _rtl92s_dm_switch_baseband_mrc(hw); | ||
732 | } | ||
733 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h new file mode 100644 index 000000000000..9051a556acc4 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h | |||
@@ -0,0 +1,164 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __RTL_92S_DM_H__ | ||
30 | #define __RTL_92S_DM_H__ | ||
31 | |||
32 | struct dig_t { | ||
33 | u8 dig_enable_flag; | ||
34 | u8 dig_algorithm; | ||
35 | u8 dig_twoport_algorithm; | ||
36 | u8 dig_ext_port_stage; | ||
37 | u8 dig_dbgmode; | ||
38 | u8 dig_slgorithm_switch; | ||
39 | |||
40 | long rssi_lowthresh; | ||
41 | long rssi_highthresh; | ||
42 | |||
43 | u32 fa_lowthresh; | ||
44 | u32 fa_highthresh; | ||
45 | |||
46 | long rssi_highpower_lowthresh; | ||
47 | long rssi_highpower_highthresh; | ||
48 | |||
49 | u8 dig_state; | ||
50 | u8 dig_highpwrstate; | ||
51 | u8 cur_sta_connectstate; | ||
52 | u8 pre_sta_connectstate; | ||
53 | u8 cur_ap_connectstate; | ||
54 | u8 pre_ap_connectstate; | ||
55 | |||
56 | u8 cur_pd_thstate; | ||
57 | u8 pre_pd_thstate; | ||
58 | u8 cur_cs_ratiostate; | ||
59 | u8 pre_cs_ratiostate; | ||
60 | |||
61 | u32 pre_igvalue; | ||
62 | u32 cur_igvalue; | ||
63 | |||
64 | u8 backoff_enable_flag; | ||
65 | char backoff_val; | ||
66 | char backoffval_range_max; | ||
67 | char backoffval_range_min; | ||
68 | u8 rx_gain_range_max; | ||
69 | u8 rx_gain_range_min; | ||
70 | |||
71 | long rssi_val; | ||
72 | }; | ||
73 | |||
74 | enum dm_dig_alg { | ||
75 | DIG_ALGO_BY_FALSE_ALARM = 0, | ||
76 | DIG_ALGO_BY_RSSI = 1, | ||
77 | DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2, | ||
78 | DIG_ALGO_BY_TOW_PORT = 3, | ||
79 | DIG_ALGO_MAX | ||
80 | }; | ||
81 | |||
82 | enum dm_dig_two_port_alg { | ||
83 | DIG_TWO_PORT_ALGO_RSSI = 0, | ||
84 | DIG_TWO_PORT_ALGO_FALSE_ALARM = 1, | ||
85 | }; | ||
86 | |||
87 | enum dm_dig_dbg { | ||
88 | DM_DBG_OFF = 0, | ||
89 | DM_DBG_ON = 1, | ||
90 | DM_DBG_MAX | ||
91 | }; | ||
92 | |||
93 | enum dm_dig_sta { | ||
94 | DM_STA_DIG_OFF = 0, | ||
95 | DM_STA_DIG_ON, | ||
96 | DM_STA_DIG_MAX | ||
97 | }; | ||
98 | |||
99 | enum dm_dig_connect { | ||
100 | DIG_STA_DISCONNECT = 0, | ||
101 | DIG_STA_CONNECT = 1, | ||
102 | DIG_STA_BEFORE_CONNECT = 2, | ||
103 | DIG_AP_DISCONNECT = 3, | ||
104 | DIG_AP_CONNECT = 4, | ||
105 | DIG_AP_ADD_STATION = 5, | ||
106 | DIG_CONNECT_MAX | ||
107 | }; | ||
108 | |||
109 | enum dm_dig_ext_port_alg { | ||
110 | DIG_EXT_PORT_STAGE_0 = 0, | ||
111 | DIG_EXT_PORT_STAGE_1 = 1, | ||
112 | DIG_EXT_PORT_STAGE_2 = 2, | ||
113 | DIG_EXT_PORT_STAGE_3 = 3, | ||
114 | DIG_EXT_PORT_STAGE_MAX = 4, | ||
115 | }; | ||
116 | |||
117 | enum dm_ratr_sta { | ||
118 | DM_RATR_STA_HIGH = 0, | ||
119 | DM_RATR_STA_MIDDLEHIGH = 1, | ||
120 | DM_RATR_STA_MIDDLE = 2, | ||
121 | DM_RATR_STA_MIDDLELOW = 3, | ||
122 | DM_RATR_STA_LOW = 4, | ||
123 | DM_RATR_STA_ULTRALOW = 5, | ||
124 | DM_RATR_STA_MAX | ||
125 | }; | ||
126 | |||
127 | #define DM_TYPE_BYFW 0 | ||
128 | #define DM_TYPE_BYDRIVER 1 | ||
129 | |||
130 | #define TX_HIGH_PWR_LEVEL_NORMAL 0 | ||
131 | #define TX_HIGH_PWR_LEVEL_LEVEL1 1 | ||
132 | #define TX_HIGH_PWR_LEVEL_LEVEL2 2 | ||
133 | |||
134 | #define HAL_DM_DIG_DISABLE BIT(0) /* Disable Dig */ | ||
135 | #define HAL_DM_HIPWR_DISABLE BIT(1) /* Disable High Power */ | ||
136 | |||
137 | #define TX_HIGHPWR_LEVEL_NORMAL 0 | ||
138 | #define TX_HIGHPWR_LEVEL_NORMAL1 1 | ||
139 | #define TX_HIGHPWR_LEVEL_NORMAL2 2 | ||
140 | |||
141 | #define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 | ||
142 | #define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 | ||
143 | |||
144 | #define DM_DIG_THRESH_HIGH 40 | ||
145 | #define DM_DIG_THRESH_LOW 35 | ||
146 | #define DM_FALSEALARM_THRESH_LOW 40 | ||
147 | #define DM_FALSEALARM_THRESH_HIGH 1000 | ||
148 | #define DM_DIG_HIGH_PWR_THRESH_HIGH 75 | ||
149 | #define DM_DIG_HIGH_PWR_THRESH_LOW 70 | ||
150 | #define DM_DIG_BACKOFF 12 | ||
151 | #define DM_DIG_MAX 0x3e | ||
152 | #define DM_DIG_MIN 0x1c | ||
153 | #define DM_DIG_MIN_Netcore 0x12 | ||
154 | #define DM_DIG_BACKOFF_MAX 12 | ||
155 | #define DM_DIG_BACKOFF_MIN -4 | ||
156 | |||
157 | extern struct dig_t digtable; | ||
158 | |||
159 | void rtl92s_dm_watchdog(struct ieee80211_hw *hw); | ||
160 | void rtl92s_dm_init(struct ieee80211_hw *hw); | ||
161 | void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw); | ||
162 | |||
163 | #endif | ||
164 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c new file mode 100644 index 000000000000..3b5af0113d7f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c | |||
@@ -0,0 +1,654 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../pci.h" | ||
32 | #include "../base.h" | ||
33 | #include "reg.h" | ||
34 | #include "def.h" | ||
35 | #include "fw.h" | ||
36 | |||
37 | static void _rtl92s_fw_set_rqpn(struct ieee80211_hw *hw) | ||
38 | { | ||
39 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
40 | |||
41 | rtl_write_dword(rtlpriv, RQPN, 0xffffffff); | ||
42 | rtl_write_dword(rtlpriv, RQPN + 4, 0xffffffff); | ||
43 | rtl_write_byte(rtlpriv, RQPN + 8, 0xff); | ||
44 | rtl_write_byte(rtlpriv, RQPN + 0xB, 0x80); | ||
45 | } | ||
46 | |||
47 | static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw) | ||
48 | { | ||
49 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
50 | u32 ichecktime = 200; | ||
51 | u16 tmpu2b; | ||
52 | u8 tmpu1b, cpustatus = 0; | ||
53 | |||
54 | _rtl92s_fw_set_rqpn(hw); | ||
55 | |||
56 | /* Enable CPU. */ | ||
57 | tmpu1b = rtl_read_byte(rtlpriv, SYS_CLKR); | ||
58 | /* AFE source */ | ||
59 | rtl_write_byte(rtlpriv, SYS_CLKR, (tmpu1b | SYS_CPU_CLKSEL)); | ||
60 | |||
61 | tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | ||
62 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | FEN_CPUEN)); | ||
63 | |||
64 | /* Polling IMEM Ready after CPU has refilled. */ | ||
65 | do { | ||
66 | cpustatus = rtl_read_byte(rtlpriv, TCR); | ||
67 | if (cpustatus & IMEM_RDY) { | ||
68 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
69 | ("IMEM Ready after CPU has refilled.\n")); | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | udelay(100); | ||
74 | } while (ichecktime--); | ||
75 | |||
76 | if (!(cpustatus & IMEM_RDY)) | ||
77 | return false; | ||
78 | |||
79 | return true; | ||
80 | } | ||
81 | |||
82 | static enum fw_status _rtl92s_firmware_get_nextstatus( | ||
83 | enum fw_status fw_currentstatus) | ||
84 | { | ||
85 | enum fw_status next_fwstatus = 0; | ||
86 | |||
87 | switch (fw_currentstatus) { | ||
88 | case FW_STATUS_INIT: | ||
89 | next_fwstatus = FW_STATUS_LOAD_IMEM; | ||
90 | break; | ||
91 | case FW_STATUS_LOAD_IMEM: | ||
92 | next_fwstatus = FW_STATUS_LOAD_EMEM; | ||
93 | break; | ||
94 | case FW_STATUS_LOAD_EMEM: | ||
95 | next_fwstatus = FW_STATUS_LOAD_DMEM; | ||
96 | break; | ||
97 | case FW_STATUS_LOAD_DMEM: | ||
98 | next_fwstatus = FW_STATUS_READY; | ||
99 | break; | ||
100 | default: | ||
101 | break; | ||
102 | } | ||
103 | |||
104 | return next_fwstatus; | ||
105 | } | ||
106 | |||
107 | static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw) | ||
108 | { | ||
109 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
110 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
111 | |||
112 | switch (rtlphy->rf_type) { | ||
113 | case RF_1T1R: | ||
114 | return 0x11; | ||
115 | break; | ||
116 | case RF_1T2R: | ||
117 | return 0x12; | ||
118 | break; | ||
119 | case RF_2T2R: | ||
120 | return 0x22; | ||
121 | break; | ||
122 | default: | ||
123 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
124 | ("Unknown RF type(%x)\n", | ||
125 | rtlphy->rf_type)); | ||
126 | break; | ||
127 | } | ||
128 | return 0x22; | ||
129 | } | ||
130 | |||
131 | static void _rtl92s_firmwareheader_priveupdate(struct ieee80211_hw *hw, | ||
132 | struct fw_priv *pfw_priv) | ||
133 | { | ||
134 | /* Update RF types for RATR settings. */ | ||
135 | pfw_priv->rf_config = _rtl92s_firmware_header_map_rftype(hw); | ||
136 | } | ||
137 | |||
138 | |||
139 | |||
140 | static bool _rtl92s_cmd_send_packet(struct ieee80211_hw *hw, | ||
141 | struct sk_buff *skb, u8 last) | ||
142 | { | ||
143 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
144 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
145 | struct rtl8192_tx_ring *ring; | ||
146 | struct rtl_tx_desc *pdesc; | ||
147 | unsigned long flags; | ||
148 | u8 idx = 0; | ||
149 | |||
150 | ring = &rtlpci->tx_ring[TXCMD_QUEUE]; | ||
151 | |||
152 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); | ||
153 | |||
154 | idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; | ||
155 | pdesc = &ring->desc[idx]; | ||
156 | rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb); | ||
157 | __skb_queue_tail(&ring->queue, skb); | ||
158 | |||
159 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | ||
160 | |||
161 | return true; | ||
162 | } | ||
163 | |||
164 | static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, | ||
165 | u8 *code_virtual_address, u32 buffer_len) | ||
166 | { | ||
167 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
168 | struct sk_buff *skb; | ||
169 | struct rtl_tcb_desc *tcb_desc; | ||
170 | unsigned char *seg_ptr; | ||
171 | u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE; | ||
172 | u16 frag_length, frag_offset = 0; | ||
173 | u16 extra_descoffset = 0; | ||
174 | u8 last_inipkt = 0; | ||
175 | |||
176 | _rtl92s_fw_set_rqpn(hw); | ||
177 | |||
178 | if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) { | ||
179 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
180 | ("Size over FIRMWARE_CODE_SIZE!\n")); | ||
181 | |||
182 | return false; | ||
183 | } | ||
184 | |||
185 | extra_descoffset = 0; | ||
186 | |||
187 | do { | ||
188 | if ((buffer_len - frag_offset) > frag_threshold) { | ||
189 | frag_length = frag_threshold + extra_descoffset; | ||
190 | } else { | ||
191 | frag_length = (u16)(buffer_len - frag_offset + | ||
192 | extra_descoffset); | ||
193 | last_inipkt = 1; | ||
194 | } | ||
195 | |||
196 | /* Allocate skb buffer to contain firmware */ | ||
197 | /* info and tx descriptor info. */ | ||
198 | skb = dev_alloc_skb(frag_length); | ||
199 | skb_reserve(skb, extra_descoffset); | ||
200 | seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length - | ||
201 | extra_descoffset)); | ||
202 | memcpy(seg_ptr, code_virtual_address + frag_offset, | ||
203 | (u32)(frag_length - extra_descoffset)); | ||
204 | |||
205 | tcb_desc = (struct rtl_tcb_desc *)(skb->cb); | ||
206 | tcb_desc->queue_index = TXCMD_QUEUE; | ||
207 | tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT; | ||
208 | tcb_desc->last_inipkt = last_inipkt; | ||
209 | |||
210 | _rtl92s_cmd_send_packet(hw, skb, last_inipkt); | ||
211 | |||
212 | frag_offset += (frag_length - extra_descoffset); | ||
213 | |||
214 | } while (frag_offset < buffer_len); | ||
215 | |||
216 | rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ); | ||
217 | |||
218 | return true ; | ||
219 | } | ||
220 | |||
221 | static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, | ||
222 | u8 loadfw_status) | ||
223 | { | ||
224 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
225 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
226 | struct rt_firmware *firmware = (struct rt_firmware *)rtlhal->pfirmware; | ||
227 | u32 tmpu4b; | ||
228 | u8 cpustatus = 0; | ||
229 | short pollingcnt = 1000; | ||
230 | bool rtstatus = true; | ||
231 | |||
232 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n", | ||
233 | loadfw_status)); | ||
234 | |||
235 | firmware->fwstatus = (enum fw_status)loadfw_status; | ||
236 | |||
237 | switch (loadfw_status) { | ||
238 | case FW_STATUS_LOAD_IMEM: | ||
239 | /* Polling IMEM code done. */ | ||
240 | do { | ||
241 | cpustatus = rtl_read_byte(rtlpriv, TCR); | ||
242 | if (cpustatus & IMEM_CODE_DONE) | ||
243 | break; | ||
244 | udelay(5); | ||
245 | } while (pollingcnt--); | ||
246 | |||
247 | if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) { | ||
248 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
249 | ("FW_STATUS_LOAD_IMEM" | ||
250 | " FAIL CPU, Status=%x\r\n", cpustatus)); | ||
251 | goto status_check_fail; | ||
252 | } | ||
253 | break; | ||
254 | |||
255 | case FW_STATUS_LOAD_EMEM: | ||
256 | /* Check Put Code OK and Turn On CPU */ | ||
257 | /* Polling EMEM code done. */ | ||
258 | do { | ||
259 | cpustatus = rtl_read_byte(rtlpriv, TCR); | ||
260 | if (cpustatus & EMEM_CODE_DONE) | ||
261 | break; | ||
262 | udelay(5); | ||
263 | } while (pollingcnt--); | ||
264 | |||
265 | if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) { | ||
266 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
267 | ("FW_STATUS_LOAD_EMEM" | ||
268 | " FAIL CPU, Status=%x\r\n", cpustatus)); | ||
269 | goto status_check_fail; | ||
270 | } | ||
271 | |||
272 | /* Turn On CPU */ | ||
273 | rtstatus = _rtl92s_firmware_enable_cpu(hw); | ||
274 | if (rtstatus != true) { | ||
275 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
276 | ("Enable CPU fail!\n")); | ||
277 | goto status_check_fail; | ||
278 | } | ||
279 | break; | ||
280 | |||
281 | case FW_STATUS_LOAD_DMEM: | ||
282 | /* Polling DMEM code done */ | ||
283 | do { | ||
284 | cpustatus = rtl_read_byte(rtlpriv, TCR); | ||
285 | if (cpustatus & DMEM_CODE_DONE) | ||
286 | break; | ||
287 | udelay(5); | ||
288 | } while (pollingcnt--); | ||
289 | |||
290 | if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) { | ||
291 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
292 | ("Polling DMEM code done" | ||
293 | " fail ! cpustatus(%#x)\n", cpustatus)); | ||
294 | goto status_check_fail; | ||
295 | } | ||
296 | |||
297 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
298 | ("DMEM code download success," | ||
299 | " cpustatus(%#x)\n", cpustatus)); | ||
300 | |||
301 | /* Prevent Delay too much and being scheduled out */ | ||
302 | /* Polling Load Firmware ready */ | ||
303 | pollingcnt = 2000; | ||
304 | do { | ||
305 | cpustatus = rtl_read_byte(rtlpriv, TCR); | ||
306 | if (cpustatus & FWRDY) | ||
307 | break; | ||
308 | udelay(40); | ||
309 | } while (pollingcnt--); | ||
310 | |||
311 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
312 | ("Polling Load Firmware ready," | ||
313 | " cpustatus(%x)\n", cpustatus)); | ||
314 | |||
315 | if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) || | ||
316 | (pollingcnt <= 0)) { | ||
317 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
318 | ("Polling Load Firmware" | ||
319 | " ready fail ! cpustatus(%x)\n", cpustatus)); | ||
320 | goto status_check_fail; | ||
321 | } | ||
322 | |||
323 | /* If right here, we can set TCR/RCR to desired value */ | ||
324 | /* and config MAC lookback mode to normal mode */ | ||
325 | tmpu4b = rtl_read_dword(rtlpriv, TCR); | ||
326 | rtl_write_dword(rtlpriv, TCR, (tmpu4b & (~TCR_ICV))); | ||
327 | |||
328 | tmpu4b = rtl_read_dword(rtlpriv, RCR); | ||
329 | rtl_write_dword(rtlpriv, RCR, (tmpu4b | RCR_APPFCS | | ||
330 | RCR_APP_ICV | RCR_APP_MIC)); | ||
331 | |||
332 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
333 | ("Current RCR settings(%#x)\n", tmpu4b)); | ||
334 | |||
335 | /* Set to normal mode. */ | ||
336 | rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL); | ||
337 | break; | ||
338 | |||
339 | default: | ||
340 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
341 | ("Unknown status check!\n")); | ||
342 | rtstatus = false; | ||
343 | break; | ||
344 | } | ||
345 | |||
346 | status_check_fail: | ||
347 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), " | ||
348 | "rtstatus(%x)\n", loadfw_status, rtstatus)); | ||
349 | return rtstatus; | ||
350 | } | ||
351 | |||
352 | int rtl92s_download_fw(struct ieee80211_hw *hw) | ||
353 | { | ||
354 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
355 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
356 | struct rt_firmware *firmware = NULL; | ||
357 | struct fw_hdr *pfwheader; | ||
358 | struct fw_priv *pfw_priv = NULL; | ||
359 | u8 *puc_mappedfile = NULL; | ||
360 | u32 ul_filelength = 0; | ||
361 | u32 file_length = 0; | ||
362 | u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE; | ||
363 | u8 fwstatus = FW_STATUS_INIT; | ||
364 | bool rtstatus = true; | ||
365 | |||
366 | if (!rtlhal->pfirmware) | ||
367 | return 1; | ||
368 | |||
369 | firmware = (struct rt_firmware *)rtlhal->pfirmware; | ||
370 | firmware->fwstatus = FW_STATUS_INIT; | ||
371 | |||
372 | puc_mappedfile = firmware->sz_fw_tmpbuffer; | ||
373 | file_length = firmware->sz_fw_tmpbufferlen; | ||
374 | |||
375 | /* 1. Retrieve FW header. */ | ||
376 | firmware->pfwheader = (struct fw_hdr *) puc_mappedfile; | ||
377 | pfwheader = firmware->pfwheader; | ||
378 | firmware->firmwareversion = byte(pfwheader->version, 0); | ||
379 | firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */ | ||
380 | |||
381 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:" | ||
382 | "%x, size:%x," | ||
383 | "imemsize:%x, sram size:%x\n", pfwheader->signature, | ||
384 | pfwheader->version, pfwheader->dmem_size, | ||
385 | pfwheader->img_imem_size, pfwheader->img_sram_size)); | ||
386 | |||
387 | /* 2. Retrieve IMEM image. */ | ||
388 | if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size > | ||
389 | sizeof(firmware->fw_imem))) { | ||
390 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
391 | ("memory for data image is less than IMEM required\n")); | ||
392 | goto fail; | ||
393 | } else { | ||
394 | puc_mappedfile += fwhdr_size; | ||
395 | |||
396 | memcpy(firmware->fw_imem, puc_mappedfile, | ||
397 | pfwheader->img_imem_size); | ||
398 | firmware->fw_imem_len = pfwheader->img_imem_size; | ||
399 | } | ||
400 | |||
401 | /* 3. Retriecve EMEM image. */ | ||
402 | if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) { | ||
403 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
404 | ("memory for data image is less than EMEM required\n")); | ||
405 | goto fail; | ||
406 | } else { | ||
407 | puc_mappedfile += firmware->fw_imem_len; | ||
408 | |||
409 | memcpy(firmware->fw_emem, puc_mappedfile, | ||
410 | pfwheader->img_sram_size); | ||
411 | firmware->fw_emem_len = pfwheader->img_sram_size; | ||
412 | } | ||
413 | |||
414 | /* 4. download fw now */ | ||
415 | fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus); | ||
416 | while (fwstatus != FW_STATUS_READY) { | ||
417 | /* Image buffer redirection. */ | ||
418 | switch (fwstatus) { | ||
419 | case FW_STATUS_LOAD_IMEM: | ||
420 | puc_mappedfile = firmware->fw_imem; | ||
421 | ul_filelength = firmware->fw_imem_len; | ||
422 | break; | ||
423 | case FW_STATUS_LOAD_EMEM: | ||
424 | puc_mappedfile = firmware->fw_emem; | ||
425 | ul_filelength = firmware->fw_emem_len; | ||
426 | break; | ||
427 | case FW_STATUS_LOAD_DMEM: | ||
428 | /* Partial update the content of header private. */ | ||
429 | pfwheader = firmware->pfwheader; | ||
430 | pfw_priv = &pfwheader->fwpriv; | ||
431 | _rtl92s_firmwareheader_priveupdate(hw, pfw_priv); | ||
432 | puc_mappedfile = (u8 *)(firmware->pfwheader) + | ||
433 | RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; | ||
434 | ul_filelength = fwhdr_size - | ||
435 | RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; | ||
436 | break; | ||
437 | default: | ||
438 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
439 | ("Unexpected Download step!!\n")); | ||
440 | goto fail; | ||
441 | break; | ||
442 | } | ||
443 | |||
444 | /* <2> Download image file */ | ||
445 | rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile, | ||
446 | ul_filelength); | ||
447 | |||
448 | if (rtstatus != true) { | ||
449 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n")); | ||
450 | goto fail; | ||
451 | } | ||
452 | |||
453 | /* <3> Check whether load FW process is ready */ | ||
454 | rtstatus = _rtl92s_firmware_checkready(hw, fwstatus); | ||
455 | if (rtstatus != true) { | ||
456 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n")); | ||
457 | goto fail; | ||
458 | } | ||
459 | |||
460 | fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus); | ||
461 | } | ||
462 | |||
463 | return rtstatus; | ||
464 | fail: | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static u32 _rtl92s_fill_h2c_cmd(struct sk_buff *skb, u32 h2cbufferlen, | ||
469 | u32 cmd_num, u32 *pelement_id, u32 *pcmd_len, | ||
470 | u8 **pcmb_buffer, u8 *cmd_start_seq) | ||
471 | { | ||
472 | u32 totallen = 0, len = 0, tx_desclen = 0; | ||
473 | u32 pre_continueoffset = 0; | ||
474 | u8 *ph2c_buffer; | ||
475 | u8 i = 0; | ||
476 | |||
477 | do { | ||
478 | /* 8 - Byte aligment */ | ||
479 | len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8); | ||
480 | |||
481 | /* Buffer length is not enough */ | ||
482 | if (h2cbufferlen < totallen + len + tx_desclen) | ||
483 | break; | ||
484 | |||
485 | /* Clear content */ | ||
486 | ph2c_buffer = (u8 *)skb_put(skb, (u32)len); | ||
487 | memset((ph2c_buffer + totallen + tx_desclen), 0, len); | ||
488 | |||
489 | /* CMD len */ | ||
490 | SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen), | ||
491 | 0, 16, pcmd_len[i]); | ||
492 | |||
493 | /* CMD ID */ | ||
494 | SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen), | ||
495 | 16, 8, pelement_id[i]); | ||
496 | |||
497 | /* CMD Sequence */ | ||
498 | *cmd_start_seq = *cmd_start_seq % 0x80; | ||
499 | SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen), | ||
500 | 24, 7, *cmd_start_seq); | ||
501 | ++*cmd_start_seq; | ||
502 | |||
503 | /* Copy memory */ | ||
504 | memcpy((ph2c_buffer + totallen + tx_desclen + | ||
505 | H2C_TX_CMD_HDR_LEN), pcmb_buffer[i], pcmd_len[i]); | ||
506 | |||
507 | /* CMD continue */ | ||
508 | /* set the continue in prevoius cmd. */ | ||
509 | if (i < cmd_num - 1) | ||
510 | SET_BITS_TO_LE_4BYTE((ph2c_buffer + pre_continueoffset), | ||
511 | 31, 1, 1); | ||
512 | |||
513 | pre_continueoffset = totallen; | ||
514 | |||
515 | totallen += len; | ||
516 | } while (++i < cmd_num); | ||
517 | |||
518 | return totallen; | ||
519 | } | ||
520 | |||
521 | static u32 _rtl92s_get_h2c_cmdlen(u32 h2cbufferlen, u32 cmd_num, u32 *pcmd_len) | ||
522 | { | ||
523 | u32 totallen = 0, len = 0, tx_desclen = 0; | ||
524 | u8 i = 0; | ||
525 | |||
526 | do { | ||
527 | /* 8 - Byte aligment */ | ||
528 | len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8); | ||
529 | |||
530 | /* Buffer length is not enough */ | ||
531 | if (h2cbufferlen < totallen + len + tx_desclen) | ||
532 | break; | ||
533 | |||
534 | totallen += len; | ||
535 | } while (++i < cmd_num); | ||
536 | |||
537 | return totallen + tx_desclen; | ||
538 | } | ||
539 | |||
540 | static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd, | ||
541 | u8 *pcmd_buffer) | ||
542 | { | ||
543 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
544 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
545 | struct rtl_tcb_desc *cb_desc; | ||
546 | struct sk_buff *skb; | ||
547 | u32 element_id = 0; | ||
548 | u32 cmd_len = 0; | ||
549 | u32 len; | ||
550 | |||
551 | switch (h2c_cmd) { | ||
552 | case FW_H2C_SETPWRMODE: | ||
553 | element_id = H2C_SETPWRMODE_CMD ; | ||
554 | cmd_len = sizeof(struct h2c_set_pwrmode_parm); | ||
555 | break; | ||
556 | case FW_H2C_JOINBSSRPT: | ||
557 | element_id = H2C_JOINBSSRPT_CMD; | ||
558 | cmd_len = sizeof(struct h2c_joinbss_rpt_parm); | ||
559 | break; | ||
560 | case FW_H2C_WOWLAN_UPDATE_GTK: | ||
561 | element_id = H2C_WOWLAN_UPDATE_GTK_CMD; | ||
562 | cmd_len = sizeof(struct h2c_wpa_two_way_parm); | ||
563 | break; | ||
564 | case FW_H2C_WOWLAN_UPDATE_IV: | ||
565 | element_id = H2C_WOWLAN_UPDATE_IV_CMD; | ||
566 | cmd_len = sizeof(unsigned long long); | ||
567 | break; | ||
568 | case FW_H2C_WOWLAN_OFFLOAD: | ||
569 | element_id = H2C_WOWLAN_FW_OFFLOAD; | ||
570 | cmd_len = sizeof(u8); | ||
571 | break; | ||
572 | default: | ||
573 | break; | ||
574 | } | ||
575 | |||
576 | len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len); | ||
577 | skb = dev_alloc_skb(len); | ||
578 | cb_desc = (struct rtl_tcb_desc *)(skb->cb); | ||
579 | cb_desc->queue_index = TXCMD_QUEUE; | ||
580 | cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL; | ||
581 | cb_desc->last_inipkt = false; | ||
582 | |||
583 | _rtl92s_fill_h2c_cmd(skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &element_id, | ||
584 | &cmd_len, &pcmd_buffer, &rtlhal->h2c_txcmd_seq); | ||
585 | _rtl92s_cmd_send_packet(hw, skb, false); | ||
586 | rtlpriv->cfg->ops->tx_polling(hw, TXCMD_QUEUE); | ||
587 | |||
588 | return true; | ||
589 | } | ||
590 | |||
591 | void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 Mode) | ||
592 | { | ||
593 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
594 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
595 | struct h2c_set_pwrmode_parm pwrmode; | ||
596 | u16 max_wakeup_period = 0; | ||
597 | |||
598 | pwrmode.mode = Mode; | ||
599 | pwrmode.flag_low_traffic_en = 0; | ||
600 | pwrmode.flag_lpnav_en = 0; | ||
601 | pwrmode.flag_rf_low_snr_en = 0; | ||
602 | pwrmode.flag_dps_en = 0; | ||
603 | pwrmode.bcn_rx_en = 0; | ||
604 | pwrmode.bcn_to = 0; | ||
605 | SET_BITS_TO_LE_2BYTE((u8 *)(&pwrmode) + 8, 0, 16, | ||
606 | mac->vif->bss_conf.beacon_int); | ||
607 | pwrmode.app_itv = 0; | ||
608 | pwrmode.awake_bcn_itvl = ppsc->reg_max_lps_awakeintvl; | ||
609 | pwrmode.smart_ps = 1; | ||
610 | pwrmode.bcn_pass_period = 10; | ||
611 | |||
612 | /* Set beacon pass count */ | ||
613 | if (pwrmode.mode == FW_PS_MIN_MODE) | ||
614 | max_wakeup_period = mac->vif->bss_conf.beacon_int; | ||
615 | else if (pwrmode.mode == FW_PS_MAX_MODE) | ||
616 | max_wakeup_period = mac->vif->bss_conf.beacon_int * | ||
617 | mac->vif->bss_conf.dtim_period; | ||
618 | |||
619 | if (max_wakeup_period >= 500) | ||
620 | pwrmode.bcn_pass_cnt = 1; | ||
621 | else if ((max_wakeup_period >= 300) && (max_wakeup_period < 500)) | ||
622 | pwrmode.bcn_pass_cnt = 2; | ||
623 | else if ((max_wakeup_period >= 200) && (max_wakeup_period < 300)) | ||
624 | pwrmode.bcn_pass_cnt = 3; | ||
625 | else if ((max_wakeup_period >= 20) && (max_wakeup_period < 200)) | ||
626 | pwrmode.bcn_pass_cnt = 5; | ||
627 | else | ||
628 | pwrmode.bcn_pass_cnt = 1; | ||
629 | |||
630 | _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_SETPWRMODE, (u8 *)&pwrmode); | ||
631 | |||
632 | } | ||
633 | |||
634 | void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, | ||
635 | u8 mstatus, u8 ps_qosinfo) | ||
636 | { | ||
637 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
638 | struct h2c_joinbss_rpt_parm joinbss_rpt; | ||
639 | |||
640 | joinbss_rpt.opmode = mstatus; | ||
641 | joinbss_rpt.ps_qos_info = ps_qosinfo; | ||
642 | joinbss_rpt.bssid[0] = mac->bssid[0]; | ||
643 | joinbss_rpt.bssid[1] = mac->bssid[1]; | ||
644 | joinbss_rpt.bssid[2] = mac->bssid[2]; | ||
645 | joinbss_rpt.bssid[3] = mac->bssid[3]; | ||
646 | joinbss_rpt.bssid[4] = mac->bssid[4]; | ||
647 | joinbss_rpt.bssid[5] = mac->bssid[5]; | ||
648 | SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 8, 0, 16, | ||
649 | mac->vif->bss_conf.beacon_int); | ||
650 | SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 10, 0, 16, mac->assoc_id); | ||
651 | |||
652 | _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_JOINBSSRPT, (u8 *)&joinbss_rpt); | ||
653 | } | ||
654 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h new file mode 100644 index 000000000000..74cc503efe8a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h | |||
@@ -0,0 +1,375 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __REALTEK_FIRMWARE92S_H__ | ||
30 | #define __REALTEK_FIRMWARE92S_H__ | ||
31 | |||
32 | #define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 | ||
33 | #define RTL8190_CPU_START_OFFSET 0x80 | ||
34 | /* Firmware Local buffer size. 64k */ | ||
35 | #define MAX_FIRMWARE_CODE_SIZE 0xFF00 | ||
36 | |||
37 | #define RT_8192S_FIRMWARE_HDR_SIZE 80 | ||
38 | #define RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE 32 | ||
39 | |||
40 | /* support till 64 bit bus width OS */ | ||
41 | #define MAX_DEV_ADDR_SIZE 8 | ||
42 | #define MAX_FIRMWARE_INFORMATION_SIZE 32 | ||
43 | #define MAX_802_11_HEADER_LENGTH (40 + \ | ||
44 | MAX_FIRMWARE_INFORMATION_SIZE) | ||
45 | #define ENCRYPTION_MAX_OVERHEAD 128 | ||
46 | #define MAX_FRAGMENT_COUNT 8 | ||
47 | #define MAX_TRANSMIT_BUFFER_SIZE (1600 + \ | ||
48 | (MAX_802_11_HEADER_LENGTH + \ | ||
49 | ENCRYPTION_MAX_OVERHEAD) *\ | ||
50 | MAX_FRAGMENT_COUNT) | ||
51 | |||
52 | #define H2C_TX_CMD_HDR_LEN 8 | ||
53 | |||
54 | /* The following DM control code are for Reg0x364, */ | ||
55 | #define FW_DIG_ENABLE_CTL BIT(0) | ||
56 | #define FW_HIGH_PWR_ENABLE_CTL BIT(1) | ||
57 | #define FW_SS_CTL BIT(2) | ||
58 | #define FW_RA_INIT_CTL BIT(3) | ||
59 | #define FW_RA_BG_CTL BIT(4) | ||
60 | #define FW_RA_N_CTL BIT(5) | ||
61 | #define FW_PWR_TRK_CTL BIT(6) | ||
62 | #define FW_IQK_CTL BIT(7) | ||
63 | #define FW_FA_CTL BIT(8) | ||
64 | #define FW_DRIVER_CTRL_DM_CTL BIT(9) | ||
65 | #define FW_PAPE_CTL_BY_SW_HW BIT(10) | ||
66 | #define FW_DISABLE_ALL_DM 0 | ||
67 | #define FW_PWR_TRK_PARAM_CLR 0x0000ffff | ||
68 | #define FW_RA_PARAM_CLR 0xffff0000 | ||
69 | |||
70 | enum desc_packet_type { | ||
71 | DESC_PACKET_TYPE_INIT = 0, | ||
72 | DESC_PACKET_TYPE_NORMAL = 1, | ||
73 | }; | ||
74 | |||
75 | /* 8-bytes alignment required */ | ||
76 | struct fw_priv { | ||
77 | /* --- long word 0 ---- */ | ||
78 | /* 0x12: CE product, 0x92: IT product */ | ||
79 | u8 signature_0; | ||
80 | /* 0x87: CE product, 0x81: IT product */ | ||
81 | u8 signature_1; | ||
82 | /* 0x81: PCI-AP, 01:PCIe, 02: 92S-U, | ||
83 | * 0x82: USB-AP, 0x12: 72S-U, 03:SDIO */ | ||
84 | u8 hci_sel; | ||
85 | /* the same value as reigster value */ | ||
86 | u8 chip_version; | ||
87 | /* customer ID low byte */ | ||
88 | u8 customer_id_0; | ||
89 | /* customer ID high byte */ | ||
90 | u8 customer_id_1; | ||
91 | /* 0x11: 1T1R, 0x12: 1T2R, | ||
92 | * 0x92: 1T2R turbo, 0x22: 2T2R */ | ||
93 | u8 rf_config; | ||
94 | /* 4: 4EP, 6: 6EP, 11: 11EP */ | ||
95 | u8 usb_ep_num; | ||
96 | |||
97 | /* --- long word 1 ---- */ | ||
98 | /* regulatory class bit map 0 */ | ||
99 | u8 regulatory_class_0; | ||
100 | /* regulatory class bit map 1 */ | ||
101 | u8 regulatory_class_1; | ||
102 | /* regulatory class bit map 2 */ | ||
103 | u8 regulatory_class_2; | ||
104 | /* regulatory class bit map 3 */ | ||
105 | u8 regulatory_class_3; | ||
106 | /* 0:SWSI, 1:HWSI, 2:HWPI */ | ||
107 | u8 rfintfs; | ||
108 | u8 def_nettype; | ||
109 | u8 rsvd010; | ||
110 | u8 rsvd011; | ||
111 | |||
112 | /* --- long word 2 ---- */ | ||
113 | /* 0x00: normal, 0x03: MACLBK, 0x01: PHYLBK */ | ||
114 | u8 lbk_mode; | ||
115 | /* 1: for MP use, 0: for normal | ||
116 | * driver (to be discussed) */ | ||
117 | u8 mp_mode; | ||
118 | u8 rsvd020; | ||
119 | u8 rsvd021; | ||
120 | u8 rsvd022; | ||
121 | u8 rsvd023; | ||
122 | u8 rsvd024; | ||
123 | u8 rsvd025; | ||
124 | |||
125 | /* --- long word 3 ---- */ | ||
126 | /* QoS enable */ | ||
127 | u8 qos_en; | ||
128 | /* 40MHz BW enable */ | ||
129 | /* 4181 convert AMSDU to AMPDU, 0: disable */ | ||
130 | u8 bw_40mhz_en; | ||
131 | u8 amsdu2ampdu_en; | ||
132 | /* 11n AMPDU enable */ | ||
133 | u8 ampdu_en; | ||
134 | /* FW offloads, 0: driver handles */ | ||
135 | u8 rate_control_offload; | ||
136 | /* FW offloads, 0: driver handles */ | ||
137 | u8 aggregation_offload; | ||
138 | u8 rsvd030; | ||
139 | u8 rsvd031; | ||
140 | |||
141 | /* --- long word 4 ---- */ | ||
142 | /* 1. FW offloads, 0: driver handles */ | ||
143 | u8 beacon_offload; | ||
144 | /* 2. FW offloads, 0: driver handles */ | ||
145 | u8 mlme_offload; | ||
146 | /* 3. FW offloads, 0: driver handles */ | ||
147 | u8 hwpc_offload; | ||
148 | /* 4. FW offloads, 0: driver handles */ | ||
149 | u8 tcp_checksum_offload; | ||
150 | /* 5. FW offloads, 0: driver handles */ | ||
151 | u8 tcp_offload; | ||
152 | /* 6. FW offloads, 0: driver handles */ | ||
153 | u8 ps_control_offload; | ||
154 | /* 7. FW offloads, 0: driver handles */ | ||
155 | u8 wwlan_offload; | ||
156 | u8 rsvd040; | ||
157 | |||
158 | /* --- long word 5 ---- */ | ||
159 | /* tcp tx packet length low byte */ | ||
160 | u8 tcp_tx_frame_len_L; | ||
161 | /* tcp tx packet length high byte */ | ||
162 | u8 tcp_tx_frame_len_H; | ||
163 | /* tcp rx packet length low byte */ | ||
164 | u8 tcp_rx_frame_len_L; | ||
165 | /* tcp rx packet length high byte */ | ||
166 | u8 tcp_rx_frame_len_H; | ||
167 | u8 rsvd050; | ||
168 | u8 rsvd051; | ||
169 | u8 rsvd052; | ||
170 | u8 rsvd053; | ||
171 | }; | ||
172 | |||
173 | /* 8-byte alinment required */ | ||
174 | struct fw_hdr { | ||
175 | |||
176 | /* --- LONG WORD 0 ---- */ | ||
177 | u16 signature; | ||
178 | /* 0x8000 ~ 0x8FFF for FPGA version, | ||
179 | * 0x0000 ~ 0x7FFF for ASIC version, */ | ||
180 | u16 version; | ||
181 | /* define the size of boot loader */ | ||
182 | u32 dmem_size; | ||
183 | |||
184 | |||
185 | /* --- LONG WORD 1 ---- */ | ||
186 | /* define the size of FW in IMEM */ | ||
187 | u32 img_imem_size; | ||
188 | /* define the size of FW in SRAM */ | ||
189 | u32 img_sram_size; | ||
190 | |||
191 | /* --- LONG WORD 2 ---- */ | ||
192 | /* define the size of DMEM variable */ | ||
193 | u32 fw_priv_size; | ||
194 | u32 rsvd0; | ||
195 | |||
196 | /* --- LONG WORD 3 ---- */ | ||
197 | u32 rsvd1; | ||
198 | u32 rsvd2; | ||
199 | |||
200 | struct fw_priv fwpriv; | ||
201 | |||
202 | } ; | ||
203 | |||
204 | enum fw_status { | ||
205 | FW_STATUS_INIT = 0, | ||
206 | FW_STATUS_LOAD_IMEM = 1, | ||
207 | FW_STATUS_LOAD_EMEM = 2, | ||
208 | FW_STATUS_LOAD_DMEM = 3, | ||
209 | FW_STATUS_READY = 4, | ||
210 | }; | ||
211 | |||
212 | struct rt_firmware { | ||
213 | struct fw_hdr *pfwheader; | ||
214 | enum fw_status fwstatus; | ||
215 | u16 firmwareversion; | ||
216 | u8 fw_imem[RTL8190_MAX_FIRMWARE_CODE_SIZE]; | ||
217 | u8 fw_emem[RTL8190_MAX_FIRMWARE_CODE_SIZE]; | ||
218 | u32 fw_imem_len; | ||
219 | u32 fw_emem_len; | ||
220 | u8 sz_fw_tmpbuffer[164000]; | ||
221 | u32 sz_fw_tmpbufferlen; | ||
222 | u16 cmdpacket_fragthresold; | ||
223 | }; | ||
224 | |||
225 | struct h2c_set_pwrmode_parm { | ||
226 | u8 mode; | ||
227 | u8 flag_low_traffic_en; | ||
228 | u8 flag_lpnav_en; | ||
229 | u8 flag_rf_low_snr_en; | ||
230 | /* 1: dps, 0: 32k */ | ||
231 | u8 flag_dps_en; | ||
232 | u8 bcn_rx_en; | ||
233 | u8 bcn_pass_cnt; | ||
234 | /* beacon TO (ms). ¡§=0¡¨ no limit. */ | ||
235 | u8 bcn_to; | ||
236 | u16 bcn_itv; | ||
237 | /* only for VOIP mode. */ | ||
238 | u8 app_itv; | ||
239 | u8 awake_bcn_itvl; | ||
240 | u8 smart_ps; | ||
241 | /* unit: 100 ms */ | ||
242 | u8 bcn_pass_period; | ||
243 | }; | ||
244 | |||
245 | struct h2c_joinbss_rpt_parm { | ||
246 | u8 opmode; | ||
247 | u8 ps_qos_info; | ||
248 | u8 bssid[6]; | ||
249 | u16 bcnitv; | ||
250 | u16 aid; | ||
251 | } ; | ||
252 | |||
253 | struct h2c_wpa_ptk { | ||
254 | /* EAPOL-Key Key Confirmation Key (KCK) */ | ||
255 | u8 kck[16]; | ||
256 | /* EAPOL-Key Key Encryption Key (KEK) */ | ||
257 | u8 kek[16]; | ||
258 | /* Temporal Key 1 (TK1) */ | ||
259 | u8 tk1[16]; | ||
260 | union { | ||
261 | /* Temporal Key 2 (TK2) */ | ||
262 | u8 tk2[16]; | ||
263 | struct { | ||
264 | u8 tx_mic_key[8]; | ||
265 | u8 rx_mic_key[8]; | ||
266 | } athu; | ||
267 | } u; | ||
268 | }; | ||
269 | |||
270 | struct h2c_wpa_two_way_parm { | ||
271 | /* algorithm TKIP or AES */ | ||
272 | u8 pairwise_en_alg; | ||
273 | u8 group_en_alg; | ||
274 | struct h2c_wpa_ptk wpa_ptk_value; | ||
275 | } ; | ||
276 | |||
277 | enum h2c_cmd { | ||
278 | FW_H2C_SETPWRMODE = 0, | ||
279 | FW_H2C_JOINBSSRPT = 1, | ||
280 | FW_H2C_WOWLAN_UPDATE_GTK = 2, | ||
281 | FW_H2C_WOWLAN_UPDATE_IV = 3, | ||
282 | FW_H2C_WOWLAN_OFFLOAD = 4, | ||
283 | }; | ||
284 | |||
285 | enum fw_h2c_cmd { | ||
286 | H2C_READ_MACREG_CMD, /*0*/ | ||
287 | H2C_WRITE_MACREG_CMD, | ||
288 | H2C_READBB_CMD, | ||
289 | H2C_WRITEBB_CMD, | ||
290 | H2C_READRF_CMD, | ||
291 | H2C_WRITERF_CMD, /*5*/ | ||
292 | H2C_READ_EEPROM_CMD, | ||
293 | H2C_WRITE_EEPROM_CMD, | ||
294 | H2C_READ_EFUSE_CMD, | ||
295 | H2C_WRITE_EFUSE_CMD, | ||
296 | H2C_READ_CAM_CMD, /*10*/ | ||
297 | H2C_WRITE_CAM_CMD, | ||
298 | H2C_SETBCNITV_CMD, | ||
299 | H2C_SETMBIDCFG_CMD, | ||
300 | H2C_JOINBSS_CMD, | ||
301 | H2C_DISCONNECT_CMD, /*15*/ | ||
302 | H2C_CREATEBSS_CMD, | ||
303 | H2C_SETOPMode_CMD, | ||
304 | H2C_SITESURVEY_CMD, | ||
305 | H2C_SETAUTH_CMD, | ||
306 | H2C_SETKEY_CMD, /*20*/ | ||
307 | H2C_SETSTAKEY_CMD, | ||
308 | H2C_SETASSOCSTA_CMD, | ||
309 | H2C_DELASSOCSTA_CMD, | ||
310 | H2C_SETSTAPWRSTATE_CMD, | ||
311 | H2C_SETBASICRATE_CMD, /*25*/ | ||
312 | H2C_GETBASICRATE_CMD, | ||
313 | H2C_SETDATARATE_CMD, | ||
314 | H2C_GETDATARATE_CMD, | ||
315 | H2C_SETPHYINFO_CMD, | ||
316 | H2C_GETPHYINFO_CMD, /*30*/ | ||
317 | H2C_SETPHY_CMD, | ||
318 | H2C_GETPHY_CMD, | ||
319 | H2C_READRSSI_CMD, | ||
320 | H2C_READGAIN_CMD, | ||
321 | H2C_SETATIM_CMD, /*35*/ | ||
322 | H2C_SETPWRMODE_CMD, | ||
323 | H2C_JOINBSSRPT_CMD, | ||
324 | H2C_SETRATABLE_CMD, | ||
325 | H2C_GETRATABLE_CMD, | ||
326 | H2C_GETCCXREPORT_CMD, /*40*/ | ||
327 | H2C_GETDTMREPORT_CMD, | ||
328 | H2C_GETTXRATESTATICS_CMD, | ||
329 | H2C_SETUSBSUSPEND_CMD, | ||
330 | H2C_SETH2CLBK_CMD, | ||
331 | H2C_TMP1, /*45*/ | ||
332 | H2C_WOWLAN_UPDATE_GTK_CMD, | ||
333 | H2C_WOWLAN_FW_OFFLOAD, | ||
334 | H2C_TMP2, | ||
335 | H2C_TMP3, | ||
336 | H2C_WOWLAN_UPDATE_IV_CMD, /*50*/ | ||
337 | H2C_TMP4, | ||
338 | MAX_H2CCMD /*52*/ | ||
339 | }; | ||
340 | |||
341 | /* The following macros are used for FW | ||
342 | * CMD map and parameter updated. */ | ||
343 | #define FW_CMD_IO_CLR(rtlpriv, _Bit) \ | ||
344 | do { \ | ||
345 | udelay(1000); \ | ||
346 | rtlpriv->rtlhal.fwcmd_iomap &= (~_Bit); \ | ||
347 | } while (0); | ||
348 | |||
349 | #define FW_CMD_IO_UPDATE(rtlpriv, _val) \ | ||
350 | rtlpriv->rtlhal.fwcmd_iomap = _val; | ||
351 | |||
352 | #define FW_CMD_IO_SET(rtlpriv, _val) \ | ||
353 | do { \ | ||
354 | rtl_write_word(rtlpriv, LBUS_MON_ADDR, (u16)_val); \ | ||
355 | FW_CMD_IO_UPDATE(rtlpriv, _val); \ | ||
356 | } while (0); | ||
357 | |||
358 | #define FW_CMD_PARA_SET(rtlpriv, _val) \ | ||
359 | do { \ | ||
360 | rtl_write_dword(rtlpriv, LBUS_ADDR_MASK, _val); \ | ||
361 | rtlpriv->rtlhal.fwcmd_ioparam = _val; \ | ||
362 | } while (0); | ||
363 | |||
364 | #define FW_CMD_IO_QUERY(rtlpriv) \ | ||
365 | (u16)(rtlpriv->rtlhal.fwcmd_iomap) | ||
366 | #define FW_CMD_IO_PARA_QUERY(rtlpriv) \ | ||
367 | ((u32)(rtlpriv->rtlhal.fwcmd_ioparam)) | ||
368 | |||
369 | int rtl92s_download_fw(struct ieee80211_hw *hw); | ||
370 | void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); | ||
371 | void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, | ||
372 | u8 mstatus, u8 ps_qosinfo); | ||
373 | |||
374 | #endif | ||
375 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c new file mode 100644 index 000000000000..2e9005d0454b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c | |||
@@ -0,0 +1,2512 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../efuse.h" | ||
32 | #include "../base.h" | ||
33 | #include "../regd.h" | ||
34 | #include "../cam.h" | ||
35 | #include "../ps.h" | ||
36 | #include "../pci.h" | ||
37 | #include "reg.h" | ||
38 | #include "def.h" | ||
39 | #include "phy.h" | ||
40 | #include "dm.h" | ||
41 | #include "fw.h" | ||
42 | #include "led.h" | ||
43 | #include "hw.h" | ||
44 | |||
45 | void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | ||
46 | { | ||
47 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
48 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
49 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
50 | |||
51 | switch (variable) { | ||
52 | case HW_VAR_RCR: { | ||
53 | *((u32 *) (val)) = rtlpci->receive_config; | ||
54 | break; | ||
55 | } | ||
56 | case HW_VAR_RF_STATE: { | ||
57 | *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; | ||
58 | break; | ||
59 | } | ||
60 | case HW_VAR_FW_PSMODE_STATUS: { | ||
61 | *((bool *) (val)) = ppsc->fw_current_inpsmode; | ||
62 | break; | ||
63 | } | ||
64 | case HW_VAR_CORRECT_TSF: { | ||
65 | u64 tsf; | ||
66 | u32 *ptsf_low = (u32 *)&tsf; | ||
67 | u32 *ptsf_high = ((u32 *)&tsf) + 1; | ||
68 | |||
69 | *ptsf_high = rtl_read_dword(rtlpriv, (TSFR + 4)); | ||
70 | *ptsf_low = rtl_read_dword(rtlpriv, TSFR); | ||
71 | |||
72 | *((u64 *) (val)) = tsf; | ||
73 | |||
74 | break; | ||
75 | } | ||
76 | case HW_VAR_MRC: { | ||
77 | *((bool *)(val)) = rtlpriv->dm.current_mrc_switch; | ||
78 | break; | ||
79 | } | ||
80 | default: { | ||
81 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
82 | ("switch case not process\n")); | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | |||
88 | void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | ||
89 | { | ||
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 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
94 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
95 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
96 | |||
97 | switch (variable) { | ||
98 | case HW_VAR_ETHER_ADDR:{ | ||
99 | rtl_write_dword(rtlpriv, IDR0, ((u32 *)(val))[0]); | ||
100 | rtl_write_word(rtlpriv, IDR4, ((u16 *)(val + 4))[0]); | ||
101 | break; | ||
102 | } | ||
103 | case HW_VAR_BASIC_RATE:{ | ||
104 | u16 rate_cfg = ((u16 *) val)[0]; | ||
105 | u8 rate_index = 0; | ||
106 | |||
107 | if (rtlhal->version == VERSION_8192S_ACUT) | ||
108 | rate_cfg = rate_cfg & 0x150; | ||
109 | else | ||
110 | rate_cfg = rate_cfg & 0x15f; | ||
111 | |||
112 | rate_cfg |= 0x01; | ||
113 | |||
114 | rtl_write_byte(rtlpriv, RRSR, rate_cfg & 0xff); | ||
115 | rtl_write_byte(rtlpriv, RRSR + 1, | ||
116 | (rate_cfg >> 8) & 0xff); | ||
117 | |||
118 | while (rate_cfg > 0x1) { | ||
119 | rate_cfg = (rate_cfg >> 1); | ||
120 | rate_index++; | ||
121 | } | ||
122 | rtl_write_byte(rtlpriv, INIRTSMCS_SEL, rate_index); | ||
123 | |||
124 | break; | ||
125 | } | ||
126 | case HW_VAR_BSSID:{ | ||
127 | rtl_write_dword(rtlpriv, BSSIDR, ((u32 *)(val))[0]); | ||
128 | rtl_write_word(rtlpriv, BSSIDR + 4, | ||
129 | ((u16 *)(val + 4))[0]); | ||
130 | break; | ||
131 | } | ||
132 | case HW_VAR_SIFS:{ | ||
133 | rtl_write_byte(rtlpriv, SIFS_OFDM, val[0]); | ||
134 | rtl_write_byte(rtlpriv, SIFS_OFDM + 1, val[1]); | ||
135 | break; | ||
136 | } | ||
137 | case HW_VAR_SLOT_TIME:{ | ||
138 | u8 e_aci; | ||
139 | |||
140 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
141 | ("HW_VAR_SLOT_TIME %x\n", val[0])); | ||
142 | |||
143 | rtl_write_byte(rtlpriv, SLOT_TIME, val[0]); | ||
144 | |||
145 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { | ||
146 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
147 | HW_VAR_AC_PARAM, | ||
148 | (u8 *)(&e_aci)); | ||
149 | } | ||
150 | break; | ||
151 | } | ||
152 | case HW_VAR_ACK_PREAMBLE:{ | ||
153 | u8 reg_tmp; | ||
154 | u8 short_preamble = (bool) (*(u8 *) val); | ||
155 | reg_tmp = (mac->cur_40_prime_sc) << 5; | ||
156 | if (short_preamble) | ||
157 | reg_tmp |= 0x80; | ||
158 | |||
159 | rtl_write_byte(rtlpriv, RRSR + 2, reg_tmp); | ||
160 | break; | ||
161 | } | ||
162 | case HW_VAR_AMPDU_MIN_SPACE:{ | ||
163 | u8 min_spacing_to_set; | ||
164 | u8 sec_min_space; | ||
165 | |||
166 | min_spacing_to_set = *((u8 *)val); | ||
167 | if (min_spacing_to_set <= 7) { | ||
168 | if (rtlpriv->sec.pairwise_enc_algorithm == | ||
169 | NO_ENCRYPTION) | ||
170 | sec_min_space = 0; | ||
171 | else | ||
172 | sec_min_space = 1; | ||
173 | |||
174 | if (min_spacing_to_set < sec_min_space) | ||
175 | min_spacing_to_set = sec_min_space; | ||
176 | if (min_spacing_to_set > 5) | ||
177 | min_spacing_to_set = 5; | ||
178 | |||
179 | mac->min_space_cfg = | ||
180 | ((mac->min_space_cfg & 0xf8) | | ||
181 | min_spacing_to_set); | ||
182 | |||
183 | *val = min_spacing_to_set; | ||
184 | |||
185 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
186 | ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", | ||
187 | mac->min_space_cfg)); | ||
188 | |||
189 | rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, | ||
190 | mac->min_space_cfg); | ||
191 | } | ||
192 | break; | ||
193 | } | ||
194 | case HW_VAR_SHORTGI_DENSITY:{ | ||
195 | u8 density_to_set; | ||
196 | |||
197 | density_to_set = *((u8 *) val); | ||
198 | mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; | ||
199 | mac->min_space_cfg |= (density_to_set << 3); | ||
200 | |||
201 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
202 | ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", | ||
203 | mac->min_space_cfg)); | ||
204 | |||
205 | rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, | ||
206 | mac->min_space_cfg); | ||
207 | |||
208 | break; | ||
209 | } | ||
210 | case HW_VAR_AMPDU_FACTOR:{ | ||
211 | u8 factor_toset; | ||
212 | u8 regtoset; | ||
213 | u8 factorlevel[18] = { | ||
214 | 2, 4, 4, 7, 7, 13, 13, | ||
215 | 13, 2, 7, 7, 13, 13, | ||
216 | 15, 15, 15, 15, 0}; | ||
217 | u8 index = 0; | ||
218 | |||
219 | factor_toset = *((u8 *) val); | ||
220 | if (factor_toset <= 3) { | ||
221 | factor_toset = (1 << (factor_toset + 2)); | ||
222 | if (factor_toset > 0xf) | ||
223 | factor_toset = 0xf; | ||
224 | |||
225 | for (index = 0; index < 17; index++) { | ||
226 | if (factorlevel[index] > factor_toset) | ||
227 | factorlevel[index] = | ||
228 | factor_toset; | ||
229 | } | ||
230 | |||
231 | for (index = 0; index < 8; index++) { | ||
232 | regtoset = ((factorlevel[index * 2]) | | ||
233 | (factorlevel[index * | ||
234 | 2 + 1] << 4)); | ||
235 | rtl_write_byte(rtlpriv, | ||
236 | AGGLEN_LMT_L + index, | ||
237 | regtoset); | ||
238 | } | ||
239 | |||
240 | regtoset = ((factorlevel[16]) | | ||
241 | (factorlevel[17] << 4)); | ||
242 | rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset); | ||
243 | |||
244 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
245 | ("Set HW_VAR_AMPDU_FACTOR: %#x\n", | ||
246 | factor_toset)); | ||
247 | } | ||
248 | break; | ||
249 | } | ||
250 | case HW_VAR_AC_PARAM:{ | ||
251 | u8 e_aci = *((u8 *) val); | ||
252 | rtl92s_dm_init_edca_turbo(hw); | ||
253 | |||
254 | if (rtlpci->acm_method != eAcmWay2_SW) | ||
255 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
256 | HW_VAR_ACM_CTRL, | ||
257 | (u8 *)(&e_aci)); | ||
258 | break; | ||
259 | } | ||
260 | case HW_VAR_ACM_CTRL:{ | ||
261 | u8 e_aci = *((u8 *) val); | ||
262 | union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&( | ||
263 | mac->ac[0].aifs)); | ||
264 | u8 acm = p_aci_aifsn->f.acm; | ||
265 | u8 acm_ctrl = rtl_read_byte(rtlpriv, AcmHwCtrl); | ||
266 | |||
267 | acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? | ||
268 | 0x0 : 0x1); | ||
269 | |||
270 | if (acm) { | ||
271 | switch (e_aci) { | ||
272 | case AC0_BE: | ||
273 | acm_ctrl |= AcmHw_BeqEn; | ||
274 | break; | ||
275 | case AC2_VI: | ||
276 | acm_ctrl |= AcmHw_ViqEn; | ||
277 | break; | ||
278 | case AC3_VO: | ||
279 | acm_ctrl |= AcmHw_VoqEn; | ||
280 | break; | ||
281 | default: | ||
282 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
283 | ("HW_VAR_ACM_CTRL acm set " | ||
284 | "failed: eACI is %d\n", acm)); | ||
285 | break; | ||
286 | } | ||
287 | } else { | ||
288 | switch (e_aci) { | ||
289 | case AC0_BE: | ||
290 | acm_ctrl &= (~AcmHw_BeqEn); | ||
291 | break; | ||
292 | case AC2_VI: | ||
293 | acm_ctrl &= (~AcmHw_ViqEn); | ||
294 | break; | ||
295 | case AC3_VO: | ||
296 | acm_ctrl &= (~AcmHw_BeqEn); | ||
297 | break; | ||
298 | default: | ||
299 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
300 | ("switch case not process\n")); | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, | ||
306 | ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl)); | ||
307 | rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl); | ||
308 | break; | ||
309 | } | ||
310 | case HW_VAR_RCR:{ | ||
311 | rtl_write_dword(rtlpriv, RCR, ((u32 *) (val))[0]); | ||
312 | rtlpci->receive_config = ((u32 *) (val))[0]; | ||
313 | break; | ||
314 | } | ||
315 | case HW_VAR_RETRY_LIMIT:{ | ||
316 | u8 retry_limit = ((u8 *) (val))[0]; | ||
317 | |||
318 | rtl_write_word(rtlpriv, RETRY_LIMIT, | ||
319 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | ||
320 | retry_limit << RETRY_LIMIT_LONG_SHIFT); | ||
321 | break; | ||
322 | } | ||
323 | case HW_VAR_DUAL_TSF_RST: { | ||
324 | break; | ||
325 | } | ||
326 | case HW_VAR_EFUSE_BYTES: { | ||
327 | rtlefuse->efuse_usedbytes = *((u16 *) val); | ||
328 | break; | ||
329 | } | ||
330 | case HW_VAR_EFUSE_USAGE: { | ||
331 | rtlefuse->efuse_usedpercentage = *((u8 *) val); | ||
332 | break; | ||
333 | } | ||
334 | case HW_VAR_IO_CMD: { | ||
335 | break; | ||
336 | } | ||
337 | case HW_VAR_WPA_CONFIG: { | ||
338 | rtl_write_byte(rtlpriv, REG_SECR, *((u8 *) val)); | ||
339 | break; | ||
340 | } | ||
341 | case HW_VAR_SET_RPWM:{ | ||
342 | break; | ||
343 | } | ||
344 | case HW_VAR_H2C_FW_PWRMODE:{ | ||
345 | break; | ||
346 | } | ||
347 | case HW_VAR_FW_PSMODE_STATUS: { | ||
348 | ppsc->fw_current_inpsmode = *((bool *) val); | ||
349 | break; | ||
350 | } | ||
351 | case HW_VAR_H2C_FW_JOINBSSRPT:{ | ||
352 | break; | ||
353 | } | ||
354 | case HW_VAR_AID:{ | ||
355 | break; | ||
356 | } | ||
357 | case HW_VAR_CORRECT_TSF:{ | ||
358 | break; | ||
359 | } | ||
360 | case HW_VAR_MRC: { | ||
361 | bool bmrc_toset = *((bool *)val); | ||
362 | u8 u1bdata = 0; | ||
363 | |||
364 | if (bmrc_toset) { | ||
365 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
366 | MASKBYTE0, 0x33); | ||
367 | u1bdata = (u8)rtl_get_bbreg(hw, | ||
368 | ROFDM1_TRXPATHENABLE, | ||
369 | MASKBYTE0); | ||
370 | rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, | ||
371 | MASKBYTE0, | ||
372 | ((u1bdata & 0xf0) | 0x03)); | ||
373 | u1bdata = (u8)rtl_get_bbreg(hw, | ||
374 | ROFDM0_TRXPATHENABLE, | ||
375 | MASKBYTE1); | ||
376 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
377 | MASKBYTE1, | ||
378 | (u1bdata | 0x04)); | ||
379 | |||
380 | /* Update current settings. */ | ||
381 | rtlpriv->dm.current_mrc_switch = bmrc_toset; | ||
382 | } else { | ||
383 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
384 | MASKBYTE0, 0x13); | ||
385 | u1bdata = (u8)rtl_get_bbreg(hw, | ||
386 | ROFDM1_TRXPATHENABLE, | ||
387 | MASKBYTE0); | ||
388 | rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, | ||
389 | MASKBYTE0, | ||
390 | ((u1bdata & 0xf0) | 0x01)); | ||
391 | u1bdata = (u8)rtl_get_bbreg(hw, | ||
392 | ROFDM0_TRXPATHENABLE, | ||
393 | MASKBYTE1); | ||
394 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
395 | MASKBYTE1, (u1bdata & 0xfb)); | ||
396 | |||
397 | /* Update current settings. */ | ||
398 | rtlpriv->dm.current_mrc_switch = bmrc_toset; | ||
399 | } | ||
400 | |||
401 | break; | ||
402 | } | ||
403 | default: | ||
404 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
405 | ("switch case not process\n")); | ||
406 | break; | ||
407 | } | ||
408 | |||
409 | } | ||
410 | |||
411 | void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) | ||
412 | { | ||
413 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
414 | u8 sec_reg_value = 0x0; | ||
415 | |||
416 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d " | ||
417 | "GroupEncAlgorithm = %d\n", | ||
418 | rtlpriv->sec.pairwise_enc_algorithm, | ||
419 | rtlpriv->sec.group_enc_algorithm)); | ||
420 | |||
421 | if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { | ||
422 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
423 | ("not open hw encryption\n")); | ||
424 | return; | ||
425 | } | ||
426 | |||
427 | sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; | ||
428 | |||
429 | if (rtlpriv->sec.use_defaultkey) { | ||
430 | sec_reg_value |= SCR_TXUSEDK; | ||
431 | sec_reg_value |= SCR_RXUSEDK; | ||
432 | } | ||
433 | |||
434 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n", | ||
435 | sec_reg_value)); | ||
436 | |||
437 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); | ||
438 | |||
439 | } | ||
440 | |||
441 | static u8 _rtl92ce_halset_sysclk(struct ieee80211_hw *hw, u8 data) | ||
442 | { | ||
443 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
444 | u8 waitcount = 100; | ||
445 | bool bresult = false; | ||
446 | u8 tmpvalue; | ||
447 | |||
448 | rtl_write_byte(rtlpriv, SYS_CLKR + 1, data); | ||
449 | |||
450 | /* Wait the MAC synchronized. */ | ||
451 | udelay(400); | ||
452 | |||
453 | /* Check if it is set ready. */ | ||
454 | tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1); | ||
455 | bresult = ((tmpvalue & BIT(7)) == (data & BIT(7))); | ||
456 | |||
457 | if ((data & (BIT(6) | BIT(7))) == false) { | ||
458 | waitcount = 100; | ||
459 | tmpvalue = 0; | ||
460 | |||
461 | while (1) { | ||
462 | waitcount--; | ||
463 | |||
464 | tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1); | ||
465 | if ((tmpvalue & BIT(6))) | ||
466 | break; | ||
467 | |||
468 | printk(KERN_ERR "wait for BIT(6) return value %x\n", | ||
469 | tmpvalue); | ||
470 | if (waitcount == 0) | ||
471 | break; | ||
472 | |||
473 | udelay(10); | ||
474 | } | ||
475 | |||
476 | if (waitcount == 0) | ||
477 | bresult = false; | ||
478 | else | ||
479 | bresult = true; | ||
480 | } | ||
481 | |||
482 | return bresult; | ||
483 | } | ||
484 | |||
485 | void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw) | ||
486 | { | ||
487 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
488 | u8 u1tmp; | ||
489 | |||
490 | /* The following config GPIO function */ | ||
491 | rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO)); | ||
492 | u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL); | ||
493 | |||
494 | /* config GPIO3 to input */ | ||
495 | u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK; | ||
496 | rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp); | ||
497 | |||
498 | } | ||
499 | |||
500 | static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw) | ||
501 | { | ||
502 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
503 | u8 u1tmp; | ||
504 | u8 retval = ERFON; | ||
505 | |||
506 | /* The following config GPIO function */ | ||
507 | rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO)); | ||
508 | u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL); | ||
509 | |||
510 | /* config GPIO3 to input */ | ||
511 | u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK; | ||
512 | rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp); | ||
513 | |||
514 | /* On some of the platform, driver cannot read correct | ||
515 | * value without delay between Write_GPIO_SEL and Read_GPIO_IN */ | ||
516 | mdelay(10); | ||
517 | |||
518 | /* check GPIO3 */ | ||
519 | u1tmp = rtl_read_byte(rtlpriv, GPIO_IN); | ||
520 | retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF; | ||
521 | |||
522 | return retval; | ||
523 | } | ||
524 | |||
525 | static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw) | ||
526 | { | ||
527 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
528 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
529 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
530 | |||
531 | u8 i; | ||
532 | u8 tmpu1b; | ||
533 | u16 tmpu2b; | ||
534 | u8 pollingcnt = 20; | ||
535 | |||
536 | if (rtlpci->first_init) { | ||
537 | /* Reset PCIE Digital */ | ||
538 | tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); | ||
539 | tmpu1b &= 0xFE; | ||
540 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b); | ||
541 | udelay(1); | ||
542 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b | BIT(0)); | ||
543 | } | ||
544 | |||
545 | /* Switch to SW IO control */ | ||
546 | tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); | ||
547 | if (tmpu1b & BIT(7)) { | ||
548 | tmpu1b &= ~(BIT(6) | BIT(7)); | ||
549 | |||
550 | /* Set failed, return to prevent hang. */ | ||
551 | if (!_rtl92ce_halset_sysclk(hw, tmpu1b)) | ||
552 | return; | ||
553 | } | ||
554 | |||
555 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0); | ||
556 | udelay(50); | ||
557 | rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); | ||
558 | udelay(50); | ||
559 | |||
560 | /* Clear FW RPWM for FW control LPS.*/ | ||
561 | rtl_write_byte(rtlpriv, RPWM, 0x0); | ||
562 | |||
563 | /* Reset MAC-IO and CPU and Core Digital BIT(10)/11/15 */ | ||
564 | tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); | ||
565 | tmpu1b &= 0x73; | ||
566 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b); | ||
567 | /* wait for BIT 10/11/15 to pull high automatically!! */ | ||
568 | mdelay(1); | ||
569 | |||
570 | rtl_write_byte(rtlpriv, CMDR, 0); | ||
571 | rtl_write_byte(rtlpriv, TCR, 0); | ||
572 | |||
573 | /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */ | ||
574 | tmpu1b = rtl_read_byte(rtlpriv, 0x562); | ||
575 | tmpu1b |= 0x08; | ||
576 | rtl_write_byte(rtlpriv, 0x562, tmpu1b); | ||
577 | tmpu1b &= ~(BIT(3)); | ||
578 | rtl_write_byte(rtlpriv, 0x562, tmpu1b); | ||
579 | |||
580 | /* Enable AFE clock source */ | ||
581 | tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL); | ||
582 | rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01)); | ||
583 | /* Delay 1.5ms */ | ||
584 | mdelay(2); | ||
585 | tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1); | ||
586 | rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb)); | ||
587 | |||
588 | /* Enable AFE Macro Block's Bandgap */ | ||
589 | tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); | ||
590 | rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0))); | ||
591 | mdelay(1); | ||
592 | |||
593 | /* Enable AFE Mbias */ | ||
594 | tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); | ||
595 | rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02)); | ||
596 | mdelay(1); | ||
597 | |||
598 | /* Enable LDOA15 block */ | ||
599 | tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL); | ||
600 | rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0))); | ||
601 | |||
602 | /* Set Digital Vdd to Retention isolation Path. */ | ||
603 | tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); | ||
604 | rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11))); | ||
605 | |||
606 | /* For warm reboot NIC disappera bug. */ | ||
607 | tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | ||
608 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13))); | ||
609 | |||
610 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68); | ||
611 | |||
612 | /* Enable AFE PLL Macro Block */ | ||
613 | /* We need to delay 100u before enabling PLL. */ | ||
614 | udelay(200); | ||
615 | tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL); | ||
616 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); | ||
617 | |||
618 | /* for divider reset */ | ||
619 | udelay(100); | ||
620 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | | ||
621 | BIT(4) | BIT(6))); | ||
622 | udelay(10); | ||
623 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); | ||
624 | udelay(10); | ||
625 | |||
626 | /* Enable MAC 80MHZ clock */ | ||
627 | tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1); | ||
628 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0))); | ||
629 | mdelay(1); | ||
630 | |||
631 | /* Release isolation AFE PLL & MD */ | ||
632 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6); | ||
633 | |||
634 | /* Enable MAC clock */ | ||
635 | tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); | ||
636 | rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11))); | ||
637 | |||
638 | /* Enable Core digital and enable IOREG R/W */ | ||
639 | tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | ||
640 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11))); | ||
641 | |||
642 | tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); | ||
643 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b & ~(BIT(7))); | ||
644 | |||
645 | /* enable REG_EN */ | ||
646 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15))); | ||
647 | |||
648 | /* Switch the control path. */ | ||
649 | tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); | ||
650 | rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2)))); | ||
651 | |||
652 | tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); | ||
653 | tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6))); | ||
654 | if (!_rtl92ce_halset_sysclk(hw, tmpu1b)) | ||
655 | return; /* Set failed, return to prevent hang. */ | ||
656 | |||
657 | rtl_write_word(rtlpriv, CMDR, 0x07FC); | ||
658 | |||
659 | /* MH We must enable the section of code to prevent load IMEM fail. */ | ||
660 | /* Load MAC register from WMAc temporarily We simulate macreg. */ | ||
661 | /* txt HW will provide MAC txt later */ | ||
662 | rtl_write_byte(rtlpriv, 0x6, 0x30); | ||
663 | rtl_write_byte(rtlpriv, 0x49, 0xf0); | ||
664 | |||
665 | rtl_write_byte(rtlpriv, 0x4b, 0x81); | ||
666 | |||
667 | rtl_write_byte(rtlpriv, 0xb5, 0x21); | ||
668 | |||
669 | rtl_write_byte(rtlpriv, 0xdc, 0xff); | ||
670 | rtl_write_byte(rtlpriv, 0xdd, 0xff); | ||
671 | rtl_write_byte(rtlpriv, 0xde, 0xff); | ||
672 | rtl_write_byte(rtlpriv, 0xdf, 0xff); | ||
673 | |||
674 | rtl_write_byte(rtlpriv, 0x11a, 0x00); | ||
675 | rtl_write_byte(rtlpriv, 0x11b, 0x00); | ||
676 | |||
677 | for (i = 0; i < 32; i++) | ||
678 | rtl_write_byte(rtlpriv, INIMCS_SEL + i, 0x1b); | ||
679 | |||
680 | rtl_write_byte(rtlpriv, 0x236, 0xff); | ||
681 | |||
682 | rtl_write_byte(rtlpriv, 0x503, 0x22); | ||
683 | |||
684 | if (ppsc->support_aspm && !ppsc->support_backdoor) | ||
685 | rtl_write_byte(rtlpriv, 0x560, 0x40); | ||
686 | else | ||
687 | rtl_write_byte(rtlpriv, 0x560, 0x00); | ||
688 | |||
689 | rtl_write_byte(rtlpriv, DBG_PORT, 0x91); | ||
690 | |||
691 | /* Set RX Desc Address */ | ||
692 | rtl_write_dword(rtlpriv, RDQDA, rtlpci->rx_ring[RX_MPDU_QUEUE].dma); | ||
693 | rtl_write_dword(rtlpriv, RCDA, rtlpci->rx_ring[RX_CMD_QUEUE].dma); | ||
694 | |||
695 | /* Set TX Desc Address */ | ||
696 | rtl_write_dword(rtlpriv, TBKDA, rtlpci->tx_ring[BK_QUEUE].dma); | ||
697 | rtl_write_dword(rtlpriv, TBEDA, rtlpci->tx_ring[BE_QUEUE].dma); | ||
698 | rtl_write_dword(rtlpriv, TVIDA, rtlpci->tx_ring[VI_QUEUE].dma); | ||
699 | rtl_write_dword(rtlpriv, TVODA, rtlpci->tx_ring[VO_QUEUE].dma); | ||
700 | rtl_write_dword(rtlpriv, TBDA, rtlpci->tx_ring[BEACON_QUEUE].dma); | ||
701 | rtl_write_dword(rtlpriv, TCDA, rtlpci->tx_ring[TXCMD_QUEUE].dma); | ||
702 | rtl_write_dword(rtlpriv, TMDA, rtlpci->tx_ring[MGNT_QUEUE].dma); | ||
703 | rtl_write_dword(rtlpriv, THPDA, rtlpci->tx_ring[HIGH_QUEUE].dma); | ||
704 | rtl_write_dword(rtlpriv, HDA, rtlpci->tx_ring[HCCA_QUEUE].dma); | ||
705 | |||
706 | rtl_write_word(rtlpriv, CMDR, 0x37FC); | ||
707 | |||
708 | /* To make sure that TxDMA can ready to download FW. */ | ||
709 | /* We should reset TxDMA if IMEM RPT was not ready. */ | ||
710 | do { | ||
711 | tmpu1b = rtl_read_byte(rtlpriv, TCR); | ||
712 | if ((tmpu1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE) | ||
713 | break; | ||
714 | |||
715 | udelay(5); | ||
716 | } while (pollingcnt--); | ||
717 | |||
718 | if (pollingcnt <= 0) { | ||
719 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
720 | ("Polling TXDMA_INIT_VALUE " | ||
721 | "timeout!! Current TCR(%#x)\n", tmpu1b)); | ||
722 | tmpu1b = rtl_read_byte(rtlpriv, CMDR); | ||
723 | rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN)); | ||
724 | udelay(2); | ||
725 | /* Reset TxDMA */ | ||
726 | rtl_write_byte(rtlpriv, CMDR, tmpu1b | TXDMA_EN); | ||
727 | } | ||
728 | |||
729 | /* After MACIO reset,we must refresh LED state. */ | ||
730 | if ((ppsc->rfoff_reason == RF_CHANGE_BY_IPS) || | ||
731 | (ppsc->rfoff_reason == 0)) { | ||
732 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
733 | struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); | ||
734 | enum rf_pwrstate rfpwr_state_toset; | ||
735 | rfpwr_state_toset = _rtl92se_rf_onoff_detect(hw); | ||
736 | |||
737 | if (rfpwr_state_toset == ERFON) | ||
738 | rtl92se_sw_led_on(hw, pLed0); | ||
739 | } | ||
740 | } | ||
741 | |||
742 | static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw) | ||
743 | { | ||
744 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
745 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
746 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
747 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
748 | u8 i; | ||
749 | u16 tmpu2b; | ||
750 | |||
751 | /* 1. System Configure Register (Offset: 0x0000 - 0x003F) */ | ||
752 | |||
753 | /* 2. Command Control Register (Offset: 0x0040 - 0x004F) */ | ||
754 | /* Turn on 0x40 Command register */ | ||
755 | rtl_write_word(rtlpriv, CMDR, (BBRSTN | BB_GLB_RSTN | | ||
756 | SCHEDULE_EN | MACRXEN | MACTXEN | DDMA_EN | FW2HW_EN | | ||
757 | RXDMA_EN | TXDMA_EN | HCI_RXDMA_EN | HCI_TXDMA_EN)); | ||
758 | |||
759 | /* Set TCR TX DMA pre 2 FULL enable bit */ | ||
760 | rtl_write_dword(rtlpriv, TCR, rtl_read_dword(rtlpriv, TCR) | | ||
761 | TXDMAPRE2FULL); | ||
762 | |||
763 | /* Set RCR */ | ||
764 | rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config); | ||
765 | |||
766 | /* 3. MACID Setting Register (Offset: 0x0050 - 0x007F) */ | ||
767 | |||
768 | /* 4. Timing Control Register (Offset: 0x0080 - 0x009F) */ | ||
769 | /* Set CCK/OFDM SIFS */ | ||
770 | /* CCK SIFS shall always be 10us. */ | ||
771 | rtl_write_word(rtlpriv, SIFS_CCK, 0x0a0a); | ||
772 | rtl_write_word(rtlpriv, SIFS_OFDM, 0x1010); | ||
773 | |||
774 | /* Set AckTimeout */ | ||
775 | rtl_write_byte(rtlpriv, ACK_TIMEOUT, 0x40); | ||
776 | |||
777 | /* Beacon related */ | ||
778 | rtl_write_word(rtlpriv, BCN_INTERVAL, 100); | ||
779 | rtl_write_word(rtlpriv, ATIMWND, 2); | ||
780 | |||
781 | /* 5. FIFO Control Register (Offset: 0x00A0 - 0x015F) */ | ||
782 | /* 5.1 Initialize Number of Reserved Pages in Firmware Queue */ | ||
783 | /* Firmware allocate now, associate with FW internal setting.!!! */ | ||
784 | |||
785 | /* 5.2 Setting TX/RX page size 0/1/2/3/4=64/128/256/512/1024 */ | ||
786 | /* 5.3 Set driver info, we only accept PHY status now. */ | ||
787 | /* 5.4 Set RXDMA arbitration to control RXDMA/MAC/FW R/W for RXFIFO */ | ||
788 | rtl_write_byte(rtlpriv, RXDMA, rtl_read_byte(rtlpriv, RXDMA) | BIT(6)); | ||
789 | |||
790 | /* 6. Adaptive Control Register (Offset: 0x0160 - 0x01CF) */ | ||
791 | /* Set RRSR to all legacy rate and HT rate | ||
792 | * CCK rate is supported by default. | ||
793 | * CCK rate will be filtered out only when associated | ||
794 | * AP does not support it. | ||
795 | * Only enable ACK rate to OFDM 24M | ||
796 | * Disable RRSR for CCK rate in A-Cut */ | ||
797 | |||
798 | if (rtlhal->version == VERSION_8192S_ACUT) | ||
799 | rtl_write_byte(rtlpriv, RRSR, 0xf0); | ||
800 | else if (rtlhal->version == VERSION_8192S_BCUT) | ||
801 | rtl_write_byte(rtlpriv, RRSR, 0xff); | ||
802 | rtl_write_byte(rtlpriv, RRSR + 1, 0x01); | ||
803 | rtl_write_byte(rtlpriv, RRSR + 2, 0x00); | ||
804 | |||
805 | /* A-Cut IC do not support CCK rate. We forbid ARFR to */ | ||
806 | /* fallback to CCK rate */ | ||
807 | for (i = 0; i < 8; i++) { | ||
808 | /*Disable RRSR for CCK rate in A-Cut */ | ||
809 | if (rtlhal->version == VERSION_8192S_ACUT) | ||
810 | rtl_write_dword(rtlpriv, ARFR0 + i * 4, 0x1f0ff0f0); | ||
811 | } | ||
812 | |||
813 | /* Different rate use different AMPDU size */ | ||
814 | /* MCS32/ MCS15_SG use max AMPDU size 15*2=30K */ | ||
815 | rtl_write_byte(rtlpriv, AGGLEN_LMT_H, 0x0f); | ||
816 | /* MCS0/1/2/3 use max AMPDU size 4*2=8K */ | ||
817 | rtl_write_word(rtlpriv, AGGLEN_LMT_L, 0x7442); | ||
818 | /* MCS4/5 use max AMPDU size 8*2=16K 6/7 use 10*2=20K */ | ||
819 | rtl_write_word(rtlpriv, AGGLEN_LMT_L + 2, 0xddd7); | ||
820 | /* MCS8/9 use max AMPDU size 8*2=16K 10/11 use 10*2=20K */ | ||
821 | rtl_write_word(rtlpriv, AGGLEN_LMT_L + 4, 0xd772); | ||
822 | /* MCS12/13/14/15 use max AMPDU size 15*2=30K */ | ||
823 | rtl_write_word(rtlpriv, AGGLEN_LMT_L + 6, 0xfffd); | ||
824 | |||
825 | /* Set Data / Response auto rate fallack retry count */ | ||
826 | rtl_write_dword(rtlpriv, DARFRC, 0x04010000); | ||
827 | rtl_write_dword(rtlpriv, DARFRC + 4, 0x09070605); | ||
828 | rtl_write_dword(rtlpriv, RARFRC, 0x04010000); | ||
829 | rtl_write_dword(rtlpriv, RARFRC + 4, 0x09070605); | ||
830 | |||
831 | /* 7. EDCA Setting Register (Offset: 0x01D0 - 0x01FF) */ | ||
832 | /* Set all rate to support SG */ | ||
833 | rtl_write_word(rtlpriv, SG_RATE, 0xFFFF); | ||
834 | |||
835 | /* 8. WMAC, BA, and CCX related Register (Offset: 0x0200 - 0x023F) */ | ||
836 | /* Set NAV protection length */ | ||
837 | rtl_write_word(rtlpriv, NAV_PROT_LEN, 0x0080); | ||
838 | /* CF-END Threshold */ | ||
839 | rtl_write_byte(rtlpriv, CFEND_TH, 0xFF); | ||
840 | /* Set AMPDU minimum space */ | ||
841 | rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 0x07); | ||
842 | /* Set TXOP stall control for several queue/HI/BCN/MGT/ */ | ||
843 | rtl_write_byte(rtlpriv, TXOP_STALL_CTRL, 0x00); | ||
844 | |||
845 | /* 9. Security Control Register (Offset: 0x0240 - 0x025F) */ | ||
846 | /* 10. Power Save Control Register (Offset: 0x0260 - 0x02DF) */ | ||
847 | /* 11. General Purpose Register (Offset: 0x02E0 - 0x02FF) */ | ||
848 | /* 12. Host Interrupt Status Register (Offset: 0x0300 - 0x030F) */ | ||
849 | /* 13. Test Mode and Debug Control Register (Offset: 0x0310 - 0x034F) */ | ||
850 | |||
851 | /* 14. Set driver info, we only accept PHY status now. */ | ||
852 | rtl_write_byte(rtlpriv, RXDRVINFO_SZ, 4); | ||
853 | |||
854 | /* 15. For EEPROM R/W Workaround */ | ||
855 | /* 16. For EFUSE to share REG_SYS_FUNC_EN with EEPROM!!! */ | ||
856 | tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); | ||
857 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, tmpu2b | BIT(13)); | ||
858 | tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); | ||
859 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, tmpu2b & (~BIT(8))); | ||
860 | |||
861 | /* 17. For EFUSE */ | ||
862 | /* We may R/W EFUSE in EEPROM mode */ | ||
863 | if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { | ||
864 | u8 tempval; | ||
865 | |||
866 | tempval = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1); | ||
867 | tempval &= 0xFE; | ||
868 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tempval); | ||
869 | |||
870 | /* Change Program timing */ | ||
871 | rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72); | ||
872 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n")); | ||
873 | } | ||
874 | |||
875 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n")); | ||
876 | |||
877 | } | ||
878 | |||
879 | static void _rtl92se_hw_configure(struct ieee80211_hw *hw) | ||
880 | { | ||
881 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
882 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
883 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
884 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
885 | |||
886 | u8 reg_bw_opmode = 0; | ||
887 | u32 reg_ratr = 0, reg_rrsr = 0; | ||
888 | u8 regtmp = 0; | ||
889 | |||
890 | reg_bw_opmode = BW_OPMODE_20MHZ; | ||
891 | reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | | ||
892 | RATE_ALL_OFDM_2SS; | ||
893 | reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; | ||
894 | |||
895 | regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL); | ||
896 | reg_rrsr = ((reg_rrsr & 0x000fffff) << 8) | regtmp; | ||
897 | rtl_write_dword(rtlpriv, INIRTSMCS_SEL, reg_rrsr); | ||
898 | rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); | ||
899 | |||
900 | /* Set Retry Limit here */ | ||
901 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, | ||
902 | (u8 *)(&rtlpci->shortretry_limit)); | ||
903 | |||
904 | rtl_write_byte(rtlpriv, MLT, 0x8f); | ||
905 | |||
906 | /* For Min Spacing configuration. */ | ||
907 | switch (rtlphy->rf_type) { | ||
908 | case RF_1T2R: | ||
909 | case RF_1T1R: | ||
910 | rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3); | ||
911 | break; | ||
912 | case RF_2T2R: | ||
913 | case RF_2T2R_GREEN: | ||
914 | rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3); | ||
915 | break; | ||
916 | } | ||
917 | rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, rtlhal->minspace_cfg); | ||
918 | } | ||
919 | |||
920 | int rtl92se_hw_init(struct ieee80211_hw *hw) | ||
921 | { | ||
922 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
923 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
924 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
925 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
926 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
927 | u8 tmp_byte = 0; | ||
928 | |||
929 | bool rtstatus = true; | ||
930 | u8 tmp_u1b; | ||
931 | int err = false; | ||
932 | u8 i; | ||
933 | int wdcapra_add[] = { | ||
934 | EDCAPARA_BE, EDCAPARA_BK, | ||
935 | EDCAPARA_VI, EDCAPARA_VO}; | ||
936 | u8 secr_value = 0x0; | ||
937 | |||
938 | rtlpci->being_init_adapter = true; | ||
939 | |||
940 | rtlpriv->intf_ops->disable_aspm(hw); | ||
941 | |||
942 | /* 1. MAC Initialize */ | ||
943 | /* Before FW download, we have to set some MAC register */ | ||
944 | _rtl92se_macconfig_before_fwdownload(hw); | ||
945 | |||
946 | rtlhal->version = (enum version_8192s)((rtl_read_dword(rtlpriv, | ||
947 | PMC_FSM) >> 16) & 0xF); | ||
948 | |||
949 | rtl8192se_gpiobit3_cfg_inputmode(hw); | ||
950 | |||
951 | /* 2. download firmware */ | ||
952 | rtstatus = rtl92s_download_fw(hw); | ||
953 | if (!rtstatus) { | ||
954 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
955 | ("Failed to download FW. " | ||
956 | "Init HW without FW now.., Please copy FW into" | ||
957 | "/lib/firmware/rtlwifi\n")); | ||
958 | rtlhal->fw_ready = false; | ||
959 | } else { | ||
960 | rtlhal->fw_ready = true; | ||
961 | } | ||
962 | |||
963 | /* After FW download, we have to reset MAC register */ | ||
964 | _rtl92se_macconfig_after_fwdownload(hw); | ||
965 | |||
966 | /*Retrieve default FW Cmd IO map. */ | ||
967 | rtlhal->fwcmd_iomap = rtl_read_word(rtlpriv, LBUS_MON_ADDR); | ||
968 | rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK); | ||
969 | |||
970 | /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */ | ||
971 | if (rtl92s_phy_mac_config(hw) != true) { | ||
972 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n")); | ||
973 | return rtstatus; | ||
974 | } | ||
975 | |||
976 | /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */ | ||
977 | /* We must set flag avoid BB/RF config period later!! */ | ||
978 | rtl_write_dword(rtlpriv, CMDR, 0x37FC); | ||
979 | |||
980 | /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */ | ||
981 | if (rtl92s_phy_bb_config(hw) != true) { | ||
982 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n")); | ||
983 | return rtstatus; | ||
984 | } | ||
985 | |||
986 | /* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */ | ||
987 | /* Before initalizing RF. We can not use FW to do RF-R/W. */ | ||
988 | |||
989 | rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; | ||
990 | |||
991 | /* RF Power Save */ | ||
992 | #if 0 | ||
993 | /* H/W or S/W RF OFF before sleep. */ | ||
994 | if (rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) { | ||
995 | u32 rfoffreason = rtlpriv->psc.rfoff_reason; | ||
996 | |||
997 | rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT; | ||
998 | rtlpriv->psc.rfpwr_state = ERFON; | ||
999 | rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason, true); | ||
1000 | } else { | ||
1001 | /* gpio radio on/off is out of adapter start */ | ||
1002 | if (rtlpriv->psc.hwradiooff == false) { | ||
1003 | rtlpriv->psc.rfpwr_state = ERFON; | ||
1004 | rtlpriv->psc.rfoff_reason = 0; | ||
1005 | } | ||
1006 | } | ||
1007 | #endif | ||
1008 | |||
1009 | /* Before RF-R/W we must execute the IO from Scott's suggestion. */ | ||
1010 | rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB); | ||
1011 | if (rtlhal->version == VERSION_8192S_ACUT) | ||
1012 | rtl_write_byte(rtlpriv, SPS1_CTRL + 3, 0x07); | ||
1013 | else | ||
1014 | rtl_write_byte(rtlpriv, RF_CTRL, 0x07); | ||
1015 | |||
1016 | if (rtl92s_phy_rf_config(hw) != true) { | ||
1017 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n")); | ||
1018 | return rtstatus; | ||
1019 | } | ||
1020 | |||
1021 | /* After read predefined TXT, we must set BB/MAC/RF | ||
1022 | * register as our requirement */ | ||
1023 | |||
1024 | rtlphy->rfreg_chnlval[0] = rtl92s_phy_query_rf_reg(hw, | ||
1025 | (enum radio_path)0, | ||
1026 | RF_CHNLBW, | ||
1027 | RFREG_OFFSET_MASK); | ||
1028 | rtlphy->rfreg_chnlval[1] = rtl92s_phy_query_rf_reg(hw, | ||
1029 | (enum radio_path)1, | ||
1030 | RF_CHNLBW, | ||
1031 | RFREG_OFFSET_MASK); | ||
1032 | |||
1033 | /*---- Set CCK and OFDM Block "ON"----*/ | ||
1034 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); | ||
1035 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); | ||
1036 | |||
1037 | /*3 Set Hardware(Do nothing now) */ | ||
1038 | _rtl92se_hw_configure(hw); | ||
1039 | |||
1040 | /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */ | ||
1041 | /* TX power index for different rate set. */ | ||
1042 | /* Get original hw reg values */ | ||
1043 | rtl92s_phy_get_hw_reg_originalvalue(hw); | ||
1044 | /* Write correct tx power index */ | ||
1045 | rtl92s_phy_set_txpower(hw, rtlphy->current_channel); | ||
1046 | |||
1047 | /* We must set MAC address after firmware download. */ | ||
1048 | for (i = 0; i < 6; i++) | ||
1049 | rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); | ||
1050 | |||
1051 | /* EEPROM R/W workaround */ | ||
1052 | tmp_u1b = rtl_read_byte(rtlpriv, MAC_PINMUX_CFG); | ||
1053 | rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, tmp_u1b & (~BIT(3))); | ||
1054 | |||
1055 | rtl_write_byte(rtlpriv, 0x4d, 0x0); | ||
1056 | |||
1057 | if (hal_get_firmwareversion(rtlpriv) >= 0x49) { | ||
1058 | tmp_byte = rtl_read_byte(rtlpriv, FW_RSVD_PG_CRTL) & (~BIT(4)); | ||
1059 | tmp_byte = tmp_byte | BIT(5); | ||
1060 | rtl_write_byte(rtlpriv, FW_RSVD_PG_CRTL, tmp_byte); | ||
1061 | rtl_write_dword(rtlpriv, TXDESC_MSK, 0xFFFFCFFF); | ||
1062 | } | ||
1063 | |||
1064 | /* We enable high power and RA related mechanism after NIC | ||
1065 | * initialized. */ | ||
1066 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT); | ||
1067 | |||
1068 | /* Add to prevent ASPM bug. */ | ||
1069 | /* Always enable hst and NIC clock request. */ | ||
1070 | rtl92s_phy_switch_ephy_parameter(hw); | ||
1071 | |||
1072 | /* Security related | ||
1073 | * 1. Clear all H/W keys. | ||
1074 | * 2. Enable H/W encryption/decryption. */ | ||
1075 | rtl_cam_reset_all_entry(hw); | ||
1076 | secr_value |= SCR_TXENCENABLE; | ||
1077 | secr_value |= SCR_RXENCENABLE; | ||
1078 | secr_value |= SCR_NOSKMC; | ||
1079 | rtl_write_byte(rtlpriv, REG_SECR, secr_value); | ||
1080 | |||
1081 | for (i = 0; i < 4; i++) | ||
1082 | rtl_write_dword(rtlpriv, wdcapra_add[i], 0x5e4322); | ||
1083 | |||
1084 | if (rtlphy->rf_type == RF_1T2R) { | ||
1085 | bool mrc2set = true; | ||
1086 | /* Turn on B-Path */ | ||
1087 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, (u8 *)&mrc2set); | ||
1088 | } | ||
1089 | |||
1090 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON); | ||
1091 | rtl92s_dm_init(hw); | ||
1092 | rtlpci->being_init_adapter = false; | ||
1093 | |||
1094 | return err; | ||
1095 | } | ||
1096 | |||
1097 | void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr) | ||
1098 | { | ||
1099 | } | ||
1100 | |||
1101 | void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) | ||
1102 | { | ||
1103 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1104 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1105 | u32 reg_rcr = rtlpci->receive_config; | ||
1106 | |||
1107 | if (rtlpriv->psc.rfpwr_state != ERFON) | ||
1108 | return; | ||
1109 | |||
1110 | if (check_bssid == true) { | ||
1111 | reg_rcr |= (RCR_CBSSID); | ||
1112 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); | ||
1113 | } else if (check_bssid == false) { | ||
1114 | reg_rcr &= (~RCR_CBSSID); | ||
1115 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); | ||
1116 | } | ||
1117 | |||
1118 | } | ||
1119 | |||
1120 | static int _rtl92se_set_media_status(struct ieee80211_hw *hw, | ||
1121 | enum nl80211_iftype type) | ||
1122 | { | ||
1123 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1124 | u8 bt_msr = rtl_read_byte(rtlpriv, MSR); | ||
1125 | enum led_ctl_mode ledaction = LED_CTL_NO_LINK; | ||
1126 | u32 temp; | ||
1127 | bt_msr &= ~MSR_LINK_MASK; | ||
1128 | |||
1129 | switch (type) { | ||
1130 | case NL80211_IFTYPE_UNSPECIFIED: | ||
1131 | bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); | ||
1132 | ledaction = LED_CTL_LINK; | ||
1133 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1134 | ("Set Network type to NO LINK!\n")); | ||
1135 | break; | ||
1136 | case NL80211_IFTYPE_ADHOC: | ||
1137 | bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); | ||
1138 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1139 | ("Set Network type to Ad Hoc!\n")); | ||
1140 | break; | ||
1141 | case NL80211_IFTYPE_STATION: | ||
1142 | bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); | ||
1143 | ledaction = LED_CTL_LINK; | ||
1144 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1145 | ("Set Network type to STA!\n")); | ||
1146 | break; | ||
1147 | case NL80211_IFTYPE_AP: | ||
1148 | bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); | ||
1149 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1150 | ("Set Network type to AP!\n")); | ||
1151 | break; | ||
1152 | default: | ||
1153 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1154 | ("Network type %d not support!\n", type)); | ||
1155 | return 1; | ||
1156 | break; | ||
1157 | |||
1158 | } | ||
1159 | |||
1160 | rtl_write_byte(rtlpriv, (MSR), bt_msr); | ||
1161 | |||
1162 | temp = rtl_read_dword(rtlpriv, TCR); | ||
1163 | rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8))); | ||
1164 | rtl_write_dword(rtlpriv, TCR, temp | BIT(8)); | ||
1165 | |||
1166 | |||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | /* HW_VAR_MEDIA_STATUS & HW_VAR_CECHK_BSSID */ | ||
1171 | int rtl92se_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) | ||
1172 | { | ||
1173 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1174 | |||
1175 | if (_rtl92se_set_media_status(hw, type)) | ||
1176 | return -EOPNOTSUPP; | ||
1177 | |||
1178 | if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { | ||
1179 | if (type != NL80211_IFTYPE_AP) | ||
1180 | rtl92se_set_check_bssid(hw, true); | ||
1181 | } else { | ||
1182 | rtl92se_set_check_bssid(hw, false); | ||
1183 | } | ||
1184 | |||
1185 | return 0; | ||
1186 | } | ||
1187 | |||
1188 | /* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ | ||
1189 | void rtl92se_set_qos(struct ieee80211_hw *hw, int aci) | ||
1190 | { | ||
1191 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1192 | rtl92s_dm_init_edca_turbo(hw); | ||
1193 | |||
1194 | switch (aci) { | ||
1195 | case AC1_BK: | ||
1196 | rtl_write_dword(rtlpriv, EDCAPARA_BK, 0xa44f); | ||
1197 | break; | ||
1198 | case AC0_BE: | ||
1199 | /* rtl_write_dword(rtlpriv, EDCAPARA_BE, u4b_ac_param); */ | ||
1200 | break; | ||
1201 | case AC2_VI: | ||
1202 | rtl_write_dword(rtlpriv, EDCAPARA_VI, 0x5e4322); | ||
1203 | break; | ||
1204 | case AC3_VO: | ||
1205 | rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222); | ||
1206 | break; | ||
1207 | default: | ||
1208 | RT_ASSERT(false, ("invalid aci: %d !\n", aci)); | ||
1209 | break; | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | void rtl92se_enable_interrupt(struct ieee80211_hw *hw) | ||
1214 | { | ||
1215 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1216 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1217 | |||
1218 | rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]); | ||
1219 | /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */ | ||
1220 | rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F); | ||
1221 | |||
1222 | rtlpci->irq_enabled = true; | ||
1223 | } | ||
1224 | |||
1225 | void rtl92se_disable_interrupt(struct ieee80211_hw *hw) | ||
1226 | { | ||
1227 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1228 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1229 | |||
1230 | rtl_write_dword(rtlpriv, INTA_MASK, 0); | ||
1231 | rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); | ||
1232 | |||
1233 | rtlpci->irq_enabled = false; | ||
1234 | } | ||
1235 | |||
1236 | |||
1237 | static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data) | ||
1238 | { | ||
1239 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1240 | u8 waitcnt = 100; | ||
1241 | bool result = false; | ||
1242 | u8 tmp; | ||
1243 | |||
1244 | rtl_write_byte(rtlpriv, SYS_CLKR + 1, data); | ||
1245 | |||
1246 | /* Wait the MAC synchronized. */ | ||
1247 | udelay(400); | ||
1248 | |||
1249 | /* Check if it is set ready. */ | ||
1250 | tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1); | ||
1251 | result = ((tmp & BIT(7)) == (data & BIT(7))); | ||
1252 | |||
1253 | if ((data & (BIT(6) | BIT(7))) == false) { | ||
1254 | waitcnt = 100; | ||
1255 | tmp = 0; | ||
1256 | |||
1257 | while (1) { | ||
1258 | waitcnt--; | ||
1259 | tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1); | ||
1260 | |||
1261 | if ((tmp & BIT(6))) | ||
1262 | break; | ||
1263 | |||
1264 | printk(KERN_ERR "wait for BIT(6) return value %x\n", | ||
1265 | tmp); | ||
1266 | |||
1267 | if (waitcnt == 0) | ||
1268 | break; | ||
1269 | udelay(10); | ||
1270 | } | ||
1271 | |||
1272 | if (waitcnt == 0) | ||
1273 | result = false; | ||
1274 | else | ||
1275 | result = true; | ||
1276 | } | ||
1277 | |||
1278 | return result; | ||
1279 | } | ||
1280 | |||
1281 | static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw) | ||
1282 | { | ||
1283 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1284 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1285 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1286 | u8 u1btmp; | ||
1287 | |||
1288 | if (rtlhal->driver_going2unload) | ||
1289 | rtl_write_byte(rtlpriv, 0x560, 0x0); | ||
1290 | |||
1291 | /* Power save for BB/RF */ | ||
1292 | u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL); | ||
1293 | u1btmp |= BIT(0); | ||
1294 | rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp); | ||
1295 | rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0); | ||
1296 | rtl_write_byte(rtlpriv, TXPAUSE, 0xFF); | ||
1297 | rtl_write_word(rtlpriv, CMDR, 0x57FC); | ||
1298 | udelay(100); | ||
1299 | rtl_write_word(rtlpriv, CMDR, 0x77FC); | ||
1300 | rtl_write_byte(rtlpriv, PHY_CCA, 0x0); | ||
1301 | udelay(10); | ||
1302 | rtl_write_word(rtlpriv, CMDR, 0x37FC); | ||
1303 | udelay(10); | ||
1304 | rtl_write_word(rtlpriv, CMDR, 0x77FC); | ||
1305 | udelay(10); | ||
1306 | rtl_write_word(rtlpriv, CMDR, 0x57FC); | ||
1307 | rtl_write_word(rtlpriv, CMDR, 0x0000); | ||
1308 | |||
1309 | if (rtlhal->driver_going2unload) { | ||
1310 | u1btmp = rtl_read_byte(rtlpriv, (REG_SYS_FUNC_EN + 1)); | ||
1311 | u1btmp &= ~(BIT(0)); | ||
1312 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1btmp); | ||
1313 | } | ||
1314 | |||
1315 | u1btmp = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); | ||
1316 | |||
1317 | /* Add description. After switch control path. register | ||
1318 | * after page1 will be invisible. We can not do any IO | ||
1319 | * for register>0x40. After resume&MACIO reset, we need | ||
1320 | * to remember previous reg content. */ | ||
1321 | if (u1btmp & BIT(7)) { | ||
1322 | u1btmp &= ~(BIT(6) | BIT(7)); | ||
1323 | if (!_rtl92s_set_sysclk(hw, u1btmp)) { | ||
1324 | printk(KERN_ERR "Switch ctrl path fail\n"); | ||
1325 | return; | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | /* Power save for MAC */ | ||
1330 | if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS && | ||
1331 | !rtlhal->driver_going2unload) { | ||
1332 | /* enable LED function */ | ||
1333 | rtl_write_byte(rtlpriv, 0x03, 0xF9); | ||
1334 | /* SW/HW radio off or halt adapter!! For example S3/S4 */ | ||
1335 | } else { | ||
1336 | /* LED function disable. Power range is about 8mA now. */ | ||
1337 | /* if write 0xF1 disconnet_pci power | ||
1338 | * ifconfig wlan0 down power are both high 35:70 */ | ||
1339 | /* if write oxF9 disconnet_pci power | ||
1340 | * ifconfig wlan0 down power are both low 12:45*/ | ||
1341 | rtl_write_byte(rtlpriv, 0x03, 0xF9); | ||
1342 | } | ||
1343 | |||
1344 | rtl_write_byte(rtlpriv, SYS_CLKR + 1, 0x70); | ||
1345 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, 0x68); | ||
1346 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x00); | ||
1347 | rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); | ||
1348 | rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, 0x0E); | ||
1349 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | ||
1350 | |||
1351 | } | ||
1352 | |||
1353 | static void _rtl92se_gen_refreshledstate(struct ieee80211_hw *hw) | ||
1354 | { | ||
1355 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1356 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1357 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1358 | struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); | ||
1359 | |||
1360 | if (rtlpci->up_first_time == 1) | ||
1361 | return; | ||
1362 | |||
1363 | if (rtlpriv->psc.rfoff_reason == RF_CHANGE_BY_IPS) | ||
1364 | rtl92se_sw_led_on(hw, pLed0); | ||
1365 | else | ||
1366 | rtl92se_sw_led_off(hw, pLed0); | ||
1367 | } | ||
1368 | |||
1369 | |||
1370 | static void _rtl92se_power_domain_init(struct ieee80211_hw *hw) | ||
1371 | { | ||
1372 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1373 | u16 tmpu2b; | ||
1374 | u8 tmpu1b; | ||
1375 | |||
1376 | rtlpriv->psc.pwrdomain_protect = true; | ||
1377 | |||
1378 | tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); | ||
1379 | if (tmpu1b & BIT(7)) { | ||
1380 | tmpu1b &= ~(BIT(6) | BIT(7)); | ||
1381 | if (!_rtl92s_set_sysclk(hw, tmpu1b)) { | ||
1382 | rtlpriv->psc.pwrdomain_protect = false; | ||
1383 | return; | ||
1384 | } | ||
1385 | } | ||
1386 | |||
1387 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0); | ||
1388 | rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); | ||
1389 | |||
1390 | /* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */ | ||
1391 | tmpu1b = rtl_read_byte(rtlpriv, SYS_FUNC_EN + 1); | ||
1392 | |||
1393 | /* If IPS we need to turn LED on. So we not | ||
1394 | * not disable BIT 3/7 of reg3. */ | ||
1395 | if (rtlpriv->psc.rfoff_reason & (RF_CHANGE_BY_IPS | RF_CHANGE_BY_HW)) | ||
1396 | tmpu1b &= 0xFB; | ||
1397 | else | ||
1398 | tmpu1b &= 0x73; | ||
1399 | |||
1400 | rtl_write_byte(rtlpriv, SYS_FUNC_EN + 1, tmpu1b); | ||
1401 | /* wait for BIT 10/11/15 to pull high automatically!! */ | ||
1402 | mdelay(1); | ||
1403 | |||
1404 | rtl_write_byte(rtlpriv, CMDR, 0); | ||
1405 | rtl_write_byte(rtlpriv, TCR, 0); | ||
1406 | |||
1407 | /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */ | ||
1408 | tmpu1b = rtl_read_byte(rtlpriv, 0x562); | ||
1409 | tmpu1b |= 0x08; | ||
1410 | rtl_write_byte(rtlpriv, 0x562, tmpu1b); | ||
1411 | tmpu1b &= ~(BIT(3)); | ||
1412 | rtl_write_byte(rtlpriv, 0x562, tmpu1b); | ||
1413 | |||
1414 | /* Enable AFE clock source */ | ||
1415 | tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL); | ||
1416 | rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01)); | ||
1417 | /* Delay 1.5ms */ | ||
1418 | udelay(1500); | ||
1419 | tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1); | ||
1420 | rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb)); | ||
1421 | |||
1422 | /* Enable AFE Macro Block's Bandgap */ | ||
1423 | tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); | ||
1424 | rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0))); | ||
1425 | mdelay(1); | ||
1426 | |||
1427 | /* Enable AFE Mbias */ | ||
1428 | tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); | ||
1429 | rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02)); | ||
1430 | mdelay(1); | ||
1431 | |||
1432 | /* Enable LDOA15 block */ | ||
1433 | tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL); | ||
1434 | rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0))); | ||
1435 | |||
1436 | /* Set Digital Vdd to Retention isolation Path. */ | ||
1437 | tmpu2b = rtl_read_word(rtlpriv, SYS_ISO_CTRL); | ||
1438 | rtl_write_word(rtlpriv, SYS_ISO_CTRL, (tmpu2b | BIT(11))); | ||
1439 | |||
1440 | |||
1441 | /* For warm reboot NIC disappera bug. */ | ||
1442 | tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN); | ||
1443 | rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(13))); | ||
1444 | |||
1445 | rtl_write_byte(rtlpriv, SYS_ISO_CTRL + 1, 0x68); | ||
1446 | |||
1447 | /* Enable AFE PLL Macro Block */ | ||
1448 | tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL); | ||
1449 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); | ||
1450 | /* Enable MAC 80MHZ clock */ | ||
1451 | tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1); | ||
1452 | rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0))); | ||
1453 | mdelay(1); | ||
1454 | |||
1455 | /* Release isolation AFE PLL & MD */ | ||
1456 | rtl_write_byte(rtlpriv, SYS_ISO_CTRL, 0xA6); | ||
1457 | |||
1458 | /* Enable MAC clock */ | ||
1459 | tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); | ||
1460 | rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11))); | ||
1461 | |||
1462 | /* Enable Core digital and enable IOREG R/W */ | ||
1463 | tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN); | ||
1464 | rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11))); | ||
1465 | /* enable REG_EN */ | ||
1466 | rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15))); | ||
1467 | |||
1468 | /* Switch the control path. */ | ||
1469 | tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); | ||
1470 | rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2)))); | ||
1471 | |||
1472 | tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); | ||
1473 | tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6))); | ||
1474 | if (!_rtl92s_set_sysclk(hw, tmpu1b)) { | ||
1475 | rtlpriv->psc.pwrdomain_protect = false; | ||
1476 | return; | ||
1477 | } | ||
1478 | |||
1479 | rtl_write_word(rtlpriv, CMDR, 0x37FC); | ||
1480 | |||
1481 | /* After MACIO reset,we must refresh LED state. */ | ||
1482 | _rtl92se_gen_refreshledstate(hw); | ||
1483 | |||
1484 | rtlpriv->psc.pwrdomain_protect = false; | ||
1485 | } | ||
1486 | |||
1487 | void rtl92se_card_disable(struct ieee80211_hw *hw) | ||
1488 | { | ||
1489 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1490 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1491 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1492 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1493 | enum nl80211_iftype opmode; | ||
1494 | u8 wait = 30; | ||
1495 | |||
1496 | rtlpriv->intf_ops->enable_aspm(hw); | ||
1497 | |||
1498 | if (rtlpci->driver_is_goingto_unload || | ||
1499 | ppsc->rfoff_reason > RF_CHANGE_BY_PS) | ||
1500 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); | ||
1501 | |||
1502 | /* we should chnge GPIO to input mode | ||
1503 | * this will drop away current about 25mA*/ | ||
1504 | rtl8192se_gpiobit3_cfg_inputmode(hw); | ||
1505 | |||
1506 | /* this is very important for ips power save */ | ||
1507 | while (wait-- >= 10 && rtlpriv->psc.pwrdomain_protect) { | ||
1508 | if (rtlpriv->psc.pwrdomain_protect) | ||
1509 | mdelay(20); | ||
1510 | else | ||
1511 | break; | ||
1512 | } | ||
1513 | |||
1514 | mac->link_state = MAC80211_NOLINK; | ||
1515 | opmode = NL80211_IFTYPE_UNSPECIFIED; | ||
1516 | _rtl92se_set_media_status(hw, opmode); | ||
1517 | |||
1518 | _rtl92s_phy_set_rfhalt(hw); | ||
1519 | udelay(100); | ||
1520 | } | ||
1521 | |||
1522 | void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta, | ||
1523 | u32 *p_intb) | ||
1524 | { | ||
1525 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1526 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1527 | |||
1528 | *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; | ||
1529 | rtl_write_dword(rtlpriv, ISR, *p_inta); | ||
1530 | |||
1531 | *p_intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1]; | ||
1532 | rtl_write_dword(rtlpriv, ISR + 4, *p_intb); | ||
1533 | } | ||
1534 | |||
1535 | void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw) | ||
1536 | { | ||
1537 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1538 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1539 | u16 bcntime_cfg = 0; | ||
1540 | u16 bcn_cw = 6, bcn_ifs = 0xf; | ||
1541 | u16 atim_window = 2; | ||
1542 | |||
1543 | /* ATIM Window (in unit of TU). */ | ||
1544 | rtl_write_word(rtlpriv, ATIMWND, atim_window); | ||
1545 | |||
1546 | /* Beacon interval (in unit of TU). */ | ||
1547 | rtl_write_word(rtlpriv, BCN_INTERVAL, mac->beacon_interval); | ||
1548 | |||
1549 | /* DrvErlyInt (in unit of TU). (Time to send | ||
1550 | * interrupt to notify driver to change | ||
1551 | * beacon content) */ | ||
1552 | rtl_write_word(rtlpriv, BCN_DRV_EARLY_INT, 10 << 4); | ||
1553 | |||
1554 | /* BcnDMATIM(in unit of us). Indicates the | ||
1555 | * time before TBTT to perform beacon queue DMA */ | ||
1556 | rtl_write_word(rtlpriv, BCN_DMATIME, 256); | ||
1557 | |||
1558 | /* Force beacon frame transmission even | ||
1559 | * after receiving beacon frame from | ||
1560 | * other ad hoc STA */ | ||
1561 | rtl_write_byte(rtlpriv, BCN_ERR_THRESH, 100); | ||
1562 | |||
1563 | /* Beacon Time Configuration */ | ||
1564 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
1565 | bcntime_cfg |= (bcn_cw << BCN_TCFG_CW_SHIFT); | ||
1566 | |||
1567 | /* TODO: bcn_ifs may required to be changed on ASIC */ | ||
1568 | bcntime_cfg |= bcn_ifs << BCN_TCFG_IFS; | ||
1569 | |||
1570 | /*for beacon changed */ | ||
1571 | rtl92s_phy_set_beacon_hwreg(hw, mac->beacon_interval); | ||
1572 | } | ||
1573 | |||
1574 | void rtl92se_set_beacon_interval(struct ieee80211_hw *hw) | ||
1575 | { | ||
1576 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1577 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1578 | u16 bcn_interval = mac->beacon_interval; | ||
1579 | |||
1580 | /* Beacon interval (in unit of TU). */ | ||
1581 | rtl_write_word(rtlpriv, BCN_INTERVAL, bcn_interval); | ||
1582 | /* 2008.10.24 added by tynli for beacon changed. */ | ||
1583 | rtl92s_phy_set_beacon_hwreg(hw, bcn_interval); | ||
1584 | } | ||
1585 | |||
1586 | void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw, | ||
1587 | u32 add_msr, u32 rm_msr) | ||
1588 | { | ||
1589 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1590 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1591 | |||
1592 | RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, | ||
1593 | ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); | ||
1594 | |||
1595 | if (add_msr) | ||
1596 | rtlpci->irq_mask[0] |= add_msr; | ||
1597 | |||
1598 | if (rm_msr) | ||
1599 | rtlpci->irq_mask[0] &= (~rm_msr); | ||
1600 | |||
1601 | rtl92se_disable_interrupt(hw); | ||
1602 | rtl92se_enable_interrupt(hw); | ||
1603 | } | ||
1604 | |||
1605 | static void _rtl8192se_get_IC_Inferiority(struct ieee80211_hw *hw) | ||
1606 | { | ||
1607 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1608 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1609 | u8 efuse_id; | ||
1610 | |||
1611 | rtlhal->ic_class = IC_INFERIORITY_A; | ||
1612 | |||
1613 | /* Only retrieving while using EFUSE. */ | ||
1614 | if ((rtlefuse->epromtype == EEPROM_BOOT_EFUSE) && | ||
1615 | !rtlefuse->autoload_failflag) { | ||
1616 | efuse_id = efuse_read_1byte(hw, EFUSE_IC_ID_OFFSET); | ||
1617 | |||
1618 | if (efuse_id == 0xfe) | ||
1619 | rtlhal->ic_class = IC_INFERIORITY_B; | ||
1620 | } | ||
1621 | } | ||
1622 | |||
1623 | static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | ||
1624 | { | ||
1625 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1626 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1627 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1628 | u16 i, usvalue; | ||
1629 | u16 eeprom_id; | ||
1630 | u8 tempval; | ||
1631 | u8 hwinfo[HWSET_MAX_SIZE_92S]; | ||
1632 | u8 rf_path, index; | ||
1633 | |||
1634 | if (rtlefuse->epromtype == EEPROM_93C46) { | ||
1635 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1636 | ("RTL819X Not boot from eeprom, check it !!")); | ||
1637 | } else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { | ||
1638 | rtl_efuse_shadow_map_update(hw); | ||
1639 | |||
1640 | memcpy((void *)hwinfo, (void *) | ||
1641 | &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], | ||
1642 | HWSET_MAX_SIZE_92S); | ||
1643 | } | ||
1644 | |||
1645 | RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), | ||
1646 | hwinfo, HWSET_MAX_SIZE_92S); | ||
1647 | |||
1648 | eeprom_id = *((u16 *)&hwinfo[0]); | ||
1649 | if (eeprom_id != RTL8190_EEPROM_ID) { | ||
1650 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
1651 | ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); | ||
1652 | rtlefuse->autoload_failflag = true; | ||
1653 | } else { | ||
1654 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); | ||
1655 | rtlefuse->autoload_failflag = false; | ||
1656 | } | ||
1657 | |||
1658 | if (rtlefuse->autoload_failflag == true) | ||
1659 | return; | ||
1660 | |||
1661 | _rtl8192se_get_IC_Inferiority(hw); | ||
1662 | |||
1663 | /* Read IC Version && Channel Plan */ | ||
1664 | /* VID, DID SE 0xA-D */ | ||
1665 | rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; | ||
1666 | rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; | ||
1667 | rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; | ||
1668 | rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; | ||
1669 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; | ||
1670 | |||
1671 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1672 | ("EEPROMId = 0x%4x\n", eeprom_id)); | ||
1673 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1674 | ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); | ||
1675 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1676 | ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); | ||
1677 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1678 | ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); | ||
1679 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1680 | ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); | ||
1681 | |||
1682 | for (i = 0; i < 6; i += 2) { | ||
1683 | usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; | ||
1684 | *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; | ||
1685 | } | ||
1686 | |||
1687 | for (i = 0; i < 6; i++) | ||
1688 | rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); | ||
1689 | |||
1690 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
1691 | (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr))); | ||
1692 | |||
1693 | /* Get Tx Power Level by Channel */ | ||
1694 | /* Read Tx power of Channel 1 ~ 14 from EEPROM. */ | ||
1695 | /* 92S suupport RF A & B */ | ||
1696 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
1697 | for (i = 0; i < 3; i++) { | ||
1698 | /* Read CCK RF A & B Tx power */ | ||
1699 | rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] = | ||
1700 | hwinfo[EEPROM_TXPOWERBASE + rf_path * 3 + i]; | ||
1701 | |||
1702 | /* Read OFDM RF A & B Tx power for 1T */ | ||
1703 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = | ||
1704 | hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i]; | ||
1705 | |||
1706 | /* Read OFDM RF A & B Tx power for 2T */ | ||
1707 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i] | ||
1708 | = hwinfo[EEPROM_TXPOWERBASE + 12 + | ||
1709 | rf_path * 3 + i]; | ||
1710 | } | ||
1711 | } | ||
1712 | |||
1713 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
1714 | for (i = 0; i < 3; i++) | ||
1715 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
1716 | ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, | ||
1717 | i, rtlefuse->eeprom_chnlarea_txpwr_cck | ||
1718 | [rf_path][i])); | ||
1719 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
1720 | for (i = 0; i < 3; i++) | ||
1721 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
1722 | ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", | ||
1723 | rf_path, i, | ||
1724 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | ||
1725 | [rf_path][i])); | ||
1726 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
1727 | for (i = 0; i < 3; i++) | ||
1728 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
1729 | ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", | ||
1730 | rf_path, i, | ||
1731 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif | ||
1732 | [rf_path][i])); | ||
1733 | |||
1734 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
1735 | |||
1736 | /* Assign dedicated channel tx power */ | ||
1737 | for (i = 0; i < 14; i++) { | ||
1738 | /* channel 1~3 use the same Tx Power Level. */ | ||
1739 | if (i < 3) | ||
1740 | index = 0; | ||
1741 | /* Channel 4-8 */ | ||
1742 | else if (i < 8) | ||
1743 | index = 1; | ||
1744 | /* Channel 9-14 */ | ||
1745 | else | ||
1746 | index = 2; | ||
1747 | |||
1748 | /* Record A & B CCK /OFDM - 1T/2T Channel area | ||
1749 | * tx power */ | ||
1750 | rtlefuse->txpwrlevel_cck[rf_path][i] = | ||
1751 | rtlefuse->eeprom_chnlarea_txpwr_cck | ||
1752 | [rf_path][index]; | ||
1753 | rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = | ||
1754 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | ||
1755 | [rf_path][index]; | ||
1756 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = | ||
1757 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif | ||
1758 | [rf_path][index]; | ||
1759 | } | ||
1760 | |||
1761 | for (i = 0; i < 14; i++) { | ||
1762 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1763 | ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " | ||
1764 | "[0x%x / 0x%x / 0x%x]\n", rf_path, i, | ||
1765 | rtlefuse->txpwrlevel_cck[rf_path][i], | ||
1766 | rtlefuse->txpwrlevel_ht40_1s[rf_path][i], | ||
1767 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); | ||
1768 | } | ||
1769 | } | ||
1770 | |||
1771 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
1772 | for (i = 0; i < 3; i++) { | ||
1773 | /* Read Power diff limit. */ | ||
1774 | rtlefuse->eeprom_pwrgroup[rf_path][i] = | ||
1775 | hwinfo[EEPROM_TXPWRGROUP + rf_path * 3 + i]; | ||
1776 | } | ||
1777 | } | ||
1778 | |||
1779 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
1780 | /* Fill Pwr group */ | ||
1781 | for (i = 0; i < 14; i++) { | ||
1782 | /* Chanel 1-3 */ | ||
1783 | if (i < 3) | ||
1784 | index = 0; | ||
1785 | /* Channel 4-8 */ | ||
1786 | else if (i < 8) | ||
1787 | index = 1; | ||
1788 | /* Channel 9-13 */ | ||
1789 | else | ||
1790 | index = 2; | ||
1791 | |||
1792 | rtlefuse->pwrgroup_ht20[rf_path][i] = | ||
1793 | (rtlefuse->eeprom_pwrgroup[rf_path][index] & | ||
1794 | 0xf); | ||
1795 | rtlefuse->pwrgroup_ht40[rf_path][i] = | ||
1796 | ((rtlefuse->eeprom_pwrgroup[rf_path][index] & | ||
1797 | 0xf0) >> 4); | ||
1798 | |||
1799 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1800 | ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", | ||
1801 | rf_path, i, | ||
1802 | rtlefuse->pwrgroup_ht20[rf_path][i])); | ||
1803 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1804 | ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", | ||
1805 | rf_path, i, | ||
1806 | rtlefuse->pwrgroup_ht40[rf_path][i])); | ||
1807 | } | ||
1808 | } | ||
1809 | |||
1810 | for (i = 0; i < 14; i++) { | ||
1811 | /* Read tx power difference between HT OFDM 20/40 MHZ */ | ||
1812 | /* channel 1-3 */ | ||
1813 | if (i < 3) | ||
1814 | index = 0; | ||
1815 | /* Channel 4-8 */ | ||
1816 | else if (i < 8) | ||
1817 | index = 1; | ||
1818 | /* Channel 9-14 */ | ||
1819 | else | ||
1820 | index = 2; | ||
1821 | |||
1822 | tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF + | ||
1823 | index]) & 0xff; | ||
1824 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); | ||
1825 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = | ||
1826 | ((tempval >> 4) & 0xF); | ||
1827 | |||
1828 | /* Read OFDM<->HT tx power diff */ | ||
1829 | /* Channel 1-3 */ | ||
1830 | if (i < 3) | ||
1831 | index = 0; | ||
1832 | /* Channel 4-8 */ | ||
1833 | else if (i < 8) | ||
1834 | index = 0x11; | ||
1835 | /* Channel 9-14 */ | ||
1836 | else | ||
1837 | index = 1; | ||
1838 | |||
1839 | tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index]) | ||
1840 | & 0xff; | ||
1841 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = | ||
1842 | (tempval & 0xF); | ||
1843 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = | ||
1844 | ((tempval >> 4) & 0xF); | ||
1845 | |||
1846 | tempval = (*(u8 *)&hwinfo[TX_PWR_SAFETY_CHK]); | ||
1847 | rtlefuse->txpwr_safetyflag = (tempval & 0x01); | ||
1848 | } | ||
1849 | |||
1850 | rtlefuse->eeprom_regulatory = 0; | ||
1851 | if (rtlefuse->eeprom_version >= 2) { | ||
1852 | /* BIT(0)~2 */ | ||
1853 | if (rtlefuse->eeprom_version >= 4) | ||
1854 | rtlefuse->eeprom_regulatory = | ||
1855 | (hwinfo[EEPROM_REGULATORY] & 0x7); | ||
1856 | else /* BIT(0) */ | ||
1857 | rtlefuse->eeprom_regulatory = | ||
1858 | (hwinfo[EEPROM_REGULATORY] & 0x1); | ||
1859 | } | ||
1860 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1861 | ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); | ||
1862 | |||
1863 | for (i = 0; i < 14; i++) | ||
1864 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1865 | ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, | ||
1866 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); | ||
1867 | for (i = 0; i < 14; i++) | ||
1868 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1869 | ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, | ||
1870 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); | ||
1871 | for (i = 0; i < 14; i++) | ||
1872 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1873 | ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, | ||
1874 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); | ||
1875 | for (i = 0; i < 14; i++) | ||
1876 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1877 | ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, | ||
1878 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); | ||
1879 | |||
1880 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n", | ||
1881 | rtlefuse->txpwr_safetyflag)); | ||
1882 | |||
1883 | /* Read RF-indication and Tx Power gain | ||
1884 | * index diff of legacy to HT OFDM rate. */ | ||
1885 | tempval = (*(u8 *)&hwinfo[EEPROM_RFIND_POWERDIFF]) & 0xff; | ||
1886 | rtlefuse->eeprom_txpowerdiff = tempval; | ||
1887 | rtlefuse->legacy_httxpowerdiff = | ||
1888 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; | ||
1889 | |||
1890 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n", | ||
1891 | rtlefuse->eeprom_txpowerdiff)); | ||
1892 | |||
1893 | /* Get TSSI value for each path. */ | ||
1894 | usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; | ||
1895 | rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8); | ||
1896 | usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B]; | ||
1897 | rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); | ||
1898 | |||
1899 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", | ||
1900 | rtlefuse->eeprom_tssi[RF90_PATH_A], | ||
1901 | rtlefuse->eeprom_tssi[RF90_PATH_B])); | ||
1902 | |||
1903 | /* Read antenna tx power offset of B/C/D to A from EEPROM */ | ||
1904 | /* and read ThermalMeter from EEPROM */ | ||
1905 | tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER]; | ||
1906 | rtlefuse->eeprom_thermalmeter = tempval; | ||
1907 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n", | ||
1908 | rtlefuse->eeprom_thermalmeter)); | ||
1909 | |||
1910 | /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */ | ||
1911 | rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f); | ||
1912 | rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100; | ||
1913 | |||
1914 | /* Read CrystalCap from EEPROM */ | ||
1915 | tempval = (*(u8 *)&hwinfo[EEPROM_CRYSTALCAP]) >> 4; | ||
1916 | rtlefuse->eeprom_crystalcap = tempval; | ||
1917 | /* CrystalCap, BIT(12)~15 */ | ||
1918 | rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap; | ||
1919 | |||
1920 | /* Read IC Version && Channel Plan */ | ||
1921 | /* Version ID, Channel plan */ | ||
1922 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | ||
1923 | rtlefuse->txpwr_fromeprom = true; | ||
1924 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n", | ||
1925 | rtlefuse->eeprom_channelplan)); | ||
1926 | |||
1927 | /* Read Customer ID or Board Type!!! */ | ||
1928 | tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE]; | ||
1929 | /* Change RF type definition */ | ||
1930 | if (tempval == 0) | ||
1931 | rtlphy->rf_type = RF_2T2R; | ||
1932 | else if (tempval == 1) | ||
1933 | rtlphy->rf_type = RF_1T2R; | ||
1934 | else if (tempval == 2) | ||
1935 | rtlphy->rf_type = RF_1T2R; | ||
1936 | else if (tempval == 3) | ||
1937 | rtlphy->rf_type = RF_1T1R; | ||
1938 | |||
1939 | /* 1T2R but 1SS (1x1 receive combining) */ | ||
1940 | rtlefuse->b1x1_recvcombine = false; | ||
1941 | if (rtlphy->rf_type == RF_1T2R) { | ||
1942 | tempval = rtl_read_byte(rtlpriv, 0x07); | ||
1943 | if (!(tempval & BIT(0))) { | ||
1944 | rtlefuse->b1x1_recvcombine = true; | ||
1945 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1946 | ("RF_TYPE=1T2R but only 1SS\n")); | ||
1947 | } | ||
1948 | } | ||
1949 | rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; | ||
1950 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID]; | ||
1951 | |||
1952 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x", | ||
1953 | rtlefuse->eeprom_oemid)); | ||
1954 | |||
1955 | /* set channel paln to world wide 13 */ | ||
1956 | rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; | ||
1957 | } | ||
1958 | |||
1959 | void rtl92se_read_eeprom_info(struct ieee80211_hw *hw) | ||
1960 | { | ||
1961 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1962 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1963 | u8 tmp_u1b = 0; | ||
1964 | |||
1965 | tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD); | ||
1966 | |||
1967 | if (tmp_u1b & BIT(4)) { | ||
1968 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); | ||
1969 | rtlefuse->epromtype = EEPROM_93C46; | ||
1970 | } else { | ||
1971 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); | ||
1972 | rtlefuse->epromtype = EEPROM_BOOT_EFUSE; | ||
1973 | } | ||
1974 | |||
1975 | if (tmp_u1b & BIT(5)) { | ||
1976 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); | ||
1977 | rtlefuse->autoload_failflag = false; | ||
1978 | _rtl92se_read_adapter_info(hw); | ||
1979 | } else { | ||
1980 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); | ||
1981 | rtlefuse->autoload_failflag = true; | ||
1982 | } | ||
1983 | } | ||
1984 | |||
1985 | static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw, | ||
1986 | struct ieee80211_sta *sta) | ||
1987 | { | ||
1988 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1989 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1990 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1991 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1992 | u32 ratr_value; | ||
1993 | u8 ratr_index = 0; | ||
1994 | u8 nmode = mac->ht_enable; | ||
1995 | u8 mimo_ps = IEEE80211_SMPS_OFF; | ||
1996 | u16 shortgi_rate = 0; | ||
1997 | u32 tmp_ratr_value = 0; | ||
1998 | u8 curtxbw_40mhz = mac->bw_40; | ||
1999 | u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? | ||
2000 | 1 : 0; | ||
2001 | u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? | ||
2002 | 1 : 0; | ||
2003 | enum wireless_mode wirelessmode = mac->mode; | ||
2004 | |||
2005 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
2006 | ratr_value = sta->supp_rates[1] << 4; | ||
2007 | else | ||
2008 | ratr_value = sta->supp_rates[0]; | ||
2009 | ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | | ||
2010 | sta->ht_cap.mcs.rx_mask[0] << 12); | ||
2011 | switch (wirelessmode) { | ||
2012 | case WIRELESS_MODE_B: | ||
2013 | ratr_value &= 0x0000000D; | ||
2014 | break; | ||
2015 | case WIRELESS_MODE_G: | ||
2016 | ratr_value &= 0x00000FF5; | ||
2017 | break; | ||
2018 | case WIRELESS_MODE_N_24G: | ||
2019 | case WIRELESS_MODE_N_5G: | ||
2020 | nmode = 1; | ||
2021 | if (mimo_ps == IEEE80211_SMPS_STATIC) { | ||
2022 | ratr_value &= 0x0007F005; | ||
2023 | } else { | ||
2024 | u32 ratr_mask; | ||
2025 | |||
2026 | if (get_rf_type(rtlphy) == RF_1T2R || | ||
2027 | get_rf_type(rtlphy) == RF_1T1R) { | ||
2028 | if (curtxbw_40mhz) | ||
2029 | ratr_mask = 0x000ff015; | ||
2030 | else | ||
2031 | ratr_mask = 0x000ff005; | ||
2032 | } else { | ||
2033 | if (curtxbw_40mhz) | ||
2034 | ratr_mask = 0x0f0ff015; | ||
2035 | else | ||
2036 | ratr_mask = 0x0f0ff005; | ||
2037 | } | ||
2038 | |||
2039 | ratr_value &= ratr_mask; | ||
2040 | } | ||
2041 | break; | ||
2042 | default: | ||
2043 | if (rtlphy->rf_type == RF_1T2R) | ||
2044 | ratr_value &= 0x000ff0ff; | ||
2045 | else | ||
2046 | ratr_value &= 0x0f0ff0ff; | ||
2047 | |||
2048 | break; | ||
2049 | } | ||
2050 | |||
2051 | if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT) | ||
2052 | ratr_value &= 0x0FFFFFFF; | ||
2053 | else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT) | ||
2054 | ratr_value &= 0x0FFFFFF0; | ||
2055 | |||
2056 | if (nmode && ((curtxbw_40mhz && | ||
2057 | curshortgi_40mhz) || (!curtxbw_40mhz && | ||
2058 | curshortgi_20mhz))) { | ||
2059 | |||
2060 | ratr_value |= 0x10000000; | ||
2061 | tmp_ratr_value = (ratr_value >> 12); | ||
2062 | |||
2063 | for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { | ||
2064 | if ((1 << shortgi_rate) & tmp_ratr_value) | ||
2065 | break; | ||
2066 | } | ||
2067 | |||
2068 | shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | | ||
2069 | (shortgi_rate << 4) | (shortgi_rate); | ||
2070 | |||
2071 | rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate); | ||
2072 | } | ||
2073 | |||
2074 | rtl_write_dword(rtlpriv, ARFR0 + ratr_index * 4, ratr_value); | ||
2075 | if (ratr_value & 0xfffff000) | ||
2076 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_N); | ||
2077 | else | ||
2078 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG); | ||
2079 | |||
2080 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | ||
2081 | ("%x\n", rtl_read_dword(rtlpriv, ARFR0))); | ||
2082 | } | ||
2083 | |||
2084 | static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, | ||
2085 | struct ieee80211_sta *sta, | ||
2086 | u8 rssi_level) | ||
2087 | { | ||
2088 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2089 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2090 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
2091 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2092 | struct rtl_sta_info *sta_entry = NULL; | ||
2093 | u32 ratr_bitmap; | ||
2094 | u8 ratr_index = 0; | ||
2095 | u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | ||
2096 | ? 1 : 0; | ||
2097 | u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? | ||
2098 | 1 : 0; | ||
2099 | u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? | ||
2100 | 1 : 0; | ||
2101 | enum wireless_mode wirelessmode = 0; | ||
2102 | bool shortgi = false; | ||
2103 | u32 ratr_value = 0; | ||
2104 | u8 shortgi_rate = 0; | ||
2105 | u32 mask = 0; | ||
2106 | u32 band = 0; | ||
2107 | bool bmulticast = false; | ||
2108 | u8 macid = 0; | ||
2109 | u8 mimo_ps = IEEE80211_SMPS_OFF; | ||
2110 | |||
2111 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
2112 | wirelessmode = sta_entry->wireless_mode; | ||
2113 | if (mac->opmode == NL80211_IFTYPE_STATION) | ||
2114 | curtxbw_40mhz = mac->bw_40; | ||
2115 | else if (mac->opmode == NL80211_IFTYPE_AP || | ||
2116 | mac->opmode == NL80211_IFTYPE_ADHOC) | ||
2117 | macid = sta->aid + 1; | ||
2118 | |||
2119 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
2120 | ratr_bitmap = sta->supp_rates[1] << 4; | ||
2121 | else | ||
2122 | ratr_bitmap = sta->supp_rates[0]; | ||
2123 | ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | | ||
2124 | sta->ht_cap.mcs.rx_mask[0] << 12); | ||
2125 | switch (wirelessmode) { | ||
2126 | case WIRELESS_MODE_B: | ||
2127 | band |= WIRELESS_11B; | ||
2128 | ratr_index = RATR_INX_WIRELESS_B; | ||
2129 | if (ratr_bitmap & 0x0000000c) | ||
2130 | ratr_bitmap &= 0x0000000d; | ||
2131 | else | ||
2132 | ratr_bitmap &= 0x0000000f; | ||
2133 | break; | ||
2134 | case WIRELESS_MODE_G: | ||
2135 | band |= (WIRELESS_11G | WIRELESS_11B); | ||
2136 | ratr_index = RATR_INX_WIRELESS_GB; | ||
2137 | |||
2138 | if (rssi_level == 1) | ||
2139 | ratr_bitmap &= 0x00000f00; | ||
2140 | else if (rssi_level == 2) | ||
2141 | ratr_bitmap &= 0x00000ff0; | ||
2142 | else | ||
2143 | ratr_bitmap &= 0x00000ff5; | ||
2144 | break; | ||
2145 | case WIRELESS_MODE_A: | ||
2146 | band |= WIRELESS_11A; | ||
2147 | ratr_index = RATR_INX_WIRELESS_A; | ||
2148 | ratr_bitmap &= 0x00000ff0; | ||
2149 | break; | ||
2150 | case WIRELESS_MODE_N_24G: | ||
2151 | case WIRELESS_MODE_N_5G: | ||
2152 | band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B); | ||
2153 | ratr_index = RATR_INX_WIRELESS_NGB; | ||
2154 | |||
2155 | if (mimo_ps == IEEE80211_SMPS_STATIC) { | ||
2156 | if (rssi_level == 1) | ||
2157 | ratr_bitmap &= 0x00070000; | ||
2158 | else if (rssi_level == 2) | ||
2159 | ratr_bitmap &= 0x0007f000; | ||
2160 | else | ||
2161 | ratr_bitmap &= 0x0007f005; | ||
2162 | } else { | ||
2163 | if (rtlphy->rf_type == RF_1T2R || | ||
2164 | rtlphy->rf_type == RF_1T1R) { | ||
2165 | if (rssi_level == 1) { | ||
2166 | ratr_bitmap &= 0x000f0000; | ||
2167 | } else if (rssi_level == 3) { | ||
2168 | ratr_bitmap &= 0x000fc000; | ||
2169 | } else if (rssi_level == 5) { | ||
2170 | ratr_bitmap &= 0x000ff000; | ||
2171 | } else { | ||
2172 | if (curtxbw_40mhz) | ||
2173 | ratr_bitmap &= 0x000ff015; | ||
2174 | else | ||
2175 | ratr_bitmap &= 0x000ff005; | ||
2176 | } | ||
2177 | } else { | ||
2178 | if (rssi_level == 1) { | ||
2179 | ratr_bitmap &= 0x0f8f0000; | ||
2180 | } else if (rssi_level == 3) { | ||
2181 | ratr_bitmap &= 0x0f8fc000; | ||
2182 | } else if (rssi_level == 5) { | ||
2183 | ratr_bitmap &= 0x0f8ff000; | ||
2184 | } else { | ||
2185 | if (curtxbw_40mhz) | ||
2186 | ratr_bitmap &= 0x0f8ff015; | ||
2187 | else | ||
2188 | ratr_bitmap &= 0x0f8ff005; | ||
2189 | } | ||
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 | band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B); | ||
2203 | ratr_index = RATR_INX_WIRELESS_NGB; | ||
2204 | |||
2205 | if (rtlphy->rf_type == RF_1T2R) | ||
2206 | ratr_bitmap &= 0x000ff0ff; | ||
2207 | else | ||
2208 | ratr_bitmap &= 0x0f8ff0ff; | ||
2209 | break; | ||
2210 | } | ||
2211 | |||
2212 | if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT) | ||
2213 | ratr_bitmap &= 0x0FFFFFFF; | ||
2214 | else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT) | ||
2215 | ratr_bitmap &= 0x0FFFFFF0; | ||
2216 | |||
2217 | if (shortgi) { | ||
2218 | ratr_bitmap |= 0x10000000; | ||
2219 | /* Get MAX MCS available. */ | ||
2220 | ratr_value = (ratr_bitmap >> 12); | ||
2221 | for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { | ||
2222 | if ((1 << shortgi_rate) & ratr_value) | ||
2223 | break; | ||
2224 | } | ||
2225 | |||
2226 | shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | | ||
2227 | (shortgi_rate << 4) | (shortgi_rate); | ||
2228 | rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate); | ||
2229 | } | ||
2230 | |||
2231 | mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf); | ||
2232 | |||
2233 | RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n", | ||
2234 | mask, ratr_bitmap)); | ||
2235 | rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap); | ||
2236 | rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8))); | ||
2237 | |||
2238 | if (macid != 0) | ||
2239 | sta_entry->ratr_index = ratr_index; | ||
2240 | } | ||
2241 | |||
2242 | void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw, | ||
2243 | struct ieee80211_sta *sta, u8 rssi_level) | ||
2244 | { | ||
2245 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2246 | |||
2247 | if (rtlpriv->dm.useramask) | ||
2248 | rtl92se_update_hal_rate_mask(hw, sta, rssi_level); | ||
2249 | else | ||
2250 | rtl92se_update_hal_rate_table(hw, sta); | ||
2251 | } | ||
2252 | |||
2253 | void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw) | ||
2254 | { | ||
2255 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2256 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
2257 | u16 sifs_timer; | ||
2258 | |||
2259 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | ||
2260 | (u8 *)&mac->slot_time); | ||
2261 | sifs_timer = 0x0e0e; | ||
2262 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); | ||
2263 | |||
2264 | } | ||
2265 | |||
2266 | /* this ifunction is for RFKILL, it's different with windows, | ||
2267 | * because UI will disable wireless when GPIO Radio Off. | ||
2268 | * And here we not check or Disable/Enable ASPM like windows*/ | ||
2269 | bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) | ||
2270 | { | ||
2271 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2272 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
2273 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
2274 | enum rf_pwrstate rfpwr_toset, cur_rfstate; | ||
2275 | unsigned long flag = 0; | ||
2276 | bool actuallyset = false; | ||
2277 | bool turnonbypowerdomain = false; | ||
2278 | |||
2279 | /* just 8191se can check gpio before firstup, 92c/92d have fixed it */ | ||
2280 | if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) | ||
2281 | return false; | ||
2282 | |||
2283 | if (ppsc->swrf_processing) | ||
2284 | return false; | ||
2285 | |||
2286 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
2287 | if (ppsc->rfchange_inprogress) { | ||
2288 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2289 | return false; | ||
2290 | } else { | ||
2291 | ppsc->rfchange_inprogress = true; | ||
2292 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2293 | } | ||
2294 | |||
2295 | cur_rfstate = ppsc->rfpwr_state; | ||
2296 | |||
2297 | /* because after _rtl92s_phy_set_rfhalt, all power | ||
2298 | * closed, so we must open some power for GPIO check, | ||
2299 | * or we will always check GPIO RFOFF here, | ||
2300 | * And we should close power after GPIO check */ | ||
2301 | if (RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { | ||
2302 | _rtl92se_power_domain_init(hw); | ||
2303 | turnonbypowerdomain = true; | ||
2304 | } | ||
2305 | |||
2306 | rfpwr_toset = _rtl92se_rf_onoff_detect(hw); | ||
2307 | |||
2308 | if ((ppsc->hwradiooff == true) && (rfpwr_toset == ERFON)) { | ||
2309 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
2310 | ("RFKILL-HW Radio ON, RF ON\n")); | ||
2311 | |||
2312 | rfpwr_toset = ERFON; | ||
2313 | ppsc->hwradiooff = false; | ||
2314 | actuallyset = true; | ||
2315 | } else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) { | ||
2316 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
2317 | ("RFKILL-HW Radio OFF, RF OFF\n")); | ||
2318 | |||
2319 | rfpwr_toset = ERFOFF; | ||
2320 | ppsc->hwradiooff = true; | ||
2321 | actuallyset = true; | ||
2322 | } | ||
2323 | |||
2324 | if (actuallyset) { | ||
2325 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
2326 | ppsc->rfchange_inprogress = false; | ||
2327 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2328 | |||
2329 | /* this not include ifconfig wlan0 down case */ | ||
2330 | /* } else if (rfpwr_toset == ERFOFF || cur_rfstate == ERFOFF) { */ | ||
2331 | } else { | ||
2332 | /* because power_domain_init may be happen when | ||
2333 | * _rtl92s_phy_set_rfhalt, this will open some powers | ||
2334 | * and cause current increasing about 40 mA for ips, | ||
2335 | * rfoff and ifconfig down, so we set | ||
2336 | * _rtl92s_phy_set_rfhalt again here */ | ||
2337 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC && | ||
2338 | turnonbypowerdomain) { | ||
2339 | _rtl92s_phy_set_rfhalt(hw); | ||
2340 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | ||
2341 | } | ||
2342 | |||
2343 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
2344 | ppsc->rfchange_inprogress = false; | ||
2345 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2346 | } | ||
2347 | |||
2348 | *valid = 1; | ||
2349 | return !ppsc->hwradiooff; | ||
2350 | |||
2351 | } | ||
2352 | |||
2353 | /* Is_wepkey just used for WEP used as group & pairwise key | ||
2354 | * if pairwise is AES ang group is WEP Is_wepkey == false.*/ | ||
2355 | void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, | ||
2356 | bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all) | ||
2357 | { | ||
2358 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2359 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
2360 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
2361 | u8 *macaddr = p_macaddr; | ||
2362 | |||
2363 | u32 entry_id = 0; | ||
2364 | bool is_pairwise = false; | ||
2365 | |||
2366 | static u8 cam_const_addr[4][6] = { | ||
2367 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | ||
2368 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, | ||
2369 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, | ||
2370 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} | ||
2371 | }; | ||
2372 | static u8 cam_const_broad[] = { | ||
2373 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
2374 | }; | ||
2375 | |||
2376 | if (clear_all) { | ||
2377 | u8 idx = 0; | ||
2378 | u8 cam_offset = 0; | ||
2379 | u8 clear_number = 5; | ||
2380 | |||
2381 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); | ||
2382 | |||
2383 | for (idx = 0; idx < clear_number; idx++) { | ||
2384 | rtl_cam_mark_invalid(hw, cam_offset + idx); | ||
2385 | rtl_cam_empty_entry(hw, cam_offset + idx); | ||
2386 | |||
2387 | if (idx < 5) { | ||
2388 | memset(rtlpriv->sec.key_buf[idx], 0, | ||
2389 | MAX_KEY_LEN); | ||
2390 | rtlpriv->sec.key_len[idx] = 0; | ||
2391 | } | ||
2392 | } | ||
2393 | |||
2394 | } else { | ||
2395 | switch (enc_algo) { | ||
2396 | case WEP40_ENCRYPTION: | ||
2397 | enc_algo = CAM_WEP40; | ||
2398 | break; | ||
2399 | case WEP104_ENCRYPTION: | ||
2400 | enc_algo = CAM_WEP104; | ||
2401 | break; | ||
2402 | case TKIP_ENCRYPTION: | ||
2403 | enc_algo = CAM_TKIP; | ||
2404 | break; | ||
2405 | case AESCCMP_ENCRYPTION: | ||
2406 | enc_algo = CAM_AES; | ||
2407 | break; | ||
2408 | default: | ||
2409 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2410 | ("switch case not process\n")); | ||
2411 | enc_algo = CAM_TKIP; | ||
2412 | break; | ||
2413 | } | ||
2414 | |||
2415 | if (is_wepkey || rtlpriv->sec.use_defaultkey) { | ||
2416 | macaddr = cam_const_addr[key_index]; | ||
2417 | entry_id = key_index; | ||
2418 | } else { | ||
2419 | if (is_group) { | ||
2420 | macaddr = cam_const_broad; | ||
2421 | entry_id = key_index; | ||
2422 | } else { | ||
2423 | if (mac->opmode == NL80211_IFTYPE_AP) { | ||
2424 | entry_id = rtl_cam_get_free_entry(hw, | ||
2425 | p_macaddr); | ||
2426 | if (entry_id >= TOTAL_CAM_ENTRY) { | ||
2427 | RT_TRACE(rtlpriv, | ||
2428 | COMP_SEC, DBG_EMERG, | ||
2429 | ("Can not find free hw" | ||
2430 | " security cam entry\n")); | ||
2431 | return; | ||
2432 | } | ||
2433 | } else { | ||
2434 | entry_id = CAM_PAIRWISE_KEY_POSITION; | ||
2435 | } | ||
2436 | |||
2437 | key_index = PAIRWISE_KEYIDX; | ||
2438 | is_pairwise = true; | ||
2439 | } | ||
2440 | } | ||
2441 | |||
2442 | if (rtlpriv->sec.key_len[key_index] == 0) { | ||
2443 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
2444 | ("delete one entry, entry_id is %d\n", | ||
2445 | entry_id)); | ||
2446 | if (mac->opmode == NL80211_IFTYPE_AP) | ||
2447 | rtl_cam_del_entry(hw, p_macaddr); | ||
2448 | rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); | ||
2449 | } else { | ||
2450 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | ||
2451 | ("The insert KEY length is %d\n", | ||
2452 | rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); | ||
2453 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | ||
2454 | ("The insert KEY is %x %x\n", | ||
2455 | rtlpriv->sec.key_buf[0][0], | ||
2456 | rtlpriv->sec.key_buf[0][1])); | ||
2457 | |||
2458 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
2459 | ("add one entry\n")); | ||
2460 | if (is_pairwise) { | ||
2461 | RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, | ||
2462 | "Pairwiase Key content :", | ||
2463 | rtlpriv->sec.pairwise_key, | ||
2464 | rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); | ||
2465 | |||
2466 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
2467 | ("set Pairwiase key\n")); | ||
2468 | |||
2469 | rtl_cam_add_one_entry(hw, macaddr, key_index, | ||
2470 | entry_id, enc_algo, | ||
2471 | CAM_CONFIG_NO_USEDK, | ||
2472 | rtlpriv->sec.key_buf[key_index]); | ||
2473 | } else { | ||
2474 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
2475 | ("set group key\n")); | ||
2476 | |||
2477 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
2478 | rtl_cam_add_one_entry(hw, | ||
2479 | rtlefuse->dev_addr, | ||
2480 | PAIRWISE_KEYIDX, | ||
2481 | CAM_PAIRWISE_KEY_POSITION, | ||
2482 | enc_algo, CAM_CONFIG_NO_USEDK, | ||
2483 | rtlpriv->sec.key_buf[entry_id]); | ||
2484 | } | ||
2485 | |||
2486 | rtl_cam_add_one_entry(hw, macaddr, key_index, | ||
2487 | entry_id, enc_algo, | ||
2488 | CAM_CONFIG_NO_USEDK, | ||
2489 | rtlpriv->sec.key_buf[entry_id]); | ||
2490 | } | ||
2491 | |||
2492 | } | ||
2493 | } | ||
2494 | } | ||
2495 | |||
2496 | void rtl92se_suspend(struct ieee80211_hw *hw) | ||
2497 | { | ||
2498 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
2499 | |||
2500 | rtlpci->up_first_time = true; | ||
2501 | } | ||
2502 | |||
2503 | void rtl92se_resume(struct ieee80211_hw *hw) | ||
2504 | { | ||
2505 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
2506 | u32 val; | ||
2507 | |||
2508 | pci_read_config_dword(rtlpci->pdev, 0x40, &val); | ||
2509 | if ((val & 0x0000ff00) != 0) | ||
2510 | pci_write_config_dword(rtlpci->pdev, 0x40, | ||
2511 | val & 0xffff00ff); | ||
2512 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h new file mode 100644 index 000000000000..6160a9bfe98a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __REALTEK_PCI92SE_HW_H__ | ||
30 | #define __REALTEK_PCI92SE_HW_H__ | ||
31 | |||
32 | #define MSR_LINK_MANAGED 2 | ||
33 | #define MSR_LINK_NONE 0 | ||
34 | #define MSR_LINK_SHIFT 0 | ||
35 | #define MSR_LINK_ADHOC 1 | ||
36 | #define MSR_LINK_MASTER 3 | ||
37 | |||
38 | enum WIRELESS_NETWORK_TYPE { | ||
39 | WIRELESS_11B = 1, | ||
40 | WIRELESS_11G = 2, | ||
41 | WIRELESS_11A = 4, | ||
42 | WIRELESS_11N = 8 | ||
43 | }; | ||
44 | |||
45 | void rtl92se_get_hw_reg(struct ieee80211_hw *hw, | ||
46 | u8 variable, u8 *val); | ||
47 | void rtl92se_read_eeprom_info(struct ieee80211_hw *hw); | ||
48 | void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, | ||
49 | u32 *inta, u32 *intb); | ||
50 | int rtl92se_hw_init(struct ieee80211_hw *hw); | ||
51 | void rtl92se_card_disable(struct ieee80211_hw *hw); | ||
52 | void rtl92se_enable_interrupt(struct ieee80211_hw *hw); | ||
53 | void rtl92se_disable_interrupt(struct ieee80211_hw *hw); | ||
54 | int rtl92se_set_network_type(struct ieee80211_hw *hw, | ||
55 | enum nl80211_iftype type); | ||
56 | void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); | ||
57 | void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr); | ||
58 | void rtl92se_set_qos(struct ieee80211_hw *hw, int aci); | ||
59 | void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw); | ||
60 | void rtl92se_set_beacon_interval(struct ieee80211_hw *hw); | ||
61 | void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw, | ||
62 | u32 add_msr, u32 rm_msr); | ||
63 | void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, | ||
64 | u8 *val); | ||
65 | void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw, | ||
66 | struct ieee80211_sta *sta, u8 rssi_level); | ||
67 | void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw); | ||
68 | bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, | ||
69 | u8 *valid); | ||
70 | void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw); | ||
71 | void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw); | ||
72 | void rtl92se_set_key(struct ieee80211_hw *hw, | ||
73 | u32 key_index, u8 *macaddr, bool is_group, | ||
74 | u8 enc_algo, bool is_wepkey, bool clear_all); | ||
75 | void rtl92se_suspend(struct ieee80211_hw *hw); | ||
76 | void rtl92se_resume(struct ieee80211_hw *hw); | ||
77 | |||
78 | #endif | ||
79 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c new file mode 100644 index 000000000000..6d4f66616680 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../pci.h" | ||
32 | #include "reg.h" | ||
33 | #include "led.h" | ||
34 | |||
35 | static void _rtl92se_init_led(struct ieee80211_hw *hw, | ||
36 | struct rtl_led *pled, enum rtl_led_pin ledpin) | ||
37 | { | ||
38 | pled->hw = hw; | ||
39 | pled->ledpin = ledpin; | ||
40 | pled->ledon = false; | ||
41 | } | ||
42 | |||
43 | void rtl92se_init_sw_leds(struct ieee80211_hw *hw) | ||
44 | { | ||
45 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
46 | _rtl92se_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); | ||
47 | _rtl92se_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); | ||
48 | } | ||
49 | |||
50 | void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) | ||
51 | { | ||
52 | u8 ledcfg; | ||
53 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
54 | |||
55 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, | ||
56 | ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin)); | ||
57 | |||
58 | ledcfg = rtl_read_byte(rtlpriv, LEDCFG); | ||
59 | |||
60 | switch (pled->ledpin) { | ||
61 | case LED_PIN_GPIO0: | ||
62 | break; | ||
63 | case LED_PIN_LED0: | ||
64 | rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0xf0); | ||
65 | break; | ||
66 | case LED_PIN_LED1: | ||
67 | rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0x0f); | ||
68 | break; | ||
69 | default: | ||
70 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
71 | ("switch case not process\n")); | ||
72 | break; | ||
73 | } | ||
74 | pled->ledon = true; | ||
75 | } | ||
76 | |||
77 | void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | ||
78 | { | ||
79 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
80 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
81 | u8 ledcfg; | ||
82 | |||
83 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, | ||
84 | ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin)); | ||
85 | |||
86 | ledcfg = rtl_read_byte(rtlpriv, LEDCFG); | ||
87 | |||
88 | switch (pled->ledpin) { | ||
89 | case LED_PIN_GPIO0: | ||
90 | break; | ||
91 | case LED_PIN_LED0: | ||
92 | ledcfg &= 0xf0; | ||
93 | if (pcipriv->ledctl.led_opendrain == true) | ||
94 | rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1))); | ||
95 | else | ||
96 | rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3))); | ||
97 | break; | ||
98 | case LED_PIN_LED1: | ||
99 | ledcfg &= 0x0f; | ||
100 | rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3))); | ||
101 | break; | ||
102 | default: | ||
103 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
104 | ("switch case not process\n")); | ||
105 | break; | ||
106 | } | ||
107 | pled->ledon = false; | ||
108 | } | ||
109 | |||
110 | static void _rtl92se_sw_led_control(struct ieee80211_hw *hw, | ||
111 | enum led_ctl_mode ledaction) | ||
112 | { | ||
113 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
114 | struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); | ||
115 | switch (ledaction) { | ||
116 | case LED_CTL_POWER_ON: | ||
117 | case LED_CTL_LINK: | ||
118 | case LED_CTL_NO_LINK: | ||
119 | rtl92se_sw_led_on(hw, pLed0); | ||
120 | break; | ||
121 | case LED_CTL_POWER_OFF: | ||
122 | rtl92se_sw_led_off(hw, pLed0); | ||
123 | break; | ||
124 | default: | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) | ||
130 | { | ||
131 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
132 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
133 | |||
134 | if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && | ||
135 | (ledaction == LED_CTL_TX || | ||
136 | ledaction == LED_CTL_RX || | ||
137 | ledaction == LED_CTL_SITE_SURVEY || | ||
138 | ledaction == LED_CTL_LINK || | ||
139 | ledaction == LED_CTL_NO_LINK || | ||
140 | ledaction == LED_CTL_START_TO_LINK || | ||
141 | ledaction == LED_CTL_POWER_ON)) { | ||
142 | return; | ||
143 | } | ||
144 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", | ||
145 | ledaction)); | ||
146 | |||
147 | _rtl92se_sw_led_control(hw, ledaction); | ||
148 | } | ||
149 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/rtlwifi/rtl8192se/led.h new file mode 100644 index 000000000000..8cce3870af3c --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __REALTEK_PCI92SE_LED_H__ | ||
30 | #define __REALTEK_PCI92SE_LED_H__ | ||
31 | |||
32 | void rtl92se_init_sw_leds(struct ieee80211_hw *hw); | ||
33 | void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
34 | void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
35 | void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); | ||
36 | |||
37 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c new file mode 100644 index 000000000000..63b45e60a95e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c | |||
@@ -0,0 +1,1740 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../pci.h" | ||
32 | #include "../ps.h" | ||
33 | #include "reg.h" | ||
34 | #include "def.h" | ||
35 | #include "phy.h" | ||
36 | #include "rf.h" | ||
37 | #include "dm.h" | ||
38 | #include "fw.h" | ||
39 | #include "hw.h" | ||
40 | #include "table.h" | ||
41 | |||
42 | static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask) | ||
43 | { | ||
44 | u32 i; | ||
45 | |||
46 | for (i = 0; i <= 31; i++) { | ||
47 | if (((bitmask >> i) & 0x1) == 1) | ||
48 | break; | ||
49 | } | ||
50 | |||
51 | return i; | ||
52 | } | ||
53 | |||
54 | u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) | ||
55 | { | ||
56 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
57 | u32 returnvalue = 0, originalvalue, bitshift; | ||
58 | |||
59 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n", | ||
60 | regaddr, bitmask)); | ||
61 | |||
62 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
63 | bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); | ||
64 | returnvalue = (originalvalue & bitmask) >> bitshift; | ||
65 | |||
66 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
67 | ("BBR MASK=0x%x Addr[0x%x]=0x%x\n", | ||
68 | bitmask, regaddr, originalvalue)); | ||
69 | |||
70 | return returnvalue; | ||
71 | |||
72 | } | ||
73 | |||
74 | void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, | ||
75 | u32 data) | ||
76 | { | ||
77 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
78 | u32 originalvalue, bitshift; | ||
79 | |||
80 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
81 | " data(%#x)\n", regaddr, bitmask, data)); | ||
82 | |||
83 | if (bitmask != MASKDWORD) { | ||
84 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
85 | bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); | ||
86 | data = ((originalvalue & (~bitmask)) | (data << bitshift)); | ||
87 | } | ||
88 | |||
89 | rtl_write_dword(rtlpriv, regaddr, data); | ||
90 | |||
91 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
92 | " data(%#x)\n", regaddr, bitmask, data)); | ||
93 | |||
94 | } | ||
95 | |||
96 | static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
97 | enum radio_path rfpath, u32 offset) | ||
98 | { | ||
99 | |||
100 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
101 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
102 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
103 | u32 newoffset; | ||
104 | u32 tmplong, tmplong2; | ||
105 | u8 rfpi_enable = 0; | ||
106 | u32 retvalue = 0; | ||
107 | |||
108 | offset &= 0x3f; | ||
109 | newoffset = offset; | ||
110 | |||
111 | tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); | ||
112 | |||
113 | if (rfpath == RF90_PATH_A) | ||
114 | tmplong2 = tmplong; | ||
115 | else | ||
116 | tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); | ||
117 | |||
118 | tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) | | ||
119 | BLSSI_READEDGE; | ||
120 | |||
121 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
122 | tmplong & (~BLSSI_READEDGE)); | ||
123 | |||
124 | mdelay(1); | ||
125 | |||
126 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); | ||
127 | mdelay(1); | ||
128 | |||
129 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong | | ||
130 | BLSSI_READEDGE); | ||
131 | mdelay(1); | ||
132 | |||
133 | if (rfpath == RF90_PATH_A) | ||
134 | rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, | ||
135 | BIT(8)); | ||
136 | else if (rfpath == RF90_PATH_B) | ||
137 | rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, | ||
138 | BIT(8)); | ||
139 | |||
140 | if (rfpi_enable) | ||
141 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, | ||
142 | BLSSI_READBACK_DATA); | ||
143 | else | ||
144 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | ||
145 | BLSSI_READBACK_DATA); | ||
146 | |||
147 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | ||
148 | BLSSI_READBACK_DATA); | ||
149 | |||
150 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", | ||
151 | rfpath, pphyreg->rflssi_readback, retvalue)); | ||
152 | |||
153 | return retvalue; | ||
154 | |||
155 | } | ||
156 | |||
157 | static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
158 | enum radio_path rfpath, u32 offset, | ||
159 | u32 data) | ||
160 | { | ||
161 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
162 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
163 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
164 | u32 data_and_addr = 0; | ||
165 | u32 newoffset; | ||
166 | |||
167 | offset &= 0x3f; | ||
168 | newoffset = offset; | ||
169 | |||
170 | data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; | ||
171 | rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); | ||
172 | |||
173 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", | ||
174 | rfpath, pphyreg->rf3wire_offset, data_and_addr)); | ||
175 | } | ||
176 | |||
177 | |||
178 | u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, | ||
179 | u32 regaddr, u32 bitmask) | ||
180 | { | ||
181 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
182 | u32 original_value, readback_value, bitshift; | ||
183 | unsigned long flags; | ||
184 | |||
185 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " | ||
186 | "bitmask(%#x)\n", regaddr, rfpath, bitmask)); | ||
187 | |||
188 | spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); | ||
189 | |||
190 | original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); | ||
191 | |||
192 | bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); | ||
193 | readback_value = (original_value & bitmask) >> bitshift; | ||
194 | |||
195 | spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); | ||
196 | |||
197 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " | ||
198 | "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath, | ||
199 | bitmask, original_value)); | ||
200 | |||
201 | return readback_value; | ||
202 | } | ||
203 | |||
204 | void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, | ||
205 | u32 regaddr, u32 bitmask, u32 data) | ||
206 | { | ||
207 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
208 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
209 | u32 original_value, bitshift; | ||
210 | unsigned long flags; | ||
211 | |||
212 | if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) | ||
213 | return; | ||
214 | |||
215 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
216 | " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); | ||
217 | |||
218 | spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); | ||
219 | |||
220 | if (bitmask != RFREG_OFFSET_MASK) { | ||
221 | original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, | ||
222 | regaddr); | ||
223 | bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); | ||
224 | data = ((original_value & (~bitmask)) | (data << bitshift)); | ||
225 | } | ||
226 | |||
227 | _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data); | ||
228 | |||
229 | spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); | ||
230 | |||
231 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), " | ||
232 | "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); | ||
233 | |||
234 | } | ||
235 | |||
236 | void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, | ||
237 | u8 operation) | ||
238 | { | ||
239 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
240 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
241 | |||
242 | if (!is_hal_stop(rtlhal)) { | ||
243 | switch (operation) { | ||
244 | case SCAN_OPT_BACKUP: | ||
245 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN); | ||
246 | break; | ||
247 | case SCAN_OPT_RESTORE: | ||
248 | rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN); | ||
249 | break; | ||
250 | default: | ||
251 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
252 | ("Unknown operation.\n")); | ||
253 | break; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | |||
258 | void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
259 | enum nl80211_channel_type ch_type) | ||
260 | { | ||
261 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
262 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
263 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
264 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
265 | u8 reg_bw_opmode; | ||
266 | u8 reg_prsr_rsc; | ||
267 | |||
268 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", | ||
269 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? | ||
270 | "20MHz" : "40MHz")); | ||
271 | |||
272 | if (rtlphy->set_bwmode_inprogress) | ||
273 | return; | ||
274 | if (is_hal_stop(rtlhal)) | ||
275 | return; | ||
276 | |||
277 | rtlphy->set_bwmode_inprogress = true; | ||
278 | |||
279 | reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE); | ||
280 | reg_prsr_rsc = rtl_read_byte(rtlpriv, RRSR + 2); | ||
281 | |||
282 | switch (rtlphy->current_chan_bw) { | ||
283 | case HT_CHANNEL_WIDTH_20: | ||
284 | reg_bw_opmode |= BW_OPMODE_20MHZ; | ||
285 | rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); | ||
286 | break; | ||
287 | case HT_CHANNEL_WIDTH_20_40: | ||
288 | reg_bw_opmode &= ~BW_OPMODE_20MHZ; | ||
289 | rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); | ||
290 | break; | ||
291 | default: | ||
292 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
293 | ("unknown bandwidth: %#X\n", | ||
294 | rtlphy->current_chan_bw)); | ||
295 | break; | ||
296 | } | ||
297 | |||
298 | switch (rtlphy->current_chan_bw) { | ||
299 | case HT_CHANNEL_WIDTH_20: | ||
300 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); | ||
301 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); | ||
302 | |||
303 | if (rtlhal->version >= VERSION_8192S_BCUT) | ||
304 | rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58); | ||
305 | break; | ||
306 | case HT_CHANNEL_WIDTH_20_40: | ||
307 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); | ||
308 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); | ||
309 | |||
310 | rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, | ||
311 | (mac->cur_40_prime_sc >> 1)); | ||
312 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); | ||
313 | |||
314 | if (rtlhal->version >= VERSION_8192S_BCUT) | ||
315 | rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18); | ||
316 | break; | ||
317 | default: | ||
318 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
319 | ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); | ||
320 | break; | ||
321 | } | ||
322 | |||
323 | rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); | ||
324 | rtlphy->set_bwmode_inprogress = false; | ||
325 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
326 | } | ||
327 | |||
328 | static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
329 | u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid, | ||
330 | u32 para1, u32 para2, u32 msdelay) | ||
331 | { | ||
332 | struct swchnlcmd *pcmd; | ||
333 | |||
334 | if (cmdtable == NULL) { | ||
335 | RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); | ||
336 | return false; | ||
337 | } | ||
338 | |||
339 | if (cmdtableidx >= cmdtablesz) | ||
340 | return false; | ||
341 | |||
342 | pcmd = cmdtable + cmdtableidx; | ||
343 | pcmd->cmdid = cmdid; | ||
344 | pcmd->para1 = para1; | ||
345 | pcmd->para2 = para2; | ||
346 | pcmd->msdelay = msdelay; | ||
347 | |||
348 | return true; | ||
349 | } | ||
350 | |||
351 | static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
352 | u8 channel, u8 *stage, u8 *step, u32 *delay) | ||
353 | { | ||
354 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
355 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
356 | struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; | ||
357 | u32 precommoncmdcnt; | ||
358 | struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; | ||
359 | u32 postcommoncmdcnt; | ||
360 | struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; | ||
361 | u32 rfdependcmdcnt; | ||
362 | struct swchnlcmd *currentcmd = NULL; | ||
363 | u8 rfpath; | ||
364 | u8 num_total_rfpath = rtlphy->num_total_rfpath; | ||
365 | |||
366 | precommoncmdcnt = 0; | ||
367 | _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
368 | MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); | ||
369 | _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
370 | MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); | ||
371 | |||
372 | postcommoncmdcnt = 0; | ||
373 | |||
374 | _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, | ||
375 | MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); | ||
376 | |||
377 | rfdependcmdcnt = 0; | ||
378 | |||
379 | RT_ASSERT((channel >= 1 && channel <= 14), | ||
380 | ("illegal channel for Zebra: %d\n", channel)); | ||
381 | |||
382 | _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
383 | MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, | ||
384 | RF_CHNLBW, channel, 10); | ||
385 | |||
386 | _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
387 | MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); | ||
388 | |||
389 | do { | ||
390 | switch (*stage) { | ||
391 | case 0: | ||
392 | currentcmd = &precommoncmd[*step]; | ||
393 | break; | ||
394 | case 1: | ||
395 | currentcmd = &rfdependcmd[*step]; | ||
396 | break; | ||
397 | case 2: | ||
398 | currentcmd = &postcommoncmd[*step]; | ||
399 | break; | ||
400 | } | ||
401 | |||
402 | if (currentcmd->cmdid == CMDID_END) { | ||
403 | if ((*stage) == 2) { | ||
404 | return true; | ||
405 | } else { | ||
406 | (*stage)++; | ||
407 | (*step) = 0; | ||
408 | continue; | ||
409 | } | ||
410 | } | ||
411 | |||
412 | switch (currentcmd->cmdid) { | ||
413 | case CMDID_SET_TXPOWEROWER_LEVEL: | ||
414 | rtl92s_phy_set_txpower(hw, channel); | ||
415 | break; | ||
416 | case CMDID_WRITEPORT_ULONG: | ||
417 | rtl_write_dword(rtlpriv, currentcmd->para1, | ||
418 | currentcmd->para2); | ||
419 | break; | ||
420 | case CMDID_WRITEPORT_USHORT: | ||
421 | rtl_write_word(rtlpriv, currentcmd->para1, | ||
422 | (u16)currentcmd->para2); | ||
423 | break; | ||
424 | case CMDID_WRITEPORT_UCHAR: | ||
425 | rtl_write_byte(rtlpriv, currentcmd->para1, | ||
426 | (u8)currentcmd->para2); | ||
427 | break; | ||
428 | case CMDID_RF_WRITEREG: | ||
429 | for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { | ||
430 | rtlphy->rfreg_chnlval[rfpath] = | ||
431 | ((rtlphy->rfreg_chnlval[rfpath] & | ||
432 | 0xfffffc00) | currentcmd->para2); | ||
433 | rtl_set_rfreg(hw, (enum radio_path)rfpath, | ||
434 | currentcmd->para1, | ||
435 | RFREG_OFFSET_MASK, | ||
436 | rtlphy->rfreg_chnlval[rfpath]); | ||
437 | } | ||
438 | break; | ||
439 | default: | ||
440 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
441 | ("switch case not process\n")); | ||
442 | break; | ||
443 | } | ||
444 | |||
445 | break; | ||
446 | } while (true); | ||
447 | |||
448 | (*delay) = currentcmd->msdelay; | ||
449 | (*step)++; | ||
450 | return false; | ||
451 | } | ||
452 | |||
453 | u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) | ||
454 | { | ||
455 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
456 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
457 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
458 | u32 delay; | ||
459 | bool ret; | ||
460 | |||
461 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
462 | ("switch to channel%d\n", | ||
463 | rtlphy->current_channel)); | ||
464 | |||
465 | if (rtlphy->sw_chnl_inprogress) | ||
466 | return 0; | ||
467 | |||
468 | if (rtlphy->set_bwmode_inprogress) | ||
469 | return 0; | ||
470 | |||
471 | if (is_hal_stop(rtlhal)) | ||
472 | return 0; | ||
473 | |||
474 | rtlphy->sw_chnl_inprogress = true; | ||
475 | rtlphy->sw_chnl_stage = 0; | ||
476 | rtlphy->sw_chnl_step = 0; | ||
477 | |||
478 | do { | ||
479 | if (!rtlphy->sw_chnl_inprogress) | ||
480 | break; | ||
481 | |||
482 | ret = _rtl92s_phy_sw_chnl_step_by_step(hw, | ||
483 | rtlphy->current_channel, | ||
484 | &rtlphy->sw_chnl_stage, | ||
485 | &rtlphy->sw_chnl_step, &delay); | ||
486 | if (!ret) { | ||
487 | if (delay > 0) | ||
488 | mdelay(delay); | ||
489 | else | ||
490 | continue; | ||
491 | } else { | ||
492 | rtlphy->sw_chnl_inprogress = false; | ||
493 | } | ||
494 | break; | ||
495 | } while (true); | ||
496 | |||
497 | rtlphy->sw_chnl_inprogress = false; | ||
498 | |||
499 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
500 | |||
501 | return 1; | ||
502 | } | ||
503 | |||
504 | static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw) | ||
505 | { | ||
506 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
507 | u8 u1btmp; | ||
508 | |||
509 | u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL); | ||
510 | u1btmp |= BIT(0); | ||
511 | |||
512 | rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp); | ||
513 | rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0); | ||
514 | rtl_write_byte(rtlpriv, TXPAUSE, 0xFF); | ||
515 | rtl_write_word(rtlpriv, CMDR, 0x57FC); | ||
516 | udelay(100); | ||
517 | |||
518 | rtl_write_word(rtlpriv, CMDR, 0x77FC); | ||
519 | rtl_write_byte(rtlpriv, PHY_CCA, 0x0); | ||
520 | udelay(10); | ||
521 | |||
522 | rtl_write_word(rtlpriv, CMDR, 0x37FC); | ||
523 | udelay(10); | ||
524 | |||
525 | rtl_write_word(rtlpriv, CMDR, 0x77FC); | ||
526 | udelay(10); | ||
527 | |||
528 | rtl_write_word(rtlpriv, CMDR, 0x57FC); | ||
529 | |||
530 | /* we should chnge GPIO to input mode | ||
531 | * this will drop away current about 25mA*/ | ||
532 | rtl8192se_gpiobit3_cfg_inputmode(hw); | ||
533 | } | ||
534 | |||
535 | bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
536 | enum rf_pwrstate rfpwr_state) | ||
537 | { | ||
538 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
539 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
540 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
541 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
542 | bool bresult = true; | ||
543 | u8 i, queue_id; | ||
544 | struct rtl8192_tx_ring *ring = NULL; | ||
545 | |||
546 | if (rfpwr_state == ppsc->rfpwr_state) | ||
547 | return false; | ||
548 | |||
549 | ppsc->set_rfpowerstate_inprogress = true; | ||
550 | |||
551 | switch (rfpwr_state) { | ||
552 | case ERFON:{ | ||
553 | if ((ppsc->rfpwr_state == ERFOFF) && | ||
554 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { | ||
555 | |||
556 | bool rtstatus; | ||
557 | u32 InitializeCount = 0; | ||
558 | do { | ||
559 | InitializeCount++; | ||
560 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
561 | ("IPS Set eRf nic enable\n")); | ||
562 | rtstatus = rtl_ps_enable_nic(hw); | ||
563 | } while ((rtstatus != true) && | ||
564 | (InitializeCount < 10)); | ||
565 | |||
566 | RT_CLEAR_PS_LEVEL(ppsc, | ||
567 | RT_RF_OFF_LEVL_HALT_NIC); | ||
568 | } else { | ||
569 | RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, | ||
570 | ("awake, sleeped:%d ms " | ||
571 | "state_inap:%x\n", | ||
572 | jiffies_to_msecs(jiffies - | ||
573 | ppsc->last_sleep_jiffies), | ||
574 | rtlpriv->psc.state_inap)); | ||
575 | ppsc->last_awake_jiffies = jiffies; | ||
576 | rtl_write_word(rtlpriv, CMDR, 0x37FC); | ||
577 | rtl_write_byte(rtlpriv, TXPAUSE, 0x00); | ||
578 | rtl_write_byte(rtlpriv, PHY_CCA, 0x3); | ||
579 | } | ||
580 | |||
581 | if (mac->link_state == MAC80211_LINKED) | ||
582 | rtlpriv->cfg->ops->led_control(hw, | ||
583 | LED_CTL_LINK); | ||
584 | else | ||
585 | rtlpriv->cfg->ops->led_control(hw, | ||
586 | LED_CTL_NO_LINK); | ||
587 | break; | ||
588 | } | ||
589 | case ERFOFF:{ | ||
590 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { | ||
591 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
592 | ("IPS Set eRf nic disable\n")); | ||
593 | rtl_ps_disable_nic(hw); | ||
594 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | ||
595 | } else { | ||
596 | if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) | ||
597 | rtlpriv->cfg->ops->led_control(hw, | ||
598 | LED_CTL_NO_LINK); | ||
599 | else | ||
600 | rtlpriv->cfg->ops->led_control(hw, | ||
601 | LED_CTL_POWER_OFF); | ||
602 | } | ||
603 | break; | ||
604 | } | ||
605 | case ERFSLEEP: | ||
606 | if (ppsc->rfpwr_state == ERFOFF) | ||
607 | break; | ||
608 | |||
609 | for (queue_id = 0, i = 0; | ||
610 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | ||
611 | ring = &pcipriv->dev.tx_ring[queue_id]; | ||
612 | if (skb_queue_len(&ring->queue) == 0 || | ||
613 | queue_id == BEACON_QUEUE) { | ||
614 | queue_id++; | ||
615 | continue; | ||
616 | } else { | ||
617 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
618 | ("eRf Off/Sleep: " | ||
619 | "%d times TcbBusyQueue[%d] = " | ||
620 | "%d before doze!\n", | ||
621 | (i + 1), queue_id, | ||
622 | skb_queue_len(&ring->queue))); | ||
623 | |||
624 | udelay(10); | ||
625 | i++; | ||
626 | } | ||
627 | |||
628 | if (i >= MAX_DOZE_WAITING_TIMES_9x) { | ||
629 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
630 | ("\nERFOFF: %d times" | ||
631 | "TcbBusyQueue[%d] = %d !\n", | ||
632 | MAX_DOZE_WAITING_TIMES_9x, | ||
633 | queue_id, | ||
634 | skb_queue_len(&ring->queue))); | ||
635 | break; | ||
636 | } | ||
637 | } | ||
638 | |||
639 | RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, | ||
640 | ("Set ERFSLEEP awaked:%d ms\n", | ||
641 | jiffies_to_msecs(jiffies - | ||
642 | ppsc->last_awake_jiffies))); | ||
643 | |||
644 | RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, | ||
645 | ("sleep awaked:%d ms " | ||
646 | "state_inap:%x\n", jiffies_to_msecs(jiffies - | ||
647 | ppsc->last_awake_jiffies), | ||
648 | rtlpriv->psc.state_inap)); | ||
649 | ppsc->last_sleep_jiffies = jiffies; | ||
650 | _rtl92se_phy_set_rf_sleep(hw); | ||
651 | break; | ||
652 | default: | ||
653 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
654 | ("switch case not process\n")); | ||
655 | bresult = false; | ||
656 | break; | ||
657 | } | ||
658 | |||
659 | if (bresult) | ||
660 | ppsc->rfpwr_state = rfpwr_state; | ||
661 | |||
662 | ppsc->set_rfpowerstate_inprogress = false; | ||
663 | |||
664 | return bresult; | ||
665 | } | ||
666 | |||
667 | static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw, | ||
668 | enum radio_path rfpath) | ||
669 | { | ||
670 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
671 | bool rtstatus = true; | ||
672 | u32 tmpval = 0; | ||
673 | |||
674 | /* If inferiority IC, we have to increase the PA bias current */ | ||
675 | if (rtlhal->ic_class != IC_INFERIORITY_A) { | ||
676 | tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf); | ||
677 | rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1); | ||
678 | } | ||
679 | |||
680 | return rtstatus; | ||
681 | } | ||
682 | |||
683 | static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, | ||
684 | u32 reg_addr, u32 bitmask, u32 data) | ||
685 | { | ||
686 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
687 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
688 | |||
689 | if (reg_addr == RTXAGC_RATE18_06) | ||
690 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = | ||
691 | data; | ||
692 | if (reg_addr == RTXAGC_RATE54_24) | ||
693 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = | ||
694 | data; | ||
695 | if (reg_addr == RTXAGC_CCK_MCS32) | ||
696 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = | ||
697 | data; | ||
698 | if (reg_addr == RTXAGC_MCS03_MCS00) | ||
699 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = | ||
700 | data; | ||
701 | if (reg_addr == RTXAGC_MCS07_MCS04) | ||
702 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = | ||
703 | data; | ||
704 | if (reg_addr == RTXAGC_MCS11_MCS08) | ||
705 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = | ||
706 | data; | ||
707 | if (reg_addr == RTXAGC_MCS15_MCS12) { | ||
708 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = | ||
709 | data; | ||
710 | rtlphy->pwrgroup_cnt++; | ||
711 | } | ||
712 | } | ||
713 | |||
714 | static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) | ||
715 | { | ||
716 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
717 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
718 | |||
719 | /*RF Interface Sowrtware Control */ | ||
720 | rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
721 | rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
722 | rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
723 | rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
724 | |||
725 | /* RF Interface Readback Value */ | ||
726 | rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
727 | rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
728 | rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
729 | rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
730 | |||
731 | /* RF Interface Output (and Enable) */ | ||
732 | rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; | ||
733 | rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; | ||
734 | rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE; | ||
735 | rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE; | ||
736 | |||
737 | /* RF Interface (Output and) Enable */ | ||
738 | rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; | ||
739 | rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; | ||
740 | rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE; | ||
741 | rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE; | ||
742 | |||
743 | /* Addr of LSSI. Wirte RF register by driver */ | ||
744 | rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = | ||
745 | RFPGA0_XA_LSSIPARAMETER; | ||
746 | rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = | ||
747 | RFPGA0_XB_LSSIPARAMETER; | ||
748 | rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset = | ||
749 | RFPGA0_XC_LSSIPARAMETER; | ||
750 | rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset = | ||
751 | RFPGA0_XD_LSSIPARAMETER; | ||
752 | |||
753 | /* RF parameter */ | ||
754 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; | ||
755 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; | ||
756 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; | ||
757 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; | ||
758 | |||
759 | /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ | ||
760 | rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
761 | rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
762 | rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
763 | rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
764 | |||
765 | /* Tranceiver A~D HSSI Parameter-1 */ | ||
766 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; | ||
767 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; | ||
768 | rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1; | ||
769 | rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1; | ||
770 | |||
771 | /* Tranceiver A~D HSSI Parameter-2 */ | ||
772 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; | ||
773 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; | ||
774 | rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2; | ||
775 | rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2; | ||
776 | |||
777 | /* RF switch Control */ | ||
778 | rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = | ||
779 | RFPGA0_XAB_SWITCHCONTROL; | ||
780 | rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = | ||
781 | RFPGA0_XAB_SWITCHCONTROL; | ||
782 | rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = | ||
783 | RFPGA0_XCD_SWITCHCONTROL; | ||
784 | rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = | ||
785 | RFPGA0_XCD_SWITCHCONTROL; | ||
786 | |||
787 | /* AGC control 1 */ | ||
788 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | ||
789 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; | ||
790 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; | ||
791 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; | ||
792 | |||
793 | /* AGC control 2 */ | ||
794 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; | ||
795 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; | ||
796 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; | ||
797 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | ||
798 | |||
799 | /* RX AFE control 1 */ | ||
800 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = | ||
801 | ROFDM0_XARXIQIMBALANCE; | ||
802 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = | ||
803 | ROFDM0_XBRXIQIMBALANCE; | ||
804 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = | ||
805 | ROFDM0_XCRXIQIMBALANCE; | ||
806 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = | ||
807 | ROFDM0_XDRXIQIMBALANCE; | ||
808 | |||
809 | /* RX AFE control 1 */ | ||
810 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | ||
811 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; | ||
812 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; | ||
813 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | ||
814 | |||
815 | /* Tx AFE control 1 */ | ||
816 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = | ||
817 | ROFDM0_XATXIQIMBALANCE; | ||
818 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = | ||
819 | ROFDM0_XBTXIQIMBALANCE; | ||
820 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = | ||
821 | ROFDM0_XCTXIQIMBALANCE; | ||
822 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = | ||
823 | ROFDM0_XDTXIQIMBALANCE; | ||
824 | |||
825 | /* Tx AFE control 2 */ | ||
826 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | ||
827 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; | ||
828 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; | ||
829 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | ||
830 | |||
831 | /* Tranceiver LSSI Readback */ | ||
832 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = | ||
833 | RFPGA0_XA_LSSIREADBACK; | ||
834 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = | ||
835 | RFPGA0_XB_LSSIREADBACK; | ||
836 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = | ||
837 | RFPGA0_XC_LSSIREADBACK; | ||
838 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = | ||
839 | RFPGA0_XD_LSSIREADBACK; | ||
840 | |||
841 | /* Tranceiver LSSI Readback PI mode */ | ||
842 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = | ||
843 | TRANSCEIVERA_HSPI_READBACK; | ||
844 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = | ||
845 | TRANSCEIVERB_HSPI_READBACK; | ||
846 | } | ||
847 | |||
848 | |||
849 | static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype) | ||
850 | { | ||
851 | int i; | ||
852 | u32 *phy_reg_table; | ||
853 | u32 *agc_table; | ||
854 | u16 phy_reg_len, agc_len; | ||
855 | |||
856 | agc_len = AGCTAB_ARRAYLENGTH; | ||
857 | agc_table = rtl8192seagctab_array; | ||
858 | /* Default RF_type: 2T2R */ | ||
859 | phy_reg_len = PHY_REG_2T2RARRAYLENGTH; | ||
860 | phy_reg_table = rtl8192sephy_reg_2t2rarray; | ||
861 | |||
862 | if (configtype == BASEBAND_CONFIG_PHY_REG) { | ||
863 | for (i = 0; i < phy_reg_len; i = i + 2) { | ||
864 | if (phy_reg_table[i] == 0xfe) | ||
865 | mdelay(50); | ||
866 | else if (phy_reg_table[i] == 0xfd) | ||
867 | mdelay(5); | ||
868 | else if (phy_reg_table[i] == 0xfc) | ||
869 | mdelay(1); | ||
870 | else if (phy_reg_table[i] == 0xfb) | ||
871 | udelay(50); | ||
872 | else if (phy_reg_table[i] == 0xfa) | ||
873 | udelay(5); | ||
874 | else if (phy_reg_table[i] == 0xf9) | ||
875 | udelay(1); | ||
876 | |||
877 | /* Add delay for ECS T20 & LG malow platform, */ | ||
878 | udelay(1); | ||
879 | |||
880 | rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD, | ||
881 | phy_reg_table[i + 1]); | ||
882 | } | ||
883 | } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { | ||
884 | for (i = 0; i < agc_len; i = i + 2) { | ||
885 | rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD, | ||
886 | agc_table[i + 1]); | ||
887 | |||
888 | /* Add delay for ECS T20 & LG malow platform */ | ||
889 | udelay(1); | ||
890 | } | ||
891 | } | ||
892 | |||
893 | return true; | ||
894 | } | ||
895 | |||
896 | static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw, | ||
897 | u8 configtype) | ||
898 | { | ||
899 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
900 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
901 | u32 *phy_regarray2xtxr_table; | ||
902 | u16 phy_regarray2xtxr_len; | ||
903 | int i; | ||
904 | |||
905 | if (rtlphy->rf_type == RF_1T1R) { | ||
906 | phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray; | ||
907 | phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH; | ||
908 | } else if (rtlphy->rf_type == RF_1T2R) { | ||
909 | phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray; | ||
910 | phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH; | ||
911 | } else { | ||
912 | return false; | ||
913 | } | ||
914 | |||
915 | if (configtype == BASEBAND_CONFIG_PHY_REG) { | ||
916 | for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) { | ||
917 | if (phy_regarray2xtxr_table[i] == 0xfe) | ||
918 | mdelay(50); | ||
919 | else if (phy_regarray2xtxr_table[i] == 0xfd) | ||
920 | mdelay(5); | ||
921 | else if (phy_regarray2xtxr_table[i] == 0xfc) | ||
922 | mdelay(1); | ||
923 | else if (phy_regarray2xtxr_table[i] == 0xfb) | ||
924 | udelay(50); | ||
925 | else if (phy_regarray2xtxr_table[i] == 0xfa) | ||
926 | udelay(5); | ||
927 | else if (phy_regarray2xtxr_table[i] == 0xf9) | ||
928 | udelay(1); | ||
929 | |||
930 | rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i], | ||
931 | phy_regarray2xtxr_table[i + 1], | ||
932 | phy_regarray2xtxr_table[i + 2]); | ||
933 | } | ||
934 | } | ||
935 | |||
936 | return true; | ||
937 | } | ||
938 | |||
939 | static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw, | ||
940 | u8 configtype) | ||
941 | { | ||
942 | int i; | ||
943 | u32 *phy_table_pg; | ||
944 | u16 phy_pg_len; | ||
945 | |||
946 | phy_pg_len = PHY_REG_ARRAY_PGLENGTH; | ||
947 | phy_table_pg = rtl8192sephy_reg_array_pg; | ||
948 | |||
949 | if (configtype == BASEBAND_CONFIG_PHY_REG) { | ||
950 | for (i = 0; i < phy_pg_len; i = i + 3) { | ||
951 | if (phy_table_pg[i] == 0xfe) | ||
952 | mdelay(50); | ||
953 | else if (phy_table_pg[i] == 0xfd) | ||
954 | mdelay(5); | ||
955 | else if (phy_table_pg[i] == 0xfc) | ||
956 | mdelay(1); | ||
957 | else if (phy_table_pg[i] == 0xfb) | ||
958 | udelay(50); | ||
959 | else if (phy_table_pg[i] == 0xfa) | ||
960 | udelay(5); | ||
961 | else if (phy_table_pg[i] == 0xf9) | ||
962 | udelay(1); | ||
963 | |||
964 | _rtl92s_store_pwrindex_diffrate_offset(hw, | ||
965 | phy_table_pg[i], | ||
966 | phy_table_pg[i + 1], | ||
967 | phy_table_pg[i + 2]); | ||
968 | rtl92s_phy_set_bb_reg(hw, phy_table_pg[i], | ||
969 | phy_table_pg[i + 1], | ||
970 | phy_table_pg[i + 2]); | ||
971 | } | ||
972 | } | ||
973 | |||
974 | return true; | ||
975 | } | ||
976 | |||
977 | static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) | ||
978 | { | ||
979 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
980 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
981 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
982 | bool rtstatus = true; | ||
983 | |||
984 | /* 1. Read PHY_REG.TXT BB INIT!! */ | ||
985 | /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */ | ||
986 | if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R || | ||
987 | rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) { | ||
988 | rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG); | ||
989 | |||
990 | if (rtlphy->rf_type != RF_2T2R && | ||
991 | rtlphy->rf_type != RF_2T2R_GREEN) | ||
992 | /* so we should reconfig BB reg with the right | ||
993 | * PHY parameters. */ | ||
994 | rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw, | ||
995 | BASEBAND_CONFIG_PHY_REG); | ||
996 | } else { | ||
997 | rtstatus = false; | ||
998 | } | ||
999 | |||
1000 | if (rtstatus != true) { | ||
1001 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
1002 | ("Write BB Reg Fail!!")); | ||
1003 | goto phy_BB8190_Config_ParaFile_Fail; | ||
1004 | } | ||
1005 | |||
1006 | /* 2. If EEPROM or EFUSE autoload OK, We must config by | ||
1007 | * PHY_REG_PG.txt */ | ||
1008 | if (rtlefuse->autoload_failflag == false) { | ||
1009 | rtlphy->pwrgroup_cnt = 0; | ||
1010 | |||
1011 | rtstatus = _rtl92s_phy_config_bb_with_pg(hw, | ||
1012 | BASEBAND_CONFIG_PHY_REG); | ||
1013 | } | ||
1014 | if (rtstatus != true) { | ||
1015 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
1016 | ("_rtl92s_phy_bb_config_parafile(): " | ||
1017 | "BB_PG Reg Fail!!")); | ||
1018 | goto phy_BB8190_Config_ParaFile_Fail; | ||
1019 | } | ||
1020 | |||
1021 | /* 3. BB AGC table Initialization */ | ||
1022 | rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB); | ||
1023 | |||
1024 | if (rtstatus != true) { | ||
1025 | printk(KERN_ERR "_rtl92s_phy_bb_config_parafile(): " | ||
1026 | "AGC Table Fail\n"); | ||
1027 | goto phy_BB8190_Config_ParaFile_Fail; | ||
1028 | } | ||
1029 | |||
1030 | /* Check if the CCK HighPower is turned ON. */ | ||
1031 | /* This is used to calculate PWDB. */ | ||
1032 | rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw, | ||
1033 | RFPGA0_XA_HSSIPARAMETER2, 0x200)); | ||
1034 | |||
1035 | phy_BB8190_Config_ParaFile_Fail: | ||
1036 | return rtstatus; | ||
1037 | } | ||
1038 | |||
1039 | u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) | ||
1040 | { | ||
1041 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1042 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1043 | int i; | ||
1044 | bool rtstatus = true; | ||
1045 | u32 *radio_a_table; | ||
1046 | u32 *radio_b_table; | ||
1047 | u16 radio_a_tblen, radio_b_tblen; | ||
1048 | |||
1049 | radio_a_tblen = RADIOA_1T_ARRAYLENGTH; | ||
1050 | radio_a_table = rtl8192seradioa_1t_array; | ||
1051 | |||
1052 | /* Using Green mode array table for RF_2T2R_GREEN */ | ||
1053 | if (rtlphy->rf_type == RF_2T2R_GREEN) { | ||
1054 | radio_b_table = rtl8192seradiob_gm_array; | ||
1055 | radio_b_tblen = RADIOB_GM_ARRAYLENGTH; | ||
1056 | } else { | ||
1057 | radio_b_table = rtl8192seradiob_array; | ||
1058 | radio_b_tblen = RADIOB_ARRAYLENGTH; | ||
1059 | } | ||
1060 | |||
1061 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath)); | ||
1062 | rtstatus = true; | ||
1063 | |||
1064 | switch (rfpath) { | ||
1065 | case RF90_PATH_A: | ||
1066 | for (i = 0; i < radio_a_tblen; i = i + 2) { | ||
1067 | if (radio_a_table[i] == 0xfe) | ||
1068 | /* Delay specific ms. Only RF configuration | ||
1069 | * requires delay. */ | ||
1070 | mdelay(50); | ||
1071 | else if (radio_a_table[i] == 0xfd) | ||
1072 | mdelay(5); | ||
1073 | else if (radio_a_table[i] == 0xfc) | ||
1074 | mdelay(1); | ||
1075 | else if (radio_a_table[i] == 0xfb) | ||
1076 | udelay(50); | ||
1077 | else if (radio_a_table[i] == 0xfa) | ||
1078 | udelay(5); | ||
1079 | else if (radio_a_table[i] == 0xf9) | ||
1080 | udelay(1); | ||
1081 | else | ||
1082 | rtl92s_phy_set_rf_reg(hw, rfpath, | ||
1083 | radio_a_table[i], | ||
1084 | MASK20BITS, | ||
1085 | radio_a_table[i + 1]); | ||
1086 | |||
1087 | /* Add delay for ECS T20 & LG malow platform */ | ||
1088 | udelay(1); | ||
1089 | } | ||
1090 | |||
1091 | /* PA Bias current for inferiority IC */ | ||
1092 | _rtl92s_phy_config_rfpa_bias_current(hw, rfpath); | ||
1093 | break; | ||
1094 | case RF90_PATH_B: | ||
1095 | for (i = 0; i < radio_b_tblen; i = i + 2) { | ||
1096 | if (radio_b_table[i] == 0xfe) | ||
1097 | /* Delay specific ms. Only RF configuration | ||
1098 | * requires delay.*/ | ||
1099 | mdelay(50); | ||
1100 | else if (radio_b_table[i] == 0xfd) | ||
1101 | mdelay(5); | ||
1102 | else if (radio_b_table[i] == 0xfc) | ||
1103 | mdelay(1); | ||
1104 | else if (radio_b_table[i] == 0xfb) | ||
1105 | udelay(50); | ||
1106 | else if (radio_b_table[i] == 0xfa) | ||
1107 | udelay(5); | ||
1108 | else if (radio_b_table[i] == 0xf9) | ||
1109 | udelay(1); | ||
1110 | else | ||
1111 | rtl92s_phy_set_rf_reg(hw, rfpath, | ||
1112 | radio_b_table[i], | ||
1113 | MASK20BITS, | ||
1114 | radio_b_table[i + 1]); | ||
1115 | |||
1116 | /* Add delay for ECS T20 & LG malow platform */ | ||
1117 | udelay(1); | ||
1118 | } | ||
1119 | break; | ||
1120 | case RF90_PATH_C: | ||
1121 | ; | ||
1122 | break; | ||
1123 | case RF90_PATH_D: | ||
1124 | ; | ||
1125 | break; | ||
1126 | default: | ||
1127 | break; | ||
1128 | } | ||
1129 | |||
1130 | return rtstatus; | ||
1131 | } | ||
1132 | |||
1133 | |||
1134 | bool rtl92s_phy_mac_config(struct ieee80211_hw *hw) | ||
1135 | { | ||
1136 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1137 | u32 i; | ||
1138 | u32 arraylength; | ||
1139 | u32 *ptraArray; | ||
1140 | |||
1141 | arraylength = MAC_2T_ARRAYLENGTH; | ||
1142 | ptraArray = rtl8192semac_2t_array; | ||
1143 | |||
1144 | for (i = 0; i < arraylength; i = i + 2) | ||
1145 | rtl_write_byte(rtlpriv, ptraArray[i], (u8)ptraArray[i + 1]); | ||
1146 | |||
1147 | return true; | ||
1148 | } | ||
1149 | |||
1150 | |||
1151 | bool rtl92s_phy_bb_config(struct ieee80211_hw *hw) | ||
1152 | { | ||
1153 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1154 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1155 | bool rtstatus = true; | ||
1156 | u8 pathmap, index, rf_num = 0; | ||
1157 | u8 path1, path2; | ||
1158 | |||
1159 | _rtl92s_phy_init_register_definition(hw); | ||
1160 | |||
1161 | /* Config BB and AGC */ | ||
1162 | rtstatus = _rtl92s_phy_bb_config_parafile(hw); | ||
1163 | |||
1164 | |||
1165 | /* Check BB/RF confiuration setting. */ | ||
1166 | /* We only need to configure RF which is turned on. */ | ||
1167 | path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf)); | ||
1168 | mdelay(10); | ||
1169 | path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf)); | ||
1170 | pathmap = path1 | path2; | ||
1171 | |||
1172 | rtlphy->rf_pathmap = pathmap; | ||
1173 | for (index = 0; index < 4; index++) { | ||
1174 | if ((pathmap >> index) & 0x1) | ||
1175 | rf_num++; | ||
1176 | } | ||
1177 | |||
1178 | if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) || | ||
1179 | (rtlphy->rf_type == RF_1T2R && rf_num != 2) || | ||
1180 | (rtlphy->rf_type == RF_2T2R && rf_num != 2) || | ||
1181 | (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) { | ||
1182 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
1183 | ("RF_Type(%x) does not match " | ||
1184 | "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num)); | ||
1185 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
1186 | ("path1 0x%x, path2 0x%x, pathmap " | ||
1187 | "0x%x\n", path1, path2, pathmap)); | ||
1188 | } | ||
1189 | |||
1190 | return rtstatus; | ||
1191 | } | ||
1192 | |||
1193 | bool rtl92s_phy_rf_config(struct ieee80211_hw *hw) | ||
1194 | { | ||
1195 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1196 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1197 | |||
1198 | /* Initialize general global value */ | ||
1199 | if (rtlphy->rf_type == RF_1T1R) | ||
1200 | rtlphy->num_total_rfpath = 1; | ||
1201 | else | ||
1202 | rtlphy->num_total_rfpath = 2; | ||
1203 | |||
1204 | /* Config BB and RF */ | ||
1205 | return rtl92s_phy_rf6052_config(hw); | ||
1206 | } | ||
1207 | |||
1208 | void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) | ||
1209 | { | ||
1210 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1211 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1212 | |||
1213 | /* read rx initial gain */ | ||
1214 | rtlphy->default_initialgain[0] = rtl_get_bbreg(hw, | ||
1215 | ROFDM0_XAAGCCORE1, MASKBYTE0); | ||
1216 | rtlphy->default_initialgain[1] = rtl_get_bbreg(hw, | ||
1217 | ROFDM0_XBAGCCORE1, MASKBYTE0); | ||
1218 | rtlphy->default_initialgain[2] = rtl_get_bbreg(hw, | ||
1219 | ROFDM0_XCAGCCORE1, MASKBYTE0); | ||
1220 | rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, | ||
1221 | ROFDM0_XDAGCCORE1, MASKBYTE0); | ||
1222 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain " | ||
1223 | "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", | ||
1224 | rtlphy->default_initialgain[0], | ||
1225 | rtlphy->default_initialgain[1], | ||
1226 | rtlphy->default_initialgain[2], | ||
1227 | rtlphy->default_initialgain[3])); | ||
1228 | |||
1229 | /* read framesync */ | ||
1230 | rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); | ||
1231 | rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, | ||
1232 | MASKDWORD); | ||
1233 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1234 | ("Default framesync (0x%x) = 0x%x\n", | ||
1235 | ROFDM0_RXDETECTOR3, rtlphy->framesync)); | ||
1236 | |||
1237 | } | ||
1238 | |||
1239 | static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel, | ||
1240 | u8 *cckpowerlevel, u8 *ofdmpowerLevel) | ||
1241 | { | ||
1242 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1243 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1244 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1245 | u8 index = (channel - 1); | ||
1246 | |||
1247 | /* 1. CCK */ | ||
1248 | /* RF-A */ | ||
1249 | cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index]; | ||
1250 | /* RF-B */ | ||
1251 | cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index]; | ||
1252 | |||
1253 | /* 2. OFDM for 1T or 2T */ | ||
1254 | if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) { | ||
1255 | /* Read HT 40 OFDM TX power */ | ||
1256 | ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index]; | ||
1257 | ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index]; | ||
1258 | } else if (rtlphy->rf_type == RF_2T2R) { | ||
1259 | /* Read HT 40 OFDM TX power */ | ||
1260 | ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index]; | ||
1261 | ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index]; | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw, | ||
1266 | u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel) | ||
1267 | { | ||
1268 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1269 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1270 | |||
1271 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; | ||
1272 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; | ||
1273 | } | ||
1274 | |||
1275 | void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel) | ||
1276 | { | ||
1277 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1278 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1279 | /* [0]:RF-A, [1]:RF-B */ | ||
1280 | u8 cckpowerlevel[2], ofdmpowerLevel[2]; | ||
1281 | |||
1282 | if (rtlefuse->txpwr_fromeprom == false) | ||
1283 | return; | ||
1284 | |||
1285 | /* Mainly we use RF-A Tx Power to write the Tx Power registers, | ||
1286 | * but the RF-B Tx Power must be calculated by the antenna diff. | ||
1287 | * So we have to rewrite Antenna gain offset register here. | ||
1288 | * Please refer to BB register 0x80c | ||
1289 | * 1. For CCK. | ||
1290 | * 2. For OFDM 1T or 2T */ | ||
1291 | _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0], | ||
1292 | &ofdmpowerLevel[0]); | ||
1293 | |||
1294 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
1295 | ("Channel-%d, cckPowerLevel (A / B) = " | ||
1296 | "0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", | ||
1297 | channel, cckpowerlevel[0], cckpowerlevel[1], | ||
1298 | ofdmpowerLevel[0], ofdmpowerLevel[1])); | ||
1299 | |||
1300 | _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0], | ||
1301 | &ofdmpowerLevel[0]); | ||
1302 | |||
1303 | rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]); | ||
1304 | rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerLevel[0], channel); | ||
1305 | |||
1306 | } | ||
1307 | |||
1308 | void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw) | ||
1309 | { | ||
1310 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1311 | u16 pollingcnt = 10000; | ||
1312 | u32 tmpvalue; | ||
1313 | |||
1314 | /* Make sure that CMD IO has be accepted by FW. */ | ||
1315 | do { | ||
1316 | udelay(10); | ||
1317 | |||
1318 | tmpvalue = rtl_read_dword(rtlpriv, WFM5); | ||
1319 | if (tmpvalue == 0) | ||
1320 | break; | ||
1321 | } while (--pollingcnt); | ||
1322 | |||
1323 | if (pollingcnt == 0) | ||
1324 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n")); | ||
1325 | } | ||
1326 | |||
1327 | |||
1328 | static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) | ||
1329 | { | ||
1330 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1331 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1332 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1333 | u32 input, current_aid = 0; | ||
1334 | |||
1335 | if (is_hal_stop(rtlhal)) | ||
1336 | return; | ||
1337 | |||
1338 | /* We re-map RA related CMD IO to combinational ones */ | ||
1339 | /* if FW version is v.52 or later. */ | ||
1340 | switch (rtlhal->current_fwcmd_io) { | ||
1341 | case FW_CMD_RA_REFRESH_N: | ||
1342 | rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB; | ||
1343 | break; | ||
1344 | case FW_CMD_RA_REFRESH_BG: | ||
1345 | rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB; | ||
1346 | break; | ||
1347 | default: | ||
1348 | break; | ||
1349 | } | ||
1350 | |||
1351 | switch (rtlhal->current_fwcmd_io) { | ||
1352 | case FW_CMD_RA_RESET: | ||
1353 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1354 | ("FW_CMD_RA_RESET\n")); | ||
1355 | rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); | ||
1356 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1357 | break; | ||
1358 | case FW_CMD_RA_ACTIVE: | ||
1359 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1360 | ("FW_CMD_RA_ACTIVE\n")); | ||
1361 | rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); | ||
1362 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1363 | break; | ||
1364 | case FW_CMD_RA_REFRESH_N: | ||
1365 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1366 | ("FW_CMD_RA_REFRESH_N\n")); | ||
1367 | input = FW_RA_REFRESH; | ||
1368 | rtl_write_dword(rtlpriv, WFM5, input); | ||
1369 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1370 | rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK); | ||
1371 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1372 | break; | ||
1373 | case FW_CMD_RA_REFRESH_BG: | ||
1374 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1375 | ("FW_CMD_RA_REFRESH_BG\n")); | ||
1376 | rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); | ||
1377 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1378 | rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK); | ||
1379 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1380 | break; | ||
1381 | case FW_CMD_RA_REFRESH_N_COMB: | ||
1382 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1383 | ("FW_CMD_RA_REFRESH_N_COMB\n")); | ||
1384 | input = FW_RA_IOT_N_COMB; | ||
1385 | rtl_write_dword(rtlpriv, WFM5, input); | ||
1386 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1387 | break; | ||
1388 | case FW_CMD_RA_REFRESH_BG_COMB: | ||
1389 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1390 | ("FW_CMD_RA_REFRESH_BG_COMB\n")); | ||
1391 | input = FW_RA_IOT_BG_COMB; | ||
1392 | rtl_write_dword(rtlpriv, WFM5, input); | ||
1393 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1394 | break; | ||
1395 | case FW_CMD_IQK_ENABLE: | ||
1396 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1397 | ("FW_CMD_IQK_ENABLE\n")); | ||
1398 | rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE); | ||
1399 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1400 | break; | ||
1401 | case FW_CMD_PAUSE_DM_BY_SCAN: | ||
1402 | /* Lower initial gain */ | ||
1403 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17); | ||
1404 | rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17); | ||
1405 | /* CCA threshold */ | ||
1406 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40); | ||
1407 | break; | ||
1408 | case FW_CMD_RESUME_DM_BY_SCAN: | ||
1409 | /* CCA threshold */ | ||
1410 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); | ||
1411 | rtl92s_phy_set_txpower(hw, rtlphy->current_channel); | ||
1412 | break; | ||
1413 | case FW_CMD_HIGH_PWR_DISABLE: | ||
1414 | if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) | ||
1415 | break; | ||
1416 | |||
1417 | /* Lower initial gain */ | ||
1418 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17); | ||
1419 | rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17); | ||
1420 | /* CCA threshold */ | ||
1421 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40); | ||
1422 | break; | ||
1423 | case FW_CMD_HIGH_PWR_ENABLE: | ||
1424 | if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || | ||
1425 | (rtlpriv->dm.dynamic_txpower_enable == true)) | ||
1426 | break; | ||
1427 | |||
1428 | /* CCA threshold */ | ||
1429 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); | ||
1430 | break; | ||
1431 | case FW_CMD_LPS_ENTER: | ||
1432 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1433 | ("FW_CMD_LPS_ENTER\n")); | ||
1434 | current_aid = rtlpriv->mac80211.assoc_id; | ||
1435 | rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER | | ||
1436 | ((current_aid | 0xc000) << 8))); | ||
1437 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1438 | /* FW set TXOP disable here, so disable EDCA | ||
1439 | * turbo mode until driver leave LPS */ | ||
1440 | break; | ||
1441 | case FW_CMD_LPS_LEAVE: | ||
1442 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1443 | ("FW_CMD_LPS_LEAVE\n")); | ||
1444 | rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE); | ||
1445 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1446 | break; | ||
1447 | case FW_CMD_ADD_A2_ENTRY: | ||
1448 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, | ||
1449 | ("FW_CMD_ADD_A2_ENTRY\n")); | ||
1450 | rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY); | ||
1451 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1452 | break; | ||
1453 | case FW_CMD_CTRL_DM_BY_DRIVER: | ||
1454 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
1455 | ("FW_CMD_CTRL_DM_BY_DRIVER\n")); | ||
1456 | rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER); | ||
1457 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1458 | break; | ||
1459 | |||
1460 | default: | ||
1461 | break; | ||
1462 | } | ||
1463 | |||
1464 | rtl92s_phy_chk_fwcmd_iodone(hw); | ||
1465 | |||
1466 | /* Clear FW CMD operation flag. */ | ||
1467 | rtlhal->set_fwcmd_inprogress = false; | ||
1468 | } | ||
1469 | |||
1470 | bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) | ||
1471 | { | ||
1472 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1473 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1474 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1475 | u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv); | ||
1476 | u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv); | ||
1477 | bool bPostProcessing = false; | ||
1478 | |||
1479 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
1480 | ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", | ||
1481 | fw_cmdio, rtlhal->set_fwcmd_inprogress)); | ||
1482 | |||
1483 | do { | ||
1484 | /* We re-map to combined FW CMD ones if firmware version */ | ||
1485 | /* is v.53 or later. */ | ||
1486 | switch (fw_cmdio) { | ||
1487 | case FW_CMD_RA_REFRESH_N: | ||
1488 | fw_cmdio = FW_CMD_RA_REFRESH_N_COMB; | ||
1489 | break; | ||
1490 | case FW_CMD_RA_REFRESH_BG: | ||
1491 | fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB; | ||
1492 | break; | ||
1493 | default: | ||
1494 | break; | ||
1495 | } | ||
1496 | |||
1497 | /* If firmware version is v.62 or later, | ||
1498 | * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */ | ||
1499 | if (hal_get_firmwareversion(rtlpriv) >= 0x3E) { | ||
1500 | if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER) | ||
1501 | fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW; | ||
1502 | } | ||
1503 | |||
1504 | |||
1505 | /* We shall revise all FW Cmd IO into Reg0x364 | ||
1506 | * DM map table in the future. */ | ||
1507 | switch (fw_cmdio) { | ||
1508 | case FW_CMD_RA_INIT: | ||
1509 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n")); | ||
1510 | fw_cmdmap |= FW_RA_INIT_CTL; | ||
1511 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1512 | /* Clear control flag to sync with FW. */ | ||
1513 | FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL); | ||
1514 | break; | ||
1515 | case FW_CMD_DIG_DISABLE: | ||
1516 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
1517 | ("Set DIG disable!!\n")); | ||
1518 | fw_cmdmap &= ~FW_DIG_ENABLE_CTL; | ||
1519 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1520 | break; | ||
1521 | case FW_CMD_DIG_ENABLE: | ||
1522 | case FW_CMD_DIG_RESUME: | ||
1523 | if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) { | ||
1524 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
1525 | ("Set DIG enable or resume!!\n")); | ||
1526 | fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL); | ||
1527 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1528 | } | ||
1529 | break; | ||
1530 | case FW_CMD_DIG_HALT: | ||
1531 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
1532 | ("Set DIG halt!!\n")); | ||
1533 | fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL); | ||
1534 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1535 | break; | ||
1536 | case FW_CMD_TXPWR_TRACK_THERMAL: { | ||
1537 | u8 thermalval = 0; | ||
1538 | fw_cmdmap |= FW_PWR_TRK_CTL; | ||
1539 | |||
1540 | /* Clear FW parameter in terms of thermal parts. */ | ||
1541 | fw_param &= FW_PWR_TRK_PARAM_CLR; | ||
1542 | |||
1543 | thermalval = rtlpriv->dm.thermalvalue; | ||
1544 | fw_param |= ((thermalval << 24) | | ||
1545 | (rtlefuse->thermalmeter[0] << 16)); | ||
1546 | |||
1547 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
1548 | ("Set TxPwr tracking!! " | ||
1549 | "FwCmdMap(%#x), FwParam(%#x)\n", | ||
1550 | fw_cmdmap, fw_param)); | ||
1551 | |||
1552 | FW_CMD_PARA_SET(rtlpriv, fw_param); | ||
1553 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1554 | |||
1555 | /* Clear control flag to sync with FW. */ | ||
1556 | FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL); | ||
1557 | } | ||
1558 | break; | ||
1559 | /* The following FW CMDs are only compatible to | ||
1560 | * v.53 or later. */ | ||
1561 | case FW_CMD_RA_REFRESH_N_COMB: | ||
1562 | fw_cmdmap |= FW_RA_N_CTL; | ||
1563 | |||
1564 | /* Clear RA BG mode control. */ | ||
1565 | fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL); | ||
1566 | |||
1567 | /* Clear FW parameter in terms of RA parts. */ | ||
1568 | fw_param &= FW_RA_PARAM_CLR; | ||
1569 | |||
1570 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
1571 | ("[FW CMD] [New Version] " | ||
1572 | "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), " | ||
1573 | "FwParam(%#x)\n", fw_cmdmap, fw_param)); | ||
1574 | |||
1575 | FW_CMD_PARA_SET(rtlpriv, fw_param); | ||
1576 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1577 | |||
1578 | /* Clear control flag to sync with FW. */ | ||
1579 | FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL); | ||
1580 | break; | ||
1581 | case FW_CMD_RA_REFRESH_BG_COMB: | ||
1582 | fw_cmdmap |= FW_RA_BG_CTL; | ||
1583 | |||
1584 | /* Clear RA n-mode control. */ | ||
1585 | fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL); | ||
1586 | /* Clear FW parameter in terms of RA parts. */ | ||
1587 | fw_param &= FW_RA_PARAM_CLR; | ||
1588 | |||
1589 | FW_CMD_PARA_SET(rtlpriv, fw_param); | ||
1590 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1591 | |||
1592 | /* Clear control flag to sync with FW. */ | ||
1593 | FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL); | ||
1594 | break; | ||
1595 | case FW_CMD_IQK_ENABLE: | ||
1596 | fw_cmdmap |= FW_IQK_CTL; | ||
1597 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1598 | /* Clear control flag to sync with FW. */ | ||
1599 | FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL); | ||
1600 | break; | ||
1601 | /* The following FW CMD is compatible to v.62 or later. */ | ||
1602 | case FW_CMD_CTRL_DM_BY_DRIVER_NEW: | ||
1603 | fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL; | ||
1604 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1605 | break; | ||
1606 | /* The followed FW Cmds needs post-processing later. */ | ||
1607 | case FW_CMD_RESUME_DM_BY_SCAN: | ||
1608 | fw_cmdmap |= (FW_DIG_ENABLE_CTL | | ||
1609 | FW_HIGH_PWR_ENABLE_CTL | | ||
1610 | FW_SS_CTL); | ||
1611 | |||
1612 | if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE || | ||
1613 | !digtable.dig_enable_flag) | ||
1614 | fw_cmdmap &= ~FW_DIG_ENABLE_CTL; | ||
1615 | |||
1616 | if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || | ||
1617 | (rtlpriv->dm.dynamic_txpower_enable == true)) | ||
1618 | fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; | ||
1619 | |||
1620 | if ((digtable.dig_ext_port_stage == | ||
1621 | DIG_EXT_PORT_STAGE_0) || | ||
1622 | (digtable.dig_ext_port_stage == | ||
1623 | DIG_EXT_PORT_STAGE_1)) | ||
1624 | fw_cmdmap &= ~FW_DIG_ENABLE_CTL; | ||
1625 | |||
1626 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1627 | bPostProcessing = true; | ||
1628 | break; | ||
1629 | case FW_CMD_PAUSE_DM_BY_SCAN: | ||
1630 | fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | | ||
1631 | FW_HIGH_PWR_ENABLE_CTL | | ||
1632 | FW_SS_CTL); | ||
1633 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1634 | bPostProcessing = true; | ||
1635 | break; | ||
1636 | case FW_CMD_HIGH_PWR_DISABLE: | ||
1637 | fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; | ||
1638 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1639 | bPostProcessing = true; | ||
1640 | break; | ||
1641 | case FW_CMD_HIGH_PWR_ENABLE: | ||
1642 | if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) && | ||
1643 | (rtlpriv->dm.dynamic_txpower_enable != true)) { | ||
1644 | fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL | | ||
1645 | FW_SS_CTL); | ||
1646 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1647 | bPostProcessing = true; | ||
1648 | } | ||
1649 | break; | ||
1650 | case FW_CMD_DIG_MODE_FA: | ||
1651 | fw_cmdmap |= FW_FA_CTL; | ||
1652 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1653 | break; | ||
1654 | case FW_CMD_DIG_MODE_SS: | ||
1655 | fw_cmdmap &= ~FW_FA_CTL; | ||
1656 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1657 | break; | ||
1658 | case FW_CMD_PAPE_CONTROL: | ||
1659 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
1660 | ("[FW CMD] Set PAPE Control\n")); | ||
1661 | fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW; | ||
1662 | |||
1663 | FW_CMD_IO_SET(rtlpriv, fw_cmdmap); | ||
1664 | break; | ||
1665 | default: | ||
1666 | /* Pass to original FW CMD processing callback | ||
1667 | * routine. */ | ||
1668 | bPostProcessing = true; | ||
1669 | break; | ||
1670 | } | ||
1671 | } while (false); | ||
1672 | |||
1673 | /* We shall post processing these FW CMD if | ||
1674 | * variable bPostProcessing is set. */ | ||
1675 | if (bPostProcessing && !rtlhal->set_fwcmd_inprogress) { | ||
1676 | rtlhal->set_fwcmd_inprogress = true; | ||
1677 | /* Update current FW Cmd for callback use. */ | ||
1678 | rtlhal->current_fwcmd_io = fw_cmdio; | ||
1679 | } else { | ||
1680 | return false; | ||
1681 | } | ||
1682 | |||
1683 | _rtl92s_phy_set_fwcmd_io(hw); | ||
1684 | return true; | ||
1685 | } | ||
1686 | |||
1687 | static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw) | ||
1688 | { | ||
1689 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1690 | u32 delay = 100; | ||
1691 | u8 regu1; | ||
1692 | |||
1693 | regu1 = rtl_read_byte(rtlpriv, 0x554); | ||
1694 | while ((regu1 & BIT(5)) && (delay > 0)) { | ||
1695 | regu1 = rtl_read_byte(rtlpriv, 0x554); | ||
1696 | delay--; | ||
1697 | /* We delay only 50us to prevent | ||
1698 | * being scheduled out. */ | ||
1699 | udelay(50); | ||
1700 | } | ||
1701 | } | ||
1702 | |||
1703 | void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw) | ||
1704 | { | ||
1705 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1706 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1707 | |||
1708 | /* The way to be capable to switch clock request | ||
1709 | * when the PG setting does not support clock request. | ||
1710 | * This is the backdoor solution to switch clock | ||
1711 | * request before ASPM or D3. */ | ||
1712 | rtl_write_dword(rtlpriv, 0x540, 0x73c11); | ||
1713 | rtl_write_dword(rtlpriv, 0x548, 0x2407c); | ||
1714 | |||
1715 | /* Switch EPHY parameter!!!! */ | ||
1716 | rtl_write_word(rtlpriv, 0x550, 0x1000); | ||
1717 | rtl_write_byte(rtlpriv, 0x554, 0x20); | ||
1718 | _rtl92s_phy_check_ephy_switchready(hw); | ||
1719 | |||
1720 | rtl_write_word(rtlpriv, 0x550, 0xa0eb); | ||
1721 | rtl_write_byte(rtlpriv, 0x554, 0x3e); | ||
1722 | _rtl92s_phy_check_ephy_switchready(hw); | ||
1723 | |||
1724 | rtl_write_word(rtlpriv, 0x550, 0xff80); | ||
1725 | rtl_write_byte(rtlpriv, 0x554, 0x39); | ||
1726 | _rtl92s_phy_check_ephy_switchready(hw); | ||
1727 | |||
1728 | /* Delay L1 enter time */ | ||
1729 | if (ppsc->support_aspm && !ppsc->support_backdoor) | ||
1730 | rtl_write_byte(rtlpriv, 0x560, 0x40); | ||
1731 | else | ||
1732 | rtl_write_byte(rtlpriv, 0x560, 0x00); | ||
1733 | |||
1734 | } | ||
1735 | |||
1736 | void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 BeaconInterval) | ||
1737 | { | ||
1738 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1739 | rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | (BeaconInterval << 8)); | ||
1740 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h new file mode 100644 index 000000000000..37e504af6446 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h | |||
@@ -0,0 +1,101 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __RTL92S_PHY_H__ | ||
30 | #define __RTL92S_PHY_H__ | ||
31 | |||
32 | #define MAX_TXPWR_IDX_NMODE_92S 63 | ||
33 | #define MAX_DOZE_WAITING_TIMES_9x 64 | ||
34 | |||
35 | /* Channel switch:The size of | ||
36 | * command tables for switch channel */ | ||
37 | #define MAX_PRECMD_CNT 16 | ||
38 | #define MAX_RFDEPENDCMD_CNT 16 | ||
39 | #define MAX_POSTCMD_CNT 16 | ||
40 | |||
41 | #define RF90_PATH_MAX 4 | ||
42 | |||
43 | enum version_8192s { | ||
44 | VERSION_8192S_ACUT, | ||
45 | VERSION_8192S_BCUT, | ||
46 | VERSION_8192S_CCUT | ||
47 | }; | ||
48 | |||
49 | enum swchnlcmd_id { | ||
50 | CMDID_END, | ||
51 | CMDID_SET_TXPOWEROWER_LEVEL, | ||
52 | CMDID_BBREGWRITE10, | ||
53 | CMDID_WRITEPORT_ULONG, | ||
54 | CMDID_WRITEPORT_USHORT, | ||
55 | CMDID_WRITEPORT_UCHAR, | ||
56 | CMDID_RF_WRITEREG, | ||
57 | }; | ||
58 | |||
59 | struct swchnlcmd { | ||
60 | enum swchnlcmd_id cmdid; | ||
61 | u32 para1; | ||
62 | u32 para2; | ||
63 | u32 msdelay; | ||
64 | }; | ||
65 | |||
66 | enum baseband_config_type { | ||
67 | /* Radio Path A */ | ||
68 | BASEBAND_CONFIG_PHY_REG = 0, | ||
69 | /* Radio Path B */ | ||
70 | BASEBAND_CONFIG_AGC_TAB = 1, | ||
71 | }; | ||
72 | |||
73 | #define hal_get_firmwareversion(rtlpriv) \ | ||
74 | (((struct rt_firmware *)(rtlpriv->rtlhal.pfirmware))->firmwareversion) | ||
75 | |||
76 | u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); | ||
77 | void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, | ||
78 | u32 data); | ||
79 | void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); | ||
80 | u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, | ||
81 | u32 regaddr, u32 bitmask); | ||
82 | void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, | ||
83 | u32 regaddr, u32 bitmask, u32 data); | ||
84 | void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
85 | enum nl80211_channel_type ch_type); | ||
86 | u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw); | ||
87 | bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
88 | enum rf_pwrstate rfpower_state); | ||
89 | bool rtl92s_phy_mac_config(struct ieee80211_hw *hw); | ||
90 | void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw); | ||
91 | bool rtl92s_phy_bb_config(struct ieee80211_hw *hw); | ||
92 | bool rtl92s_phy_rf_config(struct ieee80211_hw *hw); | ||
93 | void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); | ||
94 | void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel); | ||
95 | bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fwcmd_io); | ||
96 | void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw); | ||
97 | void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval); | ||
98 | u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) ; | ||
99 | |||
100 | #endif | ||
101 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h new file mode 100644 index 000000000000..0116eaddbfac --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h | |||
@@ -0,0 +1,1188 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __REALTEK_92S_REG_H__ | ||
30 | #define __REALTEK_92S_REG_H__ | ||
31 | |||
32 | /* 1. System Configuration Registers */ | ||
33 | #define REG_SYS_ISO_CTRL 0x0000 | ||
34 | #define REG_SYS_FUNC_EN 0x0002 | ||
35 | #define PMC_FSM 0x0004 | ||
36 | #define SYS_CLKR 0x0008 | ||
37 | #define EPROM_CMD 0x000A | ||
38 | #define EE_VPD 0x000C | ||
39 | #define AFE_MISC 0x0010 | ||
40 | #define SPS0_CTRL 0x0011 | ||
41 | #define SPS1_CTRL 0x0018 | ||
42 | #define RF_CTRL 0x001F | ||
43 | #define LDOA15_CTRL 0x0020 | ||
44 | #define LDOV12D_CTRL 0x0021 | ||
45 | #define LDOHCI12_CTRL 0x0022 | ||
46 | #define LDO_USB_SDIO 0x0023 | ||
47 | #define LPLDO_CTRL 0x0024 | ||
48 | #define AFE_XTAL_CTRL 0x0026 | ||
49 | #define AFE_PLL_CTRL 0x0028 | ||
50 | #define REG_EFUSE_CTRL 0x0030 | ||
51 | #define REG_EFUSE_TEST 0x0034 | ||
52 | #define PWR_DATA 0x0038 | ||
53 | #define DBG_PORT 0x003A | ||
54 | #define DPS_TIMER 0x003C | ||
55 | #define RCLK_MON 0x003E | ||
56 | |||
57 | /* 2. Command Control Registers */ | ||
58 | #define CMDR 0x0040 | ||
59 | #define TXPAUSE 0x0042 | ||
60 | #define LBKMD_SEL 0x0043 | ||
61 | #define TCR 0x0044 | ||
62 | #define RCR 0x0048 | ||
63 | #define MSR 0x004C | ||
64 | #define SYSF_CFG 0x004D | ||
65 | #define RX_PKY_LIMIT 0x004E | ||
66 | #define MBIDCTRL 0x004F | ||
67 | |||
68 | /* 3. MACID Setting Registers */ | ||
69 | #define MACIDR 0x0050 | ||
70 | #define MACIDR0 0x0050 | ||
71 | #define MACIDR4 0x0054 | ||
72 | #define BSSIDR 0x0058 | ||
73 | #define HWVID 0x005E | ||
74 | #define MAR 0x0060 | ||
75 | #define MBIDCAMCONTENT 0x0068 | ||
76 | #define MBIDCAMCFG 0x0070 | ||
77 | #define BUILDTIME 0x0074 | ||
78 | #define BUILDUSER 0x0078 | ||
79 | |||
80 | #define IDR0 MACIDR0 | ||
81 | #define IDR4 MACIDR4 | ||
82 | |||
83 | /* 4. Timing Control Registers */ | ||
84 | #define TSFR 0x0080 | ||
85 | #define SLOT_TIME 0x0089 | ||
86 | #define USTIME 0x008A | ||
87 | #define SIFS_CCK 0x008C | ||
88 | #define SIFS_OFDM 0x008E | ||
89 | #define PIFS_TIME 0x0090 | ||
90 | #define ACK_TIMEOUT 0x0091 | ||
91 | #define EIFSTR 0x0092 | ||
92 | #define BCN_INTERVAL 0x0094 | ||
93 | #define ATIMWND 0x0096 | ||
94 | #define BCN_DRV_EARLY_INT 0x0098 | ||
95 | #define BCN_DMATIME 0x009A | ||
96 | #define BCN_ERR_THRESH 0x009C | ||
97 | #define MLT 0x009D | ||
98 | #define RSVD_MAC_TUNE_US 0x009E | ||
99 | |||
100 | /* 5. FIFO Control Registers */ | ||
101 | #define RQPN 0x00A0 | ||
102 | #define RQPN1 0x00A0 | ||
103 | #define RQPN2 0x00A1 | ||
104 | #define RQPN3 0x00A2 | ||
105 | #define RQPN4 0x00A3 | ||
106 | #define RQPN5 0x00A4 | ||
107 | #define RQPN6 0x00A5 | ||
108 | #define RQPN7 0x00A6 | ||
109 | #define RQPN8 0x00A7 | ||
110 | #define RQPN9 0x00A8 | ||
111 | #define RQPN10 0x00A9 | ||
112 | #define LD_RQPN 0x00AB | ||
113 | #define RXFF_BNDY 0x00AC | ||
114 | #define RXRPT_BNDY 0x00B0 | ||
115 | #define TXPKTBUF_PGBNDY 0x00B4 | ||
116 | #define PBP 0x00B5 | ||
117 | #define RXDRVINFO_SZ 0x00B6 | ||
118 | #define TXFF_STATUS 0x00B7 | ||
119 | #define RXFF_STATUS 0x00B8 | ||
120 | #define TXFF_EMPTY_TH 0x00B9 | ||
121 | #define SDIO_RX_BLKSZ 0x00BC | ||
122 | #define RXDMA 0x00BD | ||
123 | #define RXPKT_NUM 0x00BE | ||
124 | #define C2HCMD_UDT_SIZE 0x00C0 | ||
125 | #define C2HCMD_UDT_ADDR 0x00C2 | ||
126 | #define FIFOPAGE1 0x00C4 | ||
127 | #define FIFOPAGE2 0x00C8 | ||
128 | #define FIFOPAGE3 0x00CC | ||
129 | #define FIFOPAGE4 0x00D0 | ||
130 | #define FIFOPAGE5 0x00D4 | ||
131 | #define FW_RSVD_PG_CRTL 0x00D8 | ||
132 | #define RXDMA_AGG_PG_TH 0x00D9 | ||
133 | #define TXDESC_MSK 0x00DC | ||
134 | #define TXRPTFF_RDPTR 0x00E0 | ||
135 | #define TXRPTFF_WTPTR 0x00E4 | ||
136 | #define C2HFF_RDPTR 0x00E8 | ||
137 | #define C2HFF_WTPTR 0x00EC | ||
138 | #define RXFF0_RDPTR 0x00F0 | ||
139 | #define RXFF0_WTPTR 0x00F4 | ||
140 | #define RXFF1_RDPTR 0x00F8 | ||
141 | #define RXFF1_WTPTR 0x00FC | ||
142 | #define RXRPT0_RDPTR 0x0100 | ||
143 | #define RXRPT0_WTPTR 0x0104 | ||
144 | #define RXRPT1_RDPTR 0x0108 | ||
145 | #define RXRPT1_WTPTR 0x010C | ||
146 | #define RX0_UDT_SIZE 0x0110 | ||
147 | #define RX1PKTNUM 0x0114 | ||
148 | #define RXFILTERMAP 0x0116 | ||
149 | #define RXFILTERMAP_GP1 0x0118 | ||
150 | #define RXFILTERMAP_GP2 0x011A | ||
151 | #define RXFILTERMAP_GP3 0x011C | ||
152 | #define BCNQ_CTRL 0x0120 | ||
153 | #define MGTQ_CTRL 0x0124 | ||
154 | #define HIQ_CTRL 0x0128 | ||
155 | #define VOTID7_CTRL 0x012c | ||
156 | #define VOTID6_CTRL 0x0130 | ||
157 | #define VITID5_CTRL 0x0134 | ||
158 | #define VITID4_CTRL 0x0138 | ||
159 | #define BETID3_CTRL 0x013c | ||
160 | #define BETID0_CTRL 0x0140 | ||
161 | #define BKTID2_CTRL 0x0144 | ||
162 | #define BKTID1_CTRL 0x0148 | ||
163 | #define CMDQ_CTRL 0x014c | ||
164 | #define TXPKT_NUM_CTRL 0x0150 | ||
165 | #define TXQ_PGADD 0x0152 | ||
166 | #define TXFF_PG_NUM 0x0154 | ||
167 | #define TRXDMA_STATUS 0x0156 | ||
168 | |||
169 | /* 6. Adaptive Control Registers */ | ||
170 | #define INIMCS_SEL 0x0160 | ||
171 | #define TX_RATE_REG INIMCS_SEL | ||
172 | #define INIRTSMCS_SEL 0x0180 | ||
173 | #define RRSR 0x0181 | ||
174 | #define ARFR0 0x0184 | ||
175 | #define ARFR1 0x0188 | ||
176 | #define ARFR2 0x018C | ||
177 | #define ARFR3 0x0190 | ||
178 | #define ARFR4 0x0194 | ||
179 | #define ARFR5 0x0198 | ||
180 | #define ARFR6 0x019C | ||
181 | #define ARFR7 0x01A0 | ||
182 | #define AGGLEN_LMT_H 0x01A7 | ||
183 | #define AGGLEN_LMT_L 0x01A8 | ||
184 | #define DARFRC 0x01B0 | ||
185 | #define RARFRC 0x01B8 | ||
186 | #define MCS_TXAGC 0x01C0 | ||
187 | #define CCK_TXAGC 0x01C8 | ||
188 | |||
189 | /* 7. EDCA Setting Registers */ | ||
190 | #define EDCAPARA_VO 0x01D0 | ||
191 | #define EDCAPARA_VI 0x01D4 | ||
192 | #define EDCAPARA_BE 0x01D8 | ||
193 | #define EDCAPARA_BK 0x01DC | ||
194 | #define BCNTCFG 0x01E0 | ||
195 | #define CWRR 0x01E2 | ||
196 | #define ACMAVG 0x01E4 | ||
197 | #define AcmHwCtrl 0x01E7 | ||
198 | #define VO_ADMTM 0x01E8 | ||
199 | #define VI_ADMTM 0x01EC | ||
200 | #define BE_ADMTM 0x01F0 | ||
201 | #define RETRY_LIMIT 0x01F4 | ||
202 | #define SG_RATE 0x01F6 | ||
203 | |||
204 | /* 8. WMAC, BA and CCX related Register. */ | ||
205 | #define NAV_CTRL 0x0200 | ||
206 | #define BW_OPMODE 0x0203 | ||
207 | #define BACAMCMD 0x0204 | ||
208 | #define BACAMCONTENT 0x0208 | ||
209 | |||
210 | /* the 0x2xx register WMAC definition */ | ||
211 | #define LBDLY 0x0210 | ||
212 | #define FWDLY 0x0211 | ||
213 | #define HWPC_RX_CTRL 0x0218 | ||
214 | #define MQIR 0x0220 | ||
215 | #define MAIR 0x0222 | ||
216 | #define MSIR 0x0224 | ||
217 | #define CLM_RESULT 0x0227 | ||
218 | #define NHM_RPI_CNT 0x0228 | ||
219 | #define RXERR_RPT 0x0230 | ||
220 | #define NAV_PROT_LEN 0x0234 | ||
221 | #define CFEND_TH 0x0236 | ||
222 | #define AMPDU_MIN_SPACE 0x0237 | ||
223 | #define TXOP_STALL_CTRL 0x0238 | ||
224 | |||
225 | /* 9. Security Control Registers */ | ||
226 | #define REG_RWCAM 0x0240 | ||
227 | #define REG_WCAMI 0x0244 | ||
228 | #define REG_RCAMO 0x0248 | ||
229 | #define REG_CAMDBG 0x024C | ||
230 | #define REG_SECR 0x0250 | ||
231 | |||
232 | /* 10. Power Save Control Registers */ | ||
233 | #define WOW_CTRL 0x0260 | ||
234 | #define PSSTATUS 0x0261 | ||
235 | #define PSSWITCH 0x0262 | ||
236 | #define MIMOPS_WAIT_PERIOD 0x0263 | ||
237 | #define LPNAV_CTRL 0x0264 | ||
238 | #define WFM0 0x0270 | ||
239 | #define WFM1 0x0280 | ||
240 | #define WFM2 0x0290 | ||
241 | #define WFM3 0x02A0 | ||
242 | #define WFM4 0x02B0 | ||
243 | #define WFM5 0x02C0 | ||
244 | #define WFCRC 0x02D0 | ||
245 | #define FW_RPT_REG 0x02c4 | ||
246 | |||
247 | /* 11. General Purpose Registers */ | ||
248 | #define PSTIME 0x02E0 | ||
249 | #define TIMER0 0x02E4 | ||
250 | #define TIMER1 0x02E8 | ||
251 | #define GPIO_CTRL 0x02EC | ||
252 | #define GPIO_IN 0x02EC | ||
253 | #define GPIO_OUT 0x02ED | ||
254 | #define GPIO_IO_SEL 0x02EE | ||
255 | #define GPIO_MOD 0x02EF | ||
256 | #define GPIO_INTCTRL 0x02F0 | ||
257 | #define MAC_PINMUX_CFG 0x02F1 | ||
258 | #define LEDCFG 0x02F2 | ||
259 | #define PHY_REG 0x02F3 | ||
260 | #define PHY_REG_DATA 0x02F4 | ||
261 | #define REG_EFUSE_CLK 0x02F8 | ||
262 | |||
263 | /* 12. Host Interrupt Status Registers */ | ||
264 | #define INTA_MASK 0x0300 | ||
265 | #define ISR 0x0308 | ||
266 | |||
267 | /* 13. Test Mode and Debug Control Registers */ | ||
268 | #define DBG_PORT_SWITCH 0x003A | ||
269 | #define BIST 0x0310 | ||
270 | #define DBS 0x0314 | ||
271 | #define CPUINST 0x0318 | ||
272 | #define CPUCAUSE 0x031C | ||
273 | #define LBUS_ERR_ADDR 0x0320 | ||
274 | #define LBUS_ERR_CMD 0x0324 | ||
275 | #define LBUS_ERR_DATA_L 0x0328 | ||
276 | #define LBUS_ERR_DATA_H 0x032C | ||
277 | #define LX_EXCEPTION_ADDR 0x0330 | ||
278 | #define WDG_CTRL 0x0334 | ||
279 | #define INTMTU 0x0338 | ||
280 | #define INTM 0x033A | ||
281 | #define FDLOCKTURN0 0x033C | ||
282 | #define FDLOCKTURN1 0x033D | ||
283 | #define TRXPKTBUF_DBG_DATA 0x0340 | ||
284 | #define TRXPKTBUF_DBG_CTRL 0x0348 | ||
285 | #define DPLL 0x034A | ||
286 | #define CBUS_ERR_ADDR 0x0350 | ||
287 | #define CBUS_ERR_CMD 0x0354 | ||
288 | #define CBUS_ERR_DATA_L 0x0358 | ||
289 | #define CBUS_ERR_DATA_H 0x035C | ||
290 | #define USB_SIE_INTF_ADDR 0x0360 | ||
291 | #define USB_SIE_INTF_WD 0x0361 | ||
292 | #define USB_SIE_INTF_RD 0x0362 | ||
293 | #define USB_SIE_INTF_CTRL 0x0363 | ||
294 | #define LBUS_MON_ADDR 0x0364 | ||
295 | #define LBUS_ADDR_MASK 0x0368 | ||
296 | |||
297 | /* Boundary is 0x37F */ | ||
298 | |||
299 | /* 14. PCIE config register */ | ||
300 | #define TP_POLL 0x0500 | ||
301 | #define PM_CTRL 0x0502 | ||
302 | #define PCIF 0x0503 | ||
303 | |||
304 | #define THPDA 0x0514 | ||
305 | #define TMDA 0x0518 | ||
306 | #define TCDA 0x051C | ||
307 | #define HDA 0x0520 | ||
308 | #define TVODA 0x0524 | ||
309 | #define TVIDA 0x0528 | ||
310 | #define TBEDA 0x052C | ||
311 | #define TBKDA 0x0530 | ||
312 | #define TBDA 0x0534 | ||
313 | #define RCDA 0x0538 | ||
314 | #define RDQDA 0x053C | ||
315 | #define DBI_WDATA 0x0540 | ||
316 | #define DBI_RDATA 0x0544 | ||
317 | #define DBI_CTRL 0x0548 | ||
318 | #define MDIO_DATA 0x0550 | ||
319 | #define MDIO_CTRL 0x0554 | ||
320 | #define PCI_RPWM 0x0561 | ||
321 | #define PCI_CPWM 0x0563 | ||
322 | |||
323 | /* Config register (Offset 0x800-) */ | ||
324 | #define PHY_CCA 0x803 | ||
325 | |||
326 | /* Min Spacing related settings. */ | ||
327 | #define MAX_MSS_DENSITY_2T 0x13 | ||
328 | #define MAX_MSS_DENSITY_1T 0x0A | ||
329 | |||
330 | /* Rx DMA Control related settings */ | ||
331 | #define RXDMA_AGG_EN BIT(7) | ||
332 | |||
333 | #define RPWM PCI_RPWM | ||
334 | |||
335 | /* Regsiter Bit and Content definition */ | ||
336 | |||
337 | #define ISO_MD2PP BIT(0) | ||
338 | #define ISO_PA2PCIE BIT(3) | ||
339 | #define ISO_PLL2MD BIT(4) | ||
340 | #define ISO_PWC_DV2RP BIT(11) | ||
341 | #define ISO_PWC_RV2RP BIT(12) | ||
342 | |||
343 | |||
344 | #define FEN_MREGEN BIT(15) | ||
345 | #define FEN_DCORE BIT(11) | ||
346 | #define FEN_CPUEN BIT(10) | ||
347 | |||
348 | #define PAD_HWPD_IDN BIT(22) | ||
349 | |||
350 | #define SYS_CLKSEL_80M BIT(0) | ||
351 | #define SYS_PS_CLKSEL BIT(1) | ||
352 | #define SYS_CPU_CLKSEL BIT(2) | ||
353 | #define SYS_MAC_CLK_EN BIT(11) | ||
354 | #define SYS_SWHW_SEL BIT(14) | ||
355 | #define SYS_FWHW_SEL BIT(15) | ||
356 | |||
357 | #define CmdEEPROM_En BIT(5) | ||
358 | #define CmdEERPOMSEL BIT(4) | ||
359 | #define Cmd9346CR_9356SEL BIT(4) | ||
360 | |||
361 | #define AFE_MBEN BIT(1) | ||
362 | #define AFE_BGEN BIT(0) | ||
363 | |||
364 | #define SPS1_SWEN BIT(1) | ||
365 | #define SPS1_LDEN BIT(0) | ||
366 | |||
367 | #define RF_EN BIT(0) | ||
368 | #define RF_RSTB BIT(1) | ||
369 | #define RF_SDMRSTB BIT(2) | ||
370 | |||
371 | #define LDA15_EN BIT(0) | ||
372 | |||
373 | #define LDV12_EN BIT(0) | ||
374 | #define LDV12_SDBY BIT(1) | ||
375 | |||
376 | #define XTAL_GATE_AFE BIT(10) | ||
377 | |||
378 | #define APLL_EN BIT(0) | ||
379 | |||
380 | #define AFR_CardBEn BIT(0) | ||
381 | #define AFR_CLKRUN_SEL BIT(1) | ||
382 | #define AFR_FuncRegEn BIT(2) | ||
383 | |||
384 | #define APSDOFF_STATUS BIT(15) | ||
385 | #define APSDOFF BIT(14) | ||
386 | #define BBRSTN BIT(13) | ||
387 | #define BB_GLB_RSTN BIT(12) | ||
388 | #define SCHEDULE_EN BIT(10) | ||
389 | #define MACRXEN BIT(9) | ||
390 | #define MACTXEN BIT(8) | ||
391 | #define DDMA_EN BIT(7) | ||
392 | #define FW2HW_EN BIT(6) | ||
393 | #define RXDMA_EN BIT(5) | ||
394 | #define TXDMA_EN BIT(4) | ||
395 | #define HCI_RXDMA_EN BIT(3) | ||
396 | #define HCI_TXDMA_EN BIT(2) | ||
397 | |||
398 | #define StopHCCA BIT(6) | ||
399 | #define StopHigh BIT(5) | ||
400 | #define StopMgt BIT(4) | ||
401 | #define StopVO BIT(3) | ||
402 | #define StopVI BIT(2) | ||
403 | #define StopBE BIT(1) | ||
404 | #define StopBK BIT(0) | ||
405 | |||
406 | #define LBK_NORMAL 0x00 | ||
407 | #define LBK_MAC_LB (BIT(0) | BIT(1) | BIT(3)) | ||
408 | #define LBK_MAC_DLB (BIT(0) | BIT(1)) | ||
409 | #define LBK_DMA_LB (BIT(0) | BIT(1) | BIT(2)) | ||
410 | |||
411 | #define TCP_OFDL_EN BIT(25) | ||
412 | #define HWPC_TX_EN BIT(24) | ||
413 | #define TXDMAPRE2FULL BIT(23) | ||
414 | #define DISCW BIT(20) | ||
415 | #define TCRICV BIT(19) | ||
416 | #define CfendForm BIT(17) | ||
417 | #define TCRCRC BIT(16) | ||
418 | #define FAKE_IMEM_EN BIT(15) | ||
419 | #define TSFRST BIT(9) | ||
420 | #define TSFEN BIT(8) | ||
421 | #define FWALLRDY (BIT(0) | BIT(1) | BIT(2) | \ | ||
422 | BIT(3) | BIT(4) | BIT(5) | \ | ||
423 | BIT(6) | BIT(7)) | ||
424 | #define FWRDY BIT(7) | ||
425 | #define BASECHG BIT(6) | ||
426 | #define IMEM BIT(5) | ||
427 | #define DMEM_CODE_DONE BIT(4) | ||
428 | #define EXT_IMEM_CHK_RPT BIT(3) | ||
429 | #define EXT_IMEM_CODE_DONE BIT(2) | ||
430 | #define IMEM_CHK_RPT BIT(1) | ||
431 | #define IMEM_CODE_DONE BIT(0) | ||
432 | #define IMEM_CODE_DONE BIT(0) | ||
433 | #define IMEM_CHK_RPT BIT(1) | ||
434 | #define EMEM_CODE_DONE BIT(2) | ||
435 | #define EMEM_CHK_RPT BIT(3) | ||
436 | #define DMEM_CODE_DONE BIT(4) | ||
437 | #define IMEM_RDY BIT(5) | ||
438 | #define BASECHG BIT(6) | ||
439 | #define FWRDY BIT(7) | ||
440 | #define LOAD_FW_READY (IMEM_CODE_DONE | \ | ||
441 | IMEM_CHK_RPT | \ | ||
442 | EMEM_CODE_DONE | \ | ||
443 | EMEM_CHK_RPT | \ | ||
444 | DMEM_CODE_DONE | \ | ||
445 | IMEM_RDY | \ | ||
446 | BASECHG | \ | ||
447 | FWRDY) | ||
448 | #define TCR_TSFEN BIT(8) | ||
449 | #define TCR_TSFRST BIT(9) | ||
450 | #define TCR_FAKE_IMEM_EN BIT(15) | ||
451 | #define TCR_CRC BIT(16) | ||
452 | #define TCR_ICV BIT(19) | ||
453 | #define TCR_DISCW BIT(20) | ||
454 | #define TCR_HWPC_TX_EN BIT(24) | ||
455 | #define TCR_TCP_OFDL_EN BIT(25) | ||
456 | #define TXDMA_INIT_VALUE (IMEM_CHK_RPT | \ | ||
457 | EXT_IMEM_CHK_RPT) | ||
458 | |||
459 | #define RCR_APPFCS BIT(31) | ||
460 | #define RCR_DIS_ENC_2BYTE BIT(30) | ||
461 | #define RCR_DIS_AES_2BYTE BIT(29) | ||
462 | #define RCR_HTC_LOC_CTRL BIT(28) | ||
463 | #define RCR_ENMBID BIT(27) | ||
464 | #define RCR_RX_TCPOFDL_EN BIT(26) | ||
465 | #define RCR_APP_PHYST_RXFF BIT(25) | ||
466 | #define RCR_APP_PHYST_STAFF BIT(24) | ||
467 | #define RCR_CBSSID BIT(23) | ||
468 | #define RCR_APWRMGT BIT(22) | ||
469 | #define RCR_ADD3 BIT(21) | ||
470 | #define RCR_AMF BIT(20) | ||
471 | #define RCR_ACF BIT(19) | ||
472 | #define RCR_ADF BIT(18) | ||
473 | #define RCR_APP_MIC BIT(17) | ||
474 | #define RCR_APP_ICV BIT(16) | ||
475 | #define RCR_RXFTH BIT(13) | ||
476 | #define RCR_AICV BIT(12) | ||
477 | #define RCR_RXDESC_LK_EN BIT(11) | ||
478 | #define RCR_APP_BA_SSN BIT(6) | ||
479 | #define RCR_ACRC32 BIT(5) | ||
480 | #define RCR_RXSHFT_EN BIT(4) | ||
481 | #define RCR_AB BIT(3) | ||
482 | #define RCR_AM BIT(2) | ||
483 | #define RCR_APM BIT(1) | ||
484 | #define RCR_AAP BIT(0) | ||
485 | #define RCR_MXDMA_OFFSET 8 | ||
486 | #define RCR_FIFO_OFFSET 13 | ||
487 | |||
488 | |||
489 | #define MSR_LINK_MASK ((1 << 0) | (1 << 1)) | ||
490 | #define MSR_LINK_MANAGED 2 | ||
491 | #define MSR_LINK_NONE 0 | ||
492 | #define MSR_LINK_SHIFT 0 | ||
493 | #define MSR_LINK_ADHOC 1 | ||
494 | #define MSR_LINK_MASTER 3 | ||
495 | #define MSR_NOLINK 0x00 | ||
496 | #define MSR_ADHOC 0x01 | ||
497 | #define MSR_INFRA 0x02 | ||
498 | #define MSR_AP 0x03 | ||
499 | |||
500 | #define ENUART BIT(7) | ||
501 | #define ENJTAG BIT(3) | ||
502 | #define BTMODE (BIT(2) | BIT(1)) | ||
503 | #define ENBT BIT(0) | ||
504 | |||
505 | #define ENMBID BIT(7) | ||
506 | #define BCNUM (BIT(6) | BIT(5) | BIT(4)) | ||
507 | |||
508 | #define USTIME_EDCA 0xFF00 | ||
509 | #define USTIME_TSF 0x00FF | ||
510 | |||
511 | #define SIFS_TRX 0xFF00 | ||
512 | #define SIFS_CTX 0x00FF | ||
513 | |||
514 | #define ENSWBCN BIT(15) | ||
515 | #define DRVERLY_TU 0x0FF0 | ||
516 | #define DRVERLY_US 0x000F | ||
517 | #define BCN_TCFG_CW_SHIFT 8 | ||
518 | #define BCN_TCFG_IFS 0 | ||
519 | |||
520 | #define RRSR_RSC_OFFSET 21 | ||
521 | #define RRSR_SHORT_OFFSET 23 | ||
522 | #define RRSR_RSC_BW_40M 0x600000 | ||
523 | #define RRSR_RSC_UPSUBCHNL 0x400000 | ||
524 | #define RRSR_RSC_LOWSUBCHNL 0x200000 | ||
525 | #define RRSR_SHORT 0x800000 | ||
526 | #define RRSR_1M BIT(0) | ||
527 | #define RRSR_2M BIT(1) | ||
528 | #define RRSR_5_5M BIT(2) | ||
529 | #define RRSR_11M BIT(3) | ||
530 | #define RRSR_6M BIT(4) | ||
531 | #define RRSR_9M BIT(5) | ||
532 | #define RRSR_12M BIT(6) | ||
533 | #define RRSR_18M BIT(7) | ||
534 | #define RRSR_24M BIT(8) | ||
535 | #define RRSR_36M BIT(9) | ||
536 | #define RRSR_48M BIT(10) | ||
537 | #define RRSR_54M BIT(11) | ||
538 | #define RRSR_MCS0 BIT(12) | ||
539 | #define RRSR_MCS1 BIT(13) | ||
540 | #define RRSR_MCS2 BIT(14) | ||
541 | #define RRSR_MCS3 BIT(15) | ||
542 | #define RRSR_MCS4 BIT(16) | ||
543 | #define RRSR_MCS5 BIT(17) | ||
544 | #define RRSR_MCS6 BIT(18) | ||
545 | #define RRSR_MCS7 BIT(19) | ||
546 | #define BRSR_AckShortPmb BIT(23) | ||
547 | |||
548 | #define RATR_1M 0x00000001 | ||
549 | #define RATR_2M 0x00000002 | ||
550 | #define RATR_55M 0x00000004 | ||
551 | #define RATR_11M 0x00000008 | ||
552 | #define RATR_6M 0x00000010 | ||
553 | #define RATR_9M 0x00000020 | ||
554 | #define RATR_12M 0x00000040 | ||
555 | #define RATR_18M 0x00000080 | ||
556 | #define RATR_24M 0x00000100 | ||
557 | #define RATR_36M 0x00000200 | ||
558 | #define RATR_48M 0x00000400 | ||
559 | #define RATR_54M 0x00000800 | ||
560 | #define RATR_MCS0 0x00001000 | ||
561 | #define RATR_MCS1 0x00002000 | ||
562 | #define RATR_MCS2 0x00004000 | ||
563 | #define RATR_MCS3 0x00008000 | ||
564 | #define RATR_MCS4 0x00010000 | ||
565 | #define RATR_MCS5 0x00020000 | ||
566 | #define RATR_MCS6 0x00040000 | ||
567 | #define RATR_MCS7 0x00080000 | ||
568 | #define RATR_MCS8 0x00100000 | ||
569 | #define RATR_MCS9 0x00200000 | ||
570 | #define RATR_MCS10 0x00400000 | ||
571 | #define RATR_MCS11 0x00800000 | ||
572 | #define RATR_MCS12 0x01000000 | ||
573 | #define RATR_MCS13 0x02000000 | ||
574 | #define RATR_MCS14 0x04000000 | ||
575 | #define RATR_MCS15 0x08000000 | ||
576 | |||
577 | #define RATE_ALL_CCK (RATR_1M | RATR_2M | \ | ||
578 | RATR_55M | RATR_11M) | ||
579 | #define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | \ | ||
580 | RATR_12M | RATR_18M | \ | ||
581 | RATR_24M | RATR_36M | \ | ||
582 | RATR_48M | RATR_54M) | ||
583 | #define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | \ | ||
584 | RATR_MCS2 | RATR_MCS3 | \ | ||
585 | RATR_MCS4 | RATR_MCS5 | \ | ||
586 | RATR_MCS6 | RATR_MCS7) | ||
587 | #define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | \ | ||
588 | RATR_MCS10 | RATR_MCS11 | \ | ||
589 | RATR_MCS12 | RATR_MCS13 | \ | ||
590 | RATR_MCS14 | RATR_MCS15) | ||
591 | |||
592 | #define AC_PARAM_TXOP_LIMIT_OFFSET 16 | ||
593 | #define AC_PARAM_ECW_MAX_OFFSET 12 | ||
594 | #define AC_PARAM_ECW_MIN_OFFSET 8 | ||
595 | #define AC_PARAM_AIFS_OFFSET 0 | ||
596 | |||
597 | #define AcmHw_HwEn BIT(0) | ||
598 | #define AcmHw_BeqEn BIT(1) | ||
599 | #define AcmHw_ViqEn BIT(2) | ||
600 | #define AcmHw_VoqEn BIT(3) | ||
601 | #define AcmHw_BeqStatus BIT(4) | ||
602 | #define AcmHw_ViqStatus BIT(5) | ||
603 | #define AcmHw_VoqStatus BIT(6) | ||
604 | |||
605 | #define RETRY_LIMIT_SHORT_SHIFT 8 | ||
606 | #define RETRY_LIMIT_LONG_SHIFT 0 | ||
607 | |||
608 | #define NAV_UPPER_EN BIT(16) | ||
609 | #define NAV_UPPER 0xFF00 | ||
610 | #define NAV_RTSRST 0xFF | ||
611 | |||
612 | #define BW_OPMODE_20MHZ BIT(2) | ||
613 | #define BW_OPMODE_5G BIT(1) | ||
614 | #define BW_OPMODE_11J BIT(0) | ||
615 | |||
616 | #define RXERR_RPT_RST BIT(27) | ||
617 | #define RXERR_OFDM_PPDU 0 | ||
618 | #define RXERR_OFDM_FALSE_ALARM 1 | ||
619 | #define RXERR_OFDM_MPDU_OK 2 | ||
620 | #define RXERR_OFDM_MPDU_FAIL 3 | ||
621 | #define RXERR_CCK_PPDU 4 | ||
622 | #define RXERR_CCK_FALSE_ALARM 5 | ||
623 | #define RXERR_CCK_MPDU_OK 6 | ||
624 | #define RXERR_CCK_MPDU_FAIL 7 | ||
625 | #define RXERR_HT_PPDU 8 | ||
626 | #define RXERR_HT_FALSE_ALARM 9 | ||
627 | #define RXERR_HT_MPDU_TOTAL 10 | ||
628 | #define RXERR_HT_MPDU_OK 11 | ||
629 | #define RXERR_HT_MPDU_FAIL 12 | ||
630 | #define RXERR_RX_FULL_DROP 15 | ||
631 | |||
632 | #define SCR_TXUSEDK BIT(0) | ||
633 | #define SCR_RXUSEDK BIT(1) | ||
634 | #define SCR_TXENCENABLE BIT(2) | ||
635 | #define SCR_RXENCENABLE BIT(3) | ||
636 | #define SCR_SKBYA2 BIT(4) | ||
637 | #define SCR_NOSKMC BIT(5) | ||
638 | |||
639 | #define CAM_VALID BIT(15) | ||
640 | #define CAM_NOTVALID 0x0000 | ||
641 | #define CAM_USEDK BIT(5) | ||
642 | |||
643 | #define CAM_NONE 0x0 | ||
644 | #define CAM_WEP40 0x01 | ||
645 | #define CAM_TKIP 0x02 | ||
646 | #define CAM_AES 0x04 | ||
647 | #define CAM_WEP104 0x05 | ||
648 | |||
649 | #define TOTAL_CAM_ENTRY 32 | ||
650 | #define HALF_CAM_ENTRY 16 | ||
651 | |||
652 | #define CAM_WRITE BIT(16) | ||
653 | #define CAM_READ 0x00000000 | ||
654 | #define CAM_POLLINIG BIT(31) | ||
655 | |||
656 | #define WOW_PMEN BIT(0) | ||
657 | #define WOW_WOMEN BIT(1) | ||
658 | #define WOW_MAGIC BIT(2) | ||
659 | #define WOW_UWF BIT(3) | ||
660 | |||
661 | #define GPIOMUX_EN BIT(3) | ||
662 | #define GPIOSEL_GPIO 0 | ||
663 | #define GPIOSEL_PHYDBG 1 | ||
664 | #define GPIOSEL_BT 2 | ||
665 | #define GPIOSEL_WLANDBG 3 | ||
666 | #define GPIOSEL_GPIO_MASK (~(BIT(0)|BIT(1))) | ||
667 | |||
668 | #define HST_RDBUSY BIT(0) | ||
669 | #define CPU_WTBUSY BIT(1) | ||
670 | |||
671 | #define IMR8190_DISABLED 0x0 | ||
672 | #define IMR_CPUERR BIT(5) | ||
673 | #define IMR_ATIMEND BIT(4) | ||
674 | #define IMR_TBDOK BIT(3) | ||
675 | #define IMR_TBDER BIT(2) | ||
676 | #define IMR_BCNDMAINT8 BIT(1) | ||
677 | #define IMR_BCNDMAINT7 BIT(0) | ||
678 | #define IMR_BCNDMAINT6 BIT(31) | ||
679 | #define IMR_BCNDMAINT5 BIT(30) | ||
680 | #define IMR_BCNDMAINT4 BIT(29) | ||
681 | #define IMR_BCNDMAINT3 BIT(28) | ||
682 | #define IMR_BCNDMAINT2 BIT(27) | ||
683 | #define IMR_BCNDMAINT1 BIT(26) | ||
684 | #define IMR_BCNDOK8 BIT(25) | ||
685 | #define IMR_BCNDOK7 BIT(24) | ||
686 | #define IMR_BCNDOK6 BIT(23) | ||
687 | #define IMR_BCNDOK5 BIT(22) | ||
688 | #define IMR_BCNDOK4 BIT(21) | ||
689 | #define IMR_BCNDOK3 BIT(20) | ||
690 | #define IMR_BCNDOK2 BIT(19) | ||
691 | #define IMR_BCNDOK1 BIT(18) | ||
692 | #define IMR_TIMEOUT2 BIT(17) | ||
693 | #define IMR_TIMEOUT1 BIT(16) | ||
694 | #define IMR_TXFOVW BIT(15) | ||
695 | #define IMR_PSTIMEOUT BIT(14) | ||
696 | #define IMR_BCNINT BIT(13) | ||
697 | #define IMR_RXFOVW BIT(12) | ||
698 | #define IMR_RDU BIT(11) | ||
699 | #define IMR_RXCMDOK BIT(10) | ||
700 | #define IMR_BDOK BIT(9) | ||
701 | #define IMR_HIGHDOK BIT(8) | ||
702 | #define IMR_COMDOK BIT(7) | ||
703 | #define IMR_MGNTDOK BIT(6) | ||
704 | #define IMR_HCCADOK BIT(5) | ||
705 | #define IMR_BKDOK BIT(4) | ||
706 | #define IMR_BEDOK BIT(3) | ||
707 | #define IMR_VIDOK BIT(2) | ||
708 | #define IMR_VODOK BIT(1) | ||
709 | #define IMR_ROK BIT(0) | ||
710 | |||
711 | #define TPPOLL_BKQ BIT(0) | ||
712 | #define TPPOLL_BEQ BIT(1) | ||
713 | #define TPPOLL_VIQ BIT(2) | ||
714 | #define TPPOLL_VOQ BIT(3) | ||
715 | #define TPPOLL_BQ BIT(4) | ||
716 | #define TPPOLL_CQ BIT(5) | ||
717 | #define TPPOLL_MQ BIT(6) | ||
718 | #define TPPOLL_HQ BIT(7) | ||
719 | #define TPPOLL_HCCAQ BIT(8) | ||
720 | #define TPPOLL_STOPBK BIT(9) | ||
721 | #define TPPOLL_STOPBE BIT(10) | ||
722 | #define TPPOLL_STOPVI BIT(11) | ||
723 | #define TPPOLL_STOPVO BIT(12) | ||
724 | #define TPPOLL_STOPMGT BIT(13) | ||
725 | #define TPPOLL_STOPHIGH BIT(14) | ||
726 | #define TPPOLL_STOPHCCA BIT(15) | ||
727 | #define TPPOLL_SHIFT 8 | ||
728 | |||
729 | #define CCX_CMD_CLM_ENABLE BIT(0) | ||
730 | #define CCX_CMD_NHM_ENABLE BIT(1) | ||
731 | #define CCX_CMD_FUNCTION_ENABLE BIT(8) | ||
732 | #define CCX_CMD_IGNORE_CCA BIT(9) | ||
733 | #define CCX_CMD_IGNORE_TXON BIT(10) | ||
734 | #define CCX_CLM_RESULT_READY BIT(16) | ||
735 | #define CCX_NHM_RESULT_READY BIT(16) | ||
736 | #define CCX_CMD_RESET 0x0 | ||
737 | |||
738 | |||
739 | #define HWSET_MAX_SIZE_92S 128 | ||
740 | #define EFUSE_MAX_SECTION 16 | ||
741 | #define EFUSE_REAL_CONTENT_LEN 512 | ||
742 | |||
743 | #define RTL8190_EEPROM_ID 0x8129 | ||
744 | #define EEPROM_HPON 0x02 | ||
745 | #define EEPROM_CLK 0x06 | ||
746 | #define EEPROM_TESTR 0x08 | ||
747 | |||
748 | #define EEPROM_VID 0x0A | ||
749 | #define EEPROM_DID 0x0C | ||
750 | #define EEPROM_SVID 0x0E | ||
751 | #define EEPROM_SMID 0x10 | ||
752 | |||
753 | #define EEPROM_MAC_ADDR 0x12 | ||
754 | #define EEPROM_NODE_ADDRESS_BYTE_0 0x12 | ||
755 | |||
756 | #define EEPROM_PWDIFF 0x54 | ||
757 | |||
758 | #define EEPROM_TXPOWERBASE 0x50 | ||
759 | #define EEPROM_TX_PWR_INDEX_RANGE 28 | ||
760 | |||
761 | #define EEPROM_TX_PWR_HT20_DIFF 0x62 | ||
762 | #define DEFAULT_HT20_TXPWR_DIFF 2 | ||
763 | #define EEPROM_TX_PWR_OFDM_DIFF 0x65 | ||
764 | |||
765 | #define EEPROM_TXPWRGROUP 0x67 | ||
766 | #define EEPROM_REGULATORY 0x6D | ||
767 | |||
768 | #define TX_PWR_SAFETY_CHK 0x6D | ||
769 | #define EEPROM_TXPWINDEX_CCK_24G 0x5D | ||
770 | #define EEPROM_TXPWINDEX_OFDM_24G 0x6B | ||
771 | #define EEPROM_HT2T_CH1_A 0x6c | ||
772 | #define EEPROM_HT2T_CH7_A 0x6d | ||
773 | #define EEPROM_HT2T_CH13_A 0x6e | ||
774 | #define EEPROM_HT2T_CH1_B 0x6f | ||
775 | #define EEPROM_HT2T_CH7_B 0x70 | ||
776 | #define EEPROM_HT2T_CH13_B 0x71 | ||
777 | |||
778 | #define EEPROM_TSSI_A 0x74 | ||
779 | #define EEPROM_TSSI_B 0x75 | ||
780 | |||
781 | #define EEPROM_RFIND_POWERDIFF 0x76 | ||
782 | #define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 | ||
783 | |||
784 | #define EEPROM_THERMALMETER 0x77 | ||
785 | #define EEPROM_BLUETOOTH_COEXIST 0x78 | ||
786 | #define EEPROM_BLUETOOTH_TYPE 0x4f | ||
787 | |||
788 | #define EEPROM_OPTIONAL 0x78 | ||
789 | #define EEPROM_WOWLAN 0x78 | ||
790 | |||
791 | #define EEPROM_CRYSTALCAP 0x79 | ||
792 | #define EEPROM_CHANNELPLAN 0x7B | ||
793 | #define EEPROM_VERSION 0x7C | ||
794 | #define EEPROM_CUSTOMID 0x7A | ||
795 | #define EEPROM_BOARDTYPE 0x7E | ||
796 | |||
797 | #define EEPROM_CHANNEL_PLAN_FCC 0x0 | ||
798 | #define EEPROM_CHANNEL_PLAN_IC 0x1 | ||
799 | #define EEPROM_CHANNEL_PLAN_ETSI 0x2 | ||
800 | #define EEPROM_CHANNEL_PLAN_SPAIN 0x3 | ||
801 | #define EEPROM_CHANNEL_PLAN_FRANCE 0x4 | ||
802 | #define EEPROM_CHANNEL_PLAN_MKK 0x5 | ||
803 | #define EEPROM_CHANNEL_PLAN_MKK1 0x6 | ||
804 | #define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 | ||
805 | #define EEPROM_CHANNEL_PLAN_TELEC 0x8 | ||
806 | #define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 | ||
807 | #define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA | ||
808 | #define EEPROM_CHANNEL_PLAN_NCC 0xB | ||
809 | #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 | ||
810 | |||
811 | #define FW_DIG_DISABLE 0xfd00cc00 | ||
812 | #define FW_DIG_ENABLE 0xfd000000 | ||
813 | #define FW_DIG_HALT 0xfd000001 | ||
814 | #define FW_DIG_RESUME 0xfd000002 | ||
815 | #define FW_HIGH_PWR_DISABLE 0xfd000008 | ||
816 | #define FW_HIGH_PWR_ENABLE 0xfd000009 | ||
817 | #define FW_ADD_A2_ENTRY 0xfd000016 | ||
818 | #define FW_TXPWR_TRACK_ENABLE 0xfd000017 | ||
819 | #define FW_TXPWR_TRACK_DISABLE 0xfd000018 | ||
820 | #define FW_TXPWR_TRACK_THERMAL 0xfd000019 | ||
821 | #define FW_TXANT_SWITCH_ENABLE 0xfd000023 | ||
822 | #define FW_TXANT_SWITCH_DISABLE 0xfd000024 | ||
823 | #define FW_RA_INIT 0xfd000026 | ||
824 | #define FW_CTRL_DM_BY_DRIVER 0Xfd00002a | ||
825 | #define FW_RA_IOT_BG_COMB 0xfd000030 | ||
826 | #define FW_RA_IOT_N_COMB 0xfd000031 | ||
827 | #define FW_RA_REFRESH 0xfd0000a0 | ||
828 | #define FW_RA_UPDATE_MASK 0xfd0000a2 | ||
829 | #define FW_RA_DISABLE 0xfd0000a4 | ||
830 | #define FW_RA_ACTIVE 0xfd0000a6 | ||
831 | #define FW_RA_DISABLE_RSSI_MASK 0xfd0000ac | ||
832 | #define FW_RA_ENABLE_RSSI_MASK 0xfd0000ad | ||
833 | #define FW_RA_RESET 0xfd0000af | ||
834 | #define FW_DM_DISABLE 0xfd00aa00 | ||
835 | #define FW_IQK_ENABLE 0xf0000020 | ||
836 | #define FW_IQK_SUCCESS 0x0000dddd | ||
837 | #define FW_IQK_FAIL 0x0000ffff | ||
838 | #define FW_OP_FAILURE 0xffffffff | ||
839 | #define FW_TX_FEEDBACK_NONE 0xfb000000 | ||
840 | #define FW_TX_FEEDBACK_DTM_ENABLE (FW_TX_FEEDBACK_NONE | 0x1) | ||
841 | #define FW_TX_FEEDBACK_CCX_ENABL (FW_TX_FEEDBACK_NONE | 0x2) | ||
842 | #define FW_BB_RESET_ENABLE 0xff00000d | ||
843 | #define FW_BB_RESET_DISABLE 0xff00000e | ||
844 | #define FW_CCA_CHK_ENABLE 0xff000011 | ||
845 | #define FW_CCK_RESET_CNT 0xff000013 | ||
846 | #define FW_LPS_ENTER 0xfe000010 | ||
847 | #define FW_LPS_LEAVE 0xfe000011 | ||
848 | #define FW_INDIRECT_READ 0xf2000000 | ||
849 | #define FW_INDIRECT_WRITE 0xf2000001 | ||
850 | #define FW_CHAN_SET 0xf3000001 | ||
851 | |||
852 | #define RFPC 0x5F | ||
853 | #define RCR_9356SEL BIT(6) | ||
854 | #define TCR_LRL_OFFSET 0 | ||
855 | #define TCR_SRL_OFFSET 8 | ||
856 | #define TCR_MXDMA_OFFSET 21 | ||
857 | #define TCR_SAT BIT(24) | ||
858 | #define RCR_MXDMA_OFFSET 8 | ||
859 | #define RCR_FIFO_OFFSET 13 | ||
860 | #define RCR_OnlyErlPkt BIT(31) | ||
861 | #define CWR 0xDC | ||
862 | #define RETRYCTR 0xDE | ||
863 | |||
864 | #define CPU_GEN_SYSTEM_RESET 0x00000001 | ||
865 | |||
866 | #define CCX_COMMAND_REG 0x890 | ||
867 | #define CLM_PERIOD_REG 0x894 | ||
868 | #define NHM_PERIOD_REG 0x896 | ||
869 | |||
870 | #define NHM_THRESHOLD0 0x898 | ||
871 | #define NHM_THRESHOLD1 0x899 | ||
872 | #define NHM_THRESHOLD2 0x89A | ||
873 | #define NHM_THRESHOLD3 0x89B | ||
874 | #define NHM_THRESHOLD4 0x89C | ||
875 | #define NHM_THRESHOLD5 0x89D | ||
876 | #define NHM_THRESHOLD6 0x89E | ||
877 | #define CLM_RESULT_REG 0x8D0 | ||
878 | #define NHM_RESULT_REG 0x8D4 | ||
879 | #define NHM_RPI_COUNTER0 0x8D8 | ||
880 | #define NHM_RPI_COUNTER1 0x8D9 | ||
881 | #define NHM_RPI_COUNTER2 0x8DA | ||
882 | #define NHM_RPI_COUNTER3 0x8DB | ||
883 | #define NHM_RPI_COUNTER4 0x8DC | ||
884 | #define NHM_RPI_COUNTER5 0x8DD | ||
885 | #define NHM_RPI_COUNTER6 0x8DE | ||
886 | #define NHM_RPI_COUNTER7 0x8DF | ||
887 | |||
888 | #define HAL_8192S_HW_GPIO_OFF_BIT BIT(3) | ||
889 | #define HAL_8192S_HW_GPIO_OFF_MASK 0xF7 | ||
890 | #define HAL_8192S_HW_GPIO_WPS_BIT BIT(4) | ||
891 | |||
892 | #define RPMAC_RESET 0x100 | ||
893 | #define RPMAC_TXSTART 0x104 | ||
894 | #define RPMAC_TXLEGACYSIG 0x108 | ||
895 | #define RPMAC_TXHTSIG1 0x10c | ||
896 | #define RPMAC_TXHTSIG2 0x110 | ||
897 | #define RPMAC_PHYDEBUG 0x114 | ||
898 | #define RPMAC_TXPACKETNNM 0x118 | ||
899 | #define RPMAC_TXIDLE 0x11c | ||
900 | #define RPMAC_TXMACHEADER0 0x120 | ||
901 | #define RPMAC_TXMACHEADER1 0x124 | ||
902 | #define RPMAC_TXMACHEADER2 0x128 | ||
903 | #define RPMAC_TXMACHEADER3 0x12c | ||
904 | #define RPMAC_TXMACHEADER4 0x130 | ||
905 | #define RPMAC_TXMACHEADER5 0x134 | ||
906 | #define RPMAC_TXDATATYPE 0x138 | ||
907 | #define RPMAC_TXRANDOMSEED 0x13c | ||
908 | #define RPMAC_CCKPLCPPREAMBLE 0x140 | ||
909 | #define RPMAC_CCKPLCPHEADER 0x144 | ||
910 | #define RPMAC_CCKCRC16 0x148 | ||
911 | #define RPMAC_OFDMRXCRC32OK 0x170 | ||
912 | #define RPMAC_OFDMRXCRC32ER 0x174 | ||
913 | #define RPMAC_OFDMRXPARITYER 0x178 | ||
914 | #define RPMAC_OFDMRXCRC8ER 0x17c | ||
915 | #define RPMAC_CCKCRXRC16ER 0x180 | ||
916 | #define RPMAC_CCKCRXRC32ER 0x184 | ||
917 | #define RPMAC_CCKCRXRC32OK 0x188 | ||
918 | #define RPMAC_TXSTATUS 0x18c | ||
919 | |||
920 | #define RF_BB_CMD_ADDR 0x02c0 | ||
921 | #define RF_BB_CMD_DATA 0x02c4 | ||
922 | |||
923 | #define RFPGA0_RFMOD 0x800 | ||
924 | |||
925 | #define RFPGA0_TXINFO 0x804 | ||
926 | #define RFPGA0_PSDFUNCTION 0x808 | ||
927 | |||
928 | #define RFPGA0_TXGAINSTAGE 0x80c | ||
929 | |||
930 | #define RFPGA0_RFTIMING1 0x810 | ||
931 | #define RFPGA0_RFTIMING2 0x814 | ||
932 | #define RFPGA0_XA_HSSIPARAMETER1 0x820 | ||
933 | #define RFPGA0_XA_HSSIPARAMETER2 0x824 | ||
934 | #define RFPGA0_XB_HSSIPARAMETER1 0x828 | ||
935 | #define RFPGA0_XB_HSSIPARAMETER2 0x82c | ||
936 | #define RFPGA0_XC_HSSIPARAMETER1 0x830 | ||
937 | #define RFPGA0_XC_HSSIPARAMETER2 0x834 | ||
938 | #define RFPGA0_XD_HSSIPARAMETER1 0x838 | ||
939 | #define RFPGA0_XD_HSSIPARAMETER2 0x83c | ||
940 | #define RFPGA0_XA_LSSIPARAMETER 0x840 | ||
941 | #define RFPGA0_XB_LSSIPARAMETER 0x844 | ||
942 | #define RFPGA0_XC_LSSIPARAMETER 0x848 | ||
943 | #define RFPGA0_XD_LSSIPARAMETER 0x84c | ||
944 | |||
945 | #define RFPGA0_RFWAKEUP_PARAMETER 0x850 | ||
946 | #define RFPGA0_RFSLEEPUP_PARAMETER 0x854 | ||
947 | |||
948 | #define RFPGA0_XAB_SWITCHCONTROL 0x858 | ||
949 | #define RFPGA0_XCD_SWITCHCONTROL 0x85c | ||
950 | |||
951 | #define RFPGA0_XA_RFINTERFACEOE 0x860 | ||
952 | #define RFPGA0_XB_RFINTERFACEOE 0x864 | ||
953 | #define RFPGA0_XC_RFINTERFACEOE 0x868 | ||
954 | #define RFPGA0_XD_RFINTERFACEOE 0x86c | ||
955 | |||
956 | #define RFPGA0_XAB_RFINTERFACESW 0x870 | ||
957 | #define RFPGA0_XCD_RFINTERFACESW 0x874 | ||
958 | |||
959 | #define RFPGA0_XAB_RFPARAMETER 0x878 | ||
960 | #define RFPGA0_XCD_RFPARAMETER 0x87c | ||
961 | |||
962 | #define RFPGA0_ANALOGPARAMETER1 0x880 | ||
963 | #define RFPGA0_ANALOGPARAMETER2 0x884 | ||
964 | #define RFPGA0_ANALOGPARAMETER3 0x888 | ||
965 | #define RFPGA0_ANALOGPARAMETER4 0x88c | ||
966 | |||
967 | #define RFPGA0_XA_LSSIREADBACK 0x8a0 | ||
968 | #define RFPGA0_XB_LSSIREADBACK 0x8a4 | ||
969 | #define RFPGA0_XC_LSSIREADBACK 0x8a8 | ||
970 | #define RFPGA0_XD_LSSIREADBACK 0x8ac | ||
971 | |||
972 | #define RFPGA0_PSDREPORT 0x8b4 | ||
973 | #define TRANSCEIVERA_HSPI_READBACK 0x8b8 | ||
974 | #define TRANSCEIVERB_HSPI_READBACK 0x8bc | ||
975 | #define RFPGA0_XAB_RFINTERFACERB 0x8e0 | ||
976 | #define RFPGA0_XCD_RFINTERFACERB 0x8e4 | ||
977 | #define RFPGA1_RFMOD 0x900 | ||
978 | |||
979 | #define RFPGA1_TXBLOCK 0x904 | ||
980 | #define RFPGA1_DEBUGSELECT 0x908 | ||
981 | #define RFPGA1_TXINFO 0x90c | ||
982 | |||
983 | #define RCCK0_SYSTEM 0xa00 | ||
984 | |||
985 | #define RCCK0_AFESETTING 0xa04 | ||
986 | #define RCCK0_CCA 0xa08 | ||
987 | |||
988 | #define RCCK0_RXAGC1 0xa0c | ||
989 | #define RCCK0_RXAGC2 0xa10 | ||
990 | |||
991 | #define RCCK0_RXHP 0xa14 | ||
992 | |||
993 | #define RCCK0_DSPPARAMETER1 0xa18 | ||
994 | #define RCCK0_DSPPARAMETER2 0xa1c | ||
995 | |||
996 | #define RCCK0_TXFILTER1 0xa20 | ||
997 | #define RCCK0_TXFILTER2 0xa24 | ||
998 | #define RCCK0_DEBUGPORT 0xa28 | ||
999 | #define RCCK0_FALSEALARMREPORT 0xa2c | ||
1000 | #define RCCK0_TRSSIREPORT 0xa50 | ||
1001 | #define RCCK0_RXREPORT 0xa54 | ||
1002 | #define RCCK0_FACOUNTERLOWER 0xa5c | ||
1003 | #define RCCK0_FACOUNTERUPPER 0xa58 | ||
1004 | |||
1005 | #define ROFDM0_LSTF 0xc00 | ||
1006 | |||
1007 | #define ROFDM0_TRXPATHENABLE 0xc04 | ||
1008 | #define ROFDM0_TRMUXPAR 0xc08 | ||
1009 | #define ROFDM0_TRSWISOLATION 0xc0c | ||
1010 | |||
1011 | #define ROFDM0_XARXAFE 0xc10 | ||
1012 | #define ROFDM0_XARXIQIMBALANCE 0xc14 | ||
1013 | #define ROFDM0_XBRXAFE 0xc18 | ||
1014 | #define ROFDM0_XBRXIQIMBALANCE 0xc1c | ||
1015 | #define ROFDM0_XCRXAFE 0xc20 | ||
1016 | #define ROFDM0_XCRXIQIMBALANCE 0xc24 | ||
1017 | #define ROFDM0_XDRXAFE 0xc28 | ||
1018 | #define ROFDM0_XDRXIQIMBALANCE 0xc2c | ||
1019 | |||
1020 | #define ROFDM0_RXDETECTOR1 0xc30 | ||
1021 | #define ROFDM0_RXDETECTOR2 0xc34 | ||
1022 | #define ROFDM0_RXDETECTOR3 0xc38 | ||
1023 | #define ROFDM0_RXDETECTOR4 0xc3c | ||
1024 | |||
1025 | #define ROFDM0_RXDSP 0xc40 | ||
1026 | #define ROFDM0_CFO_AND_DAGC 0xc44 | ||
1027 | #define ROFDM0_CCADROP_THRESHOLD 0xc48 | ||
1028 | #define ROFDM0_ECCA_THRESHOLD 0xc4c | ||
1029 | |||
1030 | #define ROFDM0_XAAGCCORE1 0xc50 | ||
1031 | #define ROFDM0_XAAGCCORE2 0xc54 | ||
1032 | #define ROFDM0_XBAGCCORE1 0xc58 | ||
1033 | #define ROFDM0_XBAGCCORE2 0xc5c | ||
1034 | #define ROFDM0_XCAGCCORE1 0xc60 | ||
1035 | #define ROFDM0_XCAGCCORE2 0xc64 | ||
1036 | #define ROFDM0_XDAGCCORE1 0xc68 | ||
1037 | #define ROFDM0_XDAGCCORE2 0xc6c | ||
1038 | |||
1039 | #define ROFDM0_AGCPARAMETER1 0xc70 | ||
1040 | #define ROFDM0_AGCPARAMETER2 0xc74 | ||
1041 | #define ROFDM0_AGCRSSITABLE 0xc78 | ||
1042 | #define ROFDM0_HTSTFAGC 0xc7c | ||
1043 | |||
1044 | #define ROFDM0_XATXIQIMBALANCE 0xc80 | ||
1045 | #define ROFDM0_XATXAFE 0xc84 | ||
1046 | #define ROFDM0_XBTXIQIMBALANCE 0xc88 | ||
1047 | #define ROFDM0_XBTXAFE 0xc8c | ||
1048 | #define ROFDM0_XCTXIQIMBALANCE 0xc90 | ||
1049 | #define ROFDM0_XCTXAFE 0xc94 | ||
1050 | #define ROFDM0_XDTXIQIMBALANCE 0xc98 | ||
1051 | #define ROFDM0_XDTXAFE 0xc9c | ||
1052 | |||
1053 | #define ROFDM0_RXHP_PARAMETER 0xce0 | ||
1054 | #define ROFDM0_TXPSEUDO_NOISE_WGT 0xce4 | ||
1055 | #define ROFDM0_FRAME_SYNC 0xcf0 | ||
1056 | #define ROFDM0_DFSREPORT 0xcf4 | ||
1057 | #define ROFDM0_TXCOEFF1 0xca4 | ||
1058 | #define ROFDM0_TXCOEFF2 0xca8 | ||
1059 | #define ROFDM0_TXCOEFF3 0xcac | ||
1060 | #define ROFDM0_TXCOEFF4 0xcb0 | ||
1061 | #define ROFDM0_TXCOEFF5 0xcb4 | ||
1062 | #define ROFDM0_TXCOEFF6 0xcb8 | ||
1063 | |||
1064 | |||
1065 | #define ROFDM1_LSTF 0xd00 | ||
1066 | #define ROFDM1_TRXPATHENABLE 0xd04 | ||
1067 | |||
1068 | #define ROFDM1_CFO 0xd08 | ||
1069 | #define ROFDM1_CSI1 0xd10 | ||
1070 | #define ROFDM1_SBD 0xd14 | ||
1071 | #define ROFDM1_CSI2 0xd18 | ||
1072 | #define ROFDM1_CFOTRACKING 0xd2c | ||
1073 | #define ROFDM1_TRXMESAURE1 0xd34 | ||
1074 | #define ROFDM1_INTF_DET 0xd3c | ||
1075 | #define ROFDM1_PSEUDO_NOISESTATEAB 0xd50 | ||
1076 | #define ROFDM1_PSEUDO_NOISESTATECD 0xd54 | ||
1077 | #define ROFDM1_RX_PSEUDO_NOISE_WGT 0xd58 | ||
1078 | |||
1079 | #define ROFDM_PHYCOUNTER1 0xda0 | ||
1080 | #define ROFDM_PHYCOUNTER2 0xda4 | ||
1081 | #define ROFDM_PHYCOUNTER3 0xda8 | ||
1082 | |||
1083 | #define ROFDM_SHORT_CFOAB 0xdac | ||
1084 | #define ROFDM_SHORT_CFOCD 0xdb0 | ||
1085 | #define ROFDM_LONG_CFOAB 0xdb4 | ||
1086 | #define ROFDM_LONG_CFOCD 0xdb8 | ||
1087 | #define ROFDM_TAIL_CFOAB 0xdbc | ||
1088 | #define ROFDM_TAIL_CFOCD 0xdc0 | ||
1089 | #define ROFDM_PW_MEASURE1 0xdc4 | ||
1090 | #define ROFDM_PW_MEASURE2 0xdc8 | ||
1091 | #define ROFDM_BW_REPORT 0xdcc | ||
1092 | #define ROFDM_AGC_REPORT 0xdd0 | ||
1093 | #define ROFDM_RXSNR 0xdd4 | ||
1094 | #define ROFDM_RXEVMCSI 0xdd8 | ||
1095 | #define ROFDM_SIG_REPORT 0xddc | ||
1096 | |||
1097 | |||
1098 | #define RTXAGC_RATE18_06 0xe00 | ||
1099 | #define RTXAGC_RATE54_24 0xe04 | ||
1100 | #define RTXAGC_CCK_MCS32 0xe08 | ||
1101 | #define RTXAGC_MCS03_MCS00 0xe10 | ||
1102 | #define RTXAGC_MCS07_MCS04 0xe14 | ||
1103 | #define RTXAGC_MCS11_MCS08 0xe18 | ||
1104 | #define RTXAGC_MCS15_MCS12 0xe1c | ||
1105 | |||
1106 | |||
1107 | #define RF_AC 0x00 | ||
1108 | #define RF_IQADJ_G1 0x01 | ||
1109 | #define RF_IQADJ_G2 0x02 | ||
1110 | #define RF_POW_TRSW 0x05 | ||
1111 | #define RF_GAIN_RX 0x06 | ||
1112 | #define RF_GAIN_TX 0x07 | ||
1113 | #define RF_TXM_IDAC 0x08 | ||
1114 | #define RF_BS_IQGEN 0x0F | ||
1115 | |||
1116 | #define RF_MODE1 0x10 | ||
1117 | #define RF_MODE2 0x11 | ||
1118 | #define RF_RX_AGC_HP 0x12 | ||
1119 | #define RF_TX_AGC 0x13 | ||
1120 | #define RF_BIAS 0x14 | ||
1121 | #define RF_IPA 0x15 | ||
1122 | #define RF_POW_ABILITY 0x17 | ||
1123 | #define RF_MODE_AG 0x18 | ||
1124 | #define RF_CHANNEL 0x18 | ||
1125 | #define RF_CHNLBW 0x18 | ||
1126 | #define RF_TOP 0x19 | ||
1127 | #define RF_RX_G1 0x1A | ||
1128 | #define RF_RX_G2 0x1B | ||
1129 | #define RF_RX_BB2 0x1C | ||
1130 | #define RF_RX_BB1 0x1D | ||
1131 | #define RF_RCK1 0x1E | ||
1132 | #define RF_RCK2 0x1F | ||
1133 | |||
1134 | #define RF_TX_G1 0x20 | ||
1135 | #define RF_TX_G2 0x21 | ||
1136 | #define RF_TX_G3 0x22 | ||
1137 | #define RF_TX_BB1 0x23 | ||
1138 | #define RF_T_METER 0x24 | ||
1139 | #define RF_SYN_G1 0x25 | ||
1140 | #define RF_SYN_G2 0x26 | ||
1141 | #define RF_SYN_G3 0x27 | ||
1142 | #define RF_SYN_G4 0x28 | ||
1143 | #define RF_SYN_G5 0x29 | ||
1144 | #define RF_SYN_G6 0x2A | ||
1145 | #define RF_SYN_G7 0x2B | ||
1146 | #define RF_SYN_G8 0x2C | ||
1147 | |||
1148 | #define RF_RCK_OS 0x30 | ||
1149 | #define RF_TXPA_G1 0x31 | ||
1150 | #define RF_TXPA_G2 0x32 | ||
1151 | #define RF_TXPA_G3 0x33 | ||
1152 | |||
1153 | #define BRFMOD 0x1 | ||
1154 | #define BCCKEN 0x1000000 | ||
1155 | #define BOFDMEN 0x2000000 | ||
1156 | |||
1157 | #define BXBTXAGC 0xf00 | ||
1158 | #define BXCTXAGC 0xf000 | ||
1159 | #define BXDTXAGC 0xf0000 | ||
1160 | |||
1161 | #define B3WIRE_DATALENGTH 0x800 | ||
1162 | #define B3WIRE_ADDRESSLENGTH 0x400 | ||
1163 | |||
1164 | #define BRFSI_RFENV 0x10 | ||
1165 | |||
1166 | #define BLSSI_READADDRESS 0x7f800000 | ||
1167 | #define BLSSI_READEDGE 0x80000000 | ||
1168 | #define BLSSI_READBACK_DATA 0xfffff | ||
1169 | |||
1170 | #define BADCLKPHASE 0x4000000 | ||
1171 | |||
1172 | #define BCCK_SIDEBAND 0x10 | ||
1173 | |||
1174 | #define BTX_AGCRATECCK 0x7f00 | ||
1175 | |||
1176 | #define MASKBYTE0 0xff | ||
1177 | #define MASKBYTE1 0xff00 | ||
1178 | #define MASKBYTE2 0xff0000 | ||
1179 | #define MASKBYTE3 0xff000000 | ||
1180 | #define MASKHWORD 0xffff0000 | ||
1181 | #define MASKLWORD 0x0000ffff | ||
1182 | #define MASKDWORD 0xffffffff | ||
1183 | |||
1184 | #define MAKS12BITS 0xfffff | ||
1185 | #define MASK20BITS 0xfffff | ||
1186 | #define RFREG_OFFSET_MASK 0xfffff | ||
1187 | |||
1188 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c new file mode 100644 index 000000000000..1d3a48330399 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c | |||
@@ -0,0 +1,546 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "reg.h" | ||
32 | #include "def.h" | ||
33 | #include "phy.h" | ||
34 | #include "rf.h" | ||
35 | #include "dm.h" | ||
36 | |||
37 | |||
38 | static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel, | ||
39 | u8 chnl, u32 *ofdmbase, u32 *mcsbase, | ||
40 | u8 *p_final_pwridx) | ||
41 | { | ||
42 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
43 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
44 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
45 | u32 pwrbase0, pwrbase1; | ||
46 | u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0; | ||
47 | u8 i, pwrlevel[4]; | ||
48 | |||
49 | for (i = 0; i < 2; i++) | ||
50 | pwrlevel[i] = p_pwrlevel[i]; | ||
51 | |||
52 | /* We only care about the path A for legacy. */ | ||
53 | if (rtlefuse->eeprom_version < 2) { | ||
54 | pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf); | ||
55 | } else if (rtlefuse->eeprom_version >= 2) { | ||
56 | legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff | ||
57 | [RF90_PATH_A][chnl - 1]; | ||
58 | |||
59 | /* For legacy OFDM, tx pwr always > HT OFDM pwr. | ||
60 | * We do not care Path B | ||
61 | * legacy OFDM pwr diff. NO BB register | ||
62 | * to notify HW. */ | ||
63 | pwrbase0 = pwrlevel[0] + legacy_pwrdiff; | ||
64 | } | ||
65 | |||
66 | pwrbase0 = (pwrbase0 << 24) | (pwrbase0 << 16) | (pwrbase0 << 8) | | ||
67 | pwrbase0; | ||
68 | *ofdmbase = pwrbase0; | ||
69 | |||
70 | /* MCS rates */ | ||
71 | if (rtlefuse->eeprom_version >= 2) { | ||
72 | /* Check HT20 to HT40 diff */ | ||
73 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { | ||
74 | for (i = 0; i < 2; i++) { | ||
75 | /* rf-A, rf-B */ | ||
76 | /* HT 20<->40 pwr diff */ | ||
77 | ht20_pwrdiff = rtlefuse->txpwr_ht20diff | ||
78 | [i][chnl - 1]; | ||
79 | |||
80 | if (ht20_pwrdiff < 8) /* 0~+7 */ | ||
81 | pwrlevel[i] += ht20_pwrdiff; | ||
82 | else /* index8-15=-8~-1 */ | ||
83 | pwrlevel[i] -= (16 - ht20_pwrdiff); | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /* use index of rf-A */ | ||
89 | pwrbase1 = pwrlevel[0]; | ||
90 | pwrbase1 = (pwrbase1 << 24) | (pwrbase1 << 16) | (pwrbase1 << 8) | | ||
91 | pwrbase1; | ||
92 | *mcsbase = pwrbase1; | ||
93 | |||
94 | /* The following is for Antenna | ||
95 | * diff from Ant-B to Ant-A */ | ||
96 | p_final_pwridx[0] = pwrlevel[0]; | ||
97 | p_final_pwridx[1] = pwrlevel[1]; | ||
98 | |||
99 | switch (rtlefuse->eeprom_regulatory) { | ||
100 | case 3: | ||
101 | /* The following is for calculation | ||
102 | * of the power diff for Ant-B to Ant-A. */ | ||
103 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
104 | p_final_pwridx[0] += rtlefuse->pwrgroup_ht40 | ||
105 | [RF90_PATH_A][ | ||
106 | chnl - 1]; | ||
107 | p_final_pwridx[1] += rtlefuse->pwrgroup_ht40 | ||
108 | [RF90_PATH_B][ | ||
109 | chnl - 1]; | ||
110 | } else { | ||
111 | p_final_pwridx[0] += rtlefuse->pwrgroup_ht20 | ||
112 | [RF90_PATH_A][ | ||
113 | chnl - 1]; | ||
114 | p_final_pwridx[1] += rtlefuse->pwrgroup_ht20 | ||
115 | [RF90_PATH_B][ | ||
116 | chnl - 1]; | ||
117 | } | ||
118 | break; | ||
119 | default: | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
124 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx " | ||
125 | "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], | ||
126 | p_final_pwridx[1])); | ||
127 | } else { | ||
128 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx " | ||
129 | "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], | ||
130 | p_final_pwridx[1])); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, | ||
135 | u8 *p_final_pwridx) | ||
136 | { | ||
137 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
138 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
139 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
140 | char ant_pwr_diff = 0; | ||
141 | u32 u4reg_val = 0; | ||
142 | |||
143 | if (rtlphy->rf_type == RF_2T2R) { | ||
144 | ant_pwr_diff = p_final_pwridx[1] - p_final_pwridx[0]; | ||
145 | |||
146 | /* range is from 7~-8, | ||
147 | * index = 0x0~0xf */ | ||
148 | if (ant_pwr_diff > 7) | ||
149 | ant_pwr_diff = 7; | ||
150 | if (ant_pwr_diff < -8) | ||
151 | ant_pwr_diff = -8; | ||
152 | |||
153 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
154 | ("Antenna Diff from RF-B " | ||
155 | "to RF-A = %d (0x%x)\n", ant_pwr_diff, | ||
156 | ant_pwr_diff & 0xf)); | ||
157 | |||
158 | ant_pwr_diff &= 0xf; | ||
159 | } | ||
160 | |||
161 | /* Antenna TX power difference */ | ||
162 | rtlefuse->antenna_txpwdiff[2] = 0;/* RF-D, don't care */ | ||
163 | rtlefuse->antenna_txpwdiff[1] = 0;/* RF-C, don't care */ | ||
164 | rtlefuse->antenna_txpwdiff[0] = (u8)(ant_pwr_diff); /* RF-B */ | ||
165 | |||
166 | u4reg_val = rtlefuse->antenna_txpwdiff[2] << 8 | | ||
167 | rtlefuse->antenna_txpwdiff[1] << 4 | | ||
168 | rtlefuse->antenna_txpwdiff[0]; | ||
169 | |||
170 | rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC), | ||
171 | u4reg_val); | ||
172 | |||
173 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
174 | ("Write BCD-Diff(0x%x) = 0x%x\n", | ||
175 | RFPGA0_TXGAINSTAGE, u4reg_val)); | ||
176 | } | ||
177 | |||
178 | static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, | ||
179 | u8 chnl, u8 index, | ||
180 | u32 pwrbase0, | ||
181 | u32 pwrbase1, | ||
182 | u32 *p_outwrite_val) | ||
183 | { | ||
184 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
185 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
186 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
187 | u8 i, chnlgroup, pwrdiff_limit[4]; | ||
188 | u32 writeval, customer_limit; | ||
189 | |||
190 | /* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */ | ||
191 | switch (rtlefuse->eeprom_regulatory) { | ||
192 | case 0: | ||
193 | /* Realtek better performance increase power diff | ||
194 | * defined by Realtek for large power */ | ||
195 | chnlgroup = 0; | ||
196 | |||
197 | writeval = rtlphy->mcs_txpwrlevel_origoffset | ||
198 | [chnlgroup][index] + | ||
199 | ((index < 2) ? pwrbase0 : pwrbase1); | ||
200 | |||
201 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
202 | ("RTK better performance, " | ||
203 | "writeval = 0x%x\n", writeval)); | ||
204 | break; | ||
205 | case 1: | ||
206 | /* Realtek regulatory increase power diff defined | ||
207 | * by Realtek for regulatory */ | ||
208 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
209 | writeval = ((index < 2) ? pwrbase0 : pwrbase1); | ||
210 | |||
211 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
212 | ("Realtek regulatory, " | ||
213 | "40MHz, writeval = 0x%x\n", writeval)); | ||
214 | } else { | ||
215 | if (rtlphy->pwrgroup_cnt == 1) | ||
216 | chnlgroup = 0; | ||
217 | |||
218 | if (rtlphy->pwrgroup_cnt >= 3) { | ||
219 | if (chnl <= 3) | ||
220 | chnlgroup = 0; | ||
221 | else if (chnl >= 4 && chnl <= 8) | ||
222 | chnlgroup = 1; | ||
223 | else if (chnl > 8) | ||
224 | chnlgroup = 2; | ||
225 | if (rtlphy->pwrgroup_cnt == 4) | ||
226 | chnlgroup++; | ||
227 | } | ||
228 | |||
229 | writeval = rtlphy->mcs_txpwrlevel_origoffset | ||
230 | [chnlgroup][index] | ||
231 | + ((index < 2) ? | ||
232 | pwrbase0 : pwrbase1); | ||
233 | |||
234 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
235 | ("Realtek regulatory, " | ||
236 | "20MHz, writeval = 0x%x\n", writeval)); | ||
237 | } | ||
238 | break; | ||
239 | case 2: | ||
240 | /* Better regulatory don't increase any power diff */ | ||
241 | writeval = ((index < 2) ? pwrbase0 : pwrbase1); | ||
242 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
243 | ("Better regulatory, " | ||
244 | "writeval = 0x%x\n", writeval)); | ||
245 | break; | ||
246 | case 3: | ||
247 | /* Customer defined power diff. increase power diff | ||
248 | defined by customer. */ | ||
249 | chnlgroup = 0; | ||
250 | |||
251 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
252 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
253 | ("customer's limit, 40MHz = 0x%x\n", | ||
254 | rtlefuse->pwrgroup_ht40 | ||
255 | [RF90_PATH_A][chnl - 1])); | ||
256 | } else { | ||
257 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
258 | ("customer's limit, 20MHz = 0x%x\n", | ||
259 | rtlefuse->pwrgroup_ht20 | ||
260 | [RF90_PATH_A][chnl - 1])); | ||
261 | } | ||
262 | |||
263 | for (i = 0; i < 4; i++) { | ||
264 | pwrdiff_limit[i] = | ||
265 | (u8)((rtlphy->mcs_txpwrlevel_origoffset | ||
266 | [chnlgroup][index] & (0x7f << (i * 8))) | ||
267 | >> (i * 8)); | ||
268 | |||
269 | if (rtlphy->current_chan_bw == | ||
270 | HT_CHANNEL_WIDTH_20_40) { | ||
271 | if (pwrdiff_limit[i] > | ||
272 | rtlefuse->pwrgroup_ht40 | ||
273 | [RF90_PATH_A][chnl - 1]) { | ||
274 | pwrdiff_limit[i] = | ||
275 | rtlefuse->pwrgroup_ht20 | ||
276 | [RF90_PATH_A][chnl - 1]; | ||
277 | } | ||
278 | } else { | ||
279 | if (pwrdiff_limit[i] > | ||
280 | rtlefuse->pwrgroup_ht20 | ||
281 | [RF90_PATH_A][chnl - 1]) { | ||
282 | pwrdiff_limit[i] = | ||
283 | rtlefuse->pwrgroup_ht20 | ||
284 | [RF90_PATH_A][chnl - 1]; | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | |||
289 | customer_limit = (pwrdiff_limit[3] << 24) | | ||
290 | (pwrdiff_limit[2] << 16) | | ||
291 | (pwrdiff_limit[1] << 8) | | ||
292 | (pwrdiff_limit[0]); | ||
293 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
294 | ("Customer's limit = 0x%x\n", | ||
295 | customer_limit)); | ||
296 | |||
297 | writeval = customer_limit + ((index < 2) ? | ||
298 | pwrbase0 : pwrbase1); | ||
299 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
300 | ("Customer, writeval = " | ||
301 | "0x%x\n", writeval)); | ||
302 | break; | ||
303 | default: | ||
304 | chnlgroup = 0; | ||
305 | writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] + | ||
306 | ((index < 2) ? pwrbase0 : pwrbase1); | ||
307 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
308 | ("RTK better performance, " | ||
309 | "writeval = 0x%x\n", writeval)); | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | if (rtlpriv->dm.dynamic_txhighpower_lvl == TX_HIGH_PWR_LEVEL_LEVEL1) | ||
314 | writeval = 0x10101010; | ||
315 | else if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
316 | TX_HIGH_PWR_LEVEL_LEVEL2) | ||
317 | writeval = 0x0; | ||
318 | |||
319 | *p_outwrite_val = writeval; | ||
320 | |||
321 | } | ||
322 | |||
323 | static void _rtl92s_write_ofdm_powerreg(struct ieee80211_hw *hw, | ||
324 | u8 index, u32 val) | ||
325 | { | ||
326 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
327 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
328 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
329 | u16 regoffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; | ||
330 | u8 i, rfa_pwr[4]; | ||
331 | u8 rfa_lower_bound = 0, rfa_upper_bound = 0, rf_pwr_diff = 0; | ||
332 | u32 writeval = val; | ||
333 | |||
334 | /* If path A and Path B coexist, we must limit Path A tx power. | ||
335 | * Protect Path B pwr over or under flow. We need to calculate | ||
336 | * upper and lower bound of path A tx power. */ | ||
337 | if (rtlphy->rf_type == RF_2T2R) { | ||
338 | rf_pwr_diff = rtlefuse->antenna_txpwdiff[0]; | ||
339 | |||
340 | /* Diff=-8~-1 */ | ||
341 | if (rf_pwr_diff >= 8) { | ||
342 | /* Prevent underflow!! */ | ||
343 | rfa_lower_bound = 0x10 - rf_pwr_diff; | ||
344 | /* if (rf_pwr_diff >= 0) Diff = 0-7 */ | ||
345 | } else { | ||
346 | rfa_upper_bound = RF6052_MAX_TX_PWR - rf_pwr_diff; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | for (i = 0; i < 4; i++) { | ||
351 | rfa_pwr[i] = (u8)((writeval & (0x7f << (i * 8))) >> (i * 8)); | ||
352 | if (rfa_pwr[i] > RF6052_MAX_TX_PWR) | ||
353 | rfa_pwr[i] = RF6052_MAX_TX_PWR; | ||
354 | |||
355 | /* If path A and Path B coexist, we must limit Path A tx power. | ||
356 | * Protect Path B pwr over or under flow. We need to calculate | ||
357 | * upper and lower bound of path A tx power. */ | ||
358 | if (rtlphy->rf_type == RF_2T2R) { | ||
359 | /* Diff=-8~-1 */ | ||
360 | if (rf_pwr_diff >= 8) { | ||
361 | /* Prevent underflow!! */ | ||
362 | if (rfa_pwr[i] < rfa_lower_bound) | ||
363 | rfa_pwr[i] = rfa_lower_bound; | ||
364 | /* Diff = 0-7 */ | ||
365 | } else if (rf_pwr_diff >= 1) { | ||
366 | /* Prevent overflow */ | ||
367 | if (rfa_pwr[i] > rfa_upper_bound) | ||
368 | rfa_pwr[i] = rfa_upper_bound; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | } | ||
373 | |||
374 | writeval = (rfa_pwr[3] << 24) | (rfa_pwr[2] << 16) | (rfa_pwr[1] << 8) | | ||
375 | rfa_pwr[0]; | ||
376 | |||
377 | rtl_set_bbreg(hw, regoffset[index], 0x7f7f7f7f, writeval); | ||
378 | } | ||
379 | |||
380 | void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw, | ||
381 | u8 *p_pwrlevel, u8 chnl) | ||
382 | { | ||
383 | u32 writeval, pwrbase0, pwrbase1; | ||
384 | u8 index = 0; | ||
385 | u8 finalpwr_idx[4]; | ||
386 | |||
387 | _rtl92s_get_powerbase(hw, p_pwrlevel, chnl, &pwrbase0, &pwrbase1, | ||
388 | &finalpwr_idx[0]); | ||
389 | _rtl92s_set_antennadiff(hw, &finalpwr_idx[0]); | ||
390 | |||
391 | for (index = 0; index < 6; index++) { | ||
392 | _rtl92s_get_txpower_writeval_byregulatory(hw, chnl, index, | ||
393 | pwrbase0, pwrbase1, &writeval); | ||
394 | |||
395 | _rtl92s_write_ofdm_powerreg(hw, index, writeval); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel) | ||
400 | { | ||
401 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
402 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
403 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
404 | u32 txagc = 0; | ||
405 | bool dont_inc_cck_or_turboscanoff = false; | ||
406 | |||
407 | if (((rtlefuse->eeprom_version >= 2) && | ||
408 | (rtlefuse->txpwr_safetyflag == 1)) || | ||
409 | ((rtlefuse->eeprom_version >= 2) && | ||
410 | (rtlefuse->eeprom_regulatory != 0))) | ||
411 | dont_inc_cck_or_turboscanoff = true; | ||
412 | |||
413 | if (mac->act_scanning == true) { | ||
414 | txagc = 0x3f; | ||
415 | if (dont_inc_cck_or_turboscanoff) | ||
416 | txagc = pwrlevel; | ||
417 | } else { | ||
418 | txagc = pwrlevel; | ||
419 | |||
420 | if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
421 | TX_HIGH_PWR_LEVEL_LEVEL1) | ||
422 | txagc = 0x10; | ||
423 | else if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
424 | TX_HIGH_PWR_LEVEL_LEVEL2) | ||
425 | txagc = 0x0; | ||
426 | } | ||
427 | |||
428 | if (txagc > RF6052_MAX_TX_PWR) | ||
429 | txagc = RF6052_MAX_TX_PWR; | ||
430 | |||
431 | rtl_set_bbreg(hw, RTXAGC_CCK_MCS32, BTX_AGCRATECCK, txagc); | ||
432 | |||
433 | } | ||
434 | |||
435 | bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) | ||
436 | { | ||
437 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
438 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
439 | u32 u4reg_val = 0; | ||
440 | u8 rfpath; | ||
441 | bool rtstatus = true; | ||
442 | struct bb_reg_def *pphyreg; | ||
443 | |||
444 | /* Initialize RF */ | ||
445 | for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { | ||
446 | |||
447 | pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
448 | |||
449 | /* Store original RFENV control type */ | ||
450 | switch (rfpath) { | ||
451 | case RF90_PATH_A: | ||
452 | case RF90_PATH_C: | ||
453 | u4reg_val = rtl92s_phy_query_bb_reg(hw, | ||
454 | pphyreg->rfintfs, | ||
455 | BRFSI_RFENV); | ||
456 | break; | ||
457 | case RF90_PATH_B: | ||
458 | case RF90_PATH_D: | ||
459 | u4reg_val = rtl92s_phy_query_bb_reg(hw, | ||
460 | pphyreg->rfintfs, | ||
461 | BRFSI_RFENV << 16); | ||
462 | break; | ||
463 | } | ||
464 | |||
465 | /* Set RF_ENV enable */ | ||
466 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfe, | ||
467 | BRFSI_RFENV << 16, 0x1); | ||
468 | |||
469 | /* Set RF_ENV output high */ | ||
470 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); | ||
471 | |||
472 | /* Set bit number of Address and Data for RF register */ | ||
473 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2, | ||
474 | B3WIRE_ADDRESSLENGTH, 0x0); | ||
475 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2, | ||
476 | B3WIRE_DATALENGTH, 0x0); | ||
477 | |||
478 | /* Initialize RF fom connfiguration file */ | ||
479 | switch (rfpath) { | ||
480 | case RF90_PATH_A: | ||
481 | rtstatus = rtl92s_phy_config_rf(hw, | ||
482 | (enum radio_path)rfpath); | ||
483 | break; | ||
484 | case RF90_PATH_B: | ||
485 | rtstatus = rtl92s_phy_config_rf(hw, | ||
486 | (enum radio_path)rfpath); | ||
487 | break; | ||
488 | case RF90_PATH_C: | ||
489 | break; | ||
490 | case RF90_PATH_D: | ||
491 | break; | ||
492 | } | ||
493 | |||
494 | /* Restore RFENV control type */ | ||
495 | switch (rfpath) { | ||
496 | case RF90_PATH_A: | ||
497 | case RF90_PATH_C: | ||
498 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, BRFSI_RFENV, | ||
499 | u4reg_val); | ||
500 | break; | ||
501 | case RF90_PATH_B: | ||
502 | case RF90_PATH_D: | ||
503 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, | ||
504 | BRFSI_RFENV << 16, | ||
505 | u4reg_val); | ||
506 | break; | ||
507 | } | ||
508 | |||
509 | if (rtstatus != true) { | ||
510 | printk(KERN_ERR "Radio[%d] Fail!!", rfpath); | ||
511 | goto fail; | ||
512 | } | ||
513 | |||
514 | } | ||
515 | |||
516 | return rtstatus; | ||
517 | |||
518 | fail: | ||
519 | return rtstatus; | ||
520 | } | ||
521 | |||
522 | void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) | ||
523 | { | ||
524 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
525 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
526 | |||
527 | switch (bandwidth) { | ||
528 | case HT_CHANNEL_WIDTH_20: | ||
529 | rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & | ||
530 | 0xfffff3ff) | 0x0400); | ||
531 | rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, | ||
532 | rtlphy->rfreg_chnlval[0]); | ||
533 | break; | ||
534 | case HT_CHANNEL_WIDTH_20_40: | ||
535 | rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & | ||
536 | 0xfffff3ff)); | ||
537 | rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, | ||
538 | rtlphy->rfreg_chnlval[0]); | ||
539 | break; | ||
540 | default: | ||
541 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
542 | ("unknown bandwidth: %#X\n", | ||
543 | bandwidth)); | ||
544 | break; | ||
545 | } | ||
546 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h new file mode 100644 index 000000000000..3843baa1a874 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __INC_RTL92S_RF_H | ||
30 | #define __INC_RTL92S_RF_H | ||
31 | |||
32 | #define RF6052_MAX_TX_PWR 0x3F | ||
33 | |||
34 | void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | ||
35 | u8 bandwidth); | ||
36 | bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) ; | ||
37 | void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, | ||
38 | u8 powerlevel); | ||
39 | void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw, | ||
40 | u8 *p_pwrlevel, u8 chnl); | ||
41 | |||
42 | #endif | ||
43 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c new file mode 100644 index 000000000000..1c6cb1d7d660 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c | |||
@@ -0,0 +1,423 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include <linux/vmalloc.h> | ||
31 | |||
32 | #include "../wifi.h" | ||
33 | #include "../core.h" | ||
34 | #include "../pci.h" | ||
35 | #include "reg.h" | ||
36 | #include "def.h" | ||
37 | #include "phy.h" | ||
38 | #include "dm.h" | ||
39 | #include "fw.h" | ||
40 | #include "hw.h" | ||
41 | #include "sw.h" | ||
42 | #include "trx.h" | ||
43 | #include "led.h" | ||
44 | |||
45 | static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) | ||
46 | { | ||
47 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
48 | |||
49 | /*close ASPM for AMD defaultly */ | ||
50 | rtlpci->const_amdpci_aspm = 0; | ||
51 | |||
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 = 2; | ||
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 | /* | ||
70 | * In Hw/Sw Radio Off situation. | ||
71 | * 0 - Default, | ||
72 | * 1 - From ASPM setting without low Mac Pwr, | ||
73 | * 2 - From ASPM setting with low Mac Pwr, | ||
74 | * 3 - Bus D3 | ||
75 | * set default to RTL8192CE:0 RTL8192SE:2 | ||
76 | */ | ||
77 | rtlpci->const_hwsw_rfoff_d3 = 2; | ||
78 | |||
79 | /* | ||
80 | * This setting works for those device with | ||
81 | * backdoor ASPM setting such as EPHY setting. | ||
82 | * 0 - Not support ASPM, | ||
83 | * 1 - Support ASPM, | ||
84 | * 2 - According to chipset. | ||
85 | */ | ||
86 | rtlpci->const_support_pciaspm = 2; | ||
87 | } | ||
88 | |||
89 | static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) | ||
90 | { | ||
91 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
92 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
93 | const struct firmware *firmware; | ||
94 | struct rt_firmware *pfirmware = NULL; | ||
95 | int err = 0; | ||
96 | u16 earlyrxthreshold = 7; | ||
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 | rtlpriv->dm.useramask = true; | ||
103 | |||
104 | /* compatible 5G band 91se just 2.4G band & smsp */ | ||
105 | rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; | ||
106 | rtlpriv->rtlhal.bandset = BAND_ON_2_4G; | ||
107 | rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; | ||
108 | |||
109 | rtlpci->transmit_config = 0; | ||
110 | |||
111 | rtlpci->receive_config = | ||
112 | RCR_APPFCS | | ||
113 | RCR_APWRMGT | | ||
114 | /*RCR_ADD3 |*/ | ||
115 | RCR_AMF | | ||
116 | RCR_ADF | | ||
117 | RCR_APP_MIC | | ||
118 | RCR_APP_ICV | | ||
119 | RCR_AICV | | ||
120 | /* Accept ICV error, CRC32 Error */ | ||
121 | RCR_ACRC32 | | ||
122 | RCR_AB | | ||
123 | /* Accept Broadcast, Multicast */ | ||
124 | RCR_AM | | ||
125 | /* Accept Physical match */ | ||
126 | RCR_APM | | ||
127 | /* Accept Destination Address packets */ | ||
128 | /*RCR_AAP |*/ | ||
129 | RCR_APP_PHYST_STAFF | | ||
130 | /* Accept PHY status */ | ||
131 | RCR_APP_PHYST_RXFF | | ||
132 | (earlyrxthreshold << RCR_FIFO_OFFSET); | ||
133 | |||
134 | rtlpci->irq_mask[0] = (u32) | ||
135 | (IMR_ROK | | ||
136 | IMR_VODOK | | ||
137 | IMR_VIDOK | | ||
138 | IMR_BEDOK | | ||
139 | IMR_BKDOK | | ||
140 | IMR_HCCADOK | | ||
141 | IMR_MGNTDOK | | ||
142 | IMR_COMDOK | | ||
143 | IMR_HIGHDOK | | ||
144 | IMR_BDOK | | ||
145 | IMR_RXCMDOK | | ||
146 | /*IMR_TIMEOUT0 |*/ | ||
147 | IMR_RDU | | ||
148 | IMR_RXFOVW | | ||
149 | IMR_BCNINT | ||
150 | /*| IMR_TXFOVW*/ | ||
151 | /*| IMR_TBDOK | | ||
152 | IMR_TBDER*/); | ||
153 | |||
154 | rtlpci->irq_mask[1] = (u32) 0; | ||
155 | |||
156 | rtlpci->shortretry_limit = 0x30; | ||
157 | rtlpci->longretry_limit = 0x30; | ||
158 | |||
159 | rtlpci->first_init = true; | ||
160 | |||
161 | /* for LPS & IPS */ | ||
162 | rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; | ||
163 | rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; | ||
164 | rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; | ||
165 | rtlpriv->psc.reg_fwctrl_lps = 3; | ||
166 | rtlpriv->psc.reg_max_lps_awakeintvl = 5; | ||
167 | /* for ASPM, you can close aspm through | ||
168 | * set const_support_pciaspm = 0 */ | ||
169 | rtl92s_init_aspm_vars(hw); | ||
170 | |||
171 | if (rtlpriv->psc.reg_fwctrl_lps == 1) | ||
172 | rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; | ||
173 | else if (rtlpriv->psc.reg_fwctrl_lps == 2) | ||
174 | rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; | ||
175 | else if (rtlpriv->psc.reg_fwctrl_lps == 3) | ||
176 | rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; | ||
177 | |||
178 | /* for firmware buf */ | ||
179 | rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware)); | ||
180 | if (!rtlpriv->rtlhal.pfirmware) { | ||
181 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
182 | ("Can't alloc buffer for fw.\n")); | ||
183 | return 1; | ||
184 | } | ||
185 | |||
186 | printk(KERN_INFO "rtl8192se: Driver for Realtek RTL8192SE/RTL8191SE\n" | ||
187 | " Loading firmware %s\n", rtlpriv->cfg->fw_name); | ||
188 | /* request fw */ | ||
189 | err = request_firmware(&firmware, rtlpriv->cfg->fw_name, | ||
190 | rtlpriv->io.dev); | ||
191 | if (err) { | ||
192 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
193 | ("Failed to request firmware!\n")); | ||
194 | return 1; | ||
195 | } | ||
196 | if (firmware->size > sizeof(struct rt_firmware)) { | ||
197 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
198 | ("Firmware is too big!\n")); | ||
199 | release_firmware(firmware); | ||
200 | return 1; | ||
201 | } | ||
202 | |||
203 | pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; | ||
204 | memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); | ||
205 | pfirmware->sz_fw_tmpbufferlen = firmware->size; | ||
206 | release_firmware(firmware); | ||
207 | |||
208 | return err; | ||
209 | } | ||
210 | |||
211 | static void rtl92s_deinit_sw_vars(struct ieee80211_hw *hw) | ||
212 | { | ||
213 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
214 | |||
215 | if (rtlpriv->rtlhal.pfirmware) { | ||
216 | vfree(rtlpriv->rtlhal.pfirmware); | ||
217 | rtlpriv->rtlhal.pfirmware = NULL; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | static struct rtl_hal_ops rtl8192se_hal_ops = { | ||
222 | .init_sw_vars = rtl92s_init_sw_vars, | ||
223 | .deinit_sw_vars = rtl92s_deinit_sw_vars, | ||
224 | .read_eeprom_info = rtl92se_read_eeprom_info, | ||
225 | .interrupt_recognized = rtl92se_interrupt_recognized, | ||
226 | .hw_init = rtl92se_hw_init, | ||
227 | .hw_disable = rtl92se_card_disable, | ||
228 | .hw_suspend = rtl92se_suspend, | ||
229 | .hw_resume = rtl92se_resume, | ||
230 | .enable_interrupt = rtl92se_enable_interrupt, | ||
231 | .disable_interrupt = rtl92se_disable_interrupt, | ||
232 | .set_network_type = rtl92se_set_network_type, | ||
233 | .set_chk_bssid = rtl92se_set_check_bssid, | ||
234 | .set_qos = rtl92se_set_qos, | ||
235 | .set_bcn_reg = rtl92se_set_beacon_related_registers, | ||
236 | .set_bcn_intv = rtl92se_set_beacon_interval, | ||
237 | .update_interrupt_mask = rtl92se_update_interrupt_mask, | ||
238 | .get_hw_reg = rtl92se_get_hw_reg, | ||
239 | .set_hw_reg = rtl92se_set_hw_reg, | ||
240 | .update_rate_tbl = rtl92se_update_hal_rate_tbl, | ||
241 | .fill_tx_desc = rtl92se_tx_fill_desc, | ||
242 | .fill_tx_cmddesc = rtl92se_tx_fill_cmddesc, | ||
243 | .query_rx_desc = rtl92se_rx_query_desc, | ||
244 | .set_channel_access = rtl92se_update_channel_access_setting, | ||
245 | .radio_onoff_checking = rtl92se_gpio_radio_on_off_checking, | ||
246 | .set_bw_mode = rtl92s_phy_set_bw_mode, | ||
247 | .switch_channel = rtl92s_phy_sw_chnl, | ||
248 | .dm_watchdog = rtl92s_dm_watchdog, | ||
249 | .scan_operation_backup = rtl92s_phy_scan_operation_backup, | ||
250 | .set_rf_power_state = rtl92s_phy_set_rf_power_state, | ||
251 | .led_control = rtl92se_led_control, | ||
252 | .set_desc = rtl92se_set_desc, | ||
253 | .get_desc = rtl92se_get_desc, | ||
254 | .tx_polling = rtl92se_tx_polling, | ||
255 | .enable_hw_sec = rtl92se_enable_hw_security_config, | ||
256 | .set_key = rtl92se_set_key, | ||
257 | .init_sw_leds = rtl92se_init_sw_leds, | ||
258 | .get_bbreg = rtl92s_phy_query_bb_reg, | ||
259 | .set_bbreg = rtl92s_phy_set_bb_reg, | ||
260 | .get_rfreg = rtl92s_phy_query_rf_reg, | ||
261 | .set_rfreg = rtl92s_phy_set_rf_reg, | ||
262 | }; | ||
263 | |||
264 | static struct rtl_mod_params rtl92se_mod_params = { | ||
265 | .sw_crypto = false, | ||
266 | .inactiveps = true, | ||
267 | .swctrl_lps = true, | ||
268 | .fwctrl_lps = false, | ||
269 | }; | ||
270 | |||
271 | /* Because memory R/W bursting will cause system hang/crash | ||
272 | * for 92se, so we don't read back after every write action */ | ||
273 | static struct rtl_hal_cfg rtl92se_hal_cfg = { | ||
274 | .bar_id = 1, | ||
275 | .write_readback = false, | ||
276 | .name = "rtl92s_pci", | ||
277 | .fw_name = "rtlwifi/rtl8192sefw.bin", | ||
278 | .ops = &rtl8192se_hal_ops, | ||
279 | .mod_params = &rtl92se_mod_params, | ||
280 | |||
281 | .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, | ||
282 | .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, | ||
283 | .maps[SYS_CLK] = SYS_CLKR, | ||
284 | .maps[MAC_RCR_AM] = RCR_AM, | ||
285 | .maps[MAC_RCR_AB] = RCR_AB, | ||
286 | .maps[MAC_RCR_ACRC32] = RCR_ACRC32, | ||
287 | .maps[MAC_RCR_ACF] = RCR_ACF, | ||
288 | .maps[MAC_RCR_AAP] = RCR_AAP, | ||
289 | |||
290 | .maps[EFUSE_TEST] = REG_EFUSE_TEST, | ||
291 | .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, | ||
292 | .maps[EFUSE_CLK] = REG_EFUSE_CLK, | ||
293 | .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, | ||
294 | .maps[EFUSE_PWC_EV12V] = 0, /* nouse for 8192se */ | ||
295 | .maps[EFUSE_FEN_ELDR] = 0, /* nouse for 8192se */ | ||
296 | .maps[EFUSE_LOADER_CLK_EN] = 0,/* nouse for 8192se */ | ||
297 | .maps[EFUSE_ANA8M] = EFUSE_ANA8M, | ||
298 | .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE_92S, | ||
299 | .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, | ||
300 | .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, | ||
301 | |||
302 | .maps[RWCAM] = REG_RWCAM, | ||
303 | .maps[WCAMI] = REG_WCAMI, | ||
304 | .maps[RCAMO] = REG_RCAMO, | ||
305 | .maps[CAMDBG] = REG_CAMDBG, | ||
306 | .maps[SECR] = REG_SECR, | ||
307 | .maps[SEC_CAM_NONE] = CAM_NONE, | ||
308 | .maps[SEC_CAM_WEP40] = CAM_WEP40, | ||
309 | .maps[SEC_CAM_TKIP] = CAM_TKIP, | ||
310 | .maps[SEC_CAM_AES] = CAM_AES, | ||
311 | .maps[SEC_CAM_WEP104] = CAM_WEP104, | ||
312 | |||
313 | .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, | ||
314 | .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, | ||
315 | .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, | ||
316 | .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, | ||
317 | .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, | ||
318 | .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, | ||
319 | .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, | ||
320 | .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, | ||
321 | .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, | ||
322 | .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, | ||
323 | .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, | ||
324 | .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, | ||
325 | .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, | ||
326 | .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, | ||
327 | .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, | ||
328 | .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, | ||
329 | |||
330 | .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, | ||
331 | .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, | ||
332 | .maps[RTL_IMR_BcnInt] = IMR_BCNINT, | ||
333 | .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, | ||
334 | .maps[RTL_IMR_RDU] = IMR_RDU, | ||
335 | .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, | ||
336 | .maps[RTL_IMR_BDOK] = IMR_BDOK, | ||
337 | .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, | ||
338 | .maps[RTL_IMR_TBDER] = IMR_TBDER, | ||
339 | .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, | ||
340 | .maps[RTL_IMR_COMDOK] = IMR_COMDOK, | ||
341 | .maps[RTL_IMR_TBDOK] = IMR_TBDOK, | ||
342 | .maps[RTL_IMR_BKDOK] = IMR_BKDOK, | ||
343 | .maps[RTL_IMR_BEDOK] = IMR_BEDOK, | ||
344 | .maps[RTL_IMR_VIDOK] = IMR_VIDOK, | ||
345 | .maps[RTL_IMR_VODOK] = IMR_VODOK, | ||
346 | .maps[RTL_IMR_ROK] = IMR_ROK, | ||
347 | .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), | ||
348 | |||
349 | .maps[RTL_RC_CCK_RATE1M] = DESC92S_RATE1M, | ||
350 | .maps[RTL_RC_CCK_RATE2M] = DESC92S_RATE2M, | ||
351 | .maps[RTL_RC_CCK_RATE5_5M] = DESC92S_RATE5_5M, | ||
352 | .maps[RTL_RC_CCK_RATE11M] = DESC92S_RATE11M, | ||
353 | .maps[RTL_RC_OFDM_RATE6M] = DESC92S_RATE6M, | ||
354 | .maps[RTL_RC_OFDM_RATE9M] = DESC92S_RATE9M, | ||
355 | .maps[RTL_RC_OFDM_RATE12M] = DESC92S_RATE12M, | ||
356 | .maps[RTL_RC_OFDM_RATE18M] = DESC92S_RATE18M, | ||
357 | .maps[RTL_RC_OFDM_RATE24M] = DESC92S_RATE24M, | ||
358 | .maps[RTL_RC_OFDM_RATE36M] = DESC92S_RATE36M, | ||
359 | .maps[RTL_RC_OFDM_RATE48M] = DESC92S_RATE48M, | ||
360 | .maps[RTL_RC_OFDM_RATE54M] = DESC92S_RATE54M, | ||
361 | |||
362 | .maps[RTL_RC_HT_RATEMCS7] = DESC92S_RATEMCS7, | ||
363 | .maps[RTL_RC_HT_RATEMCS15] = DESC92S_RATEMCS15, | ||
364 | }; | ||
365 | |||
366 | static struct pci_device_id rtl92se_pci_ids[] __devinitdata = { | ||
367 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)}, | ||
368 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)}, | ||
369 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)}, | ||
370 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8173, rtl92se_hal_cfg)}, | ||
371 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8174, rtl92se_hal_cfg)}, | ||
372 | {}, | ||
373 | }; | ||
374 | |||
375 | MODULE_DEVICE_TABLE(pci, rtl92se_pci_ids); | ||
376 | |||
377 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); | ||
378 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | ||
379 | MODULE_LICENSE("GPL"); | ||
380 | MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless"); | ||
381 | MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin"); | ||
382 | |||
383 | module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444); | ||
384 | module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444); | ||
385 | module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444); | ||
386 | module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444); | ||
387 | MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); | ||
388 | MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); | ||
389 | MODULE_PARM_DESC(swlps, "using linked sw control power save (default 1 is " | ||
390 | "open)\n"); | ||
391 | |||
392 | |||
393 | static struct pci_driver rtl92se_driver = { | ||
394 | .name = KBUILD_MODNAME, | ||
395 | .id_table = rtl92se_pci_ids, | ||
396 | .probe = rtl_pci_probe, | ||
397 | .remove = rtl_pci_disconnect, | ||
398 | |||
399 | #ifdef CONFIG_PM | ||
400 | .suspend = rtl_pci_suspend, | ||
401 | .resume = rtl_pci_resume, | ||
402 | #endif | ||
403 | |||
404 | }; | ||
405 | |||
406 | static int __init rtl92se_module_init(void) | ||
407 | { | ||
408 | int ret = 0; | ||
409 | |||
410 | ret = pci_register_driver(&rtl92se_driver); | ||
411 | if (ret) | ||
412 | RT_ASSERT(false, (": No device found\n")); | ||
413 | |||
414 | return ret; | ||
415 | } | ||
416 | |||
417 | static void __exit rtl92se_module_exit(void) | ||
418 | { | ||
419 | pci_unregister_driver(&rtl92se_driver); | ||
420 | } | ||
421 | |||
422 | module_init(rtl92se_module_init); | ||
423 | module_exit(rtl92se_module_exit); | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h new file mode 100644 index 000000000000..fc4eb285a0ac --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | *****************************************************************************/ | ||
27 | #ifndef __REALTEK_PCI92SE_SW_H__ | ||
28 | #define __REALTEK_PCI92SE_SW_H__ | ||
29 | |||
30 | #define EFUSE_MAX_SECTION 16 | ||
31 | |||
32 | int rtl92se_init_sw(struct ieee80211_hw *hw); | ||
33 | void rtl92se_deinit_sw(struct ieee80211_hw *hw); | ||
34 | void rtl92se_init_var_map(struct ieee80211_hw *hw); | ||
35 | |||
36 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/rtlwifi/rtl8192se/table.c new file mode 100644 index 000000000000..154185b3969d --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.c | |||
@@ -0,0 +1,634 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | * Created on 2010/ 5/18, 1:41 | ||
29 | *****************************************************************************/ | ||
30 | |||
31 | #include "table.h" | ||
32 | |||
33 | u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH] = { | ||
34 | 0x01c, 0x07000000, | ||
35 | 0x800, 0x00040000, | ||
36 | 0x804, 0x00008003, | ||
37 | 0x808, 0x0000fc00, | ||
38 | 0x80c, 0x0000000a, | ||
39 | 0x810, 0x10005088, | ||
40 | 0x814, 0x020c3d10, | ||
41 | 0x818, 0x00200185, | ||
42 | 0x81c, 0x00000000, | ||
43 | 0x820, 0x01000000, | ||
44 | 0x824, 0x00390004, | ||
45 | 0x828, 0x01000000, | ||
46 | 0x82c, 0x00390004, | ||
47 | 0x830, 0x00000004, | ||
48 | 0x834, 0x00690200, | ||
49 | 0x838, 0x00000004, | ||
50 | 0x83c, 0x00690200, | ||
51 | 0x840, 0x00010000, | ||
52 | 0x844, 0x00010000, | ||
53 | 0x848, 0x00000000, | ||
54 | 0x84c, 0x00000000, | ||
55 | 0x850, 0x00000000, | ||
56 | 0x854, 0x00000000, | ||
57 | 0x858, 0x48484848, | ||
58 | 0x85c, 0x65a965a9, | ||
59 | 0x860, 0x0f7f0130, | ||
60 | 0x864, 0x0f7f0130, | ||
61 | 0x868, 0x0f7f0130, | ||
62 | 0x86c, 0x0f7f0130, | ||
63 | 0x870, 0x03000700, | ||
64 | 0x874, 0x03000300, | ||
65 | 0x878, 0x00020002, | ||
66 | 0x87c, 0x004f0201, | ||
67 | 0x880, 0xa8300ac1, | ||
68 | 0x884, 0x00000058, | ||
69 | 0x888, 0x00000008, | ||
70 | 0x88c, 0x00000004, | ||
71 | 0x890, 0x00000000, | ||
72 | 0x894, 0xfffffffe, | ||
73 | 0x898, 0x40302010, | ||
74 | 0x89c, 0x00706050, | ||
75 | 0x8b0, 0x00000000, | ||
76 | 0x8e0, 0x00000000, | ||
77 | 0x8e4, 0x00000000, | ||
78 | 0xe00, 0x30333333, | ||
79 | 0xe04, 0x2a2d2e2f, | ||
80 | 0xe08, 0x00003232, | ||
81 | 0xe10, 0x30333333, | ||
82 | 0xe14, 0x2a2d2e2f, | ||
83 | 0xe18, 0x30333333, | ||
84 | 0xe1c, 0x2a2d2e2f, | ||
85 | 0xe30, 0x01007c00, | ||
86 | 0xe34, 0x01004800, | ||
87 | 0xe38, 0x1000dc1f, | ||
88 | 0xe3c, 0x10008c1f, | ||
89 | 0xe40, 0x021400a0, | ||
90 | 0xe44, 0x281600a0, | ||
91 | 0xe48, 0xf8000001, | ||
92 | 0xe4c, 0x00002910, | ||
93 | 0xe50, 0x01007c00, | ||
94 | 0xe54, 0x01004800, | ||
95 | 0xe58, 0x1000dc1f, | ||
96 | 0xe5c, 0x10008c1f, | ||
97 | 0xe60, 0x021400a0, | ||
98 | 0xe64, 0x281600a0, | ||
99 | 0xe6c, 0x00002910, | ||
100 | 0xe70, 0x31ed92fb, | ||
101 | 0xe74, 0x361536fb, | ||
102 | 0xe78, 0x361536fb, | ||
103 | 0xe7c, 0x361536fb, | ||
104 | 0xe80, 0x361536fb, | ||
105 | 0xe84, 0x000d92fb, | ||
106 | 0xe88, 0x000d92fb, | ||
107 | 0xe8c, 0x31ed92fb, | ||
108 | 0xed0, 0x31ed92fb, | ||
109 | 0xed4, 0x31ed92fb, | ||
110 | 0xed8, 0x000d92fb, | ||
111 | 0xedc, 0x000d92fb, | ||
112 | 0xee0, 0x000d92fb, | ||
113 | 0xee4, 0x015e5448, | ||
114 | 0xee8, 0x21555448, | ||
115 | 0x900, 0x00000000, | ||
116 | 0x904, 0x00000023, | ||
117 | 0x908, 0x00000000, | ||
118 | 0x90c, 0x01121313, | ||
119 | 0xa00, 0x00d047c8, | ||
120 | 0xa04, 0x80ff0008, | ||
121 | 0xa08, 0x8ccd8300, | ||
122 | 0xa0c, 0x2e62120f, | ||
123 | 0xa10, 0x9500bb78, | ||
124 | 0xa14, 0x11144028, | ||
125 | 0xa18, 0x00881117, | ||
126 | 0xa1c, 0x89140f00, | ||
127 | 0xa20, 0x1a1b0000, | ||
128 | 0xa24, 0x090e1317, | ||
129 | 0xa28, 0x00000204, | ||
130 | 0xa2c, 0x10d30000, | ||
131 | 0xc00, 0x40071d40, | ||
132 | 0xc04, 0x00a05633, | ||
133 | 0xc08, 0x000000e4, | ||
134 | 0xc0c, 0x6c6c6c6c, | ||
135 | 0xc10, 0x08800000, | ||
136 | 0xc14, 0x40000100, | ||
137 | 0xc18, 0x08000000, | ||
138 | 0xc1c, 0x40000100, | ||
139 | 0xc20, 0x08000000, | ||
140 | 0xc24, 0x40000100, | ||
141 | 0xc28, 0x08000000, | ||
142 | 0xc2c, 0x40000100, | ||
143 | 0xc30, 0x6de9ac44, | ||
144 | 0xc34, 0x469652cf, | ||
145 | 0xc38, 0x49795994, | ||
146 | 0xc3c, 0x0a979764, | ||
147 | 0xc40, 0x1f7c403f, | ||
148 | 0xc44, 0x000100b7, | ||
149 | 0xc48, 0xec020000, | ||
150 | 0xc4c, 0x007f037f, | ||
151 | 0xc50, 0x69543420, | ||
152 | 0xc54, 0x433c0094, | ||
153 | 0xc58, 0x69543420, | ||
154 | 0xc5c, 0x433c0094, | ||
155 | 0xc60, 0x69543420, | ||
156 | 0xc64, 0x433c0094, | ||
157 | 0xc68, 0x69543420, | ||
158 | 0xc6c, 0x433c0094, | ||
159 | 0xc70, 0x2c7f000d, | ||
160 | 0xc74, 0x0186155b, | ||
161 | 0xc78, 0x0000001f, | ||
162 | 0xc7c, 0x00b91612, | ||
163 | 0xc80, 0x40000100, | ||
164 | 0xc84, 0x20f60000, | ||
165 | 0xc88, 0x20000080, | ||
166 | 0xc8c, 0x20200000, | ||
167 | 0xc90, 0x40000100, | ||
168 | 0xc94, 0x00000000, | ||
169 | 0xc98, 0x40000100, | ||
170 | 0xc9c, 0x00000000, | ||
171 | 0xca0, 0x00492492, | ||
172 | 0xca4, 0x00000000, | ||
173 | 0xca8, 0x00000000, | ||
174 | 0xcac, 0x00000000, | ||
175 | 0xcb0, 0x00000000, | ||
176 | 0xcb4, 0x00000000, | ||
177 | 0xcb8, 0x00000000, | ||
178 | 0xcbc, 0x28000000, | ||
179 | 0xcc0, 0x00000000, | ||
180 | 0xcc4, 0x00000000, | ||
181 | 0xcc8, 0x00000000, | ||
182 | 0xccc, 0x00000000, | ||
183 | 0xcd0, 0x00000000, | ||
184 | 0xcd4, 0x00000000, | ||
185 | 0xcd8, 0x64b22427, | ||
186 | 0xcdc, 0x00766932, | ||
187 | 0xce0, 0x00222222, | ||
188 | 0xce4, 0x00000000, | ||
189 | 0xce8, 0x37644302, | ||
190 | 0xcec, 0x2f97d40c, | ||
191 | 0xd00, 0x00000750, | ||
192 | 0xd04, 0x00000403, | ||
193 | 0xd08, 0x0000907f, | ||
194 | 0xd0c, 0x00000001, | ||
195 | 0xd10, 0xa0633333, | ||
196 | 0xd14, 0x33333c63, | ||
197 | 0xd18, 0x6a8f5b6b, | ||
198 | 0xd1c, 0x00000000, | ||
199 | 0xd20, 0x00000000, | ||
200 | 0xd24, 0x00000000, | ||
201 | 0xd28, 0x00000000, | ||
202 | 0xd2c, 0xcc979975, | ||
203 | 0xd30, 0x00000000, | ||
204 | 0xd34, 0x00000000, | ||
205 | 0xd38, 0x00000000, | ||
206 | 0xd3c, 0x00027293, | ||
207 | 0xd40, 0x00000000, | ||
208 | 0xd44, 0x00000000, | ||
209 | 0xd48, 0x00000000, | ||
210 | 0xd50, 0x6437140a, | ||
211 | 0xd54, 0x024dbd02, | ||
212 | 0xd58, 0x00000000, | ||
213 | 0xd5c, 0x30032064, | ||
214 | 0xd60, 0x4653de68, | ||
215 | 0xd64, 0x00518a3c, | ||
216 | 0xd68, 0x00002101, | ||
217 | 0xf14, 0x00000003, | ||
218 | 0xf4c, 0x00000000, | ||
219 | 0xf00, 0x00000300, | ||
220 | }; | ||
221 | |||
222 | u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH] = { | ||
223 | 0x844, 0xffffffff, 0x00010000, | ||
224 | 0x804, 0x0000000f, 0x00000001, | ||
225 | 0x824, 0x00f0000f, 0x00300004, | ||
226 | 0x82c, 0x00f0000f, 0x00100002, | ||
227 | 0x870, 0x04000000, 0x00000001, | ||
228 | 0x864, 0x00000400, 0x00000000, | ||
229 | 0x878, 0x000f000f, 0x00000002, | ||
230 | 0xe74, 0x0f000000, 0x00000002, | ||
231 | 0xe78, 0x0f000000, 0x00000002, | ||
232 | 0xe7c, 0x0f000000, 0x00000002, | ||
233 | 0xe80, 0x0f000000, 0x00000002, | ||
234 | 0x90c, 0x000000ff, 0x00000011, | ||
235 | 0xc04, 0x000000ff, 0x00000011, | ||
236 | 0xd04, 0x0000000f, 0x00000001, | ||
237 | 0x1f4, 0xffff0000, 0x00007777, | ||
238 | 0x234, 0xf8000000, 0x0000000a, | ||
239 | }; | ||
240 | |||
241 | u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH] = { | ||
242 | 0x804, 0x0000000f, 0x00000003, | ||
243 | 0x824, 0x00f0000f, 0x00300004, | ||
244 | 0x82c, 0x00f0000f, 0x00300002, | ||
245 | 0x870, 0x04000000, 0x00000001, | ||
246 | 0x864, 0x00000400, 0x00000000, | ||
247 | 0x878, 0x000f000f, 0x00000002, | ||
248 | 0xe74, 0x0f000000, 0x00000002, | ||
249 | 0xe78, 0x0f000000, 0x00000002, | ||
250 | 0xe7c, 0x0f000000, 0x00000002, | ||
251 | 0xe80, 0x0f000000, 0x00000002, | ||
252 | 0x90c, 0x000000ff, 0x00000011, | ||
253 | 0xc04, 0x000000ff, 0x00000033, | ||
254 | 0xd04, 0x0000000f, 0x00000003, | ||
255 | 0x1f4, 0xffff0000, 0x00007777, | ||
256 | 0x234, 0xf8000000, 0x0000000a, | ||
257 | }; | ||
258 | |||
259 | u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH] = { | ||
260 | 0xe00, 0xffffffff, 0x06090909, | ||
261 | 0xe04, 0xffffffff, 0x00030406, | ||
262 | 0xe08, 0x0000ff00, 0x00000000, | ||
263 | 0xe10, 0xffffffff, 0x0a0c0d0e, | ||
264 | 0xe14, 0xffffffff, 0x04070809, | ||
265 | 0xe18, 0xffffffff, 0x0a0c0d0e, | ||
266 | 0xe1c, 0xffffffff, 0x04070809, | ||
267 | 0xe00, 0xffffffff, 0x04040404, | ||
268 | 0xe04, 0xffffffff, 0x00020204, | ||
269 | 0xe08, 0x0000ff00, 0x00000000, | ||
270 | 0xe10, 0xffffffff, 0x02040404, | ||
271 | 0xe14, 0xffffffff, 0x00000002, | ||
272 | 0xe18, 0xffffffff, 0x02040404, | ||
273 | 0xe1c, 0xffffffff, 0x00000002, | ||
274 | 0xe00, 0xffffffff, 0x04040404, | ||
275 | 0xe04, 0xffffffff, 0x00020204, | ||
276 | 0xe08, 0x0000ff00, 0x00000000, | ||
277 | 0xe10, 0xffffffff, 0x02040404, | ||
278 | 0xe14, 0xffffffff, 0x00000002, | ||
279 | 0xe18, 0xffffffff, 0x02040404, | ||
280 | 0xe1c, 0xffffffff, 0x00000002, | ||
281 | 0xe00, 0xffffffff, 0x02020202, | ||
282 | 0xe04, 0xffffffff, 0x00020202, | ||
283 | 0xe08, 0x0000ff00, 0x00000000, | ||
284 | 0xe10, 0xffffffff, 0x02020202, | ||
285 | 0xe14, 0xffffffff, 0x00000002, | ||
286 | 0xe18, 0xffffffff, 0x02020202, | ||
287 | 0xe1c, 0xffffffff, 0x00000002, | ||
288 | }; | ||
289 | |||
290 | u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH] = { | ||
291 | 0x000, 0x00030159, | ||
292 | 0x001, 0x00030250, | ||
293 | 0x002, 0x00010000, | ||
294 | 0x010, 0x0008000f, | ||
295 | 0x011, 0x000231fc, | ||
296 | 0x010, 0x000c000f, | ||
297 | 0x011, 0x0003f9f8, | ||
298 | 0x010, 0x0002000f, | ||
299 | 0x011, 0x00020101, | ||
300 | 0x014, 0x0001093e, | ||
301 | 0x014, 0x0009093e, | ||
302 | 0x015, 0x0000f8f4, | ||
303 | 0x017, 0x000f6500, | ||
304 | 0x01a, 0x00013056, | ||
305 | 0x01b, 0x00060000, | ||
306 | 0x01c, 0x00000300, | ||
307 | 0x01e, 0x00031059, | ||
308 | 0x021, 0x00054000, | ||
309 | 0x022, 0x0000083c, | ||
310 | 0x023, 0x00001558, | ||
311 | 0x024, 0x00000060, | ||
312 | 0x025, 0x00022583, | ||
313 | 0x026, 0x0000f200, | ||
314 | 0x027, 0x000eacf1, | ||
315 | 0x028, 0x0009bd54, | ||
316 | 0x029, 0x00004582, | ||
317 | 0x02a, 0x00000001, | ||
318 | 0x02b, 0x00021334, | ||
319 | 0x02a, 0x00000000, | ||
320 | 0x02b, 0x0000000a, | ||
321 | 0x02a, 0x00000001, | ||
322 | 0x02b, 0x00000808, | ||
323 | 0x02b, 0x00053333, | ||
324 | 0x02c, 0x0000000c, | ||
325 | 0x02a, 0x00000002, | ||
326 | 0x02b, 0x00000808, | ||
327 | 0x02b, 0x0005b333, | ||
328 | 0x02c, 0x0000000d, | ||
329 | 0x02a, 0x00000003, | ||
330 | 0x02b, 0x00000808, | ||
331 | 0x02b, 0x00063333, | ||
332 | 0x02c, 0x0000000d, | ||
333 | 0x02a, 0x00000004, | ||
334 | 0x02b, 0x00000808, | ||
335 | 0x02b, 0x0006b333, | ||
336 | 0x02c, 0x0000000d, | ||
337 | 0x02a, 0x00000005, | ||
338 | 0x02b, 0x00000709, | ||
339 | 0x02b, 0x00053333, | ||
340 | 0x02c, 0x0000000d, | ||
341 | 0x02a, 0x00000006, | ||
342 | 0x02b, 0x00000709, | ||
343 | 0x02b, 0x0005b333, | ||
344 | 0x02c, 0x0000000d, | ||
345 | 0x02a, 0x00000007, | ||
346 | 0x02b, 0x00000709, | ||
347 | 0x02b, 0x00063333, | ||
348 | 0x02c, 0x0000000d, | ||
349 | 0x02a, 0x00000008, | ||
350 | 0x02b, 0x00000709, | ||
351 | 0x02b, 0x0006b333, | ||
352 | 0x02c, 0x0000000d, | ||
353 | 0x02a, 0x00000009, | ||
354 | 0x02b, 0x0000060a, | ||
355 | 0x02b, 0x00053333, | ||
356 | 0x02c, 0x0000000d, | ||
357 | 0x02a, 0x0000000a, | ||
358 | 0x02b, 0x0000060a, | ||
359 | 0x02b, 0x0005b333, | ||
360 | 0x02c, 0x0000000d, | ||
361 | 0x02a, 0x0000000b, | ||
362 | 0x02b, 0x0000060a, | ||
363 | 0x02b, 0x00063333, | ||
364 | 0x02c, 0x0000000d, | ||
365 | 0x02a, 0x0000000c, | ||
366 | 0x02b, 0x0000060a, | ||
367 | 0x02b, 0x0006b333, | ||
368 | 0x02c, 0x0000000d, | ||
369 | 0x02a, 0x0000000d, | ||
370 | 0x02b, 0x0000050b, | ||
371 | 0x02b, 0x00053333, | ||
372 | 0x02c, 0x0000000d, | ||
373 | 0x02a, 0x0000000e, | ||
374 | 0x02b, 0x0000050b, | ||
375 | 0x02b, 0x00066623, | ||
376 | 0x02c, 0x0000001a, | ||
377 | 0x02a, 0x000e4000, | ||
378 | 0x030, 0x00020000, | ||
379 | 0x031, 0x000b9631, | ||
380 | 0x032, 0x0000130d, | ||
381 | 0x033, 0x00000187, | ||
382 | 0x013, 0x00019e6c, | ||
383 | 0x013, 0x00015e94, | ||
384 | 0x000, 0x00010159, | ||
385 | 0x018, 0x0000f401, | ||
386 | 0x0fe, 0x00000000, | ||
387 | 0x01e, 0x0003105b, | ||
388 | 0x0fe, 0x00000000, | ||
389 | 0x000, 0x00030159, | ||
390 | 0x010, 0x0004000f, | ||
391 | 0x011, 0x000203f9, | ||
392 | }; | ||
393 | |||
394 | u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH] = { | ||
395 | 0x000, 0x00030159, | ||
396 | 0x001, 0x00001041, | ||
397 | 0x002, 0x00011000, | ||
398 | 0x005, 0x00080fc0, | ||
399 | 0x007, 0x000fc803, | ||
400 | 0x013, 0x00017cb0, | ||
401 | 0x013, 0x00011cc0, | ||
402 | 0x013, 0x0000dc60, | ||
403 | 0x013, 0x00008c60, | ||
404 | 0x013, 0x00004450, | ||
405 | 0x013, 0x00000020, | ||
406 | }; | ||
407 | |||
408 | u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH] = { | ||
409 | 0x000, 0x00030159, | ||
410 | 0x001, 0x00001041, | ||
411 | 0x002, 0x00011000, | ||
412 | 0x005, 0x00080fc0, | ||
413 | 0x007, 0x000fc803, | ||
414 | }; | ||
415 | |||
416 | u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH] = { | ||
417 | 0x020, 0x00000035, | ||
418 | 0x048, 0x0000000e, | ||
419 | 0x049, 0x000000f0, | ||
420 | 0x04a, 0x00000077, | ||
421 | 0x04b, 0x00000083, | ||
422 | 0x0b5, 0x00000021, | ||
423 | 0x0dc, 0x000000ff, | ||
424 | 0x0dd, 0x000000ff, | ||
425 | 0x0de, 0x000000ff, | ||
426 | 0x0df, 0x000000ff, | ||
427 | 0x116, 0x00000000, | ||
428 | 0x117, 0x00000000, | ||
429 | 0x118, 0x00000000, | ||
430 | 0x119, 0x00000000, | ||
431 | 0x11a, 0x00000000, | ||
432 | 0x11b, 0x00000000, | ||
433 | 0x11c, 0x00000000, | ||
434 | 0x11d, 0x00000000, | ||
435 | 0x160, 0x0000000b, | ||
436 | 0x161, 0x0000000b, | ||
437 | 0x162, 0x0000000b, | ||
438 | 0x163, 0x0000000b, | ||
439 | 0x164, 0x0000000b, | ||
440 | 0x165, 0x0000000b, | ||
441 | 0x166, 0x0000000b, | ||
442 | 0x167, 0x0000000b, | ||
443 | 0x168, 0x0000000b, | ||
444 | 0x169, 0x0000000b, | ||
445 | 0x16a, 0x0000000b, | ||
446 | 0x16b, 0x0000000b, | ||
447 | 0x16c, 0x0000000b, | ||
448 | 0x16d, 0x0000000b, | ||
449 | 0x16e, 0x0000000b, | ||
450 | 0x16f, 0x0000000b, | ||
451 | 0x170, 0x0000000b, | ||
452 | 0x171, 0x0000000b, | ||
453 | 0x172, 0x0000000b, | ||
454 | 0x173, 0x0000000b, | ||
455 | 0x174, 0x0000000b, | ||
456 | 0x175, 0x0000000b, | ||
457 | 0x176, 0x0000000b, | ||
458 | 0x177, 0x0000000b, | ||
459 | 0x178, 0x0000000b, | ||
460 | 0x179, 0x0000000b, | ||
461 | 0x17a, 0x0000000b, | ||
462 | 0x17b, 0x0000000b, | ||
463 | 0x17c, 0x0000000b, | ||
464 | 0x17d, 0x0000000b, | ||
465 | 0x17e, 0x0000000b, | ||
466 | 0x17f, 0x0000000b, | ||
467 | 0x236, 0x0000000c, | ||
468 | 0x503, 0x00000022, | ||
469 | 0x560, 0x00000000, | ||
470 | }; | ||
471 | |||
472 | u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH] = { | ||
473 | 0xc78, 0x7f000001, | ||
474 | 0xc78, 0x7f010001, | ||
475 | 0xc78, 0x7e020001, | ||
476 | 0xc78, 0x7d030001, | ||
477 | 0xc78, 0x7c040001, | ||
478 | 0xc78, 0x7b050001, | ||
479 | 0xc78, 0x7a060001, | ||
480 | 0xc78, 0x79070001, | ||
481 | 0xc78, 0x78080001, | ||
482 | 0xc78, 0x77090001, | ||
483 | 0xc78, 0x760a0001, | ||
484 | 0xc78, 0x750b0001, | ||
485 | 0xc78, 0x740c0001, | ||
486 | 0xc78, 0x730d0001, | ||
487 | 0xc78, 0x720e0001, | ||
488 | 0xc78, 0x710f0001, | ||
489 | 0xc78, 0x70100001, | ||
490 | 0xc78, 0x6f110001, | ||
491 | 0xc78, 0x6f120001, | ||
492 | 0xc78, 0x6e130001, | ||
493 | 0xc78, 0x6d140001, | ||
494 | 0xc78, 0x6d150001, | ||
495 | 0xc78, 0x6c160001, | ||
496 | 0xc78, 0x6b170001, | ||
497 | 0xc78, 0x6a180001, | ||
498 | 0xc78, 0x6a190001, | ||
499 | 0xc78, 0x691a0001, | ||
500 | 0xc78, 0x681b0001, | ||
501 | 0xc78, 0x671c0001, | ||
502 | 0xc78, 0x661d0001, | ||
503 | 0xc78, 0x651e0001, | ||
504 | 0xc78, 0x641f0001, | ||
505 | 0xc78, 0x63200001, | ||
506 | 0xc78, 0x4c210001, | ||
507 | 0xc78, 0x4b220001, | ||
508 | 0xc78, 0x4a230001, | ||
509 | 0xc78, 0x49240001, | ||
510 | 0xc78, 0x48250001, | ||
511 | 0xc78, 0x47260001, | ||
512 | 0xc78, 0x46270001, | ||
513 | 0xc78, 0x45280001, | ||
514 | 0xc78, 0x44290001, | ||
515 | 0xc78, 0x2c2a0001, | ||
516 | 0xc78, 0x2b2b0001, | ||
517 | 0xc78, 0x2a2c0001, | ||
518 | 0xc78, 0x292d0001, | ||
519 | 0xc78, 0x282e0001, | ||
520 | 0xc78, 0x272f0001, | ||
521 | 0xc78, 0x26300001, | ||
522 | 0xc78, 0x25310001, | ||
523 | 0xc78, 0x24320001, | ||
524 | 0xc78, 0x23330001, | ||
525 | 0xc78, 0x22340001, | ||
526 | 0xc78, 0x09350001, | ||
527 | 0xc78, 0x08360001, | ||
528 | 0xc78, 0x07370001, | ||
529 | 0xc78, 0x06380001, | ||
530 | 0xc78, 0x05390001, | ||
531 | 0xc78, 0x043a0001, | ||
532 | 0xc78, 0x033b0001, | ||
533 | 0xc78, 0x023c0001, | ||
534 | 0xc78, 0x013d0001, | ||
535 | 0xc78, 0x003e0001, | ||
536 | 0xc78, 0x003f0001, | ||
537 | 0xc78, 0x7f400001, | ||
538 | 0xc78, 0x7f410001, | ||
539 | 0xc78, 0x7e420001, | ||
540 | 0xc78, 0x7d430001, | ||
541 | 0xc78, 0x7c440001, | ||
542 | 0xc78, 0x7b450001, | ||
543 | 0xc78, 0x7a460001, | ||
544 | 0xc78, 0x79470001, | ||
545 | 0xc78, 0x78480001, | ||
546 | 0xc78, 0x77490001, | ||
547 | 0xc78, 0x764a0001, | ||
548 | 0xc78, 0x754b0001, | ||
549 | 0xc78, 0x744c0001, | ||
550 | 0xc78, 0x734d0001, | ||
551 | 0xc78, 0x724e0001, | ||
552 | 0xc78, 0x714f0001, | ||
553 | 0xc78, 0x70500001, | ||
554 | 0xc78, 0x6f510001, | ||
555 | 0xc78, 0x6f520001, | ||
556 | 0xc78, 0x6e530001, | ||
557 | 0xc78, 0x6d540001, | ||
558 | 0xc78, 0x6d550001, | ||
559 | 0xc78, 0x6c560001, | ||
560 | 0xc78, 0x6b570001, | ||
561 | 0xc78, 0x6a580001, | ||
562 | 0xc78, 0x6a590001, | ||
563 | 0xc78, 0x695a0001, | ||
564 | 0xc78, 0x685b0001, | ||
565 | 0xc78, 0x675c0001, | ||
566 | 0xc78, 0x665d0001, | ||
567 | 0xc78, 0x655e0001, | ||
568 | 0xc78, 0x645f0001, | ||
569 | 0xc78, 0x63600001, | ||
570 | 0xc78, 0x4c610001, | ||
571 | 0xc78, 0x4b620001, | ||
572 | 0xc78, 0x4a630001, | ||
573 | 0xc78, 0x49640001, | ||
574 | 0xc78, 0x48650001, | ||
575 | 0xc78, 0x47660001, | ||
576 | 0xc78, 0x46670001, | ||
577 | 0xc78, 0x45680001, | ||
578 | 0xc78, 0x44690001, | ||
579 | 0xc78, 0x2c6a0001, | ||
580 | 0xc78, 0x2b6b0001, | ||
581 | 0xc78, 0x2a6c0001, | ||
582 | 0xc78, 0x296d0001, | ||
583 | 0xc78, 0x286e0001, | ||
584 | 0xc78, 0x276f0001, | ||
585 | 0xc78, 0x26700001, | ||
586 | 0xc78, 0x25710001, | ||
587 | 0xc78, 0x24720001, | ||
588 | 0xc78, 0x23730001, | ||
589 | 0xc78, 0x22740001, | ||
590 | 0xc78, 0x09750001, | ||
591 | 0xc78, 0x08760001, | ||
592 | 0xc78, 0x07770001, | ||
593 | 0xc78, 0x06780001, | ||
594 | 0xc78, 0x05790001, | ||
595 | 0xc78, 0x047a0001, | ||
596 | 0xc78, 0x037b0001, | ||
597 | 0xc78, 0x027c0001, | ||
598 | 0xc78, 0x017d0001, | ||
599 | 0xc78, 0x007e0001, | ||
600 | 0xc78, 0x007f0001, | ||
601 | 0xc78, 0x3000001e, | ||
602 | 0xc78, 0x3001001e, | ||
603 | 0xc78, 0x3002001e, | ||
604 | 0xc78, 0x3003001e, | ||
605 | 0xc78, 0x3004001e, | ||
606 | 0xc78, 0x3405001e, | ||
607 | 0xc78, 0x3806001e, | ||
608 | 0xc78, 0x3e07001e, | ||
609 | 0xc78, 0x3e08001e, | ||
610 | 0xc78, 0x4409001e, | ||
611 | 0xc78, 0x460a001e, | ||
612 | 0xc78, 0x480b001e, | ||
613 | 0xc78, 0x480c001e, | ||
614 | 0xc78, 0x4e0d001e, | ||
615 | 0xc78, 0x560e001e, | ||
616 | 0xc78, 0x5a0f001e, | ||
617 | 0xc78, 0x5e10001e, | ||
618 | 0xc78, 0x6211001e, | ||
619 | 0xc78, 0x6c12001e, | ||
620 | 0xc78, 0x7213001e, | ||
621 | 0xc78, 0x7214001e, | ||
622 | 0xc78, 0x7215001e, | ||
623 | 0xc78, 0x7216001e, | ||
624 | 0xc78, 0x7217001e, | ||
625 | 0xc78, 0x7218001e, | ||
626 | 0xc78, 0x7219001e, | ||
627 | 0xc78, 0x721a001e, | ||
628 | 0xc78, 0x721b001e, | ||
629 | 0xc78, 0x721c001e, | ||
630 | 0xc78, 0x721d001e, | ||
631 | 0xc78, 0x721e001e, | ||
632 | 0xc78, 0x721f001e, | ||
633 | }; | ||
634 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/rtlwifi/rtl8192se/table.h new file mode 100644 index 000000000000..b4ed6d951ebb --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /****************************************************************************** | ||
2 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. | ||
3 | * | ||
4 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
5 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
6 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
7 | * more details. | ||
8 | * | ||
9 | * You should have received a copy of the GNU General Public License along with | ||
10 | * this program; if not, write to the Free Software Foundation, Inc., | ||
11 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
12 | * | ||
13 | * The full GNU General Public License is included in this distribution in the | ||
14 | * file called LICENSE. | ||
15 | * | ||
16 | * Contact Information: | ||
17 | * wlanfae <wlanfae@realtek.com> | ||
18 | * | ||
19 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
20 | * | ||
21 | ******************************************************************************/ | ||
22 | #ifndef __INC_HAL8192SE_FW_IMG_H | ||
23 | #define __INC_HAL8192SE_FW_IMG_H | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | |||
27 | /*Created on 2010/ 4/12, 5:56*/ | ||
28 | |||
29 | #define PHY_REG_2T2RARRAYLENGTH 372 | ||
30 | extern u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH]; | ||
31 | #define PHY_CHANGETO_1T1RARRAYLENGTH 48 | ||
32 | extern u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH]; | ||
33 | #define PHY_CHANGETO_1T2RARRAYLENGTH 45 | ||
34 | extern u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH]; | ||
35 | #define PHY_REG_ARRAY_PGLENGTH 84 | ||
36 | extern u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH]; | ||
37 | #define RADIOA_1T_ARRAYLENGTH 202 | ||
38 | extern u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH]; | ||
39 | #define RADIOB_ARRAYLENGTH 22 | ||
40 | extern u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH]; | ||
41 | #define RADIOB_GM_ARRAYLENGTH 10 | ||
42 | extern u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH]; | ||
43 | #define MAC_2T_ARRAYLENGTH 106 | ||
44 | extern u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH]; | ||
45 | #define AGCTAB_ARRAYLENGTH 320 | ||
46 | extern u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH]; | ||
47 | |||
48 | #endif | ||
49 | |||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c new file mode 100644 index 000000000000..5cf442373d46 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
@@ -0,0 +1,976 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../pci.h" | ||
32 | #include "../base.h" | ||
33 | #include "reg.h" | ||
34 | #include "def.h" | ||
35 | #include "phy.h" | ||
36 | #include "fw.h" | ||
37 | #include "trx.h" | ||
38 | #include "led.h" | ||
39 | |||
40 | static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue) | ||
41 | { | ||
42 | __le16 fc = rtl_get_fc(skb); | ||
43 | |||
44 | if (unlikely(ieee80211_is_beacon(fc))) | ||
45 | return QSLT_BEACON; | ||
46 | if (ieee80211_is_mgmt(fc)) | ||
47 | return QSLT_MGNT; | ||
48 | if (ieee80211_is_nullfunc(fc)) | ||
49 | return QSLT_HIGH; | ||
50 | |||
51 | return skb->priority; | ||
52 | } | ||
53 | |||
54 | static int _rtl92se_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu) | ||
55 | { | ||
56 | int rate_idx = 0; | ||
57 | |||
58 | if (first_ampdu) { | ||
59 | if (false == isht) { | ||
60 | switch (desc_rate) { | ||
61 | case DESC92S_RATE1M: | ||
62 | rate_idx = 0; | ||
63 | break; | ||
64 | case DESC92S_RATE2M: | ||
65 | rate_idx = 1; | ||
66 | break; | ||
67 | case DESC92S_RATE5_5M: | ||
68 | rate_idx = 2; | ||
69 | break; | ||
70 | case DESC92S_RATE11M: | ||
71 | rate_idx = 3; | ||
72 | break; | ||
73 | case DESC92S_RATE6M: | ||
74 | rate_idx = 4; | ||
75 | break; | ||
76 | case DESC92S_RATE9M: | ||
77 | rate_idx = 5; | ||
78 | break; | ||
79 | case DESC92S_RATE12M: | ||
80 | rate_idx = 6; | ||
81 | break; | ||
82 | case DESC92S_RATE18M: | ||
83 | rate_idx = 7; | ||
84 | break; | ||
85 | case DESC92S_RATE24M: | ||
86 | rate_idx = 8; | ||
87 | break; | ||
88 | case DESC92S_RATE36M: | ||
89 | rate_idx = 9; | ||
90 | break; | ||
91 | case DESC92S_RATE48M: | ||
92 | rate_idx = 10; | ||
93 | break; | ||
94 | case DESC92S_RATE54M: | ||
95 | rate_idx = 11; | ||
96 | break; | ||
97 | default: | ||
98 | rate_idx = 0; | ||
99 | break; | ||
100 | } | ||
101 | } else { | ||
102 | rate_idx = 11; | ||
103 | } | ||
104 | |||
105 | return rate_idx; | ||
106 | } | ||
107 | |||
108 | switch (desc_rate) { | ||
109 | case DESC92S_RATE1M: | ||
110 | rate_idx = 0; | ||
111 | break; | ||
112 | case DESC92S_RATE2M: | ||
113 | rate_idx = 1; | ||
114 | break; | ||
115 | case DESC92S_RATE5_5M: | ||
116 | rate_idx = 2; | ||
117 | break; | ||
118 | case DESC92S_RATE11M: | ||
119 | rate_idx = 3; | ||
120 | break; | ||
121 | case DESC92S_RATE6M: | ||
122 | rate_idx = 4; | ||
123 | break; | ||
124 | case DESC92S_RATE9M: | ||
125 | rate_idx = 5; | ||
126 | break; | ||
127 | case DESC92S_RATE12M: | ||
128 | rate_idx = 6; | ||
129 | break; | ||
130 | case DESC92S_RATE18M: | ||
131 | rate_idx = 7; | ||
132 | break; | ||
133 | case DESC92S_RATE24M: | ||
134 | rate_idx = 8; | ||
135 | break; | ||
136 | case DESC92S_RATE36M: | ||
137 | rate_idx = 9; | ||
138 | break; | ||
139 | case DESC92S_RATE48M: | ||
140 | rate_idx = 10; | ||
141 | break; | ||
142 | case DESC92S_RATE54M: | ||
143 | rate_idx = 11; | ||
144 | break; | ||
145 | default: | ||
146 | rate_idx = 11; | ||
147 | break; | ||
148 | } | ||
149 | return rate_idx; | ||
150 | } | ||
151 | |||
152 | static u8 _rtl92s_query_rxpwrpercentage(char antpower) | ||
153 | { | ||
154 | if ((antpower <= -100) || (antpower >= 20)) | ||
155 | return 0; | ||
156 | else if (antpower >= 0) | ||
157 | return 100; | ||
158 | else | ||
159 | return 100 + antpower; | ||
160 | } | ||
161 | |||
162 | static u8 _rtl92s_evm_db_to_percentage(char value) | ||
163 | { | ||
164 | char ret_val; | ||
165 | ret_val = value; | ||
166 | |||
167 | if (ret_val >= 0) | ||
168 | ret_val = 0; | ||
169 | |||
170 | if (ret_val <= -33) | ||
171 | ret_val = -33; | ||
172 | |||
173 | ret_val = 0 - ret_val; | ||
174 | ret_val *= 3; | ||
175 | |||
176 | if (ret_val == 99) | ||
177 | ret_val = 100; | ||
178 | |||
179 | return ret_val; | ||
180 | } | ||
181 | |||
182 | static long _rtl92se_translate_todbm(struct ieee80211_hw *hw, | ||
183 | u8 signal_strength_index) | ||
184 | { | ||
185 | long signal_power; | ||
186 | |||
187 | signal_power = (long)((signal_strength_index + 1) >> 1); | ||
188 | signal_power -= 95; | ||
189 | return signal_power; | ||
190 | } | ||
191 | |||
192 | static long _rtl92se_signal_scale_mapping(struct ieee80211_hw *hw, | ||
193 | long currsig) | ||
194 | { | ||
195 | long retsig = 0; | ||
196 | |||
197 | /* Step 1. Scale mapping. */ | ||
198 | if (currsig > 47) | ||
199 | retsig = 100; | ||
200 | else if (currsig > 14 && currsig <= 47) | ||
201 | retsig = 100 - ((47 - currsig) * 3) / 2; | ||
202 | else if (currsig > 2 && currsig <= 14) | ||
203 | retsig = 48 - ((14 - currsig) * 15) / 7; | ||
204 | else if (currsig >= 0) | ||
205 | retsig = currsig * 9 + 1; | ||
206 | |||
207 | return retsig; | ||
208 | } | ||
209 | |||
210 | |||
211 | static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, | ||
212 | struct rtl_stats *pstats, u8 *pdesc, | ||
213 | struct rx_fwinfo *p_drvinfo, | ||
214 | bool packet_match_bssid, | ||
215 | bool packet_toself, | ||
216 | bool packet_beacon) | ||
217 | { | ||
218 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
219 | struct phy_sts_cck_8192s_t *cck_buf; | ||
220 | s8 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 in_powersavemode = false; | ||
225 | bool is_cck_rate; | ||
226 | |||
227 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); | ||
228 | pstats->packet_matchbssid = packet_match_bssid; | ||
229 | pstats->packet_toself = packet_toself; | ||
230 | pstats->is_cck = is_cck_rate; | ||
231 | pstats->packet_beacon = packet_beacon; | ||
232 | pstats->is_cck = is_cck_rate; | ||
233 | pstats->rx_mimo_signalquality[0] = -1; | ||
234 | pstats->rx_mimo_signalquality[1] = -1; | ||
235 | |||
236 | if (is_cck_rate) { | ||
237 | u8 report, cck_highpwr; | ||
238 | cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; | ||
239 | |||
240 | if (!in_powersavemode) | ||
241 | cck_highpwr = (u8) rtl_get_bbreg(hw, | ||
242 | RFPGA0_XA_HSSIPARAMETER2, | ||
243 | 0x200); | ||
244 | else | ||
245 | cck_highpwr = false; | ||
246 | |||
247 | if (!cck_highpwr) { | ||
248 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | ||
249 | report = cck_buf->cck_agc_rpt & 0xc0; | ||
250 | report = report >> 6; | ||
251 | switch (report) { | ||
252 | case 0x3: | ||
253 | rx_pwr_all = -40 - (cck_agc_rpt & 0x3e); | ||
254 | break; | ||
255 | case 0x2: | ||
256 | rx_pwr_all = -20 - (cck_agc_rpt & 0x3e); | ||
257 | break; | ||
258 | case 0x1: | ||
259 | rx_pwr_all = -2 - (cck_agc_rpt & 0x3e); | ||
260 | break; | ||
261 | case 0x0: | ||
262 | rx_pwr_all = 14 - (cck_agc_rpt & 0x3e); | ||
263 | break; | ||
264 | } | ||
265 | } else { | ||
266 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | ||
267 | report = p_drvinfo->cfosho[0] & 0x60; | ||
268 | report = report >> 5; | ||
269 | switch (report) { | ||
270 | case 0x3: | ||
271 | rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1); | ||
272 | break; | ||
273 | case 0x2: | ||
274 | rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1); | ||
275 | break; | ||
276 | case 0x1: | ||
277 | rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1); | ||
278 | break; | ||
279 | case 0x0: | ||
280 | rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1); | ||
281 | break; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all); | ||
286 | |||
287 | /* CCK gain is smaller than OFDM/MCS gain, */ | ||
288 | /* so we add gain diff by experiences, the val is 6 */ | ||
289 | pwdb_all += 6; | ||
290 | if (pwdb_all > 100) | ||
291 | pwdb_all = 100; | ||
292 | /* modify the offset to make the same gain index with OFDM. */ | ||
293 | if (pwdb_all > 34 && pwdb_all <= 42) | ||
294 | pwdb_all -= 2; | ||
295 | else if (pwdb_all > 26 && pwdb_all <= 34) | ||
296 | pwdb_all -= 6; | ||
297 | else if (pwdb_all > 14 && pwdb_all <= 26) | ||
298 | pwdb_all -= 8; | ||
299 | else if (pwdb_all > 4 && pwdb_all <= 14) | ||
300 | pwdb_all -= 4; | ||
301 | |||
302 | pstats->rx_pwdb_all = pwdb_all; | ||
303 | pstats->recvsignalpower = rx_pwr_all; | ||
304 | |||
305 | if (packet_match_bssid) { | ||
306 | u8 sq; | ||
307 | if (pstats->rx_pwdb_all > 40) { | ||
308 | sq = 100; | ||
309 | } else { | ||
310 | sq = cck_buf->sq_rpt; | ||
311 | if (sq > 64) | ||
312 | sq = 0; | ||
313 | else if (sq < 20) | ||
314 | sq = 100; | ||
315 | else | ||
316 | sq = ((64 - sq) * 100) / 44; | ||
317 | } | ||
318 | |||
319 | pstats->signalquality = sq; | ||
320 | pstats->rx_mimo_signalquality[0] = sq; | ||
321 | pstats->rx_mimo_signalquality[1] = -1; | ||
322 | } | ||
323 | } else { | ||
324 | rtlpriv->dm.rfpath_rxenable[0] = | ||
325 | rtlpriv->dm.rfpath_rxenable[1] = true; | ||
326 | for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { | ||
327 | if (rtlpriv->dm.rfpath_rxenable[i]) | ||
328 | rf_rx_num++; | ||
329 | |||
330 | rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & | ||
331 | 0x3f) * 2) - 110; | ||
332 | rssi = _rtl92s_query_rxpwrpercentage(rx_pwr[i]); | ||
333 | total_rssi += rssi; | ||
334 | rtlpriv->stats.rx_snr_db[i] = | ||
335 | (long)(p_drvinfo->rxsnr[i] / 2); | ||
336 | |||
337 | if (packet_match_bssid) | ||
338 | pstats->rx_mimo_signalstrength[i] = (u8) rssi; | ||
339 | } | ||
340 | |||
341 | rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; | ||
342 | pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all); | ||
343 | pstats->rx_pwdb_all = pwdb_all; | ||
344 | pstats->rxpower = rx_pwr_all; | ||
345 | pstats->recvsignalpower = rx_pwr_all; | ||
346 | |||
347 | if (GET_RX_STATUS_DESC_RX_HT(pdesc) && | ||
348 | GET_RX_STATUS_DESC_RX_MCS(pdesc) >= DESC92S_RATEMCS8 && | ||
349 | GET_RX_STATUS_DESC_RX_MCS(pdesc) <= DESC92S_RATEMCS15) | ||
350 | max_spatial_stream = 2; | ||
351 | else | ||
352 | max_spatial_stream = 1; | ||
353 | |||
354 | for (i = 0; i < max_spatial_stream; i++) { | ||
355 | evm = _rtl92s_evm_db_to_percentage(p_drvinfo->rxevm[i]); | ||
356 | |||
357 | if (packet_match_bssid) { | ||
358 | if (i == 0) | ||
359 | pstats->signalquality = (u8)(evm & | ||
360 | 0xff); | ||
361 | pstats->rx_mimo_signalquality[i] = | ||
362 | (u8) (evm & 0xff); | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | |||
367 | if (is_cck_rate) | ||
368 | pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw, | ||
369 | pwdb_all)); | ||
370 | else if (rf_rx_num != 0) | ||
371 | pstats->signalstrength = (u8) (_rtl92se_signal_scale_mapping(hw, | ||
372 | total_rssi /= rf_rx_num)); | ||
373 | } | ||
374 | |||
375 | static void _rtl92se_process_ui_rssi(struct ieee80211_hw *hw, | ||
376 | struct rtl_stats *pstats) | ||
377 | { | ||
378 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
379 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
380 | u8 rfpath; | ||
381 | u32 last_rssi, tmpval; | ||
382 | |||
383 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
384 | rtlpriv->stats.rssi_calculate_cnt++; | ||
385 | |||
386 | if (rtlpriv->stats.ui_rssi.total_num++ >= | ||
387 | PHY_RSSI_SLID_WIN_MAX) { | ||
388 | rtlpriv->stats.ui_rssi.total_num = | ||
389 | PHY_RSSI_SLID_WIN_MAX; | ||
390 | last_rssi = rtlpriv->stats.ui_rssi.elements[ | ||
391 | rtlpriv->stats.ui_rssi.index]; | ||
392 | rtlpriv->stats.ui_rssi.total_val -= last_rssi; | ||
393 | } | ||
394 | |||
395 | rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; | ||
396 | rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] | ||
397 | = pstats->signalstrength; | ||
398 | |||
399 | if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) | ||
400 | rtlpriv->stats.ui_rssi.index = 0; | ||
401 | |||
402 | tmpval = rtlpriv->stats.ui_rssi.total_val / | ||
403 | rtlpriv->stats.ui_rssi.total_num; | ||
404 | rtlpriv->stats.signal_strength = _rtl92se_translate_todbm(hw, | ||
405 | (u8) tmpval); | ||
406 | pstats->rssi = rtlpriv->stats.signal_strength; | ||
407 | } | ||
408 | |||
409 | if (!pstats->is_cck && pstats->packet_toself) { | ||
410 | for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; | ||
411 | rfpath++) { | ||
412 | if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { | ||
413 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
414 | pstats->rx_mimo_signalstrength[rfpath]; | ||
415 | |||
416 | } | ||
417 | |||
418 | if (pstats->rx_mimo_signalstrength[rfpath] > | ||
419 | rtlpriv->stats.rx_rssi_percentage[rfpath]) { | ||
420 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
421 | ((rtlpriv->stats.rx_rssi_percentage[rfpath] | ||
422 | * (RX_SMOOTH_FACTOR - 1)) + | ||
423 | (pstats->rx_mimo_signalstrength[rfpath])) / | ||
424 | (RX_SMOOTH_FACTOR); | ||
425 | |||
426 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
427 | rtlpriv->stats.rx_rssi_percentage[rfpath] | ||
428 | + 1; | ||
429 | } else { | ||
430 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
431 | ((rtlpriv->stats.rx_rssi_percentage[rfpath] | ||
432 | * (RX_SMOOTH_FACTOR - 1)) + | ||
433 | (pstats->rx_mimo_signalstrength[rfpath])) / | ||
434 | (RX_SMOOTH_FACTOR); | ||
435 | } | ||
436 | |||
437 | } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | static void _rtl92se_update_rxsignalstatistics(struct ieee80211_hw *hw, | ||
442 | struct rtl_stats *pstats) | ||
443 | { | ||
444 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
445 | int weighting = 0; | ||
446 | |||
447 | if (rtlpriv->stats.recv_signal_power == 0) | ||
448 | rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; | ||
449 | |||
450 | if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) | ||
451 | weighting = 5; | ||
452 | else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) | ||
453 | weighting = (-5); | ||
454 | |||
455 | rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * 5 | ||
456 | + pstats->recvsignalpower + | ||
457 | weighting) / 6; | ||
458 | } | ||
459 | |||
460 | static void _rtl92se_process_pwdb(struct ieee80211_hw *hw, | ||
461 | struct rtl_stats *pstats) | ||
462 | { | ||
463 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
464 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
465 | long undec_sm_pwdb = 0; | ||
466 | |||
467 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
468 | return; | ||
469 | } else { | ||
470 | undec_sm_pwdb = | ||
471 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
472 | } | ||
473 | |||
474 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
475 | if (undec_sm_pwdb < 0) | ||
476 | undec_sm_pwdb = pstats->rx_pwdb_all; | ||
477 | |||
478 | if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { | ||
479 | undec_sm_pwdb = | ||
480 | (((undec_sm_pwdb) * | ||
481 | (RX_SMOOTH_FACTOR - 1)) + | ||
482 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | ||
483 | |||
484 | undec_sm_pwdb = undec_sm_pwdb + 1; | ||
485 | } else { | ||
486 | undec_sm_pwdb = (((undec_sm_pwdb) * | ||
487 | (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / | ||
488 | (RX_SMOOTH_FACTOR); | ||
489 | } | ||
490 | |||
491 | rtlpriv->dm.undecorated_smoothed_pwdb = undec_sm_pwdb; | ||
492 | _rtl92se_update_rxsignalstatistics(hw, pstats); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | static void rtl_92s_process_streams(struct ieee80211_hw *hw, | ||
497 | struct rtl_stats *pstats) | ||
498 | { | ||
499 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
500 | u32 stream; | ||
501 | |||
502 | for (stream = 0; stream < 2; stream++) { | ||
503 | if (pstats->rx_mimo_signalquality[stream] != -1) { | ||
504 | if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { | ||
505 | rtlpriv->stats.rx_evm_percentage[stream] = | ||
506 | pstats->rx_mimo_signalquality[stream]; | ||
507 | } | ||
508 | |||
509 | rtlpriv->stats.rx_evm_percentage[stream] = | ||
510 | ((rtlpriv->stats.rx_evm_percentage[stream] * | ||
511 | (RX_SMOOTH_FACTOR - 1)) + | ||
512 | (pstats->rx_mimo_signalquality[stream] * | ||
513 | 1)) / (RX_SMOOTH_FACTOR); | ||
514 | } | ||
515 | } | ||
516 | } | ||
517 | |||
518 | static void _rtl92se_process_ui_link_quality(struct ieee80211_hw *hw, | ||
519 | struct rtl_stats *pstats) | ||
520 | { | ||
521 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
522 | u32 last_evm = 0, tmpval; | ||
523 | |||
524 | if (pstats->signalquality != 0) { | ||
525 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
526 | |||
527 | if (rtlpriv->stats.ui_link_quality.total_num++ >= | ||
528 | PHY_LINKQUALITY_SLID_WIN_MAX) { | ||
529 | rtlpriv->stats.ui_link_quality.total_num = | ||
530 | PHY_LINKQUALITY_SLID_WIN_MAX; | ||
531 | last_evm = | ||
532 | rtlpriv->stats.ui_link_quality.elements[ | ||
533 | rtlpriv->stats.ui_link_quality.index]; | ||
534 | rtlpriv->stats.ui_link_quality.total_val -= | ||
535 | last_evm; | ||
536 | } | ||
537 | |||
538 | rtlpriv->stats.ui_link_quality.total_val += | ||
539 | pstats->signalquality; | ||
540 | rtlpriv->stats.ui_link_quality.elements[ | ||
541 | rtlpriv->stats.ui_link_quality.index++] = | ||
542 | pstats->signalquality; | ||
543 | |||
544 | if (rtlpriv->stats.ui_link_quality.index >= | ||
545 | PHY_LINKQUALITY_SLID_WIN_MAX) | ||
546 | rtlpriv->stats.ui_link_quality.index = 0; | ||
547 | |||
548 | tmpval = rtlpriv->stats.ui_link_quality.total_val / | ||
549 | rtlpriv->stats.ui_link_quality.total_num; | ||
550 | rtlpriv->stats.signal_quality = tmpval; | ||
551 | |||
552 | rtlpriv->stats.last_sigstrength_inpercent = tmpval; | ||
553 | |||
554 | rtl_92s_process_streams(hw, pstats); | ||
555 | |||
556 | } | ||
557 | } | ||
558 | } | ||
559 | |||
560 | static void _rtl92se_process_phyinfo(struct ieee80211_hw *hw, | ||
561 | u8 *buffer, | ||
562 | struct rtl_stats *pcurrent_stats) | ||
563 | { | ||
564 | |||
565 | if (!pcurrent_stats->packet_matchbssid && | ||
566 | !pcurrent_stats->packet_beacon) | ||
567 | return; | ||
568 | |||
569 | _rtl92se_process_ui_rssi(hw, pcurrent_stats); | ||
570 | _rtl92se_process_pwdb(hw, pcurrent_stats); | ||
571 | _rtl92se_process_ui_link_quality(hw, pcurrent_stats); | ||
572 | } | ||
573 | |||
574 | static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, | ||
575 | struct sk_buff *skb, struct rtl_stats *pstats, | ||
576 | u8 *pdesc, struct rx_fwinfo *p_drvinfo) | ||
577 | { | ||
578 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
579 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
580 | |||
581 | struct ieee80211_hdr *hdr; | ||
582 | u8 *tmp_buf; | ||
583 | u8 *praddr; | ||
584 | u8 *psaddr; | ||
585 | __le16 fc; | ||
586 | u16 type, cfc; | ||
587 | bool packet_matchbssid, packet_toself, packet_beacon; | ||
588 | |||
589 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; | ||
590 | |||
591 | hdr = (struct ieee80211_hdr *)tmp_buf; | ||
592 | fc = hdr->frame_control; | ||
593 | cfc = le16_to_cpu(fc); | ||
594 | type = WLAN_FC_GET_TYPE(fc); | ||
595 | praddr = hdr->addr1; | ||
596 | psaddr = hdr->addr2; | ||
597 | |||
598 | packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && | ||
599 | (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? | ||
600 | hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ? | ||
601 | hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && | ||
602 | (!pstats->crc) && (!pstats->icv)); | ||
603 | |||
604 | packet_toself = packet_matchbssid && | ||
605 | (!compare_ether_addr(praddr, rtlefuse->dev_addr)); | ||
606 | |||
607 | if (ieee80211_is_beacon(fc)) | ||
608 | packet_beacon = true; | ||
609 | |||
610 | _rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, | ||
611 | packet_matchbssid, packet_toself, packet_beacon); | ||
612 | _rtl92se_process_phyinfo(hw, tmp_buf, pstats); | ||
613 | } | ||
614 | |||
615 | bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, | ||
616 | struct ieee80211_rx_status *rx_status, u8 *pdesc, | ||
617 | struct sk_buff *skb) | ||
618 | { | ||
619 | struct rx_fwinfo *p_drvinfo; | ||
620 | u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc); | ||
621 | |||
622 | stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc); | ||
623 | stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8; | ||
624 | stats->rx_bufshift = (u8)(GET_RX_STATUS_DESC_SHIFT(pdesc) & 0x03); | ||
625 | stats->icv = (u16)GET_RX_STATUS_DESC_ICV(pdesc); | ||
626 | stats->crc = (u16)GET_RX_STATUS_DESC_CRC32(pdesc); | ||
627 | stats->hwerror = (u16)(stats->crc | stats->icv); | ||
628 | stats->decrypted = !GET_RX_STATUS_DESC_SWDEC(pdesc); | ||
629 | |||
630 | stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc); | ||
631 | stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc); | ||
632 | stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1); | ||
633 | stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc); | ||
634 | stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc); | ||
635 | |||
636 | if (stats->hwerror) | ||
637 | return false; | ||
638 | |||
639 | rx_status->freq = hw->conf.channel->center_freq; | ||
640 | rx_status->band = hw->conf.channel->band; | ||
641 | |||
642 | if (GET_RX_STATUS_DESC_CRC32(pdesc)) | ||
643 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
644 | |||
645 | if (!GET_RX_STATUS_DESC_SWDEC(pdesc)) | ||
646 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
647 | |||
648 | if (GET_RX_STATUS_DESC_BW(pdesc)) | ||
649 | rx_status->flag |= RX_FLAG_40MHZ; | ||
650 | |||
651 | if (GET_RX_STATUS_DESC_RX_HT(pdesc)) | ||
652 | rx_status->flag |= RX_FLAG_HT; | ||
653 | |||
654 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | ||
655 | |||
656 | if (stats->decrypted) | ||
657 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
658 | |||
659 | rx_status->rate_idx = _rtl92se_rate_mapping((bool) | ||
660 | GET_RX_STATUS_DESC_RX_HT(pdesc), | ||
661 | (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc), | ||
662 | (bool)GET_RX_STATUS_DESC_PAGGR(pdesc)); | ||
663 | |||
664 | |||
665 | rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc); | ||
666 | if (phystatus == true) { | ||
667 | p_drvinfo = (struct rx_fwinfo *)(skb->data + | ||
668 | stats->rx_bufshift); | ||
669 | _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc, | ||
670 | p_drvinfo); | ||
671 | } | ||
672 | |||
673 | /*rx_status->qual = stats->signal; */ | ||
674 | rx_status->signal = stats->rssi + 10; | ||
675 | /*rx_status->noise = -stats->noise; */ | ||
676 | |||
677 | return true; | ||
678 | } | ||
679 | |||
680 | void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, | ||
681 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | ||
682 | struct ieee80211_tx_info *info, struct sk_buff *skb, | ||
683 | u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) | ||
684 | { | ||
685 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
686 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
687 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
688 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
689 | struct ieee80211_sta *sta = info->control.sta; | ||
690 | u8 *pdesc = (u8 *) pdesc_tx; | ||
691 | u16 seq_number; | ||
692 | __le16 fc = hdr->frame_control; | ||
693 | u8 reserved_macid = 0; | ||
694 | u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue); | ||
695 | bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG))); | ||
696 | bool lastseg = (!(hdr->frame_control & | ||
697 | cpu_to_le16(IEEE80211_FCTL_MOREFRAGS))); | ||
698 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, | ||
699 | PCI_DMA_TODEVICE); | ||
700 | u8 bw_40 = 0; | ||
701 | |||
702 | if (mac->opmode == NL80211_IFTYPE_STATION) { | ||
703 | bw_40 = mac->bw_40; | ||
704 | } else if (mac->opmode == NL80211_IFTYPE_AP || | ||
705 | mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
706 | if (sta) | ||
707 | bw_40 = sta->ht_cap.cap & | ||
708 | IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
709 | } | ||
710 | |||
711 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | ||
712 | |||
713 | rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); | ||
714 | |||
715 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S); | ||
716 | |||
717 | if (firstseg) { | ||
718 | if (rtlpriv->dm.useramask) { | ||
719 | /* set txdesc macId */ | ||
720 | if (ptcb_desc->mac_id < 32) { | ||
721 | SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id); | ||
722 | reserved_macid |= ptcb_desc->mac_id; | ||
723 | } | ||
724 | } | ||
725 | SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid); | ||
726 | |||
727 | SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >= | ||
728 | DESC92S_RATEMCS0) ? 1 : 0)); | ||
729 | |||
730 | if (rtlhal->version == VERSION_8192S_ACUT) { | ||
731 | if (ptcb_desc->hw_rate == DESC92S_RATE1M || | ||
732 | ptcb_desc->hw_rate == DESC92S_RATE2M || | ||
733 | ptcb_desc->hw_rate == DESC92S_RATE5_5M || | ||
734 | ptcb_desc->hw_rate == DESC92S_RATE11M) { | ||
735 | ptcb_desc->hw_rate = DESC92S_RATE12M; | ||
736 | } | ||
737 | } | ||
738 | |||
739 | SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate); | ||
740 | |||
741 | if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) | ||
742 | SET_TX_DESC_TX_SHORT(pdesc, 0); | ||
743 | |||
744 | /* Aggregation related */ | ||
745 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
746 | SET_TX_DESC_AGG_ENABLE(pdesc, 1); | ||
747 | |||
748 | /* For AMPDU, we must insert SSN into TX_DESC */ | ||
749 | SET_TX_DESC_SEQ(pdesc, seq_number); | ||
750 | |||
751 | /* Protection mode related */ | ||
752 | /* For 92S, if RTS/CTS are set, HW will execute RTS. */ | ||
753 | /* We choose only one protection mode to execute */ | ||
754 | SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable && | ||
755 | !ptcb_desc->cts_enable) ? 1 : 0)); | ||
756 | SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ? | ||
757 | 1 : 0)); | ||
758 | SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); | ||
759 | |||
760 | SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate); | ||
761 | SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0); | ||
762 | SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc); | ||
763 | SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= | ||
764 | DESC92S_RATE54M) ? | ||
765 | (ptcb_desc->rts_use_shortpreamble ? 1 : 0) | ||
766 | : (ptcb_desc->rts_use_shortgi ? 1 : 0))); | ||
767 | |||
768 | |||
769 | /* Set Bandwidth and sub-channel settings. */ | ||
770 | if (bw_40) { | ||
771 | if (ptcb_desc->packet_bw) { | ||
772 | SET_TX_DESC_TX_BANDWIDTH(pdesc, 1); | ||
773 | /* use duplicated mode */ | ||
774 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); | ||
775 | } else { | ||
776 | SET_TX_DESC_TX_BANDWIDTH(pdesc, 0); | ||
777 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, | ||
778 | mac->cur_40_prime_sc); | ||
779 | } | ||
780 | } else { | ||
781 | SET_TX_DESC_TX_BANDWIDTH(pdesc, 0); | ||
782 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); | ||
783 | } | ||
784 | |||
785 | /* 3 Fill necessary field in First Descriptor */ | ||
786 | /*DWORD 0*/ | ||
787 | SET_TX_DESC_LINIP(pdesc, 0); | ||
788 | SET_TX_DESC_OFFSET(pdesc, 32); | ||
789 | SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); | ||
790 | |||
791 | /*DWORD 1*/ | ||
792 | SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index); | ||
793 | |||
794 | /* Fill security related */ | ||
795 | if (info->control.hw_key) { | ||
796 | struct ieee80211_key_conf *keyconf; | ||
797 | |||
798 | keyconf = info->control.hw_key; | ||
799 | switch (keyconf->cipher) { | ||
800 | case WLAN_CIPHER_SUITE_WEP40: | ||
801 | case WLAN_CIPHER_SUITE_WEP104: | ||
802 | SET_TX_DESC_SEC_TYPE(pdesc, 0x1); | ||
803 | break; | ||
804 | case WLAN_CIPHER_SUITE_TKIP: | ||
805 | SET_TX_DESC_SEC_TYPE(pdesc, 0x2); | ||
806 | break; | ||
807 | case WLAN_CIPHER_SUITE_CCMP: | ||
808 | SET_TX_DESC_SEC_TYPE(pdesc, 0x3); | ||
809 | break; | ||
810 | default: | ||
811 | SET_TX_DESC_SEC_TYPE(pdesc, 0x0); | ||
812 | break; | ||
813 | |||
814 | } | ||
815 | } | ||
816 | |||
817 | /* Set Packet ID */ | ||
818 | SET_TX_DESC_PACKET_ID(pdesc, 0); | ||
819 | |||
820 | /* We will assign magement queue to BK. */ | ||
821 | SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); | ||
822 | |||
823 | /* Alwasy enable all rate fallback range */ | ||
824 | SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); | ||
825 | |||
826 | /* Fix: I don't kown why hw use 6.5M to tx when set it */ | ||
827 | SET_TX_DESC_USER_RATE(pdesc, | ||
828 | ptcb_desc->use_driver_rate ? 1 : 0); | ||
829 | |||
830 | /* Set NON_QOS bit. */ | ||
831 | if (!ieee80211_is_data_qos(fc)) | ||
832 | SET_TX_DESC_NON_QOS(pdesc, 1); | ||
833 | |||
834 | } | ||
835 | |||
836 | /* Fill fields that are required to be initialized | ||
837 | * in all of the descriptors */ | ||
838 | /*DWORD 0 */ | ||
839 | SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); | ||
840 | SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); | ||
841 | |||
842 | /* DWORD 7 */ | ||
843 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); | ||
844 | |||
845 | /* DOWRD 8 */ | ||
846 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); | ||
847 | |||
848 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); | ||
849 | } | ||
850 | |||
851 | void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, | ||
852 | bool firstseg, bool lastseg, struct sk_buff *skb) | ||
853 | { | ||
854 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
855 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
856 | struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb); | ||
857 | |||
858 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, | ||
859 | PCI_DMA_TODEVICE); | ||
860 | |||
861 | /* Clear all status */ | ||
862 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S); | ||
863 | |||
864 | /* This bit indicate this packet is used for FW download. */ | ||
865 | if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) { | ||
866 | /* For firmware downlaod we only need to set LINIP */ | ||
867 | SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt); | ||
868 | |||
869 | /* 92SE must set as 1 for firmware download HW DMA error */ | ||
870 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | ||
871 | SET_TX_DESC_LAST_SEG(pdesc, 1); | ||
872 | |||
873 | /* 92SE need not to set TX packet size when firmware download */ | ||
874 | SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len)); | ||
875 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); | ||
876 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); | ||
877 | |||
878 | SET_TX_DESC_OWN(pdesc, 1); | ||
879 | } else { /* H2C Command Desc format (Host TXCMD) */ | ||
880 | /* 92SE must set as 1 for firmware download HW DMA error */ | ||
881 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | ||
882 | SET_TX_DESC_LAST_SEG(pdesc, 1); | ||
883 | |||
884 | SET_TX_DESC_OFFSET(pdesc, 0x20); | ||
885 | |||
886 | /* Buffer size + command header */ | ||
887 | SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len)); | ||
888 | /* Fixed queue of H2C command */ | ||
889 | SET_TX_DESC_QUEUE_SEL(pdesc, 0x13); | ||
890 | |||
891 | SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq); | ||
892 | |||
893 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); | ||
894 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); | ||
895 | |||
896 | SET_TX_DESC_OWN(pdesc, 1); | ||
897 | |||
898 | } | ||
899 | } | ||
900 | |||
901 | void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | ||
902 | { | ||
903 | if (istx == true) { | ||
904 | switch (desc_name) { | ||
905 | case HW_DESC_OWN: | ||
906 | SET_TX_DESC_OWN(pdesc, 1); | ||
907 | break; | ||
908 | case HW_DESC_TX_NEXTDESC_ADDR: | ||
909 | SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); | ||
910 | break; | ||
911 | default: | ||
912 | RT_ASSERT(false, ("ERR txdesc :%d not process\n", | ||
913 | desc_name)); | ||
914 | break; | ||
915 | } | ||
916 | } else { | ||
917 | switch (desc_name) { | ||
918 | case HW_DESC_RXOWN: | ||
919 | SET_RX_STATUS_DESC_OWN(pdesc, 1); | ||
920 | break; | ||
921 | case HW_DESC_RXBUFF_ADDR: | ||
922 | SET_RX_STATUS__DESC_BUFF_ADDR(pdesc, *(u32 *) val); | ||
923 | break; | ||
924 | case HW_DESC_RXPKT_LEN: | ||
925 | SET_RX_STATUS_DESC_PKT_LEN(pdesc, *(u32 *) val); | ||
926 | break; | ||
927 | case HW_DESC_RXERO: | ||
928 | SET_RX_STATUS_DESC_EOR(pdesc, 1); | ||
929 | break; | ||
930 | default: | ||
931 | RT_ASSERT(false, ("ERR rxdesc :%d not process\n", | ||
932 | desc_name)); | ||
933 | break; | ||
934 | } | ||
935 | } | ||
936 | } | ||
937 | |||
938 | u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) | ||
939 | { | ||
940 | u32 ret = 0; | ||
941 | |||
942 | if (istx == true) { | ||
943 | switch (desc_name) { | ||
944 | case HW_DESC_OWN: | ||
945 | ret = GET_TX_DESC_OWN(desc); | ||
946 | break; | ||
947 | case HW_DESC_TXBUFF_ADDR: | ||
948 | ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc); | ||
949 | break; | ||
950 | default: | ||
951 | RT_ASSERT(false, ("ERR txdesc :%d not process\n", | ||
952 | desc_name)); | ||
953 | break; | ||
954 | } | ||
955 | } else { | ||
956 | switch (desc_name) { | ||
957 | case HW_DESC_OWN: | ||
958 | ret = GET_RX_STATUS_DESC_OWN(desc); | ||
959 | break; | ||
960 | case HW_DESC_RXPKT_LEN: | ||
961 | ret = GET_RX_STATUS_DESC_PKT_LEN(desc); | ||
962 | break; | ||
963 | default: | ||
964 | RT_ASSERT(false, ("ERR rxdesc :%d not process\n", | ||
965 | desc_name)); | ||
966 | break; | ||
967 | } | ||
968 | } | ||
969 | return ret; | ||
970 | } | ||
971 | |||
972 | void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) | ||
973 | { | ||
974 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
975 | rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue)); | ||
976 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h new file mode 100644 index 000000000000..05862c51b861 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 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 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __REALTEK_PCI92SE_TRX_H__ | ||
30 | #define __REALTEK_PCI92SE_TRX_H__ | ||
31 | |||
32 | void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, | ||
33 | u8 *pdesc, struct ieee80211_tx_info *info, | ||
34 | struct sk_buff *skb, u8 hw_queue, | ||
35 | struct rtl_tcb_desc *ptcb_desc); | ||
36 | void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool firstseg, | ||
37 | bool lastseg, struct sk_buff *skb); | ||
38 | bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, | ||
39 | struct ieee80211_rx_status *rx_status, u8 *pdesc, | ||
40 | struct sk_buff *skb); | ||
41 | void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); | ||
42 | u32 rtl92se_get_desc(u8 *pdesc, bool istx, u8 desc_name); | ||
43 | void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); | ||
44 | |||
45 | #endif | ||