From: Bruno Randolf <bruno@thinktube.com>
To: ath5k-devel@lists.ath5k.org
Cc: mcgrof@gmail.com, jirislaby@gmail.com, mickflemm@gmail.com,
linux-wireless@vger.kernel.org, linville@tuxdriver.com,
johannes@sipsolutions.net, flamingice@sourmilk.net,
jbenc@suse.cz
Subject: [PATCH 3/3] mac80211: enable IBSS merging
Date: Fri, 15 Feb 2008 16:02:02 +0900 [thread overview]
Message-ID: <20080215070202.32461.62689.stgit@one> (raw)
In-Reply-To: <20080215070116.32461.80795.stgit@one>
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
next prev parent reply other threads:[~2008-02-15 7:02 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` Bruno Randolf [this message]
2008-02-15 15:09 ` [PATCH 3/3] mac80211: enable IBSS merging 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:21 ` [PATCH 3/3] mac80211: enable IBSS merging Bruno Randolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080215070202.32461.62689.stgit@one \
--to=bruno@thinktube.com \
--cc=ath5k-devel@lists.ath5k.org \
--cc=flamingice@sourmilk.net \
--cc=jbenc@suse.cz \
--cc=jirislaby@gmail.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=mcgrof@gmail.com \
--cc=mickflemm@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.