// SPDX-License-Identifier: GPL-2.0
/*
 * Intersil Prism2 driver with Host AP (software access point) support
 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
 * <j@w1.fi>
 * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
 *
 * This file is to be included into hostap.c when S/W AP functionality is
 * compiled.
 *
 * AP:  FIX:
 * - if unicast Class 2 (assoc,reassoc,disassoc) frame received from
 *   unauthenticated STA, send deauth. frame (8802.11: 5.5)
 * - if unicast Class 3 (data with to/from DS,deauth,pspoll) frame received
 *   from authenticated, but unassoc STA, send disassoc frame (8802.11: 5.5)
 * - if unicast Class 3 received from unauthenticated STA, send deauth. frame
 *   (8802.11: 5.5)
 */

#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/delay.h>
#include <linux/random.h>
#include <linux/if_arp.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/moduleparam.h>
#include <linux/etherdevice.h>

#include "hostap_wlan.h"
#include "hostap.h"
#include "hostap_ap.h"

static int other_ap_policy[MAX_PARM_DEVICES] = { AP_OTHER_AP_SKIP_ALL,
						 DEF_INTS };
module_param_array(other_ap_policy, int, NULL, 0444);
MODULE_PARM_DESC(other_ap_policy, "Other AP beacon monitoring policy (0-3)");

static int ap_max_inactivity[MAX_PARM_DEVICES] = { AP_MAX_INACTIVITY_SEC,
						   DEF_INTS };
module_param_array(ap_max_inactivity, int, NULL, 0444);
MODULE_PARM_DESC(ap_max_inactivity, "AP timeout (in seconds) for station "
		 "inactivity");

static int ap_bridge_packets[MAX_PARM_DEVICES] = { 1, DEF_INTS };
module_param_array(ap_bridge_packets, int, NULL, 0444);
MODULE_PARM_DESC(ap_bridge_packets, "Bridge packets directly between "
		 "stations");

static int autom_ap_wds[MAX_PARM_DEVICES] = { 0, DEF_INTS };
module_param_array(autom_ap_wds, int, NULL, 0444);
MODULE_PARM_DESC(autom_ap_wds, "Add WDS connections to other APs "
		 "automatically");


static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta);
static void hostap_event_expired_sta(struct net_device *dev,
				     struct sta_info *sta);
static void handle_add_proc_queue(struct work_struct *work);

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
static void handle_wds_oper_queue(struct work_struct *work);
static void prism2_send_mgmt(struct net_device *dev,
			     u16 type_subtype, char *body,
			     int body_len, u8 *addr, u16 tx_cb_idx);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */


#if !defined(PRISM2_NO_PROCFS_DEBUG) && defined(CONFIG_PROC_FS)
static int ap_debug_proc_show(struct seq_file *m, void *v)
{
	struct ap_data *ap = PDE_DATA(file_inode(m->file));

	seq_printf(m, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
	seq_printf(m, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
	seq_printf(m, "max_inactivity=%u\n", ap->max_inactivity / HZ);
	seq_printf(m, "bridge_packets=%u\n", ap->bridge_packets);
	seq_printf(m, "nullfunc_ack=%u\n", ap->nullfunc_ack);
	seq_printf(m, "autom_ap_wds=%u\n", ap->autom_ap_wds);
	seq_printf(m, "auth_algs=%u\n", ap->local->auth_algs);
	seq_printf(m, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);
	return 0;
}
#endif

static void ap_sta_hash_add(struct ap_data *ap, struct sta_info *sta)
{
	sta->hnext = ap->sta_hash[STA_HASH(sta->addr)];
	ap->sta_hash[STA_HASH(sta->addr)] = sta;
}

static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta)
{
	struct sta_info *s;

	s = ap->sta_hash[STA_HASH(sta->addr)];
	if (s == NULL) return;
	if (ether_addr_equal(s->addr, sta->addr)) {
		ap->sta_hash[STA_HASH(sta->addr)] = s->hnext;
		return;
	}

	while (s->hnext != NULL && !ether_addr_equal(s->hnext->addr, sta->addr))
		s = s->hnext;
	if (s->hnext != NULL)
		s->hnext = s->hnext->hnext;
	else
		printk("AP: could not remove STA %pM from hash table\n",
		       sta->addr);
}

static void ap_free_sta(struct ap_data *ap, struct sta_info *sta)
{
	if (sta->ap && sta->local)
		hostap_event_expired_sta(sta->local->dev, sta);

	if (ap->proc != NULL) {
		char name[20];
		sprintf(name, "%pM", sta->addr);
		remove_proc_entry(name, ap->proc);
	}

	if (sta->crypt) {
		sta->crypt->ops->deinit(sta->crypt->priv);
		kfree(sta->crypt);
		sta->crypt = NULL;
	}

	skb_queue_purge(&sta->tx_buf);

	ap->num_sta--;
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	if (sta->aid > 0)
		ap->sta_aid[sta->aid - 1] = NULL;

	if (!sta->ap)
		kfree(sta->u.sta.challenge);
	timer_shutdown_sync(&sta->timer);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

	kfree(sta);
}


static void hostap_set_tim(local_info_t *local, int aid, int set)
{
	if (local->func->set_tim)
		local->func->set_tim(local->dev, aid, set);
}


static void hostap_event_new_sta(struct net_device *dev, struct sta_info *sta)
{
	union iwreq_data wrqu;
	memset(&wrqu, 0, sizeof(wrqu));
	memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN);
	wrqu.addr.sa_family = ARPHRD_ETHER;
	wireless_send_event(dev, IWEVREGISTERED, &wrqu, NULL);
}


static void hostap_event_expired_sta(struct net_device *dev,
				     struct sta_info *sta)
{
	union iwreq_data wrqu;
	memset(&wrqu, 0, sizeof(wrqu));
	memcpy(wrqu.addr.sa_data, sta->addr, ETH_ALEN);
	wrqu.addr.sa_family = ARPHRD_ETHER;
	wireless_send_event(dev, IWEVEXPIRED, &wrqu, NULL);
}


#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT

static void ap_handle_timer(struct timer_list *t)
{
	struct sta_info *sta = from_timer(sta, t, timer);
	local_info_t *local;
	struct ap_data *ap;
	unsigned long next_time = 0;
	int was_assoc;

	if (sta == NULL || sta->local == NULL || sta->local->ap == NULL) {
		PDEBUG(DEBUG_AP, "ap_handle_timer() called with NULL data\n");
		return;
	}

	local = sta->local;
	ap = local->ap;
	was_assoc = sta->flags & WLAN_STA_ASSOC;

	if (atomic_read(&sta->users) != 0)
		next_time = jiffies + HZ;
	else if ((sta->flags & WLAN_STA_PERM) && !(sta->flags & WLAN_STA_AUTH))
		next_time = jiffies + ap->max_inactivity;

	if (time_before(jiffies, sta->last_rx + ap->max_inactivity)) {
		/* station activity detected; reset timeout state */
		sta->timeout_next = STA_NULLFUNC;
		next_time = sta->last_rx + ap->max_inactivity;
	} else if (sta->timeout_next == STA_DISASSOC &&
		   !(sta->flags & WLAN_STA_PENDING_POLL)) {
		/* STA ACKed data nullfunc frame poll */
		sta->timeout_next = STA_NULLFUNC;
		next_time = jiffies + ap->max_inactivity;
	}

	if (next_time) {
		sta->timer.expires = next_time;
		add_timer(&sta->timer);
		return;
	}

	if (sta->ap)
		sta->timeout_next = STA_DEAUTH;

	if (sta->timeout_next == STA_DEAUTH && !(sta->flags & WLAN_STA_PERM)) {
		spin_lock(&ap->sta_table_lock);
		ap_sta_hash_del(ap, sta);
		list_del(&sta->list);
		spin_unlock(&ap->sta_table_lock);
		sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
	} else if (sta->timeout_next == STA_DISASSOC)
		sta->flags &= ~WLAN_STA_ASSOC;

	if (was_assoc && !(sta->flags & WLAN_STA_ASSOC) && !sta->ap)
		hostap_event_expired_sta(local->dev, sta);

	if (sta->timeout_next == STA_DEAUTH && sta->aid > 0 &&
	    !skb_queue_empty(&sta->tx_buf)) {
		hostap_set_tim(local, sta->aid, 0);
		sta->flags &= ~WLAN_STA_TIM;
	}

	if (sta->ap) {
		if (ap->autom_ap_wds) {
			PDEBUG(DEBUG_AP, "%s: removing automatic WDS "
			       "connection to AP %pM\n",
			       local->dev->name, sta->addr);
			hostap_wds_link_oper(local, sta->addr, WDS_DEL);
		}
	} else if (sta->timeout_next == STA_NULLFUNC) {
		/* send data frame to poll STA and check whether this frame
		 * is ACKed */
		/* FIX: IEEE80211_STYPE_NULLFUNC would be more appropriate, but
		 * it is apparently not retried so TX Exc events are not
		 * received for it */
		sta->flags |= WLAN_STA_PENDING_POLL;
		prism2_send_mgmt(local->dev, IEEE80211_FTYPE_DATA |
				 IEEE80211_STYPE_DATA, NULL, 0,
				 sta->addr, ap->tx_callback_poll);
	} else {
		int deauth = sta->timeout_next == STA_DEAUTH;
		__le16 resp;
		PDEBUG(DEBUG_AP, "%s: sending %s info to STA %pM"
		       "(last=%lu, jiffies=%lu)\n",
		       local->dev->name,
		       deauth ? "deauthentication" : "disassociation",
		       sta->addr, sta->last_rx, jiffies);

		resp = cpu_to_le16(deauth ? WLAN_REASON_PREV_AUTH_NOT_VALID :
				   WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
		prism2_send_mgmt(local->dev, IEEE80211_FTYPE_MGMT |
				 (deauth ? IEEE80211_STYPE_DEAUTH :
				  IEEE80211_STYPE_DISASSOC),
				 (char *) &resp, 2, sta->addr, 0);
	}

	if (sta->timeout_next == STA_DEAUTH) {
		if (sta->flags & WLAN_STA_PERM) {
			PDEBUG(DEBUG_AP, "%s: STA %pM"
			       " would have been removed, "
			       "but it has 'perm' flag\n",
			       local->dev->name, sta->addr);
		} else
			ap_free_sta(ap, sta);
		return;
	}

	if (sta->timeout_next == STA_NULLFUNC) {
		sta->timeout_next = STA_DISASSOC;
		sta->timer.expires = jiffies + AP_DISASSOC_DELAY;
	} else {
		sta->timeout_next = STA_DEAUTH;
		sta->timer.expires = jiffies + AP_DEAUTH_DELAY;
	}

	add_timer(&sta->timer);
}


void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
			    int resend)
{
	u8 addr[ETH_ALEN];
	__le16 resp;
	int i;

	PDEBUG(DEBUG_AP, "%s: Deauthenticate all stations\n", dev->name);
	eth_broadcast_addr(addr);

	resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);

	/* deauth message sent; try to resend it few times; the message is
	 * broadcast, so it may be delayed until next DTIM; there is not much
	 * else we can do at this point since the driver is going to be shut
	 * down */
	for (i = 0; i < 5; i++) {
		prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
				 IEEE80211_STYPE_DEAUTH,
				 (char *) &resp, 2, addr, 0);

		if (!resend || ap->num_sta <= 0)
			return;

		mdelay(50);
	}
}


static int ap_control_proc_show(struct seq_file *m, void *v)
{
	struct ap_data *ap = PDE_DATA(file_inode(m->file));
	char *policy_txt;
	struct mac_entry *entry;

	if (v == SEQ_START_TOKEN) {
		switch (ap->mac_restrictions.policy) {
		case MAC_POLICY_OPEN:
			policy_txt = "open";
			break;
		case MAC_POLICY_ALLOW:
			policy_txt = "allow";
			break;
		case MAC_POLICY_DENY:
			policy_txt = "deny";
			break;
		default:
			policy_txt = "unknown";
			break;
		}
		seq_printf(m, "MAC policy: %s\n", policy_txt);
		seq_printf(m, "MAC entries: %u\n", ap->mac_restrictions.entries);
		seq_puts(m, "MAC list:\n");
		return 0;
	}

	entry = v;
	seq_printf(m, "%pM\n", entry->addr);
	return 0;
}

static void *ap_control_proc_start(struct seq_file *m, loff_t *_pos)
{
	struct ap_data *ap = PDE_DATA(file_inode(m->file));
	spin_lock_bh(&ap->mac_restrictions.lock);
	return seq_list_start_head(&ap->mac_restrictions.mac_list, *_pos);
}

static void *ap_control_proc_next(struct seq_file *m, void *v, loff_t *_pos)
{
	struct ap_data *ap = PDE_DATA(file_inode(m->file));
	return seq_list_next(v, &ap->mac_restrictions.mac_list, _pos);
}

