* [PATCH 1/3] mac80211: better definition of mactime
@ 2008-02-15 7:01 Bruno Randolf
2008-02-15 7:01 ` [PATCH 2/3] mac80211: move function ieee80211_sta_join_ibss() Bruno Randolf
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Bruno Randolf @ 2008-02-15 7:01 UTC (permalink / raw)
To: ath5k-devel
Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes,
flamingice, jbenc
define mactime as the time when the first data symbol arrived at the HW. the
old definition was questionable because 802.11 defines timestamp only for
beacon and probe response frames, and there it means the timestamp field.
a stricter definition of mactime is necessary for correct merging of IBSS.
note that it is up to the driver to convert whatever its hardware returns to
this definition. unfortunately we don't know for example when atheros hardware
takes its rx timestamp exactly :(
Signed-off-by: Bruno Randolf <bruno@thinktube.com>
---
include/net/mac80211.h | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 460da54..1b807f4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -295,7 +295,8 @@ enum mac80211_rx_flags {
* The low-level driver should provide this information (the subset
* supported by hardware) to the 802.11 code with each received
* frame.
- * @mactime: MAC timestamp as defined by 802.11
+ * @mactime: value in microseconds of the 64-bit Time Synchronization Function
+ * (TSF) timer when the first data symbol (MPDU) arrived at the hardware.
* @band: the active band when this frame was received
* @freq: frequency the radio was tuned to when receiving this frame, in MHz
* @ssi: signal strength when receiving this frame
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 2/3] mac80211: move function ieee80211_sta_join_ibss() 2008-02-15 7:01 [PATCH 1/3] mac80211: better definition of mactime Bruno Randolf @ 2008-02-15 7:01 ` Bruno Randolf 2008-02-15 12:52 ` Johannes Berg 2008-02-15 7:02 ` [PATCH 3/3] mac80211: enable IBSS merging Bruno Randolf 2008-02-15 12:52 ` [PATCH 1/3] mac80211: better definition of mactime Johannes Berg 2 siblings, 1 reply; 13+ messages in thread From: Bruno Randolf @ 2008-02-15 7:01 UTC (permalink / raw) To: ath5k-devel Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes, flamingice, jbenc this moves ieee80211_sta_join_ibss() up for the next patch (ibss merge). --- net/mac80211/ieee80211_sta.c | 317 +++++++++++++++++++++--------------------- 1 files changed, 159 insertions(+), 158 deletions(-) diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 2c7b8be..72d7a86 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -2030,6 +2030,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, @@ -2896,164 +3055,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) ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] mac80211: move function ieee80211_sta_join_ibss() 2008-02-15 7:01 ` [PATCH 2/3] mac80211: move function ieee80211_sta_join_ibss() Bruno Randolf @ 2008-02-15 12:52 ` Johannes Berg 0 siblings, 0 replies; 13+ messages in thread From: Johannes Berg @ 2008-02-15 12:52 UTC (permalink / raw) To: Bruno Randolf Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless, linville, flamingice, jbenc [-- Attachment #1: Type: text/plain, Size: 11575 bytes --] On Fri, 2008-02-15 at 16:01 +0900, Bruno Randolf wrote: > this moves ieee80211_sta_join_ibss() up for the next patch (ibss merge). Dunno if it needs sign-off, but Acked-by: Johannes Berg <johannes@sipsolutions.net> > --- > > net/mac80211/ieee80211_sta.c | 317 +++++++++++++++++++++--------------------- > 1 files changed, 159 insertions(+), 158 deletions(-) > > > diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c > index 2c7b8be..72d7a86 100644 > --- a/net/mac80211/ieee80211_sta.c > +++ b/net/mac80211/ieee80211_sta.c > @@ -2030,6 +2030,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, > @@ -2896,164 +3055,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) > > [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 828 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/3] mac80211: enable IBSS merging 2008-02-15 7:01 [PATCH 1/3] mac80211: better definition of mactime Bruno Randolf 2008-02-15 7:01 ` [PATCH 2/3] mac80211: move function ieee80211_sta_join_ibss() Bruno Randolf @ 2008-02-15 7:02 ` Bruno Randolf 2008-02-15 15:09 ` Johannes Berg 2008-02-15 12:52 ` [PATCH 1/3] mac80211: better definition of mactime Johannes Berg 2 siblings, 1 reply; 13+ messages in thread From: Bruno Randolf @ 2008-02-15 7:02 UTC (permalink / raw) To: ath5k-devel Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes, flamingice, jbenc note: ieee80211_get_bitrate() might be better places elsewhere, but i d= on't know where it would fit. enable IBSS cell merging. if an IBSS beacon with the same channel, same= ESSID and a TSF higher than the local TSF (mactime) is received, we have to j= oin its BSSID. while this might not be immediately apparent from reading the 8= 02.11 standard it is compliant and necessary to make IBSS mode functional in = many cases. most drivers have a similar behaviour. * move the relevant code section (previously only containing debug code= ) down to the end of the function, so we can reuse the bss structure. * we have to compare the mactime (TSF at the time of packet receive) ra= ther than the current TSF. since some drivers are not able to give a reliabl= e mactime we fall back to use the current TSF, which will be enough to ca= tch most (but not all) cases where an IBSS merge is necessary. * in IBSS mode we want to allow beacons to override probe response info= so we can correctly do merges. * we don't only configure beacons based on scan results, so change that message. * to enable this we have to let all beacons thru in IBSS mode, even if = they have a different BSSID. Signed-off-by: Bruno Randolf <bruno@thinktube.com> --- include/net/mac80211.h | 3 + net/mac80211/ieee80211_sta.c | 107 +++++++++++++++++++++++++++++++---= -------- net/mac80211/rx.c | 5 ++ 3 files changed, 84 insertions(+), 31 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 1b807f4..c634607 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -276,7 +276,8 @@ struct ieee80211_tx_control { * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on * the frame. * @RX_FLAG_TSFT: The timestamp passed in the RX status (@mactime fiel= d) - * is valid. + * is valid. This is useful in monitor mode and necessary for beacon f= rames + * to enable IBSS merging. */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR =3D 1<<0, diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.= c index 72d7a86..8b24d1f 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -2189,6 +2189,19 @@ static int ieee80211_sta_join_ibss(struct net_de= vice *dev, } =20 =20 +static inline int ieee80211_get_bitrate(struct wiphy *phy, + enum ieee80211_band band, int rate_idx) +{ + struct ieee80211_supported_band *sband; + if (band > 0 && band < IEEE80211_NUM_BANDS) { + sband =3D phy->bands[band]; + if (rate_idx > 0 && rate_idx < sband->n_bitrates) + return sband->bitrates[rate_idx].bitrate; + } + return 0; +} + + static void ieee80211_rx_bss_info(struct net_device *dev, struct ieee80211_mgmt *mgmt, size_t len, @@ -2202,7 +2215,7 @@ static void ieee80211_rx_bss_info(struct net_devi= ce *dev, struct ieee80211_sta_bss *bss; struct sta_info *sta; struct ieee80211_sub_if_data *sdata =3D IEEE80211_DEV_TO_SUB_IF(dev); - u64 timestamp; + u64 beacon_timestamp, rx_timestamp; DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac2); =20 @@ -2219,31 +2232,7 @@ static void ieee80211_rx_bss_info(struct net_dev= ice *dev, if (baselen > len) return; =20 - timestamp =3D le64_to_cpu(mgmt->u.beacon.timestamp); - - if (sdata->vif.type =3D=3D IEEE80211_IF_TYPE_IBSS && beacon && - memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) =3D=3D 0) { -#ifdef CONFIG_MAC80211_IBSS_DEBUG - static unsigned long last_tsf_debug =3D 0; - u64 tsf; - if (local->ops->get_tsf) - tsf =3D local->ops->get_tsf(local_to_hw(local)); - else - tsf =3D -1LLU; - if (time_after(jiffies, last_tsf_debug + 5 * HZ)) { - printk(KERN_DEBUG "RX beacon SA=3D%s BSSID=3D" - "%s TSF=3D0x%llx BCN=3D0x%llx diff=3D%lld " - "@%lu\n", - print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->bssid), - (unsigned long long)tsf, - (unsigned long long)timestamp, - (unsigned long long)(tsf - timestamp), - jiffies); - last_tsf_debug =3D jiffies; - } -#endif /* CONFIG_MAC80211_IBSS_DEBUG */ - } - + beacon_timestamp =3D le64_to_cpu(mgmt->u.beacon.timestamp); ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems= ); =20 if (sdata->vif.type =3D=3D IEEE80211_IF_TYPE_IBSS && elems.supp_rates= && @@ -2329,8 +2318,10 @@ static void ieee80211_rx_bss_info(struct net_dev= ice *dev, =20 bss->band =3D rx_status->band; =20 - if (bss->probe_resp && beacon) { - /* Do not allow beacon to override data from Probe Response. */ + if (sdata->vif.type !=3D IEEE80211_IF_TYPE_IBSS && + bss->probe_resp && beacon) { + /* STA mode: + * Do not allow beacon to override data from Probe Response. */ ieee80211_rx_bss_put(dev, bss); return; } @@ -2427,13 +2418,71 @@ static void ieee80211_rx_bss_info(struct net_de= vice *dev, bss->ht_ie_len =3D 0; } =20 - bss->timestamp =3D timestamp; + bss->timestamp =3D beacon_timestamp; bss->last_update =3D jiffies; bss->rssi =3D rx_status->ssi; bss->signal =3D rx_status->signal; bss->noise =3D rx_status->noise; if (!beacon) bss->probe_resp++; + + /* check if we need to merge IBSS */ + if (sdata->vif.type =3D=3D IEEE80211_IF_TYPE_IBSS && beacon && + !local->sta_sw_scanning && !local->sta_hw_scanning && + mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS && + bss->freq =3D=3D local->oper_channel->center_freq && + elems.ssid_len =3D=3D sdata->u.sta.ssid_len && + memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) =3D=3D= 0) { + if (rx_status->flag & RX_FLAG_TSFT) { + /* in order for correct IBSS merging we need mactime + * + * since mactime is defined as the time the first data + * symbol of the frame hits the PHY, and the timestamp + * of the beacon is defined as "the time that the data + * symbol containing the first bit of the timestamp is + * transmitted to the PHY plus the transmitting STA=E2=80=99s + * delays through its local PHY from the MAC-PHY + * interface to its interface with the WM" + * (802.11 11.1.2) - equals the time this bit arrives at + * the receiver - we have to take into account the + * offset between the two. + * e.g: at 1 MBit that means mactime is 192 usec earlier + * (=3D24 bytes * 8 usecs/byte) than the beacon timestamp. + */ + int rate =3D ieee80211_get_bitrate(local->hw.wiphy, + rx_status->band, rx_status->rate_idx); + if (rate) + rx_timestamp =3D rx_status->mactime + + (24 * 8 * 10 / rate); + else + rx_timestamp =3D rx_status->mactime; + } else if (local && local->ops && local->ops->get_tsf) + /* second best option: get current TSF */ + rx_timestamp =3D local->ops->get_tsf(local_to_hw(local)); + else + /* can't merge without knowing the TSF */ + rx_timestamp =3D -1LLU; +#ifdef CONFIG_MAC80211_IBSS_DEBUG + printk(KERN_DEBUG "RX beacon SA=3D%s BSSID=3D" + "%s TSF=3D0x%llx BCN=3D0x%llx diff=3D%lld @%lu\n", + print_mac(mac, mgmt->sa), + print_mac(mac2, mgmt->bssid), + (unsigned long long)rx_timestamp, + (unsigned long long)beacon_timestamp, + (unsigned long long)(rx_timestamp - beacon_timestamp), + jiffies); +#endif /* CONFIG_MAC80211_IBSS_DEBUG */ + if (beacon_timestamp > rx_timestamp) { + if (CONFIG_MAC80211_IBSS_DEBUG || net_ratelimit()) + printk(KERN_DEBUG "%s: beacon TSF higher than " + "local TSF - IBSS merge with BSSID %s\n", + dev->name, print_mac(mac, mgmt->bssid)); + ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); + ieee80211_ibss_add_sta(dev, NULL, + mgmt->bssid, mgmt->sa); + } + } + ieee80211_rx_bss_put(dev, bss); } =20 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 943ba90..5dfe6f2 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1694,7 +1694,10 @@ static int prepare_for_handlers(struct ieee80211= _sub_if_data *sdata, case IEEE80211_IF_TYPE_IBSS: if (!bssid) return 0; - if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { + if ((rx->fc & IEEE80211_FCTL_FTYPE) =3D=3D IEEE80211_FTYPE_MGMT && + (rx->fc & IEEE80211_FCTL_STYPE) =3D=3D IEEE80211_STYPE_BEACON) + return 1; + else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { if (!(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) return 0; rx->flags &=3D ~IEEE80211_TXRXD_RXRA_MATCH; - To unsubscribe from this list: send the line "unsubscribe linux-wireles= s" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] mac80211: enable IBSS merging 2008-02-15 7:02 ` [PATCH 3/3] mac80211: enable IBSS merging Bruno Randolf @ 2008-02-15 15:09 ` Johannes Berg 2008-02-16 2:29 ` [PATCH] " Bruno Randolf 0 siblings, 1 reply; 13+ messages in thread From: Johannes Berg @ 2008-02-15 15:09 UTC (permalink / raw) To: Bruno Randolf Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless, linville, flamingice, jbenc [-- Attachment #1: Type: text/plain, Size: 776 bytes --] > +static inline int ieee80211_get_bitrate(struct wiphy *phy, > + enum ieee80211_band band, int rate_idx) > +{ > + struct ieee80211_supported_band *sband; > + if (band > 0 && band < IEEE80211_NUM_BANDS) { > + sband = phy->bands[band]; > + if (rate_idx > 0 && rate_idx < sband->n_bitrates) > + return sband->bitrates[rate_idx].bitrate; > + } > + return 0; > +} You don't need to do this. In the rx info (struct ieee80211_txrx_data rx) we already have the bitrate info available (rx->u.rx.rate), you might not have access to it but __ieee80211_rx() refuses packets with an invalid rate or band. Hence, you can leave out *all* the sanity checks and just do phy->bands[band]->bitrates[rate_idx] which doesn't need an inline function. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 828 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] mac80211: enable IBSS merging 2008-02-15 15:09 ` Johannes Berg @ 2008-02-16 2:29 ` Bruno Randolf 2008-02-17 9:11 ` Johannes Berg 0 siblings, 1 reply; 13+ messages in thread From: Bruno Randolf @ 2008-02-16 2:29 UTC (permalink / raw) To: ath5k-devel Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes, flamingice, jbenc enable IBSS cell merging. if an IBSS beacon with the same channel, same= ESSID and a TSF higher than the local TSF (mactime) is received, we have to j= oin its BSSID. while this might not be immediately apparent from reading the 80= 2.11 standard it is compliant and necessary to make IBSS mode functional in = many cases. most drivers have a similar behaviour. * move the relevant code section (previously only containing debug code= ) down to the end of the function, so we can reuse the bss structure. * we have to compare the mactime (TSF at the time of packet receive) ra= ther than the current TSF. since mactime is defined as the time the first da= ta symbol arrived we add the time until byte 24 where the timestamp reside= s, since this is how the beacon timestamp is defined. as some some drivers are n= ot able to give a reliable mactime we fall back to use the current TSF, which w= ill be enough to catch most (but not all) cases where an IBSS merge is necessa= ry. * in IBSS mode we want to allow beacons to override probe response info= so we can correctly do merges. * we don't only configure beacons based on scan results, so change that message. * to enable this we have to let all beacons thru in IBSS mode, even if = they have a different BSSID. Signed-off-by: Bruno Randolf <bruno@thinktube.com> --- include/net/mac80211.h | 3 + net/mac80211/ieee80211_sta.c | 90 ++++++++++++++++++++++++++++------= -------- net/mac80211/rx.c | 5 ++ 3 files changed, 67 insertions(+), 31 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 1b807f4..c634607 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -276,7 +276,8 @@ struct ieee80211_tx_control { * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on * the frame. * @RX_FLAG_TSFT: The timestamp passed in the RX status (@mactime fiel= d) - * is valid. + * is valid. This is useful in monitor mode and necessary for beacon f= rames + * to enable IBSS merging. */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR =3D 1<<0, diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.= c index 72d7a86..fb96b51 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -2202,7 +2202,7 @@ static void ieee80211_rx_bss_info(struct net_devi= ce *dev, struct ieee80211_sta_bss *bss; struct sta_info *sta; struct ieee80211_sub_if_data *sdata =3D IEEE80211_DEV_TO_SUB_IF(dev); - u64 timestamp; + u64 beacon_timestamp, rx_timestamp; DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac2); =20 @@ -2219,31 +2219,7 @@ static void ieee80211_rx_bss_info(struct net_dev= ice *dev, if (baselen > len) return; =20 - timestamp =3D le64_to_cpu(mgmt->u.beacon.timestamp); - - if (sdata->vif.type =3D=3D IEEE80211_IF_TYPE_IBSS && beacon && - memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) =3D=3D 0) { -#ifdef CONFIG_MAC80211_IBSS_DEBUG - static unsigned long last_tsf_debug =3D 0; - u64 tsf; - if (local->ops->get_tsf) - tsf =3D local->ops->get_tsf(local_to_hw(local)); - else - tsf =3D -1LLU; - if (time_after(jiffies, last_tsf_debug + 5 * HZ)) { - printk(KERN_DEBUG "RX beacon SA=3D%s BSSID=3D" - "%s TSF=3D0x%llx BCN=3D0x%llx diff=3D%lld " - "@%lu\n", - print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->bssid), - (unsigned long long)tsf, - (unsigned long long)timestamp, - (unsigned long long)(tsf - timestamp), - jiffies); - last_tsf_debug =3D jiffies; - } -#endif /* CONFIG_MAC80211_IBSS_DEBUG */ - } - + beacon_timestamp =3D le64_to_cpu(mgmt->u.beacon.timestamp); ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems= ); =20 if (sdata->vif.type =3D=3D IEEE80211_IF_TYPE_IBSS && elems.supp_rates= && @@ -2329,8 +2305,10 @@ static void ieee80211_rx_bss_info(struct net_dev= ice *dev, =20 bss->band =3D rx_status->band; =20 - if (bss->probe_resp && beacon) { - /* Do not allow beacon to override data from Probe Response. */ + if (sdata->vif.type !=3D IEEE80211_IF_TYPE_IBSS && + bss->probe_resp && beacon) { + /* STA mode: + * Do not allow beacon to override data from Probe Response. */ ieee80211_rx_bss_put(dev, bss); return; } @@ -2427,13 +2405,67 @@ static void ieee80211_rx_bss_info(struct net_de= vice *dev, bss->ht_ie_len =3D 0; } =20 - bss->timestamp =3D timestamp; + bss->timestamp =3D beacon_timestamp; bss->last_update =3D jiffies; bss->rssi =3D rx_status->ssi; bss->signal =3D rx_status->signal; bss->noise =3D rx_status->noise; if (!beacon) bss->probe_resp++; + + /* check if we need to merge IBSS */ + if (sdata->vif.type =3D=3D IEEE80211_IF_TYPE_IBSS && beacon && + !local->sta_sw_scanning && !local->sta_hw_scanning && + mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS && + bss->freq =3D=3D local->oper_channel->center_freq && + elems.ssid_len =3D=3D sdata->u.sta.ssid_len && + memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) =3D=3D= 0) { + if (rx_status->flag & RX_FLAG_TSFT) { + /* in order for correct IBSS merging we need mactime + * + * since mactime is defined as the time the first data + * symbol of the frame hits the PHY, and the timestamp + * of the beacon is defined as "the time that the data + * symbol containing the first bit of the timestamp is + * transmitted to the PHY plus the transmitting STA=E2=80=99s + * delays through its local PHY from the MAC-PHY + * interface to its interface with the WM" + * (802.11 11.1.2) - equals the time this bit arrives at + * the receiver - we have to take into account the + * offset between the two. + * e.g: at 1 MBit that means mactime is 192 usec earlier + * (=3D24 bytes * 8 usecs/byte) than the beacon timestamp. + */ + int rate =3D local->hw.wiphy->bands[rx_status->band]-> + bitrates[rx_status->rate_idx].bitrate; + rx_timestamp =3D rx_status->mactime + (24 * 8 * 10 / rate); + } else if (local && local->ops && local->ops->get_tsf) + /* second best option: get current TSF */ + rx_timestamp =3D local->ops->get_tsf(local_to_hw(local)); + else + /* can't merge without knowing the TSF */ + rx_timestamp =3D -1LLU; +#ifdef CONFIG_MAC80211_IBSS_DEBUG + printk(KERN_DEBUG "RX beacon SA=3D%s BSSID=3D" + "%s TSF=3D0x%llx BCN=3D0x%llx diff=3D%lld @%lu\n", + print_mac(mac, mgmt->sa), + print_mac(mac2, mgmt->bssid), + (unsigned long long)rx_timestamp, + (unsigned long long)beacon_timestamp, + (unsigned long long)(rx_timestamp - beacon_timestamp), + jiffies); +#endif /* CONFIG_MAC80211_IBSS_DEBUG */ + if (beacon_timestamp > rx_timestamp) { + if (CONFIG_MAC80211_IBSS_DEBUG || net_ratelimit()) + printk(KERN_DEBUG "%s: beacon TSF higher than " + "local TSF - IBSS merge with BSSID %s\n", + dev->name, print_mac(mac, mgmt->bssid)); + ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); + ieee80211_ibss_add_sta(dev, NULL, + mgmt->bssid, mgmt->sa); + } + } + ieee80211_rx_bss_put(dev, bss); } =20 diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 943ba90..5dfe6f2 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1694,7 +1694,10 @@ static int prepare_for_handlers(struct ieee80211= _sub_if_data *sdata, case IEEE80211_IF_TYPE_IBSS: if (!bssid) return 0; - if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { + if ((rx->fc & IEEE80211_FCTL_FTYPE) =3D=3D IEEE80211_FTYPE_MGMT && + (rx->fc & IEEE80211_FCTL_STYPE) =3D=3D IEEE80211_STYPE_BEACON) + return 1; + else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { if (!(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) return 0; rx->flags &=3D ~IEEE80211_TXRXD_RXRA_MATCH; - To unsubscribe from this list: send the line "unsubscribe linux-wireles= s" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] mac80211: enable IBSS merging 2008-02-16 2:29 ` [PATCH] " Bruno Randolf @ 2008-02-17 9:11 ` Johannes Berg 2008-02-18 1:42 ` bruno randolf 2008-02-18 2:03 ` bruno randolf 0 siblings, 2 replies; 13+ messages in thread From: Johannes Berg @ 2008-02-17 9:11 UTC (permalink / raw) To: Bruno Randolf Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless, linville, flamingice, jbenc [-- Attachment #1: Type: text/plain, Size: 1806 bytes --] On Sat, 2008-02-16 at 11:29 +0900, Bruno Randolf wrote: > enable IBSS cell merging. if an IBSS beacon with the same channel, same ESSID > and a TSF higher than the local TSF (mactime) is received, we have to join its > BSSID. while this might not be immediately apparent from reading the 802.11 > standard it is compliant and necessary to make IBSS mode functional in many > cases. most drivers have a similar behaviour. > [...] Looks good, thanks for your patience. I have two minor comments still, sorry for the lack of focus in earlier review. > + } else if (local && local->ops && local->ops->get_tsf) > + /* second best option: get current TSF */ > + rx_timestamp = local->ops->get_tsf(local_to_hw(local)); This is assuming that we don't manage to process the frame within 192 usecs. I guess that will be true since we defer it to a tasklet, but do we want to bet on it in the future or should we simply widen the window where the merge *won't* happen because the driver doesn't provide enough info and also add the 24 bytes offset here? Also something else that just occurred to me... You wrote in the description: > * to enable this we have to let all beacons thru in IBSS mode, even if > they have a different BSSID. which I think refers to the last hunk of your patch. However, hardware also has such filters, so I think we also should set the FIF_BCN_PRBRESP_PROMISC filter flag when IBSS is enabled, we don't want to force drivers to do this implicitly when IBSS interfaces are added. Again, thanks for your patience, and if you want this patch merged now here's my Acked-by: Johannes Berg <johannes@sipsolutions.net> and we can address these remaining two points in follow-up patches instead of respinning this all the time. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 828 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] mac80211: enable IBSS merging 2008-02-17 9:11 ` Johannes Berg @ 2008-02-18 1:42 ` bruno randolf 2008-02-18 11:15 ` Johannes Berg 2008-02-18 2:03 ` bruno randolf 1 sibling, 1 reply; 13+ messages in thread From: bruno randolf @ 2008-02-18 1:42 UTC (permalink / raw) To: Johannes Berg Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless, linville, flamingice, jbenc On Sunday 17 February 2008 18:11:43 Johannes Berg wrote: > Looks good, thanks for your patience. thanks for your review :) > I have two minor comments still, > sorry for the lack of focus in earlier review. > > > + } else if (local && local->ops && local->ops->get_tsf) > > + /* second best option: get current TSF */ > > + rx_timestamp = local->ops->get_tsf(local_to_hw(local)); > > This is assuming that we don't manage to process the frame within 192 > usecs. I guess that will be true since we defer it to a tasklet, but do > we want to bet on it in the future or should we simply widen the window > where the merge *won't* happen because the driver doesn't provide enough > info and also add the 24 bytes offset here? true. i'll change that and resend the patch. i have to rebase it anyways for the current tree. > Also something else that just occurred to me... You wrote in the > > description: > > * to enable this we have to let all beacons thru in IBSS mode, even if > > they have a different BSSID. > > which I think refers to the last hunk of your patch. However, hardware > also has such filters, so I think we also should set the > FIF_BCN_PRBRESP_PROMISC filter flag when IBSS is enabled, we don't want > to force drivers to do this implicitly when IBSS interfaces are added. hmm, i don't know about that and i don't seem to need that for ath5k, so can we do that in a follow up patch, please? bruno ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] mac80211: enable IBSS merging 2008-02-18 1:42 ` bruno randolf @ 2008-02-18 11:15 ` Johannes Berg 0 siblings, 0 replies; 13+ messages in thread From: Johannes Berg @ 2008-02-18 11:15 UTC (permalink / raw) To: bruno randolf Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless, linville, flamingice, jbenc [-- Attachment #1: Type: text/plain, Size: 464 bytes --] > > which I think refers to the last hunk of your patch. However, hardware > > also has such filters, so I think we also should set the > > FIF_BCN_PRBRESP_PROMISC filter flag when IBSS is enabled, we don't want > > to force drivers to do this implicitly when IBSS interfaces are added. > > hmm, i don't know about that and i don't seem to need that for ath5k, so can > we do that in a follow up patch, please? Yeah sure, we can do that. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 828 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] mac80211: enable IBSS merging 2008-02-17 9:11 ` Johannes Berg 2008-02-18 1:42 ` bruno randolf @ 2008-02-18 2:03 ` bruno randolf 2008-02-18 11:16 ` Johannes Berg 1 sibling, 1 reply; 13+ messages in thread From: bruno randolf @ 2008-02-18 2:03 UTC (permalink / raw) To: Johannes Berg Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless, linville, flamingice, jbenc On Sunday 17 February 2008 18:11:43 Johannes Berg wrote: > Looks good, thanks for your patience. I have two minor comments still, > sorry for the lack of focus in earlier review. > > > + } else if (local && local->ops && local->ops->get_tsf) > > + /* second best option: get current TSF */ > > + rx_timestamp = local->ops->get_tsf(local_to_hw(local)); > > This is assuming that we don't manage to process the frame within 192 > usecs. I guess that will be true since we defer it to a tasklet, but do > we want to bet on it in the future or should we simply widen the window > where the merge *won't* happen because the driver doesn't provide enough > info and also add the 24 bytes offset here? sorry, i was to fast in agreeing ;) on a second thought i realized that we don't need to worry about that: since we get to handle the frame after it was received *completely*, we can be sure that the current time returned by get_tsf() is later than the time when byte 24 was received. so no need for adding the offset. i'll rebase the unmodified patch series and resend it. bruno ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] mac80211: enable IBSS merging 2008-02-18 2:03 ` bruno randolf @ 2008-02-18 11:16 ` Johannes Berg 0 siblings, 0 replies; 13+ messages in thread From: Johannes Berg @ 2008-02-18 11:16 UTC (permalink / raw) To: bruno randolf Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless, linville, flamingice, jbenc [-- Attachment #1: Type: text/plain, Size: 734 bytes --] > > This is assuming that we don't manage to process the frame within 192 > > usecs. I guess that will be true since we defer it to a tasklet, but do > > we want to bet on it in the future or should we simply widen the window > > where the merge *won't* happen because the driver doesn't provide enough > > info and also add the 24 bytes offset here? > > sorry, i was to fast in agreeing ;) > on a second thought i realized that we don't need to worry about that: > > since we get to handle the frame after it was received *completely*, we can be > sure that the current time returned by get_tsf() is later than the time when > byte 24 was received. so no need for adding the offset. Hah, good point. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 828 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] mac80211: better definition of mactime 2008-02-15 7:01 [PATCH 1/3] mac80211: better definition of mactime Bruno Randolf 2008-02-15 7:01 ` [PATCH 2/3] mac80211: move function ieee80211_sta_join_ibss() Bruno Randolf 2008-02-15 7:02 ` [PATCH 3/3] mac80211: enable IBSS merging Bruno Randolf @ 2008-02-15 12:52 ` Johannes Berg 2 siblings, 0 replies; 13+ messages in thread From: Johannes Berg @ 2008-02-15 12:52 UTC (permalink / raw) To: Bruno Randolf Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless, linville, flamingice, jbenc [-- Attachment #1: Type: text/plain, Size: 1583 bytes --] On Fri, 2008-02-15 at 16:01 +0900, Bruno Randolf wrote: > define mactime as the time when the first data symbol arrived at the HW. the > old definition was questionable because 802.11 defines timestamp only for > beacon and probe response frames, and there it means the timestamp field. > > a stricter definition of mactime is necessary for correct merging of IBSS. > > note that it is up to the driver to convert whatever its hardware returns to > this definition. unfortunately we don't know for example when atheros hardware > takes its rx timestamp exactly :( > > Signed-off-by: Bruno Randolf <bruno@thinktube.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> > --- > > include/net/mac80211.h | 3 ++- > 1 files changed, 2 insertions(+), 1 deletions(-) > > > diff --git a/include/net/mac80211.h b/include/net/mac80211.h > index 460da54..1b807f4 100644 > --- a/include/net/mac80211.h > +++ b/include/net/mac80211.h > @@ -295,7 +295,8 @@ enum mac80211_rx_flags { > * The low-level driver should provide this information (the subset > * supported by hardware) to the 802.11 code with each received > * frame. > - * @mactime: MAC timestamp as defined by 802.11 > + * @mactime: value in microseconds of the 64-bit Time Synchronization Function > + * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. > * @band: the active band when this frame was received > * @freq: frequency the radio was tuned to when receiving this frame, in MHz > * @ssi: signal strength when receiving this frame > > [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 828 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 0/3] IBSS merge final resend
@ 2008-02-18 2:20 Bruno Randolf
2008-02-18 2:20 ` [PATCH 1/3] mac80211: better definition of mactime Bruno Randolf
0 siblings, 1 reply; 13+ messages in thread
From: Bruno Randolf @ 2008-02-18 2:20 UTC (permalink / raw)
To: ath5k-devel
Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes,
flamingice, jbenc
The following series implements IBSS merging.
it is based on wireless-2.6 everything.
bruno
---
Bruno Randolf (3):
mac80211: enable IBSS merging
mac80211: move function ieee80211_sta_join_ibss()
mac80211: better definition of mactime
include/net/mac80211.h | 6 -
net/mac80211/ieee80211_sta.c | 407 +++++++++++++++++++++++-------------------
net/mac80211/rx.c | 5 -
3 files changed, 228 insertions(+), 190 deletions(-)
--
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 1/3] mac80211: better definition of mactime 2008-02-18 2:20 [PATCH 0/3] IBSS merge final resend Bruno Randolf @ 2008-02-18 2:20 ` Bruno Randolf 0 siblings, 0 replies; 13+ messages in thread From: Bruno Randolf @ 2008-02-18 2:20 UTC (permalink / raw) To: ath5k-devel Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes, flamingice, jbenc define mactime as the time when the first data symbol arrived at the HW. the old definition was questionable because 802.11 defines timestamp only for beacon and probe response frames, and there it means the timestamp field. a stricter definition of mactime is necessary for correct merging of IBSS. note that it is up to the driver to convert whatever its hardware returns to this definition. unfortunately we don't know for example when atheros hardware takes its rx timestamp exactly :( Signed-off-by: Bruno Randolf <bruno@thinktube.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> --- include/net/mac80211.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 460da54..1b807f4 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -295,7 +295,8 @@ enum mac80211_rx_flags { * The low-level driver should provide this information (the subset * supported by hardware) to the 802.11 code with each received * frame. - * @mactime: MAC timestamp as defined by 802.11 + * @mactime: value in microseconds of the 64-bit Time Synchronization Function + * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. * @band: the active band when this frame was received * @freq: frequency the radio was tuned to when receiving this frame, in MHz * @ssi: signal strength when receiving this frame ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2008-02-18 11:16 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-02-15 7:01 [PATCH 1/3] mac80211: better definition of mactime Bruno Randolf 2008-02-15 7:01 ` [PATCH 2/3] mac80211: move function ieee80211_sta_join_ibss() Bruno Randolf 2008-02-15 12:52 ` Johannes Berg 2008-02-15 7:02 ` [PATCH 3/3] mac80211: enable IBSS merging Bruno Randolf 2008-02-15 15:09 ` Johannes Berg 2008-02-16 2:29 ` [PATCH] " Bruno Randolf 2008-02-17 9:11 ` Johannes Berg 2008-02-18 1:42 ` bruno randolf 2008-02-18 11:15 ` Johannes Berg 2008-02-18 2:03 ` bruno randolf 2008-02-18 11:16 ` Johannes Berg 2008-02-15 12:52 ` [PATCH 1/3] mac80211: better definition of mactime Johannes Berg -- strict thread matches above, loose matches on Subject: below -- 2008-02-18 2:20 [PATCH 0/3] IBSS merge final resend Bruno Randolf 2008-02-18 2:20 ` [PATCH 1/3] mac80211: better definition of mactime Bruno Randolf
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).