-
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathHalModule.cpp
More file actions
2610 lines (2312 loc) · 107 KB
/
HalModule.cpp
File metadata and controls
2610 lines (2312 loc) · 107 KB
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#include "HalModule.h"
#include "FirmwareManager.h"
#include "Hal8812PhyReg.h"
#include "Hal8814_PhyTables.h"
#include "PhyTableLoader.h"
#include "phydm_pre_define.h"
#include "registry_priv.h"
#include "rtl8812a_hal.h"
#include "rtl8812a_spec.h"
/* 8814AU register + page constants extracted from upstream
* hal/rtl8814a_spec.h and hal/rtl8814a_hal.h. Inlined here because the
* upstream headers pull in kernel-only deps (drv_conf.h, hal_data.h). */
namespace rtl8814a {
constexpr uint16_t REG_FIFOPAGE_INFO_1_8814A = 0x0230;
constexpr uint16_t REG_FIFOPAGE_INFO_2_8814A = 0x0234;
constexpr uint16_t REG_FIFOPAGE_INFO_3_8814A = 0x0238;
constexpr uint16_t REG_FIFOPAGE_INFO_4_8814A = 0x023C;
constexpr uint16_t REG_FIFOPAGE_INFO_5_8814A = 0x0240;
constexpr uint16_t REG_RQPN_CTRL_2_8814A = 0x022C;
constexpr uint16_t REG_FIFOPAGE_CTRL_2_8814A = 0x0204;
constexpr uint16_t REG_TXPKTBUF_BCNQ_BDNY_8814A = 0x0424;
constexpr uint16_t REG_TXPKTBUF_BCNQ1_BDNY_8814A = 0x0426; /* spec calls it +2 */
constexpr uint16_t REG_MGQ_PGBNDY_8814A = 0x047A;
constexpr uint16_t REG_RXFF_PTR_8814A = 0x011C;
constexpr uint32_t HPQ_PGNUM_8814A = 0x20; /* 32 pages per queue (USB) */
constexpr uint32_t LPQ_PGNUM_8814A = 0x20;
constexpr uint32_t NPQ_PGNUM_8814A = 0x20;
constexpr uint32_t EPQ_PGNUM_8814A = 0x20;
constexpr uint32_t BCNQ_PAGE_NUM_8814 = 0x08;
constexpr uint32_t WOWLAN_PAGE_NUM_8814 = 0x00;
constexpr uint32_t TXPKT_PGNUM_8814A =
2048 - BCNQ_PAGE_NUM_8814 - WOWLAN_PAGE_NUM_8814;
constexpr uint32_t PUB_PGNUM_8814A = TXPKT_PGNUM_8814A - HPQ_PGNUM_8814A -
NPQ_PGNUM_8814A - LPQ_PGNUM_8814A -
EPQ_PGNUM_8814A;
constexpr uint16_t TX_PAGE_BOUNDARY_8814A = TXPKT_PGNUM_8814A;
constexpr uint16_t WMM_NORMAL_TX_PAGE_BOUNDARY_8814A = TXPKT_PGNUM_8814A + 1;
constexpr uint32_t MAX_RX_DMA_BUFFER_SIZE_8814A = 0x5C00;
constexpr uint16_t RX_DMA_BOUNDARY_8814A = MAX_RX_DMA_BUFFER_SIZE_8814A - 1;
} // namespace rtl8814a
#include <chrono>
#include <memory>
#include <thread>
#define DRVINFO_SZ 4
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
HalModule::HalModule(
RtlUsbAdapter device, std::shared_ptr<EepromManager> eepromManager,
std::shared_ptr<RadioManagementModule> radioManagementModule,
Logger_t logger)
: _device{device}, _radioManagementModule{radioManagementModule},
_eepromManager{eepromManager}, _logger{logger} {}
bool HalModule::rtw_hal_init(SelectedChannel selectedChannel) {
auto status = rtl8812au_hal_init();
if (status) {
_radioManagementModule->init_hw_mlme_ext(selectedChannel);
_radioManagementModule->SetMonitorMode();
} else {
_logger->error("rtw_hal_init: fail");
}
return status;
}
bool HalModule::rtl8812au_hal_init() {
// Check if MAC has already power on. by tynli. 2011.05.27.
auto value8 = _device.rtw_read8(REG_SYS_CLKR + 1);
auto regCr = _device.rtw_read8(REG_CR);
_logger->info("power-on :REG_SYS_CLKR 0x09=0x{:X}. REG_CR 0x100=0x{:X}",
(int)value8, (int)regCr);
if ((value8 & BIT3) != 0 && (regCr != 0 && regCr != 0xEA)) {
/* pHalData.bMACFuncEnable = TRUE; */
_logger->info("MAC has already power on");
} else {
/* pHalData.bMACFuncEnable = FALSE; */
/* Set FwPSState to ALL_ON mode to prevent from the I/O be return because of
* 32k */
/* state which is set before sleep under wowlan mode. 2012.01.04. by tynli.
*/
/* pHalData.FwPSState = FW_PS_STATE_ALL_ON_88E; */
_logger->info("MAC has not been powered on yet");
}
/* 8814AU divergence on PRE-fwdl init only: skip 8812-era RF_CTRL pokes,
* hw_reset (no-op on cold boot anyway), and our aircrack-ng-ported
* card_enable_flow power-seq — all of which write to registers
* rtw88_8814au never touches pre-fwdl (e.g. REG_RF_CTRL=0x05/0x07,
* REG_OPT_CTRL+2=0x05/0x07). The 8814 pre-fwdl state is set up by the
* 242-op rtw88-mimic inside FirmwareDownload_8814A instead.
*
* POST-fwdl init flow (Queue/Page/WMAC/MSR/Aggregation/BB/RF) is run for
* both chips — these write to chip-version-agnostic registers and the
* functions that do diverge dispatch internally on ICType. */
const bool is_8814a = _eepromManager->version_id.ICType == CHIP_8814A;
if (!is_8814a) {
_device.rtw_write8(REG_RF_CTRL, 5);
_device.rtw_write8(REG_RF_CTRL, 7);
_device.rtw_write8(REG_RF_B_CTRL_8812, 5);
_device.rtw_write8(REG_RF_B_CTRL_8812, 7);
// If HW didn't go through a complete de-initial procedure,
// it probably occurs some problem for double initial procedure.
// Like "CONFIG_DEINIT_BEFORE_INIT" in 92du chip
_device.rtl8812au_hw_reset();
auto initPowerOnStatus = InitPowerOn();
if (initPowerOnStatus == false) {
return false;
}
}
/* LLT table init: 8812 needs it pre-fw download; 8814AU does NOT — rtw88
* runs LLT init AFTER fw boot, and doing it pre-fw on 8814 breaks the
* beacon-queue fwdl path (the chip silently rejects bulk OUT writes). */
if (_eepromManager->version_id.ICType != CHIP_8814A) {
if (!InitLLTTable8812A(TX_PAGE_BOUNDARY_8812)) {
_logger->error("InitLLTTable8812A failed");
return false;
}
}
_InitHardwareDropIncorrectBulkOut_8812A();
auto fwManager = std::make_unique<FirmwareManager>(_device, _logger);
fwManager->FirmwareDownload(_eepromManager->version_id.ICType);
/* 8814AU: now that fw is running, the chip will accept EFUSE reads
* without breaking RSVD-page fwdl (which is past). Read the board's
* actual rfe_type, PA/LNA types, crystal cap, etc., so that
* GetPhyContext() returns real values to PhyTableLoader instead of
* the fallback rfe_type=1 used pre-EFUSE-read. */
_eepromManager->LateInitFor8814A();
PHY_MACConfig8812();
if (is_8814a) {
/* 8814AU has its own TX FIFO page allocation: 2048 total pages vs 8812's
* 256, set via 32-bit FIFOPAGE_INFO_{1..5} regs + 16-bit BCNQ/MGQ page
* boundaries. The 8812 path uses 8-bit REG_RQPN / REG_BCNQ_BDNY etc.
* which silently no-op on 8814 — that leaves HPQ with 0 pages, so MGT
* frames submitted via bulk OUT have nowhere to land and the chip never
* drains the EP (USB bulk OUT times out). */
_InitQueueReservedPage_8814AUsb();
/* TX buffer boundary is set inside _InitQueueReservedPage_8814AUsb. Skip
* _InitTxBufferBoundary_8812AUsb. */
_InitQueuePriority_8812AUsb(); /* dispatches on CHIP_8814A internally */
_InitPageBoundary_8814AUsb();
/* _InitTransferPageSize_8814AUsb is a no-op upstream. */
/* 8814AU auto-LLT trigger via 32-bit BIT16 of REG_AUTO_LLT_8814A (0x0208,
* aliased as REG_TDECTRL). The generic Realtek bit definition is
* BIT_AUTO_INIT_LLT = BIT(16) (see hal_com_reg.h). The upstream OOT
* code at rtl8814a_hal_init.c::InitLLTTable8814A writes BIT0 of an 8-bit
* read at 0x208 — that's a different bit entirely; empirically the
* trigger never fires (auto-LLT "completes in 0 polls" because BIT0
* was never set). Use the correct BIT(16) trigger as a 32-bit RMW.
* Without auto-LLT, the chip's TX FIFO page-count regs we just set are
* advertised but no free-page list is linked, so the chip's TX queues
* have nowhere to store inbound bulk-OUT frames and vendor-control
* transfers to OUT EPs time out forever. */
constexpr uint16_t REG_AUTO_LLT_8814A = 0x0208;
constexpr uint32_t AUTO_INIT_LLT_BIT = 1u << 16; /* renamed: hal_com_reg.h's BIT_AUTO_INIT_LLT macro collides */
uint32_t llt = _device.rtw_read32(REG_AUTO_LLT_8814A);
_logger->info("8814A auto-LLT pre REG_AUTO_LLT=0x{:08x}", llt);
_device.rtw_write32(REG_AUTO_LLT_8814A, llt | AUTO_INIT_LLT_BIT);
int polls = 0;
do {
llt = _device.rtw_read32(REG_AUTO_LLT_8814A);
if (!(llt & AUTO_INIT_LLT_BIT))
break;
std::this_thread::sleep_for(std::chrono::milliseconds(2));
++polls;
} while (polls < 200);
if (llt & AUTO_INIT_LLT_BIT) {
_logger->error("8814A auto-LLT did not complete (REG_AUTO_LLT=0x{:08x} "
"after {} polls)",
llt, polls);
} else {
_logger->info(
"8814A auto-LLT completed in {} polls (REG_AUTO_LLT=0x{:08x})", polls,
llt);
}
} else {
_InitQueueReservedPage_8812AUsb();
_InitTxBufferBoundary_8812AUsb();
_InitQueuePriority_8812AUsb();
_InitPageBoundary_8812AUsb();
_InitTransferPageSize_8812AUsb();
}
// Get Rx PHY status in order to report RSSI and others.
_InitDriverInfoSize_8812A(DRVINFO_SZ);
_InitInterrupt_8812AU();
_InitNetworkType_8812A(); /* set msr */
_InitWMACSetting_8812A();
_InitAdaptiveCtrl_8812AUsb();
_InitEDCA_8812AUsb();
_InitRetryFunction_8812A();
init_UsbAggregationSetting_8812A();
_InitBeaconParameters_8812A();
_InitBeaconMaxError_8812A();
_InitBurstPktLen(); // added by page. 20110919
// Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to
// patch Hw bug which Hw initials RxFF boundry size to a value which is larger
// than the real Rx buffer size in 88E. 2011.08.05. by tynli.
value8 = _device.rtw_read8(REG_CR);
_device.rtw_write8(REG_CR, (uint8_t)(value8 | MACTXEN | MACRXEN));
_device.rtw_write16(REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
_device.rtw_write16(REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
/* 8814AU BB/RF domain power-on. Without these writes, the chip's BB
* register space (0x800-0xFFF) silently rejects writes via vendor
* control transfer — PhyTableLoader runs 1837 writes but read-back
* shows none of them stuck. Verified by pyusb experiment: writing
* 0xCAFEBABE to MAC reg 0x0114 succeeds, but writing same to BB reg
* 0x0824 returns success at USB level yet chip leaves the reg
* unchanged.
*
* Mirrors rtw88_8814au rtw8814a.c:289-303:
* 1. enable USB→BB path: REG_SYS_FUNC_EN |= BIT_FEN_USBA (BIT2)
* 2. release BB reset: REG_SYS_CFG3_8814A+2 |= BB_RSTB|BB_GLB_RST
* 3. power on RF paths A..D: REG_RF_CTRL[0/1/2/3] = RF_EN|RF_RSTB|
* RF_SDM_RSTB (= 0x07) — 4 separate registers for the 4 RF
* chains of the 4T4R chip. */
if (_eepromManager->version_id.ICType == CHIP_8814A) {
constexpr uint16_t REG_SYS_CFG3_8814A_HI = 0x1000 + 2;
constexpr uint16_t REG_RF_CTRL_A = 0x001F;
constexpr uint16_t REG_RF_CTRL_B = 0x0020;
constexpr uint16_t REG_RF_CTRL_C = 0x0021;
constexpr uint16_t REG_RF_CTRL_D = 0x0076;
constexpr uint8_t RF_PWR_ON = 0x07; /* RF_EN | RF_RSTB | RF_SDM_RSTB */
const uint8_t syf = _device.rtw_read8(REG_SYS_FUNC_EN);
_device.rtw_write8(REG_SYS_FUNC_EN, (uint8_t)(syf | BIT(2)));
const uint8_t bb_cfg = _device.rtw_read8(REG_SYS_CFG3_8814A_HI);
_device.rtw_write8(REG_SYS_CFG3_8814A_HI, (uint8_t)(bb_cfg | 0x03));
_device.rtw_write8(REG_RF_CTRL_A, RF_PWR_ON);
_device.rtw_write8(REG_RF_CTRL_B, RF_PWR_ON);
_device.rtw_write8(REG_RF_CTRL_C, RF_PWR_ON);
_device.rtw_write8(REG_RF_CTRL_D, RF_PWR_ON);
_logger->info("8814A BB/RF domain powered on (FEN_USBA, BB_RSTB, RF A..D)");
}
auto bbConfig8812Status = PHY_BBConfig8812();
if (bbConfig8812Status == false) {
return false;
}
PHY_RF6052_Config_8812();
if (_eepromManager->version_id.RFType == RF_TYPE_1T1R) {
PHY_BB8812_Config_1T();
}
if (registry_priv::rf_config == RF_TYPE_1T2R) {
_device.phy_set_bb_reg(rTxPath_Jaguar, bMaskLWord, 0x1111);
}
if (registry_priv::channel <= 14) {
_radioManagementModule->PHY_SwitchWirelessBand8812(BandType::BAND_ON_2_4G);
} else {
_radioManagementModule->PHY_SwitchWirelessBand8812(BandType::BAND_ON_5G);
}
_radioManagementModule->rtw_hal_set_chnl_bw(
registry_priv::channel, ChannelWidth_t::CHANNEL_WIDTH_20,
HAL_PRIME_CHNL_OFFSET_DONT_CARE, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
// HW SEQ CTRL
// set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM.
// On 8814 the chip rejects 8-bit access at offset 0x423 (byte 3 of
// FWHW_TXQ_CTRL@0x420) — the rtw_write8 at this address silently no-ops
// and rtw_read8 returns 0 regardless of the actual byte. Verified by the
// diag dump: rtw_read32(0x420) shows byte3=0x03 but rtw_read8(0x423)=0x00.
// Use a 32-bit aligned RMW so the chip's USB controller handles it as a
// word-sized access.
if (is_8814a) {
uint32_t txqctl = _device.rtw_read32(REG_FWHW_TXQ_CTRL);
txqctl = (txqctl & 0x00FFFFFFu) | (0xFFu << 24);
_device.rtw_write32(REG_FWHW_TXQ_CTRL, txqctl);
} else {
_device.rtw_write8(REG_HWSEQ_CTRL, 0xFF);
}
// Disable BAR, suggested by Scott
// 2010.04.09 add by hpfan
_device.rtw_write32(REG_BAR_MODE_CTRL, 0x0201ffff);
if (registry_priv::wifi_spec) {
_device.rtw_write16(REG_FAST_EDCA_CTRL, 0);
}
// Nav limit , suggest by scott
_device.rtw_write8(0x652, 0x0);
/* 0x4c6[3] 1: RTS BW = Data BW */
/* 0: RTS BW depends on CCA / secondary CCA result. */
_device.rtw_write8(REG_QUEUE_CTRL,
(uint8_t)(_device.rtw_read8(REG_QUEUE_CTRL) & 0xF7));
/* enable Tx report. */
_device.rtw_write8(REG_FWHW_TXQ_CTRL + 1, 0x0F);
/* Suggested by SD1 pisa. Added by tynli. 2011.10.21. */
_device.rtw_write8(REG_EARLY_MODE_CONTROL_8812 + 3,
0x01); /* Pretx_en, for WEP/TKIP SEC */
/* tynli_test_tx_report. */
_device.rtw_write16(REG_TX_RPT_TIME, 0x3DF0);
/* Reset USB mode switch setting */
_device.rtw_write8(REG_SDIO_CTRL_8812, 0x0);
_device.rtw_write8(REG_ACLK_MON, 0x0);
_device.rtw_write8(REG_USB_HRPWM, 0);
// TODO:
///* ack for xmit mgmt frames. */
_device.rtw_write32(REG_FWHW_TXQ_CTRL,
_device.rtw_read32(REG_FWHW_TXQ_CTRL) | BIT12);
/* Final safety re-write of MAC/RX enable bits. Some of the post-fwdl
* init helpers can overwrite REG_CR back to only MACTXEN|MACRXEN
* (clearing DMA + protocol + scheduler) — verified via post-init pyusb
* probe showing REG_CR=0xc0. And REG_RXFLTMAP2 read back as 0 instead
* of the 0xFFFF we want for monitor-mode data-frame acceptance. Force
* the final state here so RX bulk IN actually moves frames.
*
* 8814 hypothesis: firmware programs REG_CR after it boots and may set
* bits beyond our 0x00FF mask (ENSEC=BIT9, CALTMR_EN=BIT10 — both in
* the upstream _InitPowerOn_8814AU OR-mask, neither in our cr_final).
* Forcing 0x00FF on 8814 could clobber fw-set high bits that gate TX.
* Read current REG_CR first, then OR in our minimum-required bits
* instead of clobbering the whole word. */
uint16_t cr_observed = _device.rtw_read16(REG_CR);
uint16_t cr_min = (uint16_t)(HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN |
RXDMA_EN | PROTOCOL_EN | SCHEDULE_EN |
MACTXEN | MACRXEN);
uint16_t cr_final = static_cast<uint16_t>(cr_observed | cr_min);
_device.rtw_write16(REG_CR, cr_final);
_device.rtw_write16(REG_RXFLTMAP2, 0xFFFF);
_logger->info(
"post-init final: REG_CR observed=0x{:04x} written=0x{:04x} "
"REG_RXFLTMAP2=0xFFFF",
cr_observed, cr_final);
if (is_8814a) {
/* TX-validation diagnostic. Read back the registers that gate USB→TX
* dataflow to confirm what state the chip is actually in at the end of
* init. One log per register to dodge the Logger format helper's
* placeholder-overflow truncation. */
using namespace rtl8814a;
_logger->info("8814A TX-state CR = 0x{:04x}", _device.rtw_read16(REG_CR));
_logger->info("8814A TX-state TXPAUSE(0x522) = 0x{:02x}",
_device.rtw_read8(0x0522));
_logger->info("8814A TX-state FWHW_TXQ_CTRL(0x420) = 0x{:08x}",
_device.rtw_read32(0x0420));
_logger->info("8814A TX-state FIFOPAGE_CTRL_2 = 0x{:08x}",
_device.rtw_read32(REG_FIFOPAGE_CTRL_2_8814A));
_logger->info("8814A TX-state MGQ_PGBNDY = 0x{:04x}",
_device.rtw_read16(REG_MGQ_PGBNDY_8814A));
_logger->info("8814A TX-state FIFOPAGE_INFO_1(HPQ) = 0x{:08x}",
_device.rtw_read32(REG_FIFOPAGE_INFO_1_8814A));
_logger->info("8814A TX-state FIFOPAGE_INFO_5(PUB) = 0x{:08x}",
_device.rtw_read32(REG_FIFOPAGE_INFO_5_8814A));
_logger->info("8814A TX-state MCUFWDL = 0x{:08x}",
_device.rtw_read32(0x0080));
_logger->info("8814A TX-state TXDMA_STATUS(0x210) = 0x{:08x}",
_device.rtw_read32(0x0210));
_logger->info("8814A TX-state TXDMA_OFFSET_CHK(0x20C) = 0x{:08x}",
_device.rtw_read32(0x020C));
/* 8-bit read of 0x423 is unreliable on 8814; surface both 8-bit and the
* byte-3 of the 32-bit FWHW_TXQ_CTRL word for comparison. */
_logger->info("8814A TX-state HWSEQ_CTRL(0x423,8bit) = 0x{:02x}",
_device.rtw_read8(0x0423));
_logger->info("8814A TX-state HWSEQ_CTRL(byte3 of 0x420 32bit) = 0x{:02x}",
(_device.rtw_read32(REG_FWHW_TXQ_CTRL) >> 24) & 0xFF);
_logger->info("8814A TX-state TCR(0x604) = 0x{:08x}",
_device.rtw_read32(0x0604));
_logger->info("8814A TX-state RCR(0x608) = 0x{:08x}",
_device.rtw_read32(0x0608));
}
return true;
}
bool HalModule::InitPowerOn() {
if (_macPwrCtrlOn) {
return true;
}
WLAN_PWR_CFG *enable_flow =
(_eepromManager->version_id.ICType == CHIP_8814A)
? rtl8814A_card_enable_flow
: Rtl8812_NIC_ENABLE_FLOW;
if (!HalPwrSeqCmdParsing(enable_flow)) {
_logger->error("InitPowerOn: run power on flow fail");
return false;
}
/* Enable MAC DMA/WMAC/SCHEDULE/SEC block — 8812 only.
*
* On 8814AU, rtw88's usbmon trace shows that REG_CR is left untouched at
* power-on and the chip is held in a minimal state until firmware boots.
* The firmware itself programs REG_CR after it's running. If we set
* HCI_TXDMA/RXDMA/PROTOCOL_EN/SCHEDULE_EN/ENSEC before fwdl, the chip's
* MAC starts processing TX queues normally, so beacon-queue submissions
* (used as the firmware-RSVD-page transport) aren't held for IDDMA and
* BIT15 of REG_FIFOPAGE_CTRL_2 never gets set. */
if (_eepromManager->version_id.ICType != CHIP_8814A) {
/* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy.
* Added by tynli. 2011.08.31. */
_device.rtw_write16(REG_CR,
0x00); /* suggseted by zhouzhou, by page, 20111230 */
uint16_t u2btmp = _device.rtw_read16(REG_CR);
u2btmp |= (ushort)(HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
_device.rtw_write16(REG_CR, u2btmp);
}
_macPwrCtrlOn = true;
return true;
}
/* 8814AU's LLT (linked-list table) for TX FIFO pages is initialized by chip
* hardware: set BIT0 of REG_AUTO_LLT (0x0208), then poll for the bit to
* clear, meaning init is done. Mirrors upstream InitLLTTable8814A in
* hal/rtl8814a/rtl8814a_hal_init.c. */
bool HalModule::InitLLTTable8814A() {
constexpr uint16_t REG_AUTO_LLT_8814A = 0x0208;
uint8_t v = _device.rtw_read8(REG_AUTO_LLT_8814A);
_device.rtw_write8(REG_AUTO_LLT_8814A, (uint8_t)(v | BIT0));
for (int i = 0; i < 100; ++i) {
v = _device.rtw_read8(REG_AUTO_LLT_8814A);
if (!(v & BIT0)) {
_logger->info("InitLLTTable8814A: auto-init OK after {} iters", i);
return true;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
_logger->error("InitLLTTable8814A: timeout waiting for BIT0 to clear");
return false;
}
bool HalModule::InitLLTTable8812A(uint8_t txpktbuf_bndy) {
bool status;
for (uint32_t i = 0; i < (txpktbuf_bndy - 1); i++) {
status = _LLTWrite_8812A(i, i + 1);
if (true != status) {
return false;
}
}
/* end of list */
status = _LLTWrite_8812A((uint32_t)(txpktbuf_bndy - 1), 0xFF);
if (status == false) {
return false;
}
/* Make the other pages as ring buffer */
/* This ring buffer is used as beacon buffer if we config this MAC as two MAC
* transfer. */
/* Otherwise used as local loopback buffer. */
uint32_t Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER_8812;
for (uint32_t i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
status = _LLTWrite_8812A(i, (i + 1));
if (status == false) {
return false;
}
}
/* Let last entry point to the start entry of ring buffer */
status = _LLTWrite_8812A(Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
if (status == false) {
return false;
}
return true;
}
bool HalModule::_LLTWrite_8812A(uint32_t address, uint32_t data) {
bool status = true;
int32_t count = 0;
uint32_t value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
_LLT_OP(_LLT_WRITE_ACCESS);
_device.rtw_write32(REG_LLT_INIT, value);
/* polling */
do {
value = _device.rtw_read32(REG_LLT_INIT);
if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
break;
}
if (count > POLLING_LLT_THRESHOLD) {
status = false;
break;
}
++count;
} while (true);
return status;
}
void HalModule::_InitHardwareDropIncorrectBulkOut_8812A() {
uint32_t value32 = _device.rtw_read32(REG_TXDMA_OFFSET_CHK);
value32 |= DROP_DATA_EN;
_device.rtw_write32(REG_TXDMA_OFFSET_CHK, value32);
}
bool HalModule::HalPwrSeqCmdParsing(WLAN_PWR_CFG *PwrSeqCmd) {
bool bHWICSupport = false;
uint32_t AryIdx = 0;
// UInt16 offset = 0;
uint32_t pollingCount = 0; /* polling autoload done. */
do {
auto PwrCfgCmd = PwrSeqCmd[AryIdx];
/* Filter by interface type — entries marked PCI- or SDIO-only must NOT
* run on USB. Upstream rtl8814au's power-seq has several PCI-only entries
* (e.g. writes to 0x0301, 0x0071, 0x0042) that, when leaked into the USB
* path, leave the chip in a state where it never acknowledges beacon-
* queue bulk OUTs (BIT15 of REG_FIFOPAGE_CTRL_2 stays clear) — which
* blocks the IDDMA copy that loads firmware into the 8051's DMEM/IMEM.
*
* Fab/cut filtering is intentionally relaxed to ALL_MSK for now: most
* pwr-seq entries are flagged ALL_MSK on both axes, and the CUT
* extraction from SYS_CFG isn't trustworthy across the Jaguar family. */
const uint8_t kIntfBit = PWR_INTF_USB_MSK;
if (!(GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & kIntfBit)) {
AryIdx++;
continue;
}
switch (PwrCfgCmd.cmd) {
case PWR_CMD_READ:
break;
case PWR_CMD_WRITE: {
auto offset = PwrCfgCmd.offset;
/* Read the value from system register */
auto currentOffsetValue = _device.rtw_read8(offset);
currentOffsetValue =
(uint8_t)(currentOffsetValue & (uint8_t)(~PwrCfgCmd.msk));
currentOffsetValue =
(uint8_t)(currentOffsetValue | ((PwrCfgCmd.value) & (PwrCfgCmd.msk)));
/* Write the value back to sytem register */
_device.rtw_write8(offset, currentOffsetValue);
} break;
case PWR_CMD_POLLING:
{
auto bPollingBit = false;
auto offset = (PwrCfgCmd.offset);
uint32_t maxPollingCnt = 5000;
bool flag = false;
maxPollingCnt = 5000;
do {
auto value = _device.rtw_read8(offset);
value = (uint8_t)(value & PwrCfgCmd.msk);
if (value == ((PwrCfgCmd.value) & PwrCfgCmd.msk)) {
bPollingBit = true;
} else {
using namespace std::chrono_literals;
std::this_thread::sleep_for(10ms);
}
if (pollingCount++ > maxPollingCnt) {
// TODO: RTW_ERR("HalPwrSeqCmdParsing: Fail to polling
// Offset[%#x]=%02x\n", offset, value);
/* For PCIE + USB package poll power bit timeout issue only modify
* 8821AE and 8723BE */
if (bHWICSupport && offset == 0x06 && flag == false) {
// TODO: RTW_ERR("[WARNING] PCIE polling(0x%X) timeout(%d), Toggle
// 0x04[3] and try again.\n", offset, maxPollingCnt);
_device.rtw_write8(0x04, (uint8_t)(_device.rtw_read8(0x04) | BIT3));
_device.rtw_write8(0x04,
(uint8_t)(_device.rtw_read8(0x04) & ~BIT3));
/* Retry Polling Process one more time */
pollingCount = 0;
flag = true;
} else {
return false;
}
}
} while (!bPollingBit);
}
break;
case PWR_CMD_DELAY: {
if (PwrCfgCmd.value == (uint8_t)PWRSEQ_DELAY_US) {
std::this_thread::sleep_for(
std::chrono::microseconds(PwrCfgCmd.offset));
} else {
std::this_thread::sleep_for(
std::chrono::milliseconds(PwrCfgCmd.offset));
}
} break;
case PWR_CMD_END:
/* When this command is parsed, end the process */
return true;
break;
default:
break;
}
AryIdx++; /* Add Array Index */
} while (true);
return true;
}
void HalModule::PHY_MACConfig8812() {
if (_eepromManager->version_id.ICType == CHIP_8814A) {
odm_read_and_config_mp_8814a_mac_reg();
} else {
odm_read_and_config_mp_8812a_mac_reg();
}
}
void HalModule::odm_read_and_config_mp_8814a_mac_reg() {
auto ctx = _eepromManager->GetPhyContext();
PhyTableLoader::Load(array_mp_8814a_mac_reg, array_mp_8814a_mac_reg_len, ctx,
[this](uint32_t addr, uint32_t value) {
_device.rtw_write8(static_cast<uint16_t>(addr),
static_cast<uint8_t>(value));
});
}
void HalModule::odm_read_and_config_mp_8814a_phy_reg() {
auto ctx = _eepromManager->GetPhyContext();
/* odm_config_bb_phy_8812a is chip-agnostic for the phydm special addresses
* 0xfe/fd/fc/fb/fa/f9 (sleep/delay opcodes shared across Realtek chips) and
* defers to odm_set_bb_reg for normal writes. Reusing it avoids forking the
* helper. */
PhyTableLoader::Load(array_mp_8814a_phy_reg, array_mp_8814a_phy_reg_len, ctx,
[this](uint32_t addr, uint32_t value) {
odm_config_bb_phy_8812a(addr, 0xFFFFFFFFu, value);
});
}
void HalModule::odm_read_and_config_mp_8814a_agc_tab() {
auto ctx = _eepromManager->GetPhyContext();
PhyTableLoader::Load(array_mp_8814a_agc_tab, array_mp_8814a_agc_tab_len, ctx,
[this](uint32_t addr, uint32_t value) {
odm_config_bb_agc_8812a(addr, 0xFFFFFFFFu, value);
});
}
bool HalModule::phy_BB8814_Config_ParaFile() {
odm_read_and_config_mp_8814a_phy_reg();
odm_read_and_config_mp_8814a_agc_tab();
return true;
}
/******************************************************************************
* mac_reg.TXT
******************************************************************************/
static u32 array_mp_8812a_mac_reg[] = {
0x010, 0x0000000C, 0x80000200, 0x00000000, 0x40000000, 0x00000000,
0x011, 0x00000066, 0xA0000000, 0x00000000, 0x011, 0x0000005A,
0xB0000000, 0x00000000, 0x025, 0x0000000F, 0x072, 0x00000000,
0x420, 0x00000080, 0x428, 0x0000000A, 0x429, 0x00000010,
0x430, 0x00000000, 0x431, 0x00000000, 0x432, 0x00000000,
0x433, 0x00000001, 0x434, 0x00000002, 0x435, 0x00000003,
0x436, 0x00000005, 0x437, 0x00000007, 0x438, 0x00000000,
0x439, 0x00000000, 0x43A, 0x00000000, 0x43B, 0x00000001,
0x43C, 0x00000002, 0x43D, 0x00000003, 0x43E, 0x00000005,
0x43F, 0x00000007, 0x440, 0x0000005D, 0x441, 0x00000001,
0x442, 0x00000000, 0x444, 0x00000010, 0x445, 0x00000000,
0x446, 0x00000000, 0x447, 0x00000000, 0x448, 0x00000000,
0x449, 0x000000F0, 0x44A, 0x0000000F, 0x44B, 0x0000003E,
0x44C, 0x00000010, 0x44D, 0x00000000, 0x44E, 0x00000000,
0x44F, 0x00000000, 0x450, 0x00000000, 0x451, 0x000000F0,
0x452, 0x0000000F, 0x453, 0x00000000, 0x45B, 0x00000080,
0x460, 0x00000066, 0x461, 0x00000066, 0x4C8, 0x000000FF,
0x4C9, 0x00000008, 0x4CC, 0x000000FF, 0x4CD, 0x000000FF,
0x4CE, 0x00000001, 0x500, 0x00000026, 0x501, 0x000000A2,
0x502, 0x0000002F, 0x503, 0x00000000, 0x504, 0x00000028,
0x505, 0x000000A3, 0x506, 0x0000005E, 0x507, 0x00000000,
0x508, 0x0000002B, 0x509, 0x000000A4, 0x50A, 0x0000005E,
0x50B, 0x00000000, 0x50C, 0x0000004F, 0x50D, 0x000000A4,
0x50E, 0x00000000, 0x50F, 0x00000000, 0x512, 0x0000001C,
0x514, 0x0000000A, 0x516, 0x0000000A, 0x525, 0x0000004F,
0x550, 0x00000010, 0x551, 0x00000010, 0x559, 0x00000002,
0x55C, 0x00000050, 0x55D, 0x000000FF, 0x604, 0x00000009,
0x605, 0x00000030, 0x607, 0x00000003, 0x608, 0x0000000E,
0x609, 0x0000002A, 0x620, 0x000000FF, 0x621, 0x000000FF,
0x622, 0x000000FF, 0x623, 0x000000FF, 0x624, 0x000000FF,
0x625, 0x000000FF, 0x626, 0x000000FF, 0x627, 0x000000FF,
0x638, 0x00000050, 0x63C, 0x0000000A, 0x63D, 0x0000000A,
0x63E, 0x0000000E, 0x63F, 0x0000000E, 0x640, 0x00000080,
0x642, 0x00000040, 0x643, 0x00000000, 0x652, 0x000000C8,
0x66E, 0x00000005, 0x700, 0x00000021, 0x701, 0x00000043,
0x702, 0x00000065, 0x703, 0x00000087, 0x708, 0x00000021,
0x709, 0x00000043, 0x70A, 0x00000065, 0x70B, 0x00000087,
0x718, 0x00000040,
};
#define COND_ELSE 2
#define COND_ENDIF 3
void HalModule::odm_read_and_config_mp_8812a_mac_reg() {
u32 i = 0;
u8 c_cond;
bool is_matched = true, is_skipped = false;
u32 array_len = sizeof(array_mp_8812a_mac_reg) / sizeof(u32);
u32 *array = array_mp_8812a_mac_reg;
u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0;
// PHYDM_DBG(p_dm, ODM_COMP_INIT,
//("===> odm_read_and_config_mp_8812a_mac_reg\n"));
while ((i + 1) < array_len) {
v1 = array[i];
v2 = array[i + 1];
if (v1 & (BIT(31) | BIT(30))) { /*positive & negative condition*/
if (v1 & BIT(31)) { /* positive condition*/
c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
if (c_cond == COND_ENDIF) { /*end*/
is_matched = true;
is_skipped = false;
// PHYDM_DBG(p_dm, ODM_COMP_INIT, ("ENDIF\n"));
} else if (c_cond == COND_ELSE) { /*else*/
is_matched = is_skipped ? false : true;
// PHYDM_DBG(p_dm, ODM_COMP_INIT, ("ELSE\n"));
} else { /*if , else if*/
pre_v1 = v1;
pre_v2 = v2;
// PHYDM_DBG(p_dm, ODM_COMP_INIT, ("IF or ELSE IF\n"));
}
} else if (v1 & BIT(30)) { /*negative condition*/
if (is_skipped == false) {
if (check_positive(pre_v1, pre_v2, v2)) {
is_matched = true;
is_skipped = true;
} else {
is_matched = false;
is_skipped = false;
}
} else
is_matched = false;
}
} else {
if (is_matched) {
ushort addr = (uint16_t)v1;
uint8_t data = (uint8_t)v2;
odm_write_1byte(addr, data);
}
}
i = i + 2;
}
}
void HalModule::odm_write_1byte(uint16_t reg_addr, uint8_t data) {
_device.rtw_write8(reg_addr, data);
}
#define RTL871X_HCI_TYPE_RTW_USB BIT1
bool HalModule::check_positive(int32_t condition1, int32_t condition2,
int32_t condition4) {
auto originalBoardType = _eepromManager->GetBoardType();
u8 boardType = ((originalBoardType & BIT(4)) >> 4) << 0 | /* _GLNA*/
((originalBoardType & BIT(3)) >> 3) << 1 | /* _GPA*/
((originalBoardType & BIT(7)) >> 7) << 2 | /* _ALNA*/
((originalBoardType & BIT(6)) >> 6) << 3 | /* _APA */
((originalBoardType & BIT(2)) >> 2) << 4 | /* _BT*/
((originalBoardType & BIT(1)) >> 1) << 5 | /* _NGFF*/
((originalBoardType & BIT(5)) >> 5) << 6; /* _TRSWT*/
uint32_t cond1 = condition1;
uint32_t cond2 = condition2;
uint32_t cond4 = condition4;
uint32_t cut_version_for_para = (_eepromManager->cut_version == ODM_CUT_A)
? (uint32_t)15
: (uint32_t)_eepromManager->version_id.CUTVersion;
uint32_t pkg_type_for_para = 15;
uint32_t driver1 = cut_version_for_para << 24 |
((uint32_t)RTL871X_HCI_TYPE_RTW_USB & 0xF0) << 16 |
pkg_type_for_para << 12 |
((uint32_t)RTL871X_HCI_TYPE_RTW_USB & 0x0F) << 8 | boardType;
uint32_t driver2 = ((uint32_t)_eepromManager->TypeGLNA & 0xFF) << 0 |
((uint32_t)_eepromManager->TypeGPA & 0xFF) << 8 |
((uint32_t)_eepromManager->TypeALNA & 0xFF) << 16 |
((uint32_t)_eepromManager->TypeAPA & 0xFF) << 24;
uint32_t driver4 = ((uint32_t)_eepromManager->TypeGLNA & 0xFF00) >> 8 |
((uint32_t)_eepromManager->TypeGPA & 0xFF00) |
((uint32_t)_eepromManager->TypeALNA & 0xFF00) << 8 |
((uint32_t)_eepromManager->TypeAPA & 0xFF00) << 16;
/*============== value Defined Check ===============*/
/*QFN type [15:12] and cut version [27:24] need to do value check*/
if (((cond1 & 0x0000F000) != 0) &&
((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) {
return false;
}
if (((cond1 & 0x0F000000) != 0) &&
((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) {
return false;
}
/*=============== Bit Defined Check ================*/
/* We don't care [31:28] */
cond1 &= 0x00FF0FFF;
driver1 &= 0x00FF0FFF;
if ((cond1 & driver1) == cond1) {
uint32_t bit_mask = 0;
if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/
{
return true;
}
if ((cond1 & BIT0) != 0) /*GLNA*/
{
bit_mask |= 0x000000FF;
}
if ((cond1 & BIT1) != 0) /*GPA*/
{
bit_mask |= 0x0000FF00;
}
if ((cond1 & BIT2) != 0) /*ALNA*/
{
bit_mask |= 0x00FF0000;
}
if ((cond1 & BIT3) != 0) /*APA*/
{
bit_mask |= 0xFF000000;
}
if (((cond2 & bit_mask) == (driver2 & bit_mask)) &&
((cond4 & bit_mask) ==
(driver4 & bit_mask))) /* board_type of each RF path is matched*/
{
return true;
} else {
return false;
}
} else {
return false;
}
}
void HalModule::_InitQueueReservedPage_8812AUsb() {
uint32_t numHQ = 0;
uint32_t numLQ = 0;
uint32_t numNQ = 0;
uint32_t value32;
uint8_t value8;
bool bWiFiConfig = registry_priv::wifi_spec;
if (!bWiFiConfig) {
if (_device.OutEpQueueSel & TxSele::TX_SELE_HQ) {
numHQ = NORMAL_PAGE_NUM_HPQ_8812;
}
if (_device.OutEpQueueSel & TxSele::TX_SELE_LQ) {
numLQ = NORMAL_PAGE_NUM_LPQ_8812;
}
/* NOTE: This step shall be proceed before writting REG_RQPN.
*/
if (_device.OutEpQueueSel & TxSele::TX_SELE_NQ) {
numNQ = NORMAL_PAGE_NUM_NPQ_8812;
}
} else {
/* WMM */
if (_device.OutEpQueueSel & TxSele::TX_SELE_HQ) {
numHQ = WMM_NORMAL_PAGE_NUM_HPQ_8812;
}
if (_device.OutEpQueueSel & TxSele::TX_SELE_LQ) {
numLQ = WMM_NORMAL_PAGE_NUM_LPQ_8812;
}
/* NOTE: This step shall be proceed before writting REG_RQPN.
*/
if (_device.OutEpQueueSel & TxSele::TX_SELE_NQ) {
numNQ = WMM_NORMAL_PAGE_NUM_NPQ_8812;
}
}
uint32_t numPubQ = TX_TOTAL_PAGE_NUMBER_8812 - numHQ - numLQ - numNQ;
value8 = (uint8_t)_NPQ(numNQ);
_device.rtw_write8(REG_RQPN_NPQ, value8);
/* TX DMA */
value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
_device.rtw_write32(REG_RQPN, value32);
}
void HalModule::_InitTxBufferBoundary_8812AUsb() {
uint8_t txPageBoundary8812 = TX_PAGE_BOUNDARY_8812;
_device.rtw_write8(REG_BCNQ_BDNY, txPageBoundary8812);
_device.rtw_write8(REG_MGQ_BDNY, txPageBoundary8812);
_device.rtw_write8(REG_WMAC_LBK_BF_HD, txPageBoundary8812);
_device.rtw_write8(REG_TRXFF_BNDY, txPageBoundary8812);
_device.rtw_write8(REG_TDECTRL + 1, txPageBoundary8812);
}
void HalModule::_InitQueuePriority_8812AUsb() {
/* 8814AU upstream collapses 3-out and 4-out into the same Three-EP priority
* init. 8812 has a distinct Four-EP variant. */
if (_eepromManager->version_id.ICType == CHIP_8814A) {
switch (_device.OutEpNumber) {
case 2:
_InitNormalChipTwoOutEpPriority_8814AUsb();
break;
case 3:
case 4:
_InitNormalChipThreeOutEpPriority_8814AUsb();
break;
default:
_logger->error(
"_InitQueuePriority_8814AUsb(): unexpected OutEpNumber={}",
(int)_device.OutEpNumber);
break;
}
return;
}
switch (_device.OutEpNumber) {
case 2:
_InitNormalChipTwoOutEpPriority_8812AUsb();
break;
case 3:
_InitNormalChipThreeOutEpPriority_8812AUsb();
break;
case 4:
_InitNormalChipFourOutEpPriority_8812AUsb();
break;
default:
_logger->error("_InitQueuePriority_8812AUsb(): Shall not reach here!");
break;
}
}
void HalModule::_InitNormalChipTwoOutEpPriority_8814AUsb() {
/* Mirrors _InitNormalChipTwoOutEpPriority_8812AUsb. Same logic — the only
* 8814 delta is the BIT2 set in _InitNormalChipRegPriority_8814AUsb. */
uint16_t valueHi;
uint16_t valueLow;
switch (_device.OutEpQueueSel) {
case (TxSele::TX_SELE_HQ | TxSele::TX_SELE_LQ):
valueHi = QUEUE_HIGH;
valueLow = QUEUE_LOW;
break;
case (TxSele::TX_SELE_NQ | TxSele::TX_SELE_LQ):
valueHi = QUEUE_NORMAL;
valueLow = QUEUE_LOW;
break;
case (TxSele::TX_SELE_HQ | TxSele::TX_SELE_NQ):
valueHi = QUEUE_HIGH;
valueLow = QUEUE_NORMAL;