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
94 changes: 87 additions & 7 deletions src/jaguar1/EepromManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,12 +392,15 @@ static uint8_t classify_channel(uint8_t ch, uint8_t *group, uint8_t *cck_group)
if (cck_group) *cck_group = static_cast<uint8_t>(cck_gp);
return 0; /* 2.4G */
}
/* 5G group boundaries — verbatim from upstream `rtw_get_ch_group`
* (core/rtw_rf.c). NB the gp3/gp4 split is at 98/100 (not 80/82) and the
* top group runs to 253: channels 82..98 belong to gp3, not gp4. */
int gp = -1;
if (15 <= ch && ch <= 42) gp = 0;
if (16 <= ch && ch <= 42) gp = 0;
else if (44 <= ch && ch <= 48) gp = 1;
else if (50 <= ch && ch <= 58) gp = 2;
else if (60 <= ch && ch <= 80) gp = 3;
else if (82 <= ch && ch <= 106) gp = 4;
else if (60 <= ch && ch <= 98) gp = 3;
else if (100 <= ch && ch <= 106) gp = 4;
else if (108 <= ch && ch <= 114) gp = 5;
else if (116 <= ch && ch <= 122) gp = 6;
else if (124 <= ch && ch <= 130) gp = 7;
Expand All @@ -406,7 +409,7 @@ static uint8_t classify_channel(uint8_t ch, uint8_t *group, uint8_t *cck_group)
else if (149 <= ch && ch <= 155) gp = 10;
else if (157 <= ch && ch <= 161) gp = 11;
else if (165 <= ch && ch <= 171) gp = 12;
else if (173 <= ch && ch <= 177) gp = 13;
else if (173 <= ch && ch <= 253) gp = 13;
if (gp < 0) return 0xFF;
if (group) *group = static_cast<uint8_t>(gp);
return 1; /* 5G */
Expand All @@ -423,6 +426,54 @@ static const uint8_t kCenterCh5gAll[65] = {
165, 167, 169, 171, 173, 175, 177,
};

/* Vendor default PG TX-power maps — verbatim from upstream `hal_com_phycfg.c`
* (`pg_txpwr_def_info` + per-chip `rtl88{12,21}a_pg_txpwr_def_info`). Each map
* is the per-path byte stream that starts at PG offset `pg_txpwr_saddr` (0x10),
* laid out identically to the EFUSE PG block (2.4G 18 B + 5G 24 B per path).
* The kernel's `hal_load_pg_txpwr_info` uses these as fallback sources
* (PG_DATA -> IC_DEF -> DEF): a base cell whose EFUSE byte is invalid
* (> txgi_max = 63, e.g. an unprogrammed 0xFF) is filled from the IC map, then
* the generic map. 0xEE/0xFF bytes at base positions are themselves invalid and
* fall through to the next source. */
static const uint8_t kPgTxpwrDefGeneric[168] = {
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE,
0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24,
0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x04, 0xEE,
0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE};

static const uint8_t kPgTxpwrDef8814a[168] = {
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE,
0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02,
0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE,
0xEE, 0xEE, 0xEE, 0xEE, 0x00, 0xEE, 0xEE, 0xEE};

static const uint8_t kPgTxpwrDef8812a[82] = {
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF,
0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF, 0x00, 0xEE, 0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02, 0xEE, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x02, 0xEE, 0xFF, 0xFF, 0xEE, 0xFF,
0x00, 0xEE};

static const uint8_t kPgTxpwrDef8821a[39] = {
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x24, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};

