linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] ibss merge resend
@ 2008-02-05 10:49 Bruno Randolf
  2008-02-05 10:49 ` [PATCH 1/2] mac80211: move function ieee80211_sta_join_ibss() Bruno Randolf
  2008-02-05 10:49 ` [PATCH 2/2] mac80211: enable IBSS merging Bruno Randolf
  0 siblings, 2 replies; 15+ messages in thread
From: Bruno Randolf @ 2008-02-05 10:49 UTC (permalink / raw)
  To: ath5k-devel
  Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes,
	flamingice, jbenc

hello!

i resend my ibss merge patch, in order to address all issues that have come up
since the first try. the first patch just moves the function
ieee80211_sta_join_ibss(), the second one changes functionality.

greetings, 

bruno

---

Bruno Randolf (2):
      mac80211: enable IBSS merging
      mac80211: move function ieee80211_sta_join_ibss()


 net/mac80211/ieee80211_sta.c |  385 ++++++++++++++++++++++--------------------
 net/mac80211/rx.c            |    5 -
 2 files changed, 204 insertions(+), 186 deletions(-)


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/2] mac80211: move function ieee80211_sta_join_ibss()
  2008-02-05 10:49 [PATCH 0/2] ibss merge resend Bruno Randolf
@ 2008-02-05 10:49 ` Bruno Randolf
  2008-02-05 10:49 ` [PATCH 2/2] mac80211: enable IBSS merging Bruno Randolf
  1 sibling, 0 replies; 15+ messages in thread
From: Bruno Randolf @ 2008-02-05 10:49 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).

Signed-off-by: Bruno Randolf <bruno@thinktube.com>
---

 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 7be1e73..08f89fa 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,
@@ -2894,164 +3053,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] 15+ messages in thread

* [PATCH 2/2] mac80211: enable IBSS merging
  2008-02-05 10:49 [PATCH 0/2] ibss merge resend Bruno Randolf
  2008-02-05 10:49 ` [PATCH 1/2] mac80211: move function ieee80211_sta_join_ibss() Bruno Randolf
@ 2008-02-05 10:49 ` Bruno Randolf
  2008-02-05 11:08   ` Johannes Berg
  1 sibling, 1 reply; 15+ messages in thread
From: Bruno Randolf @ 2008-02-05 10:49 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 ESSID and a TSF
higher than the local TSF (mactime) is received, we have to join its BSSID.

* 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) rather
than the current TSF.

* 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 all 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>
---

 net/mac80211/ieee80211_sta.c |   68 +++++++++++++++++++++++++-----------------
 net/mac80211/rx.c            |    5 ++-
 2 files changed, 45 insertions(+), 28 deletions(-)


diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 08f89fa..7f72f32 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_device *dev,
 	struct ieee80211_sta_bss *bss;
 	struct sta_info *sta;
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	u64 timestamp;
+	u64 timestamp, mactime;
 	DECLARE_MAC_BUF(mac);
 	DECLARE_MAC_BUF(mac2);
 
@@ -2220,30 +2220,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 		return;
 
 	timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
-
-	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
-	    memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
-#ifdef CONFIG_MAC80211_IBSS_DEBUG
-		static unsigned long last_tsf_debug = 0;
-		u64 tsf;
-		if (local->ops->get_tsf)
-			tsf = local->ops->get_tsf(local_to_hw(local));
-		else
-			tsf = -1LLU;
-		if (time_after(jiffies, last_tsf_debug + 5 * HZ)) {
-			printk(KERN_DEBUG "RX beacon SA=%s BSSID="
-			       "%s TSF=0x%llx BCN=0x%llx diff=%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 = jiffies;
-		}
-#endif /* CONFIG_MAC80211_IBSS_DEBUG */
-	}
-
 	ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
 	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
@@ -2329,8 +2305,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
 	bss->band = rx_status->band;
 
-	if (bss->probe_resp && beacon) {
-		/* Do not allow beacon to override data from Probe Response. */
+	if (sdata->vif.type != 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;
 	}
@@ -2434,6 +2412,42 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 	bss->noise = rx_status->noise;
 	if (!beacon)
 		bss->probe_resp++;
+
+	/* check if we need to merge IBSS */
+	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
+	    !local->sta_sw_scanning && !local->sta_hw_scanning &&
+	    mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS &&
+	    memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) {
+		if (rx_status->flag & RX_FLAG_TSFT)
+			/* in order for correct IBSS merging we need mactime */
+			mactime = rx_status->mactime;
+		else if (local && local->ops && local->ops->get_tsf)
+			/* second best option: get current TSF */
+			mactime = local->ops->get_tsf(local_to_hw(local));
+		else
+			/* can't merge without knowing the TSF */
+			mactime = -1LLU;
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+		printk(KERN_DEBUG "RX beacon SA=%s BSSID="
+		       "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
+		       print_mac(mac, mgmt->sa),
+		       print_mac(mac2, mgmt->bssid),
+		       (unsigned long long)mactime,
+		       (unsigned long long)timestamp,
+		       (unsigned long long)(mactime - timestamp),
+		       jiffies);
+#endif /* CONFIG_MAC80211_IBSS_DEBUG */
+		if (mactime <= 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);
 }
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index beda1bf..ed7cf37 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1612,7 +1612,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) == IEEE80211_FTYPE_MGMT &&
+		    (rx->fc & IEEE80211_FCTL_STYPE) == 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 &= ~IEEE80211_TXRXD_RXRA_MATCH;


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] mac80211: enable IBSS merging
  2008-02-05 10:49 ` [PATCH 2/2] mac80211: enable IBSS merging Bruno Randolf
