/* Copyright  2016 MediaTek Inc.
 * Author: Nelson Chang <nelson.chang@mediatek.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#include "raether.h"

int fe_pdma_wait_dma_idle(void)
{
	unsigned int reg_val;
	unsigned int loop_cnt = 0;

	while (1) {
		if (loop_cnt++ > 1000)
			break;
		reg_val = sys_reg_read(PDMA_GLO_CFG);
		if ((reg_val & RX_DMA_BUSY)) {
			pr_warn("\n  RX_DMA_BUSY !!! ");
			continue;
		}
		if ((reg_val & TX_DMA_BUSY)) {
			pr_warn("\n  TX_DMA_BUSY !!! ");
			continue;
		}
		return 0;
	}

	return -1;
}

int fe_pdma_rx_dma_init(struct net_device *dev)
{
	int i;
	unsigned int skb_size;
	struct END_DEVICE *ei_local = netdev_priv(dev);
	dma_addr_t dma_addr;

	skb_size = SKB_DATA_ALIGN(MAX_RX_LENGTH + NET_IP_ALIGN + NET_SKB_PAD) +
		   SKB_DATA_ALIGN(sizeof(struct skb_shared_info));

	/* Initial RX Ring 0 */
	ei_local->rx_ring[0] = dma_alloc_coherent(dev->dev.parent,
						num_rx_desc *
						sizeof(struct PDMA_rxdesc),
						&ei_local->phy_rx_ring[0],
						GFP_ATOMIC | __GFP_ZERO);
	pr_debug("\nphy_rx_ring[0] = 0x%08x, rx_ring[0] = 0x%p\n",
		 (unsigned int)ei_local->phy_rx_ring[0],
		 (void *)ei_local->rx_ring[0]);

	for (i = 0; i < num_rx_desc; i++) {
		ei_local->netrx_skb_data[0][i] =
			raeth_alloc_skb_data(skb_size, GFP_KERNEL);
		if (!ei_local->netrx_skb_data[0][i]) {
			pr_err("rx skbuff buffer allocation failed!");
			goto no_rx_mem;
		}

		memset(&ei_local->rx_ring[0][i], 0, sizeof(struct PDMA_rxdesc));
		ei_local->rx_ring[0][i].rxd_info2.DDONE_bit = 0;
		ei_local->rx_ring[0][i].rxd_info2.LS0 = 0;
		ei_local->rx_ring[0][i].rxd_info2.PLEN0 = MAX_RX_LENGTH;
		dma_addr = dma_map_single(dev->dev.parent,
					  ei_local->netrx_skb_data[0][i] +
					  NET_SKB_PAD,
					  MAX_RX_LENGTH,
					  DMA_FROM_DEVICE);
		ei_local->rx_ring[0][i].rxd_info1.PDP0 = dma_addr;
		if (unlikely
		    (dma_mapping_error
		     (dev->dev.parent,
		      ei_local->rx_ring[0][i].rxd_info1.PDP0))) {
			pr_err("[%s]dma_map_single() failed...\n", __func__);
			goto no_rx_mem;
		}
	}

	/* Tell the adapter where the RX rings are located. */
	sys_reg_write(RX_BASE_PTR0, phys_to_bus((u32)ei_local->phy_rx_ring[0]));
	sys_reg_write(RX_MAX_CNT0, cpu_to_le32((u32)num_rx_desc));
	sys_reg_write(RX_CALC_IDX0, cpu_to_le32((u32)(num_rx_desc - 1)));

	sys_reg_write(PDMA_RST_CFG, PST_DRX_IDX0);

	return 0;

no_rx_mem:
	return -ENOMEM;
}

