Changes in mac80211 to make at76c50x-usb working again
RFC 1/1 Changes in mac80211 to make at76c50x-usb working again
Hi,
the at76c50x-usb driver fails to authenticate with an AP. The last working major kernel version was 2.6.30. I investigated the problem and found out that the driver needs to send a join command (CMD_JOIN) prior to the actual authentication process. For the join command, the driver needs to know the bssid of the AP. The problem is now that the mac80211 layer does not inform the driver about the bssid prior to the authentication. So we have a chicken-and-egg dilemma.
The following patch solves the described problem. As it modifies generic mac80211 code and thus has influence on all drivers I'm open for comments on how to make a proper, probably less intrusive patch.
Sebastian
---
net/mac80211/main.c +3 -11
@@ -180,17 +180,9 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,if (!changed)return ; -if (sdata->vif.type ==NL80211_IFTYPE_STATION ) { -/* -* While not associated, claim a BSSID of all-zeroes -* so that drivers don't do any weird things with the -* BSSID at that time. -*/ -if (sdata->vif.bss_conf.assoc) - sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; -else - sdata->vif.bss_conf.bssid = zero; - }else if (sdata->vif.type ==NL80211_IFTYPE_ADHOC ) +if (sdata->vif.type ==NL80211_IFTYPE_STATION ) + sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; +else if (sdata->vif.type ==NL80211_IFTYPE_ADHOC ) sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;else if (sdata->vif.type ==NL80211_IFTYPE_AP ) sdata->vif.bss_conf.bssid = sdata->vif.addr;
net/mac80211/mlme.c +3 -0
@@ -2042,6 +2042,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, wk->sdata = sdata; wk->done = ieee80211_probe_auth_done; +memcpy (sdata->u.mgd.bssid, req->bss->bssid,ETH_ALEN ); +ieee80211_bss_info_change_notify (sdata,BSS_CHANGED_BSSID ); +ieee80211_add_work (wk);return 0 ; }
Quoted 10 lines · Sebastian Smolorz
Hi,
the at76c50x-usb driver fails to authenticate with an AP. The last working major kernel version was 2.6.30. I investigated the problem and found out that the driver needs to send a join command (
CMD_JOIN) prior to the actual authentication process. For the join command, the driver needs to know the bssid of the AP. The problem is now that the mac80211 layer does not inform the driver about the bssid prior to the authentication. So we have a chicken-and-egg dilemma.
Quoted 5 lines
The following patch solves the described problem. As it modifies generic mac80211 code and thus has influence on all drivers I'm open for comments on how to make a proper, probably less intrusive patch.
Sebastian
Hey, thanks for giving attention to this! See below...
Quoted 31 lines
---
net/mac80211/main.c +3
-11@@ -180,17 +180,9 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,if (!changed)return ; -if (sdata->vif.type ==NL80211_IFTYPE_STATION ) { -/* -* While not associated, claim a BSSID of all-zeroes -* so that drivers don't do any weird things with the -* BSSID at that time. -*/ -if (sdata->vif.bss_conf.assoc) - sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; -else - sdata->vif.bss_conf.bssid = zero; - }else if (sdata->vif.type ==NL80211_IFTYPE_ADHOC ) +if (sdata->vif.type ==NL80211_IFTYPE_STATION ) + sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; +else if (sdata->vif.type ==NL80211_IFTYPE_ADHOC ) sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;else if (sdata->vif.type ==NL80211_IFTYPE_AP ) sdata->vif.bss_conf.bssid = sdata->vif.addr;net/mac80211/mlme.c +0
-0
net/mac80211/mlme.c int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, · line 2050
Quoted 9 lines
net/mac80211/mlme.c +3
-0@@ -2042,6 +2042,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, wk->sdata = sdata; wk->done = ieee80211_probe_auth_done; +memcpy (sdata->u.mgd.bssid, req->bss->bssid,ETH_ALEN ); +ieee80211_bss_info_change_notify (sdata,BSS_CHANGED_BSSID ); +ieee80211_add_work (wk);return 0 ; }
FWIW, the code being removed from ieee80211_bss_info_change_notify above was introduced by the following commit:
commit 9cef873798dfcdc10ff40b02abf1de935ceeba85
Author: Johannes Berg <[email protected]> Date: Thu May 14 13:10:14 2009 +0200
mac80211: fix managed mode BSSID handling
Currently, we will ask the driver to configure right away when somebody changes the desired BSSID. That's totally strange because then we will configure the driver without even knowing whether the BSS exists. Change this to only configure the BSSID when associated, and configure a zero BSSID when not associated.
As a side effect, this fixes an issue with the iwlwifi driver which doesn't implement sta_notify properly and uses the BSSID instead and gets very confused if the BSSID is cleared before we disassociate, which results in the warning Marcel posted [1] and iwlwifi bug 1995 [2].
[1] http://thread.gmane.org/gmane.linux.kernel.wireless.general/32598
[2] http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1995
It would be best to avoid reintroducing the bug mentioned in that commit. Perhaps ensuring that iwlwifi's sta_notify is correct would be worthwhile?
What other issues might be introduced from setting a non-zero BSSID when not associated? Will that limit scan results for any devices? Trigger a premature auth or assoc? Etc?
John
Signature · 2 lines
John W. Linville Someday the world will need a hero, and you [email protected] might be all we have. Be ready.
Johannes Berg
maintainerQuoted 4 lines · John W. Linville
Quoted 3 lines · Sebastian Smolorz
Hi,
the at76c50x-usb driver fails to authenticate with an AP.
We need more information on how it fails.
Quoted 13 lines
Quoted 7 lines
The last working
major kernel version was 2.6.30. I investigated the problem and found out that the driver needs to send a join command (CMD_JOIN) prior to the actual authentication process. For the join command, the driver needs to know the bssid of the AP. The problem is now that the mac80211 layer does not inform the driver about the bssid prior to the authentication. So we have a chicken-and-egg dilemma.[1] http://thread.gmane.org/gmane.linux.kernel.wireless.general/32598
[2] http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1995
Quoted 7 lines
Cc Marcel Holtmann <[email protected]>Signed-off-by Johannes Berg <[email protected]>Signed-off-by John W. Linville <[email protected]>It would be best to avoid reintroducing the bug mentioned in that commit. Perhaps ensuring that iwlwifi's
sta_notifyis correct would be worthwhile?
mac80211's sta_notify was since fixed.
Quoted 3 lines
What other issues might be introduced from setting a non-zero BSSID when not associated? Will that limit scan results for any devices? Trigger a premature auth or assoc? Etc?
I still think this is the wrong thing to do though.
What if you want to implement fast roaming? In that case, you still have to authenticate to one AP while associated with another, etc.
johannes
Quoted 7 lines · Johannes Berg
Quoted 4 lines · John W. Linville
Quoted 3 lines · Sebastian Smolorz
Hi,
the at76c50x-usb driver fails to authenticate with an AP.
We need more information on how it fails.
The problem is that the following if-statement is never true:
http://lxr.linux.no/#linux+v2.6.34/drivers/net/wireless/at76c50x-usb.c#L1986
What else information do you need? dmesg output, debugfs trace?
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
The last working
major kernel version was 2.6.30. I investigated the problem and found out that the driver needs to send a join command (CMD_JOIN) prior to the actual authentication process. For the join command, the driver needs to know the bssid of the AP. The problem is now that the mac80211 layer does not inform the driver about the bssid prior to the authentication. So we have a chicken-and-egg dilemma.
Signature · 1 line
Sebastian
Johannes Berg
maintainerQuoted 5 lines · Sebastian Smolorz
Quoted 4 lines · Johannes Berg
Quoted 3 lines · John W. Linville
Quoted 2 lines · Sebastian Smolorz
Hi,
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
the at76c50x-usb driver fails to authenticate with an AP.
We need more information on how it fails.
The problem is that the following if-statement is never true:
http://lxr.linux.no/#linux+v2.6.34/drivers/net/wireless/at76c50x-usb.c#L1986
That link doesn't work.
johannes
Quoted 8 lines · Johannes Berg
Quoted 7 lines · Sebastian Smolorz
Quoted 6 lines · Johannes Berg
Quoted 4 lines · John W. Linville
Quoted 3 lines · Sebastian Smolorz
Hi,
the at76c50x-usb driver fails to authenticate with an AP.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
We need more information on how it fails.
The problem is that the following if-statement is never true:
http://lxr.linux.no/#linux+v2.6.34/drivers/net/wireless/at76c50x-usb.c#L1986
That link doesn't work.
Hm, for me it works. Alternatively:
http://lxr.free-electrons.com/source/drivers/net/wireless/at76c50x-usb.c#L1986
Anyway, it is line 1986 in drivers/net/wireless/at76c50x-usb.c, kernel version 2.6.34.
Signature · 1 line
Sebastian
Johannes Berg
maintainerQuoted 7 lines · Sebastian Smolorz
Quoted 6 lines · Johannes Berg
Quoted 5 lines · Sebastian Smolorz
Quoted 4 lines · Johannes Berg
Quoted 3 lines · John W. Linville
Quoted 2 lines · Sebastian Smolorz
Hi,
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
the at76c50x-usb driver fails to authenticate with an AP.
We need more information on how it fails.
The problem is that the following if-statement is never true:
Hm, for me it works. Alternatively:
http://lxr.free-electrons.com/source/drivers/net/wireless/at76c50x-usb.c#L1986
That works. However, that if statement _will_ be true?
I suppose at76 has some issue where it won't send out frames before knowing the BSSID?
johannes
Quoted 5 lines · Johannes Berg
Quoted 2 lines · John W. Linville
Quoted 1 line · Sebastian Smolorz
the at76c50x-usb driver fails to authenticate with an AP.
We need more information on how it fails.
I debugged this a long time ago. The problem is that firmware's CMD_JOIN only works if bssid is correct one. I remember trying ff:ff:ff:ff:ff:ff, but that didn't work for some reason. The join command needs to be sent before association, otherwise transmission won't work at all. And if I use a random bssid the firmware will filter the replies. But I tested this a long time ago, I might remember something wrong.
I was thinking a hack which would get bssid from association frames and then send CMD_JOIN, before the association frame. IMHO no need to change mac80211 because of this old hardware.
Kalle
Quoted 15 lines · Kalle Valo
Quoted 5 lines · Johannes Berg
Quoted 2 lines · John W. Linville
Quoted 1 line · Sebastian Smolorz
the at76c50x-usb driver fails to authenticate with an AP.
We need more information on how it fails.
I debugged this a long time ago. The problem is that firmware's
CMD_JOINonly works if bssid is correct one. I remember trying ff:ff:ff:ff:ff:ff, but that didn't work for some reason. The join command needs to be sent before association, otherwise transmission won't work at all. And if I use a random bssid the firmware will filter the replies. But I tested this a long time ago, I might remember something wrong.
Quoted 2 lines
I was thinking a hack which would get bssid from association frames and then send
CMD_JOIN, before the association frame.
Could you elaborate a little bit on this?
How do we proceed to make the driver working again? Do you want to work on this issue?
Signature · 1 line
Sebastian
Quoted 10 lines · Sebastian Smolorz
Quoted 8 lines · Kalle Valo
I debugged this a long time ago. The problem is that firmware's
CMD_JOINonly works if bssid is correct one. I remember trying ff:ff:ff:ff:ff:ff, but that didn't work for some reason. The join command needs to be sent before association, otherwise transmission won't work at all. And if I use a random bssid the firmware will filter the replies. But I tested this a long time ago, I might remember something wrong.
Quoted 4 lines
Quoted 2 lines
I was thinking a hack which would get bssid from association frames and then send
CMD_JOIN, before the association frame.Could you elaborate a little bit on this?
Basically my idea is this (all in tx path):
1. if tx frame is an association frame, get bssid from the frame
2. if bssid == priv->bssid, goto step 6
3. store tx frame, don't transmit it yet
4. send CMD_JOIN with new bssid
5. wait for command completion
6. priv->bssid = bssid
7. transmit tx frame
8. done
Ugly as hell, but one option to get the driver working again.
Quoted 2 lines
How do we proceed to make the driver working again? Do you want to work on this issue?
Sorry, currently I only have time to review patches and send comments. If you have the time, it would be great to if you could fix the driver finally.
Signature · 1 line
Kalle Valo
Quoted 26 lines · Kalle Valo
Quoted 9 lines · Sebastian Smolorz
Quoted 8 lines · Kalle Valo
I debugged this a long time ago. The problem is that firmware's
CMD_JOINonly works if bssid is correct one. I remember trying ff:ff:ff:ff:ff:ff, but that didn't work for some reason. The join command needs to be sent before association, otherwise transmission won't work at all. And if I use a random bssid the firmware will filter the replies. But I tested this a long time ago, I might remember something wrong.Quoted 4 lines
Quoted 2 lines
I was thinking a hack which would get bssid from association frames and then send
CMD_JOIN, before the association frame.Could you elaborate a little bit on this?
Basically my idea is this (all in tx path):
1. if tx frame is an association frame, get bssid from the frame
2. if bssid ==priv->bssid, goto step 6
3. store tx frame, don't transmit it yet
4. sendCMD_JOINwith new bssid
5. wait for command completion
6.priv->bssid= bssid
7. transmit tx frame
8. done
Quoted 8 lines
Ugly as hell, but one option to get the driver working again.
Quoted 2 lines
How do we proceed to make the driver working again? Do you want to work on this issue?
Sorry, currently I only have time to review patches and send comments. If you have the time, it would be great to if you could fix the driver finally.
OK, I will write a patch.
Signature · 1 line
Sebastian