@ 2008-02-05 11:08   ` Johannes Berg
  2008-02-06  2:46     ` [PATCH] addressing johannes latest comments and adding a channel check Bruno Randolf
  2008-02-06  2:49     ` [PATCH] mac80211: enable IBSS merging Bruno Randolf
  0 siblings, 2 replies; 15+ messages in thread
From: Johannes Berg @ 2008-02-05 11:08 UTC (permalink / raw)
  To: Bruno Randolf
  Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc

[-- Attachment #1: Type: text/plain, Size: 735 bytes --]


> +	/* check if we need to merge IBSS */
> +	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
> +	    !local->sta_sw_scanning && !local->sta_hw_scanning &&
> +	    mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS &&
> +	    memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) {

This needs to test whether elems.ssid_len == sdata->u.sta.ssid_len
(before doing the memcmp to not overrun the frame).

> +		if (rx_status->flag & RX_FLAG_TSFT)
> +			/* in order for correct IBSS merging we need mactime */
> +			mactime = rx_status->mactime;

This needs to be documented (with the RX flag I guess) and b43(legacy)
should be changed to include the TSFT in beacon frames in IBSS mode...

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH] addressing johannes latest comments and adding a channel check...
  2008-02-05 11:08   ` Johannes Berg
@ 2008-02-06  2:46     ` Bruno Randolf
  2008-02-06  2:59       ` [ath5k-devel] " bruno randolf
  2008-02-06  2:49     ` [PATCH] mac80211: enable IBSS merging Bruno Randolf
  1 sibling, 1 reply; 15+ messages in thread
From: Bruno Randolf @ 2008-02-06  2:46 UTC (permalink / raw)
  To: ath5k-devel
  Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes,
	flamingice, jbenc

mac80211: enable IBSS merging

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.

* 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) rather
than the current TSF. since some drivers are not able to give a reliable
mactime we fall back to use the current TSF, which will be enough to catch 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 |   70 ++++++++++++++++++++++++++----------------
 net/mac80211/rx.c            |    5 ++-
 3 files changed, 49 insertions(+), 29 deletions(-)


diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 460da54..4ae3a12 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 field)
- *	is valid.
+ *	is valid. This is useful in monitor mode and necessary for beacon frames
+ *	to enable IBSS merging.
  */
 enum mac80211_rx_flags {
 	RX_FLAG_MMIC_ERROR	= 1<<0,
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 08f89fa..4df18ae 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_device *dev,
 	struct ieee80211_sta_bss *bss;
 	struct sta_info *sta;
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	u64 timestamp;
+	u64 timestamp, mactime;
 	DECLARE_MAC_BUF(mac);
 	DECLARE_MAC_BUF(mac2);
 
@@ -2220,30 +2220,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 		return;
 
 	timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
-
-	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
-	    memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
-#ifdef CONFIG_MAC80211_IBSS_DEBUG
-		static unsigned long last_tsf_debug = 0;
-		u64 tsf;
-		if (local->ops->get_tsf)
-			tsf = local->ops->get_tsf(local_to_hw(local));
-		else
-			tsf = -1LLU;
-		if (time_after(jiffies, last_tsf_debug + 5 * HZ)) {
-			printk(KERN_DEBUG "RX beacon SA=%s BSSID="
-			       "%s TSF=0x%llx BCN=0x%llx diff=%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 = jiffies;
-		}
-#endif /* CONFIG_MAC80211_IBSS_DEBUG */
-	}
-
 	ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
 	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
@@ -2329,8 +2305,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
 	bss->band = rx_status->band;
 
-	if (bss->probe_resp && beacon) {
-		/* Do not allow beacon to override data from Probe Response. */
+	if (sdata->vif.type != 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;
 	}
@@ -2434,6 +2412,44 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 	bss->noise = rx_status->noise;
 	if (!beacon)
 		bss->probe_resp++;
+
+	/* check if we need to merge IBSS */
+	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
+	    !local->sta_sw_scanning && !local->sta_hw_scanning &&
+	    mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS &&
+	    bss->freq == local->oper_channel->center_freq &&
+	    elems.ssid_len == sdata->u.sta.ssid_len &&
+	    memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) {
+		if (rx_status->flag & RX_FLAG_TSFT)
+			/* in order for correct IBSS merging we need mactime */
+			mactime = rx_status->mactime;
+		else if (local && local->ops && local->ops->get_tsf)
+			/* second best option: get current TSF */
+			mactime = local->ops->get_tsf(local_to_hw(local));
+		else
+			/* can't merge without knowing the TSF */
+			mactime = -1LLU;
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+		printk(KERN_DEBUG "RX beacon SA=%s BSSID="
+		       "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
+		       print_mac(mac, mgmt->sa),
+		       print_mac(mac2, mgmt->bssid),
+		       (unsigned long long)mactime,
+		       (unsigned long long)timestamp,
+		       (unsigned long long)(mactime - timestamp),
+		       jiffies);
+#endif /* CONFIG_MAC80211_IBSS_DEBUG */
+		if (mactime <= 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);
 }
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index beda1bf..ed7cf37 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1612,7 +1612,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) == IEEE80211_FTYPE_MGMT &&
+		    (rx->fc & IEEE80211_FCTL_STYPE) == 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 &= ~IEEE80211_TXRXD_RXRA_MATCH;


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH] mac80211: enable IBSS merging
  2008-02-05 11:08   ` Johannes Berg
  2008-02-06  2:46     ` [PATCH] addressing johannes latest comments and adding a channel check Bruno Randolf
@ 2008-02-06  2:49     ` Bruno Randolf
  2008-02-06 23:52       ` Johannes Berg
  1 sibling, 1 reply; 15+ messages in thread
From: Bruno Randolf @ 2008-02-06  2:49 UTC (permalink / raw)
  To: ath5k-devel
  Cc: mcgrof, jirislaby, mickflemm, linux-wireless, linville, johannes,
	flamingice, jbenc

addressing johannes latest comments and adding a channel check...

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.

* 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) rather
than the current TSF. since some drivers are not able to give a reliable
mactime we fall back to use the current TSF, which will be enough to catch 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 |   70 ++++++++++++++++++++++++++----------------
 net/mac80211/rx.c            |    5 ++-
 3 files changed, 49 insertions(+), 29 deletions(-)


diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 460da54..4ae3a12 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 field)
- *	is valid.
+ *	is valid. This is useful in monitor mode and necessary for beacon frames
+ *	to enable IBSS merging.
  */
 enum mac80211_rx_flags {
 	RX_FLAG_MMIC_ERROR	= 1<<0,
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 08f89fa..4df18ae 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_device *dev,
 	struct ieee80211_sta_bss *bss;
 	struct sta_info *sta;
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	u64 timestamp;
+	u64 timestamp, mactime;
 	DECLARE_MAC_BUF(mac);
 	DECLARE_MAC_BUF(mac2);
 
@@ -2220,30 +2220,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 		return;
 
 	timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
-
-	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
-	    memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
-#ifdef CONFIG_MAC80211_IBSS_DEBUG
-		static unsigned long last_tsf_debug = 0;
-		u64 tsf;
-		if (local->ops->get_tsf)
-			tsf = local->ops->get_tsf(local_to_hw(local));
-		else
-			tsf = -1LLU;
-		if (time_after(jiffies, last_tsf_debug + 5 * HZ)) {
-			printk(KERN_DEBUG "RX beacon SA=%s BSSID="
-			       "%s TSF=0x%llx BCN=0x%llx diff=%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 = jiffies;
-		}
-#endif /* CONFIG_MAC80211_IBSS_DEBUG */
-	}
-
 	ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
 	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
@@ -2329,8 +2305,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
 	bss->band = rx_status->band;
 
-	if (bss->probe_resp && beacon) {
-		/* Do not allow beacon to override data from Probe Response. */
+	if (sdata->vif.type != 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;
 	}
@@ -2434,6 +2412,44 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 	bss->noise = rx_status->noise;
 	if (!beacon)
 		bss->probe_resp++;
+
+	/* check if we need to merge IBSS */
+	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
+	    !local->sta_sw_scanning && !local->sta_hw_scanning &&
+	    mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS &&
+	    bss->freq == local->oper_channel->center_freq &&
+	    elems.ssid_len == sdata->u.sta.ssid_len &&
+	    memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) {
+		if (rx_status->flag & RX_FLAG_TSFT)
+			/* in order for correct IBSS merging we need mactime */
+			mactime = rx_status->mactime;
+		else if (local && local->ops && local->ops->get_tsf)
+			/* second best option: get current TSF */
+			mactime = local->ops->get_tsf(local_to_hw(local));
+		else
+			/* can't merge without knowing the TSF */
+			mactime = -1LLU;
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+		printk(KERN_DEBUG "RX beacon SA=%s BSSID="
+		       "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
+		       print_mac(mac, mgmt->sa),
+		       print_mac(mac2, mgmt->bssid),
+		       (unsigned long long)mactime,
+		       (unsigned long long)timestamp,
+		       (unsigned long long)(mactime - timestamp),
+		       jiffies);
+#endif /* CONFIG_MAC80211_IBSS_DEBUG */
+		if (mactime <= 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);
 }
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index beda1bf..ed7cf37 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1612,7 +1612,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) == IEEE80211_FTYPE_MGMT &&
+		    (rx->fc & IEEE80211_FCTL_STYPE) == 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 &= ~IEEE80211_TXRXD_RXRA_MATCH;


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [ath5k-devel] [PATCH] addressing johannes latest comments and adding a channel check...
  2008-02-06  2:46     ` [PATCH] addressing johannes latest comments and adding a channel check Bruno Randolf
