// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device.h"

#include "ralink.h"

#include <ddk/protocol/usb.h>
#include <fbl/algorithm.h>
#include <lib/fit/defer.h>
#include <lib/sync/completion.h>
#include <lib/zx/vmo.h>
#include <usb/usb-request.h>
#include <wlan/common/channel.h>
#include <wlan/common/cipher.h>
#include <wlan/common/logging.h>
#include <wlan/common/mac_frame.h>
#include <wlan/common/tx_vector.h>
#include <wlan/mlme/debug.h>
#include <wlan/protocol/mac.h>
#include <wlan/protocol/phy-impl.h>
#include <zircon/assert.h>
#include <zircon/hw/usb.h>
#include <zircon/status.h>

#include <endian.h>
#include <inttypes.h>

#include <algorithm>
#include <cstdio>
#include <iterator>

#define RALINK_DUMP_EEPROM 0
#define RALINK_DUMP_RX 0
#define RALINK_DUMP_RX_UCAST_ONLY 1
#define RALINK_DUMP_TX 0
#define RALINK_DUMP_TXPOWER 0

#define CHECK_REG(reg, op, status)                                      \
    do {                                                                \
        if (status != ZX_OK) {                                          \
            errorf("" #op "Register error for " #reg ": %d\n", status); \
            return status;                                              \
        }                                                               \
    } while (0)
#define CHECK_READ(reg, status) CHECK_REG(reg, Read, status)
#define CHECK_WRITE(reg, status) CHECK_REG(reg, Write, status)

namespace {

zx_status_t sleep_for(zx::duration t) {
    return zx::nanosleep(zx::deadline_after(t));
}

constexpr size_t kReadReqCount = 128;
constexpr size_t kReadBufSize = 4096;  // Reflecting max A-MSDU length for Ralink: 3839 bytes
constexpr size_t kWriteReqCount = 128;
constexpr size_t kWriteBufSize = 4096;
constexpr size_t kMacHdrAddr1Offset = 4;

constexpr char kFirmwareFile[] = "rt2870.bin";

constexpr int kMaxBusyReads = 20;

// The polling interval and slack for asynchronous transmission reports, when the transmit hardware
// is believed to be idle.
constexpr zx::duration kAsyncTxInterruptIdlePollInterval = zx::msec(100);
constexpr zx::duration kAsyncTxInterruptIdlePollSlack = zx::msec(10);

// The polling interval and slack for asynchronous transmission reports, when the transmit hardware
// is believed to be busy. This interval must be small enough to ensure that packet transmission
// does not overflow the 16-entry hardware TX stats FIFO.
constexpr zx::duration kAsyncTxInterruptBusyPollInterval = zx::msec(1);
constexpr zx::duration kAsyncTxInterruptBusyPollSlack = zx::usec(100);

// The duration of lead time before a beacon frame used to send the pre-beacon notification.
constexpr zx::duration kPreTbttLeadTime = zx::msec(6);

// The polling interval for beacon frame interrupts, for when the interrupt is close but has not yet
// elapsed.
constexpr zx::duration kTbttInterruptPollInterval = zx::msec(1);

// Key which will shut down the currently running interrupt thread.
constexpr uint64_t kInterruptShutdownKey = 1;

// Key indicating an asynchronous transmission report interrupt.
constexpr uint64_t kAsyncTxInterruptKey = 2;

// Key indicating a beacon frame interrupt.
constexpr uint64_t kTbttInterruptKey = 3;

// TODO(hahnr): Use bcast_mac from MacAddr once it was moved to common/.
const uint8_t kBcastAddr[ETH_MAC_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// TX packet ID used to signal an invalid or untracked (e.g. beacon frame) packet.
constexpr int kInvalidTxPacketId = 0;

// The <cstdlib> overloads confuse the compiler for <cstdint> types.
template <typename T> constexpr T abs(T t) {
    return t < 0 ? -t : t;
}

int8_t extract_tx_power(int byte_offset, bool is_5ghz, uint16_t eeprom_word) {
    uint8_t val = (byte_offset % 2) ? (eeprom_word >> 8) : eeprom_word;
    int8_t power = *reinterpret_cast<int8_t*>(&val);
    int8_t min_power = is_5ghz ? ralink::kMinTxPower_A : ralink::kMinTxPower_BG;
    int8_t max_power = is_5ghz ? ralink::kMaxTxPower_A : ralink::kMaxTxPower_BG;
    return fbl::clamp(power, min_power, max_power);
}
}  // namespace

namespace ralink {

namespace wlan_device = ::fuchsia::wlan::device;

#define DEV(c) static_cast<Device*>(c)
static zx_protocol_device_t wlanphy_impl_device_ops = {
    .version = DEVICE_OPS_VERSION,
    .unbind = [](void* ctx) { DEV(ctx)->PhyUnbind(); },
    .release = [](void* ctx) { DEV(ctx)->PhyRelease(); },
};

static zx_protocol_device_t wlanmac_device_ops = {
    .version = DEVICE_OPS_VERSION,
    .unbind = [](void* ctx) { DEV(ctx)->MacUnbind(); },
    .release = [](void* ctx) { DEV(ctx)->MacRelease(); },
};

static wlanphy_impl_protocol_ops_t wlanphy_impl_ops = {
    .query = [](void* ctx, wlanphy_info_t* info) -> zx_status_t {
        return DEV(ctx)->PhyQuery(info);
    },
    .create_iface = [](void* ctx, uint16_t mac_role, uint16_t* id) -> zx_status_t {
        return DEV(ctx)->CreateIface(mac_role, id);
    },
    .destroy_iface = [](void* ctx, uint16_t id) -> zx_status_t {
        return DEV(ctx)->DestroyIface(id);
    }};

static wlanmac_protocol_ops_t wlanmac_ops = {
    .query = [](void* ctx, uint32_t options, wlanmac_info_t* info) -> zx_status_t {
        return DEV(ctx)->WlanmacQuery(options, info);
    },
    .start = [](void* ctx, wlanmac_ifc_t* info, void* cookie) -> zx_status_t {
        return DEV(ctx)->WlanmacStart(info, cookie);
    },
    .stop = [](void* ctx) { DEV(ctx)->WlanmacStop(); },
    .queue_tx = [](void* ctx, uint32_t options, wlan_tx_packet_t* pkt) -> zx_status_t {
        return DEV(ctx)->WlanmacQueueTx(options, pkt);
    },
    .set_channel = [](void* ctx, uint32_t options, wlan_channel_t* chan) -> zx_status_t {
        return DEV(ctx)->WlanmacSetChannel(options, chan);
    },
    .configure_bss = [](void* ctx, uint32_t options, wlan_bss_config_t* config) -> zx_status_t {
        return DEV(ctx)->WlanmacConfigureBss(options, config);
    },
    .enable_beaconing = [](void* ctx, uint32_t options, wlan_bcn_config_t* bcn_cfg) -> zx_status_t {
        return DEV(ctx)->WlanmacEnableBeaconing(options, bcn_cfg != nullptr);
    },
    .configure_beacon = [](void* ctx, uint32_t options, wlan_tx_packet_t* pkt) -> zx_status_t {
        return DEV(ctx)->WlanmacConfigureBeacon(options, pkt);
    },
    .set_key = [](void* ctx, uint32_t options, wlan_key_config_t* key_config) -> zx_status_t {
        return DEV(ctx)->WlanmacSetKey(options, key_config);
    },
    .configure_assoc = [](void* ctx, uint32_t options, wlan_assoc_ctx* assoc_ctx) -> zx_status_t {
        // TODO(NET-1265): Configure the chipset for this association
        return ZX_OK;
    },
    .clear_assoc = [](void* ctx, uint32_t options, const uint8_t* mac) -> zx_status_t {
        return DEV(ctx)->WlanmacClearAssoc(options, mac);
    },
};
#undef DEV

constexpr zx::duration Device::kDefaultBusyWait;

Device::Device(zx_device_t* device, usb_protocol_t usb, uint8_t bulk_in,
               std::vector<uint8_t>&& bulk_out, size_t parent_req_size)
    : parent_(device), usb_(usb), parent_req_size_(parent_req_size), rx_endpt_(bulk_in),
      tx_endpts_(std::move(bulk_out)) {
    debugf("Device dev=%p bulk_in=%u\n", parent_, rx_endpt_);
    used_wcid_bitmap_.Reset(kMaxValidWcid);
}

Device::~Device() {
    debugfn();
    for (auto req : free_write_reqs_) {
        usb_request_release(req);
    }
}

zx_status_t Device::Bind() {
    debugfn();

    AsicVerId avi;
    zx_status_t status = ReadRegister(&avi);
    CHECK_READ(ASIC_VER_ID, status);

    rt_type_ = avi.ver_id();
    rt_rev_ = avi.rev_id();
    infof("RT chipset %#x, rev %#x\n", rt_type_, rt_rev_);

    bool autorun = false;
    status = DetectAutoRun(&autorun);
    if (status != ZX_OK) { return status; }

    EfuseCtrl ec;
    status = ReadRegister(&ec);
    CHECK_READ(EFUSE_CTRL, status);

    debugf("efuse ctrl reg: %#x\n", ec.val());
    bool efuse_present = ec.sel_efuse() > 0;
    debugf("efuse present: %s\n", efuse_present ? "Y" : "N");

    status = ReadEeprom();
    if (status != ZX_OK) {
        errorf("failed to read eeprom\n");
        return status;
    }

    status = ValidateEeprom();
    if (status != ZX_OK) {
        errorf("failed to validate eeprom\n");
        return status;
    }

    status = InitializeRfVal();
    if (status != ZX_OK) { return status; }

    int count = 0;
    for (auto& entry : rf_vals_) {
        bool is_5ghz = entry.second.channel > 14;

        // The eeprom is organized into uint16_ts, but the tx power elements are 8 bits.
        // eeprom_offset represents the eeprom entry for the channel, and extract_tx_power will
        // select the correct bits and clamp them between kMinTxPower and kMaxTxPower.
        ZX_DEBUG_ASSERT(!is_5ghz || count >= 14);
        auto byte_offset = is_5ghz ? (count - 14) : count;
        auto eeprom_offset = byte_offset >> 1;

        // Determine where to find the tx power elements
        auto power1_offset = (is_5ghz ? EEPROM_TXPOWER_A1 : EEPROM_TXPOWER_BG1) + eeprom_offset;
        auto power2_offset = (is_5ghz ? EEPROM_TXPOWER_A2 : EEPROM_TXPOWER_BG2) + eeprom_offset;

        int16_t txpower1, txpower2;
        status = ReadEepromField(power1_offset, reinterpret_cast<uint16_t*>(&txpower1));
        CHECK_READ(EEPROM_TXPOWER_1, status);
        status = ReadEepromField(power2_offset, reinterpret_cast<uint16_t*>(&txpower2));
        CHECK_READ(EEPROM_TXPOWER_2, status);

        // Note: It reads [19, 24] for 2GHz channels,
        // [6, 12] for 5GHz UNII-1,2 channels,
        // [-1, 0] for 5GHz UNII-3 channels. The last appears to be invalid.
        entry.second.default_power1 = extract_tx_power(byte_offset, is_5ghz, txpower1);
        entry.second.default_power2 = extract_tx_power(byte_offset, is_5ghz, txpower2);

        count++;

#if RALINK_DUMP_TXPOWER
        auto rf_val = entry.second;
        auto cal = entry.second.cal_values;
        debugf(
            "[ralink] RF Vals: chan:%3u [eeprom_tx_power_upperbound] 1:%3d 2:%3d 3:%3d "
            "[calibration] "
            "tx0 gain:%3u phase:%3u tx1 gain:%3u phase:%3u\n",
            rf_val.channel, rf_val.default_power1, rf_val.default_power2, rf_val.default_power3,
            cal.gain_cal_tx0, cal.phase_cal_tx0, cal.gain_cal_tx1, cal.phase_cal_tx1);
#endif  // RALINK_DUMP_TXPOWER
    }

    if (rt_type_ == RT5390 || rt_type_ == RT5592) {
        status = ReadEepromField(EEPROM_CHIP_ID, &rf_type_);
        if (status != ZX_OK) {
            errorf("could not read chip id err=%d\n", status);
            return status;
        }
        infof("RF chipset %#x\n", rf_type_);
    } else {
        // TODO(tkilbourn): support other RF chipsets
        errorf("RF chipset %#x not supported!\n", rf_type_);
        return ZX_ERR_NOT_SUPPORTED;
    }

    // TODO(tkilbourn): default antenna configs

    EepromFreq ef;
    ReadEepromField(&ef);
    debugf("freq offset=%#x\n", ef.offset());

    EepromEirpMaxTxPower eemtp;
    ReadEepromField(&eemtp);
    if (eemtp.power_2g() < kEirpMaxPower) {
        warnf("has EIRP tx power limit\n");
        warnf("TODO: limit tx power (bug NET-86)\n");
    }

    // rfkill switch
    GpioCtrl gc;
    status = ReadRegister(&gc);
    CHECK_READ(GPIO_CTRL, status);
    gc.set_gpio2_dir(1);
    status = WriteRegister(gc);
    CHECK_WRITE(GPIO_CTRL, status);

    // Add the device. The radios are not active yet though; we wait until the wlanmac start method
    // is called.
    status = AddPhyDevice();
    if (status != ZX_OK) {
        errorf("could not add device err=%d\n", status);
    } else {
        infof("device added\n");
    }

    // TODO(tkilbourn): if status != ZX_OK, reset the hw
    return status;
}

zx_status_t Device::ReadRegister(uint16_t offset, uint32_t* value) {
    auto ret = usb_control_in(&usb_, (USB_DIR_IN | USB_TYPE_VENDOR), kMultiRead, 0, offset,
                              ZX_TIME_INFINITE, value, sizeof(*value), nullptr);
    return ret;
}

template <uint16_t A> zx_status_t Device::ReadRegister(Register<A>* reg) {
    return ReadRegister(A, reg->mut_val());
}

zx_status_t Device::WriteRegister(uint16_t offset, uint32_t value) {
    auto ret = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kMultiWrite, 0, offset,
                               ZX_TIME_INFINITE, &value, sizeof(value));
    return ret;
}

template <uint16_t A> zx_status_t Device::WriteRegister(const Register<A>& reg) {
    return WriteRegister(A, reg.val());
}

zx_status_t Device::ReadEeprom() {
    debugfn();
    // Read 4 entries at a time
    static_assert((kEepromSize % 8) == 0, "EEPROM size must be a multiple of 8.");
    for (unsigned int i = 0; i < eeprom_.size(); i += 8) {
        EfuseCtrl ec;
        zx_status_t status = ReadRegister(&ec);
        CHECK_READ(EFUSE_CTRL, status);

        // Set the address and tell it to load the next four words. Addresses
        // must be 16-byte aligned.
        ec.set_efsrom_ain(i << 1);
        ec.set_efsrom_mode(0);
        ec.set_efsrom_kick(1);
        status = WriteRegister(ec);
        CHECK_WRITE(EFUSE_CTRL, status);

        // Wait until the registers are ready for reading.
        status = BusyWait(&ec, [&ec]() { return !ec.efsrom_kick(); });
        if (status != ZX_OK) {
            if (status == ZX_ERR_TIMED_OUT) { errorf("ralink busy wait for EFUSE_CTRL failed\n"); }
            return status;
        }

        // Read the registers into the eeprom. EEPROM is read in descending
        // order, and are always return in host order but to be interpreted as
        // little endian.
        RfuseData0 rd0;
        status = ReadRegister(&rd0);
        CHECK_READ(EFUSE_DATA0, status);
        eeprom_[i] = htole32(rd0.val()) & 0xffff;
        eeprom_[i + 1] = htole32(rd0.val()) >> 16;

        RfuseData1 rd1;
        status = ReadRegister(&rd1);
        CHECK_READ(EFUSE_DATA1, status);
        eeprom_[i + 2] = htole32(rd1.val()) & 0xffff;
        eeprom_[i + 3] = htole32(rd1.val()) >> 16;

        RfuseData2 rd2;
        status = ReadRegister(&rd2);
        CHECK_READ(EFUSE_DATA2, status);
        eeprom_[i + 4] = htole32(rd2.val()) & 0xffff;
        eeprom_[i + 5] = htole32(rd2.val()) >> 16;

        RfuseData3 rd3;
        status = ReadRegister(&rd3);
        CHECK_READ(EFUSE_DATA3, status);
        eeprom_[i + 6] = htole32(rd3.val()) & 0xffff;
        eeprom_[i + 7] = htole32(rd3.val()) >> 16;
    }

#if RALINK_DUMP_EEPROM
    std::printf("ralink: eeprom dump");
    for (size_t i = 0; i < eeprom_.size(); i++) {
        if (i % 8 == 0) { std::printf("\n0x%04zx: ", i); }
        std::printf("%04x ", eeprom_[i]);
    }
    std::printf("\n");
#endif

    return ZX_OK;
}

zx_status_t Device::ReadEepromField(uint16_t addr, uint16_t* value) {
    if (addr >= eeprom_.size()) { return ZX_ERR_INVALID_ARGS; }
    *value = letoh16(eeprom_[addr]);
    return ZX_OK;
}

zx_status_t Device::ReadEepromByte(uint16_t addr, uint8_t* value) {
    uint16_t word_addr = addr >> 1;
    uint16_t word_val;
    zx_status_t result = ReadEepromField(word_addr, &word_val);
    if (result != ZX_OK) { return result; }
    if (addr & 0x1) {
        *value = (word_val >> 8) & 0xff;
    } else {
        *value = word_val & 0xff;
    }
    return ZX_OK;
}

template <uint16_t A> zx_status_t Device::ReadEepromField(EepromField<A>* field) {
    return ReadEepromField(field->addr(), field->mut_val());
}

template <uint16_t A> zx_status_t Device::WriteEepromField(const EepromField<A>& field) {
    if (field.addr() > kEepromSize) { return ZX_ERR_INVALID_ARGS; }
    eeprom_[field.addr()] = field.val();
    return ZX_OK;
}

zx_status_t Device::ValidateEeprom() {
    debugfn();
    memcpy(mac_addr_, eeprom_.data() + EEPROM_MAC_ADDR_0, sizeof(mac_addr_));
    // TODO(tkilbourn): validate mac address
    infof("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr_[0], mac_addr_[1], mac_addr_[2],
          mac_addr_[3], mac_addr_[4], mac_addr_[5]);

    EepromNicConf0 enc0;
    ReadEepromField(&enc0);
    if (enc0.val() == 0xffff || enc0.val() == 0x2860 || enc0.val() == 0x2872) {
        // These values need some eeprom patching; not supported yet.
        errorf("unsupported value for EEPROM_NIC_CONF0=%#x\n", enc0.val());
        return ZX_ERR_NOT_SUPPORTED;
    }
    tx_path_ = enc0.txpath();
    rx_path_ = enc0.rxpath();

    EepromNicConf1 enc1;
    ReadEepromField(&enc1);
    if (enc1.val() == 0xffff) {
        errorf("unsupported value for EEPROM_NIC_CONF1=%#x\n", enc1.val());
        return ZX_ERR_NOT_SUPPORTED;
    }

    debugf("EEPROM NIC Conf0: val %u rxpath %x txpath %x rf_type %x\n", enc0.val(), enc0.rxpath(),
           enc0.txpath(), enc0.rf_type());
    debugf(
        "EEPROM NIC Conf1: val %u hw_radio %u ext_tx_alc %u ext_lna_2g %u ext_lna_5g %u "
        "cardbus_accel %u bw40m_sb_2g %u bw40m_sb_5g %u wps_pbc %u bw40m_2g %u bw40m_5g %u "
        "broadband_ext_lna %u ant_diversity %u int_tx_alc %u bt_coexist %u dac_test %u\n",
        enc1.val(), enc1.hw_radio(), enc1.external_tx_alc(), enc1.external_lna_2g(),
        enc1.external_lna_5g(), enc1.cardbus_accel(), enc1.bw40m_sb_2g(), enc1.bw40m_sb_5g(),
        enc1.wps_pbc(), enc1.bw40m_2g(), enc1.bw40m_5g(), enc1.broadband_ext_lna(),
        enc1.ant_diversity(), enc1.internal_tx_alc(), enc1.bt_coexist(), enc1.dac_test());

    has_external_lna_2g_ = enc1.external_lna_2g();
    has_external_lna_5g_ = enc1.external_lna_5g();
    antenna_diversity_ = enc1.ant_diversity();

    EepromFreq ef;
    ReadEepromField(&ef);
    if (ef.offset() == 0x00ff) {
        ef.set_offset(0);
        WriteEepromField(ef);
        debugf("Freq: %#x\n", ef.val());
    }
    // TODO(tkilbourn): check/set LED mode

    EepromLna el;
    ReadEepromField(&el);
    auto default_lna_gain = el.a0();

    EepromRssiBg erbg;
    ReadEepromField(&erbg);
    if (abs(erbg.offset0()) > 10) { erbg.set_offset0(0); }
    if (abs(erbg.offset1()) > 10) { erbg.set_offset1(0); }
    bg_rssi_offset_[0] = erbg.offset0();
    bg_rssi_offset_[1] = erbg.offset1();
    WriteEepromField(erbg);

    EepromRssiBg2 erbg2;
    ReadEepromField(&erbg2);
    if (abs(erbg2.offset2()) > 10) { erbg2.set_offset2(0); }
    if (erbg2.lna_a1() == 0x00 || erbg2.lna_a1() == 0xff) { erbg2.set_lna_a1(default_lna_gain); }
    bg_rssi_offset_[2] = erbg2.offset2();
    WriteEepromField(erbg2);

    // TODO(tkilbourn): check and set RSSI for A

    return ZX_OK;
}

zx_status_t Device::LoadFirmware() {
    debugfn();
    zx_handle_t fw_handle;
    size_t fw_size = 0;
    zx_status_t status = load_firmware(zxdev_, kFirmwareFile, &fw_handle, &fw_size);
    if (status != ZX_OK) {
        errorf("failed to load firmware '%s': err=%d\n", kFirmwareFile, status);
        return status;
    }
    if (fw_size < 4) {
        errorf("FW: bad length (%zu)\n", fw_size);
        return ZX_ERR_BAD_STATE;
    }
    infof("opened firmware '%s' (%zd bytes)\n", kFirmwareFile, fw_size);

    zx::vmo fw(fw_handle);
    uint8_t fwversion[2];
    status = fw.read(fwversion, fw_size - 4, 2);
    if (status != ZX_OK) {
        errorf("error reading fw version\n");
        return ZX_ERR_BAD_STATE;
    }
    infof("FW version %u.%u\n", fwversion[0], fwversion[1]);
    // Linux rt2x00 driver has more intricate size checking for different
    // chipsets. We just care that it's 8kB for ralink.
    if (fw_size != 8192) {
        errorf("FW: bad length (%zu)\n", fw_size);
        return ZX_ERR_BAD_STATE;
    }

    // TODO(tkilbourn): check crc, 4kB at a time

    AutoWakeupCfg awc;
    debugf("writing auto wakeup\n");
    status = WriteRegister(awc);
    CHECK_WRITE(AUTO_WAKEUP_CFG, status);
    debugf("auto wakeup written\n");

    // Wait for hardware to stabilize
    status = WaitForMacCsr();
    if (status != ZX_OK) {
        errorf("unstable hardware\n");
        return status;
    }
    debugf("hardware stabilized\n");

    status = DisableWpdma();
    if (status != ZX_OK) { return status; }

    bool autorun = false;
    status = DetectAutoRun(&autorun);
    if (status != ZX_OK) { return status; }
    if (autorun) {
        infof("not loading firmware, NIC is in autorun mode\n");
        return ZX_OK;
    }
    debugf("autorun not enabled\n");

    // Send the firmware to the chip. Start at offset 4096 and send 4096 bytes
    size_t offset = 4096;
    size_t remaining = fw_size - offset;
    uint8_t buf[64];
    uint16_t addr = FW_IMAGE_BASE;

    while (remaining) {
        size_t to_send = std::min(remaining, sizeof(buf));
        status = fw.read(buf, offset, to_send);
        if (status != ZX_OK) {
            errorf("error reading firmware\n");
            return ZX_ERR_BAD_STATE;
        }
        status = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kMultiWrite, 0, addr,
                                 ZX_TIME_INFINITE, buf, to_send);
        if (status != ZX_OK) {
            errorf("failed to send firmware\n");
            return ZX_ERR_BAD_STATE;
        }
        remaining -= to_send;
        offset += to_send;
        addr += to_send;
    }
    debugf("sent firmware\n");

    H2mMailboxCid hmc;
    hmc.set_val(~0);
    status = WriteRegister(hmc);
    CHECK_WRITE(H2M_MAILBOX_CID, status);

    H2mMailboxStatus hms;
    hms.set_val(~0);
    status = WriteRegister(hms);
    CHECK_WRITE(H2M_MAILBOX_STATUS, status);

    // Tell the device to load the firmware
    status = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kDeviceMode, kFirmware, 0,
                             ZX_TIME_INFINITE, nullptr, 0);
    if (status != ZX_OK) {
        errorf("failed to send load firmware command\n");
        return status;
    }
    sleep_for(zx::msec(10));

    H2mMailboxCsr hmcsr;
    status = WriteRegister(hmcsr);
    CHECK_WRITE(H2M_MAILBOX_CSR, status);

    SysCtrl sc;
    status = BusyWait(&sc, [&sc]() { return sc.mcu_ready(); }, zx::msec(1));
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) { errorf("system MCU not ready\n"); }
        return status;
    }

    // Disable WPDMA again
    status = DisableWpdma();
    if (status != ZX_OK) { return status; }

    // Initialize firmware and boot the MCU
    H2mBbpAgent hba;
    status = WriteRegister(hba);
    CHECK_WRITE(H2M_BBP_AGENT, status);

    status = WriteRegister(hmcsr);
    CHECK_WRITE(H2M_MAILBOX_CSR, status);

    H2mIntSrc his;
    status = WriteRegister(his);
    CHECK_WRITE(H2M_INT_SRC, status);

    status = McuCommand(MCU_BOOT_SIGNAL, 0, 0, 0);
    if (status != ZX_OK) {
        errorf("error booting MCU err=%d\n", status);
        return status;
    }
    sleep_for(zx::msec(1));

    return ZX_OK;
}

