/*
 * WiMedia Logical Link Control Protocol (WLP)
 *
 * 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.
 *
 *
 * Implementation of the WLP association protocol.
 *
 * FIXME: Docs
 *
 * A UWB network interface will configure a WSS through wlp_wss_setup() after
 * the interface has been assigned a MAC address, typically after
 * "ifconfig" has been called. When the interface goes down it should call
 * wlp_wss_remove().
 *
 * When the WSS is ready for use the user interacts via sysfs to create,
 * discover, and activate WSS.
 *
 * wlp_wss_enroll_activate()
 *
 * wlp_wss_create_activate()
 * 	wlp_wss_set_wssid_hash()
 * 		wlp_wss_comp_wssid_hash()
 * 	wlp_wss_sel_bcast_addr()
 * 	wlp_wss_sysfs_add()
 *
 * Called when no more references to WSS exist:
 * 	wlp_wss_release()
 * 		wlp_wss_reset()
 */

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


size_t wlp_wss_key_print(char *buf, size_t bufsize, u8 *key)
{
	size_t result;

	result = scnprintf(buf, bufsize,
			  "%02x %02x %02x %02x %02x %02x "
			  "%02x %02x %02x %02x %02x %02x "
			  "%02x %02x %02x %02x",
			  key[0], key[1], key[2], key[3],
			  key[4], key[5], key[6], key[7],
			  key[8], key[9], key[10], key[11],
			  key[12], key[13], key[14], key[15]);
	return result;
}

/**
 * Compute WSSID hash
 * WLP Draft 0.99 [7.2.1]
 *
 * The WSSID hash for a WSSID is the result of an octet-wise exclusive-OR
 * of all octets in the WSSID.
 */
static
u8 wlp_wss_comp_wssid_hash(struct wlp_uuid *wssid)
{
	return wssid->data[0]  ^ wssid->data[1]  ^ wssid->data[2]
	       ^ wssid->data[3]  ^ wssid->data[4]  ^ wssid->data[5]
	       ^ wssid->data[6]  ^ wssid->data[7]  ^ wssid->data[8]
	       ^ wssid->data[9]  ^ wssid->data[10] ^ wssid->data[11]
	       ^ wssid->data[12] ^ wssid->data[13] ^ wssid->data[14]
	       ^ wssid->data[15];
}

/**
 * Select a multicast EUI-48 for the WSS broadcast address.
 * WLP Draft 0.99 [7.2.1]
 *
 * Selected based on the WiMedia Alliance OUI, 00-13-88, within the WLP
 * range, [01-13-88-00-01-00, 01-13-88-00-01-FF] inclusive.
 *
 * This address is currently hardcoded.
 * FIXME?
 */
static
struct uwb_mac_addr wlp_wss_sel_bcast_addr(struct wlp_wss *wss)
{
	struct uwb_mac_addr bcast = {
		.data = { 0x01, 0x13, 0x88, 0x00, 0x01, 0x00 }
	};
	return bcast;
}

/**
 * Clear the contents of the WSS structure - all except kobj, mutex, virtual
 *
 * We do not want to reinitialize - the internal kobj should not change as
 * it still points to the parent received during setup. The mutex should
 * remain also. We thus just reset values individually.
 * The virutal address assigned to WSS will remain the same for the
 * lifetime of the WSS. We only reset the fields that can change during its
 * lifetime.
 */
void wlp_wss_reset(struct wlp_wss *wss)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	d_fnstart(5, dev, "wss (%p) \n", wss);
	memset(&wss->wssid, 0, sizeof(wss->wssid));
	wss->hash = 0;
	memset(&wss->name[0], 0, sizeof(wss->name));
	memset(&wss->bcast, 0, sizeof(wss->bcast));
	wss->secure_status = WLP_WSS_UNSECURE;
	memset(&wss->master_key[0], 0, sizeof(wss->master_key));
	wss->tag = 0;
	wss->state = WLP_WSS_STATE_NONE;
	d_fnend(5, dev, "wss (%p) \n", wss);
}

/**
 * Create sysfs infrastructure for WSS
 *
 * The WSS is configured to have the interface as parent (see wlp_wss_setup())
 * a new sysfs directory that includes wssid as its name is created in the
 * interface's sysfs directory. The group of files interacting with WSS are
 * created also.
 */
static
int wlp_wss_sysfs_add(struct wlp_wss *wss, char *wssid_str)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	int result;

	d_fnstart(5, dev, "wss (%p), wssid: %s\n", wss, wssid_str);
	result = kobject_set_name(&wss->kobj, "wss-%s", wssid_str);
	if (result < 0)
		return result;
	wss->kobj.ktype = &wss_ktype;
	result = kobject_init_and_add(&wss->kobj,
			&wss_ktype, wss->kobj.parent, "wlp");
	if (result < 0) {
		dev_err(dev, "WLP: Cannot register WSS kobject.\n");
		goto error_kobject_register;
	}
	result = sysfs_create_group(&wss->kobj, &wss_attr_group);
	if (result < 0) {
		dev_err(dev, "WLP: Cannot register WSS attributes: %d\n",
			result);
		goto error_sysfs_create_group;
	}
	d_fnend(5, dev, "Completed. result = %d \n", result);
	return 0;
