Files
xone_macos/tests/test_mt76.cpp
T
portersky c9ea1a6919 feat: port MT76 radio init and CLI tool
Complete the radio bring-up sequence: init_registers now writes the
upstream register values (PBF out of reset, beacon TX off), crystal
calibration, MAC/BSSID programming, channel evaluation, and beacon
programming through an MCU burst into PBF shared memory. The beacon
txwi is the full 20-byte struct and the RF patch is applied on the
cold firmware path.

Download firmware per product (xone_dongle_02e6.bin / 02fe.bin) and
add the xone_cli debug tool (info, firmware, radio-init/deinit, burst,
reg-read/write, led, recover). Recover uses USBDeviceReEnumerate for a
host-side port reset.

Co-Authored-By: grok4.6: internet search (firmware split, beacon SRAM, upstream issues)
Co-Authored-By: qwen3.8-27b@q2_k_xl: initial radio init and CLI implementation
Co-Authored-By: deepseek/deepseek-v4-pro-0813: final radio init fixes and verification
2026-08-17 19:29:51 +02:00

132 lines
5.5 KiB
C++

#include "unity.h"
#include "mt76/mt76_defs.hpp"
void setUp() {}
void tearDown() {}
// Pin the bitfield helpers to kernel BIT/GENMASK/FIELD_PREP semantics.
void test_bitfield_helpers(void)
{
TEST_ASSERT_EQUAL_UINT32(xone::mt76::bit(0), 0x1u);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::bit(30), 0x40000000u);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::genmask(5, 0), 0x3Fu);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::genmask(7, 6), 0xC0u);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::genmask(25, 16), 0x03FF0000u);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::genmask(31, 0), 0xFFFFFFFFu);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::field_prep(xone::mt76::genmask(7, 6), 1), 0x40u);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::field_prep(xone::mt76::genmask(25, 16), 0x01),
0x00010000u);
}
// Pin the EFUSE register layout to transport/mt76_defs.h values.
void test_efuse_registers(void)
{
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_efuse_ctrl, 0x0024);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_efuse_ctrl_kick, 0x40000000u);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_efuse_ctrl_ain, 0x03FF0000u);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_efuse_data_base, 0x0028);
TEST_ASSERT_EQUAL_UINT16(xone::mt76::mt_ee_chip_id, 0x0000);
TEST_ASSERT_EQUAL_UINT16(xone::mt76::mt_ee_version, 0x0002);
TEST_ASSERT_EQUAL_UINT16(xone::mt76::mt_ee_mac_addr, 0x0004);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_vend_type_cfg, 0x40000000u);
}
// Pin the firmware load layout to transport/mt76.c values.
void test_firmware_layout(void)
{
TEST_ASSERT_EQUAL_UINT32(xone::mt76::fw_ilm_offset, 0x080000);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::fw_dlm_offset, 0x110800);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::fw_chunk_size, 0x3800);
TEST_ASSERT_EQUAL_UINT32(sizeof(xone::mt76::fw_header), 32);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_fce_dma_addr, 0x0230);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_fce_dma_len, 0x0234);
}
// Pin the MCU command layer to transport/mt76_defs.h values.
void test_mcu_commands(void)
{
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(xone::mt76::mcu_cmd::cmd_fun_set_op), 1);
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(xone::mt76::mcu_cmd::cmd_burst_write), 8);
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(xone::mt76::mcu_cmd::cmd_power_saving_op), 20);
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(xone::mt76::mcu_cmd::cmd_switch_channel_op), 30);
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(xone::mt76::power_mode::radio_off), 0x30);
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(xone::mt76::power_mode::radio_on), 0x31);
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(xone::mt76::ms_command::ms_set_mac_address),
0x00);
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(xone::mt76::ms_command::ms_set_idle_time), 0x05);
TEST_ASSERT_EQUAL_UINT32(
static_cast<std::uint32_t>(
xone::mt76::ms_command::ms_set_chan_candidates), 0x07);
}
// Pin the radio init register addresses to transport/mt76_defs.h values.
void test_radio_registers(void)
{
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_mac_sys_ctrl, 0x1004);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_usb_dma_cfg, 0x0238);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_edca_cfg_ac(2), 0x1308);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_bbp_agc(1), 0x2304);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_beacon_time_cfg, 0x1114);
TEST_ASSERT_EQUAL_UINT32(
xone::mt76::mt_beacon_time_cfg_beacon_tx,
static_cast<std::uint32_t>(xone::mt76::bit(20)));
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_mcu_memmap_wlan, 0x410000);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_mac_addr_dw0, 0x1008);
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_mac_bssid_dw0, 0x1010);
}
// Pin the channel table to transport/mt76.c values.
void test_channel_table(void)
{
using namespace xone::mt76;
TEST_ASSERT_EQUAL_UINT32(num_channels, 12);
TEST_ASSERT_EQUAL_UINT8(channels[0].index, 0x01);
TEST_ASSERT_EQUAL_UINT8(channels[0].bandwidth,
static_cast<std::uint8_t>(phy_bandwidth::bw_20));
TEST_ASSERT_TRUE(channels[0].scan);
TEST_ASSERT_EQUAL_UINT8(channels[3].index, 0x24);
TEST_ASSERT_EQUAL_UINT8(channels[3].group,
static_cast<std::uint8_t>(cal_channel_group::ch_5g_unii_1));
TEST_ASSERT_EQUAL_UINT8(channels[7].index, 0x95);
TEST_ASSERT_EQUAL_UINT8(channels[7].bandwidth,
static_cast<std::uint8_t>(phy_bandwidth::bw_80));
TEST_ASSERT_EQUAL_UINT8(channels[11].index, 0xa5);
TEST_ASSERT_FALSE(channels[11].scan);
}
// Pin the beacon frame layout to transport/mt76.c values.
void test_beacon_layout(void)
{
TEST_ASSERT_EQUAL_UINT32(xone::mt76::mt_beacon_base, 0xc000);
TEST_ASSERT_EQUAL_UINT16(xone::mt76::ieee80211_fc_beacon, 0x0080);
TEST_ASSERT_EQUAL_UINT32(
xone::mt76::field_prep(xone::mt76::mt_rxwi_rate_phy,
static_cast<std::uint32_t>(
xone::mt76::phy_type::phy_ofdm)),
0x2000u);
TEST_ASSERT_EQUAL_UINT8(xone::mt76::mt_txwi_ack_ctl_nseq, 0x02);
TEST_ASSERT_EQUAL_UINT32(sizeof(xone::mt76::broadcast_address), 6);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_bitfield_helpers);
RUN_TEST(test_efuse_registers);
RUN_TEST(test_firmware_layout);
RUN_TEST(test_mcu_commands);
RUN_TEST(test_radio_registers);
RUN_TEST(test_channel_table);
RUN_TEST(test_beacon_layout);
return UNITY_END();
}