feat: port MT76 register and EFUSE access
Add the mt76::chip class on top of the USB transport: 32-bit register read/write via vendor requests, register polling, and EFUSE reads with the kick/control sequence from transport/mt76.c. Expose chip_id() and mac_address() (with the 62:45:bd fallback). Verified on hardware: chip ID 0x7612 (MT7612) and MAC address read from EFUSE. Co-Authored-By: qwen3.8-27b@q2_k_xl: ported register and EFUSE layer
This commit is contained in:
+31
-3
@@ -9,12 +9,40 @@
|
||||
// association and WCID/AES-CCMP key setup (encryption runs on-chip).
|
||||
// ==============================================================================
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xone::usb {
|
||||
class transport;
|
||||
}
|
||||
|
||||
namespace xone::mt76 {
|
||||
|
||||
// Load the firmware image for the given dongle PID into the chip.
|
||||
// TODO(phase 3): port from xone_mt76_load_firmware().
|
||||
auto load_firmware(std::uint16_t pid, char const *firmware_path) -> bool;
|
||||
// Owns the MT76 chip protocol on top of an open USB transport. Port of
|
||||
// struct xone_mt76 plus the register/EFUSE layer of transport/mt76.c.
|
||||
class chip {
|
||||
public:
|
||||
explicit chip(usb::transport &transport);
|
||||
|
||||
// 32-bit register read/write (addr may include mt_vend_type_cfg).
|
||||
auto read_register(std::uint32_t addr) -> std::uint32_t;
|
||||
auto write_register(std::uint32_t addr, std::uint32_t val) -> void;
|
||||
|
||||
// Poll until (read_register(offset) & mask) == val. False on timeout.
|
||||
auto poll(std::uint32_t offset, std::uint32_t mask, std::uint32_t val) -> bool;
|
||||
|
||||
// Read EFUSE bytes at the 16-bit block address. Returns 0 or -errno.
|
||||
auto read_efuse(std::uint16_t addr, void *data, std::size_t len) -> int;
|
||||
|
||||
// Chip ID from EFUSE (e.g. MT7612). 0 on failure.
|
||||
auto chip_id() -> std::uint16_t;
|
||||
|
||||
// MAC address from EFUSE with the 62:45:bd fallback applied.
|
||||
auto mac_address() -> std::array<std::uint8_t, 6>;
|
||||
|
||||
private:
|
||||
usb::transport &transport_;
|
||||
};
|
||||
|
||||
} // namespace xone::mt76
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
// ==============================================================================
|
||||
// MT76 chip register definitions (port of transport/mt76_defs.h)
|
||||
// ==============================================================================
|
||||
// Only the registers needed so far are ported; the rest land with the radio
|
||||
// init and firmware load increments.
|
||||
// ==============================================================================
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace xone::mt76 {
|
||||
|
||||
// Bitfield helpers (port of the kernel BIT/GENMASK/FIELD_PREP macros).
|
||||
inline constexpr auto bit(std::uint32_t n) -> std::uint32_t
|
||||
{
|
||||
return 1u << n;
|
||||
}
|
||||
|
||||
inline constexpr auto genmask(std::uint32_t hi, std::uint32_t lo) -> std::uint32_t
|
||||
{
|
||||
return (~0u << lo) & (~0u >> (31 - hi));
|
||||
}
|
||||
|
||||
inline constexpr auto field_prep(std::uint32_t mask, std::uint32_t val) -> std::uint32_t
|
||||
{
|
||||
return (val << __builtin_ctz(mask)) & mask;
|
||||
}
|
||||
|
||||
// Register address flag: use the config-space vendor request codes.
|
||||
constexpr std::uint32_t mt_vend_type_cfg = bit(30);
|
||||
|
||||
// EFUSE control register.
|
||||
constexpr std::uint32_t mt_efuse_ctrl = 0x0024;
|
||||
constexpr std::uint32_t mt_efuse_ctrl_aout = genmask(5, 0);
|
||||
constexpr std::uint32_t mt_efuse_ctrl_mode = genmask(7, 6);
|
||||
constexpr std::uint32_t mt_efuse_ctrl_ldo_off_time = genmask(13, 8);
|
||||
constexpr std::uint32_t mt_efuse_ctrl_ldo_on_time = genmask(15, 14);
|
||||
constexpr std::uint32_t mt_efuse_ctrl_ain = genmask(25, 16);
|
||||
constexpr std::uint32_t mt_efuse_ctrl_kick = bit(30);
|
||||
constexpr std::uint32_t mt_efuse_ctrl_sel = bit(31);
|
||||
|
||||
// EFUSE data registers (one per 32-bit word of the 16-byte block).
|
||||
constexpr std::uint32_t mt_efuse_data_base = 0x0028;
|
||||
|
||||
// EFUSE block addresses.
|
||||
constexpr std::uint16_t mt_ee_chip_id = 0x0000;
|
||||
constexpr std::uint16_t mt_ee_version = 0x0002;
|
||||
constexpr std::uint16_t mt_ee_mac_addr = 0x0004;
|
||||
|
||||
// EFUSE read modes (MT_EFUSE_CTRL_MODE field).
|
||||
enum efuse_mode : std::uint32_t {
|
||||
efuse_read = 0,
|
||||
efuse_physical_read,
|
||||
};
|
||||
|
||||
} // namespace xone::mt76
|
||||
Reference in New Issue
Block a user