zx_status_t Device::EnableRadio() {
    debugfn();

    // Wakeup the MCU
    zx_status_t status = McuCommand(MCU_WAKEUP, 0xff, 0, 2);
    if (status != ZX_OK) {
        errorf("error waking MCU err=%d\n", status);
        return status;
    }
    sleep_for(zx::msec(1));

    // Wait for WPDMA to be ready
    WpdmaGloCfg wgc;
    auto wpdma_pred = [&wgc]() { return !wgc.tx_dma_busy() && !wgc.rx_dma_busy(); };
    status = BusyWait(&wgc, wpdma_pred, zx::msec(10));
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) { errorf("WPDMA busy\n"); }
        return status;
    }

    // Set up USB DMA
    UsbDmaCfg udc;
    status = ReadRegister(&udc);
    CHECK_READ(USB_DMA_CFG, status);
    udc.set_phy_wd_en(0);
    udc.set_rx_agg_en(0);
    udc.set_rx_agg_to(128);
    // There appears to be a bug in the Linux driver, where an overflow is
    // setting the rx aggregation limit too low. For now, I'm using the
    // (incorrect) low value that Linux uses, but we should look into increasing
    // this.
    udc.set_rx_agg_limit(45);
    udc.set_udma_rx_en(1);
    udc.set_udma_tx_en(1);
    status = WriteRegister(udc);
    CHECK_WRITE(USB_DMA_CFG, status);

    // Wait for WPDMA again
    status = BusyWait(&wgc, wpdma_pred, zx::msec(10));
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) { errorf("WPDMA busy\n"); }
        return status;
    }

    status = InitRegisters();
    if (status != ZX_OK) {
        errorf("failed to initialize registers\n");
        return status;
    }

    // Wait for MAC status ready
    MacStatusReg msr;
    status =
        BusyWait(&msr, [&msr]() { return !msr.tx_status() && !msr.rx_status(); }, zx::msec(10));
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) { errorf("BBP busy\n"); }
        return status;
    }

    // Initialize firmware
    H2mBbpAgent hba;
    status = WriteRegister(hba);
    CHECK_WRITE(H2M_BBP_AGENT, status);

    H2mMailboxCsr hmc;
    status = WriteRegister(hmc);
    CHECK_WRITE(H2M_MAILBOX_CSR, status);

    H2mIntSrc his;
    status = WriteRegister(his);
    CHECK_WRITE(H2M_INT_SRC, status);

    status = McuCommand(MCU_BOOT_SIGNAL, 0, 0, 0);
    if (status != ZX_OK) {
        errorf("error booting MCU err=%d\n", status);
        return status;
    }
    sleep_for(zx::msec(1));

    status = WaitForBbp();
    if (status != ZX_OK) {
        errorf("error waiting for BBP=%d\n", status);
        return status;
    }

    status = InitBbp();
    if (status != ZX_OK) {
        errorf("error initializing BBP=%d\n", status);
        return status;
    }

    status = InitRfcsr();
    if (status != ZX_OK) {
        errorf("error initializing RF=%d\n", status);
        return status;
    }

    // enable rx
    MacSysCtrl msc;
    status = ReadRegister(&msc);
    CHECK_READ(MAC_SYS_CTRL, status);
    msc.set_mac_tx_en(1);
    msc.set_mac_rx_en(0);
    status = WriteRegister(msc);
    CHECK_WRITE(MAC_SYS_CTRL, status);

    sleep_for(zx::usec(50));

    status = ReadRegister(&wgc);
    CHECK_READ(WPDMA_GLO_CFG, status);
    wgc.set_tx_dma_en(1);
    wgc.set_rx_dma_en(1);
    wgc.set_wpdma_bt_size(2);
    wgc.set_tx_wb_ddone(1);
    status = WriteRegister(wgc);
    CHECK_WRITE(WPDMA_GLO_CFG, status);

    status = ReadRegister(&msc);
    CHECK_READ(MAC_SYS_CTRL, status);
    msc.set_mac_tx_en(1);
    msc.set_mac_rx_en(1);
    status = WriteRegister(msc);
    CHECK_WRITE(MAC_SYS_CTRL, status);

    // TODO(tkilbourn): LED control stuff

    return ZX_OK;
}

zx_status_t Device::InitRegisters() {
    debugfn();

    zx_status_t status = DisableWpdma();
    if (status != ZX_OK) { return status; }

    status = WaitForMacCsr();
    if (status != ZX_OK) {
        errorf("hardware unstable\n");
        return status;
    }

    SysCtrl sc;
    status = ReadRegister(&sc);
    CHECK_READ(SYS_CTRL, status);
    sc.set_pme_oen(0);
    status = WriteRegister(sc);
    CHECK_WRITE(SYS_CTRL, status);

    MacSysCtrl msc;
    msc.set_mac_srst(1);
    msc.set_bbp_hrst(1);
    status = WriteRegister(msc);
    CHECK_WRITE(MAC_SYS_CTRL, status);

    UsbDmaCfg udc;
    status = WriteRegister(udc);
    CHECK_WRITE(USB_DMA_CFG, status);

    status = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kDeviceMode, kReset, 0,
                             ZX_TIME_INFINITE, nullptr, 0);
    if (status != ZX_OK) {
        errorf("failed reset\n");
        return status;
    }

    msc.clear();
    status = WriteRegister(msc);
    CHECK_WRITE(MAC_SYS_CTRL, status);

    LegacyBasicRate lbr;
    lbr.set_rate_1mbps(1);
    lbr.set_rate_2mbps(1);
    lbr.set_rate_5_5mbps(1);
    lbr.set_rate_11mbps(1);
    lbr.set_rate_6mbps(1);
    lbr.set_rate_9mbps(1);
    lbr.set_rate_24mbps(1);
    status = WriteRegister(lbr);
    CHECK_WRITE(LEGACY_BASIC_RATE, status);

    HtBasicRate hbr;
    hbr.set_val(0x8003);
    status = WriteRegister(hbr);
    CHECK_WRITE(HT_BASIC_RATE, status);

    msc.clear();
    status = WriteRegister(msc);
    CHECK_WRITE(MAC_SYS_CTRL, status);

    BcnTimeCfg btc;
    status = ReadRegister(&btc);
    CHECK_READ(BCN_TIME_CFG, status);
    btc.set_bcn_intval(1600);
    btc.set_tsf_timer_en(0);
    btc.set_tsf_sync_mode(0);
    btc.set_tbtt_timer_en(0);
    btc.set_bcn_tx_en(0);
    btc.set_tsf_ins_comp(0);
    status = WriteRegister(btc);
    CHECK_WRITE(BCN_TIME_CFG, status);

    status = SetRxFilter();
    if (status != ZX_OK) { return status; }

    BkoffSlotCfg bsc;
    status = ReadRegister(&bsc);
    CHECK_READ(BKOFF_SLOT_CFG, status);
    bsc.set_slot_time(9);
    bsc.set_cc_delay_time(2);
    status = WriteRegister(bsc);
    CHECK_WRITE(BKOFF_SLOT_CFG, status);

    TxSwCfg0 tswc0;
    // TX_SW_CFG register values come from Linux kernel driver
    tswc0.set_dly_txpe_en(0x04);
    tswc0.set_dly_pape_en(0x04);
    // All other TX_SW_CFG0 values are 0 (set by using 0 as starting value)
    status = WriteRegister(tswc0);
    CHECK_WRITE(TX_SW_CFG0, status);

    TxSwCfg1 tswc1;
    if (rt_type_ == RT5390) {
        tswc1.set_dly_pape_dis(0x06);
        tswc1.set_dly_trsw_dis(0x06);
        tswc1.set_dly_rftr_dis(0x08);
    }  // else value will be set to zero
    status = WriteRegister(tswc1);
    CHECK_WRITE(TX_SW_CFG1, status);

    TxSwCfg2 tswc2;
    // All bits set to zero.
    status = WriteRegister(tswc2);
    CHECK_WRITE(TX_SW_CFG2, status);

    TxLinkCfg tlc;
    status = ReadRegister(&tlc);
    CHECK_READ(TX_LINK_CFG, status);
    tlc.set_remote_mfb_lifetime(32);
    tlc.set_tx_mfb_en(0);
    tlc.set_remote_umfs_en(0);
    tlc.set_tx_mrq_en(0);
    tlc.set_tx_rdg_en(0);
    tlc.set_tx_cfack_en(1);
    tlc.set_remote_mfb(0);
    tlc.set_remote_mfs(0);
    status = WriteRegister(tlc);
    CHECK_WRITE(TX_LINK_CFG, status);

    TxTimeoutCfg ttc;
    status = ReadRegister(&ttc);
    CHECK_READ(TX_TIMEOUT_CFG, status);
    ttc.set_mpdu_life_time(9);
    ttc.set_rx_ack_timeout(32);
    ttc.set_txop_timeout(10);
    status = WriteRegister(ttc);
    CHECK_WRITE(TX_TIMEOUT_CFG, status);

    MaxLenCfg mlc;
    status = ReadRegister(&mlc);
    CHECK_READ(MAX_LEN_CFG, status);
    mlc.set_max_mpdu_len(3840);
    mlc.set_max_psdu_len(3);
    mlc.set_min_psdu_len(10);
    mlc.set_min_mpdu_len(10);
    status = WriteRegister(mlc);
    CHECK_WRITE(MAX_LEN_CFG, status);

    LedCfg lc;
    status = ReadRegister(&lc);
    CHECK_READ(LED_CFG, status);
    lc.set_led_on_time(70);
    lc.set_led_off_time(30);
    lc.set_slow_blk_time(3);
    lc.set_r_led_mode(3);
    lc.set_g_led_mode(3);
    lc.set_y_led_mode(3);
    lc.set_led_pol(1);
    status = WriteRegister(lc);
    CHECK_WRITE(LED_CFG, status);

    MaxPcnt mp;
    mp.set_max_rx0q_pcnt(0x9f);
    mp.set_max_tx2q_pcnt(0xbf);
    mp.set_max_tx1q_pcnt(0x3f);
    mp.set_max_tx0q_pcnt(0x1f);
    status = WriteRegister(mp);
    CHECK_WRITE(MAX_PCNT, status);

    TxRtyCfg trc;
    status = ReadRegister(&trc);
    CHECK_READ(TX_RTY_CFG, status);
    trc.set_short_rty_limit(2);
    trc.set_long_rty_limit(2);
    trc.set_long_rty_thres(2000);
    trc.set_nag_rty_mode(0);
    trc.set_agg_rty_mode(0);
    trc.set_tx_autofb_en(1);
    status = WriteRegister(trc);
    CHECK_WRITE(TX_RTY_CFG, status);

    AutoRspCfg arc;
    status = ReadRegister(&arc);
    CHECK_READ(AUTO_RSP_CFG, status);
    arc.set_auto_rsp_en(1);
    arc.set_bac_ackpolicy_en(1);
    arc.set_cts_40m_mode(1);
    arc.set_cts_40m_ref(0);
    arc.set_cck_short_en(0);
    arc.set_ctrl_wrap_en(0);
    arc.set_bac_ack_policy(0);
    arc.set_ctrl_pwr_bit(0);
    status = WriteRegister(arc);
    CHECK_WRITE(AUTO_RSP_CFG, status);

    CckProtCfg cpc;
    status = ReadRegister(&cpc);
    CHECK_READ(CCK_PROT_CFG, status);
    cpc.set_prot_rate(3);
    cpc.set_prot_ctrl(0);
    cpc.set_prot_nav(1);
    cpc.set_txop_allow_cck_tx(1);
    cpc.set_txop_allow_ofdm_tx(1);
    cpc.set_txop_allow_mm20_tx(1);
    cpc.set_txop_allow_mm40_tx(0);
    cpc.set_txop_allow_gf20_tx(1);
    cpc.set_txop_allow_gf40_tx(0);
    cpc.set_rtsth_en(1);
    status = WriteRegister(cpc);
    CHECK_WRITE(CCK_PROT_CFG, status);

    OfdmProtCfg opc;
    status = ReadRegister(&opc);
    CHECK_READ(OFDM_PROT_CFG, status);
    opc.set_prot_rate(3);
    opc.set_prot_ctrl(0);
    opc.set_prot_nav(1);
    opc.set_txop_allow_cck_tx(1);
    opc.set_txop_allow_ofdm_tx(1);
    opc.set_txop_allow_mm20_tx(1);
    opc.set_txop_allow_mm40_tx(0);
    opc.set_txop_allow_gf20_tx(1);
    opc.set_txop_allow_gf40_tx(0);
    opc.set_rtsth_en(1);
    status = WriteRegister(opc);
    CHECK_WRITE(OFDM_PROT_CFG, status);

    Mm20ProtCfg mm20pc;
    status = ReadRegister(&mm20pc);
    CHECK_READ(MM20_PROT_CFG, status);
    mm20pc.set_prot_rate(0x4004);
    mm20pc.set_prot_ctrl(1);
    mm20pc.set_prot_nav(1);
    mm20pc.set_txop_allow_cck_tx(0);
    mm20pc.set_txop_allow_ofdm_tx(1);
    mm20pc.set_txop_allow_mm20_tx(1);
    mm20pc.set_txop_allow_mm40_tx(0);
    mm20pc.set_txop_allow_gf20_tx(1);
    mm20pc.set_txop_allow_gf40_tx(0);
    mm20pc.set_rtsth_en(0);
    status = WriteRegister(mm20pc);
    CHECK_WRITE(MM20_PROT_CFG, status);

    Mm40ProtCfg mm40pc;
    status = ReadRegister(&mm40pc);
    CHECK_READ(MM40_PROT_CFG, status);
    mm40pc.set_prot_rate(0x4084);
    mm40pc.set_prot_ctrl(1);
    mm40pc.set_prot_nav(1);
    mm40pc.set_txop_allow_cck_tx(0);
    mm40pc.set_txop_allow_ofdm_tx(1);
    mm40pc.set_txop_allow_mm20_tx(1);
    mm40pc.set_txop_allow_mm40_tx(1);
    mm40pc.set_txop_allow_gf20_tx(1);
    mm40pc.set_txop_allow_gf40_tx(1);
    mm40pc.set_rtsth_en(0);
    status = WriteRegister(mm40pc);
    CHECK_WRITE(MM40_PROT_CFG, status);

    Gf20ProtCfg gf20pc;
    status = ReadRegister(&gf20pc);
    CHECK_READ(GF20_PROT_CFG, status);
    gf20pc.set_prot_rate(0x4004);
    gf20pc.set_prot_ctrl(1);
    gf20pc.set_prot_nav(1);
    gf20pc.set_txop_allow_cck_tx(0);
    gf20pc.set_txop_allow_ofdm_tx(1);
    gf20pc.set_txop_allow_mm20_tx(1);
    gf20pc.set_txop_allow_mm40_tx(0);
    gf20pc.set_txop_allow_gf20_tx(1);
    gf20pc.set_txop_allow_gf40_tx(0);
    gf20pc.set_rtsth_en(0);
    status = WriteRegister(gf20pc);
    CHECK_WRITE(GF20_PROT_CFG, status);

    Gf40ProtCfg gf40pc;
    status = ReadRegister(&gf40pc);
    CHECK_READ(GF40_PROT_CFG, status);
    gf40pc.set_prot_rate(0x4084);
    gf40pc.set_prot_ctrl(1);
    gf40pc.set_prot_nav(1);
    gf40pc.set_txop_allow_cck_tx(0);
    gf40pc.set_txop_allow_ofdm_tx(1);
    gf40pc.set_txop_allow_mm20_tx(1);
    gf40pc.set_txop_allow_mm40_tx(1);
    gf40pc.set_txop_allow_gf20_tx(1);
    gf40pc.set_txop_allow_gf40_tx(1);
    gf40pc.set_rtsth_en(0);
    status = WriteRegister(gf40pc);
    CHECK_WRITE(GF40_PROT_CFG, status);

    PbfCfg pc;
    pc.set_rx0q_en(1);
    pc.set_tx2q_en(1);
    pc.set_tx2q_num(20);
    pc.set_tx1q_num(7);
    status = WriteRegister(pc);
    CHECK_WRITE(PBF_CFG, status);

    WpdmaGloCfg wgc;
    status = ReadRegister(&wgc);
    CHECK_READ(WPDMA_GLO_CFG, status);
    wgc.set_tx_dma_en(0);
    wgc.set_tx_dma_busy(0);
    wgc.set_rx_dma_en(0);
    wgc.set_rx_dma_busy(0);
    wgc.set_wpdma_bt_size(3);
    wgc.set_tx_wb_ddone(0);
    wgc.set_big_endian(0);
    wgc.set_hdr_seg_len(0);
    status = WriteRegister(wgc);
    CHECK_WRITE(WPDMA_GLO_CFG, status);

    TxopCtrlCfg tcc;
    status = ReadRegister(&tcc);
    CHECK_READ(TXOP_CTRL_CFG, status);
    tcc.set_txop_trun_en(0x3f);
    tcc.set_lsig_txop_en(0);
    tcc.set_ext_cca_en(0);
    tcc.set_ext_cca_dly(88);
    tcc.set_ext_cw_min(0);
    status = WriteRegister(tcc);
    CHECK_WRITE(TXOP_CTRL_CFG, status);

    TxopHldrEt the;
    the.set_tx40m_blk_en(1);
    if (rt_type_ == RT5592) { the.set_reserved_unk(4); }
    status = WriteRegister(the);
    CHECK_WRITE(TXOP_HLDR_ET, status);

    TxRtsCfg txrtscfg;
    status = ReadRegister(&txrtscfg);
    CHECK_READ(TX_RTS_CFG, status);
    txrtscfg.set_rts_rty_limit(7);
    txrtscfg.set_rts_thres(2353);  // IEEE80211_MAX_RTS_THRESHOLD in Linux
    txrtscfg.set_rts_fbk_en(1);
    status = WriteRegister(txrtscfg);
    CHECK_WRITE(TX_RTS_CFG, status);

    ExpAckTime eat;
    eat.set_exp_cck_ack_time(0x00ca);
    eat.set_exp_ofdm_ack_time(0x0024);
    status = WriteRegister(eat);
    CHECK_WRITE(EXP_ACK_TIME, status);

    XifsTimeCfg xtc;
    status = ReadRegister(&xtc);
    CHECK_READ(XIFS_TIME_CFG, status);
    xtc.set_cck_sifs_time(16);
    xtc.set_ofdm_sifs_time(16);
    xtc.set_ofdm_xifs_time(4);
    xtc.set_eifs_time(314);
    xtc.set_bb_rxend_en(1);
    status = WriteRegister(xtc);
    CHECK_WRITE(XIFS_TIME_CFG, status);

    PwrPinCfg ppc;
    ppc.set_io_rf_pe(1);
    ppc.set_io_ra_pe(1);
    status = WriteRegister(ppc);
    CHECK_WRITE(PWR_PIN_CFG, status);

    // TODO(porce): Factor out encryption key clearing
    for (int i = 0; i < 4; i++) {
        status = WriteRegister(SHARED_KEY_MODE_BASE + i * sizeof(uint32_t), 0);
        CHECK_WRITE(SHARED_KEY_MODE, status);
    }

    RxWcidEntry rwe;
    memset(&rwe.mac, 0xff, sizeof(rwe.mac));
    memset(&rwe.ba_sess_mask, 0xff, sizeof(rwe.ba_sess_mask));
    for (int i = 0; i < 256; i++) {
        uint16_t addr = RX_WCID_BASE + i * sizeof(rwe);
        status = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kMultiWrite, 0, addr,
                                 ZX_TIME_INFINITE, &rwe, sizeof(rwe));
        if (status != ZX_OK) {
            errorf("failed to set RX WCID search entry\n");
            return ZX_ERR_BAD_STATE;
        }

        status = WriteRegister(WCID_ATTR_BASE + i * sizeof(uint32_t), 0);
        CHECK_WRITE(WCID_ATTR, status);

        status = WriteRegister(IV_EIV_BASE + i * 8, 0);
        CHECK_WRITE(IV_EIV, status);
    }

    // TODO(tkilbourn): Clear beacons ?????? (probably not needed as long as we are only STA)

    UsCycCnt ucc;
    status = ReadRegister(&ucc);
    CHECK_READ(US_CYC_CNT, status);
    ucc.set_us_cyc_count(30);
    status = WriteRegister(ucc);
    CHECK_WRITE(US_CYC_CNT, status);

    HtFbkCfg0 hfc0;
    status = ReadRegister(&hfc0);
    CHECK_READ(HT_FBK_CFG0, status);
    hfc0.set_ht_mcs0_fbk(0);
    hfc0.set_ht_mcs1_fbk(0);
    hfc0.set_ht_mcs2_fbk(1);
    hfc0.set_ht_mcs3_fbk(2);
    hfc0.set_ht_mcs4_fbk(3);
    hfc0.set_ht_mcs5_fbk(4);
    hfc0.set_ht_mcs6_fbk(5);
    hfc0.set_ht_mcs7_fbk(6);
    status = WriteRegister(hfc0);
    CHECK_WRITE(HT_FBK_CFG0, status);

    HtFbkCfg1 hfc1;
    status = ReadRegister(&hfc1);
    CHECK_READ(HT_FBK_CFG1, status);
    hfc1.set_ht_mcs8_fbk(8);
    hfc1.set_ht_mcs9_fbk(8);
    hfc1.set_ht_mcs10_fbk(9);
    hfc1.set_ht_mcs11_fbk(10);
    hfc1.set_ht_mcs12_fbk(11);
    hfc1.set_ht_mcs13_fbk(12);
    hfc1.set_ht_mcs14_fbk(13);
    hfc1.set_ht_mcs15_fbk(14);
    status = WriteRegister(hfc1);
    CHECK_WRITE(HT_FBK_CFG1, status);

    LgFbkCfg0 lfc0;
    status = ReadRegister(&lfc0);
    CHECK_READ(LG_FBK_CFG0, status);
    lfc0.set_ofdm0_fbk(8);
    lfc0.set_ofdm1_fbk(8);
    lfc0.set_ofdm2_fbk(9);
    lfc0.set_ofdm3_fbk(10);
    lfc0.set_ofdm4_fbk(11);
    lfc0.set_ofdm5_fbk(12);
    lfc0.set_ofdm6_fbk(13);
    lfc0.set_ofdm7_fbk(14);
    status = WriteRegister(lfc0);
    CHECK_WRITE(LG_FBK_CFG0, status);

    LgFbkCfg1 lfc1;
    status = ReadRegister(&lfc1);
    CHECK_READ(LG_FBK_CFG1, status);
    lfc1.set_cck0_fbk(0);
    lfc1.set_cck1_fbk(0);
    lfc1.set_cck2_fbk(1);
    lfc1.set_cck3_fbk(2);
    status = WriteRegister(lfc1);
    CHECK_WRITE(LG_FBK_CFG1, status);

    // Linux does not force BA window sizes.
    ForceBaWinsize fbw;
    status = ReadRegister(&fbw);
    CHECK_READ(FORCE_BA_WINSIZE, status);
    fbw.set_force_ba_winsize(0);
    fbw.set_force_ba_winsize_en(0);
    status = WriteRegister(fbw);
    CHECK_WRITE(FORCE_BA_WINSIZE, status);

    // Reading the stats counters will clear them. We don't need to look at the
    // values.
    RxStaCnt0 rsc0;
    ReadRegister(&rsc0);
    RxStaCnt1 rsc1;
    ReadRegister(&rsc1);
    RxStaCnt2 rsc2;
    ReadRegister(&rsc2);
    TxStaCnt0 tsc0;
    ReadRegister(&tsc0);
    TxStaCnt1 tsc1;
    ReadRegister(&tsc1);
    TxStaCnt2 tsc2;
    ReadRegister(&tsc2);

    IntTimerCfg itc;
    status = ReadRegister(&itc);
    CHECK_READ(INT_TIMER_CFG, status);
    itc.set_pre_tbtt_timer(6 << 4);  // 6.144 msec
    status = WriteRegister(itc);
    CHECK_WRITE(INT_TIMER_CFG, status);

    ChTimeCfg ctc;
    status = ReadRegister(&ctc);
    CHECK_READ(CH_TIME_CFG, status);
    ctc.set_ch_sta_timer_en(1);
    ctc.set_tx_as_ch_busy(1);
    ctc.set_rx_as_ch_busy(1);
    ctc.set_nav_as_ch_busy(1);
    ctc.set_eifs_as_ch_busy(1);
    status = WriteRegister(ctc);
    CHECK_WRITE(CH_TIME_CFG, status);

    return ZX_OK;
}

zx_status_t Device::InitBbp() {
    debugfn();

    switch (rt_type_) {
    case RT5390:
        return InitBbp5390();
    case RT5592:
        return InitBbp5592();
    default:
        errorf("Invalid device type in InitBbp\n");
        return ZX_ERR_NOT_FOUND;
    }
}

