]> git.ipfire.org Git - thirdparty/kernel/stable.git/blob - drivers/staging/rtlwifi/rtl8822be/fw.c
8e24da16752c23e1cddb447efe2cc25d6f65f73b
[thirdparty/kernel/stable.git] / drivers / staging / rtlwifi / rtl8822be / fw.c
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
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
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
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
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
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
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
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, skb->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
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 memcpy((u8 *)skb_put(skb, size), buf, size);
468
469 if (!_rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, BEACON_QUEUE))
470 return false;
471
472 /* These code isn't actually need, because halmac will check
473 * BCN_VALID
474 */
475
476 /* Polling Beacon Queue to send Beacon */
477 u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
478 count = 0;
479 while ((count < 20) && (u1b_tmp & BIT(4))) {
480 count++;
481 udelay(10);
482 u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
483 }
484
485 if (count >= 20)
486 pr_err("%s polling beacon fail\n", __func__);
487
488 return true;
489 }
490
491 bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf,
492 u32 size)
493 {
494 struct sk_buff *skb = NULL;
495
496 /* without GFP_DMA, pci_map_single() may not work */
497 skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA);
498 memcpy((u8 *)skb_put(skb, size), buf, size);
499
500 return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE);
501 }
502
503 /* Rsvd page HALMAC_RSVD_DRV_PGNUM_8822B occupies 16 page (2048 byte) */
504 #define BEACON_PG 0 /* ->1 */
505 #define PSPOLL_PG 2
506 #define NULL_PG 3
507 #define PROBERSP_PG 4 /* ->5 */
508 #define QOS_NULL_PG 6
509 #define BT_QOS_NULL_PG 7
510
511 #define TOTAL_RESERVED_PKT_LEN 1024
512
513 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {/* page size = 128 */
514 /* page 0 beacon */
515 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
516 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
517 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
520 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
521 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
522 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
523 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
524 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
525 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
528 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
529 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
530 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
531
532 /* page 1 beacon */
533 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 0x10, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 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
550 /* page 2 ps-poll */
551 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
552 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x18, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567
568 /* page 3 null */
569 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
570 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
571 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x72, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585
586 /* page 4 probe_resp */
587 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
588 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
589 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
590 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
591 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
592 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
593 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
594 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
595 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
596 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
597 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
601 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603
604 /* page 5 probe_resp */
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 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621
622 /* page 6 qos null data */
623 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
624 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
625 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
634 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639
640 /* page 7 BT-qos null data */
641 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
642 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
643 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 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 };
658
659 void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
660 {
661 struct rtl_priv *rtlpriv = rtl_priv(hw);
662 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
663 struct sk_buff *skb = NULL;
664
665 u32 totalpacketlen;
666 bool rtstatus;
667 u8 u1_rsvd_page_loc[7] = {0};
668 bool b_dlok = false;
669
670 u8 *beacon;
671 u8 *p_pspoll;
672 u8 *nullfunc;
673 u8 *p_probersp;
674 u8 *qosnull;
675 u8 *btqosnull;
676
677 memset(u1_rsvd_page_loc, 0, sizeof(u1_rsvd_page_loc));
678
679 /*---------------------------------------------------------
680 * (1) beacon
681 *---------------------------------------------------------
682 */
683 beacon = &reserved_page_packet[BEACON_PG * 128];
684 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
685 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
686
687 /*-------------------------------------------------------
688 * (2) ps-poll
689 *--------------------------------------------------------
690 */
691 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
692 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
693 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
694 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
695
696 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1_rsvd_page_loc, PSPOLL_PG);
697
698 /*--------------------------------------------------------
699 * (3) null data
700 *---------------------------------------------------------
701 */
702 nullfunc = &reserved_page_packet[NULL_PG * 128];
703 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
704 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
705 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
706
707 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1_rsvd_page_loc, NULL_PG);
708
709 /*---------------------------------------------------------
710 * (4) probe response
711 *----------------------------------------------------------
712 */
713 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
714 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
715 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
716 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
717
718 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1_rsvd_page_loc, PROBERSP_PG);
719
720 /*---------------------------------------------------------
721 * (5) QoS null data
722 *----------------------------------------------------------
723 */
724 qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
725 SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
726 SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
727 SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
728
729 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1_rsvd_page_loc, QOS_NULL_PG);
730
731 /*---------------------------------------------------------
732 * (6) BT QoS null data
733 *----------------------------------------------------------
734 */
735 btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
736 SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
737 SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
738 SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
739
740 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1_rsvd_page_loc,
741 BT_QOS_NULL_PG);
742
743 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
744
745 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
746 "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
747 &reserved_page_packet[0], totalpacketlen);
748 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
749 "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
750 u1_rsvd_page_loc, 3);
751
752 skb = dev_alloc_skb(totalpacketlen);
753 memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet,
754 totalpacketlen);
755
756 rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE);
757
758 if (rtstatus)
759 b_dlok = true;
760
761 if (b_dlok) {
762 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
763 "Set RSVD page location to Fw.\n");
764 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n",
765 u1_rsvd_page_loc, 3);
766 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE,
767 sizeof(u1_rsvd_page_loc),
768 u1_rsvd_page_loc);
769 } else
770 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
771 "Set RSVD page location to Fw FAIL!!!!!!.\n");
772 }
773
774 /* Should check FW support p2p or not. */
775 static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
776 u8 ctwindow)
777 {
778 u8 u1_ctwindow_period[1] = {ctwindow};
779
780 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1,
781 u1_ctwindow_period);
782 }
783
784 void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
785 {
786 struct rtl_priv *rtlpriv = rtl_priv(hw);
787 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
788 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
789 struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
790 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
791 u8 i;
792 u16 ctwindow;
793 u32 start_time, tsf_low;
794
795 switch (p2p_ps_state) {
796 case P2P_PS_DISABLE:
797 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
798 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
799 break;
800 case P2P_PS_ENABLE:
801 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
802 /* update CTWindow value. */
803 if (p2pinfo->ctwindow > 0) {
804 p2p_ps_offload->ctwindow_en = 1;
805 ctwindow = p2pinfo->ctwindow;
806 rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow);
807 }
808 /* hw only support 2 set of NoA */
809 for (i = 0; i < p2pinfo->noa_num; i++) {
810 /* To control the register setting for which NOA*/
811 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
812 if (i == 0)
813 p2p_ps_offload->noa0_en = 1;
814 else
815 p2p_ps_offload->noa1_en = 1;
816 /* config P2P NoA Descriptor Register */
817 rtl_write_dword(rtlpriv, 0x5E0,
818 p2pinfo->noa_duration[i]);
819 rtl_write_dword(rtlpriv, 0x5E4,
820 p2pinfo->noa_interval[i]);
821
822 /*Get Current TSF value */
823 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B);
824
825 start_time = p2pinfo->noa_start_time[i];
826 if (p2pinfo->noa_count_type[i] != 1) {
827 while (start_time <= (tsf_low + (50 * 1024))) {
828 start_time += p2pinfo->noa_interval[i];
829 if (p2pinfo->noa_count_type[i] != 255)
830 p2pinfo->noa_count_type[i]--;
831 }
832 }
833 rtl_write_dword(rtlpriv, 0x5E8, start_time);
834 rtl_write_dword(rtlpriv, 0x5EC,
835 p2pinfo->noa_count_type[i]);
836 }
837 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
838 /* rst p2p circuit */
839 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4));
840 p2p_ps_offload->offload_en = 1;
841
842 if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) {
843 p2p_ps_offload->role = 1;
844 p2p_ps_offload->allstasleep = 0;
845 } else {
846 p2p_ps_offload->role = 0;
847 }
848 p2p_ps_offload->discovery = 0;
849 }
850 break;
851 case P2P_PS_SCAN:
852 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
853 p2p_ps_offload->discovery = 1;
854 break;
855 case P2P_PS_SCAN_DONE:
856 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
857 p2p_ps_offload->discovery = 0;
858 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
859 break;
860 default:
861 break;
862 }
863
864 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1,
865 (u8 *)p2p_ps_offload);
866 }
867
868 static
869 void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw,
870 u8 c2h_sub_cmd_id,
871 u8 c2h_cmd_len,
872 u8 *c2h_content_buf)
873 {
874 struct rtl_priv *rtlpriv = rtl_priv(hw);
875 struct rtl_halmac_ops *halmac_ops;
876
877 switch (c2h_sub_cmd_id) {
878 case 0x0F:
879 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
880 "[C2H], C2H_8822BE_TX_REPORT!\n");
881 rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len);
882 break;
883 default:
884 /* indicate c2h pkt + rx desc to halmac */
885 halmac_ops = rtlpriv->halmac.ops;
886 halmac_ops->halmac_c2h_handle(rtlpriv,
887 c2h_content_buf - 24 - 2 - 2,
888 c2h_cmd_len + 24 + 2 + 2);
889 break;
890 }
891 }
892
893 void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
894 u8 c2h_cmd_len, u8 *tmp_buf)
895 {
896 struct rtl_priv *rtlpriv = rtl_priv(hw);
897 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
898
899 if (c2h_cmd_id == 0xFF) {
900 rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0],
901 c2h_cmd_len - 2,
902 tmp_buf + 2);
903 return;
904 }
905
906 switch (c2h_cmd_id) {
907 case C2H_8822B_DBG:
908 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
909 "[C2H], C2H_8822BE_DBG!!\n");
910 break;
911 case C2H_8822B_TXBF:
912 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
913 "[C2H], C2H_8822B_TXBF!!\n");
914 break;
915 case C2H_8822B_BT_INFO:
916 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
917 "[C2H], C2H_8822BE_BT_INFO!!\n");
918 if (rtlpriv->cfg->ops->get_btc_status())
919 btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
920 c2h_cmd_len);
921 break;
922 case C2H_8822B_BT_MP:
923 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
924 "[C2H], C2H_8822BE_BT_MP!!\n");
925 if (rtlpriv->cfg->ops->get_btc_status())
926 btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
927 c2h_cmd_len);
928 break;
929 default:
930 if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing(
931 rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf))
932 break;
933
934 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
935 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
936 break;
937 }
938 }
939
940 void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
941 {
942 struct rtl_priv *rtlpriv = rtl_priv(hw);
943 u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
944 u8 *tmp_buf = NULL;
945
946 c2h_cmd_id = buffer[0];
947 c2h_cmd_seq = buffer[1];
948 c2h_cmd_len = len - 2;
949 tmp_buf = buffer + 2;
950
951 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
952 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
953 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
954
955 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
956 "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
957
958 switch (c2h_cmd_id) {
959 case C2H_8822B_BT_INFO:
960 case C2H_8822B_BT_MP:
961 rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
962 break;
963 default:
964 rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
965 tmp_buf);
966 break;
967 }
968 }