/******************************************************************************
 *
 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
 * Copyright(c) 2018 Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

#include "src/iwlwifi/fw/api/tx.h"

#include <zircon/status.h>
#include <zircon/types.h>

//#include <src/iwlwifi/ieee80211.h>

#if 0  // NEEDS_PORTING
#include "src/iwlwifi/iwl-op-mode.h"
#endif  // NEEDS_PORTING
#include "src/iwlwifi/iwl-csr.h"
#include "src/iwlwifi/iwl-debug.h"
#include "src/iwlwifi/iwl-io.h"
#include "src/iwlwifi/iwl-prph.h"
#include "src/iwlwifi/iwl-scd.h"
#include "src/iwlwifi/pcie/internal.h"
#include "src/iwlwifi/platform/ieee80211.h"

#define IWL_TX_CRC_SIZE 4
#define IWL_TX_DELIMITER_SIZE 4

#define TB1_MAX_SIZE sizeof(struct iwl_device_cmd)  // 304-byte

/*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
 * DMA services
 *
 * Theory of operation
 *
 * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
 * of buffer descriptors, each of which points to one or more data buffers for
 * the device to read from or fill.  Driver and device exchange status of each
 * queue via "read" and "write" pointers.  Driver keeps minimum of 2 empty
 * entries in each circular buffer, to protect against confusing empty and full
 * queue states.
 *
 * The device reads or writes the data in the queues via the device's several
 * DMA/FIFO channels.  Each queue is mapped to a single DMA channel.
 *
 * For Tx queue, there are low mark and high mark limits. If, after queuing
 * the packet for Tx, free space become < low mark, Tx queue stopped. When
 * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
 * Tx queue resumed.
 *
 ***************************************************/

int iwl_queue_space(struct iwl_trans* trans, const struct iwl_txq* q) {
  uint16_t max;
  uint16_t used;

  /*
   * To avoid ambiguity between empty and completely full queues, there
   * should always be less than max_tfd_queue_size elements in the queue.
   * If q->n_window is smaller than max_tfd_queue_size, there is no need
   * to reserve any queue entries for this purpose.
   */
  if (q->n_window < trans->cfg->base_params->max_tfd_queue_size) {
    max = q->n_window;
  } else {
    max = trans->cfg->base_params->max_tfd_queue_size - 1;
  }

  /*
   * max_tfd_queue_size is a power of 2, so the following is equivalent to
   * modulo by max_tfd_queue_size and is well defined.
   */
  used = (q->write_ptr - q->read_ptr) & (trans->cfg->base_params->max_tfd_queue_size - 1);

  if (WARN_ON(used > max)) {
    return 0;
  }

  return max - used;
}

/*
 * iwl_queue_init - Initialize queue's high/low-water and read/write indexes
 */
static zx_status_t iwl_queue_init(struct iwl_txq* q, uint16_t slots_num) {
  q->n_window = slots_num;

  // slots_num must be power-of-two size, otherwise iwl_pcie_get_cmd_index is broken.
  if (WARN_ON(slots_num <= 0 || (slots_num & (slots_num - 1)) != 0)) {
    return ZX_ERR_INVALID_ARGS;
  }

  q->low_mark = q->n_window / 4;
  if (q->low_mark < 4) {
    q->low_mark = 4;
  }

  q->high_mark = q->n_window / 8;
  if (q->high_mark < 2) {
    q->high_mark = 2;
  }

  q->write_ptr = 0;
  q->read_ptr = 0;

  return ZX_OK;
}

zx_status_t iwl_pcie_alloc_dma_ptr(struct iwl_trans* trans, struct iwl_dma_ptr* ptr, size_t size) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  zx_status_t status = iwl_iobuf_allocate_contiguous(&trans_pcie->pci_dev->dev, size, &ptr->io_buf);
  if (status != ZX_OK) {
    return status;
  }

  ptr->size = size;
  ptr->addr = iwl_iobuf_virtual(ptr->io_buf);
  ptr->dma = iwl_iobuf_physical(ptr->io_buf);
  return ZX_OK;
}

void iwl_pcie_free_dma_ptr(struct iwl_trans* trans, struct iwl_dma_ptr* ptr) {
  iwl_iobuf_release(ptr->io_buf);
  ptr->io_buf = NULL;
}

static void iwl_pcie_txq_stuck_timer(void* data) {
  struct iwl_txq* txq = data;

  mtx_lock(&txq->lock);
  /* check if triggered erroneously */
  if (txq->read_ptr == txq->write_ptr) {
    mtx_unlock(&txq->lock);
    return;
  }
  mtx_unlock(&txq->lock);

#if 0   // NEEDS_PORTING
  struct iwl_trans_pcie* trans_pcie = txq->trans_pcie;
  struct iwl_trans* trans = iwl_trans_pcie_get_trans(trans_pcie);
  iwl_trans_pcie_log_scd_error(trans, txq);

  iwl_force_nmi(trans);
#endif  // NEEDS_PORTING
}

/*
 * iwl_pcie_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
 */
static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans* trans, struct iwl_txq* txq,
                                             uint16_t byte_cnt, int num_tbs) {
  struct iwlagn_scd_bc_tbl* scd_bc_tbl;
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  int write_ptr = txq->write_ptr;
  int txq_id = txq->id;
  uint16_t len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
  __le16 bc_ent;
  struct iwl_tx_cmd* tx_cmd =
      (void*)((struct iwl_device_cmd*)iwl_iobuf_virtual(
                  txq->entries[iwl_pcie_get_cmd_index(txq, txq->write_ptr)].cmd))
          ->payload;
  uint8_t sta_id = tx_cmd->sta_id;

  scd_bc_tbl = trans_pcie->scd_bc_tbls.addr;

#if 0   // NEEDS_PORTING
    // TODO(37594): encryption
    switch (sec_ctl & TX_CMD_SEC_MSK) {
    case TX_CMD_SEC_CCM:
        len += IEEE80211_CCMP_128_MIC_LEN;
        break;
    case TX_CMD_SEC_TKIP:
        len += IEEE80211_TKIP_ICV_LEN;
        break;
    case TX_CMD_SEC_WEP:
        len += IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN;
        break;
    }
#endif  // NEEDS_PORTING
  if (trans_pcie->bc_table_dword) {
    len = DIV_ROUND_UP(len, 4);
  }

  if (len > 0xFFF) {
    IWL_WARN(trans, "%s(): invalid len: %d (expect smaller than 4096\n", __func__, len);
    return;
  }
  if (write_ptr >= TFD_QUEUE_SIZE_MAX) {
    IWL_WARN(trans, "%s(): invalid write_ptr: %d (expect smaller than %d.\n", __func__, write_ptr,
             TFD_QUEUE_SIZE_MAX);
    return;
  }

  bc_ent = cpu_to_le16(len | (sta_id << 12));

  scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;

  if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) {
    scd_bc_tbl[txq_id].tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
  }
}

#if 0   // NEEDS_PORTING
static void iwl_pcie_txq_inval_byte_cnt_tbl(struct iwl_trans* trans, struct iwl_txq* txq) {
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    struct iwlagn_scd_bc_tbl* scd_bc_tbl = trans_pcie->scd_bc_tbls.addr;
    int txq_id = txq->id;
    int read_ptr = txq->read_ptr;
    uint8_t sta_id = 0;
    __le16 bc_ent;
    struct iwl_tx_cmd* tx_cmd = (void*)txq->entries[read_ptr].cmd->payload;

    WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);

    if (txq_id != trans_pcie->cmd_queue) { sta_id = tx_cmd->sta_id; }

    bc_ent = cpu_to_le16(1 | (sta_id << 12));

    scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;

    if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) {
        scd_bc_tbl[txq_id].tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
    }
}
#endif  // NEEDS_PORTING

/*
 * iwl_pcie_txq_inc_wr_ptr - Send new write index to hardware
 */
static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans* trans, struct iwl_txq* txq) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  uint32_t reg = 0;
  int txq_id = txq->id;

  iwl_assert_lock_held(&txq->lock);

  /*
   * explicitly wake up the NIC if:
   * 1. shadow registers aren't enabled
   * 2. NIC is woken up for CMD regardless of shadow outside this function
   * 3. there is a chance that the NIC is asleep
   */
  if (!trans->cfg->base_params->shadow_reg_enable && txq_id != trans_pcie->cmd_queue &&
      test_bit(STATUS_TPOWER_PMI, &trans->status)) {
    /*
     * wake up nic if it's powered down ...
     * uCode will wake up, and interrupt us again, so next
     * time we'll skip this part.
     */
    reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);

    if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
      IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n", txq_id, reg);
      iwl_set_bit(trans, CSR_GP_CNTRL, BIT(trans->cfg->csr->flag_mac_access_req));
      txq->need_update = true;
      return;
    }
  }

  /*
   * if not in power-save mode, uCode will never sleep when we're
   * trying to tx (during RFKILL, we're not trying to tx).
   */
  IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, txq->write_ptr);
  if (!txq->block) {
    iwl_write32(trans, HBUS_TARG_WRPTR, txq->write_ptr | (txq_id << 8));
  }
}

void iwl_pcie_txq_check_wrptrs(struct iwl_trans* trans) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  int i;

  for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
    struct iwl_txq* txq = trans_pcie->txq[i];

    if (!test_bit(i, trans_pcie->queue_used)) {
      continue;
    }

    mtx_lock(&txq->lock);
    if (txq->need_update) {
      iwl_pcie_txq_inc_wr_ptr(trans, txq);
      txq->need_update = false;
    }
    mtx_unlock(&txq->lock);
  }
}

static inline void iwl_pcie_tfd_set_tb(struct iwl_trans* trans, void* tfd, uint8_t idx,
                                       zx_paddr_t addr, uint16_t len) {
  struct iwl_tfd* tfd_fh = (void*)tfd;
  struct iwl_tfd_tb* tb = &tfd_fh->tbs[idx];

  uint16_t hi_n_len = len << 4;

  tb->lo = cpu_to_le32(addr);
  hi_n_len |= iwl_get_dma_hi_addr(addr);

  tb->hi_n_len = cpu_to_le16(hi_n_len);

  tfd_fh->num_tbs = idx + 1;
}

static inline uint8_t iwl_pcie_tfd_get_num_tbs(struct iwl_trans* trans, void* _tfd) {
  if (trans->cfg->use_tfh) {
    struct iwl_tfh_tfd* tfd = _tfd;

    return le16_to_cpu(tfd->num_tbs) & 0x1f;
  } else {
    struct iwl_tfd* tfd = _tfd;

    return tfd->num_tbs & 0x1f;
  }
}

//
// Since DMA addresses are manipulated by iobufs, we don't do DMA unmap here. Instead,
// we update the TFD entry only (zero-ing num_tbs).
//
static void iwl_pcie_tfd_unmap(struct iwl_trans* trans, struct iwl_cmd_meta* meta,
                               struct iwl_txq* txq, int index) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  int num_tbs;
  void* tfd = iwl_pcie_get_tfd(trans, txq, index);

  /* Sanity check on number of chunks */
  num_tbs = iwl_pcie_tfd_get_num_tbs(trans, tfd);

  if (num_tbs > trans_pcie->max_tbs) {
    IWL_ERR(trans, "Too many chunks: %i\n", num_tbs);
    /* @todo issue fatal error, it is quite serious situation */
    return;
  }

  // First TB is never freed - it's the bidirectional DMA data.
  // All first TBs (first_tb_bufs) will be freed at iwl_pcie_txq_free().

  if (trans->cfg->use_tfh) {
    struct iwl_tfh_tfd* tfd_fh = (void*)tfd;

    tfd_fh->num_tbs = 0;
  } else {
    struct iwl_tfd* tfd_fh = (void*)tfd;

    tfd_fh->num_tbs = 0;
  }
}