zx_status_t Device::InitBbp5390() {
    debugfn();

    Bbp4 reg;
    zx_status_t status = ReadBbp(&reg);
    CHECK_READ(BBP4, status);
    reg.set_mac_if_ctrl(1);
    status = WriteBbp(reg);
    CHECK_WRITE(BBP4, status);

    std::vector<RegInitValue> reg_init_values{
        // clang-format off
        RegInitValue(31,  0x08),
        RegInitValue(65,  0x2c),
        RegInitValue(66,  0x38),
        RegInitValue(68,  0x0b),
        RegInitValue(69,  0x12),
        RegInitValue(73,  0x13),
        RegInitValue(75,  0x46),
        RegInitValue(76,  0x28),
        RegInitValue(77,  0x59),
        RegInitValue(70,  0x0a),
        RegInitValue(79,  0x13),
        RegInitValue(80,  0x05),
        RegInitValue(81,  0x33),
        RegInitValue(82,  0x62),
        RegInitValue(83,  0x7a),
        RegInitValue(84,  0x9a),
        RegInitValue(86,  0x38),
        RegInitValue(91,  0x04),
        RegInitValue(92,  0x02),
        RegInitValue(103, 0xc0),
        RegInitValue(104, 0x92),
        RegInitValue(105, 0x3c),
        RegInitValue(106, 0x03),
        RegInitValue(128, 0x12),
// clang-format off
    };
    status = WriteBbpGroup(reg_init_values);
    if (status != ZX_OK) {
        return status;
    }

    // disable unused dac/adc
    Bbp138 bbp138;
    status = ReadBbp(&bbp138);
    CHECK_READ(BBP138, status);
    if (tx_path_ == 1) {
        bbp138.set_tx_dac1(1);
    }
    if (rx_path_ == 1) {
        bbp138.set_rx_adc1(0);
    }
    status = WriteBbp(bbp138);
    CHECK_WRITE(BBP138, status);

    // TODO(tkilbourn): check for bt coexist (don't need this yet)

    // Use hardware antenna diversity for these chips
    if (rt_rev_ >= REV_RT5390R) {
        status = WriteBbp(BbpRegister<150>(0x00));
        CHECK_WRITE(BBP150, status);
        status = WriteBbp(BbpRegister<151>(0x00));
        CHECK_WRITE(BBP151, status);
        status = WriteBbp(BbpRegister<154>(0x00));
        CHECK_WRITE(BBP154, status);
    }

    Bbp152 bbp152;
    status = ReadBbp(&bbp152);
    CHECK_READ(BBP152, status);
    bbp152.set_rx_default_ant(antenna_diversity_ == 3 ? 0 : 1);
    status = WriteBbp(bbp152);
    CHECK_WRITE(BBP152, status);

    // frequency calibration
    status = WriteBbp(BbpRegister<142>(0x01));
    CHECK_WRITE(BBP142, status);
    status = WriteBbp(BbpRegister<143>(0x39));
    CHECK_WRITE(BBP143, status);

    for (size_t index = 0; index < EEPROM_BBP_SIZE; index++) {
        uint16_t val;
        status = ReadEepromField(EEPROM_BBP_START + index, &val);
        CHECK_READ(EEPROM_BBP, status);
        if (val != 0xffff && val != 0x0000) {
            status = WriteBbp(val >> 8, val & 0xff);
            if (status != ZX_OK) {
                errorf("WriteRegister error for BBP reg %u: %d\n", val >> 8, status);
                return status;
            }
        }
    }
    return ZX_OK;
}

zx_status_t Device::InitBbp5592() {
    // Initialize first group of BBP registers
    std::vector<RegInitValue> reg_init_values {
// clang-format off
        RegInitValue(65, 0x2c),
        RegInitValue(66, 0x38),
        RegInitValue(68, 0x0b),
        RegInitValue(69, 0x12),
        RegInitValue(70, 0x0a),
        RegInitValue(73, 0x10),
        RegInitValue(81, 0x37),
        RegInitValue(82, 0x62),
        RegInitValue(83, 0x6a),
        RegInitValue(84, 0x99),
        RegInitValue(86, 0x00),
        RegInitValue(91, 0x04),
        RegInitValue(92, 0x00),
        RegInitValue(103, 0x00),
        RegInitValue(105, 0x05),
        RegInitValue(106, 0x35),
        // clang-format on
    };
    zx_status_t status = WriteBbpGroup(reg_init_values);
    if (status != ZX_OK) { return status; }

    // Set MLD (Maximum Likelihood Detection) in BBP location 105
    Bbp105 bbp105;
    status = ReadBbp(&bbp105);
    CHECK_READ(BBP105, status);
    bbp105.set_mld(rx_path_ == 2 ? 1 : 0);
    status = WriteBbp(bbp105);
    CHECK_WRITE(BBP105, status);

    // Set MAC_IF_CTRL in BBP location 4
    Bbp4 bbp4;
    status = ReadBbp(&bbp4);
    CHECK_READ(BBP4, status);
    bbp4.set_mac_if_ctrl(1);
    status = WriteBbp(bbp4);
    CHECK_WRITE(BBP4, status);

    // Initialize second group of BBP registers
    std::vector<RegInitValue> reg_init_values2{
        // clang-format off
        RegInitValue(20,  0x06),
        RegInitValue(31,  0x08),
        RegInitValue(65,  0x2c),
        RegInitValue(68,  0xdd),
        RegInitValue(69,  0x1a),
        RegInitValue(70,  0x05),
        RegInitValue(73,  0x13),
        RegInitValue(74,  0x0f),
        RegInitValue(75,  0x4f),
        RegInitValue(76,  0x28),
        RegInitValue(77,  0x59),
        RegInitValue(84,  0x9a),
        RegInitValue(86,  0x38),
        RegInitValue(88,  0x90),
        RegInitValue(91,  0x04),
        RegInitValue(92,  0x02),
        RegInitValue(95,  0x9a),
        RegInitValue(98,  0x12),
        RegInitValue(103, 0xc0),
        RegInitValue(104, 0x92),
        RegInitValue(105, 0x3c),
        RegInitValue(106, 0x35),
        RegInitValue(128, 0x12),
        RegInitValue(134, 0xd0),
        RegInitValue(135, 0xf6),
        RegInitValue(137, 0x0f),
        // clang-format on
    };
    status = WriteBbpGroup(reg_init_values2);
    if (status != ZX_OK) { return status; }

    // Set GLRT values (Generalized likelihood ratio tests?)
    // clang-format off
    uint8_t glrt_values[] = { 0xe0, 0x1f, 0x38, 0x32, 0x08, 0x28, 0x19, 0x0a,
                              0xff, 0x00, 0x16, 0x10, 0x10, 0x0b, 0x36, 0x2c,
                              0x26, 0x24, 0x42, 0x36, 0x30, 0x2d, 0x4c, 0x46,
                              0x3d, 0x40, 0x3e, 0x42, 0x3d, 0x40, 0x3c, 0x34,
                              0x2c, 0x2f, 0x3c, 0x35, 0x2e, 0x2a, 0x49, 0x41,
                              0x36, 0x31, 0x30, 0x30, 0x0e, 0x0d, 0x28, 0x21,
                              0x1c, 0x16, 0x50, 0x4a, 0x43, 0x40, 0x10, 0x10,
                              0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              0x7d, 0x14, 0x32, 0x2c, 0x36, 0x4c, 0x43, 0x2c,
                              0x2e, 0x36, 0x30, 0x6e };
    // clang-format on
    status = WriteGlrtBlock(glrt_values, sizeof(glrt_values), 0x80);
    if (status != ZX_OK) { return status; }

    // Set MAC_IF_CTRL in BBP location 4
    status = ReadBbp(&bbp4);
    CHECK_READ(BBP4, status);
    bbp4.set_mac_if_ctrl(1);
    status = WriteBbp(bbp4);
    CHECK_WRITE(BBP4, status);

    // Set default rx antenna in BBP location 152
    Bbp152 bbp152;
    status = ReadBbp(&bbp152);
    CHECK_READ(BBP152, status);
    bbp152.set_rx_default_ant(antenna_diversity_ == 3 ? 0 : 1);
    status = WriteBbp(bbp152);
    CHECK_WRITE(BBP152, status);

    // Set bit 7 in BBP location 254 (as per Linux)
    if (rt_rev_ >= REV_RT5592C) {
        Bbp254 bbp254;
        status = ReadBbp(&bbp254);
        CHECK_READ(BBP254, status);
        bbp254.set_unk_bit7(1);
        status = WriteBbp(bbp254);
        CHECK_WRITE(BBP254, status);
    }

    // Frequency calibration
    status = WriteBbp(BbpRegister<142>(0x01));
    CHECK_WRITE(BBP142, status);
    status = WriteBbp(BbpRegister<143>(0x39));
    CHECK_WRITE(BBP143, status);

    status = WriteBbp(BbpRegister<84>(0x19));
    CHECK_WRITE(BBP84, status);

    if (rt_rev_ >= REV_RT5592C) {
        status = WriteBbp(BbpRegister<103>(0xc0));
        CHECK_WRITE(BBP103, status);
    }

    return ZX_OK;
}

zx_status_t Device::InitRfcsr() {
    debugfn();

    std::vector<RegInitValue> rfcsr_init_table;
    switch (rt_type_) {
    case RT5390:
        if (rt_rev_ >= REV_RT5390F) {
            rfcsr_init_table = {
                // clang-format off
                RegInitValue(1,  0x0f),
                RegInitValue(2,  0x80),
                RegInitValue(3,  0x88),
                RegInitValue(5,  0x10),
                RegInitValue(6,  0xe0),
                RegInitValue(7,  0x00),
                RegInitValue(10, 0x53),
                RegInitValue(11, 0x4a),
                RegInitValue(12, 0x46),
                RegInitValue(13, 0x9f),
                RegInitValue(14, 0x00),
                RegInitValue(15, 0x00),
                RegInitValue(16, 0x00),
                RegInitValue(18, 0x03),
                RegInitValue(19, 0x00),
                RegInitValue(20, 0x00),
                RegInitValue(21, 0x00),
                RegInitValue(22, 0x20),
                RegInitValue(23, 0x00),
                RegInitValue(24, 0x00),
                RegInitValue(25, 0x80),
                RegInitValue(26, 0x00),
                RegInitValue(27, 0x09),
                RegInitValue(28, 0x00),
                RegInitValue(29, 0x10),
                RegInitValue(30, 0x10),
                RegInitValue(31, 0x80),
                RegInitValue(32, 0x80),
                RegInitValue(33, 0x00),
                RegInitValue(34, 0x07),
                RegInitValue(35, 0x12),
                RegInitValue(36, 0x00),
                RegInitValue(37, 0x08),
                RegInitValue(38, 0x85),
                RegInitValue(39, 0x1b),
                RegInitValue(40, 0x0b),
                RegInitValue(41, 0xbb),
                RegInitValue(42, 0xd2),
                RegInitValue(43, 0x9a),
                RegInitValue(44, 0x0e),
                RegInitValue(45, 0xa2),
                RegInitValue(46, 0x73),
                RegInitValue(47, 0x00),
                RegInitValue(48, 0x10),
                RegInitValue(49, 0x94),
                RegInitValue(52, 0x38),
                RegInitValue(53, 0x00),
                RegInitValue(54, 0x78),
                RegInitValue(55, 0x44),
                RegInitValue(56, 0x42),
                RegInitValue(57, 0x80),
                RegInitValue(58, 0x7f),
                RegInitValue(59, 0x8f),
                RegInitValue(60, 0x45),
                RegInitValue(61, 0xd1), // 0xd5 for non-USB
                RegInitValue(62, 0x00),
                RegInitValue(63, 0x00),
                // clang-format on
            };
        } else {
            // RT5390 before rev. F
            rfcsr_init_table = {
                // clang-format off
                RegInitValue(1,  0x0f),
                RegInitValue(2,  0x80),
                RegInitValue(3,  0x88),
                RegInitValue(5,  0x10),
                RegInitValue(6,  0xa0),
                RegInitValue(7,  0x00),
                RegInitValue(10, 0x53),
                RegInitValue(11, 0x4a),
                RegInitValue(12, 0x46),
                RegInitValue(13, 0x9f),
                RegInitValue(14, 0x00),
                RegInitValue(15, 0x00),
                RegInitValue(16, 0x00),
                RegInitValue(18, 0x03),
                RegInitValue(19, 0x00),
                RegInitValue(20, 0x00),
                RegInitValue(21, 0x00),
                RegInitValue(22, 0x20),
                RegInitValue(23, 0x00),
                RegInitValue(24, 0x00),
                RegInitValue(25, 0xc0),
                RegInitValue(26, 0x00),
                RegInitValue(27, 0x09),
                RegInitValue(28, 0x00),
                RegInitValue(29, 0x10),
                RegInitValue(30, 0x10),
                RegInitValue(31, 0x80),
                RegInitValue(32, 0x80),
                RegInitValue(33, 0x00),
                RegInitValue(34, 0x07),
                RegInitValue(35, 0x12),
                RegInitValue(36, 0x00),
                RegInitValue(37, 0x08),
                RegInitValue(38, 0x85),
                RegInitValue(39, 0x1b),
                RegInitValue(40, 0x0b),
                RegInitValue(41, 0xbb),
                RegInitValue(42, 0xd2),
                RegInitValue(43, 0x9a),
                RegInitValue(44, 0x0e),
                RegInitValue(45, 0xa2),
                RegInitValue(46, 0x7b),
                RegInitValue(47, 0x00),
                RegInitValue(48, 0x10),
                RegInitValue(49, 0x94),
                RegInitValue(52, 0x38),
                RegInitValue(53, 0x84),
                RegInitValue(54, 0x78),
                RegInitValue(55, 0x44),
                RegInitValue(56, 0x22),
                RegInitValue(57, 0x80),
                RegInitValue(58, 0x7f),
                RegInitValue(59, 0x8f),
                RegInitValue(60, 0x45),
                RegInitValue(61, 0xdd), // 0xb5 for non-USB
                RegInitValue(62, 0x00),
                RegInitValue(63, 0x00),
                // clang-format on
            };
        }
        break;
    case RT5592:
        rfcsr_init_table = {
            // clang-format off
            RegInitValue(1,  0x3f),
            RegInitValue(3,  0x08),
            RegInitValue(5,  0x10),
            RegInitValue(6,  0xe4),
            RegInitValue(7,  0x00),
            RegInitValue(14, 0x00),
            RegInitValue(15, 0x00),
            RegInitValue(16, 0x00),
            RegInitValue(18, 0x03),
            RegInitValue(19, 0x4d),
            RegInitValue(20, 0x10),
            RegInitValue(21, 0x8d),
            RegInitValue(26, 0x82),
            RegInitValue(28, 0x00),
            RegInitValue(29, 0x10),
            RegInitValue(33, 0xc0),
            RegInitValue(34, 0x07),
            RegInitValue(35, 0x12),
            RegInitValue(47, 0x0c),
            RegInitValue(53, 0x22),
            RegInitValue(63, 0x07),
            RegInitValue(2,  0x80),
            // clang-format on
        };
        break;
    default:
        errorf("Invalid device type in %s\n", __FUNCTION__);
        return ZX_ERR_NOT_FOUND;
    }

    // Init calibration
    Rfcsr2 r2;
    zx_status_t status = ReadRfcsr(&r2);
    CHECK_READ(RF2, status);

    r2.set_rescal_en(1);
    status = WriteRfcsr(r2);
    CHECK_WRITE(RF2, status);

    sleep_for(zx::msec(1));
    r2.set_rescal_en(0);
    status = WriteRfcsr(r2);
    CHECK_WRITE(RF2, status);

    // Configure rfcsr registers
    for (const auto& entry : rfcsr_init_table) {
        status = WriteRfcsr(entry.addr, entry.val);
        if (status != ZX_OK) {
            errorf("WriteRegister error for RFCSR %u: %d\n", entry.addr, status);
            return status;
        }
    }

    if (rt_type_ == RT5592) {
        sleep_for(zx::msec(1));
        AdjustFreqOffset();
        if (rt_rev_ >= REV_RT5592C) {
            status = WriteBbp(BbpRegister<103>(0xc0));
            CHECK_WRITE(BBP103, status);
        }
    }

    status = NormalModeSetup();
    if (status != ZX_OK) { return status; }

    if (rt_type_ == RT5592 && rt_rev_ >= REV_RT5592C) {
        status = WriteBbp(BbpRegister<27>(0x03));
        CHECK_WRITE(BBP27, status);
    }
    // TODO(tkilbourn): led open drain enable ??? (doesn't appear in vendor driver?)

    return ZX_OK;
}

zx_status_t Device::McuCommand(uint8_t command, uint8_t token, uint8_t arg0, uint8_t arg1) {
    debugf("McuCommand %u\n", command);
    H2mMailboxCsr hmc;
    zx_status_t status = BusyWait(&hmc, [&hmc]() { return !hmc.owner(); });
    if (status != ZX_OK) { return status; }

    hmc.set_owner(1);
    hmc.set_cmd_token(token);
    hmc.set_arg0(arg0);
    hmc.set_arg1(arg1);
    status = WriteRegister(hmc);
    CHECK_WRITE(H2M_MAILBOX_CSR, status);

    HostCmd hc;
    hc.set_command(command);
    status = WriteRegister(hc);
    CHECK_WRITE(HOST_CMD, status);
    sleep_for(zx::msec(1));

    return status;
}

zx_status_t Device::ReadBbp(uint8_t addr, uint8_t* val) {
    BbpCsrCfg bcc;
    auto pred = [&bcc]() { return !bcc.bbp_csr_kick(); };

    zx_status_t status = BusyWait(&bcc, pred);
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) { errorf("timed out waiting for BBP\n"); }
        return status;
    }

    bcc.clear();
    bcc.set_bbp_addr(addr);
    bcc.set_bbp_csr_rw(1);
    bcc.set_bbp_csr_kick(1);
    bcc.set_bbp_rw_mode(1);
    status = WriteRegister(bcc);
    CHECK_WRITE(BBP_CSR_CFG, status);

    status = BusyWait(&bcc, pred);
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) {
            errorf("timed out waiting for BBP\n");
            *val = 0xff;
        }
        return status;
    }

    *val = bcc.bbp_data();
    return ZX_OK;
}

template <uint8_t A> zx_status_t Device::ReadBbp(BbpRegister<A>* reg) {
    return ReadBbp(reg->addr(), reg->mut_val());
}

zx_status_t Device::WriteBbp(uint8_t addr, uint8_t val) {
    BbpCsrCfg bcc;
    zx_status_t status = BusyWait(&bcc, [&bcc]() { return !bcc.bbp_csr_kick(); });
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) { errorf("timed out waiting for BBP\n"); }
        return status;
    }

    bcc.clear();
    bcc.set_bbp_data(val);
    bcc.set_bbp_addr(addr);
    bcc.set_bbp_csr_rw(0);
    bcc.set_bbp_csr_kick(1);
    bcc.set_bbp_rw_mode(1);
    status = WriteRegister(bcc);
    CHECK_WRITE(BBP_CSR_CFG, status);
    return status;
}

template <uint8_t A> zx_status_t Device::WriteBbp(const BbpRegister<A>& reg) {
    return WriteBbp(reg.addr(), reg.val());
}

zx_status_t Device::WriteBbpGroup(const std::vector<RegInitValue>& regs) {
    for (auto reg : regs) {
        zx_status_t status = WriteBbp(reg.addr, reg.val);
        if (status != ZX_OK) {
            errorf("WriteRegister error for BBP reg %u: %d\n", reg.addr, status);
            return status;
        }
    }
    return ZX_OK;
}

zx_status_t Device::WaitForBbp() {
    H2mBbpAgent hba;
    zx_status_t status = WriteRegister(hba);
    CHECK_WRITE(H2M_BBP_AGENT, status);

    H2mMailboxCsr hmc;
    status = WriteRegister(hmc);
    CHECK_WRITE(H2M_MAILBOX_CSR, status);
    sleep_for(zx::msec(1));

    uint8_t val;
    for (unsigned int i = 0; i < kMaxBusyReads; i++) {
        status = ReadBbp(0, &val);
        CHECK_READ(BBP0, status);
        if ((val != 0xff) && (val != 0x00)) { return ZX_OK; }
        sleep_for(kDefaultBusyWait);
    }
    errorf("timed out waiting for BBP ready\n");
    return ZX_ERR_TIMED_OUT;
}

zx_status_t Device::WriteGlrt(uint8_t addr, uint8_t val) {
    zx_status_t status;
    status = WriteBbp(195, addr);
    CHECK_WRITE(BBP_GLRT_ADDR, status);
    status = WriteBbp(196, val);
    CHECK_WRITE(BBP_GLRT_VAL, status);
    return ZX_OK;
}

zx_status_t Device::WriteGlrtGroup(const std::vector<RegInitValue>& regs) {
    for (auto reg : regs) {
        zx_status_t status = WriteGlrt(reg.addr, reg.val);
        if (status != ZX_OK) {
            errorf("WriteRegister error for GLRT reg %u: %d\n", reg.addr, status);
            return status;
        }
    }
    return ZX_OK;
}

zx_status_t Device::WriteGlrtBlock(uint8_t values[], size_t size, size_t offset) {
    zx_status_t status = ZX_OK;
    size_t ndx;
    for (ndx = 0; ndx < size && status == ZX_OK; ndx++) {
        status = WriteGlrt(offset + ndx, values[ndx]);
    }
    return status;
}

zx_status_t Device::ReadRfcsr(uint8_t addr, uint8_t* val) {
    RfCsrCfg rcc;
    auto pred = [&rcc]() { return !rcc.rf_csr_kick(); };

    zx_status_t status = BusyWait(&rcc, pred);
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) { errorf("timed out waiting for RFCSR\n"); }
        return status;
    }

    rcc.clear();
    rcc.set_rf_csr_addr(addr);
    rcc.set_rf_csr_rw(0);
    rcc.set_rf_csr_kick(1);
    status = WriteRegister(rcc);
    CHECK_WRITE(RF_CSR_CFG, status);

    status = BusyWait(&rcc, pred);
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) {
            errorf("timed out waiting for RFCSR\n");
            *val = 0xff;
        }
        return status;
    }

    *val = rcc.rf_csr_data();
    return ZX_OK;
}

template <uint8_t A> zx_status_t Device::ReadRfcsr(RfcsrRegister<A>* reg) {
    return ReadRfcsr(reg->addr(), reg->mut_val());
}

zx_status_t Device::WriteRfcsr(uint8_t addr, uint8_t val) {
    RfCsrCfg rcc;
    zx_status_t status = BusyWait(&rcc, [&rcc]() { return !rcc.rf_csr_kick(); });
    if (status != ZX_OK) {
        if (status == ZX_ERR_TIMED_OUT) { errorf("timed out waiting for RFCSR\n"); }
        return status;
    }

    rcc.clear();
    rcc.set_rf_csr_data(val);
    rcc.set_rf_csr_addr(addr);
    rcc.set_rf_csr_rw(1);
    rcc.set_rf_csr_kick(1);
    status = WriteRegister(rcc);
    CHECK_WRITE(RF_CSR_CFG, status);
    return status;
}

template <uint8_t A> zx_status_t Device::WriteRfcsr(const RfcsrRegister<A>& reg) {
    return WriteRfcsr(reg.addr(), reg.val());
}

zx_status_t Device::WriteRfcsrGroup(const std::vector<RegInitValue>& regs) {
    for (auto reg : regs) {
        zx_status_t status = WriteRfcsr(reg.addr, reg.val);
        if (status != ZX_OK) {
            errorf("WriteRegister error for RFCSR reg %u: %d\n", reg.addr, status);
            return status;
        }
    }
    return ZX_OK;
}

zx_status_t Device::DisableWpdma() {
    WpdmaGloCfg wgc;
    zx_status_t status = ReadRegister(&wgc);
    CHECK_READ(WPDMA_GLO_CFG, status);
    wgc.set_tx_dma_en(0);
    wgc.set_tx_dma_busy(0);
    wgc.set_rx_dma_en(0);
    wgc.set_rx_dma_busy(0);
    wgc.set_tx_wb_ddone(1);
    status = WriteRegister(wgc);
    CHECK_WRITE(WPDMA_GLO_CFG, status);
    debugf("disabled WPDMA\n");
    return ZX_OK;
}

zx_status_t Device::DetectAutoRun(bool* autorun) {
    uint32_t fw_mode = 0;
    zx_status_t status = usb_control_in(&usb_, (USB_DIR_IN | USB_TYPE_VENDOR), kDeviceMode, kAutorun,
                                        0, ZX_TIME_INFINITE, &fw_mode, sizeof(fw_mode), nullptr);
    if (status < 0) {
        errorf("DeviceMode error: %d\n", status);
        return status;
    }

    fw_mode = letoh32(fw_mode);
    if ((fw_mode & 0x03) == 2) {
        debugf("AUTORUN\n");
        *autorun = true;
    } else {
        *autorun = false;
    }
    return ZX_OK;
}

zx_status_t Device::WaitForMacCsr() {
    AsicVerId avi;
    return BusyWait(&avi, [&avi]() { return avi.val() && avi.val() != ~0u; }, zx::msec(1));
}

zx_status_t Device::SetRxFilter() {
    // TODO(porce): Support dynamic filter configuration
    RxFiltrCfg rfc;
    zx_status_t status = ReadRegister(&rfc);
    CHECK_READ(RX_FILTR_CFG, status);
    rfc.set_drop_crc_err(1);
    rfc.set_drop_phy_err(1);
    rfc.set_drop_uc_nome(1);
    rfc.set_drop_not_mybss(0);
    rfc.set_drop_ver_err(1);
    rfc.set_drop_mc(0);
    rfc.set_drop_bc(0);
    rfc.set_drop_dupl(1);
    rfc.set_drop_cfack(1);
    rfc.set_drop_cfend(1);
    rfc.set_drop_ack(1);
    rfc.set_drop_cts(1);
    rfc.set_drop_rts(1);
    rfc.set_drop_pspoll(1);
    rfc.set_drop_ba(1);  // TODO(porce): Revisit for AMPDU
    rfc.set_drop_bar(1);
    rfc.set_drop_ctrl_rsv(1);
    status = WriteRegister(rfc);
    CHECK_WRITE(RX_FILTR_CFG, status);

    return ZX_OK;
}

constexpr uint8_t kFreqOffsetBound = 0x5f;

zx_status_t Device::AdjustFreqOffset() {
    EepromFreq ef;
    ReadEepromField(&ef);
    uint8_t freq_offset = std::min<uint8_t>(ef.offset(), kFreqOffsetBound);

    Rfcsr17 r17;
    zx_status_t status = ReadRfcsr(&r17);
    CHECK_READ(RF17, status);
    uint8_t prev_freq_off = r17.freq_offset();

    if (prev_freq_off != freq_offset) {
        status = McuCommand(MCU_FREQ_OFFSET, 0xff, freq_offset, prev_freq_off);
        if (status != ZX_OK) { errorf("could not set frequency offset\n"); }
    }

    return status;
}

