/*
 * hostapd / Driver interaction with Atheros driver
 * Copyright (c) 2004, Sam Leffler <sam@errno.com>
 * Copyright (c) 2004, Video54 Technologies
 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
 * Copyright (c) 2009, Atheros Communications
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"
#include <net/if.h>
#include <sys/ioctl.h>

#include "common.h"
#include "eloop.h"
#include "common/ieee802_11_defs.h"
#include "l2_packet/l2_packet.h"
#include "p2p/p2p.h"

#include "common.h"
#ifndef _BYTE_ORDER
#ifdef WORDS_BIGENDIAN
#define _BYTE_ORDER _BIG_ENDIAN
#else
#define _BYTE_ORDER _LITTLE_ENDIAN
#endif
#endif /* _BYTE_ORDER */

/*
 * Note, the ATH_WPS_IE setting must match with the driver build.. If the
 * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail.
 */
#define ATH_WPS_IE

#include "ieee80211_external.h"


#ifdef CONFIG_WPS
#include <netpacket/packet.h>
#endif /* CONFIG_WPS */

#ifndef ETH_P_80211_RAW
#define ETH_P_80211_RAW 0x0019
#endif

#include "linux_wext.h"

#include "driver.h"
#include "eloop.h"
#include "priv_netlink.h"
#include "l2_packet/l2_packet.h"
#include "common/ieee802_11_defs.h"
#include "netlink.h"
#include "linux_ioctl.h"


struct atheros_driver_data {
	struct hostapd_data *hapd;		/* back pointer */

	char	iface[IFNAMSIZ + 1];
	int     ifindex;
	struct l2_packet_data *sock_xmit;	/* raw packet xmit socket */
	struct l2_packet_data *sock_recv;	/* raw packet recv socket */
	int	ioctl_sock;			/* socket for ioctl() use */
	struct netlink_data *netlink;
	int	we_version;
	u8	acct_mac[ETH_ALEN];
	struct hostap_sta_driver_data acct_data;

	struct l2_packet_data *sock_raw; /* raw 802.11 management frames */
	struct wpabuf *wpa_ie;
	struct wpabuf *wps_beacon_ie;
	struct wpabuf *wps_probe_resp_ie;
	u8	own_addr[ETH_ALEN];
};

static int atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
			      int reason_code);
static int atheros_set_privacy(void *priv, int enabled);

static const char * athr_get_ioctl_name(int op)
{
	switch (op) {
	case IEEE80211_IOCTL_SETPARAM:
		return "SETPARAM";
	case IEEE80211_IOCTL_GETPARAM:
		return "GETPARAM";
	case IEEE80211_IOCTL_SETKEY:
		return "SETKEY";
	case IEEE80211_IOCTL_SETWMMPARAMS:
		return "SETWMMPARAMS";
	case IEEE80211_IOCTL_DELKEY:
		return "DELKEY";
	case IEEE80211_IOCTL_GETWMMPARAMS:
		return "GETWMMPARAMS";
	case IEEE80211_IOCTL_SETMLME:
		return "SETMLME";
	case IEEE80211_IOCTL_GETCHANINFO:
		return "GETCHANINFO";
	case IEEE80211_IOCTL_SETOPTIE:
		return "SETOPTIE";
	case IEEE80211_IOCTL_GETOPTIE:
		return "GETOPTIE";
	case IEEE80211_IOCTL_ADDMAC:
		return "ADDMAC";
	case IEEE80211_IOCTL_DELMAC:
		return "DELMAC";
	case IEEE80211_IOCTL_GETCHANLIST:
		return "GETCHANLIST";
	case IEEE80211_IOCTL_SETCHANLIST:
		return "SETCHANLIST";
	case IEEE80211_IOCTL_KICKMAC:
		return "KICKMAC";
	case IEEE80211_IOCTL_CHANSWITCH:
		return "CHANSWITCH";
	case IEEE80211_IOCTL_GETMODE:
		return "GETMODE";
	case IEEE80211_IOCTL_SETMODE:
		return "SETMODE";
	case IEEE80211_IOCTL_GET_APPIEBUF:
		return "GET_APPIEBUF";
	case IEEE80211_IOCTL_SET_APPIEBUF:
		return "SET_APPIEBUF";
	case IEEE80211_IOCTL_SET_ACPARAMS:
		return "SET_ACPARAMS";
	case IEEE80211_IOCTL_FILTERFRAME:
		return "FILTERFRAME";
	case IEEE80211_IOCTL_SET_RTPARAMS:
		return "SET_RTPARAMS";
	case IEEE80211_IOCTL_SET_MEDENYENTRY:
		return "SET_MEDENYENTRY";
	case IEEE80211_IOCTL_GET_MACADDR:
		return "GET_MACADDR";
	case IEEE80211_IOCTL_SET_HBRPARAMS:
		return "SET_HBRPARAMS";
	case IEEE80211_IOCTL_SET_RXTIMEOUT:
		return "SET_RXTIMEOUT";
	case IEEE80211_IOCTL_STA_STATS:
		return "STA_STATS";
	case IEEE80211_IOCTL_GETWPAIE:
		return "GETWPAIE";
	default:
		return "??";
	}
}


static const char * athr_get_param_name(int op)
{
	switch (op) {
	case IEEE80211_IOC_MCASTCIPHER:
		return "MCASTCIPHER";
	case IEEE80211_PARAM_MCASTKEYLEN:
		return "MCASTKEYLEN";
	case IEEE80211_PARAM_UCASTCIPHERS:
		return "UCASTCIPHERS";
	case IEEE80211_PARAM_KEYMGTALGS:
		return "KEYMGTALGS";
	case IEEE80211_PARAM_RSNCAPS:
		return "RSNCAPS";
	case IEEE80211_PARAM_WPA:
		return "WPA";
	case IEEE80211_PARAM_AUTHMODE:
		return "AUTHMODE";
	case IEEE80211_PARAM_PRIVACY:
		return "PRIVACY";
	case IEEE80211_PARAM_COUNTERMEASURES:
		return "COUNTERMEASURES";
	default:
		return "??";
	}
}


static int
set80211priv(struct atheros_driver_data *drv, int op, void *data, int len)
{
	struct iwreq iwr;
	int do_inline = len < IFNAMSIZ;

	/* Certain ioctls must use the non-inlined method */
	if (op == IEEE80211_IOCTL_SET_APPIEBUF ||
	    op == IEEE80211_IOCTL_FILTERFRAME)
		do_inline = 0;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
	if (do_inline) {
		/*
		 * Argument data fits inline; put it there.
		 */
		memcpy(iwr.u.name, data, len);
	} else {
		/*
		 * Argument data too big for inline transfer; setup a
		 * parameter block instead; the kernel will transfer
		 * the data for the driver.
		 */
		iwr.u.data.pointer = data;
		iwr.u.data.length = len;
	}

	if (ioctl(drv->ioctl_sock, op, &iwr) < 0) {
		wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x "
			   "(%s) len=%d failed: %d (%s)",
			   __func__, drv->iface, op,
			   athr_get_ioctl_name(op),
			   len, errno, strerror(errno));
		return -1;
	}
	return 0;
}

static int
set80211param(struct atheros_driver_data *drv, int op, int arg)
{
	struct iwreq iwr;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
	iwr.u.mode = op;
	memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg));

	if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
		wpa_printf(MSG_INFO,
			   "%s: %s: Failed to set parameter (op %d (%s) arg %d): ioctl[IEEE80211_IOCTL_SETPARAM]: %s",
			   __func__, drv->iface, op, athr_get_param_name(op),
			   arg, strerror(errno));
		return -1;
	}
	return 0;
}

#ifndef CONFIG_NO_STDOUT_DEBUG
static const char *
ether_sprintf(const u8 *addr)
{
	static char buf[sizeof(MACSTR)];

	if (addr != NULL)
		snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
	else
		snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
	return buf;
}
#endif /* CONFIG_NO_STDOUT_DEBUG */

/*
 * Configure WPA parameters.
 */
static int
atheros_configure_wpa(struct atheros_driver_data *drv,
		      struct wpa_bss_params *params)
{
	int v;

