]> Pileus Git - ~andy/linux/blobdiff - net/mac80211/main.c
netdev: Kill NETIF_F_MULTI_QUEUE.
[~andy/linux] / net / mac80211 / main.c
index 863923964d2105edecc59f32683e49733bfb5d01..c74607eda1eec7e5f2e528cab87983fb4ab64a2f 100644 (file)
@@ -291,9 +291,9 @@ static int ieee80211_open(struct net_device *dev)
                if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
                        local->fif_other_bss++;
 
-               netif_tx_lock_bh(local->mdev);
+               netif_addr_lock_bh(local->mdev);
                ieee80211_configure_filter(local);
-               netif_tx_unlock_bh(local->mdev);
+               netif_addr_unlock_bh(local->mdev);
                break;
        case IEEE80211_IF_TYPE_STA:
        case IEEE80211_IF_TYPE_IBSS:
@@ -307,7 +307,8 @@ static int ieee80211_open(struct net_device *dev)
                if (res)
                        goto err_stop;
 
-               ieee80211_if_config(dev);
+               if (ieee80211_vif_is_mesh(&sdata->vif))
+                       ieee80211_start_mesh(sdata->dev);
                changed |= ieee80211_reset_erp_info(dev);
                ieee80211_bss_info_change_notify(sdata, changed);
                ieee80211_enable_keys(sdata);
@@ -489,9 +490,9 @@ static int ieee80211_stop(struct net_device *dev)
                if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
                        local->fif_other_bss--;
 
-               netif_tx_lock_bh(local->mdev);
+               netif_addr_lock_bh(local->mdev);
                ieee80211_configure_filter(local);
-               netif_tx_unlock_bh(local->mdev);
+               netif_addr_unlock_bh(local->mdev);
                break;
        case IEEE80211_IF_TYPE_MESH_POINT:
        case IEEE80211_IF_TYPE_STA:
@@ -620,7 +621,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
 
        /* ensure that TX flow won't interrupt us
         * until the end of the call to requeue function */
-       txq = &local->mdev->tx_queue;
+       txq = netdev_get_tx_queue(local->mdev, 0);
        spin_lock_bh(&txq->lock);
 
        /* create a new queue for this aggregation */
@@ -861,7 +862,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
 
        /* avoid ordering issues: we are the only one that can modify
         * the content of the qdiscs */
-       txq = &local->mdev->tx_queue;
+       txq = netdev_get_tx_queue(local->mdev, 0);
        spin_lock_bh(&txq->lock);
        /* remove the queue for this aggregation */
        ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
@@ -971,7 +972,6 @@ static const struct header_ops ieee80211_header_ops = {
        .cache_update   = eth_header_cache_update,
 };
 
-/* Must not be called for mdev */
 void ieee80211_if_setup(struct net_device *dev)
 {
        ether_setup(dev);
@@ -981,62 +981,52 @@ void ieee80211_if_setup(struct net_device *dev)
        dev->change_mtu = ieee80211_change_mtu;
        dev->open = ieee80211_open;
        dev->stop = ieee80211_stop;
-       dev->destructor = ieee80211_if_free;
+       dev->destructor = free_netdev;
 }
 
 /* everything else */
 
-static int __ieee80211_if_config(struct net_device *dev,
-                                struct sk_buff *beacon)
+int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
 {
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_conf conf;
 
-       if (!local->ops->config_interface || !netif_running(dev))
+       if (WARN_ON(!netif_running(sdata->dev)))
+               return 0;
+
+       if (!local->ops->config_interface)
                return 0;
 
        memset(&conf, 0, sizeof(conf));
-       conf.type = sdata->vif.type;
+       conf.changed = changed;
+
        if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
            sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                conf.bssid = sdata->u.sta.bssid;
                conf.ssid = sdata->u.sta.ssid;
                conf.ssid_len = sdata->u.sta.ssid_len;
-       } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
-               conf.beacon = beacon;
-               ieee80211_start_mesh(dev);
        } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
+               conf.bssid = sdata->dev->dev_addr;
                conf.ssid = sdata->u.ap.ssid;
                conf.ssid_len = sdata->u.ap.ssid_len;
-               conf.beacon = beacon;
+       } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
+               u8 zero[ETH_ALEN] = { 0 };
+               conf.bssid = zero;
+               conf.ssid = zero;
+               conf.ssid_len = 0;
+       } else {
+               WARN_ON(1);
+               return -EINVAL;
        }
-       return local->ops->config_interface(local_to_hw(local),
-                                           &sdata->vif, &conf);
-}
 
-int ieee80211_if_config(struct net_device *dev)
-{
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT &&
-           (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
-               return ieee80211_if_config_beacon(dev);
-       return __ieee80211_if_config(dev, NULL);
-}
+       if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID)))
+               return -EINVAL;
 
-int ieee80211_if_config_beacon(struct net_device *dev)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       struct sk_buff *skb;
+       if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID)))
+               return -EINVAL;
 
-       if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
-               return 0;
-       skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif);
-       if (!skb)
-               return -ENOMEM;
-       return __ieee80211_if_config(dev, skb);
+       return local->ops->config_interface(local_to_hw(local),
+                                           &sdata->vif, &conf);
 }
 
 int ieee80211_hw_config(struct ieee80211_local *local)
@@ -1688,9 +1678,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        if (!mdev)
                goto fail_mdev_alloc;
 
-       if (ieee80211_num_queues(hw) > 1)
-               mdev->features |= NETIF_F_MULTI_QUEUE;
-
        mwdev = netdev_priv(mdev);
        mdev->ieee80211_ptr = mwdev;
        mwdev->wiphy = local->hw.wiphy;
@@ -1776,7 +1763,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
                printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
                       wiphy_name(local->hw.wiphy));
 
-       local->reg_state = IEEE80211_DEV_REGISTERED;
        rtnl_unlock();
 
        ieee80211_led_init(local);
@@ -1806,30 +1792,20 @@ EXPORT_SYMBOL(ieee80211_register_hw);
 void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 {
        struct ieee80211_local *local = hw_to_local(hw);
-       struct ieee80211_sub_if_data *sdata, *tmp;
 
        tasklet_kill(&local->tx_pending_tasklet);
        tasklet_kill(&local->tasklet);
 
        rtnl_lock();
 
-       BUG_ON(local->reg_state != IEEE80211_DEV_REGISTERED);
-
-       local->reg_state = IEEE80211_DEV_UNREGISTERED;
-
        /*
         * At this point, interface list manipulations are fine
         * because the driver cannot be handing us frames any
         * more and the tasklet is killed.
         */
 
-       /*
-        * First, we remove all virtual interfaces.
-        */
-       list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
-               list_del(&sdata->list);
-               __ieee80211_if_del(local, sdata);
-       }
+       /* First, we remove all virtual interfaces. */
+       ieee80211_remove_interfaces(local);
 
        /* then, finally, remove the master interface */
        unregister_netdevice(local->mdev);