]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/wireless/nl80211.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[mv-sheeva.git] / net / wireless / nl80211.c
index 3a7b8a2f2d5aafbd2e2ca4305566dd7c87672e22..6b41d15c4a05b354b1e571e6132a4e6c3904bc3f 100644 (file)
@@ -3955,6 +3955,55 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
                }
        }
 
+       if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
+               u8 *rates =
+                       nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
+               int n_rates =
+                       nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
+               struct ieee80211_supported_band *sband =
+                       wiphy->bands[ibss.channel->band];
+               int i, j;
+
+               if (n_rates == 0) {
+                       err = -EINVAL;
+                       goto out;
+               }
+
+               for (i = 0; i < n_rates; i++) {
+                       int rate = (rates[i] & 0x7f) * 5;
+                       bool found = false;
+
+                       for (j = 0; j < sband->n_bitrates; j++) {
+                               if (sband->bitrates[j].bitrate == rate) {
+                                       found = true;
+                                       ibss.basic_rates |= BIT(j);
+                                       break;
+                               }
+                       }
+                       if (!found) {
+                               err = -EINVAL;
+                               goto out;
+                       }
+               }
+       } else {
+               /*
+               * If no rates were explicitly configured,
+               * use the mandatory rate set for 11b or
+               * 11a for maximum compatibility.
+               */
+               struct ieee80211_supported_band *sband =
+                       wiphy->bands[ibss.channel->band];
+               int j;
+               u32 flag = ibss.channel->band == IEEE80211_BAND_5GHZ ?
+                       IEEE80211_RATE_MANDATORY_A :
+                       IEEE80211_RATE_MANDATORY_B;
+
+               for (j = 0; j < sband->n_bitrates; j++) {
+                       if (sband->bitrates[j].flags & flag)
+                               ibss.basic_rates |= BIT(j);
+               }
+       }
+
        err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
 
 out:
@@ -4653,7 +4702,8 @@ static int nl80211_register_action(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto unlock_rtnl;
 
-       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
                err = -EOPNOTSUPP;
                goto out;
        }
@@ -4703,7 +4753,8 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
                err = -EOPNOTSUPP;
                goto out;
        }