diff options
author | Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com> | 2010-06-14 05:55:31 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-06-14 15:39:34 -0400 |
commit | fbd2c8dcbc69616d2e15b8a269a86b3a05d45aea (patch) | |
tree | 4ae08bd02d5e0d317828300f3255824df732e4b3 /net | |
parent | 7b9a4b001971c89f35d55180867753a612d17458 (diff) |
mac80211: Set basic rates while joining ibss network
This patch adds support to nl80211 and mac80211 to set basic rates when
joining/creating ibss network.
Original patch was posted by Johannes Berg on the linux-wireless posting list.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ibss.c | 4 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 49 |
3 files changed, 54 insertions, 1 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index bfd7286488c7..9f4e64ed8b83 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -172,6 +172,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
172 | rcu_assign_pointer(ifibss->presp, skb); | 172 | rcu_assign_pointer(ifibss->presp, skb); |
173 | 173 | ||
174 | sdata->vif.bss_conf.beacon_int = beacon_int; | 174 | sdata->vif.bss_conf.beacon_int = beacon_int; |
175 | sdata->vif.bss_conf.basic_rates = basic_rates; | ||
175 | bss_change = BSS_CHANGED_BEACON_INT; | 176 | bss_change = BSS_CHANGED_BEACON_INT; |
176 | bss_change |= ieee80211_reset_erp_info(sdata); | 177 | bss_change |= ieee80211_reset_erp_info(sdata); |
177 | bss_change |= BSS_CHANGED_BSSID; | 178 | bss_change |= BSS_CHANGED_BSSID; |
@@ -529,7 +530,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
529 | sdata->drop_unencrypted = 0; | 530 | sdata->drop_unencrypted = 0; |
530 | 531 | ||
531 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, | 532 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, |
532 | ifibss->channel, 3, /* first two are basic */ | 533 | ifibss->channel, ifibss->basic_rates, |
533 | capability, 0); | 534 | capability, 0); |
534 | } | 535 | } |
535 | 536 | ||
@@ -859,6 +860,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
859 | sdata->u.ibss.fixed_bssid = false; | 860 | sdata->u.ibss.fixed_bssid = false; |
860 | 861 | ||
861 | sdata->u.ibss.privacy = params->privacy; | 862 | sdata->u.ibss.privacy = params->privacy; |
863 | sdata->u.ibss.basic_rates = params->basic_rates; | ||
862 | 864 | ||
863 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; | 865 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; |
864 | 866 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9d753a02a2e4..c3c2be3f8a2c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -387,6 +387,8 @@ struct ieee80211_if_ibss { | |||
387 | unsigned long request; | 387 | unsigned long request; |
388 | unsigned long last_scan_completed; | 388 | unsigned long last_scan_completed; |
389 | 389 | ||
390 | u32 basic_rates; | ||
391 | |||
390 | bool timer_running; | 392 | bool timer_running; |
391 | 393 | ||
392 | bool fixed_bssid; | 394 | bool fixed_bssid; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c65e67e9231c..41529aca794c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3955,6 +3955,55 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
3955 | } | 3955 | } |
3956 | } | 3956 | } |
3957 | 3957 | ||
3958 | if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { | ||
3959 | u8 *rates = | ||
3960 | nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | ||
3961 | int n_rates = | ||
3962 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | ||
3963 | struct ieee80211_supported_band *sband = | ||
3964 | wiphy->bands[ibss.channel->band]; | ||
3965 | int i, j; | ||
3966 | |||
3967 | if (n_rates == 0) { | ||
3968 | err = -EINVAL; | ||
3969 | goto out; | ||
3970 | } | ||
3971 | |||
3972 | for (i = 0; i < n_rates; i++) { | ||
3973 | int rate = (rates[i] & 0x7f) * 5; | ||
3974 | bool found = false; | ||
3975 | |||
3976 | for (j = 0; j < sband->n_bitrates; j++) { | ||
3977 | if (sband->bitrates[j].bitrate == rate) { | ||
3978 | found = true; | ||
3979 | ibss.basic_rates |= BIT(j); | ||
3980 | break; | ||
3981 | } | ||
3982 | } | ||
3983 | if (!found) { | ||
3984 | err = -EINVAL; | ||
3985 | goto out; | ||
3986 | } | ||
3987 | } | ||
3988 | } else { | ||
3989 | /* | ||
3990 | * If no rates were explicitly configured, | ||
3991 | * use the mandatory rate set for 11b or | ||
3992 | * 11a for maximum compatibility. | ||
3993 | */ | ||
3994 | struct ieee80211_supported_band *sband = | ||
3995 | wiphy->bands[ibss.channel->band]; | ||
3996 | int j; | ||
3997 | u32 flag = ibss.channel->band == IEEE80211_BAND_5GHZ ? | ||
3998 | IEEE80211_RATE_MANDATORY_A : | ||
3999 | IEEE80211_RATE_MANDATORY_B; | ||
4000 | |||
4001 | for (j = 0; j < sband->n_bitrates; j++) { | ||
4002 | if (sband->bitrates[j].flags & flag) | ||
4003 | ibss.basic_rates |= BIT(j); | ||
4004 | } | ||
4005 | } | ||
4006 | |||
3958 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); | 4007 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); |
3959 | 4008 | ||
3960 | out: | 4009 | out: |