/******************************************************************************
 *
 * Copyright(c) 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 "third_party/iwlwifi/fw/api/tx.h"
#include "third_party/iwlwifi/iwl-csr.h"
#include "third_party/iwlwifi/iwl-debug.h"
#include "third_party/iwlwifi/iwl-io.h"
#include "third_party/iwlwifi/pcie/internal.h"

/*
 * iwl_pcie_gen2_tx_stop - Stop all Tx DMA channels
 */
void iwl_pcie_gen2_tx_stop(struct iwl_trans* trans) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  size_t txq_id;

  /*
   * 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));

  /* Unmap DMA from host system and free skb's */
  for (txq_id = 0; txq_id < ARRAY_SIZE(trans_pcie->txq); txq_id++) {
    if (!trans_pcie->txq[txq_id]) {
      continue;
    }
    iwl_pcie_gen2_txq_unmap(trans, txq_id);
  }
}

/*
 * iwl_pcie_txq_update_byte_tbl - Set up entry in Tx byte-count array
 */
void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie* trans_pcie, struct iwl_txq* txq,
                                   uint16_t byte_cnt, int num_tbs) {
  struct iwlagn_scd_bc_tbl* scd_bc_tbl = txq->bc_tbl.addr;
  struct iwl_trans* trans = iwl_trans_pcie_get_trans(trans_pcie);
  struct iwl_gen3_bc_tbl* scd_bc_tbl_gen3 = txq->bc_tbl.addr;
  int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
  uint8_t filled_tfd_size, num_fetch_chunks;
  uint16_t len = byte_cnt;
  __le16 bc_ent;

  if (trans_pcie->bc_table_dword) {
    len = DIV_ROUND_UP(len, 4);
  }

  if (WARN_ON(len > 0xFFF || idx >= txq->n_window)) {
    return;
  }

  filled_tfd_size = offsetof(struct iwl_tfh_tfd, tbs) + num_tbs * sizeof(struct iwl_tfh_tb);
  /*
   * filled_tfd_size contains the number of filled bytes in the TFD.
   * Dividing it by 64 will give the number of chunks to fetch
   * to SRAM- 0 for one chunk, 1 for 2 and so on.
   * If, for example, TFD contains only 3 TBs then 32 bytes
   * of the TFD are used, and only one chunk of 64 bytes should
   * be fetched
   */
  num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1;

  bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12));
  if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
    scd_bc_tbl_gen3->tfd_offset[idx] = bc_ent;
  } else {
    scd_bc_tbl->tfd_offset[idx] = bc_ent;
  }
}

/*
 * iwl_pcie_gen2_txq_inc_wr_ptr - Send new write index to hardware
 */
void iwl_pcie_gen2_txq_inc_wr_ptr(struct iwl_trans* trans, struct iwl_txq* txq) {
  iwl_assert_lock_held(&txq->lock);

  IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq->id, txq->write_ptr);

  /*
   * 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_write32(trans, HBUS_TARG_WRPTR, txq->write_ptr | (txq->id << 16));
}

static uint8_t iwl_pcie_gen2_get_num_tbs(struct iwl_trans* trans, struct iwl_tfh_tfd* tfd) {
  return le16_to_cpu(tfd->num_tbs) & 0x1f;
}

static void iwl_pcie_gen2_tfd_unmap(struct iwl_trans* trans, struct iwl_cmd_meta* meta,
                                    struct iwl_tfh_tfd* tfd) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  int i, num_tbs;

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

  if (num_tbs > trans_pcie->max_tbs) {
    IWL_ERR(trans, "Too many chunks: %i\n", num_tbs);
    return;
  }

  /* first TB is never freed - it's the bidirectional DMA data */
  for (i = 1; i < num_tbs; i++) {
#if 0   // NEEDS_PORTING
        if (meta->tbs & BIT(i))
            dma_unmap_page(trans->dev, le64_to_cpu(tfd->tbs[i].addr),
                           le16_to_cpu(tfd->tbs[i].tb_len), DMA_TO_DEVICE);
        else
            dma_unmap_single(trans->dev, le64_to_cpu(tfd->tbs[i].addr),
                             le16_to_cpu(tfd->tbs[i].tb_len), DMA_TO_DEVICE);
#endif  // NEEDS_PORTING
  }

  tfd->num_tbs = 0;
}

