[PATCH iw] phy: Allow set netns by fd

2015-02-13 Thread Vadim Kochan
From: Vadim Kochan 

Added possibility to change network namespace
for phy device by network namespace name from
/var/run/netns or by absolute file path:

iw phy XXX set netns name 

iw tries to open fd of given nsname from /var/run/netns
or by absoute path if nsname contains "/".

Signed-off-by: Vadim Kochan 
---
 phy.c | 55 ++-
 1 file changed, 46 insertions(+), 9 deletions(-)

diff --git a/phy.c b/phy.c
index aab462d..271c9d9 100644
--- a/phy.c
+++ b/phy.c
@@ -2,6 +2,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
@@ -296,6 +299,24 @@ COMMAND(set, retry, "[short ] [long ]",
NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_retry,
"Set retry limit.");
 
+#ifndef NETNS_RUN_DIR
+#define NETNS_RUN_DIR "/var/run/netns"
+#endif
+int netns_get_fd(const char *name)
+{
+   char pathbuf[MAXPATHLEN];
+   const char *path, *ptr;
+
+   path = name;
+   ptr = strchr(name, '/');
+   if (!ptr) {
+   snprintf(pathbuf, sizeof(pathbuf), "%s/%s",
+   NETNS_RUN_DIR, name );
+   path = pathbuf;
+   }
+   return open(path, O_RDONLY);
+}
+
 static int handle_netns(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,
@@ -303,26 +324,42 @@ static int handle_netns(struct nl80211_state *state,
enum id_input id)
 {
char *end;
+   int fd;
 
-   if (argc != 1)
+   if (argc < 1 || !*argv[0])
return 1;
 
-   if (!*argv[0])
+   if (argc == 1) {
+   NLA_PUT_U32(msg, NL80211_ATTR_PID,
+   strtoul(argv[0], &end, 10));
+   if (*end != '\0') {
+   printf("Invalid parameter: pid(%s)\n", argv[0]);
+   return 1;
+   }
+   return 0;
+   }
+
+   if (argc != 2 || strcmp(argv[0], "name"))
return 1;
 
-   NLA_PUT_U32(msg, NL80211_ATTR_PID,
-   strtoul(argv[0], &end, 10));
+   if ((fd = netns_get_fd(argv[1])) >= 0) {
+   NLA_PUT_U32(msg, NL80211_ATTR_NETNS_FD, fd);
+   return 0;
+   } else {
+   printf("Invalid parameter: nsname(%s)\n", argv[0]);
+   }
 
-   if (*end != '\0')
-   return 1;
+   return 1;
 
-   return 0;
  nla_put_failure:
return -ENOBUFS;
 }
-COMMAND(set, netns, "",
+COMMAND(set, netns, "{  | name  }",
NL80211_CMD_SET_WIPHY_NETNS, 0, CIB_PHY, handle_netns,
-   "Put this wireless device into a different network namespace");
+   "Put this wireless device into a different network namespace:\n"
+   "- change network namespace by process id\n"
+   " - change network namespace by name from "NETNS_RUN_DIR"\n"
+   "   or by absolute path (man ip-netns)\n");
 
 static int handle_coverage(struct nl80211_state *state,
struct nl_cb *cb,
-- 
2.2.2

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Fwd: Kernel 3.6.0 works, newer doesn't

2015-02-13 Thread Pat Erley

On 02/13/2015 09:58 PM, Tim-Hinnerk Heuer wrote:

Hi can someone here help with this issue, please? I'm willing to give
more info if necessary or help out otherwise. I am a programmer but
haven't done much with Linux drivers yet.



First key is probably defining 'not working'.  Second key is likely to
be a dmesg output of it 'not working'.  Third detail that is likely to
help is what distribution you're running and how how you're attempting
to manage the wifi device(networkmanager/wicd/etc).



Hi there,

Sorry, I'm new to this list, so excuse my newbie question.

I have Linux 3.6.0-030600-generic #201209302035 SMP Mon Oct 1 00:36:01
UTC 2012 x86_64 x86_64 x86_64 GNU/Linux installed and it works great.
My WLAN driver works with this version, but not with any newer version
of the kernel. Am I right that backports can help me with that?

Can I somehow upgrade to a newer version of the kernel and keep my
WIFI USB driver and maybe even upgrade to newer kernels? Or even
better, does someone here have the capacity to fix the problem in
newer kernels?

My Wifi USB Card is the
Asus USB N13

```
lsusb
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 004: ID 0b05:1784 ASUSTek Computer, Inc. USB-N13
802.11n Network Adapter (rev. A1) [Ralink RT3072]

Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

sudo lsmod|grep rt
xt_addrtype12713  2
x_tables   29846  6
ip_tables,ipt_MASQUERADE,xt_conntrack,iptable_filter,xt_addrtype,iptable_nat
rt2800usb  26998  0
rt2x00usb  20762  1 rt2800usb
rt2800lib  63557  1 rt2800usb
rt2x00lib  55527  3 rt2x00usb,rt2800lib,rt2800usb
mac80211  564631  3 rt2x00lib,rt2x00usb,rt2800lib
cfg80211  212917  2 mac80211,rt2x00lib
crc_ccitt  12667  1 rt2800lib
parport_pc 32866  0
parport46562  3 lp,ppdev,parport_pc
```

Running Ubuntu 14.04.

Thanks for your patience.
Tim


-- Forwarded message --
From: Greg KH 
Date: 14 February 2015 at 04:19
Subject: Re: Kernel 3.6.0 works, newer doesn't
To: Tim-Hinnerk Heuer 
Cc: linux-...@vger.kernel.org


On Fri, Feb 13, 2015 at 11:20:33PM +1300, Tim-Hinnerk Heuer wrote:

Hi there,

Sorry, I'm new to this list, so excuse my newbie question.

I have Linux 3.6.0-030600-generic #201209302035 SMP Mon Oct 1 00:36:01
UTC 2012 x86_64 x86_64 x86_64 GNU/Linux installed and it works great.
My WLAN driver works with this version, but not with any newer version
of the kernel. Am I right that backports can help me with that?


I suggest working with the driver authors of that driver to fix it to
work with the latest kernel version.  It is merged into the main
kernel.org repo, right?  Which one is it?

The networking mailing list should be able to help you out the best, try
sending this to the linux-wireless@vger.kernel.org

hope this helps,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Fwd: Kernel 3.6.0 works, newer doesn't

2015-02-13 Thread Tim-Hinnerk Heuer
Hi can someone here help with this issue, please? I'm willing to give
more info if necessary or help out otherwise. I am a programmer but
haven't done much with Linux drivers yet.


Hi there,

Sorry, I'm new to this list, so excuse my newbie question.

I have Linux 3.6.0-030600-generic #201209302035 SMP Mon Oct 1 00:36:01
UTC 2012 x86_64 x86_64 x86_64 GNU/Linux installed and it works great.
My WLAN driver works with this version, but not with any newer version
of the kernel. Am I right that backports can help me with that?

Can I somehow upgrade to a newer version of the kernel and keep my
WIFI USB driver and maybe even upgrade to newer kernels? Or even
better, does someone here have the capacity to fix the problem in
newer kernels?

My Wifi USB Card is the
Asus USB N13

```
lsusb
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 004: ID 0b05:1784 ASUSTek Computer, Inc. USB-N13
802.11n Network Adapter (rev. A1) [Ralink RT3072]

Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

sudo lsmod|grep rt
xt_addrtype12713  2
x_tables   29846  6
ip_tables,ipt_MASQUERADE,xt_conntrack,iptable_filter,xt_addrtype,iptable_nat
rt2800usb  26998  0
rt2x00usb  20762  1 rt2800usb
rt2800lib  63557  1 rt2800usb
rt2x00lib  55527  3 rt2x00usb,rt2800lib,rt2800usb
mac80211  564631  3 rt2x00lib,rt2x00usb,rt2800lib
cfg80211  212917  2 mac80211,rt2x00lib
crc_ccitt  12667  1 rt2800lib
parport_pc 32866  0
parport46562  3 lp,ppdev,parport_pc
```

Running Ubuntu 14.04.

Thanks for your patience.
Tim


-- Forwarded message --
From: Greg KH 
Date: 14 February 2015 at 04:19
Subject: Re: Kernel 3.6.0 works, newer doesn't
To: Tim-Hinnerk Heuer 
Cc: linux-...@vger.kernel.org


On Fri, Feb 13, 2015 at 11:20:33PM +1300, Tim-Hinnerk Heuer wrote:
> Hi there,
>
> Sorry, I'm new to this list, so excuse my newbie question.
>
> I have Linux 3.6.0-030600-generic #201209302035 SMP Mon Oct 1 00:36:01
> UTC 2012 x86_64 x86_64 x86_64 GNU/Linux installed and it works great.
> My WLAN driver works with this version, but not with any newer version
> of the kernel. Am I right that backports can help me with that?

I suggest working with the driver authors of that driver to fix it to
work with the latest kernel version.  It is merged into the main
kernel.org repo, right?  Which one is it?

The networking mailing list should be able to help you out the best, try
sending this to the linux-wireless@vger.kernel.org

hope this helps,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] mac80211: use rhashtable for station table

2015-02-13 Thread Sergey Ryazanov
2015-02-14 0:47 GMT+03:00 Johannes Berg :
> We currently have a hand-rolled table with 256 entries and are
> using the last byte of the MAC address as the hash. This hash
> is obviously very fast, but collisions are easily created and
> we waste a lot of space in the common case of just connecting
> as a client to an AP where we just have a single station. The
> other common case of an AP is also suboptimal due to the size
> of the hash table and the ease of causing collisions.
>
> Convert all of this to use rhashtable with jhash, which gives
> us the advantage of a far better hash function (with random
> perturbation to avoid hash collision attacks) and of course
> that the hash table grows and shrinks dynamically with chain
> length, improving both cases above.
>
A nice change! Couple of years ago I did some tests with real sets of
MACs and jhash gives a better distribution than usage of a last octet.

BTW, why do you use full address and generic jhash? Hashing of two
least significant words could be faster. Isn't it?

-- 
Sergey
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] mac80211: use rhashtable for station table

