Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux...
[linux/fpc-iii.git] / drivers / net / wireless / realtek / rtlwifi / rtl8723ae / fw.c
blobb7c0d38ee5b5850623ce2f49554ed9e82e66c0e0
1 /******************************************************************************
3 * Copyright(c) 2009-2012 Realtek Corporation.
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.
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.
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
26 #include "../wifi.h"
27 #include "../pci.h"
28 #include "../base.h"
29 #include "../core.h"
30 #include "reg.h"
31 #include "def.h"
32 #include "fw.h"
33 #include "../rtl8723com/fw_common.h"
35 static bool _rtl8723e_check_fw_read_last_h2c(struct ieee80211_hw *hw,
36 u8 boxnum)
38 struct rtl_priv *rtlpriv = rtl_priv(hw);
39 u8 val_hmetfr, val_mcutst_1;
40 bool result = false;
42 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
43 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
45 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
46 result = true;
47 return result;
50 static void _rtl8723e_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
51 u32 cmd_len, u8 *cmdbuffer)
53 struct rtl_priv *rtlpriv = rtl_priv(hw);
54 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
55 u8 boxnum;
56 u16 box_reg = 0, box_extreg = 0;
57 u8 u1b_tmp;
58 bool isfw_read = false;
59 u8 buf_index = 0;
60 bool bwrite_sucess = false;
61 u8 wait_h2c_limmit = 100;
62 u8 wait_writeh2c_limmit = 100;
63 u8 boxcontent[4], boxextcontent[2];
64 u32 h2c_waitcounter = 0;
65 unsigned long flag;
66 u8 idx;
68 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
70 while (true) {
71 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
72 if (rtlhal->h2c_setinprogress) {
73 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
74 "H2C set in progress! Wait to set..element_id(%d).\n",
75 element_id);
77 while (rtlhal->h2c_setinprogress) {
78 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
79 flag);
80 h2c_waitcounter++;
81 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
82 "Wait 100 us (%d times)...\n",
83 h2c_waitcounter);
84 udelay(100);
86 if (h2c_waitcounter > 1000)
87 return;
88 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
89 flag);
91 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
92 } else {
93 rtlhal->h2c_setinprogress = true;
94 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
95 break;
99 while (!bwrite_sucess) {
100 wait_writeh2c_limmit--;
101 if (wait_writeh2c_limmit == 0) {
102 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
103 "Write H2C fail because no trigger for FW INT!\n");
104 break;
107 boxnum = rtlhal->last_hmeboxnum;
108 switch (boxnum) {
109 case 0:
110 box_reg = REG_HMEBOX_0;
111 box_extreg = REG_HMEBOX_EXT_0;
112 break;
113 case 1:
114 box_reg = REG_HMEBOX_1;
115 box_extreg = REG_HMEBOX_EXT_1;
116 break;
117 case 2:
118 box_reg = REG_HMEBOX_2;
119 box_extreg = REG_HMEBOX_EXT_2;
120 break;
121 case 3:
122 box_reg = REG_HMEBOX_3;
123 box_extreg = REG_HMEBOX_EXT_3;
124 break;
125 default:
126 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
127 "switch case not process\n");
128 break;
131 isfw_read = _rtl8723e_check_fw_read_last_h2c(hw, boxnum);
132 while (!isfw_read) {
134 wait_h2c_limmit--;
135 if (wait_h2c_limmit == 0) {
136 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
137 "Wating too long for FW read clear HMEBox(%d)!\n",
138 boxnum);
139 break;
142 udelay(10);
144 isfw_read = _rtl8723e_check_fw_read_last_h2c(hw,
145 boxnum);
146 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
147 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
148 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
149 boxnum, u1b_tmp);
152 if (!isfw_read) {
153 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
154 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
155 boxnum);
156 break;
159 memset(boxcontent, 0, sizeof(boxcontent));
160 memset(boxextcontent, 0, sizeof(boxextcontent));
161 boxcontent[0] = element_id;
162 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
163 "Write element_id box_reg(%4x) = %2x\n",
164 box_reg, element_id);
166 switch (cmd_len) {
167 case 1:
168 boxcontent[0] &= ~(BIT(7));
169 memcpy((u8 *)(boxcontent) + 1,
170 cmdbuffer + buf_index, 1);
172 for (idx = 0; idx < 4; idx++) {
173 rtl_write_byte(rtlpriv, box_reg + idx,
174 boxcontent[idx]);
176 break;
177 case 2:
178 boxcontent[0] &= ~(BIT(7));
179 memcpy((u8 *)(boxcontent) + 1,
180 cmdbuffer + buf_index, 2);
182 for (idx = 0; idx < 4; idx++) {
183 rtl_write_byte(rtlpriv, box_reg + idx,
184 boxcontent[idx]);
186 break;
187 case 3:
188 boxcontent[0] &= ~(BIT(7));
189 memcpy((u8 *)(boxcontent) + 1,
190 cmdbuffer + buf_index, 3);
192 for (idx = 0; idx < 4; idx++) {
193 rtl_write_byte(rtlpriv, box_reg + idx,
194 boxcontent[idx]);
196 break;
197 case 4:
198 boxcontent[0] |= (BIT(7));
199 memcpy((u8 *)(boxextcontent),
200 cmdbuffer + buf_index, 2);
201 memcpy((u8 *)(boxcontent) + 1,
202 cmdbuffer + buf_index + 2, 2);
204 for (idx = 0; idx < 2; idx++) {
205 rtl_write_byte(rtlpriv, box_extreg + idx,
206 boxextcontent[idx]);
209 for (idx = 0; idx < 4; idx++) {
210 rtl_write_byte(rtlpriv, box_reg + idx,
211 boxcontent[idx]);
213 break;
214 case 5:
215 boxcontent[0] |= (BIT(7));
216 memcpy((u8 *)(boxextcontent),
217 cmdbuffer + buf_index, 2);
218 memcpy((u8 *)(boxcontent) + 1,
219 cmdbuffer + buf_index + 2, 3);
221 for (idx = 0; idx < 2; idx++) {
222 rtl_write_byte(rtlpriv, box_extreg + idx,
223 boxextcontent[idx]);
226 for (idx = 0; idx < 4; idx++) {
227 rtl_write_byte(rtlpriv, box_reg + idx,
228 boxcontent[idx]);
230 break;
231 default:
232 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
233 "switch case not process\n");
234 break;
237 bwrite_sucess = true;
239 rtlhal->last_hmeboxnum = boxnum + 1;
240 if (rtlhal->last_hmeboxnum == 4)
241 rtlhal->last_hmeboxnum = 0;
243 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
244 "pHalData->last_hmeboxnum = %d\n",
245 rtlhal->last_hmeboxnum);
248 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
249 rtlhal->h2c_setinprogress = false;
250 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
252 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
255 void rtl8723e_fill_h2c_cmd(struct ieee80211_hw *hw,
256 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
258 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
259 u32 tmp_cmdbuf[2];
261 if (!rtlhal->fw_ready) {
262 RT_ASSERT(false,
263 "return H2C cmd because of Fw download fail!!!\n");
264 return;
266 memset(tmp_cmdbuf, 0, 8);
267 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
268 _rtl8723e_fill_h2c_command(hw, element_id, cmd_len,
269 (u8 *)&tmp_cmdbuf);
272 void rtl8723e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
274 struct rtl_priv *rtlpriv = rtl_priv(hw);
275 u8 u1_h2c_set_pwrmode[3] = { 0 };
276 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
278 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
280 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
281 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
282 (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
283 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
284 ppsc->reg_max_lps_awakeintvl);
286 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
287 "rtl8723e_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
288 u1_h2c_set_pwrmode, 3);
289 rtl8723e_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
292 #define BEACON_PG 0 /* ->1 */
293 #define PSPOLL_PG 2
294 #define NULL_PG 3
295 #define PROBERSP_PG 4 /* ->5 */
297 #define TOTAL_RESERVED_PKT_LEN 768
299 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
300 /* page 0 beacon */
301 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
302 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
303 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
306 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
307 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
308 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
309 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
310 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
311 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
315 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 /* page 1 beacon */
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 /* page 2 ps-poll */
337 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
338 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
351 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 /* page 3 null */
355 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
356 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
357 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
369 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 /* page 4 probe_resp */
373 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
374 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
375 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
376 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
377 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
378 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
379 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
380 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
381 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
382 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
383 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
387 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 /* page 5 probe_resp */
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 void rtl8723e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
411 struct rtl_priv *rtlpriv = rtl_priv(hw);
412 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
413 struct sk_buff *skb = NULL;
414 u32 totalpacketlen;
415 bool rtstatus;
416 u8 u1rsvdpageloc[3] = { 0 };
417 bool b_dlok = false;
418 u8 *beacon;
419 u8 *p_pspoll;
420 u8 *nullfunc;
421 u8 *p_probersp;
423 /*---------------------------------------------------------
424 * (1) beacon
425 *---------------------------------------------------------
427 beacon = &reserved_page_packet[BEACON_PG * 128];
428 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
429 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
431 /*-------------------------------------------------------
432 * (2) ps-poll
433 *--------------------------------------------------------
435 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
436 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
437 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
438 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
440 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
442 /*--------------------------------------------------------
443 * (3) null data
444 *---------------------------------------------------------
446 nullfunc = &reserved_page_packet[NULL_PG * 128];
447 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
448 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
449 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
451 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
453 /*---------------------------------------------------------
454 * (4) probe response
455 *----------------------------------------------------------
457 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
458 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
459 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
460 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
462 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
464 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
466 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
467 "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
468 &reserved_page_packet[0], totalpacketlen);
469 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
470 "rtl8723e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
471 u1rsvdpageloc, 3);
473 skb = dev_alloc_skb(totalpacketlen);
474 memcpy((u8 *)skb_put(skb, totalpacketlen),
475 &reserved_page_packet, totalpacketlen);
477 rtstatus = rtl_cmd_send_packet(hw, skb);
479 if (rtstatus)
480 b_dlok = true;
482 if (b_dlok) {
483 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
484 "Set RSVD page location to Fw.\n");
485 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
486 "H2C_RSVDPAGE:\n",
487 u1rsvdpageloc, 3);
488 rtl8723e_fill_h2c_cmd(hw, H2C_RSVDPAGE,
489 sizeof(u1rsvdpageloc), u1rsvdpageloc);
490 } else
491 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
492 "Set RSVD page location to Fw FAIL!!!!!!.\n");
495 void rtl8723e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
497 u8 u1_joinbssrpt_parm[1] = { 0 };
499 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
501 rtl8723e_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
504 static void rtl8723e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
505 u8 ctwindow)
507 u8 u1_ctwindow_period[1] = { ctwindow};
509 rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
513 void rtl8723e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
515 struct rtl_priv *rtlpriv = rtl_priv(hw);
516 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
517 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
518 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
519 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
520 u8 i;
521 u16 ctwindow;
522 u32 start_time, tsf_low;
524 switch (p2p_ps_state) {
525 case P2P_PS_DISABLE:
526 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
527 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
528 break;
529 case P2P_PS_ENABLE:
530 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
531 /* update CTWindow value. */
532 if (p2pinfo->ctwindow > 0) {
533 p2p_ps_offload->ctwindow_en = 1;
534 ctwindow = p2pinfo->ctwindow;
535 rtl8723e_set_p2p_ctw_period_cmd(hw, ctwindow);
538 /* hw only support 2 set of NoA */
539 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
540 /* To control the register setting for which NOA*/
541 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
542 if (i == 0)
543 p2p_ps_offload->noa0_en = 1;
544 else
545 p2p_ps_offload->noa1_en = 1;
547 /* config P2P NoA Descriptor Register */
548 rtl_write_dword(rtlpriv, 0x5E0,
549 p2pinfo->noa_duration[i]);
550 rtl_write_dword(rtlpriv, 0x5E4,
551 p2pinfo->noa_interval[i]);
553 /*Get Current TSF value */
554 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
556 start_time = p2pinfo->noa_start_time[i];
557 if (p2pinfo->noa_count_type[i] != 1) {
558 while (start_time <=
559 (tsf_low+(50*1024))) {
560 start_time +=
561 p2pinfo->noa_interval[i];
562 if (p2pinfo->noa_count_type[i] != 255)
563 p2pinfo->noa_count_type[i]--;
566 rtl_write_dword(rtlpriv, 0x5E8, start_time);
567 rtl_write_dword(rtlpriv, 0x5EC,
568 p2pinfo->noa_count_type[i]);
572 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
573 /* rst p2p circuit */
574 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
576 p2p_ps_offload->offload_en = 1;
578 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
579 p2p_ps_offload->role = 1;
580 p2p_ps_offload->allstasleep = 0;
581 } else {
582 p2p_ps_offload->role = 0;
585 p2p_ps_offload->discovery = 0;
587 break;
588 case P2P_PS_SCAN:
589 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
590 p2p_ps_offload->discovery = 1;
591 break;
592 case P2P_PS_SCAN_DONE:
593 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
594 p2p_ps_offload->discovery = 0;
595 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
596 break;
597 default:
598 break;
601 rtl8723e_fill_h2c_cmd(hw, H2C_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);