commit:     1460a7472a1a86edb1bb089bb321b4f5562ddc9d
Author:     Marco Genasci <fedeliallalinea <AT> gmail <DOT> com>
AuthorDate: Sat Apr  3 16:23:35 2021 +0000
Commit:     Joonas Niilola <juippis <AT> gentoo <DOT> org>
CommitDate: Sun Apr 11 08:06:27 2021 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=1460a747

net-wireless/broadcom-sta: linux >=5.9 support

Closes: https://bugs.gentoo.org/761286
Package-Manager: Portage-3.0.17, Repoman-3.0.2
Signed-off-by: Marco Genasci <fedeliallalinea <AT> gmail.com>
Closes: https://github.com/gentoo/gentoo/pull/20246
Signed-off-by: Joonas Niilola <juippis <AT> gentoo.org>

 .../broadcom-sta-6.30.223.271-r6.ebuild            |   1 +
 .../broadcom-sta-6.30.223.271-r6-linux-5.9.patch   | 211 +++++++++++++++++++++
 2 files changed, 212 insertions(+)

diff --git a/net-wireless/broadcom-sta/broadcom-sta-6.30.223.271-r6.ebuild 
b/net-wireless/broadcom-sta/broadcom-sta-6.30.223.271-r6.ebuild
index a75c785b267..57a5de8d0d2 100644
--- a/net-wireless/broadcom-sta/broadcom-sta-6.30.223.271-r6.ebuild
+++ b/net-wireless/broadcom-sta/broadcom-sta-6.30.223.271-r6.ebuild
@@ -34,6 +34,7 @@ PATCHES=(
        "${FILESDIR}/${PN}-6.30.223.271-r4-linux-4.15.patch"
        "${FILESDIR}/${PN}-6.30.223.271-r5-linux-5.1.patch"
        "${FILESDIR}/${PN}-6.30.223.271-r5-linux-5.6.patch"
+       "${FILESDIR}/${PN}-6.30.223.271-r6-linux-5.9.patch"
 )
 
 MODULE_NAMES="wl(net/wireless)"

diff --git 
a/net-wireless/broadcom-sta/files/broadcom-sta-6.30.223.271-r6-linux-5.9.patch 
b/net-wireless/broadcom-sta/files/broadcom-sta-6.30.223.271-r6-linux-5.9.patch
new file mode 100644
index 00000000000..6ef476464c0
--- /dev/null
+++ 
b/net-wireless/broadcom-sta/files/broadcom-sta-6.30.223.271-r6-linux-5.9.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

Reply via email to