error_sysfs_create_group:

	kobject_put(&wss->kobj); /* will free name if needed */
	return result;
error_kobject_register:
	kfree(wss->kobj.name);
	wss->kobj.name = NULL;
	wss->kobj.ktype = NULL;
	return result;
}


/**
 * Release WSS
 *
 * No more references exist to this WSS. We should undo everything that was
 * done in wlp_wss_create_activate() except removing the group. The group
 * is not removed because an object can be unregistered before the group is
 * created. We also undo any additional operations on the WSS after this
 * (addition of members).
 *
 * If memory was allocated for the kobject's name then it will
 * be freed by the kobject system during this time.
 *
 * The EDA cache is removed and reinitilized when the WSS is removed. We
 * thus loose knowledge of members of this WSS at that time and need not do
 * it here.
 */
void wlp_wss_release(struct kobject *kobj)
{
	struct wlp_wss *wss = container_of(kobj, struct wlp_wss, kobj);

	wlp_wss_reset(wss);
}

/**
 * Enroll into a WSS using provided neighbor as registrar
 *
 * First search the neighborhood information to learn which neighbor is
 * referred to, next proceed with enrollment.
 *
 * &wss->mutex is held
 */
static
int wlp_wss_enroll_target(struct wlp_wss *wss, struct wlp_uuid *wssid,
			  struct uwb_dev_addr *dest)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	struct wlp_neighbor_e *neighbor;
	char buf[WLP_WSS_UUID_STRSIZE];
	int result = -ENXIO;
	struct uwb_dev_addr *dev_addr;

	wlp_wss_uuid_print(buf, sizeof(buf), wssid);
	d_fnstart(5, dev, "wss %p, wssid %s, registrar %02x:%02x \n",
		  wss, buf, dest->data[1], dest->data[0]);
	mutex_lock(&wlp->nbmutex);
	list_for_each_entry(neighbor, &wlp->neighbors, node) {
		dev_addr = &neighbor->uwb_dev->dev_addr;
		if (!memcmp(dest, dev_addr, sizeof(*dest))) {
			d_printf(5, dev, "Neighbor %02x:%02x is valid, "
				 "enrolling. \n",
				 dev_addr->data[1], dev_addr->data[0]);
			result = wlp_enroll_neighbor(wlp, neighbor, wss,
						     wssid);
			break;
		}
	}
	if (result == -ENXIO)
		dev_err(dev, "WLP: Cannot find neighbor %02x:%02x. \n",
			dest->data[1], dest->data[0]);
	mutex_unlock(&wlp->nbmutex);
	d_fnend(5, dev, "wss %p, wssid %s, registrar %02x:%02x, result %d \n",
		  wss, buf, dest->data[1], dest->data[0], result);
	return result;
}

/**
 * Enroll into a WSS previously discovered
 *
 * User provides WSSID of WSS, search for neighbor that has this WSS
 * activated and attempt to enroll.
 *
 * &wss->mutex is held
 */
static
int wlp_wss_enroll_discovered(struct wlp_wss *wss, struct wlp_uuid *wssid)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	struct wlp_neighbor_e *neighbor;
	struct wlp_wssid_e *wssid_e;
	char buf[WLP_WSS_UUID_STRSIZE];
	int result = -ENXIO;

	wlp_wss_uuid_print(buf, sizeof(buf), wssid);
	d_fnstart(5, dev, "wss %p, wssid %s \n", wss, buf);
	mutex_lock(&wlp->nbmutex);
	list_for_each_entry(neighbor, &wlp->neighbors, node) {
		list_for_each_entry(wssid_e, &neighbor->wssid, node) {
			if (!memcmp(wssid, &wssid_e->wssid, sizeof(*wssid))) {
				d_printf(5, dev, "Found WSSID %s in neighbor "
					 "%02x:%02x cache. \n", buf,
					 neighbor->uwb_dev->dev_addr.data[1],
					 neighbor->uwb_dev->dev_addr.data[0]);
				result = wlp_enroll_neighbor(wlp, neighbor,
							     wss, wssid);
				if (result == 0) /* enrollment success */
					goto out;
				break;
			}
		}
	}
out:
	if (result == -ENXIO)
		dev_err(dev, "WLP: Cannot find WSSID %s in cache. \n", buf);
	mutex_unlock(&wlp->nbmutex);
	d_fnend(5, dev, "wss %p, wssid %s, result %d \n", wss, buf, result);
	return result;
}

