提交 b59066a2 编写于 作者: J Johannes Berg 提交者: John W. Linville

mac80211: IBSS supported rate fixes

Currently mac80211 announces a rate set with no basic rates,
this fixes it to use 1/2 or 6/9 Mbit as basic rates by default.
Additionally, mac80211 will currently adopt the peer's entire
rate set, rather than just the basic rate set; fix that too.
Signed-off-by: NJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 e0d61887
...@@ -63,19 +63,18 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -63,19 +63,18 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
const u8 *bssid, const int beacon_int, const u8 *bssid, const int beacon_int,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
const size_t supp_rates_len, const u32 basic_rates,
const u8 *supp_rates,
const u16 capability, u64 tsf) const u16 capability, u64 tsf)
{ {
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
int rates, i, j; int rates, i;
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_mgmt *mgmt; struct ieee80211_mgmt *mgmt;
u8 *pos; u8 *pos;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
u32 bss_change; u32 bss_change;
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
/* Reset own TSF to allow time synchronization work. */ /* Reset own TSF to allow time synchronization work. */
drv_reset_tsf(local); drv_reset_tsf(local);
...@@ -101,6 +100,16 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -101,6 +100,16 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
sband = local->hw.wiphy->bands[chan->band]; sband = local->hw.wiphy->bands[chan->band];
/* build supported rates array */
pos = supp_rates;
for (i = 0; i < sband->n_bitrates; i++) {
int rate = sband->bitrates[i].bitrate;
u8 basic = 0;
if (basic_rates & BIT(i))
basic = 0x80;
*pos++ = basic | (u8) (rate / 5);
}
/* Build IBSS probe response */ /* Build IBSS probe response */
mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon)); mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
...@@ -118,7 +127,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -118,7 +127,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
*pos++ = ifibss->ssid_len; *pos++ = ifibss->ssid_len;
memcpy(pos, ifibss->ssid, ifibss->ssid_len); memcpy(pos, ifibss->ssid, ifibss->ssid_len);
rates = supp_rates_len; rates = sband->n_bitrates;
if (rates > 8) if (rates > 8)
rates = 8; rates = 8;
pos = skb_put(skb, 2 + rates); pos = skb_put(skb, 2 + rates);
...@@ -140,8 +149,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -140,8 +149,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
*pos++ = 0; *pos++ = 0;
*pos++ = 0; *pos++ = 0;
if (supp_rates_len > 8) { if (sband->n_bitrates > 8) {
rates = supp_rates_len - 8; rates = sband->n_bitrates - 8;
pos = skb_put(skb, 2 + rates); pos = skb_put(skb, 2 + rates);
*pos++ = WLAN_EID_EXT_SUPP_RATES; *pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos++ = rates; *pos++ = rates;
...@@ -162,15 +171,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -162,15 +171,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
bss_change |= BSS_CHANGED_BEACON_ENABLED; bss_change |= BSS_CHANGED_BEACON_ENABLED;
ieee80211_bss_info_change_notify(sdata, bss_change); ieee80211_bss_info_change_notify(sdata, bss_change);
rates = 0; ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
for (i = 0; i < supp_rates_len; i++) {
int bitrate = (supp_rates[i] & 0x7f) * 5;
for (j = 0; j < sband->n_bitrates; j++)
if (sband->bitrates[j].bitrate == bitrate)
rates |= BIT(j);
}
ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
ifibss->state = IEEE80211_IBSS_MLME_JOINED; ifibss->state = IEEE80211_IBSS_MLME_JOINED;
mod_timer(&ifibss->timer, mod_timer(&ifibss->timer,
...@@ -184,15 +185,35 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -184,15 +185,35 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
struct ieee80211_bss *bss) struct ieee80211_bss *bss)
{ {
struct ieee80211_supported_band *sband;
u32 basic_rates;
int i, j;
u16 beacon_int = bss->cbss.beacon_interval; u16 beacon_int = bss->cbss.beacon_interval;
if (beacon_int < 10) if (beacon_int < 10)
beacon_int = 10; beacon_int = 10;
sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band];
basic_rates = 0;
for (i = 0; i < bss->supp_rates_len; i++) {
int rate = (bss->supp_rates[i] & 0x7f) * 5;
bool is_basic = !!(bss->supp_rates[i] & 0x80);
for (j = 0; j < sband->n_bitrates; j++) {
if (sband->bitrates[j].bitrate == rate) {
if (is_basic)
basic_rates |= BIT(j);
break;
}
}
}
__ieee80211_sta_join_ibss(sdata, bss->cbss.bssid, __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
beacon_int, beacon_int,
bss->cbss.channel, bss->cbss.channel,
bss->supp_rates_len, bss->supp_rates, basic_rates,
bss->cbss.capability, bss->cbss.capability,
bss->cbss.tsf); bss->cbss.tsf);
} }
...@@ -449,9 +470,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) ...@@ -449,9 +470,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
u8 *pos;
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
u16 capability; u16 capability;
int i; int i;
...@@ -480,15 +499,9 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) ...@@ -480,15 +499,9 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
else else
sdata->drop_unencrypted = 0; sdata->drop_unencrypted = 0;
pos = supp_rates;
for (i = 0; i < sband->n_bitrates; i++) {
int rate = sband->bitrates[i].bitrate;
*pos++ = (u8) (rate / 5);
}
__ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
ifibss->channel, sband->n_bitrates, ifibss->channel, 3, /* first two are basic */
supp_rates, capability, 0); capability, 0);
} }
static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册