blob: 7eae27f8e173fdf18a005b5cf0eb184326d01e68 [file] [log] [blame]
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05001/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../base.h"
Larry Finger557f9332014-09-26 16:40:27 -050029#include "../core.h"
Larry Finger89d32c92017-01-19 14:28:06 -060030#include "../efuse.h"
Larry Fingerb1a3bfc2014-09-26 16:40:23 -050031#include "reg.h"
32#include "def.h"
33#include "fw.h"
34#include "dm.h"
35
36static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable)
37{
38 struct rtl_priv *rtlpriv = rtl_priv(hw);
39 u8 tmp;
40
41 if (enable) {
42 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x05);
43
44 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
45 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
46 } else {
47 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
48 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
49 }
50}
51
Larry Fingerb1a3bfc2014-09-26 16:40:23 -050052static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
53 enum version_8192e version,
54 u8 *buffer, u32 size)
55{
56 struct rtl_priv *rtlpriv = rtl_priv(hw);
57 u8 *bufferptr = (u8 *)buffer;
58 u32 pagenums, remainsize;
59 u32 page, offset;
60
61 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "FW size is %d bytes,\n", size);
62
Larry Finger89d32c92017-01-19 14:28:06 -060063 rtl_fill_dummy(bufferptr, &size);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -050064
65 pagenums = size / FW_8192C_PAGE_SIZE;
66 remainsize = size % FW_8192C_PAGE_SIZE;
67
Larry Fingera44f59d2016-12-15 12:23:02 -060068 if (pagenums > 8)
69 pr_err("Page numbers should not greater then 8\n");
Larry Fingerb1a3bfc2014-09-26 16:40:23 -050070
71 for (page = 0; page < pagenums; page++) {
72 offset = page * FW_8192C_PAGE_SIZE;
Larry Finger89d32c92017-01-19 14:28:06 -060073 rtl_fw_page_write(hw, page, (bufferptr + offset),
74 FW_8192C_PAGE_SIZE);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -050075 udelay(2);
76 }
77
78 if (remainsize) {
79 offset = pagenums * FW_8192C_PAGE_SIZE;
80 page = pagenums;
Larry Finger89d32c92017-01-19 14:28:06 -060081 rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -050082 }
83}
84
85static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw)
86{
87 struct rtl_priv *rtlpriv = rtl_priv(hw);
88 int err = -EIO;
89 u32 counter = 0;
90 u32 value32;
91
92 do {
93 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
94 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
95 (!(value32 & FWDL_CHKSUM_RPT)));
96
97 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
Larry Fingera44f59d2016-12-15 12:23:02 -060098 pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
99 value32);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500100 goto exit;
101 }
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500102 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
103 value32 |= MCUFWDL_RDY;
104 value32 &= ~WINTINI_RDY;
105 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
106
107 rtl92ee_firmware_selfreset(hw);
108 counter = 0;
109
110 do {
111 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
Larry Fingerc93ac392016-12-15 12:23:10 -0600112 if (value32 & WINTINI_RDY)
113 return 0;
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500114
115 udelay(FW_8192C_POLLING_DELAY*10);
116
117 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
118
Larry Fingera44f59d2016-12-15 12:23:02 -0600119 pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n",
120 value32, counter);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500121
122exit:
123 return err;
124}
125
126int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
127{
128 struct rtl_priv *rtlpriv = rtl_priv(hw);
129 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger8d882bc2015-08-03 15:56:16 -0500130 struct rtlwifi_firmware_header *pfwheader;
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500131 u8 *pfwdata;
132 u32 fwsize;
133 int err;
134 enum version_8192e version = rtlhal->version;
135
136 if (!rtlhal->pfirmware)
137 return 1;
138
Larry Finger8d882bc2015-08-03 15:56:16 -0500139 pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
140 rtlhal->fw_version = le16_to_cpu(pfwheader->version);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500141 rtlhal->fw_subversion = pfwheader->subversion;
142 pfwdata = (u8 *)rtlhal->pfirmware;
143 fwsize = rtlhal->fwsize;
144 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
145 "normal Firmware SIZE %d\n" , fwsize);
146
147 if (IS_FW_HEADER_EXIST(pfwheader)) {
148 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
149 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
150 pfwheader->version, pfwheader->signature,
Larry Finger8d882bc2015-08-03 15:56:16 -0500151 (int)sizeof(struct rtlwifi_firmware_header));
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500152
Larry Finger8d882bc2015-08-03 15:56:16 -0500153 pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
154 fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500155 } else {
156 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
157 "Firmware no Header, Signature(%#x)\n",
158 pfwheader->signature);
159 }
160
161 if (rtlhal->mac_func_enable) {
162 if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
163 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
164 rtl92ee_firmware_selfreset(hw);
165 }
166 }
167 _rtl92ee_enable_fw_download(hw, true);
168 _rtl92ee_write_fw(hw, version, pfwdata, fwsize);
169 _rtl92ee_enable_fw_download(hw, false);
170
171 err = _rtl92ee_fw_free_to_go(hw);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500172
173 return 0;
174}
175
176static bool _rtl92ee_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
177{
178 struct rtl_priv *rtlpriv = rtl_priv(hw);
179 u8 val_hmetfr;
180 bool result = false;
181
182 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
183 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
184 result = true;
185 return result;
186}
187
188static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
189 u32 cmd_len, u8 *cmdbuffer)
190{
191 struct rtl_priv *rtlpriv = rtl_priv(hw);
192 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
193 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
194 u8 boxnum;
195 u16 box_reg = 0, box_extreg = 0;
196 u8 u1b_tmp;
197 bool isfw_read = false;
198 u8 buf_index = 0;
199 bool bwrite_sucess = false;
200 u8 wait_h2c_limmit = 100;
201 u8 boxcontent[4], boxextcontent[4];
202 u32 h2c_waitcounter = 0;
203 unsigned long flag;
204 u8 idx;
205
206 if (ppsc->dot11_psmode != EACTIVE ||
207 ppsc->inactive_pwrstate == ERFOFF) {
208 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
209 "FillH2CCommand8192E(): Return because RF is off!!!\n");
210 return;
211 }
212
213 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , "come in\n");
214
215 /* 1. Prevent race condition in setting H2C cmd.
216 * (copy from MgntActSet_RF_State().)
217 */
218 while (true) {
219 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
220 if (rtlhal->h2c_setinprogress) {
221 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
222 "H2C set in progress! Wait to set..element_id(%d).\n",
223 element_id);
224
225 while (rtlhal->h2c_setinprogress) {
226 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
227 flag);
228 h2c_waitcounter++;
229 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
230 "Wait 100 us (%d times)...\n",
231 h2c_waitcounter);
232 udelay(100);
233
234 if (h2c_waitcounter > 1000)
235 return;
236 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
237 flag);
238 }
239 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
240 } else {
241 rtlhal->h2c_setinprogress = true;
242 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
243 break;
244 }
245 }
246
247 while (!bwrite_sucess) {
248 /* 2. Find the last BOX number which has been writen. */
249 boxnum = rtlhal->last_hmeboxnum;
250 switch (boxnum) {
251 case 0:
252 box_reg = REG_HMEBOX_0;
253 box_extreg = REG_HMEBOX_EXT_0;
254 break;
255 case 1:
256 box_reg = REG_HMEBOX_1;
257 box_extreg = REG_HMEBOX_EXT_1;
258 break;
259 case 2:
260 box_reg = REG_HMEBOX_2;
261 box_extreg = REG_HMEBOX_EXT_2;
262 break;
263 case 3:
264 box_reg = REG_HMEBOX_3;
265 box_extreg = REG_HMEBOX_EXT_3;
266 break;
267 default:
268 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700269 "switch case %#x not processed\n", boxnum);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500270 break;
271 }
272
273 /* 3. Check if the box content is empty. */
274 isfw_read = false;
275 u1b_tmp = rtl_read_byte(rtlpriv, REG_CR);
276
277 if (u1b_tmp != 0xea) {
278 isfw_read = true;
279 } else {
280 if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS) == 0xea ||
281 rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY) == 0xea)
282 rtl_write_byte(rtlpriv, REG_SYS_CFG1 + 3, 0xff);
283 }
284
285 if (isfw_read) {
286 wait_h2c_limmit = 100;
287 isfw_read = _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
288 while (!isfw_read) {
289 wait_h2c_limmit--;
290 if (wait_h2c_limmit == 0) {
291 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
292 "Waiting too long for FW read clear HMEBox(%d)!!!\n",
293 boxnum);
294 break;
295 }
296 udelay(10);
297 isfw_read =
298 _rtl92ee_check_fw_read_last_h2c(hw, boxnum);
299 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
300 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
301 "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n",
302 boxnum, u1b_tmp);
303 }
304 }
305
306 /* If Fw has not read the last
307 * H2C cmd, break and give up this H2C.
308 */
309 if (!isfw_read) {
310 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
311 "Write H2C reg BOX[%d] fail,Fw don't read.\n",
312 boxnum);
313 break;
314 }
315 /* 4. Fill the H2C cmd into box */
316 memset(boxcontent, 0, sizeof(boxcontent));
317 memset(boxextcontent, 0, sizeof(boxextcontent));
318 boxcontent[0] = element_id;
319 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
320 "Write element_id box_reg(%4x) = %2x\n",
321 box_reg, element_id);
322
323 switch (cmd_len) {
324 case 1:
325 case 2:
326 case 3:
327 /*boxcontent[0] &= ~(BIT(7));*/
328 memcpy((u8 *)(boxcontent) + 1,
329 cmdbuffer + buf_index, cmd_len);
330
331 for (idx = 0; idx < 4; idx++) {
332 rtl_write_byte(rtlpriv, box_reg + idx,
333 boxcontent[idx]);
334 }
335 break;
336 case 4:
337 case 5:
338 case 6:
339 case 7:
340 /*boxcontent[0] |= (BIT(7));*/
341 memcpy((u8 *)(boxextcontent),
342 cmdbuffer + buf_index+3, cmd_len-3);
343 memcpy((u8 *)(boxcontent) + 1,
344 cmdbuffer + buf_index, 3);
345
346 for (idx = 0; idx < 4; idx++) {
347 rtl_write_byte(rtlpriv, box_extreg + idx,
348 boxextcontent[idx]);
349 }
350
351 for (idx = 0; idx < 4; idx++) {
352 rtl_write_byte(rtlpriv, box_reg + idx,
353 boxcontent[idx]);
354 }
355 break;
356 default:
357 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700358 "switch case %#x not processed\n", cmd_len);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500359 break;
360 }
361
362 bwrite_sucess = true;
363
364 rtlhal->last_hmeboxnum = boxnum + 1;
365 if (rtlhal->last_hmeboxnum == 4)
366 rtlhal->last_hmeboxnum = 0;
367
368 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD ,
369 "pHalData->last_hmeboxnum = %d\n",
370 rtlhal->last_hmeboxnum);
371 }
372
373 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
374 rtlhal->h2c_setinprogress = false;
375 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
376
377 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD , "go out\n");
378}
379
380void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw,
381 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
382{
383 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
384 u32 tmp_cmdbuf[2];
385
386 if (!rtlhal->fw_ready) {
Larry Finger531940f2016-12-15 12:22:57 -0600387 WARN_ONCE(true,
388 "rtl8192ee: error H2C cmd because of Fw download fail!!!\n");
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500389 return;
390 }
391
392 memset(tmp_cmdbuf, 0, 8);
393 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
394 _rtl92ee_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
395}
396
397void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw)
398{
399 u8 u1b_tmp;
400 struct rtl_priv *rtlpriv = rtl_priv(hw);
401
402 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
403 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
404
405 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
406 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
407
408 udelay(50);
409
410 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
411 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0)));
412
413 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
414 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2)));
415
416 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD ,
417 " _8051Reset92E(): 8051 reset success .\n");
418}
419
420void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
421{
422 struct rtl_priv *rtlpriv = rtl_priv(hw);
423 u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 };
424 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
Ping-Ke Shih42213f22017-06-18 11:12:49 -0500425 u8 rlbm, power_state = 0, byte5 = 0;
426 u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
Ping-Ke Shih54685f92017-06-18 11:12:46 -0500427 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
Ping-Ke Shih42213f22017-06-18 11:12:49 -0500428 bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
429 btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
Ping-Ke Shih135f4fb2017-06-21 12:15:31 -0500430 bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
431 btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
432
433 if (bt_ctrl_lps)
434 mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500435
Ping-Ke Shih42213f22017-06-18 11:12:49 -0500436 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
437 mode, bt_ctrl_lps);
438
439 switch (mode) {
440 case FW_PS_MIN_MODE:
441 rlbm = 0;
442 awake_intvl = 2;
443 break;
444 case FW_PS_MAX_MODE:
445 rlbm = 1;
446 awake_intvl = 2;
447 break;
448 case FW_PS_DTIM_MODE:
449 rlbm = 2;
450 awake_intvl = ppsc->reg_max_lps_awakeintvl;
451 /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
452 * is only used in swlps.
453 */
454 break;
455 default:
456 rlbm = 2;
457 awake_intvl = 4;
458 break;
459 }
460
461 if (rtlpriv->mac80211.p2p) {
462 awake_intvl = 2;
463 rlbm = 1;
464 }
465
466 if (mode == FW_PS_ACTIVE_MODE) {
467 byte5 = 0x40;
468 power_state = FW_PWR_STATE_ACTIVE;
469 } else {
470 if (bt_ctrl_lps) {
471 byte5 = btc_ops->btc_get_lps_val(rtlpriv);
472 power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
473
474 if ((rlbm == 2) && (byte5 & BIT(4))) {
475 /* Keep awake interval to 1 to prevent from
476 * decreasing coex performance
477 */
478 awake_intvl = 2;
479 rlbm = 2;
480 }
481 } else {
482 byte5 = 0x40;
483 power_state = FW_PWR_STATE_RF_OFF;
484 }
485 }
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500486
487 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500488 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
489 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
Ping-Ke Shih135f4fb2017-06-21 12:15:31 -0500490 bt_ctrl_lps ? 0 :
491 ((rtlpriv->mac80211.p2p) ?
492 ppsc->smart_ps : 1));
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500493 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
Ping-Ke Shih42213f22017-06-18 11:12:49 -0500494 awake_intvl);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500495 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500496 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
Ping-Ke Shih54685f92017-06-18 11:12:46 -0500497 SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500498
499 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
500 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
501 u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH);
Ping-Ke Shih54685f92017-06-18 11:12:46 -0500502 if (rtlpriv->cfg->ops->get_btc_status())
503 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
504 H2C_92E_PWEMODE_LENGTH);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500505 rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH,
506 u1_h2c_set_pwrmode);
507}
508
509void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
510{
511 u8 parm[3] = { 0 , 0 , 0 };
512 /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
513 * bit1=0-->update Media Status to MACID
514 * bit1=1-->update Media Status from MACID to MACID_End
515 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
516 * parm[2]: MACID_End
517 */
518
519 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
520 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
521
522 rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
523}
524
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500525#define BEACON_PG 0 /* ->1 */
526#define PSPOLL_PG 2
527#define NULL_PG 3
528#define PROBERSP_PG 4 /* ->5 */
Ping-Ke Shih74a7dfb2017-02-23 11:19:57 -0600529#define QOS_NULL_PG 6
530#define BT_QOS_NULL_PG 7
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500531
Ping-Ke Shih74a7dfb2017-02-23 11:19:57 -0600532#define TOTAL_RESERVED_PKT_LEN 1024
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500533
534static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
535 /* page 0 beacon */
536 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
537 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
538 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
541 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
542 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
543 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
544 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
545 0x09, 0x03, 0xFF, 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, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
549 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
550 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
551 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
552
553 /* page 1 beacon */
554 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 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
571 /* page 2 ps-poll */
572 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
573 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588
589 /* page 3 null */
590 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
591 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
592 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606
607 /* page 4 probe_resp */
608 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
609 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
610 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
611 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
612 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
613 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
614 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
615 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
616 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
617 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
618 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
622 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624
625 /* page 5 probe_resp */
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Ping-Ke Shih74a7dfb2017-02-23 11:19:57 -0600633 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638
639 /* page 6 qos null data */
640 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
641 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
642 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
652 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656
657 /* page 7 BT-qos null data */
658 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
659 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
660 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678};
679
680void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
681{
682 struct rtl_priv *rtlpriv = rtl_priv(hw);
683 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
684 struct sk_buff *skb = NULL;
685
686 u32 totalpacketlen;
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500687 u8 u1rsvdpageloc[5] = { 0 };
688 bool b_dlok = false;
689
690 u8 *beacon;
691 u8 *p_pspoll;
692 u8 *nullfunc;
693 u8 *p_probersp;
Ping-Ke Shih74a7dfb2017-02-23 11:19:57 -0600694 u8 *qosnull;
695 u8 *btqosnull;
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500696 /*---------------------------------------------------------
697 * (1) beacon
698 *---------------------------------------------------------
699 */
700 beacon = &reserved_page_packet[BEACON_PG * 128];
701 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
702 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
703
704 /*-------------------------------------------------------
705 * (2) ps-poll
706 *--------------------------------------------------------
707 */
708 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
709 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
710 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
711 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
712
713 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
714
715 /*--------------------------------------------------------
716 * (3) null data
717 *---------------------------------------------------------
718 */
719 nullfunc = &reserved_page_packet[NULL_PG * 128];
720 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
721 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
722 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
723
724 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
725
726 /*---------------------------------------------------------
727 * (4) probe response
728 *----------------------------------------------------------
729 */
730 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
731 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
732 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
733 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
734
735 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
736
Ping-Ke Shih74a7dfb2017-02-23 11:19:57 -0600737 /*---------------------------------------------------------
738 * (5) QoS null data
739 *----------------------------------------------------------
740 */
741 qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
742 SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
743 SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
744 SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
745
746 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
747
748 /*---------------------------------------------------------
749 * (6) BT QoS null data
750 *----------------------------------------------------------
751 */
752 btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
753 SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
754 SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
755 SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
756
757 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
758
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500759 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
760
761 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
762 "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
763 &reserved_page_packet[0], totalpacketlen);
764 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
765 "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
766 u1rsvdpageloc, 3);
767
768 skb = dev_alloc_skb(totalpacketlen);
yuan linyuad941e62017-06-18 22:49:30 +0800769 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500770
Troy Tanb661a5d2015-01-20 11:01:22 -0600771 b_dlok = true;
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500772
773 if (b_dlok) {
774 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
775 "Set RSVD page location to Fw.\n");
776 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
777 "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
778 rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE,
779 sizeof(u1rsvdpageloc), u1rsvdpageloc);
780 } else {
781 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
782 "Set RSVD page location to Fw FAIL!!!!!!.\n");
783 }
784}
785
786/*Shoud check FW support p2p or not.*/
787static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
788{
789 u8 u1_ctwindow_period[1] = {ctwindow};
790
791 rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
792}
793
794void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
795{
796 struct rtl_priv *rtlpriv = rtl_priv(hw);
797 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
798 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
799 struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
800 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
801 u8 i;
802 u16 ctwindow;
803 u32 start_time, tsf_low;
804
805 switch (p2p_ps_state) {
806 case P2P_PS_DISABLE:
807 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_DISABLE\n");
808 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
809 break;
810 case P2P_PS_ENABLE:
811 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_ENABLE\n");
812 /* update CTWindow value. */
813 if (p2pinfo->ctwindow > 0) {
814 p2p_ps_offload->ctwindow_en = 1;
815 ctwindow = p2pinfo->ctwindow;
816 rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow);
817 }
818 /* hw only support 2 set of NoA */
819 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
820 /* To control the register setting for which NOA*/
821 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
822 if (i == 0)
823 p2p_ps_offload->noa0_en = 1;
824 else
825 p2p_ps_offload->noa1_en = 1;
826 /* config P2P NoA Descriptor Register */
827 rtl_write_dword(rtlpriv, 0x5E0,
828 p2pinfo->noa_duration[i]);
829 rtl_write_dword(rtlpriv, 0x5E4,
830 p2pinfo->noa_interval[i]);
831
832 /*Get Current TSF value */
833 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
834
835 start_time = p2pinfo->noa_start_time[i];
836 if (p2pinfo->noa_count_type[i] != 1) {
837 while (start_time <= (tsf_low + (50 * 1024))) {
838 start_time += p2pinfo->noa_interval[i];
839 if (p2pinfo->noa_count_type[i] != 255)
840 p2pinfo->noa_count_type[i]--;
841 }
842 }
843 rtl_write_dword(rtlpriv, 0x5E8, start_time);
844 rtl_write_dword(rtlpriv, 0x5EC,
845 p2pinfo->noa_count_type[i]);
846 }
847 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
848 /* rst p2p circuit */
849 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
850 p2p_ps_offload->offload_en = 1;
851
852 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
853 p2p_ps_offload->role = 1;
854 p2p_ps_offload->allstasleep = 0;
855 } else {
856 p2p_ps_offload->role = 0;
857 }
858 p2p_ps_offload->discovery = 0;
859 }
860 break;
861 case P2P_PS_SCAN:
862 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN\n");
863 p2p_ps_offload->discovery = 1;
864 break;
865 case P2P_PS_SCAN_DONE:
866 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN_DONE\n");
867 p2p_ps_offload->discovery = 0;
868 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
869 break;
870 default:
871 break;
872 }
873 rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1,
874 (u8 *)p2p_ps_offload);
875}
876
877static void _rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw,
878 u8 *cmd_buf, u8 cmd_len)
879{
880 u8 rate = cmd_buf[0] & 0x3F;
881 bool collision_state = cmd_buf[3] & BIT(0);
882
883 rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state);
884}
885
Ping-Ke Shihcceb0a52017-02-06 21:30:08 -0600886void rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
887 u8 c2h_cmd_len, u8 *tmp_buf)
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500888{
889 struct rtl_priv *rtlpriv = rtl_priv(hw);
Ping-Ke Shih6aad6072017-07-02 13:12:31 -0500890 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500891
892 switch (c2h_cmd_id) {
893 case C2H_8192E_DBG:
894 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
895 "[C2H], C2H_8723BE_DBG!!\n");
896 break;
897 case C2H_8192E_TXBF:
898 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
899 "[C2H], C2H_8192E_TXBF!!\n");
900 break;
901 case C2H_8192E_TX_REPORT:
902 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE ,
903 "[C2H], C2H_8723BE_TX_REPORT!\n");
Ping-Ke Shih84795802017-06-18 11:12:44 -0500904 rtl_tx_report_handler(hw, tmp_buf, c2h_cmd_len);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500905 break;
906 case C2H_8192E_BT_INFO:
907 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
908 "[C2H], C2H_8723BE_BT_INFO!!\n");
Ping-Ke Shih6aad6072017-07-02 13:12:31 -0500909 if (rtlpriv->cfg->ops->get_btc_status())
910 btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
911 c2h_cmd_len);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500912 break;
913 case C2H_8192E_BT_MP:
914 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
915 "[C2H], C2H_8723BE_BT_MP!!\n");
Ping-Ke Shih6aad6072017-07-02 13:12:31 -0500916 if (rtlpriv->cfg->ops->get_btc_status())
917 btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
918 c2h_cmd_len);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500919 break;
920 case C2H_8192E_RA_RPT:
921 _rtl92ee_c2h_ra_report_handler(hw, tmp_buf, c2h_cmd_len);
922 break;
923 default:
924 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
Masanari Iidaad480132015-04-27 23:14:58 +0900925 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500926 break;
927 }
928}
929
930void rtl92ee_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
931{
932 struct rtl_priv *rtlpriv = rtl_priv(hw);
933 u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
934 u8 *tmp_buf = NULL;
935
936 c2h_cmd_id = buffer[0];
937 c2h_cmd_seq = buffer[1];
938 c2h_cmd_len = len - 2;
939 tmp_buf = buffer + 2;
940
941 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
942 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
943 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
944
945 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
946 "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
947
Ping-Ke Shihcceb0a52017-02-06 21:30:08 -0600948 switch (c2h_cmd_id) {
949 case C2H_8192E_BT_INFO:
950 case C2H_8192E_BT_MP:
951 rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
952 break;
953 default:
954 rtl92ee_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
955 tmp_buf);
956 break;
957 }
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500958}