/*
 * Copyright (c) 2010 Broadcom Corporation
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "sdio.h"

#include <lib/ddk/device.h>
#include <lib/ddk/metadata.h>
#include <lib/ddk/trace/event.h>
#include <lib/sync/completion.h>
#include <lib/zircon-internal/align.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <zircon/errors.h>
#include <zircon/status.h>

#include <algorithm>
#include <atomic>
#include <limits>

#include <wifi/wifi-config.h>

#ifndef _ALL_SOURCE
#define _ALL_SOURCE
#endif
#include <threads.h>

#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/brcm_hw_ids.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/brcmu_utils.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/brcmu_wifi.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/chip.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/chipset/firmware.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/debug.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/defs.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/inspect/device_inspect.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/linuxisms.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/netbuf.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/soc.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/timer.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/workqueue.h"

#define DCMD_RESP_TIMEOUT_MSEC (2500)

#if !defined(NDEBUG)

#define BRCMF_TRAP_INFO_SIZE 80

#define CBUF_LEN (128)

/* Device console log buffer state */
#define CONSOLE_BUFFER_MAX 2024

struct rte_console {
  /* Virtual UART
   * When there is no UART (e.g. Quickturn),
   * the host should write a complete
   * input line directly into cbuf and then write
   * the length into vcons_in.
   * This may also be used when there is a real UART
   * (at risk of conflicting with
   * the real UART).  vcons_out is currently unused.
   */
  uint vcons_in;
  uint vcons_out;

  /* Output (logging) buffer
   * Console output is written to a ring buffer log_buf at index log_idx.
   * The host may read the output when it sees log_idx advance.
   * Output will be lost if the output wraps around faster than the host
   * polls.
   */
  struct rte_log_le log_le;

  /* Console input line buffer
   * Characters are read one at a time into cbuf
   * until <CR> is received, then
   * the buffer is processed as a command line.
   * Also used for virtual UART.
   */
  uint cbuf_idx;
  char cbuf[CBUF_LEN];
};

#endif /* !defined(NDEBUG) */
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/chipcommon.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/debug.h"

#define TXQLEN 2048         /* bulk tx queue length */
#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */
#define TXLOW (TXHI - 256)  /* turn off flow control below TXLOW */
#define PRIOMASK 7

#define TXRETRIES 2 /* # of retries for tx frames */

/* Default for max rx frames in
   one scheduling */
#define BRCMF_RXBOUND 50

/* Default for max tx frames in
   one scheduling */
#define BRCMF_TXBOUND 20

#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */

/* Block size used for downloading
   of dongle image */
#define MEMBLOCK 2048
/* Must be large enough to hold
   biggest possible glom */
#define MAX_DATA_BUF (32 * 1024)

#define BRCMF_FIRSTREAD (1 << 6)

#define BRCMF_CONSOLE_INTERVAL 100 /* watchdog interval to poll console */

/* SBSDIO_DEVICE_CTL */

// clang-format off

/* 1: device will assert busy signal when receiving CMD53 */
#define SBSDIO_DEVCTL_SETBUSY       0x01
/* 1: assertion of sdio interrupt is synchronous to the sdio clock */
#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02
/* 1: mask all interrupts to host except the chipActive (rev 8) */
#define SBSDIO_DEVCTL_CA_INT_ONLY   0x04
/* 1: isolate internal sdio signals, put external pads in tri-state; requires
 * sdio bus power cycle to clear (rev 9) */
#define SBSDIO_DEVCTL_PADS_ISO      0x08
/* Force SD->SB reset mapping (rev 11) */
#define SBSDIO_DEVCTL_SB_RST_CTL    0x30
/*   Determined by CoreControl bit */
#define SBSDIO_DEVCTL_RST_CORECTL   0x00
/*   Force backplane reset */
#define SBSDIO_DEVCTL_RST_BPRESET   0x10
/*   Force no backplane reset */
#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20

/* direct(mapped) cis space */

/* MAPPED common CIS address */
#define SBSDIO_CIS_BASE_COMMON 0x1000
/* maximum bytes in one CIS */
#define SBSDIO_CIS_SIZE_LIMIT 0x200
/* cis offset addr is < 17 bits */
#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF

/* manfid tuple length, include tuple, link bytes */
#define SBSDIO_CIS_MANFID_TUPLE_LEN 6

#define SD_REG(field) (offsetof(struct sdpcmd_regs, field))

/* SDIO function 1 register CHIPCLKCSR */
/* Force ALP request to backplane */
#define SBSDIO_FORCE_ALP           0x01
/* Force HT request to backplane */
#define SBSDIO_FORCE_HT            0x02
/* Force ILP request to backplane */
#define SBSDIO_FORCE_ILP           0x04
/* Make ALP ready (power up xtal) */
#define SBSDIO_ALP_AVAIL_REQ       0x08
/* Make HT ready (power up PLL) */
#define SBSDIO_HT_AVAIL_REQ        0x10
/* Squelch clock requests from HW */
#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
/* Status: ALP is ready */
#define SBSDIO_ALP_AVAIL           0x40
/* Status: HT is ready */
#define SBSDIO_HT_AVAIL            0x80
#define SBSDIO_CSR_MASK 0x1F
#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
#define SBSDIO_ALPAV(regval) ((regval)&SBSDIO_AVBITS)
#define SBSDIO_HTAV(regval) (((regval)&SBSDIO_AVBITS) == SBSDIO_AVBITS)
#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))

/* intstatus */
#define I_SMB_SW0 (1 << 0)        /* To SB Mail S/W interrupt 0 */
#define I_SMB_SW1 (1 << 1)        /* To SB Mail S/W interrupt 1 */
#define I_SMB_SW2 (1 << 2)        /* To SB Mail S/W interrupt 2 */
#define I_SMB_SW3 (1 << 3)        /* To SB Mail S/W interrupt 3 */
#define I_SMB_SW_MASK 0x0000000f  /* To SB Mail S/W interrupts mask */
#define I_SMB_SW_SHIFT 0          /* To SB Mail S/W interrupts shift */
#define I_HMB_SW0 (1 << 4)        /* To Host Mail S/W interrupt 0 */
#define I_HMB_SW1 (1 << 5)        /* To Host Mail S/W interrupt 1 */
#define I_HMB_SW2 (1 << 6)        /* To Host Mail S/W interrupt 2 */
#define I_HMB_SW3 (1 << 7)        /* To Host Mail S/W interrupt 3 */
#define I_HMB_SW_MASK 0x000000f0  /* To Host Mail S/W interrupts mask */
#define I_HMB_SW_SHIFT 4          /* To Host Mail S/W interrupts shift */
#define I_WR_OOSYNC (1 << 8)      /* Write Frame Out Of Sync */
#define I_RD_OOSYNC (1 << 9)      /* Read Frame Out Of Sync */
#define I_PC (1 << 10)            /* descriptor error */
#define I_PD (1 << 11)            /* data error */
#define I_DE (1 << 12)            /* Descriptor protocol Error */
#define I_RU (1 << 13)            /* Receive descriptor Underflow */
#define I_RO (1 << 14)            /* Receive fifo Overflow */
#define I_XU (1 << 15)            /* Transmit fifo Underflow */
#define I_RI (1 << 16)            /* Receive Interrupt */
#define I_BUSPWR (1 << 17)        /* SDIO Bus Power Change (rev 9) */
#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */
#define I_XI (1 << 24)            /* Transmit Interrupt */
#define I_RF_TERM (1 << 25)       /* Read Frame Terminate */
#define I_WF_TERM (1 << 26)       /* Write Frame Terminate */
#define I_PCMCIA_XU (1 << 27)     /* PCMCIA Transmit FIFO Underflow */
#define I_SBINT (1 << 28)         /* sbintstatus Interrupt */
#define I_CHIPACTIVE (1 << 29)    /* chip from doze to active state */
#define I_SRESET (1 << 30)        /* CCCR RES interrupt */
#define I_IOE2 (1U << 31)         /* CCCR IOE2 Bit Changed */
#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)
#define I_DMA (I_RI | I_XI | I_ERRORS)

/* corecontrol */
#define CC_CISRDY            (1 << 0)     /* CIS Ready */
#define CC_BPRESEN           (1 << 1)     /* CCCR RES signal */
#define CC_F2RDY             (1 << 2)     /* set CCCR IOR2 bit */
#define CC_CLRPADSISO        (1 << 3)     /* clear SDIO pads isolation */
#define CC_XMTDATAAVAIL_MODE (1 << 4)
#define CC_XMTDATAAVAIL_CTRL (1 << 5)

/* SDA_FRAMECTRL */
#define SFC_RF_TERM  (1 << 0)  /* Read Frame Terminate */
#define SFC_WF_TERM  (1 << 1)  /* Write Frame Terminate */
#define SFC_CRC4WOOS (1 << 2)  /* CRC error for write out of sync */
#define SFC_ABORTALL (1 << 3)  /* Abort all in-progress frames */

/*
 * Software allocation of To SB Mailbox resources
 */

/* tosbmailbox bits corresponding to intstatus bits */
#define SMB_NAK     (1 << 0)   /* Frame NAK */
#define SMB_INT_ACK (1 << 1)   /* Host Interrupt ACK */
#define SMB_USE_OOB (1 << 2)   /* Use OOB Wakeup */
#define SMB_DEV_INT (1 << 3)   /* Miscellaneous Interrupt */

/* tosbmailboxdata */
#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version */

/*
 * Software allocation of To Host Mailbox resources
 */

/* intstatus bits */
#define I_HMB_FC_STATE I_HMB_SW0  /* Flow Control State */
#define I_HMB_FC_CHANGE I_HMB_SW1 /* Flow Control State Changed */
#define I_HMB_FRAME_IND I_HMB_SW2 /* Frame Indication */
#define I_HMB_HOST_INT I_HMB_SW3  /* Miscellaneous Interrupt */

/* tohostmailboxdata */
#define HMB_DATA_NAKHANDLED 0x0001   /* retransmit NAK'd frame */
#define HMB_DATA_DEVREADY   0x0002   /* talk to host after enable */
#define HMB_DATA_FC         0x0004   /* per prio flowcontrol update flag */
#define HMB_DATA_FWREADY    0x0008   /* fw ready for protocol activity */
#define HMB_DATA_FWHALT     0x0010   /* firmware halted */

#define HMB_DATA_FCDATA_MASK   0xff000000
#define HMB_DATA_FCDATA_SHIFT  24

#define HMB_DATA_VERSION_MASK  0x00ff0000
#define HMB_DATA_VERSION_SHIFT 16

/*
 * Software-defined protocol header
 */

/* Current protocol version */
#define SDPCM_PROT_VERSION 4

/*
 * Shared structure between dongle and the host.
 * The structure contains pointers to trap or assert information.
 */
#define SDPCM_SHARED_VERSION       0x0003
#define SDPCM_SHARED_VERSION_MASK  0x00FF
#define SDPCM_SHARED_ASSERT_BUILT  0x0100
#define SDPCM_SHARED_ASSERT        0x0200
#define SDPCM_SHARED_TRAP          0x0400

/* Space for header read, limit for data packets */
#define MAX_HDR_READ  (1 << 6)
#define MAX_RX_DATASZ 2048

// clang-format on

/* Bump up limit on waiting for HT to account for first startup;
 * if the image is doing a CRC calculation before programming the PMU
 * for HT availability, it could take a couple hundred ms more, so
 * max out at a 1 second (1000000us).
 */
#undef PMU_MAX_TRANSITION_DLY_USEC
#define PMU_MAX_TRANSITION_DLY_USEC 1000000

/* Value for ChipClockCSR during initial setup */
#define BRCMF_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ)

/* Flags for SDH calls */
#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)

#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change when idle */
#define BRCMF_IDLE_INTERVAL 1

#define KSO_WAIT_US 50
#define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY_USEC / KSO_WAIT_US)
#define BRCMF_SDIO_MAX_ACCESS_ERRORS 5

#define BC_CORE_POWER_CONTROL_RELOAD 0x2
#define BC_CORE_POWER_CONTROL_SHIFT 13

/*
 * Conversion of 802.1D priority to precedence level
 */
static uint prio2prec(uint32_t prio) {
  return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ? (prio ^ 2) : prio;
}

#if !defined(NDEBUG)
struct brcmf_trap_info {
  uint32_t type;
  uint32_t epc;
  uint32_t cpsr;
  uint32_t spsr;
  uint32_t r0;  /* a1 */
  uint32_t r1;  /* a2 */
  uint32_t r2;  /* a3 */
  uint32_t r3;  /* a4 */
  uint32_t r4;  /* v1 */
  uint32_t r5;  /* v2 */
  uint32_t r6;  /* v3 */
  uint32_t r7;  /* v4 */
  uint32_t r8;  /* v5 */
  uint32_t r9;  /* sb/v6 */
  uint32_t r10; /* sl/v7 */
  uint32_t r11; /* fp/v8 */
  uint32_t r12; /* ip */
  uint32_t r13; /* sp */
  uint32_t r14; /* lr */
  uint32_t pc;  /* r15 */
};
#endif /* !defined(NDEBUG) */

struct sdpcm_shared {
  uint32_t flags;
  uint32_t trap_addr;
  uint32_t assert_exp_addr;
  uint32_t assert_file_addr;
  uint32_t assert_line;
#if !defined(NDEBUG)
  uint32_t console_addr; /* Address of struct rte_console */
#endif                   // !defined(NDEBUG)
  uint32_t msgtrace_addr;
  uint8_t tag[32];
  uint32_t brpt_addr;
};

struct sdpcm_shared_le {
  uint32_t flags;
  uint32_t trap_addr;
  uint32_t assert_exp_addr;
  uint32_t assert_file_addr;
  uint32_t assert_line;
#if !defined(NDEBUG)
  uint32_t console_addr; /* Address of struct rte_console */
#endif                   // !defined(NDEBUG)
  uint32_t msgtrace_addr;
  uint8_t tag[32];
  uint32_t brpt_addr;
};

/* clkstate */
#define CLK_NONE 0
#define CLK_SDONLY 1
#define CLK_PENDING 2
#define CLK_AVAIL 3

#if !defined(NDEBUG)
static int qcount[NUMPRIO];
#endif /* !defined(NDEBUG) */

#define DEFAULT_SDIO_DRIVE_STRENGTH 6 /* in milliamps */

#define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL)

/* Limit on rounding up frames */
static const uint16_t max_roundup = 512;

enum brcmf_sdio_frmtype {
  BRCMF_SDIO_FT_NORMAL,
  BRCMF_SDIO_FT_SUPER,
  BRCMF_SDIO_FT_SUB,
};

#define SDIOD_DRVSTR_KEY(chip, pmu) ((((uint32_t)chip) << 16) | (pmu))

/* SDIO Pad drive strength to select value mappings */
struct sdiod_drive_str {
  uint8_t strength; /* Pad Drive Strength in mA */
  uint8_t sel;      /* Chip-specific select value */
};

/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
    {32, 0x6}, {26, 0x7}, {22, 0x4}, {16, 0x5}, {12, 0x2}, {8, 0x3}, {4, 0x0}, {0, 0x1}};

/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
    {6, 0x7}, {5, 0x6}, {4, 0x5}, {3, 0x4}, {2, 0x2}, {1, 0x1}, {0, 0x0}};

/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
    {3, 0x3}, {2, 0x2}, {1, 0x1}, {0, 0x0}};

/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
    {16, 0x7}, {12, 0x5}, {8, 0x3}, {4, 0x1}};

void pkt_align(struct brcmf_netbuf* p, int len, int align) {
  const auto datalign_unsized = reinterpret_cast<uint64_t>(p->data);
  ZX_DEBUG_ASSERT(roundup(datalign_unsized, align) - datalign_unsized <=
                  std::numeric_limits<uint32_t>::max());
  const auto datalign = static_cast<uint32_t>(roundup(datalign_unsized, align) - datalign_unsized);
  if (datalign) {
    brcmf_netbuf_shrink_head(p, datalign);
  }
  brcmf_netbuf_set_length_to(p, ZX_ROUNDUP(len, SDIOD_SIZE_ALIGNMENT));
}

/* To check if there's window offered */
static bool data_ok(struct brcmf_sdio* bus) {
  return (uint8_t)(bus->tx_max - bus->tx_seq) != 0 &&
         ((uint8_t)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
}

/*
 * Read bus->ctrl_frame_stat, and if it's value is true, acquire the lock for bus->sdiodev->func1,
 * call fn(), set bus->ctrl_frame_stat to false, and release the lock.
 */
void brcmf_sdio_if_ctrl_frame_stat_set(struct brcmf_sdio* bus, std::function<void()> fn) {
  if (bus->ctrl_frame_stat.load()) {
    sdio_claim_host(bus->sdiodev->func1);
    if (bus->ctrl_frame_stat.load()) {
      fn();
      bus->ctrl_frame_stat.store(false);
    }
    sdio_release_host(bus->sdiodev->func1);
  }
}

/*
 * Read bus->ctrl_frame_stat, and if it's value is false, acquire the lock for bus->sdiodev->func1,
 * call fn(), and release the lock.
 */
void brcmf_sdio_if_ctrl_frame_stat_clear(struct brcmf_sdio* bus, std::function<void()> fn) {
  if (!bus->ctrl_frame_stat.load()) {
    sdio_claim_host(bus->sdiodev->func1);
    if (!bus->ctrl_frame_stat.load()) {
      fn();
    }
    sdio_release_host(bus->sdiodev->func1);
  }
}

static zx_status_t brcmf_sdio_kso_control(struct brcmf_sdio* bus, bool on) {
  uint8_t wr_val = 0;
  uint8_t rd_val, cmp_val, bmask;
  zx_status_t err = ZX_OK;
  int err_cnt = 0;
  int try_cnt = 0;

  BRCMF_DBG(TRACE, "Enter: on=%d", on);

  wr_val = static_cast<uint8_t>(static_cast<uint8_t>(on) << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
  /* 1st KSO write goes to AOS wake up core if device is asleep  */
  brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);

  if (on) {
    /* device WAKEUP through KSO:
     * write bit 0 & read back until
     * both bits 0 (kso bit) & 1 (dev on status) are set
     */
    cmp_val = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK | SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK;
    bmask = cmp_val;
    zx_nanosleep(zx_deadline_after(ZX_USEC(2000)));
  } else {
    /* Put device to sleep, turn off KSO */
    cmp_val = 0;
    /* only check for bit0, bit1(dev on status) may not
     * get cleared right away
     */
    bmask = SBSDIO_FUNC1_SLEEPCSR_KSO_MASK;
  }

  do {
    /* reliable KSO bit set/clr:
     * the sdiod sleep write access is synced to PMU 32khz clk
     * just one write attempt may fail,
     * read it back until it matches written value
     */
    rd_val = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
    if (err == ZX_OK) {
      if ((rd_val & bmask) == cmp_val) {
        break;
      }
      err_cnt = 0;
    }
    /* bail out upon subsequent access errors */
    if (err != ZX_OK && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) {
      break;
    }

    zx_nanosleep(zx_deadline_after(ZX_USEC(KSO_WAIT_US)));
    brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);

  } while (try_cnt++ < MAX_KSO_ATTEMPTS);

  if (try_cnt > 2) {
    BRCMF_DBG(SDIO, "try_cnt=%d rd_val=0x%x err=%d", try_cnt, rd_val, err);
  }

  if (try_cnt > MAX_KSO_ATTEMPTS) {
    BRCMF_ERR("max tries: rd_val=0x%x err=%d", rd_val, err);
  }

  return err;
}

#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)