static void ap_control_proc_stop(struct seq_file *m, void *v)
{
	struct ap_data *ap = PDE_DATA(file_inode(m->file));
	spin_unlock_bh(&ap->mac_restrictions.lock);
}

static const struct seq_operations ap_control_proc_seqops = {
	.start	= ap_control_proc_start,
	.next	= ap_control_proc_next,
	.stop	= ap_control_proc_stop,
	.show	= ap_control_proc_show,
};

int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
{
	struct mac_entry *entry;

	entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL);
	if (entry == NULL)
		return -ENOMEM;

	memcpy(entry->addr, mac, ETH_ALEN);

	spin_lock_bh(&mac_restrictions->lock);
	list_add_tail(&entry->list, &mac_restrictions->mac_list);
	mac_restrictions->entries++;
	spin_unlock_bh(&mac_restrictions->lock);

	return 0;
}


int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
{
	struct list_head *ptr;
	struct mac_entry *entry;

	spin_lock_bh(&mac_restrictions->lock);
	for (ptr = mac_restrictions->mac_list.next;
	     ptr != &mac_restrictions->mac_list; ptr = ptr->next) {
		entry = list_entry(ptr, struct mac_entry, list);

		if (ether_addr_equal(entry->addr, mac)) {
			list_del(ptr);
			kfree(entry);
			mac_restrictions->entries--;
			spin_unlock_bh(&mac_restrictions->lock);
			return 0;
		}
	}
	spin_unlock_bh(&mac_restrictions->lock);
	return -1;
}


static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
			       u8 *mac)
{
	struct mac_entry *entry;
	int found = 0;

	if (mac_restrictions->policy == MAC_POLICY_OPEN)
		return 0;

	spin_lock_bh(&mac_restrictions->lock);
	list_for_each_entry(entry, &mac_restrictions->mac_list, list) {
		if (ether_addr_equal(entry->addr, mac)) {
			found = 1;
			break;
		}
	}
	spin_unlock_bh(&mac_restrictions->lock);

	if (mac_restrictions->policy == MAC_POLICY_ALLOW)
		return !found;
	else
		return found;
}


void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
{
	struct list_head *ptr, *n;
	struct mac_entry *entry;

	if (mac_restrictions->entries == 0)
		return;

	spin_lock_bh(&mac_restrictions->lock);
	for (ptr = mac_restrictions->mac_list.next, n = ptr->next;
	     ptr != &mac_restrictions->mac_list;
	     ptr = n, n = ptr->next) {
		entry = list_entry(ptr, struct mac_entry, list);
		list_del(ptr);
		kfree(entry);
	}
	mac_restrictions->entries = 0;
	spin_unlock_bh(&mac_restrictions->lock);
}


int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac)
{
	struct sta_info *sta;
	__le16 resp;

	spin_lock_bh(&ap->sta_table_lock);
	sta = ap_get_sta(ap, mac);
	if (sta) {
		ap_sta_hash_del(ap, sta);
		list_del(&sta->list);
	}
	spin_unlock_bh(&ap->sta_table_lock);

	if (!sta)
		return -EINVAL;

	resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
	prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH,
			 (char *) &resp, 2, sta->addr, 0);

	if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
		hostap_event_expired_sta(dev, sta);

	ap_free_sta(ap, sta);

	return 0;
}

#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */


void ap_control_kickall(struct ap_data *ap)
{
	struct list_head *ptr, *n;
	struct sta_info *sta;

	spin_lock_bh(&ap->sta_table_lock);
	for (ptr = ap->sta_list.next, n = ptr->next; ptr != &ap->sta_list;
	     ptr = n, n = ptr->next) {
		sta = list_entry(ptr, struct sta_info, list);
		ap_sta_hash_del(ap, sta);
		list_del(&sta->list);
		if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
			hostap_event_expired_sta(sta->local->dev, sta);
		ap_free_sta(ap, sta);
	}
	spin_unlock_bh(&ap->sta_table_lock);
}


#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT

static int prism2_ap_proc_show(struct seq_file *m, void *v)
{
	struct sta_info *sta = v;
	int i;

	if (v == SEQ_START_TOKEN) {
		seq_printf(m, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
		return 0;
	}

	if (!sta->ap)
		return 0;

	seq_printf(m, "%pM %d %d %d %d '",
		   sta->addr,
		   sta->u.ap.channel, sta->last_rx_signal,
		   sta->last_rx_silence, sta->last_rx_rate);

	for (i = 0; i < sta->u.ap.ssid_len; i++) {
		if (sta->u.ap.ssid[i] >= 32 && sta->u.ap.ssid[i] < 127)
			seq_putc(m, sta->u.ap.ssid[i]);
		else
			seq_printf(m, "<%02x>", sta->u.ap.ssid[i]);
	}

	seq_putc(m, '\'');
	if (sta->capability & WLAN_CAPABILITY_ESS)
		seq_puts(m, " [ESS]");
	if (sta->capability & WLAN_CAPABILITY_IBSS)
		seq_puts(m, " [IBSS]");
	if (sta->capability & WLAN_CAPABILITY_PRIVACY)
		seq_puts(m, " [WEP]");
	seq_putc(m, '\n');
	return 0;
}

static void *prism2_ap_proc_start(struct seq_file *m, loff_t *_pos)
{
	struct ap_data *ap = PDE_DATA(file_inode(m->file));
	spin_lock_bh(&ap->sta_table_lock);
	return seq_list_start_head(&ap->sta_list, *_pos);
}

static void *prism2_ap_proc_next(struct seq_file *m, void *v, loff_t *_pos)
{
	struct ap_data *ap = PDE_DATA(file_inode(m->file));
	return seq_list_next(v, &ap->sta_list, _pos);
}

static void prism2_ap_proc_stop(struct seq_file *m, void *v)
{
	struct ap_data *ap = PDE_DATA(file_inode(m->file));
	spin_unlock_bh(&ap->sta_table_lock);
}

static const struct seq_operations prism2_ap_proc_seqops = {
	.start	= prism2_ap_proc_start,
	.next	= prism2_ap_proc_next,
	.stop	= prism2_ap_proc_stop,
	.show	= prism2_ap_proc_show,
};
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */


void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver)
{
	if (!ap)
		return;

	if (sta_fw_ver == PRISM2_FW_VER(0,8,0)) {
		PDEBUG(DEBUG_AP, "Using data::nullfunc ACK workaround - "
		       "firmware upgrade recommended\n");
		ap->nullfunc_ack = 1;
	} else
		ap->nullfunc_ack = 0;

	if (sta_fw_ver == PRISM2_FW_VER(1,4,2)) {
		printk(KERN_WARNING "%s: Warning: secondary station firmware "
		       "version 1.4.2 does not seem to work in Host AP mode\n",
		       ap->local->dev->name);
	}
}


/* Called only as a tasklet (software IRQ) */
static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
{
	struct ap_data *ap = data;
	struct ieee80211_hdr *hdr;

	if (!ap->local->hostapd || !ap->local->apdev) {
		dev_kfree_skb(skb);
		return;
	}

	/* Pass the TX callback frame to the hostapd; use 802.11 header version
	 * 1 to indicate failure (no ACK) and 2 success (frame ACKed) */

	hdr = (struct ieee80211_hdr *) skb->data;
	hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_VERS);
	hdr->frame_control |= cpu_to_le16(ok ? BIT(1) : BIT(0));

	skb->dev = ap->local->apdev;
	skb_pull(skb, hostap_80211_get_hdrlen(hdr->frame_control));
	skb->pkt_type = PACKET_OTHERHOST;
	skb->protocol = cpu_to_be16(ETH_P_802_2);
	memset(skb->cb, 0, sizeof(skb->cb));
	netif_rx(skb);
}


#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
/* Called only as a tasklet (software IRQ) */
static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
{
	struct ap_data *ap = data;
	struct net_device *dev = ap->local->dev;
	struct ieee80211_hdr *hdr;
	u16 auth_alg, auth_transaction, status;
	__le16 *pos;
	struct sta_info *sta = NULL;
	char *txt = NULL;

	if (ap->local->hostapd) {
		dev_kfree_skb(skb);
		return;
	}

	hdr = (struct ieee80211_hdr *) skb->data;
	if (!ieee80211_is_auth(hdr->frame_control) ||
	    skb->len < IEEE80211_MGMT_HDR_LEN + 6) {
		printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid "
		       "frame\n", dev->name);
		dev_kfree_skb(skb);
		return;
	}

	pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
	auth_alg = le16_to_cpu(*pos++);
	auth_transaction = le16_to_cpu(*pos++);
	status = le16_to_cpu(*pos++);

	if (!ok) {
		txt = "frame was not ACKed";
		goto done;
	}

	spin_lock(&ap->sta_table_lock);
	sta = ap_get_sta(ap, hdr->addr1);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock(&ap->sta_table_lock);

	if (!sta) {
		txt = "STA not found";
		goto done;
	}

	if (status == WLAN_STATUS_SUCCESS &&
	    ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
	     (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
		txt = "STA authenticated";
		sta->flags |= WLAN_STA_AUTH;
		sta->last_auth = jiffies;
	} else if (status != WLAN_STATUS_SUCCESS)
		txt = "authentication failed";

 done:
	if (sta)
		atomic_dec(&sta->users);
	if (txt) {
		PDEBUG(DEBUG_AP, "%s: %pM auth_cb - alg=%d "
		       "trans#=%d status=%d - %s\n",
		       dev->name, hdr->addr1,
		       auth_alg, auth_transaction, status, txt);
	}
	dev_kfree_skb(skb);
}


/* Called only as a tasklet (software IRQ) */
static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
{
	struct ap_data *ap = data;
	struct net_device *dev = ap->local->dev;
	struct ieee80211_hdr *hdr;
	u16 status;
	__le16 *pos;
	struct sta_info *sta = NULL;
	char *txt = NULL;

	if (ap->local->hostapd) {
		dev_kfree_skb(skb);
		return;
	}

	hdr = (struct ieee80211_hdr *) skb->data;
	if ((!ieee80211_is_assoc_resp(hdr->frame_control) &&
	     !ieee80211_is_reassoc_resp(hdr->frame_control)) ||
	    skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
		printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid "
		       "frame\n", dev->name);
		dev_kfree_skb(skb);
		return;
	}

	if (!ok) {
		txt = "frame was not ACKed";
		goto done;
	}

	spin_lock(&ap->sta_table_lock);
	sta = ap_get_sta(ap, hdr->addr1);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock(&ap->sta_table_lock);

	if (!sta) {
		txt = "STA not found";
		goto done;
	}

	pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
	pos++;
	status = le16_to_cpu(*pos++);
	if (status == WLAN_STATUS_SUCCESS) {
		if (!(sta->flags & WLAN_STA_ASSOC))
			hostap_event_new_sta(dev, sta);
		txt = "STA associated";
		sta->flags |= WLAN_STA_ASSOC;
		sta->last_assoc = jiffies;
	} else
		txt = "association failed";

 done:
	if (sta)
		atomic_dec(&sta->users);
	if (txt) {
		PDEBUG(DEBUG_AP, "%s: %pM assoc_cb - %s\n",
		       dev->name, hdr->addr1, txt);
	}
	dev_kfree_skb(skb);
}

/* Called only as a tasklet (software IRQ); TX callback for poll frames used
 * in verifying whether the STA is still present. */
static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
{
	struct ap_data *ap = data;
	struct ieee80211_hdr *hdr;
	struct sta_info *sta;

	if (skb->len < 24)
		goto fail;
	hdr = (struct ieee80211_hdr *) skb->data;
	if (ok) {
		spin_lock(&ap->sta_table_lock);
		sta = ap_get_sta(ap, hdr->addr1);
		if (sta)
			sta->flags &= ~WLAN_STA_PENDING_POLL;
		spin_unlock(&ap->sta_table_lock);
	} else {
		PDEBUG(DEBUG_AP,
		       "%s: STA %pM did not ACK activity poll frame\n",
		       ap->local->dev->name, hdr->addr1);
	}

 fail:
	dev_kfree_skb(skb);
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */


void hostap_init_data(local_info_t *local)
{
	struct ap_data *ap = local->ap;

	if (ap == NULL) {
		printk(KERN_WARNING "hostap_init_data: ap == NULL\n");
		return;
	}
	memset(ap, 0, sizeof(struct ap_data));
	ap->local = local;

	ap->ap_policy = GET_INT_PARM(other_ap_policy, local->card_idx);
	ap->bridge_packets = GET_INT_PARM(ap_bridge_packets, local->card_idx);
	ap->max_inactivity =
		GET_INT_PARM(ap_max_inactivity, local->card_idx) * HZ;
	ap->autom_ap_wds = GET_INT_PARM(autom_ap_wds, local->card_idx);

	spin_lock_init(&ap->sta_table_lock);
	INIT_LIST_HEAD(&ap->sta_list);

	/* Initialize task queue structure for AP management */
	INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue);

	ap->tx_callback_idx =
		hostap_tx_callback_register(local, hostap_ap_tx_cb, ap);
	if (ap->tx_callback_idx == 0)
		printk(KERN_WARNING "%s: failed to register TX callback for "
		       "AP\n", local->dev->name);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue);

	ap->tx_callback_auth =
		hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap);
	ap->tx_callback_assoc =
		hostap_tx_callback_register(local, hostap_ap_tx_cb_assoc, ap);
	ap->tx_callback_poll =
		hostap_tx_callback_register(local, hostap_ap_tx_cb_poll, ap);
	if (ap->tx_callback_auth == 0 || ap->tx_callback_assoc == 0 ||
		ap->tx_callback_poll == 0)
		printk(KERN_WARNING "%s: failed to register TX callback for "
		       "AP\n", local->dev->name);

	spin_lock_init(&ap->mac_restrictions.lock);
	INIT_LIST_HEAD(&ap->mac_restrictions.mac_list);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

	ap->initialized = 1;
}