static void iwl_pcie_gen2_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 idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);

  iwl_assert_lock_held(&txq->lock);

  iwl_pcie_gen2_tfd_unmap(trans, &txq->entries[idx].meta, iwl_pcie_get_tfd(trans, txq, idx));

  /* free SKB */
  if (txq->entries) {
    struct sk_buff* skb;

    skb = txq->entries[idx].skb;

    /* Can be called from irqs-disabled context
     * If skb is not NULL, it means that the whole queue is being
     * freed and that the queue is not empty - free the skb
     */
    if (skb) {
      iwl_op_mode_free_skb(trans->op_mode, skb);
      txq->entries[idx].skb = NULL;
    }
  }
}

#if 0  // NEEDS_PORTING
static int iwl_pcie_gen2_set_tb(struct iwl_trans* trans, struct iwl_tfh_tfd* tfd, dma_addr_t addr,
                                uint16_t len) {
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    int idx = iwl_pcie_gen2_get_num_tbs(trans, tfd);
    struct iwl_tfh_tb* tb;

    if (WARN_ON(idx >= IWL_TFH_NUM_TBS)) { return -EINVAL; }
    tb = &tfd->tbs[idx];

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

    put_unaligned_le64(addr, &tb->addr);
    tb->tb_len = cpu_to_le16(len);

    tfd->num_tbs = cpu_to_le16(idx + 1);

    return idx;
}

static int iwl_pcie_gen2_build_amsdu(struct iwl_trans* trans, struct sk_buff* skb,
                                     struct iwl_tfh_tfd* tfd, int start_len, uint8_t hdr_len,
                                     struct iwl_device_cmd* dev_cmd) {
#ifdef CONFIG_INET
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    struct iwl_tx_cmd_gen2* tx_cmd = (void*)dev_cmd->payload;
    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 */
    iv_len = ieee80211_has_protected(hdr->frame_control) ? fuchsia_wlan_ieee80211_CCMP_HDR_LEN : 0;

    trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), &dev_cmd->hdr, start_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 tb_len;
        dma_addr_t tb_phys;
        uint8_t* 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);

        hdr_page->pos += snap_ip_tcp_hdrlen;

        tb_len = hdr_page->pos - start_hdr;
        tb_phys = dma_map_single(trans->dev, start_hdr, tb_len, DMA_TO_DEVICE);
        if (unlikely(dma_mapping_error(trans->dev, tb_phys))) {
            dev_kfree_skb(csum_skb);
            goto out_err;
        }
        iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb_len);
        trace_iwlwifi_dev_tx_tb(trans->dev, skb, start_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) {
            tb_len = min_t(unsigned int, tso.size, data_left);
            tb_phys = dma_map_single(trans->dev, tso.data, tb_len, DMA_TO_DEVICE);
            if (unlikely(dma_mapping_error(trans->dev, tb_phys))) {
                dev_kfree_skb(csum_skb);
                goto out_err;
            }
            iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb_len);
            trace_iwlwifi_dev_tx_tb(trans->dev, skb, tso.data, tb_len);

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

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

    return 0;

out_err:
#endif
    return -EINVAL;
}

static struct iwl_tfh_tfd* iwl_pcie_gen2_build_tx_amsdu(
    struct iwl_trans* trans, struct iwl_txq* txq, struct iwl_device_cmd* dev_cmd,
    struct sk_buff* skb, struct iwl_cmd_meta* out_meta, int hdr_len, int tx_cmd_len) {
    int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
    struct iwl_tfh_tfd* tfd = iwl_pcie_get_tfd(trans, txq, idx);
    dma_addr_t tb_phys;
    int len;
    void* tb1_addr;

    tb_phys = iwl_pcie_get_first_tb_dma(txq, idx);

    iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, IWL_FIRST_TB_SIZE);

    /*
     * The second TB (tb1) points to the remainder of the TX command
     * and the 802.11 header - dword aligned size
     * (This calculation modifies the TX command, so do it before the
     * setup of the first TB)
     */
    len = tx_cmd_len + sizeof(struct iwl_cmd_header) + hdr_len - IWL_FIRST_TB_SIZE;

    /* do not align A-MSDU to dword as the subframe header aligns it */

    /* map the data for TB1 */
    tb1_addr = ((uint8_t*)&dev_cmd->hdr) + IWL_FIRST_TB_SIZE;
    tb_phys = dma_map_single(trans->dev, tb1_addr, len, DMA_TO_DEVICE);
    if (unlikely(dma_mapping_error(trans->dev, tb_phys))) { goto out_err; }
    iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, len);

    if (iwl_pcie_gen2_build_amsdu(trans, skb, tfd, len + IWL_FIRST_TB_SIZE, hdr_len, dev_cmd)) {
        goto out_err;
    }

    /* building the A-MSDU might have changed this data, memcpy it now */
    memcpy(&txq->first_tb_bufs[idx], dev_cmd, IWL_FIRST_TB_SIZE);
    return tfd;

