// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021, MediaTek Inc.
 * Copyright (c) 2021-2022, Intel Corporation.
 *
 * Authors:
 *  Amir Hanania <amir.hanania@intel.com>
 *  Haijun Liu <haijun.liu@mediatek.com>
 *  Eliot Lee <eliot.lee@intel.com>
 *  Moises Veleta <moises.veleta@intel.com>
 *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
 *
 * Contributors:
 *  Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
 *  Sreehari Kancharla <sreehari.kancharla@intel.com>
 */

#include <linux/atomic.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/minmax.h>
#include <linux/netdevice.h>
#include <linux/pm_runtime.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/workqueue.h>

#include "t7xx_dpmaif.h"
#include "t7xx_hif_dpmaif.h"
#include "t7xx_hif_dpmaif_tx.h"
#include "t7xx_pci.h"

#define DPMAIF_SKB_TX_BURST_CNT	5
#define DPMAIF_DRB_LIST_LEN	6144

/* DRB dtype */
#define DES_DTYP_PD		0
#define DES_DTYP_MSG		1

static unsigned int t7xx_dpmaif_update_drb_rd_idx(struct dpmaif_ctrl *dpmaif_ctrl,
						  unsigned int q_num)
{
	struct dpmaif_tx_queue *txq = &dpmaif_ctrl->txq[q_num];
	unsigned int old_sw_rd_idx, new_hw_rd_idx, drb_cnt;
	unsigned long flags;

	if (!txq->que_started)
		return 0;

	old_sw_rd_idx = txq->drb_rd_idx;
	new_hw_rd_idx = t7xx_dpmaif_ul_get_rd_idx(&dpmaif_ctrl->hw_info, q_num);
	if (new_hw_rd_idx >= DPMAIF_DRB_LIST_LEN) {
		dev_err(dpmaif_ctrl->dev, "Out of range read index: %u\n", new_hw_rd_idx);
		return 0;
	}

	if (old_sw_rd_idx <= new_hw_rd_idx)
		drb_cnt = new_hw_rd_idx - old_sw_rd_idx;
	else
		drb_cnt = txq->drb_size_cnt - old_sw_rd_idx + new_hw_rd_idx;

	spin_lock_irqsave(&txq->tx_lock, flags);
	txq->drb_rd_idx = new_hw_rd_idx;
	spin_unlock_irqrestore(&txq->tx_lock, flags);

	return drb_cnt;
}

static unsigned int t7xx_dpmaif_release_tx_buffer(struct dpmaif_ctrl *dpmaif_ctrl,
						  unsigned int q_num, unsigned int release_cnt)
{
	struct dpmaif_tx_queue *txq = &dpmaif_ctrl->txq[q_num];
	struct dpmaif_callbacks *cb = dpmaif_ctrl->callbacks;
	struct dpmaif_drb_skb *cur_drb_skb, *drb_skb_base;
	struct dpmaif_drb *cur_drb, *drb_base;
	unsigned int drb_cnt, i, cur_idx;
	unsigned long flags;

	drb_skb_base = txq->drb_skb_base;
	drb_base = txq->drb_base;

	spin_lock_irqsave(&txq->tx_lock, flags);
	drb_cnt = txq->drb_size_cnt;
	cur_idx = txq->drb_release_rd_idx;
	spin_unlock_irqrestore(&txq->tx_lock, flags);

	for (i = 0; i < release_cnt; i++) {
		cur_drb = drb_base + cur_idx;
		if (FIELD_GET(DRB_HDR_DTYP, le32_to_cpu(cur_drb->header)) == DES_DTYP_PD) {
			cur_drb_skb = drb_skb_base + cur_idx;
			if (!cur_drb_skb->is_msg)
				dma_unmap_single(dpmaif_ctrl->dev, cur_drb_skb->bus_addr,
						 cur_drb_skb->data_len, DMA_TO_DEVICE);

			if (!FIELD_GET(DRB_HDR_CONT, le32_to_cpu(cur_drb->header))) {
				if (!cur_drb_skb->skb) {
					dev_err(dpmaif_ctrl->dev,
						"txq%u: DRB check fail, invalid skb\n", q_num);
					continue;
				}

				dev_kfree_skb_any(cur_drb_skb->skb);
			}

			cur_drb_skb->skb = NULL;
		}

		spin_lock_irqsave(&txq->tx_lock, flags);
		cur_idx = t7xx_ring_buf_get_next_wr_idx(drb_cnt, cur_idx);
		txq->drb_release_rd_idx = cur_idx;
		spin_unlock_irqrestore(&txq->tx_lock, flags);

		if (atomic_inc_return(&txq->tx_budget) > txq->drb_size_cnt / 8)
			cb->state_notify(dpmaif_ctrl->t7xx_dev, DMPAIF_TXQ_STATE_IRQ, txq->index);
	}

	if (FIELD_GET(DRB_HDR_CONT, le32_to_cpu(cur_drb->header)))
		dev_err(dpmaif_ctrl->dev, "txq%u: DRB not marked as the last one\n", q_num);

	return i;
}