int fe_pdma_tx_dma_init(struct net_device *dev)
{
	int i;
	struct END_DEVICE *ei_local = netdev_priv(dev);

	for (i = 0; i < num_tx_desc; i++)
		ei_local->skb_free[i] = 0;

	ei_local->tx_ring_full = 0;
	ei_local->free_idx = 0;
	ei_local->tx_ring0 =
	    dma_alloc_coherent(dev->dev.parent,
			       num_tx_desc * sizeof(struct PDMA_txdesc),
			       &ei_local->phy_tx_ring0,
			       GFP_ATOMIC | __GFP_ZERO);
	pr_debug("\nphy_tx_ring = 0x%08x, tx_ring = 0x%p\n",
		 (unsigned int)ei_local->phy_tx_ring0,
		 (void *)ei_local->tx_ring0);

	for (i = 0; i < num_tx_desc; i++) {
		memset(&ei_local->tx_ring0[i], 0, sizeof(struct PDMA_txdesc));
		ei_local->tx_ring0[i].txd_info2.LS0_bit = 1;
		ei_local->tx_ring0[i].txd_info2.DDONE_bit = 1;
	}

	/* Tell the adapter where the TX rings are located. */
	sys_reg_write(TX_BASE_PTR0, phys_to_bus((u32)ei_local->phy_tx_ring0));
	sys_reg_write(TX_MAX_CNT0, cpu_to_le32((u32)num_tx_desc));
	sys_reg_write(TX_CTX_IDX0, 0);
#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR
	ei_local->tx_cpu_owner_idx0 = 0;
#endif
	sys_reg_write(PDMA_RST_CFG, PST_DTX_IDX0);

	return 0;
}

void fe_pdma_rx_dma_deinit(struct net_device *dev)
{
	struct END_DEVICE *ei_local = netdev_priv(dev);
	int i;

	/* free RX Ring */
	dma_free_coherent(dev->dev.parent,
			  num_rx_desc * sizeof(struct PDMA_rxdesc),
			  ei_local->rx_ring[0], ei_local->phy_rx_ring[0]);

	/* free RX data */
	for (i = 0; i < num_rx_desc; i++) {
		raeth_free_skb_data(ei_local->netrx_skb_data[0][i]);
		ei_local->netrx_skb_data[0][i] = NULL;
	}
}

void fe_pdma_tx_dma_deinit(struct net_device *dev)
{
	struct END_DEVICE *ei_local = netdev_priv(dev);
	int i;

	/* free TX Ring */
	if (ei_local->tx_ring0)
		dma_free_coherent(dev->dev.parent,
				  num_tx_desc *
				  sizeof(struct PDMA_txdesc),
				  ei_local->tx_ring0,
				  ei_local->phy_tx_ring0);

	/* free TX data */
	for (i = 0; i < num_tx_desc; i++) {
		if ((ei_local->skb_free[i] != 0) &&
		    (ei_local->skb_free[i] != (struct sk_buff *)0xFFFFFFFF))
			dev_kfree_skb_any(ei_local->skb_free[i]);
	}
}

void set_fe_pdma_glo_cfg(void)
{
	unsigned int dma_glo_cfg = 0;

	dma_glo_cfg =
	    (TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN | PDMA_BT_SIZE_16DWORDS |
	     MULTI_EN | ADMA_RX_BT_SIZE_32DWORDS);
//	dma_glo_cfg |= (RX_2B_OFFSET);

	sys_reg_write(PDMA_GLO_CFG, dma_glo_cfg);
}

/* @brief cal txd number for a page
 *
 *  @parm size
 *
 *  @return frag_txd_num
 */
static inline unsigned int pdma_cal_frag_txd_num(unsigned int size)
{
	unsigned int frag_txd_num = 0;

	if (size == 0)
		return 0;
	while (size > 0) {
		if (size > MAX_PTXD_LEN) {
			frag_txd_num++;
			size -= MAX_PTXD_LEN;
		} else {
			frag_txd_num++;
			size = 0;
		}
	}
	return frag_txd_num;
}

