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;
426 
427 	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , "FW LPS mode = %d\n", mode);
428 
429 	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
430 	rlbm = 0;/*YJ,temp,120316. FW now not support RLBM=2.*/
431 	SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
432 	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
433 					 (rtlpriv->mac80211.p2p) ?
434 					 ppsc->smart_ps : 1);
435 	SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
436 					       ppsc->reg_max_lps_awakeintvl);
437 	SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
438 	if (mode == FW_PS_ACTIVE_MODE)
439 		power_state |= FW_PWR_STATE_ACTIVE;
440 	else
441 		power_state |= FW_PWR_STATE_RF_OFF;
442 	SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
443 
444 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
445 		      "rtl92c_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
446 		      u1_h2c_set_pwrmode, H2C_92E_PWEMODE_LENGTH);
447 	rtl92ee_fill_h2c_cmd(hw, H2C_92E_SETPWRMODE, H2C_92E_PWEMODE_LENGTH,
448 			     u1_h2c_set_pwrmode);
449 }
450 
451 void rtl92ee_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
452 {
453 	u8 parm[3] = { 0 , 0 , 0 };
454 	/* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
455 	 *          bit1=0-->update Media Status to MACID
456 	 *          bit1=1-->update Media Status from MACID to MACID_End
457 	 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
458 	 * parm[2]: MACID_End
459 	 */
460 
461 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
462 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
463 
464 	rtl92ee_fill_h2c_cmd(hw, H2C_92E_MSRRPT, 3, parm);
465 }
466 
467 #define BEACON_PG		0 /* ->1 */
468 #define PSPOLL_PG		2
469 #define NULL_PG			3
470 #define PROBERSP_PG		4 /* ->5 */
471 #define QOS_NULL_PG		6
472 #define BT_QOS_NULL_PG	7
473 
474 #define TOTAL_RESERVED_PKT_LEN	1024
475 
476 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
477 	/* page 0 beacon */
478 	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
479 	0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
480 	0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
481 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 	0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
483 	0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
484 	0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
485 	0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
486 	0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
487 	0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
488 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 	0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
491 	0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
492 	0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
493 	0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
494 
495 	/* page 1 beacon */
496 	0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
497 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 	0x10, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
508 	0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
509 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512 
513 	/* page 2  ps-poll */
514 	0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
515 	0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
516 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
525 	0x18, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
526 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
527 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530 
531 	/* page 3  null */
532 	0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
533 	0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
534 	0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
535 	0x00, 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 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 	0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 	0x72, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
544 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
545 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 
549 	/* page 4  probe_resp */
550 	0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
551 	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
552 	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
553 	0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
554 	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
555 	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
556 	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
557 	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
558 	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
559 	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
560 	0x03, 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 	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
564 	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 
567 	/* page 5  probe_resp */
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 	0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
576 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
577 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 
581 	/* page 6 qos null data */
582 	0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
583 	0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
584 	0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 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 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 	0x1A, 0x00, 0x28, 0x8C, 0x00, 0x12, 0x00, 0x00,
594 	0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
595 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 
599 	/* page 7 BT-qos null data */
600 	0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
601 	0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
602 	0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
603 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 	0x00, 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 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 	0x00, 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 	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 };
621 
622 void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
623 {
624 	struct rtl_priv *rtlpriv = rtl_priv(hw);
625 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
626 	struct sk_buff *skb = NULL;
627 
628 	u32 totalpacketlen;
629 	u8 u1rsvdpageloc[5] = { 0 };
630 	bool b_dlok = false;
631 
632 	u8 *beacon;
633 	u8 *p_pspoll;
634 	u8 *nullfunc;
635 	u8 *p_probersp;
636 	u8 *qosnull;
637 	u8 *btqosnull;
638 	/*---------------------------------------------------------
639 	 *			(1) beacon
640 	 *---------------------------------------------------------
641 	 */
642 	beacon = &reserved_page_packet[BEACON_PG * 128];
643 	SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
644 	SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
645 
646 	/*-------------------------------------------------------
647 	 *			(2) ps-poll
648 	 *--------------------------------------------------------
649 	 */
650 	p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
651 	SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
652 	SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
653 	SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
654 
655 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1rsvdpageloc, PSPOLL_PG);
656 
657 	/*--------------------------------------------------------
658 	 *			(3) null data
659 	 *---------------------------------------------------------
660 	 */
661 	nullfunc = &reserved_page_packet[NULL_PG * 128];
662 	SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
663 	SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
664 	SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
665 
666 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1rsvdpageloc, NULL_PG);
667 
668 	/*---------------------------------------------------------
669 	 *			(4) probe response
670 	 *----------------------------------------------------------
671 	 */
672 	p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
673 	SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
674 	SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
675 	SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
676 
677 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1rsvdpageloc, PROBERSP_PG);
678 
679 	/*---------------------------------------------------------
680 	 *			(5) QoS null data
681 	 *----------------------------------------------------------
682 	 */
683 	qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
684 	SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
685 	SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
686 	SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
687 
688 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1rsvdpageloc, QOS_NULL_PG);
689 
690 	/*---------------------------------------------------------
691 	 *			(6) BT QoS null data
692 	 *----------------------------------------------------------
693 	 */
694 	btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
695 	SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
696 	SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
697 	SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
698 
699 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1rsvdpageloc, BT_QOS_NULL_PG);
700 
701 	totalpacketlen = TOTAL_RESERVED_PKT_LEN;
702 
703 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
704 		      "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
705 		      &reserved_page_packet[0], totalpacketlen);
706 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
707 		      "rtl92ee_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
708 		      u1rsvdpageloc, 3);
709 
710 	skb = dev_alloc_skb(totalpacketlen);
711 	memcpy((u8 *)skb_put(skb, totalpacketlen),
712 	       &reserved_page_packet, totalpacketlen);
713 
714 	b_dlok = true;
715 
716 	if (b_dlok) {
717 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
718 			 "Set RSVD page location to Fw.\n");
719 		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD ,
720 			      "H2C_RSVDPAGE:\n", u1rsvdpageloc, 3);
721 		rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE,
722 				     sizeof(u1rsvdpageloc), u1rsvdpageloc);
723 	} else {
724 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
725 			 "Set RSVD page location to Fw FAIL!!!!!!.\n");
726 	}
727 }
728 
729 /*Shoud check FW support p2p or not.*/
730 static void rtl92ee_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, u8 ctwindow)
731 {
732 	u8 u1_ctwindow_period[1] = {ctwindow};
733 
734 	rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_CTW_CMD, 1, u1_ctwindow_period);
735 }
736 
737 void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
738 {
739 	struct rtl_priv *rtlpriv = rtl_priv(hw);
740 	struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
741 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
742 	struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
743 	struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
744 	u8 i;
745 	u16 ctwindow;
746 	u32 start_time, tsf_low;
747 
748 	switch (p2p_ps_state) {
749 	case P2P_PS_DISABLE:
750 		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_DISABLE\n");
751 		memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
752 		break;
753 	case P2P_PS_ENABLE:
754 		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_ENABLE\n");
755 		/* update CTWindow value. */
756 		if (p2pinfo->ctwindow > 0) {
757 			p2p_ps_offload->ctwindow_en = 1;
758 			ctwindow = p2pinfo->ctwindow;
759 			rtl92ee_set_p2p_ctw_period_cmd(hw, ctwindow);
760 		}
761 		/* hw only support 2 set of NoA */
762 		for (i = 0 ; i < p2pinfo->noa_num ; i++) {
763 			/* To control the register setting for which NOA*/
764 			rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
765 			if (i == 0)
766 				p2p_ps_offload->noa0_en = 1;
767 			else
768 				p2p_ps_offload->noa1_en = 1;
769 			/* config P2P NoA Descriptor Register */
770 			rtl_write_dword(rtlpriv, 0x5E0,
771 					p2pinfo->noa_duration[i]);
772 			rtl_write_dword(rtlpriv, 0x5E4,
773 					p2pinfo->noa_interval[i]);
774 
775 			/*Get Current TSF value */
776 			tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
777 
778 			start_time = p2pinfo->noa_start_time[i];
779 			if (p2pinfo->noa_count_type[i] != 1) {
780 				while (start_time <= (tsf_low + (50 * 1024))) {
781 					start_time += p2pinfo->noa_interval[i];
782 					if (p2pinfo->noa_count_type[i] != 255)
783 						p2pinfo->noa_count_type[i]--;
784 				}
785 			}
786 			rtl_write_dword(rtlpriv, 0x5E8, start_time);
787 			rtl_write_dword(rtlpriv, 0x5EC,
788 					p2pinfo->noa_count_type[i]);
789 		}
790 		if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
791 			/* rst p2p circuit */
792 			rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, BIT(4));
793 			p2p_ps_offload->offload_en = 1;
794 
795 			if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) {
796 				p2p_ps_offload->role = 1;
797 				p2p_ps_offload->allstasleep = 0;
798 			} else {
799 				p2p_ps_offload->role = 0;
800 			}
801 			p2p_ps_offload->discovery = 0;
802 		}
803 		break;
804 	case P2P_PS_SCAN:
805 		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN\n");
806 		p2p_ps_offload->discovery = 1;
807 		break;
808 	case P2P_PS_SCAN_DONE:
809 		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "P2P_PS_SCAN_DONE\n");
810 		p2p_ps_offload->discovery = 0;
811 		p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
812 		break;
813 	default:
814 		break;
815 	}
816 	rtl92ee_fill_h2c_cmd(hw, H2C_92E_P2P_PS_OFFLOAD, 1,
817 			     (u8 *)p2p_ps_offload);
818 }
819 
820 static void _rtl92ee_c2h_ra_report_handler(struct ieee80211_hw *hw,
821 					   u8 *cmd_buf, u8 cmd_len)
822 {
823 	u8 rate = cmd_buf[0] & 0x3F;
824 	bool collision_state = cmd_buf[3] & BIT(0);
825 
826 	rtl92ee_dm_dynamic_arfb_select(hw, rate, collision_state);
827 }
828 
829 void rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
830 				 u8 c2h_cmd_len, u8 *tmp_buf)
831 {
832 	struct rtl_priv *rtlpriv = rtl_priv(hw);
833 
834 	switch (c2h_cmd_id) {
835 	case C2H_8192E_DBG:
836 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
837 			 "[C2H], C2H_8723BE_DBG!!\n");
838 		break;
839 	case C2H_8192E_TXBF:
840 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
841 			 "[C2H], C2H_8192E_TXBF!!\n");
842 		break;
843 	case C2H_8192E_TX_REPORT:
844 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE ,
845 			 "[C2H], C2H_8723BE_TX_REPORT!\n");
846 		break;
847 	case C2H_8192E_BT_INFO:
848 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
849 			 "[C2H], C2H_8723BE_BT_INFO!!\n");
850 		rtlpriv->btcoexist.btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
851 							      c2h_cmd_len);
852 		break;
853 	case C2H_8192E_BT_MP:
854 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
855 			 "[C2H], C2H_8723BE_BT_MP!!\n");
856 		break;
857 	case C2H_8192E_RA_RPT:
858 		_rtl92ee_c2h_ra_report_handler(hw, tmp_buf, c2h_cmd_len);
859 		break;
860 	default:
861 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
862 			 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
863 		break;
864 	}
865 }
866 
867 void rtl92ee_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
868 {
869 	struct rtl_priv *rtlpriv = rtl_priv(hw);
870 	u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
871 	u8 *tmp_buf = NULL;
872 
873 	c2h_cmd_id = buffer[0];
874 	c2h_cmd_seq = buffer[1];
875 	c2h_cmd_len = len - 2;
876 	tmp_buf = buffer + 2;
877 
878 	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
879 		 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
880 		 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
881 
882 	RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
883 		      "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
884 
885 	switch (c2h_cmd_id) {
886 	case C2H_8192E_BT_INFO:
887 	case C2H_8192E_BT_MP:
888 		rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
889 		break;
890 	default:
891 		rtl92ee_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
892 					    tmp_buf);
893 		break;
894 	}
895 }
896