>On Sun, 05 Jan 2014 04:02:30 +0100
>"Armin K." <kre...@email.com> wrote:
>
> On 5.1.2014 2:42, Aleksandar Kuktin wrote:

> > So I expect I will be unable to make it compile since I have no idea
> > even where to begin with fixing this much lossage.
> 
> Use the patches from my Archlinux AUR package:
> 
> https://aur.archlinux.org/packages/br/broadcom-sta-dkms/broadcom-sta-dkms.tar.gz

I had to apply the changes manually since the hybrid's code changed in
the meantime and these patches do not apply anymore. I'm attaching the
new patches to this e-mail.

> > [snip]
> > 
> > For reference, what kernel do you build your version against?
> 
> 3.13.0-rc5, as mentioned in the document.

Right. I read many packages in there but forgot to look at the kernel.

While I made a lot of progress, I am now in a way worse off then I was
before. I built the module, built the lib80211 module (which is
autoselecting so I had to build an unneeded driver to make it build),
unloaded both the b43 and ssb (which required disabling the b44 driver
- that one's for Broadcom ethernet devices), loaded wl and got treated
to this:

lib80211: common routines for IEEE802.11 drivers
lib80211_crypt: registered algorithm 'NULL'
wl: module license 'MIXED/Proprietary' taints kernel.
Disabling lock debugging due to kernel taint
malloc in abgphy done
wl driver 6.30.223.141 (r415941) failed with code 21
------------[ cut here ]------------
kernel BUG at include/net/cfg80211.h:3127!
invalid opcode: 0000 [#1] PREEMPT SMP
Modules linked in: wl(PO+) lib80211
CPU: 0 PID: 165 Comm: modprobe Tainted: P        W  O 3.12.1 #17
... and so on with the rest of the backtrace ...

The backtrace happens because wl_cfg80211_detach() from the open-source
part of wl gets passed zero as argument to which then ndev_to_wl()
(which is a wrapper over a wrapper to some function defined in
include/net/cfg80211.h) panics. That's not the problem.

The problem is the line about "failed with code 21", the cause of which
I managed to trace into the blob. Or rather, that is not the problem,
that is an accomplishment (this was my first time debugging the kernel
and it was fun!), but the problem is that I have been living for years
in open source where everything is possible (subject to the Law of
conservation of matter), but now I'm looking at having to either debug
a blob (nevermind I'm legaly not supposed to do that) or wait (read:
beg) for Broadcom to mercifully decide to *try* to fix the problem and
maybe succeed, but also maybe not, provided they don't give up halfway
through.

-- 
Svi moji e-mailovi su kriptografski potpisani. Proverite ih.
All of my e-mails are cryptographically signed. Verify them.
--
You don't need an AI for a robot uprising.
Humans will do just fine.
diff -Naur wl-old/Makefile wl-new/Makefile
--- wl-old/Makefile	2013-08-01 08:52:22.000000000 +0200
+++ wl-new/Makefile	2014-01-05 14:42:57.000000000 +0100
@@ -126,17 +126,23 @@
 EXTRA_CFLAGS       += -I$(src)/src/shared/bcmwifi/include
 #EXTRA_CFLAGS       += -DBCMDBG_ASSERT
 
+ifeq ($(KVER),)
+       KVER = $(shell uname -r)
+endif
+
+PWD      = $(shell pwd)
+
 EXTRA_LDFLAGS      := $(src)/lib/wlc_hybrid.o_shipped
 
-KBASE              ?= /lib/modules/`uname -r`
+KBASE              ?= /lib/modules/$(KVER)
 KBUILD_DIR         ?= $(KBASE)/build
 MDEST_DIR          ?= $(KBASE)/kernel/drivers/net/wireless
 
 all:
-	KBUILD_NOPEDANTIC=1 make -C $(KBUILD_DIR) M=`pwd`
+	KBUILD_NOPEDANTIC=1 make -C $(KBUILD_DIR) M=$(PWD)
 
 clean:
-	KBUILD_NOPEDANTIC=1 make -C $(KBUILD_DIR) M=`pwd` clean
+	KBUILD_NOPEDANTIC=1 make -C $(KBUILD_DIR) M=$(PWD) clean
 
 install:
 	install -D -m 755 wl.ko $(MDEST_DIR)
diff -Naur wl-old/src/wl/sys/wl_linux.c wl-new/src/wl/sys/wl_linux.c
--- wl-old/src/wl/sys/wl_linux.c	2013-08-01 08:52:22.000000000 +0200
+++ wl-new/src/wl/sys/wl_linux.c	2014-01-05 14:44:11.000000000 +0100
@@ -179,6 +179,8 @@
 static void wl_report_radio_state(wl_info_t *wl);
 #endif
 
+MODULE_LICENSE("MIXED/Proprietary");
+
 static struct pci_device_id wl_id_table[] =
 {
 	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -235,7 +237,7 @@
 #define to_str(s) #s
 #define quote_str(s) to_str(s)
 
-#define BRCM_WLAN_IFNAME eth%d
+#define BRCM_WLAN_IFNAME wlan%d
 
 static char intf_name[IFNAMSIZ] = quote_str(BRCM_WLAN_IFNAME);
 
diff -Naur wl-old/Makefile wl-new/Makefile
--- wl-old/Makefile	2014-01-05 15:18:51.000000000 +0100
+++ wl-new/Makefile	2014-01-05 14:47:53.000000000 +0100
@@ -21,7 +21,7 @@
 ifneq ($(KERNELRELEASE),)
 
   LINUXVER_GOODFOR_CFG80211:=$(strip $(shell \
-    if [ "$(VERSION)" -ge "2" -a "$(PATCHLEVEL)" -ge "6" -a "$(SUBLEVEL)" -ge "32" -o "$(VERSION)" -ge "3" ]; then \
+    if [ "$(VERSION)" -ge "3" -o "$(VERSION)" -ge "2" -a "$(PATCHLEVEL)" -ge "6" -a "$(SUBLEVEL)" -ge "32" ]; then \
       echo TRUE; \
     else \
       echo FALSE; \
@@ -29,7 +29,7 @@
   ))
 
     LINUXVER_WEXT_ONLY:=$(strip $(shell \
-    if [ "$(VERSION)" -ge "2" -a "$(PATCHLEVEL)" -ge "6" -a "$(SUBLEVEL)" -ge "17" ]; then \
+    if [ "$(VERSION)" -ge "3" -o "$(VERSION)" -ge "2" -a "$(PATCHLEVEL)" -ge "6" -a "$(SUBLEVEL)" -ge "17" ]; then \
       echo FALSE; \
     else \
       echo TRUE; \
diff -Naur wl-old/src/include/bcmutils.h wl-new/src/include/bcmutils.h
--- wl-old/src/include/bcmutils.h	2013-08-01 08:52:22.000000000 +0200
+++ wl-new/src/include/bcmutils.h	2014-01-05 14:49:02.000000000 +0100
@@ -612,11 +612,14 @@
 extern void prhex(const char *msg, uchar *buf, uint len);
 
 extern bcm_tlv_t *BCMROMFN(bcm_next_tlv)(bcm_tlv_t *elt, int *buflen);
-extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key);
 extern bcm_tlv_t *BCMROMFN(bcm_parse_ordered_tlvs)(void *buf, int buflen, uint key);
 
 extern const char *bcmerrorstr(int bcmerror);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
 extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(void *buf, int buflen, uint key);
+#else
+extern bcm_tlv_t *BCMROMFN(bcm_parse_tlvs)(const void *buf, int buflen, uint key);
+#endif
 
 typedef uint32 mbool;
 #define mboolset(mb, bit)		((mb) |= (bit))		
diff -Naur wl-old/src/wl/sys/wl_cfg80211_hybrid.c wl-new/src/wl/sys/wl_cfg80211_hybrid.c
--- wl-old/src/wl/sys/wl_cfg80211_hybrid.c	2013-08-01 08:52:22.000000000 +0200
+++ wl-new/src/wl/sys/wl_cfg80211_hybrid.c	2014-01-05 15:09:33.000000000 +0100
@@ -1443,7 +1443,10 @@
 		memset(&scb_val, 0, sizeof(scb_val));
 		err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t));
 		if (err) {
-			WL_DBG(("Could not get rssi (%d)\n", err));
+			if (err != -EINVAL) {
+				// Don't fill syslog with EINVAL error
+				WL_ERR(("Could not get rssi (%d)\n", err));
+			}
 			return err;
 		}
 		rssi = dtoh32(scb_val.val);
@@ -2009,8 +2012,13 @@
 	struct bcm_tlv *tim;
 	s32 dtim_period;
 	size_t ie_len;
-	u8 *ie;
 	s32 err = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
+	u8 *ie;
+#else
+	const u8 *ie;
+	const struct cfg80211_bss_ies *ies;
+#endif
 
 	ssid = &wl->profile->ssid;
 	bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
@@ -2040,8 +2048,14 @@
 	} else {
 		WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
-		ie = (u8 *)(bss->ies->data);
-		ie_len = bss->ies->len;
+		ies = (const struct cfg80211_bss_ies*)rcu_dereference(bss->ies);
+		if (!ies) {
+			/* This should never happen */
+			err = -EIO;
+			goto update_bss_info_out;
+		}
+		ie = ies->data;
+		ie_len = (size_t)(ies->len);
 #else
 		ie = bss->information_elements;
 		ie_len = bss->len_information_elements;
diff -Naur wl-old/src/wl/sys/wl_iw.h wl-new/src/wl/sys/wl_iw.h
--- wl-old/src/wl/sys/wl_iw.h	2013-08-01 08:52:22.000000000 +0200
+++ wl-new/src/wl/sys/wl_iw.h	2014-01-05 15:09:54.000000000 +0100
@@ -22,6 +22,7 @@
 #define _wl_iw_h_
 
 #include <linux/wireless.h>
+#include <linux/semaphore.h>
 
 #include <typedefs.h>
 #include <proto/ethernet.h>
diff -Naur wl-old/src/wl/sys/wl_linux.c wl-new/src/wl/sys/wl_linux.c
--- wl-old/src/wl/sys/wl_linux.c	2014-01-05 15:18:51.000000000 +0100
+++ wl-new/src/wl/sys/wl_linux.c	2014-01-05 15:18:04.000000000 +0100
@@ -912,7 +912,11 @@
 	pci_set_drvdata(pdev, NULL);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
 static struct pci_driver wl_pci_driver = {
+#else
+static struct pci_driver wl_pci_driver __refdata = {
+#endif
 	name:		"wl",
 	probe:		wl_pci_probe,
 	suspend:	wl_suspend,
@@ -1683,11 +1687,7 @@
 	}
 
 	WL_LOCK(wl);
-	if (!capable(CAP_NET_ADMIN)) {
-		bcmerror = BCME_EPERM;
-	} else {
-		bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
-	}
+	bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
 	WL_UNLOCK(wl);
 
 done1:
@@ -3237,7 +3237,7 @@
 void
 wl_tkip_printstats(wl_info_t *wl, bool group_key)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
 	char debug_buf[512];
 	int idx;
 	if (wl->tkipmodops) {
@@ -3410,6 +3410,7 @@
 	return 0;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
 static int
 wl_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
 {
@@ -3464,19 +3465,89 @@
 	return length;
 }
 
+#else
+
+static int
+wl_proc_read(struct seq_file *seq, void *offset)
+{
+	wl_info_t * wl = (wl_info_t *)seq->private;
+	int bcmerror, to_user;
+
+	WL_LOCK(wl);
+	bcmerror = wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL);
+	WL_UNLOCK(wl);
+
+	seq_printf(seq, "%d\n", to_user);
+	return bcmerror;
+}
+
+static ssize_t wl_proc_write(struct file *file, const char __user *buff,
+			     size_t length, loff_t *ppos)
+{
+	struct seq_file *seq = file->private_data;
+	wl_info_t * wl = (wl_info_t *)seq->private;
+	int bcmerror, from_user = 0;
+
+	if (length != 1) {
+		WL_ERROR(("%s: Invalid data length\n", __FUNCTION__));
+		return -EIO;
+	}
+
+	if (copy_from_user(&from_user, buff, 1)) {
+		WL_ERROR(("%s: copy from user failed\n", __FUNCTION__));
+		return -EFAULT;
+	}
+
+	if (from_user >= 0x30)
+		from_user -= 0x30;
+
+	WL_LOCK(wl);
+	bcmerror = wlc_ioctl(wl->wlc, WLC_SET_MONITOR, &from_user, sizeof(int), NULL);
+	WL_UNLOCK(wl);
+
+	if (bcmerror < 0) {
+		WL_ERROR(("%s: SET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
+		return -EIO;
+	}
+	*ppos += length;
+	return length;
+}
+
+static int wl_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, wl_proc_read, PDE_DATA(inode));
+}
+
+static const struct file_operations wl_proc_fops = {
+	.owner = THIS_MODULE,
+	.open = wl_proc_open,
+	.read = seq_read,
+	.write = wl_proc_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+#endif
+
 static int
 wl_reg_proc_entry(wl_info_t *wl)
 {
 	char tmp[32];
 	sprintf(tmp, "%s%d", HYBRID_PROC, wl->pub->unit);
-	if ((wl->proc_entry = create_proc_entry(tmp, 0644, NULL)) == NULL) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+	wl->proc_entry = create_proc_entry(tmp, 0644, NULL);
+	if (wl->proc_entry) {
+		wl->proc_entry->read_proc = wl_proc_read;
+		wl->proc_entry->write_proc = wl_proc_write;
+		wl->proc_entry->data = wl;
+	} 
+#else
+	wl->proc_entry = proc_create_data(tmp, 0644, NULL, &wl_proc_fops, wl);
+#endif
+	if (!wl->proc_entry) {
 		WL_ERROR(("%s: create_proc_entry %s failed\n", __FUNCTION__, tmp));
 		ASSERT(0);
 		return -1;
 	}
-	wl->proc_entry->read_proc = wl_proc_read;
-	wl->proc_entry->write_proc = wl_proc_write;
-	wl->proc_entry->data = wl;
 	return 0;
 }
 #ifdef WLOFFLD

Attachment: signature.asc
Description: PGP signature

-- 
http://linuxfromscratch.org/mailman/listinfo/blfs-dev
FAQ: http://www.linuxfromscratch.org/blfs/faq.html
Unsubscribe: See the above information page

Reply via email to