blob: 5360d533235944a94fe931ab76ce4e04439a77ab [file] [log] [blame]
Larry Fingerf0eb8562013-03-24 22:06:42 -05001/******************************************************************************
2 *
3 * Copyright(c) 2009-2013 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 *
Larry Fingerf0eb8562013-03-24 22:06:42 -050014 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
Chen, Chien-Chia2a2ac752013-04-02 22:01:55 +080026#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
Larry Finger557f9332014-09-26 16:40:27 -050029#include "../core.h"
Larry Fingerf0eb8562013-03-24 22:06:42 -050030#include "reg.h"
31#include "def.h"
32#include "fw.h"
33
Larry Fingerf0eb8562013-03-24 22:06:42 -050034static void _rtl88e_enable_fw_download(struct ieee80211_hw *hw, bool enable)
35{
36 struct rtl_priv *rtlpriv = rtl_priv(hw);
37 u8 tmp;
38
39 if (enable) {
40 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
41 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
42
43 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
44 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
45
46 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
47 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
48 } else {
49 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
50 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
51
52 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
53 }
54}
55
56static void _rtl88e_fw_block_write(struct ieee80211_hw *hw,
57 const u8 *buffer, u32 size)
58{
59 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingerc151aed2014-09-22 09:39:25 -050060 u32 blocksize = sizeof(u32);
61 u8 *bufferptr = (u8 *)buffer;
Larry Fingerf0eb8562013-03-24 22:06:42 -050062 u32 *pu4BytePtr = (u32 *)buffer;
Larry Fingerc151aed2014-09-22 09:39:25 -050063 u32 i, offset, blockcount, remainsize;
Larry Fingerf0eb8562013-03-24 22:06:42 -050064
Larry Fingerc151aed2014-09-22 09:39:25 -050065 blockcount = size / blocksize;
66 remainsize = size % blocksize;
Larry Fingerf0eb8562013-03-24 22:06:42 -050067
Larry Fingerc151aed2014-09-22 09:39:25 -050068 for (i = 0; i < blockcount; i++) {
69 offset = i * blocksize;
Larry Fingerf0eb8562013-03-24 22:06:42 -050070 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
71 *(pu4BytePtr + i));
72 }
73
Larry Fingerc151aed2014-09-22 09:39:25 -050074 if (remainsize) {
75 offset = blockcount * blocksize;
76 bufferptr += offset;
77 for (i = 0; i < remainsize; i++) {
Larry Fingerf0eb8562013-03-24 22:06:42 -050078 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
Larry Fingerc151aed2014-09-22 09:39:25 -050079 offset + i), *(bufferptr + i));
Larry Fingerf0eb8562013-03-24 22:06:42 -050080 }
81 }
82}
83
84static void _rtl88e_fw_page_write(struct ieee80211_hw *hw,
85 u32 page, const u8 *buffer, u32 size)
86{
87 struct rtl_priv *rtlpriv = rtl_priv(hw);
88 u8 value8;
89 u8 u8page = (u8) (page & 0x07);
90
91 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
92
93 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
94 _rtl88e_fw_block_write(hw, buffer, size);
95}
96
97static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
98{
99 u32 fwlen = *pfwlen;
100 u8 remain = (u8) (fwlen % 4);
101
102 remain = (remain == 0) ? 0 : (4 - remain);
103
104 while (remain > 0) {
105 pfwbuf[fwlen] = 0;
106 fwlen++;
107 remain--;
108 }
109
110 *pfwlen = fwlen;
111}
112
113static void _rtl88e_write_fw(struct ieee80211_hw *hw,
114 enum version_8188e version, u8 *buffer, u32 size)
115{
116 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingerc151aed2014-09-22 09:39:25 -0500117 u8 *bufferptr = (u8 *)buffer;
118 u32 pagenums, remainsize;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500119 u32 page, offset;
120
121 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
122
Larry Fingerc151aed2014-09-22 09:39:25 -0500123 _rtl88e_fill_dummy(bufferptr, &size);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500124
Larry Fingerc151aed2014-09-22 09:39:25 -0500125 pagenums = size / FW_8192C_PAGE_SIZE;
126 remainsize = size % FW_8192C_PAGE_SIZE;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500127
Larry Fingerc151aed2014-09-22 09:39:25 -0500128 if (pagenums > 8) {
Larry Fingerf0eb8562013-03-24 22:06:42 -0500129 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
130 "Page numbers should not greater then 8\n");
131 }
132
Larry Fingerc151aed2014-09-22 09:39:25 -0500133 for (page = 0; page < pagenums; page++) {
Larry Fingerf0eb8562013-03-24 22:06:42 -0500134 offset = page * FW_8192C_PAGE_SIZE;
Larry Fingerc151aed2014-09-22 09:39:25 -0500135 _rtl88e_fw_page_write(hw, page, (bufferptr + offset),
Larry Fingerf0eb8562013-03-24 22:06:42 -0500136 FW_8192C_PAGE_SIZE);
137 }
138
Larry Fingerc151aed2014-09-22 09:39:25 -0500139 if (remainsize) {
140 offset = pagenums * FW_8192C_PAGE_SIZE;
141 page = pagenums;
142 _rtl88e_fw_page_write(hw, page, (bufferptr + offset),
143 remainsize);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500144 }
145}
146
147static int _rtl88e_fw_free_to_go(struct ieee80211_hw *hw)
148{
149 struct rtl_priv *rtlpriv = rtl_priv(hw);
150 int err = -EIO;
151 u32 counter = 0;
152 u32 value32;
153
154 do {
155 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
156 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
157 (!(value32 & FWDL_CHKSUM_RPT)));
158
159 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
160 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
161 "chksum report faill ! REG_MCUFWDL:0x%08x .\n",
162 value32);
163 goto exit;
164 }
165
166 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
167 "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32);
168
169 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
170 value32 |= MCUFWDL_RDY;
171 value32 &= ~WINTINI_RDY;
172 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
173
174 rtl88e_firmware_selfreset(hw);
175 counter = 0;
176
177 do {
178 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
179 if (value32 & WINTINI_RDY) {
180 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
181 "Polling FW ready success!! REG_MCUFWDL:0x%08x.\n",
182 value32);
183 err = 0;
184 goto exit;
185 }
186
187 udelay(FW_8192C_POLLING_DELAY);
188
189 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
190
191 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
192 "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32);
193
194exit:
195 return err;
196}
197
Larry Fingerc151aed2014-09-22 09:39:25 -0500198int rtl88e_download_fw(struct ieee80211_hw *hw,
199 bool buse_wake_on_wlan_fw)
Larry Fingerf0eb8562013-03-24 22:06:42 -0500200{
201 struct rtl_priv *rtlpriv = rtl_priv(hw);
202 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger201b63c2015-08-03 15:56:15 -0500203 struct rtlwifi_firmware_header *pfwheader;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500204 u8 *pfwdata;
205 u32 fwsize;
206 int err;
207 enum version_8188e version = rtlhal->version;
208
209 if (!rtlhal->pfirmware)
210 return 1;
211
Larry Finger201b63c2015-08-03 15:56:15 -0500212 pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
Joe Perches1851cb42014-03-24 13:15:40 -0700213 pfwdata = rtlhal->pfirmware;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500214 fwsize = rtlhal->fwsize;
215 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
216 "normal Firmware SIZE %d\n", fwsize);
217
218 if (IS_FW_HEADER_EXIST(pfwheader)) {
219 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
220 "Firmware Version(%d), Signature(%#x), Size(%d)\n",
Larry Fingerc151aed2014-09-22 09:39:25 -0500221 pfwheader->version, pfwheader->signature,
Larry Finger201b63c2015-08-03 15:56:15 -0500222 (int)sizeof(struct rtlwifi_firmware_header));
Larry Fingerf0eb8562013-03-24 22:06:42 -0500223
Larry Finger201b63c2015-08-03 15:56:15 -0500224 pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
225 fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500226 }
227
228 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
229 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
230 rtl88e_firmware_selfreset(hw);
231 }
232 _rtl88e_enable_fw_download(hw, true);
233 _rtl88e_write_fw(hw, version, pfwdata, fwsize);
234 _rtl88e_enable_fw_download(hw, false);
235
236 err = _rtl88e_fw_free_to_go(hw);
Larry Fingerc151aed2014-09-22 09:39:25 -0500237 if (err) {
238 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
239 "Firmware is not ready to run!\n");
240 } else {
241 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
242 "Firmware is ready to run!\n");
243 }
Larry Fingerf0eb8562013-03-24 22:06:42 -0500244
Larry Fingerf0eb8562013-03-24 22:06:42 -0500245 return 0;
246}
247
248static bool _rtl88e_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
249{
250 struct rtl_priv *rtlpriv = rtl_priv(hw);
251 u8 val_hmetfr;
252
253 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
254 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
255 return true;
256 return false;
257}
258
259static void _rtl88e_fill_h2c_command(struct ieee80211_hw *hw,
260 u8 element_id, u32 cmd_len,
261 u8 *cmd_b)
262{
263 struct rtl_priv *rtlpriv = rtl_priv(hw);
264 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
265 u8 boxnum;
266 u16 box_reg = 0, box_extreg = 0;
267 u8 u1b_tmp;
268 bool isfw_read = false;
269 u8 buf_index = 0;
270 bool write_sucess = false;
Larry Fingerc151aed2014-09-22 09:39:25 -0500271 u8 wait_h2c_limmit = 100;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500272 u8 wait_writeh2c_limit = 100;
Larry Fingerc151aed2014-09-22 09:39:25 -0500273 u8 boxcontent[4], boxextcontent[4];
Larry Fingerf0eb8562013-03-24 22:06:42 -0500274 u32 h2c_waitcounter = 0;
275 unsigned long flag;
276 u8 idx;
277
278 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
279
280 while (true) {
281 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
282 if (rtlhal->h2c_setinprogress) {
283 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
284 "H2C set in progress! Wait to set..element_id(%d).\n",
285 element_id);
286
287 while (rtlhal->h2c_setinprogress) {
288 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
289 flag);
290 h2c_waitcounter++;
291 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
292 "Wait 100 us (%d times)...\n",
293 h2c_waitcounter);
294 udelay(100);
295
296 if (h2c_waitcounter > 1000)
297 return;
298 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
299 flag);
300 }
301 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
302 } else {
303 rtlhal->h2c_setinprogress = true;
304 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
305 break;
306 }
307 }
308
309 while (!write_sucess) {
310 wait_writeh2c_limit--;
311 if (wait_writeh2c_limit == 0) {
312 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
313 "Write H2C fail because no trigger for FW INT!\n");
314 break;
315 }
316
317 boxnum = rtlhal->last_hmeboxnum;
318 switch (boxnum) {
319 case 0:
320 box_reg = REG_HMEBOX_0;
321 box_extreg = REG_HMEBOX_EXT_0;
322 break;
323 case 1:
324 box_reg = REG_HMEBOX_1;
325 box_extreg = REG_HMEBOX_EXT_1;
326 break;
327 case 2:
328 box_reg = REG_HMEBOX_2;
329 box_extreg = REG_HMEBOX_EXT_2;
330 break;
331 case 3:
332 box_reg = REG_HMEBOX_3;
333 box_extreg = REG_HMEBOX_EXT_3;
334 break;
335 default:
Larry Fingerc151aed2014-09-22 09:39:25 -0500336 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700337 "switch case %#x not processed\n", boxnum);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500338 break;
339 }
Larry Fingerf0eb8562013-03-24 22:06:42 -0500340 isfw_read = _rtl88e_check_fw_read_last_h2c(hw, boxnum);
341 while (!isfw_read) {
Larry Fingerc151aed2014-09-22 09:39:25 -0500342 wait_h2c_limmit--;
343 if (wait_h2c_limmit == 0) {
Larry Fingerf0eb8562013-03-24 22:06:42 -0500344 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Larry Fingerc151aed2014-09-22 09:39:25 -0500345 "Waiting too long for FW read clear HMEBox(%d)!\n",
346 boxnum);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500347 break;
348 }
349
350 udelay(10);
351
352 isfw_read = _rtl88e_check_fw_read_last_h2c(hw, boxnum);
353 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
354 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Larry Fingerc151aed2014-09-22 09:39:25 -0500355 "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
356 boxnum, u1b_tmp);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500357 }
358
359 if (!isfw_read) {
360 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
Larry Fingerc151aed2014-09-22 09:39:25 -0500361 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
362 boxnum);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500363 break;
364 }
365
Larry Fingerc151aed2014-09-22 09:39:25 -0500366 memset(boxcontent, 0, sizeof(boxcontent));
367 memset(boxextcontent, 0, sizeof(boxextcontent));
368 boxcontent[0] = element_id;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500369 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
370 "Write element_id box_reg(%4x) = %2x\n",
371 box_reg, element_id);
372
373 switch (cmd_len) {
374 case 1:
375 case 2:
376 case 3:
Larry Fingerc151aed2014-09-22 09:39:25 -0500377 /*boxcontent[0] &= ~(BIT(7));*/
378 memcpy((u8 *)(boxcontent) + 1,
379 cmd_b + buf_index, cmd_len);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500380
Larry Fingerc151aed2014-09-22 09:39:25 -0500381 for (idx = 0; idx < 4; idx++) {
382 rtl_write_byte(rtlpriv, box_reg + idx,
383 boxcontent[idx]);
384 }
Larry Fingerf0eb8562013-03-24 22:06:42 -0500385 break;
386 case 4:
387 case 5:
388 case 6:
389 case 7:
Larry Fingerc151aed2014-09-22 09:39:25 -0500390 /*boxcontent[0] |= (BIT(7));*/
391 memcpy((u8 *)(boxextcontent),
392 cmd_b + buf_index+3, cmd_len-3);
393 memcpy((u8 *)(boxcontent) + 1,
394 cmd_b + buf_index, 3);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500395
396 for (idx = 0; idx < 2; idx++) {
397 rtl_write_byte(rtlpriv, box_extreg + idx,
Larry Fingerc151aed2014-09-22 09:39:25 -0500398 boxextcontent[idx]);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500399 }
400
401 for (idx = 0; idx < 4; idx++) {
402 rtl_write_byte(rtlpriv, box_reg + idx,
Larry Fingerc151aed2014-09-22 09:39:25 -0500403 boxcontent[idx]);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500404 }
405 break;
406 default:
Larry Fingerc151aed2014-09-22 09:39:25 -0500407 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700408 "switch case %#x not processed\n", cmd_len);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500409 break;
410 }
411
412 write_sucess = true;
413
414 rtlhal->last_hmeboxnum = boxnum + 1;
415 if (rtlhal->last_hmeboxnum == 4)
416 rtlhal->last_hmeboxnum = 0;
417
418 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
419 "pHalData->last_hmeboxnum = %d\n",
Larry Fingerc151aed2014-09-22 09:39:25 -0500420 rtlhal->last_hmeboxnum);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500421 }
422
423 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
424 rtlhal->h2c_setinprogress = false;
425 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
426
427 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
428}
429
430void rtl88e_fill_h2c_cmd(struct ieee80211_hw *hw,
Larry Fingerc151aed2014-09-22 09:39:25 -0500431 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
Larry Fingerf0eb8562013-03-24 22:06:42 -0500432{
433 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
434 u32 tmp_cmdbuf[2];
435
Larry Fingerc151aed2014-09-22 09:39:25 -0500436 if (!rtlhal->fw_ready) {
437 RT_ASSERT(false,
438 "return H2C cmd because of Fw download fail!!!\n");
Larry Fingerf0eb8562013-03-24 22:06:42 -0500439 return;
440 }
441
442 memset(tmp_cmdbuf, 0, 8);
Larry Fingerc151aed2014-09-22 09:39:25 -0500443 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500444 _rtl88e_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
445
446 return;
447}
448
449void rtl88e_firmware_selfreset(struct ieee80211_hw *hw)
450{
451 u8 u1b_tmp;
452 struct rtl_priv *rtlpriv = rtl_priv(hw);
453
454 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
455 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2))));
456 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2)));
457 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Larry Fingerc151aed2014-09-22 09:39:25 -0500458 "8051Reset88E(): 8051 reset success\n");
459
Larry Fingerf0eb8562013-03-24 22:06:42 -0500460}
461
462void rtl88e_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
463{
464 struct rtl_priv *rtlpriv = rtl_priv(hw);
465 u8 u1_h2c_set_pwrmode[H2C_88E_PWEMODE_LENGTH] = { 0 };
466 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
Larry Fingerc151aed2014-09-22 09:39:25 -0500467 u8 rlbm, power_state = 0;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500468 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
Larry Fingerc151aed2014-09-22 09:39:25 -0500469
Larry Fingerf0eb8562013-03-24 22:06:42 -0500470 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
Larry Fingerc151aed2014-09-22 09:39:25 -0500471 rlbm = 0;/*YJ, temp, 120316. FW now not support RLBM=2.*/
472 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500473 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
Larry Fingerc151aed2014-09-22 09:39:25 -0500474 (rtlpriv->mac80211.p2p) ? ppsc->smart_ps : 1);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500475 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
Larry Fingerc151aed2014-09-22 09:39:25 -0500476 ppsc->reg_max_lps_awakeintvl);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500477 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
478 if (mode == FW_PS_ACTIVE_MODE)
479 power_state |= FW_PWR_STATE_ACTIVE;
480 else
481 power_state |= FW_PWR_STATE_RF_OFF;
Larry Fingerc151aed2014-09-22 09:39:25 -0500482
Larry Fingerf0eb8562013-03-24 22:06:42 -0500483 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
484
485 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
486 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
487 u1_h2c_set_pwrmode, H2C_88E_PWEMODE_LENGTH);
Larry Fingerc151aed2014-09-22 09:39:25 -0500488 rtl88e_fill_h2c_cmd(hw, H2C_88E_SETPWRMODE,
489 H2C_88E_PWEMODE_LENGTH, u1_h2c_set_pwrmode);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500490}
491
492void rtl88e_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
493{
494 u8 u1_joinbssrpt_parm[1] = { 0 };
495
496 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
497
498 rtl88e_fill_h2c_cmd(hw, H2C_88E_JOINBSSRPT, 1, u1_joinbssrpt_parm);
499}
500
501void rtl88e_set_fw_ap_off_load_cmd(struct ieee80211_hw *hw,
502 u8 ap_offload_enable)
503{
504 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
505 u8 u1_apoffload_parm[H2C_88E_AP_OFFLOAD_LENGTH] = { 0 };
506
507 SET_H2CCMD_AP_OFFLOAD_ON(u1_apoffload_parm, ap_offload_enable);
508 SET_H2CCMD_AP_OFFLOAD_HIDDEN(u1_apoffload_parm, mac->hiddenssid);
509 SET_H2CCMD_AP_OFFLOAD_DENYANY(u1_apoffload_parm, 0);
510
Larry Fingerc151aed2014-09-22 09:39:25 -0500511 rtl88e_fill_h2c_cmd(hw, H2C_88E_AP_OFFLOAD,
512 H2C_88E_AP_OFFLOAD_LENGTH, u1_apoffload_parm);
513
Larry Fingerf0eb8562013-03-24 22:06:42 -0500514}
515
Larry Fingerf0eb8562013-03-24 22:06:42 -0500516#define BEACON_PG 0 /* ->1 */
517#define PSPOLL_PG 2
518#define NULL_PG 3
519#define PROBERSP_PG 4 /* ->5 */
520
521#define TOTAL_RESERVED_PKT_LEN 768
522
523static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
524 /* page 0 beacon */
525 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
526 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
527 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
530 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
531 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
532 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
533 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
534 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
535 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
539 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541
542 /* page 1 beacon */
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559
560 /* page 2 ps-poll */
561 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
562 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
575 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577
578 /* page 3 null */
579 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
580 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
581 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
593 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595
596 /* page 4 probe_resp */
597 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
598 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
599 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
600 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
601 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
602 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
603 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
604 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
605 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
606 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
607 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
611 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613
614 /* page 5 probe_resp */
615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631};
632
633void rtl88e_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
634{
635 struct rtl_priv *rtlpriv = rtl_priv(hw);
636 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
637 struct sk_buff *skb = NULL;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500638 u32 totalpacketlen;
Larry Fingerc151aed2014-09-22 09:39:25 -0500639 bool rtstatus;
640 u8 u1rsvdpageloc[5] = { 0 };
641 bool b_dlok = false;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500642 u8 *beacon;
Larry Fingerc151aed2014-09-22 09:39:25 -0500643 u8 *p_pspoll;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500644 u8 *nullfunc;
Larry Fingerc151aed2014-09-22 09:39:25 -0500645 u8 *p_probersp;
646
Larry Fingerf0eb8562013-03-24 22:06:42 -0500647 /*---------------------------------------------------------
648 * (1) beacon
649 *---------------------------------------------------------
650 */
651 beacon = &reserved_page_packet[BEACON_PG * 128];
652 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
653 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
654
655 /*-------------------------------------------------------
656 * (2) ps-poll
657 *--------------------------------------------------------
658 */
Larry Fingerc151aed2014-09-22 09:39:25 -0500659 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
660 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
661 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
662 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500663
Larry Fingerc151aed2014-09-22 09:39:25 -0500664 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500665
666 /*--------------------------------------------------------
667 * (3) null data
668 *---------------------------------------------------------
669 */
670 nullfunc = &reserved_page_packet[NULL_PG * 128];
671 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
672 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
673 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
674
Larry Fingerc151aed2014-09-22 09:39:25 -0500675 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500676
677 /*---------------------------------------------------------
678 * (4) probe response
679 *----------------------------------------------------------
680 */
Larry Fingerc151aed2014-09-22 09:39:25 -0500681 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
682 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
683 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
684 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500685
Larry Fingerc151aed2014-09-22 09:39:25 -0500686 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500687
688 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
689
690 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
691 "rtl88e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
692 &reserved_page_packet[0], totalpacketlen);
693 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
694 "rtl88e_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
Larry Fingerc151aed2014-09-22 09:39:25 -0500695 u1rsvdpageloc, 3);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500696
697 skb = dev_alloc_skb(totalpacketlen);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500698 memcpy(skb_put(skb, totalpacketlen),
699 &reserved_page_packet, totalpacketlen);
700
Larry Finger557f9332014-09-26 16:40:27 -0500701 rtstatus = rtl_cmd_send_packet(hw, skb);
Larry Fingerc151aed2014-09-22 09:39:25 -0500702
703 if (rtstatus)
704 b_dlok = true;
705
706 if (b_dlok) {
Larry Fingerf0eb8562013-03-24 22:06:42 -0500707 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
708 "Set RSVD page location to Fw.\n");
709 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
Larry Fingerc151aed2014-09-22 09:39:25 -0500710 "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500711 rtl88e_fill_h2c_cmd(hw, H2C_88E_RSVDPAGE,
Larry Fingerc151aed2014-09-22 09:39:25 -0500712 sizeof(u1rsvdpageloc), u1rsvdpageloc);
Larry Fingerf0eb8562013-03-24 22:06:42 -0500713 } else
714 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
715 "Set RSVD page location to Fw FAIL!!!!!!.\n");
716}
717
Larry Fingerc151aed2014-09-22 09:39:25 -0500718/*Should check FW support p2p or not.*/
Larry Fingerf0eb8562013-03-24 22:06:42 -0500719static void rtl88e_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
720{
Larry Fingerc151aed2014-09-22 09:39:25 -0500721 u8 u1_ctwindow_period[1] = { ctwindow};
Larry Fingerf0eb8562013-03-24 22:06:42 -0500722
723 rtl88e_fill_h2c_cmd(hw, H2C_88E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
Larry Fingerc151aed2014-09-22 09:39:25 -0500724
Larry Fingerf0eb8562013-03-24 22:06:42 -0500725}
726
727void rtl88e_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
728{
729 struct rtl_priv *rtlpriv = rtl_priv(hw);
730 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
731 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
732 struct rtl_p2p_ps_info *p2pinfo = &(rtlps->p2p_ps_info);
733 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
734 u8 i;
735 u16 ctwindow;
736 u32 start_time, tsf_low;
737
738 switch (p2p_ps_state) {
739 case P2P_PS_DISABLE:
740 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
Larry Finger7fe3b3a2014-09-26 16:40:22 -0500741 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
Larry Fingerf0eb8562013-03-24 22:06:42 -0500742 break;
743 case P2P_PS_ENABLE:
744 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
745 /* update CTWindow value. */
746 if (p2pinfo->ctwindow > 0) {
747 p2p_ps_offload->ctwindow_en = 1;
748 ctwindow = p2pinfo->ctwindow;
749 rtl88e_set_p2p_ctw_period_cmd(hw, ctwindow);
750 }
Larry Fingerc151aed2014-09-22 09:39:25 -0500751
Larry Fingerf0eb8562013-03-24 22:06:42 -0500752 /* hw only support 2 set of NoA */
Larry Fingerc151aed2014-09-22 09:39:25 -0500753 for (i = 0 ; i < p2pinfo->noa_num; i++) {
Larry Fingerf0eb8562013-03-24 22:06:42 -0500754 /* To control the register setting for which NOA*/
755 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
756 if (i == 0)
757 p2p_ps_offload->noa0_en = 1;
758 else
759 p2p_ps_offload->noa1_en = 1;
760
761 /* config P2P NoA Descriptor Register */
762 rtl_write_dword(rtlpriv, 0x5E0,
763 p2pinfo->noa_duration[i]);
764 rtl_write_dword(rtlpriv, 0x5E4,
765 p2pinfo->noa_interval[i]);
766
767 /*Get Current TSF value */
768 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
769
770 start_time = p2pinfo->noa_start_time[i];
771 if (p2pinfo->noa_count_type[i] != 1) {
Larry Fingerc151aed2014-09-22 09:39:25 -0500772 while (start_time <= (tsf_low+(50*1024))) {
Larry Fingerf0eb8562013-03-24 22:06:42 -0500773 start_time += p2pinfo->noa_interval[i];
774 if (p2pinfo->noa_count_type[i] != 255)
775 p2pinfo->noa_count_type[i]--;
776 }
777 }
778 rtl_write_dword(rtlpriv, 0x5E8, start_time);
779 rtl_write_dword(rtlpriv, 0x5EC,
780 p2pinfo->noa_count_type[i]);
781 }
782
783 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
784 /* rst p2p circuit */
785 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
786
787 p2p_ps_offload->offload_en = 1;
788
789 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
790 p2p_ps_offload->role = 1;
Larry Fingerc151aed2014-09-22 09:39:25 -0500791 p2p_ps_offload->allstasleep = -1;
Larry Fingerf0eb8562013-03-24 22:06:42 -0500792 } else {
793 p2p_ps_offload->role = 0;
794 }
795
796 p2p_ps_offload->discovery = 0;
797 }
798 break;
799 case P2P_PS_SCAN:
800 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
801 p2p_ps_offload->discovery = 1;
802 break;
803 case P2P_PS_SCAN_DONE:
804 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
805 p2p_ps_offload->discovery = 0;
806 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
807 break;
808 default:
809 break;
810 }
811
812 rtl88e_fill_h2c_cmd(hw, H2C_88E_P2P_PS_OFFLOAD, 1,
813 (u8 *)p2p_ps_offload);
Larry Fingerc151aed2014-09-22 09:39:25 -0500814
Larry Fingerf0eb8562013-03-24 22:06:42 -0500815}