int fe_fill_tx_desc(struct net_device *dev,
		    unsigned long *tx_cpu_owner_idx,
		    struct sk_buff *skb,
		    int gmac_no)
{
	struct END_DEVICE *ei_local = netdev_priv(dev);
	struct PDMA_txdesc *tx_ring = &ei_local->tx_ring0[*tx_cpu_owner_idx];
	struct PDMA_TXD_INFO2_T txd_info2_tmp;
	struct PDMA_TXD_INFO4_T txd_info4_tmp;

	tx_ring->txd_info1.SDP0 = virt_to_phys(skb->data);
	txd_info2_tmp.SDL0 = skb->len;
	txd_info4_tmp.FPORT = gmac_no;
	txd_info4_tmp.TSO = 0;

	if (ei_local->features & FE_CSUM_OFFLOAD) {
		if (skb->ip_summed == CHECKSUM_PARTIAL)
			txd_info4_tmp.TUI_CO = 7;
		else
			txd_info4_tmp.TUI_CO = 0;
	}

	if (ei_local->features & FE_HW_VLAN_TX) {
		if (skb_vlan_tag_present(skb))
			txd_info4_tmp.VLAN_TAG =
				0x10000 | skb_vlan_tag_get(skb);
		else
			txd_info4_tmp.VLAN_TAG = 0;
	}
#if defined(CONFIG_RA_HW_NAT) || defined(CONFIG_RA_HW_NAT_MODULE)
	if (IS_MAGIC_TAG_PROTECT_VALID_HEAD(skb)) {
		if (FOE_MAGIC_TAG_HEAD(skb) == FOE_MAGIC_PPE) {
			if (ppe_hook_rx_eth) {
				/* PPE */
				txd_info4_tmp.FPORT = 4;
				FOE_MAGIC_TAG(skb) = 0;
			}
		}
	} else if (IS_MAGIC_TAG_PROTECT_VALID_TAIL(skb)) {
		if (FOE_MAGIC_TAG_TAIL(skb) == FOE_MAGIC_PPE) {
			if (ppe_hook_rx_eth) {
				/* PPE */
				txd_info4_tmp.FPORT = 4;
				FOE_MAGIC_TAG(skb) = 0;
			}
		}
	}
#endif

	txd_info2_tmp.LS0_bit = 1;
	txd_info2_tmp.DDONE_bit = 0;

	tx_ring->txd_info4 = txd_info4_tmp;
	tx_ring->txd_info2 = txd_info2_tmp;

	return 0;
}

static int fe_fill_tx_tso_data(struct END_DEVICE *ei_local,
			       unsigned int frag_offset,
			       unsigned int frag_size,
			       unsigned long *tx_cpu_owner_idx,
			       unsigned int nr_frags,
			       int gmac_no)
{
	struct PSEUDO_ADAPTER *p_ad;
	unsigned int size;
	unsigned int frag_txd_num;
	struct PDMA_txdesc *tx_ring;

	frag_txd_num = pdma_cal_frag_txd_num(frag_size);
	tx_ring = &ei_local->tx_ring0[*tx_cpu_owner_idx];

	while (frag_txd_num > 0) {
		if (frag_size < MAX_PTXD_LEN)
			size = frag_size;
		else
			size = MAX_PTXD_LEN;

		if (ei_local->skb_txd_num % 2 == 0) {
			*tx_cpu_owner_idx =
			    (*tx_cpu_owner_idx + 1) % num_tx_desc;
			tx_ring = &ei_local->tx_ring0[*tx_cpu_owner_idx];

			while (tx_ring->txd_info2.DDONE_bit == 0) {
				if (gmac_no == 2) {
					p_ad =
					    netdev_priv(ei_local->pseudo_dev);
					p_ad->stat.tx_errors++;
				} else {
					ei_local->stat.tx_errors++;
				}
			}
			tx_ring->txd_info1.SDP0 = frag_offset;
			tx_ring->txd_info2.SDL0 = size;
			if (((nr_frags == 0)) && (frag_txd_num == 1))
				tx_ring->txd_info2.LS0_bit = 1;
			else
				tx_ring->txd_info2.LS0_bit = 0;
			tx_ring->txd_info2.DDONE_bit = 0;
			tx_ring->txd_info4.FPORT = gmac_no;
		} else {
			tx_ring->txd_info3.SDP1 = frag_offset;
			tx_ring->txd_info2.SDL1 = size;
			if (((nr_frags == 0)) && (frag_txd_num == 1))
				tx_ring->txd_info2.LS1_bit = 1;
			else
				tx_ring->txd_info2.LS1_bit = 0;
		}
		frag_offset += size;
		frag_size -= size;
		frag_txd_num--;
		ei_local->skb_txd_num++;
	}

	return 0;
}

