/*
 * WiMedia Logical Link Control Protocol (WLP)
 * Message exchange infrastructure
 *
 * Copyright (C) 2007 Intel Corporation
 * Reinette Chatre <reinette.chatre@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.
 *
 *
 * FIXME: Docs
 *
 */

#include <linux/etherdevice.h>
#include <linux/wlp.h>
#define D_LOCAL 5
#include <linux/uwb/debug.h>
#include "wlp-internal.h"


/**
 * Direct incoming association msg to correct parsing routine
 *
 * We only expect D1, E1, C1, C3 messages as new. All other incoming
 * association messages should form part of an established session that is
 * handled elsewhere.
 * The handling of these messages often require calling sleeping functions
 * - this cannot be done in interrupt context. We use the kernel's
 * workqueue to handle these messages.
 */
static
void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
			   struct uwb_dev_addr *src)
{
	struct device *dev = &wlp->rc->uwb_dev.dev;
	struct wlp_frame_assoc *assoc = (void *) skb->data;
	struct wlp_assoc_frame_ctx *frame_ctx;
	d_fnstart(5, dev, "wlp %p, skb %p\n", wlp, skb);
	frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC);
	if (frame_ctx == NULL) {
		dev_err(dev, "WLP: Unable to allocate memory for association "
			"frame handling.\n");
		kfree_skb(skb);
		goto out;
	}
	frame_ctx->wlp = wlp;
	frame_ctx->skb = skb;
	frame_ctx->src = *src;
	switch (assoc->type) {
	case WLP_ASSOC_D1:
		d_printf(5, dev, "Received a D1 frame.\n");
		INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame);
		schedule_work(&frame_ctx->ws);
		break;
	case WLP_ASSOC_E1:
		d_printf(5, dev, "Received a E1 frame. FIXME?\n");
		kfree_skb(skb); /* Temporary until we handle it */
		kfree(frame_ctx); /* Temporary until we handle it */
		break;
	case WLP_ASSOC_C1:
		d_printf(5, dev, "Received a C1 frame.\n");
		INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame);
		schedule_work(&frame_ctx->ws);
		break;
	case WLP_ASSOC_C3:
		d_printf(5, dev, "Received a C3 frame.\n");
		INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame);
		schedule_work(&frame_ctx->ws);
		break;
	default:
		dev_err(dev, "Received unexpected association frame. "
			"Type = %d \n", assoc->type);
		kfree_skb(skb);
		kfree(frame_ctx);
		break;
	}
out:
	d_fnend(5, dev, "wlp %p\n", wlp);
}

/**
 * Process incoming association frame
 *
 * Although it could be possible to deal with some incoming association
 * messages without creating a new session we are keeping things simple. We
 * do not accept new association messages if there is a session in progress
 * and the messages do not belong to that session.
 *
 * If an association message arrives that causes the creation of a session
 * (WLP_ASSOC_E1) while we are in the process of creating a session then we
 * rely on the neighbor mutex to protect the data. That is, the new session
 * will not be started until the previous is completed.
 */
static
void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
			     struct uwb_dev_addr *src)
{
	struct device *dev = &wlp->rc->uwb_dev.dev;
	struct wlp_frame_assoc *assoc = (void *) skb->data;
	struct wlp_session *session = wlp->session;
	u8 version;
	d_fnstart(5, dev, "wlp %p, skb %p\n", wlp, skb);

