1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2016  Realtek Corporation.
5  *
6  * Contact Information:
7  * wlanfae <wlanfae@realtek.com>
8  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9  * Hsinchu 300, Taiwan.
10  *
11  * Larry Finger <Larry.Finger@lwfinger.net>
12  *
13  *****************************************************************************/
14 
15 #include "../wifi.h"
16 #include "../pci.h"
17 #include "../base.h"
18 #include "reg.h"
19 #include "def.h"
20 #include "fw.h"
21 
_rtl8822be_check_fw_read_last_h2c(struct ieee80211_hw * hw,u8 boxnum)22 static bool _rtl8822be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
23 					      u8 boxnum)
24 {
25 	struct rtl_priv *rtlpriv = rtl_priv(hw);
26 	u8 val_hmetfr;
27 	bool result = false;
28 
29 	val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR_8822B);
30 	if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
31 		result = true;
32 	return result;
33 }
34 
_rtl8822be_fill_h2c_command(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)35 static void _rtl8822be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
36 					u32 cmd_len, u8 *cmdbuffer)
37 {
38 	struct rtl_priv *rtlpriv = rtl_priv(hw);
39 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
40 	u8 boxnum;
41 	u16 box_reg = 0, box_extreg = 0;
42 	u8 u1b_tmp;
43 	bool isfw_read;
44 	u8 buf_index = 0;
45 	bool bwrite_success = false;
46 	u8 wait_h2c_limmit = 100;
47 	u8 boxcontent[4], boxextcontent[4];
48 	u32 h2c_waitcounter = 0;
49 	unsigned long flag;
50 	u8 idx;
51 
52 	/* 1. Prevent race condition in setting H2C cmd.
53 	 * (copy from MgntActSet_RF_State().)
54 	 */
55 	while (true) {
56 		spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
57 		if (rtlhal->h2c_setinprogress) {
58 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
59 				 "H2C set in progress! wait..H2C_ID=%d.\n",
60 				 element_id);
61 
62 			while (rtlhal->h2c_setinprogress) {
63 				spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
64 						       flag);
65 				h2c_waitcounter++;
66 				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
67 					 "Wait 100 us (%d times)...\n",
68 					 h2c_waitcounter);
69 				udelay(100);
70 
71 				if (h2c_waitcounter > 1000)
72 					return;
73 				spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
74 						  flag);
75 			}
76 			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
77 		} else {
78 			rtlhal->h2c_setinprogress = true;
79 			spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
80 			break;
81 		}
82 	}
83 
84 	while (!bwrite_success) {
85 		/* 2. Find the last BOX number which has been written. */
86 		boxnum = rtlhal->last_hmeboxnum;
87 		switch (boxnum) {
88 		case 0:
89 			box_reg = REG_HMEBOX0_8822B;
90 			box_extreg = REG_HMEBOX_E0_8822B;
91 			break;
92 		case 1:
93 			box_reg = REG_HMEBOX1_8822B;
94 			box_extreg = REG_HMEBOX_E1_8822B;
95 			break;
96 		case 2:
97 			box_reg = REG_HMEBOX2_8822B;
98 			box_extreg = REG_HMEBOX_E2_8822B;
99 			break;
100 		case 3:
101 			box_reg = REG_HMEBOX3_8822B;
102 			box_extreg = REG_HMEBOX_E3_8822B;
103 			break;
104 		default:
105 			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
106 				 "switch case not process\n");
107 			break;
108 		}
109 
110 		/* 3. Check if the box content is empty. */
111 		u1b_tmp = rtl_read_byte(rtlpriv, REG_CR_8822B);
112 
113 		if (u1b_tmp == 0xea) {
114 			if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS_8822B) ==
115 				    0xea ||
116 			    rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY_8822B) ==
117 				    0xea)
118 				rtl_write_byte(rtlpriv, REG_SYS_CFG1_8822B + 3,
119 					       0xff);
120 
121 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
122 				 "REG_CR is unavaliable\n");
123 			break;
124 		}
125 
126 		wait_h2c_limmit = 100;
127 		isfw_read = _rtl8822be_check_fw_read_last_h2c(hw, boxnum);
128 		while (!isfw_read) {
129 			wait_h2c_limmit--;
130 			if (wait_h2c_limmit == 0) {
131 				RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING,
132 					 "Wait too long for FW clear MB%d!!!\n",
133 					 boxnum);
134 				break;
135 			}
136 			udelay(10);
137 			isfw_read =
138 				_rtl8822be_check_fw_read_last_h2c(hw, boxnum);
139 			u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
140 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
141 				 "Waiting for FW clear MB%d!!! 0x130 = %2x\n",
142 				 boxnum, u1b_tmp);
143 		}
144 
145 		/* If Fw has not read the last H2C cmd,
146 		 * break and give up this H2C.
147 		 */
148 		if (!isfw_read) {
149 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
150 				 "Write H2C reg BOX[%d] fail,Fw don't read.\n",
151 				 boxnum);
152 			break;
153 		}
154 		/* 4. Fill the H2C cmd into box */
155 		memset(boxcontent, 0, sizeof(boxcontent));
156 		memset(boxextcontent, 0, sizeof(boxextcontent));
157 		boxcontent[0] = element_id;
158 		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
159 			 "Write element_id box_reg(%4x) = %2x\n", box_reg,
160 			 element_id);
161 
162 		switch (cmd_len) {
163 		case 1:
164 		case 2:
165 		case 3:
166 			/*boxcontent[0] &= ~(BIT(7));*/
167 			memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index,
168 			       cmd_len);
169 
170 			for (idx = 0; idx < 4; idx++) {
171 				rtl_write_byte(rtlpriv, box_reg + idx,
172 					       boxcontent[idx]);
173 			}
174 			break;
175 		case 4:
176 		case 5:
177 		case 6:
178 		case 7:
179 			/*boxcontent[0] |= (BIT(7));*/
180 			memcpy((u8 *)(boxextcontent), cmdbuffer + buf_index + 3,
181 			       cmd_len - 3);
182 			memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index,
183 			       3);
184 
185 			for (idx = 0; idx < 4; idx++) {
186 				rtl_write_byte(rtlpriv, box_extreg + idx,
187 					       boxextcontent[idx]);
188 			}
189 
190 			for (idx = 0; idx < 4; idx++) {
191 				rtl_write_byte(rtlpriv, box_reg + idx,
192 					       boxcontent[idx]);
193 			}
194 			break;
195 		default:
196 			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
197 				 "switch case not process\n");
198 			break;
199 		}
200 
201 		bwrite_success = true;
202 
203 		rtlhal->last_hmeboxnum = boxnum + 1;
204 		if (rtlhal->last_hmeboxnum == 4)
205 			rtlhal->last_hmeboxnum = 0;
206 
207 		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
208 			 "pHalData->last_hmeboxnum  = %d\n",
209 			 rtlhal->last_hmeboxnum);
210 	}
211 
212 	spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
213 	rtlhal->h2c_setinprogress = false;
214 	spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
215 
216 	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
217 }
218 
rtl8822be_fill_h2c_cmd(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)219 void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len,
220 			    u8 *cmdbuffer)
221 {
222 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
223 	struct rtl_priv *rtlpriv = rtl_priv(hw);
224 	u8 tmp_cmdbuf[8];
225 
226 	if (!rtlhal->fw_ready) {
227 		WARN_ONCE(true,
228 			  "return H2C cmd because of Fw download fail!!!\n");
229 		return;
230 	}
231 
232 	memset(tmp_cmdbuf, 0, 8);
233 	memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
234 
235 	RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
236 		 "h2c cmd: len=%d %02X%02X%02X%02X %02X%02X%02X%02X\n", cmd_len,
237 		 tmp_cmdbuf[2], tmp_cmdbuf[1], tmp_cmdbuf[0], element_id,
238 		 tmp_cmdbuf[6], tmp_cmdbuf[5], tmp_cmdbuf[4], tmp_cmdbuf[3]);
239 
240 	_rtl8822be_fill_h2c_command(hw, element_id, cmd_len, tmp_cmdbuf);
241 }
242 
rtl8822be_set_default_port_id_cmd(struct ieee80211_hw * hw)243 void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw)
244 {
245 	u8 h2c_set_default_port_id[H2C_DEFAULT_PORT_ID_LEN];
246 
247 	SET_H2CCMD_DFTPID_PORT_ID(h2c_set_default_port_id, 0);
248 	SET_H2CCMD_DFTPID_MAC_ID(h2c_set_default_port_id, 0);
249 
250 	rtl8822be_fill_h2c_cmd(hw, H2C_8822B_DEFAULT_PORT_ID,
251 			       H2C_DEFAULT_PORT_ID_LEN,
252 			       h2c_set_default_port_id);
253 }
254 
rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw * hw,u8 mode)255 void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
256 {
257 	struct rtl_priv *rtlpriv = rtl_priv(hw);
258 	u8 u1_h2c_set_pwrmode[H2C_8822B_PWEMODE_LENGTH] = {0};
259 	static u8 prev_h2c[H2C_8822B_PWEMODE_LENGTH] = {0};
260 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
261 	u8 rlbm, power_state = 0, byte5 = 0;
262 	u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
263 	u8 smart_ps = 0;
264 	struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
265 	bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
266 			    btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
267 	bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
268 			  btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
269 
270 	memset(u1_h2c_set_pwrmode, 0, H2C_8822B_PWEMODE_LENGTH);
271 
272 	if (bt_ctrl_lps)
273 		mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
274 
275 	RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
276 		 mode, bt_ctrl_lps);
277 
278 	switch (mode) {
279 	case FW_PS_MIN_MODE:
280 		rlbm = 0;
281 		awake_intvl = 2;
282 		smart_ps = ppsc->smart_ps;
283 		break;
284 	case FW_PS_MAX_MODE:
285 		rlbm = 1;
286 		awake_intvl = 2;
287 		smart_ps = ppsc->smart_ps;
288 		break;
289 	case FW_PS_DTIM_MODE:
290 		rlbm = 2;
291 		awake_intvl = ppsc->reg_max_lps_awakeintvl;
292 		/*
293 		 * hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
294 		 * is only used in swlps.
295 		 */
296 		smart_ps = ppsc->smart_ps;
297 		break;
298 	case FW_PS_ACTIVE_MODE:
299 		rlbm = 0;
300 		awake_intvl = 1;
301 		break;
302 	default:
303 		rlbm = 2;
304 		awake_intvl = 4;
305 		smart_ps = ppsc->smart_ps;
306 		break;
307 	}
308 
309 	if (rtlpriv->mac80211.p2p) {
310 		awake_intvl = 2;
311 		rlbm = 1;
312 	}
313 
314 	if (mode == FW_PS_ACTIVE_MODE) {
315 		byte5 = 0x40;
316 		power_state = FW_PWR_STATE_ACTIVE;
317 	} else {
318 		if (bt_ctrl_lps) {
319 			byte5 = btc_ops->btc_get_lps_val(rtlpriv);
320 			power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
321 
322 			if (rlbm == 2 && (byte5 & BIT(4))) {
323 				/* Keep awake interval to 1 to prevent from
324 				 * decreasing coex performance
325 				 */
326 				awake_intvl = 2;
327 				rlbm = 2;
328 			}
329 			smart_ps = 0;
330 		} else {
331 			byte5 = 0x40;
332 			power_state = FW_PWR_STATE_RF_OFF;
333 		}
334 	}
335 
336 	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
337 	SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
338 	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, smart_ps);
339 	SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, awake_intvl);
340 	SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
341 	SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
342 	SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
343 
344 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
345 		      "rtl8822be_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
346 		      u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH);
347 	if (rtlpriv->cfg->ops->get_btc_status())
348 		btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
349 					     H2C_8822B_PWEMODE_LENGTH);
350 
351 	if (!memcmp(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH))
352 		return;
353 	memcpy(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH);
354 
355 	rtl8822be_set_default_port_id_cmd(hw);
356 	rtl8822be_fill_h2c_cmd(hw, H2C_8822B_SETPWRMODE,
357 			       H2C_8822B_PWEMODE_LENGTH, u1_h2c_set_pwrmode);
358 }
359 
rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw * hw,u8 mstatus)360 void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
361 {
362 	u8 parm[4] = {0, 0, 0, 0};
363 	/* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
364 	 *          bit1=0-->update Media Status to MACID
365 	 *          bit1=1-->update Media Status from MACID to MACID_End
366 	 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
367 	 * parm[2]: MACID_End
368 	 * parm[3]: bit2-0: port ID
369 	 */
370 
371 	SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
372 	SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
373 
374 	rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MSRRPT, 4, parm);
375 }
376 
_rtl8822be_send_bcn_or_cmd_packet(struct ieee80211_hw * hw,struct sk_buff * skb,u8 hw_queue)377 static bool _rtl8822be_send_bcn_or_cmd_packet(struct ieee80211_hw *hw,
378 					      struct sk_buff *skb, u8 hw_queue)
379 {
380 	struct rtl_priv *rtlpriv = rtl_priv(hw);
381 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
382 	struct rtl8192_tx_ring *ring;
383 	struct rtl_tx_desc *pdesc;
384 	struct rtl_tx_buffer_desc *pbd_desc;
385 	unsigned long flags;
386 	struct sk_buff *pskb = NULL;
387 	u8 *pdesc_or_bddesc;
388 	dma_addr_t dma_addr;
389 
390 	if (hw_queue != BEACON_QUEUE && hw_queue != H2C_QUEUE)
391 		return false;
392 
393 	ring = &rtlpci->tx_ring[hw_queue];
394 
395 	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
396 
397 	if (hw_queue == BEACON_QUEUE) {
398 		pdesc = &ring->desc[0];
399 		pbd_desc = &ring->buffer_desc[0];
400 		pdesc_or_bddesc = (u8 *)pbd_desc;
401 
402 		/* free previous beacon queue */
403 		pskb = __skb_dequeue(&ring->queue);
404 
405 		if (!pskb)
406 			goto free_prev_skb_done;
407 
408 		dma_addr = rtlpriv->cfg->ops->get_desc(
409 				hw, (u8 *)pbd_desc, true, HW_DESC_TXBUFF_ADDR);
410 
411 		pci_unmap_single(rtlpci->pdev, dma_addr, pskb->len,
412 				 PCI_DMA_TODEVICE);
413 		kfree_skb(pskb);
414 
415 free_prev_skb_done:
416 		;
417 
418 	} else { /* hw_queue == TXCMD_QUEUE */
419 		if (rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) {
420 			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
421 				 "get_available_desc fail hw_queue=%d\n",
422 				 hw_queue);
423 			spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
424 					       flags);
425 			return false;
426 		}
427 
428 		pdesc = &ring->desc[ring->cur_tx_wp];
429 		pbd_desc = &ring->buffer_desc[ring->cur_tx_wp];
430 		pdesc_or_bddesc = (u8 *)pdesc;
431 	}
432 
433 	rtlpriv->cfg->ops->fill_tx_special_desc(hw, (u8 *)pdesc, (u8 *)pbd_desc,
434 						skb, hw_queue);
435 
436 	__skb_queue_tail(&ring->queue, skb);
437 
438 	rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc_or_bddesc, true,
439 				    HW_DESC_OWN, (u8 *)&hw_queue);
440 
441 	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
442 
443 	rtlpriv->cfg->ops->tx_polling(hw, hw_queue);
444 
445 	return true;
446 }
447 
rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv * rtlpriv,u8 * buf,u32 size)448 bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf,
449 					     u32 size)
450 {
451 	struct sk_buff *skb = NULL;
452 	u8 u1b_tmp;
453 	int count;
454 
455 	skb = dev_alloc_skb(size);
456 	if (!skb)
457 		return false;
458 	memcpy((u8 *)skb_put(skb, size), buf, size);
459 
460 	if (!_rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, BEACON_QUEUE))
461 		return false;
462 
463 	/* These code isn't actually need, because halmac will check
464 	 * BCN_VALID
465 	 */
466 
467 	/* Polling Beacon Queue to send Beacon */
468 	u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
469 	count = 0;
470 	while ((count < 20) && (u1b_tmp & BIT(4))) {
471 		count++;
472 		udelay(10);
473 		u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
474 	}
475 
476 	if (count >= 20)
477 		pr_err("%s polling beacon fail\n", __func__);
478 
479 	return true;
480 }
481 
rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv * rtlpriv,u8 * buf,u32 size)482 bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf,
483 				       u32 size)
484 {
485 	struct sk_buff *skb = NULL;
486 
487 	/* without GFP_DMA, pci_map_single() may not work */
488 	skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA);
489 	memcpy((u8 *)skb_put(skb, size), buf, size);
490 
491 	return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE);
492 }
493 
494 /* Rsvd page HALMAC_RSVD_DRV_PGNUM_8822B occupies 16 page (2048 byte) */
495 #define BEACON_PG	0 /* ->1 */
496 #define PSPOLL_PG	2
497 #define NULL_PG	3
498 #define PROBERSP_PG	4 /* ->5 */
499 #define QOS_NULL_PG	6
500 #define BT_QOS_NULL_PG	7
501 
502 #define TOTAL_RESERVED_PKT_LEN	1024
503 
504 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {/* page size = 128 */
505 	/* page 0 beacon */
506 	0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
507 	0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
508 	0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
509 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510 	0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
511 	0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
512 	0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
513 	0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
514 	0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
515 	0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
516 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 	0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
519 	0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
520 	0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
521 	0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
522 
523 	/* page 1 beacon */
524 	0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
525 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 	0x10, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
535 	0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 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 
541 	/* page 2  ps-poll */
542 	0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
543 	0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
544 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552 	0x18, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
553 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
554 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 
559 	/* page 3  null */
560 	0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
561 	0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
562 	0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
563 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 	0x72, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
571 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
572 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 
577 	/* page 4  probe_resp */
578 	0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
579 	0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
580 	0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
581 	0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
582 	0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
583 	0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
584 	0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
585 	0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
586 	0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
587 	0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
588 	0x03, 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 	0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
592 	0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 
595 	/* page 5  probe_resp */
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 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 	0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
607 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
608 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 
613 	/* page 6 qos null data */
614 	0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
615 	0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
616 	0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
617 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 	0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
625 	0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
626 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 	0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 
631 	/* page 7 BT-qos null data */
632 	0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
633 	0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
634 	0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
635 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 	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 };
649 
rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw * hw,bool b_dl_finished)650 void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
651 {
652 	struct rtl_priv *rtlpriv = rtl_priv(hw);
653 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
654 	struct sk_buff *skb = NULL;
655 
656 	u32 totalpacketlen;
657 	bool rtstatus;
658 	u8 u1_rsvd_page_loc[7] = {0};
659 	bool b_dlok = false;
660 
661 	u8 *beacon;
662 	u8 *p_pspoll;
663 	u8 *nullfunc;
664 	u8 *p_probersp;
665 	u8 *qosnull;
666 	u8 *btqosnull;
667 
668 	memset(u1_rsvd_page_loc, 0, sizeof(u1_rsvd_page_loc));
669 
670 	/*---------------------------------------------------------
671 	 *			(1) beacon
672 	 *---------------------------------------------------------
673 	 */
674 	beacon = &reserved_page_packet[BEACON_PG * 128];
675 	SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
676 	SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
677 
678 	/*-------------------------------------------------------
679 	 *			(2) ps-poll
680 	 *--------------------------------------------------------
681 	 */
682 	p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
683 	SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
684 	SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
685 	SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
686 
687 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1_rsvd_page_loc, PSPOLL_PG);
688 
689 	/*--------------------------------------------------------
690 	 *			(3) null data
691 	 *---------------------------------------------------------
692 	 */
693 	nullfunc = &reserved_page_packet[NULL_PG * 128];
694 	SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
695 	SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
696 	SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
697 
698 	SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1_rsvd_page_loc, NULL_PG);
699 
700 	/*---------------------------------------------------------
701 	 *			(4) probe response
702 	 *----------------------------------------------------------
703 	 */
704 	p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
705 	SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
706 	SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
707 	SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
708 
709 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1_rsvd_page_loc, PROBERSP_PG);
710 
711 	/*---------------------------------------------------------
712 	 *			(5) QoS null data
713 	 *----------------------------------------------------------
714 	 */
715 	qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
716 	SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
717 	SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
718 	SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
719 
720 	SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1_rsvd_page_loc, QOS_NULL_PG);
721 
722 	/*---------------------------------------------------------
723 	 *			(6) BT QoS null data
724 	 *----------------------------------------------------------
725 	 */
726 	btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
727 	SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
728 	SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
729 	SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
730 
731 	SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1_rsvd_page_loc,
732 						 BT_QOS_NULL_PG);
733 
734 	totalpacketlen = TOTAL_RESERVED_PKT_LEN;
735 
736 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
737 		      "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
738 		      &reserved_page_packet[0], totalpacketlen);
739 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
740 		      "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
741 		      u1_rsvd_page_loc, 3);
742 
743 	skb = dev_alloc_skb(totalpacketlen);
744 	memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet,
745 	       totalpacketlen);
746 
747 	rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE);
748 
749 	if (rtstatus)
750 		b_dlok = true;
751 
752 	if (b_dlok) {
753 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
754 			 "Set RSVD page location to Fw.\n");
755 		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n",
756 			      u1_rsvd_page_loc, 3);
757 		rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE,
758 				       sizeof(u1_rsvd_page_loc),
759 				       u1_rsvd_page_loc);
760 	} else {
761 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
762 			 "Set RSVD page location to Fw FAIL!!!!!!.\n");
763 	}
764 }
765 
766 /* Should check FW support p2p or not. */
rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw * hw,u8 ctwindow)767 static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
768 					     u8 ctwindow)
769 {
770 	u8 u1_ctwindow_period[1] = {ctwindow};
771 
772 	rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1,
773 			       u1_ctwindow_period);
774 }
775 
rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw * hw,u8 p2p_ps_state)776 void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
777 {
778 	struct rtl_priv *rtlpriv = rtl_priv(hw);
779 	struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
780 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
781 	struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
782 	struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
783 	u8 i;
784 	u16 ctwindow;
785 	u32 start_time, tsf_low;
786 
787 	switch (p2p_ps_state) {
788 	case P2P_PS_DISABLE:
789 		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
790 		memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
791 		break;
792 	case P2P_PS_ENABLE:
793 		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
794 		/* update CTWindow value. */
795 		if (p2pinfo->ctwindow > 0) {
796 			p2p_ps_offload->ctwindow_en = 1;
797 			ctwindow = p2pinfo->ctwindow;
798 			rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow);
799 		}
800 		/* hw only support 2 set of NoA */
801 		for (i = 0; i < p2pinfo->noa_num; i++) {
802 			/* To control the register setting for which NOA*/
803 			rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
804 			if (i == 0)
805 				p2p_ps_offload->noa0_en = 1;
806 			else
807 				p2p_ps_offload->noa1_en = 1;
808 			/* config P2P NoA Descriptor Register */
809 			rtl_write_dword(rtlpriv, 0x5E0,
810 					p2pinfo->noa_duration[i]);
811 			rtl_write_dword(rtlpriv, 0x5E4,
812 					p2pinfo->noa_interval[i]);
813 
814 			/*Get Current TSF value */
815 			tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B);
816 
817 			start_time = p2pinfo->noa_start_time[i];
818 			if (p2pinfo->noa_count_type[i] != 1) {
819 				while (start_time <= (tsf_low + (50 * 1024))) {
820 					start_time += p2pinfo->noa_interval[i];
821 					if (p2pinfo->noa_count_type[i] != 255)
822 						p2pinfo->noa_count_type[i]--;
823 				}
824 			}
825 			rtl_write_dword(rtlpriv, 0x5E8, start_time);
826 			rtl_write_dword(rtlpriv, 0x5EC,
827 					p2pinfo->noa_count_type[i]);
828 		}
829 		if (p2pinfo->opp_ps == 1 || p2pinfo->noa_num > 0) {
830 			/* rst p2p circuit */
831 			rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4));
832 			p2p_ps_offload->offload_en = 1;
833 
834 			if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) {
835 				p2p_ps_offload->role = 1;
836 				p2p_ps_offload->allstasleep = 0;
837 			} else {
838 				p2p_ps_offload->role = 0;
839 			}
840 			p2p_ps_offload->discovery = 0;
841 		}
842 		break;
843 	case P2P_PS_SCAN:
844 		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
845 		p2p_ps_offload->discovery = 1;
846 		break;
847 	case P2P_PS_SCAN_DONE:
848 		RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
849 		p2p_ps_offload->discovery = 0;
850 		p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
851 		break;
852 	default:
853 		break;
854 	}
855 
856 	rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1,
857 			       (u8 *)p2p_ps_offload);
858 }
859 
860 static
rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw * hw,u8 c2h_sub_cmd_id,u8 c2h_cmd_len,u8 * c2h_content_buf)861 void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw,
862 				       u8 c2h_sub_cmd_id,
863 				       u8 c2h_cmd_len,
864 				       u8 *c2h_content_buf)
865 {
866 	struct rtl_priv *rtlpriv = rtl_priv(hw);
867 	struct rtl_halmac_ops *halmac_ops;
868 
869 	switch (c2h_sub_cmd_id) {
870 	case 0x0F:
871 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
872 			 "[C2H], C2H_8822BE_TX_REPORT!\n");
873 		rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len);
874 		break;
875 	default:
876 		/* indicate c2h pkt + rx desc to halmac */
877 		halmac_ops = rtlpriv->halmac.ops;
878 		halmac_ops->halmac_c2h_handle(rtlpriv,
879 					      c2h_content_buf - 24 - 2 - 2,
880 					      c2h_cmd_len + 24 + 2 + 2);
881 		break;
882 	}
883 }
884 
rtl8822be_c2h_content_parsing(struct ieee80211_hw * hw,u8 c2h_cmd_id,u8 c2h_cmd_len,u8 * tmp_buf)885 void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
886 				   u8 c2h_cmd_len, u8 *tmp_buf)
887 {
888 	struct rtl_priv *rtlpriv = rtl_priv(hw);
889 	struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
890 
891 	if (c2h_cmd_id == 0xFF) {
892 		rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0],
893 						  c2h_cmd_len - 2,
894 						  tmp_buf + 2);
895 		return;
896 	}
897 
898 	switch (c2h_cmd_id) {
899 	case C2H_8822B_DBG:
900 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
901 			 "[C2H], C2H_8822BE_DBG!!\n");
902 		break;
903 	case C2H_8822B_TXBF:
904 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
905 			 "[C2H], C2H_8822B_TXBF!!\n");
906 		break;
907 	case C2H_8822B_BT_INFO:
908 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
909 			 "[C2H], C2H_8822BE_BT_INFO!!\n");
910 		if (rtlpriv->cfg->ops->get_btc_status())
911 			btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
912 						   c2h_cmd_len);
913 		break;
914 	case C2H_8822B_BT_MP:
915 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
916 			 "[C2H], C2H_8822BE_BT_MP!!\n");
917 		if (rtlpriv->cfg->ops->get_btc_status())
918 			btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
919 						     c2h_cmd_len);
920 		break;
921 	default:
922 		if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing(
923 			    rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf))
924 			break;
925 
926 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
927 			 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
928 		break;
929 	}
930 }
931 
rtl8822be_c2h_packet_handler(struct ieee80211_hw * hw,u8 * buffer,u8 len)932 void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
933 {
934 	struct rtl_priv *rtlpriv = rtl_priv(hw);
935 	u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
936 	u8 *tmp_buf = NULL;
937 
938 	c2h_cmd_id = buffer[0];
939 	c2h_cmd_seq = buffer[1];
940 	c2h_cmd_len = len - 2;
941 	tmp_buf = buffer + 2;
942 
943 	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
944 		 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
945 		 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
946 
947 	RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
948 		      "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
949 
950 	switch (c2h_cmd_id) {
951 	case C2H_8822B_BT_INFO:
952 	case C2H_8822B_BT_MP:
953 		rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
954 		break;
955 	default:
956 		rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
957 					      tmp_buf);
958 		break;
959 	}
960 }
961