/* Turn backplane clock on or off */
static zx_status_t brcmf_sdio_htclk(struct brcmf_sdio* bus, bool on, bool pendok) {
  zx_status_t err;
  uint8_t clkctl, clkreq, devctl;
  zx_time_t timeout;

  BRCMF_DBG(SDIO, "Enter");

  clkctl = 0;

  if (bus->sr_enabled) {
    bus->clkstate = (on ? CLK_AVAIL : CLK_SDONLY);
    return ZX_OK;
  }

  if (on) {
    /* Request HT Avail */
    clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;

    brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
    if (err != ZX_OK) {
      BRCMF_ERR("HT Avail request error: %d", err);
      return ZX_ERR_IO_REFUSED;
    }

    /* Check current status */
    clkctl = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
    if (err != ZX_OK) {
      BRCMF_ERR("HT Avail read error: %d", err);
      return ZX_ERR_IO_REFUSED;
    }

    /* Go to pending and await interrupt if appropriate */
    if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
      /* Allow only clock-available interrupt */
      devctl = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err);
      if (err != ZX_OK) {
        BRCMF_ERR("Devctl error setting CA: %d", err);
        return ZX_ERR_IO_REFUSED;
      }

      devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
      brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_DEVICE_CTL, devctl, &err);
      BRCMF_DBG(SDIO, "CLKCTL: set PENDING");
      bus->clkstate = CLK_PENDING;

      return ZX_OK;
    } else if (bus->clkstate == CLK_PENDING) {
      /* Cancel CA-only interrupt filter */
      devctl = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err);
      devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
      brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_DEVICE_CTL, devctl, &err);
    }

    /* Otherwise, wait here (polling) for HT Avail */
    timeout = zx_clock_get_monotonic() + ZX_USEC(PMU_MAX_TRANSITION_DLY_USEC);
    while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
      clkctl = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
      if (zx_clock_get_monotonic() > timeout) {
        break;
      } else {
        zx_nanosleep(zx_deadline_after(ZX_USEC(5000)));
      }
    }
    if (err != ZX_OK) {
      BRCMF_ERR("HT Avail request error: %d", err);
      return ZX_ERR_IO_REFUSED;
    }
    if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
      BRCMF_ERR("HT Avail timeout (%d): clkctl 0x%02x", PMU_MAX_TRANSITION_DLY_USEC, clkctl);
      return ZX_ERR_SHOULD_WAIT;
    }

    /* Mark clock available */
    bus->clkstate = CLK_AVAIL;
    BRCMF_DBG(SDIO, "CLKCTL: turned ON");

#if !defined(NDEBUG)
    if (!bus->alp_only) {
      if (SBSDIO_ALPONLY(clkctl)) {
        BRCMF_ERR("HT Clock should be on");
      }
    }
#endif /* !defined(NDEBUG) */

  } else {
    clkreq = 0;

    if (bus->clkstate == CLK_PENDING) {
      /* Cancel CA-only interrupt filter */
      devctl = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err);
      devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
      brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_DEVICE_CTL, devctl, &err);
    }

    bus->clkstate = CLK_SDONLY;
    brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err);
    BRCMF_DBG(SDIO, "CLKCTL: turned OFF");
    if (err != ZX_OK) {
      BRCMF_ERR("Failed access turning clock off: %d", err);
      return ZX_ERR_IO_REFUSED;
    }
  }
  return ZX_OK;
}

/* Change idle/active SD state */
static zx_status_t brcmf_sdio_sdclk(struct brcmf_sdio* bus, bool on) {
  BRCMF_DBG(SDIO, "Enter");

  if (on) {
    bus->clkstate = CLK_SDONLY;
  } else {
    bus->clkstate = CLK_NONE;
  }

  return ZX_OK;
}

/* Transition SD and backplane clock readiness */
static zx_status_t brcmf_sdio_clkctl(struct brcmf_sdio* bus, uint target, bool pendok) {
  uint oldstate = bus->clkstate;

  BRCMF_DBG(SDIO, "Enter");

  /* Early exit if we're already there */
  if (bus->clkstate == target) {
    return ZX_OK;
  }
  if (bus->ci->chip == BRCM_CC_4359_CHIP_ID && target == CLK_NONE) {
    BRCMF_DBG(TEMP, "Returning because chip is 4359");
    return ZX_OK;
  }

  switch (target) {
    case CLK_AVAIL:
      /* Make sure SD clock is available */
      if (bus->clkstate == CLK_NONE) {
        brcmf_sdio_sdclk(bus, true);
      }
      /* Now request HT Avail on the backplane */
      brcmf_sdio_htclk(bus, true, pendok);
      break;

    case CLK_SDONLY:
      /* Remove HT request, or bring up SD clock */
      if (bus->clkstate == CLK_NONE) {
        brcmf_sdio_sdclk(bus, true);
      } else if (bus->clkstate == CLK_AVAIL) {
        brcmf_sdio_htclk(bus, false, false);
      } else {
        BRCMF_ERR("request for %d -> %d", bus->clkstate, target);
      }
      break;

    case CLK_NONE:
      /* Make sure to remove HT request */
      if (bus->clkstate == CLK_AVAIL) {
        brcmf_sdio_htclk(bus, false, false);
      }
      /* Now remove the SD clock */
      brcmf_sdio_sdclk(bus, false);
      break;
  }
  BRCMF_DBG(SDIO, "%d -> %d", oldstate, bus->clkstate);

  return ZX_OK;
}

static zx_status_t brcmf_sdio_bus_sleep(struct brcmf_sdio* bus, bool sleep, bool pendok) {
  zx_status_t err = ZX_OK;
  uint8_t clkcsr;

  BRCMF_DBG(SDIO, "Enter: request %s currently %s", (sleep ? "SLEEP" : "WAKE"),
            (bus->sleeping ? "SLEEP" : "WAKE"));

  /* If SR is enabled control bus state with KSO */
  if (bus->sr_enabled) {
    /* Done if we're already in the requested state */
    if (sleep == bus->sleeping) {
      goto end;
    }

    /* Going to sleep */
    if (sleep) {
      clkcsr = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
      if ((clkcsr & SBSDIO_CSR_MASK) == 0) {
        BRCMF_DBG(SDIO, "no clock, set ALP");
        brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_ALP_AVAIL_REQ, &err);
      }
      err = brcmf_sdio_kso_control(bus, false);
    } else {
      err = brcmf_sdio_kso_control(bus, true);
    }
    if (err != ZX_OK) {
      BRCMF_ERR("error while changing bus sleep state %d", err);
      goto done;
    }
  }

end:
  /* control clocks */
  if (sleep) {
    if (!bus->sr_enabled) {
      brcmf_sdio_clkctl(bus, CLK_NONE, pendok);
    }
  } else {
    brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
    brcmf_sdio_wd_timer(bus, true);
  }
  bus->sleeping = sleep;
  BRCMF_DBG(SDIO, "new state %s", (sleep ? "SLEEP" : "WAKE"));
done:
  BRCMF_DBG(SDIO, "Exit: err=%d", err);
  return err;
}

static inline bool brcmf_sdio_valid_shared_address(uint32_t addr) {
  return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
}

static zx_status_t __brcmf_sdio_sharedrw(struct brcmf_sdio* bus, struct sdpcm_shared* sh,
                                         bool write) {
  uint32_t addr = 0;
  zx_status_t rv;
  uint32_t shaddr = 0;

  if (write) {
    if (sh == nullptr) {
      BRCMF_ERR("Input sdpcm pointer doesn't exist");
      return ZX_ERR_INVALID_ARGS;
    }
    if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
      BRCMF_ERR("sdpcm shared version unsupported: dhd %d dongle %d", SDPCM_SHARED_VERSION,
                sh->flags & SDPCM_SHARED_VERSION_MASK);
      return ZX_ERR_WRONG_TYPE;
    }
  }

  sdio_claim_host(bus->sdiodev->func1);
  brcmf_sdio_bus_sleep(bus, false, false);

  /*
   * Read last word in socram to determine
   * address of sdpcm_shared structure
   */
  shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
  if (!bus->ci->rambase && brcmf_chip_sr_capable(bus->ci)) {
    shaddr -= bus->ci->srsize;
  }
  rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (uint8_t*)&addr, 4);
  if (rv != ZX_OK) {
    goto fail;
  }

  /*
   * Check if addr is valid.
   * NVRAM length at the end of memory should have been overwritten.
   */
  if (!brcmf_sdio_valid_shared_address(addr)) {
    BRCMF_ERR("invalid sdpcm_shared address 0x%08X", addr);
    rv = ZX_ERR_INVALID_ARGS;
    goto fail;
  }

  BRCMF_DBG(INFO, "sdpcm_shared address 0x%08X", addr);

  /* Read or write hndrte_shared structure */
  rv = brcmf_sdiod_ramrw(bus->sdiodev, write, addr, (uint8_t*)sh, sizeof(struct sdpcm_shared_le));
  if (rv != ZX_OK) {
    goto fail;
  }

  sdio_release_host(bus->sdiodev->func1);

  if (!write && (sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
    BRCMF_ERR("sdpcm shared version unsupported: dhd %d dongle %d", SDPCM_SHARED_VERSION,
              sh->flags & SDPCM_SHARED_VERSION_MASK);
    return ZX_ERR_WRONG_TYPE;
  }
  return ZX_OK;

fail:
  BRCMF_ERR("unable to %s sdpcm_shared info: rv=%d (addr=0x%x)", write ? "write" : "read", rv,
            addr);
  sdio_release_host(bus->sdiodev->func1);
  return rv;
}

static zx_status_t brcmf_sdio_shared_read(struct brcmf_sdio* bus, struct sdpcm_shared* sh) {
  return __brcmf_sdio_sharedrw(bus, sh, false);
}

static zx_status_t brcmf_sdio_shared_write(struct brcmf_sdio* bus, struct sdpcm_shared* sh) {
  return __brcmf_sdio_sharedrw(bus, sh, true);
}

#if !defined(NDEBUG)
static void brcmf_sdio_get_console_addr(struct brcmf_sdio* bus) {
  struct sdpcm_shared sh;

  if (brcmf_sdio_shared_read(bus, &sh) == ZX_OK) {
    bus->console_addr = sh.console_addr;
  }
}
#else  /* !defined(NDEBUG) */
static void brcmf_sdio_get_console_addr(struct brcmf_sdio* bus) {}
#endif /* !defined(NDEBUG) */

static uint32_t brcmf_sdio_hostmail(struct brcmf_sdio* bus) {
  struct brcmf_sdio_dev* sdiod = bus->sdiodev;
  struct brcmf_core* core = bus->sdio_core;
  uint32_t intstatus = 0;
  uint32_t hmb_data;
  uint8_t fcbits;
  zx_status_t ret;

  BRCMF_DBG(SDIO, "Enter");

  /* Read mailbox data and ack that we did so */
  hmb_data = brcmf_sdiod_func1_rl(sdiod, core->base + SD_REG(tohostmailboxdata), &ret);

  if (ret == ZX_OK) {
    brcmf_sdiod_func1_wl(sdiod, core->base + SD_REG(tosbmailbox), SMB_INT_ACK, &ret);
  }

  bus->sdcnt.f1regdata += 2;

  /* dongle indicates the firmware has halted/crashed */
  if (hmb_data & HMB_DATA_FWHALT) {
    BRCMF_ERR("mailbox indicates firmware halted");
  }

  /* Dongle recomposed rx frames, accept them again */
  if (hmb_data & HMB_DATA_NAKHANDLED) {
    BRCMF_DBG(SDIO, "Dongle reports NAK handled, expect rtx of %d", bus->rx_seq);
    if (!bus->rxskip) {
      BRCMF_ERR("unexpected NAKHANDLED!");
    }

    bus->rxskip = false;
    intstatus |= I_HMB_FRAME_IND;
  }

  /*
   * DEVREADY does not occur with gSPI.
   */
  if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
    bus->sdpcm_ver = (hmb_data & HMB_DATA_VERSION_MASK) >> HMB_DATA_VERSION_SHIFT;
    if (bus->sdpcm_ver != SDPCM_PROT_VERSION) {
      BRCMF_ERR(
          "Version mismatch, dongle reports %d, "
          "expecting %d",
          bus->sdpcm_ver, SDPCM_PROT_VERSION);
    } else {
      BRCMF_DBG(SDIO, "Dongle ready, protocol version %d", bus->sdpcm_ver);
    }

    /*
     * Retrieve console state address now that firmware should have
     * updated it.
     */
    brcmf_sdio_get_console_addr(bus);
  }

  /*
   * Flow Control has been moved into the RX headers and this out of band
   * method isn't used any more.
   * remaining backward compatible with older dongles.
   */
  if (hmb_data & HMB_DATA_FC) {
    fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT;

    if (fcbits & ~bus->flowcontrol) {
      bus->sdcnt.fc_xoff++;
    }

    if (bus->flowcontrol & ~fcbits) {
      bus->sdcnt.fc_xon++;
    }

    bus->sdcnt.fc_rcvd++;
    bus->flowcontrol = fcbits;
  }

  /* Shouldn't be any others */
  if (hmb_data & ~(HMB_DATA_DEVREADY | HMB_DATA_NAKHANDLED | HMB_DATA_FC | HMB_DATA_FWREADY |
                   HMB_DATA_FWHALT | HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) {
    BRCMF_ERR("Unknown mailbox data content: 0x%02x", hmb_data);
  }

  return intstatus;
}

static void brcmf_sdio_rxfail(struct brcmf_sdio* bus, bool abort, bool rtx) {
  struct brcmf_sdio_dev* sdiod = bus->sdiodev;
  struct brcmf_core* core = bus->sdio_core;
  uint retries = 0;
  uint16_t lastrbc;
  uint8_t hi, lo;
  zx_status_t err;

  BRCMF_ERR("%sterminate frame%s", abort ? "abort command, " : "", rtx ? ", send NAK" : "");

  if (abort) {
    brcmf_sdiod_abort(bus->sdiodev, SDIO_FN_2);
  }

  brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err);
  bus->sdcnt.f1regdata++;

  /* Wait until the packet has been flushed (device/FIFO stable) */
  for (lastrbc = retries = 0xffff; retries > 0; retries--) {
    hi = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCHI, &err);
    lo = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCLO, &err);
    bus->sdcnt.f1regdata += 2;

    if ((hi == 0) && (lo == 0)) {
      break;
    }

    if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
      BRCMF_ERR("count growing: last 0x%04x now 0x%04x", lastrbc, (hi << 8) + lo);
    }
    const auto lastrbc_unsized = (hi << 8) + lo;
    ZX_DEBUG_ASSERT(lastrbc_unsized <= std::numeric_limits<uint16_t>::max());
    lastrbc = static_cast<uint16_t>(lastrbc_unsized);
  }

  if (!retries) {
    BRCMF_ERR("count never zeroed: last 0x%04x", lastrbc);
  } else {
    BRCMF_DBG_THROTTLE(SDIO, "flush took %d iterations", 0xffff - retries);
  }

  if (rtx) {
    bus->sdcnt.rxrtx++;
    brcmf_sdiod_func1_wl(sdiod, core->base + SD_REG(tosbmailbox), SMB_NAK, &err);

    bus->sdcnt.f1regdata++;
    if (err == ZX_OK) {
      bus->rxskip = true;
    }
  }

  /* Clear partial in any case */
  bus->cur_read.len = 0;
}

static void brcmf_sdio_txfail(struct brcmf_sdio* bus) {
  struct brcmf_sdio_dev* sdiodev = bus->sdiodev;
  uint8_t i, hi, lo;

  /* On failure, abort the command and terminate the frame */
  BRCMF_ERR("sdio error, abort command and terminate frame");
  bus->sdcnt.tx_sderrs++;

  brcmf_sdiod_abort(sdiodev, SDIO_FN_2);
  brcmf_sdiod_func1_wb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
  bus->sdcnt.f1regdata++;

  for (i = 0; i < 3; i++) {
    hi = brcmf_sdiod_func1_rb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
    lo = brcmf_sdiod_func1_rb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
    bus->sdcnt.f1regdata += 2;
    if ((hi == 0) && (lo == 0)) {
      break;
    }
  }
}

/* return total length of buffer chain */
static uint brcmf_sdio_glom_len(struct brcmf_sdio* bus) {
  struct brcmf_netbuf* p;
  uint total;

  total = 0;
  brcmf_netbuf_list_for_every(&bus->glom, p) total += p->len;
  return total;
}

static void brcmf_sdio_free_glom(struct brcmf_sdio* bus) {
  struct brcmf_netbuf* cur;
  struct brcmf_netbuf* next;

  brcmf_netbuf_list_for_every_safe(&bus->glom, cur, next) {
    brcmf_netbuf_list_remove(&bus->glom, cur);
    brcmu_pkt_buf_free_netbuf(cur);
  }
}

/**
 * brcmfmac sdio bus specific header
 * This is the lowest layer header wrapped on the packets transmitted between
 * host and WiFi dongle which contains information needed for SDIO core and
 * firmware
 *
 * It consists of 3 parts: hardware header, hardware extension header and
 * software header
 * hardware header (frame tag) - 4 bytes
 * Byte 0~1: Frame length
 * Byte 2~3: Checksum, bit-wise inverse of frame length
 * hardware extension header - 8 bytes
 * Tx glom mode only, N/A for Rx or normal Tx
 * Byte 0~1: Packet length excluding hw frame tag
 * Byte 2: Reserved
 * Byte 3: Frame flags, bit 0: last frame indication
 * Byte 4~5: Reserved
 * Byte 6~7: Tail padding length
 * software header - 8 bytes
 * Byte 0: Rx/Tx sequence number
 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag
 * Byte 2: Length of next data frame, reserved for Tx
 * Byte 3: Data offset
 * Byte 4: Flow control bits, reserved for Tx
 * Byte 5: Maximum Sequence number allowed by firmware for Tx, N/A for Tx packet
 * Byte 6~7: Reserved
 */
#define SDPCM_HWHDR_LEN 4
#define SDPCM_HWEXT_LEN 8
#define SDPCM_SWHDR_LEN 8
#define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN)
/* software header */
#define SDPCM_SEQ_MASK 0x000000ff
#define SDPCM_SEQ_WRAP 256
#define SDPCM_CHANNEL_MASK 0x00000f00
#define SDPCM_CHANNEL_SHIFT 8
#define SDPCM_CONTROL_CHANNEL 0 /* Control */
#define SDPCM_EVENT_CHANNEL 1   /* Asyc Event Indication */
#define SDPCM_DATA_CHANNEL 2    /* Data Xmit/Recv */
#define SDPCM_GLOM_CHANNEL 3    /* Coalesced packets */
#define SDPCM_TEST_CHANNEL 15   /* Test/debug packets */
#define SDPCM_GLOMDESC(p) (((uint8_t*)p)[1] & 0x80)
#define SDPCM_NEXTLEN_MASK 0x00ff0000
#define SDPCM_NEXTLEN_SHIFT 16
#define SDPCM_DOFFSET_MASK 0xff000000
#define SDPCM_DOFFSET_SHIFT 24
#define SDPCM_FCMASK_MASK 0x000000ff
#define SDPCM_WINDOW_MASK 0x0000ff00
#define SDPCM_WINDOW_SHIFT 8