2015-02-13 Thread Ben Greear
On 02/13/2015 01:47 PM, Johannes Berg wrote:
> From: Johannes Berg 
> 
> We currently have a hand-rolled table with 256 entries and are
> using the last byte of the MAC address as the hash. This hash
> is obviously very fast, but collisions are easily created and
> we waste a lot of space in the common case of just connecting
> as a client to an AP where we just have a single station. The
> other common case of an AP is also suboptimal due to the size
> of the hash table and the ease of causing collisions.
> 
> Convert all of this to use rhashtable with jhash, which gives
> us the advantage of a far better hash function (with random
> perturbation to avoid hash collision attacks) and of course
> that the hash table grows and shrinks dynamically with chain
> length, improving both cases above.

Oooh, maybe finally time to mix local addr with peer addr to
make lots of vifs connected to same AP hash well too? :)

Thanks,
Ben

-- 
Ben Greear 
Candela Technologies Inc  http://www.candelatech.com

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] mac80211: use rhashtable for station table

2015-02-13 Thread Johannes Berg
From: Johannes Berg 

We currently have a hand-rolled table with 256 entries and are
using the last byte of the MAC address as the hash. This hash
is obviously very fast, but collisions are easily created and
we waste a lot of space in the common case of just connecting
as a client to an AP where we just have a single station. The
other common case of an AP is also suboptimal due to the size
of the hash table and the ease of causing collisions.

Convert all of this to use rhashtable with jhash, which gives
us the advantage of a far better hash function (with random
perturbation to avoid hash collision attacks) and of course
that the hash table grows and shrinks dynamically with chain
length, improving both cases above.

Signed-off-by: Johannes Berg 
---
 net/mac80211/ieee80211_i.h |  3 +-
 net/mac80211/main.c|  9 +++--
 net/mac80211/rx.c  |  4 +--
 net/mac80211/sta_info.c| 87 --
 net/mac80211/sta_info.h| 37 ++--
 net/mac80211/status.c  |  4 +--
 6 files changed, 59 insertions(+), 85 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3afe36824703..798392398ab5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1195,7 +1196,7 @@ struct ieee80211_local {
spinlock_t tim_lock;
unsigned long num_sta;
struct list_head sta_list;
-   struct sta_info __rcu *sta_hash[STA_HASH_SIZE];
+   struct rhashtable sta_hash;
struct timer_list sta_cleanup;
int sta_generation;
 
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5e09d354c5a5..95d59d24b271 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -557,6 +557,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
 
local = wiphy_priv(wiphy);
 
+   if (sta_info_init(local))
+   goto err_free;
+
local->hw.wiphy = wiphy;
 
local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);
@@ -629,8 +632,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
spin_lock_init(&local->ack_status_lock);
idr_init(&local->ack_status_frames);
 
-   sta_info_init(local);
-
for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
skb_queue_head_init(&local->pending[i]);
atomic_set(&local->agg_queue_stop[i], 0);
@@ -650,6 +651,9 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
ieee80211_roc_setup(local);
 
return &local->hw;
+ err_free:
+   wiphy_free(wiphy);
+   return NULL;
 }
 EXPORT_SYMBOL(ieee80211_alloc_hw_nm);
 
