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

#include <linux/netdevice.h>
#include <nss_dp_dev.h>
#include <asm/cacheflush.h>
#include "syn_dma_reg.h"

/*
 * syn_dp_tx_error_cnt()
 *	Set the error counters.
 */
static inline void syn_dp_tx_error_cnt(struct syn_dp_info_tx *tx_info, uint32_t status)
{
	atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_errors);
	(status & DESC_TX_TIMEOUT) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_jabber_timeout_errors) : 0;
	(status & DESC_TX_FRAME_FLUSHED) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_frame_flushed_errors) : 0;
	(status & DESC_TX_LOST_CARRIER) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_loss_of_carrier_errors) : 0;
	(status & DESC_TX_NO_CARRIER) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_no_carrier_errors) : 0;
	(status & DESC_TX_LATE_COLLISION) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_late_collision_errors) : 0;
	(status & DESC_TX_EXC_COLLISIONS) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_excessive_collision_errors) : 0;
	(status & DESC_TX_EXC_DEFERRAL) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_excessive_deferral_errors) : 0;
	(status & DESC_TX_UNDERFLOW) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_underflow_errors) : 0;
	(status & DESC_TX_IPV4_CHK_ERROR) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_ip_header_errors) : 0;
	(status & DESC_TX_PAY_CHK_ERROR) ? atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_ip_payload_errors) : 0;
}

/*
 * syn_dp_tx_clear_buf_entry()
 *	Clear the Tx info after Tx is over.
 */
static inline void syn_dp_tx_clear_buf_entry(struct syn_dp_info_tx *tx_info, uint32_t tx_skb_index)
{
	tx_info->tx_buf_pool[tx_skb_index].len = 0;
	tx_info->tx_buf_pool[tx_skb_index].skb = NULL;
	tx_info->tx_buf_pool[tx_skb_index].shinfo_addr_virt = 0;
}

/*
 * syn_dp_tx_set_desc_sg()
 *	Populate the tx desc structure with the buffer address for SG packets
 */
static inline struct dma_desc_tx *syn_dp_tx_set_desc_sg(struct syn_dp_info_tx *tx_info,
					   uint32_t buffer, unsigned int length, uint32_t status)
{
	uint32_t tx_idx = tx_info->tx_idx;
	struct dma_desc_tx *txdesc = tx_info->tx_desc + tx_idx;

#ifdef SYN_DP_DEBUG
	BUG_ON(atomic_read((atomic_t *)&tx_info->busy_tx_desc_cnt) > SYN_DP_TX_DESC_SIZE);
	BUG_ON(txdesc != (tx_info->tx_desc + tx_idx));
	BUG_ON(!syn_dp_gmac_is_tx_desc_empty(txdesc));
	BUG_ON(syn_dp_gmac_is_tx_desc_owned_by_dma(txdesc));
#endif

	if (likely(length <= SYN_DP_MAX_DESC_BUFF_LEN)) {
		txdesc->length  = ((length << DESC_SIZE1_SHIFT) & DESC_SIZE1_MASK);
		txdesc->buffer2 = 0;
	} else {
		txdesc->length  = (SYN_DP_MAX_DESC_BUFF_LEN << DESC_SIZE1_SHIFT) & DESC_SIZE1_MASK;
		txdesc->length |= ((length - SYN_DP_MAX_DESC_BUFF_LEN) << DESC_SIZE2_SHIFT) & DESC_SIZE2_MASK;
		txdesc->buffer2 = buffer + SYN_DP_MAX_DESC_BUFF_LEN;
	}

	txdesc->buffer1 = buffer;

	txdesc->status = (status | ((tx_idx == (SYN_DP_TX_DESC_SIZE - 1)) ? DESC_TX_DESC_END_OF_RING : 0));

	tx_info->tx_idx = syn_dp_tx_inc_index(tx_idx, 1);
	return txdesc;
}

/*
 * syn_dp_tx_process_nr_frags()
 *	Process nr frags for the SG packets
 */
static inline struct dma_desc_tx *syn_dp_tx_process_nr_frags(struct syn_dp_info_tx *tx_info,
				struct sk_buff *skb, uint32_t *total_length, uint32_t nr_frags)
{
	struct dma_desc_tx *tx_desc;
	dma_addr_t dma_addr;
	unsigned int length, i = 0;

	do {
		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i++];
		void *frag_addr = skb_frag_address(frag);
		length = skb_frag_size(frag);

#ifdef SYN_DP_DEBUG
		BUG_ON(!length);
#endif