/*
 * iwl_pcie_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
 * @trans - transport private data
 * @txq - tx queue
 *
 * Does NOT advance any TFD circular buffer read/write indexes
 * Does NOT free the TFD itself (which is within circular buffer)
 */
void iwl_pcie_txq_free_tfd(struct iwl_trans* trans, struct iwl_txq* txq) {
  /* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and
   * idx is bounded by n_window
   */
  int rd_ptr = txq->read_ptr;
  int idx = iwl_pcie_get_cmd_index(txq, rd_ptr);

  iwl_assert_lock_held(&txq->lock);

  /* We have only q->n_window txq->entries, but we use
   * TFD_QUEUE_SIZE_MAX tfds
   */
  iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, txq, rd_ptr);
}

// Build TX queue transfer descriptor.
//
// TODO(fxbug.dev/61186): refactor this for testing.
//
static zx_status_t iwl_pcie_txq_build_tfd(struct iwl_trans* trans, struct iwl_txq* txq,
                                          zx_paddr_t addr, uint16_t len, bool reset,
                                          uint32_t* num_tbs) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  void* tfd;

  void* tfds = iwl_iobuf_virtual(txq->tfds);
  tfd = tfds + trans_pcie->tfd_size * txq->write_ptr;

  if (reset) {
    memset(tfd, 0, trans_pcie->tfd_size);
  }

  *num_tbs = iwl_pcie_tfd_get_num_tbs(trans, tfd);

  /* Each TFD can point to a maximum max_tbs Tx buffers */
  if (*num_tbs >= trans_pcie->max_tbs) {
    IWL_ERR(trans, "Error can not send more than %d chunks\n", trans_pcie->max_tbs);
    return ZX_ERR_INVALID_ARGS;
  }

  if (addr & ~IWL_TX_DMA_MASK) {
    IWL_WARN(trans, "Unaligned address = %lx\n", addr);
    return ZX_ERR_INVALID_ARGS;
  }

  iwl_pcie_tfd_set_tb(trans, tfd, *num_tbs, addr, len);

  return ZX_OK;
}

zx_status_t iwl_pcie_txq_alloc(struct iwl_trans* trans, struct iwl_txq* txq, uint16_t slots_num,
                               bool cmd_queue) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

  if (WARN_ON(txq->entries || txq->tfds)) {
    return ZX_ERR_BAD_STATE;
  }

  size_t tfd_sz = trans_pcie->tfd_size * trans->cfg->base_params->max_tfd_queue_size;
  if (trans->cfg->use_tfh) {
    tfd_sz = trans_pcie->tfd_size * slots_num;
  }

  iwl_irq_timer_create(trans->dev, iwl_pcie_txq_stuck_timer, &txq, &txq->stuck_timer);
  txq->trans_pcie = trans_pcie;

  txq->n_window = slots_num;

  txq->entries = calloc(slots_num, sizeof(struct iwl_pcie_txq_entry));

  if (!txq->entries) {
    goto error;
  }

  if (cmd_queue) {
    for (int i = 0; i < slots_num; i++) {
      zx_status_t status = iwl_iobuf_allocate_contiguous(
          &trans_pcie->pci_dev->dev, sizeof(struct iwl_device_cmd), &txq->entries[i].cmd);
      if (status != ZX_OK) {
        goto error;
      }
    }
  }

  // Circular buffer of transmit frame descriptors (TFDs), shared with device.
  zx_status_t status = iwl_iobuf_allocate_contiguous(&trans_pcie->pci_dev->dev, tfd_sz, &txq->tfds);
  if (status != ZX_OK) {
    goto error;
  }
  txq->dma_addr = iwl_iobuf_physical(txq->tfds);

  BUILD_BUG_ON(IWL_FIRST_TB_SIZE_ALIGN != sizeof(struct iwl_pcie_first_tb_buf));

  size_t tb0_buf_sz = sizeof(struct iwl_pcie_first_tb_buf) * slots_num;

  status =
      iwl_iobuf_allocate_contiguous(&trans_pcie->pci_dev->dev, tb0_buf_sz, &txq->first_tb_bufs);
  if (status != ZX_OK) {
    goto err_free_tfds;
  }

  return ZX_OK;

err_free_tfds:
  iwl_iobuf_release(txq->tfds);
  txq->tfds = NULL;
error:
  if (txq->entries && cmd_queue) {
    for (int i = 0; i < slots_num; i++) {
      iwl_iobuf_release(txq->entries[i].cmd);
      txq->entries[i].cmd = NULL;
    }
  }
  free(txq->entries);
  txq->entries = NULL;

  return ZX_ERR_NO_MEMORY;
}

zx_status_t iwl_pcie_txq_init(struct iwl_trans* trans, struct iwl_txq* txq, uint16_t slots_num,
                              bool cmd_queue) {
  uint32_t tfd_queue_max_size = trans->cfg->base_params->max_tfd_queue_size;

  txq->need_update = false;

  // max_tfd_queue_size must be power-of-two size, otherwise iwl_queue_inc_wrap and
  // iwl_queue_dec_wrap are broken.
  if (WARN_ON(tfd_queue_max_size & (tfd_queue_max_size - 1))) {
    IWL_ERR(trans, "Max tfd queue size must be a power of two, but is %d", tfd_queue_max_size);
    return ZX_ERR_INVALID_ARGS;
  }

  /* Initialize queue's high/low-water marks, and head/tail indexes */
  zx_status_t status = iwl_queue_init(txq, slots_num);
  if (status != ZX_OK) {
    return status;
  }

  mtx_init(&txq->lock, mtx_plain);

#if 0   // NEEDS_PORTING
    if (cmd_queue) {
        static struct lock_class_key iwl_pcie_cmd_queue_lock_class;
        lockdep_set_class(&txq->lock, &iwl_pcie_cmd_queue_lock_class);
    }

    __skb_queue_head_init(&txq->overflow_q);
#endif  // NEEDS_PORTING

  return 0;
}

#if 0   // NEEDS_PORTING
void iwl_pcie_free_tso_page(struct iwl_trans_pcie* trans_pcie, struct sk_buff* skb) {
    struct page** page_ptr;

    page_ptr = (void*)((uint8_t*)skb->cb + trans_pcie->page_offs);

    if (*page_ptr) {
        __free_page(*page_ptr);
        *page_ptr = NULL;
    }
}
#endif  // NEEDS_PORTING

static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans* trans) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

  iwl_assert_lock_held(&trans_pcie->reg_lock);

  if (trans_pcie->ref_cmd_in_flight) {
    trans_pcie->ref_cmd_in_flight = false;
    IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight - unref\n");
    iwl_trans_unref(trans);
  }

  if (!trans->cfg->base_params->apmg_wake_up_wa) {
    return;
  }
  if (WARN_ON(!trans_pcie->cmd_hold_nic_awake)) {
    return;
  }

  trans_pcie->cmd_hold_nic_awake = false;
  __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, BIT(trans->cfg->csr->flag_mac_access_req));
}

//
// This function will traverse all remaining entries in a Tx queue.
//
// On the last entry, unref the device so that the power management code can put this device into
// power saving mode. In addition, for command queue, clear the ref_cmd_in_flight bit.
//
void iwl_pcie_txq_unmap(struct iwl_trans* trans, int txq_id) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[txq_id];

  mtx_lock(&txq->lock);
  while (txq->write_ptr != txq->read_ptr) {
    IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", txq_id, txq->read_ptr);

    if (txq_id != trans_pcie->cmd_queue) {
#if 0   // NEEDS_PORTING
            iwl_pcie_free_tso_page(trans_pcie, skb);
#endif  // NEEDS_PORTING
    }
    iwl_pcie_txq_free_tfd(trans, txq);
    txq->read_ptr = iwl_queue_inc_wrap(trans, txq->read_ptr);

    if (txq->read_ptr == txq->write_ptr) {
      mtx_lock(&trans_pcie->reg_lock);
      if (txq_id != trans_pcie->cmd_queue) {
        IWL_DEBUG_RPM(trans, "Q %d - last tx freed\n", txq->id);
        iwl_trans_unref(trans);
      } else {
        iwl_pcie_clear_cmd_in_flight(trans);
      }
      mtx_unlock(&trans_pcie->reg_lock);
    }
  }

  mtx_unlock(&txq->lock);

  /* just in case - this queue may have been stopped */
  iwl_wake_queue(trans, txq);
}

/*
 * iwl_pcie_txq_free - Deallocate DMA queue.
 * @txq: Transmit queue to deallocate.
 *
 * Empty queue by removing and destroying all BD's.
 * Free all buffers.
 * 0-fill, but do not free "txq" descriptor structure.
 */
static void iwl_pcie_txq_free(struct iwl_trans* trans, int txq_id) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[txq_id];
  int i;

  if (WARN_ON(!txq)) {
    return;
  }

  iwl_pcie_txq_unmap(trans, txq_id);

  /* De-alloc array of command/tx buffers */
  if (txq_id == trans_pcie->cmd_queue) {
    for (i = 0; i < txq->n_window; i++) {
      iwl_iobuf_release(txq->entries[i].cmd);
      txq->entries[i].cmd = NULL;
      if (txq->entries[i].dup_io_buf) {
        iwl_iobuf_release(txq->entries[i].dup_io_buf);
        txq->entries[i].dup_io_buf = NULL;
      }
    }
  }

  /* De-alloc circular buffer of TFDs */
  iwl_iobuf_release(txq->tfds);
  txq->tfds = NULL;
  txq->dma_addr = 0;
  iwl_iobuf_release(txq->first_tb_bufs);
  txq->first_tb_bufs = NULL;

  free(txq->entries);
  txq->entries = NULL;

  iwl_irq_timer_release_sync(txq->stuck_timer);
  txq->stuck_timer = NULL;

  /* 0-fill queue descriptor structure */
  memset(txq, 0, sizeof(*txq));
}

void iwl_pcie_tx_start(struct iwl_trans* trans, uint32_t scd_base_addr) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  int nq = trans->cfg->base_params->num_of_queues;
  int chan;
  uint32_t reg_val;
  int clear_dwords =
      (SCD_TRANS_TBL_OFFSET_QUEUE(nq) - SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(uint32_t);

  /* make sure all queue are not stopped/used */
  memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
  memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));

  trans_pcie->scd_base_addr = iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);

  if (scd_base_addr != 0 && scd_base_addr != trans_pcie->scd_base_addr) {
    IWL_WARN(trans, "iwl_pcie_tx_start(): expect scd_base_addr 0x%x, but actual 0x%x\n",
             scd_base_addr, trans_pcie->scd_base_addr);
  }

  /* reset context data, TX status and translation data */
  iwl_trans_write_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND, NULL,
                      clear_dwords);

  iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10);

  /* The chain extension of the SCD doesn't work well. This feature is
   * enabled by default by the HW, so we need to disable it manually.
   */
  if (trans->cfg->base_params->scd_chain_ext_wa) {
    iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
  }

  iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, trans_pcie->cmd_fifo,
                          trans_pcie->cmd_q_wdg_timeout);

  /* Activate all Tx DMA/FIFO channels */
  iwl_scd_activate_fifos(trans);

  /* Enable DMA channel */
  for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++)
    iwl_write_direct32(
        trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
        FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);

  /* Update FH chicken bits */
  reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG);
  iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);

  /* Enable L1-Active */
  if (trans->cfg->device_family < IWL_DEVICE_FAMILY_8000) {
    iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
  }
}