static int fe_fill_tx_tso_frag(struct net_device *netdev,
			       struct sk_buff *skb,
			       unsigned long *tx_cpu_owner_idx,
			       int gmac_no)
{
	struct END_DEVICE *ei_local = netdev_priv(netdev);
	struct PSEUDO_ADAPTER *p_ad;
	unsigned int size;
	unsigned int frag_txd_num;
	skb_frag_t * frag;
	unsigned int nr_frags;
	unsigned int frag_offset, frag_size;
	struct PDMA_txdesc *tx_ring;
	int i = 0, j = 0, unmap_idx = 0;

	nr_frags = skb_shinfo(skb)->nr_frags;
	tx_ring = &ei_local->tx_ring0[*tx_cpu_owner_idx];

	for (i = 0; i < nr_frags; i++) {
		frag = &skb_shinfo(skb)->frags[i];
		frag_offset = 0;
		frag_size = skb_frag_size(frag);
		frag_txd_num = pdma_cal_frag_txd_num(frag_size);

		while (frag_txd_num > 0) {
			if (frag_size < MAX_PTXD_LEN)
				size = frag_size;
			else
				size = MAX_PTXD_LEN;

			if (ei_local->skb_txd_num % 2 == 0) {
				*tx_cpu_owner_idx =
					(*tx_cpu_owner_idx + 1) % num_tx_desc;
				tx_ring =
					&ei_local->tx_ring0[*tx_cpu_owner_idx];

				while (tx_ring->txd_info2.DDONE_bit == 0) {
					if (gmac_no == 2) {
						p_ad =
						    netdev_priv
						    (ei_local->pseudo_dev);
						p_ad->stat.tx_errors++;
					} else {
						ei_local->stat.tx_errors++;
					}
				}

				tx_ring->txd_info1.SDP0 = skb_frag_dma_map(netdev->dev.parent, frag, frag_offset, size, DMA_TO_DEVICE);

				if (unlikely
				    (dma_mapping_error
				     (netdev->dev.parent,
				      tx_ring->txd_info1.SDP0))) {
					pr_err
					    ("[%s]dma_map_page() failed\n",
					     __func__);
					goto err_dma;
				}

				tx_ring->txd_info2.SDL0 = size;

				if ((frag_txd_num == 1) &&
				    (i == (nr_frags - 1)))
					tx_ring->txd_info2.LS0_bit = 1;
				else
					tx_ring->txd_info2.LS0_bit = 0;
				tx_ring->txd_info2.DDONE_bit = 0;
				tx_ring->txd_info4.FPORT = gmac_no;
			} else {
				tx_ring->txd_info3.SDP1 = skb_frag_dma_map(netdev->dev.parent, frag, frag_offset, size, DMA_TO_DEVICE);

				if (unlikely
				    (dma_mapping_error
				     (netdev->dev.parent,
				      tx_ring->txd_info3.SDP1))) {
					pr_err
					    ("[%s]dma_map_page() failed\n",
					     __func__);
					goto err_dma;
				}
				tx_ring->txd_info2.SDL1 = size;
				if ((frag_txd_num == 1) &&
				    (i == (nr_frags - 1)))
					tx_ring->txd_info2.LS1_bit = 1;
				else
					tx_ring->txd_info2.LS1_bit = 0;
			}
			frag_offset += size;
			frag_size -= size;
			frag_txd_num--;
			ei_local->skb_txd_num++;
		}
	}

	return 0;

err_dma:
	/* unmap dma */
	j = *tx_cpu_owner_idx;
	unmap_idx = i;
	for (i = 0; i < unmap_idx; i++) {
		frag = &skb_shinfo(skb)->frags[i];
		frag_size = skb_frag_size(frag);
		frag_txd_num = pdma_cal_frag_txd_num(frag_size);

		while (frag_txd_num > 0) {
			if (frag_size < MAX_PTXD_LEN)
				size = frag_size;
			else
				size = MAX_PTXD_LEN;
			if (ei_local->skb_txd_num % 2 == 0) {
				j = (j + 1) % num_tx_desc;
				dma_unmap_page(netdev->dev.parent,
					       ei_local->tx_ring0[j].
					       txd_info1.SDP0,
					       ei_local->tx_ring0[j].
					       txd_info2.SDL0, DMA_TO_DEVICE);
				/* reinit txd */
				ei_local->tx_ring0[j].txd_info2.LS0_bit = 1;
				ei_local->tx_ring0[j].txd_info2.DDONE_bit = 1;
			} else {
				dma_unmap_page(netdev->dev.parent,
					       ei_local->tx_ring0[j].
					       txd_info3.SDP1,
					       ei_local->tx_ring0[j].
					       txd_info2.SDL1, DMA_TO_DEVICE);
				/* reinit txd */
				ei_local->tx_ring0[j].txd_info2.LS1_bit = 1;
			}
			frag_size -= size;
			frag_txd_num--;
			ei_local->skb_txd_num++;
		}
	}

	return -1;
}

