/*
 * Agere Systems Inc.
 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
 *
 * Copyright © 2005 Agere Systems Inc.
 * All rights reserved.
 *   http://www.agere.com
 *
 *------------------------------------------------------------------------------
 *
 * et1310_rx.c - Routines used to perform data reception
 *
 *------------------------------------------------------------------------------
 *
 * SOFTWARE LICENSE
 *
 * This software is provided subject to the following terms and conditions,
 * which you should read carefully before using the software.  Using this
 * software indicates your acceptance of these terms and conditions.  If you do
 * not agree with these terms and conditions, do not use the software.
 *
 * Copyright © 2005 Agere Systems Inc.
 * All rights reserved.
 *
 * Redistribution and use in source or binary forms, with or without
 * modifications, 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 as comments in the code as
 *    well as in the documentation and/or other materials provided with the
 *    distribution.
 *
 * . 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 of Agere Systems Inc. nor the names of the contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * Disclaimer
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. 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, INCLUDING, BUT NOT LIMITED TO, 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 "et131x_version.h"
#include "et131x_defs.h"

#include <linux/pci.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>

#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <asm/system.h>

#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/ioport.h>

#include "et1310_phy.h"
#include "et131x_adapter.h"
#include "et1310_rx.h"
#include "et131x.h"

void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd);

/**
 * et131x_rx_dma_memory_alloc
 * @adapter: pointer to our private adapter structure
 *
 * Returns 0 on success and errno on failure (as defined in errno.h)
 *
 * Allocates Free buffer ring 1 for sure, free buffer ring 0 if required,
 * and the Packet Status Ring.
 */
int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
{
	u32 i, j;
	u32 bufsize;
	u32 pktStatRingSize, FBRChunkSize;
	struct rx_ring *rx_ring;

	/* Setup some convenience pointers */
	rx_ring = &adapter->rx_ring;

	/* Alloc memory for the lookup table */
#ifdef USE_FBR0
	rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
#endif
	rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);

	/* The first thing we will do is configure the sizes of the buffer
	 * rings. These will change based on jumbo packet support.  Larger
	 * jumbo packets increases the size of each entry in FBR0, and the
	 * number of entries in FBR0, while at the same time decreasing the
	 * number of entries in FBR1.
	 *
	 * FBR1 holds "large" frames, FBR0 holds "small" frames.  If FBR1
	 * entries are huge in order to accomodate a "jumbo" frame, then it
	 * will have less entries.  Conversely, FBR1 will now be relied upon
	 * to carry more "normal" frames, thus it's entry size also increases
	 * and the number of entries goes up too (since it now carries
	 * "small" + "regular" packets.
	 *
	 * In this scheme, we try to maintain 512 entries between the two
	 * rings. Also, FBR1 remains a constant size - when it's size doubles
	 * the number of entries halves.  FBR0 increases in size, however.
	 */

	if (adapter->RegistryJumboPacket < 2048) {
#ifdef USE_FBR0
		rx_ring->Fbr0BufferSize = 256;
		rx_ring->Fbr0NumEntries = 512;
#endif
		rx_ring->Fbr1BufferSize = 2048;
		rx_ring->Fbr1NumEntries = 512;
	} else if (adapter->RegistryJumboPacket < 4096) {
#ifdef USE_FBR0
		rx_ring->Fbr0BufferSize = 512;
		rx_ring->Fbr0NumEntries = 1024;
#endif
		rx_ring->Fbr1BufferSize = 4096;
		rx_ring->Fbr1NumEntries = 512;
	} else {
#ifdef USE_FBR0
		rx_ring->Fbr0BufferSize = 1024;
		rx_ring->Fbr0NumEntries = 768;
#endif
		rx_ring->Fbr1BufferSize = 16384;
		rx_ring->Fbr1NumEntries = 128;
	}

#ifdef USE_FBR0
	adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr0NumEntries +
	    adapter->rx_ring.Fbr1NumEntries;
#else
	adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr1NumEntries;
#endif

	/* Allocate an area of memory for Free Buffer Ring 1 */
	bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) + 0xfff;
	rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev,
						    bufsize,
						    &rx_ring->pFbr1RingPa);
	if (!rx_ring->pFbr1RingVa) {
		dev_err(&adapter->pdev->dev,
			  "Cannot alloc memory for Free Buffer Ring 1\n");
		return -ENOMEM;
	}

	/* Save physical address
	 *
	 * NOTE: pci_alloc_consistent(), used above to alloc DMA regions,
	 * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
	 * are ever returned, make sure the high part is retrieved here
	 * before storing the adjusted address.
	 */
	rx_ring->Fbr1Realpa = rx_ring->pFbr1RingPa;

	/* Align Free Buffer Ring 1 on a 4K boundary */
	et131x_align_allocated_memory(adapter,
				      &rx_ring->Fbr1Realpa,
				      &rx_ring->Fbr1offset, 0x0FFF);

	rx_ring->pFbr1RingVa = (void *)((u8 *) rx_ring->pFbr1RingVa +
					rx_ring->Fbr1offset);