@@ -1173,7 +1177,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 
destroy_workqueue(local->workqueue);
wiphy_unregister(local->hw.wiphy);
-   sta_info_stop(local);
ieee80211_wep_free(local);
ieee80211_led_exit(local);
kfree(local->int_scan_req);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ed38d8302659..aa238a66ae2e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3417,7 +3417,7 @@ static void __ieee80211_rx_handle_packet(struct 
ieee80211_hw *hw,
__le16 fc;
struct ieee80211_rx_data rx;
struct ieee80211_sub_if_data *prev;
-   struct sta_info *sta, *tmp, *prev_sta;
+   struct sta_info *sta, *prev_sta;
int err = 0;
 
fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
@@ -3454,7 +3454,7 @@ static void __ieee80211_rx_handle_packet(struct 
ieee80211_hw *hw,
if (ieee80211_is_data(fc)) {
prev_sta = NULL;
 
-   for_each_sta_info(local, hdr->addr2, sta, tmp) {
+   for_each_sta_info(local, hdr->addr2, sta) {
if (!prev_sta) {
prev_sta = sta;
continue;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 00ca8dcc2bcf..0535bf89e115 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -68,28 +68,7 @@
 static int sta_info_hash_del(struct ieee80211_local *local,
 struct sta_info *sta)
 {
-   struct sta_info *s;
-
-   s = rcu_dereference_protected(local->sta_hash[STA_HASH(sta->sta.addr)],
- lockdep_is_held(&local->sta_mtx));
-   if (!s)
-   return -ENOENT;
-   if (s == sta) {
-   rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)],
-  s->hnext);
-   return 0;
-   }
-
-   while (rcu_access_pointer(s->hnext) &&
-  rcu_access_pointer(s->hnext) != sta)
-   s = rcu_dereference_protected(s->hnext,
-   lockdep_is_held(&local->sta_mtx));
-   if (rcu_access_pointer(s->hnext)) {
-   rcu_assign_

Re: [PATCH 1/3] mwifiex: add cfg80211 set_default_mgmt_key handler

2015-02-13 Thread Johannes Berg
On Thu, 2015-02-12 at 23:45 +0530, Avinash Patil wrote:
> From: Xinming Hu 
> 
> It is observed that hostapd failed to setup with management frame
> protection mode enabled when using mwifiex.
> 
> This is because hostapd will try to install IGTK using
> cfg80211 set_default_mgmt_key handler.
> 
> we have already support IGTK install in set_key handler, so just work
> around this issue by add an empty cfg80211_set_default_mgmt_key handler.

I believe that this is incorrect since the key should only be installed
for TX after this handler, not in the set_key handler. This should make
a difference in the case of rekeying? Perhaps hostapd doesn't actually
program the key until rekeying with all stations finishes though.

johannes

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] ath10k: Increase AST table SKID length limit

2015-02-13 Thread SenthilKumar Jegadeesan
The current SKID length configuration causes firmware
to reject peer creation for not able to allocate
AST entries for peers. This issue is observed when
least significant 3 bytes are used ramdomly to create
client MAC addresses.

AST table SKID length configuration is increased to
maximum value to fix this issue.

Signed-off-by: SenthilKumar Jegadeesan 
---
 drivers/net/wireless/ath/ath10k/hw.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 460771f..7f04645 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -223,7 +223,7 @@ struct ath10k_pktlog_hdr {
 #define TARGET_10X_NUM_WDS_ENTRIES 32
 #define TARGET_10X_DMA_BURST_SIZE  0
 #define TARGET_10X_MAC_AGGR_DELIM  0
-#define TARGET_10X_AST_SKID_LIMIT  16
+#define TARGET_10X_AST_SKID_LIMIT  128
 #define TARGET_10X_NUM_STATIONS128
 #define TARGET_10X_NUM_PEERS   ((TARGET_10X_NUM_STATIONS) + \
 (TARGET_10X_NUM_VDEVS))
--
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 10/10] mac80211: add standard deviation to Minstrels throughput statistic

2015-02-13 Thread Thomas Huehn
This patch adds the statistical descriptor "standard deviation"
to better describe the current properties of Minstrel and
Minstrel-HTs success probability distribution. The standard
deviation (SD) is calculated as exponential weighted moving
standard deviation (EWMSD) and its current value is added as
new column in all rc_stats (in debugfs).

Signed-off-by: Thomas Huehn 
---
 net/mac80211/rc80211_minstrel.c| 19 ++-
 net/mac80211/rc80211_minstrel.h| 22 +-
 net/mac80211/rc80211_minstrel_debugfs.c| 19 ---
 net/mac80211/rc80211_minstrel_ht_debugfs.c | 14 +-
 4 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 42dfef8..c108f03 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -161,7 +161,7 @@ minstrel_update_rates(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
 }
 
 /*
-* Recalculate success probabilities and counters for a given rate using EWMA
+* Recalculate statistics and counters of a given rate
 */
 void
 minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
@@ -169,11 +169,20 @@ minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
if (unlikely(mrs->attempts > 0)) {
mrs->sample_skipped = 0;
mrs->cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
-   if (unlikely(!mrs->att_hist))
+   if (unlikely(!mrs->att_hist)) {
mrs->prob_ewma = mrs->cur_prob;
-   else
+   } else {
+   /* update exponential weighted moving variance */
+   mrs->prob_ewmsd = minstrel_ewmsd(mrs->prob_ewmsd,
+mrs->cur_prob,
+mrs->prob_ewma,
+EWMA_LEVEL);
+
+   /*update exponential weighted moving avarage */
mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
-mrs->cur_prob, EWMA_LEVEL);
+  mrs->cur_prob,
+  EWMA_LEVEL);
+   }
mrs->att_hist += mrs->attempts;
mrs->succ_hist += mrs->success;
} else {
@@ -200,7 +209,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
struct minstrel_rate *mr = &mi->r[i];
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
 
-   /* Update success probabilities per rate */
+   /* Update statistics of success probability per rate */
minstrel_calc_rate_stats(mrs);
 
/* Sample less often below the 10% chance of success.
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 38158b0..713c81e 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -35,6 +35,24 @@ minstrel_ewma(int old, int new, int weight)
return old + incr;
 }
 
+/*
+ * Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation
+ */
+static inline int
+minstrel_ewmsd(int old_ewmsd, int cur_prob, int prob_ewma, int weight)
+{
+   int diff, incr, tmp_var;
+
+   /* calculate exponential weighted moving variance */
+   diff = MINSTREL_TRUNC((cur_prob - prob_ewma) * 100);
+   incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
+   tmp_var = old_ewmsd * old_ewmsd;
+   tmp_var = weight * (tmp_var + diff * incr / 100) / EWMA_DIV;
+
+   /* return standard deviation */
+   return (u16) int_sqrt(tmp_var);
+}
+
 struct minstrel_rate_stats {
/* current / last sampling period attempts/success counters */
u16 attempts, last_attempts;
@@ -45,9 +63,11 @@ struct minstrel_rate_stats {
 
/* statistis of packet delivery probability
 *  cur_prob  - current prob within last update intervall
-*  prob_ewma - exponential weighted moving average of prob */
+*  prob_ewma - exponential weighted moving average of prob
+*  prob_ewmsd - exp. weighted moving standard deviation of prob */
unsigned int cur_prob;
unsigned int prob_ewma;
+   u16 prob_ewmsd;
 
/* maximum retry counts */
u8 retry_count;
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c 
b/net/mac80211/rc80211_minstrel_debugfs.c
index 182d552..a217a2c 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -85,10 +85,12 @@ minstrel_stats_open(struct inode *inode, struct file *file)
file->private_data = ms;
p = ms->buf;
p += sprintf(p, "\n");
-   p += sprintf(p, "best   __rate___statistics__"
-

[PATCH v2 09/10] mac80211: reduce calculation costs of EWMA

2015-02-13 Thread Thomas Huehn
This patch reduces the calculation costs of the EWMA macro from
"2x multiplication and 1 addition" down to "1x multiplication and
2x additions". This slightly improves performance depending on the
CPU architecture.

Signed-off-by: Thomas Huehn 
---
 net/mac80211/rc80211_minstrel.h | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 6693d8d..38158b0 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -27,7 +27,12 @@
 static inline int
 minstrel_ewma(int old, int new, int weight)
 {
-   return (new * (EWMA_DIV - weight) + old * weight) / EWMA_DIV;
+   int diff, incr;
+
+   diff = new - old;
+   incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
+
+   return old + incr;
 }
 
 struct minstrel_rate_stats {
-- 
2.2.2

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 06/10] mac80211: improve Minstrel variable & function naming

2015-02-13 Thread Thomas Huehn
This patch ensures a consistent usage of variable names for type
"minstrel_rate_stats" to be used as "mrs" and from type minstrel_rate
as "mr" across both Minstrel & Minstrel-HT. In addition some
variable and function names got changed to more meaningful ones.

Signed-off-by: Thomas Huehn 
---
 net/mac80211/rc80211_minstrel.c|  26 +++
 net/mac80211/rc80211_minstrel.h|  13 ++--
 net/mac80211/rc80211_minstrel_debugfs.c|   4 +-
 net/mac80211/rc80211_minstrel_ht.c | 112 ++---
 net/mac80211/rc80211_minstrel_ht.h |   2 +-
 net/mac80211/rc80211_minstrel_ht_debugfs.c |  36 +-
 6 files changed, 98 insertions(+), 95 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 4858e67..89db6cf 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -137,9 +137,9 @@ minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
mrs->sample_skipped = 0;
mrs->cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
if (unlikely(!mrs->att_hist))
-   mrs->probability = mrs->cur_prob;
+   mrs->prob_ewma = mrs->cur_prob;
else
-   mrs->probability = minstrel_ewma(mrs->probability,
+   mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
 mrs->cur_prob, EWMA_LEVEL);
mrs->att_hist += mrs->attempts;
mrs->succ_hist += mrs->success;
@@ -176,15 +176,15 @@ minstrel_update_stats(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
minstrel_calc_rate_stats(mrs);
 
/* Update throughput per rate, reset thr. below 10% success */
-   if (mrs->probability < MINSTREL_FRAC(10, 100))
+   if (mrs->prob_ewma < MINSTREL_FRAC(10, 100))
mrs->cur_tp = 0;
else
-   mrs->cur_tp = mrs->probability * (100 / usecs);
+   mrs->cur_tp = mrs->prob_ewma * (100 / usecs);
 
/* Sample less often below the 10% chance of success.
 * Sample less often above the 95% chance of success. */
-   if (mrs->probability > MINSTREL_FRAC(95, 100) ||
-   mrs->probability < MINSTREL_FRAC(10, 100)) {
+   if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
+   mrs->prob_ewma < MINSTREL_FRAC(10, 100)) {
mr->adjusted_retry_count = mrs->retry_count >> 1;
if (mr->adjusted_retry_count > 2)
mr->adjusted_retry_count = 2;
@@ -204,11 +204,11 @@ minstrel_update_stats(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
 * choose the maximum throughput rate as max_prob_rate
 * (2) if all success probabilities < 95%, the rate with
 * highest success probability is chosen as max_prob_rate */
-   if (mrs->probability >= MINSTREL_FRAC(95, 100)) {
+   if (mrs->prob_ewma >= MINSTREL_FRAC(95, 100)) {
if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp)
tmp_prob_rate = i;
} else {
-   if (mrs->probability >= 
mi->r[tmp_prob_rate].stats.probability)
+   if (mrs->prob_ewma >= 
mi->r[tmp_prob_rate].stats.prob_ewma)
tmp_prob_rate = i;
}
}
@@ -227,7 +227,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
 #endif
 
/* Reset update timer */
-   mi->stats_update = jiffies;
+   mi->last_stats_update = jiffies;
 
minstrel_update_rates(mp, mi);
 }
@@ -265,7 +265,7 @@ minstrel_tx_status(void *priv, struct 
ieee80211_supported_band *sband,
if (mi->sample_deferred > 0)
mi->sample_deferred--;
 
-   if (time_after(jiffies, mi->stats_update +
+   if (time_after(jiffies, mi->last_stats_update +
(mp->update_interval * HZ) / 1000))
minstrel_update_stats(mp, mi);
 }
@@ -397,7 +397,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
 * has a probability of >95%, we shouldn't be attempting
 * to use it, as this only wastes precious airtime */
if (!mrr_capable &&
-  (mi->r[ndx].stats.probability > MINSTREL_FRAC(95, 100)))
+  (mi->r[ndx].stats.prob_ewma > MINSTREL_FRAC(95, 100)))
return;
 
mi->prev_sample = true;
@@ -531,7 +531,7 @@ minstrel_rate_init(void *priv, struct 
ieee80211_supported_band *sband,
}
 
mi->n_rates = n;
-   mi->stats_update = jiffies;
+   mi->last_stats_update = jiffies;
 
init_sample_table(mi);
minstrel_update_rates(mp, mi);
@@ -565,7 +565,7 @@ minstrel

[PATCH v2 03/10] mac80211: add new Minstrel statistic output via csv

2015-02-13 Thread Thomas Huehn
This patch adds a new debugfs file "rc_stats_csv" to output Minstrels
statistics in a common csv format that is easy to parse.

Signed-off-by: Thomas Huehn 
Signed-off-by: Stefan Venz 
---
 net/mac80211/rc80211_minstrel.h|  6 +-
 net/mac80211/rc80211_minstrel_debugfs.c| 95 ++
 net/mac80211/rc80211_minstrel_ht_debugfs.c |  2 +-
 3 files changed, 88 insertions(+), 15 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 410efe6..9613e73 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -13,7 +13,6 @@
 #define EWMA_DIV   128
 #define SAMPLE_COLUMNS 10  /* number of columns in sample table */
 
-
 /* scaled fraction values */
 #define MINSTREL_SCALE  16
 #define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
@@ -24,7 +23,7 @@
 
 /*
  * Perform EWMA (Exponentially Weighted Moving Average) calculation
-  */
+ */
 static inline int
 minstrel_ewma(int old, int new, int weight)
 {
@@ -95,6 +94,7 @@ struct minstrel_sta_info {
 
 #ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *dbg_stats;
+   struct dentry *dbg_stats_csv;
 #endif
 };
 
@@ -121,7 +121,6 @@ struct minstrel_priv {
u32 fixed_rate_idx;
struct dentry *dbg_fixed_rate;
 #endif
-
 };
 
 struct minstrel_debugfs_info {
@@ -135,6 +134,7 @@ void minstrel_remove_sta_debugfs(void *priv, void 
*priv_sta);
 
 /* debugfs */
 int minstrel_stats_open(struct inode *inode, struct file *file);
+int minstrel_stats_csv_open(struct inode *inode, struct file *file);
 ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, 
loff_t *ppos);
 int minstrel_stats_release(struct inode *inode, struct file *file);
 
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c 
b/net/mac80211/rc80211_minstrel_debugfs.c
index 2d70081..ab15ca6 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -54,6 +54,22 @@
 #include 
 #include "rc80211_minstrel.h"
 
+ssize_t
+minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t 
*ppos)
+{
+   struct minstrel_debugfs_info *ms;
+
+   ms = file->private_data;
+   return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len);
+}
+
+int
+minstrel_stats_release(struct inode *inode, struct file *file)
+{
+   kfree(file->private_data);
+   return 0;
+}
+
 int
 minstrel_stats_open(struct inode *inode, struct file *file)
 {
@@ -115,25 +131,76 @@ minstrel_stats_open(struct inode *inode, struct file 
*file)
return 0;
 }
 
-ssize_t
-minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t 
*ppos)
+static const struct file_operations minstrel_stat_fops = {
+   .owner = THIS_MODULE,
+   .open = minstrel_stats_open,
+   .read = minstrel_stats_read,
+   .release = minstrel_stats_release,
+   .llseek = default_llseek,
+};
+
+int
+minstrel_stats_csv_open(struct inode *inode, struct file *file)
 {
+   struct minstrel_sta_info *mi = inode->i_private;
struct minstrel_debugfs_info *ms;
+   struct timeval tv;
+   unsigned int i, tp, prob, eprob;
+   char *p;
 
-   ms = file->private_data;
-   return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len);
-}
+   ms = kmalloc(2048, GFP_KERNEL);
+   if (!ms)
+   return -ENOMEM;
+
+   file->private_data = ms;
+   p = ms->buf;
+
+   do_gettimeofday(&tv);
+
+   for (i = 0; i < mi->n_rates; i++) {
+   struct minstrel_rate *mr = &mi->r[i];
+   struct minstrel_rate_stats *mrs = &mi->r[i].stats;
+
+   p += sprintf(p, "%ld.%.6ld,", tv.tv_sec, tv.tv_usec);
+   p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A," : ","));
+   p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B," : ","));
+   p += sprintf(p, "%s" ,((i == mi->max_tp_rate[2]) ? "C," : ","));
+   p += sprintf(p, "%s" ,((i == mi->max_tp_rate[3]) ? "D," : ","));
+   p += sprintf(p, "%s" ,((i == mi->max_prob_rate) ? "P," : ","));
+
+   p += sprintf(p, "%u%s", mr->bitrate / 2,
+   (mr->bitrate & 1 ? ".5," : ","));
+   p += sprintf(p, "%u,", i);
+   p += sprintf(p, "%u,",mr->perfect_tx_time);
+
+   tp = MINSTREL_TRUNC(mrs->cur_tp / 10);
+   prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
+   eprob = MINSTREL_TRUNC(mrs->probability * 1000);
+
+   p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u,"
+   "%llu,%llu,%d,%d\n",
+   tp / 10, tp % 10,
+   eprob / 10, eprob % 10,
+   prob / 10, prob % 10,
+   mrs->retry_count,
+   mrs->last_success,
+   mrs->last_attempts,
+   (uns

[PATCH v2 02/10] mac80211: enhance readability of Minstrel-HTs rc_stats output

2015-02-13 Thread Thomas Huehn
This patch restructures the rc_stats debugfs table of Minstrel-HT in
order to achieve better human readability. A new layout of the
statistics and a new header is added. In addition to the old layout
there are two new columns of information added:
idx - representing the rate index of each rate in mac80211 which
  can be used to set specific rates as fixed rate via debugfs
airtime - the tx-time in micro seconds that a 1200 Byte packet
  takes to be transmitted over the air at the given rate

The old layout of rc_stats:

type   rate  tpt eprob *prob ret  *ok(*cum)ok(  cum)
HT20/LGI   MCS0  5.6 100.0 100.0   10(   0) 1(1)
HT20/LGI   B   MCS1 10.5 100.0 100.0   00(   0) 1(1)
HT20/LGI  AMCS2 14.8 100.0 100.0   00(   0) 1(1)
...

is changed into this new layout:

best   rate____statistics__last___  
  __sum-of
mode guard #  rate  [name   idx airtime]  [ ø(tp) ø(prob)]  
[prob.|retry|suc|att]  [#success | #attempts]
HT20  LGI  1 MCS0 01480  0.0  0.0  0.0   1 0 0  
   0   0
HT20  LGI  1 B   MCS1 1 740 10.5100.0100.0   0 0 0  
   1   1
HT20  LGI  1AMCS2 2 496 14.8100.0100.0   0 0 0  
   1   1
...

Signed-off-by: Thomas Huehn 
Signed-off-by: Stefan Venz 
---
 net/mac80211/rc80211_minstrel_ht_debugfs.c | 49 +-
 1 file changed, 34 insertions(+), 15 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c 
b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index 20c676b..7fc690f 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -19,7 +19,7 @@ static char *
 minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
 {
const struct mcs_group *mg;
-   unsigned int j, tp, prob, eprob;
+   unsigned int j, tp, prob, eprob, tx_time;
char htmode = '2';
char gimode = 'L';
u32 gflags;
@@ -45,12 +45,19 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, 
char *p)
if (!(mi->groups[i].supported & BIT(j)))
continue;
 
-   if (gflags & IEEE80211_TX_RC_MCS)
-   p += sprintf(p, " HT%c0/%cGI ", htmode, gimode);
-   else if (gflags & IEEE80211_TX_RC_VHT_MCS)
-   p += sprintf(p, "VHT%c0/%cGI ", htmode, gimode);
-   else
-   p += sprintf(p, " CCK/%cP   ", j < 4 ? 'L' : 'S');
+   if (gflags & IEEE80211_TX_RC_MCS) {
+   p += sprintf(p, "HT%c0  ", htmode);
+   p += sprintf(p, "%cGI  ", gimode);
+   p += sprintf(p, "%d  ", mg->streams);
+   } else if (gflags & IEEE80211_TX_RC_VHT_MCS) {
+   p += sprintf(p, "VHT%c0 ", htmode);
+   p += sprintf(p, "%cGI ", gimode);
+   p += sprintf(p, "%d  ", mg->streams);
+   } else {
+   p += sprintf(p, "CCK");
+   p += sprintf(p, "%cP  ", j < 4 ? 'L' : 'S');
+   p += sprintf(p, "1 ");
+   }
 
*(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' ';
*(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' ';
@@ -59,21 +66,27 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, 
char *p)
*(p++) = (idx == mi->max_prob_rate) ? 'P' : ' ';
 
if (gflags & IEEE80211_TX_RC_MCS) {
-   p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j);
+   p += sprintf(p, "  MCS%-2u", (mg->streams - 1) * 8 + j);
} else if (gflags & IEEE80211_TX_RC_VHT_MCS) {
-   p += sprintf(p, " MCS%-1u/%1u", j, mg->streams);
+   p += sprintf(p, "  MCS%-1u/%1u", j, mg->streams);
} else {
int r = bitrates[j % 4];
 
-   p += sprintf(p, " %2u.%1uM ", r / 10, r % 10);
+   p += sprintf(p, "   %2u.%1uM", r / 10, r % 10);
}
 
+   p += sprintf(p, "  %3u  ", idx);
+
+   /* tx_time[rate(i)] in usec */
+   tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000);
+   p += sprintf(p, "%6u   ", tx_time);
+
tp = mr->cur_tp / 10;
prob = MINSTREL_TRUNC(mr->cur_prob * 1000);
eprob = MINSTREL_TRUNC(mr->probability * 1000);
 
-   p += sprintf(p, " %4u.%1u %3u.%1u %3u.%1u "
-   "%3u %4u(%4u) %9llu(%9llu)\n",
+   p += sprintf(p, "%4u.%1u   %3u.%1u %3u.%1u "
+   "%3u   %3u %-3u   %9llu   %-9llu\n",
tp / 10, tp % 10,

[PATCH v2 07/10] mac80211: restructure per-rate throughput calculation into function

2015-02-13 Thread Thomas Huehn
This patch moves Minstrels and Minstrel-HTs per-rate throughput
calculation (EWMA(thr)) into a dedicated function to be called.
Therefore the variable "unsigned int cur_tp" within struct
"minstrel_rate_stats" becomes obsolete.  and is removed to free
up its space.

Signed-off-by: Thomas Huehn 
---
 net/mac80211/rc80211_minstrel.c| 46 +++--
 net/mac80211/rc80211_minstrel.h|  4 +-
 net/mac80211/rc80211_minstrel_debugfs.c| 12 ++---
 net/mac80211/rc80211_minstrel_ht.c | 79 ++
 net/mac80211/rc80211_minstrel_ht.h |  1 +
 net/mac80211/rc80211_minstrel_ht_debugfs.c | 12 ++---
 6 files changed, 94 insertions(+), 60 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 89db6cf..28de2f7a 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -69,13 +69,34 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
return i;
 }
 
+/* return current EMWA throughput */
+int minstrel_get_tp_avg(struct minstrel_rate *mr)
+{
+   int tp_avg, usecs;
+
+   usecs = mr->perfect_tx_time;
+   if (!usecs)
+   usecs = 100;
+
+   /* reset thr. below 10% success */
+   if (mr->stats.prob_ewma < MINSTREL_FRAC(10, 100))
+   tp_avg = 0;
+   else
+   tp_avg = MINSTREL_TRUNC(mr->stats.prob_ewma * (10 / usecs));
+
+   return tp_avg;
+}
+
+
+
 /* find & sort topmost throughput rates */
 static inline void
 minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
 {
int j = MAX_THR_RATES;
 
-   while (j > 0 && mi->r[i].stats.cur_tp > mi->r[tp_list[j - 
1]].stats.cur_tp)
+   while (j > 0 && (minstrel_get_tp_avg(&mi->r[i]) >
+   minstrel_get_tp_avg(&mi->r[tp_list[j - 1]])))
j--;
if (j < MAX_THR_RATES - 1)
memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1));
@@ -158,8 +179,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
 {
u8 tmp_tp_rate[MAX_THR_RATES];
u8 tmp_prob_rate = 0;
-   u32 usecs;
-   int i;
+   int i, tmp_cur_tp, tmp_prob_tp;
 
for (i = 0; i < MAX_THR_RATES; i++)
tmp_tp_rate[i] = 0;
@@ -168,19 +188,9 @@ minstrel_update_stats(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
struct minstrel_rate *mr = &mi->r[i];
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
 
-   usecs = mr->perfect_tx_time;
-   if (!usecs)
-   usecs = 100;
-
/* Update success probabilities per rate */
minstrel_calc_rate_stats(mrs);
 
-   /* Update throughput per rate, reset thr. below 10% success */
-   if (mrs->prob_ewma < MINSTREL_FRAC(10, 100))
-   mrs->cur_tp = 0;
-   else
-   mrs->cur_tp = mrs->prob_ewma * (100 / usecs);
-
/* Sample less often below the 10% chance of success.
 * Sample less often above the 95% chance of success. */
if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
@@ -205,7 +215,9 @@ minstrel_update_stats(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
 * (2) if all success probabilities < 95%, the rate with
 * highest success probability is chosen as max_prob_rate */
if (mrs->prob_ewma >= MINSTREL_FRAC(95, 100)) {
-   if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp)
+   tmp_cur_tp = minstrel_get_tp_avg(mr);
+   tmp_prob_tp = 
minstrel_get_tp_avg(&mi->r[tmp_prob_rate]);
+   if (tmp_cur_tp >= tmp_prob_tp)
tmp_prob_rate = i;
} else {
if (mrs->prob_ewma >= 
mi->r[tmp_prob_rate].stats.prob_ewma)
@@ -676,11 +688,15 @@ static u32 minstrel_get_expected_throughput(void 
*priv_sta)
 {
struct minstrel_sta_info *mi = priv_sta;
int idx = mi->max_tp_rate[0];
+   int tmp_cur_tp;
 
/* convert pkt per sec in kbps (1200 is the average pkt size used for
 * computing cur_tp
 */
-   return MINSTREL_TRUNC(mi->r[idx].stats.cur_tp) * 1200 * 8 / 1024;
+   tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx]);
+   tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024;
+
+   return tmp_cur_tp;
 }
 
 const struct rate_control_ops mac80211_minstrel = {
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 58f2870..490df3b 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -38,9 +38,6 @@ struct minstrel_rate_stats {
/* total attempts/success counters */
u64 att_hist, succ_hist;
 
-   /* current EWMA of rate throughput */
-   unsigned int cur_tp;
-
/* statistis 

[PATCH v2 05/10] mac80211: unify Minstrel & Minstrel-HTs calculation of rate statistics

2015-02-13 Thread Thomas Huehn
This patch unifies the calculation of Minstrels and Minstrel-HTs
per-rate statistic. The new common function minstrel_calc_rate_stats()
is called when a statistic update is performed.

Signed-off-by: Thomas Huehn 
---
 net/mac80211/rc80211_minstrel.c| 44 --
 net/mac80211/rc80211_minstrel.h|  3 +++
 net/mac80211/rc80211_minstrel_ht.c | 28 +---
 3 files changed, 32 insertions(+), 43 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 7c86a00..4858e67 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -127,6 +127,32 @@ minstrel_update_rates(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
rate_control_set_rates(mp->hw, mi->sta, ratetbl);
 }
 
+/*
+* Recalculate success probabilities and counters for a given rate using EWMA
+*/
+void
+minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
+{
+   if (unlikely(mrs->attempts > 0)) {
+   mrs->sample_skipped = 0;
+   mrs->cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
+   if (unlikely(!mrs->att_hist))
+   mrs->probability = mrs->cur_prob;
+   else
+   mrs->probability = minstrel_ewma(mrs->probability,
+mrs->cur_prob, EWMA_LEVEL);
+   mrs->att_hist += mrs->attempts;
+   mrs->succ_hist += mrs->success;
+   } else {
+   mrs->sample_skipped++;
+   }
+
+   mrs->last_success = mrs->success;
+   mrs->last_attempts = mrs->attempts;
+   mrs->success = 0;
+   mrs->attempts = 0;
+}
+
 static void
 minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
 {
@@ -146,22 +172,8 @@ minstrel_update_stats(struct minstrel_priv *mp, struct 
minstrel_sta_info *mi)
if (!usecs)
usecs = 100;
 
-   if (unlikely(mrs->attempts > 0)) {
-   mrs->sample_skipped = 0;
-   mrs->cur_prob = MINSTREL_FRAC(mrs->success,
- mrs->attempts);
-   mrs->succ_hist += mrs->success;
-   mrs->att_hist += mrs->attempts;
-   mrs->probability = minstrel_ewma(mrs->probability,
-mrs->cur_prob,
-EWMA_LEVEL);
-   } else
-   mrs->sample_skipped++;
-
-   mrs->last_success = mrs->success;
-   mrs->last_attempts = mrs->attempts;
-   mrs->success = 0;
-   mrs->attempts = 0;
+   /* Update success probabilities per rate */
+   minstrel_calc_rate_stats(mrs);
 
/* Update throughput per rate, reset thr. below 10% success */
if (mrs->probability < MINSTREL_FRAC(10, 100))
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 9613e73..728144c 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -132,6 +132,9 @@ extern const struct rate_control_ops mac80211_minstrel;
 void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
 void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
 
+/* Recalculate success probabilities and counters for a given rate using EWMA 
*/
+void minstrel_calc_rate_stats(struct minstrel_rate_stats *mr);
+
 /* debugfs */
 int minstrel_stats_open(struct inode *inode, struct file *file);
 int minstrel_stats_csv_open(struct inode *inode, struct file *file);
diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
index 80452cf..381d089 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -311,32 +311,6 @@ minstrel_get_ratestats(struct minstrel_ht_sta *mi, int 
index)
return &mi->groups[index / MCS_GROUP_RATES].rates[index % 
MCS_GROUP_RATES];
 }
 
-
-/*
- * Recalculate success probabilities and counters for a rate using EWMA
- */
-static void
-minstrel_calc_rate_ewma(struct minstrel_rate_stats *mr)
-{
-   if (unlikely(mr->attempts > 0)) {
-   mr->sample_skipped = 0;
-   mr->cur_prob = MINSTREL_FRAC(mr->success, mr->attempts);
-   if (!mr->att_hist)
-   mr->probability = mr->cur_prob;
-   else
-   mr->probability = minstrel_ewma(mr->probability,
-   mr->cur_prob, EWMA_LEVEL);
-   mr->att_hist += mr->attempts;
-   mr->succ_hist += mr->success;
-   } else {
-   mr->sample_skipped++;
-   }
-   mr->last_success = mr->success;
-   mr->last_attempts = mr->attempts;
-   mr->success = 0;
-   mr->attempts = 0;
-}
-
 /*
  * Calculate throughput b

[PATCH v2 08/10] mac80211: add max. lossless throughput per rate to rc_stats

2015-02-13 Thread Thomas Huehn
This patch adds the new statistic "maximum possible lossless
throughput" to Minstrels and Minstrel-HTs rc_stats (in debugfs). This
enables comprehensive comparison between current per-rate throughput
and max. achievable per-rate throughput.

Signed-off-by: Thomas Huehn 
---
 net/mac80211/rc80211_minstrel.c| 12 
 net/mac80211/rc80211_minstrel.h|  1 +
 net/mac80211/rc80211_minstrel_debugfs.c| 18 +++---
 net/mac80211/rc80211_minstrel_ht.c | 19 +++
 net/mac80211/rc80211_minstrel_ht.h |  1 +
 net/mac80211/rc80211_minstrel_ht_debugfs.c | 20 
 6 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 28de2f7a..42dfef8 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -87,7 +87,19 @@ int minstrel_get_tp_avg(struct minstrel_rate *mr)
return tp_avg;
 }
 
+/* return max. potential lossless throughput */
+int minstrel_get_tp_max(struct minstrel_rate *mr)
+{
+   int tp_max, usecs;
 
+   usecs = mr->perfect_tx_time;
+   if (!usecs)
+   usecs = 100;
+
+   tp_max = 10 / usecs;
+
+   return tp_max;
+}
 
 /* find & sort topmost throughput rates */
 static inline void
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 490df3b..6693d8d 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -135,6 +135,7 @@ void minstrel_remove_sta_debugfs(void *priv, void 
*priv_sta);
 /* Recalculate success probabilities and counters for a given rate using EWMA 
*/
 void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs);
 int minstrel_get_tp_avg(struct minstrel_rate *mr);
+int minstrel_get_tp_max(struct minstrel_rate *mr);
 
 /* debugfs */
 int minstrel_stats_open(struct inode *inode, struct file *file);
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c 
b/net/mac80211/rc80211_minstrel_debugfs.c
index d8ccef7..182d552 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -75,7 +75,7 @@ minstrel_stats_open(struct inode *inode, struct file *file)
 {
struct minstrel_sta_info *mi = inode->i_private;
struct minstrel_debugfs_info *ms;
-   unsigned int i, tp_avg, prob, eprob;
+   unsigned int i, tp_max, tp_avg, prob, eprob;
char *p;
 
ms = kmalloc(2048, GFP_KERNEL);
@@ -85,9 +85,9 @@ minstrel_stats_open(struct inode *inode, struct file *file)
file->private_data = ms;
p = ms->buf;
p += sprintf(p, "\n");
-   p += sprintf(p, "best   ___rate___statistics__"
+   p += sprintf(p, "best   __rate___statistics__"
"last_____sum-of\n");
-   p += sprintf(p, "rate  [name idx airtime]  [ ??(tp) ??(prob)]  "
+   p += sprintf(p, "rate  [name idx airtime max_tp]  [ ??(tp) ??(prob)]  "
"[prob.|retry|suc|att]  [#success | #attempts]\n");
 
for (i = 0; i < mi->n_rates; i++) {
@@ -103,14 +103,16 @@ minstrel_stats_open(struct inode *inode, struct file 
*file)
p += sprintf(p, " %3u%s ", mr->bitrate / 2,
(mr->bitrate & 1 ? ".5" : "  "));
p += sprintf(p, "%3u  ", i);
-   p += sprintf(p, "%6u  ", mr->perfect_tx_time);
+   p += sprintf(p, "%6u ", mr->perfect_tx_time);
 
+   tp_max = minstrel_get_tp_max(mr);
tp_avg = minstrel_get_tp_avg(mr);
prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
 
-   p += sprintf(p, " %4u.%1u   %3u.%1u %3u.%1u %3u"
+   p += sprintf(p, "%4u.%1u   %4u.%1u   %3u.%1u %3u.%1u %3u"
"   %3u %-3u   %9llu   %-9llu\n",
+   tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
prob / 10, prob % 10,
@@ -145,7 +147,7 @@ minstrel_stats_csv_open(struct inode *inode, struct file 
*file)
struct minstrel_sta_info *mi = inode->i_private;
struct minstrel_debugfs_info *ms;
struct timeval tv;
-   unsigned int i, tp_avg, prob, eprob;
+   unsigned int i, tp_max, tp_avg, prob, eprob;
char *p;
 
ms = kmalloc(2048, GFP_KERNEL);
@@ -173,12 +175,14 @@ minstrel_stats_csv_open(struct inode *inode, struct file 
*file)
p += sprintf(p, "%u,", i);
p += sprintf(p, "%u,",mr->perfect_tx_time);
 
+   tp_max = minstrel_get_tp_max(mr);
tp_avg = minstrel_get_tp_avg(mr);
prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
 
-

[PATCH v2 04/10] mac80211: add new Minstrel-HT statistic output via csv

2015-02-13 Thread Thomas Huehn
This patch adds a new debugfs file "rc_stats_csv" to output
Minstrel-HTs statistics in a common csv format that is easy
to parse.

Signed-off-by: Thomas Huehn 
Signed-off-by: Stefan Venz 
---
 net/mac80211/rc80211_minstrel_ht.h |   1 +
 net/mac80211/rc80211_minstrel_ht_debugfs.c | 145 -
 2 files changed, 144 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_ht.h 
b/net/mac80211/rc80211_minstrel_ht.h
index f2217d6..3cc30e8 100644
--- a/net/mac80211/rc80211_minstrel_ht.h
+++ b/net/mac80211/rc80211_minstrel_ht.h
@@ -112,6 +112,7 @@ struct minstrel_ht_sta_priv {
};
 #ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *dbg_stats;
+   struct dentry *dbg_stats_csv;
 #endif
void *ratelist;
void *sample_table;
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c 
b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index b300513..ae05780 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -107,8 +107,8 @@ minstrel_ht_stats_open(struct inode *inode, struct file 
*file)
struct minstrel_ht_sta *mi = &msp->ht;
struct minstrel_debugfs_info *ms;
unsigned int i;
-   char *p;
int ret;
+   char *p;
 
if (!msp->is_ht) {
inode->i_private = &msp->legacy;
@@ -146,7 +146,6 @@ minstrel_ht_stats_open(struct inode *inode, struct file 
*file)
MINSTREL_TRUNC(mi->avg_ampdu_len),
MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10);
ms->len = p - ms->buf;
-
WARN_ON(ms->len + sizeof(*ms) > 32768);
 
return nonseekable_open(inode, file);
@@ -160,6 +159,145 @@ static const struct file_operations minstrel_ht_stat_fops 
= {
.llseek = no_llseek,
 };
 
+static char *
+minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p,
+   struct timeval tv)
+{
+   const struct mcs_group *mg;
+   unsigned int j, tp, prob, eprob, tx_time;
+   char htmode = '2';
+   char gimode = 'L';
+   u32 gflags;
+
+   if (!mi->groups[i].supported)
+   return p;
+
+   mg = &minstrel_mcs_groups[i];
+   gflags = mg->flags;
+
+   if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+   htmode = '4';
+   else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+   htmode = '8';
+   if (gflags & IEEE80211_TX_RC_SHORT_GI)
+   gimode = 'S';
+
+   for (j = 0; j < MCS_GROUP_RATES; j++) {
+   struct minstrel_rate_stats *mr = &mi->groups[i].rates[j];
+   static const int bitrates[4] = { 10, 20, 55, 110 };
+   int idx = i * MCS_GROUP_RATES + j;
+
+   if (!(mi->groups[i].supported & BIT(j)))
+   continue;
+
+   p += sprintf(p, "%ld.%.6ld,", tv.tv_sec, tv.tv_usec);
+
+   if (gflags & IEEE80211_TX_RC_MCS) {
+   p += sprintf(p, "HT%c0,", htmode);
+   p += sprintf(p, "%cGI,", gimode);
+   p += sprintf(p, "%d,", mg->streams);
+   } else if (gflags & IEEE80211_TX_RC_VHT_MCS) {
+   p += sprintf(p, "VHT%c0,", htmode);
+   p += sprintf(p, "%cGI,", gimode);
+   p += sprintf(p, "%d,", mg->streams);
+   } else {
+   p += sprintf(p, "CCK,");
+   p += sprintf(p, "%cP,", j < 4 ? 'L' : 'S');
+   p += sprintf(p, "1,");
+   }
+
+   p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[0]) ? "A," : 
","));
+   p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[1]) ? "B," : 
","));
+   p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[2]) ? "C," : 
","));
+   p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[3]) ? "D," : 
","));
+   p += sprintf(p, "%s" ,((idx == mi->max_prob_rate) ? "P," : 
","));
+
+   if (gflags & IEEE80211_TX_RC_MCS) {
+   p += sprintf(p, "MCS%-2u,", (mg->streams - 1) * 8 + j);
+   } else if (gflags & IEEE80211_TX_RC_VHT_MCS) {
+   p += sprintf(p, "MCS%-1u/%1u,", j, mg->streams);
+   } else {
+   int r = bitrates[j % 4];
+   p += sprintf(p, "%2u.%1uM,", r / 10, r % 10);
+   }
+
+   p += sprintf(p, "%u,", idx);
+   tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000);
+   p += sprintf(p, "%u,", tx_time);
+
+   tp = mr->cur_tp / 10;
+   prob = MINSTREL_TRUNC(mr->cur_prob * 1000);
+   eprob = MINSTREL_TRUNC(mr->probability * 1000);
+
+   p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u,%llu,%llu,",
+   tp / 10, tp % 10,
+   eprob / 10, eprob % 10,
+   prob / 10, prob % 10,
+  

[PATCH v2 01/10] mac80211: enhance readability of Minstrels rc_stats output

2015-02-13 Thread Thomas Huehn
This patch restructures the rc_stats debugfs table of Minstrel in
order to achieve better human readability. A new layout of the
statistics and a new header is added. In addition to the old layout
there are two new columns of information added:
idx - representing the rate index of each rate in mac80211 which
  can be used to set specific rates as fixed rate via debugfs
airtime - the tx-time in micro seconds that a 1200 Byte packet
  takes to be transmitted over the air at the given rate

The old layout of rc_stats:

rate  tpt  eprob *prob ret  *ok(*cum)ok(  cum)
 DP 1  0.9  93.5 100.0   10(   0) 2(2)
2  0.4  40.0 100.0   00(   0) 4(10)
5.50.0   0.0   0.0   00(   0) 0(0)
...

is changed into this new layout:

best   ___rate___statistics__last___
__sum-of
rate  [name idx tx-time]  [ ø(tp) ø(prob)]  [prob.|retry|suc|att]  [#success | 
#attempts]
 DP   1 0 9738  0.993.5 100.0   1 1 1 2   2
  2 1 4922  0.440.0 100.0   1 0 0 4   10
  5.5   2 1858  0.0 0.0   0.0   2 0 0 0   0
...

Signed-off-by: Thomas Huehn 
Signed-off-by: Stefan Venz 
---
 net/mac80211/rc80211_minstrel_debugfs.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_debugfs.c 
b/net/mac80211/rc80211_minstrel_debugfs.c
index 2acab1b..2d70081 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -68,8 +68,12 @@ minstrel_stats_open(struct inode *inode, struct file *file)
 
file->private_data = ms;
p = ms->buf;
-   p += sprintf(p, "rate  tpt eprob *prob"
-   "  *ok(*cum)ok(  cum)\n");
+   p += sprintf(p, "\n");
+   p += sprintf(p, "best   ___rate___statistics__"
+   "last_____sum-of\n");
+   p += sprintf(p, "rate  [name idx airtime]  [ ø(tp) ø(prob)]  "
+   "[prob.|retry|suc|att]  [#success | #attempts]\n");
+
for (i = 0; i < mi->n_rates; i++) {
struct minstrel_rate *mr = &mi->r[i];
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
@@ -79,18 +83,22 @@ minstrel_stats_open(struct inode *inode, struct file *file)
*(p++) = (i == mi->max_tp_rate[2]) ? 'C' : ' ';
*(p++) = (i == mi->max_tp_rate[3]) ? 'D' : ' ';
*(p++) = (i == mi->max_prob_rate) ? 'P' : ' ';
-   p += sprintf(p, "%3u%s", mr->bitrate / 2,
+
+   p += sprintf(p, " %3u%s ", mr->bitrate / 2,
(mr->bitrate & 1 ? ".5" : "  "));
+   p += sprintf(p, "%3u  ", i);
+   p += sprintf(p, "%6u  ", mr->perfect_tx_time);
 
tp = MINSTREL_TRUNC(mrs->cur_tp / 10);
prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
eprob = MINSTREL_TRUNC(mrs->probability * 1000);
 
-   p += sprintf(p, " %4u.%1u %3u.%1u %3u.%1u"
-   " %4u(%4u) %9llu(%9llu)\n",
+   p += sprintf(p, " %4u.%1u   %3u.%1u %3u.%1u %3u"
+   "   %3u %-3u   %9llu   %-9llu\n",
tp / 10, tp % 10,
eprob / 10, eprob % 10,
prob / 10, prob % 10,
+   mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
(unsigned long long)mrs->succ_hist,
-- 
2.2.2

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/10] Improve Minstrels & Minstrel-HTs common code base & statistics

2015-02-13 Thread Thomas Huehn
This patch series adds several improvements to the readability, the
output format of rc_stats and the calculated statistics of Minstrel
and Minstrel-HT. Variable names got more consistent and functions
got unified between both rate control algorithms.

Greetings Thomas

---
Changes in v2:
- fix define MACRO from CPTCFG_* into CONFIG_*
- change standard deviation symbol sigma into "sd"

[PATCH v2 01/10] mac80211: enhance readability of Minstrels rc_stats
[PATCH v2 02/10] mac80211: enhance readability of Minstrel-HTs
[PATCH v2 03/10] mac80211: add new Minstrel statistic output via csv
[PATCH v2 04/10] mac80211: add new Minstrel-HT statistic output via
[PATCH v2 05/10] mac80211: unify Minstrel & Minstrel-HTs calculation
[PATCH v2 06/10] mac80211: improve Minstrel variable & function
[PATCH v2 07/10] mac80211: restructure per-rate throughput
[PATCH v2 08/10] mac80211: add max. lossless throughput per rate to
[PATCH v2 09/10] mac80211: reduce calculation costs of EWMA
[PATCH v2 10/10] mac80211: add standard deviation to Minstrels
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ath10k: Increase AST table SKID length limit

2015-02-13 Thread SenthilKumar Jegadeesan
On Thu, Feb 12, 2015 at 05:13:21AM -0800, Ben Greear wrote:
> 
> 
> On 02/12/2015 01:28 AM, SenthilKumar Jegadeesan wrote:
> >The current SKID length configuration causes firmware
> >to reject peer creation for not able to allocate
> >AST entries for peers. This issue is observed when
> >least significant 3 bytes are used ramdomly to create
> >client MAC addresses.
> >
> >AST table SKID length configuration is increased to
> >maximum value to fix this issue.
> 
> If your firmware is like 10.1, then probably AST length should
> really be same as config.num_peers?
> 
> 10.1 firmware definitely has same or similar issue in it's
> AST table handling, for what that is worth.
> 
> Thanks,
> Ben

I agree. New patch will address this case.

Thanks,
Senthil J
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] ath10k: workaround qca6174 sta powersave issue

2015-02-13 Thread Michal Kazior
qca6184 WLAN.RM.2.0-00073 has a bug in sta
powersave state machine and requires peer param to
be poked to enable the powersave.

Calling this unconditionally should be safe for
other chips/firmwares.

Signed-off-by: Michal Kazior 
---
 drivers/net/wireless/ath/ath10k/mac.c | 12 
 drivers/net/wireless/ath/ath10k/wmi.h |  3 ++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index d6d2f0f..8ed0ba6 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1853,6 +1853,18 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
}
 
arvif->is_up = true;
+
+   /* Workaround: Some firmware revisions (tested with qca6174
+* WLAN.RM.2.0-00073) have buggy powersave state machine and must be
+* poked with peer param command.
+*/
+   ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
+   WMI_PEER_DUMMY_VAR, 1);
+   if (ret) {
+   ath10k_warn(ar, "failed to poke peer %pM param for ps 
workaround on vdev %i: %d\n",
+   arvif->bssid, arvif->vdev_id, ret);
+   return;
+   }
 }
 
 static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index 20ce360..c56de92 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4436,7 +4436,8 @@ enum wmi_peer_param {
WMI_PEER_AUTHORIZE  = 0x3,
WMI_PEER_CHAN_WIDTH = 0x4,
WMI_PEER_NSS= 0x5,
-   WMI_PEER_USE_4ADDR  = 0x6
+   WMI_PEER_USE_4ADDR  = 0x6,
+   WMI_PEER_DUMMY_VAR  = 0xff, /* dummy parameter for STA PS workaround */
 };
 
 struct wmi_peer_set_param_cmd {
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] ath10k: disable multi-vif ps by default

2015-02-13 Thread Michal Kazior
Not all firmware revisions have a proper
multi-interface client powersaving implementation,
e.g. qca6174 WLAN.RM.2.0-00073.

Signed-off-by: Michal Kazior 
---
@Kalle: 999.999.0.636 seems to work okay with
multi-vif PS so you might want to bump it with the
MULTI_VIF_PS_SUPPORT feature flag set.

 drivers/net/wireless/ath/ath10k/core.h |  7 +++
 drivers/net/wireless/ath/ath10k/mac.c  | 31 +--
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index d60e46f..c900ef2 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -288,6 +288,7 @@ struct ath10k_vif {
bool is_started;
bool is_up;
bool spectral_enabled;
+   bool ps;
u32 aid;
u8 bssid[ETH_ALEN];
 
@@ -413,6 +414,12 @@ enum ath10k_fw_features {
 */
ATH10K_FW_FEATURE_WMI_10_2 = 4,
 
+   /* Some firmware revisions lack proper multi-interface client powersave
+* implementation. Enabling PS could result in connection drops,
+* traffic stalls, etc.
+*/
+   ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT = 5,
+
/* keep last */
ATH10K_FW_FEATURE_COUNT,
 };
diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 8ed0ba6..bab8adc 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1253,6 +1253,20 @@ static int ath10k_mac_vif_recalc_ps_poll_count(struct 
ath10k_vif *arvif)
return 0;
 }
 
+static int ath10k_mac_ps_vif_count(struct ath10k *ar)
+{
+   struct ath10k_vif *arvif;
+   int num = 0;
+
+   lockdep_assert_held(&ar->conf_mutex);
+
+   list_for_each_entry(arvif, &ar->arvifs, list)
+   if (arvif->ps)
+   num++;
+
+   return num;
+}
+
 static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
 {
struct ath10k *ar = arvif->ar;
@@ -1262,13 +1276,24 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif 
*arvif)
enum wmi_sta_ps_mode psmode;
int ret;
int ps_timeout;
+   bool enable_ps;
 
lockdep_assert_held(&arvif->ar->conf_mutex);
 
if (arvif->vif->type != NL80211_IFTYPE_STATION)
return 0;
 
-   if (vif->bss_conf.ps) {
+   enable_ps = arvif->ps;
+
+   if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 &&
+   !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
+ ar->fw_features)) {
+   ath10k_warn(ar, "refusing to enable ps on vdev %i: not 
supported by fw\n",
+   arvif->vdev_id);
+   enable_ps = false;
+   }
+
+   if (enable_ps) {
psmode = WMI_STA_PS_MODE_ENABLED;
param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
 
@@ -3546,7 +3571,9 @@ static void ath10k_bss_info_changed(struct ieee80211_hw 
*hw,
}
 
if (changed & BSS_CHANGED_PS) {
-   ret = ath10k_mac_vif_setup_ps(arvif);
+   arvif->ps = vif->bss_conf.ps;
+
+   ret = ath10k_config_ps(ar);
if (ret)
ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
arvif->vdev_id, ret);
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] iwl4965: Enable checking of format strings

2015-02-13 Thread Rasmus Villemoes
On Fri, Feb 13 2015, David Laight  wrote:

> From: Rasmus Villemoes
>> Well, probably the linker is allowed to overlap "anonymous" objects
>> (string literals) with whatever const char[] (or indeed any const)
>> object it finds containing the appropriate byte sequence. But I think
>> language lawyers would insist that for
>> 
>> const char foo[] = "a string";
>> const char bar[] = "a string";
>
> A quick test shows those are separate strings.
> But 'const char *foo = "xxx";' will share.

Yes, of course, because in that case you are actually creating two
objects, "xxx" which the linker will find some place to put, and foo
which is initialized to the address of whereever "xxx" was/will be
put. So one is wasting sizeof(const char*). Also, passing foo to a
function means the compiler has to load the value of foo and use that,
instead of simply passing the compile-time (well, link-time) constant
address of "xxx".

> You also need -O1 to get the strings into .rodata.str.n so that the linker
> can merge them.

Sure, optimization has to be turned on, but isn't the kernel always
compiled with -O2? ISTR that there are some things which won't even
work/compile with -O0.

Rasmus
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] iwl4965: Enable checking of format strings