static int t7xx_dpmaif_tx_release(struct dpmaif_ctrl *dpmaif_ctrl,
				  unsigned int q_num, unsigned int budget)
{
	struct dpmaif_tx_queue *txq = &dpmaif_ctrl->txq[q_num];
	unsigned int rel_cnt, real_rel_cnt;

	/* Update read index from HW */
	t7xx_dpmaif_update_drb_rd_idx(dpmaif_ctrl, q_num);

	rel_cnt = t7xx_ring_buf_rd_wr_count(txq->drb_size_cnt, txq->drb_release_rd_idx,
					    txq->drb_rd_idx, DPMAIF_READ);

	real_rel_cnt = min_not_zero(budget, rel_cnt);
	if (real_rel_cnt)
		real_rel_cnt = t7xx_dpmaif_release_tx_buffer(dpmaif_ctrl, q_num, real_rel_cnt);

	return real_rel_cnt < rel_cnt ? -EAGAIN : 0;
}

static bool t7xx_dpmaif_drb_ring_not_empty(struct dpmaif_tx_queue *txq)
{
	return !!t7xx_dpmaif_update_drb_rd_idx(txq->dpmaif_ctrl, txq->index);
}

static void t7xx_dpmaif_tx_done(struct work_struct *work)
{
	struct dpmaif_tx_queue *txq = container_of(work, struct dpmaif_tx_queue, dpmaif_tx_work);
	struct dpmaif_ctrl *dpmaif_ctrl = txq->dpmaif_ctrl;
	struct dpmaif_hw_info *hw_info;
	int ret;

	ret = pm_runtime_resume_and_get(dpmaif_ctrl->dev);
	if (ret < 0 && ret != -EACCES)
		return;

	/* The device may be in low power state. Disable sleep if needed */
	t7xx_pci_disable_sleep(dpmaif_ctrl->t7xx_dev);
	if (t7xx_pci_sleep_disable_complete(dpmaif_ctrl->t7xx_dev)) {
		hw_info = &dpmaif_ctrl->hw_info;
		ret = t7xx_dpmaif_tx_release(dpmaif_ctrl, txq->index, txq->drb_size_cnt);
		if (ret == -EAGAIN ||
		    (t7xx_dpmaif_ul_clr_done(hw_info, txq->index) &&
		     t7xx_dpmaif_drb_ring_not_empty(txq))) {
			queue_work(dpmaif_ctrl->txq[txq->index].worker,
				   &dpmaif_ctrl->txq[txq->index].dpmaif_tx_work);
			/* Give the device time to enter the low power state */
			t7xx_dpmaif_clr_ip_busy_sts(hw_info);
		} else {
			t7xx_dpmaif_clr_ip_busy_sts(hw_info);
			t7xx_dpmaif_unmask_ulq_intr(hw_info, txq->index);
		}
	}

	t7xx_pci_enable_sleep(dpmaif_ctrl->t7xx_dev);
	pm_runtime_mark_last_busy(dpmaif_ctrl->dev);
	pm_runtime_put_autosuspend(dpmaif_ctrl->dev);
}