		dma_addr = (dma_addr_t)virt_to_phys(frag_addr);

		dmac_clean_range_no_dsb(frag_addr, frag_addr + length);

		*total_length += length;
		tx_desc = syn_dp_tx_set_desc_sg(tx_info, dma_addr, length, DESC_OWN_BY_DMA);
	} while ( i < nr_frags);

	return tx_desc;
}

/*
 * syn_dp_tx_nr_frags()
 *	TX routine for Synopsys GMAC SG packets with nr frags
 */
int syn_dp_tx_nr_frags(struct syn_dp_info_tx *tx_info, struct sk_buff *skb)
{
	dma_addr_t dma_addr;
	unsigned int length = skb_headlen(skb);
	struct dma_desc_tx *first_desc, *tx_desc;
	unsigned int desc_needed = 0, total_len = 0;
	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
	uint32_t last_idx;

#ifdef SYN_DP_DEBUG
	BUG_ON(nr_frags > MAX_SKB_FRAGS);
	BUG_ON(!length);
#endif

	/*
	 * Total descriptor needed will be sum of number of nr_frags and head skb.
	 */
	desc_needed = 1 + nr_frags;

	/*
	 * If we don't have enough tx descriptor for this pkt, return busy.
	 */
	if (unlikely((SYN_DP_TX_DESC_SIZE - atomic_read((atomic_t *)&tx_info->busy_tx_desc_cnt)) < desc_needed)) {
		atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_desc_not_avail);
		netdev_dbg(tx_info->netdev, "Not enough descriptors available %d", desc_needed);
		return NETDEV_TX_BUSY;
	}

	/*
	 * Flush the dma for non-paged skb data
	 */
	dma_addr = (dma_addr_t)virt_to_phys(skb->data);
	dmac_clean_range_no_dsb((void *)skb->data, (void *)(skb->data + length));

	total_len = length;

	/*
	 * Fill the non paged data (skb->data) in the first descriptor.
	 * We defer setting the desc_own_by_dma for first fragment until
	 * all the descriptors for this frame are ready.
	 */
	first_desc = syn_dp_tx_set_desc_sg(tx_info, dma_addr, length, DESC_TX_FIRST);

	/*
	 * Fill other fragments which are part of nr_frags in the remaining descriptors
	 * and returns the last descriptor.
	 */
	tx_desc = syn_dp_tx_process_nr_frags(tx_info, skb, &total_len, nr_frags);

	/*
	 * Save the tx index of the last descriptor of the segment
	 */
	last_idx = ((tx_info->tx_idx - 1) & SYN_DP_TX_DESC_MAX_INDEX);


	/*
	 * Fill the buffer pool in the last segment of the fragment only
	 * instead of filling in all the descriptors for the fragments
	 */
	tx_info->tx_buf_pool[last_idx].skb = skb;
	tx_info->tx_buf_pool[last_idx].len = total_len;
	tx_info->tx_buf_pool[last_idx].shinfo_addr_virt = (size_t)skb->end;

	/*
	 * For the last fragment, Enable the interrupt and set LS bit
	 */
	tx_desc->status |= (DESC_TX_LAST | DESC_TX_INT_ENABLE);

	/*
	 * Ensure all write completed before setting own by dma bit so when gmac
	 * HW takeover this descriptor, all the fields are filled correctly
	 */
	wmb();

	/*
	 * We've now written all of the descriptors in our scatter-gather list
	 * and need to write the "OWN" bit of the first one to mark the chain
	 * as available to the DMA engine. Also, add checksum calculation bit
	 * for the first descriptor if needed
	 */
	first_desc->status |= (DESC_OWN_BY_DMA | ((skb->ip_summed == CHECKSUM_PARTIAL) ? DESC_TX_CIS_TCP_PSEUDO_CS : 0));

	atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_nr_frags_pkts);
	atomic_add(desc_needed, (atomic_t *)&tx_info->busy_tx_desc_cnt);
	syn_resume_dma_tx(tx_info->mac_base);

	if (unlikely((SYN_DP_TX_DESC_SIZE - atomic_read((atomic_t *)&tx_info->busy_tx_desc_cnt)) < tx_desc_threshold_size)) {
		netif_stop_queue(tx_info->netdev);
	}

	return 0;
}

