|
@@ -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 u8 *supp_rates,
|
|
|
|
|
|
+ const u32 basic_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,
|
|
|
|
|
|
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,
|
|
*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,
|
|
*pos++ = 0;
|
|
*pos++ = 0;
|
|
*pos++ = 0;
|
|
*pos++ = 0;
|
|
|
|
|
|
- if (supp_rates_len > 8) {
|
|
|
|
- rates = supp_rates_len - 8;
|
|
|
|
|
|
+ if (sband->n_bitrates > 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,
|
|
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;
|
|
|
|
- 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);
|
|
|
|
|
|
+ ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, 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,
|
|
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)
|
|
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)
|
|
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,
|
|
|
|
- supp_rates, capability, 0);
|
|
|
|
|
|
+ ifibss->channel, 3, /* first two are basic */
|
|
|
|
+ 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)
|