static void t7xx_setup_msg_drb(struct dpmaif_ctrl *dpmaif_ctrl, unsigned int q_num,
			       unsigned int cur_idx, unsigned int pkt_len, unsigned int count_l,
			       unsigned int channel_id)
{
	struct dpmaif_drb *drb_base = dpmaif_ctrl->txq[q_num].drb_base;
	struct dpmaif_drb *drb = drb_base + cur_idx;

	drb->header = cpu_to_le32(FIELD_PREP(DRB_HDR_DTYP, DES_DTYP_MSG) |
				  FIELD_PREP(DRB_HDR_CONT, 1) |
				  FIELD_PREP(DRB_HDR_DATA_LEN, pkt_len));

	drb->msg.msg_hdr = cpu_to_le32(FIELD_PREP(DRB_MSG_COUNT_L, count_l) |
				       FIELD_PREP(DRB_MSG_CHANNEL_ID, channel_id) |
				       FIELD_PREP(DRB_MSG_L4_CHK, 1));
}

static void t7xx_setup_payload_drb(struct dpmaif_ctrl *dpmaif_ctrl, unsigned int q_num,
				   unsigned int cur_idx, dma_addr_t data_addr,
				   unsigned int pkt_size, bool last_one)
{
	struct dpmaif_drb *drb_base = dpmaif_ctrl->txq[q_num].drb_base;
	struct dpmaif_drb *drb = drb_base + cur_idx;
	u32 header;

	header = FIELD_PREP(DRB_HDR_DTYP, DES_DTYP_PD) | FIELD_PREP(DRB_HDR_DATA_LEN, pkt_size);
	if (!last_one)
		header |= FIELD_PREP(DRB_HDR_CONT, 1);

	drb->header = cpu_to_le32(header);
	drb->pd.data_addr_l = cpu_to_le32(lower_32_bits(data_addr));
	drb->pd.data_addr_h = cpu_to_le32(upper_32_bits(data_addr));
}

static void t7xx_record_drb_skb(struct dpmaif_ctrl *dpmaif_ctrl, unsigned int q_num,
				unsigned int cur_idx, struct sk_buff *skb, bool is_msg,
				bool is_frag, bool is_last_one, dma_addr_t bus_addr,
				unsigned int data_len)
{
	struct dpmaif_drb_skb *drb_skb_base = dpmaif_ctrl->txq[q_num].drb_skb_base;
	struct dpmaif_drb_skb *drb_skb = drb_skb_base + cur_idx;

	drb_skb->skb = skb;
	drb_skb->bus_addr = bus_addr;
	drb_skb->data_len = data_len;
	drb_skb->index = cur_idx;
	drb_skb->is_msg = is_msg;
	drb_skb->is_frag = is_frag;
	drb_skb->is_last = is_last_one;
}

