Skip to contentSkip to conversation

Changes in mac80211 to make at76c50x-usb working again

RFC In review Sebastian Smolorz 4 participants 11 messages Jun 15, 2010 – Jun 17, 2010 mac80211

lore
Share & tools
lore
#0 lore raw

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
index a1bf46c..6c34b4f 100644
@@ -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
index 4dad08f..b06b175 100644
@@ -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;
 }
#1 lore raw
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
index a1bf46c..6c34b4f 100644
@@ -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
index 4dad08f..b06b175 100644

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.
maintainer
#2 lore raw
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.

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

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?

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

#3 lore raw
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
maintainer
#4 lore raw
Quoted 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

#5 lore raw
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
maintainer
#6 lore raw
Quoted 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

#7 lore raw
In reply to Johannes Berg
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

#8 lore raw
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_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.

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
#9 lore raw
Quoted 10 lines · Sebastian Smolorz
Quoted 8 lines · Kalle Valo

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.

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
#10 lore raw
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_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.

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

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