zx_status_t Device::NormalModeSetup() {
    debugfn();

    Bbp138 bbp138;
    zx_status_t status = ReadBbp(&bbp138);
    CHECK_READ(BBP138, status);
    if (rx_path_) { bbp138.set_rx_adc1(0); }
    if (tx_path_) { bbp138.set_tx_dac1(1); }
    status = WriteBbp(bbp138);
    CHECK_WRITE(BBP138, status);

    Rfcsr38 r38;
    status = ReadRfcsr(&r38);
    CHECK_READ(RF38, status);
    r38.set_rx_lo1_en(0);
    status = WriteRfcsr(r38);
    CHECK_WRITE(RF38, status);

    Rfcsr39 r39;
    status = ReadRfcsr(&r39);
    CHECK_READ(RF39, status);
    r39.set_rx_lo2_en(0);
    status = WriteRfcsr(r39);
    CHECK_WRITE(RF39, status);

    Bbp4 bbp4;
    status = ReadBbp(&bbp4);
    CHECK_READ(BBP4, status);
    bbp4.set_mac_if_ctrl(1);
    status = WriteBbp(bbp4);
    CHECK_WRITE(BBP4, status);

    Rfcsr30 r30;
    status = ReadRfcsr(&r30);
    CHECK_READ(RF30, status);
    r30.set_rx_vcm(2);
    status = WriteRfcsr(r30);
    CHECK_WRITE(RF30, status);

    return ZX_OK;
}

zx_status_t Device::StartQueues() {
    // RX queue
    MacSysCtrl msc;
    zx_status_t status = ReadRegister(&msc);
    CHECK_READ(MAC_SYS_CTRL, status);
    msc.set_mac_rx_en(1);
    status = WriteRegister(msc);
    CHECK_WRITE(MAC_SYS_CTRL, status);

    // Beacon queue  --  maybe this isn't started here
    // BcnTimeCfg btc;
    // status = ReadRegister(&btc);
    // CHECK_READ(BCN_TIME_CFG, status);
    // btc.set_tsf_timer_en(1);
    // btc.set_tbtt_timer_en(1);
    // btc.set_bcn_tx_en(1);
    // status = WriteRegister(btc);
    // CHECK_WRITE(BCN_TIME_CFG, status);

    // kick the rx queue???

    return ZX_OK;
}

zx_status_t Device::StopRxQueue() {
    MacSysCtrl msc;
    zx_status_t status = ReadRegister(&msc);
    CHECK_READ(MAC_SYS_CTRL, status);
    msc.set_mac_rx_en(0);
    status = WriteRegister(msc);
    CHECK_WRITE(MAC_SYS_CTRL, status);

    return ZX_OK;
}

zx_status_t Device::SetupInterface() {
    BcnTimeCfg btc;
    zx_status_t status = ReadRegister(&btc);
    CHECK_READ(BCN_TIME_CFG, status);
    btc.set_tsf_sync_mode(1);
    status = WriteRegister(btc);
    CHECK_WRITE(BCN_TIME_CFG, status);

    TbttSyncCfg tsc;
    status = ReadRegister(&tsc);
    CHECK_READ(TBTT_SYNC_CFG, status);
    tsc.set_tbtt_adjust(16);
    tsc.set_bcn_exp_win(32);
    tsc.set_bcn_aifsn(2);
    tsc.set_bcn_cwmin(4);
    status = WriteRegister(tsc);
    CHECK_WRITE(TBTT_SYNC_CFG, status);

    MacAddrDw0 mac0;
    MacAddrDw1 mac1;
    mac0.set_mac_addr_0(mac_addr_[0]);
    mac0.set_mac_addr_1(mac_addr_[1]);
    mac0.set_mac_addr_2(mac_addr_[2]);
    mac0.set_mac_addr_3(mac_addr_[3]);
    mac1.set_mac_addr_4(mac_addr_[4]);
    mac1.set_mac_addr_5(mac_addr_[5]);
    mac1.set_unicast_to_me_mask(0xff);
    status = WriteRegister(mac0);
    CHECK_WRITE(MAC_ADDR_DW0, status);
    status = WriteRegister(mac1);
    CHECK_WRITE(MAC_ADDR_DW1, status);

    return ZX_OK;
}

zx_status_t Device::InitializeRfVal() {
    if (rt_type_ == RT5390) {
        rf_vals_.insert({
            // clang-format off
                // RfVal(channel, N, R, K)
                {1, RfVal(1, 241, 2, 2)},
                {2, RfVal(2, 241, 2, 7)},
                {3, RfVal(3, 242, 2, 2)},
                {4, RfVal(4, 242, 2, 7)},
                {5, RfVal(5, 243, 2, 2)},
                {6, RfVal(6, 243, 2, 7)},
                {7, RfVal(7, 244, 2, 2)},
                {8, RfVal(8, 244, 2, 7)},
                {9, RfVal(9, 245, 2, 2)},
                {10, RfVal(10, 245, 2, 7)},
                {11, RfVal(11, 246, 2, 2)},
                {12, RfVal(12, 246, 2, 7)},
                {13, RfVal(13, 247, 2, 2)},
                {14, RfVal(14, 248, 2, 4)},
            // clang-format on
        });
    } else if (rt_type_ == RT5592) {
        DebugIndex debug_index;
        zx_status_t status = ReadRegister(&debug_index);
        CHECK_READ(DEBUG_INDEX, status);
        if (debug_index.reserved_xtal()) {
            // 40 MHz xtal
            rf_vals_.insert({
                // clang-format off
                    // RfVal(channel,  N, R, K,  mod)
                    {1,   RfVal(1,   241, 3, 2,  10)},
                    {2,   RfVal(2,   241, 3, 7,  10)},
                    {3,   RfVal(3,   242, 3, 2,  10)},
                    {4,   RfVal(4,   242, 3, 7,  10)},
                    {5,   RfVal(5,   243, 3, 2,  10)},
                    {6,   RfVal(6,   243, 3, 7,  10)},
                    {7,   RfVal(7,   244, 3, 2,  10)},
                    {8,   RfVal(8,   244, 3, 7,  10)},
                    {9,   RfVal(9,   245, 3, 2,  10)},
                    {10,  RfVal(10,  245, 3, 7,  10)},
                    {11,  RfVal(11,  246, 3, 2,  10)},
                    {12,  RfVal(12,  246, 3, 7,  10)},
                    {13,  RfVal(13,  247, 3, 2,  10)},
                    {14,  RfVal(14,  248, 3, 4,  10)},
                    {36,  RfVal(36,  86,  1, 4,  12)},
                    {38,  RfVal(38,  86,  1, 6,  12)},
                    {40,  RfVal(40,  86,  1, 8,  12)},
                    {42,  RfVal(42,  86,  1, 10, 12)},
                    {44,  RfVal(44,  87,  1, 0,  12)},
                    {46,  RfVal(46,  87,  1, 2,  12)},
                    {48,  RfVal(48,  87,  1, 4,  12)},
                    {50,  RfVal(50,  87,  1, 6,  12)},
                    {52,  RfVal(52,  87,  1, 8,  12)},
                    {54,  RfVal(54,  87,  1, 10, 12)},
                    {56,  RfVal(56,  88,  1, 0,  12)},
                    {58,  RfVal(58,  88,  1, 2,  12)},
                    {60,  RfVal(60,  88,  1, 4,  12)},
                    {62,  RfVal(62,  88,  1, 6,  12)},
                    {64,  RfVal(64,  88,  1, 8,  12)},
                    {100, RfVal(100, 91,  1, 8,  12)},
                    {102, RfVal(102, 91,  1, 10, 12)},
                    {104, RfVal(104, 92,  1, 0,  12)},
                    {106, RfVal(106, 92,  1, 2,  12)},
                    {108, RfVal(108, 92,  1, 4,  12)},
                    {110, RfVal(110, 92,  1, 6,  12)},
                    {112, RfVal(112, 92,  1, 8,  12)},
                    {114, RfVal(114, 92,  1, 10, 12)},
                    {116, RfVal(116, 93,  1, 0,  12)},
                    {118, RfVal(118, 93,  1, 2,  12)},
                    {120, RfVal(120, 93,  1, 4,  12)},
                    {122, RfVal(122, 93,  1, 6,  12)},
                    {124, RfVal(124, 93,  1, 8,  12)},
                    {126, RfVal(126, 93,  1, 10, 12)},
                    {128, RfVal(128, 94,  1, 0,  12)},
                    {130, RfVal(130, 94,  1, 2,  12)},
                    {132, RfVal(132, 94,  1, 4,  12)},
                    {134, RfVal(134, 94,  1, 6,  12)},
                    {136, RfVal(136, 94,  1, 8,  12)},
                    {138, RfVal(138, 94,  1, 10, 12)},
                    {140, RfVal(140, 95,  1, 0,  12)},
                    {149, RfVal(149, 95,  1, 9,  12)},
                    {151, RfVal(151, 95,  1, 11, 12)},
                    {153, RfVal(153, 96,  1, 1,  12)},
                    {155, RfVal(155, 96,  1, 3,  12)},
                    {157, RfVal(157, 96,  1, 5,  12)},
                    {159, RfVal(159, 96,  1, 7,  12)},
                    {161, RfVal(161, 96,  1, 9,  12)},
                    {165, RfVal(165, 97,  1, 1,  12)},
                    {184, RfVal(184, 82,  1, 0,  12)},
                    {188, RfVal(188, 82,  1, 4,  12)},
                    {192, RfVal(192, 82,  1, 8,  12)},
                    {196, RfVal(196, 83,  1, 0,  12)},
                // clang-format on
            });
        } else {
            // 20 MHz xtal
            rf_vals_.insert({
                // clang-format off
                    // RfVal(channel,  N, R, K, mod)
                    {1,   RfVal(1,   482, 3, 4,  10)},
                    {2,   RfVal(2,   483, 3, 4,  10)},
                    {3,   RfVal(3,   484, 3, 4,  10)},
                    {4,   RfVal(4,   485, 3, 4,  10)},
                    {5,   RfVal(5,   486, 3, 4,  10)},
                    {6,   RfVal(6,   487, 3, 4,  10)},
                    {7,   RfVal(7,   488, 3, 4,  10)},
                    {8,   RfVal(8,   489, 3, 4,  10)},
                    {9,   RfVal(9,   490, 3, 4,  10)},
                    {10,  RfVal(10,  491, 3, 4,  10)},
                    {11,  RfVal(11,  492, 3, 4,  10)},
                    {12,  RfVal(12,  493, 3, 4,  10)},
                    {13,  RfVal(13,  494, 3, 4,  10)},
                    {14,  RfVal(14,  496, 3, 8,  10)},
                    {36,  RfVal(36,  172, 1, 8,  12)},
                    {38,  RfVal(38,  173, 1, 0,  12)},
                    {40,  RfVal(40,  173, 1, 4,  12)},
                    {42,  RfVal(42,  173, 1, 8,  12)},
                    {44,  RfVal(44,  174, 1, 0,  12)},
                    {46,  RfVal(46,  174, 1, 4,  12)},
                    {48,  RfVal(48,  174, 1, 8,  12)},
                    {50,  RfVal(50,  175, 1, 0,  12)},
                    {52,  RfVal(52,  175, 1, 4,  12)},
                    {54,  RfVal(54,  175, 1, 8,  12)},
                    {56,  RfVal(56,  176, 1, 0,  12)},
                    {58,  RfVal(58,  176, 1, 4,  12)},
                    {60,  RfVal(60,  176, 1, 8,  12)},
                    {62,  RfVal(62,  177, 1, 0,  12)},
                    {64,  RfVal(64,  177, 1, 4,  12)},
                    {100, RfVal(100, 183, 1, 4,  12)},
                    {102, RfVal(102, 183, 1, 8,  12)},
                    {104, RfVal(104, 184, 1, 0,  12)},
                    {106, RfVal(106, 184, 1, 4,  12)},
                    {108, RfVal(108, 184, 1, 8,  12)},
                    {110, RfVal(110, 185, 1, 0,  12)},
                    {112, RfVal(112, 185, 1, 4,  12)},
                    {114, RfVal(114, 185, 1, 8,  12)},
                    {116, RfVal(116, 186, 1, 0,  12)},
                    {118, RfVal(118, 186, 1, 4,  12)},
                    {120, RfVal(120, 186, 1, 8,  12)},
                    {122, RfVal(122, 187, 1, 0,  12)},
                    {124, RfVal(124, 187, 1, 4,  12)},
                    {126, RfVal(126, 187, 1, 8,  12)},
                    {128, RfVal(128, 188, 1, 0,  12)},
                    {130, RfVal(130, 188, 1, 4,  12)},
                    {132, RfVal(132, 188, 1, 8,  12)},
                    {134, RfVal(134, 189, 1, 0,  12)},
                    {136, RfVal(136, 189, 1, 4,  12)},
                    {138, RfVal(138, 189, 1, 8,  12)},
                    {140, RfVal(140, 190, 1, 0,  12)},
                    {149, RfVal(149, 191, 1, 6,  12)},
                    {151, RfVal(151, 191, 1, 10, 12)},
                    {153, RfVal(153, 192, 1, 2,  12)},
                    {155, RfVal(155, 192, 1, 6,  12)},
                    {157, RfVal(157, 192, 1, 10, 12)},
                    {159, RfVal(159, 193, 1, 2,  12)},
                    {161, RfVal(161, 193, 1, 6,  12)},
                    {165, RfVal(165, 194, 1, 2,  12)},
                    {184, RfVal(184, 164, 1, 0,  12)},
                    {188, RfVal(188, 164, 1, 4,  12)},
                    {192, RfVal(192, 165, 1, 8,  12)},
                    {196, RfVal(196, 166, 1, 0,  12)},
                // clang-format on
            });
        }
        // Read all of our Tx calibration values
        TxCalibrationValues ch0_14, ch36_64, ch100_138, ch140_165;
        ReadEepromByte(EEPROM_GAIN_CAL_TX0_CH0_14, &ch0_14.gain_cal_tx0);
        ReadEepromByte(EEPROM_GAIN_CAL_TX0_CH36_64, &ch36_64.gain_cal_tx0);
        ReadEepromByte(EEPROM_GAIN_CAL_TX0_CH100_138, &ch100_138.gain_cal_tx0);
        ReadEepromByte(EEPROM_GAIN_CAL_TX0_CH140_165, &ch140_165.gain_cal_tx0);
        ReadEepromByte(EEPROM_PHASE_CAL_TX0_CH0_14, &ch0_14.phase_cal_tx0);
        ReadEepromByte(EEPROM_PHASE_CAL_TX0_CH36_64, &ch36_64.phase_cal_tx0);
        ReadEepromByte(EEPROM_PHASE_CAL_TX0_CH100_138, &ch100_138.phase_cal_tx0);
        ReadEepromByte(EEPROM_PHASE_CAL_TX0_CH140_165, &ch140_165.phase_cal_tx0);
        ReadEepromByte(EEPROM_GAIN_CAL_TX1_CH0_14, &ch0_14.gain_cal_tx1);
        ReadEepromByte(EEPROM_GAIN_CAL_TX1_CH36_64, &ch36_64.gain_cal_tx1);
        ReadEepromByte(EEPROM_GAIN_CAL_TX1_CH100_138, &ch100_138.gain_cal_tx1);
        ReadEepromByte(EEPROM_GAIN_CAL_TX1_CH140_165, &ch140_165.gain_cal_tx1);
        ReadEepromByte(EEPROM_PHASE_CAL_TX1_CH0_14, &ch0_14.phase_cal_tx1);
        ReadEepromByte(EEPROM_PHASE_CAL_TX1_CH36_64, &ch36_64.phase_cal_tx1);
        ReadEepromByte(EEPROM_PHASE_CAL_TX1_CH100_138, &ch100_138.phase_cal_tx1);
        ReadEepromByte(EEPROM_PHASE_CAL_TX1_CH140_165, &ch140_165.phase_cal_tx1);
        // Note: Regardless the channel, EEPROM reads 0xff for all
        // gain calibrations and phase calibrations, making them seemingly invalid table.
        for (auto& entry : rf_vals_) {
            if (entry.second.channel <= 14) {
                entry.second.cal_values = ch0_14;
            } else if (entry.second.channel <= 64) {
                entry.second.cal_values = ch36_64;
            } else if (entry.second.channel <= 138) {
                entry.second.cal_values = ch100_138;
            } else {
                entry.second.cal_values = ch140_165;
            }
        }
    } else {
        errorf("Unrecognized device family in %s\n", __FUNCTION__);
        return ZX_ERR_NOT_FOUND;
    }
    return ZX_OK;
}

constexpr uint8_t kHwTxPowerPerChainMax = 20;  // dBm
constexpr uint8_t kHwTxPowerPerChainMin = 0;   // dBm

zx_status_t Device::ConfigureChannel5390(const wlan_channel_t& chan) {
    zx_status_t status;
    RfVal rf_val;
    status = LookupRfVal(chan, &rf_val);
    if (status != ZX_OK) { return status; }

    WriteRfcsr(RfcsrRegister<8>(rf_val.N));
    WriteRfcsr(RfcsrRegister<9>(rf_val.K & 0x0f));
    Rfcsr11 r11;
    status = ReadRfcsr(&r11);
    CHECK_READ(RF11, status);
    r11.set_r(rf_val.R);
    status = WriteRfcsr(r11);
    CHECK_WRITE(RF11, status);

    // TODO(porce): Study why this configuration is outside ConfigureTxpower()
    Rfcsr49 r49;
    status = ReadRfcsr(&r49);
    CHECK_READ(RF49, status);

    // See for EIRP table
    // https://www.air802.com/fcc-rules-and-regulations.html
    constexpr uint8_t target_eirp = 30;
    uint8_t tx_power = GetPerChainTxPower(chan, target_eirp);
    r49.set_tx(tx_power);
    status = WriteRfcsr(r49);
    CHECK_WRITE(RF49, status);

#if RALINK_DUMP_TXPOWER
    debugf(
        "[ralink] TxPower for chan:%s [sw_bound] 2GHz:%u [hw_bound] 1:%d "
        "2:%d 3:%d rectified:%u [result] tx_power1:%u\n",
        wlan::common::ChanStr(chan).c_str(), kRfPowerBound2_4Ghz, rf_val.default_power1,
        rf_val.default_power2, rf_val.default_power3, rectified_hw_upperbound1, tx_power1);
#endif  // RALINK_DUMP_TXPOWER

    Rfcsr1 r1;
    status = ReadRfcsr(&r1);
    CHECK_READ(RF1, status);
    r1.set_rf_block_en(1);
    r1.set_pll_pd(1);
    r1.set_rx0_pd(1);
    r1.set_tx0_pd(1);
    status = WriteRfcsr(r1);
    CHECK_WRITE(RF1, status);

    status = AdjustFreqOffset();
    if (status != ZX_OK) { return status; }

    if (chan.primary <= 14) {
        int hw_index = chan.primary - 1;
        if (rt_rev_ >= REV_RT5390F) {
            static const uint8_t r55[] = {
                0x23, 0x23, 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
            };
            static const uint8_t r59[] = {
                0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x04, 0x04,
            };
            static_assert(sizeof(r55) == sizeof(r59),
                          "r55 and r59 should have the same number of entries.");
            ZX_DEBUG_ASSERT(hw_index < (ssize_t)sizeof(r55));
            WriteRfcsr(RfcsrRegister<55>(r55[hw_index]));
            WriteRfcsr(RfcsrRegister<59>(r59[hw_index]));
        } else {
            static const uint8_t r59[] = {
                0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86,
            };
            ZX_DEBUG_ASSERT(hw_index < (ssize_t)sizeof(r59));
            WriteRfcsr(RfcsrRegister<59>(r59[hw_index]));
        }
    }

    Rfcsr30 r30;
    status = ReadRfcsr(&r30);
    CHECK_READ(RF30, status);
    switch (chan.cbw) {
    case CBW20:
        r30.set_tx_h20m(0);
        r30.set_rx_h20m(0);
        break;
    case CBW40ABOVE:
    case CBW40BELOW:
        r30.set_tx_h20m(1);
        r30.set_rx_h20m(1);
        break;
    default:
        // Unreachable
        ZX_DEBUG_ASSERT(0);
        break;
    }
    status = WriteRfcsr(r30);
    CHECK_WRITE(RF30, status);

    Rfcsr3 r3;
    status = ReadRfcsr(&r3);
    CHECK_READ(RF3, status);
    r3.set_vcocal_en(1);
    status = WriteRfcsr(r3);
    CHECK_WRITE(RF3, status);

    return status;
}

zx_status_t Device::ConfigureChannel5592(const wlan_channel_t& chan) {
    zx_status_t status;
    RfVal rf_val;
    status = LookupRfVal(chan, &rf_val);
    if (status != ZX_OK) { return status; }

    // Set LDO_CORE_VLEVEL in LDO_CFG0
    LdoCfg0 lc0;
    status = ReadRegister(&lc0);
    CHECK_READ(LDO_CFG0, status);
    if (wlan::common::Is5Ghz(chan) || chan.cbw == CBW40ABOVE || chan.cbw == CBW40BELOW) {
        lc0.set_ldo_core_vlevel(5);
    } else {
        // TODO(porce): Investigate if extra CBW40 in 2GHz support is necessary
        lc0.set_ldo_core_vlevel(0);
    }
    status = WriteRegister(lc0);
    CHECK_WRITE(LDO_CFG0, status);

    // Set N, R, K, mod values
    Rfcsr8 r8;
    r8.set_n(rf_val.N & 0xff);
    status = WriteRfcsr(r8);
    CHECK_WRITE(RF8, status);

    Rfcsr9 r9;
    status = ReadRfcsr(&r9);
    CHECK_READ(RF9, status);
    r9.set_k(rf_val.K & 0xf);
    r9.set_n((rf_val.N & 0x100) >> 8);
    r9.set_mod(((rf_val.mod - 8) & 0x4) >> 2);
    status = WriteRfcsr(r9);
    CHECK_WRITE(RF9, status);

    Rfcsr11 r11;
    status = ReadRfcsr(&r11);
    CHECK_READ(RF11, status);
    r11.set_r(rf_val.R - 1);
    r11.set_mod(rf_val.mod - 8);
    status = WriteRfcsr(r11);
    CHECK_WRITE(RF11, status);

    if (chan.primary <= 14) {
        std::vector<RegInitValue> reg_init_values{
            // clang-format off
            RegInitValue(10, 0x90),
            RegInitValue(11, 0x4a),
            RegInitValue(12, 0x52),
            RegInitValue(13, 0x42),
            RegInitValue(22, 0x40),
            RegInitValue(24, 0x4a),
            RegInitValue(25, 0x80),
            RegInitValue(27, 0x42),
            RegInitValue(36, 0x80),
            RegInitValue(37, 0x08),
            RegInitValue(38, 0x89),
            RegInitValue(39, 0x1b),
            RegInitValue(40, 0x0d),
            RegInitValue(41, 0x9b),
            RegInitValue(42, 0xd5),
            RegInitValue(43, 0x72),
            RegInitValue(44, 0x0e),
            RegInitValue(45, 0xa2),
            RegInitValue(46, 0x6b),
            RegInitValue(48, 0x10),
            RegInitValue(51, 0x3e),
            RegInitValue(52, 0x48),
            RegInitValue(54, 0x38),
            RegInitValue(56, 0xa1),
            RegInitValue(57, 0x00),
            RegInitValue(58, 0x39),
            RegInitValue(60, 0x45),
            RegInitValue(61, 0x91),
            RegInitValue(62, 0x39),
            // clang-format on
        };
        status = WriteRfcsrGroup(reg_init_values);
        if (status != ZX_OK) { return status; }

        uint8_t val = (chan.primary <= 10) ? 0x07 : 0x06;
        status = WriteRfcsr(23, val);
        CHECK_WRITE(RF23, status);
        status = WriteRfcsr(59, val);
        CHECK_WRITE(RF59, status);

        status = WriteRfcsr(55, 0x43);
        CHECK_WRITE(RF55, status);
    } else {
        std::vector<RegInitValue> reg_init_values{
            // clang-format off
            RegInitValue(10, 0x97),
            RegInitValue(11, 0x40),
            RegInitValue(25, 0xbf),
            RegInitValue(27, 0x42),
            RegInitValue(36, 0x00),
            RegInitValue(37, 0x04),
            RegInitValue(38, 0x85),
            RegInitValue(40, 0x42),
            RegInitValue(41, 0xbb),
            RegInitValue(42, 0xd7),
            RegInitValue(45, 0x41),
            RegInitValue(48, 0x00),
            RegInitValue(57, 0x77),
            RegInitValue(60, 0x05),
            RegInitValue(61, 0x01),
            // clang-format on
        };
        status = WriteRfcsrGroup(reg_init_values);
        if (status != ZX_OK) { return status; }

        if (chan.primary <= 64) {
            std::vector<RegInitValue> reg_init_values{
                // clang-format off
                RegInitValue(12, 0x2e),
                RegInitValue(13, 0x22),
                RegInitValue(22, 0x60),
                RegInitValue(23, 0x7f),
                RegInitValue(24, chan.primary <= 50 ? 0x09 : 0x07),
                RegInitValue(39, 0x1c),
                RegInitValue(43, 0x5b),
                RegInitValue(44, 0x40),
                RegInitValue(46, 0x00),
                RegInitValue(51, 0xfe),
                RegInitValue(52, 0x0c),
                RegInitValue(54, 0xf8),
                RegInitValue(55, chan.primary <= 50 ? 0x06 : 0x04),
                RegInitValue(56, chan.primary <= 50 ? 0xd3 : 0xbb),
                RegInitValue(58, 0x15),
                RegInitValue(59, 0x7f),
                RegInitValue(62, 0x15),
                // clang-format on
            };
            status = WriteRfcsrGroup(reg_init_values);
            if (status != ZX_OK) { return status; }
        } else if (chan.primary <= 165) {
            std::vector<RegInitValue> reg_init_values{
                // clang-format off
                RegInitValue(12, 0x0e),
                RegInitValue(13, 0x42),
                RegInitValue(22, 0x40),
                RegInitValue(23, chan.primary <= 153 ? 0x3c : 0x38),
                RegInitValue(24, chan.primary <= 153 ? 0x06 : 0x05),
                RegInitValue(39, chan.primary <= 138 ? 0x1a : 0x18),
                RegInitValue(43, chan.primary <= 138 ? 0x3b : 0x1b),
                RegInitValue(44, chan.primary <= 138 ? 0x20 : 0x10),
                RegInitValue(46, chan.primary <= 138 ? 0x18 : 0x08),
                RegInitValue(51, chan.primary <= 124 ? 0xfc : 0xec),
                RegInitValue(52, 0x06),
                RegInitValue(54, 0xeb),
                RegInitValue(55, chan.primary <= 138 ? 0x01 : 0x00),
                RegInitValue(56, chan.primary <= 128 ? 0xbb : 0xab),
                RegInitValue(58, chan.primary <= 116 ? 0x1d : 0x15),
                RegInitValue(59, chan.primary <= 138 ? 0x3f : 0x7c),
                RegInitValue(62, chan.primary <= 116 ? 0x1d : 0x15),
                // clang-format on
            };
            status = WriteRfcsrGroup(reg_init_values);
            if (status != ZX_OK) { return status; }
        }
    }

    // TODO(porce): Study why this configuration is outside ConfigureTxpower()
    Rfcsr49 r49;
    status = ReadRfcsr(&r49);
    CHECK_READ(RF49, status);
    constexpr uint8_t target_eirp = 30;
    uint8_t tx_power1 = GetPerChainTxPower(chan, target_eirp);
    r49.set_tx(tx_power1);
    status = WriteRfcsr(r49);
    CHECK_WRITE(RF49, status);
    Rfcsr50 r50;
    status = ReadRfcsr(&r50);
    CHECK_READ(RF50, status);
    uint8_t tx_power2 = GetPerChainTxPower(chan, target_eirp);
    r50.set_tx(tx_power2);
    status = WriteRfcsr(r50);
    CHECK_WRITE(RF50, status);

    Rfcsr1 r1;
    status = ReadRfcsr(&r1);
    CHECK_READ(RF1, status);
    r1.set_rf_block_en(1);
    r1.set_pll_pd(1);
    r1.set_rx0_pd(rx_path_ >= 1);
    r1.set_tx0_pd(tx_path_ >= 1);
    r1.set_rx1_pd(rx_path_ == 2);
    r1.set_tx1_pd(tx_path_ == 2);
    r1.set_rx2_pd(0);
    r1.set_tx2_pd(0);
    status = WriteRfcsr(r1);
    CHECK_WRITE(RF1, status);

    status = WriteRfcsr(6, 0xe4);
    CHECK_WRITE(RF6, status);

    switch (chan.cbw) {  // RFCSR30
    case CBW20:
        status = WriteRfcsr(30, 0x10);
        break;
    case CBW40ABOVE:
    case CBW40BELOW:
        status = WriteRfcsr(30, 0x16);
        break;
    default:
        ZX_DEBUG_ASSERT(0);
        break;
    }
    CHECK_WRITE(RF30, status);

    status = WriteRfcsr(31, 0x80);
    CHECK_WRITE(RF31, status);
    status = WriteRfcsr(32, 0x80);
    CHECK_WRITE(RF32, status);

    status = AdjustFreqOffset();
    if (status != ZX_OK) { return status; }

    Rfcsr3 r3;
    status = ReadRfcsr(&r3);
    CHECK_READ(RF3, status);
    r3.set_vcocal_en(1);
    status = WriteRfcsr(r3);
    CHECK_WRITE(RF3, status);

    std::vector<RegInitValue> bbp_init_values{
        // clang-format off
        RegInitValue(62, 0x37 - lna_gain_),
        RegInitValue(63, 0x37 - lna_gain_),
        RegInitValue(64, 0x37 - lna_gain_),
        RegInitValue(79, wlan::common::Is2Ghz(chan)? 0x1c : 0x18),
        RegInitValue(80, wlan::common::Is2Ghz(chan)? 0x0e : 0x08),
        RegInitValue(81, wlan::common::Is2Ghz(chan)? 0x3a : 0x38),
        RegInitValue(82, wlan::common::Is2Ghz(chan)? 0x62 : 0x92),
        // clang-format on
    };
    status = WriteBbpGroup(bbp_init_values);
    if (status != ZX_OK) { return status; }

    std::vector<RegInitValue> glrt_init_values{
        // clang-format off
        RegInitValue(128, wlan::common::Is2Ghz(chan)? 0xe0 : 0xf0),
        RegInitValue(129, wlan::common::Is2Ghz(chan)? 0x1f : 0x1e),
        RegInitValue(130, wlan::common::Is2Ghz(chan)? 0x38 : 0x28),
        RegInitValue(131, wlan::common::Is2Ghz(chan)? 0x32 : 0x20),
        RegInitValue(133, wlan::common::Is2Ghz(chan)? 0x28 : 0x7f),
        RegInitValue(124, wlan::common::Is2Ghz(chan)? 0x19 : 0x7f),
        // clang-format on
    };
    status = WriteGlrtGroup(glrt_init_values);
    if (status != ZX_OK) { return status; }

    return ZX_OK;
}

