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