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