[MAC80211]: Add support for setting TX power and radio status
authorMichael Buesch <mb@bu3sch.de>
Thu, 20 Sep 2007 20:06:39 +0000 (22:06 +0200)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:52:23 +0000 (16:52 -0700)
This adds support for disabling the radio and setting the TXpower
through wext.
This also fixes the prism TXpower ioctl (It always overwrote the TXpower
value in ieee80211_hw_config())

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mac80211/ieee80211.c
net/mac80211/ieee80211_ioctl.c

index 4229d15..2385333 100644 (file)
@@ -704,7 +704,12 @@ int ieee80211_hw_config(struct ieee80211_local *local)
 
        local->hw.conf.channel = chan->chan;
        local->hw.conf.channel_val = chan->val;
-       local->hw.conf.power_level = chan->power_level;
+       if (!local->hw.conf.power_level) {
+               local->hw.conf.power_level = chan->power_level;
+       } else {
+               local->hw.conf.power_level = min(chan->power_level,
+                                                local->hw.conf.power_level);
+       }
        local->hw.conf.freq = chan->freq;
        local->hw.conf.phymode = mode->mode;
        local->hw.conf.antenna_max = chan->antenna_max;
index 6ccdde8..b4cce44 100644 (file)
@@ -666,6 +666,38 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
        return 0;
 }
 
+static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
+                                     struct iw_request_info *info,
+                                     union iwreq_data *data, char *extra)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       bool need_reconfig = 0;
+
+       if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
+               return -EINVAL;
+       if (data->txpower.flags & IW_TXPOW_RANGE)
+               return -EINVAL;
+       if (!data->txpower.fixed)
+               return -EINVAL;
+
+       if (local->hw.conf.power_level != data->txpower.value) {
+               local->hw.conf.power_level = data->txpower.value;
+               need_reconfig = 1;
+       }
+       if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
+               local->hw.conf.radio_enabled = !(data->txpower.disabled);
+               need_reconfig = 1;
+       }
+       if (need_reconfig) {
+               ieee80211_hw_config(local);
+               /* The return value of hw_config is not of big interest here,
+                * as it doesn't say that it failed because of _this_ config
+                * change or something else. Ignore it. */
+       }
+
+       return 0;
+}
+
 static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
                                   struct iw_request_info *info,
                                   union iwreq_data *data, char *extra)
@@ -1339,7 +1371,7 @@ static const iw_handler ieee80211_handler[] =
        (iw_handler) ieee80211_ioctl_giwrts,            /* SIOCGIWRTS */
        (iw_handler) ieee80211_ioctl_siwfrag,           /* SIOCSIWFRAG */
        (iw_handler) ieee80211_ioctl_giwfrag,           /* SIOCGIWFRAG */
-       (iw_handler) NULL,                              /* SIOCSIWTXPOW */
+       (iw_handler) ieee80211_ioctl_siwtxpower,        /* SIOCSIWTXPOW */
        (iw_handler) ieee80211_ioctl_giwtxpower,        /* SIOCGIWTXPOW */
        (iw_handler) ieee80211_ioctl_siwretry,          /* SIOCSIWRETRY */
        (iw_handler) ieee80211_ioctl_giwretry,          /* SIOCGIWRETRY */