/*
 * syn_dp_tx_frag_list()
 *	TX routine for Synopsys GMAC SG packets with frag lists
 */
int syn_dp_tx_frag_list(struct syn_dp_info_tx *tx_info, struct sk_buff *skb)
{
	dma_addr_t dma_addr;
	struct sk_buff *iter_skb;
	struct dma_desc_tx *first_desc, *tx_desc;
	unsigned int length = skb_headlen(skb);
	unsigned int desc_needed = 1, total_len = 0;
	unsigned int nr_frags = skb_shinfo(skb)->nr_frags, fraglist_nr_frags = 0;
	uint32_t last_idx;

	/*
	 * When skb is fragmented, count the number of descriptors needed
	 */
	if (unlikely(nr_frags)) {
#ifdef SYN_DP_DEBUG
		BUG_ON(nr_frags > MAX_SKB_FRAGS);
		BUG_ON(!length);
#endif
		desc_needed += nr_frags;
	}

	/*
	 * Walk through fraglist skbs, also making note of nr_frags
	 */
	skb_walk_frags(skb, iter_skb) {
		fraglist_nr_frags = skb_shinfo(iter_skb)->nr_frags;

#ifdef SYN_DP_DEBUG
		/* It is unlikely below check hits, BUG_ON */
		BUG_ON(fraglist_nr_frags > MAX_SKB_FRAGS);
#endif
		/* One descriptor for skb->data and more for nr_frags */
		desc_needed +=  (1 + fraglist_nr_frags);
	}

	/*
	 * If we don't have enough tx descriptor for this pkt, return busy.
	 */
	if (unlikely((SYN_DP_TX_DESC_SIZE - atomic_read((atomic_t *)&tx_info->busy_tx_desc_cnt)) < desc_needed)) {
		atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_desc_not_avail);
		netdev_dbg(tx_info->netdev, "Not enough descriptors available %d", desc_needed);
		return NETDEV_TX_BUSY;
	}

	dma_addr = (dma_addr_t)virt_to_phys(skb->data);

	/*
	 * Flush the data area of the head skb
	 */
	dmac_clean_range_no_dsb((void *)skb->data, (void *)(skb->data + length));

	total_len = length;

	/*
	 * Fill the first skb of the frag list chain in the first descriptor
	 * We defer setting the desc_own_by_dma bit for first fragment until
	 * all the descriptors for this frame are ready.
	 */
	first_desc = syn_dp_tx_set_desc_sg(tx_info, dma_addr, length, DESC_TX_FIRST);

	/*
	 * Fill other fragments which are part of nr_frags in the remaining descriptors
	 * and returns the last descriptor.
	 */
	if (unlikely(nr_frags)) {
		tx_desc = syn_dp_tx_process_nr_frags(tx_info, skb, &total_len, nr_frags);
	}

	/*
	 * Walk through fraglist skbs, also making note of nr_frags and filling it in descriptors
	 */
	skb_walk_frags(skb, iter_skb) {
		length = skb_headlen(iter_skb);

#ifdef SYN_DP_DEBUG
		BUG_ON(!length);
#endif

		dma_addr = (dma_addr_t)virt_to_phys(iter_skb->data);

		dmac_clean_range_no_dsb((void *)iter_skb->data, (void *)(iter_skb->data + length));

		total_len += length;

		/*
		 * Fill the non paged data skb->data.
		 */
		tx_desc = syn_dp_tx_set_desc_sg(tx_info, dma_addr, length, DESC_OWN_BY_DMA);

		/*
		 * Check if nr_frags is available for the skb. If so, fill the
		 * fragments in the descriptors else, continue
		 */
		fraglist_nr_frags = skb_shinfo(iter_skb)->nr_frags;

		/*
		 * Fill other fragments which are part of nr_frags in the remaining descriptors
		 * and returns the last descriptor.
		 */
		if (unlikely(fraglist_nr_frags)) {
			tx_desc = syn_dp_tx_process_nr_frags(tx_info, iter_skb, &total_len, fraglist_nr_frags);
		}
	}

	/*
	 * Save the tx index of the last descriptor of the segment
	 */
	last_idx = ((tx_info->tx_idx - 1) & SYN_DP_TX_DESC_MAX_INDEX);


	/*
	 * Fill the buffer pool in the last segment of the fragment only
	 * instead of filling in all the descriptors for the fragments
	 */
	tx_info->tx_buf_pool[last_idx].skb = skb;
	tx_info->tx_buf_pool[last_idx].len = total_len;
	tx_info->tx_buf_pool[last_idx].shinfo_addr_virt = (size_t)skb->end;

	/*
	 * For the last fragment, Enable the interrupt and set LS bit
	 */
	tx_desc->status |= (DESC_TX_LAST | DESC_TX_INT_ENABLE);

	/*
	 * Ensure all write completed before setting own by dma bit so when gmac
	 * HW takeover this descriptor, all the fields are filled correctly
	 */
	wmb();

	/*
	 * We've now written all of the descriptors in our scatter-gather list
	 * and need to write the "OWN" bit of the first one to mark the chain
	 * as available to the DMA engine. Also, add checksum calculation
	 * bit in the first descriptor if needed.
	 */
	first_desc->status |= (DESC_OWN_BY_DMA | ((skb->ip_summed == CHECKSUM_PARTIAL) ? DESC_TX_CIS_TCP_PSEUDO_CS : 0));

	atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_fraglist_pkts);
	atomic_add(desc_needed, (atomic_t *)&tx_info->busy_tx_desc_cnt);
	syn_resume_dma_tx(tx_info->mac_base);

	if (unlikely((SYN_DP_TX_DESC_SIZE - atomic_read((atomic_t *)&tx_info->busy_tx_desc_cnt)) < tx_desc_threshold_size)) {
		netif_stop_queue(tx_info->netdev);
	}

	return 0;
}