out_err:
    iwl_pcie_gen2_tfd_unmap(trans, out_meta, tfd);
    return NULL;
}

static int iwl_pcie_gen2_tx_add_frags(struct iwl_trans* trans, struct sk_buff* skb,
                                      struct iwl_tfh_tfd* tfd, struct iwl_cmd_meta* out_meta) {
    int i;

    for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
        const skb_frag_t* frag = &skb_shinfo(skb)->frags[i];
        dma_addr_t tb_phys;
        int tb_idx;

        if (!skb_frag_size(frag)) { continue; }

        tb_phys = skb_frag_dma_map(trans->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE);

        if (unlikely(dma_mapping_error(trans->dev, tb_phys))) { return -ENOMEM; }
        tb_idx = iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, skb_frag_size(frag));
        trace_iwlwifi_dev_tx_tb(trans->dev, skb, skb_frag_address(frag), skb_frag_size(frag));
        if (tb_idx < 0) { return tb_idx; }

        out_meta->tbs |= BIT(tb_idx);
    }

    return 0;
}

static struct iwl_tfh_tfd* iwl_pcie_gen2_build_tx(struct iwl_trans* trans, struct iwl_txq* txq,
                                                  struct iwl_device_cmd* dev_cmd,
                                                  struct sk_buff* skb,
                                                  struct iwl_cmd_meta* out_meta, int hdr_len,
                                                  int tx_cmd_len, bool pad) {
    int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
    struct iwl_tfh_tfd* tfd = iwl_pcie_get_tfd(trans, txq, idx);
    dma_addr_t tb_phys;
    int len, tb1_len, tb2_len;
    void* tb1_addr;
    struct sk_buff* frag;

    tb_phys = iwl_pcie_get_first_tb_dma(txq, idx);

    /* The first TB points to bi-directional DMA data */
    memcpy(&txq->first_tb_bufs[idx], dev_cmd, IWL_FIRST_TB_SIZE);

    iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, IWL_FIRST_TB_SIZE);

    /*
     * The second TB (tb1) points to the remainder of the TX command
     * and the 802.11 header - dword aligned size
     * (This calculation modifies the TX command, so do it before the
     * setup of the first TB)
     */
    len = tx_cmd_len + sizeof(struct iwl_cmd_header) + hdr_len - IWL_FIRST_TB_SIZE;

    if (pad) {
        tb1_len = ALIGN(len, 4);
    } else {
        tb1_len = len;
    }

    /* map the data for TB1 */
    tb1_addr = ((uint8_t*)&dev_cmd->hdr) + IWL_FIRST_TB_SIZE;
    tb_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
    if (unlikely(dma_mapping_error(trans->dev, tb_phys))) { goto out_err; }
    iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb1_len);
    trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), &dev_cmd->hdr,
                         IWL_FIRST_TB_SIZE + tb1_len, hdr_len);

    /* set up TFD's third entry to point to remainder of skb's head */
    tb2_len = skb_headlen(skb) - hdr_len;

    if (tb2_len > 0) {
        tb_phys = dma_map_single(trans->dev, skb->data + hdr_len, tb2_len, DMA_TO_DEVICE);
        if (unlikely(dma_mapping_error(trans->dev, tb_phys))) { goto out_err; }
        iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb2_len);
        trace_iwlwifi_dev_tx_tb(trans->dev, skb, skb->data + hdr_len, tb2_len);
    }

    if (iwl_pcie_gen2_tx_add_frags(trans, skb, tfd, out_meta)) { goto out_err; }

    skb_walk_frags(skb, frag) {
        tb_phys = dma_map_single(trans->dev, frag->data, skb_headlen(frag), DMA_TO_DEVICE);
        if (unlikely(dma_mapping_error(trans->dev, tb_phys))) { goto out_err; }
        iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, skb_headlen(frag));
        trace_iwlwifi_dev_tx_tb(trans->dev, skb, frag->data, skb_headlen(frag));
        if (iwl_pcie_gen2_tx_add_frags(trans, frag, tfd, out_meta)) { goto out_err; }
    }

    return tfd;

