Bug#843387:

2016-11-20 Thread Luis Ortega
So here's the v2 of the patch. It's been thoroughly tested and the warnings
are avoided now. Additionally, I threw in improvements in the modified
functions. Regrettably, one change I had to leave out was modernizing the
parameters in cfg80211_get_bss(), since it made the warning on NULL bss from
wl_notify_roaming_status() reappear, no matter what I tried.

One piece of advise: sometimes the driver will fail to connect, just as it did
before. NetworkManager will prompt for the password but it won't join.
Connecting manually through the networks list will succeed, however it may be
necessary to retry a few times.

Enabling the debug information we can see how, upon a successful connection,
two EAPOL_MSG events are ignored by the driver, whereas on unsuccessful ones,
they keep popping until we are DEAUTHenticated.

If anyone at Broadcom ever reads this, please give some love to this driver.
Or better yet, push for it being open sourced. We would all be very grateful.
--- a/amd64/src/wl/sys/wl_cfg80211_hybrid.c
+++ b/amd64/src/wl/sys/wl_cfg80211_hybrid.c
@@ -1968,7 +1968,7 @@
 
 	if (dtoh32(bi->length) > WL_BSS_INFO_MAX) {
 		WL_DBG(("Beacon is larger than buffer. Discarding\n"));
-		return err;
+		return -E2BIG;
 	}
 	notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
 	 WL_BSS_INFO_MAX, GFP_KERNEL);
@@ -1992,9 +1992,15 @@
 	beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
 	wl_rst_ie(wl);
 
-	wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
-	wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
+	err = wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
+	if (err)
+		goto inform_single_bss_out;
+
+	err = wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
 	 offsetof(struct wl_cfg80211_bss_info, frame_buf));
+	if (err)
+		goto inform_single_bss_out;
+
 	notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.beacon.variable) +
 	wl_get_ielen(wl);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
@@ -2006,14 +2012,14 @@
 #endif
 	if (freq == 0) {
 		WL_ERR(("Invalid channel, fail to chcnage channel to freq\n"));
-		kfree(notif_bss_info);
-		return -EINVAL;
+		err = -EINVAL;
+		goto inform_single_bss_out;
 	}
 	channel = ieee80211_get_channel(wiphy, freq);
 	if (unlikely(!channel)) {
 		WL_ERR(("ieee80211_get_channel error\n"));
-		kfree(notif_bss_info);
-		return -EINVAL;
+		err = -EINVAL;
+		goto inform_single_bss_out;
 	}
 
 	WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
@@ -2021,28 +2027,37 @@
 		mgmt->u.beacon.capab_info, &bi->BSSID));
 
 	signal = notif_bss_info->rssi * 100;
-	cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
-	le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
-	if (unlikely(!cbss)) {
-		WL_ERR(("cfg80211_inform_bss_frame error\n"));
-		kfree(notif_bss_info);
-		return -EINVAL;
-	}
 