/*
 * syn_dp_tx_set_desc()
 *	Populate the tx desc structure with the buffer address.
 */
static inline void syn_dp_tx_set_desc(struct syn_dp_info_tx *tx_info,
					   uint32_t buffer, struct sk_buff *skb, uint32_t offload_needed,
					   uint32_t status)
{
	uint32_t tx_idx = tx_info->tx_idx;
	struct dma_desc_tx *txdesc = tx_info->tx_desc + tx_idx;
	unsigned int length = skb->len;

#ifdef SYN_DP_DEBUG
	BUG_ON(atomic_read((atomic_t *)&tx_info->busy_tx_desc_cnt) > SYN_DP_TX_DESC_SIZE);
	BUG_ON(txdesc != (tx_info->tx_desc + tx_idx));
	BUG_ON(!syn_dp_gmac_is_tx_desc_empty(txdesc));
	BUG_ON(syn_dp_gmac_is_tx_desc_owned_by_dma(txdesc));
#endif

	if (likely(length <= SYN_DP_MAX_DESC_BUFF_LEN)) {
		txdesc->length = ((length << DESC_SIZE1_SHIFT) & DESC_SIZE1_MASK);
		txdesc->buffer2 = 0;
	} else {
		txdesc->length = (SYN_DP_MAX_DESC_BUFF_LEN << DESC_SIZE1_SHIFT) & DESC_SIZE1_MASK;
		txdesc->length |= ((length - SYN_DP_MAX_DESC_BUFF_LEN) << DESC_SIZE2_SHIFT) & DESC_SIZE2_MASK;
		txdesc->buffer2 = buffer + SYN_DP_MAX_DESC_BUFF_LEN;
	}

	txdesc->buffer1 = buffer;

	tx_info->tx_buf_pool[tx_idx].skb = skb;
	tx_info->tx_buf_pool[tx_idx].len = length;
	tx_info->tx_buf_pool[tx_idx].shinfo_addr_virt = (size_t)skb->end;

	/*
	 * Ensure all write completed before setting own by dma bit so when gmac
	 * HW takeover this descriptor, all the fields are filled correctly
	 */
	wmb();

	txdesc->status = (status | ((offload_needed) ? DESC_TX_CIS_TCP_PSEUDO_CS : 0) | ((tx_idx == (SYN_DP_TX_DESC_SIZE - 1)) ? DESC_TX_DESC_END_OF_RING : 0));

	tx_info->tx_idx = syn_dp_tx_inc_index(tx_idx, 1);
}

void syn_dp_schedule_free_tx_skb(call_single_data_t *csd)
{
	smp_call_function_single_async(tx_completion_load_balance_cpu, csd);
}

/*
 * syn_dp_tx_complete()
 *	Xmit complete, clear descriptor and free the skb
 */