#ifdef USE_FBR0
	/* Allocate an area of memory for Free Buffer Ring 0 */
	bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) + 0xfff;
	rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev,
						    bufsize,
						    &rx_ring->pFbr0RingPa);
	if (!rx_ring->pFbr0RingVa) {
		dev_err(&adapter->pdev->dev,
			  "Cannot alloc memory for Free Buffer Ring 0\n");
		return -ENOMEM;
	}

	/* Save physical address
	 *
	 * NOTE: pci_alloc_consistent(), used above to alloc DMA regions,
	 * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
	 * are ever returned, make sure the high part is retrieved here before
	 * storing the adjusted address.
	 */
	rx_ring->Fbr0Realpa = rx_ring->pFbr0RingPa;

	/* Align Free Buffer Ring 0 on a 4K boundary */
	et131x_align_allocated_memory(adapter,
				      &rx_ring->Fbr0Realpa,
				      &rx_ring->Fbr0offset, 0x0FFF);

	rx_ring->pFbr0RingVa = (void *)((u8 *) rx_ring->pFbr0RingVa +
					rx_ring->Fbr0offset);
#endif

	for (i = 0; i < (rx_ring->Fbr1NumEntries / FBR_CHUNKS);
	     i++) {
		u64 Fbr1Offset;
		u64 Fbr1TempPa;
		u32 Fbr1Align;

		/* This code allocates an area of memory big enough for N
		 * free buffers + (buffer_size - 1) so that the buffers can
		 * be aligned on 4k boundaries.  If each buffer were aligned
		 * to a buffer_size boundary, the effect would be to double
		 * the size of FBR0.  By allocating N buffers at once, we
		 * reduce this overhead.
		 */
		if (rx_ring->Fbr1BufferSize > 4096)
			Fbr1Align = 4096;
		else
			Fbr1Align = rx_ring->Fbr1BufferSize;

		FBRChunkSize =
		    (FBR_CHUNKS * rx_ring->Fbr1BufferSize) + Fbr1Align - 1;
		rx_ring->Fbr1MemVa[i] =
		    pci_alloc_consistent(adapter->pdev, FBRChunkSize,
					 &rx_ring->Fbr1MemPa[i]);

		if (!rx_ring->Fbr1MemVa[i]) {
		dev_err(&adapter->pdev->dev,
				"Could not alloc memory\n");
			return -ENOMEM;
		}

		/* See NOTE in "Save Physical Address" comment above */
		Fbr1TempPa = rx_ring->Fbr1MemPa[i];

		et131x_align_allocated_memory(adapter,
					      &Fbr1TempPa,
					      &Fbr1Offset, (Fbr1Align - 1));

		for (j = 0; j < FBR_CHUNKS; j++) {
			u32 index = (i * FBR_CHUNKS) + j;

			/* Save the Virtual address of this index for quick
			 * access later
			 */
			rx_ring->fbr[1]->virt[index] =
			    (u8 *) rx_ring->Fbr1MemVa[i] +
			    (j * rx_ring->Fbr1BufferSize) + Fbr1Offset;

			/* now store the physical address in the descriptor
			 * so the device can access it
			 */
			rx_ring->fbr[1]->bus_high[index] =
			    (u32) (Fbr1TempPa >> 32);
			rx_ring->fbr[1]->bus_low[index] = (u32) Fbr1TempPa;

			Fbr1TempPa += rx_ring->Fbr1BufferSize;

			rx_ring->fbr[1]->buffer1[index] =
			    rx_ring->fbr[1]->virt[index];
			rx_ring->fbr[1]->buffer2[index] =
			    rx_ring->fbr[1]->virt[index] - 4;
		}
	}

#ifdef USE_FBR0
	/* Same for FBR0 (if in use) */
	for (i = 0; i < (rx_ring->Fbr0NumEntries / FBR_CHUNKS);
	     i++) {
		u64 Fbr0Offset;
		u64 Fbr0TempPa;

		FBRChunkSize = ((FBR_CHUNKS + 1) * rx_ring->Fbr0BufferSize) - 1;
		rx_ring->Fbr0MemVa[i] =
		    pci_alloc_consistent(adapter->pdev, FBRChunkSize,
					 &rx_ring->Fbr0MemPa[i]);

		if (!rx_ring->Fbr0MemVa[i]) {
			dev_err(&adapter->pdev->dev,
				"Could not alloc memory\n");
			return -ENOMEM;
		}

		/* See NOTE in "Save Physical Address" comment above */
		Fbr0TempPa = rx_ring->Fbr0MemPa[i];

		et131x_align_allocated_memory(adapter,
					      &Fbr0TempPa,
					      &Fbr0Offset,
					      rx_ring->Fbr0BufferSize - 1);

		for (j = 0; j < FBR_CHUNKS; j++) {
			u32 index = (i * FBR_CHUNKS) + j;

			rx_ring->fbr[0]->virt[index] =
			    (u8 *) rx_ring->Fbr0MemVa[i] +
			    (j * rx_ring->Fbr0BufferSize) + Fbr0Offset;

			rx_ring->fbr[0]->bus_high[index] =
			    (u32) (Fbr0TempPa >> 32);
			rx_ring->fbr[0]->bus_low[index] = (u32) Fbr0TempPa;

			Fbr0TempPa += rx_ring->Fbr0BufferSize;

			rx_ring->fbr[0]->buffer1[index] =
			    rx_ring->fbr[0]->virt[index];
			rx_ring->fbr[0]->buffer2[index] =
			    rx_ring->fbr[0]->virt[index] - 4;
		}
	}