out_err:
    iwl_pcie_gen2_tfd_unmap(trans, out_meta, tfd);
    return NULL;
}

static struct iwl_tfh_tfd* iwl_pcie_gen2_build_tfd(struct iwl_trans* trans, struct iwl_txq* txq,
                                                   struct iwl_device_cmd* dev_cmd,
                                                   struct sk_buff* skb,
                                                   struct iwl_cmd_meta* out_meta) {
    struct ieee80211_hdr* hdr = (struct ieee80211_hdr*)skb->data;
    int idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
    struct iwl_tfh_tfd* tfd = iwl_pcie_get_tfd(trans, txq, idx);
    int len, hdr_len;
    bool amsdu;

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

    memset(tfd, 0, sizeof(*tfd));

    if (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) {
        len = sizeof(struct iwl_tx_cmd_gen2);
    } else {
        len = sizeof(struct iwl_tx_cmd_gen3);
    }

    amsdu = ieee80211_is_data_qos(hdr->frame_control) &&
            (*ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_A_MSDU_PRESENT);

    hdr_len = ieee80211_hdrlen(hdr->frame_control);

    /*
     * Only build A-MSDUs here if doing so by GSO, otherwise it may be
     * an A-MSDU for other reasons, e.g. NAN or an A-MSDU having been
     * built in the higher layers already.
     */
    if (amsdu && skb_shinfo(skb)->gso_size) {
        return iwl_pcie_gen2_build_tx_amsdu(trans, txq, dev_cmd, skb, out_meta, hdr_len, len);
    }
    return iwl_pcie_gen2_build_tx(trans, txq, dev_cmd, skb, out_meta, hdr_len, len, !amsdu);
}
#endif  // NEEDS_PORTING

int iwl_trans_pcie_gen2_tx(struct iwl_trans* trans, struct sk_buff* skb,
                           struct iwl_device_cmd* dev_cmd, int txq_id) {
#if 0   // NEEDS_PORTING
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    struct iwl_cmd_meta* out_meta;
    struct iwl_txq* txq = trans_pcie->txq[txq_id];
    uint16_t cmd_len;
    int idx;
    void* tfd;

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

    if (skb_is_nonlinear(skb) && skb_shinfo(skb)->nr_frags > IWL_PCIE_MAX_FRAGS(trans_pcie) &&
        __skb_linearize(skb)) {
        return -ENOMEM;
    }

    spin_lock(&txq->lock);

    if (iwl_queue_space(trans, txq) < txq->high_mark) {
        iwl_stop_queue(trans, txq);

        /* don't put the packet on the ring, if there is no room */
        if (unlikely(iwl_queue_space(trans, txq) < 3)) {
            struct iwl_device_cmd** dev_cmd_ptr;

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

            *dev_cmd_ptr = dev_cmd;
            __skb_queue_tail(&txq->overflow_q, skb);
            spin_unlock(&txq->lock);
            return 0;
        }
    }

    idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);

    /* Set up driver data for this TFD */
    txq->entries[idx].skb = skb;
    txq->entries[idx].cmd = dev_cmd;

    dev_cmd->hdr.sequence = cpu_to_le16((uint16_t)(QUEUE_TO_SEQ(txq_id) | INDEX_TO_SEQ(idx)));

    /* Set up first empty entry in queue's array of Tx/cmd buffers */
    out_meta = &txq->entries[idx].meta;
    out_meta->flags = 0;

    tfd = iwl_pcie_gen2_build_tfd(trans, txq, dev_cmd, skb, out_meta);
    if (!tfd) {
        spin_unlock(&txq->lock);
        return -1;
    }

    if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
        struct iwl_tx_cmd_gen3* tx_cmd_gen3 = (void*)dev_cmd->payload;

        cmd_len = le16_to_cpu(tx_cmd_gen3->len);
    } else {
        struct iwl_tx_cmd_gen2* tx_cmd_gen2 = (void*)dev_cmd->payload;

        cmd_len = le16_to_cpu(tx_cmd_gen2->len);
    }

    /* Set up entry for this TFD in Tx byte-count array */
    iwl_pcie_gen2_update_byte_tbl(trans_pcie, txq, cmd_len, iwl_pcie_gen2_get_num_tbs(trans, tfd));

    /* start timer if queue currently empty */
    if (txq->read_ptr == txq->write_ptr) {
        if (txq->wd_timeout) { mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout); }
        IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", txq->id);
        iwl_trans_ref(trans);
    }

    /* Tell device the write index *just past* this latest filled TFD */
    txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);
    iwl_pcie_gen2_txq_inc_wr_ptr(trans, txq);
    /*
     * At this point the frame is "transmitted" successfully
     * and we will get a TX status notification eventually.
     */
    spin_unlock(&txq->lock);
    return 0;