zx_status_t Device::LookupRfVal(const wlan_channel_t& chan, RfVal* rf_val) {
    auto center_chan_idx = wlan::common::GetCenterChanIdx(chan);
    auto entry = rf_vals_.find(center_chan_idx);
    if (entry == rf_vals_.end()) {
        errorf("Radio hardware does not support the requested channel %s\n",
               wlan::common::ChanStr(chan).c_str());
        return ZX_ERR_NOT_FOUND;
    }

    *rf_val = entry->second;
    return ZX_OK;
}

zx_status_t Device::ConfigureChannel(const wlan_channel_t& chan) {
    // TODO(porce): Factor out antenna calibration
    EepromLna lna;
    zx_status_t status = ReadEepromField(&lna);
    CHECK_READ(EEPROM_LNA, status);
    lna_gain_ = (chan.primary <= 14) ? lna.bg() : lna.a0();

    switch (rt_type_) {
    case RT5390:
        status = ConfigureChannel5390(chan);
        break;
    case RT5592:
        status = ConfigureChannel5592(chan);
        break;
    default:
        errorf("Ralink device type %u not supported\n", rt_type_);
        return ZX_ERR_NOT_FOUND;
    }

    if (status != ZX_OK) { return status; }

    WriteBbp(BbpRegister<62>(0x37 - lna_gain_));
    WriteBbp(BbpRegister<63>(0x37 - lna_gain_));
    WriteBbp(BbpRegister<64>(0x37 - lna_gain_));
    WriteBbp(BbpRegister<86>(0x00));

    if (rt_type_ == RT5592) {
        if (chan.primary <= 14) {
            WriteBbp(BbpRegister<82>(has_external_lna_2g_ ? 0x62 : 0x84));
            WriteBbp(BbpRegister<75>(has_external_lna_2g_ ? 0x46 : 0x50));
        } else {
            WriteBbp(BbpRegister<82>(0xf2));
            WriteBbp(BbpRegister<75>(has_external_lna_5g_ ? 0x46 : 0x50));
        }
    }

    TxBandCfg tbc;
    status = ReadRegister(&tbc);
    CHECK_READ(TX_BAND_CFG, status);

    switch (chan.cbw) {
    case CBW20:
        tbc.set_tx_band_sel(0);
        break;
    case CBW40ABOVE:
        tbc.set_tx_band_sel(0);
        break;
    case CBW40BELOW:
        tbc.set_tx_band_sel(1);
        break;
    default:
        // Unreachable
        ZX_DEBUG_ASSERT(0);
        break;
    }

    if (chan.primary <= 14) {
        tbc.set_a(0);
        tbc.set_bg(1);
    } else {
        tbc.set_a(1);
        tbc.set_bg(0);
    }
    status = WriteRegister(tbc);
    CHECK_WRITE(TX_BAND_CFG, status);

    // TODO(porce): Support tx_path_ >= 3
    TxPinCfg tpc;
    status = ReadRegister(&tpc);
    CHECK_READ(TX_PIN_CFG, status);
    tpc.set_pa_pe_g0_en(chan.primary <= 14);
    tpc.set_pa_pe_g1_en((chan.primary <= 14) && (tx_path_ > 1));
    tpc.set_pa_pe_a0_en(chan.primary > 14);
    tpc.set_pa_pe_a1_en((chan.primary > 14) && (tx_path_ > 1));
    tpc.set_lna_pe_a0_en(1);
    tpc.set_lna_pe_g0_en(1);
    tpc.set_lna_pe_a1_en(tx_path_ > 1);
    tpc.set_lna_pe_g1_en(tx_path_ > 1);
    tpc.set_rftr_en(1);
    tpc.set_trsw_en(1);
    tpc.set_rfrx_en(1);
    status = WriteRegister(tpc);
    CHECK_WRITE(TX_PIN_CFG, status);

    if (rt_type_ == RT5592) {
        switch (chan.cbw) {  // BBP 141
        case CBW20:
            WriteGlrt(141, 0x1a);
            break;
        case CBW40ABOVE:
        case CBW40BELOW:
            WriteGlrt(141, 0x10);
            break;
        default:
            ZX_DEBUG_ASSERT(0);
            break;
        }

        // TODO(porce) Revisit the logic for multiple antennas
        uint8_t rx_ndx;
        for (rx_ndx = 0; rx_ndx < rx_path_; rx_ndx++) {
            Bbp27 b27;
            status = ReadBbp(&b27);
            CHECK_READ(BBP27, status);
            b27.set_rx_chain_sel(rx_ndx);
            status = WriteBbp(b27);
            CHECK_WRITE(BBP27, status);
            status = WriteBbp(66, (lna_gain_ * 2) + (chan.primary <= 14 ? 0x1c : 0x24));
            CHECK_WRITE(BBP66, status);
        }

        struct RfVal rf_val;
        status = LookupRfVal(chan, &rf_val);
        if (status != ZX_OK) { return status; }

        // TODO(porce): Refactor IQ calibration
        status = WriteBbp(158, 0x2c);
        CHECK_WRITE(BBP158, status);
        status = WriteBbp(159, rf_val.cal_values.gain_cal_tx0);
        CHECK_WRITE(BBP159, status);
        status = WriteBbp(158, 0x2d);
        CHECK_WRITE(BBP158, status);
        status = WriteBbp(159, rf_val.cal_values.phase_cal_tx0);
        CHECK_WRITE(BBP159, status);
        status = WriteBbp(158, 0x4a);
        CHECK_WRITE(BBP158, status);
        status = WriteBbp(159, rf_val.cal_values.gain_cal_tx1);
        CHECK_WRITE(BBP159, status);
        status = WriteBbp(158, 0x4b);
        CHECK_WRITE(BBP158, status);
        status = WriteBbp(159, rf_val.cal_values.phase_cal_tx1);
        CHECK_WRITE(BBP159, status);

        uint8_t comp_ctl, imbalance_comp_ctl;
        status = ReadEepromByte(EEPROM_COMP_CTL, &comp_ctl);
        CHECK_READ(EEPROM_COMP_CTL, status);
        status = WriteBbp(158, 0x04);
        CHECK_WRITE(BBP158, status);
        status = WriteBbp(159, comp_ctl == 0xff ? 0 : comp_ctl);
        CHECK_WRITE(BBP159, status);
        status = ReadEepromByte(EEPROM_IMB_COMP_CTL, &imbalance_comp_ctl);
        CHECK_READ(EEPROM_IMB_COMP_CTL, status);
        status = WriteBbp(158, 0x03);
        CHECK_WRITE(BBP158, status);
        status = WriteBbp(159, imbalance_comp_ctl == 0xff ? 0 : imbalance_comp_ctl);
        CHECK_WRITE(BBP159, status);
    }

    Bbp4 b4;
    status = ReadBbp(&b4);
    CHECK_READ(BBP4, status);
    switch (chan.cbw) {
    case CBW20:
        b4.set_bandwidth(0);
        break;
    case CBW40ABOVE:
        b4.set_bandwidth(0x2);
        break;
    case CBW40BELOW:
        b4.set_bandwidth(0x2);
        break;
    default:
        // Unreachable
        ZX_DEBUG_ASSERT(0);
        break;
    }
    status = WriteBbp(b4);
    CHECK_WRITE(BBP4, status);

    Bbp3 b3;
    status = ReadBbp(&b3);
    CHECK_READ(BBP3, status);
    switch (chan.cbw) {
    case CBW20:
        b3.set_ht40_minus(0);
        break;
    case CBW40ABOVE:
        b3.set_ht40_minus(0);
        break;
    case CBW40BELOW:
        b3.set_ht40_minus(1);
        break;
    default:
        // Unreachable
        ZX_DEBUG_ASSERT(0);
        break;
    }
    status = WriteBbp(b3);
    CHECK_WRITE(BBP3, status);

    sleep_for(zx::msec(1));

    // Clear channel stats by reading the registers
    ChIdleSta cis;
    ChBusySta cbs;
    ExtChBusySta ecbs;
    status = ReadRegister(&cis);
    CHECK_READ(CH_IDLE_STA, status);
    status = ReadRegister(&cbs);
    CHECK_READ(CH_BUSY_STA, status);
    status = ReadRegister(&ecbs);
    CHECK_READ(EXT_CH_BUSY_STA, status);

    return ZX_OK;
}

uint8_t Device::GetEirpRegUpperBound(const wlan_channel_t& chan) {
    if (wlan::common::Is2Ghz(chan)) {
        return 36;
    } else if (chan.primary <= 48) {
        return 30;
    } else if (chan.primary <= 144) {
        return 29;
    } else {
        return 36;
    }
}

uint8_t Device::GetPerChainTxPower(const wlan_channel_t& chan, uint8_t eirp_target) {
    uint8_t eirp_reg_upperbound = GetEirpRegUpperBound(chan);  // dBm
    uint8_t antenna_gain = 3;                                  // dBi
    uint8_t tx_chain_cnt_contribution = 3;                     // dB, for 2 tx chains

    uint8_t result = eirp_target - antenna_gain - tx_chain_cnt_contribution;
    result = std::min(result, eirp_reg_upperbound);
    result = fbl::clamp(result, kHwTxPowerPerChainMin, kHwTxPowerPerChainMax);

#if RALINK_DUMP_TXPOWER
    debugf(
        "[ralink] TxPower for chan:%s [eirp] target:%u reg_ub:%u ant_gain:%u tx_chain_cnt:%u [hw] "
        "ub:%u lb:%u [per-chain] result:%u\n",
        wlan::common::ChanStr(chan).c_str(), eirp_target, eirp_reg_upperbound, antenna_gain,
        tx_chain_cnt, hw_upperbound, hw_lowerbound, result);
#endif  // RALINK_DUMP_TXPOWER

    return result;
}

namespace {
uint8_t CompensateTx(uint8_t power) {
    // TODO(tkilbourn): implement proper tx compensation
    uint8_t high = (power & 0xf0) >> 4;
    uint8_t low = power & 0x0f;
    return (std::min<uint8_t>(high, 0x0c) << 4) | std::min<uint8_t>(low, 0x0c);
}
}  // namespace

zx_status_t Device::ConfigureTxPower(const wlan_channel_t& chan) {
    // TODO(porce): Refactor to support
    // (1) Target EIRP configured from a higher layer
    // (2) Calcualte compensation and truncation per rate/MCS, for 4 bit size

    Bbp1 b1;
    zx_status_t status = ReadBbp(&b1);
    CHECK_READ(BBP1, status);

    b1.set_tx_power_ctrl(0);  // TODO(NET-697): Investigate the register effect.

    status = WriteBbp(b1);
    CHECK_WRITE(BBP1, status);

    // Reading of EEPOM from EEPOM_TXPOWER_BYRATE + offset, where
    // offset is in [0, 8] is all 0x6666.
    // Instead of using the value from the EEPROM, use a constant value,
    // with kTxCompMaxPower.
    constexpr uint16_t eeprom_val = kTxCompMaxPower | kTxCompMaxPower << 4 | kTxCompMaxPower << 8 |
                                    kTxCompMaxPower << 12;  // 0xcccc

    // TX_PWR_CFG_0
    TxPwrCfg0 tpc0;
    status = ReadRegister(&tpc0);
    CHECK_READ(TX_PWR_CFG_0, status);

    tpc0.set_tx_pwr_cck_1(CompensateTx(eeprom_val & 0xff));
    tpc0.set_tx_pwr_cck_5(CompensateTx((eeprom_val >> 8) & 0xff));

    tpc0.set_tx_pwr_ofdm_6(CompensateTx(eeprom_val & 0xff));
    tpc0.set_tx_pwr_ofdm_12(CompensateTx((eeprom_val >> 8) & 0xff));

    status = WriteRegister(tpc0);
    CHECK_WRITE(TX_PWR_CFG_0, status);

    // TX_PWR_CFG_1
    TxPwrCfg1 tpc1;
    status = ReadRegister(&tpc1);
    CHECK_READ(TX_PWR_CFG_1, status);

    tpc1.set_tx_pwr_ofdm_24(CompensateTx(eeprom_val & 0xff));
    tpc1.set_tx_pwr_ofdm_48(CompensateTx((eeprom_val >> 8) & 0xff));

    tpc1.set_tx_pwr_mcs_0(CompensateTx(eeprom_val & 0xff));
    tpc1.set_tx_pwr_mcs_2(CompensateTx((eeprom_val >> 8) & 0xff));

    status = WriteRegister(tpc1);
    CHECK_WRITE(TX_PWR_CFG_1, status);

    // TX_PWR_CFG_2
    TxPwrCfg2 tpc2;
    status = ReadRegister(&tpc2);
    CHECK_READ(TX_PWR_CFG_2, status);

    tpc2.set_tx_pwr_mcs_4(CompensateTx(eeprom_val & 0xff));
    tpc2.set_tx_pwr_mcs_6(CompensateTx((eeprom_val >> 8) & 0xff));

    tpc2.set_tx_pwr_mcs_8(CompensateTx(eeprom_val & 0xff));
    tpc2.set_tx_pwr_mcs_10(CompensateTx((eeprom_val >> 8) & 0xff));

    status = WriteRegister(tpc2);
    CHECK_WRITE(TX_PWR_CFG_2, status);

    // TX_PWR_CFG_3
    TxPwrCfg3 tpc3;
    status = ReadRegister(&tpc3);
    CHECK_READ(TX_PWR_CFG_3, status);

    tpc3.set_tx_pwr_mcs_12(CompensateTx(eeprom_val & 0xff));
    tpc3.set_tx_pwr_mcs_14(CompensateTx((eeprom_val >> 8) & 0xff));

    tpc3.set_tx_pwr_stbc_0(CompensateTx(eeprom_val & 0xff));
    tpc3.set_tx_pwr_stbc_2(CompensateTx((eeprom_val >> 8) & 0xff));

    status = WriteRegister(tpc3);
    CHECK_WRITE(TX_PWR_CFG_3, status);

    // TX_PWR_CFG_4
    TxPwrCfg4 tpc4;

    tpc4.set_tx_pwr_stbc_4(CompensateTx(eeprom_val & 0xff));
    tpc4.set_tx_pwr_stbc_6(CompensateTx((eeprom_val >> 8) & 0xff));

    status = WriteRegister(tpc4);
    CHECK_WRITE(TX_PWR_CFG_4, status);

    return ZX_OK;
}

template <typename R, typename Predicate>
zx_status_t Device::BusyWait(R* reg, Predicate pred, zx::duration delay) {
    zx_status_t status;
    unsigned int busy;
    for (busy = 0; busy < kMaxBusyReads; busy++) {
        status = ReadRegister(reg);
        if (status != ZX_OK) { return status; }
        if (pred()) { break; }
        sleep_for(delay);
    }
    if (busy == kMaxBusyReads) { return ZX_ERR_TIMED_OUT; }
    return ZX_OK;
}

static void dump_rx(usb_request_t* request, RxInfo rx_info, RxDesc rx_desc, Rxwi0 rxwi0,
                    Rxwi1 rxwi1, Rxwi2 rxwi2, Rxwi3 rxwi3) {
#if RALINK_DUMP_RX_UCAST_ONLY
    if (rx_desc.unicast_to_me() != 1) { return; }
#endif  // RALINK_DUMP_RX_UCAST_ONLY

#if RALINK_DUMP_RX

    {  // Length validation
        // TODO(porce): If a warning takes place, it means there is room
        // for improvement on the best understanding how the USB read chunk
        // structure, which is experimentally learned.
        auto len1 = request->response.actual;
        auto len2 = rx_info.usb_dma_rx_pkt_len();
        auto len3 = rxwi0.mpdu_total_byte_count();
        auto len4 = rx_desc.l2pad() == 1 ? 2 : 0;

        if (len1 != len2 + 8 || len1 % 4 != 0) { debugf("[ralink] USB read size incongruous)\n"); }
        debugf(
            "[ralink] USB read size : response.actual %zu usb_dma_rx_pkt_len "
            "%u rx_hdr_size %zu mpdu_total_byte_count %u l2pad_len %u\n",
            len1, len2, rx_hdr_size, len3, len4);
    }

    uint8_t* data;
    usb_request_mmap(request, reinterpret_cast<void**>(&data));
    debugf("# Rxed packet: rx_len=%" PRIu64 "\n", request->response.actual);
    debugf("  rxinfo: usb_dma_rx_pkt_len=%u\n", rx_info.usb_dma_rx_pkt_len());
    debugf("  rxdesc: ba=%u data=%u nulldata=%u frag=%u unicast_to_me=%u multicast=%u\n",
           rx_desc.ba(), rx_desc.data(), rx_desc.nulldata(), rx_desc.frag(),
           rx_desc.unicast_to_me(), rx_desc.multicast());
    debugf(
        "          broadcast=%u my_bss=%u crc_error=%u cipher_error=%u amsdu=%u htc=%u "
        "rssi=%u\n",
        rx_desc.broadcast(), rx_desc.my_bss(), rx_desc.crc_error(), rx_desc.cipher_error(),
        rx_desc.amsdu(), rx_desc.htc(), rx_desc.rssi());
    debugf(
        "          l2pad=%u ampdu=%u decrypted=%u plcp_rssi=%u cipher_alg=%u last_amsdu=%u "
        "plcp_signal=0x%04x\n",
        rx_desc.l2pad(), rx_desc.ampdu(), rx_desc.decrypted(), rx_desc.plcp_rssi(),
        rx_desc.cipher_alg(), rx_desc.last_amsdu(), rx_desc.plcp_signal());
    debugf(
        "  rxwi0 : wcid=0x%02x key_idx=%u bss_idx=%u udf=0x%02x "
        "mpdu_total_byte_count=%u tid=0x%02x\n",
        rxwi0.wcid(), rxwi0.key_idx(), rxwi0.bss_idx(), rxwi0.udf(), rxwi0.mpdu_total_byte_count(),
        rxwi0.tid());
    debugf("  rxwi1 : frag=%u seq=%u mcs=0x%02x bw=%u sgi=%u stbc=%u phy_mode=%u\n", rxwi1.frag(),
           rxwi1.seq(), rxwi1.mcs(), rxwi1.bw(), rxwi1.sgi(), rxwi1.stbc(), rxwi1.phy_mode());
    debugf("  rxwi2 : rssi0=%u rssi1=%u rssi2=%u\n", rxwi2.rssi0(), rxwi2.rssi1(), rxwi2.rssi2());
    debugf("  rxwi3 : snr0=%u snr1=%u\n", rxwi3.snr0(), rxwi3.snr1());

    finspect("[Ralink] Inbound USB request:\n");
    finspect("  Dump: %s\n", wlan::debug::HexDump(data, request->response.actual).c_str());
#endif  // RALINK_DUMP_RX
}

static const uint8_t kDataRates[4][8] = {
    // clang-format off
    // Legacy CCK
    { 2, 4, 11, 22, 0, 0, 0, 0, },
    // Legacy OFDM
    { 12, 18, 24, 36, 48, 72, 96, 108, },
    // HT Mix mode
    { 13, 26, 39, 52, 78, 104, 117, 130, },
    // HT Greenfield
    { 13, 26, 39, 52, 78, 104, 117, 130, },
    // clang-format on
};

static uint8_t ralink_mcs_to_rate(uint8_t phy_mode, uint8_t mcs, bool is_40mhz, bool is_sgi) {
    uint8_t rate = 0;            // Mbps * 2
    uint8_t rate_tbl_idx = 255;  // Init with invalid idx.
    uint8_t nss = 1;             // Minimum NSS

    if (phy_mode >= fbl::count_of(kDataRates)) { return rate; }

    switch (phy_mode) {
    case PhyMode::kLegacyCck:
        if (mcs <= kLongPreamble11Mbps) {
            // Long preamble case
            rate_tbl_idx = mcs;
        } else if (kShortPreamble1Mbps <= mcs && mcs <= kShortPreamble11Mbps) {
            // Short preamble case
            rate_tbl_idx = mcs - kShortPreamble1Mbps;
        } else {
            warnf("ralink: illegal mcs for phy %u mcs %u is_40mhz %u is_sgi %u\n", phy_mode, mcs,
                  is_40mhz, is_sgi);
            return rate;
        }
        break;
    case PhyMode::kLegacyOfdm:
        rate_tbl_idx = mcs;
        break;
    case PhyMode::kHtMixMode:
        // fallthrough
    case PhyMode::kHtGreenfield:
        if (mcs == kHtDuplicateMcs) {
            // 40MHz, ShortGuardInterval case: HT duplicate 6 Mbps.
            rate_tbl_idx = 0;
        } else if (mcs < kHtDuplicateMcs) {
            rate_tbl_idx = mcs % fbl::count_of(kDataRates[0]);
            nss = 1 + mcs / fbl::count_of(kDataRates[0]);
        } else {
            rate_tbl_idx = mcs;
        }
        break;
    default:
        warnf("ralink: unknown phy %u with mcs %u is_40mhz %u is_sgi %u\n", phy_mode, mcs, is_40mhz,
              is_sgi);
        return rate;
    }

    if (rate_tbl_idx >= fbl::count_of(kDataRates[0])) {
        warnf("ralink: illegal rate_tbl_idx %u for phy %u mcs %u is_40mhz %u is_sgi %u\n",
              rate_tbl_idx, phy_mode, mcs, is_40mhz, is_sgi);
        return rate;
    }

    rate = kDataRates[phy_mode][rate_tbl_idx] * nss;
    if (is_40mhz) {
        // 802.11n case
        // Set the multipler by the ratio of the subcarriers, not by the ratio of the bandwidth
        // rate *= 2.0769;          // Correct
        // rate *= (40MHz / 20MHz); // Incorrect

        constexpr uint8_t subcarriers_data_40 = 108;  // counts
        constexpr uint8_t subcarriers_data_20 = 52;   // counts
        rate = rate * subcarriers_data_40 / subcarriers_data_20;
    }
    if (is_sgi) { rate = static_cast<uint8_t>((static_cast<uint16_t>(rate) * 10) / 9); }

    return rate;
}