#if 0   // NEEDS_PORTING
void iwl_trans_pcie_tx_reset(struct iwl_trans* trans) {
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    int txq_id;

    /*
     * we should never get here in gen2 trans mode return early to avoid
     * having invalid accesses
     */
    if (WARN_ON_ONCE(trans->cfg->gen2)) { return; }

    for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; txq_id++) {
        struct iwl_txq* txq = trans_pcie->txq[txq_id];
        if (trans->cfg->use_tfh) {
            iwl_write_direct64(trans, FH_MEM_CBBC_QUEUE(trans, txq_id), txq->dma_addr);
        } else {
            iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(trans, txq_id), txq->dma_addr >> 8);
        }
        iwl_pcie_txq_unmap(trans, txq_id);
        txq->read_ptr = 0;
        txq->write_ptr = 0;
    }

    /* Tell NIC where to find the "keep warm" buffer */
    iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, trans_pcie->kw.dma >> 4);

    /*
     * Send 0 as the scd_base_addr since the device may have be reset
     * while we were in WoWLAN in which case SCD_SRAM_BASE_ADDR will
     * contain garbage.
     */
    iwl_pcie_tx_start(trans, 0);
}
#endif  // NEEDS_PORTING

static void iwl_pcie_tx_stop_fh(struct iwl_trans* trans) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  unsigned long flags;
  int ch, ret;
  uint32_t mask = 0;

  mtx_lock(&trans_pcie->irq_lock);

  if (!iwl_trans_grab_nic_access(trans, &flags)) {
    goto out;
  }

  /* Stop each Tx DMA channel */
  for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
    iwl_write32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
    mask |= FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch);
  }

  /* Wait for DMA channels to be idle */
  ret = iwl_poll_bit(trans, FH_TSSR_TX_STATUS_REG, mask, mask, ZX_MSEC(5), NULL);
  if (ret != ZX_OK) {
    IWL_ERR(trans, "Failing on timeout while stopping DMA channel %d [0x%08x]\n", ch,
            iwl_read32(trans, FH_TSSR_TX_STATUS_REG));
  }

  iwl_trans_release_nic_access(trans, &flags);

out:
  mtx_unlock(&trans_pcie->irq_lock);
}

/*
 * iwl_pcie_tx_stop - Stop all Tx DMA channels
 */
zx_status_t iwl_pcie_tx_stop(struct iwl_trans* trans) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  int txq_id;

  /* Turn off all Tx DMA fifos */
  iwl_scd_deactivate_fifos(trans);

  /* Turn off all Tx DMA channels */
  iwl_pcie_tx_stop_fh(trans);

  /*
   * This function can be called before the op_mode disabled the
   * queues. This happens when we have an rfkill interrupt.
   * Since we stop Tx altogether - mark the queues as stopped.
   */
  memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
  memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));

  /* This can happen: start_hw, stop_device */
  if (!trans_pcie->txq_memory) {
    return ZX_OK;
  }

  /* Unmap DMA from host system and free skb's */
  for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; txq_id++) {
    iwl_pcie_txq_unmap(trans, txq_id);
  }

  return ZX_OK;
}

/*
 * iwl_trans_tx_free - Free TXQ Context
 *
 * Destroy all TX DMA queues and structures
 */
void iwl_pcie_tx_free(struct iwl_trans* trans) {
  int txq_id;
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

  memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));

  /* Tx queues */
  if (trans_pcie->txq_memory) {
    for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; txq_id++) {
      iwl_pcie_txq_free(trans, txq_id);
      trans_pcie->txq[txq_id] = NULL;
    }
  }

  free(trans_pcie->txq_memory);
  trans_pcie->txq_memory = NULL;

  iwl_pcie_free_dma_ptr(trans, &trans_pcie->kw);

  iwl_pcie_free_dma_ptr(trans, &trans_pcie->scd_bc_tbls);
}

/*
 * iwl_pcie_tx_alloc - allocate TX context
 * Allocate all Tx DMA structures and initialize them
 */
static zx_status_t iwl_pcie_tx_alloc(struct iwl_trans* trans) {
  zx_status_t ret;
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  uint16_t bc_tbls_size = trans->cfg->base_params->num_of_queues;

  bc_tbls_size *= (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
                      ? sizeof(struct iwl_gen3_bc_tbl)
                      : sizeof(struct iwlagn_scd_bc_tbl);

  /*It is not allowed to alloc twice, so warn when this happens.
   * We cannot rely on the previous allocation, so free and fail */
  if (WARN_ON(trans_pcie->txq_memory)) {
    ret = ZX_ERR_BAD_STATE;
    goto error;
  }

  ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->scd_bc_tbls, bc_tbls_size);
  if (ret != ZX_OK) {
    IWL_ERR(trans, "Scheduler BC Table allocation failed\n");
    goto error;
  }

  /* Alloc keep-warm buffer */
  ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->kw, IWL_KW_SIZE);
  if (ret != ZX_OK) {
    IWL_ERR(trans, "Keep Warm allocation failed\n");
    goto error;
  }

  trans_pcie->txq_memory = calloc(trans->cfg->base_params->num_of_queues, sizeof(struct iwl_txq));
  if (!trans_pcie->txq_memory) {
    IWL_ERR(trans, "Not enough memory for txq\n");
    ret = ZX_ERR_NO_MEMORY;
    goto error;
  }

  /* Alloc and init all Tx queues, including the command queue (#4/#9) */
  for (int txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; txq_id++) {
    bool cmd_queue = (txq_id == trans_pcie->cmd_queue);

    int slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
    trans_pcie->txq[txq_id] = &trans_pcie->txq_memory[txq_id];
    ret = iwl_pcie_txq_alloc(trans, trans_pcie->txq[txq_id], slots_num, cmd_queue);
    if (ret != ZX_OK) {
      IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id);
      goto error;
    }
    trans_pcie->txq[txq_id]->id = txq_id;
  }

  return ZX_OK;

error:
  iwl_pcie_tx_free(trans);
  return ret;
}

zx_status_t iwl_pcie_tx_init(struct iwl_trans* trans) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  int ret;
  bool alloc = false;

  if (!trans_pcie->txq_memory) {
    ret = iwl_pcie_tx_alloc(trans);
    if (ret) {
      goto error;
    }
    alloc = true;
  }

  mtx_lock(&trans_pcie->irq_lock);

  /* Turn off all Tx DMA fifos */
  iwl_scd_deactivate_fifos(trans);

  /* Tell NIC where to find the "keep warm" buffer */
  iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, trans_pcie->kw.dma >> 4);

  mtx_unlock(&trans_pcie->irq_lock);

  /* Alloc and init all Tx queues, including the command queue (#4/#9) */
  for (int txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; txq_id++) {
    bool cmd_queue = (txq_id == trans_pcie->cmd_queue);

    int slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
    ret = iwl_pcie_txq_init(trans, trans_pcie->txq[txq_id], slots_num, cmd_queue);
    if (ret != ZX_OK) {
      IWL_ERR(trans, "Tx %d queue init failed\n", txq_id);
      goto error;
    }

    /*
     * Tell nic where to find circular buffer of TFDs for a
     * given Tx queue, and enable the DMA channel used for that
     * queue.
     * Circular buffer (TFD queue in DRAM) physical base address
     */
    iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(trans, txq_id),
                       trans_pcie->txq[txq_id]->dma_addr >> 8);
  }

  iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_AUTO_ACTIVE_MODE);
  if (trans->cfg->base_params->num_of_queues > 20) {
    iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_ENABLE_31_QUEUES);
  }

  return ZX_OK;
error:
  /*Upon error, free only if we allocated something */
  if (alloc) {
    iwl_pcie_tx_free(trans);
  }
  return ret;
}

static inline void iwl_pcie_txq_progress(struct iwl_txq* txq) {
  iwl_assert_lock_held(&txq->lock);

  if (!txq->wd_timeout) {
    return;
  }

  /*
   * station is asleep and we send data - that must
   * be uAPSD or PS-Poll. Don't rearm the timer.
   */
  if (txq->frozen) {
    return;
  }

  /*
   * if empty delete timer, otherwise move timer forward
   * since we're making progress on this queue
   */
  if (txq->read_ptr == txq->write_ptr) {
    iwl_irq_timer_stop(txq->stuck_timer);
  } else {
    iwl_irq_timer_start(txq->stuck_timer, txq->wd_timeout);
  }
}

/* Frees buffers until index _not_ inclusive */
void iwl_trans_pcie_reclaim(struct iwl_trans* trans, int txq_id, int ssn) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[txq_id];
  int tfd_num = iwl_pcie_get_cmd_index(txq, ssn);
  int read_ptr = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
  int last_to_free;

  /* This function is not meant to release cmd queue */
  if (txq_id == trans_pcie->cmd_queue) {
    IWL_WARN(trans, "iwl_trans_pcie_reclaim() is not meant to release cmd queue.\n");
    return;
  }

  mtx_lock(&txq->lock);

  if (!test_bit(txq_id, trans_pcie->queue_used)) {
    IWL_DEBUG_TX_QUEUES(trans, "Q %d inactive - ignoring idx %d\n", txq_id, ssn);
    goto out;
  }

  if (read_ptr == tfd_num) {
    goto out;
  }

  IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", txq_id, txq->read_ptr, tfd_num, ssn);

  /*Since we free until index _not_ inclusive, the one before index is
   * the last we will free. This one must be used */
  last_to_free = iwl_queue_dec_wrap(trans, tfd_num);

  if (!iwl_queue_used(txq, last_to_free)) {
    IWL_ERR(trans,
            "%s: Read index for txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n",
            __func__, txq_id, last_to_free, trans->cfg->base_params->max_tfd_queue_size,
            txq->write_ptr, txq->read_ptr);
    goto out;
  }

#if 0   // NEEDS_PORTING
    if (WARN_ON(!skb_queue_empty(skbs))) { goto out; }
#endif  // NEEDS_PORTING

  for (; read_ptr != tfd_num; txq->read_ptr = iwl_queue_inc_wrap(trans, txq->read_ptr),
                              read_ptr = iwl_pcie_get_cmd_index(txq, txq->read_ptr)) {
#if 0   // NEEDS_PORTING
        if (!trans->cfg->use_tfh) { iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); }
#endif  // NEEDS_PORTING

    ZX_ASSERT(txq->entries[read_ptr].cmd);
    iwl_iobuf_release(txq->entries[read_ptr].cmd);
    txq->entries[read_ptr].cmd = NULL;
    if (txq->entries[read_ptr].dup_io_buf) {
      iwl_iobuf_release(txq->entries[read_ptr].dup_io_buf);
      txq->entries[read_ptr].dup_io_buf = NULL;
    }

    iwl_pcie_txq_free_tfd(trans, txq);
  }

  iwl_pcie_txq_progress(txq);

#if 1  // NEEDS_PORTING
  if (iwl_queue_space(trans, txq) > txq->low_mark && test_bit(txq_id, trans_pcie->queue_stopped)) {
    iwl_wake_queue(trans, txq);
  }