static int t7xx_dpmaif_add_skb_to_ring(struct dpmaif_ctrl *dpmaif_ctrl, struct sk_buff *skb)
{
	struct dpmaif_callbacks *cb = dpmaif_ctrl->callbacks;
	unsigned int wr_cnt, send_cnt, payload_cnt;
	unsigned int cur_idx, drb_wr_idx_backup;
	struct skb_shared_info *shinfo;
	struct dpmaif_tx_queue *txq;
	struct t7xx_skb_cb *skb_cb;
	unsigned long flags;

	skb_cb = T7XX_SKB_CB(skb);
	txq = &dpmaif_ctrl->txq[skb_cb->txq_number];
	if (!txq->que_started || dpmaif_ctrl->state != DPMAIF_STATE_PWRON)
		return -ENODEV;

	atomic_set(&txq->tx_processing, 1);
	 /* Ensure tx_processing is changed to 1 before actually begin TX flow */
	smp_mb();

	shinfo = skb_shinfo(skb);
	if (shinfo->frag_list)
		dev_warn_ratelimited(dpmaif_ctrl->dev, "frag_list not supported\n");

	payload_cnt = shinfo->nr_frags + 1;
	/* nr_frags: frag cnt, 1: skb->data, 1: msg DRB */
	send_cnt = payload_cnt + 1;

	spin_lock_irqsave(&txq->tx_lock, flags);
	cur_idx = txq->drb_wr_idx;
	drb_wr_idx_backup = cur_idx;
	txq->drb_wr_idx += send_cnt;
	if (txq->drb_wr_idx >= txq->drb_size_cnt)
		txq->drb_wr_idx -= txq->drb_size_cnt;
	t7xx_setup_msg_drb(dpmaif_ctrl, txq->index, cur_idx, skb->len, 0, skb_cb->netif_idx);
	t7xx_record_drb_skb(dpmaif_ctrl, txq->index, cur_idx, skb, true, 0, 0, 0, 0);
	spin_unlock_irqrestore(&txq->tx_lock, flags);

	for (wr_cnt = 0; wr_cnt < payload_cnt; wr_cnt++) {
		bool is_frag, is_last_one = wr_cnt == payload_cnt - 1;
		unsigned int data_len;
		dma_addr_t bus_addr;
		void *data_addr;

		if (!wr_cnt) {
			data_len = skb_headlen(skb);
			data_addr = skb->data;
			is_frag = false;
		} else {
			skb_frag_t *frag = shinfo->frags + wr_cnt - 1;

			data_len = skb_frag_size(frag);
			data_addr = skb_frag_address(frag);
			is_frag = true;
		}

		bus_addr = dma_map_single(dpmaif_ctrl->dev, data_addr, data_len, DMA_TO_DEVICE);
		if (dma_mapping_error(dpmaif_ctrl->dev, bus_addr))
			goto unmap_buffers;

		cur_idx = t7xx_ring_buf_get_next_wr_idx(txq->drb_size_cnt, cur_idx);

		spin_lock_irqsave(&txq->tx_lock, flags);
		t7xx_setup_payload_drb(dpmaif_ctrl, txq->index, cur_idx, bus_addr, data_len,
				       is_last_one);
		t7xx_record_drb_skb(dpmaif_ctrl, txq->index, cur_idx, skb, false, is_frag,
				    is_last_one, bus_addr, data_len);
		spin_unlock_irqrestore(&txq->tx_lock, flags);
	}

	if (atomic_sub_return(send_cnt, &txq->tx_budget) <= (MAX_SKB_FRAGS + 2))
		cb->state_notify(dpmaif_ctrl->t7xx_dev, DMPAIF_TXQ_STATE_FULL, txq->index);

	atomic_set(&txq->tx_processing, 0);

	return 0;

unmap_buffers:
	while (wr_cnt--) {
		struct dpmaif_drb_skb *drb_skb = txq->drb_skb_base;

		cur_idx = cur_idx ? cur_idx - 1 : txq->drb_size_cnt - 1;
		drb_skb += cur_idx;
		dma_unmap_single(dpmaif_ctrl->dev, drb_skb->bus_addr,
				 drb_skb->data_len, DMA_TO_DEVICE);
	}

	txq->drb_wr_idx = drb_wr_idx_backup;
	atomic_set(&txq->tx_processing, 0);

	return -ENOMEM;
}

static bool t7xx_tx_lists_are_all_empty(const struct dpmaif_ctrl *dpmaif_ctrl)
{
	int i;

	for (i = 0; i < DPMAIF_TXQ_NUM; i++) {
		if (!skb_queue_empty(&dpmaif_ctrl->txq[i].tx_skb_head))
			return false;
	}

	return true;
}

/* Currently, only the default TX queue is used */
static struct dpmaif_tx_queue *t7xx_select_tx_queue(struct dpmaif_ctrl *dpmaif_ctrl)
{
	struct dpmaif_tx_queue *txq;

	txq = &dpmaif_ctrl->txq[DPMAIF_TX_DEFAULT_QUEUE];
	if (!txq->que_started)
		return NULL;

	return txq;
}

static unsigned int t7xx_txq_drb_wr_available(struct dpmaif_tx_queue *txq)
{
	return t7xx_ring_buf_rd_wr_count(txq->drb_size_cnt, txq->drb_release_rd_idx,
					 txq->drb_wr_idx, DPMAIF_WRITE);
}