	switch (params->wpa_group) {
	case WPA_CIPHER_CCMP:
		v = IEEE80211_CIPHER_AES_CCM;
		break;
#ifdef ATH_GCM_SUPPORT
	case WPA_CIPHER_CCMP_256:
		v = IEEE80211_CIPHER_AES_CCM_256;
		break;
	case WPA_CIPHER_GCMP:
		v = IEEE80211_CIPHER_AES_GCM;
		break;
	case WPA_CIPHER_GCMP_256:
		v = IEEE80211_CIPHER_AES_GCM_256;
		break;
#endif /* ATH_GCM_SUPPORT */
	case WPA_CIPHER_TKIP:
		v = IEEE80211_CIPHER_TKIP;
		break;
	case WPA_CIPHER_WEP104:
		v = IEEE80211_CIPHER_WEP;
		break;
	case WPA_CIPHER_WEP40:
		v = IEEE80211_CIPHER_WEP;
		break;
	case WPA_CIPHER_NONE:
		v = IEEE80211_CIPHER_NONE;
		break;
	default:
		wpa_printf(MSG_ERROR, "Unknown group key cipher %u",
			   params->wpa_group);
		return -1;
	}
	wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v);
	if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) {
		wpa_printf(MSG_INFO, "Unable to set group key cipher to %u", v);
		return -1;
	}
	if (v == IEEE80211_CIPHER_WEP) {
		/* key length is done only for specific ciphers */
		v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
		if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) {
			wpa_printf(MSG_INFO,
				   "Unable to set group key length to %u", v);
			return -1;
		}
	}

	v = 0;
	if (params->wpa_pairwise & WPA_CIPHER_CCMP)
		v |= 1<<IEEE80211_CIPHER_AES_CCM;
#ifdef ATH_GCM_SUPPORT
	if (params->wpa_pairwise & WPA_CIPHER_CCMP_256)
		v |= 1<<IEEE80211_CIPHER_AES_CCM_256;
	if (params->wpa_pairwise & WPA_CIPHER_GCMP)
		v |= 1<<IEEE80211_CIPHER_AES_GCM;
	if (params->wpa_pairwise & WPA_CIPHER_GCMP_256)
		v |= 1<<IEEE80211_CIPHER_AES_GCM_256;
#endif /* ATH_GCM_SUPPORT */
	if (params->wpa_pairwise & WPA_CIPHER_TKIP)
		v |= 1<<IEEE80211_CIPHER_TKIP;
	if (params->wpa_pairwise & WPA_CIPHER_NONE)
		v |= 1<<IEEE80211_CIPHER_NONE;
	wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
	if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) {
		wpa_printf(MSG_INFO,
			   "Unable to set pairwise key ciphers to 0x%x", v);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
		   __func__, params->wpa_key_mgmt);
	if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS,
			  params->wpa_key_mgmt)) {
		wpa_printf(MSG_INFO,
			   "Unable to set key management algorithms to 0x%x",
			   params->wpa_key_mgmt);
		return -1;
	}

	v = 0;
	if (params->rsn_preauth)
		v |= BIT(0);
#ifdef CONFIG_IEEE80211W
	if (params->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
		v |= BIT(7);
		if (params->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
			v |= BIT(6);
	}
#endif /* CONFIG_IEEE80211W */

	wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", __func__, v);
	if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) {
		wpa_printf(MSG_INFO, "Unable to set RSN capabilities to 0x%x",
			   v);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa);
	if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) {
		wpa_printf(MSG_INFO, "Unable to set WPA to %u", params->wpa);
		return -1;
	}
	return 0;
}

static int
atheros_set_ieee8021x(void *priv, struct wpa_bss_params *params)
{
	struct atheros_driver_data *drv = priv;

	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled);

	if (!params->enabled) {
		/* XXX restore state */
		if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
				  IEEE80211_AUTH_AUTO) < 0)
			return -1;
		/* IEEE80211_AUTH_AUTO ends up enabling Privacy; clear that */
		return atheros_set_privacy(drv, 0);
	}
	if (!params->wpa && !params->ieee802_1x) {
		wpa_printf(MSG_WARNING, "No 802.1X or WPA enabled!");
		return -1;
	}
	if (params->wpa && atheros_configure_wpa(drv, params) != 0) {
		wpa_printf(MSG_WARNING, "Error configuring WPA state!");
		return -1;
	}
	if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
		(params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
		wpa_printf(MSG_WARNING, "Error enabling WPA/802.1X!");
		return -1;
	}

	return 0;
}

static int
atheros_set_privacy(void *priv, int enabled)
{
	struct atheros_driver_data *drv = priv;

	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);

	return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled);
}

static int
atheros_set_sta_authorized(void *priv, const u8 *addr, int authorized)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_mlme mlme;
	int ret;

	wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d",
		   __func__, ether_sprintf(addr), authorized);

	if (authorized)
		mlme.im_op = IEEE80211_MLME_AUTHORIZE;
	else
		mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
	mlme.im_reason = 0;
	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR,
			   __func__, authorized ? "" : "un", MAC2STR(addr));
	}

	return ret;
}

static int
atheros_sta_set_flags(void *priv, const u8 *addr,
		      int total_flags, int flags_or, int flags_and)
{
	/* For now, only support setting Authorized flag */
	if (flags_or & WPA_STA_AUTHORIZED)
		return atheros_set_sta_authorized(priv, addr, 1);
	if (!(flags_and & WPA_STA_AUTHORIZED))
		return atheros_set_sta_authorized(priv, addr, 0);
	return 0;
}

static int
atheros_del_key(void *priv, const u8 *addr, int key_idx)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_del_key wk;
	int ret;

	wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d",
		   __func__, ether_sprintf(addr), key_idx);

	memset(&wk, 0, sizeof(wk));
	if (addr != NULL) {
		memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
		wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE;
	} else {
		wk.idk_keyix = key_idx;
	}

	ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk));
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s"
			   " key_idx %d)", __func__, ether_sprintf(addr),
			   key_idx);
	}

	return ret;
}

static int
atheros_set_key(const char *ifname, void *priv, enum wpa_alg alg,
		const u8 *addr, int key_idx, int set_tx, const u8 *seq,
		size_t seq_len, const u8 *key, size_t key_len)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_key wk;
	u_int8_t cipher;
	int ret;

	if (alg == WPA_ALG_NONE)
		return atheros_del_key(drv, addr, key_idx);

	wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d",
		   __func__, alg, ether_sprintf(addr), key_idx);

	switch (alg) {
	case WPA_ALG_WEP:
		cipher = IEEE80211_CIPHER_WEP;
		break;
	case WPA_ALG_TKIP:
		cipher = IEEE80211_CIPHER_TKIP;
		break;
	case WPA_ALG_CCMP:
		cipher = IEEE80211_CIPHER_AES_CCM;
		break;
#ifdef ATH_GCM_SUPPORT
	case WPA_ALG_CCMP_256:
		cipher = IEEE80211_CIPHER_AES_CCM_256;
		break;
	case WPA_ALG_GCMP:
		cipher = IEEE80211_CIPHER_AES_GCM;
		break;
	case WPA_ALG_GCMP_256:
		cipher = IEEE80211_CIPHER_AES_GCM_256;
		break;
#endif /* ATH_GCM_SUPPORT */
#ifdef CONFIG_IEEE80211W
	case WPA_ALG_IGTK:
		cipher = IEEE80211_CIPHER_AES_CMAC;
		break;
#ifdef ATH_GCM_SUPPORT
	case WPA_ALG_BIP_CMAC_256:
		cipher = IEEE80211_CIPHER_AES_CMAC_256;
		break;
	case WPA_ALG_BIP_GMAC_128:
		cipher = IEEE80211_CIPHER_AES_GMAC;
		break;
	case WPA_ALG_BIP_GMAC_256:
		cipher = IEEE80211_CIPHER_AES_GMAC_256;
		break;
#endif /* ATH_GCM_SUPPORT */
#endif /* CONFIG_IEEE80211W */
	default:
		wpa_printf(MSG_INFO, "%s: unknown/unsupported algorithm %d",
			   __func__, alg);
		return -1;
	}

	if (key_len > sizeof(wk.ik_keydata)) {
		wpa_printf(MSG_INFO, "%s: key length %lu too big", __func__,
			   (unsigned long) key_len);
		return -3;
	}

	memset(&wk, 0, sizeof(wk));
	wk.ik_type = cipher;
	wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
	if (addr == NULL || is_broadcast_ether_addr(addr)) {
		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
		wk.ik_keyix = key_idx;
		if (set_tx)
			wk.ik_flags |= IEEE80211_KEY_DEFAULT;
	} else {
		memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
		wk.ik_keyix = IEEE80211_KEYIX_NONE;
	}
	wk.ik_keylen = key_len;
	memcpy(wk.ik_keydata, key, key_len);

	ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk));
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s"
			   " key_idx %d alg %d key_len %lu set_tx %d)",
			   __func__, ether_sprintf(wk.ik_macaddr), key_idx,
			   alg, (unsigned long) key_len, set_tx);
	}

	return ret;
}


static int
atheros_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
		   u8 *seq)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_key wk;

	wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
		   __func__, ether_sprintf(addr), idx);

	memset(&wk, 0, sizeof(wk));
	if (addr == NULL)
		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
	else
		memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
	wk.ik_keyix = idx;

	if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) {
		wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data "
			   "(addr " MACSTR " key_idx %d)",
			   __func__, MAC2STR(wk.ik_macaddr), idx);
		return -1;
	}