static uint16_t ralink_phy_to_ddk_phy(uint8_t ralink_phy) {
    switch (ralink_phy) {
    case PhyMode::kLegacyCck:
        return WLAN_PHY_CCK;
    case PhyMode::kLegacyOfdm:
        return WLAN_PHY_OFDM;
    case PhyMode::kHtMixMode:
    case PhyMode::kHtGreenfield:
        // TODO(tkilbourn): set a bit somewhere indicating greenfield format, if we ever support
        // it.
        return WLAN_PHY_HT;
    default:
        warnf("received unknown PHY: %u\n", ralink_phy);
        ZX_DEBUG_ASSERT(0);  // TODO: Define Undefined Phy in DDK.
        return 0;            // Happy compiler
    }
}

static uint8_t ddk_phy_to_ralink_phy(uint16_t ddk_phy) {
    switch (ddk_phy) {
    case WLAN_PHY_CCK:
        return PhyMode::kLegacyCck;
    case WLAN_PHY_OFDM:
        return PhyMode::kLegacyOfdm;
    case WLAN_PHY_HT:
        return PhyMode::kHtMixMode;
    default:
        warnf("invalid DDK phy: %u. Fallback to PHY_OFDM\n", ddk_phy);
        return PhyMode::kLegacyOfdm;
    }
}

static uint8_t mcs_to_ralink_mcs(uint8_t vendor_phy_mode, uint8_t mcs) {
    // TODO(porce): Translate Rate index in each phy to ralink MCS values
    // For LegacyOFDM:
    // Standard MCS index: 13, 16, 5, 7, 9, 11, 1, 3 map to 6, 9, 12, 18, 24, 36, 48, 54 Mbps
    // which in turns maps to Ralink MCS index: 0, 1, 2, 3, 4, 5, 6, 7.

    // For CCK,
    // Ralink supports 0 to 3, mapping to 1, 2, 5.5, 11 Mbps, for long preamble.
    // Add value 8 to mcs index for short preamble.
    return mcs;
}

static void fill_rx_info(wlan_rx_info_t* info, RxDesc rx_desc, Rxwi1 rxwi1, Rxwi2 rxwi2,
                         Rxwi3 rxwi3, uint8_t* rssi_offsets, uint8_t lna_gain) {
    if (rx_desc.l2pad()) { info->rx_flags |= WLAN_RX_INFO_FLAGS_FRAME_BODY_PADDING_4; }
    info->valid_fields |= WLAN_RX_INFO_VALID_PHY;
    info->phy = ralink_phy_to_ddk_phy(rxwi1.phy_mode());

    uint8_t rate = ralink_mcs_to_rate(rxwi1.phy_mode(), rxwi1.mcs(), rxwi1.bw(), rxwi1.sgi());
    if (rate != 0) {
        info->valid_fields |= WLAN_RX_INFO_VALID_DATA_RATE;
        info->data_rate = rate;
    }

    info->valid_fields |= WLAN_RX_INFO_VALID_CHAN_WIDTH;
    // TODO(porce): Study how to distinguish CBW40ABOVE from CBW40BELOW, from rxwi.
    info->chan.cbw = rxwi1.bw() ? CBW40 : CBW20;

    uint8_t phy_mode = rxwi1.phy_mode();
    bool is_ht = phy_mode == PhyMode::kHtMixMode || phy_mode == PhyMode::kHtGreenfield;
    if (is_ht && rxwi1.mcs() < kMaxHtMcs) {
        info->valid_fields |= WLAN_RX_INFO_VALID_MCS;
        info->mcs = rxwi1.mcs();
    }

    // TODO(tkilbourn): check rssi1 and rssi2 and figure out what to do with them
    info->rssi_dbm = WLAN_RSSI_DBM_INVALID;
    info->rcpi_dbmh = WLAN_RCPI_DBMH_INVALID;
    info->snr_dbh = WLAN_RSNI_DBH_INVALID;

    if (rxwi2.rssi0() > 0) {
        // Use rssi offsets from the EEPROM to convert to RSSI
        auto rssi_dbm = static_cast<int8_t>(-12 - rssi_offsets[0] - lna_gain - rxwi2.rssi0());
        if (WLAN_RSSI_DBM_MIN <= rssi_dbm && rssi_dbm <= WLAN_RSSI_DBM_MAX) {
            info->valid_fields |= WLAN_RX_INFO_VALID_RSSI;
            info->rssi_dbm = rssi_dbm;
        }
    }

    // TODO(tkilbourn): check snr1 and figure out what to do with it
    if (rxwi1.phy_mode() != PhyMode::kLegacyCck && rxwi3.snr0() > 0) {
        // Convert to SNR
        auto snr_dbh = ((rxwi3.snr0() * 3 / 16) + 10) * 2;
        if (WLAN_RSNI_DBH_MIN <= snr_dbh && snr_dbh <= WLAN_RSNI_DBH_MAX) {
            info->valid_fields |= WLAN_RX_INFO_VALID_SNR;
            info->snr_dbh = snr_dbh;
        }
    }
}

void Device::HandleRxComplete(usb_request_t* request) {
    if (request->response.status == ZX_ERR_IO_REFUSED) {
        debugf("usb_reset_endpoint\n");
        usb_reset_endpoint(&usb_, rx_endpt_);
    }
    std::lock_guard<std::mutex> guard(lock_);
    auto ac = fit::defer([&]() {
        usb_request_complete_t complete = {
            .callback = &Device::ReadRequestComplete,
            .ctx = this,
        };
        usb_request_queue(&usb_, request, &complete); });

    if (request->response.status == ZX_OK) {
        // Total bytes received is (request->response.actual) bytes
        // request->response.actual := (a) + (b) + (c) + (d) + (e) + (f) + (g) + (h)
        // rf.info.usb_dma_rx_pkt_len() := (b) + (c) + (d) + (e) + (f) + (g)

        // RxInfo      :   4 bytes // (a).
        // RxWI        :  16 bytes // (b).
        // RxWI-Extra  :   8 bytes // (c). Present only for RT5592
        // MAC header  : (d) bytes // (d). (d) + (f) is rxwi0.mpdu_total_byte_count()
        // L2PAD       :   2 bytes // (e). Present only if rx_desc.l2pad() is 1
        // MAC payload : (f) bytes // (f). Start of (f) is 4-byte aligned
        // Padding     : 0~3 bytes // (g). To align in 4 bytes
        // RxDesc      :   4 bytes // (h).

        size_t rx_hdr_size = (rt_type_ == RT5592) ? 28 : 20;

        // Handle completed rx
        if (request->response.actual < rx_hdr_size + 4) {
            errorf("short read: response.actual %ld rx_hdr_size %zu\n", request->response.actual,
                   rx_hdr_size);
            return;
        }

        uint8_t* data;
        usb_request_mmap(request, reinterpret_cast<void**>(&data));
        uint32_t* data32 = reinterpret_cast<uint32_t*>(data);
        RxInfo rx_info(letoh32(data32[RxInfo::addr()]));

        if (request->response.actual < 4 + rx_info.usb_dma_rx_pkt_len()) {
            errorf("short read: response.actual %ld usb_dma_rx_pkt_len %d\n",
                   request->response.actual, rx_info.usb_dma_rx_pkt_len());
            return;
        }

        Rxwi0 rxwi0(letoh32(data32[Rxwi0::addr()]));
        Rxwi1 rxwi1(letoh32(data32[Rxwi1::addr()]));
        Rxwi2 rxwi2(letoh32(data32[Rxwi2::addr()]));
        Rxwi3 rxwi3(letoh32(data32[Rxwi3::addr()]));
        RxDesc rx_desc(*(uint32_t*)(data + 4 + rx_info.usb_dma_rx_pkt_len()));

        dump_rx(request, rx_info, rx_desc, rxwi0, rxwi1, rxwi2, rxwi3);
        if (wlanmac_proxy_ != nullptr) {
            wlan_rx_info_t wlan_rx_info = {};
            fill_rx_info(&wlan_rx_info, rx_desc, rxwi1, rxwi2, rxwi3, bg_rssi_offset_, lna_gain_);

            // Be mindful in interpretation of wlan_rx_info.chan:
            // That reflects how the radio was configured in prior,
            // and does not reflect how the incoming frame is received, which
            // shall be referred by rxwi.
            wlan_rx_info.chan = cfg_chan_;

            // TODO(porce): Pass up the byte stream after stripping off the zero padding.
            // Keep MLME ignorant of Ralink-specific L2Padding
            uint16_t mpdu_len_ota = rxwi0.mpdu_total_byte_count();
            uint16_t l2pad_len = rx_desc.l2pad() ? 2 : 0;  // 2 bytes if padded, by Ralink spec.
            uint16_t mpdu_len = mpdu_len_ota + l2pad_len;
            wlanmac_proxy_->Recv(0u, data + rx_hdr_size, mpdu_len, &wlan_rx_info);
        }

    } else {
        if (request->response.status != ZX_ERR_IO_REFUSED) {
            errorf("rx req status %d\n", request->response.status);
        }
    }
}

void Device::HandleTxComplete(usb_request_t* request) {
    if (request->response.status == ZX_ERR_IO_REFUSED) {
        debugf("usb_reset_endpoint\n");
        usb_reset_endpoint(&usb_, tx_endpts_.front());
    }
    std::lock_guard<std::mutex> guard(lock_);

    free_write_reqs_.push_back(request);
}

void Device::PhyUnbind() {
    debugfn();

    {
        std::lock_guard<std::mutex> guard(lock_);
        phy_state_ = PHY_DESTROYING;
    }

    StopInterruptPolling();
    device_remove(zxdev_);
}

void Device::PhyRelease() {
    debugfn();
    delete this;
}

void Device::MacUnbind() {
    debugfn();
    zx_device_t* dev;
    {
        std::lock_guard<std::mutex> guard(lock_);
        if (iface_state_ == IFC_DESTROYING) { return; }
        iface_state_ = IFC_DESTROYING;
        dev = wlanmac_dev_;
    }
    device_remove(dev);
}

void Device::MacRelease() {
    debugfn();
    // Do not delete this right now, as the wlanmac device shares a context with the wlanphy-impl
    // device. When the wlanphy-impl is released, then the memory will be freed. We do forget that
    // this device existed though.
    std::lock_guard<std::mutex> guard(lock_);
    wlanmac_dev_ = nullptr;
    iface_role_ = 0;
    iface_state_ = IFC_NONE;
    // Bump the iface id in case the phy isn't being released and we want to create another
    // iface.
    iface_id_++;
}

zx_status_t Device::AddPhyDevice() {
    debugfn();
    device_add_args_t args = {};
    args.version = DEVICE_ADD_ARGS_VERSION;
    args.name = "ralink-wlanphy";
    args.ctx = this;
    args.ops = &wlanphy_impl_device_ops;
    args.proto_id = ZX_PROTOCOL_WLANPHY_IMPL;
    args.proto_ops = &wlanphy_impl_ops;

    return device_add(parent_, &args, &zxdev_);
}

zx_status_t Device::AddMacDevice() {
    debugfn();
    device_add_args_t args = {};
    args.version = DEVICE_ADD_ARGS_VERSION;
    args.name = "ralink-wlanmac";
    args.ctx = this;
    args.ops = &wlanmac_device_ops;
    args.proto_id = ZX_PROTOCOL_WLANMAC;
    args.proto_ops = &wlanmac_ops;

    zx_device_t* dev;
    zx_status_t status;
    status = device_add(zxdev_, &args, &dev);
    if (status == ZX_OK) {
        std::lock_guard<std::mutex> guard(lock_);
        wlanmac_dev_ = dev;
    }
    return status;
}

zx_status_t Device::Query(wlan_info_t* info) {
    debugfn();

    memset(info, 0, sizeof(*info));
    std::memcpy(info->mac_addr, mac_addr_, ETH_MAC_SIZE);

    info->supported_phys = WLAN_PHY_DSSS | WLAN_PHY_CCK | WLAN_PHY_OFDM | WLAN_PHY_HT;
    info->mac_role = WLAN_MAC_ROLE_CLIENT;
    info->caps = WLAN_CAP_SHORT_PREAMBLE | WLAN_CAP_SHORT_SLOT_TIME;
    info->driver_features = WLAN_DRIVER_FEATURE_TX_STATUS_REPORT;
    info->num_bands = 1;
    info->bands[0] = {
        .band_id = WLAN_BAND_2GHZ,
        // These hard-coded values are experimentally proven to work,
        // but does not necessarily reflect the true capabilities of the chipset.
        .ht_supported = true,
        .ht_caps =
            {
                .ht_capability_info = 0x016e,
                .ampdu_params = 0x17,
                .supported_mcs_set =
                    {
                        // Rx MCS bitmask
                        // Supported MCS values: 0-7, 32
                        0xff,
                        0x00,
                        0x00,
                        0x00,
                        0x01,
                        0x00,
                        0x00,
                        0x00,
                        0x00,
                        0x00,
                        0x00,
                        0x00,
                        // Tx parameters
                        // - Tx MCS set defined
                        // - Tx and Rx MCS set equal
                        // - Other fields set to zero due to the first two
                        0x01,
                        0x00,
                        0x00,
                        0x00,
                    },
                // No ext capabilities (PCO, MCS feedback, HT control, RD responder)
                .ht_ext_capabilities = 0x0000,
                // No Tx beamforming
                .tx_beamforming_capabilities = 0x00000000,
                // No antenna selection
                .asel_capabilities = 0x00,
            },
        .vht_supported = false,
        .vht_caps = {},
        // TODO(NET-1375):
        // Unmark the "BasicRate" bit for the first 4 rates.
        // Rename ".basic_rates" to ".supported_rates"
        // See IEEE Std 802.11-2016, 9.4.2.3 for encoding
        .basic_rates = {0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c},
        .supported_channels =
            {
                .base_freq = 2407,
                .channels = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
            },
    };

    if (rt_type_ == RT5592) {
        info->num_bands = 2;
        // Add MCS 8-15 to band 0
        info->bands[0].ht_caps.supported_mcs_set[1] = 0xff;
        info->bands[1] = {
            .band_id = WLAN_BAND_5GHZ,
            // See above for descriptions of these capabilities
            .ht_supported = true,
            .ht_caps =
                {
                    .ht_capability_info = 0x016e,
                    .ampdu_params = 0x17,
                    .supported_mcs_set =
                        {
                            // Rx MCS bitmask
                            // Supported MCS values: 0-15, 32
                            0xff,
                            0xff,
                            0x00,
                            0x00,
                            0x01,
                            0x00,
                            0x00,
                            0x00,
                            0x00,
                            0x00,
                            0x00,
                            0x00,
                            // Tx parameters
                            0x01,
                            0x00,
                            0x00,
                            0x00,
                        },
                    .ht_ext_capabilities = 0x0000,
                    .tx_beamforming_capabilities = 0x00000000,
                    .asel_capabilities = 0x00,
                },
            .vht_supported = false,
            .vht_caps = {},
            // TODO(NET-1375):
            // Rename ".basic_rates" to ".supported_rates"
            // See IEEE Std 802.11-2016, 9.4.2.3 for encoding
            .basic_rates = {0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c},
            .supported_channels =
                {
                    .base_freq = 5000,
                    .channels =
                        {
                            36,  40,  44,  48,                                      // UNII-1
                            52,  56,  60,  64,                                      // UNII-2A
                            100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,  // UNII-2C
                            149, 153, 157, 161, 165,                                // UNII-3
                        },
                },
        };
    }

    debugf("ralink: HT capabilities for band[0]: %s\n",
           wlan::debug::Describe(info->bands[0].ht_caps).c_str());
    debugf("ralink: HT capabilities for band[1]: %s\n",
           wlan::debug::Describe(info->bands[1].ht_caps).c_str());

    return ZX_OK;
}

zx_status_t Device::PhyQuery(wlanphy_info_t* info) {
    return Query(&info->wlan_info);
}

zx_status_t Device::CreateIface(uint16_t role, uint16_t* id) {
    debugfn();

    {
        std::lock_guard<std::mutex> guard(lock_);
        if (phy_state_ != PHY_RUNNING) { return ZX_ERR_BAD_STATE; }
        if (iface_state_ != IFC_NONE) { return ZX_ERR_ALREADY_BOUND; }
        iface_state_ = IFC_CREATING;
    }

    zx_status_t status = AddMacDevice();

    if (status != ZX_OK) {
        errorf("could not add iface device err: %s\n", zx_status_get_string(status));
        std::lock_guard<std::mutex> guard(lock_);
        iface_state_ = IFC_NONE;
        return status;
    }

    {
        std::lock_guard<std::mutex> guard(lock_);
        *id = iface_id_;
        iface_role_ = role;
        iface_state_ = IFC_RUNNING;
    }

    infof("iface added\n");
    return status;
}

zx_status_t Device::DestroyIface(uint16_t id) {
    debugfn();

    zx_device_t* dev;

    {
        std::lock_guard<std::mutex> guard(lock_);
        if (phy_state_ != PHY_RUNNING || iface_state_ != IFC_RUNNING) { return ZX_ERR_BAD_STATE; }

        if (id != iface_id_) {
            errorf("unknown iface id in destroy request: %u (expected %u)\n", id, iface_id_);
            return ZX_ERR_INVALID_ARGS;
        }

        iface_state_ = IFC_DESTROYING;
        dev = wlanmac_dev_;
    }

    // device_remove() may invoke MacRelease(), so we can't hold the lock across the call
    device_remove(dev);

    return ZX_OK;
}

zx_status_t Device::WlanmacQuery(uint32_t options, wlanmac_info_t* info) {
    uint16_t role;
    {
        std::lock_guard<std::mutex> guard(lock_);
        if (phy_state_ != PHY_RUNNING || iface_state_ != IFC_RUNNING) { return ZX_ERR_BAD_STATE; }
        role = iface_role_;
    }
    zx_status_t status = Query(&info->ifc_info);
    info->ifc_info.mac_role = role;
    return status;
}

zx_status_t Device::WlanmacStart(wlanmac_ifc_t* ifc, void* cookie) {
    debugfn();
    std::lock_guard<std::mutex> guard(lock_);

    if (phy_state_ != PHY_RUNNING) { return ZX_ERR_PEER_CLOSED; }
    if (wlanmac_proxy_ != nullptr) { return ZX_ERR_ALREADY_BOUND; }

    zx_status_t status = LoadFirmware();
    if (status != ZX_OK) {
        errorf("failed to load firmware\n");
        return status;
    }

    // Initialize queues
    for (size_t i = 0; i < kReadReqCount; i++) {
        usb_request_t* req;
        zx_status_t status =
            usb_request_alloc(&req, kReadBufSize, rx_endpt_, parent_req_size_);
        if (status != ZX_OK) {
            errorf("failed to allocate rx usb request\n");
            return status;
        }
        usb_request_complete_t complete = {
            .callback = &Device::ReadRequestComplete,
            .ctx = this,
        };
        usb_request_queue(&usb_, req, &complete);
    }
    // Only one TX queue for now
    auto tx_endpt = tx_endpts_.front();
    for (size_t i = 0; i < kWriteReqCount; i++) {
        usb_request_t* req;
        zx_status_t status =
            usb_request_alloc(&req, kWriteBufSize, tx_endpt, parent_req_size_);
        if (status != ZX_OK) {
            errorf("failed to allocate tx usb request\n");
            return status;
        }
        free_write_reqs_.push_back(req);
    }

    status = EnableRadio();
    if (status != ZX_OK) {
        errorf("could not enable radio\n");
        return status;
    }

    status = StartQueues();
    if (status != ZX_OK) {
        errorf("could not start queues\n");
        return status;
    }

    status = SetupInterface();
    if (status != ZX_OK) {
        errorf("could not setup interface\n");
        return status;
    }

    // TODO(tkilbourn): configure erp?
    // TODO(tkilbourn): configure tx

    // TODO(tkilbourn): configure retry limit (move this)
    TxRtyCfg trc;
    status = ReadRegister(&trc);
    CHECK_READ(TX_RTY_CFG, status);
    trc.set_short_rty_limit(0x07);
    trc.set_long_rty_limit(0x04);
    status = WriteRegister(trc);
    CHECK_WRITE(TX_RTY_CFG, status);

    // TODO(tkilbourn): configure power save (move these)
    AutoWakeupCfg awc;
    status = ReadRegister(&awc);
    CHECK_READ(AUTO_WAKEUP_CFG, status);
    awc.set_wakeup_lead_time(0);
    awc.set_sleep_tbtt_num(0);
    awc.set_auto_wakeup_en(0);
    status = WriteRegister(awc);
    CHECK_WRITE(AUTO_WAKEUP_CFG, status);

    status = McuCommand(MCU_WAKEUP, 0xff, 0, 2);
    if (status != ZX_OK) {
        errorf("error waking MCU err=%d\n", status);
        return status;
    }

    // TODO(tkilbourn): configure antenna
    // for now I'm hardcoding some antenna values
    Bbp1 bbp1;
    status = ReadBbp(&bbp1);
    CHECK_READ(BBP1, status);
    Bbp3 bbp3;
    status = ReadBbp(&bbp3);
    CHECK_READ(BBP3, status);
    bbp3.set_val(0x00);
    bbp1.set_val(0x40);
    status = WriteBbp(bbp3);
    CHECK_WRITE(BBP3, status);
    status = WriteBbp(bbp1);
    CHECK_WRITE(BBP1, status);
    status = WriteBbp(BbpRegister<66>(0x1c));
    CHECK_WRITE(BBP66, status);

    status = SetRxFilter();
    if (status != ZX_OK) { return status; }

    wlanmac_proxy_.reset(new WlanmacIfcClient(ifc, cookie));

    wlan_channel_t chan;
    chan.primary = 1;
    chan.cbw = CBW20;
    status = WlanmacSetChannel(0, &chan);

    StartInterruptPolling();

    infof("wlan started\n");
    return ZX_OK;
}

zx_status_t Device::StartInterruptPolling() {
    // Clear all interrupts and start thread.
    IntStatus intStatus;
    auto status = ReadRegister(&intStatus);
    CHECK_READ(INT_STATUS, status);
    status = WriteRegister(intStatus);
    CHECK_WRITE(INT_STATUS, status);

    status = zx::port::create(0, &interrupt_port_);
    if (status != ZX_OK) {
        errorf("could not create port: %d\n", status);
        return status;
    }

    status = zx::timer::create(0u, ZX_CLOCK_MONOTONIC, &async_tx_interrupt_timer_);
    if (status != ZX_OK) {
        errorf("could not create async TX timer: %d\n", status);
        return status;
    }

    status = async_tx_interrupt_timer_.wait_async(interrupt_port_, kAsyncTxInterruptKey,
                                                  ZX_TIMER_SIGNALED, ZX_WAIT_ASYNC_REPEATING);
    if (status != ZX_OK) {
        errorf("could not wait on async TX timer: %d\n", status);
        return status;
    }

    status = zx::timer::create(0u, ZX_CLOCK_MONOTONIC, &tbtt_interrupt_timer_);
    if (status != ZX_OK) {
        errorf("could not create TBTT timer: %d\n", status);
        return status;
    }

    status = tbtt_interrupt_timer_.wait_async(interrupt_port_, kTbttInterruptKey, ZX_TIMER_SIGNALED,
                                              ZX_WAIT_ASYNC_REPEATING);
    if (status != ZX_OK) {
        errorf("could not wait on TBTT timer: %d\n", status);
        return status;
    }

    interrupt_thrd_ = std::thread(&Device::InterruptWorker, this);
    async_tx_interrupt_timer_.set(zx::deadline_after(kAsyncTxInterruptIdlePollInterval),
                                  kAsyncTxInterruptIdlePollSlack);
    return ZX_OK;
}

void Device::StopInterruptPolling() {
    async_tx_interrupt_timer_.cancel();
    tbtt_interrupt_timer_.cancel();
    if (interrupt_thrd_.joinable()) {
        zx_port_packet_t pkt = {
            .key = kInterruptShutdownKey,
            .type = ZX_PKT_TYPE_USER,
        };
        interrupt_port_.queue(&pkt);
        interrupt_thrd_.join();
    }
}

zx_status_t Device::OnTxReportInterruptTimer() {
    TxStatFifo stat_fifo;
    TxStatFifoExt stat_fifo_ext;
    int tracked_tx_packet_count = 0;
    while (true) {
        // TX_STAT_FIFO_EXT must be read before TX_STAT_FIFO.
        auto status = ReadRegister(&stat_fifo_ext);
        CHECK_READ(TX_STAT_FIFO_EXT, status);
        status = ReadRegister(&stat_fifo);
        CHECK_READ(TX_STAT_FIFO, status);
        if (!stat_fifo.txq_vld()) { break; }

        const int packet_id = stat_fifo.txq_pid();
        if (packet_id == kInvalidTxPacketId) { continue; }

        std::lock_guard<std::mutex> guard(lock_);
        if (wlanmac_proxy_ != nullptr) {
            wlan_tx_status report{};
            status = BuildTxStatusReport(packet_id, stat_fifo, stat_fifo_ext, &report);
            if (status == ZX_OK) {
                wlanmac_proxy_->ReportTxStatus(&report);
            } else {
                warnf("cannot build tx status report: %s.\n", zx_status_get_string(status));
            }
        }
        tracked_tx_packet_count++;
    }

    zx::duration poll_interval;
    zx::duration poll_slack;
    if (tracked_tx_packet_count < kTxStatsFifoSize / 4) {
        // Assume that the hardware is (relatively) idle, so we can afford to poll with a large
        // interval to catch any remaining long-running TX.
        poll_interval = kAsyncTxInterruptIdlePollInterval;
        poll_slack = kAsyncTxInterruptIdlePollSlack;
    } else {
        // Assume that the hardware is busy. We may see more TX completion soon.
        poll_interval = kAsyncTxInterruptBusyPollInterval;
        poll_slack = kAsyncTxInterruptBusyPollSlack;
    }
    async_tx_interrupt_timer_.set(zx::deadline_after(poll_interval), poll_slack);
    return ZX_OK;
}