#endif

	/* Allocate an area of memory for FIFO of Packet Status ring entries */
	pktStatRingSize =
	    sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries;

	rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev,
						  pktStatRingSize,
						  &rx_ring->pPSRingPa);

	if (!rx_ring->pPSRingVa) {
		dev_err(&adapter->pdev->dev,
			  "Cannot alloc memory for Packet Status Ring\n");
		return -ENOMEM;
	}
	printk(KERN_INFO "PSR %lx\n", (unsigned long) rx_ring->pPSRingPa);

	/*
	 * NOTE : pci_alloc_consistent(), used above to alloc DMA regions,
	 * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
	 * are ever returned, make sure the high part is retrieved here before
	 * storing the adjusted address.
	 */

	/* Allocate an area of memory for writeback of status information */
	rx_ring->rx_status_block = pci_alloc_consistent(adapter->pdev,
					    sizeof(struct rx_status_block),
					    &rx_ring->rx_status_bus);
	if (!rx_ring->rx_status_block) {
		dev_err(&adapter->pdev->dev,
			  "Cannot alloc memory for Status Block\n");
		return -ENOMEM;
	}
	rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD;
	printk(KERN_INFO "PRS %lx\n", (unsigned long)rx_ring->rx_status_bus);

	/* Recv
	 * pci_pool_create initializes a lookaside list. After successful
	 * creation, nonpaged fixed-size blocks can be allocated from and
	 * freed to the lookaside list.
	 * RFDs will be allocated from this pool.
	 */
	rx_ring->RecvLookaside = kmem_cache_create(adapter->netdev->name,
						   sizeof(MP_RFD),
						   0,
						   SLAB_CACHE_DMA |
						   SLAB_HWCACHE_ALIGN,
						   NULL);

	adapter->Flags |= fMP_ADAPTER_RECV_LOOKASIDE;

	/* The RFDs are going to be put on lists later on, so initialize the
	 * lists now.
	 */
	INIT_LIST_HEAD(&rx_ring->RecvList);
	return 0;
}

/**
 * et131x_rx_dma_memory_free - Free all memory allocated within this module.
 * @adapter: pointer to our private adapter structure
 */
void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
{
	u32 index;
	u32 bufsize;
	u32 pktStatRingSize;
	PMP_RFD rfd;
	struct rx_ring *rx_ring;

	/* Setup some convenience pointers */
	rx_ring = &adapter->rx_ring;

	/* Free RFDs and associated packet descriptors */
	WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd);

	while (!list_empty(&rx_ring->RecvList)) {
		rfd = (MP_RFD *) list_entry(rx_ring->RecvList.next,
					       MP_RFD, list_node);

		list_del(&rfd->list_node);
		rfd->Packet = NULL;
		kmem_cache_free(adapter->rx_ring.RecvLookaside, rfd);
	}

	/* Free Free Buffer Ring 1 */
	if (rx_ring->pFbr1RingVa) {
		/* First the packet memory */
		for (index = 0; index <
		     (rx_ring->Fbr1NumEntries / FBR_CHUNKS); index++) {
			if (rx_ring->Fbr1MemVa[index]) {
				u32 Fbr1Align;

				if (rx_ring->Fbr1BufferSize > 4096)
					Fbr1Align = 4096;
				else
					Fbr1Align = rx_ring->Fbr1BufferSize;

				bufsize =
				    (rx_ring->Fbr1BufferSize * FBR_CHUNKS) +
				    Fbr1Align - 1;

				pci_free_consistent(adapter->pdev,
						    bufsize,
						    rx_ring->Fbr1MemVa[index],
						    rx_ring->Fbr1MemPa[index]);

				rx_ring->Fbr1MemVa[index] = NULL;
			}
		}

		/* Now the FIFO itself */
		rx_ring->pFbr1RingVa = (void *)((u8 *)
				rx_ring->pFbr1RingVa - rx_ring->Fbr1offset);

		bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries)
							    + 0xfff;

		pci_free_consistent(adapter->pdev, bufsize,
				rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa);

		rx_ring->pFbr1RingVa = NULL;
	}