-	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
-	notify_ielen = le32_to_cpu(bi->ie_length);
+	if (!wl->scan_request) {
+		cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+			le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
+		if (unlikely(!cbss)) {
+			WL_ERR(("cfg80211_inform_bss_frame error\n"));
+			err = -ENOMEM;
+			goto inform_single_bss_out;
+		}
+	} else {
+		notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+		notify_ielen = le32_to_cpu(bi->ie_length);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
-	cbss = cfg80211_inform_bss(wiphy, channel, (const u8 *)(bi->BSSID.octet),
-		0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int,
-		(const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
+		cbss = cfg80211_inform_bss(wiphy, channel, (const u8 *)(bi->BSSID.octet),
+			0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int,
+			(const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
 #else
-	cbss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, (const u8 *)(bi->BSSID.octet),
-		0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int,
-		(const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
+		cbss = cfg80211_inform_bss(wiphy, channel,
+wl->active_scan ?
+CFG80211_BSS_FTYPE_PRESP : CFG80211_BSS_FTYPE_BEACON,
+(const u8 *)(bi->BSSID.octet), 0,
+beacon_proberesp->capab_info,
+beacon_proberesp->beacon_int,
+(const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
 #endif
-
-	if (unlikely(!cbss))
-		return -ENOMEM;
+		if (unlikely(!cbss)) {
+			WL_ERR(("cfg80211_inform_bss error\n"));
+			err = -ENOMEM;
+			goto inform_single_bss_out;
+		}
+	}
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
 	cfg80211_put_bss(wiphy, cbss);
@@ -2050,6 +2065,7 @@
 	cfg80211_put_bss(cbss);
 #endif
 
+inform_single_bss_out:
 	kfree(notif_bss_info);
 
 	return err;
@@ -2316,6 +2332,9 @@
 		if (err)
 			goto update_bss_info_out;
 
+		bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
+		  ssid->SSID, ssid->SSID_len, WL

Bug#843389:

2016-11-20 Thread Luis Ortega
With the v2 patch for #843387, this one is effectively not needed any more.



Bug#843387:

2016-11-08 Thread Luis Ortega
I was convinced it was solved but the symptoms have reappeared. This
patch needs further testing.

--
Luis Ortega Pérez de Villar



Bug#843389: Memory leak code path

2016-11-06 Thread Luis Ortega
Package: broadcom-sta-dkms
Version: 6.30.223.271-4

While fixing the issue reported in bug #843387 I noticed a code path that
causes a memory leak. Included is patch with the fix.

--
Luis Ortega Pérez de Villar
--- a/amd64/src/wl/sys/wl_cfg80211_hybrid.c
+++ b/amd64/src/wl/sys/wl_cfg80211_hybrid.c
@@ -2006,14 +2006,14 @@
 #endif
 	if (freq == 0) {
 		WL_ERR(("Invalid channel, fail to chcnage channel to freq\n"));
-		kfree(notif_bss_info);
-		return -EINVAL;
+		err = -EINVAL;
+		goto inform_single_bss_out;
 	}
 	channel = ieee80211_get_channel(wiphy, freq);
 	if (unlikely(!channel)) {
 		WL_ERR(("ieee80211_get_channel error\n"));
-		kfree(notif_bss_info);
-		return -EINVAL;
+		err = -EINVAL;
+		goto inform_single_bss_out;
 	}
 
 	WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
@@ -2034,8 +2034,10 @@
 		(const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
 #endif
 
-	if (unlikely(!cbss))
-		return -ENOMEM;
+	if (unlikely(!cbss)) {
+		err = -ENOMEM;
+		goto inform_single_bss_out;
+	}
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
 	cfg80211_put_bss(wiphy, cbss);
@@ -2043,6 +2045,7 @@
 	cfg80211_put_bss(cbss);
 #endif
 
+inform_single_bss_out:
 	kfree(notif_bss_info);
 
 	return err;


Bug#843387: Kernel warning on __cfg80211_connect_result and wl_notify_roaming_status

2016-11-06 Thread Luis Ortega
nc.
Macmini7,1/Mac-35C5E08120C7EEAF, BIOS MM71.88Z.0220.B00.1409291751
09/29/2014
[  160.310516]  0286 dc5a1a29 a891a245

[  160.310518]   a867a03e 88026126d720
88023eb3fd14
[  160.310520]  88026126df3a 880261b89000 88026126db18
88026f2d6d80
[  160.310521] Call Trace:
[  160.310526]  [] ? dump_stack+0x5c/0x77
[  160.310530]  [] ? __warn+0xbe/0xe0
[  160.310556]  [] ? wl_notify_roaming_status+0xb6/0x130 [wl]
[  160.310579]  [] ? wl_event_handler+0x58/0x1a0 [wl]
[  160.310605]  [] ? wl_notify_scan_status+0x310/0x310 [wl]
[  160.310608]  [] ? kthread+0xcd/0xf0
[  160.310610]  [] ? ret_from_fork+0x1f/0x40
[  160.310612]  [] ? kthread_create_on_node+0x190/0x190
[  160.310614] ---[ end trace 691fdb2f0f364a43 ]---


Attached is a proposal patch with the solution, which I have tested
satisfactorily for a week.

--
Luis Ortega Pérez de Villar
--- a/amd64/src/wl/sys/wl_cfg80211_hybrid.c
+++ b/amd64/src/wl/sys/wl_cfg80211_hybrid.c
@@ -2021,13 +2021,6 @@
 		mgmt->u.beacon.capab_info, &bi->BSSID));
 
 	signal = notif_bss_info->rssi * 100;
-	cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
-	le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
-	if (unlikely(!cbss)) {
-		WL_ERR(("cfg80211_inform_bss_frame error\n"));
-		kfree(notif_bss_info);
-		return -EINVAL;
-	}
 
 	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
 	notify_ielen = le32_to_cpu(bi->ie_length);