static inline uint8_t brcmf_sdio_getdatoffset(uint8_t* swheader) {
  uint32_t hdrvalue;
  hdrvalue = *(uint32_t*)swheader;
  return (uint8_t)((hdrvalue & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT);
}

static inline bool brcmf_sdio_fromevntchan(uint8_t* swheader) {
  uint32_t hdrvalue;
  uint8_t ret;

  hdrvalue = *(uint32_t*)swheader;
  ret = (uint8_t)((hdrvalue & SDPCM_CHANNEL_MASK) >> SDPCM_CHANNEL_SHIFT);

  return (ret == SDPCM_EVENT_CHANNEL);
}

static zx_status_t brcmf_sdio_hdparse(struct brcmf_sdio* bus, uint8_t* header,
                                      struct brcmf_sdio_hdrinfo* rd, enum brcmf_sdio_frmtype type) {
  uint16_t len, checksum;
  uint8_t rx_seq, fc, tx_seq_max;
  uint32_t swheader;

  // trace_brcmf_sdpcm_hdr(SDPCM_RX, header);

  /* hw header */
  len = *(uint16_t*)header;
  checksum = *(uint16_t*)(header + sizeof(uint16_t));
  /* All zero means no more to read */
  if (!(len | checksum)) {
    bus->rxpending = false;
    return ZX_ERR_BUFFER_TOO_SMALL;
  }
  if ((uint16_t)(~(len ^ checksum))) {
    BRCMF_ERR("HW header checksum error");
    bus->sdcnt.rx_badhdr++;
    brcmf_sdio_rxfail(bus, false, false);
    return ZX_ERR_IO;
  }
  if (len < SDPCM_HDRLEN) {
    BRCMF_ERR("HW header length error");
    return ZX_ERR_IO_DATA_INTEGRITY;
  }
  if (type == BRCMF_SDIO_FT_SUPER && (roundup(len, bus->blocksize) != rd->len)) {
    BRCMF_ERR("HW superframe header length error");
    return ZX_ERR_IO_DATA_INTEGRITY;
  }
  if (type == BRCMF_SDIO_FT_SUB && len > rd->len) {
    BRCMF_ERR("HW subframe header length error");
    return ZX_ERR_IO_DATA_INTEGRITY;
  }
  rd->len = len;

  /* software header */
  header += SDPCM_HWHDR_LEN;
  swheader = *(uint32_t*)header;
  if (type == BRCMF_SDIO_FT_SUPER && SDPCM_GLOMDESC(header)) {
    BRCMF_ERR("Glom descriptor found in superframe head");
    rd->len = 0;
    return ZX_ERR_INVALID_ARGS;
  }
  rx_seq = (uint8_t)(swheader & SDPCM_SEQ_MASK);
  rd->channel = (swheader & SDPCM_CHANNEL_MASK) >> SDPCM_CHANNEL_SHIFT;
  if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL && type != BRCMF_SDIO_FT_SUPER) {
    BRCMF_ERR("HW header length too long");
    bus->sdcnt.rx_toolong++;
    brcmf_sdio_rxfail(bus, false, false);
    rd->len = 0;
    return ZX_ERR_IO_DATA_INTEGRITY;
  }
  if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) {
    BRCMF_ERR("Wrong channel for superframe");
    rd->len = 0;
    return ZX_ERR_INVALID_ARGS;
  }
  if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL &&
      rd->channel != SDPCM_EVENT_CHANNEL) {
    BRCMF_ERR("Wrong channel for subframe");
    rd->len = 0;
    return ZX_ERR_INVALID_ARGS;
  }
  rd->dat_offset = brcmf_sdio_getdatoffset(header);
  if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) {
    BRCMF_ERR("seq %d: bad data offset", rx_seq);
    bus->sdcnt.rx_badhdr++;
    brcmf_sdio_rxfail(bus, false, false);
    rd->len = 0;
    return ZX_ERR_IO_DATA_INTEGRITY;
  }
  if (rd->seq_num != rx_seq) {
    BRCMF_DBG(SDIO, "seq %d, expected %d", rx_seq, rd->seq_num);
    bus->sdcnt.rx_badseq++;
    rd->seq_num = rx_seq;
  }
  /* no need to check the reset for subframe */
  if (type == BRCMF_SDIO_FT_SUB) {
    return ZX_OK;
  }
  rd->len_nxtfrm = (swheader & SDPCM_NEXTLEN_MASK) >> SDPCM_NEXTLEN_SHIFT;
  if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) {
    /* only warm for NON glom packet */
    if (rd->channel != SDPCM_GLOM_CHANNEL) {
      BRCMF_ERR("seq %d: next length error", rx_seq);
    }
    rd->len_nxtfrm = 0;
  }
  swheader = *(uint32_t*)(header + 4);
  fc = swheader & SDPCM_FCMASK_MASK;
  if (bus->flowcontrol != fc) {
    if (~bus->flowcontrol & fc) {
      bus->sdcnt.fc_xoff++;
    }
    if (bus->flowcontrol & ~fc) {
      bus->sdcnt.fc_xon++;
    }
    bus->sdcnt.fc_rcvd++;
    bus->flowcontrol = fc;
  }
  tx_seq_max = (swheader & SDPCM_WINDOW_MASK) >> SDPCM_WINDOW_SHIFT;
  if ((uint8_t)(tx_seq_max - bus->tx_seq) > 0x40) {
    BRCMF_ERR("tx_seq_max is %d, bus->tx_seq is %d: max tx seq number error", tx_seq_max,
              bus->tx_seq);
    bus->sdiodev->drvr->device->GetInspect()->LogSdioMaxTxSeqErr();
    tx_seq_max = bus->tx_seq + 2;
  }
  bus->tx_max = tx_seq_max;

  return ZX_OK;
}

static inline void brcmf_sdio_update_hwhdr(uint8_t* header, uint16_t frm_length) {
  *(uint16_t*)header = frm_length;
  *(((uint16_t*)header) + 1) = ~frm_length;
}

static void brcmf_sdio_hdpack(struct brcmf_sdio* bus, uint8_t* header,
                              struct brcmf_sdio_hdrinfo* hd_info) {
  uint32_t hdrval;
  uint8_t hdr_offset;

  brcmf_sdio_update_hwhdr(header, hd_info->len);
  hdr_offset = SDPCM_HWHDR_LEN;

  hdrval = hd_info->seq_num;
  hdrval |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK;
  hdrval |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK;
  *((uint32_t*)(header + hdr_offset)) = hdrval;
  *(((uint32_t*)(header + hdr_offset)) + 1) = 0;
}

static uint8_t brcmf_sdio_rxglom(struct brcmf_sdio* bus, uint8_t rxseq) {
  uint16_t dlen, totlen;
  uint8_t* dptr;
  uint8_t num = 0;
  uint16_t sublen;
  struct brcmf_netbuf* pfirst;
  struct brcmf_netbuf* pnext;

  zx_status_t errcode;
  uint8_t doff;

  struct brcmf_sdio_hdrinfo rd_new;

  TRACE_DURATION("brcmfmac:isr", "sdio_rxglom", "rxseq", TA_UINT32((uint32_t)rxseq));

  /* If packets, issue read(s) and send up packet chain */
  /* Return sequence numbers consumed? */

  BRCMF_DBG(SDIO, "start: glomd %p glom %p", bus->glomd, brcmf_netbuf_list_peek_head(&bus->glom));

  /* If there's a descriptor, generate the packet chain */
  if (bus->glomd) {
    pfirst = pnext = NULL;
    dlen = (uint16_t)(bus->glomd->len);
    dptr = bus->glomd->data;
    if (!dlen || (dlen & 1)) {
      BRCMF_ERR("bad glomd len(%d), ignore descriptor", dlen);
      dlen = 0;
    }

    for (totlen = num = 0; dlen; num++) {
      /* Get (and move past) next length */
      sublen = *(uint16_t*)(dptr);
      dlen -= sizeof(uint16_t);
      dptr += sizeof(uint16_t);
      if ((sublen < SDPCM_HDRLEN) || ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
        BRCMF_ERR("descriptor len %d bad: %d", num, sublen);
        pnext = NULL;
        break;
      }
      if (sublen % bus->sgentry_align) {
        BRCMF_ERR("sublen %d not multiple of %d", sublen, bus->sgentry_align);
      }
      totlen += sublen;

      /* For last frame, adjust read len so total
               is a block multiple */
      if (!dlen) {
        sublen += (roundup(totlen, bus->blocksize) - totlen);
        totlen = roundup(totlen, bus->blocksize);
      }

      /* Allocate/chain packet for next subframe */
      pnext = brcmu_pkt_buf_get_netbuf(sublen + bus->sgentry_align);
      if (pnext == NULL) {
        BRCMF_ERR("bcm_pkt_buf_get_netbuf failed, num %d len %d", num, sublen);
        break;
      }
      brcmf_netbuf_list_add_tail(&bus->glom, pnext);

      /* Adhere to start alignment requirements */
      pkt_align(pnext, sublen, bus->sgentry_align);
    }

    /* If all allocations succeeded, save packet chain
             in bus structure */
    if (pnext) {
      BRCMF_DBG(GLOM, "allocated %d-byte packet chain for %d subframes", totlen, num);
      if (BRCMF_IS_ON(GLOM) && bus->cur_read.len && totlen != bus->cur_read.len) {
        BRCMF_DBG(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d", bus->cur_read.len,
                  totlen, rxseq);
      }
      pfirst = pnext = NULL;
    } else {
      brcmf_sdio_free_glom(bus);
      num = 0;
    }

    /* Done with descriptor packet */
    brcmu_pkt_buf_free_netbuf(bus->glomd);
    bus->glomd = NULL;
    bus->cur_read.len = 0;
  }

  /* Ok -- either we just generated a packet chain,
           or had one from before */
  if (!brcmf_netbuf_list_is_empty(&bus->glom)) {
    if (BRCMF_IS_ON(GLOM)) {
      BRCMF_DBG(GLOM, "try superframe read, packet chain:");
      brcmf_netbuf_list_for_every(&bus->glom, pnext) {
        BRCMF_DBG(GLOM, "    %p: %p len 0x%04x (%d)", pnext, (uint8_t*)(pnext->data), pnext->len,
                  pnext->len);
      }
    }

    pfirst = brcmf_netbuf_list_peek_head(&bus->glom);
    dlen = (uint16_t)brcmf_sdio_glom_len(bus);

    /* Do an SDIO read for the superframe.  Configurable iovar to
     * read directly into the chained packet, or allocate a large
     * packet and and copy into the chain.
     */
    sdio_claim_host(bus->sdiodev->func1);
    errcode = brcmf_sdiod_recv_chain(bus->sdiodev, &bus->glom, dlen);
    sdio_release_host(bus->sdiodev->func1);
    bus->sdcnt.f2rxdata++;

    /* On failure, kill the superframe */
    if (errcode != ZX_OK) {
      BRCMF_ERR("glom read of %d bytes failed: %d", dlen, errcode);

      sdio_claim_host(bus->sdiodev->func1);
      brcmf_sdio_rxfail(bus, true, false);
      bus->sdcnt.rxglomfail++;
      brcmf_sdio_free_glom(bus);
      sdio_release_host(bus->sdiodev->func1);
      return 0;
    }

    BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(GLOM), pfirst->data, std::min<int>(pfirst->len, 48),
                       "SUPERFRAME:");

    rd_new.seq_num = rxseq;
    rd_new.len = dlen;
    sdio_claim_host(bus->sdiodev->func1);
    errcode = brcmf_sdio_hdparse(bus, pfirst->data, &rd_new, BRCMF_SDIO_FT_SUPER);
    sdio_release_host(bus->sdiodev->func1);
    if (errcode == ZX_OK) {
      const auto cur_len = rd_new.len_nxtfrm << 4;
      ZX_DEBUG_ASSERT(cur_len <= std::numeric_limits<uint16_t>::max());
      bus->cur_read.len = static_cast<uint16_t>(cur_len);

      /* Remove superframe header, remember offset */
      brcmf_netbuf_shrink_head(pfirst, rd_new.dat_offset);
    }

    num = 0;
    /* Validate all the subframe headers */
    brcmf_netbuf_list_for_every(&bus->glom, pnext) {
      /* leave when invalid subframe is found */
      if (errcode != ZX_OK) {
        break;
      }

      ZX_DEBUG_ASSERT(pnext->len <= std::numeric_limits<uint16_t>::max());
      rd_new.len = static_cast<uint16_t>(pnext->len);
      rd_new.seq_num = rxseq++;
      sdio_claim_host(bus->sdiodev->func1);
      errcode = brcmf_sdio_hdparse(bus, pnext->data, &rd_new, BRCMF_SDIO_FT_SUB);
      sdio_release_host(bus->sdiodev->func1);
      BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(GLOM), pnext->data, 32, "subframe:");

      num++;
    }

    if (errcode != ZX_OK) {
      /* Terminate frame on error */
      sdio_claim_host(bus->sdiodev->func1);
      brcmf_sdio_rxfail(bus, true, false);
      bus->sdcnt.rxglomfail++;
      brcmf_sdio_free_glom(bus);
      sdio_release_host(bus->sdiodev->func1);
      bus->cur_read.len = 0;
      return 0;
    }

    /* Basic SD framing looks ok - process each packet (header) */

    brcmf_netbuf_list_for_every_safe(&bus->glom, pfirst, pnext) {
      dptr = (uint8_t*)(pfirst->data);
      sublen = *(uint16_t*)dptr;
      doff = brcmf_sdio_getdatoffset(&dptr[SDPCM_HWHDR_LEN]);

      BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(BYTES) && BRCMF_IS_ON(DATA), dptr, pfirst->len,
                         "Rx Subframe Data:");

      brcmf_netbuf_set_length_to(pfirst, sublen);
      brcmf_netbuf_shrink_head(pfirst, doff);

      if (pfirst->len == 0) {
        brcmf_netbuf_list_remove(&bus->glom, pfirst);
        brcmu_pkt_buf_free_netbuf(pfirst);
        continue;
      }

      BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(GLOM), pfirst->data, std::min<int>(pfirst->len, 32),
                         "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p",
                         brcmf_netbuf_list_length(&bus->glom), pfirst, pfirst->data, pfirst->len,
                         brcmf_netbuf_list_next(&bus->glom, pfirst),
                         brcmf_netbuf_list_prev(&bus->glom, pfirst));
      brcmf_netbuf_list_remove(&bus->glom, pfirst);
      if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN])) {
        brcmf_rx_event(bus->sdiodev->drvr, pfirst);
      } else {
        brcmf_rx_frame(bus->sdiodev->drvr, pfirst, false);
      }
      bus->sdcnt.rxglompkts++;
    }

    bus->sdcnt.rxglomframes++;
  }
  return num;
}

static int brcmf_sdio_dcmd_resp_wait(struct brcmf_sdio* bus, bool* pending) {
  /* Wait until control frame is available */
  *pending = false;  // TODO(cphoenix): Does signal_pending() have meaning in Garnet?
  zx_status_t result;
  result = sync_completion_wait(&bus->dcmd_resp_wait, ZX_MSEC(DCMD_RESP_TIMEOUT_MSEC));
  sync_completion_reset(&bus->dcmd_resp_wait);
  return result;
}

static zx_status_t brcmf_sdio_dcmd_resp_wake(struct brcmf_sdio* bus) {
  sync_completion_signal(&bus->dcmd_resp_wait);

  return ZX_OK;
}
static void brcmf_sdio_read_control(struct brcmf_sdio* bus, uint8_t* hdr, uint len, uint doff) {
  uint rdlen, pad;
  uint8_t* buf = NULL;
  uint8_t* rbuf;
  zx_status_t sdret;

  BRCMF_DBG(TRACE, "Enter");

  if (bus->rxblen) {
    buf = static_cast<decltype(buf)>(calloc(1, bus->rxblen));
  }
  if (!buf) {
    goto done;
  }

  rbuf = bus->rxbuf;
  pad = ((unsigned long)rbuf % bus->head_align);
  if (pad) {
    rbuf += (bus->head_align - pad);
  }

  /* Copy the already-read portion over */
  memcpy(buf, hdr, BRCMF_FIRSTREAD);
  if (len <= BRCMF_FIRSTREAD) {
    goto gotpkt;
  }

  /* Raise rdlen to next SDIO block to avoid tail command */
  rdlen = len - BRCMF_FIRSTREAD;
  if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
    pad = bus->blocksize - (rdlen % bus->blocksize);
    if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
        ((len + pad) < bus->sdiodev->bus_if->maxctl)) {
      rdlen += pad;
    }
  } else if (rdlen % bus->head_align) {
    rdlen += bus->head_align - (rdlen % bus->head_align);
  }

  /* Drop if the read is too big or it exceeds our maximum */
  if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
    BRCMF_ERR("%d-byte control read exceeds %d-byte buffer", rdlen, bus->sdiodev->bus_if->maxctl);
    brcmf_sdio_rxfail(bus, false, false);
    goto done;
  }

  if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
    BRCMF_ERR("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit", len, len - doff,
              bus->sdiodev->bus_if->maxctl);
    bus->sdcnt.rx_toolong++;
    brcmf_sdio_rxfail(bus, false, false);
    goto done;
  }

  /* Read remain of frame body */
  sdret = brcmf_sdiod_recv_buf(bus->sdiodev, rbuf, rdlen);
  bus->sdcnt.f2rxdata++;

  /* Control frame failures need retransmission */
  if (sdret != ZX_OK) {
    BRCMF_ERR("read %d control bytes failed: %d", rdlen, sdret);
    bus->sdcnt.rxc_errors++;
    brcmf_sdio_rxfail(bus, true, true);
    goto done;
  } else {
    memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen);
  }

gotpkt:

  BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(BYTES) && BRCMF_IS_ON(CTL), buf, len, "RxCtrl:");

  /* Point to valid data and indicate its length */
  // spin_lock_bh(&bus->rxctl_lock);
  bus->sdiodev->drvr->irq_callback_lock.lock();
  if (bus->rxctl) {
    BRCMF_ERR("last control frame is being processed.");
    // spin_unlock_bh(&bus->rxctl_lock);
    bus->sdiodev->drvr->irq_callback_lock.unlock();
    free(buf);
    goto done;
  }
  bus->rxctl = buf + doff;
  bus->rxctl_orig = buf;
  bus->rxlen = len - doff;
  // spin_unlock_bh(&bus->rxctl_lock);
  bus->sdiodev->drvr->irq_callback_lock.unlock();

done:
  /* Awake any waiters */
  if (bus->rxlen) {
    brcmf_sdio_dcmd_resp_wake(bus);
  }
}

/* Pad read to blocksize for efficiency */
static void brcmf_sdio_pad(struct brcmf_sdio* bus, uint16_t* pad, uint16_t* rdlen) {
  if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) {
    *pad = bus->blocksize - (*rdlen % bus->blocksize);
    if (*pad <= bus->roundup && *pad < bus->blocksize &&
        *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ) {
      *rdlen += *pad;
    }
  } else if (*rdlen % bus->head_align) {
    *rdlen += bus->head_align - (*rdlen % bus->head_align);
  }
}

