Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 89915
b: refs/heads/master
c: a607268
h: refs/heads/master
i:
  89913: 0b63399
  89911: 62c2063
v: v3
  • Loading branch information
Bruno Randolf authored and John W. Linville committed Feb 29, 2008
1 parent d3bbadf commit ac7b6b5
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 159 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c132bec33c2eb5e46d8e4b80cfa5a9656d8e57e7
refs/heads/master: a607268a0d5532d6ae3777ddd0339ff7d8b037a0
317 changes: 159 additions & 158 deletions trunk/net/mac80211/ieee80211_sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,165 @@ void ieee80211_rx_bss_list_deinit(struct net_device *dev)
}


static int ieee80211_sta_join_ibss(struct net_device *dev,
struct ieee80211_if_sta *ifsta,
struct ieee80211_sta_bss *bss)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
int res, rates, i, j;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
struct ieee80211_tx_control control;
struct rate_selection ratesel;
u8 *pos;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_supported_band *sband;

sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

/* Remove possible STA entries from other IBSS networks. */
sta_info_flush(local, NULL);

if (local->ops->reset_tsf) {
/* Reset own TSF to allow time synchronization work. */
local->ops->reset_tsf(local_to_hw(local));
}
memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
res = ieee80211_if_config(dev);
if (res)
return res;

local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;

sdata = IEEE80211_DEV_TO_SUB_IF(dev);
sdata->drop_unencrypted = bss->capability &
WLAN_CAPABILITY_PRIVACY ? 1 : 0;

res = ieee80211_set_freq(local, bss->freq);

if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) {
printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
"%d MHz\n", dev->name, local->oper_channel->center_freq);
return -1;
}

/* Set beacon template */
skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
do {
if (!skb)
break;

skb_reserve(skb, local->hw.extra_tx_headroom);

mgmt = (struct ieee80211_mgmt *)
skb_put(skb, 24 + sizeof(mgmt->u.beacon));
memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
IEEE80211_STYPE_BEACON);
memset(mgmt->da, 0xff, ETH_ALEN);
memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
mgmt->u.beacon.beacon_int =
cpu_to_le16(local->hw.conf.beacon_int);
mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);

pos = skb_put(skb, 2 + ifsta->ssid_len);
*pos++ = WLAN_EID_SSID;
*pos++ = ifsta->ssid_len;
memcpy(pos, ifsta->ssid, ifsta->ssid_len);

rates = bss->supp_rates_len;
if (rates > 8)
rates = 8;
pos = skb_put(skb, 2 + rates);
*pos++ = WLAN_EID_SUPP_RATES;
*pos++ = rates;
memcpy(pos, bss->supp_rates, rates);

if (bss->band == IEEE80211_BAND_2GHZ) {
pos = skb_put(skb, 2 + 1);
*pos++ = WLAN_EID_DS_PARAMS;
*pos++ = 1;
*pos++ = ieee80211_frequency_to_channel(bss->freq);
}

pos = skb_put(skb, 2 + 2);
*pos++ = WLAN_EID_IBSS_PARAMS;
*pos++ = 2;
/* FIX: set ATIM window based on scan results */
*pos++ = 0;
*pos++ = 0;

if (bss->supp_rates_len > 8) {
rates = bss->supp_rates_len - 8;
pos = skb_put(skb, 2 + rates);
*pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos++ = rates;
memcpy(pos, &bss->supp_rates[8], rates);
}

memset(&control, 0, sizeof(control));
rate_control_get_rate(dev, sband, skb, &ratesel);
if (!ratesel.rate) {
printk(KERN_DEBUG "%s: Failed to determine TX rate "
"for IBSS beacon\n", dev->name);
break;
}
control.vif = &sdata->vif;
control.tx_rate = ratesel.rate;
if (sdata->bss_conf.use_short_preamble &&
ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
control.flags |= IEEE80211_TXCTL_NO_ACK;
control.retry_limit = 1;

ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
if (ifsta->probe_resp) {
mgmt = (struct ieee80211_mgmt *)
ifsta->probe_resp->data;
mgmt->frame_control =
IEEE80211_FC(IEEE80211_FTYPE_MGMT,
IEEE80211_STYPE_PROBE_RESP);
} else {
printk(KERN_DEBUG "%s: Could not allocate ProbeResp "
"template for IBSS\n", dev->name);
}

if (local->ops->beacon_update &&
local->ops->beacon_update(local_to_hw(local),
skb, &control) == 0) {
printk(KERN_DEBUG "%s: Configured IBSS beacon "
"template\n", dev->name);
skb = NULL;
}

rates = 0;
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
for (i = 0; i < bss->supp_rates_len; i++) {
int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
for (j = 0; j < sband->n_bitrates; j++)
if (sband->bitrates[j].bitrate == bitrate)
rates |= BIT(j);
}
ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
} while (0);

if (skb) {
printk(KERN_DEBUG "%s: Failed to configure IBSS beacon "
"template\n", dev->name);
dev_kfree_skb(skb);
}