#endif  // NEEDS_PORTING
  IWL_ERR(trans, "%s needs porting\n", __FUNCTION__);
  return -1;
}

#if 0  // NEEDS_PORTING
/*************** HOST COMMAND QUEUE FUNCTIONS   *****/

/*
 * iwl_pcie_gen2_enqueue_hcmd - enqueue a uCode command
 * @priv: device private data point
 * @cmd: a pointer to the ucode command structure
 *
 * The function returns < 0 values to indicate the operation
 * failed. On success, it returns the index (>= 0) of command in the
 * command queue.
 */
static int iwl_pcie_gen2_enqueue_hcmd(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];
    struct iwl_device_cmd* out_cmd;
    struct iwl_cmd_meta* out_meta;
    unsigned long flags;
    void* dup_buf = NULL;
    dma_addr_t phys_addr;
    int i, cmd_pos, idx;
    uint16_t copy_size, cmd_size, tb0_size;
    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];
    struct iwl_tfh_tfd* tfd;

    copy_size = sizeof(struct iwl_cmd_header_wide);
    cmd_size = sizeof(struct iwl_cmd_header_wide);

    for (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)) {
                idx = -EINVAL;
                goto free_dup_buf;
            }
        } 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(dup_buf)) {
                idx = -EINVAL;
                goto free_dup_buf;
            }

            dup_buf = kmemdup(cmddata[i], cmdlen[i], GFP_ATOMIC);
            if (!dup_buf) { return -ENOMEM; }
        } else {
            /* NOCOPY must not be followed by normal! */
            if (WARN_ON(had_nocopy)) {
                idx = -EINVAL;
                goto free_dup_buf;
            }
            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 (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE, "Command %s (%#x) is too large (%d bytes)\n",
             iwl_get_cmd_string(trans, cmd->id), cmd->id, copy_size)) {
        idx = -EINVAL;
        goto free_dup_buf;
    }

    spin_lock_bh(&txq->lock);

    idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr);
    tfd = iwl_pcie_get_tfd(trans, txq, txq->write_ptr);
    memset(tfd, 0, sizeof(*tfd));

    if (iwl_queue_space(trans, txq) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
        spin_unlock_bh(&txq->lock);

        IWL_ERR(trans, "No space in command queue\n");
        iwl_op_mode_cmd_queue_full(trans->op_mode);
        idx = -ENOSPC;
        goto free_dup_buf;
    }

    out_cmd = txq->entries[idx].cmd;
    out_meta = &txq->entries[idx].meta;

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

    /* set up the header */
    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);

    /* and copy the data that needs to be copied */
    for (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.
         */
        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, idx,
                 trans_pcie->cmd_queue);

    /* start the TFD with the minimum copy bytes */
    tb0_size = min_t(int, copy_size, IWL_FIRST_TB_SIZE);
    memcpy(&txq->first_tb_bufs[idx], &out_cmd->hdr, tb0_size);
    iwl_pcie_gen2_set_tb(trans, tfd, iwl_pcie_get_first_tb_dma(txq, idx), tb0_size);

    /* map first command fragment, if any remains */
    if (copy_size > tb0_size) {
        phys_addr = dma_map_single(trans->dev, ((uint8_t*)&out_cmd->hdr) + tb0_size,
                                   copy_size - tb0_size, DMA_TO_DEVICE);
        if (dma_mapping_error(trans->dev, phys_addr)) {
            idx = -ENOMEM;
            iwl_pcie_gen2_tfd_unmap(trans, out_meta, tfd);
            goto out;
        }
        iwl_pcie_gen2_set_tb(trans, tfd, phys_addr, copy_size - tb0_size);
    }

    /* map the remaining (adjusted) nocopy/dup fragments */
    for (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; }
        if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) { data = dup_buf; }
        phys_addr = dma_map_single(trans->dev, (void*)data, cmdlen[i], DMA_TO_DEVICE);
        if (dma_mapping_error(trans->dev, phys_addr)) {
            idx = -ENOMEM;
            iwl_pcie_gen2_tfd_unmap(trans, out_meta, tfd);
            goto out;
        }
        iwl_pcie_gen2_set_tb(trans, tfd, phys_addr, cmdlen[i]);
    }

    BUILD_BUG_ON(IWL_TFH_NUM_TBS > sizeof(out_meta->tbs) * BITS_PER_BYTE);
    out_meta->flags = cmd->flags;
    if (WARN_ON_ONCE(txq->entries[idx].free_buf)) { kzfree(txq->entries[idx].free_buf); }
    txq->entries[idx].free_buf = dup_buf;

    trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr_wide);

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

    spin_lock_irqsave(&trans_pcie->reg_lock, flags);
    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);
    }
    /* Increment and update queue's write index */
    txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);
    iwl_pcie_gen2_txq_inc_wr_ptr(trans, txq);
    spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);

