/*
 * WUSB Wire Adapter: WLP interface
 * Driver for the Linux Network stack.
 *
 * Copyright (C) 2005-2006 Intel Corporation
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 *
 * i1480u's RX handling is simple. i1480u will send the received
 * network packets broken up in fragments; 1 to N fragments make a
 * packet, we assemble them together and deliver the packet with netif_rx().
 *
 * Beacuse each USB transfer is a *single* fragment (except when the
 * transfer contains a first fragment), each URB called thus
 * back contains one or two fragments. So we queue N URBs, each with its own
 * fragment buffer. When a URB is done, we process it (adding to the
 * current skb from the fragment buffer until complete). Once
 * processed, we requeue the URB. There is always a bunch of URBs
 * ready to take data, so the intergap should be minimal.
 *
 * An URB's transfer buffer is the data field of a socket buffer. This
 * reduces copying as data can be passed directly to network layer. If a
 * complete packet or 1st fragment is received the URB's transfer buffer is
 * taken away from it and used to send data to the network layer. In this
 * case a new transfer buffer is allocated to the URB before being requeued.
 * If a "NEXT" or "LAST" fragment is received, the fragment contents is
 * appended to the RX packet under construction and the transfer buffer
 * is reused. To be able to use this buffer to assemble complete packets
 * we set each buffer's size to that of the MAX ethernet packet that can
 * be received. There is thus room for improvement in memory usage.
 *
 * When the max tx fragment size increases, we should be able to read
 * data into the skbs directly with very simple code.
 *
 * ROADMAP:
 *
 *   ENTRY POINTS:
 *
 *     i1480u_rx_setup(): setup RX context [from i1480u_open()]
 *
 *     i1480u_rx_release(): release RX context [from i1480u_stop()]
 *
 *     i1480u_rx_cb(): called when the RX USB URB receives a
 *                     packet. It removes the header and pushes it up
 *                     the Linux netdev stack with netif_rx().
 *
 *       i1480u_rx_buffer()
 *         i1480u_drop() and i1480u_fix()
 *         i1480u_skb_deliver
 *
 */

#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include "i1480u-wlp.h"

/*
 * Setup the RX context
 *
 * Each URB is provided with a transfer_buffer that is the data field
 * of a new socket buffer.
 */
int i1480u_rx_setup(struct i1480u *i1480u)
{
	int result, cnt;
	struct device *dev = &i1480u->usb_iface->dev;
	struct net_device *net_dev = i1480u->net_dev;
	struct usb_endpoint_descriptor *epd;
	struct sk_buff *skb;

	/* Alloc RX stuff */
	i1480u->rx_skb = NULL;	/* not in process of receiving packet */
	result = -ENOMEM;
	epd = &i1480u->usb_iface->cur_altsetting->endpoint[1].desc;
	for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
		struct i1480u_rx_buf *rx_buf = &i1480u->rx_buf[cnt];
		rx_buf->i1480u = i1480u;
		skb = dev_alloc_skb(i1480u_MAX_RX_PKT_SIZE);
		if (!skb) {
			dev_err(dev,
				"RX: cannot allocate RX buffer %d\n", cnt);
			result = -ENOMEM;
			goto error;
		}
		skb->dev = net_dev;
		skb->ip_summed = CHECKSUM_NONE;
		skb_reserve(skb, 2);
		rx_buf->data = skb;
		rx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
		if (unlikely(rx_buf->urb == NULL)) {
			dev_err(dev, "RX: cannot allocate URB %d\n", cnt);
			result = -ENOMEM;
			goto error;
		}
		usb_fill_bulk_urb(rx_buf->urb, i1480u->usb_dev,
			  usb_rcvbulkpipe(i1480u->usb_dev, epd->bEndpointAddress),
			  rx_buf->data->data, i1480u_MAX_RX_PKT_SIZE - 2,
			  i1480u_rx_cb, rx_buf);
		result = usb_submit_urb(rx_buf->urb, GFP_NOIO);
		if (unlikely(result < 0)) {
			dev_err(dev, "RX: cannot submit URB %d: %d\n",
				cnt, result);
			goto error;
		}
	}
	return 0;

error:
	i1480u_rx_release(i1480u);
	return result;
}


/* Release resources associated to the rx context */
void i1480u_rx_release(struct i1480u *i1480u)
{
	int cnt;
	for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
		if (i1480u->rx_buf[cnt].data)
			dev_kfree_skb(i1480u->rx_buf[cnt].data);
		if (i1480u->rx_buf[cnt].urb) {
			usb_kill_urb(i1480u->rx_buf[cnt].urb);
			usb_free_urb(i1480u->rx_buf[cnt].urb);
		}
	}
	if (i1480u->rx_skb != NULL)
		dev_kfree_skb(i1480u->rx_skb);
}