@ 2008-02-06  2:59       ` bruno randolf
  0 siblings, 0 replies; 15+ messages in thread
From: bruno randolf @ 2008-02-06  2:59 UTC (permalink / raw)
  To: ath5k-devel
  Cc: jirislaby, flamingice, linux-wireless, linville, jbenc, johannes

uups, sorry stg mail (well, i...) confused the subject lines

bruno

On Wednesday 06 February 2008 11:46:40 Bruno Randolf wrote:
> mac80211: enable IBSS merging
>
> 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.
>
> * 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) rather
> than the current TSF. since some drivers are not able to give a reliable
> mactime we fall back to use the current TSF, which will be enough to catch
> 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 |   70
> ++++++++++++++++++++++++++---------------- net/mac80211/rx.c            |  
>  5 ++-
>  3 files changed, 49 insertions(+), 29 deletions(-)
>
>
> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
> index 460da54..4ae3a12 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 field)
> - *	is valid.
> + *	is valid. This is useful in monitor mode and necessary for beacon
> frames + *	to enable IBSS merging.
>   */
>  enum mac80211_rx_flags {
>  	RX_FLAG_MMIC_ERROR	= 1<<0,
> diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
> index 08f89fa..4df18ae 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_device
> *dev, struct ieee80211_sta_bss *bss;
>  	struct sta_info *sta;
>  	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
> -	u64 timestamp;
> +	u64 timestamp, mactime;
>  	DECLARE_MAC_BUF(mac);
>  	DECLARE_MAC_BUF(mac2);
>
> @@ -2220,30 +2220,6 @@ static void ieee80211_rx_bss_info(struct net_device
> *dev, return;
>
>  	timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
> -
> -	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
> -	    memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
> -#ifdef CONFIG_MAC80211_IBSS_DEBUG
> -		static unsigned long last_tsf_debug = 0;
> -		u64 tsf;
> -		if (local->ops->get_tsf)
> -			tsf = local->ops->get_tsf(local_to_hw(local));
> -		else
> -			tsf = -1LLU;
> -		if (time_after(jiffies, last_tsf_debug + 5 * HZ)) {
> -			printk(KERN_DEBUG "RX beacon SA=%s BSSID="
> -			       "%s TSF=0x%llx BCN=0x%llx diff=%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 = jiffies;
> -		}
> -#endif /* CONFIG_MAC80211_IBSS_DEBUG */
> -	}
> -
>  	ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
>
>  	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
> @@ -2329,8 +2305,10 @@ static void ieee80211_rx_bss_info(struct net_device
> *dev,
>
>  	bss->band = rx_status->band;
>
> -	if (bss->probe_resp && beacon) {
> -		/* Do not allow beacon to override data from Probe Response. */
> +	if (sdata->vif.type != 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;
>  	}
> @@ -2434,6 +2412,44 @@ static void ieee80211_rx_bss_info(struct net_device
> *dev, bss->noise = rx_status->noise;
>  	if (!beacon)
>  		bss->probe_resp++;
> +
> +	/* check if we need to merge IBSS */
> +	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
> +	    !local->sta_sw_scanning && !local->sta_hw_scanning &&
> +	    mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS &&
> +	    bss->freq == local->oper_channel->center_freq &&
> +	    elems.ssid_len == sdata->u.sta.ssid_len &&
> +	    memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) {
> +		if (rx_status->flag & RX_FLAG_TSFT)
> +			/* in order for correct IBSS merging we need mactime */
> +			mactime = rx_status->mactime;
> +		else if (local && local->ops && local->ops->get_tsf)
> +			/* second best option: get current TSF */
> +			mactime = local->ops->get_tsf(local_to_hw(local));
> +		else
> +			/* can't merge without knowing the TSF */
> +			mactime = -1LLU;
> +#ifdef CONFIG_MAC80211_IBSS_DEBUG
> +		printk(KERN_DEBUG "RX beacon SA=%s BSSID="
> +		       "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
> +		       print_mac(mac, mgmt->sa),
> +		       print_mac(mac2, mgmt->bssid),
> +		       (unsigned long long)mactime,
> +		       (unsigned long long)timestamp,
> +		       (unsigned long long)(mactime - timestamp),
> +		       jiffies);
> +#endif /* CONFIG_MAC80211_IBSS_DEBUG */
> +		if (mactime <= 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);
>  }
>
> diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> index beda1bf..ed7cf37 100644
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -1612,7 +1612,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) == IEEE80211_FTYPE_MGMT &&
> +		    (rx->fc & IEEE80211_FCTL_STYPE) == 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 &= ~IEEE80211_TXRXD_RXRA_MATCH;
>
> _______________________________________________
> ath5k-devel mailing list
> ath5k-devel@lists.ath5k.org
> https://lists.ath5k.org/mailman/listinfo/ath5k-devel



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] mac80211: enable IBSS merging
  2008-02-06  2:49     ` [PATCH] mac80211: enable IBSS merging Bruno Randolf