out:
    spin_unlock_bh(&txq->lock);
free_dup_buf:
    if (idx < 0) { kfree(dup_buf); }
    return idx;
}

#define HOST_COMPLETE_TIMEOUT (2 * HZ * CPTCFG_IWL_TIMEOUT_FACTOR)

static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans* trans, struct iwl_host_cmd* cmd) {
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    const char* cmd_str = iwl_get_cmd_string(trans, cmd->id);
    struct iwl_txq* txq = trans_pcie->txq[trans_pcie->cmd_queue];
    int cmd_idx;
    int ret;

    IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", cmd_str);

    if (WARN(test_and_set_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status),
             "Command %s: a command is already active!\n", cmd_str)) {
        return -EIO;
    }

    IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", cmd_str);

    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;
        }
    }

    cmd_idx = iwl_pcie_gen2_enqueue_hcmd(trans, cmd);
    if (cmd_idx < 0) {
        ret = cmd_idx;
        clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
        IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", cmd_str, ret);
        return ret;
    }

    ret = wait_event_timeout(trans_pcie->wait_command_queue,
                             !test_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status),
                             HOST_COMPLETE_TIMEOUT);
    if (!ret) {
        IWL_ERR(trans, "Error sending %s: time out after %dms.\n", cmd_str,
                jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));

        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", cmd_str);
        ret = -ETIMEDOUT;

        iwl_force_nmi(trans);
        iwl_trans_fw_error(trans);

        goto cancel;
    }

    if (test_bit(STATUS_FW_ERROR, &trans->status)) {
        IWL_ERR(trans, "FW error in SYNC CMD %s\n", cmd_str);
        dump_stack();
        ret = -EIO;
        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");
        ret = -ERFKILL;
        goto cancel;
    }

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

    return 0;

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 ret;
}
#endif  // NEEDS_PORTING

int iwl_trans_pcie_gen2_send_hcmd(struct iwl_trans* trans, struct iwl_host_cmd* cmd) {
#if 0   // NEEDS_PORTING
    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 -ERFKILL;
    }

    if (cmd->flags & CMD_ASYNC) {
        int ret;

        /* An asynchronous command can not expect an SKB to be set. */
        if (WARN_ON(cmd->flags & CMD_WANT_SKB)) { return -EINVAL; }

        ret = iwl_pcie_gen2_enqueue_hcmd(trans, cmd);
        if (ret < 0) {
            IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n",
                    iwl_get_cmd_string(trans, cmd->id), ret);
            return ret;
        }
        return 0;
    }

    return iwl_pcie_gen2_send_hcmd_sync(trans, cmd);