#else   // NEEDS_PORTING
  if (iwl_queue_space(trans, txq) > txq->low_mark && test_bit(txq_id, trans_pcie->queue_stopped)) {
    struct sk_buff_head overflow_skbs;

    __skb_queue_head_init(&overflow_skbs);
    skb_queue_splice_init(&txq->overflow_q, &overflow_skbs);

    /*
     * This is tricky: we are in reclaim path which is non
     * re-entrant, so noone will try to take the access the
     * txq data from that path. We stopped tx, so we can't
     * have tx as well. Bottom line, we can unlock and re-lock
     * later.
     */
    spin_unlock_bh(&txq->lock);

    while (!skb_queue_empty(&overflow_skbs)) {
      struct sk_buff* skb = __skb_dequeue(&overflow_skbs);
      struct iwl_device_cmd* dev_cmd_ptr;

      dev_cmd_ptr = *(void**)((uint8_t*)skb->cb + trans_pcie->dev_cmd_offs);

      /*
       * Note that we can very well be overflowing again.
       * In that case, iwl_queue_space will be small again
       * and we won't wake mac80211's queue.
       */
      iwl_trans_tx(trans, skb, dev_cmd_ptr, txq_id);
    }

    if (iwl_queue_space(trans, txq) > txq->low_mark) {
      iwl_wake_queue(trans, txq);
    }

    spin_lock_bh(&txq->lock);
  }
#endif  // NEEDS_PORTING

  if (txq->read_ptr == txq->write_ptr) {
    IWL_DEBUG_RPM(trans, "Q %d - last tx reclaimed\n", txq->id);
    iwl_trans_unref(trans);
  }

out:
  mtx_unlock(&txq->lock);
}

static zx_status_t iwl_pcie_set_cmd_in_flight(struct iwl_trans* trans,
                                              const struct iwl_host_cmd* cmd) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  const struct iwl_cfg* cfg = trans->cfg;

  iwl_assert_lock_held(&trans_pcie->reg_lock);

  /* Make sure the NIC is still alive in the bus */
  if (test_bit(STATUS_TRANS_DEAD, &trans->status)) {
    return ZX_ERR_BAD_STATE;
  }

  if (!(cmd->flags & CMD_SEND_IN_IDLE) && !trans_pcie->ref_cmd_in_flight) {
    trans_pcie->ref_cmd_in_flight = true;
    IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n");
    iwl_trans_ref(trans);
  }

  /*
   * wake up the NIC to make sure that the firmware will see the host
   * command - we will let the NIC sleep once all the host commands
   * returned. This needs to be done only on NICs that have
   * apmg_wake_up_wa set.
   */
  if (cfg->base_params->apmg_wake_up_wa && !trans_pcie->cmd_hold_nic_awake) {
    __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, BIT(cfg->csr->flag_mac_access_req));

    zx_status_t status =
        iwl_poll_bit(trans, CSR_GP_CNTRL, BIT(cfg->csr->flag_val_mac_access_en),
                     (BIT(cfg->csr->flag_mac_clock_ready) | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
                     ZX_MSEC(15), NULL);
    if (status != ZX_OK) {
      __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, BIT(cfg->csr->flag_mac_access_req));
      IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
      return ZX_ERR_IO;
    }
    trans_pcie->cmd_hold_nic_awake = true;
  }

  return ZX_OK;
}

/*
 * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd
 *
 * When FW advances 'R' index, all entries between old and new 'R' index
 * need to be reclaimed. As result, some free space forms.  If there is
 * enough free space (> low mark), wake the stack that feeds us.
 */
zx_status_t iwl_pcie_cmdq_reclaim(struct iwl_trans* trans, int txq_id, uint32_t idx) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[txq_id];
  int nfreed = 0;

  // Ensure the tx_id is pointing to the cmd_queue.
  if (txq_id != trans_pcie->cmd_queue) {
    IWL_WARN(trans, "wrong command queue %d (should be %d)\n", txq_id, trans_pcie->cmd_queue);
    return ZX_ERR_INVALID_ARGS;
  }

  iwl_assert_lock_held(&txq->lock);

  idx = iwl_pcie_get_cmd_index(txq, idx);
  uint16_t r = iwl_pcie_get_cmd_index(txq, txq->read_ptr);

  if (idx >= trans->cfg->base_params->max_tfd_queue_size || (!iwl_queue_used(txq, idx))) {
    if (test_bit(txq_id, trans_pcie->queue_used)) {
      IWL_WARN(trans, "DMA queue txq_id (%d), read index %d is out of range [0-%d] wp:%d rp:%d\n",
               txq_id, idx, trans->cfg->base_params->max_tfd_queue_size, txq->write_ptr,
               txq->read_ptr);
    }
    return ZX_ERR_OUT_OF_RANGE;
  }

  for (idx = iwl_queue_inc_wrap(trans, idx); r != idx; r = iwl_queue_inc_wrap(trans, r)) {
    txq->read_ptr = iwl_queue_inc_wrap(trans, txq->read_ptr);

    if (nfreed++ > 0) {
      IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", idx, txq->write_ptr, r);
      iwl_force_nmi(trans);
      return ZX_ERR_BAD_STATE;
    }
  }

  if (txq->read_ptr == txq->write_ptr) {
    mtx_lock(&trans_pcie->reg_lock);
    iwl_pcie_clear_cmd_in_flight(trans);
    mtx_unlock(&trans_pcie->reg_lock);
  }

  iwl_pcie_txq_progress(txq);
  return ZX_OK;
}

static int iwl_pcie_txq_set_ratid_map(struct iwl_trans* trans, uint16_t ra_tid, uint16_t txq_id) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  uint32_t tbl_dw_addr;
  uint32_t tbl_dw;
  uint16_t scd_q2ratid;

  scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK;

  tbl_dw_addr = trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE(txq_id);

  tbl_dw = iwl_trans_read_mem32(trans, tbl_dw_addr);

  if (txq_id & 0x1) {
    tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
  } else {
    tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
  }

  iwl_trans_write_mem32(trans, tbl_dw_addr, tbl_dw);

  return 0;
}

/* Receiver address (actually, Rx station's index into station table),
 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))

bool iwl_trans_pcie_txq_enable(struct iwl_trans* trans, int txq_id, uint16_t ssn,
                               const struct iwl_trans_txq_scd_cfg* cfg, zx_duration_t wdg_timeout) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[txq_id];
  int fifo = -1;
  bool scd_bug = false;

  if (test_and_set_bit(txq_id, trans_pcie->queue_used)) {
    IWL_WARN(trans, "queue %d already used - expect issues\n", txq_id);
  }

  txq->wd_timeout = wdg_timeout;

  if (cfg) {
    fifo = cfg->fifo;

    /* Disable the scheduler prior configuring the cmd queue */
    if (txq_id == trans_pcie->cmd_queue && trans_pcie->scd_set_active) {
      iwl_scd_enable_set_active(trans, 0);
    }

    /* Stop this Tx queue before configuring it */
    iwl_scd_txq_set_inactive(trans, txq_id);

    /* Set this queue as a chain-building queue unless it is CMD */
    if (txq_id != trans_pcie->cmd_queue) {
      iwl_scd_txq_set_chain(trans, txq_id);
    }

    if (cfg->aggregate) {
      uint16_t ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid);

      /* Map receiver-address / traffic-ID to this queue */
      iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id);

      /* enable aggregations for the queue */
      iwl_scd_txq_enable_agg(trans, txq_id);
      txq->ampdu = true;
    } else {
      /*
       * disable aggregations for the queue, this will also
       * make the ra_tid mapping configuration irrelevant
       * since it is now a non-AGG queue.
       */
      iwl_scd_txq_disable_agg(trans, txq_id);

      ssn = txq->read_ptr;
    }
  } else {
    /*
     * If we need to move the SCD write pointer by steps of
     * 0x40, 0x80 or 0xc0, it gets stuck. Avoids this and let
     * the op_mode know by returning true later.
     * Do this only in case cfg is NULL since this trick can
     * be done only if we have DQA enabled which is true for mvm
     * only. And mvm never sets a cfg pointer.
     * This is really ugly, but this is the easiest way out for
     * this sad hardware issue.
     * This bug has been fixed on devices 9000 and up.
     */
    scd_bug =
        !trans->cfg->mq_rx_supported && !((ssn - txq->write_ptr) & 0x3f) && (ssn != txq->write_ptr);
    if (scd_bug) {
      ssn++;
    }
  }

  /* Place first TFD at index corresponding to start sequence number.
   * Assumes that ssn_idx is valid (!= 0xFFF) */
  txq->read_ptr = (ssn & 0xff);
  txq->write_ptr = (ssn & 0xff);
  iwl_write_direct32(trans, HBUS_TARG_WRPTR, (ssn & 0xff) | (txq_id << 8));

  if (cfg) {
    uint8_t frame_limit = cfg->frame_limit;

    iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);

    /* Set up Tx window size and frame limit for this queue */
    iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0);
    iwl_trans_write_mem32(
        trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(uint32_t),
        SCD_QUEUE_CTX_REG2_VAL(WIN_SIZE, frame_limit) |
            SCD_QUEUE_CTX_REG2_VAL(FRAME_LIMIT, frame_limit));

    /* Set up status area in SRAM, map to Tx DMA/FIFO, activate */
    iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
                   (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
                       (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
                       (1 << SCD_QUEUE_STTS_REG_POS_WSL) | SCD_QUEUE_STTS_REG_MSK);

    /* enable the scheduler for this queue (only) */
    if (txq_id == trans_pcie->cmd_queue && trans_pcie->scd_set_active) {
      iwl_scd_enable_set_active(trans, BIT(txq_id));
    }

    IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", txq_id, fifo,
                        ssn & 0xff);
  } else {
    IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d WrPtr: %d\n", txq_id, ssn & 0xff);
  }

  return scd_bug;
}

void iwl_trans_pcie_txq_set_shared_mode(struct iwl_trans* trans, uint32_t txq_id,
                                        bool shared_mode) {
#if 0   // NEEDS_PORTING
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    struct iwl_txq* txq = trans_pcie->txq[txq_id];

    txq->ampdu = !shared_mode;
#endif  // NEEDS_PORTING
  IWL_ERR(trans, "%s needs porting\n", __FUNCTION__);
}

void iwl_trans_pcie_txq_disable(struct iwl_trans* trans, int txq_id, bool configure_scd) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  uint32_t stts_addr = trans_pcie->scd_base_addr + SCD_TX_STTS_QUEUE_OFFSET(txq_id);
  static const uint32_t zero_val[4] = {};

  trans_pcie->txq[txq_id]->frozen_expiry_remainder = 0;
  trans_pcie->txq[txq_id]->frozen = false;

  /*
   * Upon HW Rfkill - we stop the device, and then stop the queues
   * in the op_mode. Just for the sake of the simplicity of the op_mode,
   * allow the op_mode to call txq_disable after it already called
   * stop_device.
   */
  if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {
    if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
      IWL_ERR(trans, "queue %d not used", txq_id);
    }
    return;
  }

  if (configure_scd) {
    iwl_scd_txq_set_inactive(trans, txq_id);

    zx_status_t ret = iwl_trans_write_mem(trans, stts_addr, (void*)zero_val, ARRAY_SIZE(zero_val));
    if (ret != ZX_OK) {
      IWL_ERR(trans, "cannot write memory while disable TxQ: %s\n", zx_status_get_string(ret));
    }
  }

  iwl_pcie_txq_unmap(trans, txq_id);
  trans_pcie->txq[txq_id]->ampdu = false;

  IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
}

