Beacon misses and disconnects

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,

I have a board with an AR6302G-BL3B, using the ath6kl driver. Most (>
80% of units) with this board have no issues, but the remaining ones
disconnect every 1-2 days. When this happens, wpa_supplicant shows the
following:

nl80211: Event message available
nl80211: Drv Event 48 (NL80211_CMD_DISCONNECT) received for wlan0
nl80211: Disconnect event
wlan0: Event DEAUTH (12) received
wlan0: Deauthentication notification
wlan0:  * reason 3
Deauthentication frame IE(s) - hexdump(len=0): [NULL]
wlan0: CTRL-EVENT-DISCONNECTED bssid=b0:c7:45:36:6c:b0 reason=3

So a disconnect is coming up from the ath6kl driver, probably from the firmware.

When I cat /sys/kernel/debug/ieee80211/phy0/ath6kl/tgt_stats, on these
units, I see the following:

...
         Decrypt Err          0
     Duplicate frame        705
    Tkip Mic failure          0
     TKIP format err          0
     CCMP format Err          0
     CCMP Replay Err        866

        Misc Target stats
        =================
   Beacon Miss count      12486
        Num Connects       4903
     Num disconnects       4978
     Beacon avg rssi        -58
...

Notice the high duplicate frame, beacon miss, and high disconnect
counts. On units which don’t exhibit this disconnect problem, these
counts, especially the latter 2, are 0 or fairly close to it (< 10).

I have been testing a theory that perhaps beacon misses, due to a
noisy environment or something, are causing the disconnects, and
finding no existing way to tune the beacon miss time or the number of
beacon misses before disconnect (where is the logic that controls
this? is it in the firmware? in the driver? in wpa_supplicant?) I
added two debugfs endpoints, bmiss_time, and num_beacons, which call
out to the WMI layer to set these parameters in the firmware (I
couldn’t find a WMI function to read these values from the firmware so
I cache them in struct ath6kl):

--- a/drivers/net/wireless/ath/ath6kl/debug.c 2015-05-04
11:35:47.037999199 +0800
+++ b/drivers/net/wireless/ath/ath6kl/debug.c 2015-01-09
18:56:06.106095000 +0800
@@ -1773,6 +1773,91 @@
  .llseek = default_llseek,
 };

+static ssize_t ath6kl_bmiss_time_read(struct file *file,
+      char __user *user_buf,
+      size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ char buf[16];
+ int len;
+
+ len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.bmiss_time);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath6kl_bmiss_time_write(struct file *file,
+       const char __user *user_buf,
+       size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ int ret;
+ u16 val;
+
+ ret = kstrtou16_from_user(user_buf, count, 0, &val);
+ if (ret)
+ return ret;
+
+ ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, 0, val, ar->debug.num_beacons);
+ if (ret)
+ return ret;
+
+    ar->debug.bmiss_time = val;
+
+ return count;
+}
+
+static const struct file_operations fops_bmiss_time = {
+ .open = simple_open,
+ .read = ath6kl_bmiss_time_read,
+ .write = ath6kl_bmiss_time_write,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+static ssize_t ath6kl_num_beacons_read(struct file *file,
+      char __user *user_buf,
+      size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ char buf[16];
+ int len;
+
+ len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.num_beacons);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath6kl_num_beacons_write(struct file *file,
+       const char __user *user_buf,
+       size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ int ret;
+ u16 val;
+
+ ret = kstrtou16_from_user(user_buf, count, 0, &val);
+ if (ret)
+ return ret;
+
+ ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, 0, ar->debug.bmiss_time, val);
+ if (ret)
+ return ret;
+
+    ar->debug.num_beacons = val;
+
+ return count;
+}
+
+static const struct file_operations fops_num_beacons = {
+ .open = simple_open,
+ .read = ath6kl_num_beacons_read,
+ .write = ath6kl_num_beacons_write,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+
 void ath6kl_debug_init(struct ath6kl *ar)
 {
  skb_queue_head_init(&ar->debug.fwlog_queue);
@@ -1862,6 +1947,12 @@
  debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
     &fops_power_params);

+ debugfs_create_file("bmiss_time", S_IRUSR | S_IWUSR,
+                ar->debugfs_phy, ar, &fops_bmiss_time);
+
+ debugfs_create_file("num_beacons", S_IRUSR | S_IWUSR,
+                ar->debugfs_phy, ar, &fops_num_beacons);
+
  return 0;
 }

However, this does not to appear to have fixed the issue. The beacon
misses and disconnects still occur, in bursts, as before.

The firmware version is 3.2.0.265 (is a newer one available?):

[    9.705507] ath6kl: temporary war to avoid sdio crc error
[   10.201316] ath6kl: ar6003 hw 2.1.1 sdio fw 3.2.0.265 api 3
[   10.201434] ath6kl: firmware supports: sched-scan,sta-p2pdev-duplex,rsn-cap-
override,sscan-match-list,custom-mac-addr

The ath6kl driver in 3.8.8 had this issue. I have since used backports
to use the 3.18.1 ath6kl driver in my 3.8.8 kernel, which
unfortunately I cannot upgrade because the BSP is a 156k line vendor
patch that was never merged into the mainline and would take
prohibitively long to forward-port to a 3.10 or newer kernel.

Has anyone else seen this issue? Any ideas for what else I could try?
Is my patch actually modifying the bmiss_time and num_beacon
parameters in the firmware as I expect?

Appreciate any help!

- Chris

_______________________________________________
ath6kl mailing list
ath6kl@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/ath6kl





[Index of Archives]     [Linux Kernel]     [Linux Wireless]     [Linux Bluetooth]     [Linux WPAN]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]

  Powered by Linux