来源:https://wiki.centos.org/HowTos/Laptops/Wireless/Broadcom
Broadcom Corporation Based Wireless NICs
BCM4311, BCM4312, BCM4313, BCM4321, BCM4322,
BCM43224, BCM43225, BCM43227 and BCM43228
These chipsets are not natively supported by CentOS.
- NOTE: This manual is primarily intended for EL6 and EL7. If you are running EL 5, 6, or 7, instead of compilation, you can opt to build your own kABI-compatible binary RPM package of the driver which is reusable after kernel updates. For more info, please refer to ELRepo kmod-wl page. Also, it's been reported that the this driver doesn't work with all chips, so kindly provide feedback on your experiences with Broadcom Wireless, so this manual can be kept up to date and further improved.
- NOTE: Due to an excessively restrictive license accompanying this Broadcom driver, the ELRepo repository developers have refrained from supplying it via an rpm package - hence this manual was created with the purpose of providing a single comprehenssive driver installation manual.
- NOTE: This manual is based on CentOS 6 and tested with Broadcom BCM4313 (Vendor/DeviceID 14e4:4727). Previous Wiki version was written for CentOS 5 and Broadcom BCM4311/4312 chips have been tested on it.
- NOTE: Please note that driver compilation was tested only on latest kernel version 2.6.32-573.7.1.el6.x86_64 shipped with CentOS 6.7, wl driver version 6.30.223.271 (latest). With that in mind, also note that some sections, such as Appendix A, and RHEL 7 driver compilation may apply only to the previous driver version, and older kernel versions (pre-CentOS 6.7).
Contents
- Broadcom Corporation BCM4311, BCM4312, BCM4313, BCM4321, BCM4322, BCM43224, BCM43225, BCM43227 and BCM43228 Based Wireless NICs
- Step 1: Determining WLAN chip and installing dependencies
- Step 2: Downloading and extracting Broadcom driver archive
- Step 3a: Compiling the Broadcom driver module (on EL6 and EL7)
- Step 3b: Compiling the Broadcom driver module (specifics required for EL7)
- Step 4a: Loading the driver module into kernel
- Step 4b: Loading the driver module into kernel on boot time
- Appendix A: Broadcom chip models tested and reported (by community members) as working
In order to install Broadcom BCM4311, BCM4312, BCM4313, BCM4321 or BCM4322, BCM43224, BCM43225, BCM43227, or BCM43228 based wireless network cards, the next steps should be followed:
Step 1: Determining WLAN chip and installing dependencies
First of all, make sure you are the "proud owner of Broadcom BCM43xx wireless card":
[user@host ~]$ /sbin/lspci | grep Broadcom 0b:00.0 Network controller: Broadcom Corporation BCM4312 802.11a/b/g (rev 01)
After the WLAN chip model was determined, make sure you have no missing packages needed at compile-time and install them if you do:
[root@host ~]# yum install kernel-headers kernel-devel gcc
Of course, if you're compiling the driver for Xen kernel (i.e. kernel-xen), you should install kernel-xen-devel instead of kernel-devel.
Step 2: Downloading and extracting Broadcom driver archive
Download the Broadcom BCM43xx linux driver archive from Broadcom Official website to your machine and extract it to /usr/local/src/hybrid-wl and feel free to change the ownership of the directory and it's contents to some unprivileged user
[root@host ~]# mkdir -p /usr/local/src/hybrid-wl [root@host hybrid-wl]# cd /usr/local/src/hybrid-wl [root@host hybrid-wl]# tar xvfz /path/to/the/tarball/hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz [root@host hybrid-wl]# chown -R someuser.somegroup /usr/local/src/hybrid-wl
NOTE: Why not extract it to arbitrary location and leave the ownership it is? |
Step 3a: Compiling the Broadcom driver module (on EL6 and EL7)
Driver module can be compiled as follows:
[user@host hybrid-wl]$ make -C /lib/modules/`uname -r`/build/ M=`pwd`
In my case I just ran:
[user@host hybrid-wl]$ makeMind the quotes (i.e. back quotes).
Now, with the current driver (version 6.30.223.271) it's almost certain you'll get an error message instead of compiled driver module (in fact, different scenario other that this error message is unknown to the author). The message might/will vary depending on the kernel and OS version, but on CentOS 6 it should look something like this:
make: Entering directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64' CFG80211 API is prefered for this kernel version Using CFG80211 API LD /usr/local/src/hybrid-wl/built-in.o CC [M] /usr/local/src/hybrid-wl/src/shared/linux_osl.o CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_linux.o CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_iw.o CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.o /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:83: warning: ‘enum tx_power_setting’ declared inside parameter list /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:83: warning: its scope is only this definition or declaration,/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_cfg80211_join_ibss’: /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:730: error: ‘struct cfg80211_ibss_params’ has no member named ‘channel’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: At top level: /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1096: warning: ‘enum tx_power_setting’ declared inside parameter list /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1096: error: parameter 2 (‘type’) has incomplete type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_cfg80211_set_tx_power’: /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1107: error: ‘TX_POWER_AUTOMATIC’ undeclared (first use in this /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1107: error: (Each undeclared identifier is reported only once /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1107: error: for each function it appears in.) /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1109: error: ‘TX_POWER_LIMITED’ undeclared (first use in this function) /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1115: error: ‘TX_POWER_FIXED’ undeclared (first use in this function) /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: At top level: /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1774: warning: initialization from incompatible pointer type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1779: warning: initialization from incompatible pointer type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1780: warning: initialization from incompatible pointer type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1781: warning: initialization from incompatible pointer type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1782: warning: initialization from incompatible pointer type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1783: warning: initialization from incompatible pointer type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1784: warning: initialization from incompatible pointer type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1789: warning: initialization from incompatible pointer type /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_inform_single_bss’: /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1984: error: too few arguments to function /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2023: warning: passing argument 1 of ‘cfg80211_put_bss’ from include/net/cfg80211.h:3380: note: expected ‘struct wiphy *’ but argument is of type ‘struct cfg80211_bss *’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2023: error: too few arguments to function ‘cfg80211_put_bss’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_update_bss_info’: /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2276: error: ‘struct cfg80211_bss’ has no member named /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2277: error: ‘struct cfg80211_bss’ has no member named /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2283: warning: passing argument 1 of ‘cfg80211_put_bss’ from include/net/cfg80211.h:3380: note: expected ‘struct wiphy *’ but argument is of type ‘struct cfg80211_bss *’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2283: error: too few arguments to function ‘cfg80211_put_bss’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_bss_roaming_done’: /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: warning: passing argument 2 of ‘cfg80211_roamed’ from include/net/cfg80211.h:3726: note: expected ‘struct ieee80211_channel *’ but argument is of type ‘u8 *’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: warning: passing argument 4 of ‘cfg80211_roamed’ makes include/net/cfg80211.h:3726: note: expected ‘const u8 *’ but argument is of type ‘s32’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: warning: passing argument 5 of ‘cfg80211_roamed’ makes include/net/cfg80211.h:3726: note: expected ‘size_t’ but argument is of type ‘u8 *’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: warning: passing argument 6 of ‘cfg80211_roamed’ makes include/net/cfg80211.h:3726: note: expected ‘const u8 *’ but argument is of type ‘s32’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2322: error: too few arguments to function ‘cfg80211_roamed’ /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_update_wowl’: /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:2791: warning: unused variable ‘wdev’ make[1]: *** [/usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.o] Error 1 make: *** [_module_/usr/local/src/hybrid-wl] Error 2 make: Leaving directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'
NOTE: This is where the instructions for EL6 and EL7 differ. So, for EL6, you should follow through step 3a, while for EL7, you need to apply only the patches from both steps 3a and 3b, and compile it as shown in this step (3a). So yes, for EL7, skip the 'sed' commands. |
On EL6, the driver won't compile because of the if-then-else clause for kernel version checking in file wl_cfg80211_hybrid.c. To remedy this, we'll run the following two commands:
[user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(2, 6, 3.)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c [user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(3, ., .)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c [user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(3, 11, .)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c [user@host hybrid-wl]$ sed -i 's/< KERNEL_VERSION(3, 18, .)/< KERNEL_VERSION(2, 6, 30)/' src/wl/sys/wl_cfg80211_hybrid.c [user@host hybrid-wl]$ sed -i 's/[ >][>=] KERNEL_VERSION(3, 15, .)/>= KERNEL_VERSION(2, 6, 32)/' src/wl/sys/wl_cfg80211_hybrid.c
Just these 'sed' replacements are not enough to ensure proper driver compilation. So, we also need to apply the following patch wl-kmod-fix-ioctl-handling.patch prior to actually compiling the driver. Download it to /usr/local/src and run the following command to patch the driver source code:
[user@host hybrid-wl]$ patch -p1 < ../wl-kmod-fix-ioctl-handling.patch patching file src/wl/sys/wl_cfg80211_hybrid.c Hunk #1 succeeded at 1467 (offset 17 lines). patching file src/wl/sys/wl_linux.c Hunk #1 succeeded at 1659 (offset 8 lines).
Now, try compiling the driver module again:
[user@host hybrid-wl]$ make -C /lib/modules/`uname -r`/build/ M=`pwd`
and the compile output should look something like this:
make: Entering directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64' CFG80211 API is prefered for this kernel version Using CFG80211 API LD /usr/local/src/hybrid-wl/built-in.o CC [M] /usr/local/src/hybrid-wl/src/shared/linux_osl.o CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_linux.o CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_iw.o CC [M] /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.o /usr/local/src/hybrid-wl/src/wl/sys/wl_cfg80211_hybrid.c:1802: warning: initialization from incompatible pointer type LD [M] /usr/local/src/hybrid-wl/wl.o Building modules, stage 2. CFG80211 API is prefered for this kernel version Using CFG80211 API MODPOST 1 modules CC /usr/local/src/hybrid-wl/wl.mod.o LD [M] /usr/local/src/hybrid-wl/wl.ko.unsigned NO SIGN [M] /usr/local/src/hybrid-wl/wl.ko make: Leaving directory `/usr/src/kernels/2.6.32-573.7.1.el6.x86_64'
The module, once built, can be stripped of unnecessary symbols:
[user@host hybrid-wl]$ strip --strip-debug wl.ko
What you will notice, is that driver module file size reduces (from 8.2MB to 7.2MB). And yes, your driver module works
Step 3b: Compiling the Broadcom driver module (specifics required for EL7)
If you're running EL7, you won't need to run the 'sed' commands from the previous step, however, you will need to apply this one additional patch wl-kmod-rhel7_1.patch (along with the one from step 3a):
[user@host hybrid-wl]$ patch -p1 < ../wl-kmod-rhel7_1.patch patching file src/wl/sys/wl_cfg80211_hybrid.c Hunk #1 succeeded at 1801 (offset -3 lines). Hunk #2 succeeded at 1867 (offset -3 lines). Hunk #3 succeeded at 2071 (offset -3 lines). Hunk #4 succeeded at 2804 (offset -3 lines).In my case, the above patch failed for Hunk #3, so I manually modified ./src/wl/sys/wl_cfg80211_hybrid.c