/*************** HOST COMMAND QUEUE FUNCTIONS   *****/

//
// iwl_pcie_enqueue_hcmd - enqueue a uCode command
//
// @priv: device private data point
// @cmd: a pointer to the ucode command structure
//
// Below is how a Tx host command is built:
//
// A host command from MVM can contain 2 data framgents:
//
//   - The first fragment must contain the command header including command ID, length ... etc.
//     It may not contain the payload since it can be passed in the second fragment.
//
//   - The second fragment is optional. Usually it is used for different flags from the first
//     fragment. For example, copying a host command with very large payload has performance
//     concern. Then the first fragment can only contain the command header while the second
//     fragment can contain its large payload with NOCOPY flag.
//
// So, down to the transport layer, a host command can be re-mapped to multiple descriptors in order
// to satisfy the upper layer's demand. This is why TFD (Transmit Frame Descriptor) is introduced.
//
// txq->tfds[] (TFDs) are used by driver to indicate the data fragements for firmware. A host
// command can be re-mapped into 1~3 descriptors depending on the fragment lengths and flags
// (check how the iwl_pcie_txq_build_tfd() is called in this function):
//
//   - For small-sized command (<= 20 bytes):
//
//     At driver initialization time, it already allocated a special buffer (txq->first_tb_bufs[],
//     also called 'tb0' in this function) for small host commands.
//
//     For these commands, no memory mapping is required, and just copy the whole command to the
//     buffer. Note that each entry in this buffer must be 64-byte aligned although only the first
//     20-byte is used.
//
//        <-- 20-B -->
//       +------------+
//       |     tb0    |
//       +------------+
//
//
//   - For medium-sized command (20 < len <= 328 bytes):
//
//     The first 20-byte still goes to 'tb0'. The remaining content will be mapped into the second
//     descriptor -- the 'cmd' iwl_iobuf in 'struct iwl_pcie_txq_entry'.
//
//        <-----------   20 ~ 328 bytes   ----------->
//       +------------+  +----------------------------+
//       |     tb0    |  |   2nd descriptor ('cmd')   |
//       +------------+  +----------------------------+
//           1st fragment (or with the 2nd fragment)
//
//
//   - For large-sized command (> 328 bytes):
//
//     It cannot be fit within one fragment (seems a hardware issue?). The second fragment must be
//     marked with NOCOPY flag (observed from the code using this function).
//
//     + If first fragment is smaller than or equal to 20-byte, then 2 descriptors will be built.
//       The first descriptor points to the first fragment while the second descriptor points to
//        second fragment -- the 'dup_io_buf' in 'struct iwl_pcie_txq_entry'.
//
//          <-- 20-B -->    <---------  any length  ---------->
//         +------------+  +-----------------------------------+
//         |     tb0    |  |   2nd descriptor ('dup_io_buf')   |
//         +------------+  +-----------------------------------+
//          1st fragment       2nd fragment (NOCOPY)
//
//
//     + If the first fragment is larger than 20-byte, similar as the medium-sized command, the
//       first fragment will be split into 2 descriptos: 'tb0' and 'cmd' iwl_iobuf. However, the
//       second fragment (with the NOCOPY flag) will be stored in 3rd descriptor.
//
//          <-----------   20 ~ 328 bytes   ----------->    <---------  any length  ---------->
//         +------------+  +----------------------------+  +-----------------------------------+
//         |     tb0    |  |   2nd descriptor ('cmd')   |  |   3rd descriptor ('dup_io_buf')   |
//         +------------+  +----------------------------+  +-----------------------------------+
//                     1st fragment                              2nd fragment (NOCOPY)
//
static zx_status_t iwl_pcie_enqueue_hcmd(struct iwl_trans* trans, struct iwl_host_cmd* cmd,
                                         int* cmd_idx_out) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[trans_pcie->cmd_queue];
  struct iwl_cmd_meta* out_meta;
  bool had_dup_flag = false;
  uint16_t copy_size;  // The size to copy into allocated DMA area (without the NOCOPY data).
  uint16_t cmd_size;   // Whole command size writing to HW, including header and data.
  bool had_nocopy = false;
  uint8_t group_id = iwl_cmd_groupid(cmd->id);
  const uint8_t* cmddata[IWL_MAX_CMD_TBS_PER_TFD];
  uint16_t cmdlen[IWL_MAX_CMD_TBS_PER_TFD];  // Locally manipulated data lengths.
  zx_status_t status = ZX_OK;

  if (!trans->wide_cmd_header && group_id > IWL_ALWAYS_LONG_GROUP) {
    IWL_WARN(trans, "unsupported wide command %#x\n", cmd->id);
    return ZX_ERR_INVALID_ARGS;
  }

  if (group_id != 0) {
    copy_size = sizeof(struct iwl_cmd_header_wide);
    cmd_size = sizeof(struct iwl_cmd_header_wide);
  } else {
    copy_size = sizeof(struct iwl_cmd_header);
    cmd_size = sizeof(struct iwl_cmd_header);
  }

  /* need one for the header if the first is NOCOPY */
  BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1);

  for (int i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
    cmddata[i] = cmd->data[i];
    cmdlen[i] = cmd->len[i];

    if (!cmd->len[i]) {
      continue;
    }

    /* need at least IWL_FIRST_TB_SIZE copied */
    if (copy_size < IWL_FIRST_TB_SIZE) {
      int copy = IWL_FIRST_TB_SIZE - copy_size;

      if (copy > cmdlen[i]) {
        copy = cmdlen[i];
      }
      cmdlen[i] -= copy;
      cmddata[i] += copy;
      copy_size += copy;
    }

    if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
      had_nocopy = true;
      if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
        return ZX_ERR_INVALID_ARGS;
      }
    } else if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) {
      /*
       * This is also a chunk that isn't copied
       * to the static buffer so set had_nocopy.
       */
      had_nocopy = true;

      /* only allowed once */
      if (WARN_ON(had_dup_flag)) {
        return ZX_ERR_INVALID_ARGS;
      }

      had_dup_flag = true;
    } else {
      /* NOCOPY must not be followed by normal! */
      if (WARN_ON(had_nocopy)) {
        return ZX_ERR_INVALID_ARGS;
      }
      copy_size += cmdlen[i];
    }
    cmd_size += cmd->len[i];
  }

  /*
   * If any of the command structures end up being larger than
   * the TFD_MAX_PAYLOAD_SIZE and they aren't dynamically
   * allocated into separate TFDs, then we will need to
   * increase the size of the buffers.
   */
  if (copy_size > TFD_MAX_PAYLOAD_SIZE) {
    IWL_WARN(trans, "Command %s (%#x) is too large (%d bytes, expect <= %lu bytes)\n",
             iwl_get_cmd_string(trans, cmd->id), cmd->id, copy_size, TFD_MAX_PAYLOAD_SIZE);
    return ZX_ERR_INVALID_ARGS;
  }

  mtx_lock(&txq->lock);

  if (iwl_queue_space(trans, txq) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
    mtx_unlock(&txq->lock);
    IWL_ERR(trans, "No space in command queue\n");
    iwl_op_mode_cmd_queue_full(trans->op_mode);
    return ZX_ERR_NO_RESOURCES;
  }

  int cmd_idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
  struct iwl_device_cmd* out_cmd = iwl_iobuf_virtual(txq->entries[cmd_idx].cmd);
  zx_paddr_t phys_addr = iwl_iobuf_physical(txq->entries[cmd_idx].cmd);
  out_meta = &txq->entries[cmd_idx].meta;

  memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
  if (cmd->flags & CMD_WANT_SKB) {
    out_meta->source = cmd;
  }

  /* set up the header */
  uint32_t cmd_pos;  // Pointer used with 'out_cmd' to indicate the location for 'next copy data'.
  if (group_id != 0) {
    out_cmd->hdr_wide.cmd = iwl_cmd_opcode(cmd->id);
    out_cmd->hdr_wide.group_id = group_id;
    out_cmd->hdr_wide.version = iwl_cmd_version(cmd->id);
    out_cmd->hdr_wide.length = cpu_to_le16(cmd_size - sizeof(struct iwl_cmd_header_wide));
    out_cmd->hdr_wide.reserved = 0;
    out_cmd->hdr_wide.sequence =
        cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) | INDEX_TO_SEQ(txq->write_ptr));

    cmd_pos = sizeof(struct iwl_cmd_header_wide);
    copy_size = sizeof(struct iwl_cmd_header_wide);
  } else {
    out_cmd->hdr.cmd = iwl_cmd_opcode(cmd->id);
    out_cmd->hdr.sequence =
        cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) | INDEX_TO_SEQ(txq->write_ptr));
    out_cmd->hdr.group_id = 0;

    cmd_pos = sizeof(struct iwl_cmd_header);
    copy_size = sizeof(struct iwl_cmd_header);
  }

  /* and copy the data that needs to be copied */
  for (int i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
    int copy;

    if (!cmd->len[i]) {
      continue;
    }

    /* copy everything if not nocopy/dup */
    if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | IWL_HCMD_DFL_DUP))) {
      copy = cmd->len[i];

      memcpy((uint8_t*)out_cmd + cmd_pos, cmd->data[i], copy);
      cmd_pos += copy;
      copy_size += copy;
      continue;
    }

    /*
     * Otherwise we need at least IWL_FIRST_TB_SIZE copied
     * in total (for bi-directional DMA), but copy up to what
     * we can fit into the payload for debug dump purposes.
     * TODO(43084): Remove the un-necessary memcpy below.
     */
    copy = min_t(int, TFD_MAX_PAYLOAD_SIZE - cmd_pos, cmd->len[i]);
    memcpy((uint8_t*)out_cmd + cmd_pos, cmd->data[i], copy);
    cmd_pos += copy;

    /* However, treat copy_size the proper way, we need it below */
    if (copy_size < IWL_FIRST_TB_SIZE) {
      copy = IWL_FIRST_TB_SIZE - copy_size;

      if (copy > cmd->len[i]) {
        copy = cmd->len[i];
      }
      copy_size += copy;
    }
  }

  IWL_DEBUG_HC(trans, "Sending command %s (%.2x.%.2x), seq: 0x%04X, %d bytes at %d[%d]:%d\n",
               iwl_get_cmd_string(trans, cmd->id), group_id, out_cmd->hdr.cmd,
               le16_to_cpu(out_cmd->hdr.sequence), cmd_size, txq->write_ptr, cmd_idx,
               trans_pcie->cmd_queue);

  // start the TFD with the minimum copy bytes (tb0).
  struct iwl_pcie_first_tb_buf* tb_bufs = iwl_iobuf_virtual(txq->first_tb_bufs);
  uint16_t tb0_size = min_t(int, copy_size, IWL_FIRST_TB_SIZE);
  memcpy(&tb_bufs[cmd_idx], &out_cmd->hdr, tb0_size);
  uint32_t num_tbs;
  iwl_pcie_txq_build_tfd(trans, txq, iwl_pcie_get_first_tb_dma(txq, cmd_idx), tb0_size, true,
                         &num_tbs);

  /* map first command fragment, if any remains */
  if (copy_size > tb0_size) {
    iwl_pcie_txq_build_tfd(trans, txq, phys_addr + tb0_size, copy_size - tb0_size, false, &num_tbs);
  }

  /* map the remaining (adjusted) nocopy/dup fragments */
  bool used_dup_io_buf = false;
  for (int i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
    const void* data = cmddata[i];

    if (!cmdlen[i]) {
      continue;
    }
    if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | IWL_HCMD_DFL_DUP))) {
      continue;
    }

    // Assume only one fragment needs DUP and NOCOPY. Needs to extend the txq_entry.dup_io_buf to 2
    // if we need to support 2 NOCOPY fragments.
    if (used_dup_io_buf) {
      mtx_unlock(&txq->lock);
      IWL_ERR(trans, "Cannot have 2 NOCOPY or DUP fragments in one command.\n");
      return ZX_ERR_IO_INVALID;
    } else {
      used_dup_io_buf = true;
    }

    // Allocate an io_buffer to store the remaining data (either a DUP or a NOCOPY fragment).
    //
    // For the DUP case, as the flag described, the data is copied into the io_buffer for the
    // caller to use it in Rx path.
    //
    // For the NOCOPY case, since it is larger than TFD_MAX_PAYLOAD_SIZE, we have to copy the data
    // into the io_buffer and map it to physical address. However, the original purpose of this flag
    // is to avoid copy due to performance consideration. So created TODO(42212) to track this.
    //
    struct iwl_iobuf* dup_io_buf = txq->entries[cmd_idx].dup_io_buf;

    // Allocate a cached io_buffer, copy the data, and flush the cache at once. The io_buffer will
    // be released (reclaimed) in iwl_pcie_rx_handle_rb().
    //
    // In theory, using cached io_buffer is faster. No matter how memcpy is implemented (copying
    // byte-by-byte or word-by-word), writing to cache always has smaller cycles than writing to
    // SDRAM. Even during the cache flush stage, the memory write is done in cache-line size, which
    // is still faster than CPU write.
    //
    // However, it is arguable weather flush is needed or not since some x86 platforms/PCIe devices
    // support cached read. But this is not guaranteed on all platforms (e.g. ARM). So let's play
    // safe first.
    //
    ZX_ASSERT(!dup_io_buf);
    uint16_t dup_len = cmdlen[i];
    iwl_iobuf_allocate_contiguous(&trans_pcie->pci_dev->dev, dup_len, &dup_io_buf);
    void* virt_addr = iwl_iobuf_virtual(dup_io_buf);
    memcpy(virt_addr, data, dup_len);
    phys_addr = iwl_iobuf_physical(dup_io_buf);
    iwl_pcie_txq_build_tfd(trans, txq, phys_addr, dup_len, false, &num_tbs);
    iwl_iobuf_cache_flush(dup_io_buf, 0, dup_len);
    txq->entries[cmd_idx].dup_io_buf = dup_io_buf;
  }

  BUILD_BUG_ON(IWL_TFH_NUM_TBS > sizeof(out_meta->tbs) * BITS_PER_BYTE);

  out_meta->flags = cmd->flags;

