Merge master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
[powerpc.git] / drivers / net / wireless / hostap / hostap_ap.c
index 6e109df..9da94ab 100644 (file)
@@ -46,7 +46,7 @@ static void handle_add_proc_queue(void *data);
 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
 static void handle_wds_oper_queue(void *data);
 static void prism2_send_mgmt(struct net_device *dev,
-                            int type, int subtype, char *body,
+                            u16 type_subtype, char *body,
                             int body_len, u8 *addr, u16 tx_cb_idx);
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
@@ -237,12 +237,12 @@ static void ap_handle_timer(unsigned long data)
        } else if (sta->timeout_next == STA_NULLFUNC) {
                /* send data frame to poll STA and check whether this frame
                 * is ACKed */
-               /* FIX: WLAN_FC_STYPE_NULLFUNC would be more appropriate, but
+               /* 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, WLAN_FC_TYPE_DATA,
-                                WLAN_FC_STYPE_DATA, NULL, 0,
+               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;
@@ -255,9 +255,9 @@ static void ap_handle_timer(unsigned long data)
 
                resp = cpu_to_le16(deauth ? WLAN_REASON_PREV_AUTH_NOT_VALID :
                                   WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
-               prism2_send_mgmt(local->dev, WLAN_FC_TYPE_MGMT,
-                                (deauth ? WLAN_FC_STYPE_DEAUTH :
-                                 WLAN_FC_STYPE_DISASSOC),
+               prism2_send_mgmt(local->dev, IEEE80211_FTYPE_MGMT |
+                                (deauth ? IEEE80211_STYPE_DEAUTH :
+                                 IEEE80211_STYPE_DISASSOC),
                                 (char *) &resp, 2, sta->addr, 0);
        }
 
@@ -300,7 +300,8 @@ void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
         * 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, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH,
+               prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
+                                IEEE80211_STYPE_DEAUTH,
                                 (char *) &resp, 2, addr, 0);
 
                if (!resend || ap->num_sta <= 0)
@@ -471,7 +472,7 @@ static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
                return -EINVAL;
 
        resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
-       prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH,
+       prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH,
                         (char *) &resp, 2, sta->addr, 0);
 
        if ((sta->flags & WLAN_STA_ASSOC) && !sta->ap)
@@ -489,7 +490,7 @@ static 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) {
@@ -590,22 +591,22 @@ static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
 {
        struct ap_data *ap = data;
        u16 fc;
-       struct hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        if (!ap->local->hostapd || !ap->local->apdev) {
                dev_kfree_skb(skb);
                return;
        }
 
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_control);
+       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 &= ~WLAN_FC_PVER;
+       fc &= ~IEEE80211_FCTL_VERS;
        fc |= ok ? BIT(1) : BIT(0);
-       hdr->frame_control = cpu_to_le16(fc);
+       hdr->frame_ctl = cpu_to_le16(fc);
 
        skb->dev = ap->local->apdev;
        skb_pull(skb, hostap_80211_get_hdrlen(fc));
@@ -622,7 +623,7 @@ 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 hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc, *pos, auth_alg, auth_transaction, status;
        struct sta_info *sta = NULL;
        char *txt = NULL;
@@ -632,10 +633,10 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
                return;
        }
 
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_control);
-       if (HOSTAP_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
-           HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_AUTH ||
+       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);
@@ -691,7 +692,7 @@ 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 hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc, *pos, status;
        struct sta_info *sta = NULL;
        char *txt = NULL;
@@ -701,11 +702,11 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
                return;
        }
 
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_control);
-       if (HOSTAP_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
-           (HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ASSOC_RESP &&
-            HOSTAP_FC_GET_STYPE(fc) != WLAN_FC_STYPE_REASSOC_RESP) ||
+       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);
@@ -756,12 +757,12 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
 static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
 {
        struct ap_data *ap = data;
-       struct hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        struct sta_info *sta;
 
        if (skb->len < 24)
                goto fail;
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        if (ok) {
                spin_lock(&ap->sta_table_lock);
                sta = ap_get_sta(ap, hdr->addr1);
@@ -912,12 +913,12 @@ static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta)
 
 /* Called from timer handler and from scheduled AP queue handlers */
 static void prism2_send_mgmt(struct net_device *dev,
-                            int type, int subtype, char *body,
+                            u16 type_subtype, char *body,
                             int body_len, u8 *addr, u16 tx_cb_idx)
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       struct hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc;
        struct sk_buff *skb;
        struct hostap_skb_tx_data *meta;
@@ -941,9 +942,9 @@ static void prism2_send_mgmt(struct net_device *dev,
                return;
        }
 
-       fc = (type << 2) | (subtype << 4);
+       fc = type_subtype;
        hdrlen = hostap_80211_get_hdrlen(fc);
-       hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, hdrlen);
+       hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
        if (body)
                memcpy(skb_put(skb, body_len), body, body_len);
 
