/*
 * 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/delay.h>
#include <linux/random.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 */


#ifndef PRISM2_NO_PROCFS_DEBUG
static int ap_debug_proc_read(char *page, char **start, off_t off,
			      int count, int *eof, void *data)
{
	char *p = page;
	struct ap_data *ap = (struct ap_data *) data;

	if (off != 0) {
		*eof = 1;
		return 0;
	}

	p += sprintf(p, "BridgedUnicastFrames=%u\n", ap->bridged_unicast);
	p += sprintf(p, "BridgedMulticastFrames=%u\n", ap->bridged_multicast);
	p += sprintf(p, "max_inactivity=%u\n", ap->max_inactivity / HZ);
	p += sprintf(p, "bridge_packets=%u\n", ap->bridge_packets);
	p += sprintf(p, "nullfunc_ack=%u\n", ap->nullfunc_ack);
	p += sprintf(p, "autom_ap_wds=%u\n", ap->autom_ap_wds);
	p += sprintf(p, "auth_algs=%u\n", ap->local->auth_algs);
	p += sprintf(p, "tx_drop_nonassoc=%u\n", ap->tx_drop_nonassoc);

	return (p - page);
}
#endif /* PRISM2_NO_PROCFS_DEBUG */


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 (memcmp(s->addr, sta->addr, ETH_ALEN) == 0) {
		ap->sta_hash[STA_HASH(sta->addr)] = s->hnext;
		return;
	}

	while (s->hnext != NULL && memcmp(s->hnext->addr, sta->addr, ETH_ALEN)
	       != 0)
		s = s->hnext;
	if (s->hnext != NULL)
		s->hnext = s->hnext->hnext;
	else
		printk("AP: could not remove STA " MACSTR " from hash table\n",
		       MAC2STR(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, MACSTR, MAC2STR(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 && sta->u.sta.challenge)
		kfree(sta->u.sta.challenge);
	del_timer(&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(unsigned long data)
{
	struct sta_info *sta = (struct sta_info *) data;
	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 " MACSTR "\n",
			       local->dev->name, MAC2STR(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;
		u16 resp;
		PDEBUG(DEBUG_AP, "%s: sending %s info to STA " MACSTR
		       "(last=%lu, jiffies=%lu)\n",
		       local->dev->name,
		       deauth ? "deauthentication" : "disassociation",
		       MAC2STR(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 " MACSTR " would have been "
			       "removed, but it has 'perm' flag\n",
			       local->dev->name, MAC2STR(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];
	u16 resp;
	int i;

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

	resp = __constant_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_read(char *page, char **start, off_t off,
				int count, int *eof, void *data)
{
	char *p = page;
	struct ap_data *ap = (struct ap_data *) data;
	char *policy_txt;
	struct mac_entry *entry;

	if (off != 0) {
		*eof = 1;
		return 0;
	}

	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;
	};
	p += sprintf(p, "MAC policy: %s\n", policy_txt);
	p += sprintf(p, "MAC entries: %u\n", ap->mac_restrictions.entries);
	p += sprintf(p, "MAC list:\n");
	spin_lock_bh(&ap->mac_restrictions.lock);
	list_for_each_entry(entry, &ap->mac_restrictions.mac_list, list) {
		if (p - page > PAGE_SIZE - 80) {
			p += sprintf(p, "All entries did not fit one page.\n");
			break;
		}

		p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr));
	}
	spin_unlock_bh(&ap->mac_restrictions.lock);

	return (p - page);
}


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 -1;

	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 (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
			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 (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
			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;
	u16 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

#define PROC_LIMIT (PAGE_SIZE - 80)

static int prism2_ap_proc_read(char *page, char **start, off_t off,
			       int count, int *eof, void *data)
{
	char *p = page;
	struct ap_data *ap = (struct ap_data *) data;
	struct sta_info *sta;
	int i;

	if (off > PROC_LIMIT) {
		*eof = 1;
		return 0;
	}

	p += sprintf(p, "# BSSID CHAN SIGNAL NOISE RATE SSID FLAGS\n");
	spin_lock_bh(&ap->sta_table_lock);
	list_for_each_entry(sta, &ap->sta_list, list) {
		if (!sta->ap)
			continue;

		p += sprintf(p, MACSTR " %d %d %d %d '", MAC2STR(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++)
			p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
					  sta->u.ap.ssid[i] < 127) ?
					 "%c" : "<%02x>"),
				     sta->u.ap.ssid[i]);
		p += sprintf(p, "'");
		if (sta->capability & WLAN_CAPABILITY_ESS)
			p += sprintf(p, " [ESS]");
		if (sta->capability & WLAN_CAPABILITY_IBSS)
			p += sprintf(p, " [IBSS]");
		if (sta->capability & WLAN_CAPABILITY_PRIVACY)
			p += sprintf(p, " [WEP]");
		p += sprintf(p, "\n");

		if ((p - page) > PROC_LIMIT) {
			printk(KERN_DEBUG "hostap: ap proc did not fit\n");
			break;
		}
	}
	spin_unlock_bh(&ap->sta_table_lock);

	if ((p - page) <= off) {
		*eof = 1;
		return 0;
	}

	*start = page + off;

	return (p - page - off);
}
#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;
	u16 fc;
	struct ieee80211_hdr_4addr *hdr;

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

	hdr = (struct ieee80211_hdr_4addr *) skb->data;
	fc = le16_to_cpu(hdr->frame_ctl);

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

	fc &= ~IEEE80211_FCTL_VERS;
	fc |= ok ? BIT(1) : BIT(0);
	hdr->frame_ctl = cpu_to_le16(fc);

	skb->dev = ap->local->apdev;
	skb_pull(skb, hostap_80211_get_hdrlen(fc));
	skb->pkt_type = PACKET_OTHERHOST;
	skb->protocol = __constant_htons(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_4addr *hdr;
	u16 fc, *pos, auth_alg, auth_transaction, status;
	struct sta_info *sta = NULL;
	char *txt = NULL;

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

	hdr = (struct ieee80211_hdr_4addr *) skb->data;
	fc = le16_to_cpu(hdr->frame_ctl);
	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
	    WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
	    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 = (u16 *) (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: " MACSTR " auth_cb - alg=%d trans#=%d "
		       "status=%d - %s\n",
		       dev->name, MAC2STR(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_4addr *hdr;
	u16 fc, *pos, status;
	struct sta_info *sta = NULL;
	char *txt = NULL;

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

	hdr = (struct ieee80211_hdr_4addr *) skb->data;
	fc = le16_to_cpu(hdr->frame_ctl);
	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
	    (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
	     WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_REASSOC_RESP) ||
	    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 = (u16 *) (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: " MACSTR " assoc_cb - %s\n",
		       dev->name, MAC2STR(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_4addr *hdr;
	struct sta_info *sta;

	if (skb->len < 24)
		goto fail;
	hdr = (struct ieee80211_hdr_4addr *) 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 " MACSTR " did not ACK activity "
		       "poll frame\n", ap->local->dev->name,
		       MAC2STR(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
	create_proc_read_entry("ap_debug", 0, ap->proc,
			       ap_debug_proc_read, ap);
#endif /* PRISM2_NO_PROCFS_DEBUG */

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	create_proc_read_entry("ap_control", 0, ap->proc,
			       ap_control_proc_read, ap);
	create_proc_read_entry("ap", 0, ap->proc,
			       prism2_ap_proc_read, 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;
	}

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	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 && memcmp(s->addr, sta, ETH_ALEN) != 0)
		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_4addr *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(fc);
	hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
	if (body)
		memcpy(skb_put(skb, body_len), body, body_len);

	memset(hdr, 0, hdrlen);

	/* 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 (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) {
		fc |= IEEE80211_FCTL_FROMDS;
		memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
		memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */
	} else if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL) {
		/* control:ACK does not have addr2 or addr3 */
		memset(hdr->addr2, 0, ETH_ALEN);
		memset(hdr->addr3, 0, ETH_ALEN);
	} else {
		memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* SA */
		memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
	}

	hdr->frame_ctl = 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 */


static int prism2_sta_proc_read(char *page, char **start, off_t off,
				int count, int *eof, void *data)
{
	char *p = page;
	struct sta_info *sta = (struct sta_info *) data;
	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.. */

	if (off != 0) {
		*eof = 1;
		return 0;
	}

	p += sprintf(p, "%s=" MACSTR "\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",
		     MAC2STR(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)
			p += sprintf(p, "%d%sMbps ",
				     (sta->supported_rates[i] & 0x7f) / 2,
				     sta->supported_rates[i] & 1 ? ".5" : "");
	p += sprintf(p, "\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)
		p = sta->crypt->ops->print_stats(p, sta->crypt->priv);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	if (sta->ap) {
		if (sta->u.ap.channel >= 0)
			p += sprintf(p, "channel=%d\n", sta->u.ap.channel);
		p += sprintf(p, "ssid=");
		for (i = 0; i < sta->u.ap.ssid_len; i++)
			p += sprintf(p, ((sta->u.ap.ssid[i] >= 32 &&
					  sta->u.ap.ssid[i] < 127) ?
					 "%c" : "<%02x>"),
				     sta->u.ap.ssid[i]);
		p += sprintf(p, "\n");
	}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

	return (p - page);
}


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, MACSTR, MAC2STR(sta->addr));
			sta->proc = create_proc_read_entry(
				name, 0, ap->proc,
				prism2_sta_proc_read, 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
	init_timer(&sta->timer);
	sta->timer.expires = jiffies + ap->max_inactivity;
	sta->timer.data = (unsigned long) sta;
	sta->timer.function = ap_handle_timer;
	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 = ieee80211_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 "
		       "ieee80211_crypt_wep.ko\n");
	}
}


/* Generate challenge data for shared key authentication. IEEE 802.11 specifies
 * that WEP algorithm is used for generating challange. 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);
	memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
	       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_4addr *hdr = (struct ieee80211_hdr_4addr *) 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, *pos;
	u16 resp = WLAN_STATUS_SUCCESS, fc;
	struct sta_info *sta = NULL;
	struct ieee80211_crypt_data *crypt;
	char *txt = "";

	len = skb->len - IEEE80211_MGMT_HDR_LEN;

	fc = le16_to_cpu(hdr->frame_ctl);
	hdrlen = hostap_80211_get_hdrlen(fc);

	if (len < 6) {
		PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
		       "(len=%d) from " MACSTR "\n", dev->name, len,
		       MAC2STR(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[idx];
	}

	pos = (u16 *) (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 (memcmp(dev->dev_addr, hdr->addr2, ETH_ALEN) == 0 ||
	    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 " MACSTR " is now STA\n",
			       dev->name, MAC2STR(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 ||
			    !(fc & IEEE80211_FCTL_PROTECTED)) {
				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 = (u16 *) 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: " MACSTR " auth (alg=%d trans#=%d "
		       "stat=%d len=%d fc=%04x) ==> %d (%s)\n",
		       dev->name, MAC2STR(hdr->addr2), auth_alg,
		       auth_transaction, status_code, len, fc, 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_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
	char body[12], *p, *lpos;
	int len, left;
	u16 *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 " MACSTR "\n",
		       dev->name, len, reassoc, MAC2STR(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 = (u16 *) (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
		memset(prev_ap, 0, ETH_ALEN);

	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 " MACSTR " with extra"
			       " data (%d bytes) [",
			       dev->name, MAC2STR(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 = (u16 *) body;

	if (send_deauth) {
		*pos = __constant_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 = __constant_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 = (u16 *) 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: " MACSTR " %sassoc (len=%d prev_ap=" MACSTR
	       ") => %d(%d) (%s)\n",
	       dev->name, MAC2STR(hdr->addr2), reassoc ? "re" : "", len,
	       MAC2STR(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_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
	char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
	int len;
	u16 reason_code, *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 = (u16 *) body;
	reason_code = __le16_to_cpu(*pos);

	PDEBUG(DEBUG_AP, "%s: deauthentication: " MACSTR " len=%d, "
	       "reason_code=%d\n", dev->name, MAC2STR(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 " MACSTR ", "
	       "reason_code=%d, but STA not authenticated\n", dev->name,
		       MAC2STR(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_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
	int len;
	u16 reason_code, *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 = (u16 *) body;
	reason_code = __le16_to_cpu(*pos);

	PDEBUG(DEBUG_AP, "%s: disassociation: " MACSTR " len=%d, "
	       "reason_code=%d\n", dev->name, MAC2STR(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 " MACSTR ", "
		       "reason_code=%d, but STA not authenticated\n",
		       dev->name, MAC2STR(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_4addr *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_4addr *hdr)
{
	struct net_device *dev = local->dev;
	struct sta_info *sta;
	u16 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 = __constant_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_4addr *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=" MACSTR ", TA=" MACSTR
	       " PWRMGT=%d\n",
	       MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
	       !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM));

	if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
		PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MACSTR
		       " not own MAC\n", MAC2STR(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 " MACSTR "\n",
		       local->dev->name,
		       entry->type == WDS_ADD ? "adding" : "removing",
		       MAC2STR(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_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
	int len, left;
	u16 *pos, beacon_int, capability;
	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 = (u16 *) 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_4addr *hdr;

	/* FIX: should give skb->len to handler functions and check that the
	 * buffer is long enough */
	hdr = (struct ieee80211_hdr_4addr *) skb->data;
	fc = le16_to_cpu(hdr->frame_ctl);
	type = WLAN_FC_GET_TYPE(fc);
	stype = WLAN_FC_GET_STYPE(fc);

#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 (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
			PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)="
			       MACSTR " not own MAC\n",
			       MAC2STR(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 (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
		PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=" MACSTR
		       " not own MAC\n", MAC2STR(hdr->addr1));
		goto done;
	}

	if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) {
		PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=" MACSTR
		       " not own MAC\n", MAC2STR(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;
	u16 fc;
	struct ieee80211_hdr_4addr *hdr;

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

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

	local->stats.rx_packets++;

	hdr = (struct ieee80211_hdr_4addr *) skb->data;
	fc = le16_to_cpu(hdr->frame_ctl);

	if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
	    WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT &&
	    WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_BEACON)
		goto drop;

	skb->protocol = __constant_htons(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_4addr *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 = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);

	/* Generate a fake pspoll frame to start packet delivery */
	hdr->frame_ctl = __constant_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 " MACSTR "\n", local->dev->name, MAC2STR(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 independant
 * format that the Wireless Tools will understand - Jean II */
int prism2_ap_translate_scan(struct net_device *dev, 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(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(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(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(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(current_ev, end_buf,
							  &iwe,
							  sta->u.ap.ssid
							  /* 0 byte memcpy */);

			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(
					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(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 " MACSTR " TX rate raised to"
			       " %d\n", dev->name, MAC2STR(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_4addr *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_4addr *) 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 " MACSTR "\n", MAC2STR(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_ctl |=
			__constant_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 (" MACSTR ")'s PS "
		       "mode buffer\n", local->dev->name, MAC2STR(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_4addr *hdr;
	struct hostap_skb_tx_data *meta;

	hdr = (struct ieee80211_hdr_4addr *) 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 " MACSTR " for this "
		       "TX error (@%lu)\n",
		       local->dev->name, MAC2STR(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 " MACSTR " TX rate lowered "
			       "to %d\n", local->dev->name, MAC2STR(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 " MACSTR " changed to use PS "
		       "mode (type=0x%02X, stype=0x%02X)\n",
		       MAC2STR(sta->addr), type >> 2, stype >> 4);
	} else if (!pwrmgt && (sta->flags & WLAN_STA_PS)) {
		sta->flags &= ~WLAN_STA_PS;
		PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to not use "
		       "PS mode (type=0x%02X, stype=0x%02X)\n",
		       MAC2STR(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_ctl field. */
int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *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_ctl);
	hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
			      WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc));

	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_4addr *hdr;

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

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

	fc = le16_to_cpu(hdr->frame_ctl);
	type = WLAN_FC_GET_TYPE(fc);
	stype = WLAN_FC_GET_STYPE(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 && !(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 " MACSTR
				       " (type=0x%02x, subtype=0x%02x)\n",
				       dev->name, MAC2STR(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 (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
				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 &&
		   memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {

		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 "
			       MACSTR "\n",
			       dev->name, MAC2STR(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 (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
			printk(KERN_DEBUG "%s: dropped received packet from "
			       MACSTR " with no ToDS flag (type=0x%02x, "
			       "subtype=0x%02x)\n", dev->name,
			       MAC2STR(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_4addr *hdr,
			     struct ieee80211_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_4addr *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 ieee80211_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 */
