[PATCH] mac80211: Implementation of SIOCSIWRATE
authorLarry Finger <Larry.Finger@lwfinger.net>
Tue, 10 Jul 2007 17:32:10 +0000 (19:32 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 12 Jul 2007 20:07:26 +0000 (16:07 -0400)
The WEXT ioctl SIOCSIWRATE is not implemented in mac80211. This patch
adds the missing routine. It supports the 'auto' keyword, fixed rates,
and the combination of 'auto' and a fixed rate to select an upper bound.

Based on the patch from Mohamed Abbas <mabbas@linux.intel.com>.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/ieee80211_ioctl.c

index 9c1d076..9bc209b 100644 (file)
@@ -863,6 +863,44 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
 }
 
 
+static int ieee80211_ioctl_siwrate(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_param *rate, char *extra)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_hw_mode *mode;
+       int i;
+       u32 target_rate = rate->value / 100000;
+       struct ieee80211_sub_if_data *sdata;
+
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       if (!sdata->bss)
+               return -ENODEV;
+       mode = local->oper_hw_mode;
+       /* 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->bss->max_ratectrl_rateidx = -1;
+       sdata->bss->force_unicast_rateidx = -1;
+       if (rate->value < 0)
+               return 0;
+       for (i=0; i< mode->num_rates; i++) {
+               struct ieee80211_rate *rates = &mode->rates[i];
+               int this_rate = rates->rate;
+
+               if (mode->mode == MODE_ATHEROS_TURBO ||
+                   mode->mode == MODE_ATHEROS_TURBOG)
+                       this_rate *= 2;
+               if (target_rate == this_rate) {
+                       sdata->bss->max_ratectrl_rateidx = i;
+                       if (rate->fixed)
+                               sdata->bss->force_unicast_rateidx = i;
+                       break;
+               }
+       }
+       return 0;
+}
+
 static int ieee80211_ioctl_giwrate(struct net_device *dev,
                                  struct iw_request_info *info,
                                  struct iw_param *rate, char *extra)
@@ -1658,7 +1696,7 @@ static const iw_handler ieee80211_handler[] =
        (iw_handler) NULL,                              /* SIOCGIWNICKN */
        (iw_handler) NULL,                              /* -- hole -- */
        (iw_handler) NULL,                              /* -- hole -- */
-       (iw_handler) NULL,                              /* SIOCSIWRATE */
+       (iw_handler) ieee80211_ioctl_siwrate,           /* SIOCSIWRATE */
        (iw_handler) ieee80211_ioctl_giwrate,           /* SIOCGIWRATE */
        (iw_handler) ieee80211_ioctl_siwrts,            /* SIOCSIWRTS */
        (iw_handler) ieee80211_ioctl_giwrts,            /* SIOCGIWRTS */