static unsigned int t7xx_skb_drb_cnt(struct sk_buff *skb)
{
	/* Normal DRB (frags data + skb linear data) + msg DRB */
	return skb_shinfo(skb)->nr_frags + 2;
}

static int t7xx_txq_burst_send_skb(struct dpmaif_tx_queue *txq)
{
	unsigned int drb_remain_cnt, i;
	unsigned int send_drb_cnt;
	int drb_cnt = 0;
	int ret = 0;

	drb_remain_cnt = t7xx_txq_drb_wr_available(txq);

	for (i = 0; i < DPMAIF_SKB_TX_BURST_CNT; i++) {
		struct sk_buff *skb;

		skb = skb_peek(&txq->tx_skb_head);
		if (!skb)
			break;

		send_drb_cnt = t7xx_skb_drb_cnt(skb);
		if (drb_remain_cnt < send_drb_cnt) {
			drb_remain_cnt = t7xx_txq_drb_wr_available(txq);
			continue;
		}

		drb_remain_cnt -= send_drb_cnt;

		ret = t7xx_dpmaif_add_skb_to_ring(txq->dpmaif_ctrl, skb);
		if (ret < 0) {
			dev_err(txq->dpmaif_ctrl->dev,
				"Failed to add skb to device's ring: %d\n", ret);
			break;
		}

		drb_cnt += send_drb_cnt;
		skb_unlink(skb, &txq->tx_skb_head);
	}

	if (drb_cnt > 0)
		return drb_cnt;

	return ret;
}

static void t7xx_do_tx_hw_push(struct dpmaif_ctrl *dpmaif_ctrl)
{
	bool wait_disable_sleep = true;

	do {
		struct dpmaif_tx_queue *txq;
		int drb_send_cnt;

		txq = t7xx_select_tx_queue(dpmaif_ctrl);
		if (!txq)
			return;

		drb_send_cnt = t7xx_txq_burst_send_skb(txq);
		if (drb_send_cnt <= 0) {
			usleep_range(10, 20);
			cond_resched();
			continue;
		}

		/* Wait for the PCIe resource to unlock */
		if (wait_disable_sleep) {
			if (!t7xx_pci_sleep_disable_complete(dpmaif_ctrl->t7xx_dev))
				return;

			wait_disable_sleep = false;
		}

		t7xx_dpmaif_ul_update_hw_drb_cnt(&dpmaif_ctrl->hw_info, txq->index,
						 drb_send_cnt * DPMAIF_UL_DRB_SIZE_WORD);

		cond_resched();
	} while (!t7xx_tx_lists_are_all_empty(dpmaif_ctrl) && !kthread_should_stop() &&
		 (dpmaif_ctrl->state == DPMAIF_STATE_PWRON));
}

static int t7xx_dpmaif_tx_hw_push_thread(void *arg)
{
	struct dpmaif_ctrl *dpmaif_ctrl = arg;
	int ret;

	while (!kthread_should_stop()) {
		if (t7xx_tx_lists_are_all_empty(dpmaif_ctrl) ||
		    dpmaif_ctrl->state != DPMAIF_STATE_PWRON) {
			if (wait_event_interruptible(dpmaif_ctrl->tx_wq,
						     (!t7xx_tx_lists_are_all_empty(dpmaif_ctrl) &&
						     dpmaif_ctrl->state == DPMAIF_STATE_PWRON) ||
						     kthread_should_stop()))
				continue;

			if (kthread_should_stop())
				break;
		}

		ret = pm_runtime_resume_and_get(dpmaif_ctrl->dev);
		if (ret < 0 && ret != -EACCES)
			return ret;

		t7xx_pci_disable_sleep(dpmaif_ctrl->t7xx_dev);
		t7xx_do_tx_hw_push(dpmaif_ctrl);
		t7xx_pci_enable_sleep(dpmaif_ctrl->t7xx_dev);
		pm_runtime_mark_last_busy(dpmaif_ctrl->dev);
		pm_runtime_put_autosuspend(dpmaif_ctrl->dev);
	}

	return 0;
}

