1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
33static 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
46static 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
64
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
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
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
157
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
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
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
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
230void 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
254void 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
266void 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;
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
305
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
335
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
371void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus)
372{
373 u8 parm[4] = {0, 0, 0, 0};
374
375
376
377
378
379
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
388static 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
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
426free_prev_skb_done:
427 ;
428
429 } else {
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
459bool 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
475
476
477
478
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
493bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf,
494 u32 size)
495{
496 struct sk_buff *skb = NULL;
497
498
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
506#define BEACON_PG 0
507#define PSPOLL_PG 2
508#define NULL_PG 3
509#define PROBERSP_PG 4
510#define QOS_NULL_PG 6
511#define BT_QOS_NULL_PG 7
512
513#define TOTAL_RESERVED_PKT_LEN 1024
514
515static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
516
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
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
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
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
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
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
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
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
661void 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
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
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
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
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
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
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 memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet,
756 totalpacketlen);
757
758 rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE);
759
760 if (rtstatus)
761 b_dlok = true;
762
763 if (b_dlok) {
764 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
765 "Set RSVD page location to Fw.\n");
766 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n",
767 u1_rsvd_page_loc, 3);
768 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE,
769 sizeof(u1_rsvd_page_loc),
770 u1_rsvd_page_loc);
771 } else {
772 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
773 "Set RSVD page location to Fw FAIL!!!!!!.\n");
774 }
775}
776
777
778static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw,
779 u8 ctwindow)
780{
781 u8 u1_ctwindow_period[1] = {ctwindow};
782
783 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1,
784 u1_ctwindow_period);
785}
786
787void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state)
788{
789 struct rtl_priv *rtlpriv = rtl_priv(hw);
790 struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw));
791 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
792 struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info;
793 struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload;
794 u8 i;
795 u16 ctwindow;
796 u32 start_time, tsf_low;
797
798 switch (p2p_ps_state) {
799 case P2P_PS_DISABLE:
800 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n");
801 memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload));
802 break;
803 case P2P_PS_ENABLE:
804 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n");
805
806 if (p2pinfo->ctwindow > 0) {
807 p2p_ps_offload->ctwindow_en = 1;
808 ctwindow = p2pinfo->ctwindow;
809 rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow);
810 }
811
812 for (i = 0; i < p2pinfo->noa_num; i++) {
813
814 rtl_write_byte(rtlpriv, 0x5cf, (i << 4));
815 if (i == 0)
816 p2p_ps_offload->noa0_en = 1;
817 else
818 p2p_ps_offload->noa1_en = 1;
819
820 rtl_write_dword(rtlpriv, 0x5E0,
821 p2pinfo->noa_duration[i]);
822 rtl_write_dword(rtlpriv, 0x5E4,
823 p2pinfo->noa_interval[i]);
824
825
826 tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B);
827
828 start_time = p2pinfo->noa_start_time[i];
829 if (p2pinfo->noa_count_type[i] != 1) {
830 while (start_time <= (tsf_low + (50 * 1024))) {
831 start_time += p2pinfo->noa_interval[i];
832 if (p2pinfo->noa_count_type[i] != 255)
833 p2pinfo->noa_count_type[i]--;
834 }
835 }
836 rtl_write_dword(rtlpriv, 0x5E8, start_time);
837 rtl_write_dword(rtlpriv, 0x5EC,
838 p2pinfo->noa_count_type[i]);
839 }
840 if (p2pinfo->opp_ps == 1 || p2pinfo->noa_num > 0) {
841
842 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4));
843 p2p_ps_offload->offload_en = 1;
844
845 if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) {
846 p2p_ps_offload->role = 1;
847 p2p_ps_offload->allstasleep = 0;
848 } else {
849 p2p_ps_offload->role = 0;
850 }
851 p2p_ps_offload->discovery = 0;
852 }
853 break;
854 case P2P_PS_SCAN:
855 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n");
856 p2p_ps_offload->discovery = 1;
857 break;
858 case P2P_PS_SCAN_DONE:
859 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n");
860 p2p_ps_offload->discovery = 0;
861 p2pinfo->p2p_ps_state = P2P_PS_ENABLE;
862 break;
863 default:
864 break;
865 }
866
867 rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1,
868 (u8 *)p2p_ps_offload);
869}
870
871static
872void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw,
873 u8 c2h_sub_cmd_id,
874 u8 c2h_cmd_len,
875 u8 *c2h_content_buf)
876{
877 struct rtl_priv *rtlpriv = rtl_priv(hw);
878 struct rtl_halmac_ops *halmac_ops;
879
880 switch (c2h_sub_cmd_id) {
881 case 0x0F:
882 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
883 "[C2H], C2H_8822BE_TX_REPORT!\n");
884 rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len);
885 break;
886 default:
887
888 halmac_ops = rtlpriv->halmac.ops;
889 halmac_ops->halmac_c2h_handle(rtlpriv,
890 c2h_content_buf - 24 - 2 - 2,
891 c2h_cmd_len + 24 + 2 + 2);
892 break;
893 }
894}
895
896void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
897 u8 c2h_cmd_len, u8 *tmp_buf)
898{
899 struct rtl_priv *rtlpriv = rtl_priv(hw);
900 struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
901
902 if (c2h_cmd_id == 0xFF) {
903 rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0],
904 c2h_cmd_len - 2,
905 tmp_buf + 2);
906 return;
907 }
908
909 switch (c2h_cmd_id) {
910 case C2H_8822B_DBG:
911 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
912 "[C2H], C2H_8822BE_DBG!!\n");
913 break;
914 case C2H_8822B_TXBF:
915 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
916 "[C2H], C2H_8822B_TXBF!!\n");
917 break;
918 case C2H_8822B_BT_INFO:
919 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
920 "[C2H], C2H_8822BE_BT_INFO!!\n");
921 if (rtlpriv->cfg->ops->get_btc_status())
922 btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf,
923 c2h_cmd_len);
924 break;
925 case C2H_8822B_BT_MP:
926 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
927 "[C2H], C2H_8822BE_BT_MP!!\n");
928 if (rtlpriv->cfg->ops->get_btc_status())
929 btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf,
930 c2h_cmd_len);
931 break;
932 default:
933 if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing(
934 rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf))
935 break;
936
937 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
938 "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id);
939 break;
940 }
941}
942
943void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len)
944{
945 struct rtl_priv *rtlpriv = rtl_priv(hw);
946 u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0;
947 u8 *tmp_buf = NULL;
948
949 c2h_cmd_id = buffer[0];
950 c2h_cmd_seq = buffer[1];
951 c2h_cmd_len = len - 2;
952 tmp_buf = buffer + 2;
953
954 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
955 "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n",
956 c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len);
957
958 RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE,
959 "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len);
960
961 switch (c2h_cmd_id) {
962 case C2H_8822B_BT_INFO:
963 case C2H_8822B_BT_MP:
964 rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf);
965 break;
966 default:
967 rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len,
968 tmp_buf);
969 break;
970 }
971}
972