sh: convert /proc/cpu/aligmnent, /proc/cpu/kernel_alignment to seq_file
[safe/jmp/linux-2.6] / net / mac80211 / ibss.c
index aa53768..f1362f3 100644 (file)
@@ -57,25 +57,25 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
         */
        if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
                ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
-                                   sdata->u.ibss.bssid, 0);
+                                   sdata->u.ibss.bssid, NULL, 0, 0);
 }
 
 static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                                      const u8 *bssid, const int beacon_int,
                                      struct ieee80211_channel *chan,
-                                     const size_t supp_rates_len,
-                                     const u8 *supp_rates,
+                                     const u32 basic_rates,
                                      const u16 capability, u64 tsf)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
-       int rates, i, j;
+       int rates, i;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
        u8 *pos;
        struct ieee80211_supported_band *sband;
+       struct cfg80211_bss *bss;
        u32 bss_change;
-
+       u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
 
        /* Reset own TSF to allow time synchronization work. */
        drv_reset_tsf(local);
@@ -101,6 +101,16 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 
        sband = local->hw.wiphy->bands[chan->band];
 
+       /* build supported rates array */
+       pos = supp_rates;
+       for (i = 0; i < sband->n_bitrates; i++) {
+               int rate = sband->bitrates[i].bitrate;
+               u8 basic = 0;
+               if (basic_rates & BIT(i))
+                       basic = 0x80;
+               *pos++ = basic | (u8) (rate / 5);
+       }
+
        /* Build IBSS probe response */
        mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
        memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
@@ -118,7 +128,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        *pos++ = ifibss->ssid_len;
        memcpy(pos, ifibss->ssid, ifibss->ssid_len);
 
-       rates = supp_rates_len;
+       rates = sband->n_bitrates;
        if (rates > 8)
                rates = 8;
        pos = skb_put(skb, 2 + rates);
@@ -140,8 +150,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        *pos++ = 0;
        *pos++ = 0;
 
-       if (supp_rates_len > 8) {
-               rates = supp_rates_len - 8;
+       if (sband->n_bitrates > 8) {
+               rates = sband->n_bitrates - 8;
                pos = skb_put(skb, 2 + rates);
                *pos++ = WLAN_EID_EXT_SUPP_RATES;
                *pos++ = rates;
@@ -162,37 +172,50 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        bss_change |= BSS_CHANGED_BEACON_ENABLED;
        ieee80211_bss_info_change_notify(sdata, bss_change);
 
-       rates = 0;
-       for (i = 0; i < supp_rates_len; i++) {
-               int bitrate = (supp_rates[i] & 0x7f) * 5;
-               for (j = 0; j < sband->n_bitrates; j++)
-                       if (sband->bitrates[j].bitrate == bitrate)
-                               rates |= BIT(j);
-       }
-
-       ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
+       ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
 
        ifibss->state = IEEE80211_IBSS_MLME_JOINED;
        mod_timer(&ifibss->timer,
                  round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
 
-       cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
-                                 mgmt, skb->len, 0, GFP_KERNEL);
+       bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
+                                       mgmt, skb->len, 0, GFP_KERNEL);
+       cfg80211_put_bss(bss);
        cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
 }
 
 static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                                    struct ieee80211_bss *bss)
 {
+       struct ieee80211_supported_band *sband;
+       u32 basic_rates;
+       int i, j;
        u16 beacon_int = bss->cbss.beacon_interval;
 
        if (beacon_int < 10)
                beacon_int = 10;
 
+       sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band];
+
+       basic_rates = 0;
+
+       for (i = 0; i < bss->supp_rates_len; i++) {
+               int rate = (bss->supp_rates[i] & 0x7f) * 5;
+               bool is_basic = !!(bss->supp_rates[i] & 0x80);
+
+               for (j = 0; j < sband->n_bitrates; j++) {
+                       if (sband->bitrates[j].bitrate == rate) {
+                               if (is_basic)
+                                       basic_rates |= BIT(j);
+                               break;
+                       }
+               }
+       }
+
        __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
                                  beacon_int,
                                  bss->cbss.channel,
-                                 bss->supp_rates_len, bss->supp_rates,
+                                 basic_rates,
                                  bss->cbss.capability,
                                  bss->cbss.tsf);
 }
@@ -449,9 +472,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_supported_band *sband;
-       u8 *pos;
        u8 bssid[ETH_ALEN];
-       u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
        u16 capability;
        int i;
 
@@ -475,20 +496,14 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
 
        capability = WLAN_CAPABILITY_IBSS;
 
-       if (sdata->default_key)
+       if (ifibss->privacy)
                capability |= WLAN_CAPABILITY_PRIVACY;
        else
                sdata->drop_unencrypted = 0;
 
-       pos = supp_rates;
-       for (i = 0; i < sband->n_bitrates; i++) {
-               int rate = sband->bitrates[i].bitrate;
-               *pos++ = (u8) (rate / 5);
-       }
-
        __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