int fe_fill_tx_desc_tso(struct net_device *dev,
			unsigned long *tx_cpu_owner_idx,
			struct sk_buff *skb,
			int gmac_no)
{
	struct END_DEVICE *ei_local = netdev_priv(dev);
	struct iphdr *iph = NULL;
	struct ipv6hdr *ip6h = NULL;
	struct tcphdr *th = NULL;
	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
	unsigned int len, offset;
	int err;
	struct PDMA_txdesc *tx_ring = &ei_local->tx_ring0[*tx_cpu_owner_idx];

	tx_ring->txd_info4.FPORT = gmac_no;
	tx_ring->txd_info4.TSO = 0;

	if (skb->ip_summed == CHECKSUM_PARTIAL)
		tx_ring->txd_info4.TUI_CO = 7;
	else
		tx_ring->txd_info4.TUI_CO = 0;

	if (ei_local->features & FE_HW_VLAN_TX) {
		if (skb_vlan_tag_present(skb))
			tx_ring->txd_info4.VLAN_TAG =
				0x10000 | skb_vlan_tag_get(skb);
		else
			tx_ring->txd_info4.VLAN_TAG = 0;
	}
#if defined(CONFIG_RA_HW_NAT) || defined(CONFIG_RA_HW_NAT_MODULE)
	if (IS_MAGIC_TAG_PROTECT_VALID_HEAD(skb)) {
		if (FOE_MAGIC_TAG_HEAD(skb) == FOE_MAGIC_PPE) {
			if (ppe_hook_rx_eth) {
				/* PPE */
				tx_ring->txd_info4.FPORT = 4;
				FOE_MAGIC_TAG(skb) = 0;
			}
		}
	} else if (IS_MAGIC_TAG_PROTECT_VALID_TAIL(skb)) {
		if (FOE_MAGIC_TAG_TAIL(skb) == FOE_MAGIC_PPE) {
			if (ppe_hook_rx_eth) {
				/* PPE */
				tx_ring->txd_info4.FPORT = 4;
				FOE_MAGIC_TAG(skb) = 0;
			}
		}
	}
#endif
	ei_local->skb_txd_num = 1;

	/* skb data handle */
	len = skb->len - skb->data_len;
	offset = virt_to_phys(skb->data);
	tx_ring->txd_info1.SDP0 = offset;
	if (len < MAX_PTXD_LEN) {
		tx_ring->txd_info2.SDL0 = len;
		tx_ring->txd_info2.LS0_bit = nr_frags ? 0 : 1;
		len = 0;
	} else {
		tx_ring->txd_info2.SDL0 = MAX_PTXD_LEN;
		tx_ring->txd_info2.LS0_bit = 0;
		len -= MAX_PTXD_LEN;
		offset += MAX_PTXD_LEN;
	}

	if (len > 0)
		fe_fill_tx_tso_data(ei_local, offset, len,
				    tx_cpu_owner_idx, nr_frags, gmac_no);

	/* skb fragments handle */
	if (nr_frags > 0) {
		err = fe_fill_tx_tso_frag(dev, skb, tx_cpu_owner_idx, gmac_no);
		if (unlikely(err))
			return err;
	}

	/* fill in MSS info in tcp checksum field */
	if (skb_shinfo(skb)->gso_segs > 1) {
		/* TCP over IPv4 */
		iph = (struct iphdr *)skb_network_header(skb);
		if ((iph->version == 4) && (iph->protocol == IPPROTO_TCP)) {
			th = (struct tcphdr *)skb_transport_header(skb);
			tx_ring->txd_info4.TSO = 1;
			th->check = htons(skb_shinfo(skb)->gso_size);
			dma_sync_single_for_device(dev->dev.parent,
						   virt_to_phys(th),
						   sizeof(struct tcphdr),
						   DMA_TO_DEVICE);
		}

		/* TCP over IPv6 */
		if (ei_local->features & FE_TSO_V6) {
			ip6h = (struct ipv6hdr *)skb_network_header(skb);
			if ((ip6h->nexthdr == NEXTHDR_TCP) &&
			    (ip6h->version == 6)) {
				th = (struct tcphdr *)skb_transport_header(skb);
				tx_ring->txd_info4.TSO = 1;
				th->check = htons(skb_shinfo(skb)->gso_size);
				dma_sync_single_for_device(dev->dev.parent,
							   virt_to_phys(th),
							   sizeof(struct
								  tcphdr),
							   DMA_TO_DEVICE);
			}
		}
	}
	tx_ring->txd_info2.DDONE_bit = 0;

	return 0;
}