zx_status_t Device::OnTbttInterruptTimer() {
    IntStatus intStatus;
    auto status = ReadRegister(&intStatus);
    CHECK_READ(INT_STATUS, status);

    const bool pre_tbtt_interrupt = intStatus.mac_int_1();
    if (pre_tbtt_interrupt) {
        {
            std::lock_guard<std::mutex> guard(lock_);
            if (wlanmac_proxy_ != nullptr) { wlanmac_proxy_->Indication(WLAN_INDICATION_PRE_TBTT); }
        }

        // Clear the pre-TBTT interrupt.
        intStatus.clear();
        intStatus.set_mac_int_1(1);
        status = WriteRegister(intStatus);
        CHECK_WRITE(INT_STATUS, status);

        // Wait for TBTT.
        zx::duration tbtt = RemainingTbttTime();
        tbtt_interrupt_timer_.set(zx::deadline_after(tbtt), zx::usec(1));
        return ZX_OK;
    }

    const bool tbtt_interrupt = intStatus.mac_int_0();
    if (tbtt_interrupt) {
        {
            // Due to Ralinks limitation of not being able to report actual beacon transmission,
            // TBTT is used instead.
            std::lock_guard<std::mutex> guard(lock_);
            if (wlanmac_proxy_ != nullptr) {
                wlanmac_proxy_->Indication(WLAN_INDICATION_BCN_TX_COMPLETE);
            }
        }

        // Clear the TBTT interrupts.
        intStatus.clear();
        intStatus.set_mac_int_0(1);
        status = WriteRegister(intStatus);
        CHECK_WRITE(INT_STATUS, status);

        // Wait for next Pre-TBTT.
        const zx::duration pre_tbtt = RemainingTbttTime() - kPreTbttLeadTime;
        tbtt_interrupt_timer_.set(zx::deadline_after(pre_tbtt), zx::usec(1));
        return ZX_OK;
    }

    // Pre-TBTT or TBTT interrupt is about to happen very soon, poll.
    tbtt_interrupt_timer_.set(zx::deadline_after(kTbttInterruptPollInterval), zx::usec(1));
    return ZX_OK;
}

zx_status_t Device::InterruptWorker() {
    const char kThreadName[] = "ralink-interrupt-worker";
    zx::thread::self()->set_property(ZX_PROP_NAME, kThreadName, sizeof(kThreadName));

    zx_port_packet_t pkt;
    for (;;) {
        zx::time timeout = zx::deadline_after(zx::sec(5));
        auto status = interrupt_port_.wait(timeout, &pkt);
        if (status == ZX_ERR_TIMED_OUT) {
            continue;
        } else if (status != ZX_OK) {
            if (status == ZX_ERR_BAD_HANDLE) {
                infof("interrupt port closed, exiting loop\n");
            } else {
                errorf("error waiting on interrupt port: %d\n", status);
            }
            break;
        }

        switch (pkt.type) {
        case ZX_PKT_TYPE_USER:
            if (pkt.key == kInterruptShutdownKey) { return ZX_OK; }
            break;
        case ZX_PKT_TYPE_SIGNAL_REP: {
            if (pkt.key == kAsyncTxInterruptKey) {
                status = OnTxReportInterruptTimer();
                if (status != ZX_OK) { return status; }
            } else if (pkt.key == kTbttInterruptKey) {
                status = OnTbttInterruptTimer();
                if (status != ZX_OK) { return status; }
            }
            break;
        }
        default:
            errorf("unknown port packet type: %u\n", pkt.type);
            break;
        }
    }
    return ZX_OK;
}

zx::duration Device::RemainingTbttTime() {
    TbttTimer tbttTimer;
    auto status = ReadRegister(&tbttTimer);
    if (status != ZX_OK) { return zx::usec(0); }
    return zx::usec(tbttTimer.tbtt_timer() * 64);
}

void Device::WlanmacStop() {
    debugfn();
    std::lock_guard<std::mutex> guard(lock_);
    StopInterruptPolling();
    // This is safe even if we're already unbound.
    wlanmac_proxy_.reset();

    // TODO(tkilbourn) disable radios, stop queues, etc.
}

// TODO(NET-1570): Extract into a common library.
uint16_t GetMacHdrLength(const uint8_t* buf, uint16_t len) {
    if (len < sizeof(wlan::FrameControl)) { return 0; }

    auto fc = reinterpret_cast<const wlan::FrameControl*>(buf);
    switch (fc->type()) {
    case wlan::FrameType::kManagement: {
        if (len < sizeof(wlan::MgmtFrameHeader)) { return 0; }
        auto hdr = reinterpret_cast<const wlan::MgmtFrameHeader*>(buf);
        return hdr->len();
    }
    case wlan::FrameType::kData: {
        if (len < sizeof(wlan::DataFrameHeader)) { return 0; }
        auto hdr = reinterpret_cast<const wlan::DataFrameHeader*>(buf);
        return hdr->len();
    }
    case wlan::FrameType::kControl: {
        if (len < sizeof(wlan::CtrlFrameHdr)) { return 0; }
        auto hdr = reinterpret_cast<const wlan::CtrlFrameHdr*>(buf);
        return hdr->len();
    }
    default:
        warnf("cannot compute MAC header length for unknown frame type: %u\n", fc->type());
        return 0;
    }
}

size_t Device::WriteBulkout(uint8_t* dest, const wlan_tx_packet_t& wlan_pkt) {
    // Write and return the length of
    // MPDU Header + L2Pad + MSDU + Bulkout Aggregation Pad + Bulkout Aggregation Tail Pad

    ZX_DEBUG_ASSERT(dest != nullptr);

    const auto head_data = static_cast<const uint8_t*>(wlan_pkt.packet_head.data_buffer);
    auto head_len = wlan_pkt.packet_head.data_size;
    uint16_t frame_hdr_len = GetMacHdrLength(head_data, head_len);
    // If the header length is invalid use the entire length as header length.
    // This is just as problematic as before but we need to put proper error handling
    // here first, before we can address this problem.
    if (frame_hdr_len == 0) { frame_hdr_len = head_len; }

    size_t dest_offset = 0;
    auto l2pad_len = ROUNDUP(frame_hdr_len, 4) - frame_hdr_len;

    // TODO(NET-649): Augument BulkoutAggregation with pointers and lengths.
    if (l2pad_len == 0) {
        std::memcpy(dest, head_data, head_len);
        dest_offset += head_len;

    } else {
        // Insert L2pad between MPDU header and MSDU
        auto msdu = head_data + frame_hdr_len;
        std::memcpy(dest, head_data, frame_hdr_len);
        dest_offset += frame_hdr_len;
        std::memset(dest + dest_offset, 0, l2pad_len);  // L2padding with zeros
        dest_offset += l2pad_len;
        std::memcpy(dest + dest_offset, msdu, head_len - frame_hdr_len);
        dest_offset += head_len - frame_hdr_len;
    }

    uint16_t tail_len_eff = 0;

    if (wlan_pkt.packet_tail != nullptr) {
        auto tail = wlan_pkt.packet_tail;
        uint16_t tail_offset = wlan_pkt.tail_offset;
        const uint8_t* tail_data = static_cast<const uint8_t*>(tail->data_buffer) + tail_offset;
        tail_len_eff = tail->data_size - tail_offset;
        std::memcpy(dest + dest_offset, tail_data, tail_len_eff);
        dest_offset += tail_len_eff;
    }

    // Append Bulkout Aggregate padding and its Tail padding
    auto payload_len = head_len + tail_len_eff + l2pad_len;
    auto aggregate_pad_len = ROUNDUP(payload_len, 4) - payload_len;
    auto extra_pad_len = aggregate_pad_len + GetBulkoutAggrTailLen();
    std::memset(dest + payload_len, 0, extra_pad_len);
    payload_len += extra_pad_len;

    finspect(
        "[ralink] WriteBulkout mpdu_len:%zu head_len:%zu tail_len_eff:%u frame_hdr_len:%u "
        "l2pad_len:%u aggr_pad_len:%zu extra_pad_len:%zu payload_len:%zu\n",
        GetMpduLen(wlan_pkt), head_len, tail_len_eff, frame_hdr_len, l2pad_len, aggregate_pad_len,
        extra_pad_len, payload_len);

    return payload_len;
}

void DumpWlanTxInfo(const wlan_tx_info_t& txinfo) {
    debugf("txinfo: tx_flags 0x%04x valid_fields 0x%04x phy %u cbw %u tx_vector_idx %u mcs %u\n",
           txinfo.tx_flags, txinfo.valid_fields, txinfo.phy, txinfo.cbw, txinfo.tx_vector_idx,
           txinfo.mcs);
}

void DumpTxwi(BulkoutAggregation* aggr) {
    if (aggr == nullptr) return;

    Txwi0& txwi0 = aggr->txwi0;
    Txwi1& txwi1 = aggr->txwi1;

    debugf("txwi:   frag %u mmps %u cfack %u ts %u ampdu %u mpdu_density %u txop %u mcs 0x%02x\n",
           txwi0.frag(), txwi0.mmps(), txwi0.cfack(), txwi0.ts(), txwi0.ampdu(),
           txwi0.mpdu_density(), txwi0.txop(), txwi0.mcs());
    debugf("        bw %u sgi %u stbc %u phy_mode %u ack %u nseq %u ba_win_size %u wcid 0x%02x\n",
           txwi0.bw(), txwi0.sgi(), txwi0.stbc(), txwi0.phy_mode(), txwi1.ack(), txwi1.nseq(),
           txwi1.ba_win_size(), txwi1.wcid());
    debugf("        mpdu_total_byte_count %u tx_packet_id 0x%x\n", txwi1.mpdu_total_byte_count(),
           txwi1.tx_packet_id());
}

zx_status_t Device::WlanmacEnableBeaconing(uint32_t options, bool enabled) {
    return EnableHwBcn(enabled);
}

zx_status_t Device::WlanmacConfigureBeacon(uint32_t options, wlan_tx_packet_t* bcn_pkt) {
    ZX_DEBUG_ASSERT(bcn_pkt != nullptr);
    if (bcn_pkt == nullptr) { return ZX_ERR_INVALID_ARGS; }

    auto aggr_payload_len = GetBulkoutAggrPayloadLen(*bcn_pkt);
    size_t req_len = sizeof(TxInfo) + aggr_payload_len + GetBulkoutAggrTailLen();

    if (req_len > kMaxBeaconSizeByte) {
        errorf("Beacon exceeds limit of %zu bytes: %zu\n", kMaxBeaconSizeByte, req_len);
        return ZX_ERR_BUFFER_TOO_SMALL;
    }
    auto buf = fbl::unique_ptr<uint8_t[]>(new uint8_t[req_len]);
    auto aggr = reinterpret_cast<BulkoutAggregation*>(buf.get());
    auto status = FillAggregation(aggr, bcn_pkt, kInvalidTxPacketId, aggr_payload_len);
    if (status != ZX_OK) {
        errorf("could not fill usb request packet: %d\n", status);
        return status;
    }

    BcnOffset0 bcnOffset0;
    status = ReadRegister(&bcnOffset0);
    CHECK_READ(BCN_OFFSET_0, status);

    // The Beacon layout in shared memory does not include TxInfo. Hence, skip it.
    auto data = buf.get() + sizeof(TxInfo);
    uint8_t* data_end = data + req_len - sizeof(TxInfo);
    uint16_t index = BEACON_BASE + bcnOffset0.bcn0_offset() * kBeaconOffsetFactorByte;

    // Write Beacon in chunks to the device.
    const size_t max_chunk_size = 64;
    for (; data_end - data > 0; data += max_chunk_size, index += max_chunk_size) {
        size_t writing = std::min(max_chunk_size, static_cast<size_t>(data_end - data));
        status = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kMultiWrite, 0, index,
                                 ZX_TIME_INFINITE, data, writing);
        if (status != ZX_OK) {
            std::printf("error writing Beacon to offset 0x%4x: %d\n", index, status);
            return ZX_ERR_IO;
        }
    }

    // Ensure hardware Beacons are activated.
    EnableHwBcn(true);

    return ZX_OK;
}

zx_status_t Device::WlanmacQueueTx(uint32_t options, wlan_tx_packet_t* wlan_pkt) {
    ZX_DEBUG_ASSERT(wlan_pkt != nullptr);

    auto aggr_payload_len = GetBulkoutAggrPayloadLen(*wlan_pkt);
    size_t usb_request_len = sizeof(TxInfo) + aggr_payload_len + GetBulkoutAggrTailLen();
    if (usb_request_len > kWriteBufSize) {
        errorf("usb request buffer size insufficient for tx packet -- %zu bytes needed\n",
               usb_request_len);
        return ZX_ERR_BUFFER_TOO_SMALL;
    }

    usb_request_t* req = nullptr;
    {
        std::lock_guard<std::mutex> guard(lock_);
        if (free_write_reqs_.empty()) {
            // No free write requests! Drop the packet.
            // TODO(tkilbourn): buffer the wlan_tx_packet_ts.
            static int failed_writes = 0;
            if (failed_writes++ % 50 == 0) { warnf("dropping tx; no free usb requests\n"); }
            return ZX_ERR_IO;
        }
        req = free_write_reqs_.back();
        free_write_reqs_.pop_back();
    }
    ZX_DEBUG_ASSERT(req != nullptr);

    BulkoutAggregation* aggr;
    auto status = usb_request_mmap(req, reinterpret_cast<void**>(&aggr));
    if (status != ZX_OK) {
        errorf("could not map usb request: %d\n", status);
        std::lock_guard<std::mutex> guard(lock_);
        free_write_reqs_.push_back(req);
        return status;
    }

    // Record the packet to be transmitted in the packet TX stats FIFO.
    const int packet_id = AddTxStatsFifoEntry(*wlan_pkt);
    if (packet_id != kInvalidTxPacketId) {
        // The TX hardware will become busy.  Begin firing the timer immediately.
        async_tx_interrupt_timer_.set(zx::deadline_after(zx::msec(0)),
                                      kAsyncTxInterruptBusyPollSlack);
    }

    status = FillAggregation(aggr, wlan_pkt, packet_id, aggr_payload_len);
    if (status != ZX_OK) {
        errorf("could not fill usb request packet: %d\n", status);
        return status;
    }

    // Send the whole thing
    req->header.length = usb_request_len;
    usb_request_complete_t complete = {
        .callback = &Device::WriteRequestComplete,
        .ctx = this,
    };
    usb_request_queue(&usb_, req, &complete);

#if RALINK_DUMP_TX
    debugf("[Ralink] Outbound WLAN packet meta info\n");
    DumpWlanTxInfo(wlan_pkt->info);
    DumpTxwi(aggr);
    DumpLengths(*wlan_pkt, aggr, req);
#endif  // RALINK_DUMP_TX

    return ZX_OK;
}

Device::TxStatsFifoEntry Device::RemoveTxStatsFifoEntry(int packet_id) {
    // The entry in tx_stats_fifo_ is indexed by packet ID.
    ZX_DEBUG_ASSERT(kInvalidTxPacketId < packet_id && packet_id < kTxStatsFifoSize);
    TxStatsFifoEntry entry = tx_stats_fifo_[packet_id];

    tx_stats_fifo_[packet_id].in_use = false;
    return entry;
}

int Device::AddTxStatsFifoEntry(const wlan_tx_packet_t& wlan_pkt) {
    if ((wlan_pkt.info.valid_fields & WLAN_TX_INFO_VALID_TX_VECTOR_IDX) == 0) {
        return kInvalidTxPacketId;
    }

    std::lock_guard<std::mutex> guard(lock_);
    // 0 is reserved as invalid packet ID (e.g. for beacon frames); the hardware appears to
    // ignore the TX stats registers when packet ID 0 is used. Hence, tx_stats_fifo_counter_
    // iterates on the interval [0, kTxStatsFifoSize - 1) so we generate TX packet IDs on the
    // interval [1, kTxStatsFifoSize).
    const int packet_id = tx_stats_fifo_counter_ + 1;
    static size_t num_overrun = 0;
    static size_t max_overrun = 0;
    TxStatsFifoEntry& tx_stats = tx_stats_fifo_[packet_id];
    if (!tx_stats_fifo_[packet_id].in_use) {
        if (num_overrun > 0) {
            if (num_overrun > max_overrun) {
                debugmstl(
                    "Recovered from a tx_stats_fifo_ overrun. max backlog increased: %zu -> %zu\n",
                    max_overrun, num_overrun);
                max_overrun = num_overrun;
            }
            num_overrun = 0;
        }
        tx_stats_fifo_counter_ = (tx_stats_fifo_counter_ + 1) % (kTxStatsFifoSize - 1);
        const auto bytes = static_cast<const uint8_t*>(wlan_pkt.packet_head.data_buffer);
        auto addr1_offset = bytes + kMacHdrAddr1Offset;
        std::copy(addr1_offset, addr1_offset + wlan::common::kMacAddrLen, tx_stats.peer_addr);
        tx_stats.tx_vector_idx = wlan_pkt.info.tx_vector_idx;
        tx_stats.in_use = true;
        return packet_id;
    } else {
        ++num_overrun;
        return kInvalidTxPacketId;
    }
}

::wlan::TxVector FromStatFifoRegister(const TxStatFifo& stat_fifo) {
    return ::wlan::TxVector{
        .phy = static_cast<PHY>(ralink_phy_to_ddk_phy(stat_fifo.txq_phy())),
        .cbw = stat_fifo.txq_bw() == 1 ? CBW40 : CBW20,
        .gi = stat_fifo.txq_sgi() == 1 ? WLAN_GI_400NS : WLAN_GI_800NS,
        .mcs_idx = stat_fifo.txq_mcs(),
    };
}

zx_status_t FillTxStatusEntries(tx_vec_idx_t vec_idx_first, tx_vec_idx_t vec_idx_last,
                                const TxStatFifo& stat_fifo, const uint8_t num_retries,
                                wlan_tx_status_entry_t* entries) {
    if (vec_idx_first < vec_idx_last) {
        debugmstl("invalid retry chain. first: %u < last: %u\n", vec_idx_first, vec_idx_last);
        ZX_DEBUG_ASSERT(0);
        return ZX_ERR_INTERNAL;
    }

    if (num_retries == 1) {
        // report first and last tx vectors only when there is only one retry
        // because in such cases ralink doesn't always follow the fallback-by-one rule.
        entries[0].tx_vector_idx = vec_idx_first;
        entries[0].attempts = 1;
        entries[1].tx_vector_idx = vec_idx_last;
        entries[1].attempts = 1;
        return ZX_OK;
    }

    uint8_t idx = 0;
    for (idx = 0; idx < WLAN_TX_STATUS_MAX_ENTRY && vec_idx_last + idx <= vec_idx_first; ++idx) {
        entries[idx].tx_vector_idx = vec_idx_first - idx;
        entries[idx].attempts = 1;
    }
    --idx;

    if (vec_idx_first != vec_idx_last + idx) {
        return ZX_ERR_INTERNAL;
    } else if (num_retries >= idx) {
        entries[idx].attempts += num_retries - idx;
    } else {
        // Occasionally the number of MCS fall-back can be larger than the number of
        // retries, when that happens, assume the retry chain is correct and the retry count
        // is incorrect. This seems to conform to the experimental results.
        debugmstl(
            "error parsing retry chain. intended %s, final: %s, "
            "retry_actual: %u, retry_calculated: %d, success: %u, stat_fifo: %x, \n",
            ::wlan::debug::Describe(vec_idx_first).c_str(),
            ::wlan::debug::Describe(vec_idx_last).c_str(), num_retries, idx, stat_fifo.txq_ok(),
            stat_fifo.val());
    }

    return ZX_OK;
}

zx_status_t Device::BuildTxStatusReport(int packet_id, const TxStatFifo& stat_fifo,
                                        const TxStatFifoExt& stat_fifo_ext,
                                        wlan_tx_status* report) {
    if (report == nullptr) { return ZX_ERR_INVALID_ARGS; }

    ::wlan::TxVector vec_last = FromStatFifoRegister(stat_fifo);
    tx_vec_idx_t idx_last;
    zx_status_t status = vec_last.ToIdx(&idx_last);
    ZX_DEBUG_ASSERT(status == ZX_OK);

    // MAC addr and tx vector instructed from upper layer was put in the queue, retrieve them
    TxStatsFifoEntry entry = RemoveTxStatsFifoEntry(packet_id);

    tx_vec_idx_t idx_first = entry.tx_vector_idx;
    ::wlan::TxVector vec_first;
    status = ::wlan::TxVector::FromIdx(idx_first, &vec_first);
    ZX_DEBUG_ASSERT(status == ZX_OK);

    // Start by clearing out report, setting MAC address and success
    std::memset(report, 0, sizeof(wlan_tx_status));
    std::copy(std::begin(entry.peer_addr), std::end(entry.peer_addr),
              std::begin(report->peer_addr));
    report->success = stat_fifo.txq_ok() == 1;
    uint8_t num_retries = stat_fifo_ext.txq_rty_cnt();

    if (num_retries == 0) {
        // No retry -> The transmission is attempted at the final tx vector instead of the intended.
        if (!report->success) {
            debugmstl("error in tx_stat_info: txq_rty_cnt == 0 but txq_ok == 0.\n");
        }
        idx_first = idx_last;
        vec_first = vec_last;
    } else if (!IsEqualExceptMcs(vec_first, vec_last)) {
        // auto fallback changed something other than mcs,
        // In this case only the first and last attempt can be used
        // setting num_retries to 1 to discard the rest
        num_retries = 1;
        debugmstl("error: auto fallback involves major change: %s vs %s\n",
                  ::wlan::debug::Describe(vec_first).c_str(),
                  ::wlan::debug::Describe(vec_last).c_str());
    }

    return FillTxStatusEntries(idx_first, idx_last, stat_fifo, num_retries,
                               report->tx_status_entry);
}

zx_status_t Device::FillAggregation(BulkoutAggregation* aggr, wlan_tx_packet_t* wlan_pkt,
                                    int packet_id, size_t aggr_payload_len) {
    // FillAggregation() fills up Aggregation Header, Payload, and its Tail marker.
    // Header is in the form of TxInfo. Its length field is to carry the length
    // of the Aggregation Payload.
    // Aggregation Payload consists of TXWI, MPDU header, L2pad, MSDU, and Aggregation Padding.
    // Though the name suggests 'aggregation', this code always prepared only one unit.
    // As a result, Tail marker of 4 bytes of zero padding is always appended.

    ZX_DEBUG_ASSERT(wlan_pkt != nullptr);

    std::memset(aggr, 0, sizeof(TxInfo) + GetTxwiLen());

    // TxInfo
    aggr->tx_info.set_aggr_payload_len(aggr_payload_len);
    // TODO(tkilbourn): set these more appropriately
    const bool protected_frame = (wlan_pkt->info.tx_flags & WLAN_TX_INFO_FLAGS_PROTECTED);
    uint8_t wiv = !protected_frame;
    aggr->tx_info.set_wiv(wiv);
    aggr->tx_info.set_qsel(2);

    // TxWI
    Txwi0& txwi0 = aggr->txwi0;
    txwi0.set_frag(0);
    txwi0.set_mmps(0);
    txwi0.set_cfack(0);
    txwi0.set_ts(0);  // TODO(porce): Set it 1 for beacon or proberesp.

    // TODO(NET-567): Use the outcome of the association negotiation
    txwi0.set_ampdu(1);
    txwi0.set_mpdu_density(Txwi0::kFourUsec);  // Aruba
    txwi0.set_txop(Txwi0::kHtTxop);

    uint8_t phy_mode = ddk_phy_to_ralink_phy(WLAN_PHY_OFDM);  // Default
    if (wlan_pkt->info.valid_fields & WLAN_TX_INFO_VALID_PHY) {
        phy_mode = ddk_phy_to_ralink_phy(wlan_pkt->info.phy);
    }
    txwi0.set_phy_mode(phy_mode);

    uint8_t mcs = kMaxOfdmMcs;  // this is the same as the max HT mcs
    if (wlan_pkt->info.valid_fields & WLAN_TX_INFO_VALID_MCS) {
        mcs = mcs_to_ralink_mcs(phy_mode, wlan_pkt->info.mcs);
    }
    txwi0.set_mcs(mcs);

    uint8_t cbw = CBW20;
    if (wlan_pkt->info.valid_fields & WLAN_TX_INFO_VALID_CHAN_WIDTH) {
        cbw = wlan_pkt->info.cbw;
        // TODO(porce): Investigate how to configure txwi differently
        // for CBW40ABOVE and CBW40BELOW
    }
    txwi0.set_bw(cbw == CBW20 ? k20MHz : k40MHz);

    txwi0.set_sgi(0);   // Long guard interval for robustness
    txwi0.set_stbc(0);  // TODO(porce): Define the value.

    // The frame header is always in the packet head.
    // If the frame requires protection, lookup the matching WCID.
    uint8_t wcid = kWcidUnknown;
    if (protected_frame) {
        if (wlan_pkt->packet_head.data_size >= kMacHdrAddr1Offset + ETH_MAC_SIZE) {
            auto frame_data = static_cast<const uint8_t*>(wlan_pkt->packet_head.data_buffer);
            auto addr1 = wlan::common::MacAddr(frame_data + kMacHdrAddr1Offset);

            auto wcid_lookup = GetWcid(addr1);
            if (wcid_lookup) {
                wcid = wcid_lookup.value();
            } else {
                auto fc = reinterpret_cast<const wlan::FrameControl*>(frame_data);
                warnf("no WCID found for protected frame: %u %u\n", fc->type(), fc->subtype());
            }
        }
    }

    Txwi1& txwi1 = aggr->txwi1;
    txwi1.set_ack(GetRxAckPolicy(*wlan_pkt));
    txwi1.set_nseq(0);

    // TODO(porce): Study if BlockAck window size can change without resetting the radio
    // upon completing the BlockAck session negotiation at MLME layer.
    // Separate the workflow for the BlockAck originator case from the responder case.
    txwi1.set_ba_win_size(64);
    txwi1.set_wcid(wcid);

    size_t mpdu_len = GetMpduLen(*wlan_pkt);
    txwi1.set_mpdu_total_byte_count(mpdu_len);
    txwi1.set_tx_packet_id(packet_id);

    Txwi2& txwi2 = aggr->txwi2;
    txwi2.set_iv(0);

    Txwi3& txwi3 = aggr->txwi3;
    txwi3.set_eiv(0);

    // Payload
    uint8_t* aggr_payload = aggr->payload(rt_type_);
    WriteBulkout(aggr_payload, *wlan_pkt);

    return ZX_OK;
}

