Skip to content

Instantly share code, notes, and snippets.

@joanbm
Created August 12, 2025 18:15
Show Gist options
  • Select an option

  • Save joanbm/4e7f18febc2c25f5fdf8143a739dccd1 to your computer and use it in GitHub Desktop.

Select an option

Save joanbm/4e7f18febc2c25f5fdf8143a739dccd1 to your computer and use it in GitHub Desktop.
Tentative patch for broadcom-wl 6.30.223.271 driver for Linux 6.17-rc1
From 7c805f65d72befd067ad63387aaa94b764d3f70d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joan=20Bruguera=20Mic=C3=B3?= <[email protected]>
Date: Sat, 28 Jun 2025 22:14:42 +0000
Subject: [PATCH] Tentative patch for broadcom-wl 6.30.223.271 driver for Linux
6.17-rc1
Some function prototype updates, rel. commit "wifi: cfg80211/mac80211:
Add support to get radio index" (Roopni Devanathan, 15 Jun 2025)
---
src/wl/sys/wl_cfg80211_hybrid.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c
index fa9d75e..205c5dd 100644
--- a/src/wl/sys/wl_cfg80211_hybrid.c
+++ b/src/wl/sys/wl_cfg80211_hybrid.c
@@ -68,7 +68,11 @@ wl_cfg80211_scan(struct wiphy *wiphy,
static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request);
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed);
+#else
static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
+#endif
static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ibss_params *params);
static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
@@ -87,7 +91,10 @@ static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme);
static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
+ enum nl80211_tx_power_setting type, s32 dbm);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
static s32
wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, s32 dbm);
@@ -99,7 +106,10 @@ static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
enum tx_power_setting type, s32 dbm);
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
+ u32 link_id, s32 *dbm);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, u32 /*link_id*/, s32 *dbm);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, s32 *dbm);
@@ -659,7 +669,11 @@ static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
return err;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed)
+#else
static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+#endif
{
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
struct net_device *ndev = wl_to_ndev(wl);
@@ -1093,7 +1107,10 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_c
return err;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
+ enum nl80211_tx_power_setting type, s32 dbm)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
static s32
wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, s32 dbm)
@@ -1154,7 +1171,10 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, s32 db
return err;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
+ u32 link_id, s32 *dbm)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, u32 /*link_id*/, s32 *dbm)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, s32 *dbm)
--
2.50.1
@satmandu
Copy link

Applying this to the current debian/ubuntu broadcom-sta package I get this error:

DKMS make.log for broadcom-sta-6.30.223.271 for kernel 6.17.0-rc1 (x86_64)
Tue Aug 12 07:34:39 PM EDT 2025
CFG80211 API is prefered for this kernel version
Makefile:91: Neither CFG80211 nor Wireless Extension is enabled in kernel
KBUILD_NOPEDANTIC=1 make -C /lib/modules/6.17.0-rc1/build M=`pwd`
make[1]: Entering directory '/usr/src/linux-headers-6.17.0-rc1'
make[2]: Entering directory '/var/lib/dkms/broadcom-sta/6.30.223.271/build'
CFG80211 API is prefered for this kernel version
Using CFG80211 API
Kernel architecture is X86_64
  CC [M]  src/shared/linux_osl.o
  CC [M]  src/wl/sys/wl_linux.o
  CC [M]  src/wl/sys/wl_iw.o
  CC [M]  src/wl/sys/wl_cfg80211_hybrid.o
src/wl/sys/wl_linux.c: In function ‘wl_attach’:
src/wl/sys/wl_linux.c:718:70: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
  718 |                 WL_ERROR(("%s: init_rfkill_failure\n", __FUNCTION__));
      |                                                                      ^
src/wl/sys/wl_cfg80211_hybrid.c: In function ‘wl_cfg80211_set_tx_power’:
src/wl/sys/wl_cfg80211_hybrid.c:1142:13: error: ‘dbm’ redeclared as different kind of symbol
 1142 |         s32 dbm = MBM_TO_DBM(mbm);
      |             ^~~
src/wl/sys/wl_cfg80211_hybrid.c:1121:77: note: previous definition of ‘dbm’ with type ‘s32’ {aka ‘int’}
 1121 |                                     enum nl80211_tx_power_setting type, s32 dbm)
      |                                                                         ~~~~^~~
src/wl/sys/wl_linux.c: In function ‘wl_event’:
src/wl/sys/wl_linux.c:2194:79: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
 2194 |                         WL_ERROR(("%s: WLC_GET_RADIO failed\n", __FUNCTION__));
      |                                                                               ^
In file included from ././src/include/lib80211.h:32,
                 from ././src/include/linuxver.h:152,
                 from src/wl/sys/wl_cfg80211_hybrid.c:26:
src/wl/sys/wl_cfg80211_hybrid.c:1142:30: error: ‘mbm’ undeclared (first use in this function); did you mean ‘dbm’?
 1142 |         s32 dbm = MBM_TO_DBM(mbm);
      |                              ^~~