#ifdef USE_FBR0
	/* Now the same for Free Buffer Ring 0 */
	if (rx_ring->pFbr0RingVa) {
		/* First the packet memory */
		for (index = 0; index <
		     (rx_ring->Fbr0NumEntries / FBR_CHUNKS); index++) {
			if (rx_ring->Fbr0MemVa[index]) {
				bufsize =
				    (rx_ring->Fbr0BufferSize *
				     (FBR_CHUNKS + 1)) - 1;

				pci_free_consistent(adapter->pdev,
						    bufsize,
						    rx_ring->Fbr0MemVa[index],
						    rx_ring->Fbr0MemPa[index]);

				rx_ring->Fbr0MemVa[index] = NULL;
			}
		}

		/* Now the FIFO itself */
		rx_ring->pFbr0RingVa = (void *)((u8 *)
				rx_ring->pFbr0RingVa - rx_ring->Fbr0offset);

		bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries)
							    + 0xfff;

		pci_free_consistent(adapter->pdev,
				    bufsize,
				    rx_ring->pFbr0RingVa, rx_ring->pFbr0RingPa);

		rx_ring->pFbr0RingVa = NULL;
	}
#endif

	/* Free Packet Status Ring */
	if (rx_ring->pPSRingVa) {
		pktStatRingSize =
		    sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries;

		pci_free_consistent(adapter->pdev, pktStatRingSize,
				    rx_ring->pPSRingVa, rx_ring->pPSRingPa);

		rx_ring->pPSRingVa = NULL;
	}

	/* Free area of memory for the writeback of status information */
	if (rx_ring->rx_status_block) {
		pci_free_consistent(adapter->pdev,
			sizeof(struct rx_status_block),
			rx_ring->rx_status_block, rx_ring->rx_status_bus);
		rx_ring->rx_status_block = NULL;
	}

	/* Free receive buffer pool */

	/* Free receive packet pool */

	/* Destroy the lookaside (RFD) pool */
	if (adapter->Flags & fMP_ADAPTER_RECV_LOOKASIDE) {
		kmem_cache_destroy(rx_ring->RecvLookaside);
		adapter->Flags &= ~fMP_ADAPTER_RECV_LOOKASIDE;
	}

	/* Free the FBR Lookup Table */
#ifdef USE_FBR0
	kfree(rx_ring->fbr[0]);
#endif

	kfree(rx_ring->fbr[1]);

	/* Reset Counters */
	rx_ring->nReadyRecv = 0;
}

/**
 * et131x_init_recv - Initialize receive data structures.
 * @adapter: pointer to our private adapter structure
 *
 * Returns 0 on success and errno on failure (as defined in errno.h)
 */
int et131x_init_recv(struct et131x_adapter *adapter)
{
	int status = -ENOMEM;
	PMP_RFD rfd = NULL;
	u32 rfdct;
	u32 numrfd = 0;
	struct rx_ring *rx_ring;

	/* Setup some convenience pointers */
	rx_ring = &adapter->rx_ring;

	/* Setup each RFD */
	for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) {
		rfd = kmem_cache_alloc(rx_ring->RecvLookaside,
						     GFP_ATOMIC | GFP_DMA);

		if (!rfd) {
			dev_err(&adapter->pdev->dev,
				  "Couldn't alloc RFD out of kmem_cache\n");
			status = -ENOMEM;
			continue;
		}

		rfd->Packet = NULL;

		/* Add this RFD to the RecvList */
		list_add_tail(&rfd->list_node, &rx_ring->RecvList);

		/* Increment both the available RFD's, and the total RFD's. */
		rx_ring->nReadyRecv++;
		numrfd++;
	}

	if (numrfd > NIC_MIN_NUM_RFD)
		status = 0;

	rx_ring->NumRfd = numrfd;

	if (status != 0) {
		kmem_cache_free(rx_ring->RecvLookaside, rfd);
		dev_err(&adapter->pdev->dev,
			  "Allocation problems in et131x_init_recv\n");
	}
	return status;
}

/**
 * ConfigRxDmaRegs - Start of Rx_DMA init sequence
 * @etdev: pointer to our adapter structure
 */