#endif  // NEEDS_PORTING
  IWL_ERR(trans, "%s needs porting\n", __FUNCTION__);
  return -1;
}

/*
 * iwl_pcie_gen2_txq_unmap -  Unmap any remaining DMA mappings and free skb's
 */
void iwl_pcie_gen2_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
            int idx = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
            struct sk_buff* skb = txq->entries[idx].skb;

            if (WARN_ON_ONCE(!skb)) { continue; }

            iwl_pcie_free_tso_page(trans_pcie, skb);
#endif  // NEEDS_PORTING
    }
    iwl_pcie_gen2_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 if (trans_pcie->ref_cmd_in_flight) {
        trans_pcie->ref_cmd_in_flight = false;
        IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight\n");
        iwl_trans_unref(trans);
      }
      mtx_unlock(&trans_pcie->reg_lock);
    }
  }

#if 0   // NEEDS_PORTING
    while (!skb_queue_empty(&txq->overflow_q)) {
        struct sk_buff* skb = __skb_dequeue(&txq->overflow_q);

        iwl_op_mode_free_skb(trans->op_mode, skb);
    }
#endif  // NEEDS_PORTING

  mtx_unlock(&txq->lock);

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

#if 0   // NEEDS_PORTING
void iwl_pcie_gen2_txq_free_memory(struct iwl_trans* trans, struct iwl_txq* txq) {
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    struct device* dev = trans->dev;

    /* De-alloc circular buffer of TFDs */
    if (txq->tfds) {
        dma_free_coherent(dev, trans_pcie->tfd_size * txq->n_window, txq->tfds, txq->dma_addr);
        dma_free_coherent(dev, sizeof(*txq->first_tb_bufs) * txq->n_window, txq->first_tb_bufs,
                          txq->first_tb_dma);
    }

    kfree(txq->entries);
    iwl_pcie_free_dma_ptr(trans, &txq->bc_tbl);
    kfree(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_gen2_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_gen2_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++) {
            kzfree(txq->entries[i].cmd);
            kzfree(txq->entries[i].free_buf);
        }
    del_timer_sync(&txq->stuck_timer);

    iwl_pcie_gen2_txq_free_memory(trans, txq);

    trans_pcie->txq[txq_id] = NULL;

    clear_bit(txq_id, trans_pcie->queue_used);
}

int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans* trans, struct iwl_txq** intxq, int size,
                                     unsigned int timeout) {
    int ret;

    struct iwl_txq* txq;
    txq = kzalloc(sizeof(*txq), GFP_KERNEL);
    if (!txq) { return -ENOMEM; }
    ret = iwl_pcie_alloc_dma_ptr(trans, &txq->bc_tbl,
                                 (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
                                     ? sizeof(struct iwl_gen3_bc_tbl)
                                     : sizeof(struct iwlagn_scd_bc_tbl));
    if (ret) {
        IWL_ERR(trans, "Scheduler BC Table allocation failed\n");
        kfree(txq);
        return -ENOMEM;
    }

    ret = iwl_pcie_txq_alloc(trans, txq, size, false);
    if (ret) {
        IWL_ERR(trans, "Tx queue alloc failed\n");
        goto error;
    }
    ret = iwl_pcie_txq_init(trans, txq, size, false);
    if (ret) {
        IWL_ERR(trans, "Tx queue init failed\n");
        goto error;
    }

    txq->wd_timeout = msecs_to_jiffies(timeout);

    *intxq = txq;
    return 0;

error:
    iwl_pcie_gen2_txq_free_memory(trans, txq);
    return ret;
}

int iwl_trans_pcie_txq_alloc_response(struct iwl_trans* trans, struct iwl_txq* txq,
                                      struct iwl_host_cmd* hcmd) {
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    struct iwl_tx_queue_cfg_rsp* rsp;
    int ret, qid;
    uint32_t wr_ptr;

    if (WARN_ON(iwl_rx_packet_payload_len(hcmd->resp_pkt) != sizeof(*rsp))) {
        ret = -EINVAL;
        goto error_free_resp;
    }

    rsp = (void*)hcmd->resp_pkt->data;
    qid = le16_to_cpu(rsp->queue_number);
    wr_ptr = le16_to_cpu(rsp->write_pointer);

    if (qid >= ARRAY_SIZE(trans_pcie->txq)) {
        WARN_ONCE(1, "queue index %d unsupported", qid);
        ret = -EIO;
        goto error_free_resp;
    }

    if (test_and_set_bit(qid, trans_pcie->queue_used)) {
        WARN_ONCE(1, "queue %d already used", qid);
        ret = -EIO;
        goto error_free_resp;
    }

    txq->id = qid;
    trans_pcie->txq[qid] = txq;
    wr_ptr &= (trans->cfg->base_params->max_tfd_queue_size - 1);

    /* Place first TFD at index corresponding to start sequence number */
    txq->read_ptr = wr_ptr;
    txq->write_ptr = wr_ptr;

    IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);

    iwl_free_resp(hcmd);
    return qid;

error_free_resp:
    iwl_free_resp(hcmd);
    iwl_pcie_gen2_txq_free_memory(trans, txq);
    return ret;
}
#endif  // NEEDS_PORTING