#ifdef WORDS_BIGENDIAN
	{
		/*
		 * wk.ik_keytsc is in host byte order (big endian), need to
		 * swap it to match with the byte order used in WPA.
		 */
		int i;
#ifndef WPA_KEY_RSC_LEN
#define WPA_KEY_RSC_LEN 8
#endif
		u8 tmp[WPA_KEY_RSC_LEN];
		memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
		for (i = 0; i < WPA_KEY_RSC_LEN; i++) {
			seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];
		}
	}
#else /* WORDS_BIGENDIAN */
	memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
#endif /* WORDS_BIGENDIAN */
	return 0;
}


static int
atheros_flush(void *priv)
{
	u8 allsta[IEEE80211_ADDR_LEN];
	memset(allsta, 0xff, IEEE80211_ADDR_LEN);
	return atheros_sta_deauth(priv, NULL, allsta,
				  IEEE80211_REASON_AUTH_LEAVE);
}


static int
atheros_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
			     const u8 *addr)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_sta_stats stats;

	memset(data, 0, sizeof(*data));

	/*
	 * Fetch statistics for station from the system.
	 */
	memset(&stats, 0, sizeof(stats));
	memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
	if (set80211priv(drv, IEEE80211_IOCTL_STA_STATS,
			 &stats, sizeof(stats))) {
		wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr "
			   MACSTR ")", __func__, MAC2STR(addr));
		if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
			memcpy(data, &drv->acct_data, sizeof(*data));
			return 0;
		}

		wpa_printf(MSG_INFO,
			   "Failed to get station stats information element");
		return -1;
	}

	data->rx_packets = stats.is_stats.ns_rx_data;
	data->rx_bytes = stats.is_stats.ns_rx_bytes;
	data->tx_packets = stats.is_stats.ns_tx_data;
	data->tx_bytes = stats.is_stats.ns_tx_bytes;
	return 0;
}


static int
atheros_sta_clear_stats(void *priv, const u8 *addr)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_mlme mlme;
	int ret;

	wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr));

	mlme.im_op = IEEE80211_MLME_CLEAR_STATS;
	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
			   sizeof(mlme));
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr "
			   MACSTR ")", __func__, MAC2STR(addr));
	}

	return ret;
}


static int
atheros_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
{
	struct atheros_driver_data *drv = priv;
	u8 buf[512];
	struct ieee80211req_getset_appiebuf *app_ie;

	wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__,
		   (unsigned long) ie_len);
	wpa_hexdump(MSG_DEBUG, "atheros: set_generic_elem", ie, ie_len);

	wpabuf_free(drv->wpa_ie);
	drv->wpa_ie = wpabuf_alloc_copy(ie, ie_len);

	app_ie = (struct ieee80211req_getset_appiebuf *) buf;
	os_memcpy(&(app_ie->app_buf[0]), ie, ie_len);
	app_ie->app_buflen = ie_len;

	app_ie->app_frmtype = IEEE80211_APPIE_FRAME_BEACON;

	/* append WPS IE for Beacon */
	if (drv->wps_beacon_ie != NULL) {
		os_memcpy(&(app_ie->app_buf[ie_len]),
			  wpabuf_head(drv->wps_beacon_ie),
			  wpabuf_len(drv->wps_beacon_ie));
		app_ie->app_buflen = ie_len + wpabuf_len(drv->wps_beacon_ie);
	}
	wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF(Beacon)",
		    app_ie->app_buf, app_ie->app_buflen);
	set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, app_ie,
		     sizeof(struct ieee80211req_getset_appiebuf) +
		     app_ie->app_buflen);

	/* append WPS IE for Probe Response */
	app_ie->app_frmtype = IEEE80211_APPIE_FRAME_PROBE_RESP;
	if (drv->wps_probe_resp_ie != NULL) {
		os_memcpy(&(app_ie->app_buf[ie_len]),
			  wpabuf_head(drv->wps_probe_resp_ie),
			  wpabuf_len(drv->wps_probe_resp_ie));
		app_ie->app_buflen = ie_len +
			wpabuf_len(drv->wps_probe_resp_ie);
	} else
		app_ie->app_buflen = ie_len;
	wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF(ProbeResp)",
		    app_ie->app_buf, app_ie->app_buflen);
	set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, app_ie,
		     sizeof(struct ieee80211req_getset_appiebuf) +
		     app_ie->app_buflen);
	return 0;
}

static int
atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
		   int reason_code)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_mlme mlme;
	int ret;

	wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
		   __func__, ether_sprintf(addr), reason_code);

	mlme.im_op = IEEE80211_MLME_DEAUTH;
	mlme.im_reason = reason_code;
	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR
			   " reason %d)",
			   __func__, MAC2STR(addr), reason_code);
	}

	return ret;
}

static int
atheros_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
		     int reason_code)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_mlme mlme;
	int ret;

	wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
		   __func__, ether_sprintf(addr), reason_code);

	mlme.im_op = IEEE80211_MLME_DISASSOC;
	mlme.im_reason = reason_code;
	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr "
			   MACSTR " reason %d)",
			   __func__, MAC2STR(addr), reason_code);
	}

	return ret;
}

static int atheros_set_qos_map(void *ctx, const u8 *qos_map_set,
			       u8 qos_map_set_len)
{
#ifdef CONFIG_ATHEROS_QOS_MAP
	struct atheros_driver_data *drv = ctx;
	struct ieee80211req_athdbg req;
	struct ieee80211_qos_map *qos_map = &req.data.qos_map;
	struct iwreq iwr;
	int i, up_start;

	if (qos_map_set_len < 16 || qos_map_set_len > 58 ||
	    qos_map_set_len & 1) {
		wpa_printf(MSG_ERROR, "Invalid QoS Map");
		return -1;
	} else {
		memset(&req, 0, sizeof(struct ieee80211req_athdbg));
		req.cmd = IEEE80211_DBGREQ_SETQOSMAPCONF;
		os_memset(&iwr, 0, sizeof(iwr));
		os_strlcpy(iwr.ifr_name, drv->iface, sizeof(iwr.ifr_name));
		iwr.u.data.pointer = (void *) &req;
		iwr.u.data.length = sizeof(struct ieee80211req_athdbg);
	}

	qos_map->valid = 1;
	qos_map->num_dscp_except = (qos_map_set_len - 16) / 2;
	if (qos_map->num_dscp_except) {
		for (i = 0; i < qos_map->num_dscp_except; i++) {
			qos_map->dscp_exception[i].dscp	= qos_map_set[i * 2];
			qos_map->dscp_exception[i].up =	qos_map_set[i * 2 + 1];
		}
	}

	up_start = qos_map_set_len - 16;
	for (i = 0; i < IEEE80211_MAX_QOS_UP_RANGE; i++) {
		qos_map->up[i].low = qos_map_set[up_start + (i * 2)];
		qos_map->up[i].high = qos_map_set[up_start + (i * 2) + 1];
	}

	if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_DBGREQ, &iwr) < 0) {
		wpa_printf(MSG_ERROR,
			   "%s: %s: Failed to set QoS Map: ioctl[IEEE80211_IOCTL_DBGREQ]: %s",
			   __func__, drv->iface, strerror(errno));
		return -1;
	}
#endif /* CONFIG_ATHEROS_QOS_MAP */

	return 0;
}

#if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WNM) || defined(CONFIG_HS20)
static void atheros_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
				size_t len)
{
	struct atheros_driver_data *drv = ctx;
	const struct ieee80211_mgmt *mgmt;
	union wpa_event_data event;
	u16 fc, stype;
	int ielen;
	const u8 *iebuf;

	if (len < IEEE80211_HDRLEN)
		return;

	mgmt = (const struct ieee80211_mgmt *) buf;

	fc = le_to_host16(mgmt->frame_control);

	if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
		return;

	stype = WLAN_FC_GET_STYPE(fc);

	wpa_printf(MSG_DEBUG, "%s: subtype 0x%x len %d", __func__, stype,
		   (int) len);

	if (stype == WLAN_FC_STYPE_PROBE_REQ) {
		if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
			return;

		os_memset(&event, 0, sizeof(event));
		event.rx_probe_req.sa = mgmt->sa;
		event.rx_probe_req.da = mgmt->da;
		event.rx_probe_req.bssid = mgmt->bssid;
		event.rx_probe_req.ie = mgmt->u.probe_req.variable;
		event.rx_probe_req.ie_len =
			len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
		wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event);
		return;
	}

	if (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) != 0) {
		wpa_printf(MSG_DEBUG, "%s: BSSID does not match - ignore",
			   __func__);
		return;
	}

	switch (stype) {
	case WLAN_FC_STYPE_ASSOC_REQ:
		if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req))
			break;
		ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
		iebuf = mgmt->u.assoc_req.variable;
		drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 0);
		break;
	case WLAN_FC_STYPE_REASSOC_REQ:
		if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req))
			break;
		ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
		iebuf = mgmt->u.reassoc_req.variable;
		drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 1);
		break;
	case WLAN_FC_STYPE_ACTION:
		os_memset(&event, 0, sizeof(event));
		event.rx_mgmt.frame = buf;
		event.rx_mgmt.frame_len = len;
		wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event);
		break;
	case WLAN_FC_STYPE_AUTH:
		if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth))
			break;
		os_memset(&event, 0, sizeof(event));
		os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
		os_memcpy(event.auth.bssid, mgmt->bssid, ETH_ALEN);
		event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
		event.auth.status_code =
			le_to_host16(mgmt->u.auth.status_code);
		event.auth.auth_transaction =
			le_to_host16(mgmt->u.auth.auth_transaction);
		event.auth.ies = mgmt->u.auth.variable;
		event.auth.ies_len = len - IEEE80211_HDRLEN -
			sizeof(mgmt->u.auth);
		wpa_supplicant_event(drv->hapd, EVENT_AUTH, &event);
		break;
	default:
		break;
	}
}
#endif