@ 2008-02-06 23:52       ` Johannes Berg
  2008-02-08  9:25         ` Luis R. Rodriguez
  2008-02-12  3:25         ` bruno randolf
  0 siblings, 2 replies; 15+ messages in thread
From: Johannes Berg @ 2008-02-06 23:52 UTC (permalink / raw)
  To: Bruno Randolf
  Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc

[-- Attachment #1: Type: text/plain, Size: 1631 bytes --]

Looks fine, one last question:

> +		if (mactime <= 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));

I'd rewrite that as timestamp >= mactime and rename the two variables
(maybe beacon_timestamp and phy_timestamp or so?), but that's not too
important. However, in any case "<=" seems wrong, shouldn't we only
merge when it's actually higher? If your hardware/firmware has synced
properly and the PHY delay is accounted for properly etc. then every
beacon from the own BSS will fulfil the == part of the condition, no?

Also, the beacon timestamp is defined as follows:

        A STA sending a beacon shall set the value of the beacon’s
        timestamp so that it equals the value of the STA’s TSF timer at
        the time that the data symbol containing the first bit of the
        timestamp is transmitted to the PHY plus the transmitting STA’s
        delays through its local PHY from the MAC-PHY interface to its
        interface with the WM [e.g., antenna, light-emitting diode (LED)
        emission surface].

(IEEE 802.11 11.1.2)

Since we define the RX timestamp to be when the first data symbol of the
frame hits the PHY, we here have to take into account the offset between
the two, at 1 MBit that's 192 (=24 bytes * 8 usecs/byte) usecs earlier
than the beacon timestamp.

On the other hand, you're unlikely to hit that window, but I suppose it
warrants at least a comment.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] mac80211: enable IBSS merging
  2008-02-06 23:52       ` Johannes Berg
