Revert "mac80211: fix rates setup on IBSS merge"
[safe/jmp/linux-2.6] / net / mac80211 / cfg.c
index 8c35418..b7116ef 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * mac80211 configuration hooks for cfg80211
  *
- * Copyright 2006, 2007        Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
  *
  * This file is GPLv2 as found in COPYING.
  */
@@ -78,17 +78,15 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
                                  enum nl80211_iftype type, u32 *flags,
                                  struct vif_params *params)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        int ret;
 
-       if (netif_running(dev))
+       if (ieee80211_sdata_running(sdata))
                return -EBUSY;
 
        if (!nl80211_params_check(type, params))
                return -EINVAL;
 
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
        ret = ieee80211_if_change_type(sdata, type);
        if (ret)
                return ret;
@@ -150,7 +148,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
        rcu_read_lock();
 
        if (mac_addr) {
-               sta = sta_info_get(sdata, mac_addr);
+               sta = sta_info_get_bss(sdata, mac_addr);
                if (!sta) {
                        ieee80211_key_free(key);
                        err = -ENOENT;
@@ -181,7 +179,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
        if (mac_addr) {
                ret = -ENOENT;
 
-               sta = sta_info_get(sdata, mac_addr);
+               sta = sta_info_get_bss(sdata, mac_addr);
                if (!sta)
                        goto out_unlock;
 
@@ -228,7 +226,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
        rcu_read_lock();
 
        if (mac_addr) {
-               sta = sta_info_get(sdata, mac_addr);
+               sta = sta_info_get_bss(sdata, mac_addr);
                if (!sta)
                        goto out;
 
@@ -354,7 +352,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
        sinfo->rx_packets = sta->rx_packets;
        sinfo->tx_packets = sta->tx_packets;
 
-       if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
+       if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
+           (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
                sinfo->filled |= STATION_INFO_SIGNAL;
                sinfo->signal = (s8)sta->last_signal;
        }
@@ -420,7 +419,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
 
        rcu_read_lock();
 
-       sta = sta_info_get(sdata, mac);
+       sta = sta_info_get_bss(sdata, mac);
        if (sta) {
                ret = 0;
                sta_set_sinfo(sta, sinfo);
@@ -516,6 +515,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
                if (old)
                        memcpy(new->tail, old->tail, new_tail_len);
 
+       sdata->vif.bss_conf.dtim_period = new->dtim_period;
+
        rcu_assign_pointer(sdata->u.ap.beacon, new);
 
        synchronize_rcu();
@@ -748,9 +749,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
                sdata->vif.type == NL80211_IFTYPE_AP;
 
-       rcu_read_lock();
-
-       err = sta_info_insert(sta);
+       err = sta_info_insert_rcu(sta);
        if (err) {
                rcu_read_unlock();
                return err;
@@ -769,26 +768,13 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
 {
        struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
-       struct sta_info *sta;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       if (mac) {
-               rcu_read_lock();
-
-               sta = sta_info_get(sdata, mac);
-               if (!sta) {
-                       rcu_read_unlock();
-                       return -ENOENT;
-               }
-
-               sta_info_unlink(&sta);
-               rcu_read_unlock();
-
-               sta_info_destroy(sta);
-       } else
-               sta_info_flush(local, sdata);
+       if (mac)
+               return sta_info_destroy_addr_bss(sdata, mac);
 
+       sta_info_flush(local, sdata);
        return 0;
 }
 
@@ -804,7 +790,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 
        rcu_read_lock();
 
-       sta = sta_info_get(sdata, mac);
+       sta = sta_info_get_bss(sdata, mac);
        if (!sta) {
                rcu_read_unlock();
                return -ENOENT;
@@ -1086,6 +1072,13 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
                        params->use_short_preamble;
                changed |= BSS_CHANGED_ERP_PREAMBLE;
        }
+
+       if (!sdata->vif.bss_conf.use_short_slot &&
+           sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
+               sdata->vif.bss_conf.use_short_slot = true;
+               changed |= BSS_CHANGED_ERP_SLOT;
+       }
+
        if (params->use_short_slot_time >= 0) {
                sdata->vif.bss_conf.use_short_slot =
                        params->use_short_slot_time;
@@ -1129,6 +1122,13 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
        p.cw_max = params->cwmax;
        p.cw_min = params->cwmin;
        p.txop = params->txop;
+
+       /*
+        * Setting tx queue params disables u-apsd because it's only
+        * called in master mode.
+        */
+       p.uapsd = false;
+
        if (drv_conf_tx(local, params->queue, &p)) {
                printk(KERN_DEBUG "%s: failed to set TX queue "
                       "parameters for queue %d\n",
@@ -1231,6 +1231,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
        struct ieee80211_local *local = wiphy_priv(wiphy);
        int err;
 
+       if (changed & WIPHY_PARAM_COVERAGE_CLASS) {
+               err = drv_set_coverage_class(local, wiphy->coverage_class);
+
+               if (err)
+                       return err;
+       }
+
        if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
                err = drv_set_rts_threshold(local, wiphy->rts_threshold);
 
@@ -1344,7 +1351,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
                return 0;
        }
 
-       ap = sdata->u.mgd.associated->cbss.bssid;
+       ap = sdata->u.mgd.associated->bssid;
 
        if (smps_mode == IEEE80211_SMPS_AUTOMATIC) {
                if (sdata->u.mgd.powersave)
@@ -1369,6 +1376,9 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_conf *conf = &local->hw.conf;
 
+       if (sdata->vif.type != NL80211_IFTYPE_STATION)
+               return -EOPNOTSUPP;
+
        if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
                return -EOPNOTSUPP;
 
@@ -1399,39 +1409,52 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       int i, err = -EINVAL;
-       u32 target_rate;
-       struct ieee80211_supported_band *sband;
+       int i;
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+       /*
+        * This _could_ be supported by providing a hook for
+        * drivers for this function, but at this point it
+        * doesn't seem worth bothering.
+        */
+       if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
+               return -EOPNOTSUPP;
 
-       /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
-        * target_rate = X, rate->fixed = 1 means only rate X
-        * target_rate = X, rate->fixed = 0 means all rates <= X */
-       sdata->max_ratectrl_rateidx = -1;
-       sdata->force_unicast_rateidx = -1;
 
-       if (mask->fixed)
-               target_rate = mask->fixed / 100;
-       else if (mask->maxrate)
-               target_rate = mask->maxrate / 100;
-       else
-               return 0;
+       for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+               sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
 
-       for (i=0; i< sband->n_bitrates; i++) {
-               struct ieee80211_rate *brate = &sband->bitrates[i];
-               int this_rate = brate->bitrate;
+       return 0;
+}
 
-               if (target_rate == this_rate) {
-                       sdata->max_ratectrl_rateidx = i;
-                       if (mask->fixed)
-                               sdata->force_unicast_rateidx = i;
-                       err = 0;
-                       break;
-               }
-       }
+static int ieee80211_remain_on_channel(struct wiphy *wiphy,
+                                      struct net_device *dev,
+                                      struct ieee80211_channel *chan,
+                                      enum nl80211_channel_type channel_type,
+                                      unsigned int duration,
+                                      u64 *cookie)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       return err;
+       return ieee80211_wk_remain_on_channel(sdata, chan, channel_type,
+                                             duration, cookie);
+}
+
+static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
+                                             struct net_device *dev,
+                                             u64 cookie)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);
+}
+
+static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev,
+                           struct ieee80211_channel *chan,
+                           enum nl80211_channel_type channel_type,
+                           const u8 *buf, size_t len, u64 *cookie)
+{
+       return ieee80211_mgd_action(IEEE80211_DEV_TO_SUB_IF(dev), chan,
+                                   channel_type, buf, len, cookie);
 }
 
 struct cfg80211_ops mac80211_config_ops = {
@@ -1480,4 +1503,7 @@ struct cfg80211_ops mac80211_config_ops = {
        CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
        .set_power_mgmt = ieee80211_set_power_mgmt,
        .set_bitrate_mask = ieee80211_set_bitrate_mask,
+       .remain_on_channel = ieee80211_remain_on_channel,
+       .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
+       .action = ieee80211_action,
 };