static int atheros_receive_pkt(struct atheros_driver_data *drv)
{
	int ret = 0;
	struct ieee80211req_set_filter filt;

	wpa_printf(MSG_DEBUG, "%s Enter", __func__);
	filt.app_filterype = 0;
#ifdef CONFIG_WPS
	filt.app_filterype |= IEEE80211_FILTER_TYPE_PROBE_REQ;
#endif /* CONFIG_WPS */
#ifdef CONFIG_IEEE80211R
	filt.app_filterype |= (IEEE80211_FILTER_TYPE_ASSOC_REQ |
			       IEEE80211_FILTER_TYPE_AUTH |
			       IEEE80211_FILTER_TYPE_ACTION);
#endif
#ifdef CONFIG_WNM
	filt.app_filterype |= IEEE80211_FILTER_TYPE_ACTION;
#endif /* CONFIG_WNM */
#ifdef CONFIG_HS20
	filt.app_filterype |= IEEE80211_FILTER_TYPE_ACTION;
#endif /* CONFIG_HS20 */
	if (filt.app_filterype) {
		ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt,
				   sizeof(struct ieee80211req_set_filter));
		if (ret)
			return ret;
	}

#if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R)
	drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW,
				       atheros_raw_receive, drv, 1);
	if (drv->sock_raw == NULL)
		return -1;
#endif /* CONFIG_WPS || CONFIG_IEEE80211R */
	return ret;
}

static int atheros_reset_appfilter(struct atheros_driver_data *drv)
{
	struct ieee80211req_set_filter filt;
	filt.app_filterype = 0;
	return set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt,
			    sizeof(struct ieee80211req_set_filter));
}

#ifdef CONFIG_WPS
static int
atheros_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
{
	struct atheros_driver_data *drv = priv;
	u8 buf[512];
	struct ieee80211req_getset_appiebuf *beac_ie;

	wpa_printf(MSG_DEBUG, "%s buflen = %lu frametype=%u", __func__,
		   (unsigned long) len, frametype);
	wpa_hexdump(MSG_DEBUG, "atheros: IE", ie, len);

	beac_ie = (struct ieee80211req_getset_appiebuf *) buf;
	beac_ie->app_frmtype = frametype;
	beac_ie->app_buflen = len;
	os_memcpy(&(beac_ie->app_buf[0]), ie, len);

	/* append the WPA/RSN IE if it is set already */
	if (((frametype == IEEE80211_APPIE_FRAME_BEACON) ||
	     (frametype == IEEE80211_APPIE_FRAME_PROBE_RESP)) &&
	    (drv->wpa_ie != NULL)) {
		wpa_hexdump_buf(MSG_DEBUG, "atheros: Append WPA/RSN IE",
				drv->wpa_ie);
		os_memcpy(&(beac_ie->app_buf[len]), wpabuf_head(drv->wpa_ie),
			  wpabuf_len(drv->wpa_ie));
		beac_ie->app_buflen += wpabuf_len(drv->wpa_ie);
	}

	wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF",
		    beac_ie->app_buf, beac_ie->app_buflen);
	return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie,
			    sizeof(struct ieee80211req_getset_appiebuf) +
			    beac_ie->app_buflen);
}

static int
atheros_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
		      const struct wpabuf *proberesp,
		      const struct wpabuf *assocresp)
{
	struct atheros_driver_data *drv = priv;

	wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - beacon", beacon);
	wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - proberesp",
			proberesp);
	wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - assocresp",
			assocresp);
	wpabuf_free(drv->wps_beacon_ie);
	drv->wps_beacon_ie = beacon ? wpabuf_dup(beacon) : NULL;
	wpabuf_free(drv->wps_probe_resp_ie);
	drv->wps_probe_resp_ie = proberesp ? wpabuf_dup(proberesp) : NULL;

	atheros_set_wps_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL,
			   assocresp ? wpabuf_len(assocresp) : 0,
			   IEEE80211_APPIE_FRAME_ASSOC_RESP);
	if (atheros_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
			       beacon ? wpabuf_len(beacon) : 0,
			       IEEE80211_APPIE_FRAME_BEACON))
		return -1;
	return atheros_set_wps_ie(priv,
				  proberesp ? wpabuf_head(proberesp) : NULL,
				  proberesp ? wpabuf_len(proberesp): 0,
				  IEEE80211_APPIE_FRAME_PROBE_RESP);
}
#else /* CONFIG_WPS */
#define atheros_set_ap_wps_ie NULL
#endif /* CONFIG_WPS */

#ifdef CONFIG_IEEE80211R
static int
atheros_sta_auth(void *priv, const u8 *own_addr, const u8 *addr, u16 seq,
		 u16 status_code, const u8 *ie, size_t len)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_mlme mlme;
	int ret;

	wpa_printf(MSG_DEBUG, "%s: addr=%s status_code=%d",
		   __func__, ether_sprintf(addr), status_code);

	mlme.im_op = IEEE80211_MLME_AUTH;
	mlme.im_reason = status_code;
	mlme.im_seq = seq;
	os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
	mlme.im_optie_len = len;
	if (len) {
		if (len < IEEE80211_MAX_OPT_IE) {
			os_memcpy(mlme.im_optie, ie, len);
		} else {
			wpa_printf(MSG_DEBUG, "%s: Not enough space to copy "
				   "opt_ie STA (addr " MACSTR " reason %d, "
				   "ie_len %d)",
				   __func__, MAC2STR(addr), status_code,
				   (int) len);
			return -1;
		}
	}
	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "%s: Failed to auth STA (addr " MACSTR
			   " reason %d)",
			   __func__, MAC2STR(addr), status_code);
	}
	return ret;
}

static int
atheros_sta_assoc(void *priv, const u8 *own_addr, const u8 *addr,
		  int reassoc, u16 status_code, const u8 *ie, size_t len)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_mlme mlme;
	int ret;

	wpa_printf(MSG_DEBUG, "%s: addr=%s status_code=%d reassoc %d",
		   __func__, ether_sprintf(addr), status_code, reassoc);

	if (reassoc)
		mlme.im_op = IEEE80211_MLME_REASSOC;
	else
		mlme.im_op = IEEE80211_MLME_ASSOC;
	mlme.im_reason = status_code;
	os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
	mlme.im_optie_len = len;
	if (len) {
		if (len < IEEE80211_MAX_OPT_IE) {
			os_memcpy(mlme.im_optie, ie, len);
		} else {
			wpa_printf(MSG_DEBUG, "%s: Not enough space to copy "
				   "opt_ie STA (addr " MACSTR " reason %d, "
				   "ie_len %d)",
				   __func__, MAC2STR(addr), status_code,
				   (int) len);
			return -1;
		}
	}
	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
	if (ret < 0) {
		wpa_printf(MSG_DEBUG, "%s: Failed to assoc STA (addr " MACSTR
			   " reason %d)",
			   __func__, MAC2STR(addr), status_code);
	}
	return ret;
}
#endif /* CONFIG_IEEE80211R */

static void
atheros_new_sta(struct atheros_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
{
	struct hostapd_data *hapd = drv->hapd;
	struct ieee80211req_wpaie ie;
	int ielen = 0;
	u8 *iebuf = NULL;

	/*
	 * Fetch negotiated WPA/RSN parameters from the system.
	 */
	memset(&ie, 0, sizeof(ie));
	memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
	if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {
		/*
		 * See ATH_WPS_IE comment in the beginning of the file for a
		 * possible cause for the failure..
		 */
		wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s",
			   __func__, strerror(errno));
		goto no_ie;
	}
	wpa_hexdump(MSG_MSGDUMP, "atheros req WPA IE",
		    ie.wpa_ie, IEEE80211_MAX_OPT_IE);
	wpa_hexdump(MSG_MSGDUMP, "atheros req RSN IE",
		    ie.rsn_ie, IEEE80211_MAX_OPT_IE);
#ifdef ATH_WPS_IE
	wpa_hexdump(MSG_MSGDUMP, "atheros req WPS IE",
		    ie.wps_ie, IEEE80211_MAX_OPT_IE);
#endif /* ATH_WPS_IE */
	iebuf = ie.wpa_ie;
	/* atheros seems to return some random data if WPA/RSN IE is not set.
	 * Assume the IE was not included if the IE type is unknown. */
	if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC)
		iebuf[1] = 0;
	if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {
		/* atheros-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
		 * set. This is needed for WPA2. */
		iebuf = ie.rsn_ie;
		if (iebuf[0] != WLAN_EID_RSN)
			iebuf[1] = 0;
	}

	ielen = iebuf[1];

