0
votes

I'm using linux kernel 3.3 (I cannot upgrade my kernel, sorry!) and am trying to use the wpa_cli utility to monitor the status of my WiFi connection. I'm using an Edimax WiFi dongle to connect to a wireless access point.

I expect to see something like this:

# wpa_cli status
Selected interface 'wlan0'
wpa_state=SCANNING
ip_address=XXX.XXX.XXX.XXX
address=XX:XX:XX:XX:XX:XX

Or the same thing but with wpa_state=COMPLETED, depending upon my connection status.

Parsing the this text output allows me to see if my wireless connection is active or scanning. However, I have noticed that after powering off my access point wpa_state=COMPLETED is still being returned. Using the command:

# iwlist wlan0 scanning

Forces a scan and wpa_state will occasionally be correct, but usually (99%) not.

Here is my /etc/wpa_supplicant.conf:

ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
country=US


network={
    ssid="myssid"
    psk="mypsk"
    key_mgmt=WPA-PSK
    eap=
}

After some investigation, I believe something weird is happening causing the kernel to return a cached version of the AP list. I am using the RTL8192cu driver. I've already looked at this issue, and it is not the same as mine.

My belief is that the issue may be somewhere in the kernel. In the file net/mac80211/scan.c, at line 214 in function ieee80211_scan_rx, I see a bssid from the BSS of my AP appear (when AP has power) and get put via ieee80211_rx_bss_put (here). At this point, it is returned in scan results and wpa_supplicant causes the MLME layer in the kernel to authenticate and connect with that AP. However, after disconnecting AP power, I never see the MLME layer relinquish it's atomic_t hold on that BSS. This causes the BSS to never to unlinked in the function cfg80211_bss_expire at the end of a scan (cfg80211_wext_giwscan), in file net/wireless/scan.c, line 205 (here).

Specifically, I would like to know why the atomic used to "hold" a BSS is not decremented on power removal from the AP - causing linux to miss sufficient beacons for a disconnect? Or, is there some configuration with wpa_supplicant I need to add to have the MLME kernel layer decrement it's hold on the BSS, or is this clearly a kernel bug?

I've already tried:

# wpa_cli bss_expire_age 10
# wpa_cli bss_expire_count 2

and have not resolved my issue.

1

1 Answers

0
votes

So after a lot of digging, I found that the issue was because of the kernel's rtlwifi driver. To me, it looks like the rtl8192cu driver was suppose to be responsible for handling missed beacons, by calling the function ieee80211_beacon_loss, but that call is nowhere to be found. I removed support for IEEE80211_HW_BEACON_FILTER in the rtlwifi driver and the issue has been fixed.

This patch is essentially the same changes that I made, and the comments in this file are part of what led to me this answer.