2015-02-13 Thread David Laight
From: Rasmus Villemoes
> Well, probably the linker is allowed to overlap "anonymous" objects
> (string literals) with whatever const char[] (or indeed any const)
> object it finds containing the appropriate byte sequence. But I think
> language lawyers would insist that for
> 
> const char foo[] = "a string";
> const char bar[] = "a string";

A quick test shows those are separate strings.
But 'const char *foo = "xxx";' will share.
You also need -O1 to get the strings into .rodata.str.n so that the linker
can merge them.

David

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


rtl8192cu beacon fix unreliable

2015-02-13 Thread Mike Turner
When using hostapd and an rtl8192cu Wireless USB adaptor the beacon 
doesn't start sometimes. This was tested with the 

kernel/git/davem/net-next.git repository

and

3423eb92315865d76cb8d488513bfef6ab9251d0

This behaviour is apparently random. If the beacon starts OK then it 
continues. If a beacon isn't generated then it never starts. Repeating 
cycles of hostapd stop/start may or may not generate a beacon. There are 
no specific error messages displayed either on console or in syslog. I 
have repeated hostapd stop/start a number of consecutive times and 
received a beacon each time, however I have also done this a number of 
times and never generated a beacon.

We have succesfully used the pvaret-rtl8192cu driver which is based on the 
vendor driver and used that in conjunction with the modified hostapd code 
that requires use of the rtl871xdrv driver interface and as far as we have 
seen it always generates a beacon. 

