Files
portersky 9c1b6493d8 feat: show live controller input
Route paired controller QoS data through the existing GIP protocol layer and
expose the latest gamepad report through the C API. Add a SwiftUI monitor for
buttons, d-pad, triggers, and stick positions without registering a native HID
device.

Co-Authored-By: openai/gpt-5.6-luna: GIP bridge and live input monitor
2026-08-29 13:36:54 +02:00

493 lines
17 KiB
C++

#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
// pairing and data path increments.
// ==============================================================================
#include <cstddef>
#include <cstdint>
#include "common/types.hpp"
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;
}
// Extract a bitfield (port of the kernel FIELD_GET macro).
inline constexpr auto field_get(std::uint32_t mask, std::uint32_t val)
-> std::uint32_t
{
return (val & mask) >> __builtin_ctz(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,
};
// MCU message header fields.
constexpr std::uint32_t mt_mcu_msg_len = genmask(15, 0);
constexpr std::uint32_t mt_mcu_msg_cmd_seq = genmask(19, 16);
constexpr std::uint32_t mt_mcu_msg_cmd_type = genmask(26, 20);
constexpr std::uint32_t mt_mcu_msg_port = genmask(29, 27);
constexpr std::uint32_t mt_mcu_msg_type = genmask(31, 30);
constexpr std::uint32_t mt_mcu_msg_type_cmd = bit(30);
// DMA message ports (MT_MCU_MSG_PORT field).
enum dma_msg_port : std::uint32_t {
wlan_port = 0,
cpu_rx_port,
cpu_tx_port,
host_port,
virtual_cpu_rx_port,
virtual_cpu_tx_port,
discard,
};
// MCU message header length (port of MT_CMD_HDR_LEN).
constexpr std::size_t cmd_hdr_len = 4;
// FCE DMA registers.
constexpr std::uint32_t mt_fce_dma_addr = 0x0230;
constexpr std::uint32_t mt_fce_dma_len = 0x0234;
// Firmware load registers and constants (port of XONE_MT_FW_*).
constexpr std::uint32_t xone_mt_rf_patch = 0x0130;
constexpr std::uint32_t fw_load_ivb = 0x12;
constexpr std::uint32_t fw_ilm_offset = 0x080000;
constexpr std::uint32_t fw_dlm_offset = 0x110800;
constexpr std::size_t fw_chunk_size = 0x3800;
// USB DMA control register and bits.
constexpr std::uint32_t mt_usb_u3dma_cfg = 0x9018;
constexpr std::uint32_t mt_usb_dma_cfg_rx_bulk_en = bit(22);
constexpr std::uint32_t mt_usb_dma_cfg_tx_bulk_en = bit(23);
// Firmware load configuration registers.
constexpr std::uint32_t mt_fce_pse_ctrl = 0x0800;
constexpr std::uint32_t mt_tx_cpu_from_fce_base_ptr = 0x09a0;
constexpr std::uint32_t mt_tx_cpu_from_fce_max_count = 0x09a4;
constexpr std::uint32_t mt_tx_cpu_from_fce_cpu_desc_idx = 0x09a8;
constexpr std::uint32_t mt_fce_pdma_global_conf = 0x09c4;
constexpr std::uint32_t mt_fce_skip_fs = 0x0a6c;
// Firmware file header (port of struct mt76_fw_header).
struct fw_header {
std::uint32_t ilm_len; // little-endian on disk
std::uint32_t dlm_len; // little-endian on disk
std::uint16_t build_ver;
std::uint16_t fw_ver;
std::uint8_t pad[4];
char build_time[16];
} XONE_PACKED;
// MCU command types (port of enum mt76_mcu_cmd).
enum mcu_cmd : std::uint32_t {
cmd_fun_set_op = 1,
cmd_load_cr = 2,
cmd_init_gain_op = 3,
cmd_dync_vga_op = 6,
cmd_tdls_ch_sw = 7,
cmd_burst_write = 8,
cmd_read_modify_write = 9,
cmd_random_read = 10,
cmd_burst_read = 11,
cmd_random_write = 12,
cmd_led_mode_op = 16,
cmd_power_saving_op = 20,
cmd_wow_config = 21,
cmd_wow_query = 22,
cmd_wow_feature = 24,
cmd_carrier_detect_op = 28,
cmd_rador_detect_op = 29,
cmd_switch_channel_op = 30,
cmd_calibration_op = 31,
cmd_beacon_op = 32,
cmd_antenna_op = 33,
};
// MCU function select (port of enum mt76_mcu_function).
enum mcu_function : std::uint32_t {
fun_q_select = 1,
fun_bw_setting = 2,
fun_usb2_sw_disconnect = 2, // duplicate value upstream
fun_usb3_sw_disconnect = 3,
fun_log_fw_debug_msg = 4,
fun_get_fw_version = 5,
};
// CR load modes (port of enum mt76_mcu_cr_mode).
enum cr_mode : std::uint32_t {
rf_cr = 0,
bbp_cr,
rf_bbp_cr,
hl_temp_cr_update,
};
// Radio power modes (port of enum mt76_mcu_power_mode).
enum power_mode : std::uint32_t {
radio_off = 0x30,
radio_on = 0x31,
radio_off_auto_wakeup = 0x32,
radio_off_advance = 0x33,
radio_on_advance = 0x34,
};
// Calibration types (port of enum mt76_mcu_calibration).
enum calibration : std::uint32_t {
cal_r = 1,
cal_temp_sensor,
cal_rxdcoc,
cal_rc,
cal_sx_logen,
cal_lc,
cal_tx_loft,
cal_txiq,
cal_tssi,
cal_tssi_comp,
cal_dpd,
cal_rxiqc_fi,
};
// Commands to Microsoft's proprietary firmware (port of enum xone_mt76_ms_command).
enum ms_command : std::uint32_t {
ms_set_mac_address = 0x00,
ms_add_client = 0x01,
ms_remove_client = 0x02,
ms_set_idle_time = 0x05,
ms_set_chan_candidates = 0x07,
};
// LED modes (port of enum xone_mt76_led_mode).
enum led_mode : std::uint32_t {
led_blink = 0x00,
led_on = 0x01,
led_off = 0x02,
};
// Wake-on-wireless features (port of enum xone_mt76_wow_feature).
enum wow_feature : std::uint32_t {
wow_enable = 0x01,
wow_traffic_op = 0x03,
};
// WOW traffic direction (port of enum xone_mt76_wow_traffic).
enum wow_traffic : std::uint32_t {
wow_to_firmware = 0x00,
wow_to_host = 0x01,
};
// PHY types (port of enum mt76_phy_type, used in MT_RXWI_RATE_PHY).
enum phy_type : std::uint32_t {
phy_cck = 0,
phy_ofdm,
phy_ht,
phy_ht_gf,
phy_vht,
phy_he_su = 8,
};
// PHY bandwidths (port of enum mt76_phy_bandwidth).
enum phy_bandwidth : std::uint32_t {
bw_20 = 0,
bw_40,
bw_80,
};
// Calibration channel groups (port of enum mt76_cal_channel_group).
enum cal_channel_group : std::uint32_t {
ch_5g_japan = 0,
ch_5g_unii_1,
ch_5g_unii_2,
ch_5g_unii_2e_1,
ch_5g_unii_2e_2,
ch_5g_unii_3,
};
// Channel bands (port of XONE_MT_CH_*).
constexpr std::uint8_t ch_2g_low = 0x01;
constexpr std::uint8_t ch_2g_mid = 0x02;
constexpr std::uint8_t ch_2g_high = 0x03;
constexpr std::uint8_t ch_5g_low = 0x01;
constexpr std::uint8_t ch_5g_high = 0x02;
// Channel table (port of xone_mt76_channels).
struct channel {
std::uint8_t index;
std::uint8_t band; // ch_* value
std::uint8_t bandwidth; // phy_bandwidth
std::uint8_t group; // cal_channel_group (5G only)
bool scan;
std::uint8_t power;
};
constexpr std::size_t num_channels = 12;
inline constexpr channel channels[num_channels] = {
{ 0x01, ch_2g_low, bw_20, 0, true, 0 },
{ 0x06, ch_2g_mid, bw_20, 0, true, 0 },
{ 0x0b, ch_2g_high, bw_20, 0, true, 0 },
{ 0x24, ch_5g_low, bw_40, ch_5g_unii_1, true, 0 },
{ 0x28, ch_5g_low, bw_40, ch_5g_unii_1, false, 0 },
{ 0x2c, ch_5g_high, bw_40, ch_5g_unii_1, true, 0 },
{ 0x30, ch_5g_high, bw_40, ch_5g_unii_1, false, 0 },
{ 0x95, ch_5g_low, bw_80, ch_5g_unii_3, true, 0 },
{ 0x99, ch_5g_low, bw_80, ch_5g_unii_3, false, 0 },
{ 0x9d, ch_5g_high, bw_80, ch_5g_unii_3, true, 0 },
{ 0xa1, ch_5g_high, bw_80, ch_5g_unii_3, false, 0 },
{ 0xa5, ch_5g_high, bw_80, ch_5g_unii_3, false, 0 },
};
// EFUSE TX power tables and crystal trim.
constexpr std::uint16_t mt_ee_xtal_trim_1 = 0x003a;
constexpr std::uint16_t mt_ee_xtal_trim_2 = 0x009e;
constexpr std::uint16_t mt_ee_tx_power_0_start_2g = 0x0056;
constexpr std::size_t tx_power_group_size_5g = 5;
constexpr std::uint16_t mt_ee_tx_power_0_start_5g = 0x0062;
// Crystal oscillator control registers.
constexpr std::uint32_t mt_cmb_ctrl = 0x0020;
constexpr std::uint32_t mt_xo_ctrl5 = 0x0114;
constexpr std::uint32_t mt_xo_ctrl5_c2_val = genmask(14, 8);
constexpr std::uint32_t mt_xo_ctrl6 = 0x0118;
constexpr std::uint32_t mt_xo_ctrl6_c2_ctrl = genmask(14, 8);
// MAC address registers and MCU memory map (port of MT_MCU_MEMMAP_WLAN).
constexpr std::uint32_t mt_mcu_memmap_wlan = 0x410000;
constexpr std::uint32_t mt_mac_addr_dw0 = 0x1008;
constexpr std::uint32_t mt_mac_bssid_dw0 = 0x1010;
// MAC system control register.
constexpr std::uint32_t mt_mac_sys_ctrl = 0x1004;
constexpr std::uint32_t mt_mac_sys_ctrl_reset_csr = bit(0);
constexpr std::uint32_t mt_mac_sys_ctrl_reset_bbp = bit(1);
constexpr std::uint32_t mt_mac_sys_ctrl_enable_tx = bit(2);
constexpr std::uint32_t mt_mac_sys_ctrl_enable_rx = bit(3);
// Radio init registers (port of the xone_mt76_init_registers writes).
constexpr std::uint32_t mt_usb_dma_cfg = 0x0238;
constexpr std::uint32_t mt_pwr_pin_cfg = 0x1204;
constexpr std::uint32_t mt_ldo_ctrl_1 = 0x0070;
constexpr std::uint32_t mt_wpdma_glo_cfg = 0x0208;
constexpr std::uint32_t mt_wmm_aifsn = 0x0214;
constexpr std::uint32_t mt_wmm_cwmin = 0x0218;
constexpr std::uint32_t mt_wmm_cwmax = 0x021c;
constexpr std::uint32_t mt_tso_ctrl = 0x0250;
constexpr std::uint32_t mt_pbf_sys_ctrl = 0x0400;
constexpr std::uint32_t mt_pbf_tx_max_pcnt = 0x0408;
constexpr std::uint32_t mt_auto_rsp_cfg = 0x1404;
constexpr std::uint32_t mt_max_len_cfg = 0x1018;
constexpr std::uint32_t mt_ampdu_max_len_20m1s = 0x1030;
constexpr std::uint32_t mt_ampdu_max_len_20m2s = 0x1034;
constexpr std::uint32_t mt_bkoff_slot_cfg = 0x1104;
constexpr std::uint32_t mt_edca_cfg_base = 0x1300;
inline constexpr auto mt_edca_cfg_ac(std::size_t n) -> std::uint32_t
{
return mt_edca_cfg_base + (n << 2);
}
constexpr std::uint32_t mt_tx_pin_cfg = 0x1328;
constexpr std::uint32_t mt_tx_sw_cfg0 = 0x1330;
constexpr std::uint32_t mt_tx_sw_cfg1 = 0x1334;
constexpr std::uint32_t mt_txop_ctrl_cfg = 0x1340;
constexpr std::uint32_t mt_tx_rts_cfg = 0x1344;
constexpr std::uint32_t mt_tx_timeout_cfg = 0x1348;
constexpr std::uint32_t mt_tx_retry_cfg = 0x134c;
constexpr std::uint32_t mt_cck_prot_cfg = 0x1364;
constexpr std::uint32_t mt_ofdm_prot_cfg = 0x1368;
constexpr std::uint32_t mt_mm20_prot_cfg = 0x136c;
constexpr std::uint32_t mt_gf20_prot_cfg = 0x1374;
constexpr std::uint32_t mt_gf40_prot_cfg = 0x1378;
constexpr std::uint32_t mt_exp_ack_time = 0x1380;
constexpr std::uint32_t mt_tx_alc_cfg_0 = 0x13b0;
constexpr std::uint32_t mt_tx_alc_cfg_2 = 0x13a8;
constexpr std::uint32_t mt_tx_alc_cfg_3 = 0x13ac;
constexpr std::uint32_t mt_tx_alc_cfg_4 = 0x13c0;
constexpr std::uint32_t mt_pifs_tx_cfg = 0x13ec;
constexpr std::uint32_t mt_rx_filtr_cfg = 0x1400;
constexpr std::uint32_t mt_legacy_basic_rate = 0x1408;
constexpr std::uint32_t mt_ht_basic_rate = 0x140c;
constexpr std::uint32_t mt_pn_pad_mode = 0x150c;
constexpr std::uint32_t mt_txop_hldr_et = 0x1608;
constexpr std::uint32_t mt_tx_prot_cfg6 = 0x13e0;
constexpr std::uint32_t mt_tx_prot_cfg7 = 0x13e4;
constexpr std::uint32_t mt_tx_prot_cfg8 = 0x13e8;
constexpr std::uint32_t mt_dacclk_en_dly_cfg = 0x1264;
constexpr std::uint32_t mt_rf_pa_mode_adj0 = 0x1228;
constexpr std::uint32_t mt_rf_pa_mode_adj1 = 0x122c;
constexpr std::uint32_t mt_tx0_rf_gain_corr = 0x13a0;
constexpr std::uint32_t mt_tx1_rf_gain_corr = 0x13a4;
constexpr std::uint32_t mt_pbf_cfg = 0x0404;
constexpr std::uint32_t mt_pause_enable_control1 = 0x0a38;
constexpr std::uint32_t mt_rf_bypass_0 = 0x0504;
constexpr std::uint32_t mt_rf_setting_0 = 0x050c;
constexpr std::uint32_t mt_xifs_time_cfg = 0x1100;
constexpr std::uint32_t mt_fce_l2_stuff = 0x080c;
constexpr std::uint32_t mt_ext_cca_cfg = 0x141c;
constexpr std::uint32_t mt_ch_time_cfg = 0x110c;
// BBP registers (port of MT_BBP(type, n)).
constexpr std::uint32_t mt_bbp_agc_base = 0x2300;
inline constexpr auto mt_bbp_agc(std::size_t n) -> std::uint32_t
{
return mt_bbp_agc_base + (n << 2);
}
// Beacon timer register.
constexpr std::uint32_t mt_beacon_time_cfg = 0x1114;
constexpr std::uint32_t mt_beacon_time_cfg_intval = genmask(15, 0);
constexpr std::uint32_t mt_beacon_time_cfg_timer_en = bit(16);
constexpr std::uint32_t mt_beacon_time_cfg_sync_mode = genmask(18, 17);
constexpr std::uint32_t mt_beacon_time_cfg_tbtt_en = bit(19);
constexpr std::uint32_t mt_beacon_time_cfg_beacon_tx = bit(20);
// Broadcast MAC address (port of eth_broadcast_addr).
inline constexpr std::uint8_t broadcast_address[6] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
// Beacon frame storage and TXWI fields.
constexpr std::uint32_t mt_beacon_base = 0xc000;
constexpr std::uint32_t mt_rxwi_rate_phy = genmask(15, 13);
constexpr std::uint8_t mt_txwi_ack_ctl_nseq = bit(1);
// 802.11 frame control for a beacon (MGMT type, BEACON subtype).
constexpr std::uint16_t ieee80211_fc_beacon = 0x0080;
// WCID regions (port of MT_WCID_*). n is the zero-based WCID index.
constexpr std::uint32_t mt_wcid_addr_base = 0x1800;
inline constexpr auto mt_wcid_addr(std::size_t n) -> std::uint32_t
{
return mt_wcid_addr_base + (n << 3);
}
constexpr std::uint32_t mt_wcid_key_base = 0x8000;
inline constexpr auto mt_wcid_key(std::size_t n) -> std::uint32_t
{
return mt_wcid_key_base + (n << 5);
}
constexpr std::uint32_t mt_wcid_iv_base = 0xa000;
inline constexpr auto mt_wcid_iv(std::size_t n) -> std::uint32_t
{
return mt_wcid_iv_base + (n << 3);
}
constexpr std::uint32_t mt_wcid_attr_base = 0xa800;
inline constexpr auto mt_wcid_attr(std::size_t n) -> std::uint32_t
{
return mt_wcid_attr_base + (n << 2);
}
constexpr std::uint32_t mt_wcid_attr_pairwise = bit(0);
constexpr std::uint32_t mt_wcid_attr_pkey_mode = genmask(3, 1);
constexpr std::size_t xone_mt_wcid_key_len = 16;
// TX descriptor info fields (port of MT_TXD_INFO_*), used by send_wlan.
constexpr std::uint32_t mt_txd_info_80211 = bit(19);
constexpr std::uint32_t mt_txd_info_wiv = bit(24);
constexpr std::uint32_t mt_txd_info_qsel = genmask(26, 25);
constexpr std::uint32_t mt_txd_info_dport = genmask(29, 27);
// RX FCE info fields (port of MT_RX_FCE_INFO_*), used by the RX path.
constexpr std::uint32_t mt_rx_fce_info_len = genmask(13, 0);
constexpr std::uint32_t mt_rx_fce_info_evt_type = genmask(23, 20);
// Receive descriptor (port of struct mt76_rxwi). Little-endian wire order,
// 32 bytes total. Only rxinfo and ctl are consumed by the RX path.
struct mt76_rxwi {
std::uint32_t rxinfo; // MT_RXINFO_L2PAD etc.
std::uint32_t ctl; // wcid (bits 7:0), mpdu_len (bits 29:16)
std::uint16_t tid_sn;
std::uint16_t rate;
std::uint8_t rssi[4];
std::uint32_t bbp_rxinfo[4];
};
constexpr std::uint32_t mt_rxinfo_l2pad = bit(14);
constexpr std::uint32_t mt_rxwi_ctl_wcid = genmask(7, 0);
constexpr std::uint32_t mt_rxwi_ctl_mpdu_len = genmask(29, 16);
// CPU RX event types (port of XONE_MT_EVT_*).
enum cpu_evt : std::uint32_t {
evt_button = 0x04,
evt_packet_rx = 0x0c,
evt_client_lost = 0x0e,
};
// Client command codes (port of XONE_MT_CLIENT_*).
enum client_cmd : std::uint32_t {
client_pair_req = 0x01,
client_pair_resp = 0x02,
client_enable_encryption = 0x10,
};
// 802.11 frame control: type (bits 3:2) and subtype (bits 7:4).
// FCTL_FTYPE/FCTL_STYPE are the masks used to match a frame's type/subtype.
constexpr std::uint16_t ieee80211_fctl_ftype = 0x0c;
constexpr std::uint16_t ieee80211_fctl_stype = 0xf0;
constexpr std::uint16_t ieee80211_ftype_mgmt = 0x00;
constexpr std::uint16_t ieee80211_ftype_data = 0x08;
constexpr std::uint16_t ieee80211_fctl_from_ds = 0x0200;
constexpr std::uint16_t ieee80211_fctl_protected = 0x4000;
constexpr std::uint16_t ieee80211_stype_assoc_req = 0x00;
constexpr std::uint16_t ieee80211_stype_assoc_resp = 0x10;
constexpr std::uint16_t ieee80211_stype_disassoc = 0xa0;
constexpr std::uint16_t ieee80211_stype_qos_data = 0x80;
// MGMT subtype for reserved (pairing) frames.
constexpr std::uint16_t ieee80211_stype_wlan_reserved = 0x70;
// TX descriptor fields (port of MT_TXWI_*).
constexpr std::uint32_t mt_txwi_flags_mpdu_density = genmask(7, 5);
constexpr std::uint8_t mt_txwi_ack_ctl_req = bit(0);
constexpr std::uint8_t ieee80211_ht_mpdu_density_4 = 4;
// TX queue selection (port of enum mt76_qsel).
enum qsel : std::uint32_t {
qsel_mgmt = 0,
qsel_hcca = 1,
qsel_edca = 2,
qsel_edca_2 = 3,
};
// Cipher types (port of enum mt76_cipher_type).
enum cipher_type : std::uint32_t {
cipher_none = 0,
cipher_wep40 = 1,
cipher_wep104 = 2,
cipher_tkip = 3,
cipher_aes_ccmp = 4,
};
} // namespace xone::mt76