Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ add_library(WiFiDriver
hal/Hal8812PhyReg.h
hal/Hal8812PwrSeq.c
hal/Hal8812PwrSeq.h
hal/Hal8812a_TxPwrTrack.cpp
hal/Hal8812a_TxPwrTrack.h
hal/Hal8814_PostFwdlReplay.h
hal/Hal8814PwrSeq.c
hal/Hal8814PwrSeq.h
Expand Down Expand Up @@ -55,6 +57,8 @@ add_library(WiFiDriver
src/ParsedRadioPacket.cpp
src/PhyTableLoader.cpp
src/PhyTableLoader.h
src/PowerTracking8812a.cpp
src/PowerTracking8812a.h
src/RadioManagementModule.cpp
src/RadioManagementModule.h
src/Radiotap.c
Expand Down
105 changes: 105 additions & 0 deletions hal/Hal8812a_TxPwrTrack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/* Verbatim copy of `g_delta_swing_table_idx_mp_*_txpowertrack_usb_8812a` +
* `tx_scaling_table_jaguar` from `aircrack-ng/rtl8812au` —
* `hal/phydm/rtl8812a/halhwimg8812a_rf.c:1310..1339` and
* `hal/phydm/halrf/halrf_powertracking_ce.c:538`. Do not hand-edit; if
* upstream changes these tables, regenerate from the canonical source.
*/
#include "Hal8812a_TxPwrTrack.h"

const uint8_t kDeltaSwingTable2gaP[kDeltaSwingIdxSize] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
const uint8_t kDeltaSwingTable2gaN[kDeltaSwingIdxSize] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7,
7, 8, 8, 9, 10, 10, 10, 10, 10, 10};
const uint8_t kDeltaSwingTable2gbP[kDeltaSwingIdxSize] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
const uint8_t kDeltaSwingTable2gbN[kDeltaSwingIdxSize] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 11, 11, 11, 11};
const uint8_t kDeltaSwingTable2gCckAP[kDeltaSwingIdxSize] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
const uint8_t kDeltaSwingTable2gCckAN[kDeltaSwingIdxSize] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7,
7, 8, 8, 9, 10, 10, 10, 10, 10, 10};
const uint8_t kDeltaSwingTable2gCckBP[kDeltaSwingIdxSize] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
const uint8_t kDeltaSwingTable2gCckBN[kDeltaSwingIdxSize] = {
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 11, 11, 11, 11};