void hostap_init_ap_proc(local_info_t *local)
{
	struct ap_data *ap = local->ap;

	ap->proc = local->proc;
	if (ap->proc == NULL)
		return;

#ifndef PRISM2_NO_PROCFS_DEBUG
	proc_create_single_data("ap_debug", 0, ap->proc, ap_debug_proc_show, ap);
#endif /* PRISM2_NO_PROCFS_DEBUG */

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	proc_create_seq_data("ap_control", 0, ap->proc, &ap_control_proc_seqops,
			ap);
	proc_create_seq_data("ap", 0, ap->proc, &prism2_ap_proc_seqops, ap);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

}


void hostap_free_data(struct ap_data *ap)
{
	struct sta_info *n, *sta;

	if (ap == NULL || !ap->initialized) {
		printk(KERN_DEBUG "hostap_free_data: ap has not yet been "
		       "initialized - skip resource freeing\n");
		return;
	}

	flush_work(&ap->add_sta_proc_queue);

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	flush_work(&ap->wds_oper_queue);
	if (ap->crypt)
		ap->crypt->deinit(ap->crypt_priv);
	ap->crypt = ap->crypt_priv = NULL;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

	list_for_each_entry_safe(sta, n, &ap->sta_list, list) {
		ap_sta_hash_del(ap, sta);
		list_del(&sta->list);
		if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
			hostap_event_expired_sta(sta->local->dev, sta);
		ap_free_sta(ap, sta);
	}

#ifndef PRISM2_NO_PROCFS_DEBUG
	if (ap->proc != NULL) {
		remove_proc_entry("ap_debug", ap->proc);
	}
#endif /* PRISM2_NO_PROCFS_DEBUG */

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	if (ap->proc != NULL) {
	  remove_proc_entry("ap", ap->proc);
		remove_proc_entry("ap_control", ap->proc);
	}
	ap_control_flush_macs(&ap->mac_restrictions);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

	ap->initialized = 0;
}


/* caller should have mutex for AP STA list handling */
static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta)
{
	struct sta_info *s;

	s = ap->sta_hash[STA_HASH(sta)];
	while (s != NULL && !ether_addr_equal(s->addr, sta))
		s = s->hnext;
	return s;
}


#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT

/* Called from timer handler and from scheduled AP queue handlers */
static void prism2_send_mgmt(struct net_device *dev,
			     u16 type_subtype, char *body,
			     int body_len, u8 *addr, u16 tx_cb_idx)
{
	struct hostap_interface *iface;
	local_info_t *local;
	struct ieee80211_hdr *hdr;
	u16 fc;
	struct sk_buff *skb;
	struct hostap_skb_tx_data *meta;
	int hdrlen;

	iface = netdev_priv(dev);
	local = iface->local;
	dev = local->dev; /* always use master radio device */
	iface = netdev_priv(dev);

	if (!(dev->flags & IFF_UP)) {
		PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt - device is not UP - "
		       "cannot send frame\n", dev->name);
		return;
	}

	skb = dev_alloc_skb(sizeof(*hdr) + body_len);
	if (skb == NULL) {
		PDEBUG(DEBUG_AP, "%s: prism2_send_mgmt failed to allocate "
		       "skb\n", dev->name);
		return;
	}

	fc = type_subtype;
	hdrlen = hostap_80211_get_hdrlen(cpu_to_le16(type_subtype));
	hdr = skb_put_zero(skb, hdrlen);
	if (body)
		skb_put_data(skb, body, body_len);

	/* FIX: ctrl::ack sending used special HFA384X_TX_CTRL_802_11
	 * tx_control instead of using local->tx_control */


	memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */
	if (ieee80211_is_data(hdr->frame_control)) {
		fc |= IEEE80211_FCTL_FROMDS;
		memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
		memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */
	} else if (ieee80211_is_ctl(hdr->frame_control)) {
		/* control:ACK does not have addr2 or addr3 */
		eth_zero_addr(hdr->addr2);
		eth_zero_addr(hdr->addr3);
	} else {
		memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* SA */
		memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
	}

	hdr->frame_control = cpu_to_le16(fc);

	meta = (struct hostap_skb_tx_data *) skb->cb;
	memset(meta, 0, sizeof(*meta));
	meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
	meta->iface = iface;
	meta->tx_cb_idx = tx_cb_idx;

	skb->dev = dev;
	skb_reset_mac_header(skb);
	skb_reset_network_header(skb);
	dev_queue_xmit(skb);
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

#ifdef CONFIG_PROC_FS
static int prism2_sta_proc_show(struct seq_file *m, void *v)
{
	struct sta_info *sta = m->private;
	int i;

	/* FIX: possible race condition.. the STA data could have just expired,
	 * but proc entry was still here so that the read could have started;
	 * some locking should be done here.. */

	seq_printf(m,
		   "%s=%pM\nusers=%d\naid=%d\n"
		   "flags=0x%04x%s%s%s%s%s%s%s\n"
		   "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
		   sta->ap ? "AP" : "STA",
		   sta->addr, atomic_read(&sta->users), sta->aid,
		   sta->flags,
		   sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
		   sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
		   sta->flags & WLAN_STA_PS ? " PS" : "",
		   sta->flags & WLAN_STA_TIM ? " TIM" : "",
		   sta->flags & WLAN_STA_PERM ? " PERM" : "",
		   sta->flags & WLAN_STA_AUTHORIZED ? " AUTHORIZED" : "",
		   sta->flags & WLAN_STA_PENDING_POLL ? " POLL" : "",
		   sta->capability, sta->listen_interval);
	/* supported_rates: 500 kbit/s units with msb ignored */
	for (i = 0; i < sizeof(sta->supported_rates); i++)
		if (sta->supported_rates[i] != 0)
			seq_printf(m, "%d%sMbps ",
				   (sta->supported_rates[i] & 0x7f) / 2,
				   sta->supported_rates[i] & 1 ? ".5" : "");
	seq_printf(m,
		   "\njiffies=%lu\nlast_auth=%lu\nlast_assoc=%lu\n"
		   "last_rx=%lu\nlast_tx=%lu\nrx_packets=%lu\n"
		   "tx_packets=%lu\n"
		   "rx_bytes=%lu\ntx_bytes=%lu\nbuffer_count=%d\n"
		   "last_rx: silence=%d dBm signal=%d dBm rate=%d%s Mbps\n"
		   "tx_rate=%d\ntx[1M]=%d\ntx[2M]=%d\ntx[5.5M]=%d\n"
		   "tx[11M]=%d\n"
		   "rx[1M]=%d\nrx[2M]=%d\nrx[5.5M]=%d\nrx[11M]=%d\n",
		   jiffies, sta->last_auth, sta->last_assoc, sta->last_rx,
		   sta->last_tx,
		   sta->rx_packets, sta->tx_packets, sta->rx_bytes,
		   sta->tx_bytes, skb_queue_len(&sta->tx_buf),
		   sta->last_rx_silence,
		   sta->last_rx_signal, sta->last_rx_rate / 10,
		   sta->last_rx_rate % 10 ? ".5" : "",
		   sta->tx_rate, sta->tx_count[0], sta->tx_count[1],
		   sta->tx_count[2], sta->tx_count[3],  sta->rx_count[0],
		   sta->rx_count[1], sta->rx_count[2], sta->rx_count[3]);
	if (sta->crypt && sta->crypt->ops && sta->crypt->ops->print_stats)
		sta->crypt->ops->print_stats(m, sta->crypt->priv);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	if (sta->ap) {
		if (sta->u.ap.channel >= 0)
			seq_printf(m, "channel=%d\n", sta->u.ap.channel);
		seq_puts(m, "ssid=");
		for (i = 0; i < sta->u.ap.ssid_len; i++) {
			if (sta->u.ap.ssid[i] >= 32 && sta->u.ap.ssid[i] < 127)
				seq_putc(m, sta->u.ap.ssid[i]);
			else
				seq_printf(m, "<%02x>", sta->u.ap.ssid[i]);
		}
		seq_putc(m, '\n');
	}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

	return 0;
}
#endif

static void handle_add_proc_queue(struct work_struct *work)
{
	struct ap_data *ap = container_of(work, struct ap_data,
					  add_sta_proc_queue);
	struct sta_info *sta;
	char name[20];
	struct add_sta_proc_data *entry, *prev;

	entry = ap->add_sta_proc_entries;
	ap->add_sta_proc_entries = NULL;

	while (entry) {
		spin_lock_bh(&ap->sta_table_lock);
		sta = ap_get_sta(ap, entry->addr);
		if (sta)
			atomic_inc(&sta->users);
		spin_unlock_bh(&ap->sta_table_lock);

		if (sta) {
			sprintf(name, "%pM", sta->addr);
			sta->proc = proc_create_single_data(
				name, 0, ap->proc,
				prism2_sta_proc_show, sta);

			atomic_dec(&sta->users);
		}

		prev = entry;
		entry = entry->next;
		kfree(prev);
	}
}


static struct sta_info * ap_add_sta(struct ap_data *ap, u8 *addr)
{
	struct sta_info *sta;

	sta = kzalloc(sizeof(struct sta_info), GFP_ATOMIC);
	if (sta == NULL) {
		PDEBUG(DEBUG_AP, "AP: kmalloc failed\n");
		return NULL;
	}

	/* initialize STA info data */
	sta->local = ap->local;
	skb_queue_head_init(&sta->tx_buf);
	memcpy(sta->addr, addr, ETH_ALEN);

	atomic_inc(&sta->users);
	spin_lock_bh(&ap->sta_table_lock);
	list_add(&sta->list, &ap->sta_list);
	ap->num_sta++;
	ap_sta_hash_add(ap, sta);
	spin_unlock_bh(&ap->sta_table_lock);

	if (ap->proc) {
		struct add_sta_proc_data *entry;
		/* schedule a non-interrupt context process to add a procfs
		 * entry for the STA since procfs code use GFP_KERNEL */
		entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
		if (entry) {
			memcpy(entry->addr, sta->addr, ETH_ALEN);
			entry->next = ap->add_sta_proc_entries;
			ap->add_sta_proc_entries = entry;
			schedule_work(&ap->add_sta_proc_queue);
		} else
			printk(KERN_DEBUG "Failed to add STA proc data\n");
	}

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	timer_setup(&sta->timer, ap_handle_timer, 0);
	sta->timer.expires = jiffies + ap->max_inactivity;
	if (!ap->local->hostapd)
		add_timer(&sta->timer);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

	return sta;
}


static int ap_tx_rate_ok(int rateidx, struct sta_info *sta,
			 local_info_t *local)
{
	if (rateidx > sta->tx_max_rate ||
	    !(sta->tx_supp_rates & (1 << rateidx)))
		return 0;

	if (local->tx_rate_control != 0 &&
	    !(local->tx_rate_control & (1 << rateidx)))
		return 0;

	return 1;
}


