Broadcom Wireless Drivers

Hi there!
Recently I had some trouble getting my BCM4352 working (Asus 802.11ac), here is a guide of how I fixed it!
Personally I use systemd (this is not the default for a lot of gentoo systems), some commands/steps may be different on your system, I will indicate when something I am doing is specific to systemd!
This guide requires internet access in parts, either use another computer to download these things and copy them over, or use ethernet. If you don't have ethernet either, I salute you for continuing to try o7.

This code was written on:

Linux annic-gentoo 5.16.11-gentoo202202251339 #4 SMP PREEMPT Fri Feb 25 13:42:23 -00 2022 x86_64 AMD Ryzen 7 2700X Eight-Core Processor AuthenticAMD GNU/Linux

As always, square brackets are used to show where commands are optional depending on your system

  1. Get the drivers

    The first thing I needed to do was make sure I had all the correct drivers in my /usr/src/linux/.config file. Luckily, the net-wireless/broadcom-sta package warns you when settings are missing from your kernel.

    The net-wireless/broadcom-sta package comes with the following list of errors:

    ERROR_B43: B43: If you insist on building this, you must blacklist it!
    ERROR_BCMA: BCMA: If you insist on building this, you must blacklist it!
    ERROR_SSB: SSB: If you insist on building this, you must blacklist it!
    ERROR_MAC80211: MAC80211: If you insist on building this, you must blacklist it!
    ERROR_LIB80211: LIB80211: Please enable it. If you can't find it: enabling the driver for "Intel PRO/Wireless 2200BG" (IPW2100 or IPW2200) should suffice.
    ERROR_PREEMPT_RCU: PREEMPT_RCU: Please do not set the Preemption Model to "Preemptible Kernel"; choose something else.
    ERROR_LIB80211_CRYPT_TKIP: LIB80211_CRYPT_TKIP: You will need this for WPA.
    ERROR_X86_INTEL_LPSS: X86_INTEL_LPSS: Please disable it. The module does not work with it enabled.

    If you see any of these errors Don't worry, we'll fix them!

    Run the following command to install the drivers:

    [sudo] emerge [--ask] net-wireless/broadcom-sta
  2. Now we are going to debug the errors/warnings you receive

    1. ERROR: B43, BCMA, SSB, MAC80211

      If you don't want to remove these from your kernel (I did this, by going through and deselecting each one from my menuconfig), you can add the following to your /etc/modprobe.d/blacklist.conf file:

      blacklist b43
      blacklist bcma
      blacklist brcmsmac
      blacklist ssb
    2. ERROR: LIB80211

      If you have just setup your gentoo kernel, this is the most likely error you will see. In order to solve this problem, I'll teach you the method of debugging it!
      We can see that the error is something related the Kernel. So what we must do is change settings in the kernel!
      Let's go to the kernel configuration!

      cd /usr/src/linux
      [sudo] make menuconfig

      Now that we are in the main menu, we can press the / (slash) key. You'll see a search box appear on your screen. Let's type LIB80211 and press enter. You should get a result like this:

      Symbol: LIB80211 [=m]
      Type : tristate
      Defined at net/wireless/Kconfig:206
      Depends on: NET [=y] && WIRELESS [=y]
      Selected by [m]:
      - HOSTAP [=m] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_INTERSIL [=y]
      Selected by [n]:
      - IPW2100 [=n] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_INTEL [=n] && PCI [=y] && CFG8021
      - IPW2200 [=n] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_INTEL [=n] && PCI [=y] && CFG8021
      - LIBIPW [=n] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_INTEL [=n] && PCI [=y] && CFG80211
      - LIBERTAS [=n] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_MARVELL [=n] && CFG80211 [=y]
      - RTLLIB [=n] && STAGING [=n] && WLAN [=y] && m && MODULES [=y]
      - R8188EU [=n] && STAGING [=n] && WLAN [=y] && USB [=y] && CFG80211 [=y] && m && MODULES [=y]

      The symbol highlighted in blue will be different on your system (it'll be [=n]).
      The highlighted (yellow) line will have a key difference in your setup, not all the letters in brackets will be [=m] or [=y], you need this row to have [=y] or [=m] (ignore the other rows for now).
      For me, the ones that were disabled [=n] were WLAN_VENDOR_INTERSIL and HOSTAP.
      Press ENTER to exit, and do another search with the / (slash) key. This time we will search for the value which wasn't activated (e.g. WLAN_VENDER_INTERSIL).
      Searching for WLAN_VENDOR_INTERSIL results in the following:

      Main menu
       -> Device Drivers
        -> Network device support (NETDEVICES [=y])
         -> Wireless LAN (WLAN [=y])

      Follow this route from the main menu (press enter to exit your search). For me, I ended up in the "Wireless LAN section", scrolled down to "Intersil Devices" and pressed space on it to enable it (include it). A new sub-menu appeared, oh look the Host AP option is there! That's convenient, I pressed [m] on this to modularize it!

      If you now press / (slash) and search again for LIB80211, you should see that highlighted row is now full of [=y] or [=m]. Perfect! You have successfully enable LIB80211 (in your config file, you haven't installed it yet, use the right-arrow key to go and save it to a .config file! We'll compile the kernel later!)

    3. ERROR: LIB80211_CRYPT_TKIP

      We will follow the same process as the previous step (2.b.) to solve this problem. Press / (slash) and search for LIB80211_CRYPT_TKIP

      Symbol: LIB80211_CRYPT_TKIP [=m]
      Type : tristate
      Defined at net/wireless/Kconfig:225
      Depends on: NET [=y] && WIRELESS [=y]
      Selects: CRYPTO_LIB_ARC4 [=m]
      Selected by [m]:
      - HOSTAP [=m] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_INTERSIL [=y]
      Selected by [n]:
      - LIBIPW [=n] && NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_INTEL [=n] && PCI [=y] && CFG80211

      You should notice that the requirements of this is the exact same as those for LIB80211, it should already have been selected if you follow (2.1b)

    4. ERROR: PREEMPT_RCU

      On my system, this error was safe to ignore.

    5. ERROR: X86_INTEL_LPSS

      If you do get this issue, go the main menu of config and go [Main Menu] -> [Processor type and features] -> [X86_INTEL_LPSS].
      Press space until it is deselected

  3. Compile the linux kernel

    I assume you know what you are doing here, you should be following your own method for compiling, if you have never done this before, I thoroughly recommend reading this first: Gentoo Installation AMD64 Handbook

    For completeness, I will be posting the commands I ran here (these may not work on your system....)

    $ sudo make -j16
    $ sudo make modules_install
    $ sudo make install
    $ sudo dracut --kver=5.16.11-gentoo
    $ sudo grub-mkconfig -o /boot/grub/grub.cfg
    $ sudo reboot
  4. Use an old version of wpa_supplicant

    After a long time of getting annoyed with the way iwd works (on my system it was NOT stable, I can't say why, and this isn't really meant to diss the work that went into creating it, I use it on my laptop and it is 1000x better than wpa_supplicant, but for some unknown reason it just doesn't work that well on my computer).
    Now for some bad news, the latest versions of wpa_supplicant (2.10 and 2.9 as of 2022) don't work well with broadcom-sta. SOURCE
    Even though redhat have marked this issue as closed, people have still been having problems from 2019-04-28 to this day. Some of the fixes noted might be interested to read if you really need the features of wpa_supplicant-2.9+ (or are worried about the security issues related to using old versions of software). A couple of these are related to NetworkManager (I don't use this), if you use it, it's definitely worth a read!
    In order to fix this, I used an old version of wpa_supplicant.

    mkdir ~/compile
    cd compile
    wget https://w1.fi/releases/wpa_supplicant-2.8.tar.gz
    tar -xvf wpa_supplicant-2.8.tar.gz
    cd wpa_supplicant-2.8

    Now we need to configure our supplicant, open ./wpa_supplicant/.config in your favourite editor, and write this:

    CONFIG_BACKEND=file
    CONFIG_CTRL_IFACE=y
    CONFIG_DEBUG_FILE=y
    CONFIG_DEBUG_SYSLOG=y
    CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
    CONFIG_DRIVER_NL80211=y
    CONFIG_DRIVER_WEXT=y
    CONFIG_DRIVER_WIRED=y
    CONFIG_EAP_GTC=y
    CONFIG_EAP_LEAP=y
    CONFIG_EAP_MD5=y
    CONFIG_EAP_MSCHAPV2=y
    CONFIG_EAP_OTP=y
    CONFIG_EAP_PEAP=y
    CONFIG_EAP_TLS=y
    CONFIG_EAP_TTLS=y
    CONFIG_IEEE8021X_EAPOL=y
    CONFIG_IPV6=y
    CONFIG_LIBNL32=y
    CONFIG_PEERKEY=y
    CONFIG_PKCS12=y
    CONFIG_READLINE=y
    CONFIG_SMARTCARD=y
    CONFIG_WPS=y
    CFLAGS += -I/usr/include/libnl3

    Credit to the writer of this guide, even though it's for Ubuntu and it has some errors, it provided a good boilerplate. If you currently have wpa_supplicant installed, you should remove it with the following commands:

    [sudo] emerge --deselect net-wireless/wpa_supplicant
    [sudo] emerge --depclean

    Now let's compile it:

    cd wpa_supplicant
    make
    [sudo] make install

    Running wpa_supplicant -v should now return:

    wpa_supplicant v2.8
    Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors
  5. Configure wpa_supplicant.conf

    A handy reference for writing this file can be found on the Gentoo wiki. Personally, I'll show you my configuration, because it may just work on your system (if you are connecting to a WPA Wireless Access Point)

    Edit /etc/wpa_supplicant/wpa_supplicant.conf (you need superuser acess)

    update_config=1
    ctrl_interface=/run/wpa_supplicant
    eapol_version=1
    ap_scan=1
    fast_reauth=1
    network={
     ssid="<SSID>"
     psk="<PASSPHRASE>"
     priority=5
    }

    Replace "<SSID>" and "<PASSPHRASE>" with your SSID and Passphrase (password).

  6. Configure conf.d

    Edit /etc/conf.d/wpa_supplicant (with superuser) and add this line

    wpa_supplicant_args="-B -M -c/etc/wpa_supplicant/wpa_supplicant.conf"
  7. Configure system modules

    You need to manually load the LIB80211_CRYPT_TKIP module, so create a new file: /etc/modules-load.d/lib80211_crypt_tkip ad type this in it:

    lib80211_crypt_tkip
  8. Configure Systemd

    The rest of this guide is for systemd users ONLY

    The installation we did for our wpa_supplicant did not include a systemd service, so we will make our own! This code is versatile, so should work even if you have a non-standard wireless device (like wlan0 vs wlp6s0)

    Create a new file: /etc/systemd/system/network-wireless@.service and type the following in it:

    [Unit]
    Description=Wireless network connectivity (%i)
    Wants=network.target
    Before=network.target
    BindsTo=sys-subsystem-net-devices-%i.device
    After=sys-subsystem-net-devices-%i.device

    [Service]
    Type=oneshot
    RemainAfterExit=yes
    TimeoutSec=30
    Killmode=process
    ExecStart=/bin/ip link set dev %i up
    ExecStart=/usr/local/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant.conf -i %i -B

    ExecStop=/bin/ip link set dev %i down

    [Install]
    WantedBy=multi-user.target

    Feel free to change the TimeoutSec variable, I set it at such a low value, so if anything breaks, I don't have to wait indefinitely after each reboot (and then use a livecd to rescue my system)

    If this doesn't work for you, double check the location of the ip binary (by typing whereis ip) and the installation location of wpa_supplicant (by typing whereis wpa_supplicant) and substitute the /bin/ip with your systems location.

    Now we need to choose which Wireless device we are going to use, type ifconfig to see what name your wireless card has (clue: they normally start with a w, i.e. wlan0, wlp6s0, wlp3s0). Take this name and substitute the correct value in to the following command:

    [sudo] ln -s /etc/systemd/system/network-wireless@.service /etc/systemd/system/multi-user.target.wants/network-wireless@wlp6s0.service

    Now enable wpa_supplicant

    [sudo] systemctl enable network-wireless@wlp6s0
  9. Reboot