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