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

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

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

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

		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.
	 */
	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;
}