int t7xx_dpmaif_tx_thread_init(struct dpmaif_ctrl *dpmaif_ctrl)
{
	init_waitqueue_head(&dpmaif_ctrl->tx_wq);
	dpmaif_ctrl->tx_thread = kthread_run(t7xx_dpmaif_tx_hw_push_thread,
					     dpmaif_ctrl, "dpmaif_tx_hw_push");
	return PTR_ERR_OR_ZERO(dpmaif_ctrl->tx_thread);
}

void t7xx_dpmaif_tx_thread_rel(struct dpmaif_ctrl *dpmaif_ctrl)
{
	if (dpmaif_ctrl->tx_thread)
		kthread_stop(dpmaif_ctrl->tx_thread);
}

/**
 * t7xx_dpmaif_tx_send_skb() - Add skb to the transmit queue.
 * @dpmaif_ctrl: Pointer to struct dpmaif_ctrl.
 * @txq_number: Queue number to xmit on.
 * @skb: Pointer to the skb to transmit.
 *
 * Add the skb to the queue of the skbs to be transmit.
 * Wake up the thread that push the skbs from the queue to the HW.
 *
 * Return:
 * * 0		- Success.
 * * -EBUSY	- Tx budget exhausted.
 *		  In normal circumstances t7xx_dpmaif_add_skb_to_ring() must report the txq full
 *		  state to prevent this error condition.
 */
int t7xx_dpmaif_tx_send_skb(struct dpmaif_ctrl *dpmaif_ctrl, unsigned int txq_number,
			    struct sk_buff *skb)
{
	struct dpmaif_tx_queue *txq = &dpmaif_ctrl->txq[txq_number];
	struct dpmaif_callbacks *cb = dpmaif_ctrl->callbacks;
	struct t7xx_skb_cb *skb_cb;

	if (atomic_read(&txq->tx_budget) <= t7xx_skb_drb_cnt(skb)) {
		cb->state_notify(dpmaif_ctrl->t7xx_dev, DMPAIF_TXQ_STATE_FULL, txq_number);
		return -EBUSY;
	}

	skb_cb = T7XX_SKB_CB(skb);
	skb_cb->txq_number = txq_number;
	skb_queue_tail(&txq->tx_skb_head, skb);
	wake_up(&dpmaif_ctrl->tx_wq);

	return 0;
}

void t7xx_dpmaif_irq_tx_done(struct dpmaif_ctrl *dpmaif_ctrl, unsigned int que_mask)
{
	int i;

	for (i = 0; i < DPMAIF_TXQ_NUM; i++) {
		if (que_mask & BIT(i))
			queue_work(dpmaif_ctrl->txq[i].worker, &dpmaif_ctrl->txq[i].dpmaif_tx_work);
	}
}

static int t7xx_dpmaif_tx_drb_buf_init(struct dpmaif_tx_queue *txq)
{
	size_t brb_skb_size, brb_pd_size;

	brb_pd_size = DPMAIF_DRB_LIST_LEN * sizeof(struct dpmaif_drb);
	brb_skb_size = DPMAIF_DRB_LIST_LEN * sizeof(struct dpmaif_drb_skb);

	txq->drb_size_cnt = DPMAIF_DRB_LIST_LEN;

	/* For HW && AP SW */
	txq->drb_base = dma_alloc_coherent(txq->dpmaif_ctrl->dev, brb_pd_size,
					   &txq->drb_bus_addr, GFP_KERNEL | __GFP_ZERO);
	if (!txq->drb_base)
		return -ENOMEM;

	/* For AP SW to record the skb information */
	txq->drb_skb_base = devm_kzalloc(txq->dpmaif_ctrl->dev, brb_skb_size, GFP_KERNEL);
	if (!txq->drb_skb_base) {
		dma_free_coherent(txq->dpmaif_ctrl->dev, brb_pd_size,
				  txq->drb_base, txq->drb_bus_addr);
		return -ENOMEM;
	}

	return 0;
}

