mac80211: convert to cfg80211 IBSS API
[safe/jmp/linux-2.6] / net / mac80211 / iface.c
index e822118..5242597 100644 (file)
@@ -235,8 +235,7 @@ static int ieee80211_open(struct net_device *dev)
                netif_addr_unlock_bh(local->mdev);
                break;
        case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_ADHOC:
-               sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
+               sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
                /* fall through */
        default:
                conf.vif = &sdata->vif;
@@ -258,8 +257,7 @@ static int ieee80211_open(struct net_device *dev)
                ieee80211_bss_info_change_notify(sdata, changed);
                ieee80211_enable_keys(sdata);
 
-               if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-                   !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
+               if (sdata->vif.type == NL80211_IFTYPE_STATION)
                        netif_carrier_off(dev);
                else
                        netif_carrier_on(dev);
@@ -315,17 +313,16 @@ static int ieee80211_open(struct net_device *dev)
                ieee80211_set_wmm_default(sdata);
        }
 
+       ieee80211_recalc_ps(local, -1);
+
        /*
         * ieee80211_sta_work is disabled while network interface
         * is down. Therefore, some configuration changes may not
         * yet be effective. Trigger execution of ieee80211_sta_work
         * to fix this.
         */
-       if (sdata->vif.type == NL80211_IFTYPE_STATION ||
-           sdata->vif.type == NL80211_IFTYPE_ADHOC) {
-               struct ieee80211_if_sta *ifsta = &sdata->u.sta;
-               queue_work(local->hw.workqueue, &ifsta->work);
-       }
+       if (sdata->vif.type == NL80211_IFTYPE_STATION)
+               queue_work(local->hw.workqueue, &sdata->u.mgd.work);
 
        netif_tx_start_all_queues(dev);
 
@@ -368,6 +365,18 @@ static int ieee80211_stop(struct net_device *dev)
        rcu_read_unlock();
 
        /*
+        * Announce that we are leaving the network, in case we are a
+        * station interface type. This must be done before removing
+        * all stations associated with sta_info_flush, otherwise STA
+        * information will be gone and no announce being done.
+        */
+       if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+               if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED)
+                       ieee80211_sta_deauthenticate(sdata,
+                               WLAN_REASON_DEAUTH_LEAVING);
+       }
+
+       /*
         * Remove all stations associated with this interface.
         *
         * This must be done before calling ops->remove_interface()
@@ -452,15 +461,9 @@ static int ieee80211_stop(struct net_device *dev)
                netif_addr_unlock_bh(local->mdev);
                break;
        case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_ADHOC:
-               /* Announce that we are leaving the network. */
-               if (sdata->u.sta.state != IEEE80211_STA_MLME_DISABLED)
-                       ieee80211_sta_deauthenticate(sdata,
-                                               WLAN_REASON_DEAUTH_LEAVING);
-
-               memset(sdata->u.sta.bssid, 0, ETH_ALEN);
-               del_timer_sync(&sdata->u.sta.chswitch_timer);
-               del_timer_sync(&sdata->u.sta.timer);
+               memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
+               del_timer_sync(&sdata->u.mgd.chswitch_timer);
+               del_timer_sync(&sdata->u.mgd.timer);
                /*
                 * If the timer fired while we waited for it, it will have
                 * requeued the work. Now the work will be running again
@@ -468,8 +471,11 @@ static int ieee80211_stop(struct net_device *dev)
                 * whether the interface is running, which, at this point,
                 * it no longer is.
                 */
-               cancel_work_sync(&sdata->u.sta.work);
-               cancel_work_sync(&sdata->u.sta.chswitch_work);
+               cancel_work_sync(&sdata->u.mgd.work);
+               cancel_work_sync(&sdata->u.mgd.chswitch_work);
+
+               cancel_work_sync(&sdata->u.mgd.beacon_loss_work);
+
                /*
                 * When we get here, the interface is marked down.
                 * Call synchronize_rcu() to wait for the RX path
@@ -477,13 +483,21 @@ static int ieee80211_stop(struct net_device *dev)
                 * frames at this very time on another CPU.
                 */
                synchronize_rcu();
-               skb_queue_purge(&sdata->u.sta.skb_queue);
+               skb_queue_purge(&sdata->u.mgd.skb_queue);
 
-               sdata->u.sta.flags &= ~(IEEE80211_STA_PRIVACY_INVOKED |
+               sdata->u.mgd.flags &= ~(IEEE80211_STA_PRIVACY_INVOKED |
                                        IEEE80211_STA_TKIP_WEP_USED);
-               kfree(sdata->u.sta.extra_ie);
-               sdata->u.sta.extra_ie = NULL;
-               sdata->u.sta.extra_ie_len = 0;
+               kfree(sdata->u.mgd.extra_ie);
+               sdata->u.mgd.extra_ie = NULL;
+               sdata->u.mgd.extra_ie_len = 0;
+               /* fall through */
+       case NL80211_IFTYPE_ADHOC:
+               if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+                       del_timer_sync(&sdata->u.ibss.timer);
+                       cancel_work_sync(&sdata->u.ibss.work);
+                       synchronize_rcu();
+                       skb_queue_purge(&sdata->u.ibss.skb_queue);
+               }
                /* fall through */
        case NL80211_IFTYPE_MESH_POINT:
                if (ieee80211_vif_is_mesh(&sdata->vif)) {
@@ -553,6 +567,8 @@ static int ieee80211_stop(struct net_device *dev)
                hw_reconf_flags = 0;
        }
 
+       ieee80211_recalc_ps(local, -1);
+
        /* do after stop to avoid reconfiguring when we stop anyway */
        if (hw_reconf_flags)
                ieee80211_hw_config(local, hw_reconf_flags);
@@ -629,19 +645,15 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
                if (ieee80211_vif_is_mesh(&sdata->vif))
                        mesh_rmc_free(sdata);
                break;
-       case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_ADHOC:
-               kfree(sdata->u.sta.extra_ie);
-               kfree(sdata->u.sta.assocreq_ies);
-               kfree(sdata->u.sta.assocresp_ies);
-               kfree_skb(sdata->u.sta.probe_resp);
-               kfree(sdata->u.sta.ie_probereq);
-               kfree(sdata->u.sta.ie_proberesp);
-               kfree(sdata->u.sta.ie_auth);
-               kfree(sdata->u.sta.ie_assocreq);
-               kfree(sdata->u.sta.ie_reassocreq);
-               kfree(sdata->u.sta.ie_deauth);
-               kfree(sdata->u.sta.ie_disassoc);
+               if (WARN_ON(sdata->u.ibss.presp))
+                       kfree_skb(sdata->u.ibss.presp);
+               break;
+       case NL80211_IFTYPE_STATION:
+               kfree(sdata->u.mgd.extra_ie);
+               kfree(sdata->u.mgd.assocreq_ies);
+               kfree(sdata->u.mgd.assocresp_ies);
+               kfree(sdata->u.mgd.sme_auth_ie);
                break;
        case NL80211_IFTYPE_WDS:
        case NL80211_IFTYPE_AP_VLAN:
@@ -708,9 +720,11 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
                INIT_LIST_HEAD(&sdata->u.ap.vlans);
                break;
        case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_ADHOC:
                ieee80211_sta_setup_sdata(sdata);
                break;
+       case NL80211_IFTYPE_ADHOC:
+               ieee80211_ibss_setup_sdata(sdata);
+               break;
        case NL80211_IFTYPE_MESH_POINT:
                if (ieee80211_vif_is_mesh(&sdata->vif))
                        ieee80211_mesh_init_sdata(sdata);