/*
 * 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/slab.h>
#include <linux/wlp.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;

	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);
		return;
	}
	frame_ctx->wlp = wlp;
	frame_ctx->skb = skb;
	frame_ctx->src = *src;
	switch (assoc->type) {
	case WLP_ASSOC_D1:
		INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame);
		schedule_work(&frame_ctx->ws);
		break;
	case WLP_ASSOC_E1:
		kfree_skb(skb); /* Temporary until we handle it */
		kfree(frame_ctx); /* Temporary until we handle it */
		break;
	case WLP_ASSOC_C1:
		INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame);
		schedule_work(&frame_ctx->ws);
		break;
	case WLP_ASSOC_C3:
		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;
	}
}

/*
 * 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;

	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);
	}
	return;
error:
	kfree_skb(skb);
}

/*
 * 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;

	/*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:
	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;

	if (len < sizeof(*hdr)) {
		dev_err(dev, "Not enough data to parse WLP header.\n");
		result = -EINVAL;
		goto out;
	}
	hdr = ptr;
	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;
		}
		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;
	}
	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 successfully 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;

	if (is_multicast_ether_addr(eth_hdr->h_dest)) {
		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 {
		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:
	return result;
}
EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame);