static
void i1480u_rx_unlink_urbs(struct i1480u *i1480u)
{
	int cnt;
	for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
		if (i1480u->rx_buf[cnt].urb)
			usb_unlink_urb(i1480u->rx_buf[cnt].urb);
	}
}

/* Fix an out-of-sequence packet */
#define i1480u_fix(i1480u, msg...)			\
do {							\
	if (printk_ratelimit())				\
		dev_err(&i1480u->usb_iface->dev, msg);	\
	dev_kfree_skb_irq(i1480u->rx_skb);		\
	i1480u->rx_skb = NULL;				\
	i1480u->rx_untd_pkt_size = 0;			\
} while (0)


/* Drop an out-of-sequence packet */
#define i1480u_drop(i1480u, msg...)			\
do {							\
	if (printk_ratelimit())				\
		dev_err(&i1480u->usb_iface->dev, msg);	\
	i1480u->net_dev->stats.rx_dropped++;			\
} while (0)




/* Finalizes setting up the SKB and delivers it
 *
 * We first pass the incoming frame to WLP substack for verification. It
 * may also be a WLP association frame in which case WLP will take over the
 * processing. If WLP does not take it over it will still verify it, if the
 * frame is invalid the skb will be freed by WLP and we will not continue
 * parsing.
 * */
static
void i1480u_skb_deliver(struct i1480u *i1480u)
{
	int should_parse;
	struct net_device *net_dev = i1480u->net_dev;
	struct device *dev = &i1480u->usb_iface->dev;

	should_parse = wlp_receive_frame(dev, &i1480u->wlp, i1480u->rx_skb,
					 &i1480u->rx_srcaddr);
	if (!should_parse)
		goto out;
	i1480u->rx_skb->protocol = eth_type_trans(i1480u->rx_skb, net_dev);
	net_dev->stats.rx_packets++;
	net_dev->stats.rx_bytes += i1480u->rx_untd_pkt_size;

	netif_rx(i1480u->rx_skb);		/* deliver */
out:
	i1480u->rx_skb = NULL;
	i1480u->rx_untd_pkt_size = 0;
}


/*
 * Process a buffer of data received from the USB RX endpoint
 *
 * First fragment arrives with next or last fragment. All other fragments
 * arrive alone.
 *
 * /me hates long functions.
 */