zx_status_t Device::EnableHwBcn(bool active) {
    BcnTimeCfg bcnTimeCfg;
    auto status = ReadRegister(&bcnTimeCfg);
    CHECK_READ(BCN_TIME_CFG, status);
    if (bcnTimeCfg.bcn_tx_en() != active) {
        bcnTimeCfg.set_bcn_tx_en(active);
        bcnTimeCfg.set_tbtt_timer_en(active);
        status = WriteRegister(bcnTimeCfg);
        CHECK_WRITE(BCN_TIME_CFG, status);

        IntTimerEn intTimerEn;
        status = ReadRegister(&intTimerEn);
        CHECK_READ(interrupt_timer_EN, status);
        intTimerEn.set_pre_tbtt_int_en(active);
        status = WriteRegister(intTimerEn);
        CHECK_WRITE(interrupt_timer_EN, status);

        if (active) {
            const zx::duration pre_tbtt = RemainingTbttTime() - kPreTbttLeadTime;
            tbtt_interrupt_timer_.set(zx::deadline_after(pre_tbtt), zx::usec(1));
        } else {
            tbtt_interrupt_timer_.cancel();
        }
    }
    return ZX_OK;
}

zx_status_t Device::WlanmacSetChannel(uint32_t options, wlan_channel_t* chan) {
    // Beware the multiple different return paths with different recovery requirements.

    ZX_DEBUG_ASSERT(chan != nullptr);
    debugf("channel change: from %s to %s attempting..\n", wlan::common::ChanStr(cfg_chan_).c_str(),
           wlan::common::ChanStr(*chan).c_str());

    switch (chan->cbw) {  // parameter sanity check
    case CBW20:
    case CBW40ABOVE:
    case CBW40BELOW:
        break;
    default:
        errorf("%s: unsupported CBW %u\n", __FUNCTION__, chan->cbw);
        return ZX_ERR_NOT_SUPPORTED;
        break;
    }

    zx_status_t status;
    if (options != 0) {
        status = ZX_ERR_INVALID_ARGS;
        goto setchan_failure;
    }

    status = StopRxQueue();
    if (status != ZX_OK) {
        // TODO(porce): Recover fully if the RxQueue stopped in a half-way.
        errorf("could not stop rx queue (status %d)\n", status);
        goto setchan_failure;
    }

    status = ConfigureChannel(*chan);
    if (status != ZX_OK) {
        errorf("failed in channel configuration (status %d)\n", status);
        goto setchan_recover;
    }

    status = ConfigureTxPower(*chan);
    if (status != ZX_OK) {
        errorf("failed in txpower configuration (status %d)\n", status);
        goto setchan_recover;
    }

    status = StartQueues();
    if (status != ZX_OK) {
        errorf("could not start queues (status %d)\n", status);
        // Try one more time to start queues before returning.
        goto setchan_recover;
    }

    debugf("channel change: from %s to %s succeeded\n", wlan::common::ChanStr(cfg_chan_).c_str(),
           wlan::common::ChanStr(*chan).c_str());
    cfg_chan_ = *chan;
    return ZX_OK;

setchan_recover : {
    zx_status_t recover_status = StartQueues();
    if (recover_status != ZX_OK) {
        errorf("could not start queues (recover status %d)\n", recover_status);
    }
}
    // fall-through to setchan_failure

setchan_failure:
    errorf("channel change: from %s to %s failed (status %d)\n",
           wlan::common::ChanStr(cfg_chan_).c_str(), wlan::common::ChanStr(*chan).c_str(), status);

    return status;
}

zx_status_t Device::SetBss(const uint8_t* bssid) {
    MacBssidDw0 bss0;
    MacBssidDw1 bss1;
    bss0.set_mac_addr_0(bssid[0]);
    bss0.set_mac_addr_1(bssid[1]);
    bss0.set_mac_addr_2(bssid[2]);
    bss0.set_mac_addr_3(bssid[3]);
    bss1.set_mac_addr_4(bssid[4]);
    bss1.set_mac_addr_5(bssid[5]);
    bss1.set_multi_bss_mode(MultiBssIdMode::k1BssIdMode);

    auto status = WriteRegister(bss0);
    CHECK_WRITE(BSSID_DW0, status);
    status = WriteRegister(bss1);
    CHECK_WRITE(BSSID_DW1, status);

    memcpy(bssid_, bssid, ETH_MAC_SIZE);

    return ZX_OK;
}

zx_status_t Device::WlanmacConfigureBss(uint32_t options, wlan_bss_config_t* config) {
    if (options != 0) { return ZX_ERR_INVALID_ARGS; }

    // Some APs balk at being asked to associate immediately after disassociation, so add a
    // short quiesce period if we're reconnecting to one we just disconnected from (NET-1389).
    if (!std::memcmp(config->bssid, last_disconnect_bssid_, ETH_MAC_SIZE)) {
        zx::time curr_time = zx::clock::get_monotonic();
        if (curr_time - last_disconnect_time_ < kDisconnectQuiescePeriod) {
            sleep_for((last_disconnect_time_ + kDisconnectQuiescePeriod) - curr_time);
        }
    }

    zx_status_t status = SetBss(config->bssid);
    if (status != ZX_OK) { return status; }

    // Additional configurations when BSS is managed by this device.
    // This will allow offloading Beacon management to hardware.
    if (!config->remote) {
        BcnOffset0 offset;
        offset.clear();
        offset.set_bcn0_offset(0xE0);
        auto status = WriteRegister(offset);
        CHECK_WRITE(BCN_OFFSET_0, status);

        BcnTimeCfg bcnTimeCfg;
        bcnTimeCfg.set_bcn_intval(1600);
        bcnTimeCfg.set_tsf_timer_en(1);
        bcnTimeCfg.set_tsf_sync_mode(3);
        bcnTimeCfg.set_tbtt_timer_en(1);
        bcnTimeCfg.set_bcn_tx_en(0);
        status = WriteRegister(bcnTimeCfg);
        CHECK_WRITE(BCN_TIME_CFG, status);

        TbttSyncCfg tsc;
        tsc.set_tbtt_adjust(0);
        tsc.set_bcn_exp_win(32);
        tsc.set_bcn_aifsn(1);
        tsc.set_bcn_cwmin(0);
        status = WriteRegister(tsc);
        CHECK_WRITE(TBTT_SYNC_CFG, status);

        // TODO(hahnr): Implement a less naive configuration for basic rate and xifs time.
        LegacyBasicRate lbr;
        lbr.set_rate_1mbps(1);
        lbr.set_rate_2mbps(1);
        lbr.set_rate_5_5mbps(1);
        lbr.set_rate_11mbps(1);
        status = WriteRegister(lbr);
        CHECK_WRITE(LEGACY_BASIC_RATE, status);

        XifsTimeCfg xtc;
        xtc.set_cck_sifs_time(16);
        xtc.set_ofdm_sifs_time(16);
        xtc.set_ofdm_xifs_time(4);
        xtc.set_eifs_time(342);
        xtc.set_bb_rxend_en(1);
        status = WriteRegister(xtc);
        CHECK_WRITE(XIFS_TIME_CFG, status);
    }

    return ZX_OK;
}

// Maps IEEE cipher suites to vendor specific cipher representations, called KeyMode.
// The word 'KeyMode' is intentionally used to prevent mixing this vendor specific cipher
// representation with IEEE's vendor specific cipher suites as specified in the last row of
// IEEE Std 802.11-2016, 9.4.2.25.2, Table 9-131.
// The KeyMode identifies a vendor supported cipher by a number and not as IEEE does by a type
// and OUI.
KeyMode Device::MapIeeeCipherSuiteToKeyMode(const uint8_t cipher_oui[3], uint8_t cipher_type) {
    if (memcmp(cipher_oui, wlan::common::cipher::kStandardOui, 3)) { return KeyMode::kUnsupported; }

    switch (cipher_type) {
    case wlan::common::cipher::kTkip:
        return KeyMode::kTkip;
    case wlan::common::cipher::kCcmp128:
        return KeyMode::kAes;
    default:
        return KeyMode::kUnsupported;
    }
}

uint8_t Device::DeriveSharedKeyIndex(uint8_t bss_idx, uint8_t key_idx) {
    return bss_idx * kGroupKeysPerBss + key_idx;
}

zx_status_t Device::WriteKey(const uint8_t key[], size_t key_len, uint16_t index, KeyMode mode) {
    KeyEntry keyEntry = {};
    switch (mode) {
    case KeyMode::kNone: {
        if (key_len != kNoProtectionKeyLen || key != nullptr) {
            errorf("invalid key length %zu; expected %hhu\n", key_len, kNoProtectionKeyLen);
            return ZX_ERR_INVALID_ARGS;
        }
        // No need for copying the key since the key should be zeroed in this KeyMode.
        break;
    }
    case KeyMode::kTkip: {
        if (key_len != wlan::common::cipher::kTkipKeyLenBytes) {
            errorf("invalid TKIP key length %zu; expected %hhu\n", key_len,
                   wlan::common::cipher::kTkipKeyLenBytes);
            return ZX_ERR_INVALID_ARGS;
        }

        memcpy(keyEntry.key, key, wlan::common::cipher::kTkipKeyLenBytes);
        break;
    }
    case KeyMode::kAes: {
        if (key_len != wlan::common::cipher::kCcmp128KeyLenBytes) {
            errorf("invalid CCMP-128 key length %zu; expected %hhu\n", key_len,
                   wlan::common::cipher::kCcmp128KeyLenBytes);
            return ZX_ERR_INVALID_ARGS;
        }

        memcpy(keyEntry.key, key, wlan::common::cipher::kCcmp128KeyLenBytes);
        break;
    }
    default:
        return ZX_ERR_NOT_SUPPORTED;
    }

    auto status = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kMultiWrite, 0, index,
                                  ZX_TIME_INFINITE, &keyEntry, sizeof(keyEntry));
    if (status != ZX_OK) {
        std::printf("Error writing Key Entry: %d\n", status);
        return ZX_ERR_IO;
    }
    return ZX_OK;
}

zx_status_t Device::WritePairwiseKey(uint8_t wcid, const uint8_t key[], size_t key_len,
                                     KeyMode mode) {
    uint16_t index = PAIRWISE_KEY_BASE + wcid * sizeof(KeyEntry);
    return WriteKey(key, key_len, index, mode);
}

zx_status_t Device::WriteSharedKey(uint8_t skey, const uint8_t key[], size_t key_len,
                                   KeyMode mode) {
    if (skey > kMaxSharedKeys) { return ZX_ERR_NOT_SUPPORTED; }

    uint16_t index = SHARED_KEY_BASE + skey * sizeof(KeyEntry);
    return WriteKey(key, key_len, index, mode);
}

zx_status_t Device::WriteWcid(uint8_t wcid, const uint8_t mac[]) {
    RxWcidEntry wcidEntry = {};
    memset(wcidEntry.ba_sess_mask, 0xFF, sizeof(wcidEntry.ba_sess_mask));
    memcpy(wcidEntry.mac, mac, sizeof(wcidEntry.mac));

    uint16_t index = RX_WCID_BASE + wcid * sizeof(wcidEntry);
    auto status = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kMultiWrite, 0, index,
                                  ZX_TIME_INFINITE, &wcidEntry, sizeof(wcidEntry));
    if (status != ZX_OK) {
        std::printf("Error writing WCID Entry: %d\n", status);
        return ZX_ERR_IO;
    }
    return ZX_OK;
}

zx_status_t Device::WriteWcidAttribute(uint8_t bss_idx, uint8_t wcid, KeyMode mode, KeyType type) {
    WcidAttrEntry wcidAttr = {};
    wcidAttr.set_keyType(type);
    wcidAttr.set_keyMode(mode & 0x07);
    wcidAttr.set_keyModeExt((mode & 0x08) >> 3);
    wcidAttr.set_bssIdx(bss_idx & 0x07);
    wcidAttr.set_bssIdxExt((bss_idx & 0x08) >> 3);
    wcidAttr.set_rxUsrDef(4);
    auto value = wcidAttr.val();
    auto status = WriteRegister(WCID_ATTR_BASE + wcid * sizeof(value), value);
    CHECK_WRITE(WCID_ATTRIBUTE, status);
    return ZX_OK;
}

zx_status_t Device::ResetWcid(uint8_t wcid, uint8_t skey, uint8_t key_type) {
    WriteWcid(wcid, wlan::common::kZeroMac.byte);
    WriteWcidAttribute(0, wcid, KeyMode::kNone, KeyType::kSharedKey);
    ResetIvEiv(wcid, 0, KeyMode::kNone);

    switch (key_type) {
    case WLAN_KEY_TYPE_PAIRWISE: {
        WritePairwiseKey(wcid, nullptr, kNoProtectionKeyLen, KeyMode::kNone);
        break;
    }
    case WLAN_KEY_TYPE_GROUP: {
        WriteSharedKey(skey, nullptr, kNoProtectionKeyLen, KeyMode::kNone);
        WriteSharedKeyMode(skey, KeyMode::kNone);
        break;
    }
    default:
        break;
    }
    return ZX_OK;
}

zx_status_t Device::ResetIvEiv(uint8_t wcid, uint8_t key_id, KeyMode mode) {
    IvEivEntry ivEntry = {};
    switch (mode) {
    case KeyMode::kNone:
        break;
    case KeyMode::kTkip:
        // IEEE Std.802.11-2016, 12.5.2.2
        // fallthrough
    case KeyMode::kAes:
        // IEEE Std.802.11-2016, 12.5.3.2
        ivEntry.iv[3] = 0x20 | key_id << 6;
        break;
    default:
        return ZX_ERR_NOT_SUPPORTED;
    }

    uint16_t index = IV_EIV_BASE + wcid * sizeof(ivEntry);
    auto status = usb_control_out(&usb_, (USB_DIR_OUT | USB_TYPE_VENDOR), kMultiWrite, 0, index,
                                  ZX_TIME_INFINITE, &ivEntry, sizeof(ivEntry));
    if (status != ZX_OK) {
        std::printf("Error writing IVEIV Entry: %d\n", status);
        return ZX_ERR_IO;
    }
    return ZX_OK;
}

zx_status_t Device::WriteSharedKeyMode(uint8_t skey, KeyMode mode) {
    if (skey > kMaxSharedKeys) { return ZX_ERR_NOT_SUPPORTED; }

    SharedKeyModeEntry keyMode = {};

    uint8_t skey_idx = skey % kKeyModesPerSharedKeyMode;
    uint16_t offset = SHARED_KEY_MODE_BASE + (skey / kKeyModesPerSharedKeyMode) * 4;

    // Due to key rotation, read in existing value.
    auto status = ReadRegister(offset, &keyMode.value);
    CHECK_READ(SHARED_KEY_MODE, status);

    status = keyMode.set(skey_idx, mode);
    if (status != ZX_OK) { return status; }

    status = WriteRegister(offset, keyMode.value);
    CHECK_WRITE(SHARED_KEY_MODE, status);
    return ZX_OK;
}

std::optional<uint8_t> Device::GetWcid(const wlan::common::MacAddr& addr) {
    auto iter = addr_wcid_map_.find(addr);
    if (iter == addr_wcid_map_.end()) { return std::nullopt; }

    return {iter->second};
}

zx_status_t Device::AddPeer(const wlan::common::MacAddr& addr, uint8_t* out_wcid) {
    auto iter = addr_wcid_map_.find(addr);
    if (iter != addr_wcid_map_.end()) {
        *out_wcid = iter->second;
        return ZX_OK;
    }

    size_t wcid;
    bool no_wcid_available = used_wcid_bitmap_.Get(0, kMaxValidWcid + 1, &wcid);
    if (no_wcid_available) { return ZX_ERR_NOT_SUPPORTED; }

    auto status = used_wcid_bitmap_.SetOne(wcid);
    if (status != ZX_OK) { return status; }

    addr_wcid_map_.emplace(addr, static_cast<uint8_t>(wcid));
    *out_wcid = wcid;

    return ZX_OK;
}

zx_status_t Device::RemovePeer(const wlan::common::MacAddr& addr) {
    auto iter = addr_wcid_map_.find(addr);
    if (iter == addr_wcid_map_.end()) { return ZX_ERR_NOT_FOUND; }

    uint8_t wcid = iter->second;
    auto status = used_wcid_bitmap_.ClearOne(wcid);
    if (status != ZX_OK) { return status; }

    addr_wcid_map_.erase(iter);

    return ZX_OK;
}

zx_status_t Device::WlanmacSetKey(uint32_t options, wlan_key_config_t* key_config) {
    if (options != 0) { return ZX_ERR_INVALID_ARGS; }

    auto keyMode = MapIeeeCipherSuiteToKeyMode(key_config->cipher_oui, key_config->cipher_type);
    if (keyMode == KeyMode::kUnsupported) {
        errorf("unsupported cipher suite: %d\n", key_config->cipher_type);
        return ZX_ERR_NOT_SUPPORTED;
    }

    wlan::common::MacAddr peer_addr(key_config->peer_addr);
    uint8_t wcid = 0;
    auto status = AddPeer(peer_addr, &wcid);
    if (status != ZX_OK) { return status; }

    switch (key_config->key_type) {
    case WLAN_KEY_TYPE_PAIRWISE: {
        // The driver doesn't support multiple BSS yet. Always use bss index 0.
        uint8_t bss_idx = 0;

        // Reset everything on failure.
        auto reset = fit::defer([&]() {
            RemovePeer(peer_addr);
            ResetWcid(wcid, 0, WLAN_KEY_TYPE_PAIRWISE);
        });

        status = WriteWcid(wcid, key_config->peer_addr);
        if (status != ZX_OK) { break; }

        status = WritePairwiseKey(wcid, key_config->key, key_config->key_len, keyMode);
        if (status != ZX_OK) { break; }

        status = WriteWcidAttribute(bss_idx, wcid, keyMode, KeyType::kPairwiseKey);
        if (status != ZX_OK) { break; }

        status = ResetIvEiv(wcid, 0, keyMode);
        if (status != ZX_OK) { break; }

        reset.cancel();
        return status;
    }
    case WLAN_KEY_TYPE_GROUP: {
        // The driver doesn't support multiple BSS yet. Always use bss index 0.
        uint8_t bss_idx = 0;
        uint8_t key_idx = key_config->key_idx;
        uint8_t skey = DeriveSharedKeyIndex(bss_idx, key_idx);

        // Reset everything on failure.
        auto reset = fit::defer([&]() {
            RemovePeer(peer_addr);
            ResetWcid(wcid, skey, WLAN_KEY_TYPE_GROUP);
        });

        status = WriteSharedKey(skey, key_config->key, key_config->key_len, keyMode);
        if (status != ZX_OK) { break; }

        status = WriteSharedKeyMode(skey, keyMode);
        if (status != ZX_OK) { break; }

        status = WriteWcid(wcid, kBcastAddr);
        if (status != ZX_OK) { break; }

        status = WriteWcidAttribute(bss_idx, wcid, keyMode, KeyType::kSharedKey);
        if (status != ZX_OK) { break; }

        status = ResetIvEiv(wcid, key_idx, keyMode);
        if (status != ZX_OK) { break; }

        reset.cancel();
        return status;
    }
    default: {
        errorf("unsupported key type: %d\n", key_config->key_type);
        return ZX_ERR_NOT_SUPPORTED;
    }
    }

    return status;
}

zx_status_t Device::WlanmacClearAssoc(uint32_t options, const uint8_t* bssid) {
    if (options != 0) { return ZX_ERR_INVALID_ARGS; }

    if (std::memcmp(bssid, bssid_, ETH_MAC_SIZE)) {
        errorf("request to disassociate from bssid we are not currently associated with\n");
        return ZX_ERR_NOT_FOUND;
    }

    // Set bssid to zeroes to force disassociation
    uint8_t null_bssid[ETH_MAC_SIZE] = {0};
    zx_status_t status = SetBss(null_bssid);
    if (status == ZX_OK) {
        last_disconnect_time_ = zx::clock::get_monotonic();
        std::memcpy(last_disconnect_bssid_, bssid, ETH_MAC_SIZE);
        std::memcpy(bssid_, null_bssid, ETH_MAC_SIZE);
    }
    return status;
}

void Device::ReadRequestComplete(void* ctx, usb_request_t* request) {
    auto dev = static_cast<Device*>(ctx);
    if (request->response.status == ZX_ERR_IO_NOT_PRESENT) {
        usb_request_release(request);
        return;
    }

    dev->HandleRxComplete(request);
}

void Device::WriteRequestComplete(void* ctx, usb_request_t* request) {
    auto dev = static_cast<Device*>(ctx);
    if (request->response.status == ZX_ERR_IO_NOT_PRESENT) {
        usb_request_release(request);
        return;
    }

    dev->HandleTxComplete(request);
}

uint8_t Device::GetRxAckPolicy(const wlan_tx_packet_t& wlan_pkt) {
    // TODO(NET-571): Honor what MLME instructs the chipset for this particular wlan_pkt
    // whether to wait for an acknowledgement from the recipient or not.
    // It appears that Ralink has its own logic to override the instruction
    // specified in txwi1.ack field. It shall be recorded here as it's found.
    return 1;  // Wait for acknowledgement
}

size_t Device::GetMpduLen(const wlan_tx_packet_t& wlan_pkt) {
    auto len = wlan_pkt.packet_head.data_size;
    if (wlan_pkt.packet_tail != nullptr) {
        if (wlan_pkt.packet_tail->data_size < wlan_pkt.tail_offset) { return ZX_ERR_INVALID_ARGS; }
        len += wlan_pkt.packet_tail->data_size - wlan_pkt.tail_offset;
    }
    return len;
}

size_t Device::GetTxwiLen() {
    return (rt_type_ == RT5592) ? 20 : 16;
}

size_t Device::GetBulkoutAggrTailLen() {
    return 4;
}

size_t Device::GetBulkoutAggrPayloadLen(const wlan_tx_packet_t& wlan_pkt) {
    // Structure of BulkoutAggregation's payload
    // TXWI            : 16 or 20 bytes // (a).
    // MPDU header     :      (b) bytes // (b).
    // L2PAD           :      0~3 bytes // (c).
    // MSDU            :      (d) bytes // (d).  (b) + (d) is mpdu_len
    // Bulkout Agg Pad :      0~3 bytes // (e).

    const auto head_data = static_cast<const uint8_t*>(wlan_pkt.packet_head.data_buffer);
    auto head_len = wlan_pkt.packet_head.data_size;
    auto has_tail = wlan_pkt.packet_tail != nullptr;
    uint16_t tail_len_eff = 0;
    if (has_tail) {
        auto tail = wlan_pkt.packet_tail;
        uint16_t tail_offset = wlan_pkt.tail_offset;
        tail_len_eff = tail->data_size - tail_offset;
    }

    auto mpdu_hdr_len = GetMacHdrLength(head_data, head_len);
    auto msdu_len = head_len + tail_len_eff - mpdu_hdr_len;

    auto l2pad_len = GetL2PadLen(wlan_pkt);

    auto aggr_payload_len = GetTxwiLen() + mpdu_hdr_len + l2pad_len + msdu_len;
    aggr_payload_len = ROUNDUP(aggr_payload_len, 4);

    finspect(
        "[ralink] head:%zu tail_eff:%u mpdu_hdr:%u msdu_len:%zu l2pad_len:%zu txwi:%zu "
        "aggr_payload_len:%zu\n",
        head_len, tail_len_eff, mpdu_hdr_len, msdu_len, l2pad_len, GetTxwiLen(), aggr_payload_len);
    return aggr_payload_len;
}

size_t Device::GetUsbReqLen(const wlan_tx_packet_t& wlan_pkt) {
    // Structure of BulkoutAggregation

    // TxInfo               :   4 bytes // (a).
    // Aggregation Payload  : (b) bytes // (b).
    // Bulkout Agg Tail Pad :   4 bytes // (c).

    return sizeof(TxInfo) + GetBulkoutAggrPayloadLen(wlan_pkt) + GetBulkoutAggrTailLen();
}

void Device::DumpLengths(const wlan_tx_packet_t& wlan_pkt, BulkoutAggregation* usb_pkt,
                         usb_request_t* req) {
    {
        size_t usb_request_hdr_len = req->header.length;
        size_t aggr_payload_len = usb_pkt->tx_info.aggr_payload_len();

        debugf("len:    usb_request_hdr:%zu usb_tx_pkt:%zu aggr_payload_len:%zu\n",
               usb_request_hdr_len, GetUsbReqLen(wlan_pkt), aggr_payload_len);
    }

    {  // wlan_pkt
        uint16_t wlan_pkt_head_len = wlan_pkt.packet_head.data_size;
        uint16_t wlan_pkt_tail_offset = wlan_pkt.tail_offset;
        bool has_wlan_pkt_tail = (wlan_pkt.packet_tail != nullptr);
        uint16_t wlan_pkt_tail_len = has_wlan_pkt_tail ? wlan_pkt.packet_tail->data_size : 0;
        debugf("        mpdu_len:%zu wlan_pkt head:%u\n", GetMpduLen(wlan_pkt), wlan_pkt_head_len);
        if (has_wlan_pkt_tail) {
            debugf("        wlan_pkt tail:%u offset:%u\n", wlan_pkt_tail_len, wlan_pkt_tail_offset);
        }
    }

    debugf("        txinfo:%zu txwi:%zu BulkoutTail:%zu\n", sizeof(TxInfo), GetTxwiLen(),
           GetBulkoutAggrTailLen());
}

size_t Device::GetL2PadLen(const wlan_tx_packet_t& wlan_pkt) {
    const auto head_data = static_cast<const uint8_t*>(wlan_pkt.packet_head.data_buffer);
    auto head_len = wlan_pkt.packet_head.data_size;
    auto frame_hdr_len = GetMacHdrLength(head_data, head_len);
    auto l2pad_len = ROUNDUP(frame_hdr_len, 4) - frame_hdr_len;

    finspect("[ralink] L2padding frame_hdr:%u l2pad:%u\n", frame_hdr_len, l2pad_len);
    return l2pad_len;
}

}  // namespace ralink