	if (wlp_get_version(wlp, &assoc->version, &version,
			    sizeof(assoc->version)) < 0)
		goto error;
	if (version != WLP_VERSION) {
		dev_err(dev, "Unsupported WLP version in association "
			"message.\n");
		goto error;
	}
	if (session != NULL) {
		/* Function that created this session is still holding the
		 * &wlp->mutex to protect this session. */
		if (assoc->type == session->exp_message ||
		    assoc->type == WLP_ASSOC_F0) {
			if (!memcmp(&session->neighbor_addr, src,
				   sizeof(*src))) {
				session->data = skb;
				(session->cb)(wlp);
			} else {
				dev_err(dev, "Received expected message from "
					"unexpected source.  Expected message "
					"%d or F0 from %02x:%02x, but received "
					"it from %02x:%02x. Dropping.\n",
					session->exp_message,
					session->neighbor_addr.data[1],
					session->neighbor_addr.data[0],
					src->data[1], src->data[0]);
				goto error;
			}
		} else {
			dev_err(dev, "Association already in progress. "
				"Dropping.\n");
			goto error;
		}
	} else {
		wlp_direct_assoc_frame(wlp, skb, src);
	}
	d_fnend(5, dev, "wlp %p\n", wlp);
	return;
error:
	kfree_skb(skb);
	d_fnend(5, dev, "wlp %p\n", wlp);
}

/**
 * Verify incoming frame is from connected neighbor, prep to pass to WLP client
 *
 * Verification proceeds according to WLP 0.99 [7.3.1]. The source address
 * is used to determine which neighbor is sending the frame and the WSS tag
 * is used to know to which WSS the frame belongs (we only support one WSS
 * so this test is straight forward).
 * With the WSS found we need to ensure that we are connected before
 * allowing the exchange of data frames.
 */
static
int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb,
			     struct uwb_dev_addr *src)
{
	struct device *dev = &wlp->rc->uwb_dev.dev;
	int result = -EINVAL;
	struct wlp_eda_node eda_entry;
	struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data;

	d_fnstart(6, dev, "wlp %p, skb %p \n", wlp, skb);
	/*verify*/
	result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry);
	if (result < 0) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Incoming frame is from unknown "
				"neighbor %02x:%02x.\n", src->data[1],
				src->data[0]);
		goto out;
	}
	if (hdr->tag != eda_entry.tag) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Tag of incoming frame from "
				"%02x:%02x does not match expected tag. "
				"Received 0x%02x, expected 0x%02x. \n",
				src->data[1], src->data[0], hdr->tag,
				eda_entry.tag);
		result = -EINVAL;
		goto out;
	}
	if (eda_entry.state != WLP_WSS_CONNECTED) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Incoming frame from "
				"%02x:%02x does is not from connected WSS.\n",
				src->data[1], src->data[0]);
		result = -EINVAL;
		goto out;
	}
	/*prep*/
	skb_pull(skb, sizeof(*hdr));
out:
	d_fnend(6, dev, "wlp %p, skb %p, result = %d \n", wlp, skb, result);
	return result;
}

/**
 * Receive a WLP frame from device
 *
 * @returns: 1 if calling function should free the skb
 *           0 if it successfully handled skb and freed it
 *           0 if error occured, will free skb in this case
 */
int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb,
		      struct uwb_dev_addr *src)
{
	unsigned len = skb->len;
	void *ptr = skb->data;
	struct wlp_frame_hdr *hdr;
	int result = 0;

	d_fnstart(6, dev, "skb (%p), len (%u)\n", skb, len);
	if (len < sizeof(*hdr)) {
		dev_err(dev, "Not enough data to parse WLP header.\n");
		result = -EINVAL;
		goto out;
	}
	hdr = ptr;
	d_dump(6, dev, hdr, sizeof(*hdr));
	if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) {
		dev_err(dev, "Not a WLP frame type.\n");
		result = -EINVAL;
		goto out;
	}
	switch (hdr->type) {
	case WLP_FRAME_STANDARD:
		if (len < sizeof(struct wlp_frame_std_abbrv_hdr)) {
			dev_err(dev, "Not enough data to parse Standard "
				"WLP header.\n");
			goto out;
		}
		result = wlp_verify_prep_rx_frame(wlp, skb, src);
		if (result < 0) {
			if (printk_ratelimit())
				dev_err(dev, "WLP: Verification of frame "
					"from neighbor %02x:%02x failed.\n",
					src->data[1], src->data[0]);
			goto out;
		}
		result = 1;
		break;
	case WLP_FRAME_ABBREVIATED:
		dev_err(dev, "Abbreviated frame received. FIXME?\n");
		kfree_skb(skb);
		break;
	case WLP_FRAME_CONTROL:
		dev_err(dev, "Control frame received. FIXME?\n");
		kfree_skb(skb);
		break;
	case WLP_FRAME_ASSOCIATION:
		if (len < sizeof(struct wlp_frame_assoc)) {
			dev_err(dev, "Not enough data to parse Association "
				"WLP header.\n");
			goto out;
		}
		d_printf(5, dev, "Association frame received.\n");
		wlp_receive_assoc_frame(wlp, skb, src);
		break;
	default:
		dev_err(dev, "Invalid frame received.\n");
		result = -EINVAL;
		break;
	}