@ 2008-02-08  9:25         ` Luis R. Rodriguez
  2008-02-12  3:25         ` bruno randolf
  1 sibling, 0 replies; 15+ messages in thread
From: Luis R. Rodriguez @ 2008-02-08  9:25 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Bruno Randolf, ath5k-devel, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc

On Feb 6, 2008 6:52 PM, Johannes Berg <johannes@sipsolutions.net> wrote:
> Looks fine, one last question:
>
> > +             if (mactime <= 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));
>
> I'd rewrite that as timestamp >= mactime and rename the two variables
> (maybe beacon_timestamp and phy_timestamp or so?), but that's not too
> important. However, in any case "<=" seems wrong, shouldn't we only
> merge when it's actually higher? If your hardware/firmware has synced
> properly and the PHY delay is accounted for properly etc. then every
> beacon from the own BSS will fulfil the == part of the condition, no?
>
> Also, the beacon timestamp is defined as follows:
>
>         A STA sending a beacon shall set the value of the beacon's
>         timestamp so that it equals the value of the STA's TSF timer at
>         the time that the data symbol containing the first bit of the
>         timestamp is transmitted to the PHY plus the transmitting STA's
>         delays through its local PHY from the MAC-PHY interface to its
>         interface with the WM [e.g., antenna, light-emitting diode (LED)
>         emission surface].
>
> (IEEE 802.11 11.1.2)
>
> Since we define the RX timestamp to be when the first data symbol of the
> frame hits the PHY, we here have to take into account the offset between
> the two, at 1 MBit that's 192 (=24 bytes * 8 usecs/byte) usecs earlier
> than the beacon timestamp.
>
> On the other hand, you're unlikely to hit that window, but I suppose it
> warrants at least a comment.

