#pragma once // ============================================================================== // MT76 chip protocol (MediaTek MT76xx radio in the dongle) // ============================================================================== // Port target: medusalix/xone transport/mt76.c + mt76.h + mt76_defs.h. // Firmware load (0x3800-byte chunks), EFUSE read, radio init (~80 register // writes), channel evaluation, beacon transmission, pairing mode, client // association and WCID/AES-CCMP key setup (encryption runs on-chip). // ============================================================================== #include #include #include #include #include "mt76/mt76_defs.hpp" namespace xone::usb { class transport; } namespace xone::mt76 { // 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; // Load the firmware image from a file (port of xone_mt76_load_firmware). // Resets the MCU if firmware is already loaded. Returns 0 or -errno. auto load_firmware(char const *path) -> int; // Build string of the loaded firmware image (empty until load_firmware). auto firmware_build() const -> char const *; // MCU commands (port of the xone_mt76_* wrappers around send_command). auto set_led_mode(std::uint32_t mode) -> int; auto select_function(std::uint32_t func, std::uint32_t val) -> int; auto set_power_mode(power_mode mode) -> int; auto load_cr(cr_mode mode) -> int; auto write_burst(std::uint32_t idx, void const *data, std::size_t len) -> int; auto send_ms_command(ms_command cmd, void *data, std::size_t len) -> int; auto calibrate(calibration calib, std::uint32_t val) -> int; // Initialize the radio (port of xone_mt76_init_radio). Returns 0 or -errno. auto init_radio() -> int; // Suspend or resume the radio (ports of xone_mt76_suspend/resume_radio). auto suspend_radio() -> int; auto resume_radio() -> int; // Enter or leave pairing mode (port of xone_mt76_set_pairing). auto set_pairing(bool enable) -> int; // Controller association and data path (ports of the xone_mt76_* client // functions). `addr` is a 6-byte controller MAC. // // send_wlan prepends a TXWI and frames the payload as an MCU message, // then bulk-writes it to EP OUT. auto send_wlan(std::span frame) -> int; // Send a GIP payload in an upstream QoS-data frame for one client. auto send_client_frame(std::uint8_t wcid, std::span addr, std::span frame, bool encrypted) -> int; // Associate a controller: program its WCID MAC, ADD_CLIENT ms_command, // and transmit an ASSOC_RESP mgmt frame. auto associate_client(std::uint8_t wcid, std::span addr) -> int; // Reply to a pairing request with a PAIR_RESP mgmt frame. auto pair_client(std::span addr) -> int; // Send a reserved (0x70) management command to a client, waiting for an // acknowledgment (port of xone_mt76_send_client_command). auto send_client_command(std::uint8_t wcid, std::span addr, client_cmd cmd, std::span data) -> int; // Install the per-client AES-CCMP key (16 bytes) in the chip WCID // registers (port of xone_mt76_set_client_key). auto set_client_key(std::uint8_t wcid, std::span key) -> int; // Remove a client: REMOVE_CLIENT ms_command and zero its WCID regions // (port of xone_mt76_remove_client). auto remove_client(std::uint8_t wcid) -> int; private: // Send an MCU command (port of xone_mt76_send_command). `cmd` is the // MT_MCU_MSG_CMD_TYPE field. Returns bytes written, or a negative errno. auto send_command(std::uint32_t cmd, void const *payload, std::size_t payload_len) -> int; // Firmware load steps (port of xone_mt76_*). auto load_ivb() -> int; auto send_firmware_part(std::uint32_t offset, void const *data, std::size_t len) -> int; auto send_firmware(void const *fw_data, std::size_t fw_size) -> int; auto reset_firmware() -> int; // Radio suspend/resume steps (ports of the set_wow_* wrappers). auto set_wow_enable(bool enable) -> int; auto set_wow_traffic(wow_traffic traffic) -> int; // Radio init steps (port of the xone_mt76_init_radio sub-functions). auto init_registers() -> void; auto calibrate_crystal() -> int; auto init_address() -> int; auto set_idle_time() -> int; auto calibrate_radio() -> int; auto get_channel_power(channel *chan) -> int; auto switch_channel(channel const *chan) -> int; auto evaluate_channels() -> int; auto init_channels() -> int; auto write_beacon(bool pair) -> int; auto set_channel_candidates() -> int; usb::transport &m_transport; char build_time_[17] = {}; std::array m_channels{}; channel m_current_channel{}; }; } // namespace xone::mt76