static void prism2_check_tx_rates(struct sta_info *sta)
{
	int i;

	sta->tx_supp_rates = 0;
	for (i = 0; i < sizeof(sta->supported_rates); i++) {
		if ((sta->supported_rates[i] & 0x7f) == 2)
			sta->tx_supp_rates |= WLAN_RATE_1M;
		if ((sta->supported_rates[i] & 0x7f) == 4)
			sta->tx_supp_rates |= WLAN_RATE_2M;
		if ((sta->supported_rates[i] & 0x7f) == 11)
			sta->tx_supp_rates |= WLAN_RATE_5M5;
		if ((sta->supported_rates[i] & 0x7f) == 22)
			sta->tx_supp_rates |= WLAN_RATE_11M;
	}
	sta->tx_max_rate = sta->tx_rate = sta->tx_rate_idx = 0;
	if (sta->tx_supp_rates & WLAN_RATE_1M) {
		sta->tx_max_rate = 0;
		if (ap_tx_rate_ok(0, sta, sta->local)) {
			sta->tx_rate = 10;
			sta->tx_rate_idx = 0;
		}
	}
	if (sta->tx_supp_rates & WLAN_RATE_2M) {
		sta->tx_max_rate = 1;
		if (ap_tx_rate_ok(1, sta, sta->local)) {
			sta->tx_rate = 20;
			sta->tx_rate_idx = 1;
		}
	}
	if (sta->tx_supp_rates & WLAN_RATE_5M5) {
		sta->tx_max_rate = 2;
		if (ap_tx_rate_ok(2, sta, sta->local)) {
			sta->tx_rate = 55;
			sta->tx_rate_idx = 2;
		}
	}
	if (sta->tx_supp_rates & WLAN_RATE_11M) {
		sta->tx_max_rate = 3;
		if (ap_tx_rate_ok(3, sta, sta->local)) {
			sta->tx_rate = 110;
			sta->tx_rate_idx = 3;
		}
	}
}


#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT

static void ap_crypt_init(struct ap_data *ap)
{
	ap->crypt = lib80211_get_crypto_ops("WEP");

	if (ap->crypt) {
		if (ap->crypt->init) {
			ap->crypt_priv = ap->crypt->init(0);
			if (ap->crypt_priv == NULL)
				ap->crypt = NULL;
			else {
				u8 key[WEP_KEY_LEN];
				get_random_bytes(key, WEP_KEY_LEN);
				ap->crypt->set_key(key, WEP_KEY_LEN, NULL,
						   ap->crypt_priv);
			}
		}
	}

	if (ap->crypt == NULL) {
		printk(KERN_WARNING "AP could not initialize WEP: load module "
		       "lib80211_crypt_wep.ko\n");
	}
}


/* Generate challenge data for shared key authentication. IEEE 802.11 specifies
 * that WEP algorithm is used for generating challenge. This should be unique,
 * but otherwise there is not really need for randomness etc. Initialize WEP
 * with pseudo random key and then use increasing IV to get unique challenge
 * streams.
 *
 * Called only as a scheduled task for pending AP frames.
 */
static char * ap_auth_make_challenge(struct ap_data *ap)
{
	char *tmpbuf;
	struct sk_buff *skb;

	if (ap->crypt == NULL) {
		ap_crypt_init(ap);
		if (ap->crypt == NULL)
			return NULL;
	}

	tmpbuf = kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC);
	if (tmpbuf == NULL) {
		PDEBUG(DEBUG_AP, "AP: kmalloc failed for challenge\n");
		return NULL;
	}

	skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
			    ap->crypt->extra_mpdu_prefix_len +
			    ap->crypt->extra_mpdu_postfix_len);
	if (skb == NULL) {
		kfree(tmpbuf);
		return NULL;
	}

	skb_reserve(skb, ap->crypt->extra_mpdu_prefix_len);
	skb_put_zero(skb, WLAN_AUTH_CHALLENGE_LEN);
	if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
		dev_kfree_skb(skb);
		kfree(tmpbuf);
		return NULL;
	}

	skb_copy_from_linear_data_offset(skb, ap->crypt->extra_mpdu_prefix_len,
					 tmpbuf, WLAN_AUTH_CHALLENGE_LEN);
	dev_kfree_skb(skb);

	return tmpbuf;
}


/* Called only as a scheduled task for pending AP frames. */
static void handle_authen(local_info_t *local, struct sk_buff *skb,
			  struct hostap_80211_rx_status *rx_stats)
{
	struct net_device *dev = local->dev;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	size_t hdrlen;
	struct ap_data *ap = local->ap;
	char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
	int len, olen;
	u16 auth_alg, auth_transaction, status_code;
	__le16 *pos;
	u16 resp = WLAN_STATUS_SUCCESS;
	struct sta_info *sta = NULL;
	struct lib80211_crypt_data *crypt;
	char *txt = "";

	len = skb->len - IEEE80211_MGMT_HDR_LEN;

	hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);

	if (len < 6) {
		PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
		       "(len=%d) from %pM\n", dev->name, len, hdr->addr2);
		return;
	}

	spin_lock_bh(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock_bh(&local->ap->sta_table_lock);

	if (sta && sta->crypt)
		crypt = sta->crypt;
	else {
		int idx = 0;
		if (skb->len >= hdrlen + 3)
			idx = skb->data[hdrlen + 3] >> 6;
		crypt = local->crypt_info.crypt[idx];
	}

	pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
	auth_alg = __le16_to_cpu(*pos);
	pos++;
	auth_transaction = __le16_to_cpu(*pos);
	pos++;
	status_code = __le16_to_cpu(*pos);
	pos++;

	if (ether_addr_equal(dev->dev_addr, hdr->addr2) ||
	    ap_control_mac_deny(&ap->mac_restrictions, hdr->addr2)) {
		txt = "authentication denied";
		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
		goto fail;
	}

	if (((local->auth_algs & PRISM2_AUTH_OPEN) &&
	     auth_alg == WLAN_AUTH_OPEN) ||
	    ((local->auth_algs & PRISM2_AUTH_SHARED_KEY) &&
	     crypt && auth_alg == WLAN_AUTH_SHARED_KEY)) {
	} else {
		txt = "unsupported algorithm";
		resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
		goto fail;
	}

	if (len >= 8) {
		u8 *u = (u8 *) pos;
		if (*u == WLAN_EID_CHALLENGE) {
			if (*(u + 1) != WLAN_AUTH_CHALLENGE_LEN) {
				txt = "invalid challenge len";
				resp = WLAN_STATUS_CHALLENGE_FAIL;
				goto fail;
			}
			if (len - 8 < WLAN_AUTH_CHALLENGE_LEN) {
				txt = "challenge underflow";
				resp = WLAN_STATUS_CHALLENGE_FAIL;
				goto fail;
			}
			challenge = (char *) (u + 2);
		}
	}

	if (sta && sta->ap) {
		if (time_after(jiffies, sta->u.ap.last_beacon +
			       (10 * sta->listen_interval * HZ) / 1024)) {
			PDEBUG(DEBUG_AP, "%s: no beacons received for a while,"
			       " assuming AP %pM is now STA\n",
			       dev->name, sta->addr);
			sta->ap = 0;
			sta->flags = 0;
			sta->u.sta.challenge = NULL;
		} else {
			txt = "AP trying to authenticate?";
			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
			goto fail;
		}
	}

	if ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) ||
	    (auth_alg == WLAN_AUTH_SHARED_KEY &&
	     (auth_transaction == 1 ||
	      (auth_transaction == 3 && sta != NULL &&
	       sta->u.sta.challenge != NULL)))) {
	} else {
		txt = "unknown authentication transaction number";
		resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
		goto fail;
	}

	if (sta == NULL) {
		txt = "new STA";

		if (local->ap->num_sta >= MAX_STA_COUNT) {
			/* FIX: might try to remove some old STAs first? */
			txt = "no more room for new STAs";
			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
			goto fail;
		}

		sta = ap_add_sta(local->ap, hdr->addr2);
		if (sta == NULL) {
			txt = "ap_add_sta failed";
			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
			goto fail;
		}
	}

	switch (auth_alg) {
	case WLAN_AUTH_OPEN:
		txt = "authOK";
		/* IEEE 802.11 standard is not completely clear about
		 * whether STA is considered authenticated after
		 * authentication OK frame has been send or after it
		 * has been ACKed. In order to reduce interoperability
		 * issues, mark the STA authenticated before ACK. */
		sta->flags |= WLAN_STA_AUTH;
		break;

	case WLAN_AUTH_SHARED_KEY:
		if (auth_transaction == 1) {
			if (sta->u.sta.challenge == NULL) {
				sta->u.sta.challenge =
					ap_auth_make_challenge(local->ap);
				if (sta->u.sta.challenge == NULL) {
					resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
					goto fail;
				}
			}
		} else {
			if (sta->u.sta.challenge == NULL ||
			    challenge == NULL ||
			    memcmp(sta->u.sta.challenge, challenge,
				   WLAN_AUTH_CHALLENGE_LEN) != 0 ||
			    !ieee80211_has_protected(hdr->frame_control)) {
				txt = "challenge response incorrect";
				resp = WLAN_STATUS_CHALLENGE_FAIL;
				goto fail;
			}

			txt = "challenge OK - authOK";
			/* IEEE 802.11 standard is not completely clear about
			 * whether STA is considered authenticated after
			 * authentication OK frame has been send or after it
			 * has been ACKed. In order to reduce interoperability
			 * issues, mark the STA authenticated before ACK. */
			sta->flags |= WLAN_STA_AUTH;
			kfree(sta->u.sta.challenge);
			sta->u.sta.challenge = NULL;
		}
		break;
	}

 fail:
	pos = (__le16 *) body;
	*pos = cpu_to_le16(auth_alg);
	pos++;
	*pos = cpu_to_le16(auth_transaction + 1);
	pos++;
	*pos = cpu_to_le16(resp); /* status_code */
	pos++;
	olen = 6;

	if (resp == WLAN_STATUS_SUCCESS && sta != NULL &&
	    sta->u.sta.challenge != NULL &&
	    auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 1) {
		u8 *tmp = (u8 *) pos;
		*tmp++ = WLAN_EID_CHALLENGE;
		*tmp++ = WLAN_AUTH_CHALLENGE_LEN;
		pos++;
		memcpy(pos, sta->u.sta.challenge, WLAN_AUTH_CHALLENGE_LEN);
		olen += 2 + WLAN_AUTH_CHALLENGE_LEN;
	}

	prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH,
			 body, olen, hdr->addr2, ap->tx_callback_auth);

	if (sta) {
		sta->last_rx = jiffies;
		atomic_dec(&sta->users);
	}

	if (resp) {
		PDEBUG(DEBUG_AP, "%s: %pM auth (alg=%d "
		       "trans#=%d stat=%d len=%d fc=%04x) ==> %d (%s)\n",
		       dev->name, hdr->addr2,
		       auth_alg, auth_transaction, status_code, len,
		       le16_to_cpu(hdr->frame_control), resp, txt);
	}
}


/* Called only as a scheduled task for pending AP frames. */
static void handle_assoc(local_info_t *local, struct sk_buff *skb,
			 struct hostap_80211_rx_status *rx_stats, int reassoc)
{
	struct net_device *dev = local->dev;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	char body[12], *p, *lpos;
	int len, left;
	__le16 *pos;
	u16 resp = WLAN_STATUS_SUCCESS;
	struct sta_info *sta = NULL;
	int send_deauth = 0;
	char *txt = "";
	u8 prev_ap[ETH_ALEN];

	left = len = skb->len - IEEE80211_MGMT_HDR_LEN;