-                                 ifibss->channel, sband->n_bitrates,
-                                 supp_rates, capability, 0);
+                                 ifibss->channel, 3, /* first two are basic */
+                                 capability, 0);
 }
 
 static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
@@ -499,6 +514,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_channel *chan = NULL;
        const u8 *bssid = NULL;
        int active_ibss;
+       u16 capability;
 
        active_ibss = ieee80211_sta_active_ibss(sdata);
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
@@ -509,6 +525,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
        if (active_ibss)
                return;
 
+       capability = WLAN_CAPABILITY_IBSS;
+       if (ifibss->privacy)
+               capability |= WLAN_CAPABILITY_PRIVACY;
        if (ifibss->fixed_bssid)
                bssid = ifibss->bssid;
        if (ifibss->fixed_channel)
@@ -517,16 +536,16 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
                bssid = ifibss->bssid;
        bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid,
                                       ifibss->ssid, ifibss->ssid_len,
-                                      WLAN_CAPABILITY_IBSS,
-                                      WLAN_CAPABILITY_IBSS);
+                                      WLAN_CAPABILITY_IBSS |
+                                      WLAN_CAPABILITY_PRIVACY,
+                                      capability);
 
+       if (bss) {
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-       if (bss)
                printk(KERN_DEBUG "   sta_find_ibss: selected %pM current "
                       "%pM\n", bss->cbss.bssid, ifibss->bssid);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 
-       if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
                printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
                       " based on configured SSID\n",
                       sdata->dev->name, bss->cbss.bssid);
@@ -534,8 +553,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
                ieee80211_sta_join_ibss(sdata, bss);
                ieee80211_rx_bss_put(local, bss);
                return;
-       } else if (bss)
-               ieee80211_rx_bss_put(local, bss);
+       }
 
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
        printk(KERN_DEBUG "   did not try to join ibss\n");
@@ -686,7 +704,7 @@ static void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_mgmt *mgmt;
        u16 fc;
 
-       rx_status = (struct ieee80211_rx_status *) skb->cb;
+       rx_status = IEEE80211_SKB_RXCB(skb);
        mgmt = (struct ieee80211_mgmt *) skb->data;
        fc = le16_to_cpu(mgmt->frame_control);
 
@@ -718,10 +736,13 @@ static void ieee80211_ibss_work(struct work_struct *work)
        struct ieee80211_if_ibss *ifibss;
        struct sk_buff *skb;
 
+       if (WARN_ON(local->suspended))
+               return;
+
        if (!netif_running(sdata->dev))
                return;
 
-       if (local->sw_scanning || local->hw_scanning)
+       if (local->scanning)
                return;
 
        if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_ADHOC))
@@ -754,9 +775,35 @@ static void ieee80211_ibss_timer(unsigned long data)
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
 
+       if (local->quiescing) {
+               ifibss->timer_running = true;
+               return;
+       }
+
        set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
-       queue_work(local->hw.workqueue, &ifibss->work);
+       ieee80211_queue_work(&local->hw, &ifibss->work);
+}
+
+#ifdef CONFIG_PM
+void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+
+       cancel_work_sync(&ifibss->work);
+       if (del_timer_sync(&ifibss->timer))
+               ifibss->timer_running = true;
+}
+
+void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+
+       if (ifibss->timer_running) {
+               add_timer(&ifibss->timer);
+               ifibss->timer_running = false;
+       }
 }
+#endif
 
 void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
 {
@@ -782,14 +829,13 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
                if (!sdata->u.ibss.ssid_len)
                        continue;
                sdata->u.ibss.last_scan_completed = jiffies;
-               ieee80211_sta_find_ibss(sdata);
+               mod_timer(&sdata->u.ibss.timer, 0);
        }
        mutex_unlock(&local->iflist_mtx);
 }
 
 ieee80211_rx_result
-ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-                      struct ieee80211_rx_status *rx_status)
+ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_mgmt *mgmt;
@@ -804,11 +850,10 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
        switch (fc & IEEE80211_FCTL_STYPE) {
        case IEEE80211_STYPE_PROBE_RESP:
        case IEEE80211_STYPE_BEACON:
-               memcpy(skb->cb, rx_status, sizeof(*rx_status));
        case IEEE80211_STYPE_PROBE_REQ:
        case IEEE80211_STYPE_AUTH:
                skb_queue_tail(&sdata->u.ibss.skb_queue, skb);
-               queue_work(local->hw.workqueue, &sdata->u.ibss.work);
+               ieee80211_queue_work(&local->hw, &sdata->u.ibss.work);
                return RX_QUEUED;
        }
 
@@ -826,6 +871,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
        } else
                sdata->u.ibss.fixed_bssid = false;
 
+       sdata->u.ibss.privacy = params->privacy;
+
        sdata->vif.bss_conf.beacon_int = params->beacon_interval;
 
        sdata->u.ibss.channel = params->channel;
@@ -865,7 +912,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
        ieee80211_recalc_idle(sdata->local);
 
        set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
-       queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
+       ieee80211_queue_work(&sdata->local->hw, &sdata->u.ibss.work);
 
        return 0;
 }