Agreed, "mactime" is pretty vague, if we can add some of the above to
the documentation it would probably help other driver developers.

  Luis

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] mac80211: enable IBSS merging
  2008-02-06 23:52       ` Johannes Berg
  2008-02-08  9:25         ` Luis R. Rodriguez
@ 2008-02-12  3:25         ` bruno randolf
  2008-02-12  9:50           ` Johannes Berg
  2008-02-12  9:52           ` Johannes Berg
  1 sibling, 2 replies; 15+ messages in thread
From: bruno randolf @ 2008-02-12  3:25 UTC (permalink / raw)
  To: Johannes Berg
  Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc

On Thursday 07 February 2008 08:52:35 Johannes Berg wrote:
> Looks fine, one last question:
> > +		if (mactime <=3D 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));
>
> I'd rewrite that as timestamp >=3D mactime and rename the two variabl=
es
> (maybe beacon_timestamp and phy_timestamp or so?), but that's not too
> important.

i'll do that, sure.

> However, in any case "<=3D" seems wrong, shouldn't we only=20
> merge when it's actually higher? If your hardware/firmware has synced
> properly and the PHY delay is accounted for properly etc. then every
> beacon from the own BSS will fulfil the =3D=3D part of the condition,=
 no?

true. i was not aware that the beacon timestamp is taking PHY delays in=
to=20
account and wrongly asumed that the RX timestamp should always be a bit=
=20
later.
(which is also what i saw on my atheros hardware: we usually get the RX=
=20
timestamp about 60 to 300 usec later than the beacon timestamp, but it'=
s=20
quite likely that we have not calibrated everything 100% correctly.)

> Also, the beacon timestamp is defined as follows:
>
>         A STA sending a beacon shall set the value of the beacon=E2=80=
=99s
>         timestamp so that it equals the value of the STA=E2=80=99s TS=
=46 timer at
>         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 it=
s
>         interface with the WM [e.g., antenna, light-emitting diode (L=
ED)
>         emission surface].
>
> (IEEE 802.11 11.1.2)
>
> Since we define the RX timestamp to be when the first data symbol of =
the
> frame hits the PHY, we here have to take into account the offset betw=
een
> the two, at 1 MBit that's 192 (=3D24 bytes * 8 usecs/byte) usecs earl=
ier
> than the beacon timestamp.
>
> On the other hand, you're unlikely to hit that window, but I suppose =
it
> warrants at least a comment.

thats a very good point! if everything was calibrated properly and all =
delays=20
taken into account *exactly* that would cause us to go thru a merge all=
 the=20
time, on every received beacon. i think we have to take that into accou=
nt,=20
for different bitrates. what about something like:

timestamp >=3D ( mactime + (24 * 8 / beacon_phy_rate_in_mbps ))

i'll resend my patch adding that and the other proposed changes soon.

bruno
-
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	[flat|nested] 15+ messages in thread

* Re: [PATCH] mac80211: enable IBSS merging
  2008-02-12  3:25         ` bruno randolf