#if 0   // NEEDS_PORTING
  trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr_wide);
#endif  // NEEDS_PORTING

  /* start timer if queue currently empty */
  if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) {
    iwl_irq_timer_start(txq->stuck_timer, txq->wd_timeout);
  }

  mtx_lock(&trans_pcie->reg_lock);
  status = iwl_pcie_set_cmd_in_flight(trans, cmd);
  if (status != ZX_OK) {
    mtx_unlock(&trans_pcie->reg_lock);
    mtx_unlock(&txq->lock);
    return status;
  }

  /* Increment and update queue's write index */
  txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);
  iwl_pcie_txq_inc_wr_ptr(trans, txq);
  mtx_unlock(&trans_pcie->reg_lock);
  mtx_unlock(&txq->lock);

  if (cmd_idx_out) {
    *cmd_idx_out = cmd_idx;
  }

  return ZX_OK;
}

/*
 * iwl_pcie_hcmd_complete - Pull unused buffers off the queue and reclaim them
 * @rxb: Rx buffer to reclaim
 */
void iwl_pcie_hcmd_complete(struct iwl_trans* trans, struct iwl_rx_cmd_buffer* rxb) {
  struct iwl_rx_packet* pkt = rxb_addr(rxb);
  uint16_t sequence = le16_to_cpu(pkt->hdr.sequence);
  uint8_t group_id;
  uint32_t cmd_id;
  int txq_id = SEQ_TO_QUEUE(sequence);
  int index = SEQ_TO_INDEX(sequence);
  int cmd_index;
  struct iwl_device_cmd* cmd;
  struct iwl_cmd_meta* meta;
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[trans_pcie->cmd_queue];

  /* If a Tx command is being handled and it isn't in the actual
   * command queue then there a command routing bug has been introduced
   * in the queue management code. */
  if (txq_id != trans_pcie->cmd_queue) {
    IWL_WARN(trans, "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n",
             txq_id, trans_pcie->cmd_queue, sequence, txq->read_ptr, txq->write_ptr);
#if 0   // NEEDS_PORTING
      iwl_print_hex_error(trans, pkt, 32);
#endif  // NEEDS_PORTING
    return;
  }

  mtx_lock(&txq->lock);

  cmd_index = iwl_pcie_get_cmd_index(txq, index);
  cmd = (struct iwl_device_cmd*)iwl_iobuf_virtual(txq->entries[cmd_index].cmd);
  meta = &txq->entries[cmd_index].meta;
  group_id = cmd->hdr.group_id;
  cmd_id = iwl_cmd_id(cmd->hdr.cmd, group_id, 0);

  iwl_pcie_tfd_unmap(trans, meta, txq, index);

  /* Input error checking is done when commands are added to queue. */
  if (meta->flags & CMD_WANT_SKB) {
#if 0   // NEEDS_PORTING
        struct page* p = rxb_steal_page(rxb);
#endif  // NEEDS_PORTING

    meta->source->resp_pkt = pkt;
  }

  if (meta->flags & CMD_WANT_ASYNC_CALLBACK) {
    iwl_op_mode_async_cb(trans->op_mode, cmd);
  }

  iwl_pcie_cmdq_reclaim(trans, txq_id, index);

  if (!(meta->flags & CMD_ASYNC)) {
    if (!test_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status)) {
      IWL_WARN(trans, "HCMD_ACTIVE already clear for command %s\n",
               iwl_get_cmd_string(trans, cmd_id));
    }
    clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
    IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
                   iwl_get_cmd_string(trans, cmd_id));
    sync_completion_signal(&trans_pcie->wait_command_queue);
  }

  if (meta->flags & CMD_MAKE_TRANS_IDLE) {
    IWL_DEBUG_INFO(trans, "complete %s - mark trans as idle\n",
                   iwl_get_cmd_string(trans, cmd->hdr.cmd));
    set_bit(STATUS_TRANS_IDLE, &trans->status);
#if 0   // NEEDS_PORTING
        wake_up(&trans_pcie->d0i3_waitq);
#endif  // NEEDS_PORTING
  }

  if (meta->flags & CMD_WAKE_UP_TRANS) {
    IWL_DEBUG_INFO(trans, "complete %s - clear trans idle flag\n",
                   iwl_get_cmd_string(trans, cmd->hdr.cmd));
    clear_bit(STATUS_TRANS_IDLE, &trans->status);
#if 0   // NEEDS_PORTING
        wake_up(&trans_pcie->d0i3_waitq);
#endif  // NEEDS_PORTING
  }

  meta->flags = 0;

  mtx_unlock(&txq->lock);
}

// (2 * HZ * CPTCFG_IWL_TIMEOUT_FACTOR) where CPTCFG_IWL_TIMEOUT_FACTOR is 1 by default
#define HOST_COMPLETE_TIMEOUT ZX_SEC(2)

static zx_status_t iwl_pcie_send_hcmd_async(struct iwl_trans* trans, struct iwl_host_cmd* cmd) {
  /* An asynchronous command can not expect an SKB to be set. */
  if (WARN_ON(cmd->flags & CMD_WANT_SKB)) {
    return ZX_ERR_INVALID_ARGS;
  }

  zx_status_t status = iwl_pcie_enqueue_hcmd(trans, cmd, /*cmd_idx=*/NULL);
  if (status != ZX_OK) {
    IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n",
            iwl_get_cmd_string(trans, cmd->id), status);
    return status;
  }
  return ZX_OK;
}

static zx_status_t iwl_pcie_send_hcmd_sync(struct iwl_trans* trans, struct iwl_host_cmd* cmd) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[trans_pcie->cmd_queue];

  IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", iwl_get_cmd_string(trans, cmd->id));

  if (test_and_set_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status)) {
    IWL_WARN(trans, "Command %s: a command is already active!\n",
             iwl_get_cmd_string(trans, cmd->id));
    return ZX_ERR_IO;
  }

  IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", iwl_get_cmd_string(trans, cmd->id));

#if 0   // NEEDS_PORTING
    if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) {
        ret =
            wait_event_timeout(trans_pcie->d0i3_waitq, pm_runtime_active(&trans_pcie->pci_dev->dev),
                               msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
        if (!ret) {
            IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n");
            return -ETIMEDOUT;
        }
    }
#endif  // NEEDS_PORTING

  sync_completion_reset(&trans_pcie->wait_command_queue);

  int cmd_idx;
  zx_status_t status = iwl_pcie_enqueue_hcmd(trans, cmd, &cmd_idx);
  if (status != ZX_OK) {
    clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
    IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n",
            iwl_get_cmd_string(trans, cmd->id), status);
    return status;
  }

  status = sync_completion_wait(&trans_pcie->wait_command_queue, HOST_COMPLETE_TIMEOUT);
  if (status != ZX_OK) {
    IWL_ERR(trans, "Error sending %s: time out after %ldms (%s).\n",
            iwl_get_cmd_string(trans, cmd->id),
            zx_nsec_from_duration(HOST_COMPLETE_TIMEOUT) / 1000000, zx_status_get_string(status));

    IWL_ERR(trans, "Current CMD queue read_ptr %d write_ptr %d\n", txq->read_ptr, txq->write_ptr);

    clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
    IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
                   iwl_get_cmd_string(trans, cmd->id));
    status = ZX_ERR_TIMED_OUT;

    iwl_force_nmi(trans);
    iwl_trans_fw_error(trans);

    goto cancel;
  }

  if (test_bit(STATUS_FW_ERROR, &trans->status)) {
    iwl_trans_pcie_dump_regs(trans);
    IWL_ERR(trans, "FW error in SYNC CMD %s\n", iwl_get_cmd_string(trans, cmd->id));
    status = ZX_ERR_IO;
    goto cancel;
  }

  if (!(cmd->flags & CMD_SEND_IN_RFKILL) && test_bit(STATUS_RFKILL_OPMODE, &trans->status)) {
    IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n");
    status = ZX_ERR_BAD_STATE;
    goto cancel;
  }

  if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) {
    IWL_ERR(trans, "Error: Response NULL in '%s'\n", iwl_get_cmd_string(trans, cmd->id));
    status = ZX_ERR_IO;
    goto cancel;
  }

  return ZX_OK;

cancel:
  if (cmd->flags & CMD_WANT_SKB) {
    /*
     * Cancel the CMD_WANT_SKB flag for the cmd in the
     * TX cmd queue. Otherwise in case the cmd comes
     * in later, it will possibly set an invalid
     * address (cmd->meta.source).
     */
    txq->entries[cmd_idx].meta.flags &= ~CMD_WANT_SKB;
  }

  if (cmd->resp_pkt) {
    iwl_free_resp(cmd);
    cmd->resp_pkt = NULL;
  }

  return status;
}