ifsta->state = IEEE80211_IBSS_JOINED;
mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

ieee80211_rx_bss_put(dev, bss);

return res;
}


static void ieee80211_rx_bss_info(struct net_device *dev,
struct ieee80211_mgmt *mgmt,
size_t len,
Expand Down Expand Up @@ -2891,164 +3050,6 @@ static int ieee80211_sta_config_auth(struct net_device *dev,
return -1;
}

static int ieee80211_sta_join_ibss(struct net_device *dev,
struct ieee80211_if_sta *ifsta,
struct ieee80211_sta_bss *bss)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
int res, rates, i, j;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
struct ieee80211_tx_control control;
struct rate_selection ratesel;
u8 *pos;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_supported_band *sband;

sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

/* Remove possible STA entries from other IBSS networks. */
sta_info_flush(local, NULL);

if (local->ops->reset_tsf) {
/* Reset own TSF to allow time synchronization work. */
local->ops->reset_tsf(local_to_hw(local));
}
memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
res = ieee80211_if_config(dev);
if (res)
return res;

local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;

sdata = IEEE80211_DEV_TO_SUB_IF(dev);
sdata->drop_unencrypted = bss->capability &
WLAN_CAPABILITY_PRIVACY ? 1 : 0;

res = ieee80211_set_freq(local, bss->freq);

if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) {
printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
"%d MHz\n", dev->name, local->oper_channel->center_freq);
return -1;
}

/* Set beacon template based on scan results */
skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
do {
if (!skb)
break;

skb_reserve(skb, local->hw.extra_tx_headroom);

mgmt = (struct ieee80211_mgmt *)
skb_put(skb, 24 + sizeof(mgmt->u.beacon));
memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
IEEE80211_STYPE_BEACON);
memset(mgmt->da, 0xff, ETH_ALEN);
memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
mgmt->u.beacon.beacon_int =
cpu_to_le16(local->hw.conf.beacon_int);
mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);

pos = skb_put(skb, 2 + ifsta->ssid_len);
*pos++ = WLAN_EID_SSID;
*pos++ = ifsta->ssid_len;
memcpy(pos, ifsta->ssid, ifsta->ssid_len);

rates = bss->supp_rates_len;
if (rates > 8)
rates = 8;
pos = skb_put(skb, 2 + rates);
*pos++ = WLAN_EID_SUPP_RATES;
*pos++ = rates;
memcpy(pos, bss->supp_rates, rates);

if (bss->band == IEEE80211_BAND_2GHZ) {
pos = skb_put(skb, 2 + 1);
*pos++ = WLAN_EID_DS_PARAMS;
*pos++ = 1;
*pos++ = ieee80211_frequency_to_channel(bss->freq);
}

pos = skb_put(skb, 2 + 2);
*pos++ = WLAN_EID_IBSS_PARAMS;
*pos++ = 2;
/* FIX: set ATIM window based on scan results */
*pos++ = 0;
*pos++ = 0;

if (bss->supp_rates_len > 8) {
rates = bss->supp_rates_len - 8;
pos = skb_put(skb, 2 + rates);
*pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos++ = rates;
memcpy(pos, &bss->supp_rates[8], rates);
}

memset(&control, 0, sizeof(control));
rate_control_get_rate(dev, sband, skb, &ratesel);
if (!ratesel.rate) {
printk(KERN_DEBUG "%s: Failed to determine TX rate "
"for IBSS beacon\n", dev->name);
break;
}
control.vif = &sdata->vif;
control.tx_rate = ratesel.rate;
if (sdata->bss_conf.use_short_preamble &&
ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
control.flags |= IEEE80211_TXCTL_NO_ACK;
control.retry_limit = 1;

ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
if (ifsta->probe_resp) {
mgmt = (struct ieee80211_mgmt *)
ifsta->probe_resp->data;
mgmt->frame_control =
IEEE80211_FC(IEEE80211_FTYPE_MGMT,
IEEE80211_STYPE_PROBE_RESP);
} else {
printk(KERN_DEBUG "%s: Could not allocate ProbeResp "
"template for IBSS\n", dev->name);
}

if (local->ops->beacon_update &&
local->ops->beacon_update(local_to_hw(local),
skb, &control) == 0) {
printk(KERN_DEBUG "%s: Configured IBSS beacon "
"template based on scan results\n", dev->name);
skb = NULL;
}

rates = 0;
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
for (i = 0; i < bss->supp_rates_len; i++) {
int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
for (j = 0; j < sband->n_bitrates; j++)
if (sband->bitrates[j].bitrate == bitrate)
rates |= BIT(j);
}
ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
} while (0);

if (skb) {
printk(KERN_DEBUG "%s: Failed to configure IBSS beacon "
"template\n", dev->name);
dev_kfree_skb(skb);
}

ifsta->state = IEEE80211_IBSS_JOINED;
mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

ieee80211_rx_bss_put(dev, bss);

return res;
}


static int ieee80211_sta_create_ibss(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
Expand Down

0 comments on commit ac7b6b5

Please sign in to comment.