void EepromManager::LoadTxPowerInfo() {
/* EFUSE PG TX-power block layout — port of
* `hal_load_pg_txpwr_info_path_{2,5}g` from upstream
Expand Down Expand Up @@ -463,12 +514,41 @@ void EepromManager::LoadTxPowerInfo() {
uint8_t bw40_base_2g[kMaxRfPath][6] = {};
uint8_t bw40_base_5g[kMaxRfPath][14] = {};

/* Fallback sources for invalid (unprogrammed) base cells — port of the
* kernel's PG_DATA -> IC_DEF -> DEF chain in `hal_load_pg_txpwr_info`. Pick
* the IC default map by chip; the generic map is the final fallback. */
const uint8_t *ic_def = nullptr;
size_t ic_def_len = 0;
switch (version_id.ICType) {
case CHIP_8814A: ic_def = kPgTxpwrDef8814a; ic_def_len = sizeof(kPgTxpwrDef8814a); break;
case CHIP_8812: ic_def = kPgTxpwrDef8812a; ic_def_len = sizeof(kPgTxpwrDef8812a); break;
case CHIP_8821: ic_def = kPgTxpwrDef8821a; ic_def_len = sizeof(kPgTxpwrDef8821a); break;
default: break;
}
/* Read a base byte with the vendor fallback chain. A base is invalid when it
* exceeds txgi_max (63) — the same test the kernel uses
* (IS_PG_TXPWR_BASE_INVALID). First valid of {EFUSE, IC-def, generic-def}
* wins; if all are invalid the (invalid) EFUSE byte is returned and gets
* clamped downstream, matching the kernel leaving the cell invalid. */
auto def_at = [](const uint8_t *map, size_t len, uint16_t o) -> uint8_t {
return (o >= kPgSaddr && (size_t)(o - kPgSaddr) < len) ? map[o - kPgSaddr]
: 0xFF;
};
auto read_base = [&](uint16_t o) -> uint8_t {
uint8_t v = efuse_eeprom_data[o];
if (v <= 63) return v;
if (ic_def) { uint8_t d = def_at(ic_def, ic_def_len, o); if (d <= 63) return d; }
uint8_t d = def_at(kPgTxpwrDefGeneric, sizeof(kPgTxpwrDefGeneric), o);
if (d <= 63) return d;
return v;
};

for (int path = 0; path < numTotalRfPath && path < kMaxRfPath; path++) {
/* 2.4G section — 18 bytes per path. */
for (int g = 0; g < 6; g++)
cck_base_2g[path][g] = efuse_eeprom_data[off++];
cck_base_2g[path][g] = read_base(off++);
for (int g = 0; g < 5; g++)
bw40_base_2g[path][g] = efuse_eeprom_data[off++];
bw40_base_2g[path][g] = read_base(off++);
/* Ntx=1: 1 byte (MSB=BW20, LSB=OFDM) */
{
uint8_t v = efuse_eeprom_data[off++];
Expand All @@ -487,7 +567,7 @@ void EepromManager::LoadTxPowerInfo() {

/* 5G section — 24 bytes per path. */
for (int g = 0; g < 14; g++)
bw40_base_5g[path][g] = efuse_eeprom_data[off++];
bw40_base_5g[path][g] = read_base(off++);
/* Ntx=1: 1 byte (MSB=BW20, LSB=OFDM) */
{
uint8_t v = efuse_eeprom_data[off++];
Expand Down
8 changes: 4 additions & 4 deletions src/jaguar1/RadioManagementModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1351,9 +1351,9 @@ uint32_t RadioManagementModule::phy_get_tx_bb_swing_8812a(BandType Band,
} else if (bbSwing_2G == 0)
swing = 0x00; /* 0 dB */
else if (bbSwing_2G == -3)
swing = 0x05; /* -3 dB */
swing = 0x55; /* -3 dB (all 4 paths; matches PHY_GetTxBBSwing_8814A) */
else if (bbSwing_2G == -6)
swing = 0x0A; /* -6 dB */
swing = 0xAA; /* -6 dB (all 4 paths) */
else if (bbSwing_2G == -9)
swing = 0xFF; /* -9 dB */
else
Expand All @@ -1366,9 +1366,9 @@ uint32_t RadioManagementModule::phy_get_tx_bb_swing_8812a(BandType Band,
} else if (bbSwing_5G == 0)
swing = 0x00; /* 0 dB */
else if (bbSwing_5G == -3)
swing = 0x05; /* -3 dB */
swing = 0x55; /* -3 dB (all 4 paths; matches PHY_GetTxBBSwing_8814A) */
else if (bbSwing_5G == -6)
swing = 0x0A; /* -6 dB */
swing = 0xAA; /* -6 dB (all 4 paths) */
else if (bbSwing_5G == -9)
swing = 0xFF; /* -9 dB */
else
Expand Down
Loading