int iwl_trans_pcie_send_hcmd(struct iwl_trans* trans, struct iwl_host_cmd* cmd) {
  /* Make sure the NIC is still alive in the bus */
  if (test_bit(STATUS_TRANS_DEAD, &trans->status)) {
    return ZX_ERR_BAD_STATE;
  }

  if (!(cmd->flags & CMD_SEND_IN_RFKILL) && test_bit(STATUS_RFKILL_OPMODE, &trans->status)) {
    IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n", cmd->id);
    return ZX_ERR_BAD_STATE;
  }

  IWL_DEBUG_TX(trans, "HCMD: iwl_trans_pcie_send_hcmd( %s ) len=%4d,%4d %s %s [%s %s, %s %s]\n",
               iwl_get_cmd_string(trans, cmd->id), cmd->len[0], cmd->len[1],
               cmd->flags & CMD_ASYNC ? "ASYNC" : " SYNC",
               cmd->flags & CMD_WANT_SKB ? "SKB" : "   ",
               cmd->dataflags[0] & IWL_HCMD_DFL_NOCOPY ? "NOCOPY" : "",
               cmd->dataflags[0] & IWL_HCMD_DFL_DUP ? "DUP" : "",
               cmd->dataflags[1] & IWL_HCMD_DFL_NOCOPY ? "NOCOPY" : "",
               cmd->dataflags[1] & IWL_HCMD_DFL_DUP ? "DUP" : "");

  zx_status_t status;
  if (cmd->flags & CMD_ASYNC) {
    status = iwl_pcie_send_hcmd_async(trans, cmd);
  } else {
    /* We still can fail on RFKILL that can be asserted while we wait */
    status = iwl_pcie_send_hcmd_sync(trans, cmd);
  }

  return status;
}

#if 0  // NEEDS_PORTING
#ifdef CPTCFG_MAC80211_LATENCY_MEASUREMENTS
static void iwl_trans_pci_tx_lat_add_ts_write(struct sk_buff* skb) {
    s64 temp = ktime_to_ms(ktime_get());
    s64 ts_1 = ktime_to_ns(skb->tstamp) >> 32;
    s64 diff = temp - ts_1;

#if LINUX_VERSION_IS_LESS(4, 10, 0)
    skb->tstamp.tv64 += diff << 16;
#else
    skb->tstamp += diff << 16;
#endif
}
#endif
#endif  // NEEDS_PORTING

// TODO(fxbug.dev/61556): TSO/LSO support.
static zx_status_t iwl_fill_data_tbs(struct iwl_trans* trans, struct ieee80211_mac_packet* pkt,
                                     struct iwl_txq* txq, int cmd_idx, uint32_t* num_tbs,
                                     struct iwl_cmd_meta* out_meta) {
  /*
   * Set up TFD's third entry to point directly to remainder
   * of skb's head, if any
   */
  uint16_t head_tb_len = pkt->headroom_used_size + pkt->body_size;

  if (head_tb_len > 0) {
    // Allocate the dup_io_buf
    struct iwl_iobuf* dup_io_buf = txq->entries[cmd_idx].dup_io_buf;
    ZX_ASSERT(!dup_io_buf);
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    zx_status_t ret =
        iwl_iobuf_allocate_contiguous(&trans_pcie->pci_dev->dev, head_tb_len, &dup_io_buf);
    if (ret != ZX_OK) {
      IWL_ERR(trans, "%s(): io_buffer_init() failed: %s\n", __func__, zx_status_get_string(ret));
      return ret;
    }

    // copy packet in
    char* const virt_addr = (char*)iwl_iobuf_virtual(dup_io_buf);
    memcpy(virt_addr, pkt->headroom, pkt->headroom_used_size);
    memcpy(virt_addr + pkt->headroom_used_size, pkt->body, pkt->body_size);
    iwl_iobuf_cache_flush(dup_io_buf, 0, head_tb_len);
    zx_paddr_t phys_addr = iwl_iobuf_physical(dup_io_buf);
    iwl_pcie_txq_build_tfd(trans, txq, phys_addr, head_tb_len, false, num_tbs);
    txq->entries[cmd_idx].dup_io_buf = dup_io_buf;
  }

  return ZX_OK;
}

#if 0  // NEEDS_PORTING
#ifdef CONFIG_INET
struct iwl_tso_hdr_page* get_page_hdr(struct iwl_trans* trans, size_t len) {
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    struct iwl_tso_hdr_page* p = this_cpu_ptr(trans_pcie->tso_hdr_page);

    if (!p->page) { goto alloc; }

    /* enough room on this page */
    if (p->pos + len < (uint8_t*)page_address(p->page) + PAGE_SIZE) { return p; }

    /* We don't have enough room on this page, get a new one. */
    __free_page(p->page);

alloc:
    p->page = alloc_page(GFP_ATOMIC);
    if (!p->page) { return NULL; }
    p->pos = page_address(p->page);
    return p;
}

static void iwl_compute_pseudo_hdr_csum(void* iph, struct tcphdr* tcph, bool ipv6,
                                        unsigned int len) {
    if (ipv6) {
        struct ipv6hdr* iphv6 = iph;

        tcph->check =
            ~csum_ipv6_magic(&iphv6->saddr, &iphv6->daddr, len + tcph->doff * 4, IPPROTO_TCP, 0);
    } else {
        struct iphdr* iphv4 = iph;

        ip_send_check(iphv4);
        tcph->check =
            ~csum_tcpudp_magic(iphv4->saddr, iphv4->daddr, len + tcph->doff * 4, IPPROTO_TCP, 0);
    }
}

static int iwl_fill_data_tbs_amsdu(struct iwl_trans* trans, struct sk_buff* skb,
                                   struct iwl_txq* txq, uint8_t hdr_len,
                                   struct iwl_cmd_meta* out_meta, struct iwl_device_cmd* dev_cmd,
                                   uint16_t tb1_len) {
    struct iwl_tx_cmd* tx_cmd = (void*)dev_cmd->payload;
    struct iwl_trans_pcie* trans_pcie = txq->trans_pcie;
    struct ieee80211_hdr* hdr = (void*)skb->data;
    unsigned int snap_ip_tcp_hdrlen, ip_hdrlen, total_len, hdr_room;
    unsigned int mss = skb_shinfo(skb)->gso_size;
    uint16_t length, iv_len, amsdu_pad;
    uint8_t* start_hdr;
    struct iwl_tso_hdr_page* hdr_page;
    struct page** page_ptr;
    struct tso_t tso;

    /* if the packet is protected, then it must be CCMP or GCMP */
    BUILD_BUG_ON(IEEE80211_CCMP_HDR_LEN != IEEE80211_GCMP_HDR_LEN);
    iv_len = ieee80211_has_protected(hdr->frame_control) ? IEEE80211_CCMP_HDR_LEN : 0;

    trace_iwlwifi_dev_tx(trans->dev, skb, iwl_pcie_get_tfd(trans, txq, txq->write_ptr),
                         trans_pcie->tfd_size, &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, 0);

    ip_hdrlen = skb_transport_header(skb) - skb_network_header(skb);
    snap_ip_tcp_hdrlen = 8 + ip_hdrlen + tcp_hdrlen(skb);
    total_len = skb->len - snap_ip_tcp_hdrlen - hdr_len - iv_len;
    amsdu_pad = 0;

    /* total amount of header we may need for this A-MSDU */
    hdr_room =
        DIV_ROUND_UP(total_len, mss) * (3 + snap_ip_tcp_hdrlen + sizeof(struct ethhdr)) + iv_len;

    /* Our device supports 9 segments at most, it will fit in 1 page */
    hdr_page = get_page_hdr(trans, hdr_room);
    if (!hdr_page) { return -ENOMEM; }

    get_page(hdr_page->page);
    start_hdr = hdr_page->pos;
    page_ptr = (void*)((uint8_t*)skb->cb + trans_pcie->page_offs);
    *page_ptr = hdr_page->page;
    memcpy(hdr_page->pos, skb->data + hdr_len, iv_len);
    hdr_page->pos += iv_len;

    /*
     * Pull the ieee80211 header + IV to be able to use TSO core,
     * we will restore it for the tx_status flow.
     */
    skb_pull(skb, hdr_len + iv_len);

    /*
     * Remove the length of all the headers that we don't actually
     * have in the MPDU by themselves, but that we duplicate into
     * all the different MSDUs inside the A-MSDU.
     */
    le16_add_cpu(&tx_cmd->len, -snap_ip_tcp_hdrlen);

    tso_start(skb, &tso);

    while (total_len) {
        /* this is the data left for this subframe */
        unsigned int data_left = min_t(unsigned int, mss, total_len);
        struct sk_buff* csum_skb = NULL;
        unsigned int hdr_tb_len;
        dma_addr_t hdr_tb_phys;
        struct tcphdr* tcph;
        uint8_t *iph, *subf_hdrs_start = hdr_page->pos;

        total_len -= data_left;

        memset(hdr_page->pos, 0, amsdu_pad);
        hdr_page->pos += amsdu_pad;
        amsdu_pad = (4 - (sizeof(struct ethhdr) + snap_ip_tcp_hdrlen + data_left)) & 0x3;
        ether_addr_copy(hdr_page->pos, ieee80211_get_DA(hdr));
        hdr_page->pos += ETH_ALEN;
        ether_addr_copy(hdr_page->pos, ieee80211_get_SA(hdr));
        hdr_page->pos += ETH_ALEN;

        length = snap_ip_tcp_hdrlen + data_left;
        *((__be16*)hdr_page->pos) = cpu_to_be16(length);
        hdr_page->pos += sizeof(length);

        /*
         * This will copy the SNAP as well which will be considered
         * as MAC header.
         */
        tso_build_hdr(skb, hdr_page->pos, &tso, data_left, !total_len);
        iph = hdr_page->pos + 8;
        tcph = (void*)(iph + ip_hdrlen);

        /* For testing on current hardware only */
        if (trans_pcie->sw_csum_tx) {
            csum_skb = alloc_skb(data_left + tcp_hdrlen(skb), GFP_ATOMIC);
            if (!csum_skb) { return -ENOMEM; }

            iwl_compute_pseudo_hdr_csum(iph, tcph, skb->protocol == htons(ETH_P_IPV6), data_left);

            skb_put_data(csum_skb, tcph, tcp_hdrlen(skb));
            skb_reset_transport_header(csum_skb);
            csum_skb->csum_start = (unsigned char*)tcp_hdr(csum_skb) - csum_skb->head;
        }

        hdr_page->pos += snap_ip_tcp_hdrlen;

        hdr_tb_len = hdr_page->pos - start_hdr;
        hdr_tb_phys = dma_map_single(trans->dev, start_hdr, hdr_tb_len, DMA_TO_DEVICE);
        if (unlikely(dma_mapping_error(trans->dev, hdr_tb_phys))) {
            dev_kfree_skb(csum_skb);
            return -EINVAL;
        }
        iwl_pcie_txq_build_tfd(trans, txq, hdr_tb_phys, hdr_tb_len, false);
        trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_hdr, hdr_tb_len);
        /* add this subframe's headers' length to the tx_cmd */
        le16_add_cpu(&tx_cmd->len, hdr_page->pos - subf_hdrs_start);

        /* prepare the start_hdr for the next subframe */
        start_hdr = hdr_page->pos;

        /* put the payload */
        while (data_left) {
            unsigned int size = min_t(unsigned int, tso.size, data_left);
            dma_addr_t tb_phys;

            if (trans_pcie->sw_csum_tx) { skb_put_data(csum_skb, tso.data, size); }

            tb_phys = dma_map_single(trans->dev, tso.data, size, DMA_TO_DEVICE);
            if (unlikely(dma_mapping_error(trans->dev, tb_phys))) {
                dev_kfree_skb(csum_skb);
                return -EINVAL;
            }

            iwl_pcie_txq_build_tfd(trans, txq, tb_phys, size, false);
            trace_iwlwifi_dev_tx_tb(trans->dev, skb, tso.data, size);

            data_left -= size;
            tso_build_data(skb, &tso, size);
        }

        /* For testing on early hardware only */
        if (trans_pcie->sw_csum_tx) {
            __wsum csum;

            csum = skb_checksum(csum_skb, skb_checksum_start_offset(csum_skb),
                                csum_skb->len - skb_checksum_start_offset(csum_skb), 0);
            dev_kfree_skb(csum_skb);
            dma_sync_single_for_cpu(trans->dev, hdr_tb_phys, hdr_tb_len, DMA_TO_DEVICE);
            tcph->check = csum_fold(csum);
            dma_sync_single_for_device(trans->dev, hdr_tb_phys, hdr_tb_len, DMA_TO_DEVICE);
        }
    }

    /* re -add the WiFi header and IV */
    skb_push(skb, hdr_len + iv_len);

    return 0;
}
#else   /* CONFIG_INET */
static int iwl_fill_data_tbs_amsdu(struct iwl_trans* trans, struct sk_buff* skb,
                                   struct iwl_txq* txq, uint8_t hdr_len,
                                   struct iwl_cmd_meta* out_meta, struct iwl_device_cmd* dev_cmd,
                                   uint16_t tb1_len) {
    /* No A-MSDU without CONFIG_INET */
    WARN_ON(1);

    return -1;
}
#endif  /* CONFIG_INET */
#endif  // NEEDS_PORTING

