2014-09-29 13:38:01

by Martin Hundebøll

[permalink] [raw]
Subject: iwlwifi: ibss on 6205 always stuck at 1 Mbps

Hi,

I get bad performance with IBSS on my 6205 devices running iwlwifi.
They seem to be stuck on 1 Mbps and through bisecting, it comes down to
this bad commit:

3ac40edadcb7799391452ffaa1745084c3e4c747
('iwlwifi: calculate active legacy rates per station')
https://github.com/torvalds/linux/commit/3ac40edadcb7799391452ffaa1745084c3e4c747

I have tested the issue on a few different settings:
iwlwifi (6205) => iwlwifi (6205): BAD
iwlwifi (6205) => ath9k_htc: BAD
iwlwifi (6205) => iwlwifi (6300): BAD
iwlwifi (6300) => iwlwifi (6205): GOOD
ath9k_htc => iwlwifi (6205): GOOD

So, as the first bad commit and the simple tests indicate, the issue is
related to the rate selection for 6205 devices.

dmesg and phy-info from an affected device is attached. Let me know if
more information is needed.

Thanks,
Martin

core@core01:~$ sudo iw wlan0 info
Interface wlan0
ifindex 3
wdev 0x1
addr a0:88:b4:bf:f4:cc
ssid core-test
type IBSS
wiphy 0
channel 6 (2437 MHz), width: 20 MHz (no HT), center1: 2437 MHz

core@core01:~$ sudo iw wlan0 station dump
Station 24:77:03:d7:6a:7c (on wlan0)
inactive time: 32 ms
rx bytes: 11009701
rx packets: 24719
tx bytes: 1264256
tx packets: 4032
tx retries: 501
tx failed: 0
signal: -44 dBm
signal avg: -43 dBm
tx bitrate: 1.0 MBit/s
rx bitrate: 54.0 MBit/s
authorized: yes
authenticated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no
Station f8:d1:11:0c:3f:2b (on wlan0)
inactive time: 4 ms
rx bytes: 13269604
rx packets: 33953
tx bytes: 1332906
tx packets: 4831
tx retries: 765
tx failed: 0
signal: -46 dBm
signal avg: -47 dBm
tx bitrate: 1.0 MBit/s
rx bitrate: 1.0 MBit/s
authorized: yes
authenticated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no
Station a0:88:b4:d8:b0:d8 (on wlan0)
inactive time: 20 ms
rx bytes: 7199547
rx packets: 86184
tx bytes: 135242
tx packets: 1573
tx retries: 323
tx failed: 0
signal: -41 dBm
signal avg: -40 dBm
tx bitrate: 54.0 MBit/s
rx bitrate: 1.0 MBit/s
authorized: yes
authenticated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no
Station 08:11:96:06:22:48 (on wlan0)
inactive time: 76 ms
rx bytes: 3290846
rx packets: 83190
tx bytes: 0
tx packets: 0
tx retries: 0
tx failed: 0
signal: -12 dBm
signal avg: -11 dBm
tx bitrate: 1.0 MBit/s
rx bitrate: 1.0 MBit/s
authorized: yes
authenticated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no
Station a0:88:b4:dc:f1:e0 (on wlan0)
inactive time: 104 ms
rx bytes: 3092949
rx packets: 78249
tx bytes: 0
tx packets: 0
tx retries: 0
tx failed: 0
signal: -24 dBm
signal avg: -23 dBm
tx bitrate: 1.0 MBit/s
rx bitrate: 1.0 MBit/s
authorized: yes
authenticated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no


Attachments:
phy.info (5.64 kB)
dmesg.log (55.06 kB)
Download all attachments

2014-11-12 14:04:00

by Grumbach, Emmanuel

[permalink] [raw]
Subject: RE: [PATCH] iwlwifi: dvm: Implement sta_rc_update() mac80211 callback