out:
	if (result < 0) {
		kfree_skb(skb);
		result = 0;
	}
	d_fnend(6, dev, "skb (%p)\n", skb);
	return result;
}
EXPORT_SYMBOL_GPL(wlp_receive_frame);


/**
 * Verify frame from network stack, prepare for further transmission
 *
 * @skb:   the socket buffer that needs to be prepared for transmission (it
 *         is in need of a WLP header). If this is a broadcast frame we take
 *         over the entire transmission.
 *         If it is a unicast the WSS connection should already be established
 *         and transmission will be done by the calling function.
 * @dst:   On return this will contain the device address to which the
 *         frame is destined.
 * @returns: 0 on success no tx : WLP header sucessfully applied to skb buffer,
 *                                calling function can proceed with tx
 *           1 on success with tx : WLP will take over transmission of this
 *                                  frame
 *           <0 on error
 *
 * The network stack (WLP client) is attempting to transmit a frame. We can
 * only transmit data if a local WSS is at least active (connection will be
 * done here if this is a broadcast frame and neighbor also has the WSS
 * active).
 *
 * The frame can be either broadcast or unicast. Broadcast in a WSS is
 * supported via multicast, but we don't support multicast yet (until
 * devices start to support MAB IEs). If a broadcast frame needs to be
 * transmitted it is treated as a unicast frame to each neighbor. In this
 * case the WLP takes over transmission of the skb and returns 1
 * to the caller to indicate so. Also, in this case, if a neighbor has the
 * same WSS activated but is not connected then the WSS connection will be
 * done at this time. The neighbor's virtual address will be learned at
 * this time.
 *
 * The destination address in a unicast frame is the virtual address of the
 * neighbor. This address only becomes known when a WSS connection is
 * established. We thus rely on a broadcast frame to trigger the setup of
 * WSS connections to all neighbors before we are able to send unicast
 * frames to them. This seems reasonable as IP would usually use ARP first
 * before any unicast frames are sent.
 *
 * If we are already connected to the neighbor (neighbor's virtual address
 * is known) we just prepare the WLP header and the caller will continue to
 * send the frame.
 *
 * A failure in this function usually indicates something that cannot be
 * fixed automatically. So, if this function fails (@return < 0) the calling
 * function should not retry to send the frame as it will very likely keep
 * failing.
 *
 */
int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp,
			 struct sk_buff *skb, struct uwb_dev_addr *dst)
{
	int result = -EINVAL;
	struct ethhdr *eth_hdr = (void *) skb->data;

	d_fnstart(6, dev, "wlp (%p), skb (%p) \n", wlp, skb);
	if (is_broadcast_ether_addr(eth_hdr->h_dest)) {
		d_printf(6, dev, "WLP: handling broadcast frame. \n");
		result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb);
		if (result < 0) {
			if (printk_ratelimit())
				dev_err(dev, "Unable to handle broadcast "
					"frame from WLP client.\n");
			goto out;
		}
		dev_kfree_skb_irq(skb);
		result = 1;
		/* Frame will be transmitted by WLP. */
	} else {
		d_printf(6, dev, "WLP: handling unicast frame. \n");
		result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst,
					     wlp_wss_prep_hdr, skb);
		if (unlikely(result < 0)) {
			if (printk_ratelimit())
				dev_err(dev, "Unable to prepare "
					"skb for transmission. \n");
			goto out;
		}
	}
out:
	d_fnend(6, dev, "wlp (%p), skb (%p). result = %d \n", wlp, skb, result);
	return result;
}
EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame);