int syn_dp_tx_complete(struct syn_dp_info_tx *tx_info, int budget)
{
	int busy;
	uint32_t status;
	struct dma_desc_tx *desc = NULL;
	struct sk_buff *skb;
	uint32_t tx_skb_index, len;
	uint32_t tx_packets = 0, total_len = 0;
	uint32_t count = 0;
	uint32_t free_idx;
	struct syn_dp_tx_buf *tx_buf;
	struct netdev_queue *nq;

	busy = atomic_read((atomic_t *)&tx_info->busy_tx_desc_cnt);

	if (unlikely(!busy)) {

		/*
		 * No descriptors are held by GMAC DMA, we are done
		 */
		netdev_dbg(tx_info->netdev, "No descriptors held by DMA");
		return 0;
	}

	if (likely(busy > budget)) {
		busy = budget;
	}

	tx_skb_index = syn_dp_tx_comp_index_get(tx_info);
	do {
		desc = syn_dp_tx_comp_desc_get(tx_info);
		status = desc->status;
		if (unlikely(syn_dp_gmac_is_tx_desc_owned_by_dma(status))) {

			/*
			 * Descriptor still held by gmac dma, so we are done.
			 */
			break;
		}


		if (likely(status & DESC_TX_LAST)) {
			tx_skb_index = syn_dp_tx_comp_index_get(tx_info);
			tx_buf = &tx_info->tx_buf_pool[tx_skb_index];
			skb = tx_info->skb_free_list[count] = tx_buf->skb;
			len = tx_buf->len;

#ifdef SYN_DP_DEBUG
			BUG_ON(!skb);
#endif

			tx_info->shinfo_addr_virt[count++] = tx_buf->shinfo_addr_virt;
			syn_dp_tx_clear_buf_entry(tx_info, tx_skb_index);

			if (likely(!(status & DESC_TX_ERROR))) {

				/*
				 * No error, record tx pkts/bytes and collision.
				 */
				tx_packets++;
				total_len += len;
			}
		}

		if (unlikely(status & DESC_TX_ERROR)) {
			/*
			 * Some error happened, collect error statistics.
			 */
			syn_dp_tx_error_cnt(tx_info, status);

			/*
			 * Enable DMA Tx to overcome the DMA Tx stall caused due to Jabber timeout error
			 */
			(status & DESC_TX_TIMEOUT) ? syn_enable_dma_tx(tx_info->mac_base) : 0;
		}

		tx_info->tx_comp_idx = syn_dp_tx_inc_index(tx_info->tx_comp_idx, 1);

		/*
		 * Busy is used to count the workdone with assigned budget.
		 */
		atomic_dec((atomic_t *)&tx_info->busy_tx_desc_cnt);
	} while (--busy);

	/*
	 * Prefetching the shinfo area before releasing to skb recycler gives benefit
	 * in performance.
	 * All the completed skb's shinfo are prefetched and skb's are freed in batch.
	 */

	if (unlikely(tx_completion_load_balance &&
			count > tx_completion_load_balance_threshold)) {
		unsigned long flags;
		struct list_head skb_list;
		struct sk_buff *skb;

		INIT_LIST_HEAD(&skb_list);
		for (free_idx = 0; free_idx < count; free_idx++) {
			skb = tx_info->skb_free_list[free_idx];
			tx_info->skb_free_list[free_idx] = NULL;
			tx_info->shinfo_addr_virt[free_idx] = 0;
			list_add_tail(&skb->list, &skb_list);
		}
		atomic_add(count, &syn_dp_tx_done_skb_count);
		spin_lock_irqsave(&syn_dp_tx_done_skb_list_lock, flags);
		list_splice_tail_init(&skb_list, &syn_dp_tx_done_skb_list);
		spin_unlock_irqrestore(&syn_dp_tx_done_skb_list_lock, flags);
		syn_dp_schedule_free_tx_skb(&tx_info->csd);
	} else {
		for (free_idx = 0; free_idx < count; free_idx++) {
			if (likely((free_idx + 1) < count)) {
				prefetch((void *)tx_info->shinfo_addr_virt[free_idx+1]);
			}
			dev_kfree_skb_any(tx_info->skb_free_list[free_idx]);
			tx_info->skb_free_list[free_idx] = NULL;
			tx_info->shinfo_addr_virt[free_idx] = 0;
		}
	}

	atomic64_add(tx_packets, (atomic64_t *)&tx_info->tx_stats.tx_packets);
	atomic64_add(total_len, (atomic64_t *)&tx_info->tx_stats.tx_bytes);

	nq = netdev_get_tx_queue(tx_info->netdev, SYN_DP_QUEUE_INDEX);

	/*
	 * Wake up queue if stopped earlier due to lack of descriptors
	 */
	if (unlikely(netif_tx_queue_stopped(nq)) && netif_carrier_ok(tx_info->netdev)) {
		netif_wake_queue(tx_info->netdev);
	}

	return budget - busy;
}