@@ -954,11 +955,11 @@ static void prism2_send_mgmt(struct net_device *dev,
 
 
        memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */
-       if (type == WLAN_FC_TYPE_DATA) {
-               fc |= WLAN_FC_FROMDS;
+       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 (type == WLAN_FC_TYPE_CTRL) {
+       } 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);
@@ -967,7 +968,7 @@ static void prism2_send_mgmt(struct net_device *dev,
                memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
        }
 
-       hdr->frame_control = cpu_to_le16(fc);
+       hdr->frame_ctl = cpu_to_le16(fc);
 
        meta = (struct hostap_skb_tx_data *) skb->cb;
        memset(meta, 0, sizeof(*meta));
@@ -1255,14 +1256,14 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
        }
 
        skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
-                           ap->crypt->extra_prefix_len +
-                           ap->crypt->extra_postfix_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_prefix_len);
+       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)) {
@@ -1271,7 +1272,7 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
                return NULL;
        }
 
-       memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
+       memcpy(tmpbuf, skb->data + ap->crypt->extra_mpdu_prefix_len,
               WLAN_AUTH_CHALLENGE_LEN);
        dev_kfree_skb(skb);
 
@@ -1284,8 +1285,7 @@ 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 hostap_ieee80211_hdr *hdr =
-               (struct hostap_ieee80211_hdr *) skb->data;
+       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;
@@ -1298,7 +1298,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
 
        len = skb->len - IEEE80211_MGMT_HDR_LEN;
 
-       fc = le16_to_cpu(hdr->frame_control);
+       fc = le16_to_cpu(hdr->frame_ctl);
        hdrlen = hostap_80211_get_hdrlen(fc);
 
        if (len < 6) {
@@ -1436,7 +1436,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
                            challenge == NULL ||
                            memcmp(sta->u.sta.challenge, challenge,
                                   WLAN_AUTH_CHALLENGE_LEN) != 0 ||
-                           !(fc & WLAN_FC_ISWEP)) {
+                           !(fc & IEEE80211_FCTL_PROTECTED)) {
                                txt = "challenge response incorrect";
                                resp = WLAN_STATUS_CHALLENGE_FAIL;
                                goto fail;
@@ -1476,7 +1476,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
                olen += 2 + WLAN_AUTH_CHALLENGE_LEN;
        }
 
-       prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_AUTH,
+       prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH,
                         body, olen, hdr->addr2, ap->tx_callback_auth);
 
        if (sta) {
@@ -1498,8 +1498,7 @@ 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 hostap_ieee80211_hdr *hdr =
-               (struct hostap_ieee80211_hdr *) skb->data;
+       struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char body[12], *p, *lpos;
        int len, left;
        u16 *pos;
@@ -1573,7 +1572,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
                        u++; left--;
                        ileft = *u;
                        u++; left--;
-                       
+
                        if (ileft > left || ileft == 0 ||
                            ileft > WLAN_SUPP_RATES_MAX) {
                                txt = "SUPP_RATES len error";
@@ -1675,10 +1674,10 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
                pos = (u16 *) p;
        }
 
-       prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT,
-                        (send_deauth ? WLAN_FC_STYPE_DEAUTH :
-                         (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
-                          WLAN_FC_STYPE_ASSOC_RESP)),
+       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);
@@ -1706,8 +1705,7 @@ 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 hostap_ieee80211_hdr *hdr =
-               (struct hostap_ieee80211_hdr *) skb->data;
+       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;
@@ -1748,8 +1746,7 @@ 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 hostap_ieee80211_hdr *hdr =
-               (struct hostap_ieee80211_hdr *) skb->data;
+       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;
@@ -1787,7 +1784,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
 
 /* Called only as a scheduled task for pending AP frames. */
 static void ap_handle_data_nullfunc(local_info_t *local,
-                                   struct hostap_ieee80211_hdr *hdr)
+                                   struct ieee80211_hdr_4addr *hdr)
 {
        struct net_device *dev = local->dev;
 
@@ -1797,14 +1794,14 @@ static void ap_handle_data_nullfunc(local_info_t *local,
         * send control::ACK for the data::nullfunc */
 
        printk(KERN_DEBUG "Sending control::ACK for data::nullfunc\n");
-       prism2_send_mgmt(dev, WLAN_FC_TYPE_CTRL, WLAN_FC_STYPE_ACK,
+       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 hostap_ieee80211_hdr *hdr)
+                                  struct ieee80211_hdr_4addr *hdr)
 {
        struct net_device *dev = local->dev;
        struct sta_info *sta;
@@ -1824,9 +1821,9 @@ static void ap_handle_dropped_data(local_info_t *local,
 
        reason = __constant_cpu_to_le16(
                WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
-       prism2_send_mgmt(dev, WLAN_FC_TYPE_MGMT,
+       prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
                         ((sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) ?
-                         WLAN_FC_STYPE_DEAUTH : WLAN_FC_STYPE_DISASSOC),
+                         IEEE80211_STYPE_DEAUTH : IEEE80211_STYPE_DISASSOC),
                         (char *) &reason, sizeof(reason), hdr->addr2, 0);
 
        if (sta)
@@ -1840,6 +1837,8 @@ static void ap_handle_dropped_data(local_info_t *local,
 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. */
@@ -1849,11 +1848,11 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
 
        /* add a flag for hostap_handle_sta_tx() to know that this skb should
         * be passed through even though STA is using PS */
-       memcpy(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN);
-       skb->cb[AP_SKB_CB_MAGIC_LEN] = AP_SKB_CB_BUFFERED_FRAME;
+       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 */
-               skb->cb[AP_SKB_CB_MAGIC_LEN] |= AP_SKB_CB_ADD_MOREDATA;
+               meta->flags |= HOSTAP_TX_FLAGS_ADD_MOREDATA;
        }
        dev_queue_xmit(skb);
 }
@@ -1861,7 +1860,7 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
 
 /* Called only as a scheduled task for pending AP frames. */
 static void handle_pspoll(local_info_t *local,
-                         struct hostap_ieee80211_hdr *hdr,
+                         struct ieee80211_hdr_4addr *hdr,
                          struct hostap_80211_rx_status *rx_stats)
 {
        struct net_device *dev = local->dev;
@@ -1872,7 +1871,7 @@ static void handle_pspoll(local_info_t *local,
        PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MACSTR ", TA=" MACSTR
               " PWRMGT=%d\n",
               MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
-              !!(le16_to_cpu(hdr->frame_control) & WLAN_FC_PWRMGT));
+              !!(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
@@ -1980,8 +1979,7 @@ static void handle_wds_oper_queue(void *data)
 static void handle_beacon(local_info_t *local, struct sk_buff *skb,
                          struct hostap_80211_rx_status *rx_stats)
 {
-       struct hostap_ieee80211_hdr *hdr =
-               (struct hostap_ieee80211_hdr *) skb->data;
+       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;
@@ -2047,7 +2045,7 @@ static void handle_beacon(local_info_t *local, struct sk_buff *skb,
                        u++; left--;
                        ileft = *u;
                        u++; left--;
-                       
+
                        if (ileft > left || ileft == 0 || ileft > 8) {
                                PDEBUG(DEBUG_AP, " - SUPP_RATES len error\n");
                                return;
@@ -2064,7 +2062,7 @@ static void handle_beacon(local_info_t *local, struct sk_buff *skb,
                        u++; left--;
                        ileft = *u;
                        u++; left--;
-                       
+
                        if (ileft > left || ileft != 1) {
                                PDEBUG(DEBUG_AP, " - DS_PARAMS len error\n");
                                return;
@@ -2139,21 +2137,22 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
        struct net_device *dev = local->dev;
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
        u16 fc, type, stype;
-       struct hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        /* FIX: should give skb->len to handler functions and check that the
         * buffer is long enough */
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_control);
-       type = HOSTAP_FC_GET_TYPE(fc);
-       stype = HOSTAP_FC_GET_STYPE(fc);
+       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 == WLAN_FC_TYPE_DATA) {
+       if (!local->hostapd && type == IEEE80211_FTYPE_DATA) {
                PDEBUG(DEBUG_AP, "handle_ap_item - data frame\n");
 
-               if (!(fc & WLAN_FC_TODS) || (fc & WLAN_FC_FROMDS)) {
-                       if (stype == WLAN_FC_STYPE_NULLFUNC) {
+               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 */
@@ -2172,20 +2171,21 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
                        goto done;
                }
 
-               if (local->ap->nullfunc_ack && stype == WLAN_FC_STYPE_NULLFUNC)
+               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 == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_BEACON) {
+       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 == WLAN_FC_TYPE_CTRL && stype == WLAN_FC_STYPE_PSPOLL) {
+       if (type == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL) {
                handle_pspoll(local, hdr, rx_stats);
                goto done;
        }
@@ -2197,7 +2197,7 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
        }
 
 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
-       if (type != WLAN_FC_TYPE_MGMT) {
+       if (type != IEEE80211_FTYPE_MGMT) {
                PDEBUG(DEBUG_AP, "handle_ap_item - not a management frame?\n");
                goto done;
        }
@@ -2215,32 +2215,33 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
        }
 
        switch (stype) {
-       case WLAN_FC_STYPE_ASSOC_REQ:
+       case IEEE80211_STYPE_ASSOC_REQ:
                handle_assoc(local, skb, rx_stats, 0);
                break;
-       case WLAN_FC_STYPE_ASSOC_RESP:
+       case IEEE80211_STYPE_ASSOC_RESP:
                PDEBUG(DEBUG_AP, "==> ASSOC RESP (ignored)\n");
                break;
-       case WLAN_FC_STYPE_REASSOC_REQ:
+       case IEEE80211_STYPE_REASSOC_REQ:
                handle_assoc(local, skb, rx_stats, 1);
                break;
-       case WLAN_FC_STYPE_REASSOC_RESP:
+       case IEEE80211_STYPE_REASSOC_RESP:
                PDEBUG(DEBUG_AP, "==> REASSOC RESP (ignored)\n");
                break;
-       case WLAN_FC_STYPE_ATIM:
+       case IEEE80211_STYPE_ATIM:
                PDEBUG(DEBUG_AP, "==> ATIM (ignored)\n");
                break;
-       case WLAN_FC_STYPE_DISASSOC:
+       case IEEE80211_STYPE_DISASSOC:
                handle_disassoc(local, skb, rx_stats);
                break;
-       case WLAN_FC_STYPE_AUTH:
+       case IEEE80211_STYPE_AUTH:
                handle_authen(local, skb, rx_stats);
                break;
-       case WLAN_FC_STYPE_DEAUTH:
+       case IEEE80211_STYPE_DEAUTH:
                handle_deauth(local, skb, rx_stats);
                break;
        default:
-               PDEBUG(DEBUG_AP, "Unknown mgmt frame subtype 0x%02x\n", stype);
+               PDEBUG(DEBUG_AP, "Unknown mgmt frame subtype 0x%02x\n",
+                      stype >> 4);
                break;
        }
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
@@ -2257,7 +2258,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
        struct hostap_interface *iface;
        local_info_t *local;
        u16 fc;
-       struct hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -2267,12 +2268,12 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
 
        local->stats.rx_packets++;
 
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_control);
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
+       fc = le16_to_cpu(hdr->frame_ctl);
 
        if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
-           HOSTAP_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
-           HOSTAP_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
+           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);
@@ -2288,7 +2289,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
 static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
 {
        struct sk_buff *skb;
-       struct hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        struct hostap_80211_rx_status rx_stats;
 
        if (skb_queue_empty(&sta->tx_buf))
@@ -2301,11 +2302,11 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
                return;
        }
 
-       hdr = (struct hostap_ieee80211_hdr *) skb_put(skb, 16);
+       hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
 
        /* Generate a fake pspoll frame to start packet delivery */
-       hdr->frame_control = __constant_cpu_to_le16(
-               (WLAN_FC_TYPE_CTRL << 2) | (WLAN_FC_STYPE_PSPOLL << 4));
+       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));
@@ -2348,7 +2349,7 @@ static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
                qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
                qual[count].updated = sta->last_rx_updated;
 
-               sta->last_rx_updated = 0;
+               sta->last_rx_updated = IW_QUAL_DBM;
 
                count++;
                if (count >= buf_size)
@@ -2466,7 +2467,7 @@ static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
                }
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
-               sta->last_rx_updated = 0;
+               sta->last_rx_updated = IW_QUAL_DBM;
 
                /* To be continued, we should make good use of IWEVCUSTOM */
        }
@@ -2684,7 +2685,7 @@ 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 hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        struct hostap_skb_tx_data *meta;
 
        meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2693,7 +2694,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
            meta->iface->type == HOSTAP_INTERFACE_STA)
                goto out;
 
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
        if (hdr->addr1[0] & 0x01) {
                /* broadcast/multicast frame - no AP related processing */
@@ -2707,7 +2708,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
                atomic_inc(&sta->users);
        spin_unlock(&local->ap->sta_table_lock);
 
-       if (local->iw_mode == IW_MODE_MASTER && sta == NULL && !meta->wds &&
+       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
@@ -2743,18 +2745,16 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
        if (!(sta->flags & WLAN_STA_PS))
                goto out;
 
-       if (memcmp(skb->cb, AP_SKB_CB_MAGIC, AP_SKB_CB_MAGIC_LEN) == 0) {
-               if (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_ADD_MOREDATA) {
-                       /* indicate to STA that more frames follow */
-                       hdr->frame_control |=
-                               __constant_cpu_to_le16(WLAN_FC_MOREDATA);
-               }
+       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 (skb->cb[AP_SKB_CB_MAGIC_LEN] & AP_SKB_CB_BUFFERED_FRAME) {
-                       /* packet was already buffered and now send due to
-                        * PS poll, so do not rebuffer it */
-                       goto out;
-               }
+       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) {
@@ -2821,10 +2821,10 @@ void hostap_handle_sta_release(void *ptr)
 void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
 {
        struct sta_info *sta;
-       struct hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        struct hostap_skb_tx_data *meta;
 
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        meta = (struct hostap_skb_tx_data *) skb->cb;
 
        spin_lock(&local->ap->sta_table_lock);
@@ -2839,7 +2839,7 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
 
        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 */
@@ -2877,21 +2877,22 @@ static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
                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, stype);
+                      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, stype);
-               if (type != WLAN_FC_TYPE_CTRL || stype != WLAN_FC_STYPE_PSPOLL)
+                      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_control field. */
-int hostap_update_sta_ps(local_info_t *local, struct hostap_ieee80211_hdr *hdr)
+ * 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;
@@ -2905,9 +2906,9 @@ int hostap_update_sta_ps(local_info_t *local, struct hostap_ieee80211_hdr *hdr)
        if (!sta)
                return -1;
 
-       fc = le16_to_cpu(hdr->frame_control);
-       hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT,
-                             HOSTAP_FC_GET_TYPE(fc), HOSTAP_FC_GET_STYPE(fc));
+       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;
@@ -2924,16 +2925,16 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
        int ret;
        struct sta_info *sta;
        u16 fc, type, stype;
-       struct hostap_ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        if (local->ap == NULL)
                return AP_RX_CONTINUE;
 
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
-       fc = le16_to_cpu(hdr->frame_control);
-       type = HOSTAP_FC_GET_TYPE(fc);
-       stype = HOSTAP_FC_GET_STYPE(fc);
+       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);
@@ -2947,7 +2948,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                ret = AP_RX_CONTINUE;
 
 
-       if (fc & WLAN_FC_TODS) {
+       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,
@@ -2957,15 +2958,15 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                                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,
-                                      stype);
+                                      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 & WLAN_FC_FROMDS) {
+       } else if (fc & IEEE80211_FCTL_FROMDS) {
                if (!wds) {
                        /* FromDS frame - not for us; probably
                         * broadcast/multicast in another BSS - drop */
@@ -2977,7 +2978,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                        ret = AP_RX_DROP;
                        goto out;
                }
-       } else if (stype == WLAN_FC_STYPE_NULLFUNC && sta == NULL &&
+       } else if (stype == IEEE80211_STYPE_NULLFUNC && sta == NULL &&
                   memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
 
                if (local->hostapd) {
@@ -2999,7 +3000,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                }
                ret = AP_RX_EXIT;
                goto out;
-       } else if (stype == WLAN_FC_STYPE_NULLFUNC) {
+       } 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
@@ -3012,7 +3013,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                        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, stype);
+                              MAC2STR(hdr->addr2), type >> 2, stype >> 4);
                        hostap_dump_rx_80211(dev->name, skb, rx_stats);
                }
                ret = AP_RX_DROP;