#ifdef ATH_WPS_IE
	/* if WPS IE is present, preference is given to WPS */
	if (ie.wps_ie &&
	    (ie.wps_ie[1] > 0 && (ie.wps_ie[0] == WLAN_EID_VENDOR_SPECIFIC))) {
		iebuf = ie.wps_ie;
		ielen = ie.wps_ie[1];
	}
#endif /* ATH_WPS_IE */

	if (ielen == 0)
		iebuf = NULL;
	else
		ielen += 2;

no_ie:
	drv_event_assoc(hapd, addr, iebuf, ielen, 0);

	if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
		/* Cached accounting data is not valid anymore. */
		memset(drv->acct_mac, 0, ETH_ALEN);
		memset(&drv->acct_data, 0, sizeof(drv->acct_data));
	}
}

static void
atheros_wireless_event_wireless_custom(struct atheros_driver_data *drv,
				       char *custom, char *end)
{
	wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);

	if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
		char *pos;
		u8 addr[ETH_ALEN];
		pos = strstr(custom, "addr=");
		if (pos == NULL) {
			wpa_printf(MSG_DEBUG,
				   "MLME-MICHAELMICFAILURE.indication "
				   "without sender address ignored");
			return;
		}
		pos += 5;
		if (hwaddr_aton(pos, addr) == 0) {
			union wpa_event_data data;
			os_memset(&data, 0, sizeof(data));
			data.michael_mic_failure.unicast = 1;
			data.michael_mic_failure.src = addr;
			wpa_supplicant_event(drv->hapd,
					     EVENT_MICHAEL_MIC_FAILURE, &data);
		} else {
			wpa_printf(MSG_DEBUG,
				   "MLME-MICHAELMICFAILURE.indication "
				   "with invalid MAC address");
		}
	} else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) {
		char *key, *value;
		u32 val;
		key = custom;
		while ((key = strchr(key, '\n')) != NULL) {
			key++;
			value = strchr(key, '=');
			if (value == NULL)
				continue;
			*value++ = '\0';
			val = strtoul(value, NULL, 10);
			if (strcmp(key, "mac") == 0)
				hwaddr_aton(value, drv->acct_mac);
			else if (strcmp(key, "rx_packets") == 0)
				drv->acct_data.rx_packets = val;
			else if (strcmp(key, "tx_packets") == 0)
				drv->acct_data.tx_packets = val;
			else if (strcmp(key, "rx_bytes") == 0)
				drv->acct_data.rx_bytes = val;
			else if (strcmp(key, "tx_bytes") == 0)
				drv->acct_data.tx_bytes = val;
			key = value;
		}
#ifdef CONFIG_WPS
	} else if (strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) {
		/* Some atheros kernels send push button as a wireless event */
		/* PROBLEM! this event is received for ALL BSSs ...
		 * so all are enabled for WPS... ugh.
		 */
		wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL);
#endif /* CONFIG_WPS */
#if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) || defined(CONFIG_HS20)
#define MGMT_FRAM_TAG_SIZE 30 /* hardcoded in driver */
	} else if (strncmp(custom, "Manage.prob_req ", 16) == 0) {
		/*
		 * Atheros driver uses a hack to pass Probe Request frames as a
		 * binary data in the custom wireless event. The old way (using
		 * packet sniffing) didn't work when bridging.
		 * Format: "Manage.prob_req <frame len>" | zero padding | frame
		 */
		int len = atoi(custom + 16);
		if (len < 0 || custom + MGMT_FRAM_TAG_SIZE + len > end) {
			wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event "
				   "length %d", len);
			return;
		}
		atheros_raw_receive(drv, NULL,
				    (u8 *) custom + MGMT_FRAM_TAG_SIZE, len);
	} else if (strncmp(custom, "Manage.assoc_req ", 17) == 0) {
		/* Format: "Manage.assoc_req <frame len>" | zero padding |
		 * frame */
		int len = atoi(custom + 17);
		if (len < 0 || custom + MGMT_FRAM_TAG_SIZE + len > end) {
			wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/"
				   "assoc_req/auth event length %d", len);
			return;
		}
		atheros_raw_receive(drv, NULL,
				    (u8 *) custom + MGMT_FRAM_TAG_SIZE, len);
	} else if (strncmp(custom, "Manage.action ", 14) == 0) {
		/* Format: "Manage.assoc_req <frame len>" | zero padding |
		 * frame */
		int len = atoi(custom + 14);
		if (len < 0 || custom + MGMT_FRAM_TAG_SIZE + len > end) {
			wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/"
				   "assoc_req/auth event length %d", len);
			return;
		}
		atheros_raw_receive(drv, NULL,
				    (u8 *) custom + MGMT_FRAM_TAG_SIZE, len);
	} else if (strncmp(custom, "Manage.auth ", 12) == 0) {
		/* Format: "Manage.auth <frame len>" | zero padding | frame
		 */
		int len = atoi(custom + 12);
		if (len < 0 || custom + MGMT_FRAM_TAG_SIZE + len > end) {
			wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/"
				   "assoc_req/auth event length %d", len);
			return;
		}
		atheros_raw_receive(drv, NULL,
				    (u8 *) custom + MGMT_FRAM_TAG_SIZE, len);
#endif /* CONFIG_WPS or CONFIG_IEEE80211R */
	}
}

/*
* Handle size of data problem. WEXT only allows data of 256 bytes for custom
* events, and p2p data can be much bigger. So the athr driver sends a small
* event telling me to collect the big data with an ioctl.
* On the first event, send all pending events to supplicant.
*/
static void fetch_pending_big_events(struct atheros_driver_data *drv)
{
	union wpa_event_data event;
	const struct ieee80211_mgmt *mgmt;
	u8 tbuf[IW_PRIV_SIZE_MASK]; /* max size is 2047 bytes */
	u16 fc, stype;
	struct iwreq iwr;
	size_t data_len;
	u32 freq, frame_type;

	while (1) {
		os_memset(&iwr, 0, sizeof(iwr));
		os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);

		iwr.u.data.pointer = (void *) tbuf;
		iwr.u.data.length = sizeof(tbuf);
		iwr.u.data.flags = IEEE80211_IOC_P2P_FETCH_FRAME;

		if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_P2P_BIG_PARAM, &iwr)
		    < 0) {
			if (errno == ENOSPC) {
				wpa_printf(MSG_DEBUG, "%s:%d exit",
					   __func__, __LINE__);
				return;
			}
			wpa_printf(MSG_DEBUG, "athr: %s: P2P_BIG_PARAM["
				   "P2P_FETCH_FRAME] failed: %s",
				   __func__, strerror(errno));
			return;
		}
		data_len = iwr.u.data.length;
		wpa_hexdump(MSG_DEBUG, "athr: P2P_FETCH_FRAME data",
			    (u8 *) tbuf, data_len);
		if (data_len < sizeof(freq) + sizeof(frame_type) + 24) {
			wpa_printf(MSG_DEBUG, "athr: frame too short");
			continue;
		}
		os_memcpy(&freq, tbuf, sizeof(freq));
		os_memcpy(&frame_type, &tbuf[sizeof(freq)],
			  sizeof(frame_type));
		mgmt = (void *) &tbuf[sizeof(freq) + sizeof(frame_type)];
		data_len -= sizeof(freq) + sizeof(frame_type);

		if (frame_type == IEEE80211_EV_RX_MGMT) {
			fc = le_to_host16(mgmt->frame_control);
			stype = WLAN_FC_GET_STYPE(fc);

			wpa_printf(MSG_DEBUG, "athr: EV_RX_MGMT stype=%u "
				"freq=%u len=%u", stype, freq, (int) data_len);

			if (stype == WLAN_FC_STYPE_ACTION) {
				os_memset(&event, 0, sizeof(event));
				event.rx_mgmt.frame = (const u8 *) mgmt;
				event.rx_mgmt.frame_len = data_len;
				wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT,
						     &event);
				continue;
			}
		} else {
			wpa_printf(MSG_DEBUG, "athr: %s unknown type %d",
				   __func__, frame_type);
			continue;
		}
	}
}

static void
atheros_wireless_event_atheros_custom(struct atheros_driver_data *drv,
				      int opcode, char *buf, int len)
{
	switch (opcode) {
	case IEEE80211_EV_RX_MGMT:
		wpa_printf(MSG_DEBUG, "WEXT: EV_RX_MGMT");
		fetch_pending_big_events(drv);
		break;
	default:
		break;
	}
}