static uint brcmf_sdio_readframes(struct brcmf_sdio* bus, uint maxframes) {
  struct brcmf_netbuf* pkt; /* Packet for event or data frames */
  uint16_t pad;             /* Number of pad bytes to read */
  uint rxleft = 0;          /* Remaining number of frames allowed */
  zx_status_t ret;          /* Return code from calls */
  uint rxcount = 0;         /* Total frames read */
  struct brcmf_sdio_hdrinfo* rd = &bus->cur_read;
  struct brcmf_sdio_hdrinfo rd_new;
  uint8_t head_read = 0;

  TRACE_DURATION("brcmfmac:isr", "readframes");

  /* Not finished unless we encounter no more frames indication */
  bus->rxpending = true;

  for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
       !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_SDIOD_DATA; rd->seq_num++, rxleft--) {
    /* Handle glomming separately */
    if (bus->glomd || !brcmf_netbuf_list_is_empty(&bus->glom)) {
      uint8_t cnt;
      BRCMF_DBG(GLOM, "calling rxglom: glomd %p, glom %p", bus->glomd,
                brcmf_netbuf_list_peek_head(&bus->glom));
      cnt = brcmf_sdio_rxglom(bus, rd->seq_num);
      BRCMF_DBG(GLOM, "rxglom returned %d", cnt);
      rd->seq_num += cnt - 1;
      rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
      continue;
    }

    rd->len_left = rd->len;
    /* read header first for unknow frame length */
    sdio_claim_host(bus->sdiodev->func1);
    if (!rd->len) {
      TRACE_DURATION("brcmfmac:isr", "read packet headers");
      ret = brcmf_sdiod_recv_buf(bus->sdiodev, bus->rxhdr, BRCMF_FIRSTREAD);
      bus->sdcnt.f2rxhdrs++;
      if (ret != ZX_OK) {
        BRCMF_ERR("RXHEADER FAILED: %d", ret);
        bus->sdcnt.rx_hdrfail++;
        brcmf_sdio_rxfail(bus, true, true);
        sdio_release_host(bus->sdiodev->func1);
        continue;
      }

      TRACE_INSTANT("brcmfmac:isr", "rxhdr", TRACE_SCOPE_THREAD, "frame length",
                    TA_UINT32((uint32_t) * (uint16_t*)&bus->rxhdr[0]), "checksum",
                    TA_UINT32((uint32_t) * (uint16_t*)&bus->rxhdr[2]), "seq num",
                    TA_UINT32((uint32_t)bus->rxhdr[SDPCM_HWHDR_LEN + 0]), "channel",
                    TA_UINT32((uint32_t)bus->rxhdr[SDPCM_HWHDR_LEN + 1] & 0xf), "data offset",
                    TA_UINT32((uint32_t)bus->rxhdr[SDPCM_HWHDR_LEN + 3]));

      if (brcmf_sdio_hdparse(bus, bus->rxhdr, rd, BRCMF_SDIO_FT_NORMAL) != ZX_OK) {
        sdio_release_host(bus->sdiodev->func1);
        if (!bus->rxpending) {
          break;
        } else {
          continue;
        }
      }

      if (rd->channel == SDPCM_CONTROL_CHANNEL) {
        brcmf_sdio_read_control(bus, bus->rxhdr, rd->len, rd->dat_offset);
        /* prepare the descriptor for the next read */
        const auto next_len = rd->len_nxtfrm << 4;
        ZX_DEBUG_ASSERT(next_len <= std::numeric_limits<uint16_t>::max());
        rd->len = static_cast<uint16_t>(next_len);
        rd->len_nxtfrm = 0;
        /* treat all packet as event if we don't know */
        rd->channel = SDPCM_EVENT_CHANNEL;
        sdio_release_host(bus->sdiodev->func1);
        continue;
      }
      rd->len_left = rd->len > BRCMF_FIRSTREAD ? rd->len - BRCMF_FIRSTREAD : 0;
      head_read = BRCMF_FIRSTREAD;
    }

    brcmf_sdio_pad(bus, &pad, &rd->len_left);

    pkt = brcmu_pkt_buf_get_netbuf(rd->len_left + head_read + bus->head_align);
    if (!pkt) {
      /* Give up on data, request rtx of events */
      BRCMF_ERR("brcmu_pkt_buf_get_netbuf failed");
      brcmf_sdio_rxfail(bus, false, RETRYCHAN(rd->channel));
      sdio_release_host(bus->sdiodev->func1);
      continue;
    }
    brcmf_netbuf_shrink_head(pkt, head_read);
    pkt_align(pkt, rd->len_left, bus->head_align);

    if (pkt->len > 0) {
      ret = brcmf_sdiod_recv_pkt(bus->sdiodev, pkt);
      bus->sdcnt.f2rxdata++;
    }

    sdio_release_host(bus->sdiodev->func1);

    if (ret != ZX_OK) {
      BRCMF_ERR("read %d bytes from channel %d failed: %d", rd->len, rd->channel, ret);
      brcmu_pkt_buf_free_netbuf(pkt);
      sdio_claim_host(bus->sdiodev->func1);
      brcmf_sdio_rxfail(bus, true, RETRYCHAN(rd->channel));
      sdio_release_host(bus->sdiodev->func1);
      continue;
    }

    if (head_read) {
      brcmf_netbuf_grow_head(pkt, head_read);
      memcpy(pkt->data, bus->rxhdr, head_read);
      head_read = 0;
    } else {
      memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN);
      rd_new.seq_num = rd->seq_num;
      sdio_claim_host(bus->sdiodev->func1);
      if (brcmf_sdio_hdparse(bus, bus->rxhdr, &rd_new, BRCMF_SDIO_FT_NORMAL) != ZX_OK) {
        rd->len = 0;
        brcmu_pkt_buf_free_netbuf(pkt);
        continue;
      }
      bus->sdcnt.rx_readahead_cnt++;
      if (rd->len != roundup(rd_new.len, 16)) {
        BRCMF_ERR("frame length mismatch:read %d, should be %d", rd->len,
                  roundup(rd_new.len, 16) >> 4);
        rd->len = 0;
        brcmf_sdio_rxfail(bus, true, true);
        sdio_release_host(bus->sdiodev->func1);
        brcmu_pkt_buf_free_netbuf(pkt);
        continue;
      }
      sdio_release_host(bus->sdiodev->func1);
      rd->len_nxtfrm = rd_new.len_nxtfrm;
      rd->channel = rd_new.channel;
      rd->dat_offset = rd_new.dat_offset;

      BRCMF_DBG_HEX_DUMP(!(BRCMF_IS_ON(BYTES) && BRCMF_IS_ON(DATA)) && BRCMF_IS_ON(HDRS),
                         bus->rxhdr, SDPCM_HDRLEN, "RxHdr:");

      if (rd_new.channel == SDPCM_CONTROL_CHANNEL) {
        BRCMF_ERR("readahead on control packet %d?", rd_new.seq_num);
        /* Force retry w/normal header read */
        rd->len = 0;
        sdio_claim_host(bus->sdiodev->func1);
        brcmf_sdio_rxfail(bus, false, true);
        sdio_release_host(bus->sdiodev->func1);
        brcmu_pkt_buf_free_netbuf(pkt);
        continue;
      }
    }

    BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(BYTES) && BRCMF_IS_ON(DATA), pkt->data, rd->len, "Rx Data:");

    /* Save superframe descriptor and allocate packet frame */
    if (rd->channel == SDPCM_GLOM_CHANNEL) {
      if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_HWHDR_LEN])) {
        BRCMF_DBG(GLOM, "glom descriptor, %d bytes:", rd->len);
        BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(GLOM), pkt->data, rd->len, "Glom Data:");
        brcmf_netbuf_set_length_to(pkt, rd->len);
        brcmf_netbuf_shrink_head(pkt, SDPCM_HDRLEN);
        bus->glomd = pkt;
      } else {
        BRCMF_ERR(
            "%s: glom superframe w/o "
            "descriptor!",
            __func__);
        sdio_claim_host(bus->sdiodev->func1);
        brcmf_sdio_rxfail(bus, false, false);
        sdio_release_host(bus->sdiodev->func1);
      }
      /* prepare the descriptor for the next read */
      const auto next_len = rd->len_nxtfrm << 4;
      ZX_DEBUG_ASSERT(next_len <= std::numeric_limits<uint16_t>::max());
      rd->len = static_cast<uint16_t>(next_len);
      rd->len_nxtfrm = 0;
      /* treat all packet as event if we don't know */
      rd->channel = SDPCM_EVENT_CHANNEL;
      continue;
    }

    /* Fill in packet len and prio, deliver upward */
    brcmf_netbuf_set_length_to(pkt, rd->len);
    brcmf_netbuf_shrink_head(pkt, rd->dat_offset);

    if (pkt->len == 0) {
      brcmu_pkt_buf_free_netbuf(pkt);
    } else if (rd->channel == SDPCM_EVENT_CHANNEL) {
      brcmf_rx_event(bus->sdiodev->drvr, pkt);
    } else {
      brcmf_rx_frame(bus->sdiodev->drvr, pkt, false);
    }

    /* prepare the descriptor for the next read */
    const auto next_len = rd->len_nxtfrm << 4;
    ZX_DEBUG_ASSERT(next_len <= std::numeric_limits<uint16_t>::max());
    rd->len = static_cast<uint16_t>(next_len);
    rd->len_nxtfrm = 0;
    /* treat all packet as event if we don't know */
    rd->channel = SDPCM_EVENT_CHANNEL;
  }

  rxcount = maxframes - rxleft;
  /* Message if we hit the limit */
  if (!rxleft) {
    BRCMF_DBG_THROTTLE(DATA, "hit rx limit of %d frames", maxframes);
  } else {
    BRCMF_DBG(DATA, "processed %d frames", rxcount);
  }
  /* Back off rxseq if awaiting rtx, update rx_seq */
  if (bus->rxskip) {
    rd->seq_num--;
  }
  bus->rx_seq = rd->seq_num;

  return rxcount;
}

void brcmf_sdio_wait_event_wakeup(struct brcmf_sdio* bus) {
  sync_completion_signal(&bus->ctrl_wait);
  return;
}

static zx_status_t brcmf_sdio_txpkt_hdalign(struct brcmf_sdio* bus, struct brcmf_netbuf* pkt,
                                            uint16_t* head_pad_out) {
  uint16_t head_pad;
  uint8_t* dat_buf;

  dat_buf = (uint8_t*)(pkt->data);

  /* Check head padding */
  head_pad = ((unsigned long)dat_buf % bus->head_align);
  if (head_pad) {
    if (brcmf_netbuf_head_space(pkt) < head_pad) {
      if (brcmf_netbuf_grow_realloc(pkt, head_pad, 0)) {
        return ZX_ERR_NO_MEMORY;
      }
      head_pad = 0;
    }
    brcmf_netbuf_grow_head(pkt, head_pad);
    dat_buf = (uint8_t*)(pkt->data);
  }
  memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
  if (head_pad_out) {
    *head_pad_out = head_pad;
  }
  return ZX_OK;
}

/**
 * brcmf_sdio_txpkt_prep - packet preparation for transmit
 * @bus: brcmf_sdio structure pointer
 * @pktq: packet list pointer
 * @chan: virtual channel to transmit the packet
 *
 * Processes to be applied to the packet
 *  - Align data buffer pointer
 *  - Align data buffer length
 *  - Prepare header
 * Return: negative value if there is error
 */
static zx_status_t brcmf_sdio_txpkt_prep(struct brcmf_sdio* bus, struct brcmf_netbuf_list* pktq,
                                         uint8_t chan) {
  uint16_t head_pad, total_len;
  struct brcmf_netbuf* pkt_next;
  uint8_t txseq;
  zx_status_t ret;
  struct brcmf_sdio_hdrinfo hd_info = {};

  txseq = bus->tx_seq;
  total_len = 0;
  brcmf_netbuf_list_for_every(pktq, pkt_next) {
    /* align packet data pointer */
    ret = brcmf_sdio_txpkt_hdalign(bus, pkt_next, &head_pad);
    if (ret != ZX_OK) {
      return ret;
    }
    if (head_pad) {
      memset(pkt_next->data + bus->tx_hdrlen, 0, head_pad);
    }

    total_len += pkt_next->len;

    if (pkt_next->len > std::numeric_limits<uint16_t>::max()) {
      BRCMF_ERR("brcmf_sdio_txpkt_prep failed: pkt_next len invalid (overflow)");
      return ZX_ERR_INTERNAL;
    }
    hd_info.len = static_cast<uint16_t>(pkt_next->len);
    hd_info.lastfrm = brcmf_netbuf_list_peek_tail(pktq) == pkt_next;

    hd_info.channel = chan;
    const auto dat_offset = head_pad + bus->tx_hdrlen;
    if (dat_offset > std::numeric_limits<uint8_t>::max()) {
      BRCMF_ERR("brcmf_sdio_txpkt_prep failed: dat_offset invalid (overflow)");
      return ZX_ERR_INTERNAL;
    }
    hd_info.dat_offset = static_cast<uint8_t>(dat_offset);
    hd_info.seq_num = txseq++;

    /* Now fill the header */
    brcmf_sdio_hdpack(bus, pkt_next->data, &hd_info);

    if (BRCMF_IS_ON(BYTES) && ((BRCMF_IS_ON(CTL) && chan == SDPCM_CONTROL_CHANNEL) ||
                               (BRCMF_IS_ON(DATA) && chan != SDPCM_CONTROL_CHANNEL))) {
      BRCMF_DBG_HEX_DUMP(true, pkt_next->data, hd_info.len, "Tx Frame:");
    } else if (BRCMF_IS_ON(HDRS)) {
      BRCMF_DBG_HEX_DUMP(true, pkt_next->data, head_pad + bus->tx_hdrlen, "Tx Header:");
    }
  }
  return ZX_OK;
}

/**
 * brcmf_sdio_txpkt_postp - packet post processing for transmit
 * @bus: brcmf_sdio structure pointer
 * @pktq: packet list pointer
 *
 * Processes to be applied to the packet
 *  - Remove head padding
 *  - Remove tail padding
 */
static void brcmf_sdio_txpkt_postp(struct brcmf_sdio* bus, struct brcmf_netbuf_list* pktq) {
  uint8_t* hdr;
  uint32_t dat_offset;
  struct brcmf_netbuf* pkt_next;
  struct brcmf_netbuf* tmp;

  brcmf_netbuf_list_for_every_safe(pktq, pkt_next, tmp) {
    hdr = pkt_next->data + bus->tx_hdrlen - SDPCM_SWHDR_LEN;
    dat_offset = *(uint32_t*)hdr;
    dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT;
    brcmf_netbuf_shrink_head(pkt_next, dat_offset);
  }
}

/* Writes a HW/SW header into the packet and sends it. */
/* Assumes: (a) header space already there, (b) caller holds lock */
static zx_status_t brcmf_sdio_txpkt(struct brcmf_sdio* bus, struct brcmf_netbuf_list* pktq,
                                    uint8_t chan) {
  zx_status_t ret;
  struct brcmf_netbuf* pkt_next;
  struct brcmf_netbuf* tmp;

  TRACE_DURATION("brcmfmac:isr", "sdio_txpkt");

  ret = brcmf_sdio_txpkt_prep(bus, pktq, chan);
  if (ret != ZX_OK) {
    goto done;
  }

  sdio_claim_host(bus->sdiodev->func1);
  ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq);
  bus->sdcnt.f2txdata++;

  if (ret != ZX_OK) {
    brcmf_sdio_txfail(bus);
  }

  sdio_release_host(bus->sdiodev->func1);

done:
  brcmf_sdio_txpkt_postp(bus, pktq);
  if (ret == ZX_OK) {
    const auto tx_seq = (bus->tx_seq + brcmf_netbuf_list_length(pktq)) % SDPCM_SEQ_WRAP;
    if (tx_seq > std::numeric_limits<uint8_t>::max()) {
      BRCMF_ERR("brcmf_sdio_txpkt failed: tx_seq invalid (overflow)");
      ret = ZX_ERR_INTERNAL;
    } else {
      bus->tx_seq = static_cast<uint8_t>(tx_seq);
    }
  }
  brcmf_netbuf_list_for_every_safe(pktq, pkt_next, tmp) {
    brcmf_netbuf_list_remove(pktq, pkt_next);
    brcmf_proto_bcdc_txcomplete(bus->sdiodev->drvr, pkt_next, ret == ZX_OK);
  }
  return ret;
}

// TODO(fxbug.dev/42151): Remove once bug resolved
static uint32_t brcmf_sdio_txq_full_errors = 0;
static bool brcmf_sdio_txq_full_debug_log = false;

static uint brcmf_sdio_sendfromq(struct brcmf_sdio* bus, uint maxframes) {
  struct brcmf_netbuf* pkt;
  struct brcmf_netbuf_list pktq;
  uint32_t intstat_addr = bus->sdio_core->base + SD_REG(intstatus);
  uint32_t intstatus = 0;
  zx_status_t ret = ZX_OK;
  int prec_out, i;
  uint cnt = 0;
  uint8_t tx_prec_map, pkt_num;

  TRACE_DURATION("brcmfmac:isr", "sendfromq");

  tx_prec_map = ~bus->flowcontrol;

  // TODO(fxbug.dev/42151): Remove once bug resolved
  if (unlikely(brcmf_sdio_txq_full_debug_log)) {
    int available = brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol);
    BRCMF_INFO("%s called, maxframes = %u, available in queue = %d", __func__, maxframes,
               available);
  }

  /* Send frames until the limit or some other event */
  for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
    pkt_num = 1;
    const auto pkt_num_min =
        std::min<uint32_t>(pkt_num, brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
    if (pkt_num_min > std::numeric_limits<uint8_t>::max()) {
      BRCMF_ERR("brcmf_sdio_sendfromq error: pkt_num invalid (overflow)");
      break;
    }
    pkt_num = static_cast<uint8_t>(pkt_num_min);
    brcmf_netbuf_list_init(&pktq);
    // spin_lock_bh(&bus->txq_lock);
    bus->sdiodev->drvr->irq_callback_lock.lock();
    for (i = 0; i < pkt_num; i++) {
      pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
      if (pkt == NULL) {
        break;
      }
      brcmf_netbuf_list_add_tail(&pktq, pkt);
    }
    // spin_unlock_bh(&bus->txq_lock);
    bus->sdiodev->drvr->irq_callback_lock.unlock();
    if (i == 0) {
      break;
    }

    ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);

    cnt += i;

    /* In poll mode, need to check for other events */
    if (!bus->intr) {
      /* Check device status, signal pending interrupt */
      sdio_claim_host(bus->sdiodev->func1);
      intstatus = brcmf_sdiod_func1_rl(bus->sdiodev, intstat_addr, &ret);
      sdio_release_host(bus->sdiodev->func1);

      bus->sdcnt.f2txdata++;
      if (ret != ZX_OK) {
        break;
      }
      if (intstatus & bus->hostintmask) {
        bus->ipend.store(1);
      }
    }
  }

  /* Deflow-control stack if needed */
  if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) && bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
    bus->txoff = false;
  }

  // TODO(fxbug.dev/42151): Remove once bug resolved
  if (unlikely(brcmf_sdio_txq_full_debug_log)) {
    int available = brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol);
    BRCMF_INFO("%s finished, maxframes = %u, transmitted = %u, available in queue = %d", __func__,
               maxframes, cnt, available);
  }

  return cnt;
}

static zx_status_t brcmf_sdio_tx_ctrlframe(struct brcmf_sdio* bus, uint8_t* frame, uint16_t len) {
  uint8_t doff;
  uint16_t pad;
  uint retries = 0;
  struct brcmf_sdio_hdrinfo hd_info = {};
  // TODO(cphoenix): ret, err, rv, error, status - more consistency is better.
  zx_status_t ret;

  TRACE_DURATION("brcmfmac:isr", "sdio_tx_ctrlframe");

  /* Back the pointer to make room for bus header */
  frame -= bus->tx_hdrlen;
  len += bus->tx_hdrlen;

  /* Add alignment padding (optional for ctl frames) */
  const auto doff_unsized = reinterpret_cast<uint64_t>(frame) % bus->head_align;
  if (doff_unsized > std::numeric_limits<uint8_t>::max()) {
    BRCMF_ERR("brcmf_sdio_tx_ctrlframe failed: doff invalid (overflow)");
    return ZX_ERR_INTERNAL;
  }
  doff = static_cast<uint8_t>(doff_unsized);
  if (doff) {
    frame -= doff;
    len += doff;
    memset(frame + bus->tx_hdrlen, 0, doff);
  }

  /* Round send length to next SDIO block */
  pad = 0;
  if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
    pad = bus->blocksize - (len % bus->blocksize);
    if ((pad > bus->roundup) || (pad >= bus->blocksize)) {
      pad = 0;
    }
  } else if (len % bus->head_align) {
    pad = bus->head_align - (len % bus->head_align);
  }
  len += pad;

  hd_info.len = len - pad;
  hd_info.channel = SDPCM_CONTROL_CHANNEL;
  hd_info.dat_offset = doff + bus->tx_hdrlen;
  hd_info.seq_num = bus->tx_seq;
  hd_info.lastfrm = true;
  hd_info.tail_pad = pad;
  brcmf_sdio_hdpack(bus, frame, &hd_info);

  BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(BYTES) && BRCMF_IS_ON(CTL), frame, len, "Tx Frame:");
  BRCMF_DBG_HEX_DUMP(!(BRCMF_IS_ON(BYTES) && BRCMF_IS_ON(CTL)) && BRCMF_IS_ON(HDRS), frame,
                     std::min<uint16_t>(len, 16), "TxHdr:");

  do {
    ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);

    if (ret != ZX_OK) {
      brcmf_sdio_txfail(bus);
    } else {
      bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
    }
  } while (ret != ZX_OK && retries++ < TXRETRIES);

  return ret;
}

