From b81577c42cf3e2d9e5c96fad81bffdf1e5892547 Mon Sep 17 00:00:00 2001 From: Roman Buldygin Date: Fri, 24 May 2024 03:23:11 +0300 Subject: [PATCH] Efuse read implementation --- .../ViewModels/EfuseMapViewModel.cs | 17 +++ src/EfuseManager/ViewModels/MainViewModel.cs | 13 +- .../Rtl8812au/Enumerations/EfuseType.cs | 7 + .../Rtl8812au/Modules/EepromManager.cs | 135 ++++++++---------- src/Rtl8812auNet/Rtl8812au/Rtl8812aDevice.cs | 18 ++- src/Rtl8812auNet/Rtl8812auNet.csproj | 3 + src/Rtl8812auNet/RtlUsbAdapter.cs | 14 +- 7 files changed, 119 insertions(+), 88 deletions(-) create mode 100644 src/EfuseManager/ViewModels/EfuseMapViewModel.cs create mode 100644 src/Rtl8812auNet/Rtl8812au/Enumerations/EfuseType.cs diff --git a/src/EfuseManager/ViewModels/EfuseMapViewModel.cs b/src/EfuseManager/ViewModels/EfuseMapViewModel.cs new file mode 100644 index 0000000..c081b59 --- /dev/null +++ b/src/EfuseManager/ViewModels/EfuseMapViewModel.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EfuseManager.ViewModels; + +public class EfuseMapViewModel +{ + private byte[] _originalData = new byte[512]; + + public void LoadData(byte[] efuseMap) + { + _originalData = efuseMap; + } +} \ No newline at end of file diff --git a/src/EfuseManager/ViewModels/MainViewModel.cs b/src/EfuseManager/ViewModels/MainViewModel.cs index 34c0b7e..d0d2364 100644 --- a/src/EfuseManager/ViewModels/MainViewModel.cs +++ b/src/EfuseManager/ViewModels/MainViewModel.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Rtl8812auNet; +using Rtl8812auNet.Rtl8812au.Enumerations; namespace EfuseManager.ViewModels; @@ -44,6 +45,8 @@ public DeviceViewModel? SelectedDevice set => SetProperty(ref _selectedDevice, value); } + public EfuseMapViewModel EfuseMap { get; } = new(); + private void ExecuteWrite() { throw new NotImplementedException(); @@ -58,7 +61,15 @@ private void ExecuteRead() var device = SelectedDevice.RealDevice; var rtlDevice = _driver.CreateRtlDevice(device); - //rtlDevice.Init(); + rtlDevice.NetDevOpen(new() + { + ChannelWidth = ChannelWidth.CHANNEL_WIDTH_20, + ChannelOffset = 0, + Channel = 149, + //Channel = 36 + }); + var efuseMap = rtlDevice.ReadEfuse(); + EfuseMap.LoadData(efuseMap); } private void ExecuteRefresh() diff --git a/src/Rtl8812auNet/Rtl8812au/Enumerations/EfuseType.cs b/src/Rtl8812auNet/Rtl8812au/Enumerations/EfuseType.cs new file mode 100644 index 0000000..29758ca --- /dev/null +++ b/src/Rtl8812auNet/Rtl8812au/Enumerations/EfuseType.cs @@ -0,0 +1,7 @@ +namespace Rtl8812auNet.Rtl8812au.Enumerations +{ + public enum EfuseType : byte + { + EfuseWiFi = 0 + } +} \ No newline at end of file diff --git a/src/Rtl8812auNet/Rtl8812au/Modules/EepromManager.cs b/src/Rtl8812auNet/Rtl8812au/Modules/EepromManager.cs index 2d6e4fd..434e064 100644 --- a/src/Rtl8812auNet/Rtl8812au/Modules/EepromManager.cs +++ b/src/Rtl8812auNet/Rtl8812au/Modules/EepromManager.cs @@ -9,8 +9,6 @@ namespace Rtl8812auNet.Rtl8812au.Modules; public class EepromManager { private const ushort EFUSE_MAP_LEN_JAGUAR = 512; - private const byte EFUSE_WIFI = 0; - private const UInt32 EFUSE_MAX_SECTION_JAGUAR = 64; private const UInt32 EFUSE_MAX_WORD_UNIT = 4; private const UInt32 EFUSE_REAL_CONTENT_LEN_JAGUAR = 512; private const UInt16 RTL_EEPROM_ID = 0x8129; @@ -556,7 +554,7 @@ private void hal_InitPGData_8812A() } /* Read EFUSE real map to shadow. */ - EFUSE_ShadowMapUpdate(EFUSE_WIFI); + EFUSE_ShadowMapUpdate(EfuseType.EfuseWiFi); } } else @@ -582,7 +580,7 @@ private void hal_InitPGData_8812A() /* update to default value 0xFF */ if (!_device.EepromOrEfuse) { - EFUSE_ShadowMapUpdate(EFUSE_WIFI); + EFUSE_ShadowMapUpdate(EfuseType.EfuseWiFi); } } @@ -662,7 +660,7 @@ private byte Hal_ReadPROMVersion8812A(RtlUsbAdapter device, byte[] efuse_eeprom_ return EEPROMVersion; } - private void EFUSE_ShadowMapUpdate(byte efuseType) + private void EFUSE_ShadowMapUpdate(EfuseType efuseType) { if (_device.AutoloadFailFlag) { @@ -673,17 +671,20 @@ private void EFUSE_ShadowMapUpdate(byte efuseType) } else { - Efuse_ReadAllMap(efuseType, efuse_eeprom_data); + var efuseTable = Efuse_ReadAllMap(efuseType); + efuseTable.CopyTo(efuse_eeprom_data.AsSpan()); } rtw_dump_cur_efuse(); } - private void Efuse_ReadAllMap(byte efuseType, byte[] Efuse) + private byte[] Efuse_ReadAllMap(EfuseType efuseType) { EfusePowerSwitch8812A(false, true); - efuse_ReadEFuse(efuseType, 0, EFUSE_MAP_LEN_JAGUAR, Efuse); + var efuseDump = efuse_ReadEFuse(efuseType); EfusePowerSwitch8812A(false, false); + + return efuseDump; } private void rtw_dump_cur_efuse() @@ -766,52 +767,35 @@ private void EfusePowerSwitch8812A(bool bWrite, bool pwrState) } } - private void efuse_ReadEFuse(byte efuseType, UInt16 _offset, UInt16 _size_byte, - byte[] pbuf) + private byte[] efuse_ReadEFuse(EfuseType efuseType) { - if (efuseType == EFUSE_WIFI) + if (efuseType == EfuseType.EfuseWiFi) { - Hal_EfuseReadEFuse8812A(_offset, _size_byte, pbuf); + return Hal_EfuseReadEFuse8812A(); } else { throw new NotImplementedException(); - // hal_ReadEFuse_BT(adapterState, _offset, _size_byte, pbuf, bPseudoTest); + // hal_ReadEFuse_BT(adapterState, offset, size, pbuf, bPseudoTest); } } - private void Hal_EfuseReadEFuse8812A(UInt16 _offset, UInt16 _size_byte, byte[] pbuf) + internal byte[] Hal_EfuseReadEFuse8812A() { - byte[] efuseTbl = null; - byte[] rtemp8 = new byte[1]; - UInt16 eFuse_Addr = 0; - byte offset, wren; - UInt16 i, j; - UInt16[][] eFuseWord = null; - byte u1temp = 0; - - /* */ - /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */ - /* */ - if ((_offset + _size_byte) > EFUSE_MAP_LEN_JAGUAR) - { - /* total E-Fuse table is 512bytes */ - // TODO: RTW_INFO("Hal_EfuseReadEFuse8812A(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte); - return; - } - - efuseTbl = new byte[EFUSE_MAP_LEN_JAGUAR]; - - eFuseWord = new ushort[EFUSE_MAX_SECTION_JAGUAR][]; + const UInt32 efuseMaxSectionJaguar = 64; + + var efuseTable = new byte[EFUSE_MAP_LEN_JAGUAR]; + var eFuseWord = new ushort[efuseMaxSectionJaguar][]; + for (int k = 0; k < eFuseWord.Length; k++) { eFuseWord[k] = new ushort[EFUSE_MAX_WORD_UNIT]; } /* 0. Refresh efuse init map as all oxFF. */ - for (i = 0; i < EFUSE_MAX_SECTION_JAGUAR; i++) + for (int i = 0; i < efuseMaxSectionJaguar; i++) { - for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) + for (int j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { eFuseWord[i][j] = 0xFFFF; } @@ -821,8 +805,9 @@ private void Hal_EfuseReadEFuse8812A(UInt16 _offset, UInt16 _size_byte, byte[] p /* 1. Read the first byte to check if efuse is empty!!! */ /* */ /* */ - _device.ReadEFuseByte(eFuse_Addr, rtemp8); - if (rtemp8[0] != 0xFF) + UInt16 eFuse_Addr = 0; + var rtemp8 = _device.ReadEFuseByte(eFuse_Addr); + if (rtemp8 != 0xFF) { /* RTW_INFO("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8); */ eFuse_Addr++; @@ -830,79 +815,88 @@ private void Hal_EfuseReadEFuse8812A(UInt16 _offset, UInt16 _size_byte, byte[] p else { _logger.LogInformation($"EFUSE is empty efuse_Addr-{eFuse_Addr} efuse_data={rtemp8}"); - return; + return new byte[EFUSE_MAP_LEN_JAGUAR]; } /* */ /* 2. Read real efuse content. Filter PG header and every section data. */ /* */ - while ((rtemp8[0] != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_JAGUAR)) + var pgHeader = rtemp8; + while ((pgHeader != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_JAGUAR)) { /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr-1, *rtemp8)); */ /* Check PG header for section num. */ - if ((rtemp8[0] & 0x1F) == 0x0F) + byte offset; + byte wren; + if ((pgHeader & 0x1F) == 0x0F) { /* extended header */ - u1temp = (byte)((rtemp8[0] & 0xE0) >> 5); + byte u1temp = (byte)((pgHeader & 0xE0) >> 5); /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x *rtemp&0xE0 0x%x\n", u1temp, *rtemp8 & 0xE0)); */ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header u1temp=%x\n", u1temp)); */ - _device.ReadEFuseByte(eFuse_Addr, rtemp8); + rtemp8 = _device.ReadEFuseByte(eFuse_Addr); /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("extended header efuse_Addr-%d efuse_data=%x\n", eFuse_Addr, *rtemp8)); */ - if ((rtemp8[0] & 0x0F) == 0x0F) + if ((rtemp8 & 0x0F) == 0x0F) { eFuse_Addr++; - _device.ReadEFuseByte(eFuse_Addr, rtemp8); + rtemp8 = _device.ReadEFuseByte(eFuse_Addr); - if (rtemp8[0] != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_JAGUAR)) + if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_JAGUAR)) + { eFuse_Addr++; + } continue; } else { - offset = (byte)(((rtemp8[0] & 0xF0) >> 1) | u1temp); - wren = (byte)(rtemp8[0] & 0x0F); + offset = (byte)(((rtemp8 & 0xF0) >> 1) | u1temp); + wren = (byte)(rtemp8 & 0x0F); eFuse_Addr++; } } else { - offset = (byte)((rtemp8[0] >> 4) & 0x0f); - wren = (byte)(rtemp8[0] & 0x0f); + offset = (byte)((pgHeader >> 4) & 0x0f); + wren = (byte)(pgHeader & 0x0f); } - if (offset < EFUSE_MAX_SECTION_JAGUAR) + if (offset < efuseMaxSectionJaguar) { /* Get word enable value from PG header */ /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Offset-%d Worden=%x\n", offset, wren)); */ - for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) + for (int i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { /* Check word enable condition in the section */ if (!((wren & 0x01) == 0x01)) { /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d\n", eFuse_Addr)); */ - _device.ReadEFuseByte(eFuse_Addr, rtemp8); + rtemp8 = _device.ReadEFuseByte(eFuse_Addr); eFuse_Addr++; - eFuseWord[offset][i] = (ushort)(rtemp8[0] & 0xff); + eFuseWord[offset][i] = (ushort)(rtemp8 & 0xff); if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_JAGUAR) + { break; + } /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d", eFuse_Addr)); */ - _device.ReadEFuseByte(eFuse_Addr, rtemp8); + rtemp8 = _device.ReadEFuseByte(eFuse_Addr); eFuse_Addr++; - eFuseWord[offset][i] |= (ushort)(((rtemp8[0]) << 8) & 0xff00); + eFuseWord[offset][i] |= (ushort)(((rtemp8) << 8) & 0xff00); if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_JAGUAR) + { break; + } } wren >>= 1; @@ -913,10 +907,10 @@ private void Hal_EfuseReadEFuse8812A(UInt16 _offset, UInt16 _size_byte, byte[] p { /* deal with error offset,skip error data */ _logger.LogError($"invalid offset:0x{offset:X}"); - for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) + for (int i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { /* Check word enable condition in the section */ - if (!((wren & 0x01) == 0x01)) + if ((wren & 0x01) != 0x01) { eFuse_Addr++; if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_JAGUAR) @@ -929,10 +923,10 @@ private void Hal_EfuseReadEFuse8812A(UInt16 _offset, UInt16 _size_byte, byte[] p } /* Read next PG header */ - _device.ReadEFuseByte(eFuse_Addr, rtemp8); + pgHeader = _device.ReadEFuseByte(eFuse_Addr); /* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d rtemp 0x%x\n", eFuse_Addr, *rtemp8)); */ - if (rtemp8[0] != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_JAGUAR)) + if (pgHeader != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_JAGUAR)) { eFuse_Addr++; } @@ -941,29 +935,22 @@ private void Hal_EfuseReadEFuse8812A(UInt16 _offset, UInt16 _size_byte, byte[] p /* */ /* 3. Collect 16 sections and 4 word unit into Efuse map. */ /* */ - for (i = 0; i < EFUSE_MAX_SECTION_JAGUAR; i++) + for (int i = 0; i < efuseMaxSectionJaguar; i++) { - for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) + for (int j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { - efuseTbl[(i * 8) + (j * 2)] = (byte)(eFuseWord[i][j] & 0xff); - efuseTbl[(i * 8) + ((j * 2) + 1)] = (byte)((eFuseWord[i][j] >> 8) & 0xff); + efuseTable[(i * 8) + (j * 2)] = (byte)(eFuseWord[i][j] & 0xff); + efuseTable[(i * 8) + ((j * 2) + 1)] = (byte)((eFuseWord[i][j] >> 8) & 0xff); } } - - /* */ - /* 4. Copy from Efuse map to output pointer memory!!! */ - /* */ - for (i = 0; i < _size_byte; i++) - { - pbuf[i] = efuseTbl[_offset + i]; - } - /* */ /* 5. Calculate Efuse utilization. */ /* */ // TODO: SetHwReg8812AU(HW_VARIABLES.HW_VAR_EFUSE_BYTES, (byte*)&eFuse_Addr); _logger.LogInformation($"Hal_EfuseReadEFuse8812A: eFuse_Addr offset(0x{eFuse_Addr:X}) !!"); + + return efuseTable; } /// diff --git a/src/Rtl8812auNet/Rtl8812au/Rtl8812aDevice.cs b/src/Rtl8812auNet/Rtl8812au/Rtl8812aDevice.cs index 1c33ac0..160f40a 100644 --- a/src/Rtl8812auNet/Rtl8812au/Rtl8812aDevice.cs +++ b/src/Rtl8812auNet/Rtl8812au/Rtl8812aDevice.cs @@ -10,6 +10,7 @@ public class Rtl8812aDevice { private readonly RtlUsbAdapter _device; private readonly ILogger _logger; + private readonly EepromManager _eepromManager; private readonly FrameParser _frameParser; private readonly RadioManagementModule _radioManagement; @@ -29,9 +30,9 @@ internal Rtl8812aDevice( _logger = logger; _frameParser = new FrameParser(frameParserLogger); - var eepromManager = new EepromManager(device, eepromLogger); - _radioManagement = new RadioManagementModule(HwPort.HW_PORT0, device, eepromManager, _logger); - _halModule = new HalModule(_device, _radioManagement, eepromManager, halLogger, firmwareManagerLogger); + _eepromManager = new EepromManager(device, eepromLogger); + _radioManagement = new RadioManagementModule(HwPort.HW_PORT0, device, _eepromManager, _logger); + _halModule = new HalModule(_device, _radioManagement, _eepromManager, halLogger, firmwareManagerLogger); } public void Init( @@ -62,11 +63,20 @@ private void StartWithMonitorMode(SelectedChannel selectedChannel) _radioManagement.SetMonitorMode(); } - private bool NetDevOpen(SelectedChannel selectedChannel) + internal bool NetDevOpen(SelectedChannel selectedChannel) { return _halModule.rtw_hal_init(selectedChannel); } + /// + /// Special method for EfuseManager application + /// + /// Efuse dump + internal byte[] ReadEfuse() + { + return _eepromManager.Hal_EfuseReadEFuse8812A(); + } + private void BulkDataHandler(ReadOnlySpan data) { var packet = _frameParser.ParsedRadioPacket(data); diff --git a/src/Rtl8812auNet/Rtl8812auNet.csproj b/src/Rtl8812auNet/Rtl8812auNet.csproj index 92472bb..06a8239 100644 --- a/src/Rtl8812auNet/Rtl8812auNet.csproj +++ b/src/Rtl8812auNet/Rtl8812auNet.csproj @@ -45,4 +45,7 @@ + + + diff --git a/src/Rtl8812auNet/RtlUsbAdapter.cs b/src/Rtl8812auNet/RtlUsbAdapter.cs index f100f13..a469dd6 100644 --- a/src/Rtl8812auNet/RtlUsbAdapter.cs +++ b/src/Rtl8812auNet/RtlUsbAdapter.cs @@ -189,15 +189,11 @@ private void PHY_SetBBReg8812( } - public void ReadEFuseByte(UInt16 _offset, byte[] pbuf) + public byte ReadEFuseByte(UInt16 _offset) { - UInt32 value32; - byte readbyte; - UInt16 retry; - /* Write Address */ rtw_write8(EFUSE_CTRL + 1, (byte)(_offset & 0xff)); - readbyte = rtw_read8(EFUSE_CTRL + 2); + byte readbyte = rtw_read8(EFUSE_CTRL + 2); rtw_write8(EFUSE_CTRL + 2, (byte)(((_offset >> 8) & 0x03) | (readbyte & 0xfc))); /* Write bit 32 0 */ @@ -205,8 +201,8 @@ public void ReadEFuseByte(UInt16 _offset, byte[] pbuf) rtw_write8(EFUSE_CTRL + 3, (byte)(readbyte & 0x7f)); /* Check bit 32 read-ready */ - retry = 0; - value32 = rtw_read32(EFUSE_CTRL); + UInt16 retry = 0; + UInt32 value32 = rtw_read32(EFUSE_CTRL); /* while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) */ while ((((value32 >> 24) & 0xff) & 0x80) == 0 && (retry < 10000)) { @@ -221,7 +217,7 @@ public void ReadEFuseByte(UInt16 _offset, byte[] pbuf) Thread.Sleep(50); value32 = rtw_read32(EFUSE_CTRL); - pbuf[0] = (byte)(value32 & 0xff); + return (byte)(value32 & 0xff); }