static
void i1480u_rx_buffer(struct i1480u_rx_buf *rx_buf)
{
	unsigned pkt_completed = 0;	/* !0 when we got all pkt fragments */
	size_t untd_hdr_size, untd_frg_size;
	size_t i1480u_hdr_size;
	struct wlp_rx_hdr *i1480u_hdr = NULL;

	struct i1480u *i1480u = rx_buf->i1480u;
	struct sk_buff *skb = rx_buf->data;
	int size_left = rx_buf->urb->actual_length;
	void *ptr = rx_buf->urb->transfer_buffer; /* also rx_buf->data->data */
	struct untd_hdr *untd_hdr;

	struct net_device *net_dev = i1480u->net_dev;
	struct device *dev = &i1480u->usb_iface->dev;
	struct sk_buff *new_skb;

#if 0
	dev_fnstart(dev,
		    "(i1480u %p ptr %p size_left %zu)\n", i1480u, ptr, size_left);
	dev_err(dev, "RX packet, %zu bytes\n", size_left);
	dump_bytes(dev, ptr, size_left);
#endif
	i1480u_hdr_size = sizeof(struct wlp_rx_hdr);

	while (size_left > 0) {
		if (pkt_completed) {
			i1480u_drop(i1480u, "RX: fragment follows completed"
					 "packet in same buffer. Dropping\n");
			break;
		}
		untd_hdr = ptr;
		if (size_left < sizeof(*untd_hdr)) {	/*  Check the UNTD header */
			i1480u_drop(i1480u, "RX: short UNTD header! Dropping\n");
			goto out;
		}
		if (unlikely(untd_hdr_rx_tx(untd_hdr) == 0)) {	/* Paranoia: TX set? */
			i1480u_drop(i1480u, "RX: TX bit set! Dropping\n");
			goto out;
		}
		switch (untd_hdr_type(untd_hdr)) {	/* Check the UNTD header type */
		case i1480u_PKT_FRAG_1ST: {
			struct untd_hdr_1st *untd_hdr_1st = (void *) untd_hdr;
			dev_dbg(dev, "1st fragment\n");
			untd_hdr_size = sizeof(struct untd_hdr_1st);
			if (i1480u->rx_skb != NULL)
				i1480u_fix(i1480u, "RX: 1st fragment out of "
					"sequence! Fixing\n");
			if (size_left < untd_hdr_size + i1480u_hdr_size) {
				i1480u_drop(i1480u, "RX: short 1st fragment! "
					"Dropping\n");
				goto out;
			}
			i1480u->rx_untd_pkt_size = le16_to_cpu(untd_hdr->len)
						 - i1480u_hdr_size;
			untd_frg_size = le16_to_cpu(untd_hdr_1st->fragment_len);
			if (size_left < untd_hdr_size + untd_frg_size) {
				i1480u_drop(i1480u,
					    "RX: short payload! Dropping\n");
				goto out;
			}
			i1480u->rx_skb = skb;
			i1480u_hdr = (void *) untd_hdr_1st + untd_hdr_size;
			i1480u->rx_srcaddr = i1480u_hdr->srcaddr;
			skb_put(i1480u->rx_skb, untd_hdr_size + untd_frg_size);
			skb_pull(i1480u->rx_skb, untd_hdr_size + i1480u_hdr_size);
			stats_add_sample(&i1480u->lqe_stats, (s8) i1480u_hdr->LQI - 7);
			stats_add_sample(&i1480u->rssi_stats, i1480u_hdr->RSSI + 18);
			rx_buf->data = NULL; /* need to create new buffer */
			break;
		}
		case i1480u_PKT_FRAG_NXT: {
			dev_dbg(dev, "nxt fragment\n");
			untd_hdr_size = sizeof(struct untd_hdr_rst);
			if (i1480u->rx_skb == NULL) {
				i1480u_drop(i1480u, "RX: next fragment out of "
					    "sequence! Dropping\n");
				goto out;
			}
			if (size_left < untd_hdr_size) {
				i1480u_drop(i1480u, "RX: short NXT fragment! "
					    "Dropping\n");
				goto out;
			}
			untd_frg_size = le16_to_cpu(untd_hdr->len);
			if (size_left < untd_hdr_size + untd_frg_size) {
				i1480u_drop(i1480u,
					    "RX: short payload! Dropping\n");
				goto out;
			}
			memmove(skb_put(i1480u->rx_skb, untd_frg_size),
					ptr + untd_hdr_size, untd_frg_size);
			break;
		}
		case i1480u_PKT_FRAG_LST: {
			dev_dbg(dev, "Lst fragment\n");
			untd_hdr_size = sizeof(struct untd_hdr_rst);
			if (i1480u->rx_skb == NULL) {
				i1480u_drop(i1480u, "RX: last fragment out of "
					    "sequence! Dropping\n");
				goto out;
			}
			if (size_left < untd_hdr_size) {
				i1480u_drop(i1480u, "RX: short LST fragment! "
					    "Dropping\n");
				goto out;
			}
			untd_frg_size = le16_to_cpu(untd_hdr->len);
			if (size_left < untd_frg_size + untd_hdr_size) {
				i1480u_drop(i1480u,
					    "RX: short payload! Dropping\n");
				goto out;
			}
			memmove(skb_put(i1480u->rx_skb, untd_frg_size),
					ptr + untd_hdr_size, untd_frg_size);
			pkt_completed = 1;
			break;
		}
		case i1480u_PKT_FRAG_CMP: {
			dev_dbg(dev, "cmp fragment\n");
			untd_hdr_size = sizeof(struct untd_hdr_cmp);
			if (i1480u->rx_skb != NULL)
				i1480u_fix(i1480u, "RX: fix out-of-sequence CMP"
					   " fragment!\n");
			if (size_left < untd_hdr_size + i1480u_hdr_size) {
				i1480u_drop(i1480u, "RX: short CMP fragment! "
					    "Dropping\n");
				goto out;
			}
			i1480u->rx_untd_pkt_size = le16_to_cpu(untd_hdr->len);
			untd_frg_size = i1480u->rx_untd_pkt_size;
			if (size_left < i1480u->rx_untd_pkt_size + untd_hdr_size) {
				i1480u_drop(i1480u,
					    "RX: short payload! Dropping\n");
				goto out;
			}
			i1480u->rx_skb = skb;
			i1480u_hdr = (void *) untd_hdr + untd_hdr_size;
			i1480u->rx_srcaddr = i1480u_hdr->srcaddr;
			stats_add_sample(&i1480u->lqe_stats, (s8) i1480u_hdr->LQI - 7);
			stats_add_sample(&i1480u->rssi_stats, i1480u_hdr->RSSI + 18);
			skb_put(i1480u->rx_skb, untd_hdr_size + i1480u->rx_untd_pkt_size);
			skb_pull(i1480u->rx_skb, untd_hdr_size + i1480u_hdr_size);
			rx_buf->data = NULL;	/* for hand off skb to network stack */
			pkt_completed = 1;
			i1480u->rx_untd_pkt_size -= i1480u_hdr_size; /* accurate stat */
			break;
		}
		default:
			i1480u_drop(i1480u, "RX: unknown packet type %u! "
				    "Dropping\n", untd_hdr_type(untd_hdr));
			goto out;
		}
		size_left -= untd_hdr_size + untd_frg_size;
		if (size_left > 0)
			ptr += untd_hdr_size + untd_frg_size;
	}
	if (pkt_completed)
		i1480u_skb_deliver(i1480u);
out:
	/* recreate needed RX buffers*/
	if (rx_buf->data == NULL) {
		/* buffer is being used to receive packet, create new */
		new_skb = dev_alloc_skb(i1480u_MAX_RX_PKT_SIZE);
		if (!new_skb) {
			if (printk_ratelimit())
				dev_err(dev,
				"RX: cannot allocate RX buffer\n");
		} else {
			new_skb->dev = net_dev;
			new_skb->ip_summed = CHECKSUM_NONE;
			skb_reserve(new_skb, 2);
			rx_buf->data = new_skb;
		}
	}
	return;
}