static void brcmf_sdio_bus_stop(brcmf_bus* bus_if) {
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;
  struct brcmf_core* core = bus->sdio_core;
  uint32_t local_hostintmask;
  uint8_t saveclk;
  zx_status_t err;
  int thread_result;

  BRCMF_DBG(TRACE, "Enter");
  if (bus->watchdog_tsk) {
    bus->watchdog_should_stop.store(true);
    sync_completion_signal(&bus->watchdog_wait);
    BRCMF_DBG(TEMP, "Closing and joining SDIO watchdog task");
    thread_result = thrd_join(bus->watchdog_tsk, NULL);
    BRCMF_DBG(TEMP, "Result of thread join: %d", thread_result);
    bus->watchdog_tsk = 0;
  }

  if (sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
    sdio_claim_host(sdiodev->func1);
    /* Enable clock for device interrupts */
    brcmf_sdio_bus_sleep(bus, false, false);

    /* Disable and clear interrupts at the chip level also */
    brcmf_sdiod_func1_wl(sdiodev, core->base + SD_REG(hostintmask), 0, NULL);

    local_hostintmask = bus->hostintmask;
    bus->hostintmask = 0;

    /* Force backplane clocks to assure F2 interrupt propagates */
    saveclk = brcmf_sdiod_func1_rb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
    if (err == ZX_OK) {
      brcmf_sdiod_func1_wb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, (saveclk | SBSDIO_FORCE_HT), &err);
    }
    if (err != ZX_OK) {
      BRCMF_ERR("Failed to force clock for F2: err %s", zx_status_get_string(err));
    }

    /* Turn off the bus (F2), free any pending packets */
    BRCMF_DBG(INTR, "disable SDIO interrupts");
    sdio_disable_fn(&sdiodev->sdio_proto_fn2);

    /* Clear any pending interrupts now that F2 is disabled */
    brcmf_sdiod_func1_wl(sdiodev, core->base + SD_REG(intstatus), local_hostintmask, NULL);

    sdio_release_host(sdiodev->func1);
  }
  /* Clear the data packet queues */
  brcmu_pktq_flush(&bus->txq, true, NULL, NULL);

  /* Clear any held glomming stuff */
  brcmu_pkt_buf_free_netbuf(bus->glomd);
  brcmf_sdio_free_glom(bus);

  /* Clear rx control and wake any waiters */
  // spin_lock_bh(&bus->rxctl_lock);
  sdiodev->drvr->irq_callback_lock.lock();
  bus->rxlen = 0;
  // spin_unlock_bh(&bus->rxctl_lock);
  sdiodev->drvr->irq_callback_lock.unlock();
  // TODO(cphoenix): I think the original Linux code in brcmf_sdio_dcmd_resp_wait() would have
  // gone right back to sleep, since rxlen is 0. In the current code, it will exit;
  // brcmf_sdio_bus_rxctl() will return ZX_ERR_SHOULD_WAIT; the loop in brcmf_proto_bcdc_cmplt
  // will terminate. Check once we're supporting SDIO: Is this what we want? Why was this an
  // apparent NOP in Linux?
  brcmf_sdio_dcmd_resp_wake(bus);

  /* Reset some F2 state stuff */
  bus->rxskip = false;
  bus->tx_seq = bus->rx_seq = 0;
}

static zx_status_t brcmf_sdio_intr_rstatus(struct brcmf_sdio* bus) {
  struct brcmf_core* core = bus->sdio_core;
  uint32_t addr;
  uint32_t val;
  zx_status_t ret;

  addr = core->base + SD_REG(intstatus);

  val = brcmf_sdiod_func1_rl(bus->sdiodev, addr, &ret);
  bus->sdcnt.f1regdata++;
  if (ret != ZX_OK) {
    return ret;
  }

  val &= bus->hostintmask;
  bus->fcstate.store(!!(val & I_HMB_FC_STATE));

  /* Clear interrupts */
  if (val) {
    brcmf_sdiod_func1_wl(bus->sdiodev, addr, val, &ret);
    bus->sdcnt.f1regdata++;
    bus->intstatus.fetch_or(val);
  }

  return ret;
}

static void brcmf_sdio_dpc(struct brcmf_sdio* bus) {
  struct brcmf_sdio_dev* sdiod = bus->sdiodev;
  uint32_t newstatus = 0;
  uint32_t intstat_addr = bus->sdio_core->base + SD_REG(intstatus);
  uint32_t intstatus;
  uint txlimit = bus->txbound; /* Tx frames to send before resched */
  uint framecnt;               /* Temporary counter of tx/rx frames */
  zx_status_t err = ZX_OK;

  TRACE_DURATION("brcmfmac:isr", "dpc");

  sdio_claim_host(bus->sdiodev->func1);

  /* If waiting for HTAVAIL, check status */
  if (!bus->sr_enabled && bus->clkstate == CLK_PENDING) {
    uint8_t clkctl;
    uint8_t devctl = 0;

#if !defined(NDEBUG)
    /* Check for inconsistent device control */
    devctl = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err);
#endif /* !defined(NDEBUG) */

    /* Read CSR, if clock on switch to AVAIL, else ignore */
    clkctl = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);

    BRCMF_DBG(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x", devctl, clkctl);

    if (SBSDIO_HTAV(clkctl)) {
      devctl = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err);
      devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
      brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_DEVICE_CTL, devctl, &err);
      bus->clkstate = CLK_AVAIL;
    }
  }

  /* Make sure backplane clock is on */
  brcmf_sdio_bus_sleep(bus, false, true);

  /* Pending interrupt indicates new device status */
  if (bus->ipend.load() > 0) {
    bus->ipend.store(0);
    err = brcmf_sdio_intr_rstatus(bus);
  }

  /* Start with leftover status bits */
  intstatus = bus->intstatus.exchange(0);

  /* Handle flow-control change: read new state in case our ack
   * crossed another change interrupt.  If change still set, assume
   * FC ON for safety, let next loop through do the debounce.
   */
  if (intstatus & I_HMB_FC_CHANGE) {
    intstatus &= ~I_HMB_FC_CHANGE;
    brcmf_sdiod_func1_wl(sdiod, intstat_addr, I_HMB_FC_CHANGE, &err);

    newstatus = brcmf_sdiod_func1_rl(sdiod, intstat_addr, &err);

    bus->sdcnt.f1regdata += 2;
    bus->fcstate.store(!!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
    intstatus |= (newstatus & bus->hostintmask);
  }

  /* Handle host mailbox indication */
  if (intstatus & I_HMB_HOST_INT) {
    intstatus &= ~I_HMB_HOST_INT;
    intstatus |= brcmf_sdio_hostmail(bus);
  }

  sdio_release_host(bus->sdiodev->func1);

  /* Generally don't ask for these, can get CRC errors... */
  if (intstatus & I_WR_OOSYNC) {
    BRCMF_ERR("Dongle reports WR_OOSYNC");
    intstatus &= ~I_WR_OOSYNC;
  }

  if (intstatus & I_RD_OOSYNC) {
    BRCMF_ERR("Dongle reports RD_OOSYNC");
    intstatus &= ~I_RD_OOSYNC;
  }

  if (intstatus & I_SBINT) {
    BRCMF_ERR("Dongle reports SBINT");
    intstatus &= ~I_SBINT;
  }

  /* Would be active due to wake-wlan in gSPI */
  if (intstatus & I_CHIPACTIVE) {
    BRCMF_DBG(INFO, "Dongle reports CHIPACTIVE");
    intstatus &= ~I_CHIPACTIVE;
  }

  /* Ignore frame indications if rxskip is set */
  if (bus->rxskip) {
    intstatus &= ~I_HMB_FRAME_IND;
  }

  /* On frame indication, read available frames */
  if ((intstatus & I_HMB_FRAME_IND) && (bus->clkstate == CLK_AVAIL)) {
    brcmf_sdio_readframes(bus, bus->rxbound);
    if (!bus->rxpending) {
      intstatus &= ~I_HMB_FRAME_IND;
    }
  }

  /* Keep still-pending events for next scheduling */
  if (intstatus) {
    bus->intstatus.fetch_or(intstatus);
  }

  if ((bus->clkstate == CLK_AVAIL) && data_ok(bus)) {
    brcmf_sdio_if_ctrl_frame_stat_set(bus, [&bus, &err]() {
      err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, bus->ctrl_frame_len);
      bus->ctrl_frame_err = err;
      std::atomic_thread_fence(std::memory_order_seq_cst);
      brcmf_sdio_wait_event_wakeup(bus);
    });
  }
  /* Send queued frames (limit 1 if rx may still be pending) */
  if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate.load() &&
      brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && data_ok(bus)) {
    framecnt = bus->rxpending ? std::min(txlimit, bus->txminmax) : txlimit;
    brcmf_sdio_sendfromq(bus, framecnt);
  } else if (unlikely(brcmf_sdio_txq_full_debug_log)) {
    // TODO(fxbug.dev/42151): Remove once bug resolved
    int len = brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol);
    if (len > 0) {
      BRCMF_INFO(
          "Not able to transmit queued frames right now, clkstate = %u, "
          "fcstate = %d, queue len = %d, txlimit = %u, data_ok = %s",
          bus->clkstate, bus->fcstate.load(), len, txlimit, data_ok(bus) ? "true" : "false");
      if (!data_ok(bus)) {
        BRCMF_INFO("The tx_window is not ready, tx_max: %d, tx_seq: %d", bus->tx_max, bus->tx_seq);
      }
    }
  }

  if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != ZX_OK)) {
    BRCMF_ERR("failed backplane access over SDIO, halting operation");
    bus->intstatus.store(0);
    brcmf_sdio_if_ctrl_frame_stat_set(bus, [&bus]() {
      bus->ctrl_frame_err = ZX_ERR_IO_REFUSED;
      std::atomic_thread_fence(std::memory_order_seq_cst);
      brcmf_sdio_wait_event_wakeup(bus);
    });
  } else if (bus->intstatus.load() || bus->ipend.load() > 0 ||
             (!bus->fcstate.load() && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
              data_ok(bus))) {
    bus->dpc_triggered.store(true);
  }
}

static struct pktq* brcmf_sdio_bus_gettxq(brcmf_bus* bus_if) {
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;

  return &bus->txq;
}

static zx_status_t brcmf_sdio_bus_flush_txq(brcmf_bus* bus_if, int ifidx) {
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;
  struct brcmf_pub* drvr = sdiodev->drvr;

  struct brcmf_netbuf* cur;
  struct brcmf_netbuf* next;

  std::lock_guard lock(drvr->irq_callback_lock);

  for (size_t q = 0; q <= bus->txq.hi_prec; ++q) {
    brcmf_netbuf_list_for_every_safe(&bus->txq.q[q].netbuf_list, cur, next) {
      if (cur->len <= bus->tx_hdrlen) {
        continue;
      }
      if (cur->len - bus->tx_hdrlen < BCDC_HEADER_LEN) {
        continue;
      }

      auto hdr = reinterpret_cast<struct brcmf_proto_bcdc_header*>(cur->data + bus->tx_hdrlen);
      uint8_t idx = BCDC_GET_IF_IDX(hdr);
      if (ifidx != idx) {
        continue;
      }

      brcmf_netbuf_shrink_head(cur, bus->tx_hdrlen);
      brcmf_netbuf_list_remove(&bus->txq.q[q].netbuf_list, cur);
      brcmf_proto_bcdc_txcomplete(drvr, cur, false);
    }
  }

  return ZX_OK;
}

static bool brcmf_sdio_prec_enq(struct pktq* q, struct brcmf_netbuf* pkt, int prec) {
  struct brcmf_netbuf* p;
  int eprec = -1; /* precedence to evict from */

  /* Fast case, precedence queue is not full and we are also not
   * exceeding total queue length
   */
  if (!pktq_pfull(q, prec) && !pktq_full(q)) {
    brcmu_pktq_penq(q, prec, pkt);
    return true;
  }

  /* Determine precedence from which to evict packet, if any */
  if (pktq_pfull(q, prec)) {
    eprec = prec;
  } else if (pktq_full(q)) {
    p = brcmu_pktq_peek_tail(q, &eprec);
    if (eprec > prec) {
      // TODO(fxbug.dev/42151): Remove once bug resolved
      BRCMF_ERR("Eviction precedence (%d) greater than enqueue precedence (%d)", eprec, prec);
      return false;
    }
  }

  /* Evict if needed */
  if (eprec >= 0) {
    /* Detect queueing to unconfigured precedence */
    if (eprec == prec) {
      // TODO(fxbug.dev/42151): Remove once bug resolved
      BRCMF_INFO_THROTTLE("Expected to evict from and queue to same queue %d", prec);
      return false; /* refuse newer (incoming) packet */
    }
    /* Evict packet according to discard policy */
    p = brcmu_pktq_pdeq_tail(q, eprec);
    if (p == NULL) {
      BRCMF_ERR("brcmu_pktq_pdeq_tail() failed");
    }
    brcmu_pkt_buf_free_netbuf(p);
  }

  /* Enqueue */
  p = brcmu_pktq_penq(q, prec, pkt);
  if (p == NULL) {
    BRCMF_ERR("brcmu_pktq_penq() failed");
  }

  return p != NULL;
}

static zx_status_t brcmf_sdio_bus_txdata(brcmf_bus* bus_if, brcmf_netbuf* pkt) {
  zx_status_t ret;
  uint prec;
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;

  BRCMF_DBG(TRACE, "Enter: pkt: data %p len %d", pkt->data, pkt->len);
  if (sdiodev->state != BRCMF_SDIOD_DATA) {
    return ZX_ERR_IO;
  }

  /* Add space for the header */
  brcmf_netbuf_grow_head(pkt, bus->tx_hdrlen);
  /* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */

  prec = prio2prec((pkt->priority & PRIOMASK));

  /* Check for existing queue, current flow-control,
                   pending event, or pending clock */
  BRCMF_DBG(TRACE, "deferring pktq len %d", pktq_len(&bus->txq));
  bus->sdcnt.fcqueued++;

  /* Priority based enq */
  // spin_lock_bh(&bus->txq_lock);
  sdiodev->drvr->irq_callback_lock.lock();
  if (!brcmf_sdio_prec_enq(&bus->txq, pkt, prec)) {
    brcmf_netbuf_shrink_head(pkt, bus->tx_hdrlen);
    BRCMF_INFO_THROTTLE("out of bus->txq !!!");
    sdiodev->drvr->device->GetInspect()->LogTxQueueFull();
    bus->sdcnt.tx_qfull++;
    ret = ZX_ERR_NO_RESOURCES;

    // TODO(fxbug.dev/42151): Remove once bug resolved
    ++brcmf_sdio_txq_full_errors;
    if (brcmf_sdio_txq_full_errors >= 30 && !brcmf_sdio_txq_full_debug_log) {
      // We've seen a large number of these errors in a row, start providing
      // more debug information.
      BRCMF_WARN("Excessive out of bus->txq errors, enabling debug logging");
      brcmf_sdio_txq_full_debug_log = true;
    }
  } else {
    ret = ZX_OK;

    // TODO(fxbug.dev/42151): Remove once bug resolved
    // Reset the counter here in case there was just a spurious queue issue.
    // Also stop the debug logging so we don't spam the logs unnecessarily.
    brcmf_sdio_txq_full_errors = 0;
    brcmf_sdio_txq_full_debug_log = false;
  }

  if (pktq_len(&bus->txq) >= TXHI) {
    bus->txoff = true;
  }
  // spin_unlock_bh(&bus->txq_lock);
  sdiodev->drvr->irq_callback_lock.unlock();

#if !defined(NDEBUG)
  if (pktq_plen(&bus->txq, prec) > qcount[prec]) {
    qcount[prec] = pktq_plen(&bus->txq, prec);
  }
#endif  // !defined(NDEBUG)

  brcmf_sdio_trigger_dpc(bus);
  return ret;
}

#if !defined(NDEBUG)
#define CONSOLE_LINE_MAX 192

static zx_status_t brcmf_sdio_readconsole(struct brcmf_sdio* bus) {
  struct brcmf_console* c = &bus->console;
  uint8_t line[CONSOLE_LINE_MAX];
  uint8_t ch;
  uint32_t n, idx, addr;
  zx_status_t rv;

  /* Don't do anything until FWREADY updates console address */
  if (bus->console_addr == 0) {
    return ZX_OK;
  }

  /* Read console log struct */
  addr = bus->console_addr + offsetof(struct rte_console, log_le);
  rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (uint8_t*)&c->log_le, sizeof(c->log_le));
  if (rv != ZX_OK) {
    return rv;
  }

  /* Allocate console buffer (one time only) */
  if (c->buf == NULL) {
    c->bufsize = c->log_le.buf_size;
    c->buf = static_cast<decltype(c->buf)>(malloc(c->bufsize));
    if (c->buf == NULL) {
      return ZX_ERR_NO_MEMORY;
    }
  }

  idx = c->log_le.idx;

  /* Protect against corrupt value */
  if (idx > c->bufsize) {
    return ZX_ERR_IO_DATA_INTEGRITY;
  }

  /* Skip reading the console buffer if the index pointer
   has not moved */
  if (idx == c->last) {
    return ZX_OK;
  }

  /* Read the console buffer */
  addr = c->log_le.buf;
  rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize);
  if (rv != ZX_OK) {
    return rv;
  }

  while (c->last != idx) {
    for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
      if (c->last == idx) {
        /* This would output a partial line.
         * Instead, back up
         * the buffer pointer and output this
         * line next time around.
         */
        if (c->last >= n) {
          c->last -= n;
        } else {
          c->last = c->bufsize - n;
        }
        goto break2;
      }
      ch = c->buf[c->last];
      c->last = (c->last + 1) % c->bufsize;
      if (ch == '\n') {
        break;
      }
      line[n] = ch;
    }

    if (n > 0) {
      if (line[n - 1] == '\r') {
        n--;
      }
      line[n] = 0;
      BRCMF_DBG(FWCON, "CONSOLE: %s", line);
    }
  }
break2:

  return ZX_OK;
}
#endif /* !defined(NDEBUG) */

zx_status_t brcmf_sdio_bus_txctl(brcmf_bus* bus_if, unsigned char* msg, uint msglen) {
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;
  zx_status_t wait_status;

  BRCMF_DBG(TRACE, "Enter");
  if (sdiodev->state != BRCMF_SDIOD_DATA) {
    return ZX_ERR_IO;
  }

  /* Send from dpc */
  sync_completion_reset(&bus->ctrl_wait);
  bus->ctrl_frame_buf = msg;
  if (msglen > std::numeric_limits<uint16_t>::max()) {
    BRCMF_ERR("brcmf_sdio_bus_txctl failed: msglen invalid (overflow)");
    return ZX_ERR_INTERNAL;
  }
  bus->ctrl_frame_len = static_cast<uint16_t>(msglen);
  std::atomic_thread_fence(std::memory_order_seq_cst);
  bus->ctrl_frame_stat.store(true);
  brcmf_sdio_trigger_dpc(bus);

  // Wait for a response from firmware
  wait_status = sync_completion_wait(&bus->ctrl_wait, sdiodev->ctl_done_timeout);
  if (wait_status == ZX_ERR_TIMED_OUT) {
    BRCMF_ERR("timed out waiting for txctl sdio operation to complete: %s",
              zx_status_get_string(wait_status));
    brcmf_sdio_if_ctrl_frame_stat_clear(bus, []() {
      BRCMF_ERR(
          "Unexpected clearing of ctrl_frame_stat by brcmf_sdio_dpc thread even though sdio "
          "operation timed out.");
    });
    bus->sdcnt.tx_ctlerrs++;
    return wait_status;
  }

  zx_status_t status = ZX_OK;
  brcmf_sdio_if_ctrl_frame_stat_set(bus, [&status]() { status = ZX_ERR_SHOULD_WAIT; });

  if (status != ZX_OK) {
    BRCMF_ERR("txctl ctrl_frame timeout: %s", zx_status_get_string(status));
    bus->sdcnt.tx_ctlerrs++;
    return status;
  }

  BRCMF_DBG(SDIO, "ctrl_frame complete, err=%d", bus->ctrl_frame_err);
  std::atomic_thread_fence(std::memory_order_seq_cst);
  bus->sdcnt.tx_ctlpkts++;
  return bus->ctrl_frame_err;
}

