commit:     b1469bc903cac37bff61b41532127110909d5f57
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Jun 24 16:09:49 2023 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Jun 24 16:09:49 2023 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=b1469bc9

net-wireless/broadcom-sta: add 6.30.223.271-r7

Bump to EAPI-8
Migrate to linux-mod-r1
Include arch patches
Address pkgcheck errors concerning S in pkg_setup
Fix compilation errors

Thanks to the following users that provided patches
ShadowOne333
Alan Kyder

Closes: https://bugs.gentoo.org/836093
Closes: https://bugs.gentoo.org/852569
Closes: https://bugs.gentoo.org/836165
Closes: https://bugs.gentoo.org/839648
Closes: https://bugs.gentoo.org/908711

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 .../broadcom-sta-6.30.223.271-r7.ebuild            | 103 ++++++++++
 .../broadcom-sta/files/001-null-pointer-fix.patch  |  48 +++++
 net-wireless/broadcom-sta/files/002-rdtscl.patch   |  22 +++
 net-wireless/broadcom-sta/files/003-linux47.patch  | 109 +++++++++++
 net-wireless/broadcom-sta/files/004-linux48.patch  |  64 +++++++
 .../files/005-debian-fix-kernel-warnings.patch     | 161 ++++++++++++++++
 net-wireless/broadcom-sta/files/006-linux411.patch |  27 +++
 net-wireless/broadcom-sta/files/007-linux412.patch |  78 ++++++++
 net-wireless/broadcom-sta/files/008-linux415.patch |  46 +++++
 .../files/009-fix_mac_profile_discrepancy.patch    |  14 ++
 net-wireless/broadcom-sta/files/010-linux56.patch  |  55 ++++++
 net-wireless/broadcom-sta/files/011-linux59.patch  | 211 +++++++++++++++++++++
 net-wireless/broadcom-sta/files/012-linux517.patch |  80 ++++++++
 net-wireless/broadcom-sta/files/013-linux518.patch |  71 +++++++
 net-wireless/broadcom-sta/files/014-linux414.patch |  37 ++++
 net-wireless/broadcom-sta/files/015-linux600.patch |  31 +++
 net-wireless/broadcom-sta/files/016-linux601.patch |  90 +++++++++
 .../broadcom-sta/files/broadcom-sta-modules.conf   |  17 ++
 18 files changed, 1264 insertions(+)

diff --git a/net-wireless/broadcom-sta/broadcom-sta-6.30.223.271-r7.ebuild 
b/net-wireless/broadcom-sta/broadcom-sta-6.30.223.271-r7.ebuild
new file mode 100644
index 000000000000..efe1beb913de
--- /dev/null
+++ b/net-wireless/broadcom-sta/broadcom-sta-6.30.223.271-r7.ebuild
@@ -0,0 +1,103 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+inherit linux-mod-r1
+
+DESCRIPTION="Broadcom's IEEE 802.11a/b/g/n hybrid Linux device driver"
+HOMEPAGE="https://www.broadcom.com/support/802.11";
+SRC_BASE="https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/hybrid-v35";
+SRC_URI="x86? ( ${SRC_BASE}-nodebug-pcoem-${PV//\./_}.tar.gz )
+       amd64? ( ${SRC_BASE}_64-nodebug-pcoem-${PV//\./_}.tar.gz )
+       
https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/README_${PV}.txt -> 
README-${P}.txt"
+
+LICENSE="Broadcom"
+SLOT="0"
+KEYWORDS="-* ~amd64 ~x86"
+
+RESTRICT="mirror"
+
+DEPEND="virtual/linux-sources"
+RDEPEND=""
+
+S="${WORKDIR}"
+
+PATCHES=(
+       "${FILESDIR}/001-null-pointer-fix.patch"
+       "${FILESDIR}/002-rdtscl.patch"
+       "${FILESDIR}/003-linux47.patch"
+       "${FILESDIR}/004-linux48.patch"
+       "${FILESDIR}/005-debian-fix-kernel-warnings.patch"
+       "${FILESDIR}/006-linux411.patch"
+       "${FILESDIR}/007-linux412.patch"
+       "${FILESDIR}/008-linux415.patch"
+       "${FILESDIR}/009-fix_mac_profile_discrepancy.patch"
+       "${FILESDIR}/010-linux56.patch"
+       "${FILESDIR}/011-linux59.patch"
+       "${FILESDIR}/012-linux517.patch"
+       "${FILESDIR}/013-linux518.patch"
+       "${FILESDIR}/014-linux414.patch"
+       "${FILESDIR}/015-linux600.patch"
+       "${FILESDIR}/016-linux601.patch"
+)
+
+pkg_pretend() {
+       ewarn
+       ewarn "If you are stuck using this unmaintained driver (likely in a 
MacBook),"
+       ewarn "you may be interested to know that a newer compatible wireless 
card"
+       ewarn "is supported by the in-tree brcmfmac driver. It has a model 
number "
+       ewarn "BCM943602CS and is for sale on the second hand market for less 
than "
+       ewarn "20 USD."
+       ewarn
+       ewarn "See https://wikidevi.com/wiki/Broadcom_Wireless_Adapters and"
+       ewarn "    https://wikidevi.com/wiki/Broadcom_BCM943602CS";
+       ewarn "for more information."
+       ewarn
+}
+
+pkg_setup() {
+       # bug #300570
+       # NOTE<lxnay>: module builds correctly anyway with b43 and SSB enabled
+       # make checks non-fatal. The correct fix is blackisting ssb and, perhaps
+       # b43 via udev rules. Moreover, previous fix broke binpkgs support.
+       CONFIG_CHECK="~!B43 ~!BCMA ~!SSB ~!X86_INTEL_LPSS"
+       CONFIG_CHECK2="LIB80211 ~!MAC80211 ~LIB80211_CRYPT_TKIP"
+       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_LIB80211="LIB80211: Please enable it. If you can't find it: 
enabling the driver for \"Intel PRO/Wireless 2100\" or \"Intel PRO/Wireless 
2200BG\" (IPW2100 or IPW2200) should suffice."
+       ERROR_MAC80211="MAC80211: If you insist on building this, you must 
blacklist it!"
+       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 kernel_is ge 3 8 8; then
+               CONFIG_CHECK="${CONFIG_CHECK} ${CONFIG_CHECK2} CFG80211 
~!PREEMPT_RCU ~!PREEMPT"
+       elif kernel_is ge 2 6 32; then
+               CONFIG_CHECK="${CONFIG_CHECK} ${CONFIG_CHECK2} CFG80211"
+       elif kernel_is ge 2 6 31; then
+               CONFIG_CHECK="${CONFIG_CHECK} ${CONFIG_CHECK2} WIRELESS_EXT 
~!MAC80211"
+       elif kernel_is ge 2 6 29; then
+               CONFIG_CHECK="${CONFIG_CHECK} ${CONFIG_CHECK2} WIRELESS_EXT 
COMPAT_NET_DEV_OPS"
+       else
+               CONFIG_CHECK="${CONFIG_CHECK} IEEE80211 IEEE80211_CRYPT_TKIP"
+       fi
+
+       linux-mod-r1_pkg_setup
+}
+
+src_compile() {
+       local modlist=( wl )
+       local modargs=(
+                       -C ${KV_DIR} M="${S}"
+       )
+
+       linux-mod-r1_src_compile
+}
+
+src_install() {
+       linux-mod-r1_src_install
+
+       insinto /etc/modprobe.d
+       newins "${FILESDIR}"/broadcom-sta-modules.conf wl.conf
+       dodoc "${DISTDIR}/README-${P}.txt"
+}

diff --git a/net-wireless/broadcom-sta/files/001-null-pointer-fix.patch 
b/net-wireless/broadcom-sta/files/001-null-pointer-fix.patch
new file mode 100644
index 000000000000..0ebe1e242243
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/001-null-pointer-fix.patch
@@ -0,0 +1,48 @@
+Description: Fixing null pointer crash
+
+Origin: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=773713
+Bug-Ubuntu: https://launchpad.net/bugs/1415880
+Last-Update: 2015-08-18
+
+---
+ src/wl/sys/wl_linux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c
+index 860b935..295156f 100644
+--- a/src/wl/sys/wl_linux.c
++++ b/src/wl/sys/wl_linux.c
+@@ -2157,8 +2157,8 @@ wl_start(struct sk_buff *skb, struct net_device *dev)
+       wlif = WL_DEV_IF(dev);
+       wl = WL_INFO(dev);
+ 
++      skb->prev = NULL;
+       if (WL_ALL_PASSIVE_ENAB(wl) || (WL_RTR() && WL_CONFIG_SMP())) {
+-              skb->prev = NULL;
+ 
+               TXQ_LOCK(wl);
+ 
+-- 
+1.9.1
+
+--- a/src/wl/sys/wl_linux.a    2023-04-16 23:06:52.255588442 -0500
++++ b/src/wl/sys/wl_linux.c    2023-04-16 23:07:22.315309655 -0500
+@@ -737,9 +737,6 @@
+               dev->name, device,
+               WL_ALL_PASSIVE_ENAB(wl) ?  ", Passive Mode" : "", 
EPI_VERSION_STR);
+ 
+-#ifdef BCMDBG
+-      printf(" (Compiled in " SRCBASE " at " __TIME__ " on " __DATE__ ")");
+-#endif 
+       printf("\n");
+ 
+       wl_found++;
+@@ -2098,7 +2095,7 @@
+ wl_dump_ver(wl_info_t *wl, struct bcmstrbuf *b)
+ {
+       bcm_bprintf(b, "wl%d: %s %s version %s\n", wl->pub->unit,
+-              __DATE__, __TIME__, EPI_VERSION_STR);
++              "X", "Y", EPI_VERSION_STR);
+ }
+ 
+ #if defined(BCMDBG)

