mac80211: refactor station state transitions
[pandora-kernel.git] / net / mac80211 / iface.c
index 4ee624c..e47768c 100644 (file)
@@ -188,11 +188,22 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
                if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
                        return -ENOLINK;
                break;
-       case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_AP_VLAN: {
+               struct ieee80211_sub_if_data *master;
+
                if (!sdata->bss)
                        return -ENOLINK;
+
                list_add(&sdata->u.vlan.list, &sdata->bss->vlans);
+
+               master = container_of(sdata->bss,
+                                     struct ieee80211_sub_if_data, u.ap);
+               sdata->control_port_protocol =
+                       master->control_port_protocol;
+               sdata->control_port_no_encrypt =
+                       master->control_port_no_encrypt;
                break;
+               }
        case NL80211_IFTYPE_AP:
                sdata->bss = &sdata->u.ap;
                break;
@@ -282,7 +293,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
                changed |= ieee80211_reset_erp_info(sdata);
                ieee80211_bss_info_change_notify(sdata, changed);
 
-               if (sdata->vif.type == NL80211_IFTYPE_STATION)
+               if (sdata->vif.type == NL80211_IFTYPE_STATION ||
+                   sdata->vif.type == NL80211_IFTYPE_ADHOC)
                        netif_carrier_off(dev);
                else
                        netif_carrier_on(dev);
@@ -306,8 +318,9 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
                        goto err_del_interface;
                }
 
-               /* no atomic bitop required since STA is not live yet */
-               set_sta_flag(sta, WLAN_STA_AUTHORIZED);
+               sta_info_move_state(sta, IEEE80211_STA_AUTH);
+               sta_info_move_state(sta, IEEE80211_STA_ASSOC);
+               sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
 
                res = sta_info_insert(sta);
                if (res) {
@@ -450,15 +463,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                struct ieee80211_sub_if_data *vlan, *tmpsdata;
                struct beacon_data *old_beacon =
                        rtnl_dereference(sdata->u.ap.beacon);
+               struct sk_buff *old_probe_resp =
+                       rtnl_dereference(sdata->u.ap.probe_resp);
 
                /* sdata_running will return false, so this will disable */
                ieee80211_bss_info_change_notify(sdata,
                                                 BSS_CHANGED_BEACON_ENABLED);
 
-               /* remove beacon */
+               /* remove beacon and probe response */
                RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
+               RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
                synchronize_rcu();
                kfree(old_beacon);
+               kfree_skb(old_probe_resp);
 
                /* down all dependent devices, that is VLANs */
                list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
@@ -656,7 +673,6 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_hdr *hdr;
        struct ieee80211_radiotap_header *rtap = (void *)skb->data;
-       u8 *p;
 
        if (local->hw.queues < 4)
                return 0;
@@ -667,19 +683,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
 
        hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
 
-       if (!ieee80211_is_data(hdr->frame_control)) {
-               skb->priority = 7;
-               return ieee802_1d_to_ac[skb->priority];
-       }
-       if (!ieee80211_is_data_qos(hdr->frame_control)) {
-               skb->priority = 0;
-               return ieee802_1d_to_ac[skb->priority];
-       }
-
-       p = ieee80211_get_qos_ctl(hdr);
-       skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
-
-       return ieee80211_downgrade_queue(local, skb);
+       return ieee80211_select_queue_80211(local, skb, hdr);
 }
 
 static const struct net_device_ops ieee80211_monitorif_ops = {
@@ -850,6 +854,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
        sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
        sdata->control_port_no_encrypt = false;
 
+       sdata->noack_map = 0;
+
        /* only monitor differs */
        sdata->dev->type = ARPHRD_ETHER;