static inline int rt2880_pdma_eth_send(struct net_device *dev,
				       struct sk_buff *skb, int gmac_no,
				       unsigned int num_of_frag)
{
	unsigned int length = skb->len;
	struct END_DEVICE *ei_local = netdev_priv(dev);
#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR
	unsigned long tx_cpu_owner_idx0 = ei_local->tx_cpu_owner_idx0;
#else
	unsigned long tx_cpu_owner_idx0 = sys_reg_read(TX_CTX_IDX0);
#endif
	struct PSEUDO_ADAPTER *p_ad;
	int err;

	while (ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit == 0) {
		if (gmac_no == 2) {
			if (ei_local->pseudo_dev) {
				p_ad = netdev_priv(ei_local->pseudo_dev);
				p_ad->stat.tx_errors++;
			} else {
				pr_err
				    ("pseudo_dev is still not initialize ");
				pr_err
				    ("but receive packet from GMAC2\n");
			}
		} else {
			ei_local->stat.tx_errors++;
		}
	}

	if (num_of_frag > 1)
		err = fe_fill_tx_desc_tso(dev, &tx_cpu_owner_idx0,
					  skb, gmac_no);
	else
		err = fe_fill_tx_desc(dev, &tx_cpu_owner_idx0, skb, gmac_no);
	if (err)
		return err;

	tx_cpu_owner_idx0 = (tx_cpu_owner_idx0 + 1) % num_tx_desc;
	while (ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit == 0) {
		if (gmac_no == 2) {
			p_ad = netdev_priv(ei_local->pseudo_dev);
			p_ad->stat.tx_errors++;
		} else {
			ei_local->stat.tx_errors++;
		}
	}
#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR
	ei_local->tx_cpu_owner_idx0 = tx_cpu_owner_idx0;
#endif
	/* make sure that all changes to the dma ring are flushed before we
	 * continue
	 */
	wmb();

	sys_reg_write(TX_CTX_IDX0, cpu_to_le32((u32)tx_cpu_owner_idx0));

	if (gmac_no == 2) {
		p_ad = netdev_priv(ei_local->pseudo_dev);
		p_ad->stat.tx_packets++;
		p_ad->stat.tx_bytes += length;
	} else {
		ei_local->stat.tx_packets++;
		ei_local->stat.tx_bytes += length;
	}

	return length;
}

