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
>
> 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
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
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
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ł