/*
 *  Copyright (C) 2002 Intersil Americas Inc.
 *  Copyright 2004 Jens Maurer <Jens.Maurer@gmx.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/slab.h>

#include <asm/io.h>
#include <linux/if_arp.h>

#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_mgt.h"
#include "isl_oid.h"		/* additional types and defs for isl38xx fw */
#include "isl_ioctl.h"

#include <net/iw_handler.h>

/******************************************************************************
        Global variable definition section
******************************************************************************/
int pc_debug = VERBOSE;
module_param(pc_debug, int, 0);

/******************************************************************************
    Driver general functions
******************************************************************************/
#if VERBOSE > SHOW_ERROR_MESSAGES
void
display_buffer(char *buffer, int length)
{
	if ((pc_debug & SHOW_BUFFER_CONTENTS) == 0)
		return;

	while (length > 0) {
		printk("[%02x]", *buffer & 255);
		length--;
		buffer++;
	}

	printk("\n");
}
#endif

/*****************************************************************************
    Queue handling for management frames
******************************************************************************/

/*
 * Helper function to create a PIMFOR management frame header.
 */
static void
pimfor_encode_header(int operation, u32 oid, u32 length, pimfor_header_t *h)
{
	h->version = PIMFOR_VERSION;
	h->operation = operation;
	h->device_id = PIMFOR_DEV_ID_MHLI_MIB;
	h->flags = 0;
	h->oid = cpu_to_be32(oid);
	h->length = cpu_to_be32(length);
}

/*
 * Helper function to analyze a PIMFOR management frame header.
 */
static pimfor_header_t *
pimfor_decode_header(void *data, int len)
{
	pimfor_header_t *h = data;

	while ((void *) h < data + len) {
		if (h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) {
			le32_to_cpus(&h->oid);
			le32_to_cpus(&h->length);
		} else {
			be32_to_cpus(&h->oid);
			be32_to_cpus(&h->length);
		}
		if (h->oid != OID_INL_TUNNEL)
			return h;
		h++;
	}
	return NULL;
}

/*
 * Fill the receive queue for management frames with fresh buffers.
 */
int
islpci_mgmt_rx_fill(struct net_device *ndev)
{
	islpci_private *priv = netdev_priv(ndev);
	isl38xx_control_block *cb =	/* volatile not needed */
	    (isl38xx_control_block *) priv->control_block;
	u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]);

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill\n");
#endif

	while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) {
		u32 index = curr % ISL38XX_CB_MGMT_QSIZE;
		struct islpci_membuf *buf = &priv->mgmt_rx[index];
		isl38xx_fragment *frag = &cb->rx_data_mgmt[index];

		if (buf->mem == NULL) {
			buf->mem = kmalloc(MGMT_FRAME_SIZE, GFP_ATOMIC);
			if (!buf->mem)
				return -ENOMEM;
			buf->size = MGMT_FRAME_SIZE;
		}
		if (buf->pci_addr == 0) {
			buf->pci_addr = pci_map_single(priv->pdev, buf->mem,
						       MGMT_FRAME_SIZE,
						       PCI_DMA_FROMDEVICE);
			if (!buf->pci_addr) {
				printk(KERN_WARNING
				       "Failed to make memory DMA'able.\n");
				return -ENOMEM;
			}
		}

		/* be safe: always reset control block information */
		frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
		frag->flags = 0;
		frag->address = cpu_to_le32(buf->pci_addr);
		curr++;

		/* The fragment address in the control block must have
		 * been written before announcing the frame buffer to
		 * device */
		wmb();
		cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = cpu_to_le32(curr);
	}
	return 0;
}

/*
 * Create and transmit a management frame using "operation" and "oid",
 * with arguments data/length.
 * We either return an error and free the frame, or we return 0 and
 * islpci_mgt_cleanup_transmit() frees the frame in the tx-done
 * interrupt.
 */