static zx_status_t brcmf_sdio_checkdied(struct brcmf_sdio* bus) {
  zx_status_t error;
  struct sdpcm_shared sh;

  error = brcmf_sdio_shared_read(bus, &sh);

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

  if ((sh.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
    BRCMF_DBG(INFO, "firmware not built with -assert");
  } else if (sh.flags & SDPCM_SHARED_ASSERT) {
    BRCMF_ERR("assertion in dongle");
  }

  if (sh.flags & SDPCM_SHARED_TRAP) {
    BRCMF_ERR("firmware trap in dongle");

    sh.flags &= (~SDPCM_SHARED_TRAP);
    // Clean up the share memory before triggering a recovery.
    error = brcmf_sdio_shared_write(bus, &sh);
    if (error != ZX_OK) {
      BRCMF_ERR("Write shared failed -- error: %s", zx_status_get_string(error));
      return error;
    }

    error = bus->sdiodev->drvr->recovery_trigger->firmware_crash_.Inc();
    if (error != ZX_OK) {
      BRCMF_ERR("Increase recovery trigger condition failed -- error: %s",
                zx_status_get_string(error));
      return error;
    }
  }

  return ZX_OK;
}

static zx_status_t brcmf_sdio_bus_rxctl(brcmf_bus* bus_if, unsigned char* msg, uint msglen,
                                        int* rxlen_out) {
  bool timeout;
  uint rxlen = 0;
  bool pending;
  uint8_t* buf;
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;

  BRCMF_DBG(TRACE, "Enter");
  if (sdiodev->state != BRCMF_SDIOD_DATA) {
    return ZX_ERR_IO;
  }

  /* Wait until control frame is available */
  timeout = (brcmf_sdio_dcmd_resp_wait(bus, &pending) != ZX_OK);

  // spin_lock_bh(&bus->rxctl_lock);
  sdiodev->drvr->irq_callback_lock.lock();
  rxlen = bus->rxlen;
  memcpy(msg, bus->rxctl, std::min(msglen, rxlen));
  bus->rxctl = NULL;
  buf = bus->rxctl_orig;
  bus->rxctl_orig = NULL;
  bus->rxlen = 0;
  // spin_unlock_bh(&bus->rxctl_lock);
  sdiodev->drvr->irq_callback_lock.unlock();
  free(buf);

  if (rxlen) {
    BRCMF_DBG(CTL, "resumed on rxctl frame, received %d, message length %d", rxlen, msglen);
  } else if (timeout) {
    BRCMF_ERR("resumed on timeout");
    brcmf_sdio_checkdied(bus);
  } else if (pending) {
    BRCMF_DBG(CTL, "cancelled");
    return ZX_ERR_UNAVAILABLE;
  } else {
    BRCMF_DBG(CTL, "resumed for unknown reason?");
    brcmf_sdio_checkdied(bus);
  }

  if (rxlen) {
    bus->sdcnt.rx_ctlpkts++;
  } else {
    bus->sdcnt.rx_ctlerrs++;
  }

  if (rxlen) {
    *rxlen_out = rxlen;
    return ZX_OK;
  } else {
    return ZX_ERR_SHOULD_WAIT;
  }
}

static bool brcmf_sdio_verifymemory(struct brcmf_sdio_dev* sdiodev, uint32_t ram_addr,
                                    const void* ram_data, size_t ram_sz) {
  char* ram_cmp;
  zx_status_t err;
  bool ret = true;
  int len;

  /* read back and verify */
  BRCMF_DBG(INFO, "Compare RAM dl & ul at 0x%08x; size=%zu", ram_addr, ram_sz);
  ram_cmp = static_cast<decltype(ram_cmp)>(malloc(MEMBLOCK));
  /* do not proceed while no memory but  */
  if (!ram_cmp) {
    return true;
  }

  const char* expected_data = static_cast<const char*>(ram_data);
  int address = ram_addr;
  int offset = 0;

  if (ram_sz > std::numeric_limits<int>::max()) {
    BRCMF_ERR("brcmf_sdio_verifymemory failed: ram_sz invalid (overflow)");
    return false;
  }
  const auto ram_sz_resized = static_cast<int>(ram_sz);
  while (offset < ram_sz_resized) {
    len = ((offset + MEMBLOCK) < ram_sz_resized) ? MEMBLOCK : ram_sz_resized - offset;
    err = brcmf_sdiod_ramrw(sdiodev, false, address, (uint8_t*)ram_cmp, len);
    if (err != ZX_OK) {
      BRCMF_ERR("error %d on reading %d membytes at 0x%08x", err, len, address);
      ret = false;
      break;
    } else if (memcmp(ram_cmp, expected_data + offset, len)) {
      /* On failure, find the byte offset so we can print a detailed error */
      for (int ndx = 0; ndx < len; ndx++) {
        if (ram_cmp[ndx] != expected_data[offset + ndx]) {
          BRCMF_ERR("Downloaded RAM image is corrupted at offset %d of %zu (saw:%#x expect:%#x)",
                    offset + ndx, ram_sz, ram_cmp[ndx], expected_data[offset + ndx]);

                    /*const int start = (ndx & 63) == 0 ? 0 : ((ndx & 63) - 1);*/
		    const int start = (ndx & ~63) == 0 ? 0 : ((ndx & ~63) - 64);
          const int blocks = start == 0 ? 2 : 3;
          zxlogf(ERROR, "Read:");
          for (int i = start; len >= (64 * blocks) && i < (64 * blocks); i += 16) {
            zxlogf(ERROR,
                   "%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x "
                   "%02x %02x",
                   i, ram_cmp[i + 0], ram_cmp[i + 1], ram_cmp[i + 2], ram_cmp[i + 3],
                   ram_cmp[i + 4], ram_cmp[i + 5], ram_cmp[i + 6], ram_cmp[i + 7], ram_cmp[i + 8],
                   ram_cmp[i + 9], ram_cmp[i + 10], ram_cmp[i + 11], ram_cmp[i + 12],
                   ram_cmp[i + 13], ram_cmp[i + 14], ram_cmp[i + 15]);
          }
          const char* expected = expected_data + offset;
          zxlogf(ERROR, "Expected:");
          for (int i = start; len >= (64 * blocks) && i < (64 * blocks); i += 16) {
            zxlogf(ERROR,
                   "%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x "
                   "%02x %02x",
                   i, expected[i + 0], expected[i + 1], expected[i + 2], expected[i + 3],
                   expected[i + 4], expected[i + 5], expected[i + 6], expected[i + 7],
                   expected[i + 8], expected[i + 9], expected[i + 10], expected[i + 11],
                   expected[i + 12], expected[i + 13], expected[i + 14], expected[i + 15]);
          }


          break;
        }
      }
      ret = false;
      break;
    }
    offset += len;
    address += len;
  }

  free(ram_cmp);

  return ret;
}

static zx_status_t brcmf_sdio_download_code_file(struct brcmf_sdio* bus, const void* firmware,
                                                 size_t firmware_size) {
  zx_status_t err;

  BRCMF_DBG(TRACE, "Enter");

  err = brcmf_sdiod_ramrw(bus->sdiodev, true, bus->ci->rambase, const_cast<void*>(firmware),
                          firmware_size);
  if (err != ZX_OK)
    BRCMF_ERR("error %d on writing %zu membytes at 0x%08x", err, firmware_size, bus->ci->rambase);
  else if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase, firmware, firmware_size)) {
    err = ZX_ERR_IO;
  }

  return err;
}

static zx_status_t brcmf_sdio_download_nvram(struct brcmf_sdio* bus, const void* vars,
                                             uint32_t varsz) {
  int address;
  zx_status_t err;

  BRCMF_DBG(TRACE, "Enter");

  address = bus->ci->ramsize - varsz + bus->ci->rambase;
  err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, const_cast<void*>(vars), varsz);
  if (err != ZX_OK) {
    BRCMF_ERR("error %d on writing %d nvram bytes at 0x%08x", err, varsz, address);
  } else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, vars, varsz)) {
    err = ZX_ERR_IO;
  }

  return err;
}

static zx_status_t brcmf_sdio_download_firmware(struct brcmf_sdio* bus, const void* firmware,
                                                size_t firmware_size, const void* nvram,
                                                size_t nvram_size) {
  zx_status_t bcmerror = ZX_OK;
  uint32_t rstvec;
  uint8_t attempt_times = 0;
  if (nvram_size > std::numeric_limits<uint32_t>::max()) {
    BRCMF_ERR("brcmf_sdio_download_firmware failed: nvram_size invalid (overflow)");
    return ZX_ERR_INTERNAL;
  }
  const auto nvram_size_resized = static_cast<uint32_t>(nvram_size);

  sdio_claim_host(bus->sdiodev->func1);
  brcmf_sdio_clkctl(bus, CLK_AVAIL, false);

  rstvec = *(const uint32_t*)firmware;
  BRCMF_DBG(SDIO, "firmware rstvec: %x", rstvec);
  // Download firmware with retries.
  do {
    attempt_times++;
    bcmerror = brcmf_sdio_download_code_file(bus, firmware, firmware_size);
    if (bcmerror == ZX_OK)
      break;
    BRCMF_ERR("firmware file download failed, %u retry attempts remaining.",
              FILE_LOAD_MAX_ATTEMPTS - attempt_times);
  } while (attempt_times < FILE_LOAD_MAX_ATTEMPTS);

  BRCMF_DBG(SDIO, "attempted %u times.", attempt_times);
  if (bcmerror != ZX_OK)
    goto err;

  attempt_times = 0;
  // Download nvram with retries.
  do {
    attempt_times++;
    bcmerror = brcmf_sdio_download_nvram(bus, nvram, nvram_size_resized);
    if (bcmerror == ZX_OK)
      break;
    BRCMF_ERR("nvram file download failed, %u retry attempts remaining.",
              FILE_LOAD_MAX_ATTEMPTS - attempt_times);
  } while (attempt_times < FILE_LOAD_MAX_ATTEMPTS);

  BRCMF_DBG(SDIO, "attempted %u times.", attempt_times);
  if (bcmerror != ZX_OK)
    goto err;

  /* Take arm out of reset */
  if (!brcmf_chip_set_active(bus->ci, rstvec)) {
    BRCMF_ERR("error getting out of ARM core reset");
    goto err;
  }

err:
  brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
  sdio_release_host(bus->sdiodev->func1);
  return bcmerror;
}

static void brcmf_sdio_sr_init(struct brcmf_sdio* bus) {
  zx_status_t err = ZX_OK;
  uint8_t val;

  BRCMF_DBG(TRACE, "Enter");

  val = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
  if (err != ZX_OK) {
    BRCMF_ERR("error reading SBSDIO_FUNC1_WAKEUPCTRL");
    return;
  }

  val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
  brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
  if (err != ZX_OK) {
    BRCMF_ERR("error writing SBSDIO_FUNC1_WAKEUPCTRL");
    return;
  }

  /* Add CMD14 Support */
  brcmf_sdiod_vendor_control_wb(
      bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
      (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), &err);
  if (err != ZX_OK) {
    BRCMF_ERR("error writing SDIO_CCCR_BRCM_CARDCAP");
    return;
  }

  brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_FORCE_HT, &err);
  if (err != ZX_OK) {
    BRCMF_ERR("error writing SBSDIO_FUNC1_CHIPCLKCSR");
    return;
  }

  /* set flag */
  bus->sr_enabled = true;
  BRCMF_DBG(INFO, "SR enabled");
}

/* enable KSO bit */
static zx_status_t brcmf_sdio_kso_init(struct brcmf_sdio* bus) {
  struct brcmf_core* core = bus->sdio_core;
  uint8_t val;
  zx_status_t err = ZX_OK;

  BRCMF_DBG(TRACE, "Enter");

  /* KSO bit added in SDIO core rev 12 */
  if (core->rev < 12) {
    return ZX_OK;
  }

  val = brcmf_sdiod_func1_rb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
  if (err != ZX_OK) {
    BRCMF_ERR("error reading SBSDIO_FUNC1_SLEEPCSR");
    return err;
  }

  if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) {
    val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
    brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, val, &err);
    if (err != ZX_OK) {
      BRCMF_ERR("error writing SBSDIO_FUNC1_SLEEPCSR");
      return err;
    }
  }

  return ZX_OK;
}

static zx_status_t brcmf_sdio_bus_preinit(brcmf_bus* bus_if) {
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;
  struct brcmf_core* core = bus->sdio_core;
  uint32_t value;
  zx_status_t err;

  /* the commands below use the terms tx and rx from
   * a device perspective, ie. bus:txglom affects the
   * bus transfers from device to host.
   */
  if (core->rev < 12) {
    /* for sdio core rev < 12, disable txgloming */
    value = 0;
    err = brcmf_iovar_data_set(sdiodev->drvr, "bus:txglom", &value, sizeof(uint32_t), nullptr);
  } else {
    /* otherwise, set txglomalign */
    value = sdiodev->settings->bus.sdio->sd_sgentry_align;
    /* SDIO ADMA requires at least 32 bit alignment */
    value = std::max<uint32_t>(value, DMA_ALIGNMENT);
    err = brcmf_iovar_data_set(sdiodev->drvr, "bus:txglomalign", &value, sizeof(uint32_t), nullptr);
  }

  // No support for txglomming, requires SDIO scatter/gather support (see fxbug.dev/29502)

  if (err != ZX_OK) {
    goto done;
  }

  bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
  brcmf_bus_add_txhdrlen(sdiodev->drvr, bus->tx_hdrlen);
  bus_if->always_use_fws_queue = false;

done:
  return err;
}

void brcmf_sdio_trigger_dpc(struct brcmf_sdio* bus) {
  if (!bus->dpc_triggered.load()) {
    bus->dpc_triggered.store(true);
    bus->brcmf_wq->Schedule(&bus->datawork);
  }
}

void brcmf_sdio_isr(struct brcmf_sdio* bus) {
  BRCMF_DBG(TRACE, "Enter");

  if (!bus) {
    BRCMF_ERR("bus is null pointer, exiting");
    return;
  }

  /* Count the interrupt call */
  bus->sdcnt.intrcount++;
  if (brcmf_sdio_intr_rstatus(bus) != ZX_OK) {
    BRCMF_ERR("failed backplane access");
  }

  /* Disable additional interrupts (is this needed now)? */
  if (!bus->intr) {
    BRCMF_ERR("isr w/o interrupt configured!");
  }

  bus->dpc_triggered.store(true);
  bus->brcmf_wq->Schedule(&bus->datawork);
}

void brcmf_sdio_event_handler(struct brcmf_sdio* bus);