Platform is a custom designed Atmel-ARM CPU (AT91SAM9G25) with a D-Link 
DWA-121.

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] iwl4965: Enable checking of format strings

2015-02-13 Thread Rasmus Villemoes
On Fri, Feb 13 2015, Mark Rustad  wrote:

> On 2/12/15 2:20 AM, Rasmus Villemoes wrote:
>> Rather weak arguments, but I have three of them :-)
>
> Yes, weak. All three.
>
>> (1) If I'm reading some code and spot a non-constant format
>> argument, I sometimes track back to see how e.g. fmt_value is
>> defined. If I then see it's a macro, I immediately think "ok, the
>> compiler is doing type-checking". If it is a const char[], I have
>> to remember that gcc also does it in that case (as opposed to for
>> example const char*const).
>
> GCC should check in both cases. The case you are replacing was not
> const char * const, but only const char *. Still, the compiler really
> should check either form, even though theoretically the pointer in the
> latter case could be changed, but the initial const value should be a
> good indication of what the parameters are expected to be. No real
> reason for the compiler not to check it.

I agree with all of that - just wanted to point out what gcc currently
does and doesn't, and changing to const char[] would indeed enable
checking.

>> (2) The names of these variables themselves may end up wasting a
>> few bytes in the image.
>
> Maybe in a debug image, but they should be stripped from any normal
> image. Really not a factor.