static int
islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
		    void *data, int length)
{
	islpci_private *priv = netdev_priv(ndev);
	isl38xx_control_block *cb =
	    (isl38xx_control_block *) priv->control_block;
	void *p;
	int err = -EINVAL;
	unsigned long flags;
	isl38xx_fragment *frag;
	struct islpci_membuf buf;
	u32 curr_frag;
	int index;
	int frag_len = length + PIMFOR_HEADER_SIZE;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_transmit\n");
#endif

	if (frag_len > MGMT_FRAME_SIZE) {
		printk(KERN_DEBUG "%s: mgmt frame too large %d\n",
		       ndev->name, frag_len);
		goto error;
	}

	err = -ENOMEM;
	p = buf.mem = kmalloc(frag_len, GFP_KERNEL);
	if (!buf.mem)
		goto error;

	buf.size = frag_len;

	/* create the header directly in the fragment data area */
	pimfor_encode_header(operation, oid, length, (pimfor_header_t *) p);
	p += PIMFOR_HEADER_SIZE;

	if (data)
		memcpy(p, data, length);
	else
		memset(p, 0, length);

#if VERBOSE > SHOW_ERROR_MESSAGES
	{
		pimfor_header_t *h = buf.mem;
		DEBUG(SHOW_PIMFOR_FRAMES,
		      "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x\n",
		      h->operation, oid, h->device_id, h->flags, length);

		/* display the buffer contents for debugging */
		display_buffer((char *) h, sizeof (pimfor_header_t));
		display_buffer(p, length);
	}
#endif

	err = -ENOMEM;
	buf.pci_addr = pci_map_single(priv->pdev, buf.mem, frag_len,
				      PCI_DMA_TODEVICE);
	if (!buf.pci_addr) {
		printk(KERN_WARNING "%s: cannot map PCI memory for mgmt\n",
		       ndev->name);
		goto error_free;
	}

	/* Protect the control block modifications against interrupts. */
	spin_lock_irqsave(&priv->slock, flags);
	curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ]);
	if (curr_frag - priv->index_mgmt_tx >= ISL38XX_CB_MGMT_QSIZE) {
		printk(KERN_WARNING "%s: mgmt tx queue is still full\n",
		       ndev->name);
		goto error_unlock;
	}

	/* commit the frame to the tx device queue */
	index = curr_frag % ISL38XX_CB_MGMT_QSIZE;
	priv->mgmt_tx[index] = buf;
	frag = &cb->tx_data_mgmt[index];
	frag->size = cpu_to_le16(frag_len);
	frag->flags = 0;	/* for any other than the last fragment, set to 1 */
	frag->address = cpu_to_le32(buf.pci_addr);

	/* The fragment address in the control block must have
	 * been written before announcing the frame buffer to
	 * device */
	wmb();
	cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag + 1);
	spin_unlock_irqrestore(&priv->slock, flags);

	/* trigger the device */
	islpci_trigger(priv);
	return 0;

      error_unlock:
	spin_unlock_irqrestore(&priv->slock, flags);
      error_free:
	kfree(buf.mem);
      error:
	return err;
}

/*
 * Receive a management frame from the device.
 * This can be an arbitrary number of traps, and at most one response
 * frame for a previous request sent via islpci_mgt_transmit().
 */
int
islpci_mgt_receive(struct net_device *ndev)
{
	islpci_private *priv = netdev_priv(ndev);
	isl38xx_control_block *cb =
	    (isl38xx_control_block *) priv->control_block;
	u32 curr_frag;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive\n");
#endif

	/* Only once per interrupt, determine fragment range to
	 * process.  This avoids an endless loop (i.e. lockup) if
	 * frames come in faster than we can process them. */
	curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]);
	barrier();

	for (; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) {
		pimfor_header_t *header;
		u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE;
		struct islpci_membuf *buf = &priv->mgmt_rx[index];
		u16 frag_len;
		int size;
		struct islpci_mgmtframe *frame;

		/* I have no idea (and no documentation) if flags != 0
		 * is possible.  Drop the frame, reuse the buffer. */
		if (le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) {
			printk(KERN_WARNING "%s: unknown flags 0x%04x\n",
			       ndev->name,
			       le16_to_cpu(cb->rx_data_mgmt[index].flags));
			continue;
		}

		/* The device only returns the size of the header(s) here. */
		frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size);

		/*
		 * We appear to have no way to tell the device the
		 * size of a receive buffer.  Thus, if this check
		 * triggers, we likely have kernel heap corruption. */
		if (frag_len > MGMT_FRAME_SIZE) {
			printk(KERN_WARNING
				"%s: Bogus packet size of %d (%#x).\n",
				ndev->name, frag_len, frag_len);
			frag_len = MGMT_FRAME_SIZE;
		}

		/* Ensure the results of device DMA are visible to the CPU. */
		pci_dma_sync_single_for_cpu(priv->pdev, buf->pci_addr,
					    buf->size, PCI_DMA_FROMDEVICE);

		/* Perform endianess conversion for PIMFOR header in-place. */
		header = pimfor_decode_header(buf->mem, frag_len);
		if (!header) {
			printk(KERN_WARNING "%s: no PIMFOR header found\n",
			       ndev->name);
			continue;
		}

		/* The device ID from the PIMFOR packet received from
		 * the MVC is always 0.  We forward a sensible device_id.
		 * Not that anyone upstream would care... */
		header->device_id = priv->ndev->ifindex;

#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_PIMFOR_FRAMES,
		      "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x\n",
		      header->operation, header->oid, header->device_id,
		      header->flags, header->length);

		/* display the buffer contents for debugging */
		display_buffer((char *) header, PIMFOR_HEADER_SIZE);
		display_buffer((char *) header + PIMFOR_HEADER_SIZE,
			       header->length);