diff --git a/net-wireless/broadcom-sta/files/002-rdtscl.patch 
b/net-wireless/broadcom-sta/files/002-rdtscl.patch
new file mode 100644
index 000000000000..1b9862cc3d8d
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/002-rdtscl.patch
@@ -0,0 +1,22 @@
+Since Linux 4.3, rdtscl() is no longer available and native_read_tsc()
+is renamed to rdtsc(). Move the macro contents in-line and call the
+new function. References:
+
+https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit?id=fe47ae6e1a5005b2e82f7eab57b5c3820453293a
+https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit?id=4ea1636b04dbd66536fa387bae2eea463efc705b
+
+diff -ru a/src/shared/linux_osl.c b/src/shared/linux_osl.c
+--- a/src/shared/linux_osl.c   2015-09-19 01:47:15.000000000 +0300
++++ b/src/shared/linux_osl.c   2015-11-21 15:20:30.585902518 +0200
+@@ -932,7 +932,11 @@
+       uint cycles;
+ 
+ #if defined(__i386__)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
++      cycles = (u32)rdtsc();
++#else
+       rdtscl(cycles);
++#endif
+ #else
+       cycles = 0;
+ #endif 

diff --git a/net-wireless/broadcom-sta/files/003-linux47.patch 
b/net-wireless/broadcom-sta/files/003-linux47.patch
new file mode 100644
index 000000000000..566680a09140
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/003-linux47.patch
@@ -0,0 +1,109 @@
+Since Linux 4.7, the enum ieee80211_band is no longer used
+
+This shall cause no problem's since both enums ieee80211_band
+and nl80211_band were added in the same commit:
+https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit?id=13ae75b103e07304a34ab40c9136e9f53e06475c
+
+This patch refactors the references of IEEE80211_BAND_* to NL80211_BAND_*
+
+Reference:
+https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit?id=57fbcce37be7c1d2622b56587c10ade00e96afa3
+
+--- a/src/wl/sys/wl_cfg80211_hybrid.c  2016-06-13 11:57:36.159340297 -0500
++++ b/src/wl/sys/wl_cfg80211_hybrid.c  2016-06-13 11:58:18.442323435 -0500
+@@ -236,7 +236,7 @@
+ #endif                                
+ 
+ #define CHAN2G(_channel, _freq, _flags) {                     \
+-      .band                   = IEEE80211_BAND_2GHZ,          \
++      .band                   = NL80211_BAND_2GHZ,            \
+       .center_freq            = (_freq),                      \
+       .hw_value               = (_channel),                   \
+       .flags                  = (_flags),                     \
+@@ -245,7 +245,7 @@
+ }
+ 
+ #define CHAN5G(_channel, _flags) {                            \
+-      .band                   = IEEE80211_BAND_5GHZ,          \
++      .band                   = NL80211_BAND_5GHZ,            \
+       .center_freq            = 5000 + (5 * (_channel)),      \
+       .hw_value               = (_channel),                   \
+       .flags                  = (_flags),                     \
+@@ -379,7 +379,7 @@
+ };
+ 
+ static struct ieee80211_supported_band __wl_band_2ghz = {
+-      .band = IEEE80211_BAND_2GHZ,
++      .band = NL80211_BAND_2GHZ,
+       .channels = __wl_2ghz_channels,
+       .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
+       .bitrates = wl_g_rates,
+@@ -387,7 +387,7 @@
+ };
+ 
+ static struct ieee80211_supported_band __wl_band_5ghz_a = {
+-      .band = IEEE80211_BAND_5GHZ,
++      .band = NL80211_BAND_5GHZ,
+       .channels = __wl_5ghz_a_channels,
+       .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
+       .bitrates = wl_a_rates,
+@@ -395,7 +395,7 @@
+ };
+ 
+ static struct ieee80211_supported_band __wl_band_5ghz_n = {
+-      .band = IEEE80211_BAND_5GHZ,
++      .band = NL80211_BAND_5GHZ,
+       .channels = __wl_5ghz_n_channels,
+       .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
+       .bitrates = wl_a_rates,
+@@ -1876,8 +1876,8 @@
+       wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
+ #endif
+       wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 
BIT(NL80211_IFTYPE_ADHOC);
+-      wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
+-      wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; 
++      wdev->wiphy->bands[NL80211_BAND_2GHZ] = &__wl_band_2ghz;
++      wdev->wiphy->bands[NL80211_BAND_5GHZ] = &__wl_band_5ghz_a; 
+       wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+       wdev->wiphy->cipher_suites = __wl_cipher_suites;
+       wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
+@@ -2000,7 +2000,7 @@
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+       freq = ieee80211_channel_to_frequency(notif_bss_info->channel,
+               (notif_bss_info->channel <= CH_MAX_2G_CHANNEL) ?
+-              IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
++              NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
+ #else
+       freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
+ #endif
+@@ -2116,7 +2116,7 @@
+                               return err;
+                       }
+                       chan = wf_chspec_ctlchan(chanspec);
+-                      band = (chan <= CH_MAX_2G_CHANNEL) ? 
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
++                      band = (chan <= CH_MAX_2G_CHANNEL) ? NL80211_BAND_2GHZ 
: NL80211_BAND_5GHZ;
+                       freq = ieee80211_channel_to_frequency(chan, band);
+                       channel = ieee80211_get_channel(wiphy, freq);
+                       cfg80211_ibss_joined(ndev, (u8 *)&wl->bssid, channel, 
GFP_KERNEL);
+@@ -2250,10 +2250,10 @@
+               join_params->params.chanspec_list[0] =
+                   ieee80211_frequency_to_channel(chan->center_freq);
+ 
+-              if (chan->band == IEEE80211_BAND_2GHZ) {
++              if (chan->band == NL80211_BAND_2GHZ) {
+                       chanspec |= WL_CHANSPEC_BAND_2G;
+               }
+-              else if (chan->band == IEEE80211_BAND_5GHZ) {
++              else if (chan->band == NL80211_BAND_5GHZ) {
+                       chanspec |= WL_CHANSPEC_BAND_5G;
+               }
+               else {
+@@ -2885,7 +2885,7 @@
+ 
+       if (phy == 'n' || phy == 'a' || phy == 'v') {
+               wiphy = wl_to_wiphy(wl);
+-              wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
++              wiphy->bands[NL80211_BAND_5GHZ] = &__wl_band_5ghz_n;
+       }
+ 
+       return err;

diff --git a/net-wireless/broadcom-sta/files/004-linux48.patch 
b/net-wireless/broadcom-sta/files/004-linux48.patch
new file mode 100644
index 000000000000..20e8a9ae49d2
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/004-linux48.patch
@@ -0,0 +1,64 @@
+From d3f93542326a06d920c6eb89b703384290d37b8b Mon Sep 17 00:00:00 2001
+From: Alberto Milone <[email protected]>
+Date: Fri, 2 Sep 2016 17:35:34 +0200
+Subject: [PATCH 1/1] Add support for Linux 4.8
+
+Orginal author: Krzysztof Kolasa
+---
+ src/wl/sys/wl_cfg80211_hybrid.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c
+index 2fc71fe..ec5e472 100644
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -2388,8 +2388,16 @@ wl_bss_connect_done(struct wl_cfg80211_priv *wl, struct 
net_device *ndev,
+       s32 err = 0;
+ 
+       if (wl->scan_request) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
++              struct cfg80211_scan_info info = {
++                      .aborted = true,
++              };
++              WL_DBG(("%s: Aborting scan\n", __FUNCTION__));
++              cfg80211_scan_done(wl->scan_request, &info);
++#else
+               WL_DBG(("%s: Aborting scan\n", __FUNCTION__));
+               cfg80211_scan_done(wl->scan_request, true);     
++#endif
+               wl->scan_request = NULL;
+       }
+ 
+@@ -2490,7 +2498,14 @@ wl_notify_scan_status(struct wl_cfg80211_priv *wl, 
struct net_device *ndev,
+ 
+ scan_done_out:
+       if (wl->scan_request) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
++              struct cfg80211_scan_info info = {
++                      .aborted = false,
++              };
++              cfg80211_scan_done(wl->scan_request, &info);
++#else
+               cfg80211_scan_done(wl->scan_request, false);
++#endif
+               wl->scan_request = NULL;
+       }
+       rtnl_unlock();
+@@ -2909,7 +2924,14 @@ s32 wl_cfg80211_down(struct net_device *ndev)
+       s32 err = 0;
+ 
+       if (wl->scan_request) {
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
++              struct cfg80211_scan_info info = {
++                      .aborted = true,
++              };
++              cfg80211_scan_done(wl->scan_request, &info);
++#else
+               cfg80211_scan_done(wl->scan_request, true);     
++#endif
+               wl->scan_request = NULL;
+       }
+ 
+-- 
+2.7.4
+

diff --git 
a/net-wireless/broadcom-sta/files/005-debian-fix-kernel-warnings.patch 
b/net-wireless/broadcom-sta/files/005-debian-fix-kernel-warnings.patch
new file mode 100644
index 000000000000..e9bf66a959b8
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/005-debian-fix-kernel-warnings.patch
@@ -0,0 +1,161 @@
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -1968,7 +1968,7 @@
+ 
+       if (dtoh32(bi->length) > WL_BSS_INFO_MAX) {
+               WL_DBG(("Beacon is larger than buffer. Discarding\n"));
+-              return err;
++              return -E2BIG;
+       }
+       notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - 
sizeof(u8) +
+                                WL_BSS_INFO_MAX, GFP_KERNEL);
+@@ -1992,9 +1992,15 @@
+       beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
+       wl_rst_ie(wl);
+ 
+-      wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
+-      wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
++      err = wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
++      if (err)
++              goto inform_single_bss_out;
++
++      err = wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
+                offsetof(struct wl_cfg80211_bss_info, frame_buf));
++      if (err)
++              goto inform_single_bss_out;
++
+       notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, 
u.beacon.variable) +
+                                   wl_get_ielen(wl);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+@@ -2006,14 +2012,14 @@
+ #endif
+       if (freq == 0) {
+               WL_ERR(("Invalid channel, fail to chcnage channel to freq\n"));
+-              kfree(notif_bss_info);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto inform_single_bss_out;
+       }
+       channel = ieee80211_get_channel(wiphy, freq);
+       if (unlikely(!channel)) {
+               WL_ERR(("ieee80211_get_channel error\n"));
+-              kfree(notif_bss_info);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto inform_single_bss_out;
+       }
+ 
+       WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid 
%pM\n",
+@@ -2021,28 +2027,37 @@
+               mgmt->u.beacon.capab_info, &bi->BSSID));
+ 
+       signal = notif_bss_info->rssi * 100;
+-      cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+-          le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
+-      if (unlikely(!cbss)) {
+-              WL_ERR(("cfg80211_inform_bss_frame error\n"));
+-              kfree(notif_bss_info);
+-              return -EINVAL;
+-      }
+ 
+-      notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+-      notify_ielen = le32_to_cpu(bi->ie_length);
++      if (!wl->scan_request) {
++              cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
++                      le16_to_cpu(notif_bss_info->frame_len), signal, 
GFP_KERNEL);
++              if (unlikely(!cbss)) {
++                      WL_ERR(("cfg80211_inform_bss_frame error\n"));
++                      err = -ENOMEM;
++                      goto inform_single_bss_out;
++              }
++      } else {
++              notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
++              notify_ielen = le32_to_cpu(bi->ie_length);
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
+-      cbss = cfg80211_inform_bss(wiphy, channel, (const u8 
*)(bi->BSSID.octet),
+-              0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int,
+-              (const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
++              cbss = cfg80211_inform_bss(wiphy, channel, (const u8 
*)(bi->BSSID.octet),
++                      0, beacon_proberesp->capab_info, 
beacon_proberesp->beacon_int,
++                      (const u8 *)notify_ie, notify_ielen, signal, 
GFP_KERNEL);
+ #else
+-      cbss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, 
(const u8 *)(bi->BSSID.octet),
+-              0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int,
+-              (const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
++              cbss = cfg80211_inform_bss(wiphy, channel,
++                              wl->active_scan ?
++                              CFG80211_BSS_FTYPE_PRESP : 
CFG80211_BSS_FTYPE_BEACON,
++                              (const u8 *)(bi->BSSID.octet), 0,
++                              beacon_proberesp->capab_info,
++                              beacon_proberesp->beacon_int,
++                              (const u8 *)notify_ie, notify_ielen, signal, 
GFP_KERNEL);
+ #endif
+-
+-      if (unlikely(!cbss))
+-              return -ENOMEM;
++              if (unlikely(!cbss)) {
++                      WL_ERR(("cfg80211_inform_bss error\n"));
++                      err = -ENOMEM;
++                      goto inform_single_bss_out;
++              }
++      }
+ 
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+       cfg80211_put_bss(wiphy, cbss);
+@@ -2050,6 +2065,7 @@
+       cfg80211_put_bss(cbss);
+ #endif
+ 
++inform_single_bss_out:
+       kfree(notif_bss_info);
+ 
+       return err;
+@@ -2316,6 +2332,9 @@
+               if (err)
+                       goto update_bss_info_out;
+ 
++              bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
++                    ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, 
WLAN_CAPABILITY_ESS);
++
+               ie = ((u8 *)bi) + bi->ie_offset;
+               ie_len = bi->ie_length;
+       } else {
+@@ -2328,11 +2347,18 @@
+               ie_len = bss->len_information_elements;
+ #endif
+               wl->conf->channel = *bss->channel;
++      }
++
++      if (bss) {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+               cfg80211_put_bss(wiphy, bss);
+ #else
+               cfg80211_put_bss(bss);
+ #endif
++      } else {
++              WL_DBG(("Could not update BSS\n"));
++              err = -EINVAL;
++              goto update_bss_info_out;
+       }
+ 
+       tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
+@@ -2360,10 +2386,17 @@
+       struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
+       s32 err = 0;
+ 
+-      wl_get_assoc_ies(wl);
++      err = wl_get_assoc_ies(wl);
++      if (err)
++              return err;
++
+       memcpy(wl->profile->bssid, &e->addr, ETHER_ADDR_LEN);
+       memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
+-      wl_update_bss_info(wl);
++
++      err = wl_update_bss_info(wl);
++      if (err)
++              return err;
++
+       cfg80211_roamed(ndev,
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
+                       &wl->conf->channel,      

diff --git a/net-wireless/broadcom-sta/files/006-linux411.patch 
b/net-wireless/broadcom-sta/files/006-linux411.patch
new file mode 100644
index 000000000000..7a2e8c0c6cb0
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/006-linux411.patch
@@ -0,0 +1,27 @@
+diff -u sys0/wl_cfg80211_hybrid.c sys/wl_cfg80211_hybrid.c
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -39,6 +39,10 @@
+ #include <proto/802.11.h>
+ #include <wl_cfg80211_hybrid.h>
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
++#include <linux/sched/signal.h>
++#endif
++
+ #define EVENT_TYPE(e) dtoh32((e)->event_type)
+ #define EVENT_FLAGS(e) dtoh16((e)->flags)
+ #define EVENT_STATUS(e) dtoh32((e)->status)
+diff -u sys0/wl_linux.c sys/wl_linux.c
+--- a/src/wl/sys/wl_linux.c
++++ b/src/wl/sys/wl_linux.c
+@@ -2915,7 +2915,9 @@
+       if (skb == NULL) return;
+ 
+       skb->dev = wl->monitor_dev;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
+       skb->dev->last_rx = jiffies;
++#endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+       skb_reset_mac_header(skb);
+ #else

diff --git a/net-wireless/broadcom-sta/files/007-linux412.patch 
b/net-wireless/broadcom-sta/files/007-linux412.patch
new file mode 100644
index 000000000000..1673f063cdb5
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/007-linux412.patch
@@ -0,0 +1,78 @@
+From 0b888bf115612074df99654140a1980111c29748 Mon Sep 17 00:00:00 2001
+From: Antoine Cotten <[email protected]>
+Date: Fri, 7 Jul 2017 15:17:47 +0200
+Subject: [PATCH] Apply patch from Debian bug #867258
+
+Compile fix with kernel 4.12
+https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=867258
+---
+ src/wl/sys/wl_cfg80211_hybrid.c | 29 +++++++++++++++++++++++++----
+ 1 file changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c
+index c46944a..1a9840a 100644
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -53,7 +53,11 @@ u32 wl_dbg_level = WL_DBG_ERR;
+ #endif
+ 
+ static s32 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device 
*ndev,
+-           enum nl80211_iftype type, u32 *flags, struct vif_params *params);
++           enum nl80211_iftype type,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
++           u32 *flags,
++#endif
++         struct vif_params *params);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+ static s32
+ wl_cfg80211_scan(struct wiphy *wiphy,
+@@ -466,8 +470,11 @@ wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, 
u32 len)
+ 
+ static s32
+ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
+-                         enum nl80211_iftype type, u32 *flags,
+-   struct vif_params *params)
++                         enum nl80211_iftype type,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
++                         u32 *flags,
++#endif
++                         struct vif_params *params)
+ {
+       struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+       struct wireless_dev *wdev;
+@@ -2387,6 +2394,15 @@ wl_bss_roaming_done(struct wl_cfg80211_priv *wl, struct 
net_device *ndev,
+                     const wl_event_msg_t *e, void *data)
+ {
+       struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
++      struct cfg80211_roam_info roam_info = {
++              .bssid = wl->profile->bssid,
++              .req_ie = conn_info->req_ie,
++              .req_ie_len = conn_info->req_ie_len,
++              .resp_ie = conn_info->resp_ie,
++              .resp_ie_len = conn_info->resp_ie_len,
++      };
++#endif
+       s32 err = 0;
+ 
+       err = wl_get_assoc_ies(wl);
+@@ -2401,12 +2417,17 @@ wl_bss_roaming_done(struct wl_cfg80211_priv *wl, 
struct net_device *ndev,
+               return err;
+ 
+       cfg80211_roamed(ndev,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
++                      &roam_info,
++#else
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
+                       &wl->conf->channel,      
+ #endif
+                       (u8 *)&wl->bssid,
+                       conn_info->req_ie, conn_info->req_ie_len,
+-                      conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
++                      conn_info->resp_ie, conn_info->resp_ie_len,
++#endif
++                      GFP_KERNEL);
+       WL_DBG(("Report roaming result\n"));
+ 
+       set_bit(WL_STATUS_CONNECTED, &wl->status);
+

diff --git a/net-wireless/broadcom-sta/files/008-linux415.patch 
b/net-wireless/broadcom-sta/files/008-linux415.patch
new file mode 100644
index 000000000000..1bced2f68ab1
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/008-linux415.patch
@@ -0,0 +1,46 @@
+--- a/src/wl/sys/wl_linux.c    2017-07-17 00:11:24.000000000 +0100
++++ b/src/wl/sys/wl_linux.c    2018-01-27 09:49:47.057799596 +0000
+@@ -93,7 +93,11 @@
+ 
+ #include <wlc_wowl.h>
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
++static void wl_timer(struct timer_list *tl);
++#else
+ static void wl_timer(ulong data);
++#endif
+ static void _wl_timer(wl_timer_t *t);
+ static struct net_device *wl_alloc_linux_if(wl_if_t *wlif);
+ 
+@@ -2297,10 +2301,17 @@
+       atomic_dec(&t->wl->callbacks);
+ }
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
++static void
++wl_timer(struct timer_list *tl)
++{
++      wl_timer_t *t = (wl_timer_t *)tl;
++#else
+ static void
+ wl_timer(ulong data)
+ {
+       wl_timer_t *t = (wl_timer_t *)data;
++#endif
+ 
+       if (!WL_ALL_PASSIVE_ENAB(t->wl))
+               _wl_timer(t);
+@@ -2352,9 +2363,13 @@
+ 
+       bzero(t, sizeof(wl_timer_t));
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
++      timer_setup(&t->timer, wl_timer, 0);
++#else
+       init_timer(&t->timer);
+       t->timer.data = (ulong) t;
+       t->timer.function = wl_timer;
++#endif
+       t->wl = wl;
+       t->fn = fn;
+       t->arg = arg;

diff --git 
a/net-wireless/broadcom-sta/files/009-fix_mac_profile_discrepancy.patch 
b/net-wireless/broadcom-sta/files/009-fix_mac_profile_discrepancy.patch
new file mode 100644
index 000000000000..4260eba5057a
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/009-fix_mac_profile_discrepancy.patch
@@ -0,0 +1,14 @@
+--- a/src/wl/sys/wl_cfg80211_hybrid.c  2015-09-19 00:47:30.000000000 +0200
++++ b/src/wl/sys/wl_cfg80211_hybrid.c  2018-11-14 14:06:03.313487995 +0100
+@@ -1444,11 +1444,10 @@
+       s32 rate;
+       s32 err = 0;
+ 
+       if (memcmp(mac, wl->profile->bssid, ETHER_ADDR_LEN)) {
+               WL_ERR(("Wrong Mac address, mac = %pM   profile =%pM\n", mac, 
wl->profile->bssid));
+-              return -ENOENT;
+       }
+ 
+       err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
+       if (err) {
+               WL_DBG(("Could not get rate (%d)\n", err));

diff --git a/net-wireless/broadcom-sta/files/010-linux56.patch 
b/net-wireless/broadcom-sta/files/010-linux56.patch
new file mode 100644
index 000000000000..f8d5783819cd
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/010-linux56.patch
@@ -0,0 +1,55 @@
+diff --git a/src/shared/linux_osl.c b/src/shared/linux_osl.c
+index 6157d18..8237ec7 100644
+--- a/src/shared/linux_osl.c
++++ b/src/shared/linux_osl.c
+@@ -942,7 +942,7 @@ osl_getcycles(void)
+ void *
+ osl_reg_map(uint32 pa, uint size)
+ {
+-      return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
++      return (ioremap((unsigned long)pa, (unsigned long)size));
+ }
+ 
+ void
+diff --git a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c
+index 0d05100..2ed1f0d 100644
+--- a/src/wl/sys/wl_linux.c
++++ b/src/wl/sys/wl_linux.c
+@@ -582,7 +582,7 @@ wl_attach(uint16 vendor, uint16 device, ulong regs,
+       }
+       wl->bcm_bustype = bustype;
+ 
+-      if ((wl->regsva = ioremap_nocache(dev->base_addr, PCI_BAR0_WINSZ)) == 
NULL) {
++      if ((wl->regsva = ioremap(dev->base_addr, PCI_BAR0_WINSZ)) == NULL) {
+               WL_ERROR(("wl%d: ioremap() failed\n", unit));
+               goto fail;
+       }
+@@ -772,7 +772,7 @@ wl_pci_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
+       if ((val & 0x0000ff00) != 0)
+               pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+               bar1_size = pci_resource_len(pdev, 2);
+-              bar1_addr = (uchar *)ioremap_nocache(pci_resource_start(pdev, 
2),
++              bar1_addr = (uchar *)ioremap(pci_resource_start(pdev, 2),
+                       bar1_size);
+       wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), 
PCI_BUS, pdev,
+               pdev->irq, bar1_addr, bar1_size);
+@@ -3335,12 +3335,19 @@ wl_proc_write(struct file *filp, const char __user 
*buff, size_t length, loff_t
+ }
+ 
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
++static struct proc_ops wl_fops = {
++        .proc_read     = wl_proc_read,
++        .proc_write    = wl_proc_write,
++};
++#else
+ static const struct file_operations wl_fops = {
+       .owner  = THIS_MODULE,
+       .read   = wl_proc_read,
+       .write  = wl_proc_write,
+ };
+ #endif
++#endif
+ 
+ static int
+ wl_reg_proc_entry(wl_info_t *wl)

diff --git a/net-wireless/broadcom-sta/files/011-linux59.patch 
b/net-wireless/broadcom-sta/files/011-linux59.patch
new file mode 100644
index 000000000000..6ef476464c0c
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/011-linux59.patch
@@ -0,0 +1,211 @@
+From f3d652840f8dd959395065a1cf67ca40b04ec69b Mon Sep 17 00:00:00 2001
+From: Joan Bruguera <[email protected]>
+Date: Tue, 13 Oct 2020 19:35:55 +0200
+Subject: [PATCH] Get rid of get_fs/set_fs calls in Broadcom WL driver.
+
+Tentative patch for broadcom-wl 6.30.223.271 driver for Linux 5.10 (tested 
-rc1 up to 5.10.1)
+
+Applies on top of all the patches applied to broadcom-wl-dkms 6.30.223.271-23 
on Arch Linux.
+
+NB: Some checks in wlc_ioctl_internal are likely superfluous,
+    but I'm not familiar enough with the driver to remove them with confidence.
+
+See also: https://lwn.net/Articles/722267/
+          
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=47058bb54b57962b3958a936ddbc59355e4c5504
+          
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5e6e9852d6f76e01b2e6803c74258afa5b432bc5
+
+Signed-off-by: Joan Bruguera <[email protected]>
+---
+ src/wl/sys/wl_cfg80211_hybrid.c | 25 ++-------------------
+ src/wl/sys/wl_iw.c              | 25 ++-------------------
+ src/wl/sys/wl_linux.c           | 40 ++++++++++++++++++++++++++++-----
+ src/wl/sys/wl_linux.h           |  2 ++
+ src/wl/sys/wlc_pub.h            |  1 +
+ 5 files changed, 42 insertions(+), 51 deletions(-)
+
+diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c
+index 7b606e0..1e0adb7 100644
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -38,6 +38,7 @@
+ #include <wlioctl.h>
+ #include <proto/802.11.h>
+ #include <wl_cfg80211_hybrid.h>
++#include <wl_linux.h>
+ 
+ #define EVENT_TYPE(e) dtoh32((e)->event_type)
+ #define EVENT_FLAGS(e) dtoh16((e)->flags)
+@@ -435,30 +436,7 @@ static void key_endian_to_host(struct wl_wsec_key *key)
+ static s32
+ wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
+ {
+-      struct ifreq ifr;
+-      struct wl_ioctl ioc;
+-      mm_segment_t fs;
+-      s32 err = 0;
+-
+-      BUG_ON(len < sizeof(int));
+-
+-      memset(&ioc, 0, sizeof(ioc));
+-      ioc.cmd = cmd;
+-      ioc.buf = arg;
+-      ioc.len = len;
+-      strcpy(ifr.ifr_name, dev->name);
+-      ifr.ifr_data = (caddr_t)&ioc;
+-
+-      fs = get_fs();
+-      set_fs(get_ds());
+-#if defined(WL_USE_NETDEV_OPS)
+-      err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+-#else
+-      err = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+-#endif
+-      set_fs(fs);
+-
+-      return err;
++      return wlc_ioctl_internal(dev, cmd, arg, len);
+ }
+ 
+ static s32
+diff --git a/src/wl/sys/wl_iw.c b/src/wl/sys/wl_iw.c
+index c4c610b..e346b15 100644
+--- a/src/wl/sys/wl_iw.c
++++ b/src/wl/sys/wl_iw.c
+@@ -37,6 +37,7 @@ typedef const struct si_pub  si_t;
+ 
+ #include <wl_dbg.h>
+ #include <wl_iw.h>
++#include <wl_linux.h>
+ 
+ extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status,
+       uint32 reason, char* stringBuf, uint buflen);
+@@ -103,29 +104,7 @@ dev_wlc_ioctl(
+       int len
+ )
+ {
+-      struct ifreq ifr;
+-      wl_ioctl_t ioc;
+-      mm_segment_t fs;
+-      int ret;
+-
+-      memset(&ioc, 0, sizeof(ioc));
+-      ioc.cmd = cmd;
+-      ioc.buf = arg;
+-      ioc.len = len;
+-
+-      strcpy(ifr.ifr_name, dev->name);
+-      ifr.ifr_data = (caddr_t) &ioc;
+-
+-      fs = get_fs();
+-      set_fs(get_ds());
+-#if defined(WL_USE_NETDEV_OPS)
+-      ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+-#else
+-      ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+-#endif
+-      set_fs(fs);
+-
+-      return ret;
++      return wlc_ioctl_internal(dev, cmd, arg, len);
+ }
+ 
+ static int
+diff --git a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c
+index 947cef3..f04c148 100644
+--- a/src/wl/sys/wl_linux.c
++++ b/src/wl/sys/wl_linux.c
+@@ -1643,10 +1643,7 @@ wl_ioctl(struct net_device *dev, struct ifreq *ifr, int 
cmd)
+               goto done2;
+       }
+ 
+-      if (segment_eq(get_fs(), KERNEL_DS))
+-              buf = ioc.buf;
+-
+-      else if (ioc.buf) {
++      if (ioc.buf) {
+               if (!(buf = (void *) MALLOC(wl->osh, MAX(ioc.len, 
WLC_IOCTL_MAXLEN)))) {
+                       bcmerror = BCME_NORESOURCE;
+                       goto done2;
+@@ -1667,7 +1664,7 @@ wl_ioctl(struct net_device *dev, struct ifreq *ifr, int 
cmd)
+       WL_UNLOCK(wl);
+ 
+ done1:
+-      if (ioc.buf && (ioc.buf != buf)) {
++      if (ioc.buf) {
+               if (copy_to_user(ioc.buf, buf, ioc.len))
+                       bcmerror = BCME_BADADDR;
+               MFREE(wl->osh, buf, MAX(ioc.len, WLC_IOCTL_MAXLEN));
+@@ -1680,6 +1677,39 @@ done2:
+       return (OSL_ERROR(bcmerror));
+ }
+ 
++int
++wlc_ioctl_internal(struct net_device *dev, int cmd, void *buf, int len)
++{
++      wl_info_t *wl;
++      wl_if_t *wlif;
++      int bcmerror;
++
++      if (!dev)
++              return -ENETDOWN;
++
++      wl = WL_INFO(dev);
++      wlif = WL_DEV_IF(dev);
++      if (wlif == NULL || wl == NULL || wl->dev == NULL)
++              return -ENETDOWN;
++
++      bcmerror = 0;
++
++      WL_TRACE(("wl%d: wlc_ioctl_internal: cmd 0x%x\n", wl->pub->unit, cmd));
++
++      WL_LOCK(wl);
++      if (!capable(CAP_NET_ADMIN)) {
++              bcmerror = BCME_EPERM;
++      } else {
++              bcmerror = wlc_ioctl(wl->wlc, cmd, buf, len, wlif->wlcif);
++      }
++      WL_UNLOCK(wl);
++
++      ASSERT(VALID_BCMERROR(bcmerror));
++      if (bcmerror != 0)
++              wl->pub->bcmerror = bcmerror;
++      return (OSL_ERROR(bcmerror));
++}
++
+ static struct net_device_stats*
+ wl_get_stats(struct net_device *dev)
+ {
+diff --git a/src/wl/sys/wl_linux.h b/src/wl/sys/wl_linux.h
+index 5b1048e..c8c1f41 100644
+--- a/src/wl/sys/wl_linux.h
++++ b/src/wl/sys/wl_linux.h
+@@ -22,6 +22,7 @@
+ #define _wl_linux_h_
+ 
+ #include <wlc_types.h>
++#include <wlc_pub.h>
+ 
+ typedef struct wl_timer {
+       struct timer_list       timer;
+@@ -187,6 +188,7 @@ extern irqreturn_t wl_isr(int irq, void *dev_id, struct 
pt_regs *ptregs);
+ extern int __devinit wl_pci_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent);
+ extern void wl_free(wl_info_t *wl);
+ extern int  wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
++extern int wlc_ioctl_internal(struct net_device *dev, int cmd, void *buf, int 
len);
+ extern struct net_device * wl_netdev_get(wl_info_t *wl);
+ 
+ #endif 
+diff --git a/src/wl/sys/wlc_pub.h b/src/wl/sys/wlc_pub.h
+index 53a98b8..2b5a029 100644
+--- a/src/wl/sys/wlc_pub.h
++++ b/src/wl/sys/wlc_pub.h
+@@ -24,6 +24,7 @@
+ 
+ #include <wlc_types.h>
+ #include <wlc_utils.h>
++#include <siutils.h>
+ #include "proto/802.11.h"
+ #include "proto/bcmevent.h"
+ 
+--
+2.28.0

diff --git a/net-wireless/broadcom-sta/files/012-linux517.patch 
b/net-wireless/broadcom-sta/files/012-linux517.patch
new file mode 100644
index 000000000000..6f23316691c8
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/012-linux517.patch
@@ -0,0 +1,80 @@
+From 31b7849092c43805c7fbaf7518b99874aa1b310c Mon Sep 17 00:00:00 2001
+From: Joan Bruguera <[email protected]>
+Date: Wed, 12 Jan 2022 20:49:20 +0100
+Subject: [PATCH] Tentative fix for broadcom-wl 6.30.223.271 driver for Linux 
5.17-rc1
+
+Set netdev->dev_addr through dev_addr_mod + PDE_DATA fix
+
+Since Linux 5.17 netdev->dev_addr is const and must be changed through
+dev_addr_mod, otherwise a warning is logged in dmesg and bad things may happen.
+
+NB: The #if is not wrong, dev_addr_mod is defined since Linux 5.15-rc1
+
+Plus a trivial fix for PDE_DATA.
+
+Applies on top of all the patches applied to broadcom-wl-dkms 6.30.223.271-28 
on Arch Linux.
+
+See also: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=adeef3e32146a8d2a73c399dc6f5d76a449131b1
+          
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=359745d78351c6f5442435f81549f0207ece28aa
+---
+ src/wl/sys/wl_linux.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c
+index e491df7..e4614fb 100644
+--- a/src/wl/sys/wl_linux.c
++++ b/src/wl/sys/wl_linux.c
+@@ -93,6 +93,10 @@ struct iw_statistics *wl_get_wireless_stats(struct 
net_device *dev);
+ 
+ #include <wlc_wowl.h>
+ 
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0))
++#define PDE_DATA pde_data
++#endif
++
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
+ static void wl_timer(struct timer_list *tl);
+ #else
+@@ -490,6 +494,12 @@ wl_if_setup(struct net_device *dev)
+ #endif
+ }
+ 
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
++static inline void eth_hw_addr_set(struct net_device *dev, const void *addr) {
++      memcpy(dev->dev_addr, addr, ETHER_ADDR_LEN);
++}
++#endif
++
+ static wl_info_t *
+ wl_attach(uint16 vendor, uint16 device, ulong regs,
+       uint bustype, void *btparam, uint irq, uchar* bar1_addr, uint32 
bar1_size)
+@@ -634,7 +644,7 @@ wl_attach(uint16 vendor, uint16 device, ulong regs,
+                       WL_ERROR(("wl%d: Error setting MAC ADDRESS\n", unit));
+       }
+ #endif 
+-      bcopy(&wl->pub->cur_etheraddr, dev->dev_addr, ETHER_ADDR_LEN);
++      eth_hw_addr_set(dev, wl->pub->cur_etheraddr.octet);
+ 
+       online_cpus = 1;
+ 
+@@ -1835,7 +1845,7 @@ wl_set_mac_address(struct net_device *dev, void *addr)
+ 
+       WL_LOCK(wl);
+ 
+-      bcopy(sa->sa_data, dev->dev_addr, ETHER_ADDR_LEN);
++      eth_hw_addr_set(dev, sa->sa_data);
+       err = wlc_iovar_op(wl->wlc, "cur_etheraddr", NULL, 0, sa->sa_data, 
ETHER_ADDR_LEN,
+               IOV_SET, (WL_DEV_IF(dev))->wlcif);
+       WL_UNLOCK(wl);
+@@ -3010,7 +3020,7 @@ _wl_add_monitor_if(wl_task_t *task)
+       else
+               dev->type = ARPHRD_IEEE80211_RADIOTAP;
+ 
+-      bcopy(wl->dev->dev_addr, dev->dev_addr, ETHER_ADDR_LEN);
++      eth_hw_addr_set(dev, wl->dev->dev_addr);
+ 
+ #if defined(WL_USE_NETDEV_OPS)
+       dev->netdev_ops = &wl_netdev_monitor_ops;
+-- 
+2.35.1
+

diff --git a/net-wireless/broadcom-sta/files/013-linux518.patch 
b/net-wireless/broadcom-sta/files/013-linux518.patch
new file mode 100644
index 000000000000..d837429a6899
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/013-linux518.patch
@@ -0,0 +1,71 @@
+diff -u -r a/src/shared/linux_osl.c b/src/shared/linux_osl.c
+--- a/src/shared/linux_osl.c   2022-05-24 20:51:15.662604980 +0000
++++ b/src/shared/linux_osl.c   2022-05-24 21:13:38.264472425 +0000
+@@ -599,6 +599,8 @@
+       va = kmalloc(size, GFP_ATOMIC | __GFP_ZERO);
+       if (va)
+               *pap = (ulong)__virt_to_phys(va);
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
++      va = dma_alloc_coherent(&((struct pci_dev *)osh->pdev)->dev, size, 
(dma_addr_t*)pap, GFP_ATOMIC);
+ #else
+       va = pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap);
+ #endif
+@@ -612,6 +614,8 @@
+ 
+ #ifdef __ARM_ARCH_7A__
+       kfree(va);
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
++      dma_free_coherent(&((struct pci_dev *)osh->pdev)->dev, size, va, 
(dma_addr_t)pa);
+ #else
+       pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
+ #endif
+@@ -623,7 +627,11 @@
+       int dir;
+ 
+       ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
++      dir = (direction == DMA_TX)? DMA_TO_DEVICE: DMA_FROM_DEVICE;
++#else
+       dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
++#endif
+ 
+ #if defined(__ARM_ARCH_7A__) && defined(BCMDMASGLISTOSL)
+       if (dmah != NULL) {
+@@ -641,7 +649,11 @@
+                               ASSERT(totsegs + nsegs <= MAX_DMA_SEGS);
+                               sg->page_link = 0;
+                               sg_set_buf(sg, PKTDATA(osh, skb), PKTLEN(osh, 
skb));
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
++                              dma_map_single(&((struct pci_dev 
*)osh->pdev)->dev, PKTDATA(osh, skb), PKTLEN(osh, skb), dir);
++#else
+                               pci_map_single(osh->pdev, PKTDATA(osh, skb), 
PKTLEN(osh, skb), dir);
++#endif
+                       }
+                       totsegs += nsegs;
+                       totlen += PKTLEN(osh, skb);
+@@ -656,7 +668,11 @@
+       }
+ #endif 
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
++      return (dma_map_single(&((struct pci_dev *)osh->pdev)->dev, va, size, 
dir));
++#else
+       return (pci_map_single(osh->pdev, va, size, dir));
++#endif
+ }
+ 
+ void BCMFASTPATH
+@@ -665,8 +681,13 @@
+       int dir;
+ 
+       ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
++      dir = (direction == DMA_TX)? DMA_TO_DEVICE: DMA_FROM_DEVICE;
++      dma_unmap_single(&((struct pci_dev *)osh->pdev)->dev, (uint32)pa, size, 
dir);
++#else
+       dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
+       pci_unmap_single(osh->pdev, (uint32)pa, size, dir);
++#endif
+ }
+ 
+ #if defined(BCMDBG_ASSERT)

diff --git a/net-wireless/broadcom-sta/files/014-linux414.patch 
b/net-wireless/broadcom-sta/files/014-linux414.patch
new file mode 100644
index 000000000000..0576aa5cf97c
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/014-linux414.patch
@@ -0,0 +1,37 @@
+From: Gerardo Esteban Malazdrewicz <[email protected]>
+Date: Fri, 29 Dec 2017 23:44:24 -0400
+Subject: linux414
+Origin: https://bugs.debian.org/885885
+
+linux 4.14 changed the kernel_read function prototype.
+---
+ src/shared/linux_osl.c | 12 +++++++++++-
+ 1 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/src/shared/linux_osl.c b/src/shared/linux_osl.c
+index 9adc392..b24a973 100644
+--- a/src/shared/linux_osl.c
++++ b/src/shared/linux_osl.c
+@@ -1076,11 +1076,21 @@ osl_os_get_image_block(char *buf, int len, void *image)
+ {
+       struct file *fp = (struct file *)image;
+       int rdlen;
++      loff_t pos;
+ 
+       if (!image)
+               return 0;
+ 
+-      rdlen = kernel_read(fp, fp->f_pos, buf, len);
++      pos = fp->f_pos;
++      rdlen = kernel_read(fp,
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
++                      pos,
++#endif
++                      buf, len
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
++                      ,&pos
++#endif
++      );
+       if (rdlen > 0)
+               fp->f_pos += rdlen;
+ 

diff --git a/net-wireless/broadcom-sta/files/015-linux600.patch 
b/net-wireless/broadcom-sta/files/015-linux600.patch
new file mode 100644
index 000000000000..8645907bbae4
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/015-linux600.patch
@@ -0,0 +1,31 @@
+From 933540c63f33e6ac2825d65c4b681ef3387d9146 Mon Sep 17 00:00:00 2001
+From: Antoine Cotten <[email protected]>
+Date: Mon, 15 Aug 2022 17:53:51 +0200
+Subject: [PATCH] cfg80211_roam_info compat for MLO APIs in Linux >= 6.0
+
+The 'bssid' struct field is now under 'links.bssid'.
+
+See also: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=efbabc11650040c64884ff3019b88c7bcc0ceb1d
+
+Original patch by Joan Bruguera:
+https://gist.github.com/joanbm/207210d74637870c01ef5a3c262a597d
+---
+ src/wl/sys/wl_cfg80211_hybrid.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c
+index 5e9e6d3..5ec35c5 100644
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -2412,7 +2412,11 @@ wl_bss_roaming_done(struct wl_cfg80211_priv *wl, struct 
net_device *ndev,
+       struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+       struct cfg80211_roam_info roam_info = {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 0, 0)
+               .bssid = wl->profile->bssid,
++#else
++              .links[0].bssid = wl->profile->bssid,
++#endif
+               .req_ie = conn_info->req_ie,
+               .req_ie_len = conn_info->req_ie_len,
+               .resp_ie = conn_info->resp_ie,

diff --git a/net-wireless/broadcom-sta/files/016-linux601.patch 
b/net-wireless/broadcom-sta/files/016-linux601.patch
new file mode 100644
index 000000000000..721967d275c2
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/016-linux601.patch
@@ -0,0 +1,90 @@
+diff -Nurp -u -r a/src/wl/sys/wl_cfg80211_hybrid.c 
b/src/wl/sys/wl_cfg80211_hybrid.c
+--- a/src/wl/sys/wl_cfg80211_hybrid.c  2022-12-12 00:23:30.821615599 +0000
++++ b/src/wl/sys/wl_cfg80211_hybrid.c  2022-12-12 00:35:47.854975024 +0000
+@@ -105,14 +105,28 @@ static s32 wl_cfg80211_get_tx_power(stru
+ static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
+ #endif
+ 
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
++static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
++           struct net_device *dev, int link_id, u8 key_idx, bool unicast,
++           bool multicast);
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+ static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
+            struct net_device *dev, u8 key_idx, bool unicast, bool multicast);
+ #else
+ static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
+            struct net_device *dev, u8 key_idx);
+ #endif
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
++static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
++           int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr,
++           struct key_params *params);
++static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
++           int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr);
++static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
++           int link_id, u8 key_idx, bool pairwise, const u8 *mac_addr,
++           void *cookie,
++           void (*callback) (void *cookie, struct key_params *params));
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+ static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+            u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params 
*params);
+ static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+@@ -1161,7 +1175,12 @@ static s32 wl_cfg80211_get_tx_power(stru
+       return err;
+ }
+ 
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
++static s32
++wl_cfg80211_config_default_key(struct wiphy *wiphy,
++      struct net_device *dev, int link_id, u8 key_idx, bool unicast,
++      bool multicast)
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+ static s32
+ wl_cfg80211_config_default_key(struct wiphy *wiphy,
+       struct net_device *dev, u8 key_idx, bool unicast, bool multicast)
+@@ -1186,7 +1205,12 @@ wl_cfg80211_config_default_key(struct wi
+       return 0;
+ }
+ 
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
++static s32
++wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
++                    int link_id, u8 key_idx, bool pairwise, const u8 
*mac_addr,
++                    struct key_params *params)
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+ static s32
+ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+                     u8 key_idx, bool pairwise, const u8 *mac_addr, struct 
key_params *params)
+@@ -1307,7 +1331,11 @@ wl_cfg80211_add_key(struct wiphy *wiphy,
+       return err;
+ }
+ 
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
++static s32
++wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
++                    int link_id, u8 key_idx, bool pairwise, const u8 
*mac_addr)
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+ static s32
+ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+                     u8 key_idx, bool pairwise, const u8 *mac_addr)
+@@ -1350,7 +1378,13 @@ wl_cfg80211_del_key(struct wiphy *wiphy,
+       return err;
+ }
+ 
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
++static s32
++wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
++                    int link_id, u8 key_idx, bool pairwise, const u8 
*mac_addr,
++                    void *cookie,
++                    void (*callback) (void *cookie, struct key_params * 
params))
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+ static s32
+ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+                     u8 key_idx, bool pairwise, const u8 *mac_addr, void 
*cookie,

diff --git a/net-wireless/broadcom-sta/files/broadcom-sta-modules.conf 
b/net-wireless/broadcom-sta/files/broadcom-sta-modules.conf
new file mode 100644
index 000000000000..458947e335b4
--- /dev/null
+++ b/net-wireless/broadcom-sta/files/broadcom-sta-modules.conf
@@ -0,0 +1,17 @@
+# modprobe.d configuration file for WL
+
+# Internal Aliases - Do not edit
+# ------------------------------
+alias wlan0 wl
+
+
+# Configurable module parameters
+# ------------------------------
+# passivemode:  (int)
+# wl_txq_thresh:        (int)
+# oneonly:      (int)
+# piomode:      (int)
+# instance_base:        (int)
+# nompc:        (int)
+# intf_name:    (string)
+

Reply via email to