I am seeing some strange behavior in IBSS mode with current wireless-testing.
Scenario:
* Create a new cell using ath9k.
* Wait for a while to do a background merge scan run.
* Join the cell from another peer ( say, using ath5k ).
* Station dump in peer1 1 doesn't show the new peer right away.
* The merge runs are not supposed to happen if a cell has more than one peer.
It didn't happen before, but it keeps running repeatedly now.
* Ping from peer2 to peer1 doesn't go through - peer1 to peer2 works though.
Joining an existing IBSS network using ath9k works fine, no issues here.
Also, if the second peer joins the cell quickly, before the scan run, things are okay.
I identified one bug, where the timestamp in the beacon template was not updated.
Patch below. But it doesn't fix the issue.
Any clues ?
Sujith
In IBSS mode, the beacon timestamp has to be filled with the
BSS's timestamp when joining, and set to zero when creating
a new BSS.
Signed-off-by: Sujith <[email protected]>
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index a96ce9d..f4becc1 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -64,7 +64,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
const int freq,
const size_t supp_rates_len,
const u8 *supp_rates,
- const u16 capability)
+ const u16 capability, u64 tsf)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_local *local = sdata->local;
@@ -127,6 +127,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
mgmt->u.beacon.beacon_int =
cpu_to_le16(local->hw.conf.beacon_int);
+ mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
mgmt->u.beacon.capab_info = cpu_to_le16(capability);
pos = skb_put(skb, 2 + ifibss->ssid_len);
@@ -199,7 +200,8 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
bss->cbss.beacon_interval,
bss->cbss.channel->center_freq,
bss->supp_rates_len, bss->supp_rates,
- bss->cbss.capability);
+ bss->cbss.capability,
+ bss->cbss.tsf);
}
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -502,7 +504,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
bssid, local->hw.conf.beacon_int,
local->hw.conf.channel->center_freq,
sband->n_bitrates, supp_rates,
- capability);
+ capability, 0);
}
static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
Hi Sujith!
> I am seeing some strange behavior in IBSS mode with current
> wireless-testing.
>=20
> Scenario:
>=20
> * Create a new cell using ath9k.
> * Wait for a while to do a background merge scan run.
> * Join the cell from another peer ( say, using ath5k ).
> * Station dump in peer1 1 doesn't show the new peer right away.
> * The merge runs are not supposed to happen if a cell has more than =
one
> peer.
> It didn't happen before, but it keeps running repeatedly now.
> * Ping from peer2 to peer1 doesn't go through - peer1 to peer2 works
> though.
The strange thing is after the ping from peer1 to peer2, the ping from =
peer2 to peer1 works too. The same is if I start tcpdump on peer1. Afte=
r stopping tcpdump it keeps working. Looking...
> I identified one bug, where the timestamp in the beacon template was =
not
> updated.
> Patch below. But it doesn't fix the issue.
The TSF of the beacon is setted by the hardware automatically, so to wr=
ite it in the template is not needed.
Regards
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
Alina Friedrichsen wrote:
> Maybe because the scanning code was changed? But I have discovered this bug
> at the end of the last year before the scanning code was changed the last time.
Not sure, but this is a bug for sure.
> > And it can be fixed by
> > making use of the scan start/stop mac80211 callbacks.
>
> I think a much cleaner way would be if the ath9k_hw_write_associd() honor the FIF_BCN_PRBRESP_PROMISC flag and determine with it if sc->curbssid should be set or ath_bcast_mac. So the the old sc->curbssid setting is saved. And then remove the following code...
>
> if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
> memcpy(sc->curbssid, ath_bcast_mac, ETH_ALEN);
> sc->curaid = 0;
>
> ...so that ath9k_hw_write_associd() is called if the FIF_BCN_PRBRESP_PROMISC is cleared at the end of the scanning, too. So that it can set the BSSID in the hardware back to sc->curbssid.
>
Sure, either way works, since FIF_BCN_PRBRESP_PROMISC is set only during scanning
anyway.
Sujith
Alina Friedrichsen wrote:
> But is it calculated only one time after the join? The TSF value in the template is
> really fast outdated. I think why not let __ieee80211_sta_join_ibss() call the
> set_tsf() callback, so that the TSF is mostly synced from the beginning on
> and fine-tuned later by the hardware?
Yes, the TBTT is calculated only once after joining the BSS network.
Am not sure I understand the proposal. What would the tsf value in set_tsf() be ?
11.1.4 (IEEE802.11-2007) says that the TSF has to be reset to zero on joining
an IBSS network. We do that correctly. To calculate the next TBTT, we can't use the
HW TSF, since it has just been reset. And the Beacon's timestamp + intval + FUDGE
is what we do in ath9k to get the TBTT for this peer, which I think is correct.
A sniffer shows the beacon generation being evenly distributed.
Sujith
On Fri, 2009-02-27 at 16:02 +0530, Sujith wrote:
> Alina Friedrichsen wrote:
> > Maybe because the scanning code was changed? But I have discovered this bug
> > at the end of the last year before the scanning code was changed the last time.
>
> Not sure, but this is a bug for sure.
>
> > > And it can be fixed by
> > > making use of the scan start/stop mac80211 callbacks.
> >
> > I think a much cleaner way would be if the ath9k_hw_write_associd() honor the FIF_BCN_PRBRESP_PROMISC flag and determine with it if sc->curbssid should be set or ath_bcast_mac. So the the old sc->curbssid setting is saved. And then remove the following code...
> >
> > if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
> > memcpy(sc->curbssid, ath_bcast_mac, ETH_ALEN);
> > sc->curaid = 0;
> >
> > ...so that ath9k_hw_write_associd() is called if the FIF_BCN_PRBRESP_PROMISC is cleared at the end of the scanning, too. So that it can set the BSSID in the hardware back to sc->curbssid.
> >
>
> Sure, either way works, since FIF_BCN_PRBRESP_PROMISC is set only during scanning
> anyway.
It can be set manually with monitor interface I think.
johannes
Hi Sujith!
> The strange thing is after the ping from peer1 to peer2, the ping fro=
m
> peer2 to peer1 works too. The same is if I start tcpdump on peer1. Af=
ter
> stopping tcpdump it keeps working. Looking...
I found it. :)
The problem is the following code:
[drivers/net/wireless/ath9k/main.c, ath9k_configure_filter(), line 2399=
]
if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
memcpy(sc->curbssid, ath_bcast_mac, ETH_ALEN);
sc->curaid =3D 0;
ath9k_hw_write_associd(sc);
}
}
On scanning the BSSID is set to the broadcast MAC, but never set back.
Im not sure how to fix it in the cleanest way. I know to less about the=
handling of multi interface devices. ath9k people can you help please?
Thanks
Alina
--=20
Computer Bild Tarifsieger! GMX FreeDSL - Telefonanschluss + DSL
f=FCr nur 17,95 =BF/mtl.!* http://dsl.gmx.de/?ac=3DOM.AD.PD003K11308T45=
69a
Alina Friedrichsen wrote:
> Hi Sujith!
>
> > The strange thing is after the ping from peer1 to peer2, the ping from
> > peer2 to peer1 works too. The same is if I start tcpdump on peer1. After
> > stopping tcpdump it keeps working. Looking...
>
> I found it. :)
> The problem is the following code:
> [drivers/net/wireless/ath9k/main.c, ath9k_configure_filter(), line 2399]
>
> if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
> if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
> memcpy(sc->curbssid, ath_bcast_mac, ETH_ALEN);
> sc->curaid = 0;
> ath9k_hw_write_associd(sc);
> }
> }
>
> On scanning the BSSID is set to the broadcast MAC, but never set back.
>
> Im not sure how to fix it in the cleanest way. I know to less about the handling of multi interface devices. ath9k people can you help please?
>
Yep, that is the problem. But that chunk of code (and the bug) has been there forever,
so am not sure why it is creating a problem now. And it can be fixed by
making use of the scan start/stop mac80211 callbacks.
Thanks a lot !
Sujith
Alina Friedrichsen wrote:
> > Scenario:
> >
> > * Create a new cell using ath9k.
> > * Wait for a while to do a background merge scan run.
> > * Join the cell from another peer ( say, using ath5k ).
> > * Station dump in peer1 1 doesn't show the new peer right away.
> > * The merge runs are not supposed to happen if a cell has more than one
> > peer.
> > It didn't happen before, but it keeps running repeatedly now.
> > * Ping from peer2 to peer1 doesn't go through - peer1 to peer2 works
> > though.
>
> The strange thing is after the ping from peer1 to peer2, the ping from peer2 to peer1 works too.
> The same is if I start tcpdump on peer1. After stopping tcpdump it keeps working. Looking...
>
Yep. It works after the ping from peer1 to peer2.
> > I identified one bug, where the timestamp in the beacon template was not
> > updated.
> > Patch below. But it doesn't fix the issue.
>
> The TSF of the beacon is setted by the hardware automatically, so to write it in the template is not needed.
When peer2 joins the cell, the next TBTT is calculated based on the received beacon's
timestamp. And since the TSF is reset in __ieee80211_sta_join_ibss(), to program
the TBTT timers, the timestamp is needed.
Sujith
Hi Sujith!
> Yep, that is the problem. But that chunk of code (and the bug) has be=
en
> there forever,
> so am not sure why it is creating a problem now.
Maybe because the scanning code was changed? But I have discovered this=
bug at the end of the last year before the scanning code was changed t=
he last time.
> And it can be fixed by
> making use of the scan start/stop mac80211 callbacks.
I think a much cleaner way would be if the ath9k_hw_write_associd() hon=
or the FIF_BCN_PRBRESP_PROMISC flag and determine with it if sc->curbss=
id should be set or ath_bcast_mac. So the the old sc->curbssid setting =
is saved. And then remove the following code...
if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
memcpy(sc->curbssid, ath_bcast_mac, ETH_ALEN);
sc->curaid =3D 0;
=2E..so that ath9k_hw_write_associd() is called if the FIF_BCN_PRBRESP_=
PROMISC is cleared at the end of the scanning, too. So that it can set =
the BSSID in the hardware back to sc->curbssid.
Regards
Alina
--=20
Psssst! Schon vom neuen GMX MultiMessenger geh=F6rt? Der kann`s mit all=
en: http://www.gmx.net/de/go/multimessenger01
Hi Sujith!
> When peer2 joins the cell, the next TBTT is calculated based on the
> received beacon's
> timestamp. And since the TSF is reset in __ieee80211_sta_join_ibss(),=
to
> program
> the TBTT timers, the timestamp is needed.
But is it calculated only one time after the join? The TSF value in the=
template is really fast outdated. I think why not let __ieee80211_sta_=
join_ibss() call the set_tsf() callback, so that the TSF is mostly sync=
ed from the beginning on and fine-tuned later by the hardware?
Note: set_tsf() callback is currently broken for newer chipsets. I had =
posted a patch, but this was forgotten to apply. But I can repost it, i=
n the hope that it will be applied now.
Regards
Alina
--=20
Computer Bild Tarifsieger! GMX FreeDSL - Telefonanschluss + DSL
f=FCr nur 17,95 =BF/mtl.!* http://dsl.gmx.de/?ac=3DOM.AD.PD003K11308T45=
69a
Hello!
> Yes, the TBTT is calculated only once after joining the BSS network.
What about the following, which is called after scanning?
ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
This calls indirectly the function which looks in the template for the =
TSF.
> Am not sure I understand the proposal. What would the tsf value in
> set_tsf() be ?
> 11.1.4 (IEEE802.11-2007) says that the TSF has to be reset to zero on
> joining
> an IBSS network. We do that correctly.
In the praxis setting the TSF should not a problem as log the value is =
not higher then the original TSF from the other node. As long the clock=
s are working correct and the other node is not moved with nearly light=
-speed this shouldn't happen. ;)
> To calculate the next TBTT, we
> can't use the
> HW TSF, since it has just been reset. And the Beacon's timestamp + in=
tval
> + FUDGE
> is what we do in ath9k to get the TBTT for this peer, which I think i=
s
> correct.
> A sniffer shows the beacon generation being evenly distributed.
I think the TSF timer keep this value more up-to-date than a static var=
iable in RAM, so that e.g. the speed of the CPU has a lower effect on t=
he de-sync of this value.
Regards
Alina
--=20
Computer Bild Tarifsieger! GMX FreeDSL - Telefonanschluss + DSL
f=FCr nur 17,95 =BF/mtl.!* http://dsl.gmx.de/?ac=3DOM.AD.PD003K11308T45=
69a
Hello Sujith!
> Sure, either way works, since FIF_BCN_PRBRESP_PROMISC is set only dur=
ing
> scanning
> anyway.
Okay, I think I will post a patch in the evening of CET.
So I need sleep. ;)
Regards
Alina
--=20
Computer Bild Tarifsieger! GMX FreeDSL - Telefonanschluss + DSL
f=FCr nur 17,95 =BF/mtl.!* http://dsl.gmx.de/?ac=3DOM.AD.PD003K11308T45=
69a