int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans* trans, __le16 flags, uint8_t sta_id, uint8_t tid,
                                 int cmd_id, int size, unsigned int timeout) {
#if 0   // NEEDS_PORTING
    struct iwl_txq* txq = NULL;
    struct iwl_tx_queue_cfg_cmd cmd = {
        .flags = flags,
        .sta_id = sta_id,
        .tid = tid,
    };
    struct iwl_host_cmd hcmd = {
        .id = cmd_id,
        .len = {sizeof(cmd)},
        .data =
            {
                &cmd,
            },
        .flags = CMD_WANT_SKB,
    };
    int ret;

    ret = iwl_trans_pcie_dyn_txq_alloc_dma(trans, &txq, size, timeout);
    if (ret) { return ret; }

    cmd.tfdq_addr = cpu_to_le64(txq->dma_addr);
    cmd.byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma);
    cmd.cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(size));

    ret = iwl_trans_send_cmd(trans, &hcmd);
    if (ret) { goto error; }

    return iwl_trans_pcie_txq_alloc_response(trans, txq, &hcmd);

error:
    iwl_pcie_gen2_txq_free_memory(trans, txq);
    return ret;
#endif  // NEEDS_PORTING
  IWL_ERR(trans, "%s needs porting\n", __FUNCTION__);
  return -1;
}

void iwl_trans_pcie_dyn_txq_free(struct iwl_trans* trans, int queue) {
#if 0   // NEEDS_PORTING
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

    /*
     * 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(queue, trans_pcie->queue_used)) {
        WARN_ONCE(test_bit(STATUS_DEVICE_ENABLED, &trans->status), "queue %d not used", queue);
        return;
    }

    iwl_pcie_gen2_txq_unmap(trans, queue);

    IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", queue);
#endif  // NEEDS_PORTING
  IWL_ERR(trans, "%s needs porting\n", __FUNCTION__);
}

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

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

    /* Free all TX queues */
    for (i = 0; i < ARRAY_SIZE(trans_pcie->txq); i++) {
        if (!trans_pcie->txq[i]) { continue; }

        iwl_pcie_gen2_txq_free(trans, i);
    }
}

int iwl_pcie_gen2_tx_init(struct iwl_trans* trans, int txq_id, int queue_size) {
    struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
    struct iwl_txq* queue;
    int ret;

    /* alloc and init the tx queue */
    if (!trans_pcie->txq[txq_id]) {
        queue = kzalloc(sizeof(*queue), GFP_KERNEL);
        if (!queue) {
            IWL_ERR(trans, "Not enough memory for tx queue\n");
            return -ENOMEM;
        }
        trans_pcie->txq[txq_id] = queue;
        ret = iwl_pcie_txq_alloc(trans, queue, queue_size, true);
        if (ret) {
            IWL_ERR(trans, "Tx %d queue init failed\n", txq_id);
            goto error;
        }
    } else {
        queue = trans_pcie->txq[txq_id];
    }

    ret = iwl_pcie_txq_init(trans, queue, queue_size, (txq_id == trans_pcie->cmd_queue));
    if (ret) {
        IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id);
        goto error;
    }
    trans_pcie->txq[txq_id]->id = txq_id;
    set_bit(txq_id, trans_pcie->queue_used);

    return 0;

error:
    iwl_pcie_gen2_tx_free(trans);
    return ret;
}
#endif  // NEEDS_PORTING