Sure, that was by far the weakest, and let's ignore that.

>> (3) gcc/the linker doesn't merge identical const char[] arrays
>> across translation units. It also doesn't consider their tails for
>> merging with string literals. So although these specific strings
>> are unlikely to appear elsewhere, a string such as "%10u\n" or
>> "max\n" couldn't be merged with one of the above.
>
> I haven't checked, but there is no theoretical reason that const char
> [] items could not be merged exactly as the literals are. Considering
> the boundaries the compiler guys push on optimization, doing such
> merging would be tame by comparison (speculative stores make me crazy).

Well, probably the linker is allowed to overlap "anonymous" objects
(string literals) with whatever const char[] (or indeed any const)
object it finds containing the appropriate byte sequence. But I think
language lawyers would insist that for

const char foo[] = "a string";
const char bar[] = "a string";

foo and bar have different addresses, whether they are defined in the
same or different TUs. One could then argue that if their address is
never taken explicitly it should be ok, but since passing foo to a printf
function effectively makes the address of foo escape the TU (even though
one is formally passing pointer to first element), I can certainly see
why compiler people would be reluctant to do merging of such objects.

Rasmus
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mwifiex: fix usb tx data payload offset issue

2015-02-13 Thread Avinash Patil
From: Zhaoyang Liu 