	if (len < (reassoc ? 10 : 4)) {
		PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload "
		       "(len=%d, reassoc=%d) from %pM\n",
		       dev->name, len, reassoc, hdr->addr2);
		return;
	}

	spin_lock_bh(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
		spin_unlock_bh(&local->ap->sta_table_lock);
		txt = "trying to associate before authentication";
		send_deauth = 1;
		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
		sta = NULL; /* do not decrement sta->users */
		goto fail;
	}
	atomic_inc(&sta->users);
	spin_unlock_bh(&local->ap->sta_table_lock);

	pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
	sta->capability = __le16_to_cpu(*pos);
	pos++; left -= 2;
	sta->listen_interval = __le16_to_cpu(*pos);
	pos++; left -= 2;

	if (reassoc) {
		memcpy(prev_ap, pos, ETH_ALEN);
		pos++; pos++; pos++; left -= 6;
	} else
		eth_zero_addr(prev_ap);

	if (left >= 2) {
		unsigned int ileft;
		unsigned char *u = (unsigned char *) pos;

		if (*u == WLAN_EID_SSID) {
			u++; left--;
			ileft = *u;
			u++; left--;

			if (ileft > left || ileft > MAX_SSID_LEN) {
				txt = "SSID overflow";
				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
				goto fail;
			}

			if (ileft != strlen(local->essid) ||
			    memcmp(local->essid, u, ileft) != 0) {
				txt = "not our SSID";
				resp = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
				goto fail;
			}

			u += ileft;
			left -= ileft;
		}

		if (left >= 2 && *u == WLAN_EID_SUPP_RATES) {
			u++; left--;
			ileft = *u;
			u++; left--;

			if (ileft > left || ileft == 0 ||
			    ileft > WLAN_SUPP_RATES_MAX) {
				txt = "SUPP_RATES len error";
				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
				goto fail;
			}

			memset(sta->supported_rates, 0,
			       sizeof(sta->supported_rates));
			memcpy(sta->supported_rates, u, ileft);
			prism2_check_tx_rates(sta);

			u += ileft;
			left -= ileft;
		}

		if (left > 0) {
			PDEBUG(DEBUG_AP, "%s: assoc from %pM"
			       " with extra data (%d bytes) [",
			       dev->name, hdr->addr2, left);
			while (left > 0) {
				PDEBUG2(DEBUG_AP, "<%02x>", *u);
				u++; left--;
			}
			PDEBUG2(DEBUG_AP, "]\n");
		}
	} else {
		txt = "frame underflow";
		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
		goto fail;
	}

	/* get a unique AID */
	if (sta->aid > 0)
		txt = "OK, old AID";
	else {
		spin_lock_bh(&local->ap->sta_table_lock);
		for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)
			if (local->ap->sta_aid[sta->aid - 1] == NULL)
				break;
		if (sta->aid > MAX_AID_TABLE_SIZE) {
			sta->aid = 0;
			spin_unlock_bh(&local->ap->sta_table_lock);
			resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
			txt = "no room for more AIDs";
		} else {
			local->ap->sta_aid[sta->aid - 1] = sta;
			spin_unlock_bh(&local->ap->sta_table_lock);
			txt = "OK, new AID";
		}
	}

 fail:
	pos = (__le16 *) body;

	if (send_deauth) {
		*pos = cpu_to_le16(WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
		pos++;
	} else {
		/* FIX: CF-Pollable and CF-PollReq should be set to match the
		 * values in beacons/probe responses */
		/* FIX: how about privacy and WEP? */
		/* capability */
		*pos = cpu_to_le16(WLAN_CAPABILITY_ESS);
		pos++;

		/* status_code */
		*pos = cpu_to_le16(resp);
		pos++;

		*pos = cpu_to_le16((sta && sta->aid > 0 ? sta->aid : 0) |
				     BIT(14) | BIT(15)); /* AID */
		pos++;

		/* Supported rates (Information element) */
		p = (char *) pos;
		*p++ = WLAN_EID_SUPP_RATES;
		lpos = p;
		*p++ = 0; /* len */
		if (local->tx_rate_control & WLAN_RATE_1M) {
			*p++ = local->basic_rates & WLAN_RATE_1M ? 0x82 : 0x02;
			(*lpos)++;
		}
		if (local->tx_rate_control & WLAN_RATE_2M) {
			*p++ = local->basic_rates & WLAN_RATE_2M ? 0x84 : 0x04;
			(*lpos)++;
		}
		if (local->tx_rate_control & WLAN_RATE_5M5) {
			*p++ = local->basic_rates & WLAN_RATE_5M5 ?
				0x8b : 0x0b;
			(*lpos)++;
		}
		if (local->tx_rate_control & WLAN_RATE_11M) {
			*p++ = local->basic_rates & WLAN_RATE_11M ?
				0x96 : 0x16;
			(*lpos)++;
		}
		pos = (__le16 *) p;
	}

	prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
			 (send_deauth ? IEEE80211_STYPE_DEAUTH :
			  (reassoc ? IEEE80211_STYPE_REASSOC_RESP :
			   IEEE80211_STYPE_ASSOC_RESP)),
			 body, (u8 *) pos - (u8 *) body,
			 hdr->addr2,
			 send_deauth ? 0 : local->ap->tx_callback_assoc);

	if (sta) {
		if (resp == WLAN_STATUS_SUCCESS) {
			sta->last_rx = jiffies;
			/* STA will be marked associated from TX callback, if
			 * AssocResp is ACKed */
		}
		atomic_dec(&sta->users);
	}

#if 0
	PDEBUG(DEBUG_AP, "%s: %pM %sassoc (len=%d "
	       "prev_ap=%pM) => %d(%d) (%s)\n",
	       dev->name,
	       hdr->addr2,
	       reassoc ? "re" : "", len,
	       prev_ap,
	       resp, send_deauth, txt);
#endif
}


/* Called only as a scheduled task for pending AP frames. */
static void handle_deauth(local_info_t *local, struct sk_buff *skb,
			  struct hostap_80211_rx_status *rx_stats)
{
	struct net_device *dev = local->dev;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
	int len;
	u16 reason_code;
	__le16 *pos;
	struct sta_info *sta = NULL;

	len = skb->len - IEEE80211_MGMT_HDR_LEN;

	if (len < 2) {
		printk("handle_deauth - too short payload (len=%d)\n", len);
		return;
	}

	pos = (__le16 *) body;
	reason_code = le16_to_cpu(*pos);

	PDEBUG(DEBUG_AP, "%s: deauthentication: %pM len=%d, "
	       "reason_code=%d\n", dev->name, hdr->addr2,
	       len, reason_code);

	spin_lock_bh(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta != NULL) {
		if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
			hostap_event_expired_sta(local->dev, sta);
		sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
	}
	spin_unlock_bh(&local->ap->sta_table_lock);
	if (sta == NULL) {
		printk("%s: deauthentication from %pM, "
	       "reason_code=%d, but STA not authenticated\n", dev->name,
		       hdr->addr2, reason_code);
	}
}


/* Called only as a scheduled task for pending AP frames. */
static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
			    struct hostap_80211_rx_status *rx_stats)
{
	struct net_device *dev = local->dev;
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
	int len;
	u16 reason_code;
	__le16 *pos;
	struct sta_info *sta = NULL;

	len = skb->len - IEEE80211_MGMT_HDR_LEN;

	if (len < 2) {
		printk("handle_disassoc - too short payload (len=%d)\n", len);
		return;
	}

	pos = (__le16 *) body;
	reason_code = le16_to_cpu(*pos);

	PDEBUG(DEBUG_AP, "%s: disassociation: %pM len=%d, "
	       "reason_code=%d\n", dev->name, hdr->addr2,
	       len, reason_code);

	spin_lock_bh(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta != NULL) {
		if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
			hostap_event_expired_sta(local->dev, sta);
		sta->flags &= ~WLAN_STA_ASSOC;
	}
	spin_unlock_bh(&local->ap->sta_table_lock);
	if (sta == NULL) {
		printk("%s: disassociation from %pM, "
		       "reason_code=%d, but STA not authenticated\n",
		       dev->name, hdr->addr2, reason_code);
	}
}


/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_data_nullfunc(local_info_t *local,
				    struct ieee80211_hdr *hdr)
{
	struct net_device *dev = local->dev;

	/* some STA f/w's seem to require control::ACK frame for
	 * data::nullfunc, but at least Prism2 station f/w version 0.8.0 does
	 * not send this..
	 * send control::ACK for the data::nullfunc */

	printk(KERN_DEBUG "Sending control::ACK for data::nullfunc\n");
	prism2_send_mgmt(dev, IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK,
			 NULL, 0, hdr->addr2, 0);
}


/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_dropped_data(local_info_t *local,
				   struct ieee80211_hdr *hdr)
{
	struct net_device *dev = local->dev;
	struct sta_info *sta;
	__le16 reason;

	spin_lock_bh(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock_bh(&local->ap->sta_table_lock);

	if (sta != NULL && (sta->flags & WLAN_STA_ASSOC)) {
		PDEBUG(DEBUG_AP, "ap_handle_dropped_data: STA is now okay?\n");
		atomic_dec(&sta->users);
		return;
	}

	reason = cpu_to_le16(WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
	prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
			 ((sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) ?
			  IEEE80211_STYPE_DEAUTH : IEEE80211_STYPE_DISASSOC),
			 (char *) &reason, sizeof(reason), hdr->addr2, 0);

	if (sta)
		atomic_dec(&sta->users);
}

#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */


/* Called only as a scheduled task for pending AP frames. */
static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
				 struct sk_buff *skb)
{
	struct hostap_skb_tx_data *meta;

	if (!(sta->flags & WLAN_STA_PS)) {
		/* Station has moved to non-PS mode, so send all buffered
		 * frames using normal device queue. */
		dev_queue_xmit(skb);
		return;
	}

	/* add a flag for hostap_handle_sta_tx() to know that this skb should
	 * be passed through even though STA is using PS */
	meta = (struct hostap_skb_tx_data *) skb->cb;
	meta->flags |= HOSTAP_TX_FLAGS_BUFFERED_FRAME;
	if (!skb_queue_empty(&sta->tx_buf)) {
		/* indicate to STA that more frames follow */
		meta->flags |= HOSTAP_TX_FLAGS_ADD_MOREDATA;
	}
	dev_queue_xmit(skb);
}


/* Called only as a scheduled task for pending AP frames. */
static void handle_pspoll(local_info_t *local,
			  struct ieee80211_hdr *hdr,
			  struct hostap_80211_rx_status *rx_stats)
{
	struct net_device *dev = local->dev;
	struct sta_info *sta;
	u16 aid;
	struct sk_buff *skb;

	PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%pM, TA=%pM PWRMGT=%d\n",
	       hdr->addr1, hdr->addr2, !!ieee80211_has_pm(hdr->frame_control));

	if (!ether_addr_equal(hdr->addr1, dev->dev_addr)) {
		PDEBUG(DEBUG_AP,
		       "handle_pspoll - addr1(BSSID)=%pM not own MAC\n",
		       hdr->addr1);
		return;
	}

	aid = le16_to_cpu(hdr->duration_id);
	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) {
		PDEBUG(DEBUG_PS, "   PSPOLL and AID[15:14] not set\n");
		return;
	}
	aid &= ~(BIT(15) | BIT(14));
	if (aid == 0 || aid > MAX_AID_TABLE_SIZE) {
		PDEBUG(DEBUG_PS, "   invalid aid=%d\n", aid);
		return;
	}
	PDEBUG(DEBUG_PS2, "   aid=%d\n", aid);

	spin_lock_bh(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock_bh(&local->ap->sta_table_lock);

	if (sta == NULL) {
		PDEBUG(DEBUG_PS, "   STA not found\n");
		return;
	}
	if (sta->aid != aid) {
		PDEBUG(DEBUG_PS, "   received aid=%i does not match with "
		       "assoc.aid=%d\n", aid, sta->aid);
		return;
	}

	/* FIX: todo:
	 * - add timeout for buffering (clear aid in TIM vector if buffer timed
	 *   out (expiry time must be longer than ListenInterval for
	 *   the corresponding STA; "8802-11: 11.2.1.9 AP aging function"
	 * - what to do, if buffered, pspolled, and sent frame is not ACKed by
	 *   sta; store buffer for later use and leave TIM aid bit set? use
	 *   TX event to check whether frame was ACKed?
	 */

	while ((skb = skb_dequeue(&sta->tx_buf)) != NULL) {
		/* send buffered frame .. */
		PDEBUG(DEBUG_PS2, "Sending buffered frame to STA after PS POLL"
		       " (buffer_count=%d)\n", skb_queue_len(&sta->tx_buf));

		pspoll_send_buffered(local, sta, skb);

		if (sta->flags & WLAN_STA_PS) {
			/* send only one buffered packet per PS Poll */
			/* FIX: should ignore further PS Polls until the
			 * buffered packet that was just sent is acknowledged
			 * (Tx or TxExc event) */
			break;
		}
	}

	if (skb_queue_empty(&sta->tx_buf)) {
		/* try to clear aid from TIM */
		if (!(sta->flags & WLAN_STA_TIM))
			PDEBUG(DEBUG_PS2,  "Re-unsetting TIM for aid %d\n",
			       aid);
		hostap_set_tim(local, aid, 0);
		sta->flags &= ~WLAN_STA_TIM;
	}

	atomic_dec(&sta->users);
}


#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT

static void handle_wds_oper_queue(struct work_struct *work)
{
	struct ap_data *ap = container_of(work, struct ap_data,
					  wds_oper_queue);
	local_info_t *local = ap->local;
	struct wds_oper_data *entry, *prev;

	spin_lock_bh(&local->lock);
	entry = local->ap->wds_oper_entries;
	local->ap->wds_oper_entries = NULL;
	spin_unlock_bh(&local->lock);

	while (entry) {
		PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection "
		       "to AP %pM\n",
		       local->dev->name,
		       entry->type == WDS_ADD ? "adding" : "removing",
		       entry->addr);
		if (entry->type == WDS_ADD)
			prism2_wds_add(local, entry->addr, 0);
		else if (entry->type == WDS_DEL)
			prism2_wds_del(local, entry->addr, 0, 1);

		prev = entry;
		entry = entry->next;
		kfree(prev);
	}
}