/*
 * Called when an RX URB has finished receiving or has found some kind
 * of error condition.
 *
 * LIMITATIONS:
 *
 *  - We read USB-transfers, each transfer contains a SINGLE fragment
 *    (can contain a complete packet, or a 1st, next, or last fragment
 *    of a packet).
 *    Looks like a transfer can contain more than one fragment (07/18/06)
 *
 *  - Each transfer buffer is the size of the maximum packet size (minus
 *    headroom), i1480u_MAX_PKT_SIZE - 2
 *
 *  - We always read the full USB-transfer, no partials.
 *
 *  - Each transfer is read directly into a skb. This skb will be used to
 *    send data to the upper layers if it is the first fragment or a complete
 *    packet. In the other cases the data will be copied from the skb to
 *    another skb that is being prepared for the upper layers from a prev
 *    first fragment.
 *
 * It is simply too much of a pain. Gosh, there should be a unified
 * SG infrastructure for *everything* [so that I could declare a SG
 * buffer, pass it to USB for receiving, append some space to it if
 * I wish, receive more until I have the whole chunk, adapt
 * pointers on each fragment to remove hardware headers and then
 * attach that to an skbuff and netif_rx()].
 */
void i1480u_rx_cb(struct urb *urb)
{
	int result;
	int do_parse_buffer = 1;
	struct i1480u_rx_buf *rx_buf = urb->context;
	struct i1480u *i1480u = rx_buf->i1480u;
	struct device *dev = &i1480u->usb_iface->dev;
	unsigned long flags;
	u8 rx_buf_idx = rx_buf - i1480u->rx_buf;

	switch (urb->status) {
	case 0:
		break;
	case -ECONNRESET:	/* Not an error, but a controlled situation; */
	case -ENOENT:		/* (we killed the URB)...so, no broadcast */
	case -ESHUTDOWN:	/* going away! */
		dev_err(dev, "RX URB[%u]: goind down %d\n",
			rx_buf_idx, urb->status);
		goto error;
	default:
		dev_err(dev, "RX URB[%u]: unknown status %d\n",
			rx_buf_idx, urb->status);
		if (edc_inc(&i1480u->rx_errors, EDC_MAX_ERRORS,
					EDC_ERROR_TIMEFRAME)) {
			dev_err(dev, "RX: max acceptable errors exceeded,"
					" resetting device.\n");
			i1480u_rx_unlink_urbs(i1480u);
			wlp_reset_all(&i1480u->wlp);
			goto error;
		}
		do_parse_buffer = 0;
		break;
	}
	spin_lock_irqsave(&i1480u->lock, flags);
	/* chew the data fragments, extract network packets */
	if (do_parse_buffer) {
		i1480u_rx_buffer(rx_buf);
		if (rx_buf->data) {
			rx_buf->urb->transfer_buffer = rx_buf->data->data;
			result = usb_submit_urb(rx_buf->urb, GFP_ATOMIC);
			if (result < 0) {
				dev_err(dev, "RX URB[%u]: cannot submit %d\n",
					rx_buf_idx, result);
			}
		}
	}
	spin_unlock_irqrestore(&i1480u->lock, flags);
error:
	return;
}