static void
atheros_wireless_event_wireless(struct atheros_driver_data *drv,
				char *data, int len)
{
	struct iw_event iwe_buf, *iwe = &iwe_buf;
	char *pos, *end, *custom, *buf;

	pos = data;
	end = data + len;

	while (pos + IW_EV_LCP_LEN <= end) {
		/* Event data may be unaligned, so make a local, aligned copy
		 * before processing. */
		memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
		wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d",
			   iwe->cmd, iwe->len);
		if (iwe->len <= IW_EV_LCP_LEN)
			return;

		custom = pos + IW_EV_POINT_LEN;
		if (drv->we_version > 18 &&
		    (iwe->cmd == IWEVMICHAELMICFAILURE ||
		     iwe->cmd == IWEVASSOCREQIE ||
		     iwe->cmd == IWEVCUSTOM)) {
			/* WE-19 removed the pointer from struct iw_point */
			char *dpos = (char *) &iwe_buf.u.data.length;
			int dlen = dpos - (char *) &iwe_buf;
			memcpy(dpos, pos + IW_EV_LCP_LEN,
			       sizeof(struct iw_event) - dlen);
		} else {
			memcpy(&iwe_buf, pos, sizeof(struct iw_event));
			custom += IW_EV_POINT_OFF;
		}

		switch (iwe->cmd) {
		case IWEVEXPIRED:
			drv_event_disassoc(drv->hapd,
					   (u8 *) iwe->u.addr.sa_data);
			break;
		case IWEVREGISTERED:
			atheros_new_sta(drv, (u8 *) iwe->u.addr.sa_data);
			break;
		case IWEVASSOCREQIE:
			/* Driver hack.. Use IWEVASSOCREQIE to bypass
			 * IWEVCUSTOM size limitations. Need to handle this
			 * just like IWEVCUSTOM.
			 */
		case IWEVCUSTOM:
			if (custom + iwe->u.data.length > end)
				return;
			buf = malloc(iwe->u.data.length + 1);
			if (buf == NULL)
				return;		/* XXX */
			memcpy(buf, custom, iwe->u.data.length);
			buf[iwe->u.data.length] = '\0';

			if (iwe->u.data.flags != 0) {
				atheros_wireless_event_atheros_custom(
					drv, (int) iwe->u.data.flags,
					buf, len);
			} else {
				atheros_wireless_event_wireless_custom(
					drv, buf, buf + iwe->u.data.length);
			}
			free(buf);
			break;
		}

		pos += iwe->len;
	}
}


static void
atheros_wireless_event_rtm_newlink(void *ctx,
				   struct ifinfomsg *ifi, u8 *buf, size_t len)
{
	struct atheros_driver_data *drv = ctx;
	int attrlen, rta_len;
	struct rtattr *attr;

	if (ifi->ifi_index != drv->ifindex)
		return;

	attrlen = len;
	attr = (struct rtattr *) buf;

	rta_len = RTA_ALIGN(sizeof(struct rtattr));
	while (RTA_OK(attr, attrlen)) {
		if (attr->rta_type == IFLA_WIRELESS) {
			atheros_wireless_event_wireless(
				drv, ((char *) attr) + rta_len,
				attr->rta_len - rta_len);
		}
		attr = RTA_NEXT(attr, attrlen);
	}
}


static int
atheros_get_we_version(struct atheros_driver_data *drv)
{
	struct iw_range *range;
	struct iwreq iwr;
	int minlen;
	size_t buflen;

	drv->we_version = 0;

	/*
	 * Use larger buffer than struct iw_range in order to allow the
	 * structure to grow in the future.
	 */
	buflen = sizeof(struct iw_range) + 500;
	range = os_zalloc(buflen);
	if (range == NULL)
		return -1;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
	iwr.u.data.pointer = (caddr_t) range;
	iwr.u.data.length = buflen;

	minlen = ((char *) &range->enc_capa) - (char *) range +
		sizeof(range->enc_capa);

	if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
		wpa_printf(MSG_ERROR, "ioctl[SIOCGIWRANGE]: %s",
			   strerror(errno));
		os_free(range);
		return -1;
	} else if (iwr.u.data.length >= minlen &&
		   range->we_version_compiled >= 18) {
		wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
			   "WE(source)=%d enc_capa=0x%x",
			   range->we_version_compiled,
			   range->we_version_source,
			   range->enc_capa);
		drv->we_version = range->we_version_compiled;
	}

	os_free(range);
	return 0;
}


static int
atheros_wireless_event_init(struct atheros_driver_data *drv)
{
	struct netlink_config *cfg;

	atheros_get_we_version(drv);

	cfg = os_zalloc(sizeof(*cfg));
	if (cfg == NULL)
		return -1;
	cfg->ctx = drv;
	cfg->newlink_cb = atheros_wireless_event_rtm_newlink;
	drv->netlink = netlink_init(cfg);
	if (drv->netlink == NULL) {
		os_free(cfg);
		return -1;
	}

	return 0;
}


static int
atheros_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
		   int encrypt, const u8 *own_addr, u32 flags)
{
	struct atheros_driver_data *drv = priv;
	unsigned char buf[3000];
	unsigned char *bp = buf;
	struct l2_ethhdr *eth;
	size_t len;
	int status;

	/*
	 * Prepend the Ethernet header.  If the caller left us
	 * space at the front we could just insert it but since
	 * we don't know we copy to a local buffer.  Given the frequency
	 * and size of frames this probably doesn't matter.
	 */
	len = data_len + sizeof(struct l2_ethhdr);
	if (len > sizeof(buf)) {
		bp = malloc(len);
		if (bp == NULL) {
			wpa_printf(MSG_INFO,
				   "EAPOL frame discarded, cannot malloc temp buffer of size %lu!",
				   (unsigned long) len);
			return -1;
		}
	}
	eth = (struct l2_ethhdr *) bp;
	memcpy(eth->h_dest, addr, ETH_ALEN);
	memcpy(eth->h_source, own_addr, ETH_ALEN);
	eth->h_proto = host_to_be16(ETH_P_EAPOL);
	memcpy(eth+1, data, data_len);

	wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);

	status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);

	if (bp != buf)
		free(bp);
	return status;
}

static void
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
{
	struct atheros_driver_data *drv = ctx;
	drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr),
			   len - sizeof(struct l2_ethhdr));
}

static void *
atheros_init(struct hostapd_data *hapd, struct wpa_init_params *params)
{
	struct atheros_driver_data *drv;
	struct ifreq ifr;
	struct iwreq iwr;
	char brname[IFNAMSIZ];

	drv = os_zalloc(sizeof(struct atheros_driver_data));
	if (drv == NULL) {
		wpa_printf(MSG_INFO,
			   "Could not allocate memory for atheros driver data");
		return NULL;
	}

	drv->hapd = hapd;
	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (drv->ioctl_sock < 0) {
		wpa_printf(MSG_ERROR, "socket[PF_INET,SOCK_DGRAM]: %s",
			   strerror(errno));
		goto bad;
	}
	memcpy(drv->iface, params->ifname, sizeof(drv->iface));

	memset(&ifr, 0, sizeof(ifr));
	os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
	if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
		wpa_printf(MSG_ERROR, "ioctl(SIOCGIFINDEX): %s",
			   strerror(errno));
		goto bad;
	}
	drv->ifindex = ifr.ifr_ifindex;

	drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
					handle_read, drv, 1);
	if (drv->sock_xmit == NULL)
		goto bad;
	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
		goto bad;
	os_memcpy(drv->own_addr, params->own_addr, ETH_ALEN);
	if (params->bridge[0]) {
		wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
			   params->bridge[0]);
		drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
						ETH_P_EAPOL, handle_read, drv,
						1);
		if (drv->sock_recv == NULL)
			goto bad;
	} else if (linux_br_get(brname, drv->iface) == 0) {
		wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
			   "EAPOL receive", brname);
		drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
						handle_read, drv, 1);
		if (drv->sock_recv == NULL)
			goto bad;
	} else
		drv->sock_recv = drv->sock_xmit;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);

	iwr.u.mode = IW_MODE_MASTER;

	if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
		wpa_printf(MSG_ERROR,
			   "Could not set interface to master mode! ioctl[SIOCSIWMODE]: %s",
			   strerror(errno));
		goto bad;
	}

	/* mark down during setup */
	linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
	atheros_set_privacy(drv, 0); /* default to no privacy */

	if (atheros_receive_pkt(drv))
		goto bad;

	if (atheros_wireless_event_init(drv))
		goto bad;

	return drv;
bad:
	atheros_reset_appfilter(drv);
	if (drv->sock_raw)
		l2_packet_deinit(drv->sock_raw);
	if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
		l2_packet_deinit(drv->sock_recv);
	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
	if (drv->ioctl_sock >= 0)
		close(drv->ioctl_sock);
	if (drv != NULL)
		free(drv);
	return NULL;
}