Commit 84b313b35f8158d7 ("mwifiex: make tx packet 64 byte DMA aligned")
induced payload offset issue for USB interface.

There is no USB interface header for tx packets, so there's no need to
pull interface length while processing tx skb.

This patch fixes this issue.

Signed-off-by: Zhaoyang Liu 
Signed-off-by: Amitkumar Karwar 
Signed-off-by: Avinash Patil 
---
 drivers/net/wireless/mwifiex/txrx.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/txrx.c 
b/drivers/net/wireless/mwifiex/txrx.c
index ac93557..ea4549f 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -80,11 +80,13 @@ EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
 int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
   struct mwifiex_tx_param *tx_param)
 {
-   int ret = -1;
+   int hroom, ret = -1;
struct mwifiex_adapter *adapter = priv->adapter;
u8 *head_ptr;
struct txpd *local_tx_pd = NULL;
 
+   hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
+
if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
head_ptr = mwifiex_process_uap_txpd(priv, skb);
else
@@ -92,11 +94,9 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct 
sk_buff *skb,
 
if (head_ptr) {
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
-   local_tx_pd =
-   (struct txpd *) (head_ptr + INTF_HEADER_LEN);
+   local_tx_pd = (struct txpd *)(head_ptr + hroom);
if (adapter->iface_type == MWIFIEX_USB) {
adapter->data_sent = true;
-   skb_pull(skb, INTF_HEADER_LEN);
ret = adapter->if_ops.host_to_card(adapter,
   MWIFIEX_USB_EP_DATA,
   skb, NULL);
-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html