diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 9c1d076b1944..9bc209b72d41 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c @@ -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 */