static void
atheros_deinit(void *priv)
{
	struct atheros_driver_data *drv = priv;

	atheros_reset_appfilter(drv);

	if (drv->wpa_ie || drv->wps_beacon_ie || drv->wps_probe_resp_ie) {
		wpabuf_free(drv->wpa_ie);
		wpabuf_free(drv->wps_beacon_ie);
		wpabuf_free(drv->wps_probe_resp_ie);
		atheros_set_opt_ie(priv, NULL, 0);
	}
	netlink_deinit(drv->netlink);
	(void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
	if (drv->ioctl_sock >= 0)
		close(drv->ioctl_sock);
	if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
		l2_packet_deinit(drv->sock_recv);
	if (drv->sock_xmit != NULL)
		l2_packet_deinit(drv->sock_xmit);
	if (drv->sock_raw)
		l2_packet_deinit(drv->sock_raw);
	free(drv);
}

static int
atheros_set_ssid(void *priv, const u8 *buf, int len)
{
	struct atheros_driver_data *drv = priv;
	struct iwreq iwr;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
	iwr.u.essid.flags = 1; /* SSID active */
	iwr.u.essid.pointer = (caddr_t) buf;
	iwr.u.essid.length = len + 1;

	if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
		wpa_printf(MSG_ERROR, "ioctl[SIOCSIWESSID,len=%d]: %s",
			   len, strerror(errno));
		return -1;
	}
	return 0;
}

static int
atheros_get_ssid(void *priv, u8 *buf, int len)
{
	struct atheros_driver_data *drv = priv;
	struct iwreq iwr;
	int ret = 0;

	memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
	iwr.u.essid.pointer = (caddr_t) buf;
	iwr.u.essid.length = (len > IW_ESSID_MAX_SIZE) ?
		IW_ESSID_MAX_SIZE : len;

	if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
		wpa_printf(MSG_ERROR, "ioctl[SIOCGIWESSID]: %s",
			   strerror(errno));
		ret = -1;
	} else
		ret = iwr.u.essid.length;

	return ret;
}

static int
atheros_set_countermeasures(void *priv, int enabled)
{
	struct atheros_driver_data *drv = priv;
	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
	return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled);
}

static int
atheros_commit(void *priv)
{
	struct atheros_driver_data *drv = priv;
	return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
}

static int atheros_set_authmode(void *priv, int auth_algs)
{
	int authmode;

	if ((auth_algs & WPA_AUTH_ALG_OPEN) &&
	    (auth_algs & WPA_AUTH_ALG_SHARED))
		authmode = IEEE80211_AUTH_AUTO;
	else if (auth_algs & WPA_AUTH_ALG_OPEN)
		authmode = IEEE80211_AUTH_OPEN;
	else if (auth_algs & WPA_AUTH_ALG_SHARED)
		authmode = IEEE80211_AUTH_SHARED;
	else
		return -1;

	return set80211param(priv, IEEE80211_PARAM_AUTHMODE, authmode);
}

static int atheros_set_ap(void *priv, struct wpa_driver_ap_params *params)
{
	/*
	 * TODO: Use this to replace set_authmode, set_privacy, set_ieee8021x,
	 * set_generic_elem, and hapd_set_ssid.
	 */

	wpa_printf(MSG_DEBUG, "atheros: set_ap - pairwise_ciphers=0x%x "
		   "group_cipher=0x%x key_mgmt_suites=0x%x auth_algs=0x%x "
		   "wpa_version=0x%x privacy=%d interworking=%d",
		   params->pairwise_ciphers, params->group_cipher,
		   params->key_mgmt_suites, params->auth_algs,
		   params->wpa_version, params->privacy, params->interworking);
	wpa_hexdump_ascii(MSG_DEBUG, "atheros: SSID",
			  params->ssid, params->ssid_len);
	if (params->hessid)
		wpa_printf(MSG_DEBUG, "atheros: HESSID " MACSTR,
			   MAC2STR(params->hessid));
	wpa_hexdump_buf(MSG_DEBUG, "atheros: beacon_ies",
			params->beacon_ies);
	wpa_hexdump_buf(MSG_DEBUG, "atheros: proberesp_ies",
			params->proberesp_ies);
	wpa_hexdump_buf(MSG_DEBUG, "atheros: assocresp_ies",
			params->assocresp_ies);

#if defined(CONFIG_HS20) && (defined(IEEE80211_PARAM_OSEN) || defined(CONFIG_ATHEROS_OSEN))
	if (params->osen) {
		struct wpa_bss_params bss_params;

		os_memset(&bss_params, 0, sizeof(struct wpa_bss_params));
		bss_params.enabled = 1;
		bss_params.wpa = 2;
		bss_params.wpa_pairwise = WPA_CIPHER_CCMP;
		bss_params.wpa_group = WPA_CIPHER_CCMP;
		bss_params.ieee802_1x = 1;

		if (atheros_set_privacy(priv, 1) ||
		    set80211param(priv, IEEE80211_PARAM_OSEN, 1))
			return -1;

		return atheros_set_ieee8021x(priv, &bss_params);
	}
#endif /* CONFIG_HS20 && IEEE80211_PARAM_OSEN */

	return 0;
}


#ifdef CONFIG_IEEE80211R

static int atheros_send_mgmt(void *priv, const u8 *frm, size_t data_len,
			     int noack)
{
	struct atheros_driver_data *drv = priv;
	u8 buf[1510];
	const struct ieee80211_mgmt *mgmt;
	struct ieee80211req_mgmtbuf *mgmt_frm;

	mgmt = (const struct ieee80211_mgmt *) frm;
	wpa_printf(MSG_DEBUG, "%s frmlen = %lu " MACSTR, __func__,
		   (unsigned long) data_len, MAC2STR(mgmt->da));
	mgmt_frm = (struct ieee80211req_mgmtbuf *) buf;
	memcpy(mgmt_frm->macaddr, (u8 *)mgmt->da, IEEE80211_ADDR_LEN);
	mgmt_frm->buflen = data_len;
	if (&mgmt_frm->buf[0] + data_len > buf + sizeof(buf)) {
		wpa_printf(MSG_INFO, "atheros: Too long frame for "
			   "atheros_send_mgmt (%u)", (unsigned int) data_len);
		return -1;
	}
	os_memcpy(&mgmt_frm->buf[0], frm, data_len);
	return set80211priv(drv, IEEE80211_IOCTL_SEND_MGMT, mgmt_frm,
			    sizeof(struct ieee80211req_mgmtbuf) + data_len);
}


static int atheros_add_tspec(void *priv, const u8 *addr, u8 *tspec_ie,
			     size_t tspec_ielen)
{
	struct atheros_driver_data *drv = priv;
	int retv;
	struct ieee80211req_res req;
	struct ieee80211req_res_addts *addts = &req.u.addts;

	wpa_printf(MSG_DEBUG, "%s", __func__);
	req.type = IEEE80211_RESREQ_ADDTS;
	os_memcpy(&req.macaddr[0], addr, IEEE80211_ADDR_LEN);
	os_memcpy(addts->tspecie, tspec_ie, tspec_ielen);
	retv = set80211priv(drv, IEEE80211_IOCTL_RES_REQ, &req,
			    sizeof(struct ieee80211req_res));
	if (retv < 0) {
		wpa_printf(MSG_DEBUG, "%s IEEE80211_IOCTL_RES_REQ FAILED "
			   "retv = %d", __func__, retv);
		return -1;
	}
	os_memcpy(tspec_ie, addts->tspecie, tspec_ielen);
	return addts->status;
}


static int atheros_add_sta_node(void *priv, const u8 *addr, u16 auth_alg)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211req_res req;
	struct ieee80211req_res_addnode *addnode = &req.u.addnode;

	wpa_printf(MSG_DEBUG, "%s", __func__);
	req.type = IEEE80211_RESREQ_ADDNODE;
	os_memcpy(&req.macaddr[0], addr, IEEE80211_ADDR_LEN);
	addnode->auth_alg = auth_alg;
	return set80211priv(drv, IEEE80211_IOCTL_RES_REQ, &req,
			    sizeof(struct ieee80211req_res));
}

#endif /* CONFIG_IEEE80211R */


/* Use only to set a big param, get will not work. */
static int
set80211big(struct atheros_driver_data *drv, int op, const void *data, int len)
{
	struct iwreq iwr;

	os_memset(&iwr, 0, sizeof(iwr));
	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);

	iwr.u.data.pointer = (void *) data;
	iwr.u.data.length = len;
	iwr.u.data.flags = op;
	wpa_printf(MSG_DEBUG, "%s: op=0x%x=%d (%s) len=0x%x",
		   __func__, op, op, athr_get_param_name(op), len);

	if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_P2P_BIG_PARAM, &iwr) < 0) {
		wpa_printf(MSG_DEBUG, "%s: op=0x%x (%s) subop=0x%x=%d "
			   "value=0x%x,0x%x failed: %d (%s)",
			   __func__, op, athr_get_ioctl_name(op), iwr.u.mode,
			   iwr.u.mode, iwr.u.data.length,
			   iwr.u.data.flags, errno, strerror(errno));
		return -1;
	}
	return 0;
}


