]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
Merge tag 'wireless-drivers-next-for-davem-2017-06-25' of git://git.kernel.org/pub...
[mirror_ubuntu-bionic-kernel.git] / drivers / net / wireless / realtek / rtlwifi / rtl8192ee / fw.c
1 /******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26 #include "../wifi.h"
27 #include "../pci.h"
28 #include "../base.h"
29 #include "../core.h"
30 #include "../efuse.h"
31 #include "reg.h"
32 #include "def.h"
33 #include "fw.h"
34 #include "dm.h"
35
36 static 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
52 static 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
63 rtl_fill_dummy(bufferptr, &size);
64
65 pagenums = size / FW_8192C_PAGE_SIZE;
66 remainsize = size % FW_8192C_PAGE_SIZE;
67
68 if (pagenums > 8)
69 pr_err("Page numbers should not greater then 8\n");
70
71 for (page = 0; page < pagenums; page++) {
72 offset = page * FW_8192C_PAGE_SIZE;
73 rtl_fw_page_write(hw, page, (bufferptr + offset),
74 FW_8192C_PAGE_SIZE);
75 udelay(2);
76 }
77
78 if (remainsize) {
79 offset = pagenums * FW_8192C_PAGE_SIZE;
80 page = pagenums;
81 rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
82 }
83 }
84
85 static 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) {
98 pr_err("chksum report fail! REG_MCUFWDL:0x%08x\n",
99 value32);
100 goto exit;
101 }
102 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);
112 if (value32 & WINTINI_RDY)
113 return 0;
114
115 udelay(FW_8192C_POLLING_DELAY*10);
116
117 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
118
119 pr_err("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n",
120 value32, counter);
121
122 exit:
123 return err;
124 }
125
126 int 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));
130 struct rtlwifi_firmware_header *pfwheader;
131 u8 *pfwdata;
132 u32 fwsize;
133 int err;
134 enum version_8192e version = rtlhal->version;
135
136 if (!rtlhal->pfirmware)
137 return 1;
138
139 pfwheader = (struct rtlwifi_firmware_header *)rtlhal->pfirmware;
140 rtlhal->fw_version = le16_to_cpu(pfwheader->version);
141 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,
151 (int)sizeof(struct rtlwifi_firmware_header));
152
153 pfwdata = pfwdata + sizeof(struct rtlwifi_firmware_header);
154 fwsize = fwsize - sizeof(struct rtlwifi_firmware_header);
155 } 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);
172
173 return 0;
174 }
175
176 static 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
188 static 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,
269 "switch case %#x not processed\n", boxnum);
270 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,
358 "switch case %#x not processed\n", cmd_len);
359 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
380 void 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) {
387 WARN_ONCE(true,
388 "rtl8192ee: error H2C cmd because of Fw download fail!!!\n");
389 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
397 void 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
420 void 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));
425 u8 rlbm, power_state = 0, byte5 = 0;
426 u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
427 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
428 bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
429 btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
430
431 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
432 mode, bt_ctrl_lps);
433
434 switch (mode) {
435 case FW_PS_MIN_MODE:
436 rlbm = 0;
437 awake_intvl = 2;
438 break;
439 case FW_PS_MAX_MODE:
440 rlbm = 1;
441 awake_intvl = 2;
442 break;
443 case FW_PS_DTIM_MODE:
444 rlbm = 2;
445 awake_intvl = ppsc->reg_max_lps_awakeintvl;
446 /* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
447 * is only used in swlps.
448 */
449 break;
450 default:
451 rlbm = 2;
452 awake_intvl = 4;
453 break;
454 }
455
456 if (rtlpriv->mac80211.p2p) {
457 awake_intvl = 2;
458 rlbm = 1;
459 }
460
461 if (mode == FW_PS_ACTIVE_MODE) {
462 byte5 = 0x40;
463 power_state = FW_PWR_STATE_ACTIVE;
464 } else {
465 if (bt_ctrl_lps) {
466 byte5 = btc_ops->btc_get_lps_val(rtlpriv);
467 power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
468
469 if ((rlbm == 2) && (byte5 & BIT(4))) {
470 /* Keep awake interval to 1 to prevent from
471 * decreasing coex performance
472 */
473 awake_intvl = 2;
474 rlbm = 2;
475 }
476 } else {
477 byte5 = 0x40;
478 power_state = FW_PWR_STATE_RF_OFF;
479 }
480 }
481
482 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
483 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
484 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
485 (rtlpriv->mac80211.p2p) ?
486 ppsc->smart_ps : 1);
487 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
488 awake_intvl);
489 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
490 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
491 SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
492
493 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
494 "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
495 u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH);
496 if (rtlpriv->cfg->ops->get_btc_status())
497 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
498 H2C_92E_PWEMODE_LENGTH);
499 rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH,
500 u1_h2c_set_pwrmode);
501 }
502
503 void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
504 {
505 u8 parm[3] = { 0 , 0 , 0 };
506 /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
507 * bit1=0-->update Media Status to MACID
508 * bit1=1-->update Media Status from MACID to MACID_End
509 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
510 * parm[2]: MACID_End
511 */
512
513 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
514 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
515
516 rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
517 }
518
519 #define BEACON_PG 0 /* ->1 */
520 #define PSPOLL_PG 2
521 #define NULL_PG 3
522 #define PROBERSP_PG 4 /* ->5 */
523 #define QOS_NULL_PG 6
524 #define BT_QOS_NULL_PG 7
525
526 #define TOTAL_RESERVED_PKT_LEN 1024
527
528 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
529 /* page 0 beacon */
530 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
531 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
532 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
535 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
536 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
537 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
538 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
539 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
543 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
544 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
545 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
546
547 /* page 1 beacon */
548 0x00, 0x50, 0xF2, 0x02, 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 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 0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 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
565 /* page 2 ps-poll */
566 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
567 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582
583 /* page 3 null */
584 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
585 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
586 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600
601 /* page 4 probe_resp */
602 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
603 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
604 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
605 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
606 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
607 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
608 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
609 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
610 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
611 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
612 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
616 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618
619 /* page 5 probe_resp */
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 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632
633 /* page 6 qos null data */
634 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
635 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
636 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
646 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650
651 /* page 7 BT-qos null data */
652 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
653 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
654 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
669 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 };
673
674 void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
675 {
676 struct rtl_priv *rtlpriv = rtl_priv(hw);
677 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
678 struct sk_buff *skb = NULL;
679
680 u32 totalpacketlen;
681 u8 u1rsvdpageloc[5] = { 0 };
682 bool b_dlok = false;
683
684 u8 *beacon;
685 u8 *p_pspoll;
686 u8 *nullfunc;
687 u8 *p_probersp;
688 u8 *qosnull;
689 u8 *btqosnull;
690 /*---------------------------------------------------------
691 * (1) beacon
692 *---------------------------------------------------------
693 */
694 beacon = &reserved_page_packet[BEACON_PG * 128];
695 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
696 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
697
698 /*-------------------------------------------------------
699 * (2) ps-poll
700 *--------------------------------------------------------
701 */
702 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
703 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
704 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
705 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
706
707 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
708
709 /*--------------------------------------------------------
710 * (3) null data
711 *---------------------------------------------------------
712 */
713 nullfunc = &reserved_page_packet[NULL_PG * 128];
714 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
715 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
716 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
717
718 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
719
720 /*---------------------------------------------------------
721 * (4) probe response
722 *----------------------------------------------------------
723 */
724 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
725 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
726 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
727 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
728
729 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
730
731 /*---------------------------------------------------------
732 * (5) QoS null data
733 *----------------------------------------------------------
734 */
735 qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
736 SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
737 SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
738 SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
739
740 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
741
742 /*---------------------------------------------------------
743 * (6) BT QoS null data
744 *----------------------------------------------------------
745 */
746 btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
747 SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
748 SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
749 SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
750
751 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
752
753 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
754
755 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
756 "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
757 &reserved_page_packet[0], totalpacketlen);
758 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
759 "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
760 u1rsvdpageloc, 3);
761
762 skb = dev_alloc_skb(totalpacketlen);
763 skb_put_data(skb, &reserved_page_packet, totalpacketlen);
764
765 b_dlok = true;
766
767 if (b_dlok) {
768 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
769 "Set RSVD page location to Fw.\n");
770 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
771 "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
772 rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE,
773 sizeof(u1rsvdpageloc), u1rsvdpageloc);
774 } else {
775 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
776 "Set RSVD page location to Fw FAIL!!!!!!.\n");
777 }
778 }
779
780 /*Shoud check FW support p2p or not.*/
781 static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
782 {
783 u8 u1_ctwindow_period[1] = {ctwindow};
784
785 rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
786 }
787
788 void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
789 {
790 struct rtl_priv *rtlpriv = rtl_priv(hw);
791 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
792 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
793 struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
794 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
795 u8 i;
796 u16 ctwindow;
797 u32 start_time, tsf_low;
798
799 switch (p2p_ps_state) {
800 case P2P_PS_DISABLE:
801 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_DISABLE\n");
802 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
803 break;
804 case P2P_PS_ENABLE:
805 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_ENABLE\n");
806 /* update CTWindow value. */
807 if (p2pinfo->ctwindow > 0) {
808 p2p_ps_offload->ctwindow_en = 1;
809 ctwindow = p2pinfo->ctwindow;
810 rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow);
811 }
812 /* hw only support 2 set of NoA */
813 for (i = 0 ; i < p2pinfo->noa_num ; i++) {
814 /* To control the register setting for which NOA*/
815 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
816 if (i == 0)
817 p2p_ps_offload->noa0_en = 1;
818 else
819 p2p_ps_offload->noa1_en = 1;
820 /* config P2P NoA Descriptor Register */
821 rtl_write_dword(rtlpriv, 0x5E0,
822 p2pinfo->noa_duration[i]);
823 rtl_write_dword(rtlpriv, 0x5E4,
824 p2pinfo->noa_interval[i]);
825
826 /*Get Current TSF value */
827 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
828
829 start_time = p2pinfo->noa_start_time[i];
830 if (p2pinfo->noa_count_type[i] != 1) {
831 while (start_time <= (tsf_low + (50 * 1024))) {
832 start_time += p2pinfo->noa_interval[i];
833 if (p2pinfo->noa_count_type[i] != 255)
834 p2pinfo->noa_count_type[i]--;
835 }
836 }
837 rtl_write_dword(rtlpriv, 0x5E8, start_time);
838 rtl_write_dword(rtlpriv, 0x5EC,
839 p2pinfo->noa_count_type[i]);
840 }
841 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
842 /* rst p2p circuit */
843 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
844 p2p_ps_offload->offload_en = 1;
845
846 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
847 p2p_ps_offload->role = 1;
848 p2p_ps_offload->allstasleep = 0;
849 } else {
850 p2p_ps_offload->role = 0;
851 }
852 p2p_ps_offload->discovery = 0;
853 }
854 break;
855 case P2P_PS_SCAN:
856 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN\n");
857 p2p_ps_offload->discovery = 1;
858 break;
859 case P2P_PS_SCAN_DONE:
860 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN_DONE\n");
861 p2p_ps_offload->discovery = 0;
862 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
863 break;
864 default:
865 break;
866 }
867 rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1,
868 (u8 *)p2p_ps_offload);
869 }
870
871 static void _rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw,
872 u8 *cmd_buf, u8 cmd_len)
873 {
874 u8 rate = cmd_buf[0] & 0x3F;
875 bool collision_state = cmd_buf[3] & BIT(0);
876
877 rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state);
878 }
879
880 void rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
881 u8 c2h_cmd_len, u8 *tmp_buf)
882 {
883 struct rtl_priv *rtlpriv = rtl_priv(hw);
884
885 switch (c2h_cmd_id) {
886 case C2H_8192E_DBG:
887 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
888 "[C2H], C2H_8723BE_DBG!!\n");
889 break;
890 case C2H_8192E_TXBF:
891 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
892 "[C2H], C2H_8192E_TXBF!!\n");
893 break;
894 case C2H_8192E_TX_REPORT:
895 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE ,
896 "[C2H], C2H_8723BE_TX_REPORT!\n");
897 rtl_tx_report_handler(hw, tmp_buf, c2h_cmd_len);
898 break;
899 case C2H_8192E_BT_INFO:
900 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
901 "[C2H], C2H_8723BE_BT_INFO!!\n");
902 rtlpriv->btcoexist.btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
903 c2h_cmd_len);
904 break;
905 case C2H_8192E_BT_MP:
906 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
907 "[C2H], C2H_8723BE_BT_MP!!\n");
908 break;
909 case C2H_8192E_RA_RPT:
910 _rtl92ee_c2h_ra_report_handler(hw, tmp_buf, c2h_cmd_len);
911 break;
912 default:
913 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
914 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
915 break;
916 }
917 }
918
919 void rtl92ee_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
920 {
921 struct rtl_priv *rtlpriv = rtl_priv(hw);
922 u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
923 u8 *tmp_buf = NULL;
924
925 c2h_cmd_id = buffer[0];
926 c2h_cmd_seq = buffer[1];
927 c2h_cmd_len = len - 2;
928 tmp_buf = buffer + 2;
929
930 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
931 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
932 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
933
934 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
935 "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
936
937 switch (c2h_cmd_id) {
938 case C2H_8192E_BT_INFO:
939 case C2H_8192E_BT_MP:
940 rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
941 break;
942 default:
943 rtl92ee_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
944 tmp_buf);
945 break;
946 }
947 }