/* Called only as a scheduled task for pending AP frames. */
static void handle_beacon(local_info_t *local, struct sk_buff *skb,
			  struct hostap_80211_rx_status *rx_stats)
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
	int len, left;
	u16 beacon_int, capability;
	__le16 *pos;
	char *ssid = NULL;
	unsigned char *supp_rates = NULL;
	int ssid_len = 0, supp_rates_len = 0;
	struct sta_info *sta = NULL;
	int new_sta = 0, channel = -1;

	len = skb->len - IEEE80211_MGMT_HDR_LEN;

	if (len < 8 + 2 + 2) {
		printk(KERN_DEBUG "handle_beacon - too short payload "
		       "(len=%d)\n", len);
		return;
	}

	pos = (__le16 *) body;
	left = len;

	/* Timestamp (8 octets) */
	pos += 4; left -= 8;
	/* Beacon interval (2 octets) */
	beacon_int = le16_to_cpu(*pos);
	pos++; left -= 2;
	/* Capability information (2 octets) */
	capability = le16_to_cpu(*pos);
	pos++; left -= 2;

	if (local->ap->ap_policy != AP_OTHER_AP_EVEN_IBSS &&
	    capability & WLAN_CAPABILITY_IBSS)
		return;

	if (left >= 2) {
		unsigned int ileft;
		unsigned char *u = (unsigned char *) pos;

		if (*u == WLAN_EID_SSID) {
			u++; left--;
			ileft = *u;
			u++; left--;

			if (ileft > left || ileft > MAX_SSID_LEN) {
				PDEBUG(DEBUG_AP, "SSID: overflow\n");
				return;
			}

			if (local->ap->ap_policy == AP_OTHER_AP_SAME_SSID &&
			    (ileft != strlen(local->essid) ||
			     memcmp(local->essid, u, ileft) != 0)) {
				/* not our SSID */
				return;
			}

			ssid = u;
			ssid_len = ileft;

			u += ileft;
			left -= ileft;
		}

		if (*u == WLAN_EID_SUPP_RATES) {
			u++; left--;
			ileft = *u;
			u++; left--;

			if (ileft > left || ileft == 0 || ileft > 8) {
				PDEBUG(DEBUG_AP, " - SUPP_RATES len error\n");
				return;
			}

			supp_rates = u;
			supp_rates_len = ileft;

			u += ileft;
			left -= ileft;
		}

		if (*u == WLAN_EID_DS_PARAMS) {
			u++; left--;
			ileft = *u;
			u++; left--;

			if (ileft > left || ileft != 1) {
				PDEBUG(DEBUG_AP, " - DS_PARAMS len error\n");
				return;
			}

			channel = *u;

			u += ileft;
			left -= ileft;
		}
	}

	spin_lock_bh(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta != NULL)
		atomic_inc(&sta->users);
	spin_unlock_bh(&local->ap->sta_table_lock);

	if (sta == NULL) {
		/* add new AP */
		new_sta = 1;
		sta = ap_add_sta(local->ap, hdr->addr2);
		if (sta == NULL) {
			printk(KERN_INFO "prism2: kmalloc failed for AP "
			       "data structure\n");
			return;
		}
		hostap_event_new_sta(local->dev, sta);

		/* mark APs authentication and associated for pseudo ad-hoc
		 * style communication */
		sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;

		if (local->ap->autom_ap_wds) {
			hostap_wds_link_oper(local, sta->addr, WDS_ADD);
		}
	}

	sta->ap = 1;
	if (ssid) {
		sta->u.ap.ssid_len = ssid_len;
		memcpy(sta->u.ap.ssid, ssid, ssid_len);
		sta->u.ap.ssid[ssid_len] = '\0';
	} else {
		sta->u.ap.ssid_len = 0;
		sta->u.ap.ssid[0] = '\0';
	}
	sta->u.ap.channel = channel;
	sta->rx_packets++;
	sta->rx_bytes += len;
	sta->u.ap.last_beacon = sta->last_rx = jiffies;
	sta->capability = capability;
	sta->listen_interval = beacon_int;

	atomic_dec(&sta->users);

	if (new_sta) {
		memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
		memcpy(sta->supported_rates, supp_rates, supp_rates_len);
		prism2_check_tx_rates(sta);
	}
}

#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */


/* Called only as a tasklet. */
static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
			   struct hostap_80211_rx_status *rx_stats)
{
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	struct net_device *dev = local->dev;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
	u16 fc, type, stype;
	struct ieee80211_hdr *hdr;

	/* FIX: should give skb->len to handler functions and check that the
	 * buffer is long enough */
	hdr = (struct ieee80211_hdr *) skb->data;
	fc = le16_to_cpu(hdr->frame_control);
	type = fc & IEEE80211_FCTL_FTYPE;
	stype = fc & IEEE80211_FCTL_STYPE;

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	if (!local->hostapd && type == IEEE80211_FTYPE_DATA) {
		PDEBUG(DEBUG_AP, "handle_ap_item - data frame\n");

		if (!(fc & IEEE80211_FCTL_TODS) ||
		    (fc & IEEE80211_FCTL_FROMDS)) {
			if (stype == IEEE80211_STYPE_NULLFUNC) {
				/* no ToDS nullfunc seems to be used to check
				 * AP association; so send reject message to
				 * speed up re-association */
				ap_handle_dropped_data(local, hdr);
				goto done;
			}
			PDEBUG(DEBUG_AP, "   not ToDS frame (fc=0x%04x)\n",
			       fc);
			goto done;
		}

		if (!ether_addr_equal(hdr->addr1, dev->dev_addr)) {
			PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)=%pM"
			       " not own MAC\n", hdr->addr1);
			goto done;
		}

		if (local->ap->nullfunc_ack &&
		    stype == IEEE80211_STYPE_NULLFUNC)
			ap_handle_data_nullfunc(local, hdr);
		else
			ap_handle_dropped_data(local, hdr);
		goto done;
	}

	if (type == IEEE80211_FTYPE_MGMT && stype == IEEE80211_STYPE_BEACON) {
		handle_beacon(local, skb, rx_stats);
		goto done;
	}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

	if (type == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL) {
		handle_pspoll(local, hdr, rx_stats);
		goto done;
	}

	if (local->hostapd) {
		PDEBUG(DEBUG_AP, "Unknown frame in AP queue: type=0x%02x "
		       "subtype=0x%02x\n", type, stype);
		goto done;
	}

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	if (type != IEEE80211_FTYPE_MGMT) {
		PDEBUG(DEBUG_AP, "handle_ap_item - not a management frame?\n");
		goto done;
	}

	if (!ether_addr_equal(hdr->addr1, dev->dev_addr)) {
		PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=%pM"
		       " not own MAC\n", hdr->addr1);
		goto done;
	}

	if (!ether_addr_equal(hdr->addr3, dev->dev_addr)) {
		PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=%pM"
		       " not own MAC\n", hdr->addr3);
		goto done;
	}

	switch (stype) {
	case IEEE80211_STYPE_ASSOC_REQ:
		handle_assoc(local, skb, rx_stats, 0);
		break;
	case IEEE80211_STYPE_ASSOC_RESP:
		PDEBUG(DEBUG_AP, "==> ASSOC RESP (ignored)\n");
		break;
	case IEEE80211_STYPE_REASSOC_REQ:
		handle_assoc(local, skb, rx_stats, 1);
		break;
	case IEEE80211_STYPE_REASSOC_RESP:
		PDEBUG(DEBUG_AP, "==> REASSOC RESP (ignored)\n");
		break;
	case IEEE80211_STYPE_ATIM:
		PDEBUG(DEBUG_AP, "==> ATIM (ignored)\n");
		break;
	case IEEE80211_STYPE_DISASSOC:
		handle_disassoc(local, skb, rx_stats);
		break;
	case IEEE80211_STYPE_AUTH:
		handle_authen(local, skb, rx_stats);
		break;
	case IEEE80211_STYPE_DEAUTH:
		handle_deauth(local, skb, rx_stats);
		break;
	default:
		PDEBUG(DEBUG_AP, "Unknown mgmt frame subtype 0x%02x\n",
		       stype >> 4);
		break;
	}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

 done:
	dev_kfree_skb(skb);
}


/* Called only as a tasklet (software IRQ) */
void hostap_rx(struct net_device *dev, struct sk_buff *skb,
	       struct hostap_80211_rx_status *rx_stats)
{
	struct hostap_interface *iface;
	local_info_t *local;
	struct ieee80211_hdr *hdr;

	iface = netdev_priv(dev);
	local = iface->local;

	if (skb->len < 16)
		goto drop;

	dev->stats.rx_packets++;

	hdr = (struct ieee80211_hdr *) skb->data;

	if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
	    ieee80211_is_beacon(hdr->frame_control))
		goto drop;

	skb->protocol = cpu_to_be16(ETH_P_HOSTAP);
	handle_ap_item(local, skb, rx_stats);
	return;

 drop:
	dev_kfree_skb(skb);
}


/* Called only as a tasklet (software IRQ) */
static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
{
	struct sk_buff *skb;
	struct ieee80211_hdr *hdr;
	struct hostap_80211_rx_status rx_stats;

	if (skb_queue_empty(&sta->tx_buf))
		return;

	skb = dev_alloc_skb(16);
	if (skb == NULL) {
		printk(KERN_DEBUG "%s: schedule_packet_send: skb alloc "
		       "failed\n", local->dev->name);
		return;
	}

	hdr = skb_put(skb, 16);

	/* Generate a fake pspoll frame to start packet delivery */
	hdr->frame_control = cpu_to_le16(
		IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
	memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN);
	memcpy(hdr->addr2, sta->addr, ETH_ALEN);
	hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14));

	PDEBUG(DEBUG_PS2,
	       "%s: Scheduling buffered packet delivery for STA %pM\n",
	       local->dev->name, sta->addr);

	skb->dev = local->dev;

	memset(&rx_stats, 0, sizeof(rx_stats));
	hostap_rx(local->dev, skb, &rx_stats);
}


int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
			   struct iw_quality qual[], int buf_size,
			   int aplist)
{
	struct ap_data *ap = local->ap;
	struct list_head *ptr;
	int count = 0;

	spin_lock_bh(&ap->sta_table_lock);

	for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
	     ptr = ptr->next) {
		struct sta_info *sta = (struct sta_info *) ptr;

		if (aplist && !sta->ap)
			continue;
		addr[count].sa_family = ARPHRD_ETHER;
		memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
		if (sta->last_rx_silence == 0)
			qual[count].qual = sta->last_rx_signal < 27 ?
				0 : (sta->last_rx_signal - 27) * 92 / 127;
		else
			qual[count].qual = sta->last_rx_signal -
				sta->last_rx_silence - 35;
		qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
		qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
		qual[count].updated = sta->last_rx_updated;

		sta->last_rx_updated = IW_QUAL_DBM;

		count++;
		if (count >= buf_size)
			break;
	}
	spin_unlock_bh(&ap->sta_table_lock);

	return count;
}


/* Translate our list of Access Points & Stations to a card independent
 * format that the Wireless Tools will understand - Jean II */
int prism2_ap_translate_scan(struct net_device *dev,
			     struct iw_request_info *info, char *buffer)
{
	struct hostap_interface *iface;
	local_info_t *local;
	struct ap_data *ap;
	struct list_head *ptr;
	struct iw_event iwe;
	char *current_ev = buffer;
	char *end_buf = buffer + IW_SCAN_MAX_DATA;
#if !defined(PRISM2_NO_KERNEL_IEEE80211_MGMT)
	char buf[64];
#endif

	iface = netdev_priv(dev);
	local = iface->local;
	ap = local->ap;

	spin_lock_bh(&ap->sta_table_lock);

	for (ptr = ap->sta_list.next; ptr != NULL && ptr != &ap->sta_list;
	     ptr = ptr->next) {
		struct sta_info *sta = (struct sta_info *) ptr;

		/* First entry *MUST* be the AP MAC address */
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = SIOCGIWAP;
		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
		memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
		iwe.len = IW_EV_ADDR_LEN;
		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
						  &iwe, IW_EV_ADDR_LEN);

		/* Use the mode to indicate if it's a station or
		 * an Access Point */
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = SIOCGIWMODE;
		if (sta->ap)
			iwe.u.mode = IW_MODE_MASTER;
		else
			iwe.u.mode = IW_MODE_INFRA;
		iwe.len = IW_EV_UINT_LEN;
		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
						  &iwe, IW_EV_UINT_LEN);

		/* Some quality */
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVQUAL;
		if (sta->last_rx_silence == 0)
			iwe.u.qual.qual = sta->last_rx_signal < 27 ?
				0 : (sta->last_rx_signal - 27) * 92 / 127;
		else
			iwe.u.qual.qual = sta->last_rx_signal -
				sta->last_rx_silence - 35;
		iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
		iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
		iwe.u.qual.updated = sta->last_rx_updated;
		iwe.len = IW_EV_QUAL_LEN;
		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
						  &iwe, IW_EV_QUAL_LEN);

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
		if (sta->ap) {
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = SIOCGIWESSID;
			iwe.u.data.length = sta->u.ap.ssid_len;
			iwe.u.data.flags = 1;
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf, &iwe,
							  sta->u.ap.ssid);

			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = SIOCGIWENCODE;
			if (sta->capability & WLAN_CAPABILITY_PRIVACY)
				iwe.u.data.flags =
					IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
			else
				iwe.u.data.flags = IW_ENCODE_DISABLED;
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf, &iwe,
							  sta->u.ap.ssid);

			if (sta->u.ap.channel > 0 &&
			    sta->u.ap.channel <= FREQ_COUNT) {
				memset(&iwe, 0, sizeof(iwe));
				iwe.cmd = SIOCGIWFREQ;
				iwe.u.freq.m = freq_list[sta->u.ap.channel - 1]
					* 100000;
				iwe.u.freq.e = 1;
				current_ev = iwe_stream_add_event(
					info, current_ev, end_buf, &iwe,
					IW_EV_FREQ_LEN);
			}

			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = IWEVCUSTOM;
			sprintf(buf, "beacon_interval=%d",
				sta->listen_interval);
			iwe.u.data.length = strlen(buf);
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf, &iwe, buf);
		}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

		sta->last_rx_updated = IW_QUAL_DBM;

		/* To be continued, we should make good use of IWEVCUSTOM */
	}

	spin_unlock_bh(&ap->sta_table_lock);

	return current_ev - buffer;
}


