Installing the manufactures driver for broadcom wireless adapters (the 'wl' driver)

Hello All

     I just managed to successfully install a driver for my broadcom 4312 wireless adapter. The instructions I found on this task were incomplete and caused a lot of head aches. Hopefully this post will help some people avoid my headaches.

Installation

     The first thing you should do is find out your wireless chipset. Use the following command as root and search for the wireless driver.

# lspci
...
02:00.0 Network controller: Broadcom Corporation BCM4312 802.11b/g LP-PHY (rev 01)
...
     Just for reference I have listed the relevant output line from my system.

     Refer to "http://opensuse-guide.org/wlan.php" to find out what driver you should use. For me I was recommended the wl driver. While on the system the b43 driver seems to be the default, however you need to install some custom firmware to get the b43 driver working. This will work and lwfinger has provided a lot of help on this one. So seek out those posts if you want that driver. Otherwise if you want to try the wl driver proceed...

     Now that page recommends simply downloading the driver and voila... unfortunately it is not that easy. The first thing you should do is open up yast and make sure that the "kernel-*-devel" package is installed. The '*' is for your particular kernel. For me it is 'desktop'. Also make sure you have gcc installed if you have not already.

     Now that kernel headers are installed go to the manufacturers webpage and download the appropriate driver "http://www.broadcom.com/support/802.11/linux_sta.php". Store it in a safe folder that you will not delete. You will need this for every kernel update. Also make sure you download the README.txt and give it a quick read. Once it is downloaded unpack the package, and build it. Note <driver_package> is the name of the driver you just down loaded:

# mkdir wl_driver_folder
# cp <driver_package>.tar.gz wl_driver_folder/
# cd wl_driver_folder
# tar -xzvf <driver_package>.tar.gz
# make
     If everything worked then you should have a wl.ko file in that directory. If not well you will just have to try to figure it out... it might complain about missing kernel headers (with a very cryptic error message). In that case you have not successfully installed the correct kernel-*-devel package. That was the only problem I had so if there is another error you will have to ask for help.

     Now there is a little more work. This is really important. If you get this wrong you will find your system crashing at boot. I will talk about how to boot an ill-configured system later. First we will test our newly built driver before we install it permanently. Make sure you execute all the next group of commands without rebooting. 

     So if you read the README.txt you will learn that there are a set of modules that are incompatible with wl.ko, (brcmsmac, b43, ssb, bcma, wl). So you need to make sure they are not loaded and eventually permanently removed. To see if you have these drivers run the following and take notes on what drivers show up.

# lsmod  | grep "brcmsmac\|b43\|ssb\|bcma\|wl"
     Then for each driver that shows up execute the following where <driver> is the offending module.

# rmmod <driver>
     The README recommended the following commands to get the new driver running:

# modprobe lib80211    or      # ieee80211_crypt_tkip
# modprobe cfg80211
# insmod wl.ko
      The last command will install the new driver. Soon you should be able to connect to wireless network. Now if everything works properly you can install this driver permanently. Otherwise I recommend installing the b43 driver by lwfinger. To start the installation we need to make sure that the incompatible drivers are blocked from loading. For each of those offending drivers listed before, execute the following command. Note you should make a backup of '/etc/modprobe.d/50-blacklist.conf' before these commands just in case you make a mistake.

# echo "blacklist <driver>" >> /etc/modprobe.d/50-blacklist.conf 
      Then we need to make a copy of wl.ko into the modules directory. Note <kernel> is for the kernel you have installed, run "uname -r" if you are unsure.

# mkdir /lib/modules/<kernel>/kernel/drivers/net/wireless/wl
# cp wl.ko /lib/modules/<kernel>/kernel/drivers/net/wireless/wl/
     This is the part I struggled with. We need to tell the kernel that a new module is available. I struggled to find a configuration file. It seems there is a module database that needs to be updated with the following command. This automatically scans /lib/modules/<kernel>/ for new modules and updates the database.

# depmod -a
     At this point you have blocked the incompatible modules, and "installed" the new driver. I never tried this but in theory the kernel at boot would automatically load this new module. I took it a step further and basically explicitly instructed the kernel to load the wl driver. If you want to go this next step (highly reccomended) then follow along.

     First you should make a backup of "/etc/sysconfig/kernel" just in case you make a mistake and need to recover the old configuration. Then go into yast and select the "/etc/sysconfig Editor". From the menu on the left select "System->Kernel->MODULES_LOADED_ON_BOOT". In the text field type "wl" (note the .ko extension is ommited), if there are other entries already seperate "wl" with a space.

     So now you can reboot the system. If everything worked, then you should have wireless networking right away! If it freezes on boot or fails to work then you might want to read "trouble-shooting".

Maintenance

     This driver requires some maintenance. Everytime the kernel is updated you will need to update the driver as well. Simply go into the same folder where you downloaded and built the driver and re-build it against the new kernel:

# make clean
# make
     Then you will have to copy that new version into the /lib/module/<kernel> directory as before. With a new kernel <kernel> will be a different name. So run "uname -r" to make sure. Or else you will be installing an incompatible module into a previous kernel (rendering it useless). See commands:

# mkdir /lib/modules/<kernel>/kernel/drivers/net/wireless/wl
# cp wl.ko /lib/modules/<kernel>/kernel/drivers/net/wireless/wl/
    Finally you need to build that database again:

# depmod -a
   That should be all you need to do. All that rmmod, modprobe, insmod and sysconfig editing can be skipped.

Trouble Shooting

    So my motivation in writing this article was the fact that I nearly rendered my system un-bootable trying to get this driver to work. Naturally when you do not know what you are doing you are simplying trying things, rebooting with crossed fingers then banging head and scouring forumns. Very frustrating.... if you have similar troubles let me pass on some tips. There are two things I will explain here. How to boot the unbootable and how to restore the previous module configuration from the recovery terminal.

     To boot the unbootable, you need to run a recovery kernel in run-level 1. This will disable networking (thus no crash-causing network modules should be loaded). At boot in grub2 you will have to select the more options menu entry. Then select your current kernel in recovery mode. Before you press enter, you need to configure it to boot into run-level 1. Press 'e' to edit the boot settings for that entry. That should open an editor that you can use to modify boot options. Look for the line that starts with 'kernel' and has a 'vmlinuz' or 'vmlinux' file with a long list of options. At the end of those options give '1' as an additional argument. Then press 'Ctrl-X' to load those modified settings and boot the recovery. At this point you should boot straight to a single bash terminal where you can login as root and hopefully fix your broken system.

     Ok so you need to fix the system. For me the problem was some errors in the /etc/modprobe configuration files. For you it could be something else. I will tell you how to restore the previous driver configuration so hopefully you can boot again and make a second driver installation attempt without re-installing linux. So to allow the incompatible drivers to load you need to edit those modprobe configuration files. If you made backup of 50-blacklist.conf then restore this back-up. Otherwise open the file in vim, see my command below. (Note these commands assume you followed my directions properly. If you accidentally put these commands in the wrong file you will have to figure this out yourself and fix it in the same way. In this case the 'history' command is helpful for showing your mistake).

# vim /etc/modprobe.d/50-blacklist.conf 
     Scroll down to the bottom of the file. There you should see the results of those 'echo "blacklist <driver>"' commands you gave earlier. You can delete each line by puting the cursor on the line then pressing 'dd'. Once all those lines are deleted save and exit vim by pressing ':wq'.

    If you modified the /etc/sysconfig variables to force the wl driver to load then you should modify that too. If you made a back-up of '/etc/sysconfig/kernel' then simply restore that back-up otherwise you will have to use vim:

# vim /etc/sysconfig/kernel 
   Locate the line that starts with 'MODULES_LOADED_ON_BOOT=" ... wl ... "'. The ellipsis denoting any additional entries you may have on your particular system. So on that line press 'i' to enter "insert" mode in vim (this allows you to edit the file). Then delete that 'wl' entry in the list. Then press "escape" to exit insert mode. Then press ":wq" to save the file and exit.

   So at this point you have the system configured so the previously incompatible drivers will load and the system will not be forced to load the 'wl' module. You might want to go a step further an make it impossible to load the 'wl' module by simply deleting it and updating the module database:

# rm /lib/modules/<kernel>/kernel/drivers/net/wireless/wl/wl.ko
    Finally you need to build that database again:

# depmod -a
   Hopefully this should restore your system to its earlier configuration. If you have other problems then try looking at the logs like dmesg, messages or anything else to try to figure out what is happening. Wish you luck.

Take Care
Pilotmm

‘wl’ driver is in Packman
https://forums.opensuse.org/blogs/caf4926/install-broadcom-drivers-packman-90/

Hi caf

   Thanks for your help. The instructions you gave are definitely easier than my process... Despite the head-aches it has been fun learning more about modules and its satisfying being able to manually install them. I am sure most users will use the package, I recommend that to most people. For those that like to manage their own modules and such I hope this post is helpful.

Take Care
pilot

I should reveal one thing misleading about my original post. I state that all the following instructions should be followed without a re-boot or else… In those instructions I explain how to test the driver without permanently installing it. Then I go on to explain how to permanently install them. The earlier threat does not apply to testing the module. If you get as far as the “insmod” command and you find that the driver is not working well for you then you can safely reboot. The computer will forget about all your earlier commands and everything should load as before… I do not want people thinking they have to permanently install the troublesome driver just to reboot.

Hi Pilotmm, thank you, a real lifesaver, I have been banging my head for a couple of days with this problem.

I don’t, and can’t proclaim to be experienced with the world of opensuse (or liniux as a whole), but using a few guides, installing the wl’ driver failed for me.

I now have wireless due to this guide, so for maybe a small percentage, this is a useful point of interest.

Glad my post worked for you! Its always nice to know my instructions help. Thanks for letting me know…