Wednesday, October 29, 2014

Broadcom brcmsmac without channel 12 & 13 - they did it again...

Just updated my EeePC to Ubuntu 14.10 and - bam: no wireless network connection anymore. Channels 12 & 13 are gone again.

This time we take the module parameter approach as in The missing Atheros channels to override the regulatory domain setting read from SPROM (which is US in my case where only 11 channels are allowed), because setting the regulatory domain with

iw reg set <regdom>
 
does not work.

diff -ru brcm80211.orig/brcmsmac/channel.c brcm80211/brcmsmac/channel.c
--- brcm80211.orig/brcmsmac/channel.c    2014-10-15 12:05:43.000000000 +0200
+++ brcm80211/brcmsmac/channel.c    2014-10-25 14:26:51.667082058 +0200
@@ -323,6 +323,8 @@
     return;
 }

+extern const char * get_param_regdom(void);
+
 struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
 {
     struct brcms_cm_info *wlc_cm;
@@ -330,6 +332,20 @@
     struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
     const char *ccode = sprom->alpha2;
     int ccode_len = sizeof(sprom->alpha2);
+    const char *regdom = get_param_regdom();
+    char regdom_sprom[3];
+    char regdom_param[3];
+
+    strncpy((char *)&regdom_sprom, ccode, 2);
+    regdom_sprom[2] = '\0';
+    brcms_info(wlc->hw->d11core, "Regulatory domain from SPROM: %s\n", regdom_sprom);
+
+    if (strlen(regdom) > 0) {
+        strncpy((char *)&regdom_param, regdom, 2);
+        regdom_param[2] = '\0';
+        brcms_info(wlc->hw->d11core, "Overriding regulatory domain from %s to %s\n" , regdom_sprom, regdom_param);
+        ccode = regdom;
+    }

     wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
     if (wlc_cm == NULL)
diff -ru brcm80211.orig/brcmsmac/mac80211_if.c brcm80211/brcmsmac/mac80211_if.c
--- brcm80211.orig/brcmsmac/mac80211_if.c    2014-10-15 12:05:43.000000000 +0200
+++ brcm80211/brcmsmac/mac80211_if.c    2014-10-25 14:20:46.158547508 +0200
@@ -112,6 +112,15 @@
 module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR);
 #endif

+static char *regdom = "";
+module_param(regdom, charp, S_IRUGO);
+MODULE_PARM_DESC(regdom, "Override the regulatory domain from SPROM");
+
+const char * get_param_regdom(void)
+{
+    return regdom;
+}
+
 static struct ieee80211_channel brcms_2ghz_chantable[] = {
     CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
     CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),


This adds the module parameter regdom to brcmsmac. To set this parameter persistently create /etc/modprobe.d/brcmsmac.conf with 

options brcmsmac regdom=<insert your regdom here>

Also it's a good idea to create /etc/modprobe.d/cfg80211.conf with

options cfg80211 ieee80211_regdom=<insert your regdom here>

Have fun!