int ei_pdma_start_xmit(struct sk_buff *skb, struct net_device *dev, int gmac_no)
{
	struct END_DEVICE *ei_local = netdev_priv(dev);
	unsigned long tx_cpu_owner_idx;
	unsigned int tx_cpu_owner_idx_next, tx_cpu_owner_idx_next2;
	unsigned int num_of_txd, num_of_frag;
	unsigned int nr_frags = skb_shinfo(skb)->nr_frags, i;
	skb_frag_t * frag;
	struct PSEUDO_ADAPTER *p_ad;
	unsigned int tx_cpu_cal_idx;

#if defined(CONFIG_RA_HW_NAT)  || defined(CONFIG_RA_HW_NAT_MODULE)
	if (ppe_hook_tx_eth) {
#if defined(CONFIG_RA_HW_NAT) || defined(CONFIG_RA_HW_NAT_MODULE)
		if (FOE_MAGIC_TAG(skb) != FOE_MAGIC_PPE)
#endif
			if (ppe_hook_tx_eth(skb, gmac_no) != 1) {
				dev_kfree_skb_any(skb);
				return 0;
			}
	}
#endif

//	dev->trans_start = jiffies;	/* save the timestamp */
	netif_trans_update(dev);
	spin_lock(&ei_local->page_lock);
	dma_sync_single_for_device(dev->dev.parent, virt_to_phys(skb->data),
				   skb->len, DMA_TO_DEVICE);

#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR
	tx_cpu_owner_idx = ei_local->tx_cpu_owner_idx0;
#else
	tx_cpu_owner_idx = sys_reg_read(TX_CTX_IDX0);
#endif

	if (ei_local->features & FE_TSO) {
		num_of_txd = pdma_cal_frag_txd_num(skb->len - skb->data_len);
		if (nr_frags != 0) {
			for (i = 0; i < nr_frags; i++) {
				frag = &skb_shinfo(skb)->frags[i];
				num_of_txd += pdma_cal_frag_txd_num(skb_frag_size(frag));

			}
		}
		num_of_frag = num_of_txd;
		num_of_txd = (num_of_txd + 1) >> 1;
	} else {
		num_of_frag = 1;
		num_of_txd = 1;
	}

	tx_cpu_owner_idx_next = (tx_cpu_owner_idx + num_of_txd) % num_tx_desc;

	if ((ei_local->skb_free[tx_cpu_owner_idx_next] == 0) &&
	    (ei_local->skb_free[tx_cpu_owner_idx] == 0)) {
		if (rt2880_pdma_eth_send(dev, skb, gmac_no, num_of_frag) < 0) {
			dev_kfree_skb_any(skb);
			if (gmac_no == 2) {
				p_ad = netdev_priv(ei_local->pseudo_dev);
				p_ad->stat.tx_dropped++;
			} else {
				ei_local->stat.tx_dropped++;
			}
			goto tx_err;
		}

		tx_cpu_owner_idx_next2 =
		    (tx_cpu_owner_idx_next + 1) % num_tx_desc;

		if (ei_local->skb_free[tx_cpu_owner_idx_next2] != 0)
			ei_local->tx_ring_full = 1;
	} else {
		if (gmac_no == 2) {
			p_ad = netdev_priv(ei_local->pseudo_dev);
			p_ad->stat.tx_dropped++;
		} else {
			ei_local->stat.tx_dropped++;
		}

		dev_kfree_skb_any(skb);
		spin_unlock(&ei_local->page_lock);
		return NETDEV_TX_OK;
	}

	/* SG: use multiple TXD to send the packet (only have one skb) */
	tx_cpu_cal_idx = (tx_cpu_owner_idx + num_of_txd - 1) % num_tx_desc;
	ei_local->skb_free[tx_cpu_cal_idx] = skb;
	while (--num_of_txd)
		/* MAGIC ID */
		ei_local->skb_free[(--tx_cpu_cal_idx) % num_tx_desc] =
			(struct sk_buff *)0xFFFFFFFF;

tx_err:
	spin_unlock(&ei_local->page_lock);
	return NETDEV_TX_OK;
}

int ei_pdma_xmit_housekeeping(struct net_device *netdev, int budget)
{
	struct END_DEVICE *ei_local = netdev_priv(netdev);
	struct PDMA_txdesc *tx_desc;
	unsigned long skb_free_idx;
	int tx_processed = 0;

	tx_desc = ei_local->tx_ring0;
	skb_free_idx = ei_local->free_idx;

	while (budget &&
	       (ei_local->skb_free[skb_free_idx] != 0) &&
	       (tx_desc[skb_free_idx].txd_info2.DDONE_bit == 1)) {
		if (ei_local->skb_free[skb_free_idx] !=
		    (struct sk_buff *)0xFFFFFFFF)
			dev_kfree_skb_any(ei_local->skb_free[skb_free_idx]);

		ei_local->skb_free[skb_free_idx] = 0;
		skb_free_idx = (skb_free_idx + 1) % num_tx_desc;
		budget--;
		tx_processed++;
	}

	ei_local->tx_ring_full = 0;
	ei_local->free_idx = skb_free_idx;

	return tx_processed;
}