/**
 * Enroll into WSS with provided WSSID, registrar may be provided
 *
 * @wss: out WSS that will be enrolled
 * @wssid: wssid of neighboring WSS that we want to enroll in
 * @devaddr: registrar can be specified, will be broadcast (ff:ff) if any
 *           neighbor can be used as registrar.
 *
 * &wss->mutex is held
 */
static
int wlp_wss_enroll(struct wlp_wss *wss, struct wlp_uuid *wssid,
		   struct uwb_dev_addr *devaddr)
{
	int result;
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	char buf[WLP_WSS_UUID_STRSIZE];
	struct uwb_dev_addr bcast = {.data = {0xff, 0xff} };

	wlp_wss_uuid_print(buf, sizeof(buf), wssid);
	if (wss->state != WLP_WSS_STATE_NONE) {
		dev_err(dev, "WLP: Already enrolled in WSS %s.\n", buf);
		result = -EEXIST;
		goto error;
	}
	if (!memcmp(&bcast, devaddr, sizeof(bcast))) {
		d_printf(5, dev, "Request to enroll in discovered WSS "
			 "with WSSID %s \n", buf);
		result = wlp_wss_enroll_discovered(wss, wssid);
	} else {
		d_printf(5, dev, "Request to enroll in WSSID %s with "
			 "registrar %02x:%02x\n", buf, devaddr->data[1],
			 devaddr->data[0]);
		result = wlp_wss_enroll_target(wss, wssid, devaddr);
	}
	if (result < 0) {
		dev_err(dev, "WLP: Unable to enroll into WSS %s, result %d \n",
			buf, result);
		goto error;
	}
	d_printf(2, dev, "Successfully enrolled into WSS %s \n", buf);
	result = wlp_wss_sysfs_add(wss, buf);
	if (result < 0) {
		dev_err(dev, "WLP: Unable to set up sysfs for WSS kobject.\n");
		wlp_wss_reset(wss);
	}
error:
	return result;

}

/**
 * Activate given WSS
 *
 * Prior to activation a WSS must be enrolled. To activate a WSS a device
 * includes the WSS hash in the WLP IE in its beacon in each superframe.
 * WLP 0.99 [7.2.5].
 *
 * The WSS tag is also computed at this time. We only support one activated
 * WSS so we can use the hash as a tag - there will never be a conflict.
 *
 * We currently only support one activated WSS so only one WSS hash is
 * included in the WLP IE.
 */
static
int wlp_wss_activate(struct wlp_wss *wss)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	struct uwb_rc *uwb_rc = wlp->rc;
	int result;
	struct {
		struct wlp_ie wlp_ie;
		u8 hash; /* only include one hash */
	} ie_data;

	d_fnstart(5, dev, "Activating WSS %p. \n", wss);
	BUG_ON(wss->state != WLP_WSS_STATE_ENROLLED);
	wss->hash = wlp_wss_comp_wssid_hash(&wss->wssid);
	wss->tag = wss->hash;
	memset(&ie_data, 0, sizeof(ie_data));
	ie_data.wlp_ie.hdr.element_id = UWB_IE_WLP;
	ie_data.wlp_ie.hdr.length = sizeof(ie_data) - sizeof(struct uwb_ie_hdr);
	wlp_ie_set_hash_length(&ie_data.wlp_ie, sizeof(ie_data.hash));
	ie_data.hash = wss->hash;
	result = uwb_rc_ie_add(uwb_rc, &ie_data.wlp_ie.hdr,
			       sizeof(ie_data));
	if (result < 0) {
		dev_err(dev, "WLP: Unable to add WLP IE to beacon. "
			"result = %d.\n", result);
		goto error_wlp_ie;
	}
	wss->state = WLP_WSS_STATE_ACTIVE;
	result = 0;
error_wlp_ie:
	d_fnend(5, dev, "Activating WSS %p, result = %d \n", wss, result);
	return result;
}

/**
 * Enroll in and activate WSS identified by provided WSSID
 *
 * The neighborhood cache should contain a list of all neighbors and the
 * WSS they have activated. Based on that cache we search which neighbor we
 * can perform the association process with. The user also has option to
 * specify which neighbor it prefers as registrar.
 * Successful enrollment is followed by activation.
 * Successful activation will create the sysfs directory containing
 * specific information regarding this WSS.
 */
int wlp_wss_enroll_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
			    struct uwb_dev_addr *devaddr)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	int result = 0;
	char buf[WLP_WSS_UUID_STRSIZE];

	d_fnstart(5, dev, "Enrollment and activation requested. \n");
	mutex_lock(&wss->mutex);
	result = wlp_wss_enroll(wss, wssid, devaddr);
	if (result < 0) {
		wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
		dev_err(dev, "WLP: Enrollment into WSS %s failed.\n", buf);
		goto error_enroll;
	}
	result = wlp_wss_activate(wss);
	if (result < 0) {
		dev_err(dev, "WLP: Unable to activate WSS. Undoing enrollment "
			"result = %d \n", result);
		/* Undo enrollment */
		wlp_wss_reset(wss);
		goto error_activate;
	}