const uint8_t kDeltaSwingTable5gaP[kFiveGBandNum][kDeltaSwingIdxSize] = {
{0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
{0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
{0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
};
const uint8_t kDeltaSwingTable5gaN[kFiveGBandNum][kDeltaSwingIdxSize] = {
{0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13, 14, 15, 15, 15, 15, 15},
{0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13, 14, 15, 15, 15, 15, 15},
{0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13, 14, 15, 15, 15, 15, 15},
};
const uint8_t kDeltaSwingTable5gbP[kFiveGBandNum][kDeltaSwingIdxSize] = {
{0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
{0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
{0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
};
const uint8_t kDeltaSwingTable5gbN[kFiveGBandNum][kDeltaSwingIdxSize] = {
{0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13, 14, 14, 14, 14, 14, 14},
{0, 1, 1, 2, 2, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13, 14, 14, 14, 14, 14, 14},
{0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 11, 12, 12,
13, 13, 14, 14, 15, 16, 16, 16, 16, 16},
};

const uint32_t kTxScalingTableJaguar[kTxScaleTableSize] = {
0x081, /* 0, -12.0 dB */
0x088, /* 1, -11.5 dB */
0x090, /* 2, -11.0 dB */
0x099, /* 3, -10.5 dB */
0x0A2, /* 4, -10.0 dB */
0x0AC, /* 5, -9.5 dB */
0x0B6, /* 6, -9.0 dB */
0x0C0, /* 7, -8.5 dB */
0x0CC, /* 8, -8.0 dB */
0x0D8, /* 9, -7.5 dB */
0x0E5, /* 10, -7.0 dB */
0x0F2, /* 11, -6.5 dB */
0x101, /* 12, -6.0 dB */
0x110, /* 13, -5.5 dB */
0x120, /* 14, -5.0 dB */
0x131, /* 15, -4.5 dB */
0x143, /* 16, -4.0 dB */
0x156, /* 17, -3.5 dB */
0x16A, /* 18, -3.0 dB */
0x180, /* 19, -2.5 dB */
0x197, /* 20, -2.0 dB */
0x1AF, /* 21, -1.5 dB */
0x1C8, /* 22, -1.0 dB */
0x1E3, /* 23, -0.5 dB */
0x200, /* 24, +0.0 dB */
0x21E, /* 25, +0.5 dB */
0x23E, /* 26, +1.0 dB */
0x261, /* 27, +1.5 dB */
0x285, /* 28, +2.0 dB */
0x2AB, /* 29, +2.5 dB */
0x2D3, /* 30, +3.0 dB */
0x2FE, /* 31, +3.5 dB */
0x32B, /* 32, +4.0 dB */
0x35C, /* 33, +4.5 dB */
0x38E, /* 34, +5.0 dB */
0x3C4, /* 35, +5.5 dB */
0x3FE, /* 36, +6.0 dB */
};
52 changes: 52 additions & 0 deletions hal/Hal8812a_TxPwrTrack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef HAL_8812A_TX_PWR_TRACK_H
#define HAL_8812A_TX_PWR_TRACK_H

#include <cstdint>

/* Verbatim copy of `g_delta_swing_table_idx_mp_*_txpowertrack_usb_8812a` from
* `aircrack-ng/rtl8812au/hal/phydm/rtl8812a/halhwimg8812a_rf.c:1310..1339`.
*
* These are phydm's per-band, per-RF-path, per-temperature-direction
* lookup tables for the TX BB-swing thermal compensation loop. Indexed
* by `|thermal_value - eeprom_thermal|` (clamped to 29). The value
* returned is `absolute_ofdm_swing_idx[p]` — added to
* `default_ofdm_index` (= 24 for 8812A, i.e. table-index 0x200/0dB)
* to produce the final `tx_scaling_table_jaguar[]` index that
* `odm_tx_pwr_track_set_pwr8812a` writes to BB 0xc1c[31:21]
* (path A) or 0xe1c[31:21] (path B).
*
* Dimensions: `5g*_p/n` are [3][30] — three sub-band buckets (ch36..64,
* ch100..144, ch149..177) × 30 temperature deltas. The 2G arrays
* collapse to [30] (single band).
*
* "_p" suffix = thermal_value > eeprom_thermal (chip warmer than PG),
* "_n" suffix = chip cooler (negate the delta before applying).
*
* Source tag: aircrack-ng/rtl8812au@5.6.4.2_35491.20191025
*/

constexpr int kDeltaSwingIdxSize = 30;
constexpr int kFiveGBandNum = 3;

extern const uint8_t kDeltaSwingTable2gaP[kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable2gaN[kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable2gbP[kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable2gbN[kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable2gCckAP[kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable2gCckAN[kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable2gCckBP[kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable2gCckBN[kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable5gaP[kFiveGBandNum][kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable5gaN[kFiveGBandNum][kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable5gbP[kFiveGBandNum][kDeltaSwingIdxSize];
extern const uint8_t kDeltaSwingTable5gbN[kFiveGBandNum][kDeltaSwingIdxSize];

/* phydm's TX BB-swing table for the Jaguar family, indexed by ofdm-swing
* index. Verbatim from `tx_scaling_table_jaguar` in
* `halrf_powertracking_ce.c:538`. Index 24 = 0x200 (0 dB), index 26 =
* 0x23E (+1.0 dB), table size 37 entries spanning -12 dB to +6 dB in
* 0.5 dB steps. */
constexpr int kTxScaleTableSize = 37;
extern const uint32_t kTxScalingTableJaguar[kTxScaleTableSize];

#endif /* HAL_8812A_TX_PWR_TRACK_H */
6 changes: 6 additions & 0 deletions src/EepromManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ class EepromManager {
EepromManager(RtlUsbAdapter device, Logger_t logger);
uint8_t GetBoardType();
void efuse_ShadowRead1Byte(uint16_t Offset, uint8_t *Value);
/* phydm thermal-meter pwrtrk baseline from EFUSE (set by
* `Hal_ReadThermalMeter_8812A`). Returns 0xFF when EFUSE autoload
* failed — in that case pwrtrk should be disabled because there's
* no factory-calibrated reference temperature to compute delta
* against. */
uint8_t GetEepromThermalMeter() const { return eeprom_thermal_meter; }

/* 8814AU only: read EFUSE and populate rfe_type, PA/LNA types, crystal cap,
* etc. Must be called AFTER firmware download (pre-fwdl EFUSE access
Expand Down
20 changes: 20 additions & 0 deletions src/HalModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,14 @@ bool HalModule::rtl8812au_hal_init() {

PHY_RF6052_Config_8812();

phydm_SetIgiFloor_Jaguar();

/* Initialise phydm thermal-meter pwrtrk state now that BB+RF tables
* have been applied. Mirrors phydm's `phydm_rf_init` ->
* `odm_txpowertracking_init`. The watchdog ticks themselves run from
* the channel-set path + RtlJaguarDevice background thread. */
_radioManagementModule->InitPwrTrack();

if (_eepromManager->version_id.RFType == RF_TYPE_1T1R) {
PHY_BB8812_Config_1T();
}
Expand Down Expand Up @@ -2955,6 +2963,18 @@ void HalModule::odm_config_rf_radio_b_8812a(uint32_t addr, uint32_t data) {
(uint16_t)(addr | maskfor_phy_set));
}

void HalModule::phydm_SetIgiFloor_Jaguar() {
/* Port of phydm DIG floor convergence for the Jaguar family. Upstream
* phydm_dig.c sets `dig_t->dm_dig_min = 0x1c` for
* `(ODM_RTL8812 | ODM_RTL8814A | ODM_RTL8821 | ODM_RTL8822B)` and the
* DIG watchdog walks 0xc50/0xe50 down to this floor under clean RX
* conditions. Without phydm's watchdog devourer's IGI never moves
* from the 0x20 BB-table seed and runs ~4 dB less sensitive than the
* kernel driver. Match kernel by writing the floor once here. */
_device.phy_set_bb_reg(rA_IGI_Jaguar, bMaskByte0, 0x1c);
_device.phy_set_bb_reg(rB_IGI_Jaguar, bMaskByte0, 0x1c);
}

void HalModule::PHY_BB8812_Config_1T() {
/* BB OFDM RX Path_A */
_device.phy_set_bb_reg(rRxPath_Jaguar, bRxPath_Jaguar, 0x11);
Expand Down
12 changes: 12 additions & 0 deletions src/HalModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ class HalModule {
void odm_config_rf_radio_b_8812a(uint32_t addr, uint32_t data);
void PHY_BB8812_Config_1T();

/* Pre-converge the path-A/B Initial Gain Index to phydm's documented
* DIG floor (0x1c) for all Jaguar chips. Upstream phydm runs DIG
* (Dynamic Initial Gain) from its watchdog and converges 0xc50/0xe50
* to 0x1c when no false-alarm pressure is present (phydm_dig.c:
* `dig_t->dm_dig_min = 0x1c` for ODM_RTL8812 | RTL8814A | RTL8821).
* Devourer has no phydm watchdog, so devourer's static 0x20 (from the
* BB-init table) never moves and the chip runs slightly less sensitive
* than the kernel driver. Writing 0x1c once at init matches kernel
* post-DIG-converged state — last remaining T1 canary divergence on
* 0xc50/0xe50 that wasn't a real init bug. Safe for monitor RX:
* higher sensitivity, lower CCA threshold, no TX-side impact. */
void phydm_SetIgiFloor_Jaguar();
};

#endif /* HALMODULE_H */
Loading
Loading