Skip to content

Commit

Permalink
Efuse read implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
buldo committed May 24, 2024
1 parent be288de commit b81577c
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 88 deletions.
17 changes: 17 additions & 0 deletions src/EfuseManager/ViewModels/EfuseMapViewModel.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
13 changes: 12 additions & 1 deletion src/EfuseManager/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.Extensions.Logging.Abstractions;

using Rtl8812auNet;
using Rtl8812auNet.Rtl8812au.Enumerations;

namespace EfuseManager.ViewModels;

Expand Down Expand Up @@ -44,6 +45,8 @@ public DeviceViewModel? SelectedDevice
set => SetProperty(ref _selectedDevice, value);
}

public EfuseMapViewModel EfuseMap { get; } = new();

private void ExecuteWrite()
{
throw new NotImplementedException();
Expand All @@ -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()
Expand Down
7 changes: 7 additions & 0 deletions src/Rtl8812auNet/Rtl8812au/Enumerations/EfuseType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Rtl8812auNet.Rtl8812au.Enumerations
{
public enum EfuseType : byte
{
EfuseWiFi = 0
}
}
135 changes: 61 additions & 74 deletions src/Rtl8812auNet/Rtl8812au/Modules/EepromManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -556,7 +554,7 @@ private void hal_InitPGData_8812A()
}

/* Read EFUSE real map to shadow. */
EFUSE_ShadowMapUpdate(EFUSE_WIFI);
EFUSE_ShadowMapUpdate(EfuseType.EfuseWiFi);
}
}
else
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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)
{
Expand All @@ -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()
Expand Down Expand Up @@ -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;
}
Expand All @@ -821,88 +805,98 @@ 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++;
}
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;
Expand All @@ -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)
Expand All @@ -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++;
}
Expand All @@ -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;
}

/// <remarks>
Expand Down
Loading

0 comments on commit b81577c

Please sign in to comment.