#endif

		/* nobody sends these */
		if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) {
			printk(KERN_DEBUG
			       "%s: errant PIMFOR application frame\n",
			       ndev->name);
			continue;
		}

		/* Determine frame size, skipping OID_INL_TUNNEL headers. */
		size = PIMFOR_HEADER_SIZE + header->length;
		frame = kmalloc(sizeof(struct islpci_mgmtframe) + size,
				GFP_ATOMIC);
		if (!frame)
			continue;

		frame->ndev = ndev;
		memcpy(&frame->buf, header, size);
		frame->header = (pimfor_header_t *) frame->buf;
		frame->data = frame->buf + PIMFOR_HEADER_SIZE;

#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_PIMFOR_FRAMES,
		      "frame: header: %p, data: %p, size: %d\n",
		      frame->header, frame->data, size);
#endif

		if (header->operation == PIMFOR_OP_TRAP) {
#if VERBOSE > SHOW_ERROR_MESSAGES
			printk(KERN_DEBUG
			       "TRAP: oid 0x%x, device %i, flags 0x%x length %i\n",
			       header->oid, header->device_id, header->flags,
			       header->length);
#endif

			/* Create work to handle trap out of interrupt
			 * context. */
			INIT_WORK(&frame->ws, prism54_process_trap);
			schedule_work(&frame->ws);

		} else {
			/* Signal the one waiting process that a response
			 * has been received. */
			if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) {
				printk(KERN_WARNING
				       "%s: mgmt response not collected\n",
				       ndev->name);
				kfree(frame);
			}
#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING, "Wake up Mgmt Queue\n");
#endif
			wake_up(&priv->mgmt_wqueue);
		}

	}

	return 0;
}

/*
 * Cleanup the transmit queue by freeing all frames handled by the device.
 */
void
islpci_mgt_cleanup_transmit(struct net_device *ndev)
{
	islpci_private *priv = netdev_priv(ndev);
	isl38xx_control_block *cb =	/* volatile not needed */
	    (isl38xx_control_block *) priv->control_block;
	u32 curr_frag;

#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n");
#endif

	/* Only once per cleanup, determine fragment range to
	 * process.  This avoids an endless loop (i.e. lockup) if
	 * the device became confused, incrementing device_curr_frag
	 * rapidly. */
	curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]);
	barrier();

	for (; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) {
		int index = priv->index_mgmt_tx % ISL38XX_CB_MGMT_QSIZE;
		struct islpci_membuf *buf = &priv->mgmt_tx[index];
		pci_unmap_single(priv->pdev, buf->pci_addr, buf->size,
				 PCI_DMA_TODEVICE);
		buf->pci_addr = 0;
		kfree(buf->mem);
		buf->mem = NULL;
		buf->size = 0;
	}
}

/*
 * Perform one request-response transaction to the device.
 */
int
islpci_mgt_transaction(struct net_device *ndev,
		       int operation, unsigned long oid,
		       void *senddata, int sendlen,
		       struct islpci_mgmtframe **recvframe)
{
	islpci_private *priv = netdev_priv(ndev);
	const long wait_cycle_jiffies = msecs_to_jiffies(ISL38XX_WAIT_CYCLE * 10);
	long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
	int err;
	DEFINE_WAIT(wait);

	*recvframe = NULL;

	if (mutex_lock_interruptible(&priv->mgmt_lock))
		return -ERESTARTSYS;

	prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE);
	err = islpci_mgt_transmit(ndev, operation, oid, senddata, sendlen);
	if (err)
		goto out;

	err = -ETIMEDOUT;
	while (timeout_left > 0) {
		int timeleft;
		struct islpci_mgmtframe *frame;

		timeleft = schedule_timeout_uninterruptible(wait_cycle_jiffies);
		frame = xchg(&priv->mgmt_received, NULL);
		if (frame) {
			if (frame->header->oid == oid) {
				*recvframe = frame;
				err = 0;
				goto out;
			} else {
				printk(KERN_DEBUG
				       "%s: expecting oid 0x%x, received 0x%x.\n",
				       ndev->name, (unsigned int) oid,
				       frame->header->oid);
				kfree(frame);
				frame = NULL;
			}
		}
		if (timeleft == 0) {
			printk(KERN_DEBUG
				"%s: timeout waiting for mgmt response %lu, "
				"triggering device\n",
				ndev->name, timeout_left);
			islpci_trigger(priv);
		}
		timeout_left += timeleft - wait_cycle_jiffies;
	}
	printk(KERN_WARNING "%s: timeout waiting for mgmt response\n",
	       ndev->name);

	/* TODO: we should reset the device here */
 out:
	finish_wait(&priv->mgmt_wqueue, &wait);
	mutex_unlock(&priv->mgmt_lock);
	return err;
}