/usr/src/linux-headers-6.17.0-rc1/include/linux/ieee80211.h:4830:28: note: in definition of macro ‘MBM_TO_DBM’
 4830 | #define MBM_TO_DBM(gain) ((gain) / 100)
      |                            ^~~~
src/wl/sys/wl_cfg80211_hybrid.c:1142:30: note: each undeclared identifier is reported only once for each function it appears in
 1142 |         s32 dbm = MBM_TO_DBM(mbm);
      |                              ^~~
/usr/src/linux-headers-6.17.0-rc1/include/linux/ieee80211.h:4830:28: note: in definition of macro ‘MBM_TO_DBM’
 4830 | #define MBM_TO_DBM(gain) ((gain) / 100)
      |                            ^~~~
make[4]: *** [/usr/src/linux-headers-6.17.0-rc1/scripts/Makefile.build:287: src/wl/sys/wl_cfg80211_hybrid.o] Error 1
make[4]: *** Waiting for unfinished jobs....
In file included from /usr/src/linux-headers-6.17.0-rc1/include/linux/srcu.h:21,
                 from /usr/src/linux-headers-6.17.0-rc1/include/linux/notifier.h:16,
                 from /usr/src/linux-headers-6.17.0-rc1/arch/x86/include/asm/uprobes.h:13,
                 from /usr/src/linux-headers-6.17.0-rc1/include/linux/uprobes.h:65,
                 from /usr/src/linux-headers-6.17.0-rc1/include/linux/mm_types.h:16,
                 from /usr/src/linux-headers-6.17.0-rc1/include/linux/mmzone.h:22,
                 from /usr/src/linux-headers-6.17.0-rc1/include/linux/gfp.h:7,
                 from /usr/src/linux-headers-6.17.0-rc1/include/linux/umh.h:4,
                 from /usr/src/linux-headers-6.17.0-rc1/include/linux/kmod.h:9,
                 from /usr/src/linux-headers-6.17.0-rc1/include/linux/module.h:18,
                 from ././src/include/linuxver.h:40,
                 from src/wl/sys/wl_linux.c:27:
src/wl/sys/wl_linux.c: In function ‘wl_down’:
/usr/src/linux-headers-6.17.0-rc1/include/linux/workqueue.h:772:9: warning: call to ‘__warn_flushing_systemwide_wq’ declared with attribute warning: Please avoid flushing system-wide workqueues. [-Wattribute-warning]
  772 |         __warn_flushing_systemwide_wq();                                \
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/wl/sys/wl_linux.c:1512:25: note: in expansion of macro ‘flush_scheduled_work’
 1512 |                         flush_scheduled_work();
      |                         ^~~~~~~~~~~~~~~~~~~~
make[3]: *** [/usr/src/linux-headers-6.17.0-rc1/Makefile:2011: .] Error 2
make[2]: *** [/usr/src/linux-headers-6.17.0-rc1/Makefile:248: __sub-make] Error 2
make[2]: Leaving directory '/var/lib/dkms/broadcom-sta/6.30.223.271/build'
make[1]: *** [Makefile:248: __sub-make] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-6.17.0-rc1'
make: *** [Makefile:183: all] Error 2

@satmandu
Copy link

satmandu commented Aug 13, 2025

After the 41-wl-use-timer_container_of-for-kernel-6.16.patch is applied in the debian series of the current package, I can then apply this, which is a small change of dbm to mdm:

diff -Npaur a/amd64/src/wl/sys/wl_cfg80211_hybrid.c b/amd64/src/wl/sys/wl_cfg80211_hybrid.c
--- a/amd64/src/wl/sys/wl_cfg80211_hybrid.c	2025-08-12 20:02:20.856362034 -0400
+++ b/amd64/src/wl/sys/wl_cfg80211_hybrid.c	2025-08-12 20:10:45.134208056 -0400
@@ -67,7 +67,11 @@ wl_cfg80211_scan(struct wiphy *wiphy,
 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
            struct cfg80211_scan_request *request);
 #endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed);
+#else
 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
+#endif
 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
            struct cfg80211_ibss_params *params);
 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
@@ -86,7 +90,10 @@ static int wl_cfg80211_connect(struct wi
            struct cfg80211_connect_params *sme);
 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
+                                    enum nl80211_tx_power_setting type, s32 dbm);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 static s32
 wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
                          enum nl80211_tx_power_setting type, s32 mbm);
@@ -98,7 +105,10 @@ static s32 wl_cfg80211_set_tx_power(stru
            enum tx_power_setting type, s32 mbm);
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
+                                    u32 link_id, s32 *dbm);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, u32 /*link_id*/, s32 *dbm);
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, s32 *dbm);
@@ -664,7 +674,11 @@ static s32 wl_set_retry(struct net_devic
 	return err;
 }
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, u32 changed)
+#else
 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+#endif
 {
 	struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
 	struct net_device *ndev = wl_to_ndev(wl);
@@ -1102,7 +1116,10 @@ wl_cfg80211_disconnect(struct wiphy *wip
 	return err;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
+                                    enum nl80211_tx_power_setting type, s32 mbm)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 static s32
 wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
                          enum nl80211_tx_power_setting type, s32 mbm)