void ConfigRxDmaRegs(struct et131x_adapter *etdev)
{
	struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma;
	struct rx_ring *rx_local = &etdev->rx_ring;
	struct fbr_desc *fbr_entry;
	u32 entry;
	u32 psr_num_des;
	unsigned long flags;

	/* Halt RXDMA to perform the reconfigure.  */
	et131x_rx_dma_disable(etdev);

	/* Load the completion writeback physical address
	 *
	 * NOTE : pci_alloc_consistent(), used above to alloc DMA regions,
	 * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
	 * are ever returned, make sure the high part is retrieved here
	 * before storing the adjusted address.
	 */
	writel((u32) ((u64)rx_local->rx_status_bus >> 32),
	       &rx_dma->dma_wb_base_hi);
	writel((u32) rx_local->rx_status_bus, &rx_dma->dma_wb_base_lo);

	memset(rx_local->rx_status_block, 0, sizeof(struct rx_status_block));

	/* Set the address and parameters of the packet status ring into the
	 * 1310's registers
	 */
	writel((u32) ((u64)rx_local->pPSRingPa >> 32),
	       &rx_dma->psr_base_hi);
	writel((u32) rx_local->pPSRingPa, &rx_dma->psr_base_lo);
	writel(rx_local->PsrNumEntries - 1, &rx_dma->psr_num_des);
	writel(0, &rx_dma->psr_full_offset);

	psr_num_des = readl(&rx_dma->psr_num_des) & 0xFFF;
	writel((psr_num_des * LO_MARK_PERCENT_FOR_PSR) / 100,
	       &rx_dma->psr_min_des);

	spin_lock_irqsave(&etdev->RcvLock, flags);

	/* These local variables track the PSR in the adapter structure */
	rx_local->local_psr_full = 0;

	/* Now's the best time to initialize FBR1 contents */
	fbr_entry = (struct fbr_desc *) rx_local->pFbr1RingVa;
	for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) {
		fbr_entry->addr_hi = rx_local->fbr[1]->bus_high[entry];
		fbr_entry->addr_lo = rx_local->fbr[1]->bus_low[entry];
		fbr_entry->word2 = entry;
		fbr_entry++;
	}

	/* Set the address and parameters of Free buffer ring 1 (and 0 if
	 * required) into the 1310's registers
	 */
	writel((u32) (rx_local->Fbr1Realpa >> 32), &rx_dma->fbr1_base_hi);
	writel((u32) rx_local->Fbr1Realpa, &rx_dma->fbr1_base_lo);
	writel(rx_local->Fbr1NumEntries - 1, &rx_dma->fbr1_num_des);
	writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset);

	/* This variable tracks the free buffer ring 1 full position, so it
	 * has to match the above.
	 */
	rx_local->local_Fbr1_full = ET_DMA10_WRAP;
	writel(((rx_local->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
	       &rx_dma->fbr1_min_des);

#ifdef USE_FBR0
	/* Now's the best time to initialize FBR0 contents */
	fbr_entry = (struct fbr_desc *) rx_local->pFbr0RingVa;
	for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) {
		fbr_entry->addr_hi = rx_local->fbr[0]->bus_high[entry];
		fbr_entry->addr_lo = rx_local->fbr[0]->bus_low[entry];
		fbr_entry->word2 = entry;
		fbr_entry++;
	}

	writel((u32) (rx_local->Fbr0Realpa >> 32), &rx_dma->fbr0_base_hi);
	writel((u32) rx_local->Fbr0Realpa, &rx_dma->fbr0_base_lo);
	writel(rx_local->Fbr0NumEntries - 1, &rx_dma->fbr0_num_des);
	writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset);

	/* This variable tracks the free buffer ring 0 full position, so it
	 * has to match the above.
	 */
	rx_local->local_Fbr0_full = ET_DMA10_WRAP;
	writel(((rx_local->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
	       &rx_dma->fbr0_min_des);
#endif

	/* Program the number of packets we will receive before generating an
	 * interrupt.
	 * For version B silicon, this value gets updated once autoneg is
	 *complete.
	 */
	writel(PARM_RX_NUM_BUFS_DEF, &rx_dma->num_pkt_done);

	/* The "time_done" is not working correctly to coalesce interrupts
	 * after a given time period, but rather is giving us an interrupt
	 * regardless of whether we have received packets.
	 * This value gets updated once autoneg is complete.
	 */
	writel(PARM_RX_TIME_INT_DEF, &rx_dma->max_pkt_time);

	spin_unlock_irqrestore(&etdev->RcvLock, flags);
}

/**
 * SetRxDmaTimer - Set the heartbeat timer according to line rate.
 * @etdev: pointer to our adapter structure
 */
void SetRxDmaTimer(struct et131x_adapter *etdev)
{
	/* For version B silicon, we do not use the RxDMA timer for 10 and 100
	 * Mbits/s line rates. We do not enable and RxDMA interrupt coalescing.
	 */
	if ((etdev->linkspeed == TRUEPHY_SPEED_100MBPS) ||
	    (etdev->linkspeed == TRUEPHY_SPEED_10MBPS)) {
		writel(0, &etdev->regs->rxdma.max_pkt_time);
		writel(1, &etdev->regs->rxdma.num_pkt_done);
	}
}

/**
 * et131x_rx_dma_disable - Stop of Rx_DMA on the ET1310
 * @etdev: pointer to our adapter structure
 */
void et131x_rx_dma_disable(struct et131x_adapter *etdev)
{
	u32 csr;
	/* Setup the receive dma configuration register */
	writel(0x00002001, &etdev->regs->rxdma.csr);
	csr = readl(&etdev->regs->rxdma.csr);
	if ((csr & 0x00020000) != 1) {	/* Check halt status (bit 17) */
		udelay(5);
		csr = readl(&etdev->regs->rxdma.csr);
		if ((csr & 0x00020000) != 1)
			dev_err(&etdev->pdev->dev,
			"RX Dma failed to enter halt state. CSR 0x%08x\n",
				csr);
	}
}

/**
 * et131x_rx_dma_enable - re-start of Rx_DMA on the ET1310.
 * @etdev: pointer to our adapter structure
 */
void et131x_rx_dma_enable(struct et131x_adapter *etdev)
{
	/* Setup the receive dma configuration register for normal operation */
	u32 csr =  0x2000;	/* FBR1 enable */

	if (etdev->rx_ring.Fbr1BufferSize == 4096)
		csr |= 0x0800;
	else if (etdev->rx_ring.Fbr1BufferSize == 8192)
		csr |= 0x1000;
	else if (etdev->rx_ring.Fbr1BufferSize == 16384)
		csr |= 0x1800;
#ifdef USE_FBR0
	csr |= 0x0400;		/* FBR0 enable */
	if (etdev->rx_ring.Fbr0BufferSize == 256)
		csr |= 0x0100;
	else if (etdev->rx_ring.Fbr0BufferSize == 512)
		csr |= 0x0200;
	else if (etdev->rx_ring.Fbr0BufferSize == 1024)
		csr |= 0x0300;
#endif
	writel(csr, &etdev->regs->rxdma.csr);

	csr = readl(&etdev->regs->rxdma.csr);
	if ((csr & 0x00020000) != 0) {
		udelay(5);
		csr = readl(&etdev->regs->rxdma.csr);
		if ((csr & 0x00020000) != 0) {
			dev_err(&etdev->pdev->dev,
			    "RX Dma failed to exit halt state.  CSR 0x%08x\n",
				csr);
		}
	}
}

/**
 * nic_rx_pkts - Checks the hardware for available packets
 * @etdev: pointer to our adapter
 *
 * Returns rfd, a pointer to our MPRFD.
 *
 * Checks the hardware for available packets, using completion ring
 * If packets are available, it gets an RFD from the RecvList, attaches
 * the packet to it, puts the RFD in the RecvPendList, and also returns
 * the pointer to the RFD.
 */
PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
{
	struct rx_ring *rx_local = &etdev->rx_ring;
	struct rx_status_block *status;
	struct pkt_stat_desc *psr;
	PMP_RFD rfd;
	u32 i;
	u8 *buf;
	unsigned long flags;
	struct list_head *element;
	u8 rindex;
	u16 bindex;
	u32 len;
	u32 word0;
	u32 word1;

	/* RX Status block is written by the DMA engine prior to every
	 * interrupt. It contains the next to be used entry in the Packet
	 * Status Ring, and also the two Free Buffer rings.
	 */
	status = rx_local->rx_status_block;
	word1 = status->Word1 >> 16;	/* Get the useful bits */

	/* Check the PSR and wrap bits do not match */
	if ((word1 & 0x1FFF) == (rx_local->local_psr_full & 0x1FFF))
		/* Looks like this ring is not updated yet */
		return NULL;

	/* The packet status ring indicates that data is available. */
	psr = (struct pkt_stat_desc *) (rx_local->pPSRingVa) +
			(rx_local->local_psr_full & 0xFFF);

	/* Grab any information that is required once the PSR is
	 * advanced, since we can no longer rely on the memory being
	 * accurate
	 */
	len = psr->word1 & 0xFFFF;
	rindex = (psr->word1 >> 26) & 0x03;
	bindex = (psr->word1 >> 16) & 0x3FF;
	word0 = psr->word0;

	/* Indicate that we have used this PSR entry. */
	/* FIXME wrap 12 */
	add_12bit(&rx_local->local_psr_full, 1);
	if ((rx_local->local_psr_full & 0xFFF)  > rx_local->PsrNumEntries - 1) {
		/* Clear psr full and toggle the wrap bit */
		rx_local->local_psr_full &=  ~0xFFF;
		rx_local->local_psr_full ^= 0x1000;
	}

	writel(rx_local->local_psr_full,
	       &etdev->regs->rxdma.psr_full_offset);

#ifndef USE_FBR0
	if (rindex != 1)
		return NULL;
#endif

#ifdef USE_FBR0
	if (rindex > 1 ||
		(rindex == 0 &&
		bindex > rx_local->Fbr0NumEntries - 1) ||
		(rindex == 1 &&
		bindex > rx_local->Fbr1NumEntries - 1))
#else
	if (rindex != 1 || bindex > rx_local->Fbr1NumEntries - 1)
#endif
	{
		/* Illegal buffer or ring index cannot be used by S/W*/
		dev_err(&etdev->pdev->dev,
			  "NICRxPkts PSR Entry %d indicates "
			  "length of %d and/or bad bi(%d)\n",
			  rx_local->local_psr_full & 0xFFF,
			  len, bindex);
		return NULL;
	}

	/* Get and fill the RFD. */
	spin_lock_irqsave(&etdev->RcvLock, flags);

	rfd = NULL;
	element = rx_local->RecvList.next;
	rfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);

	if (rfd == NULL) {
		spin_unlock_irqrestore(&etdev->RcvLock, flags);
		return NULL;
	}

	list_del(&rfd->list_node);
	rx_local->nReadyRecv--;

	spin_unlock_irqrestore(&etdev->RcvLock, flags);

	rfd->bufferindex = bindex;
	rfd->ringindex = rindex;

	/* In V1 silicon, there is a bug which screws up filtering of
	 * runt packets.  Therefore runt packet filtering is disabled
	 * in the MAC and the packets are dropped here.  They are
	 * also counted here.
	 */
	if (len < (NIC_MIN_PACKET_SIZE + 4)) {
		etdev->Stats.other_errors++;
		len = 0;
	}

	if (len) {
		if (etdev->ReplicaPhyLoopbk == 1) {
			buf = rx_local->fbr[rindex]->virt[bindex];

			if (memcmp(&buf[6], &etdev->CurrentAddress[0],
				   ETH_ALEN) == 0) {
				if (memcmp(&buf[42], "Replica packet",
					   ETH_HLEN)) {
					etdev->ReplicaPhyLoopbkPF = 1;
				}
			}
		}

		/* Determine if this is a multicast packet coming in */
		if ((word0 & ALCATEL_MULTICAST_PKT) &&
		    !(word0 & ALCATEL_BROADCAST_PKT)) {
			/* Promiscuous mode and Multicast mode are
			 * not mutually exclusive as was first
			 * thought.  I guess Promiscuous is just
			 * considered a super-set of the other
			 * filters. Generally filter is 0x2b when in
			 * promiscuous mode.
			 */
			if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST)
			    && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS)
			    && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
				buf = rx_local->fbr[rindex]->
						virt[bindex];

				/* Loop through our list to see if the
				 * destination address of this packet
				 * matches one in our list.
				 */
				for (i = 0;
				     i < etdev->MCAddressCount;
				     i++) {
					if (buf[0] ==
					    etdev->MCList[i][0]
					    && buf[1] ==
					    etdev->MCList[i][1]
					    && buf[2] ==
					    etdev->MCList[i][2]
					    && buf[3] ==
					    etdev->MCList[i][3]
					    && buf[4] ==
					    etdev->MCList[i][4]
					    && buf[5] ==
					    etdev->MCList[i][5]) {
						break;
					}
				}

				/* If our index is equal to the number
				 * of Multicast address we have, then
				 * this means we did not find this
				 * packet's matching address in our
				 * list.  Set the PacketSize to zero,
				 * so we free our RFD when we return
				 * from this function.
				 */
				if (i == etdev->MCAddressCount)
					len = 0;
			}

			if (len > 0)
				etdev->Stats.multircv++;
		} else if (word0 & ALCATEL_BROADCAST_PKT)
			etdev->Stats.brdcstrcv++;
		else
			/* Not sure what this counter measures in
			 * promiscuous mode. Perhaps we should check
			 * the MAC address to see if it is directed
			 * to us in promiscuous mode.
			 */
			etdev->Stats.unircv++;
	}

	if (len > 0) {
		struct sk_buff *skb = NULL;

		/* rfd->PacketSize = len - 4; */
		rfd->PacketSize = len;

		skb = dev_alloc_skb(rfd->PacketSize + 2);
		if (!skb) {
			dev_err(&etdev->pdev->dev,
				  "Couldn't alloc an SKB for Rx\n");
			return NULL;
		}

		etdev->net_stats.rx_bytes += rfd->PacketSize;

		memcpy(skb_put(skb, rfd->PacketSize),
		       rx_local->fbr[rindex]->virt[bindex],
		       rfd->PacketSize);

		skb->dev = etdev->netdev;
		skb->protocol = eth_type_trans(skb, etdev->netdev);
		skb->ip_summed = CHECKSUM_NONE;

		netif_rx(skb);
	} else {
		rfd->PacketSize = 0;
	}

	nic_return_rfd(etdev, rfd);
	return rfd;
}