static int prism2_hostapd_add_sta(struct ap_data *ap,
				  struct prism2_hostapd_param *param)
{
	struct sta_info *sta;

	spin_lock_bh(&ap->sta_table_lock);
	sta = ap_get_sta(ap, param->sta_addr);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock_bh(&ap->sta_table_lock);

	if (sta == NULL) {
		sta = ap_add_sta(ap, param->sta_addr);
		if (sta == NULL)
			return -1;
	}

	if (!(sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
		hostap_event_new_sta(sta->local->dev, sta);

	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
	sta->last_rx = jiffies;
	sta->aid = param->u.add_sta.aid;
	sta->capability = param->u.add_sta.capability;
	sta->tx_supp_rates = param->u.add_sta.tx_supp_rates;
	if (sta->tx_supp_rates & WLAN_RATE_1M)
		sta->supported_rates[0] = 2;
	if (sta->tx_supp_rates & WLAN_RATE_2M)
		sta->supported_rates[1] = 4;
	if (sta->tx_supp_rates & WLAN_RATE_5M5)
		sta->supported_rates[2] = 11;
	if (sta->tx_supp_rates & WLAN_RATE_11M)
		sta->supported_rates[3] = 22;
	prism2_check_tx_rates(sta);
	atomic_dec(&sta->users);
	return 0;
}


static int prism2_hostapd_remove_sta(struct ap_data *ap,
				     struct prism2_hostapd_param *param)
{
	struct sta_info *sta;

	spin_lock_bh(&ap->sta_table_lock);
	sta = ap_get_sta(ap, param->sta_addr);
	if (sta) {
		ap_sta_hash_del(ap, sta);
		list_del(&sta->list);
	}
	spin_unlock_bh(&ap->sta_table_lock);

	if (!sta)
		return -ENOENT;

	if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap && sta->local)
		hostap_event_expired_sta(sta->local->dev, sta);
	ap_free_sta(ap, sta);

	return 0;
}


static int prism2_hostapd_get_info_sta(struct ap_data *ap,
				       struct prism2_hostapd_param *param)
{
	struct sta_info *sta;

	spin_lock_bh(&ap->sta_table_lock);
	sta = ap_get_sta(ap, param->sta_addr);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock_bh(&ap->sta_table_lock);

	if (!sta)
		return -ENOENT;

	param->u.get_info_sta.inactive_sec = (jiffies - sta->last_rx) / HZ;

	atomic_dec(&sta->users);

	return 1;
}


static int prism2_hostapd_set_flags_sta(struct ap_data *ap,
					struct prism2_hostapd_param *param)
{
	struct sta_info *sta;

	spin_lock_bh(&ap->sta_table_lock);
	sta = ap_get_sta(ap, param->sta_addr);
	if (sta) {
		sta->flags |= param->u.set_flags_sta.flags_or;
		sta->flags &= param->u.set_flags_sta.flags_and;
	}
	spin_unlock_bh(&ap->sta_table_lock);

	if (!sta)
		return -ENOENT;

	return 0;
}


static int prism2_hostapd_sta_clear_stats(struct ap_data *ap,
					  struct prism2_hostapd_param *param)
{
	struct sta_info *sta;
	int rate;

	spin_lock_bh(&ap->sta_table_lock);
	sta = ap_get_sta(ap, param->sta_addr);
	if (sta) {
		sta->rx_packets = sta->tx_packets = 0;
		sta->rx_bytes = sta->tx_bytes = 0;
		for (rate = 0; rate < WLAN_RATE_COUNT; rate++) {
			sta->tx_count[rate] = 0;
			sta->rx_count[rate] = 0;
		}
	}
	spin_unlock_bh(&ap->sta_table_lock);

	if (!sta)
		return -ENOENT;

	return 0;
}


int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param)
{
	switch (param->cmd) {
	case PRISM2_HOSTAPD_FLUSH:
		ap_control_kickall(ap);
		return 0;
	case PRISM2_HOSTAPD_ADD_STA:
		return prism2_hostapd_add_sta(ap, param);
	case PRISM2_HOSTAPD_REMOVE_STA:
		return prism2_hostapd_remove_sta(ap, param);
	case PRISM2_HOSTAPD_GET_INFO_STA:
		return prism2_hostapd_get_info_sta(ap, param);
	case PRISM2_HOSTAPD_SET_FLAGS_STA:
		return prism2_hostapd_set_flags_sta(ap, param);
	case PRISM2_HOSTAPD_STA_CLEAR_STATS:
		return prism2_hostapd_sta_clear_stats(ap, param);
	default:
		printk(KERN_WARNING "prism2_hostapd: unknown cmd=%d\n",
		       param->cmd);
		return -EOPNOTSUPP;
	}
}


/* Update station info for host-based TX rate control and return current
 * TX rate */
static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev)
{
	int ret = sta->tx_rate;
	struct hostap_interface *iface;
	local_info_t *local;

	iface = netdev_priv(dev);
	local = iface->local;

	sta->tx_count[sta->tx_rate_idx]++;
	sta->tx_since_last_failure++;
	sta->tx_consecutive_exc = 0;
	if (sta->tx_since_last_failure >= WLAN_RATE_UPDATE_COUNT &&
	    sta->tx_rate_idx < sta->tx_max_rate) {
		/* use next higher rate */
		int old_rate, new_rate;
		old_rate = new_rate = sta->tx_rate_idx;
		while (new_rate < sta->tx_max_rate) {
			new_rate++;
			if (ap_tx_rate_ok(new_rate, sta, local)) {
				sta->tx_rate_idx = new_rate;
				break;
			}
		}
		if (old_rate != sta->tx_rate_idx) {
			switch (sta->tx_rate_idx) {
			case 0: sta->tx_rate = 10; break;
			case 1: sta->tx_rate = 20; break;
			case 2: sta->tx_rate = 55; break;
			case 3: sta->tx_rate = 110; break;
			default: sta->tx_rate = 0; break;
			}
			PDEBUG(DEBUG_AP, "%s: STA %pM TX rate raised to %d\n",
			       dev->name, sta->addr, sta->tx_rate);
		}
		sta->tx_since_last_failure = 0;
	}

	return ret;
}


/* Called only from software IRQ. Called for each TX frame prior possible
 * encryption and transmit. */
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
{
	struct sta_info *sta = NULL;
	struct sk_buff *skb = tx->skb;
	int set_tim, ret;
	struct ieee80211_hdr *hdr;
	struct hostap_skb_tx_data *meta;

	meta = (struct hostap_skb_tx_data *) skb->cb;
	ret = AP_TX_CONTINUE;
	if (local->ap == NULL || skb->len < 10 ||
	    meta->iface->type == HOSTAP_INTERFACE_STA)
		goto out;

	hdr = (struct ieee80211_hdr *) skb->data;

	if (hdr->addr1[0] & 0x01) {
		/* broadcast/multicast frame - no AP related processing */
		if (local->ap->num_sta <= 0)
			ret = AP_TX_DROP;
		goto out;
	}

	/* unicast packet - check whether destination STA is associated */
	spin_lock(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr1);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock(&local->ap->sta_table_lock);

	if (local->iw_mode == IW_MODE_MASTER && sta == NULL &&
	    !(meta->flags & HOSTAP_TX_FLAGS_WDS) &&
	    meta->iface->type != HOSTAP_INTERFACE_MASTER &&
	    meta->iface->type != HOSTAP_INTERFACE_AP) {
#if 0
		/* This can happen, e.g., when wlan0 is added to a bridge and
		 * bridging code does not know which port is the correct target
		 * for a unicast frame. In this case, the packet is send to all
		 * ports of the bridge. Since this is a valid scenario, do not
		 * print out any errors here. */
		if (net_ratelimit()) {
			printk(KERN_DEBUG "AP: drop packet to non-associated "
			       "STA %pM\n", hdr->addr1);
		}
#endif
		local->ap->tx_drop_nonassoc++;
		ret = AP_TX_DROP;
		goto out;
	}

	if (sta == NULL)
		goto out;

	if (!(sta->flags & WLAN_STA_AUTHORIZED))
		ret = AP_TX_CONTINUE_NOT_AUTHORIZED;

	/* Set tx_rate if using host-based TX rate control */
	if (!local->fw_tx_rate_control)
		local->ap->last_tx_rate = meta->rate =
			ap_update_sta_tx_rate(sta, local->dev);

	if (local->iw_mode != IW_MODE_MASTER)
		goto out;

	if (!(sta->flags & WLAN_STA_PS))
		goto out;

	if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) {
		/* indicate to STA that more frames follow */
		hdr->frame_control |=
			cpu_to_le16(IEEE80211_FCTL_MOREDATA);
	}

	if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) {
		/* packet was already buffered and now send due to
		 * PS poll, so do not rebuffer it */
		goto out;
	}

	if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) {
		PDEBUG(DEBUG_PS, "%s: No more space in STA (%pM)'s"
		       "PS mode buffer\n",
		       local->dev->name, sta->addr);
		/* Make sure that TIM is set for the station (it might not be
		 * after AP wlan hw reset). */
		/* FIX: should fix hw reset to restore bits based on STA
		 * buffer state.. */
		hostap_set_tim(local, sta->aid, 1);
		sta->flags |= WLAN_STA_TIM;
		ret = AP_TX_DROP;
		goto out;
	}

	/* STA in PS mode, buffer frame for later delivery */
	set_tim = skb_queue_empty(&sta->tx_buf);
	skb_queue_tail(&sta->tx_buf, skb);
	/* FIX: could save RX time to skb and expire buffered frames after
	 * some time if STA does not poll for them */

	if (set_tim) {
		if (sta->flags & WLAN_STA_TIM)
			PDEBUG(DEBUG_PS2, "Re-setting TIM for aid %d\n",
			       sta->aid);
		hostap_set_tim(local, sta->aid, 1);
		sta->flags |= WLAN_STA_TIM;
	}

	ret = AP_TX_BUFFERED;

 out:
	if (sta != NULL) {
		if (ret == AP_TX_CONTINUE ||
		    ret == AP_TX_CONTINUE_NOT_AUTHORIZED) {
			sta->tx_packets++;
			sta->tx_bytes += skb->len;
			sta->last_tx = jiffies;
		}

		if ((ret == AP_TX_CONTINUE ||
		     ret == AP_TX_CONTINUE_NOT_AUTHORIZED) &&
		    sta->crypt && tx->host_encrypt) {
			tx->crypt = sta->crypt;
			tx->sta_ptr = sta; /* hostap_handle_sta_release() will
					    * be called to release sta info
					    * later */
		} else
			atomic_dec(&sta->users);
	}

	return ret;
}


void hostap_handle_sta_release(void *ptr)
{
	struct sta_info *sta = ptr;
	atomic_dec(&sta->users);
}


/* Called only as a tasklet (software IRQ) */
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
{
	struct sta_info *sta;
	struct ieee80211_hdr *hdr;
	struct hostap_skb_tx_data *meta;

	hdr = (struct ieee80211_hdr *) skb->data;
	meta = (struct hostap_skb_tx_data *) skb->cb;

	spin_lock(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr1);
	if (!sta) {
		spin_unlock(&local->ap->sta_table_lock);
		PDEBUG(DEBUG_AP, "%s: Could not find STA %pM"
		       " for this TX error (@%lu)\n",
		       local->dev->name, hdr->addr1, jiffies);
		return;
	}

	sta->tx_since_last_failure = 0;
	sta->tx_consecutive_exc++;

	if (sta->tx_consecutive_exc >= WLAN_RATE_DECREASE_THRESHOLD &&
	    sta->tx_rate_idx > 0 && meta->rate <= sta->tx_rate) {
		/* use next lower rate */
		int old, rate;
		old = rate = sta->tx_rate_idx;
		while (rate > 0) {
			rate--;
			if (ap_tx_rate_ok(rate, sta, local)) {
				sta->tx_rate_idx = rate;
				break;
			}
		}
		if (old != sta->tx_rate_idx) {
			switch (sta->tx_rate_idx) {
			case 0: sta->tx_rate = 10; break;
			case 1: sta->tx_rate = 20; break;
			case 2: sta->tx_rate = 55; break;
			case 3: sta->tx_rate = 110; break;
			default: sta->tx_rate = 0; break;
			}
			PDEBUG(DEBUG_AP,
			       "%s: STA %pM TX rate lowered to %d\n",
			       local->dev->name, sta->addr, sta->tx_rate);
		}
		sta->tx_consecutive_exc = 0;
	}
	spin_unlock(&local->ap->sta_table_lock);
}