error_activate:
error_enroll:
	mutex_unlock(&wss->mutex);
	d_fnend(5, dev, "Completed. result = %d \n", result);
	return result;
}

/**
 * Create, enroll, and activate a new WSS
 *
 * @wssid: new wssid provided by user
 * @name:  WSS name requested by used.
 * @sec_status: security status requested by user
 *
 * A user requested the creation of a new WSS. All operations are done
 * locally. The new WSS will be stored locally, the hash will be included
 * in the WLP IE, and the sysfs infrastructure for this WSS will be
 * created.
 */
int wlp_wss_create_activate(struct wlp_wss *wss, struct wlp_uuid *wssid,
			    char *name, unsigned sec_status, unsigned accept)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	int result = 0;
	char buf[WLP_WSS_UUID_STRSIZE];
	d_fnstart(5, dev, "Request to create new WSS.\n");
	result = wlp_wss_uuid_print(buf, sizeof(buf), wssid);
	d_printf(5, dev, "Request to create WSS: WSSID=%s, name=%s, "
		 "sec_status=%u, accepting enrollment=%u \n",
		 buf, name, sec_status, accept);
	if (!mutex_trylock(&wss->mutex)) {
		dev_err(dev, "WLP: WLP association session in progress.\n");
		return -EBUSY;
	}
	if (wss->state != WLP_WSS_STATE_NONE) {
		dev_err(dev, "WLP: WSS already exists. Not creating new.\n");
		result = -EEXIST;
		goto out;
	}
	if (wss->kobj.parent == NULL) {
		dev_err(dev, "WLP: WSS parent not ready. Is network interface "
		       "up?\n");
		result = -ENXIO;
		goto out;
	}
	if (sec_status == WLP_WSS_SECURE) {
		dev_err(dev, "WLP: FIXME Creation of secure WSS not "
			"supported yet.\n");
		result = -EINVAL;
		goto out;
	}
	wss->wssid = *wssid;
	memcpy(wss->name, name, sizeof(wss->name));
	wss->bcast = wlp_wss_sel_bcast_addr(wss);
	wss->secure_status = sec_status;
	wss->accept_enroll = accept;
	/*wss->virtual_addr is initialized in call to wlp_wss_setup*/
	/* sysfs infrastructure */
	result = wlp_wss_sysfs_add(wss, buf);
	if (result < 0) {
		dev_err(dev, "Cannot set up sysfs for WSS kobject.\n");
		wlp_wss_reset(wss);
		goto out;
	} else
		result = 0;
	wss->state = WLP_WSS_STATE_ENROLLED;
	result = wlp_wss_activate(wss);
	if (result < 0) {
		dev_err(dev, "WLP: Unable to activate WSS. Undoing "
			"enrollment\n");
		wlp_wss_reset(wss);
		goto out;
	}
	result = 0;
out:
	mutex_unlock(&wss->mutex);
	d_fnend(5, dev, "Completed. result = %d \n", result);
	return result;
}

/**
 * Determine if neighbor has WSS activated
 *
 * @returns: 1 if neighbor has WSS activated, zero otherwise
 *
 * This can be done in two ways:
 * - send a C1 frame, parse C2/F0 response
 * - examine the WLP IE sent by the neighbor
 *
 * The WLP IE is not fully supported in hardware so we use the C1/C2 frame
 * exchange to determine if a WSS is activated. Using the WLP IE should be
 * faster and should be used when it becomes possible.
 */
int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss,
		      struct uwb_dev_addr *dev_addr)
{
	int result = 0;
	struct device *dev = &wlp->rc->uwb_dev.dev;
	char buf[WLP_WSS_UUID_STRSIZE];
	DECLARE_COMPLETION_ONSTACK(completion);
	struct wlp_session session;
	struct sk_buff  *skb;
	struct wlp_frame_assoc *resp;
	struct wlp_uuid wssid;

	wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
	d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
		  wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
	mutex_lock(&wlp->mutex);
	/* Send C1 association frame */
	result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C1);
	if (result < 0) {
		dev_err(dev, "Unable to send C1 frame to neighbor "
			"%02x:%02x (%d)\n", dev_addr->data[1],
			dev_addr->data[0], result);
		result = 0;
		goto out;
	}
	/* Create session, wait for response */
	session.exp_message = WLP_ASSOC_C2;
	session.cb = wlp_session_cb;
	session.cb_priv = &completion;
	session.neighbor_addr = *dev_addr;
	BUG_ON(wlp->session != NULL);
	wlp->session = &session;
	/* Wait for C2/F0 frame */
	result = wait_for_completion_interruptible_timeout(&completion,
						   WLP_PER_MSG_TIMEOUT * HZ);
	if (result == 0) {
		dev_err(dev, "Timeout while sending C1 to neighbor "
			     "%02x:%02x.\n", dev_addr->data[1],
			     dev_addr->data[0]);
		goto out;
	}
	if (result < 0) {
		dev_err(dev, "Unable to send C1 to neighbor %02x:%02x.\n",
			dev_addr->data[1], dev_addr->data[0]);
		result = 0;
		goto out;
	}
	/* Parse message in session->data: it will be either C2 or F0 */
	skb = session.data;
	resp = (void *) skb->data;
	d_printf(5, dev, "Received response to C1 frame. \n");
	d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len);
	if (resp->type == WLP_ASSOC_F0) {
		result = wlp_parse_f0(wlp, skb);
		if (result < 0)
			dev_err(dev, "WLP:  unable to parse incoming F0 "
				"frame from neighbor %02x:%02x.\n",
				dev_addr->data[1], dev_addr->data[0]);
		result = 0;
		goto error_resp_parse;
	}
	/* WLP version and message type fields have already been parsed */
	result = wlp_get_wssid(wlp, (void *)resp + sizeof(*resp), &wssid,
			       skb->len - sizeof(*resp));
	if (result < 0) {
		dev_err(dev, "WLP: unable to obtain WSSID from C2 frame.\n");
		result = 0;
		goto error_resp_parse;
	}
	if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))) {
		d_printf(5, dev, "WSSID in C2 frame matches local "
			 "active WSS.\n");
		result = 1;
	} else {
		dev_err(dev, "WLP: Received a C2 frame without matching "
			"WSSID.\n");
		result = 0;
	}
error_resp_parse:
	kfree_skb(skb);
out:
	wlp->session = NULL;
	mutex_unlock(&wlp->mutex);
	d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
		  wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
	return result;
}

/**
 * Activate connection with neighbor by updating EDA cache
 *
 * @wss:       local WSS to which neighbor wants to connect
 * @dev_addr:  neighbor's address
 * @wssid:     neighbor's WSSID - must be same as our WSS's WSSID
 * @tag:       neighbor's WSS tag used to identify frames transmitted by it
 * @virt_addr: neighbor's virtual EUI-48
 */
static
int wlp_wss_activate_connection(struct wlp *wlp, struct wlp_wss *wss,
				struct uwb_dev_addr *dev_addr,
				struct wlp_uuid *wssid, u8 *tag,
				struct uwb_mac_addr *virt_addr)
{
	struct device *dev = &wlp->rc->uwb_dev.dev;
	int result = 0;
	char buf[WLP_WSS_UUID_STRSIZE];
	wlp_wss_uuid_print(buf, sizeof(buf), wssid);
	d_fnstart(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual "
		  "%02x:%02x:%02x:%02x:%02x:%02x \n", wlp, wss, buf, *tag,
		  virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
		  virt_addr->data[3], virt_addr->data[4], virt_addr->data[5]);

	if (!memcmp(wssid, &wss->wssid, sizeof(*wssid))) {
		d_printf(5, dev, "WSSID from neighbor frame matches local "
			 "active WSS.\n");
		/* Update EDA cache */
		result = wlp_eda_update_node(&wlp->eda, dev_addr, wss,
					     (void *) virt_addr->data, *tag,
					     WLP_WSS_CONNECTED);
		if (result < 0)
			dev_err(dev, "WLP: Unable to update EDA cache "
				"with new connected neighbor information.\n");
	} else {
		dev_err(dev, "WLP: Neighbor does not have matching "
			"WSSID.\n");
		result = -EINVAL;
	}

	d_fnend(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual "
		  "%02x:%02x:%02x:%02x:%02x:%02x, result = %d \n",
		  wlp, wss, buf, *tag,
		  virt_addr->data[0], virt_addr->data[1], virt_addr->data[2],
		  virt_addr->data[3], virt_addr->data[4], virt_addr->data[5],
		  result);

	return result;
}

/**
 * Connect to WSS neighbor
 *
 * Use C3/C4 exchange to determine if neighbor has WSS activated and
 * retrieve the WSS tag and virtual EUI-48 of the neighbor.
 */
static
int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss,
			     struct uwb_dev_addr *dev_addr)
{
	int result;
	struct device *dev = &wlp->rc->uwb_dev.dev;
	char buf[WLP_WSS_UUID_STRSIZE];
	struct wlp_uuid wssid;
	u8 tag;
	struct uwb_mac_addr virt_addr;
	DECLARE_COMPLETION_ONSTACK(completion);
	struct wlp_session session;
	struct wlp_frame_assoc *resp;
	struct sk_buff *skb;

	wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
	d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
		  wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
	mutex_lock(&wlp->mutex);
	/* Send C3 association frame */
	result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C3);
	if (result < 0) {
		dev_err(dev, "Unable to send C3 frame to neighbor "
			"%02x:%02x (%d)\n", dev_addr->data[1],
			dev_addr->data[0], result);
		goto out;
	}
	/* Create session, wait for response */
	session.exp_message = WLP_ASSOC_C4;
	session.cb = wlp_session_cb;
	session.cb_priv = &completion;
	session.neighbor_addr = *dev_addr;
	BUG_ON(wlp->session != NULL);
	wlp->session = &session;
	/* Wait for C4/F0 frame */
	result = wait_for_completion_interruptible_timeout(&completion,
						   WLP_PER_MSG_TIMEOUT * HZ);
	if (result == 0) {
		dev_err(dev, "Timeout while sending C3 to neighbor "
			     "%02x:%02x.\n", dev_addr->data[1],
			     dev_addr->data[0]);
		result = -ETIMEDOUT;
		goto out;
	}
	if (result < 0) {
		dev_err(dev, "Unable to send C3 to neighbor %02x:%02x.\n",
			dev_addr->data[1], dev_addr->data[0]);
		goto out;
	}
	/* Parse message in session->data: it will be either C4 or F0 */
	skb = session.data;
	resp = (void *) skb->data;
	d_printf(5, dev, "Received response to C3 frame. \n");
	d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len);
	if (resp->type == WLP_ASSOC_F0) {
		result = wlp_parse_f0(wlp, skb);
		if (result < 0)
			dev_err(dev, "WLP: unable to parse incoming F0 "
				"frame from neighbor %02x:%02x.\n",
				dev_addr->data[1], dev_addr->data[0]);
		result = -EINVAL;
		goto error_resp_parse;
	}
	result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr);
	if (result < 0) {
		dev_err(dev, "WLP: Unable to parse C4 frame from neighbor.\n");
		goto error_resp_parse;
	}
	result = wlp_wss_activate_connection(wlp, wss, dev_addr, &wssid, &tag,
					     &virt_addr);
	if (result < 0) {
		dev_err(dev, "WLP: Unable to activate connection to "
			"neighbor %02x:%02x.\n", dev_addr->data[1],
			dev_addr->data[0]);
		goto error_resp_parse;
	}
error_resp_parse:
	kfree_skb(skb);
out:
	/* Record that we unsuccessfully tried to connect to this neighbor */
	if (result < 0)
		wlp_eda_update_node_state(&wlp->eda, dev_addr,
					  WLP_WSS_CONNECT_FAILED);
	wlp->session = NULL;
	mutex_unlock(&wlp->mutex);
	d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
		  wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
	return result;
}

/**
 * Connect to neighbor with common WSS, send pending frame
 *
 * This function is scheduled when a frame is destined to a neighbor with
 * which we do not have a connection. A copy of the EDA cache entry is
 * provided - not the actual cache entry (because it is protected by a
 * spinlock).
 *
 * First determine if neighbor has the same WSS activated, connect if it
 * does. The C3/C4 exchange is dual purpose to determine if neighbor has
 * WSS activated and proceed with the connection.
 *
 * The frame that triggered the connection setup is sent after connection
 * setup.
 *
 * network queue is stopped - we need to restart when done
 *
 */
static
void wlp_wss_connect_send(struct work_struct *ws)
{
	struct wlp_assoc_conn_ctx *conn_ctx = container_of(ws,
						  struct wlp_assoc_conn_ctx,
						  ws);
	struct wlp *wlp = conn_ctx->wlp;
	struct sk_buff *skb = conn_ctx->skb;
	struct wlp_eda_node *eda_entry = &conn_ctx->eda_entry;
	struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
	struct wlp_wss *wss = &wlp->wss;
	int result;
	struct device *dev = &wlp->rc->uwb_dev.dev;
	char buf[WLP_WSS_UUID_STRSIZE];

	mutex_lock(&wss->mutex);
	wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid);
	d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n",
		  wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]);
	if (wss->state < WLP_WSS_STATE_ACTIVE) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Attempting to connect with "
				"WSS that is not active or connected.\n");
		dev_kfree_skb(skb);
		goto out;
	}
	/* Establish connection - send C3 rcv C4 */
	result = wlp_wss_connect_neighbor(wlp, wss, dev_addr);
	if (result < 0) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Unable to establish connection "
				"with neighbor %02x:%02x.\n",
				dev_addr->data[1], dev_addr->data[0]);
		dev_kfree_skb(skb);
		goto out;
	}
	/* EDA entry changed, update the local copy being used */
	result = wlp_copy_eda_node(&wlp->eda, dev_addr, eda_entry);
	if (result < 0) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Cannot find EDA entry for "
				"neighbor %02x:%02x \n",
				dev_addr->data[1], dev_addr->data[0]);
	}
	result = wlp_wss_prep_hdr(wlp, eda_entry, skb);
	if (result < 0) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Unable to prepare frame header for "
				"transmission (neighbor %02x:%02x). \n",
				dev_addr->data[1], dev_addr->data[0]);
		dev_kfree_skb(skb);
		goto out;
	}
	BUG_ON(wlp->xmit_frame == NULL);
	result = wlp->xmit_frame(wlp, skb, dev_addr);
	if (result < 0) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Unable to transmit frame: %d\n",
				result);
		if (result == -ENXIO)
			dev_err(dev, "WLP: Is network interface up? \n");
		/* We could try again ... */
		dev_kfree_skb(skb);/*we need to free if tx fails */
	}