/**
 * et131x_reset_recv - Reset the receive list
 * @etdev: pointer to our adapter
 *
 * Assumption, Rcv spinlock has been acquired.
 */
void et131x_reset_recv(struct et131x_adapter *etdev)
{
	WARN_ON(list_empty(&etdev->rx_ring.RecvList));

}

/**
 * et131x_handle_recv_interrupt - Interrupt handler for receive processing
 * @etdev: pointer to our adapter
 *
 * Assumption, Rcv spinlock has been acquired.
 */
void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
{
	PMP_RFD rfd = NULL;
	u32 count = 0;
	bool done = true;

	/* Process up to available RFD's */
	while (count < NUM_PACKETS_HANDLED) {
		if (list_empty(&etdev->rx_ring.RecvList)) {
			WARN_ON(etdev->rx_ring.nReadyRecv != 0);
			done = false;
			break;
		}

		rfd = nic_rx_pkts(etdev);

		if (rfd == NULL)
			break;

		/* Do not receive any packets until a filter has been set.
		 * Do not receive any packets until we have link.
		 * If length is zero, return the RFD in order to advance the
		 * Free buffer ring.
		 */
		if (!etdev->PacketFilter ||
		    !(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) ||
		    rfd->PacketSize == 0) {
			continue;
		}

		/* Increment the number of packets we received */
		etdev->Stats.ipackets++;

		/* Set the status on the packet, either resources or success */
		if (etdev->rx_ring.nReadyRecv < RFD_LOW_WATER_MARK) {
			dev_warn(&etdev->pdev->dev,
				    "RFD's are running out\n");
		}
		count++;
	}

	if (count == NUM_PACKETS_HANDLED || !done) {
		etdev->rx_ring.UnfinishedReceives = true;
		writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO,
		       &etdev->regs->global.watchdog_timer);
	} else
		/* Watchdog timer will disable itself if appropriate. */
		etdev->rx_ring.UnfinishedReceives = false;
}

