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
47 changes: 34 additions & 13 deletions src/jaguar3/HalJaguar3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,24 +601,38 @@ void HalJaguar3::config_pa_bias_8822e() {
pg2a & 0xf, pg2b & 0xf, pg5a & 0xf, pg5b & 0xf);
}

/* Decode the packed (extended-header) EFUSE into a logical map, up to (and
* including the block holding) logical offset `upto`. Shared by read_efuse_rfe_type
* and read_efuse_txpwr_base_8822e. `map` must be zero-init'd by the caller (this
* fills 0xFF for gaps). Standard Realtek section format: header (or header+ext)
* gives a logical block offset + 4-bit word-enable; each enabled 2-byte word
* follows. */
bool HalJaguar3::probe_efuse_map(uint8_t *map, size_t len) {
/* 8822E OTP reads are not reliable after TX/coex bring-up (by design — see
* cache_efuse_8822e); probing there would flag healthy units. 8822C only. */
if (_variant != ChipVariant::C8822C)
return false;
if (map == nullptr || len != sizeof(_efuse_cache))
return false;
read_efuse_logical_map(map, len, 0xFA);
read_efuse_logical_map(map, len);
return true;
}

void HalJaguar3::read_efuse_logical_map(uint8_t *map, size_t len, uint16_t upto) {
/* Decode the packed (extended-header) EFUSE into a logical map. Shared by
* read_efuse_rfe_type and read_efuse_txpwr_base_8822e. `map` must be zero-init'd
* by the caller (this fills 0xFF for gaps). Standard Realtek section format:
* header (or header+ext) gives a logical block offset + 4-bit word-enable; each
* enabled 2-byte word follows.
*
* The walk decodes the whole programmed area. Sections are not in ascending base
* order, so it must not stop at any requested offset — measured on an RTL8822CU,
* the third section on the chip jumps to base 0x100:
*
* phys 0x00 hdr=0x00 -> base 0x000
* phys 0x09 hdr=0x10 -> base 0x008
* phys 0x12 hdr=0x0F ext=48 -> base 0x100
* phys 0x2C hdr=0x4F ext=5D -> base 0x150
*
* A walk bounded by the byte the caller asked for ends after those first three
* sections for anything below 0x100 — including EEPROM_RFE_OPTION at logical
* 0xCA — and returns a map that is 0xFF almost everywhere. On that adapter it
* made read_efuse_rfe_type() return 0 while the kernel driver reads 0x03 from
* the same chip, i.e. BB/RFE config chosen from an unprogrammed default. */
void HalJaguar3::read_efuse_logical_map(uint8_t *map, size_t len) {
constexpr uint16_t kPhysMax = 1024; /* EFUSE_REAL_CONTENT_LEN_8822C */
for (size_t i = 0; i < len; ++i) map[i] = 0xFF;

Expand All @@ -631,6 +645,15 @@ void HalJaguar3::read_efuse_logical_map(uint8_t *map, size_t len, uint16_t upto)
if (eu)
efuse_pwr_cut_8822e(true);
auto rd = [this, eu](uint16_t a) -> uint8_t {
/* A section straddling the end of the physical area would otherwise run
* `phys` past kPhysMax: the loop head checks it once per section, but a
* header + ext + four data words advance it up to ten more bytes. That
* matters because efuse_OneByteRead masks the address to 10 bits, so a
* read at 1024 aliases to 0 and would silently decode the START of the
* EFUSE into whatever logical base the truncated section named. 0xFF is
* what both walks already treat as end-of-map / skip. */
if (a >= kPhysMax)
return 0xFF;
Comment thread
josephnef marked this conversation as resolved.
if (eu)
return efuse_phys_read_8822e(a);
uint8_t d = 0xFF;
Expand Down Expand Up @@ -704,15 +727,13 @@ void HalJaguar3::read_efuse_logical_map(uint8_t *map, size_t len, uint16_t upto)
map[idx] = d;
}
}
if (base > upto + 8)
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
break; /* past the byte we need */
}
}

void HalJaguar3::cache_efuse_8822e() {
if (_variant != ChipVariant::C8822E)
return;
read_efuse_logical_map(_efuse_cache, sizeof(_efuse_cache), 0xFA);
read_efuse_logical_map(_efuse_cache, sizeof(_efuse_cache));
_efuse_cache_valid = true;
_logger->info("Jaguar3(8822e): efuse decoded (0x22={:x} 0x4c={:x} 0xca={:x})",
_efuse_cache[0x22], _efuse_cache[0x4c], _efuse_cache[0xca]);
Expand All @@ -725,7 +746,7 @@ uint8_t HalJaguar3::read_efuse_rfe_type() {
rfe = _efuse_cache[kRfeLogicalOff];
} else {
uint8_t map[0x100 + 0x40]; /* enough to cover block holding 0xCA */
read_efuse_logical_map(map, sizeof(map), kRfeLogicalOff);
read_efuse_logical_map(map, sizeof(map));
rfe = map[kRfeLogicalOff];
}
return (rfe == 0xFF) ? 0 : rfe;
Expand Down Expand Up @@ -762,7 +783,7 @@ void HalJaguar3::read_efuse_txpwr_base_8822e(uint8_t channel, uint8_t &base_a,
if (_efuse_cache_valid) {
map = _efuse_cache; /* decoded early where OTP access is reliable */
} else {
read_efuse_logical_map(local, sizeof(local), k5gB + 14);
read_efuse_logical_map(local, sizeof(local));
map = local;
}
int g = chnl_group_5g(channel);
Expand Down
9 changes: 6 additions & 3 deletions src/jaguar3/HalJaguar3.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,12 @@ class HalJaguar3 {

private:

/* Decode the packed extended-header EFUSE into a logical map up to (the block
* holding) offset `upto`. Backs read_efuse_rfe_type + read_efuse_txpwr_base. */
void read_efuse_logical_map(uint8_t *map, size_t len, uint16_t upto);
/* Decode the packed extended-header EFUSE into a logical map. Backs
* read_efuse_rfe_type + read_efuse_txpwr_base. Walks the whole programmed
* area — sections are NOT ordered by logical base, so stopping once a
* requested offset is passed would drop later sections that backfill lower
* offsets (see the .cpp for the measured case). */
void read_efuse_logical_map(uint8_t *map, size_t len);

/* One-shot decode of the logical EFUSE into _efuse_cache during rtw_hal_init,
* where OTP access is reliable. RFE + per-channel TX-power base are then served
Expand Down
Loading