@ 2008-02-12  9:50           ` Johannes Berg
  2008-02-14  6:19             ` bruno randolf
  2008-02-12  9:52           ` Johannes Berg
  1 sibling, 1 reply; 15+ messages in thread
From: Johannes Berg @ 2008-02-12  9:50 UTC (permalink / raw)
  To: bruno randolf
  Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc

[-- Attachment #1: Type: text/plain, Size: 580 bytes --]


> thats a very good point! if everything was calibrated properly and all delays 
> taken into account *exactly* that would cause us to go thru a merge all the 
> time, on every received beacon. i think we have to take that into account, 
> for different bitrates. what about something like:
> 
> timestamp >= ( mactime + (24 * 8 / beacon_phy_rate_in_mbps ))

Looks reasonable, though I'm not entirely sure how we defined 'mactime'
and whether it is at the first data or the first phy symbol. I think
it's at the first data symbol which makes this correct.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] mac80211: enable IBSS merging
  2008-02-12  3:25         ` bruno randolf
  2008-02-12  9:50           ` Johannes Berg
@ 2008-02-12  9:52           ` Johannes Berg
  2008-02-14 10:19             ` bruno randolf
  1 sibling, 1 reply; 15+ messages in thread
From: Johannes Berg @ 2008-02-12  9:52 UTC (permalink / raw)
  To: bruno randolf
  Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc

[-- Attachment #1: Type: text/plain, Size: 589 bytes --]


> true. i was not aware that the beacon timestamp is taking PHY delays into 
> account and wrongly asumed that the RX timestamp should always be a bit 
> later.
> (which is also what i saw on my atheros hardware: we usually get the RX 
> timestamp about 60 to 300 usec later than the beacon timestamp, but it's 
> quite likely that we have not calibrated everything 100% correctly.)

Later actually surprises me, are you sure it's not earlier? If
everything was calibrated perfectly it should be 192 usecs earlier (24*8
bytes at the most common 1mbit beacon rate).

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] mac80211: enable IBSS merging
  2008-02-12  9:50           ` Johannes Berg
@ 2008-02-14  6:19             ` bruno randolf
  2008-02-14 14:12               ` Johannes Berg
  0 siblings, 1 reply; 15+ messages in thread
From: bruno randolf @ 2008-02-14  6:19 UTC (permalink / raw)
  To: Johannes Berg
  Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc

On Tuesday 12 February 2008 18:50:19 Johannes Berg wrote:
> > thats a very good point! if everything was calibrated properly and =
all
> > delays taken into account *exactly* that would cause us to go thru =
a
> > merge all the time, on every received beacon. i think we have to ta=
ke
> > that into account, for different bitrates. what about something lik=
e:
> >
> > timestamp >=3D ( mactime + (24 * 8 / beacon_phy_rate_in_mbps ))
>
> Looks reasonable, though I'm not entirely sure how we defined 'mactim=
e'
> and whether it is at the first data or the first phy symbol. I think
> it's at the first data symbol which makes this correct.

hmm, it seems we don't have a strict definition of mactime... the kerne=
ldoc of=20
struct ieee80211_rx_status says:
 * @mactime: MAC timestamp as defined by 802.11

but as far as i understand 802.11, it only defines "timestamp" for beac=
on and=20
probe response frames, where it actually means the timestamp field of t=
he=20
frame.

"Local Time" is defined as: "The value of the STA=E2=80=99s TSF timer a=
t the start of=20
reception of the first octet of the timestamp field of the received fra=
me=20
(probe response or beacon) from the found BSS." [802.11 p. 103]

also in "Process Validate_MPDU: it says:
"Save arrival time of first octet of {what may be a} timestamp field."
[802.11 p 391 and 460]

which could imply that this value is given as a rx timestamp (mactime).=
 in=20
that case we could directly compare timestamp and mactime.

radiotap on the other hand defines it as the first bit of the data (MPD=
U):
 * IEEE80211_RADIOTAP_TSFT              u_int64_t       microseconds
 *
 *      Value in microseconds of the MAC's 64-bit 802.11 Time
 *      Synchronization Function timer when the first bit of the
 *      MPDU arrived at the MAC. For received frames, only.

so i guess right now it depends on the hardware what we actually get as=
=20
mactime...

i could not find any definition when the rx timestamp of atheros hardwa=
re is=20
taken.

do we have that information for other hardware? is mactime
 *) the TSF at the reception of the first phy symbol?
 *) the TSF at the reception of the first data (MPDU) symbol
 *) the TSF at the reception of the byte 24 (where the timestamp field =
of
    beacon and probe response frames is)?