/*
 * syn_dp_tx_sg()
 *	Tx routine for Synopsys GMAC scatter gather packets
 */
int syn_dp_tx_sg(struct syn_dp_info_tx *tx_info, struct sk_buff *skb)
{
	struct net_device *netdev = tx_info->netdev;
	bool has_frag_list;
	unsigned int nr_frags;

	has_frag_list = skb_has_frag_list(skb);
	nr_frags = skb_shinfo(skb)->nr_frags;

	/*
	 * Handle SG for below skb types.
	 * 1. skb has fraglist
	 * 2. skb has fraglist and any of the fragments can have nr_frags
	 */
	if (has_frag_list) {
		return syn_dp_tx_frag_list(tx_info, skb);
	}

	/*
	 * Handle SG for nr_frags
	 */
	if (nr_frags) {
		return syn_dp_tx_nr_frags(tx_info, skb);
	}

	netdev_dbg(netdev, "Not a valid non-linear packet");
	return -1;
}

/*
 * syn_dp_tx()
 *	TX routine for Synopsys GMAC
 */
int syn_dp_tx(struct syn_dp_info_tx *tx_info, struct sk_buff *skb)
{
	struct net_device *netdev = tx_info->netdev;
	dma_addr_t dma_addr;

	/*
	 * Check if it's a Scatter Gather packet
	 */
	if (unlikely(skb_is_nonlinear(skb))) {
		return syn_dp_tx_sg(tx_info, skb);
	}

	/*
	 * Linear skb processing
	 */
	if (unlikely((SYN_DP_TX_DESC_SIZE - atomic_read((atomic_t *)&tx_info->busy_tx_desc_cnt)) < 1)) {
		atomic64_inc((atomic64_t *)&tx_info->tx_stats.tx_desc_not_avail);
		netdev_dbg(netdev, "Not enough descriptors available");
		return NETDEV_TX_BUSY;
	}

	dma_addr = (dma_addr_t)virt_to_phys(skb->data);

	dmac_clean_range_no_dsb((void *)skb->data, (void *)(skb->data + skb->len));

	/*
	 * Queue packet to the GMAC rings
	 */
	syn_dp_tx_set_desc(tx_info, dma_addr, skb, (skb->ip_summed == CHECKSUM_PARTIAL),
			(DESC_TX_LAST | DESC_TX_FIRST | DESC_TX_INT_ENABLE | DESC_OWN_BY_DMA));

	syn_resume_dma_tx(tx_info->mac_base);
	atomic_inc((atomic_t *)&tx_info->busy_tx_desc_cnt);
	return 0;
}

void syn_dp_free_tx_done_skb(void *data)
{
	int max = *(int *)data;
	int count = 0;
	unsigned long flags;
	struct sk_buff *skb, *next, *skb_prefetch = NULL;
	struct list_head work_list;

	INIT_LIST_HEAD(&work_list);
	spin_lock_irqsave(&syn_dp_tx_done_skb_list_lock, flags);
	list_splice_init(&syn_dp_tx_done_skb_list, &work_list);
	spin_unlock_irqrestore(&syn_dp_tx_done_skb_list_lock, flags);

	if (list_empty(&work_list))
		return;

	skb_prefetch = list_first_entry(&work_list, struct sk_buff, list);
	if (skb_prefetch) prefetchw(skb_prefetch);

	list_for_each_entry_safe(skb, next, &work_list, list) {
		prefetch(skb_shinfo(skb));
		skb_prefetch = list_next_entry(skb, list);
		if (skb_prefetch) prefetchw(skb_prefetch);
		count++;
		skb_list_del_init(skb);
		dev_kfree_skb_any(skb);
		if (count >= max)
			break;
	}
	atomic_sub(count, &syn_dp_tx_done_skb_count);
	if (list_empty(&work_list))
		return;

	spin_lock_irqsave(&syn_dp_tx_done_skb_list_lock, flags);
	list_splice_init(&work_list, &syn_dp_tx_done_skb_list);
	spin_unlock_irqrestore(&syn_dp_tx_done_skb_list_lock, flags);
	return;
}
