cfg80211: pass netdev to change_virtual_intf
[pandora-kernel.git] / net / mac80211 / cfg.c
index 77e9ff5..eb93eb6 100644 (file)
@@ -74,19 +74,14 @@ static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
        return 0;
 }
 
-static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
+static int ieee80211_change_iface(struct wiphy *wiphy,
+                                 struct net_device *dev,
                                  enum nl80211_iftype type, u32 *flags,
                                  struct vif_params *params)
 {
-       struct net_device *dev;
        struct ieee80211_sub_if_data *sdata;
        int ret;
 
-       /* we're under RTNL */
-       dev = __dev_get_by_index(&init_net, ifindex);
-       if (!dev)
-               return -ENODEV;
-
        if (!nl80211_type_check(type))
                return -EINVAL;
 
@@ -663,6 +658,13 @@ static void sta_apply_parameters(struct ieee80211_local *local,
        }
        spin_unlock_bh(&sta->lock);
 
+       /*
+        * cfg80211 validates this (1-2007) and allows setting the AID
+        * only when creating a new station entry
+        */
+       if (params->aid)
+               sta->sta.aid = params->aid;
+
        /*
         * FIXME: updating the following information is racy when this
         *        function is called from ieee80211_change_station().
@@ -670,12 +672,6 @@ static void sta_apply_parameters(struct ieee80211_local *local,
         *        maybe we should just reject attemps to change it.
         */
 
-       if (params->aid) {
-               sta->sta.aid = params->aid;
-               if (sta->sta.aid > IEEE80211_MAX_AID)
-                       sta->sta.aid = 0; /* XXX: should this be an error? */
-       }
-
        if (params->listen_interval >= 0)
                sta->listen_interval = params->listen_interval;
 
@@ -1121,8 +1117,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
        p.txop = params->txop;
        if (drv_conf_tx(local, params->queue, &p)) {
                printk(KERN_DEBUG "%s: failed to set TX queue "
-                      "parameters for queue %d\n", local->mdev->name,
-                      params->queue);
+                      "parameters for queue %d\n",
+                      wiphy_name(local->hw.wiphy), params->queue);
                return -EINVAL;
        }
 
@@ -1255,7 +1251,7 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
                sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
 
        ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
-       if (ret)
+       if (ret && ret != -EALREADY)
                return ret;
 
        if (req->use_mfp) {
@@ -1333,6 +1329,53 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
        return 0;
 }
 
+static int ieee80211_set_tx_power(struct wiphy *wiphy,
+                                 enum tx_power_setting type, int dbm)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+       struct ieee80211_channel *chan = local->hw.conf.channel;
+       u32 changes = 0;
+
+       switch (type) {
+       case TX_POWER_AUTOMATIC:
+               local->user_power_level = -1;
+               break;
+       case TX_POWER_LIMITED:
+               if (dbm < 0)
+                       return -EINVAL;
+               local->user_power_level = dbm;
+               break;
+       case TX_POWER_FIXED:
+               if (dbm < 0)
+                       return -EINVAL;
+               /* TODO: move to cfg80211 when it knows the channel */
+               if (dbm > chan->max_power)
+                       return -EINVAL;
+               local->user_power_level = dbm;
+               break;
+       }
+
+       ieee80211_hw_config(local, changes);
+
+       return 0;
+}
+
+static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+
+       *dbm = local->hw.conf.power_level;
+
+       return 0;
+}
+
+static void ieee80211_rfkill_poll(struct wiphy *wiphy)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+
+       drv_rfkill_poll(local);
+}
+
 struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
@@ -1372,4 +1415,7 @@ struct cfg80211_ops mac80211_config_ops = {
        .join_ibss = ieee80211_join_ibss,
        .leave_ibss = ieee80211_leave_ibss,
        .set_wiphy_params = ieee80211_set_wiphy_params,
+       .set_tx_power = ieee80211_set_tx_power,
+       .get_tx_power = ieee80211_get_tx_power,
+       .rfkill_poll = ieee80211_rfkill_poll,
 };