Merge tag 's390-5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[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         if (!skb)
747                 return;
748         memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet,
749                totalpacketlen);
750
751         rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE);
752
753         if (rtstatus)
754                 b_dlok = true;
755
756         if (b_dlok) {
757                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
758                          "Set RSVD page location to Fw.\n");
759                 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n",
760                               u1_rsvd_page_loc, 3);
761                 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE,
762                                        sizeof(u1_rsvd_page_loc),
763                                        u1_rsvd_page_loc);
764         } else {
765                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
766                          "Set RSVD page location to Fw FAIL!!!!!!.\n");
767         }
768 }
769
770 /* Should check FW support p2p or not. */
771 static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
772                                              u8 ctwindow)
773 {
774         u8 u1_ctwindow_period[1] = {ctwindow};
775
776         rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1,
777                                u1_ctwindow_period);
778 }
779
780 void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
781 {
782         struct rtl_priv *rtlpriv = rtl_priv(hw);
783         struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
784         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
785         struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
786         struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
787         u8 i;
788         u16 ctwindow;
789         u32 start_time, tsf_low;
790
791         switch (p2p_ps_state) {
792         case P2P_PS_DISABLE:
793                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
794                 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
795                 break;
796         case P2P_PS_ENABLE:
797                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
798                 /* update CTWindow value. */
799                 if (p2pinfo->ctwindow > 0) {
800                         p2p_ps_offload->ctwindow_en = 1;
801                         ctwindow = p2pinfo->ctwindow;
802                         rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow);
803                 }
804                 /* hw only support 2 set of NoA */
805                 for (i = 0; i < p2pinfo->noa_num; i++) {
806                         /* To control the register setting for which NOA*/
807                         rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
808                         if (i == 0)
809                                 p2p_ps_offload->noa0_en = 1;
810                         else
811                                 p2p_ps_offload->noa1_en = 1;
812                         /* config P2P NoA Descriptor Register */
813                         rtl_write_dword(rtlpriv, 0x5E0,
814                                         p2pinfo->noa_duration[i]);
815                         rtl_write_dword(rtlpriv, 0x5E4,
816                                         p2pinfo->noa_interval[i]);
817
818                         /*Get Current TSF value */
819                         tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B);
820
821                         start_time = p2pinfo->noa_start_time[i];
822                         if (p2pinfo->noa_count_type[i] != 1) {
823                                 while (start_time <= (tsf_low + (50 * 1024))) {
824                                         start_time += p2pinfo->noa_interval[i];
825                                         if (p2pinfo->noa_count_type[i] != 255)
826                                                 p2pinfo->noa_count_type[i]--;
827                                 }
828                         }
829                         rtl_write_dword(rtlpriv, 0x5E8, start_time);
830                         rtl_write_dword(rtlpriv, 0x5EC,
831                                         p2pinfo->noa_count_type[i]);
832                 }
833                 if (p2pinfo->opp_ps == 1 || p2pinfo->noa_num > 0) {
834                         /* rst p2p circuit */
835                         rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4));
836                         p2p_ps_offload->offload_en = 1;
837
838                         if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) {
839                                 p2p_ps_offload->role = 1;
840                                 p2p_ps_offload->allstasleep = 0;
841                         } else {
842                                 p2p_ps_offload->role = 0;
843                         }
844                         p2p_ps_offload->discovery = 0;
845                 }
846                 break;
847         case P2P_PS_SCAN:
848                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
849                 p2p_ps_offload->discovery = 1;
850                 break;
851         case P2P_PS_SCAN_DONE:
852                 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
853                 p2p_ps_offload->discovery = 0;
854                 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
855                 break;
856         default:
857                 break;
858         }
859
860         rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1,
861                                (u8 *)p2p_ps_offload);
862 }
863
864 static
865 void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw,
866                                        u8 c2h_sub_cmd_id,
867                                        u8 c2h_cmd_len,
868                                        u8 *c2h_content_buf)
869 {
870         struct rtl_priv *rtlpriv = rtl_priv(hw);
871         struct rtl_halmac_ops *halmac_ops;
872
873         switch (c2h_sub_cmd_id) {
874         case 0x0F:
875                 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
876                          "[C2H], C2H_8822BE_TX_REPORT!\n");
877                 rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len);
878                 break;
879         default:
880                 /* indicate c2h pkt + rx desc to halmac */
881                 halmac_ops = rtlpriv->halmac.ops;
882                 halmac_ops->halmac_c2h_handle(rtlpriv,
883                                               c2h_content_buf - 24 - 2 - 2,
884                                               c2h_cmd_len + 24 + 2 + 2);
885                 break;
886         }
887 }
888
889 void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
890                                    u8 c2h_cmd_len, u8 *tmp_buf)
891 {
892         struct rtl_priv *rtlpriv = rtl_priv(hw);
893         struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
894
895         if (c2h_cmd_id == 0xFF) {
896                 rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0],
897                                                   c2h_cmd_len - 2,
898                                                   tmp_buf + 2);
899                 return;
900         }
901
902         switch (c2h_cmd_id) {
903         case C2H_8822B_DBG:
904                 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
905                          "[C2H], C2H_8822BE_DBG!!\n");
906                 break;
907         case C2H_8822B_TXBF:
908                 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
909                          "[C2H], C2H_8822B_TXBF!!\n");
910                 break;
911         case C2H_8822B_BT_INFO:
912                 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
913                          "[C2H], C2H_8822BE_BT_INFO!!\n");
914                 if (rtlpriv->cfg->ops->get_btc_status())
915                         btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
916                                                    c2h_cmd_len);
917                 break;
918         case C2H_8822B_BT_MP:
919                 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
920                          "[C2H], C2H_8822BE_BT_MP!!\n");
921                 if (rtlpriv->cfg->ops->get_btc_status())
922                         btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
923                                                      c2h_cmd_len);
924                 break;
925         default:
926                 if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing(
927                             rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf))
928                         break;
929
930                 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
931                          "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
932                 break;
933         }
934 }
935
936 void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
937 {
938         struct rtl_priv *rtlpriv = rtl_priv(hw);
939         u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
940         u8 *tmp_buf = NULL;
941
942         c2h_cmd_id = buffer[0];
943         c2h_cmd_seq = buffer[1];
944         c2h_cmd_len = len - 2;
945         tmp_buf = buffer + 2;
946
947         RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
948                  "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
949                  c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
950
951         RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
952                       "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
953
954         switch (c2h_cmd_id) {
955         case C2H_8822B_BT_INFO:
956         case C2H_8822B_BT_MP:
957                 rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
958                 break;
959         default:
960                 rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
961                                               tmp_buf);
962                 break;
963         }
964 }