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