// Transmit a packet from MLME.
//
// This function will create 3 TFDs:
//
//    <----------------- *dev_cmd ------------->  <--------------- *pkt from MLME ----------------->
//    <- 4B -> <------ struct iwl_tx_cmd ------>  <-- 802.11 hdr -->        <--- 802.11 payload --->
//    +------------+  +--------------------------------------------------+  +----------------------+
//    |    tb0     |  |                     tb1                          |  |         tb2          |
//    |            |  |                ('cmd_io_buf')                    |  |    ('dup_io_buf')    |
//    +------------+  +--------------------------------------------------+  +----------------------+
//    <- 20 bytes ->  <---------------- max 304 bytes ------------------->  <----  any length  ---->
//
// The 1st and 2nd descriptors are for 'struct iwl_device_cmd' structure. We copy it from the caller
// into the 'cmd' io_buffer of the txq entry.
//
// Note that the payload of 'struct iwl_device_cmd' is actually the 'struct iwl_tx_cmd'. Moreover,
// at end of 'struct iwl_tx_cmd', the MAC header of 'pkt' is also copied in iwl_mvm_set_tx_params().
//
// The 3rd descriptor is for the 802.11 payload. We re-used the 'dup_io_buf' in the structure to
// store the payload. Currently we only support one fragment (the pkt->packet_head) and always
// copy the payload because the firmware will transmit the packet in asynchronous manner.
//
zx_status_t iwl_trans_pcie_tx(struct iwl_trans* trans, struct ieee80211_mac_packet* pkt,
                              const struct iwl_device_cmd* dev_cmd, int txq_id) {
  zx_status_t ret = ZX_OK;
  ZX_DEBUG_ASSERT(trans);
  ZX_DEBUG_ASSERT(pkt);
  ZX_DEBUG_ASSERT(dev_cmd);

  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_txq* txq = trans_pcie->txq[txq_id];
  int cmd_idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);

  if (!test_bit(txq_id, trans_pcie->queue_used)) {
    IWL_ERR(trans, "TX on unused queue %d\n", txq_id);
    return ZX_ERR_INVALID_ARGS;
  }

  mtx_lock(&txq->lock);

  int available_space = iwl_queue_space(trans, txq);
  if (available_space < txq->high_mark) {
    iwl_stop_queue(trans, txq);
    IWL_WARN(trans, "stopped queue because the avaliable space (%d) is too small (< %d)\n",
             available_space, txq->high_mark);

    /* don't put the packet on the ring, if there is no room */
    if (unlikely(available_space < TX_RESERVED_SPACE)) {
      mtx_unlock(&txq->lock);
      IWL_WARN(trans, "dropped packet due to small available space: %d\n", available_space);
      return ZX_OK;
    }
  }

  // First copy 'dev_cmd' to 'out_cmd'. This is easier to copy the whole cmd to tb0 and tb1
  // respectively.
  ZX_ASSERT(!txq->entries[cmd_idx].cmd);
  zx_status_t status = iwl_iobuf_allocate_contiguous(&trans_pcie->pci_dev->dev, TB1_MAX_SIZE,
                                                     &txq->entries[cmd_idx].cmd);
  if (status != ZX_OK) {
    IWL_ERR(trans, "pcie TX io_buffer_init() failed: %s\n", zx_status_get_string(status));
    ret = status;
    goto unlock;
  }
  struct iwl_device_cmd* out_cmd = iwl_iobuf_virtual(txq->entries[cmd_idx].cmd);
  *out_cmd = *dev_cmd;  // Copy into the TXQ memory shared with the firmware.

#if 0   // NEEDS_PORTING
    /* In AGG mode, the index in the ring must correspond to the WiFi
     * sequence number. This is a HW requirements to help the SCD to parse
     * the BA.
     * Check here that the packets are in the right place on the ring.
     */
    wifi_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
    WARN_ONCE(txq->ampdu && (wifi_seq & 0xff) != txq->write_ptr, "Q: %d WiFi Seq %d tfdNum %d",
              txq_id, wifi_seq, txq->write_ptr);
#endif  // NEEDS_PORTING

  out_cmd->hdr.sequence =
      cpu_to_le16((uint16_t)(QUEUE_TO_SEQ(txq_id) | INDEX_TO_SEQ(txq->write_ptr)));

  struct iwl_cmd_meta* out_meta = &txq->entries[cmd_idx].meta;
  out_meta->flags = 0;

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // (tb0) start the TFD with the minimum copy bytes.
  //
  struct iwl_pcie_first_tb_buf* tb_bufs = iwl_iobuf_virtual(txq->first_tb_bufs);
  const uint16_t tb0_size = IWL_FIRST_TB_SIZE;
  memcpy(&tb_bufs[cmd_idx], &out_cmd->hdr, tb0_size);
  uint32_t num_tbs;

  zx_paddr_t tb0_phys = iwl_pcie_get_first_tb_dma(txq, txq->write_ptr);
  zx_paddr_t scratch_phys =
      tb0_phys + sizeof(struct iwl_cmd_header) + offsetof(struct iwl_tx_cmd, scratch);

  struct iwl_tx_cmd* tx_cmd = (struct iwl_tx_cmd*)out_cmd->payload;
  tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
  tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);

  iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, tb0_size, true, &num_tbs);

  /* there must be data left over for TB1 or this code must be changed */
  BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_FIRST_TB_SIZE);

  /////////////////////////////////////////////////////////////////////////////////////////////////
  // (tb1) the rest of 'iwl_device_cmd' and 802.11 header.
  //

  const uint16_t tb1_len =
      sizeof(struct iwl_cmd_header) + sizeof(struct iwl_tx_cmd) - tb0_size + pkt->header_size;
  // See original code: "do not align A-MSDU to dword as the subframe header aligns it"
  // TODO(51295): we don't align the length when we enable A-MSDU in the future.
  const uint16_t aligned_len = ROUND_UP(tb1_len, 4);
  if (tb1_len != aligned_len) {
    IWL_DEBUG_TX(trans, "Adjusted the tb1_len=%d ==> aligned_len=%d\n", tb1_len, aligned_len);
    tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_MH_PAD);
  }

  zx_paddr_t phys_addr = iwl_iobuf_physical(txq->entries[cmd_idx].cmd);
  zx_paddr_t tb1_phys = phys_addr + tb0_size;
  iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, false, &num_tbs);

#if 1
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // (tb2) the 802.11 payload
  //
  if ((ret = iwl_fill_data_tbs(trans, pkt, txq, cmd_idx, &num_tbs, out_meta)) != ZX_OK) {
    goto unlock;
  }
#else   // NEEDS_PORTING
  // TODO(51295): handle the GSO case in the future.
  /*
   * If gso_size wasn't set, don't give the frame "amsdu treatment"
   * (adding subframes, etc.).
   * This can happen in some testing flows when the amsdu was already
   * pre-built, and we just need to send the resulting skb.
   */
  if (amsdu && skb_shinfo(skb)->gso_size) {
    if (unlikely(iwl_fill_data_tbs_amsdu(trans, skb, txq, hdr_len, out_meta, dev_cmd, tb1_len))) {
      goto out_err;
    }
  } else {
    struct sk_buff* frag;

    if (unlikely(iwl_fill_data_tbs(trans, skb, txq, hdr_len, out_meta))) {
      goto out_err;
    }

    skb_walk_frags(skb, frag) {
      if (unlikely(iwl_fill_data_tbs(trans, frag, txq, 0, out_meta))) {
        goto out_err;
      }
    }
  }

  /* building the A-MSDU might have changed this data, so memcpy it now */
  memcpy(&txq->first_tb_bufs[txq->write_ptr], dev_cmd, IWL_FIRST_TB_SIZE);
#endif  // NEEDS_PORTING

  void* tfd = iwl_pcie_get_tfd(trans, txq, txq->write_ptr);
  /* Set up entry for this TFD in Tx byte-count array */
  iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len),
                                   iwl_pcie_tfd_get_num_tbs(trans, tfd));

#if 1  // NEEDS_PORTING
  /* start timer if queue currently empty */
  if (txq->read_ptr == txq->write_ptr) {
    iwl_trans_ref(trans);
  }
#else   // NEEDS_PORTING
  /* start timer if queue currently empty */
  if (txq->read_ptr == txq->write_ptr) {
    if (txq->wd_timeout) {
      /*
       * If the TXQ is active, then set the timer, if not,
       * set the timer in remainder so that the timer will
       * be armed with the right value when the station will
       * wake up.
       */
      if (!txq->frozen) {
        mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
      } else {
        txq->frozen_expiry_remainder = txq->wd_timeout;
      }
    }
    IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", txq->id);
    iwl_trans_ref(trans);
  }
#endif  // NEEDS_PORTING

  /* Tell device the write index *just past* this latest filled TFD */
  txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);

#if 1  // NEEDS_PORTING
  iwl_pcie_txq_inc_wr_ptr(trans, txq);
  /*
   * At this point the frame is "transmitted" successfully
   * and we will get a TX status notification eventually.
   */
#else   // NEEDS_PORTING
  bool wait_write_ptr = ieee80211_has_morefrags(fc);
  if (!wait_write_ptr) {
    iwl_pcie_txq_inc_wr_ptr(trans, txq);
  }
#endif  // NEEDS_PORTING

unlock:
  mtx_unlock(&txq->lock);

  return ret;
}