>
> Perform rate scaling properly when operating in an IBSS. Prior to this, the
> 5300 and 6205 devices (at least) would only transmit at
> 1 Mbps to other stations in an IBSS. This now allows transmission at HT rates.
>
> Signed-off-by: David Ward <[email protected]>
> ---
> drivers/net/wireless/iwlwifi/dvm/mac80211.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
> b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
> index 47e64e8..742218d 100644
> --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
> +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
> @@ -940,6 +940,22 @@ static int iwlagn_mac_sta_state(struct
> ieee80211_hw *hw,
> return ret;
> }
>
> +static void iwlagn_mac_sta_rc_update(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ieee80211_sta *sta, u32 changed) {
> + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
> +
> + if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
> + return;
> +
> + /* Update rate scaling */
> + IWL_DEBUG_INFO(priv,
> + "Updating rate scaling for station %pM\n",
> + sta->addr);
> + iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); }
> +
> static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
> struct ieee80211_vif *vif,
> struct ieee80211_channel_switch
> *ch_switch) @@ -1610,6 +1626,7 @@ const struct ieee80211_ops
> iwlagn_hw_ops = {
> .hw_scan = iwlagn_mac_hw_scan,
> .sta_notify = iwlagn_mac_sta_notify,
> .sta_state = iwlagn_mac_sta_state,
> + .sta_rc_update = iwlagn_mac_sta_rc_update,

Well - this would be called in other flows as well. For example, when we receive a beacon that changes the bandwidth or alike. I am not sure we want to re-init the rate scale data in this case, and more importantly, I am not sure it will not race with the tx / tx_status path that updates / uses the rate scale data.

> .channel_switch = iwlagn_mac_channel_switch,
> .flush = iwlagn_mac_flush,
> .tx_last_beacon = iwlagn_mac_tx_last_beacon,
> --
> 1.9.1


2014-11-12 14:33:20

by Grumbach, Emmanuel

[permalink] [raw]
Subject: RE: [PATCH] iwlwifi: dvm: Implement sta_rc_update() mac80211 callback

PiBPbiAxMiBOb3ZlbWJlciAyMDE0IDA3OjI2LCBEYXZpZCBXYXJkIDxkYXZpZC53YXJkQGxsLm1p
dC5lZHU+IHdyb3RlOg0KPiBbLi4uXQ0KPiA+ICtzdGF0aWMgdm9pZCBpd2xhZ25fbWFjX3N0YV9y
Y191cGRhdGUoc3RydWN0IGllZWU4MDIxMV9odyAqaHcsDQo+ID4gKyAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIHN0cnVjdCBpZWVlODAyMTFfdmlmICp2aWYsDQo+ID4gKyAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBpZWVlODAyMTFfc3RhICpzdGEs
IHUzMg0KPiA+ICtjaGFuZ2VkKSB7DQo+ID4gKyAgICAgICBzdHJ1Y3QgaXdsX3ByaXYgKnByaXYg
PSBJV0xfTUFDODAyMTFfR0VUX0RWTShodyk7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKCEoY2hh
bmdlZCAmIElFRUU4MDIxMV9SQ19TVVBQX1JBVEVTX0NIQU5HRUQpKQ0KPiA+ICsgICAgICAgICAg
ICAgICByZXR1cm47DQo+ID4gKw0KPiA+ICsgICAgICAgLyogVXBkYXRlIHJhdGUgc2NhbGluZyAq
Lw0KPiA+ICsgICAgICAgSVdMX0RFQlVHX0lORk8ocHJpdiwNCj4gPiArICAgICAgICAgICAgICAg
ICAgICAgICJVcGRhdGluZyByYXRlIHNjYWxpbmcgZm9yIHN0YXRpb24gJXBNXG4iLA0KPiA+ICsg
ICAgICAgICAgICAgICAgICAgICAgc3RhLT5hZGRyKTsNCj4gPiArICAgICAgIGl3bF9yc19yYXRl
X2luaXQocHJpdiwgc3RhLCBpd2xfc3RhX2lkKHN0YSkpOw0KPiANCj4gc3RhX3JjX3VwZGF0ZSgp
IG11c3QgYmUgYXRvbWljLiBJJ20gbm90IHJlYWxseSBmYW1pbGlhciB3aXRoIGl3bCB0aGF0IG11
Y2ggYnV0DQo+IGl0IHNlZW1zIHRvIG1lIGl3bF9yc19yYXRlX2luaXQoKSAtPiBpd2xfc2VuZF9s
cV9jbWQoLi4uLCAwLA0KPiB0cnVlKSBjYW4gc2xlZXAsIG5vPw0KPiANCj4gDQpZZXMgLSBnb29k
IHBvaW50Lg0K

2014-11-12 06:47:24

by David Ward

[permalink] [raw]
Subject: [PATCH] iwlwifi: dvm: Implement sta_rc_update() mac80211 callback

Perform rate scaling properly when operating in an IBSS. Prior to
this, the 5300 and 6205 devices (at least) would only transmit at
1 Mbps to other stations in an IBSS. This now allows transmission
at HT rates.

Signed-off-by: David Ward <[email protected]>
---
drivers/net/wireless/iwlwifi/dvm/mac80211.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 47e64e8..742218d 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -940,6 +940,22 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw,
return ret;
}

+static void iwlagn_mac_sta_rc_update(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u32 changed)
+{
+ struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+
+ if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
+ return;
+
+ /* Update rate scaling */
+ IWL_DEBUG_INFO(priv,
+ "Updating rate scaling for station %pM\n",
+ sta->addr);
+ iwl_rs_rate_init(priv, sta, iwl_sta_id(sta));
+}
+
static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_channel_switch *ch_switch)
@@ -1610,6 +1626,7 @@ const struct ieee80211_ops iwlagn_hw_ops = {
.hw_scan = iwlagn_mac_hw_scan,
.sta_notify = iwlagn_mac_sta_notify,
.sta_state = iwlagn_mac_sta_state,
+ .sta_rc_update = iwlagn_mac_sta_rc_update,
.channel_switch = iwlagn_mac_channel_switch,
.flush = iwlagn_mac_flush,
.tx_last_beacon = iwlagn_mac_tx_last_beacon,
--
1.9.1


2014-11-12 14:30:34

by Michal Kazior

[permalink] [raw]
Subject: Re: [PATCH] iwlwifi: dvm: Implement sta_rc_update() mac80211 callback

On 12 November 2014 07:26, David Ward <[email protected]> wrote:
[...]
> +static void iwlagn_mac_sta_rc_update(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ieee80211_sta *sta, u32 changed)
> +{
> + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
> +
> + if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
> + return;
> +
> + /* Update rate scaling */
> + IWL_DEBUG_INFO(priv,
> + "Updating rate scaling for station %pM\n",
> + sta->addr);
> + iwl_rs_rate_init(priv, sta, iwl_sta_id(sta));

sta_rc_update() must be atomic. I'm not really familiar with iwl that
much but it seems to me iwl_rs_rate_init() -> iwl_send_lq_cmd(..., 0,
true) can sleep, no?


Michał