static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
				  int pwrmgt, int type, int stype)
{
	if (pwrmgt && !(sta->flags & WLAN_STA_PS)) {
		sta->flags |= WLAN_STA_PS;
		PDEBUG(DEBUG_PS2, "STA %pM changed to use PS "
		       "mode (type=0x%02X, stype=0x%02X)\n",
		       sta->addr, type >> 2, stype >> 4);
	} else if (!pwrmgt && (sta->flags & WLAN_STA_PS)) {
		sta->flags &= ~WLAN_STA_PS;
		PDEBUG(DEBUG_PS2, "STA %pM changed to not use "
		       "PS mode (type=0x%02X, stype=0x%02X)\n",
		       sta->addr, type >> 2, stype >> 4);
		if (type != IEEE80211_FTYPE_CTL ||
		    stype != IEEE80211_STYPE_PSPOLL)
			schedule_packet_send(local, sta);
	}
}


/* Called only as a tasklet (software IRQ). Called for each RX frame to update
 * STA power saving state. pwrmgt is a flag from 802.11 frame_control field. */
int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
{
	struct sta_info *sta;
	u16 fc;

	spin_lock(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock(&local->ap->sta_table_lock);

	if (!sta)
		return -1;

	fc = le16_to_cpu(hdr->frame_control);
	hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
			      fc & IEEE80211_FCTL_FTYPE,
			      fc & IEEE80211_FCTL_STYPE);

	atomic_dec(&sta->users);
	return 0;
}


/* Called only as a tasklet (software IRQ). Called for each RX frame after
 * getting RX header and payload from hardware. */
ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
			       struct sk_buff *skb,
			       struct hostap_80211_rx_status *rx_stats,
			       int wds)
{
	int ret;
	struct sta_info *sta;
	u16 fc, type, stype;
	struct ieee80211_hdr *hdr;

	if (local->ap == NULL)
		return AP_RX_CONTINUE;

	hdr = (struct ieee80211_hdr *) skb->data;

	fc = le16_to_cpu(hdr->frame_control);
	type = fc & IEEE80211_FCTL_FTYPE;
	stype = fc & IEEE80211_FCTL_STYPE;

	spin_lock(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock(&local->ap->sta_table_lock);

	if (sta && !(sta->flags & WLAN_STA_AUTHORIZED))
		ret = AP_RX_CONTINUE_NOT_AUTHORIZED;
	else
		ret = AP_RX_CONTINUE;


	if (fc & IEEE80211_FCTL_TODS) {
		if (!wds && (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
			if (local->hostapd) {
				prism2_rx_80211(local->apdev, skb, rx_stats,
						PRISM2_RX_NON_ASSOC);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
			} else {
				printk(KERN_DEBUG "%s: dropped received packet"
				       " from non-associated STA %pM"
				       " (type=0x%02x, subtype=0x%02x)\n",
				       dev->name, hdr->addr2,
				       type >> 2, stype >> 4);
				hostap_rx(dev, skb, rx_stats);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
			}
			ret = AP_RX_EXIT;
			goto out;
		}
	} else if (fc & IEEE80211_FCTL_FROMDS) {
		if (!wds) {
			/* FromDS frame - not for us; probably
			 * broadcast/multicast in another BSS - drop */
			if (ether_addr_equal(hdr->addr1, dev->dev_addr)) {
				printk(KERN_DEBUG "Odd.. FromDS packet "
				       "received with own BSSID\n");
				hostap_dump_rx_80211(dev->name, skb, rx_stats);
			}
			ret = AP_RX_DROP;
			goto out;
		}
	} else if (stype == IEEE80211_STYPE_NULLFUNC && sta == NULL &&
		   ether_addr_equal(hdr->addr1, dev->dev_addr)) {

		if (local->hostapd) {
			prism2_rx_80211(local->apdev, skb, rx_stats,
					PRISM2_RX_NON_ASSOC);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
		} else {
			/* At least Lucent f/w seems to send data::nullfunc
			 * frames with no ToDS flag when the current AP returns
			 * after being unavailable for some time. Speed up
			 * re-association by informing the station about it not
			 * being associated. */
			printk(KERN_DEBUG "%s: rejected received nullfunc frame"
			       " without ToDS from not associated STA %pM\n",
			       dev->name, hdr->addr2);
			hostap_rx(dev, skb, rx_stats);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
		}
		ret = AP_RX_EXIT;
		goto out;
	} else if (stype == IEEE80211_STYPE_NULLFUNC) {
		/* At least Lucent cards seem to send periodic nullfunc
		 * frames with ToDS. Let these through to update SQ
		 * stats and PS state. Nullfunc frames do not contain
		 * any data and they will be dropped below. */
	} else {
		/* If BSSID (Addr3) is foreign, this frame is a normal
		 * broadcast frame from an IBSS network. Drop it silently.
		 * If BSSID is own, report the dropping of this frame. */
		if (ether_addr_equal(hdr->addr3, dev->dev_addr)) {
			printk(KERN_DEBUG "%s: dropped received packet from %pM"
			       " with no ToDS flag "
			       "(type=0x%02x, subtype=0x%02x)\n", dev->name,
			       hdr->addr2, type >> 2, stype >> 4);
			hostap_dump_rx_80211(dev->name, skb, rx_stats);
		}
		ret = AP_RX_DROP;
		goto out;
	}

	if (sta) {
		hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
				      type, stype);

		sta->rx_packets++;
		sta->rx_bytes += skb->len;
		sta->last_rx = jiffies;
	}

	if (local->ap->nullfunc_ack && stype == IEEE80211_STYPE_NULLFUNC &&
	    fc & IEEE80211_FCTL_TODS) {
		if (local->hostapd) {
			prism2_rx_80211(local->apdev, skb, rx_stats,
					PRISM2_RX_NULLFUNC_ACK);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
		} else {
			/* some STA f/w's seem to require control::ACK frame
			 * for data::nullfunc, but Prism2 f/w 0.8.0 (at least
			 * from Compaq) does not send this.. Try to generate
			 * ACK for these frames from the host driver to make
			 * power saving work with, e.g., Lucent WaveLAN f/w */
			hostap_rx(dev, skb, rx_stats);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
		}
		ret = AP_RX_EXIT;
		goto out;
	}

 out:
	if (sta)
		atomic_dec(&sta->users);

	return ret;
}


/* Called only as a tasklet (software IRQ) */
int hostap_handle_sta_crypto(local_info_t *local,
			     struct ieee80211_hdr *hdr,
			     struct lib80211_crypt_data **crypt,
			     void **sta_ptr)
{
	struct sta_info *sta;

	spin_lock(&local->ap->sta_table_lock);
	sta = ap_get_sta(local->ap, hdr->addr2);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock(&local->ap->sta_table_lock);

	if (!sta)
		return -1;

	if (sta->crypt) {
		*crypt = sta->crypt;
		*sta_ptr = sta;
		/* hostap_handle_sta_release() will be called to release STA
		 * info */
	} else
		atomic_dec(&sta->users);

	return 0;
}


/* Called only as a tasklet (software IRQ) */
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr)
{
	struct sta_info *sta;
	int ret = 0;

	spin_lock(&ap->sta_table_lock);
	sta = ap_get_sta(ap, sta_addr);
	if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap)
		ret = 1;
	spin_unlock(&ap->sta_table_lock);

	return ret;
}


/* Called only as a tasklet (software IRQ) */
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr)
{
	struct sta_info *sta;
	int ret = 0;

	spin_lock(&ap->sta_table_lock);
	sta = ap_get_sta(ap, sta_addr);
	if (sta != NULL && (sta->flags & WLAN_STA_ASSOC) && !sta->ap &&
	    ((sta->flags & WLAN_STA_AUTHORIZED) ||
	     ap->local->ieee_802_1x == 0))
		ret = 1;
	spin_unlock(&ap->sta_table_lock);

	return ret;
}


/* Called only as a tasklet (software IRQ) */
int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
{
	struct sta_info *sta;
	int ret = 1;

	if (!ap)
		return -1;

	spin_lock(&ap->sta_table_lock);
	sta = ap_get_sta(ap, sta_addr);
	if (sta)
		ret = 0;
	spin_unlock(&ap->sta_table_lock);

	if (ret == 1) {
		sta = ap_add_sta(ap, sta_addr);
		if (!sta)
			return -1;
		sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
		sta->ap = 1;
		memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
		/* No way of knowing which rates are supported since we did not
		 * get supported rates element from beacon/assoc req. Assume
		 * that remote end supports all 802.11b rates. */
		sta->supported_rates[0] = 0x82;
		sta->supported_rates[1] = 0x84;
		sta->supported_rates[2] = 0x0b;
		sta->supported_rates[3] = 0x16;
		sta->tx_supp_rates = WLAN_RATE_1M | WLAN_RATE_2M |
			WLAN_RATE_5M5 | WLAN_RATE_11M;
		sta->tx_rate = 110;
		sta->tx_max_rate = sta->tx_rate_idx = 3;
	}

	return ret;
}


/* Called only as a tasklet (software IRQ) */
int hostap_update_rx_stats(struct ap_data *ap,
			   struct ieee80211_hdr *hdr,
			   struct hostap_80211_rx_status *rx_stats)
{
	struct sta_info *sta;

	if (!ap)
		return -1;

	spin_lock(&ap->sta_table_lock);
	sta = ap_get_sta(ap, hdr->addr2);
	if (sta) {
		sta->last_rx_silence = rx_stats->noise;
		sta->last_rx_signal = rx_stats->signal;
		sta->last_rx_rate = rx_stats->rate;
		sta->last_rx_updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
		if (rx_stats->rate == 10)
			sta->rx_count[0]++;
		else if (rx_stats->rate == 20)
			sta->rx_count[1]++;
		else if (rx_stats->rate == 55)
			sta->rx_count[2]++;
		else if (rx_stats->rate == 110)
			sta->rx_count[3]++;
	}
	spin_unlock(&ap->sta_table_lock);

	return sta ? 0 : -1;
}


void hostap_update_rates(local_info_t *local)
{
	struct sta_info *sta;
	struct ap_data *ap = local->ap;

	if (!ap)
		return;

	spin_lock_bh(&ap->sta_table_lock);
	list_for_each_entry(sta, &ap->sta_list, list) {
		prism2_check_tx_rates(sta);
	}
	spin_unlock_bh(&ap->sta_table_lock);
}


void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
			 struct lib80211_crypt_data ***crypt)
{
	struct sta_info *sta;

	spin_lock_bh(&ap->sta_table_lock);
	sta = ap_get_sta(ap, addr);
	if (sta)
		atomic_inc(&sta->users);
	spin_unlock_bh(&ap->sta_table_lock);

	if (!sta && permanent)
		sta = ap_add_sta(ap, addr);

	if (!sta)
		return NULL;

	if (permanent)
		sta->flags |= WLAN_STA_PERM;

	*crypt = &sta->crypt;

	return sta;
}


void hostap_add_wds_links(local_info_t *local)
{
	struct ap_data *ap = local->ap;
	struct sta_info *sta;

	spin_lock_bh(&ap->sta_table_lock);
	list_for_each_entry(sta, &ap->sta_list, list) {
		if (sta->ap)
			hostap_wds_link_oper(local, sta->addr, WDS_ADD);
	}
	spin_unlock_bh(&ap->sta_table_lock);

	schedule_work(&local->ap->wds_oper_queue);
}


void hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type)
{
	struct wds_oper_data *entry;

	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
	if (!entry)
		return;
	memcpy(entry->addr, addr, ETH_ALEN);
	entry->type = type;
	spin_lock_bh(&local->lock);
	entry->next = local->ap->wds_oper_entries;
	local->ap->wds_oper_entries = entry;
	spin_unlock_bh(&local->lock);

	schedule_work(&local->ap->wds_oper_queue);
}


EXPORT_SYMBOL(hostap_init_data);
EXPORT_SYMBOL(hostap_init_ap_proc);
EXPORT_SYMBOL(hostap_free_data);
EXPORT_SYMBOL(hostap_check_sta_fw_version);
EXPORT_SYMBOL(hostap_handle_sta_tx_exc);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