static void t7xx_dpmaif_tx_free_drb_skb(struct dpmaif_tx_queue *txq)
{
	struct dpmaif_drb_skb *drb_skb, *drb_skb_base = txq->drb_skb_base;
	unsigned int i;

	if (!drb_skb_base)
		return;

	for (i = 0; i < txq->drb_size_cnt; i++) {
		drb_skb = drb_skb_base + i;
		if (!drb_skb->skb)
			continue;

		if (!drb_skb->is_msg)
			dma_unmap_single(txq->dpmaif_ctrl->dev, drb_skb->bus_addr,
					 drb_skb->data_len, DMA_TO_DEVICE);

		if (drb_skb->is_last) {
			dev_kfree_skb(drb_skb->skb);
			drb_skb->skb = NULL;
		}
	}
}

static void t7xx_dpmaif_tx_drb_buf_rel(struct dpmaif_tx_queue *txq)
{
	if (txq->drb_base)
		dma_free_coherent(txq->dpmaif_ctrl->dev,
				  txq->drb_size_cnt * sizeof(struct dpmaif_drb),
				  txq->drb_base, txq->drb_bus_addr);

	t7xx_dpmaif_tx_free_drb_skb(txq);
}

/**
 * t7xx_dpmaif_txq_init() - Initialize TX queue.
 * @txq: Pointer to struct dpmaif_tx_queue.
 *
 * Initialize the TX queue data structure and allocate memory for it to use.
 *
 * Return:
 * * 0		- Success.
 * * -ERROR	- Error code from failure sub-initializations.
 */
int t7xx_dpmaif_txq_init(struct dpmaif_tx_queue *txq)
{
	int ret;

	skb_queue_head_init(&txq->tx_skb_head);
	init_waitqueue_head(&txq->req_wq);
	atomic_set(&txq->tx_budget, DPMAIF_DRB_LIST_LEN);

	ret = t7xx_dpmaif_tx_drb_buf_init(txq);
	if (ret) {
		dev_err(txq->dpmaif_ctrl->dev, "Failed to initialize DRB buffers: %d\n", ret);
		return ret;
	}

	txq->worker = alloc_ordered_workqueue("md_dpmaif_tx%d_worker",
				WQ_MEM_RECLAIM | (txq->index ? 0 : WQ_HIGHPRI),
				txq->index);
	if (!txq->worker)
		return -ENOMEM;

	INIT_WORK(&txq->dpmaif_tx_work, t7xx_dpmaif_tx_done);
	spin_lock_init(&txq->tx_lock);

	return 0;
}

void t7xx_dpmaif_txq_free(struct dpmaif_tx_queue *txq)
{
	if (txq->worker)
		destroy_workqueue(txq->worker);

	skb_queue_purge(&txq->tx_skb_head);
	t7xx_dpmaif_tx_drb_buf_rel(txq);
}

void t7xx_dpmaif_tx_stop(struct dpmaif_ctrl *dpmaif_ctrl)
{
	int i;

	for (i = 0; i < DPMAIF_TXQ_NUM; i++) {
		struct dpmaif_tx_queue *txq;
		int count = 0;

		txq = &dpmaif_ctrl->txq[i];
		txq->que_started = false;
		/* Make sure TXQ is disabled */
		smp_mb();

		/* Wait for active Tx to be done */
		while (atomic_read(&txq->tx_processing)) {
			if (++count >= DPMAIF_MAX_CHECK_COUNT) {
				dev_err(dpmaif_ctrl->dev, "TX queue stop failed\n");
				break;
			}
		}
	}
}

static void t7xx_dpmaif_txq_flush_rel(struct dpmaif_tx_queue *txq)
{
	txq->que_started = false;

	cancel_work_sync(&txq->dpmaif_tx_work);
	flush_work(&txq->dpmaif_tx_work);
	t7xx_dpmaif_tx_free_drb_skb(txq);

	txq->drb_rd_idx = 0;
	txq->drb_wr_idx = 0;
	txq->drb_release_rd_idx = 0;
}

void t7xx_dpmaif_tx_clear(struct dpmaif_ctrl *dpmaif_ctrl)
{
	int i;

	for (i = 0; i < DPMAIF_TXQ_NUM; i++)
		t7xx_dpmaif_txq_flush_rel(&dpmaif_ctrl->txq[i]);
}