@@ -1163,7 +1180,10 @@ wl_cfg80211_set_tx_power(struct wiphy *w
 	return err;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 17, 0)
+static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, int radio_idx,
+                                    u32 link_id, s32 *dbm)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(6, 14, 0)
 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, u32 /*link_id*/, s32 *dbm)
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, s32 *dbm)

This fixes the build for me, at least for ubuntu 25.04/plucky.

@joanbm
Copy link
Author

joanbm commented Aug 17, 2025

@satmandu Thanks for the comment & patch for Uubntu! I quickly checked and it looks like Ubuntu's broadcom-sta has an patch (19-wl-Fix-get-set-values-for-tx_power.patch) which Arch's broadcom-wl doesn't, which causes the conflict you're mentioning.

Unfortunately since the driver has been unmaintained for so long, the patch sets have also diverged across distros (and there's little hope of them converging again), so I can't really do much :(

All of the patches I publish are only guaranteed to apply cleanly on Arch as that's what I use.

@immolo
Copy link

immolo commented Sep 1, 2025

First off, thanks for doing the lord's work with these, everyone over at Gentoo thanks you.

main point though is this still required? As 6.17.0-rc4 builds fine without the patch.

@joanbm
Copy link
Author

joanbm commented Sep 6, 2025

@immolo Yes, this is still required for 6.17.0-rc5, without this I get the following build errors:

src/wl/sys/wl_cfg80211_hybrid.c:1822:29: error: initialization of 'int (*)(struct wiphy *, int,  u32)' {aka 'int (*)(struct wiphy *, int,  unsigned int)'} from incompatible pointer type 's32 (*)(struct wiphy *, u32)' {aka 'int (*)(struct wiphy *, unsigned int)'} [-Wincompatible-pointer-types]
 1822 |         .set_wiphy_params = wl_cfg80211_set_wiphy_params,
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/wl/sys/wl_cfg80211_hybrid.c:1826:25: error: initialization of 'int (*)(struct wiphy *, struct wireless_dev *, int,  enum nl80211_tx_power_setting,  int)' from incompatible pointer type 's32 (*)(struct wiphy *, struct wireless_dev *, enum nl80211_tx_power_setting,  s32)' {aka 'int (*)(struct wiphy *, struct wireless_dev *, enum nl80211_tx_power_setting,  int)'} [-Wincompatible-pointer-types]
 1826 |         .set_tx_power = wl_cfg80211_set_tx_power,
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~
src/wl/sys/wl_cfg80211_hybrid.c:1827:25: error: initialization of 'int (*)(struct wiphy *, struct wireless_dev *, int,  unsigned int,  int *)' from incompatible pointer type 's32 (*)(struct wiphy *, struct wireless_dev *, u32,  s32 *)' {aka 'int (*)(struct wiphy *, struct wireless_dev *, unsigned int,  int *)'} [-Wincompatible-pointer-types]
 1827 |         .get_tx_power = wl_cfg80211_get_tx_power,
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~

Possibly you are building with compiler flags that make this a warning instead of an error (but, the built driver may not work correctly).

@immolo
Copy link

immolo commented Sep 6, 2025

@joanbm That was it thanks! Irony being it's the only machine in the house not running GCC16......

@grandtoubab
Copy link

Hello all
Same case on Debian. With the patch of Satmandu I was able to install 6.17.3-x64v2-xanmod1 kernel and wifi is ok!

broadcom-sta-dkms/unstable,now 6.30.223.271-28 amd64 [installé]

root@debian:/usr/src/broadcom-sta-6.30.223.271/src/wl/sys# patch wl_cfg80211_hybrid.c < /home/guy/Linux/broadcom/broadcom-wl-fix-linux-6.17.patch
patching file wl_cfg80211_hybrid.c

/lib/modules/6.17.3-x64v2-xanmod1/updates/dkms$ ls -alrt
total 8968
drwxr-xr-x 3 root root    4096 17 oct.  16:56 ..
drwxr-xr-x 2 root root    4096 17 oct.  16:56 .
-rw-r--r-- 1 root root 9174381 17 oct.  16:56 wl.ko

...
lspci -nnk | grep -i broad -A2
03:00.0 Network controller [0280]: Broadcom Inc. and subsidiaries BCM4313 802.11bgn Wireless Network Adapter [14e4:4727] (rev 01)
DeviceName: Broadcom 802.11n+BT combo module
Subsystem: Hewlett-Packard Company Device [103c:1483]
Kernel driver in use: wl

uname -a
Linux debian 6.17.3-x64v2-xanmod1 #0~20251016.g8be7ecd SMP PREEMPT_DYNAMIC Thu Oct 16 05:17:56 UTC x86_64 GNU/Linux

Thhanks to all

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment