]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/mac80211/mlme.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / net / mac80211 / mlme.c
index 4d2b582dd05587ed46ec7b8dc7d45e708e22e1a6..7f05820dc6294ce7ff96364c8e09c41e0012d603 100644 (file)
@@ -87,6 +87,7 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
                                    u8 *ssid, size_t ssid_len);
 static int ieee80211_sta_config_auth(struct net_device *dev,
                                     struct ieee80211_if_sta *ifsta);
+static void sta_rx_agg_session_timer_expired(unsigned long data);
 
 
 void ieee802_11_parse_elems(u8 *start, size_t len,
@@ -256,19 +257,8 @@ static void ieee80211_sta_def_wmm_params(struct net_device *dev,
                qparam.cw_max = 1023;
                qparam.txop = 0;
 
-               for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++)
-                       local->ops->conf_tx(local_to_hw(local),
-                                          i + IEEE80211_TX_QUEUE_DATA0,
-                                          &qparam);
-
-               if (ibss) {
-                       /* IBSS uses different parameters for Beacon sending */
-                       qparam.cw_min++;
-                       qparam.cw_min *= 2;
-                       qparam.cw_min--;
-                       local->ops->conf_tx(local_to_hw(local),
-                                          IEEE80211_TX_QUEUE_BEACON, &qparam);
-               }
+               for (i = 0; i < local_to_hw(local)->queues; i++)
+                       local->ops->conf_tx(local_to_hw(local), i, &qparam);
        }
 }
 
@@ -282,6 +272,12 @@ static void ieee80211_sta_wmm_params(struct net_device *dev,
        int count;
        u8 *pos;
 
+       if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED))
+               return;
+
+       if (!wmm_param)
+               return;
+
        if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
                return;
        count = wmm_param[6] & 0x0f;
@@ -305,29 +301,25 @@ static void ieee80211_sta_wmm_params(struct net_device *dev,
 
                switch (aci) {
                case 1:
-                       queue = IEEE80211_TX_QUEUE_DATA3;
-                       if (acm) {
+                       queue = 3;
+                       if (acm)
                                local->wmm_acm |= BIT(0) | BIT(3);
-                       }
                        break;
                case 2:
-                       queue = IEEE80211_TX_QUEUE_DATA1;
-                       if (acm) {
+                       queue = 1;
+                       if (acm)
                                local->wmm_acm |= BIT(4) | BIT(5);
-                       }
                        break;
                case 3:
-                       queue = IEEE80211_TX_QUEUE_DATA0;
-                       if (acm) {
+                       queue = 0;
+                       if (acm)
                                local->wmm_acm |= BIT(6) | BIT(7);
-                       }
                        break;
                case 0:
                default:
-                       queue = IEEE80211_TX_QUEUE_DATA2;
-                       if (acm) {
+                       queue = 2;
+                       if (acm)
                                local->wmm_acm |= BIT(1) | BIT(2);
-                       }
                        break;
                }
 
@@ -586,7 +578,7 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
                      int encrypt)
 {
        struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_tx_packet_data *pkt_data;
+       struct ieee80211_tx_info *info;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        skb->dev = sdata->local->mdev;
@@ -594,11 +586,11 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
        skb_set_network_header(skb, 0);
        skb_set_transport_header(skb, 0);
 
-       pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
-       memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
-       pkt_data->ifindex = sdata->dev->ifindex;
+       info = IEEE80211_SKB_CB(skb);
+       memset(info, 0, sizeof(struct ieee80211_tx_info));
+       info->control.ifindex = sdata->dev->ifindex;
        if (!encrypt)
-               pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
+               info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
 
        dev_queue_xmit(skb);
 }
@@ -727,9 +719,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
        if (bss) {
                if (bss->capability & WLAN_CAPABILITY_PRIVACY)
                        capab |= WLAN_CAPABILITY_PRIVACY;
-               if (bss->wmm_ie) {
+               if (bss->wmm_ie)
                        wmm = 1;
-               }
 
                /* get all rates supported by the device and the AP as
                 * some APs don't like getting a superset of their rates
@@ -821,9 +812,32 @@ static void ieee80211_send_assoc(struct net_device *dev,
                *pos++ = 1; /* WME ver */
                *pos++ = 0;
        }
+
        /* wmm support is a must to HT */
-       if (wmm && sband->ht_info.ht_supported) {
-               __le16 tmp = cpu_to_le16(sband->ht_info.cap);
+       if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
+           sband->ht_info.ht_supported && bss->ht_add_ie) {
+               struct ieee80211_ht_addt_info *ht_add_info =
+                       (struct ieee80211_ht_addt_info *)bss->ht_add_ie;
+               u16 cap = sband->ht_info.cap;
+               __le16 tmp;
+               u32 flags = local->hw.conf.channel->flags;
+
+               switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) {
+               case IEEE80211_HT_IE_CHA_SEC_ABOVE:
+                       if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
+                               cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
+                               cap &= ~IEEE80211_HT_CAP_SGI_40;
+                       }
+                       break;
+               case IEEE80211_HT_IE_CHA_SEC_BELOW:
+                       if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
+                               cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
+                               cap &= ~IEEE80211_HT_CAP_SGI_40;
+                       }
+                       break;
+               }
+
+               tmp = cpu_to_le16(cap);
                pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2);
                *pos++ = WLAN_EID_HT_CAPABILITY;
                *pos++ = sizeof(struct ieee80211_ht_cap);
@@ -1141,8 +1155,8 @@ static void ieee80211_send_addba_resp(struct net_device *dev, u8 *da, u16 tid,
        struct ieee80211_mgmt *mgmt;
        u16 capab;
 
-       skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 +
-                                       sizeof(mgmt->u.action.u.addba_resp));
+       skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
+
        if (!skb) {
                printk(KERN_DEBUG "%s: failed to allocate buffer "
                       "for addba resp frame\n", dev->name);
@@ -1190,9 +1204,7 @@ void ieee80211_send_addba_request(struct net_device *dev, const u8 *da,
        struct ieee80211_mgmt *mgmt;
        u16 capab;
 
-       skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 +
-                               sizeof(mgmt->u.action.u.addba_req));
-
+       skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
 
        if (!skb) {
                printk(KERN_ERR "%s: failed to allocate buffer "
@@ -1293,7 +1305,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
 
 
        /* examine state machine */
-       spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
+       spin_lock_bh(&sta->lock);
 
        if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
@@ -1360,7 +1372,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
        tid_agg_rx->stored_mpdu_num = 0;
        status = WLAN_STATUS_SUCCESS;
 end:
-       spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+       spin_unlock_bh(&sta->lock);
 
 end_no_lock:
        ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid,
@@ -1392,10 +1404,10 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
 
        state = &sta->ampdu_mlme.tid_state_tx[tid];
 
-       spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+       spin_lock_bh(&sta->lock);
 
        if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
-               spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+               spin_unlock_bh(&sta->lock);
                printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
                        "%d\n", *state);
                goto addba_resp_exit;
@@ -1403,7 +1415,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
 
        if (mgmt->u.action.u.addba_resp.dialog_token !=
                sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
-               spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+               spin_unlock_bh(&sta->lock);
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
@@ -1427,7 +1439,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
                        ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
                }
 
-               spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+               spin_unlock_bh(&sta->lock);
                printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid);
        } else {
                printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid);
@@ -1435,7 +1447,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
                sta->ampdu_mlme.addba_req_num[tid]++;
                /* this will allow the state check in stop_BA_session */
                *state = HT_AGG_STATE_OPERATIONAL;
-               spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+               spin_unlock_bh(&sta->lock);
                ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
                                             WLAN_BACK_INITIATOR);
        }
@@ -1454,8 +1466,7 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
        struct ieee80211_mgmt *mgmt;
        u16 params;
 
-       skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 +
-                                       sizeof(mgmt->u.action.u.delba));
+       skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
 
        if (!skb) {
                printk(KERN_ERR "%s: failed to allocate buffer "
@@ -1506,17 +1517,17 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
        }
 
        /* check if TID is in operational state */
-       spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
+       spin_lock_bh(&sta->lock);
        if (sta->ampdu_mlme.tid_state_rx[tid]
                                != HT_AGG_STATE_OPERATIONAL) {
-               spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+               spin_unlock_bh(&sta->lock);
                rcu_read_unlock();
                return;
        }
        sta->ampdu_mlme.tid_state_rx[tid] =
                HT_AGG_STATE_REQ_STOP_BA_MSK |
                (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
-       spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+       spin_unlock_bh(&sta->lock);
 
        /* stop HW Rx aggregation. ampdu_action existence
         * already verified in session init so we add the BUG_ON */
@@ -1593,10 +1604,10 @@ static void ieee80211_sta_process_delba(struct net_device *dev,
                ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid,
                                                 WLAN_BACK_INITIATOR, 0);
        else { /* WLAN_BACK_RECIPIENT */
-               spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+               spin_lock_bh(&sta->lock);
                sta->ampdu_mlme.tid_state_tx[tid] =
                                HT_AGG_STATE_OPERATIONAL;
-               spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+               spin_unlock_bh(&sta->lock);
                ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
                                             WLAN_BACK_RECIPIENT);
        }
@@ -1633,9 +1644,9 @@ void sta_addba_resp_timer_expired(unsigned long data)
 
        state = &sta->ampdu_mlme.tid_state_tx[tid];
        /* check if the TID waits for addBA response */
-       spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+       spin_lock_bh(&sta->lock);
        if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
-               spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+               spin_unlock_bh(&sta->lock);
                *state = HT_AGG_STATE_IDLE;
                printk(KERN_DEBUG "timer expired on tid %d but we are not "
                                "expecting addBA response there", tid);
@@ -1646,7 +1657,7 @@ void sta_addba_resp_timer_expired(unsigned long data)
 
        /* go through the state check in stop_BA_session */
        *state = HT_AGG_STATE_OPERATIONAL;
-       spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+       spin_unlock_bh(&sta->lock);
        ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
                                     WLAN_BACK_INITIATOR);
 
@@ -1659,7 +1670,7 @@ timer_expired_exit:
  * resetting it after each frame that arrives from the originator.
  * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
  */
-void sta_rx_agg_session_timer_expired(unsigned long data)
+static void sta_rx_agg_session_timer_expired(unsigned long data)
 {
        /* not an elegant detour, but there is no choice as the timer passes
         * only one argument, and various sta_info are needed here, so init
@@ -1848,9 +1859,8 @@ static void ieee80211_rx_mgmt_deauth(struct net_device *dev,
               " (reason=%d)\n",
               dev->name, print_mac(mac, mgmt->sa), reason_code);
 
-       if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) {
+       if (ifsta->flags & IEEE80211_STA_AUTHENTICATED)
                printk(KERN_DEBUG "%s: deauthenticated\n", dev->name);
-       }
 
        if (ifsta->state == IEEE80211_AUTHENTICATE ||
            ifsta->state == IEEE80211_ASSOCIATE ||
@@ -2013,8 +2023,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                                           local->hw.conf.channel->center_freq,
                                           ifsta->ssid, ifsta->ssid_len);
                if (bss) {
-                       sta->last_rssi = bss->rssi;
                        sta->last_signal = bss->signal;
+                       sta->last_qual = bss->qual;
                        sta->last_noise = bss->noise;
                        ieee80211_rx_bss_put(dev, bss);
                }
@@ -2038,8 +2048,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
         *        to between the sta_info_alloc() and sta_info_insert() above.
         */
 
-       sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
-                     WLAN_STA_AUTHORIZED;
+       set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
+                          WLAN_STA_AUTHORIZED);
 
        rates = 0;
        basic_rates = 0;
@@ -2083,7 +2093,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        else
                sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
 