static inline u32 bump_fbr(u32 *fbr, u32 limit)
{
	u32 v = *fbr;
	v++;
	/* This works for all cases where limit < 1024. The 1023 case
	   works because 1023++ is 1024 which means the if condition is not
	   taken but the carry of the bit into the wrap bit toggles the wrap
	   value correctly */
	if ((v & ET_DMA10_MASK) > limit) {
		v &= ~ET_DMA10_MASK;
		v ^= ET_DMA10_WRAP;
	}
	/* For the 1023 case */
	v &= (ET_DMA10_MASK|ET_DMA10_WRAP);
	*fbr = v;
	return v;
}

/**
 * NICReturnRFD - Recycle a RFD and put it back onto the receive list
 * @etdev: pointer to our adapter
 * @rfd: pointer to the RFD
 */
void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
{
	struct rx_ring *rx_local = &etdev->rx_ring;
	struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma;
	u16 bi = rfd->bufferindex;
	u8 ri = rfd->ringindex;
	unsigned long flags;

	/* We don't use any of the OOB data besides status. Otherwise, we
	 * need to clean up OOB data
	 */
	if (
#ifdef USE_FBR0
	    (ri == 0 && bi < rx_local->Fbr0NumEntries) ||
#endif
	    (ri == 1 && bi < rx_local->Fbr1NumEntries)) {
		spin_lock_irqsave(&etdev->FbrLock, flags);

		if (ri == 1) {
			struct fbr_desc *next =
			    (struct fbr_desc *) (rx_local->pFbr1RingVa) +
					 INDEX10(rx_local->local_Fbr1_full);

			/* Handle the Free Buffer Ring advancement here. Write
			 * the PA / Buffer Index for the returned buffer into
			 * the oldest (next to be freed)FBR entry
			 */
			next->addr_hi = rx_local->fbr[1]->bus_high[bi];
			next->addr_lo = rx_local->fbr[1]->bus_low[bi];
			next->word2 = bi;

			writel(bump_fbr(&rx_local->local_Fbr1_full,
				rx_local->Fbr1NumEntries - 1),
				&rx_dma->fbr1_full_offset);
		}
#ifdef USE_FBR0
		else {
			struct fbr_desc *next = (struct fbr_desc *)
				rx_local->pFbr0RingVa +
					INDEX10(rx_local->local_Fbr0_full);

			/* Handle the Free Buffer Ring advancement here. Write
			 * the PA / Buffer Index for the returned buffer into
			 * the oldest (next to be freed) FBR entry
			 */
			next->addr_hi = rx_local->fbr[0]->bus_high[bi];
			next->addr_lo = rx_local->fbr[0]->bus_low[bi];
			next->word2 = bi;

			writel(bump_fbr(&rx_local->local_Fbr0_full,
					rx_local->Fbr0NumEntries - 1),
			       &rx_dma->fbr0_full_offset);
		}
#endif
		spin_unlock_irqrestore(&etdev->FbrLock, flags);
	} else {
		dev_err(&etdev->pdev->dev,
			  "NICReturnRFD illegal Buffer Index returned\n");
	}

	/* The processing on this RFD is done, so put it back on the tail of
	 * our list
	 */
	spin_lock_irqsave(&etdev->RcvLock, flags);
	list_add_tail(&rfd->list_node, &rx_local->RecvList);
	rx_local->nReadyRecv++;
	spin_unlock_irqrestore(&etdev->RcvLock, flags);

	WARN_ON(rx_local->nReadyRecv > rx_local->NumRfd);
}