bruno
-
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	[flat|nested] 15+ messages in thread

* Re: [PATCH] mac80211: enable IBSS merging
  2008-02-12  9:52           ` Johannes Berg
@ 2008-02-14 10:19             ` bruno randolf
  0 siblings, 0 replies; 15+ messages in thread
From: bruno randolf @ 2008-02-14 10:19 UTC (permalink / raw)
  To: Johannes Berg
  Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc, Ulrich Meis

On Tuesday 12 February 2008 18:52:03 Johannes Berg wrote:
> > true. i was not aware that the beacon timestamp is taking PHY delays into
> > account and wrongly asumed that the RX timestamp should always be a bit
> > later.
> > (which is also what i saw on my atheros hardware: we usually get the RX
> > timestamp about 60 to 300 usec later than the beacon timestamp, but it's
> > quite likely that we have not calibrated everything 100% correctly.)
>
> Later actually surprises me, are you sure it's not earlier? If
> everything was calibrated perfectly it should be 192 usecs earlier (24*8
> bytes at the most common 1mbit beacon rate).

yes, i'm sure that it's later. our debug printk shows diff= (rx_tsf - 
beacon_tsf) and it's positive.

ulrich meis also confirmed that, but i think his message to the list got lost.

i'm not so surprised about that because the hardware would have to be 
calibrated 100% correctly to compensate for the TX delay as well as the RX 
delay (if both sides use ath5k) and it's really quite likely that we don't do 
that right for ath5k yet.

please see also my previous mail, i think that mactime is not well defined as 
well :(

bruno

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] mac80211: enable IBSS merging
  2008-02-14  6:19             ` bruno randolf
@ 2008-02-14 14:12               ` Johannes Berg
  0 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2008-02-14 14:12 UTC (permalink / raw)
  To: bruno randolf
  Cc: ath5k-devel, mcgrof, jirislaby, mickflemm, linux-wireless,
	linville, flamingice, jbenc

[-- Attachment #1: Type: text/plain, Size: 1413 bytes --]


> hmm, it seems we don't have a strict definition of mactime... the kerneldoc of 
> struct ieee80211_rx_status says:
>  * @mactime: MAC timestamp as defined by 802.11

Heh.

> radiotap on the other hand defines it as the first bit of the data (MPDU):
>  * IEEE80211_RADIOTAP_TSFT              u_int64_t       microseconds
>  *
>  *      Value in microseconds of the MAC's 64-bit 802.11 Time
>  *      Synchronization Function timer when the first bit of the
>  *      MPDU arrived at the MAC. For received frames, only.

Yeah I think that makes most sense and is how it is usually implemented
anyway.

> so i guess right now it depends on the hardware what we actually get as 
> mactime...

> do we have that information for other hardware? is mactime
>  *) the TSF at the reception of the first phy symbol?
>  *) the TSF at the reception of the first data (MPDU) symbol
>  *) the TSF at the reception of the byte 24 (where the timestamp field of
>     beacon and probe response frames is)?

I very much doubt there is hardware that does the last option because
there may be frames that are shorted than 24 bytes :)

The difference between the first two options is a simple constant
(depending on the PHY mode) so the driver for hardware that supports
either one of those two options can easily translate them. Hence, I
think we should declare it like radiotap does.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2008-02-14 14:12 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-05 10:49 [PATCH 0/2] ibss merge resend Bruno Randolf
2008-02-05 10:49 ` [PATCH 1/2] mac80211: move function ieee80211_sta_join_ibss() Bruno Randolf
2008-02-05 10:49 ` [PATCH 2/2] mac80211: enable IBSS merging Bruno Randolf
2008-02-05 11:08   ` Johannes Berg
2008-02-06  2:46     ` [PATCH] addressing johannes latest comments and adding a channel check Bruno Randolf
2008-02-06  2:59       ` [ath5k-devel] " bruno randolf
2008-02-06  2:49     ` [PATCH] mac80211: enable IBSS merging Bruno Randolf
2008-02-06 23:52       ` Johannes Berg
2008-02-08  9:25         ` Luis R. Rodriguez
2008-02-12  3:25         ` bruno randolf
2008-02-12  9:50           ` Johannes Berg
2008-02-14  6:19             ` bruno randolf
2008-02-14 14:12               ` Johannes Berg
2008-02-12  9:52           ` Johannes Berg
2008-02-14 10:19             ` 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).