-       if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) {
+       if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
+           (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
                struct ieee80211_ht_bss_info bss_info;
                ieee80211_ht_cap_ie_to_ht_info(
                                (struct ieee80211_ht_cap *)
@@ -2096,8 +2107,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 
        rate_control_rate_init(sta, local);
 
-       if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
-               sta->flags |= WLAN_STA_WME;
+       if (elems.wmm_param) {
+               set_sta_flags(sta, WLAN_STA_WME);
                rcu_read_unlock();
                ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param,
                                         elems.wmm_param_len);
@@ -2281,6 +2292,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
        kfree(bss->rsn_ie);
        kfree(bss->wmm_ie);
        kfree(bss->ht_ie);
+       kfree(bss->ht_add_ie);
        kfree(bss_mesh_id(bss));
        kfree(bss_mesh_cfg(bss));
        kfree(bss);
@@ -2331,7 +2343,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
        int res, rates, i, j;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
-       struct ieee80211_tx_control control;
+       struct ieee80211_tx_info *control;
        struct rate_selection ratesel;
        u8 *pos;
        struct ieee80211_sub_if_data *sdata;
@@ -2419,21 +2431,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
                        memcpy(pos, &bss->supp_rates[8], rates);
                }
 
-               memset(&control, 0, sizeof(control));
+               control = IEEE80211_SKB_CB(skb);
+
                rate_control_get_rate(dev, sband, skb, &ratesel);
-               if (!ratesel.rate) {
+               if (ratesel.rate_idx < 0) {
                        printk(KERN_DEBUG "%s: Failed to determine TX rate "
                               "for IBSS beacon\n", dev->name);
                        break;
                }
-               control.vif = &sdata->vif;
-               control.tx_rate = ratesel.rate;
+               control->control.vif = &sdata->vif;
+               control->tx_rate_idx = ratesel.rate_idx;
                if (sdata->bss_conf.use_short_preamble &&
-                   ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
-                       control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
-               control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
-               control.flags |= IEEE80211_TXCTL_NO_ACK;
-               control.retry_limit = 1;
+                   sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
+                       control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
+               control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
+               control->flags |= IEEE80211_TX_CTL_NO_ACK;
+               control->control.retry_limit = 1;
 
                ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
                if (ifsta->probe_resp) {
@@ -2448,8 +2461,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
                }
 
                if (local->ops->beacon_update &&
-                   local->ops->beacon_update(local_to_hw(local),
-                                            skb, &control) == 0) {
+                   local->ops->beacon_update(local_to_hw(local), skb) == 0) {
                        printk(KERN_DEBUG "%s: Configured IBSS beacon "
                               "template\n", dev->name);
                        skb = NULL;
@@ -2657,6 +2669,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
                bss->ht_ie_len = 0;
        }
 
+       if (elems.ht_info_elem &&
+            (!bss->ht_add_ie ||
+            bss->ht_add_ie_len != elems.ht_info_elem_len ||
+            memcmp(bss->ht_add_ie, elems.ht_info_elem,
+                       elems.ht_info_elem_len))) {
+               kfree(bss->ht_add_ie);
+               bss->ht_add_ie =
+                       kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC);
+               if (bss->ht_add_ie) {
+                       memcpy(bss->ht_add_ie, elems.ht_info_elem - 2,
+                               elems.ht_info_elem_len + 2);
+                       bss->ht_add_ie_len = elems.ht_info_elem_len + 2;
+               } else
+                       bss->ht_add_ie_len = 0;
+       } else if (!elems.ht_info_elem && bss->ht_add_ie) {
+               kfree(bss->ht_add_ie);
+               bss->ht_add_ie = NULL;
+               bss->ht_add_ie_len = 0;
+       }
+
        bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
        bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
 
@@ -2682,9 +2714,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
        bss->timestamp = beacon_timestamp;
        bss->last_update = jiffies;
-       bss->rssi = rx_status->ssi;
        bss->signal = rx_status->signal;
        bss->noise = rx_status->noise;
+       bss->qual = rx_status->qual;
        if (!beacon && !bss->probe_resp)
                bss->probe_resp = true;
 
@@ -2879,10 +2911,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
 
        ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
-       if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
-               ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param,
-                                        elems.wmm_param_len);
-       }
+       ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param,
+                                elems.wmm_param_len);
 
        /* Do not send changes to driver if we are scanning. This removes
         * requirement that driver's bss_info_changed function needs to be
@@ -3478,9 +3508,9 @@ static int ieee80211_sta_config_auth(struct net_device *dev,
                    !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
                        continue;
 
-               if (!selected || top_rssi < bss->rssi) {
+               if (!selected || top_rssi < bss->signal) {
                        selected = bss;
-                       top_rssi = bss->rssi;
+                       top_rssi = bss->signal;
                }
        }
        if (selected)
@@ -3557,10 +3587,12 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
        bss->beacon_int = local->hw.conf.beacon_int;
        bss->last_update = jiffies;
        bss->capability = WLAN_CAPABILITY_IBSS;
-       if (sdata->default_key) {
+
+       if (sdata->default_key)
                bss->capability |= WLAN_CAPABILITY_PRIVACY;
-       else
+       else
                sdata->drop_unencrypted = 0;
+
        bss->supp_rates_len = sband->n_bitrates;
        pos = bss->supp_rates;
        for (i = 0; i < sband->n_bitrates; i++) {
@@ -4114,8 +4146,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
                                          IW_EV_FREQ_LEN);
        memset(&iwe, 0, sizeof(iwe));
        iwe.cmd = IWEVQUAL;
-       iwe.u.qual.qual = bss->signal;
-       iwe.u.qual.level = bss->rssi;
+       iwe.u.qual.qual = bss->qual;
+       iwe.u.qual.level = bss->signal;
        iwe.u.qual.noise = bss->noise;
        iwe.u.qual.updated = local->wstats_flags;
        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
@@ -4146,6 +4178,14 @@ ieee80211_sta_scan_result(struct net_device *dev,
                                                  bss->rsn_ie);
        }
 
+       if (bss && bss->ht_ie) {
+               memset(&iwe, 0, sizeof(iwe));
+               iwe.cmd = IWEVGENIE;
+               iwe.u.data.length = bss->ht_ie_len;
+               current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
+                                                 bss->ht_ie);
+       }
+
        if (bss && bss->supp_rates_len > 0) {
                /* display all supported rates in readable format */
                char *p = current_ev + IW_EV_LCP_LEN;
@@ -4247,6 +4287,7 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_if_sta *ifsta = &sdata->u.sta;
+
        kfree(ifsta->extra_ie);
        if (len == 0) {
                ifsta->extra_ie = NULL;
@@ -4264,9 +4305,9 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
 }
 
 
-struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
-                                        struct sk_buff *skb, u8 *bssid,
-                                        u8 *addr)
+struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev,
+                                       struct sk_buff *skb, u8 *bssid,
+                                       u8 *addr)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct sta_info *sta;
@@ -4290,7 +4331,7 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
        if (!sta)
                return NULL;
 
-       sta->flags |= WLAN_STA_AUTHORIZED;
+       set_sta_flags(sta, WLAN_STA_AUTHORIZED);
 
        sta->supp_rates[local->hw.conf.channel->band] =
                sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band];