static int atheros_send_action(void *priv, unsigned int freq,
			       unsigned int wait,
			       const u8 *dst, const u8 *src,
			       const u8 *bssid,
			       const u8 *data, size_t data_len, int no_cck)
{
	struct atheros_driver_data *drv = priv;
	struct ieee80211_p2p_send_action *act;
	int res;

	act = os_zalloc(sizeof(*act) + data_len);
	if (act == NULL)
		return -1;
	act->freq = freq;
	os_memcpy(act->dst_addr, dst, ETH_ALEN);
	os_memcpy(act->src_addr, src, ETH_ALEN);
	os_memcpy(act->bssid, bssid, ETH_ALEN);
	os_memcpy(act + 1, data, data_len);
	wpa_printf(MSG_DEBUG, "%s: freq=%d, wait=%u, dst=" MACSTR ", src="
		   MACSTR ", bssid=" MACSTR,
		   __func__, act->freq, wait, MAC2STR(act->dst_addr),
		   MAC2STR(act->src_addr), MAC2STR(act->bssid));
	wpa_hexdump(MSG_MSGDUMP, "athr: act", (u8 *) act, sizeof(*act));
	wpa_hexdump(MSG_MSGDUMP, "athr: data", data, data_len);

	res = set80211big(drv, IEEE80211_IOC_P2P_SEND_ACTION,
			  act, sizeof(*act) + data_len);
	os_free(act);
	return res;
}


#if defined(CONFIG_WNM) && defined(IEEE80211_APPIE_FRAME_WNM)
static int athr_wnm_tfs(struct atheros_driver_data *drv, const u8* peer,
			u8 *ie, u16 *len, enum wnm_oper oper)
{
#define IEEE80211_APPIE_MAX    1024 /* max appie buffer size */
	u8 buf[IEEE80211_APPIE_MAX];
	struct ieee80211req_getset_appiebuf *tfs_ie;
	u16 val;

	wpa_printf(MSG_DEBUG, "atheros: ifname=%s, WNM TFS IE oper=%d " MACSTR,
		   drv->iface, oper, MAC2STR(peer));

	switch (oper) {
	case WNM_SLEEP_TFS_REQ_IE_SET:
		if (*len > IEEE80211_APPIE_MAX -
		    sizeof(struct ieee80211req_getset_appiebuf)) {
			wpa_printf(MSG_DEBUG, "TFS Req IE(s) too large");
			return -1;
		}
		tfs_ie = (struct ieee80211req_getset_appiebuf *) buf;
		tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM;
		tfs_ie->app_buflen = ETH_ALEN + 2 + 2 + *len;

		/* Command header for driver */
		os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN);
		val = oper;
		os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2);
		val = *len;
		os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2);

		/* copy the ie */
		os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2 + 2, ie, *len);

		if (set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, tfs_ie,
				 IEEE80211_APPIE_MAX)) {
			wpa_printf(MSG_DEBUG, "%s: Failed to set WNM TFS IE: "
				   "%s", __func__, strerror(errno));
			return -1;
		}
		break;
	case WNM_SLEEP_TFS_RESP_IE_ADD:
		tfs_ie = (struct ieee80211req_getset_appiebuf *) buf;
		tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM;
		tfs_ie->app_buflen = IEEE80211_APPIE_MAX -
			sizeof(struct ieee80211req_getset_appiebuf);
		/* Command header for driver */
		os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN);
		val = oper;
		os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2);
		val = 0;
		os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2);

		if (set80211priv(drv, IEEE80211_IOCTL_GET_APPIEBUF, tfs_ie,
				 IEEE80211_APPIE_MAX)) {
			wpa_printf(MSG_DEBUG, "%s: Failed to get WNM TFS IE: "
				   "%s", __func__, strerror(errno));
			return -1;
		}

		*len = tfs_ie->app_buflen;
		os_memcpy(ie, &(tfs_ie->app_buf[0]), *len);
		wpa_printf(MSG_DEBUG, "atheros: %c len=%d", tfs_ie->app_buf[0],
			   *len);
		break;
	case WNM_SLEEP_TFS_RESP_IE_NONE:
		*len = 0;
		break;
	case WNM_SLEEP_TFS_IE_DEL:
		tfs_ie = (struct ieee80211req_getset_appiebuf *) buf;
		tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM;
		tfs_ie->app_buflen = IEEE80211_APPIE_MAX -
			sizeof(struct ieee80211req_getset_appiebuf);
		/* Command header for driver */
		os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN);
		val = oper;
		os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2);
		val = 0;
		os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2);

		if (set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, tfs_ie,
				 IEEE80211_APPIE_MAX)) {
			wpa_printf(MSG_DEBUG, "%s: Failed to set WNM TFS IE: "
				   "%s", __func__, strerror(errno));
			return -1;
		}
		break;
	default:
		wpa_printf(MSG_DEBUG, "Unsupported TFS oper %d", oper);
		break;
	}

	return 0;
}


static int atheros_wnm_sleep(struct atheros_driver_data *drv,
			     const u8 *peer, enum wnm_oper oper)
{
	u8 *data, *pos;
	size_t dlen;
	int ret;
	u16 val;

	wpa_printf(MSG_DEBUG, "atheros: WNM-Sleep Oper %d, " MACSTR,
		   oper, MAC2STR(peer));

	dlen = ETH_ALEN + 2 + 2;
	data = os_malloc(dlen);
	if (data == NULL)
		return -1;

	/* Command header for driver */
	pos = data;
	os_memcpy(pos, peer, ETH_ALEN);
	pos += ETH_ALEN;

	val = oper;
	os_memcpy(pos, &val, 2);
	pos += 2;

	val = 0;
	os_memcpy(pos, &val, 2);

	ret = atheros_set_wps_ie(drv, data, dlen, IEEE80211_APPIE_FRAME_WNM);

	os_free(data);

	return ret;
}


static int atheros_wnm_oper(void *priv, enum wnm_oper oper, const u8 *peer,
			    u8 *buf, u16 *buf_len)
{
	struct atheros_driver_data *drv = priv;

	switch (oper) {
	case WNM_SLEEP_ENTER_CONFIRM:
	case WNM_SLEEP_ENTER_FAIL:
	case WNM_SLEEP_EXIT_CONFIRM:
	case WNM_SLEEP_EXIT_FAIL:
		return atheros_wnm_sleep(drv, peer, oper);
	case WNM_SLEEP_TFS_REQ_IE_SET:
	case WNM_SLEEP_TFS_RESP_IE_ADD:
	case WNM_SLEEP_TFS_RESP_IE_NONE:
	case WNM_SLEEP_TFS_IE_DEL:
		return athr_wnm_tfs(drv, peer, buf, buf_len, oper);
	default:
		wpa_printf(MSG_DEBUG, "atheros: Unsupported WNM operation %d",
			   oper);
		return -1;
	}
}
#endif /* CONFIG_WNM && IEEE80211_APPIE_FRAME_WNM */


const struct wpa_driver_ops wpa_driver_atheros_ops = {
	.name			= "atheros",
	.hapd_init		= atheros_init,
	.hapd_deinit		= atheros_deinit,
	.set_ieee8021x		= atheros_set_ieee8021x,
	.set_privacy		= atheros_set_privacy,
	.set_key		= atheros_set_key,
	.get_seqnum		= atheros_get_seqnum,
	.flush			= atheros_flush,
	.set_generic_elem	= atheros_set_opt_ie,
	.sta_set_flags		= atheros_sta_set_flags,
	.read_sta_data		= atheros_read_sta_driver_data,
	.hapd_send_eapol	= atheros_send_eapol,
	.sta_disassoc		= atheros_sta_disassoc,
	.sta_deauth		= atheros_sta_deauth,
	.hapd_set_ssid		= atheros_set_ssid,
	.hapd_get_ssid		= atheros_get_ssid,
	.set_countermeasures	= atheros_set_countermeasures,
	.sta_clear_stats	= atheros_sta_clear_stats,
	.commit			= atheros_commit,
	.set_ap_wps_ie		= atheros_set_ap_wps_ie,
	.set_authmode		= atheros_set_authmode,
	.set_ap			= atheros_set_ap,
#ifdef CONFIG_IEEE80211R
	.sta_assoc              = atheros_sta_assoc,
	.sta_auth               = atheros_sta_auth,
	.send_mlme       	= atheros_send_mgmt,
	.add_tspec      	= atheros_add_tspec,
	.add_sta_node    	= atheros_add_sta_node,
#endif /* CONFIG_IEEE80211R */
	.send_action		= atheros_send_action,
#if defined(CONFIG_WNM) && defined(IEEE80211_APPIE_FRAME_WNM)
	.wnm_oper		= atheros_wnm_oper,
#endif /* CONFIG_WNM && IEEE80211_APPIE_FRAME_WNM */
	.set_qos_map		= atheros_set_qos_map,
};
