1 /******************************************************************************
2 *
3 * Copyright(c) 2016 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26 #include "../wifi.h"
27 #include "../pci.h"
28 #include "../base.h"
29 #include "reg.h"
30 #include "def.h"
31 #include "fw.h"
32
_rtl8822be_check_fw_read_last_h2c(struct ieee80211_hw * hw,u8 boxnum)33 static bool _rtl8822be_check_fw_read_last_h2c(struct ieee80211_hw *hw,
34 u8 boxnum)
35 {
36 struct rtl_priv *rtlpriv = rtl_priv(hw);
37 u8 val_hmetfr;
38 bool result = false;
39
40 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR_8822B);
41 if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
42 result = true;
43 return result;
44 }
45
_rtl8822be_fill_h2c_command(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)46 static void _rtl8822be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id,
47 u32 cmd_len, u8 *cmdbuffer)
48 {
49 struct rtl_priv *rtlpriv = rtl_priv(hw);
50 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
51 u8 boxnum;
52 u16 box_reg = 0, box_extreg = 0;
53 u8 u1b_tmp;
54 bool isfw_read;
55 u8 buf_index = 0;
56 bool bwrite_success = false;
57 u8 wait_h2c_limmit = 100;
58 u8 boxcontent[4], boxextcontent[4];
59 u32 h2c_waitcounter = 0;
60 unsigned long flag;
61 u8 idx;
62
63 /* 1. Prevent race condition in setting H2C cmd.
64 * (copy from MgntActSet_RF_State().)
65 */
66 while (true) {
67 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
68 if (rtlhal->h2c_setinprogress) {
69 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
70 "H2C set in progress! wait..H2C_ID=%d.\n",
71 element_id);
72
73 while (rtlhal->h2c_setinprogress) {
74 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
75 flag);
76 h2c_waitcounter++;
77 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
78 "Wait 100 us (%d times)...\n",
79 h2c_waitcounter);
80 udelay(100);
81
82 if (h2c_waitcounter > 1000)
83 return;
84 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
85 flag);
86 }
87 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
88 } else {
89 rtlhal->h2c_setinprogress = true;
90 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
91 break;
92 }
93 }
94
95 while (!bwrite_success) {
96 /* 2. Find the last BOX number which has been writen. */
97 boxnum = rtlhal->last_hmeboxnum;
98 switch (boxnum) {
99 case 0:
100 box_reg = REG_HMEBOX0_8822B;
101 box_extreg = REG_HMEBOX_E0_8822B;
102 break;
103 case 1:
104 box_reg = REG_HMEBOX1_8822B;
105 box_extreg = REG_HMEBOX_E1_8822B;
106 break;
107 case 2:
108 box_reg = REG_HMEBOX2_8822B;
109 box_extreg = REG_HMEBOX_E2_8822B;
110 break;
111 case 3:
112 box_reg = REG_HMEBOX3_8822B;
113 box_extreg = REG_HMEBOX_E3_8822B;
114 break;
115 default:
116 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
117 "switch case not process\n");
118 break;
119 }
120
121 /* 3. Check if the box content is empty. */
122 u1b_tmp = rtl_read_byte(rtlpriv, REG_CR_8822B);
123
124 if (u1b_tmp == 0xea) {
125 if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS_8822B) ==
126 0xea ||
127 rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY_8822B) ==
128 0xea)
129 rtl_write_byte(rtlpriv, REG_SYS_CFG1_8822B + 3,
130 0xff);
131
132 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
133 "REG_CR is unavaliable\n");
134 break;
135 }
136
137 wait_h2c_limmit = 100;
138 isfw_read = _rtl8822be_check_fw_read_last_h2c(hw, boxnum);
139 while (!isfw_read) {
140 wait_h2c_limmit--;
141 if (wait_h2c_limmit == 0) {
142 RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING,
143 "Wait too long for FW clear MB%d!!!\n",
144 boxnum);
145 break;
146 }
147 udelay(10);
148 isfw_read =
149 _rtl8822be_check_fw_read_last_h2c(hw, boxnum);
150 u1b_tmp = rtl_read_byte(rtlpriv, 0x130);
151 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
152 "Waiting for FW clear MB%d!!! 0x130 = %2x\n",
153 boxnum, u1b_tmp);
154 }
155
156 /* If Fw has not read the last H2C cmd,
157 * break and give up this H2C.
158 */
159 if (!isfw_read) {
160 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
161 "Write H2C reg BOX[%d] fail,Fw don't read.\n",
162 boxnum);
163 break;
164 }
165 /* 4. Fill the H2C cmd into box */
166 memset(boxcontent, 0, sizeof(boxcontent));
167 memset(boxextcontent, 0, sizeof(boxextcontent));
168 boxcontent[0] = element_id;
169 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
170 "Write element_id box_reg(%4x) = %2x\n", box_reg,
171 element_id);
172
173 switch (cmd_len) {
174 case 1:
175 case 2:
176 case 3:
177 /*boxcontent[0] &= ~(BIT(7));*/
178 memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index,
179 cmd_len);
180
181 for (idx = 0; idx < 4; idx++) {
182 rtl_write_byte(rtlpriv, box_reg + idx,
183 boxcontent[idx]);
184 }
185 break;
186 case 4:
187 case 5:
188 case 6:
189 case 7:
190 /*boxcontent[0] |= (BIT(7));*/
191 memcpy((u8 *)(boxextcontent), cmdbuffer + buf_index + 3,
192 cmd_len - 3);
193 memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index,
194 3);
195
196 for (idx = 0; idx < 4; idx++) {
197 rtl_write_byte(rtlpriv, box_extreg + idx,
198 boxextcontent[idx]);
199 }
200
201 for (idx = 0; idx < 4; idx++) {
202 rtl_write_byte(rtlpriv, box_reg + idx,
203 boxcontent[idx]);
204 }
205 break;
206 default:
207 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
208 "switch case not process\n");
209 break;
210 }
211
212 bwrite_success = true;
213
214 rtlhal->last_hmeboxnum = boxnum + 1;
215 if (rtlhal->last_hmeboxnum == 4)
216 rtlhal->last_hmeboxnum = 0;
217
218 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
219 "pHalData->last_hmeboxnum = %d\n",
220 rtlhal->last_hmeboxnum);
221 }
222
223 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
224 rtlhal->h2c_setinprogress = false;
225 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
226
227 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
228 }
229
rtl8822be_fill_h2c_cmd(struct ieee80211_hw * hw,u8 element_id,u32 cmd_len,u8 * cmdbuffer)230 void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len,
231 u8 *cmdbuffer)
232 {
233 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
234 struct rtl_priv *rtlpriv = rtl_priv(hw);
235 u8 tmp_cmdbuf[8];
236
237 if (!rtlhal->fw_ready) {
238 WARN_ONCE(true,
239 "return H2C cmd because of Fw download fail!!!\n");
240 return;
241 }
242
243 memset(tmp_cmdbuf, 0, 8);
244 memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
245
246 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
247 "h2c cmd: len=%d %02X%02X%02X%02X %02X%02X%02X%02X\n", cmd_len,
248 tmp_cmdbuf[2], tmp_cmdbuf[1], tmp_cmdbuf[0], element_id,
249 tmp_cmdbuf[6], tmp_cmdbuf[5], tmp_cmdbuf[4], tmp_cmdbuf[3]);
250
251 _rtl8822be_fill_h2c_command(hw, element_id, cmd_len, tmp_cmdbuf);
252 }
253
rtl8822be_set_default_port_id_cmd(struct ieee80211_hw * hw)254 void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw)
255 {
256 u8 h2c_set_default_port_id[H2C_DEFAULT_PORT_ID_LEN];
257
258 SET_H2CCMD_DFTPID_PORT_ID(h2c_set_default_port_id, 0);
259 SET_H2CCMD_DFTPID_MAC_ID(h2c_set_default_port_id, 0);
260
261 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_DEFAULT_PORT_ID,
262 H2C_DEFAULT_PORT_ID_LEN,
263 h2c_set_default_port_id);
264 }
265
rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw * hw,u8 mode)266 void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
267 {
268 struct rtl_priv *rtlpriv = rtl_priv(hw);
269 u8 u1_h2c_set_pwrmode[H2C_8822B_PWEMODE_LENGTH] = {0};
270 static u8 prev_h2c[H2C_8822B_PWEMODE_LENGTH] = {0};
271 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
272 u8 rlbm, power_state = 0, byte5 = 0;
273 u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
274 u8 smart_ps = 0;
275 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
276 bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
277 btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
278 bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ?
279 btc_ops->btc_is_bt_lps_on(rtlpriv) : false);
280
281 memset(u1_h2c_set_pwrmode, 0, H2C_8822B_PWEMODE_LENGTH);
282
283 if (bt_ctrl_lps)
284 mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE);
285
286 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
287 mode, bt_ctrl_lps);
288
289 switch (mode) {
290 case FW_PS_MIN_MODE:
291 rlbm = 0;
292 awake_intvl = 2;
293 smart_ps = ppsc->smart_ps;
294 break;
295 case FW_PS_MAX_MODE:
296 rlbm = 1;
297 awake_intvl = 2;
298 smart_ps = ppsc->smart_ps;
299 break;
300 case FW_PS_DTIM_MODE:
301 rlbm = 2;
302 awake_intvl = ppsc->reg_max_lps_awakeintvl;
303 /*
304 * hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
305 * is only used in swlps.
306 */
307 smart_ps = ppsc->smart_ps;
308 break;
309 case FW_PS_ACTIVE_MODE:
310 rlbm = 0;
311 awake_intvl = 1;
312 break;
313 default:
314 rlbm = 2;
315 awake_intvl = 4;
316 smart_ps = ppsc->smart_ps;
317 break;
318 }
319
320 if (rtlpriv->mac80211.p2p) {
321 awake_intvl = 2;
322 rlbm = 1;
323 }
324
325 if (mode == FW_PS_ACTIVE_MODE) {
326 byte5 = 0x40;
327 power_state = FW_PWR_STATE_ACTIVE;
328 } else {
329 if (bt_ctrl_lps) {
330 byte5 = btc_ops->btc_get_lps_val(rtlpriv);
331 power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
332
333 if ((rlbm == 2) && (byte5 & BIT(4))) {
334 /* Keep awake interval to 1 to prevent from
335 * decreasing coex performance
336 */
337 awake_intvl = 2;
338 rlbm = 2;
339 }
340 smart_ps = 0;
341 } else {
342 byte5 = 0x40;
343 power_state = FW_PWR_STATE_RF_OFF;
344 }
345 }
346
347 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
348 SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
349 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, smart_ps);
350 SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, awake_intvl);
351 SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
352 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
353 SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
354
355 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
356 "rtl8822be_set_fw_pwrmode(): u1_h2c_set_pwrmode\n",
357 u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH);
358 if (rtlpriv->cfg->ops->get_btc_status())
359 btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode,
360 H2C_8822B_PWEMODE_LENGTH);
361
362 if (!memcmp(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH))
363 return;
364 memcpy(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH);
365
366 rtl8822be_set_default_port_id_cmd(hw);
367 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_SETPWRMODE,
368 H2C_8822B_PWEMODE_LENGTH, u1_h2c_set_pwrmode);
369 }
370
rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw * hw,u8 mstatus)371 void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
372 {
373 u8 parm[4] = {0, 0, 0, 0};
374 /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect
375 * bit1=0-->update Media Status to MACID
376 * bit1=1-->update Media Status from MACID to MACID_End
377 * parm[1]: MACID, if this is INFRA_STA, MacID = 0
378 * parm[2]: MACID_End
379 * parm[3]: bit2-0: port ID
380 */
381
382 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus);
383 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
384
385 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MSRRPT, 4, parm);
386 }
387
_rtl8822be_send_bcn_or_cmd_packet(struct ieee80211_hw * hw,struct sk_buff * skb,u8 hw_queue)388 static bool _rtl8822be_send_bcn_or_cmd_packet(struct ieee80211_hw *hw,
389 struct sk_buff *skb, u8 hw_queue)
390 {
391 struct rtl_priv *rtlpriv = rtl_priv(hw);
392 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
393 struct rtl8192_tx_ring *ring;
394 struct rtl_tx_desc *pdesc;
395 struct rtl_tx_buffer_desc *pbd_desc;
396 unsigned long flags;
397 struct sk_buff *pskb = NULL;
398 u8 *pdesc_or_bddesc;
399 dma_addr_t dma_addr;
400
401 if (hw_queue != BEACON_QUEUE && hw_queue != H2C_QUEUE)
402 return false;
403
404 ring = &rtlpci->tx_ring[hw_queue];
405
406 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
407
408 if (hw_queue == BEACON_QUEUE) {
409 pdesc = &ring->desc[0];
410 pbd_desc = &ring->buffer_desc[0];
411 pdesc_or_bddesc = (u8 *)pbd_desc;
412
413 /* free previous beacon queue */
414 pskb = __skb_dequeue(&ring->queue);
415
416 if (!pskb)
417 goto free_prev_skb_done;
418
419 dma_addr = rtlpriv->cfg->ops->get_desc(
420 hw, (u8 *)pbd_desc, true, HW_DESC_TXBUFF_ADDR);
421
422 pci_unmap_single(rtlpci->pdev, dma_addr, pskb->len,
423 PCI_DMA_TODEVICE);
424 kfree_skb(pskb);
425
426 free_prev_skb_done:
427 ;
428
429 } else { /* hw_queue == TXCMD_QUEUE */
430 if (rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) {
431 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
432 "get_available_desc fail hw_queue=%d\n",
433 hw_queue);
434 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
435 flags);
436 return false;
437 }
438
439 pdesc = &ring->desc[ring->cur_tx_wp];
440 pbd_desc = &ring->buffer_desc[ring->cur_tx_wp];
441 pdesc_or_bddesc = (u8 *)pdesc;
442 }
443
444 rtlpriv->cfg->ops->fill_tx_special_desc(hw, (u8 *)pdesc, (u8 *)pbd_desc,
445 skb, hw_queue);
446
447 __skb_queue_tail(&ring->queue, skb);
448
449 rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc_or_bddesc, true,
450 HW_DESC_OWN, (u8 *)&hw_queue);
451
452 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
453
454 rtlpriv->cfg->ops->tx_polling(hw, hw_queue);
455
456 return true;
457 }
458
rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv * rtlpriv,u8 * buf,u32 size)459 bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf,
460 u32 size)
461 {
462 struct sk_buff *skb = NULL;
463 u8 u1b_tmp;
464 int count;
465
466 skb = dev_alloc_skb(size);
467 if (!skb)
468 return false;
469 memcpy((u8 *)skb_put(skb, size), buf, size);
470
471 if (!_rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, BEACON_QUEUE))
472 return false;
473
474 /* These code isn't actually need, because halmac will check
475 * BCN_VALID
476 */
477
478 /* Polling Beacon Queue to send Beacon */
479 u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
480 count = 0;
481 while ((count < 20) && (u1b_tmp & BIT(4))) {
482 count++;
483 udelay(10);
484 u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1);
485 }
486
487 if (count >= 20)
488 pr_err("%s polling beacon fail\n", __func__);
489
490 return true;
491 }
492
rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv * rtlpriv,u8 * buf,u32 size)493 bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf,
494 u32 size)
495 {
496 struct sk_buff *skb = NULL;
497
498 /* without GFP_DMA, pci_map_single() may not work */
499 skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA);
500 memcpy((u8 *)skb_put(skb, size), buf, size);
501
502 return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE);
503 }
504
505 /* Rsvd page HALMAC_RSVD_DRV_PGNUM_8822B occupies 16 page (2048 byte) */
506 #define BEACON_PG 0 /* ->1 */
507 #define PSPOLL_PG 2
508 #define NULL_PG 3
509 #define PROBERSP_PG 4 /* ->5 */
510 #define QOS_NULL_PG 6
511 #define BT_QOS_NULL_PG 7
512
513 #define TOTAL_RESERVED_PKT_LEN 1024
514
515 static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {/* page size = 128 */
516 /* page 0 beacon */
517 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
518 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
519 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65,
522 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B,
523 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06,
524 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32,
525 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C,
526 0x09, 0x03, 0xFF, 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, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C,
530 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50,
531 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04,
532 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00,
533
534 /* page 1 beacon */
535 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00,
536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 0x10, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 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
552 /* page 2 ps-poll */
553 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B,
554 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x18, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569
570 /* page 3 null */
571 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B,
572 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78,
573 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x72, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587
588 /* page 4 probe_resp */
589 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
590 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
591 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
592 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
593 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
594 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
595 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
596 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
597 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
598 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
599 0x03, 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 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
603 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605
606 /* page 5 probe_resp */
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623
624 /* page 6 qos null data */
625 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
626 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
627 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00,
636 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641
642 /* page 7 BT-qos null data */
643 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7,
644 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02,
645 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 };
660
rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw * hw,bool b_dl_finished)661 void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
662 {
663 struct rtl_priv *rtlpriv = rtl_priv(hw);
664 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
665 struct sk_buff *skb = NULL;
666
667 u32 totalpacketlen;
668 bool rtstatus;
669 u8 u1_rsvd_page_loc[7] = {0};
670 bool b_dlok = false;
671
672 u8 *beacon;
673 u8 *p_pspoll;
674 u8 *nullfunc;
675 u8 *p_probersp;
676 u8 *qosnull;
677 u8 *btqosnull;
678
679 memset(u1_rsvd_page_loc, 0, sizeof(u1_rsvd_page_loc));
680
681 /*---------------------------------------------------------
682 * (1) beacon
683 *---------------------------------------------------------
684 */
685 beacon = &reserved_page_packet[BEACON_PG * 128];
686 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
687 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
688
689 /*-------------------------------------------------------
690 * (2) ps-poll
691 *--------------------------------------------------------
692 */
693 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
694 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
695 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
696 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
697
698 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1_rsvd_page_loc, PSPOLL_PG);
699
700 /*--------------------------------------------------------
701 * (3) null data
702 *---------------------------------------------------------
703 */
704 nullfunc = &reserved_page_packet[NULL_PG * 128];
705 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
706 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
707 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
708
709 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1_rsvd_page_loc, NULL_PG);
710
711 /*---------------------------------------------------------
712 * (4) probe response
713 *----------------------------------------------------------
714 */
715 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
716 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
717 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
718 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
719
720 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1_rsvd_page_loc, PROBERSP_PG);
721
722 /*---------------------------------------------------------
723 * (5) QoS null data
724 *----------------------------------------------------------
725 */
726 qosnull = &reserved_page_packet[QOS_NULL_PG * 128];
727 SET_80211_HDR_ADDRESS1(qosnull, mac->bssid);
728 SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr);
729 SET_80211_HDR_ADDRESS3(qosnull, mac->bssid);
730
731 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1_rsvd_page_loc, QOS_NULL_PG);
732
733 /*---------------------------------------------------------
734 * (6) BT QoS null data
735 *----------------------------------------------------------
736 */
737 btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128];
738 SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid);
739 SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr);
740 SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid);
741
742 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1_rsvd_page_loc,
743 BT_QOS_NULL_PG);
744
745 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
746
747 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
748 "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
749 &reserved_page_packet[0], totalpacketlen);
750 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
751 "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
752 u1_rsvd_page_loc, 3);
753
754 skb = dev_alloc_skb(totalpacketlen);
755 if (!skb)
756 return;
757 memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet,
758 totalpacketlen);
759
760 rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE);
761
762 if (rtstatus)
763 b_dlok = true;
764
765 if (b_dlok) {
766 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
767 "Set RSVD page location to Fw.\n");
768 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n",
769 u1_rsvd_page_loc, 3);
770 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE,
771 sizeof(u1_rsvd_page_loc),
772 u1_rsvd_page_loc);
773 } else
774 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
775 "Set RSVD page location to Fw FAIL!!!!!!.\n");
776 }
777
778 /* Should check FW support p2p or not. */
rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw * hw,u8 ctwindow)779 static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
780 u8 ctwindow)
781 {
782 u8 u1_ctwindow_period[1] = {ctwindow};
783
784 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1,
785 u1_ctwindow_period);
786 }
787
rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw * hw,u8 p2p_ps_state)788 void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
789 {
790 struct rtl_priv *rtlpriv = rtl_priv(hw);
791 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
792 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
793 struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
794 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
795 u8 i;
796 u16 ctwindow;
797 u32 start_time, tsf_low;
798
799 switch (p2p_ps_state) {
800 case P2P_PS_DISABLE:
801 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
802 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
803 break;
804 case P2P_PS_ENABLE:
805 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
806 /* update CTWindow value. */
807 if (p2pinfo->ctwindow > 0) {
808 p2p_ps_offload->ctwindow_en = 1;
809 ctwindow = p2pinfo->ctwindow;
810 rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow);
811 }
812 /* hw only support 2 set of NoA */
813 for (i = 0; i < p2pinfo->noa_num; i++) {
814 /* To control the register setting for which NOA*/
815 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
816 if (i == 0)
817 p2p_ps_offload->noa0_en = 1;
818 else
819 p2p_ps_offload->noa1_en = 1;
820 /* config P2P NoA Descriptor Register */
821 rtl_write_dword(rtlpriv, 0x5E0,
822 p2pinfo->noa_duration[i]);
823 rtl_write_dword(rtlpriv, 0x5E4,
824 p2pinfo->noa_interval[i]);
825
826 /*Get Current TSF value */
827 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B);
828
829 start_time = p2pinfo->noa_start_time[i];
830 if (p2pinfo->noa_count_type[i] != 1) {
831 while (start_time <= (tsf_low + (50 * 1024))) {
832 start_time += p2pinfo->noa_interval[i];
833 if (p2pinfo->noa_count_type[i] != 255)
834 p2pinfo->noa_count_type[i]--;
835 }
836 }
837 rtl_write_dword(rtlpriv, 0x5E8, start_time);
838 rtl_write_dword(rtlpriv, 0x5EC,
839 p2pinfo->noa_count_type[i]);
840 }
841 if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) {
842 /* rst p2p circuit */
843 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4));
844 p2p_ps_offload->offload_en = 1;
845
846 if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) {
847 p2p_ps_offload->role = 1;
848 p2p_ps_offload->allstasleep = 0;
849 } else {
850 p2p_ps_offload->role = 0;
851 }
852 p2p_ps_offload->discovery = 0;
853 }
854 break;
855 case P2P_PS_SCAN:
856 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
857 p2p_ps_offload->discovery = 1;
858 break;
859 case P2P_PS_SCAN_DONE:
860 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
861 p2p_ps_offload->discovery = 0;
862 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
863 break;
864 default:
865 break;
866 }
867
868 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1,
869 (u8 *)p2p_ps_offload);
870 }
871
872 static
rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw * hw,u8 c2h_sub_cmd_id,u8 c2h_cmd_len,u8 * c2h_content_buf)873 void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw,
874 u8 c2h_sub_cmd_id,
875 u8 c2h_cmd_len,
876 u8 *c2h_content_buf)
877 {
878 struct rtl_priv *rtlpriv = rtl_priv(hw);
879 struct rtl_halmac_ops *halmac_ops;
880
881 switch (c2h_sub_cmd_id) {
882 case 0x0F:
883 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
884 "[C2H], C2H_8822BE_TX_REPORT!\n");
885 rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len);
886 break;
887 default:
888 /* indicate c2h pkt + rx desc to halmac */
889 halmac_ops = rtlpriv->halmac.ops;
890 halmac_ops->halmac_c2h_handle(rtlpriv,
891 c2h_content_buf - 24 - 2 - 2,
892 c2h_cmd_len + 24 + 2 + 2);
893 break;
894 }
895 }
896
rtl8822be_c2h_content_parsing(struct ieee80211_hw * hw,u8 c2h_cmd_id,u8 c2h_cmd_len,u8 * tmp_buf)897 void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
898 u8 c2h_cmd_len, u8 *tmp_buf)
899 {
900 struct rtl_priv *rtlpriv = rtl_priv(hw);
901 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
902
903 if (c2h_cmd_id == 0xFF) {
904 rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0],
905 c2h_cmd_len - 2,
906 tmp_buf + 2);
907 return;
908 }
909
910 switch (c2h_cmd_id) {
911 case C2H_8822B_DBG:
912 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
913 "[C2H], C2H_8822BE_DBG!!\n");
914 break;
915 case C2H_8822B_TXBF:
916 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
917 "[C2H], C2H_8822B_TXBF!!\n");
918 break;
919 case C2H_8822B_BT_INFO:
920 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
921 "[C2H], C2H_8822BE_BT_INFO!!\n");
922 if (rtlpriv->cfg->ops->get_btc_status())
923 btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
924 c2h_cmd_len);
925 break;
926 case C2H_8822B_BT_MP:
927 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
928 "[C2H], C2H_8822BE_BT_MP!!\n");
929 if (rtlpriv->cfg->ops->get_btc_status())
930 btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
931 c2h_cmd_len);
932 break;
933 default:
934 if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing(
935 rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf))
936 break;
937
938 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
939 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
940 break;
941 }
942 }
943
rtl8822be_c2h_packet_handler(struct ieee80211_hw * hw,u8 * buffer,u8 len)944 void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
945 {
946 struct rtl_priv *rtlpriv = rtl_priv(hw);
947 u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
948 u8 *tmp_buf = NULL;
949
950 c2h_cmd_id = buffer[0];
951 c2h_cmd_seq = buffer[1];
952 c2h_cmd_len = len - 2;
953 tmp_buf = buffer + 2;
954
955 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
956 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
957 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
958
959 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
960 "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
961
962 switch (c2h_cmd_id) {
963 case C2H_8822B_BT_INFO:
964 case C2H_8822B_BT_MP:
965 rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
966 break;
967 default:
968 rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
969 tmp_buf);
970 break;
971 }
972 }
973