out:
	kfree(conn_ctx);
	BUG_ON(wlp->start_queue == NULL);
	wlp->start_queue(wlp);
	mutex_unlock(&wss->mutex);
	d_fnend(5, dev, "wlp %p, wss %p (wssid %s)\n", wlp, wss, buf);
}

/**
 * Add WLP header to outgoing skb
 *
 * @eda_entry: pointer to neighbor's entry in the EDA cache
 * @_skb:      skb containing data destined to the neighbor
 */
int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry,
		     void *_skb)
{
	struct device *dev = &wlp->rc->uwb_dev.dev;
	int result = 0;
	unsigned char *eth_addr = eda_entry->eth_addr;
	struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
	struct sk_buff *skb = _skb;
	struct wlp_frame_std_abbrv_hdr *std_hdr;

	d_fnstart(6, dev, "wlp %p \n", wlp);
	if (eda_entry->state == WLP_WSS_CONNECTED) {
		/* Add WLP header */
		BUG_ON(skb_headroom(skb) < sizeof(*std_hdr));
		std_hdr = (void *) __skb_push(skb, sizeof(*std_hdr));
		std_hdr->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID);
		std_hdr->hdr.type = WLP_FRAME_STANDARD;
		std_hdr->tag = eda_entry->wss->tag;
	} else {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Destination neighbor (Ethernet: "
				"%02x:%02x:%02x:%02x:%02x:%02x, Dev: "
				"%02x:%02x) is not connected. \n", eth_addr[0],
				eth_addr[1], eth_addr[2], eth_addr[3],
				eth_addr[4], eth_addr[5], dev_addr->data[1],
				dev_addr->data[0]);
		result = -EINVAL;
	}
	d_fnend(6, dev, "wlp %p \n", wlp);
	return result;
}


/**
 * Prepare skb for neighbor: connect if not already and prep WLP header
 *
 * This function is called in interrupt context, but it needs to sleep. We
 * temporarily stop the net queue to establish the WLP connection.
 * Setup of the WLP connection and restart of queue is scheduled
 * on the default work queue.
 *
 * run with eda->lock held (spinlock)
 */
int wlp_wss_connect_prep(struct wlp *wlp, struct wlp_eda_node *eda_entry,
			 void *_skb)
{
	int result = 0;
	struct device *dev = &wlp->rc->uwb_dev.dev;
	struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;
	unsigned char *eth_addr = eda_entry->eth_addr;
	struct sk_buff *skb = _skb;
	struct wlp_assoc_conn_ctx *conn_ctx;

	d_fnstart(5, dev, "wlp %p\n", wlp);
	d_printf(5, dev, "To neighbor %02x:%02x with eth "
		  "%02x:%02x:%02x:%02x:%02x:%02x\n", dev_addr->data[1],
		  dev_addr->data[0], eth_addr[0], eth_addr[1], eth_addr[2],
		  eth_addr[3], eth_addr[4], eth_addr[5]);
	if (eda_entry->state == WLP_WSS_UNCONNECTED) {
		/* We don't want any more packets while we set up connection */
		BUG_ON(wlp->stop_queue == NULL);
		wlp->stop_queue(wlp);
		conn_ctx = kmalloc(sizeof(*conn_ctx), GFP_ATOMIC);
		if (conn_ctx == NULL) {
			if (printk_ratelimit())
				dev_err(dev, "WLP: Unable to allocate memory "
					"for connection handling.\n");
			result = -ENOMEM;
			goto out;
		}
		conn_ctx->wlp = wlp;
		conn_ctx->skb = skb;
		conn_ctx->eda_entry = *eda_entry;
		INIT_WORK(&conn_ctx->ws, wlp_wss_connect_send);
		schedule_work(&conn_ctx->ws);
		result = 1;
	} else if (eda_entry->state == WLP_WSS_CONNECT_FAILED) {
		/* Previous connection attempts failed, don't retry - see
		 * conditions for connection in WLP 0.99 [7.6.2] */
		if (printk_ratelimit())
			dev_err(dev, "Could not connect to neighbor "
			 "previously. Not retrying. \n");
		result = -ENONET;
		goto out;
	} else { /* eda_entry->state == WLP_WSS_CONNECTED */
		d_printf(5, dev, "Neighbor is connected, preparing frame.\n");
		result = wlp_wss_prep_hdr(wlp, eda_entry, skb);
	}
out:
	d_fnend(5, dev, "wlp %p, result = %d \n", wlp, result);
	return result;
}