@@ -3020,7 +3021,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
        }
 
        if (sta) {
-               hostap_update_sta_ps2(local, sta, fc & WLAN_FC_PWRMGT,
+               hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
                                      type, stype);
 
                sta->rx_packets++;
@@ -3028,8 +3029,8 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                sta->last_rx = jiffies;
        }
 
-       if (local->ap->nullfunc_ack && stype == WLAN_FC_STYPE_NULLFUNC &&
-           fc & WLAN_FC_TODS) {
+       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);
@@ -3057,7 +3058,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
 
 /* Called only as a tasklet (software IRQ) */
 int hostap_handle_sta_crypto(local_info_t *local,
-                            struct hostap_ieee80211_hdr *hdr,
+                            struct ieee80211_hdr_4addr *hdr,
                             struct ieee80211_crypt_data **crypt,
                             void **sta_ptr)
 {
@@ -3159,7 +3160,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
 
 /* Called only as a tasklet (software IRQ) */
 int hostap_update_rx_stats(struct ap_data *ap,
-                          struct hostap_ieee80211_hdr *hdr,
+                          struct ieee80211_hdr_4addr *hdr,
                           struct hostap_80211_rx_status *rx_stats)
 {
        struct sta_info *sta;
@@ -3173,7 +3174,7 @@ int hostap_update_rx_stats(struct ap_data *ap,
                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 = 7;
+               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)