]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blame - drivers/staging/rtlwifi/rtl8822be/fw.c
Merge branches 'for-5.1/upstream-fixes', 'for-5.2/core', 'for-5.2/ish', 'for-5.2...
[mirror_ubuntu-kernels.git] / drivers / staging / rtlwifi / rtl8822be / fw.c
CommitLineData
a67cfe39 1// SPDX-License-Identifier: GPL-2.0
7e5b796c
PKS
2/******************************************************************************
3 *
4 * Copyright(c) 2016 Realtek Corporation.
5 *
7e5b796c
PKS
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
22static 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
35static 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) {
971f3f11 85 /* 2. Find the last BOX number which has been written. */
7e5b796c
PKS
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
219void 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
243void 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
255void 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
d8f36e80 322 if (rlbm == 2 && (byte5 & BIT(4))) {
7e5b796c
PKS
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
360void 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
377static 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
c40a45a4 411 pci_unmap_single(rtlpci->pdev, dma_addr, pskb->len,
7e5b796c
PKS
412 PCI_DMA_TODEVICE);
413 kfree_skb(pskb);
414
415free_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
448bool 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);
3eb23426
CIK
456 if (!skb)
457 return false;
7e5b796c
PKS
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
482bool 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);
0a54ea9f
KL
489 if (!skb)
490 return false;
7e5b796c
PKS
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
506static 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
652void 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);
d70d70ae
AP
746 if (!skb)
747 return;
7e5b796c
PKS
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);
85d00775 764 } else {
7e5b796c
PKS
765 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
766 "Set RSVD page location to Fw FAIL!!!!!!.\n");
85d00775 767 }
7e5b796c
PKS
768}
769
770/* Should check FW support p2p or not. */
771static 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
780void 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 }
d8f36e80 833 if (p2pinfo->opp_ps == 1 || p2pinfo->noa_num > 0) {
7e5b796c
PKS
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
864static
865void 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
889void 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
936void 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}