/**
 * Emulate broadcast: copy skb, send copy to neighbor (connect if not already)
 *
 * We need to copy skbs in the case where we emulate broadcast through
 * unicast. We copy instead of clone because we are modifying the data of
 * the frame after copying ... clones share data so we cannot emulate
 * broadcast using clones.
 *
 * run with eda->lock held (spinlock)
 */
int wlp_wss_send_copy(struct wlp *wlp, struct wlp_eda_node *eda_entry,
		      void *_skb)
{
	int result = -ENOMEM;
	struct device *dev = &wlp->rc->uwb_dev.dev;
	struct sk_buff *skb = _skb;
	struct sk_buff *copy;
	struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr;

	d_fnstart(5, dev, "to neighbor %02x:%02x, skb (%p) \n",
		  dev_addr->data[1], dev_addr->data[0], skb);
	copy = skb_copy(skb, GFP_ATOMIC);
	if (copy == NULL) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Unable to copy skb for "
				"transmission.\n");
		goto out;
	}
	result = wlp_wss_connect_prep(wlp, eda_entry, copy);
	if (result < 0) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Unable to connect/send skb "
				"to neighbor.\n");
		dev_kfree_skb_irq(copy);
		goto out;
	} else if (result == 1)
		/* Frame will be transmitted separately */
		goto out;
	BUG_ON(wlp->xmit_frame == NULL);
	result = wlp->xmit_frame(wlp, copy, dev_addr);
	if (result < 0) {
		if (printk_ratelimit())
			dev_err(dev, "WLP: Unable to transmit frame: %d\n",
				result);
		if ((result == -ENXIO) && printk_ratelimit())
			dev_err(dev, "WLP: Is network interface up? \n");
		/* We could try again ... */
		dev_kfree_skb_irq(copy);/*we need to free if tx fails */
	}
out:
	d_fnend(5, dev, "to neighbor %02x:%02x \n", dev_addr->data[1],
		  dev_addr->data[0]);
	return result;
}


/**
 * Setup WSS
 *
 * Should be called by network driver after the interface has been given a
 * MAC address.
 */
int wlp_wss_setup(struct net_device *net_dev, struct wlp_wss *wss)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	int result = 0;
	d_fnstart(5, dev, "wss (%p) \n", wss);
	mutex_lock(&wss->mutex);
	wss->kobj.parent = &net_dev->dev.kobj;
	if (!is_valid_ether_addr(net_dev->dev_addr)) {
		dev_err(dev, "WLP: Invalid MAC address. Cannot use for"
		       "virtual.\n");
		result = -EINVAL;
		goto out;
	}
	memcpy(wss->virtual_addr.data, net_dev->dev_addr,
	       sizeof(wss->virtual_addr.data));
out:
	mutex_unlock(&wss->mutex);
	d_fnend(5, dev, "wss (%p) \n", wss);
	return result;
}
EXPORT_SYMBOL_GPL(wlp_wss_setup);

/**
 * Remove WSS
 *
 * Called by client that configured WSS through wlp_wss_setup(). This
 * function is called when client no longer needs WSS, eg. client shuts
 * down.
 *
 * We remove the WLP IE from the beacon before initiating local cleanup.
 */
void wlp_wss_remove(struct wlp_wss *wss)
{
	struct wlp *wlp = container_of(wss, struct wlp, wss);
	struct device *dev = &wlp->rc->uwb_dev.dev;
	d_fnstart(5, dev, "wss (%p) \n", wss);
	mutex_lock(&wss->mutex);
	if (wss->state == WLP_WSS_STATE_ACTIVE)
		uwb_rc_ie_rm(wlp->rc, UWB_IE_WLP);
	if (wss->state != WLP_WSS_STATE_NONE) {
		sysfs_remove_group(&wss->kobj, &wss_attr_group);
		kobject_put(&wss->kobj);
	}
	wss->kobj.parent = NULL;
	memset(&wss->virtual_addr, 0, sizeof(wss->virtual_addr));
	/* Cleanup EDA cache */
	wlp_eda_release(&wlp->eda);
	wlp_eda_init(&wlp->eda);
	mutex_unlock(&wss->mutex);
	d_fnend(5, dev, "wss (%p) \n", wss);
}
EXPORT_SYMBOL_GPL(wlp_wss_remove);