static void brcmf_sdio_bus_watchdog(struct brcmf_sdio* bus) {
  BRCMF_DBG(TIMER, "Enter");

  /* Poll period: check device if appropriate. */
  if (!bus->sr_enabled && bus->poll && (++bus->polltick >= bus->pollrate)) {
    bool intstatus = false;

    /* Reset poll tick */
    bus->polltick = 0;

    /* Check device if no interrupts */
    if (!bus->intr || (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) {
      if (!bus->dpc_triggered.load()) {
        bool func1_pend;
        bool func2_pend;

        sdio_claim_host(bus->sdiodev->func1);

        sdio_intr_pending(&bus->sdiodev->sdio_proto_fn1, &func1_pend);
        sdio_intr_pending(&bus->sdiodev->sdio_proto_fn2, &func2_pend);
        sdio_release_host(bus->sdiodev->func1);
        intstatus = func1_pend || func2_pend;
      }

      /* If there is something, make like the ISR and
               schedule the DPC. */
      if (intstatus) {
        bus->sdcnt.pollcnt++;
        bus->ipend.store(1);

        bus->dpc_triggered.store(true);
        bus->brcmf_wq->Schedule(&bus->datawork);
      }
    }

    /* Update interrupt tracking */
    bus->sdcnt.lastintrs = bus->sdcnt.intrcount;
  }
#if !defined(NDEBUG)
  /* Poll for console output periodically */
  // This was the original check. But for some reason sdiodev->state never gets set to
  // BRCMF_SDIOD_DATA. Need to investiage TODO(fxbug.dev/36618)
  // (bus->sdiodev->state == BRCMF_SDIOD_DATA && BRCMF_IS_ON(FWCON) && bus->console_interval != 0)
  if (BRCMF_IS_ON(FWCON) && bus->console_interval != 0) {
    bus->console.count += BRCMF_WD_POLL_MSEC;
    if (bus->console.count >= bus->console_interval) {
      bus->console.count -= bus->console_interval;
      sdio_claim_host(bus->sdiodev->func1);
      /* Make sure backplane clock is on */
      brcmf_sdio_bus_sleep(bus, false, false);
      if (brcmf_sdio_readconsole(bus) != ZX_OK) { /* stop on error */
        bus->console_interval = 0;
      }
      sdio_release_host(bus->sdiodev->func1);
    }
  }
#endif /* !defined(NDEBUG) */

// TODO(cphoenix): Turn "idle" back on once things are working, and see if anything breaks.
#ifdef TEMP_DISABLE_DO_IDLE
  /* On idle timeout clear activity flag and/or turn off clock */
  if (!bus->dpc_triggered.load()) {
    std::atomic_thread_fence(std::memory_order_seq_cst);
    if ((!bus->dpc_running) && (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
      bus->idlecount++;
      if (bus->idlecount > bus->idletime) {
        BRCMF_DBG(SDIO, "idle");
        sdio_claim_host(bus->sdiodev->func1);
        brcmf_sdio_wd_timer(bus, false);
        bus->idlecount = 0;
        brcmf_sdio_bus_sleep(bus, true, false);
        sdio_release_host(bus->sdiodev->func1);
      }
    } else {
      bus->idlecount = 0;
    }
  } else {
    bus->idlecount = 0;
  }
#endif  // TEMP_DISABLE_DO_IDLE
}

void brcmf_sdio_event_handler(struct brcmf_sdio* bus) {
  bus->dpc_running = true;
  std::atomic_thread_fence(std::memory_order_seq_cst);
  while (bus->dpc_triggered.load()) {
    bus->dpc_triggered.store(false);
    brcmf_sdio_dpc(bus);
    bus->idlecount = 0;
  }
  bus->dpc_running = false;
}

static void brcmf_sdio_dataworker(WorkItem* work) {
  struct brcmf_sdio* bus = containerof(work, struct brcmf_sdio, datawork);
  // Lock here so that everything inside brcmf_sdio_event_handlers is protected.
  // This is to ensure that the event handler is only called from either the
  // workqueue or the interrupt thread. This is a little heavy-handed so there
  // is probably room for improvement here. Running without this lock will
  // eventually result in the driver failing though.
  sdio_claim_host(bus->sdiodev->func1);
  brcmf_sdio_event_handler(bus);
  sdio_release_host(bus->sdiodev->func1);
}

zx_status_t brcmf_sdio_load_files(brcmf_pub* drvr, bool reload) TA_NO_THREAD_SAFETY_ANALYSIS {
  zx_status_t status = ZX_OK;
  brcmf_bus* bus_if = drvr->bus_if;

  std::string firmware_binary;
  if ((status = wlan::brcmfmac::GetFirmwareBinary(
           drvr->device, brcmf_bus_type::BRCMF_BUS_TYPE_SDIO,
           static_cast<wlan::brcmfmac::CommonCoreId>(bus_if->chip), bus_if->chiprev,
           &firmware_binary)) != ZX_OK) {
    BRCMF_ERR("Load firmware binary failed, error: %s\n", zx_status_get_string(status));
    if (reload)
      drvr->fw_reloading.unlock();
    return status;
  }

  const size_t padded_size_firmware = ZX_ROUNDUP(firmware_binary.size(), SDIOD_SIZE_ALIGNMENT);
  firmware_binary.resize(padded_size_firmware, '\0');

  std::string nvram_binary;
  if ((status =
           wlan::brcmfmac::GetNvramBinary(drvr->device, brcmf_bus_type::BRCMF_BUS_TYPE_SDIO,
                                          static_cast<wlan::brcmfmac::CommonCoreId>(bus_if->chip),
                                          bus_if->chiprev, &nvram_binary)) != ZX_OK) {
    BRCMF_ERR("Load nvram binary failed, error: %s\n", zx_status_get_string(status));
    if (reload)
      drvr->fw_reloading.unlock();
    return status;
  }

  const size_t padded_size_nvram = ZX_ROUNDUP(nvram_binary.size(), SDIOD_SIZE_ALIGNMENT);
  nvram_binary.resize(padded_size_nvram, '\0');

  if (firmware_binary.size() > std::numeric_limits<uint32_t>::max()) {
    BRCMF_ERR("Firmware binary size too large");
    if (reload)
      drvr->fw_reloading.unlock();
    return ZX_ERR_INTERNAL;
  }

  if ((status = brcmf_sdio_firmware_callback(drvr, firmware_binary.data(), firmware_binary.size(),
                                             nvram_binary.data(), nvram_binary.size())) != ZX_OK) {
    BRCMF_ERR("Load nvram binary failed, error: %s\n", zx_status_get_string(status));
    if (reload)
      drvr->fw_reloading.unlock();
    return status;
  }

  std::string clm_binary;
  if ((status =
           wlan::brcmfmac::GetClmBinary(drvr->device, brcmf_bus_type::BRCMF_BUS_TYPE_SDIO,
                                        static_cast<wlan::brcmfmac::CommonCoreId>(bus_if->chip),
                                        bus_if->chiprev, &clm_binary)) != ZX_OK) {
    BRCMF_ERR("Load CLM binary failed, error: %s\n", zx_status_get_string(status));
    if (reload)
      drvr->fw_reloading.unlock();
    return status;
  }

  // Unlock firmware reload lock after reloading the firmware or in other failure branches above if
  // it's a reload.
  if (reload)
    drvr->fw_reloading.unlock();

  // The firmware IOVAR accesses to upload the CLM blob are always on ifidx 0, so we stub out an
  // appropriate brcmf_if instance here.
  brcmf_if ifp = {};
  ifp.drvr = drvr;
  ifp.ifidx = 0;
  if ((status = brcmf_c_process_clm_blob(&ifp, clm_binary)) != ZX_OK) {
    BRCMF_ERR("Process clm blob fail.\n");
    return status;
  }

  return ZX_OK;
}

zx_status_t brcmf_sdio_recovery(struct brcmf_bus* bus) TA_NO_THREAD_SAFETY_ANALYSIS {
  struct brcmf_sdio_dev* sdiod = bus->bus_priv.sdio;
  struct brcmf_pub* drvr = sdiod->drvr;
  zx_status_t error = ZX_OK;

  // Lock the firmware reload mutex for this function so that no interrupt will be handled in
  // the middle of it.
  drvr->fw_reloading.lock();
  // Close sdiod, so that no more data operation can proceed during during firmware reload.
  brcmf_sdiod_change_state(sdiod, BRCMF_SDIOD_DOWN);
  // Sdio clean-ups
  brcmf_sdio_reset(sdiod->bus);

  if ((error = brcmf_sdio_load_files(drvr, true)) != ZX_OK) {
    BRCMF_ERR("Failed to reload images - error: %s", zx_status_get_string(error));
    brcmf_proto_bcdc_detach(drvr);
    return error;
  }

  if ((error = brcmf_bus_started(sdiod->drvr, true)) != ZX_OK) {
    BRCMF_ERR("Initialization after bus started failed.\n");
    brcmf_proto_bcdc_detach(drvr);
    return error;
  }

  return ZX_OK;
}

void brcmf_sdio_log_stats(struct brcmf_bus* bus_if) {
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;

  zxlogf(INFO,
         "SDIO bus stats: FC: %x FC_ChangeCnt: %u TxSeq: %u TxMax: %u TxCtlCnt: %lu TxCtlErr: %lu,"
         " RxCtlCnt: %lu, RxCtlErr: %lu, Intrs: %u, HdrRead: %u, PktReads: %u, PktWrites: %u",
         bus->flowcontrol, bus->sdcnt.fc_rcvd, bus->tx_seq, bus->tx_max, bus->sdcnt.tx_ctlpkts,
         bus->sdcnt.tx_ctlerrs, bus->sdcnt.rx_ctlpkts, bus->sdcnt.rx_ctlerrs, bus->sdcnt.intrcount,
         bus->sdcnt.f2rxhdrs, bus->sdcnt.f2rxdata, bus->sdcnt.f2txdata);
  zxlogf(INFO,
         "SDIO txq stats: EnqueueCnt: %u QFullCnt: %u QLen: %u PerPrecLen [0]: %u [1]: %u [2]: %u "
         "[3]: %u",
         pktq_enq_cnt(&bus->txq), bus->sdcnt.tx_qfull, pktq_len(&bus->txq), pktq_plen(&bus->txq, 0),
         pktq_plen(&bus->txq, 1), pktq_plen(&bus->txq, 2), pktq_plen(&bus->txq, 3));
}

int brcmf_sdio_oob_irqhandler(void* cookie) {
  struct brcmf_sdio_dev* sdiodev = static_cast<decltype(sdiodev)>(cookie);
  struct brcmf_sdio* bus = sdiodev->bus;
  zx_status_t status;
  uint32_t intstatus;

  while ((status = zx_interrupt_wait(sdiodev->irq_handle, NULL)) == ZX_OK) {
    bus->sdcnt.intrcount++;
    // Sleep the interrupt handling when reloading the firmware to reduce the chaos in driver caused
    // by queued interrupts.
    std::lock_guard<std::mutex> guard(sdiodev->drvr->fw_reloading);
    BRCMF_DBG_THROTTLE(INTR, "OOB intr triggered");
    sdio_claim_host(sdiodev->func1);
    if (brcmf_sdio_intr_rstatus(sdiodev->bus)) {
      BRCMF_ERR("failed backplane access");
    }
    intstatus = sdiodev->bus->intstatus.load();
    sdiodev->bus->dpc_triggered.store(true);
    brcmf_sdio_event_handler(sdiodev->bus);
    sdio_release_host(sdiodev->func1);
    if (intstatus == 0) {
      BRCMF_DBG_THROTTLE(TEMP, "Zero intstatus; pausing 5 msec");
      zx_nanosleep(zx_deadline_after(ZX_MSEC(5)));
    }
    BRCMF_DBG_THROTTLE(INTR, "Done with OOB intr");
  }

  BRCMF_ERR("ISR exiting with status %s", zx_status_get_string(status));
  return (int)status;
}

static void brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev* sdiodev, struct brcmf_chip* ci,
                                         uint32_t drivestrength) {
  const struct sdiod_drive_str* str_tab = NULL;
  uint32_t str_mask;
  uint32_t str_shift;
  uint32_t i;
  uint32_t drivestrength_sel = 0;
  uint32_t cc_data_temp;
  uint32_t addr;

  if (!(ci->cc_caps & CC_CAP_PMU)) {
    return;
  }

  switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
    case SDIOD_DRVSTR_KEY(BRCM_CC_4330_CHIP_ID, 12):
      str_tab = sdiod_drvstr_tab1_1v8;
      str_mask = 0x00003800;
      str_shift = 11;
      break;
    case SDIOD_DRVSTR_KEY(BRCM_CC_4334_CHIP_ID, 17):
      str_tab = sdiod_drvstr_tab6_1v8;
      str_mask = 0x00001800;
      str_shift = 11;
      break;
    case SDIOD_DRVSTR_KEY(BRCM_CC_43143_CHIP_ID, 17):
      /* note: 43143 does not support tristate */
      i = countof(sdiod_drvstr_tab2_3v3) - 1;
      if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
        str_tab = sdiod_drvstr_tab2_3v3;
        str_mask = 0x00000007;
        str_shift = 0;
      } else
        BRCMF_ERR("Invalid SDIO Drive strength for chip %s, strength=%d", ci->name, drivestrength);
      break;
    case SDIOD_DRVSTR_KEY(BRCM_CC_43362_CHIP_ID, 13):
      str_tab = sdiod_drive_strength_tab5_1v8;
      str_mask = 0x00003800;
      str_shift = 11;
      break;
    default:
      BRCMF_DBG(INFO, "No SDIO driver strength init needed for chip %s rev %d pmurev %d", ci->name,
                ci->chiprev, ci->pmurev);
      break;
  }

  if (str_tab != NULL) {
    struct brcmf_core* pmu = brcmf_chip_get_pmu(ci);

    for (i = 0; str_tab[i].strength != 0; i++) {
      if (drivestrength >= str_tab[i].strength) {
        drivestrength_sel = str_tab[i].sel;
        break;
      }
    }
    addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
    brcmf_sdiod_func1_wl(sdiodev, addr, 1, NULL);
    cc_data_temp = brcmf_sdiod_func1_rl(sdiodev, addr, NULL);
    cc_data_temp &= ~str_mask;
    drivestrength_sel <<= str_shift;
    cc_data_temp |= drivestrength_sel;
    brcmf_sdiod_func1_wl(sdiodev, addr, cc_data_temp, NULL);

    BRCMF_DBG(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x",
              str_tab[i].strength, drivestrength, cc_data_temp);
  }
}

static zx_status_t brcmf_sdio_buscoreprep(void* ctx) {
  struct brcmf_sdio_dev* sdiodev = static_cast<decltype(sdiodev)>(ctx);
  zx_status_t err = ZX_OK;
  uint8_t clkval, clkset;

  /* Try forcing SDIO core to do ALPAvail request only */
  clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  brcmf_sdiod_func1_wb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  if (err != ZX_OK) {
    BRCMF_ERR("error writing for HT off");
    return err;
  }

  /* If register supported, wait for ALPAvail and then force ALP */
  /* This may take up to 15 milliseconds */
  clkval = brcmf_sdiod_func1_rb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, NULL);

  if ((clkval & ~SBSDIO_AVBITS) != clkset) {
    BRCMF_ERR("ChipClkCSR access: wrote 0x%02x read 0x%02x", clkset, clkval);
    return ZX_ERR_IO_REFUSED;
  }

  SPINWAIT(((clkval = brcmf_sdiod_func1_rb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
            !SBSDIO_ALPAV(clkval)),
           PMU_MAX_TRANSITION_DLY_USEC);

  if (!SBSDIO_ALPAV(clkval)) {
    BRCMF_ERR("timeout on ALPAV wait, clkval 0x%02x", clkval);
    return ZX_ERR_SHOULD_WAIT;
  }

  clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  brcmf_sdiod_func1_wb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  zx_nanosleep(zx_deadline_after(ZX_USEC(65)));

  /* Also, disable the extra SDIO pull-ups */
  brcmf_sdiod_func1_wb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);

  return ZX_OK;
}

static void brcmf_sdio_buscore_activate(void* ctx, struct brcmf_chip* chip, uint32_t rstvec) {
  struct brcmf_sdio_dev* sdiodev = static_cast<decltype(sdiodev)>(ctx);
  struct brcmf_core* core = sdiodev->bus->sdio_core;
  uint32_t reg_addr;

  /* clear all interrupts */
  reg_addr = core->base + SD_REG(intstatus);
  brcmf_sdiod_func1_wl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);

  if (rstvec) { /* Write reset vector to address 0 */
    brcmf_sdiod_ramrw(sdiodev, true, 0, (void*)&rstvec, sizeof(rstvec));
  }
}

static uint32_t brcmf_sdio_buscore_read32(void* ctx, uint32_t addr) {
  struct brcmf_sdio_dev* sdiodev = static_cast<decltype(sdiodev)>(ctx);
  uint32_t val, rev;

  val = brcmf_sdiod_func1_rl(sdiodev, addr, NULL);

  /*
   * this is a bit of special handling if reading the chipcommon chipid
   * register. The 4339 is a next-gen of the 4335. It uses the same
   * SDIO device id as 4335 and the chipid register returns 4335 as well.
   * It can be identified as 4339 by looking at the chip revision. It
   * is corrected here so the chip.c module has the right info.
   */
  if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) &&
      (sdiodev->product_id == SDIO_DEVICE_ID_BROADCOM_4339 ||
       sdiodev->product_id == SDIO_DEVICE_ID_BROADCOM_4335_4339)) {
    rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
    if (rev >= 2) {
      val &= ~CID_ID_MASK;
      val |= BRCM_CC_4339_CHIP_ID;
    }
  }

  return val;
}

static void brcmf_sdio_buscore_write32(void* ctx, uint32_t addr, uint32_t val) {
  struct brcmf_sdio_dev* sdiodev = static_cast<decltype(sdiodev)>(ctx);

  brcmf_sdiod_func1_wl(sdiodev, addr, val, NULL);
}

static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
    .read32 = brcmf_sdio_buscore_read32,
    .write32 = brcmf_sdio_buscore_write32,
    .prepare = brcmf_sdio_buscoreprep,
    .activate = brcmf_sdio_buscore_activate,
};

// This will wait, then dump out all SDIO transactions to date.
#ifdef SDIO_PRINTER
thrd_t sdio_thread;
static int sdio_printer(void* foo) {
  BRCMF_DBG(TEMP, "SDIO printer started");
  zx_nanosleep(zx_deadline_after(ZX_SEC(10000000)));
  psr();
  return 0;
}
#endif  // SDIO_PRINTER

static zx_status_t brcmf_sdio_probe_attach(struct brcmf_sdio* bus) {
  struct brcmf_sdio_dev* sdiodev;
  uint8_t clkctl = 0;
  zx_status_t err = ZX_OK;
  int reg_addr;
  uint32_t reg_val;
  uint32_t drivestrength;
  brcmf_mp_device* settings = nullptr;
  brcmf_sdio_pd* sdio_settings = nullptr;

  sdiodev = bus->sdiodev;
  sdio_claim_host(sdiodev->func1);

#ifdef SDIO_PRINTER
  int status = thrd_create_with_name(&sdio_thread, &sdio_printer, nullptr, "sdio_printer");
  if (status != thrd_success) {
    BRCMF_ERR("Unable to create sdio_printer thread: %d" < status);
    goto fail;
  }
#endif  // SDIO_PRINTER

  BRCMF_DBG(INFO, "brcmfmac: F1 signature read @0x18000000=0x%4x",
            brcmf_sdiod_func1_rl(sdiodev, SI_ENUM_BASE, NULL));
  BRCMF_DBG(TEMP, "Survived signature read");

  /*
   * Force PLL off until brcmf_chip_attach()
   * programs PLL control regs
   */

  brcmf_sdiod_func1_wb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, BRCMF_INIT_CLKCTL1, &err);
  if (err == ZX_OK) {
    clkctl = brcmf_sdiod_func1_rb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
  }

  if (err != ZX_OK || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
    BRCMF_ERR("ChipClkCSR access: err %s wrote 0x%02x read 0x%02x", zx_status_get_string(err),
              BRCMF_INIT_CLKCTL1, clkctl);
    goto fail;
  }

  err = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops, &bus->ci);
  if (err != ZX_OK) {
    BRCMF_ERR("brcmf_chip_attach failed: %s", zx_status_get_string(err));
    bus->ci = NULL;
    goto fail;
  }

  /* Pick up the SDIO core info struct from chip.c */
  bus->sdio_core = brcmf_chip_get_core(bus->ci, CHIPSET_SDIO_DEV_CORE);
  if (!bus->sdio_core) {
    BRCMF_ERR("call to brcmf_chip_get_core (SDIO_DEV_CORE) failed");
    err = ZX_ERR_INTERNAL;
    goto fail;
  }

  /* Pick up the CHIPCOMMON core info struct, for bulk IO in bcmsdh.c */
  sdiodev->cc_core = brcmf_chip_get_core(bus->ci, CHIPSET_CHIPCOMMON_CORE);
  if (!sdiodev->cc_core) {
    BRCMF_ERR("call to brcmf_chip_get_core (CHIPCOMMON_CORE) failed");
    err = ZX_ERR_INTERNAL;
    goto fail;
  }

  settings = static_cast<decltype(settings)>(calloc(1, sizeof(*settings)));
  if (!settings) {
    BRCMF_ERR("failed to allocate device parameters");
    err = ZX_ERR_NO_MEMORY;
    goto fail;
  }
  brcmf_get_module_param(BRCMF_BUS_TYPE_SDIO, bus->ci->chip, bus->ci->chiprev, settings);
  sdiodev->settings = settings;

  sdio_settings = static_cast<decltype(sdio_settings)>(calloc(1, sizeof(*sdio_settings)));
  if (!sdio_settings) {
    BRCMF_ERR("failed to allocate SDIO parameters");
    err = ZX_ERR_NO_MEMORY;
    goto fail;
  }
  // TODO(cphoenix): Do we really want to use default? (If so, delete =0 lines because calloc)
  sdio_settings->sd_sgentry_align = 0;      // Use default
  sdio_settings->sd_head_align = 0;         // Use default
  sdio_settings->drive_strength = 0;        // Use default
  sdio_settings->oob_irq_supported = true;  // TODO(cphoenix): Always?
  sdiodev->settings->bus.sdio = sdio_settings;

  /* platform specific configuration:
   *   alignments must be at least 4 bytes for ADMA
   */
  bus->head_align = DMA_ALIGNMENT;
  bus->sgentry_align = DMA_ALIGNMENT;
  if (sdiodev->settings->bus.sdio->sd_head_align > DMA_ALIGNMENT) {
    if (sdiodev->settings->bus.sdio->sd_head_align > std::numeric_limits<uint16_t>::max()) {
      BRCMF_ERR("brcmf_sdio_probe_attach error: sd_head_align invalid (overflow)");
      err = ZX_ERR_INTERNAL;
      goto fail;
    }
    bus->head_align = static_cast<uint16_t>(sdiodev->settings->bus.sdio->sd_head_align);
  }
  if (sdiodev->settings->bus.sdio->sd_sgentry_align > DMA_ALIGNMENT) {
    if (sdiodev->settings->bus.sdio->sd_sgentry_align > std::numeric_limits<uint8_t>::max()) {
      BRCMF_ERR("brcmf_sdio_probe_attach error: sgentry_align invalid (overflow)");
      err = ZX_ERR_INTERNAL;
      goto fail;
    }
    bus->sgentry_align = static_cast<uint16_t>(sdiodev->settings->bus.sdio->sd_sgentry_align);
  }

  err = brcmf_sdio_kso_init(bus);
  if (err != ZX_OK) {
    BRCMF_ERR("error enabling KSO: %s", zx_status_get_string(err));
    goto fail;
  }

  if (sdiodev->settings->bus.sdio->drive_strength) {
    drivestrength = sdiodev->settings->bus.sdio->drive_strength;
  } else {
    drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
  }
  brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength);

  /* Set card control so an SDIO card reset does a WLAN backplane reset */
  reg_val = brcmf_sdiod_vendor_control_rb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err);
  if (err != ZX_OK) {
    BRCMF_ERR("vendor_control_rb failed: %s", zx_status_get_string(err));
    goto fail;
  }

  reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET;
  if (reg_val > std::numeric_limits<uint8_t>::max()) {
    BRCMF_ERR("vendor_control_wb cannot be called: reg_val invalid (overflow)");
    err = ZX_ERR_INTERNAL;
    goto fail;
  }
  brcmf_sdiod_vendor_control_wb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, static_cast<uint8_t>(reg_val),
                                &err);
  if (err != ZX_OK) {
    BRCMF_ERR("vendor_control_wb failed: %s", zx_status_get_string(err));
    goto fail;
  }

  /* set PMUControl so a backplane reset does PMU state reload */
  reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol);
  reg_val = brcmf_sdiod_func1_rl(sdiodev, reg_addr, &err);
  if (err != ZX_OK) {
    BRCMF_ERR("func1_rl failed: %s", zx_status_get_string(err));
    goto fail;
  }

  reg_val |= (BC_CORE_POWER_CONTROL_RELOAD << BC_CORE_POWER_CONTROL_SHIFT);

  brcmf_sdiod_func1_wl(sdiodev, reg_addr, reg_val, &err);
  if (err != ZX_OK) {
    BRCMF_ERR("func1_wl failed: %s", zx_status_get_string(err));
    goto fail;
  }

  sdio_release_host(sdiodev->func1);

  brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);

  /* allocate header buffer */
  bus->hdrbuf = static_cast<decltype(bus->hdrbuf)>(calloc(1, MAX_HDR_READ + bus->head_align));
  if (!bus->hdrbuf) {
    BRCMF_ERR("failed to allocate memory for SDIO hdrbuf");
    // Don't go to 'fail' here because we've already released the host
    return ZX_ERR_NO_MEMORY;
  }
  /* Locate an appropriately-aligned portion of hdrbuf */
  bus->rxhdr = (uint8_t*)roundup((unsigned long)&bus->hdrbuf[0], bus->head_align);

  /* Set the poll and/or interrupt flags */
  bus->intr = true;
  bus->poll = false;
  if (bus->poll) {
    bus->pollrate = 1;
  }

  BRCMF_DBG(TEMP, "Exit");
  ZX_DEBUG_ASSERT(err == ZX_OK);
#if !defined(NDEBUG)
  if (BRCMF_IS_ON(FWCON)) {
    bus->console_interval = BRCMF_CONSOLE_INTERVAL;
  }
#endif
  return err;

fail:
  sdio_release_host(sdiodev->func1);
  BRCMF_DBG(TEMP, "* * FAIL");
  return err;
}

static int brcmf_sdio_watchdog_thread(void* data) {
  struct brcmf_sdio* bus = (struct brcmf_sdio*)data;

  /* Run until signal received */
  while (1) {
    if (bus->watchdog_should_stop.load()) {
      break;
    }
    // Wait for watchdog signal
    sync_completion_wait(&bus->watchdog_wait, ZX_TIME_INFINITE);

    if (bus->wd_active.load()) {
      brcmf_sdio_bus_watchdog(bus);
    }
    /* Count the tick for reference */
    bus->sdcnt.tickcnt++;
    sync_completion_reset(&bus->watchdog_wait);
  }
  return 0;
}

static void brcmf_sdio_watchdog(struct brcmf_sdio* bus) {
  bus->sdiodev->drvr->irq_callback_lock.lock();

  if (bus->watchdog_tsk) {
    // Signal watchdog
    sync_completion_signal(&bus->watchdog_wait);
    /* Reschedule the watchdog */
    if (bus->wd_active.load()) {
      bus->timer->Start(ZX_MSEC(BRCMF_WD_POLL_MSEC));
    }
  }
  bus->sdiodev->drvr->irq_callback_lock.unlock();
}

static zx_status_t brcmf_get_wifi_metadata(brcmf_bus* bus_if, void* data, size_t exp_size,
                                           size_t* actual) {
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  return sdiodev->drvr->device->DeviceGetMetadata(DEVICE_METADATA_WIFI_CONFIG, data, exp_size,
                                                  actual);
}

static zx_status_t brcmf_sdio_get_bootloader_macaddr(brcmf_bus* bus_if, uint8_t* mac_addr) {
  struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
  static uint8_t bootloader_macaddr[ETH_ALEN];
  static bool memoized = false;
  zx_status_t status;

  if (!memoized) {
    status = brcmf_sdiod_get_bootloader_macaddr(sdiodev, bootloader_macaddr);
    if (status != ZX_OK) {
      return status;
    }
    memoized = true;
  }

  memcpy(mac_addr, bootloader_macaddr, sizeof(bootloader_macaddr));
  return ZX_OK;
}

static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
    .get_bus_type = []() { return BRCMF_BUS_TYPE_SDIO; },
    .get_bootloader_macaddr = brcmf_sdio_get_bootloader_macaddr,
    .get_wifi_metadata = brcmf_get_wifi_metadata,
    .preinit = brcmf_sdio_bus_preinit,
    .stop = brcmf_sdio_bus_stop,
    .txdata = brcmf_sdio_bus_txdata,
    .txctl = brcmf_sdio_bus_txctl,
    .rxctl = brcmf_sdio_bus_rxctl,
    .gettxq = brcmf_sdio_bus_gettxq,
    .flush_txq = brcmf_sdio_bus_flush_txq,
    .recovery = brcmf_sdio_recovery,
    .log_stats = brcmf_sdio_log_stats,
};

zx_status_t brcmf_sdio_firmware_callback(brcmf_pub* drvr, const void* firmware,
                                         size_t firmware_size, const void* nvram,
                                         size_t nvram_size) {
  zx_status_t err = ZX_OK;
  struct brcmf_sdio_dev* sdiodev = drvr->bus_if->bus_priv.sdio;
  struct brcmf_sdio* bus = sdiodev->bus;
  struct brcmf_sdio_dev* sdiod = bus->sdiodev;
  struct brcmf_core* core = bus->sdio_core;
  struct sdpcm_shared sh = {};
  uint8_t saveclk = 0;

  BRCMF_DBG(TRACE, "Enter:");

  if (err != ZX_OK) {
    goto fail;
  }

  /* try to download image and nvram to the dongle */
  bus->alp_only = true;
  err = brcmf_sdio_download_firmware(bus, firmware, firmware_size, nvram, nvram_size);
  if (err != ZX_OK) {
    goto fail;
  }
  bus->alp_only = false;

  /* Start the watchdog timer */
  bus->sdcnt.tickcnt = 0;
  // TODO(fxbug.dev/29365): This call apparently has no effect because the state isn't
  // BRCMF_SDIOD_DATA. This was in the original driver. Once interrupts are working, figure out
  // what's going on.
  brcmf_sdio_wd_timer(bus, true);

  // Magic 200 ms pause here, because 100ms worked in the hard-coded debug recipe.
  // In addition, Broadcom said that a pause after booting may be necessary.
  // The original Linux driver doesn't have it, but I don't recommend removing this
  // without LOTS of stress testing.
  zx_nanosleep(zx_deadline_after(ZX_MSEC(200)));
  sdio_claim_host(sdiodev->func1);

  /* Make sure backplane clock is on, needed to generate F2 interrupt */
  bus->clkstate = CLK_NONE;  // TODO(cphoenix): TEMP FOR DEBUG
  brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  if (bus->clkstate != CLK_AVAIL) {
    BRCMF_ERR("Bad clockstate %d, should be %d", bus->clkstate, CLK_AVAIL);
    err = ZX_ERR_INTERNAL;
    goto release;
  }

  /* Force clocks on backplane to be sure F2 interrupt propagates */
  saveclk = brcmf_sdiod_func1_rb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
  if (err == ZX_OK) {
    brcmf_sdiod_func1_wb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, (saveclk | SBSDIO_FORCE_HT), &err);
  }
  if (err != ZX_OK) {
    BRCMF_ERR("Failed to force clock for F2: err %s", zx_status_get_string(err));
    goto release;
  }

  /* Enable function 2 (frame transfers) */
  brcmf_sdiod_func1_wl(sdiod, core->base + SD_REG(tosbmailboxdata),
                       SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL);

  err = sdio_enable_fn(&sdiodev->sdio_proto_fn2);
  BRCMF_DBG(INFO, "enable F2: err=%d", err);

  /* If F2 successfully enabled, set core and enable interrupts */
  if (err == ZX_OK) {
    /* Set up the interrupt mask and enable interrupts */
    bus->hostintmask = HOSTINTMASK;
    brcmf_sdiod_func1_wl(sdiod, core->base + SD_REG(hostintmask), bus->hostintmask, NULL);

    brcmf_sdiod_func1_wb(sdiodev, SBSDIO_WATERMARK, 8, &err);
  } else {
    /* Disable F2 again */
    sdio_disable_fn(&sdiodev->sdio_proto_fn2);
    goto release;
  }

  if (brcmf_chip_sr_capable(bus->ci)) {
    BRCMF_DBG(TEMP, "About to sr_init() (after 100 msec pause)");
    PAUSE;
    PAUSE;
    brcmf_sdio_sr_init(bus);
    PAUSE;
    PAUSE;
    BRCMF_DBG(TEMP, "Did sr_init() (100 msec ago)");
  } else {
    /* Restore previous clock setting */
    brcmf_sdiod_func1_wb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
  }

  err = brcmf_sdio_shared_read(bus, &sh);
  BRCMF_DBG(TEMP, "Read shared returned %d", err);

#if !defined(NDEBUG)
  bus->console_addr = sh.console_addr;
  BRCMF_DBG(TEMP, "console_addr 0x%x", bus->console_addr);
  brcmf_sdio_readconsole(bus);
  BRCMF_DBG(TEMP, "Should have seen readconsole output");
#endif  // !defined(NDEBUG)

  if (err == ZX_OK) {
    /* Allow full data communication using DPC from now on. */
    brcmf_sdiod_change_state(sdiod, BRCMF_SDIOD_DATA);
    // TODO(fxbug.dev/29365): The next line was added to enable watchdog to take effect immediately,
    // since it currently handles all interrupt conditions. This may or may not make the
    // previous call to brcmf_sdio_wd_timer() unnecessary; that call apparently had no effect
    // because the state wasn't BRCMF_SDIOD_DATA yet. Once interrupts are working, revisit
    // and figure out this logic.
    brcmf_sdio_wd_timer(bus, true);

    // brcmf_sdiod_intr_register() creates the interrupt thread and enables the sdio interrupt
    // through sdio proto, so it can be skipped while doing crash recovery.
    if (bus->sdiodev->drvr->fw_reloading.try_lock()) {
      err = brcmf_sdiod_intr_register(sdiodev);
      if (err != ZX_OK) {
        BRCMF_ERR("intr register failed:%d", err);
      }
      bus->sdiodev->drvr->fw_reloading.unlock();
    }
  }

  /* If we didn't come up, turn off backplane clock */
  if (err != ZX_OK) {
    BRCMF_ERR("Err %d on register OOB IRQ", err);
    brcmf_sdio_clkctl(bus, CLK_NONE, false);
  }

  sdio_release_host(sdiodev->func1);
  zx_nanosleep(zx_deadline_after(ZX_MSEC(100)));

  return ZX_OK;

release:
  sdio_release_host(sdiodev->func1);

fail:
  BRCMF_DBG(TRACE, "failed: err=%d", err);
  BRCMF_ERR("Need to implement driver release logic (fxbug.dev/29508)");
  // TODO(fxbug.dev/29508)
  // device_release_driver(&sdiodev->func2->dev);
  // device_release_driver(dev);

  return err;
}

struct brcmf_sdio* brcmf_sdio_probe(struct brcmf_sdio_dev* sdiodev) {
  zx_status_t ret;
  int thread_result;
  struct brcmf_sdio* bus;
  WorkQueue* wq;

  BRCMF_DBG(TRACE, "Enter");
  /* Allocate private bus interface state */
  bus = static_cast<decltype(bus)>(calloc(1, sizeof(struct brcmf_sdio)));
  if (!bus) {
    goto fail;
  }

  bus->sdiodev = sdiodev;
  sdiodev->bus = bus;
  brcmf_netbuf_list_init(&bus->glom);
  bus->txbound = BRCMF_TXBOUND;
  bus->rxbound = BRCMF_RXBOUND;
  bus->txminmax = BRCMF_TXMINMAX;
  bus->tx_seq = SDPCM_SEQ_WRAP - 1;

  /* single-threaded workqueue */
  char name[WorkQueue::kWorkqueueNameMaxlen];
  static int queue_uniquify = 0;
  snprintf(name, WorkQueue::kWorkqueueNameMaxlen, "brcmf_wq/%d", queue_uniquify++);
  wq = new WorkQueue(name);
  if (!wq) {
    BRCMF_ERR("insufficient memory to create txworkqueue");
    goto fail;
  }
  bus->datawork = WorkItem(brcmf_sdio_dataworker);
  bus->brcmf_wq = wq;

  /* attempt to attach to the dongle */
  ret = brcmf_sdio_probe_attach(bus);
  if (ret != ZX_OK) {
    BRCMF_ERR("brcmf_sdio_probe_attach failed: %s", zx_status_get_string(ret));
    goto fail;
  }

  // spin_lock_init(&bus->rxctl_lock);
  // spin_lock_init(&bus->txq_lock);
  bus->ctrl_wait = {};
  bus->dcmd_resp_wait = {};

  /* Initialize watchdog thread */
  bus->watchdog_wait = {};
  bus->watchdog_should_stop.store(false);
  thread_result =
      thrd_create_with_name(&bus->watchdog_tsk, &brcmf_sdio_watchdog_thread, bus, "brcmf-watchdog");

  if (thread_result != thrd_success) {
    BRCMF_ERR("brcmf_watchdog thread failed to start: error %d", thread_result);
    bus->watchdog_tsk = 0;
  }
  /* Initialize DPC thread */
  bus->dpc_triggered.store(false);
  bus->dpc_running = false;

  /* Assign bus interface call back */
  bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops;
  bus->sdiodev->bus_if->chip = bus->ci->chip;
  bus->sdiodev->bus_if->chiprev = bus->ci->chiprev;

  /* default sdio bus header length for tx packet */
  bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;

  /* Attach to the common layer, reserve hdr space */
  bus->sdiodev->drvr->bus_if = bus->sdiodev->bus_if;
  bus->sdiodev->drvr->settings = bus->sdiodev->settings;

  /* Set up the watchdog timer */
  bus->timer = new Timer(bus->sdiodev->drvr->device->GetDispatcher(),
                         std::bind(brcmf_sdio_watchdog, bus), false);

  ret = brcmf_attach(bus->sdiodev->drvr);
  if (ret != ZX_OK) {
    BRCMF_ERR("brcmf_attach failed");
    goto fail;
  }

  /* Attach and link in the protocol */
  ret = brcmf_proto_bcdc_attach(sdiodev->drvr);
  if (ret != ZX_OK) {
    BRCMF_ERR("brcmf_proto_bcdc_attach failed: %s", zx_status_get_string(ret));
    goto fail;
  }

  /* Query the F2 block size, set roundup accordingly */
  sdio_get_block_size(&sdiodev->sdio_proto_fn2, &bus->blocksize);
  bus->roundup = std::min(max_roundup, bus->blocksize);

  /* Allocate buffers */
  if (bus->sdiodev->bus_if->maxctl) {
    bus->sdiodev->bus_if->maxctl += bus->roundup;
    bus->rxblen =
        roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), DMA_ALIGNMENT) + bus->head_align;
    bus->rxbuf = static_cast<decltype(bus->rxbuf)>(malloc(bus->rxblen));
    if (!(bus->rxbuf)) {
      BRCMF_ERR("rxbuf allocation failed");
      goto fail;
    }
  }

  sdio_claim_host(bus->sdiodev->func1);

  /* Disable F2 to clear any intermediate frame state on the dongle */
  sdio_disable_fn(&bus->sdiodev->sdio_proto_fn2);

  bus->rxflow = false;

  /* Done with backplane-dependent accesses, can drop clock... */
  brcmf_sdiod_func1_wb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);

  sdio_release_host(bus->sdiodev->func1);

  /* ...and initialize clock/power states */
  bus->clkstate = CLK_SDONLY;
  bus->idletime = BRCMF_IDLE_INTERVAL;
  bus->idleclock = BRCMF_IDLE_ACTIVE;

  /* SR state */
  bus->sr_enabled = false;

  BRCMF_DBG(INFO, "completed!!");
  if (ret != ZX_OK) {
    goto fail;
  }

  return bus;

fail:
  brcmf_sdio_remove(bus);
  return NULL;
}

/* Detach and free everything */
void brcmf_sdio_remove(struct brcmf_sdio* bus) {
  BRCMF_DBG(TRACE, "Enter");

  if (bus) {
    /* De-register interrupt handler */
    brcmf_sdiod_intr_unregister(bus->sdiodev);
    brcmf_proto_bcdc_detach(bus->sdiodev->drvr);

    brcmf_detach(bus->sdiodev->drvr);

    bus->datawork.Cancel();
    if (bus->brcmf_wq) {
      delete bus->brcmf_wq;
    }
    if (bus->ci) {
      if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
        sdio_claim_host(bus->sdiodev->func1);
        brcmf_sdio_wd_timer(bus, false);
        brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
        /* Leave the device in state where it is
         * 'passive'. This is done by resetting all
         * necessary cores.
         */
        msleep(20);
        brcmf_chip_set_passive(bus->ci);
        brcmf_sdio_clkctl(bus, CLK_NONE, false);
        sdio_release_host(bus->sdiodev->func1);
      }
      brcmf_chip_detach(bus->ci);
    }
    if (bus->sdiodev->settings) {
      if (bus->sdiodev->settings->bus.sdio) {
        free(bus->sdiodev->settings->bus.sdio);
      }
      free(bus->sdiodev->settings);
    }

    delete bus->timer;
    free(bus->rxbuf);
    free(bus->hdrbuf);
    free(bus);
  }

  BRCMF_DBG(TRACE, "Bus Disconnected");
}

/*Reset things When recovering from firmware crash*/
void brcmf_sdio_reset(struct brcmf_sdio* bus) {
  BRCMF_DBG(TRACE, "Enter");

  // Stop watch dog timer temporarily.
  brcmf_sdio_wd_timer(bus, false);

  // Flush the glom rx list.
  brcmf_sdio_free_glom(bus);

  // Clean up the data path.
  bus->datawork.Cancel();
  bus->brcmf_wq->Flush();

  // Flush rx buffer.
  memset(bus->rxbuf, 0, bus->rxblen);

  // Flush tx queue.
  brcmu_pktq_flush(&bus->txq, true, NULL, NULL);

  // Restart watchdog timer
  brcmf_sdio_wd_timer(bus, true);
}

void brcmf_sdio_wd_timer(struct brcmf_sdio* bus, bool active) {
  /* Totally stop the timer */
  if (!active && bus->wd_active.load()) {
    bus->timer->Stop();
    bus->wd_active.store(false);
    return;
  }

  /* don't start the wd until fw is loaded */
  if (bus->sdiodev->state != BRCMF_SDIOD_DATA) {
    return;
  }

  if (active) {
    bus->wd_active.store(true);
    bus->timer->Start(ZX_MSEC(BRCMF_WD_POLL_MSEC));
  }
}

zx_status_t brcmf_sdio_sleep(struct brcmf_sdio* bus, bool sleep) {
  zx_status_t ret;

  sdio_claim_host(bus->sdiodev->func1);
  ret = brcmf_sdio_bus_sleep(bus, sleep, false);
  sdio_release_host(bus->sdiodev->func1);

  return ret;
}
