diff -u bcmwl-6.30.223.271+bdcom/debian/changelog bcmwl-6.30.223.271+bdcom/debian/changelog --- bcmwl-6.30.223.271+bdcom/debian/changelog +++ bcmwl-6.30.223.271+bdcom/debian/changelog @@ -1,3 +1,27 @@ +bcmwl (6.30.223.271+bdcom-0ubuntu7~20.04.3) focal; urgency=medium + + * Backported from hirsute 6.30.223.271+bdcom-0ubuntu8 (LP: #1932159) + debian/dkms.conf.in, + debian/patches/0029-Update-for-set_fs-removal-in-Linux-5.10.patch + - Add internal ioctl helper to avoid the need to use set_fs()/get_fs(), + which have been removed in Linux 5.10. + + -- Tim Gardner Thu, 24 Jun 2021 12:35:40 +0000 + +bcmwl (6.30.223.271+bdcom-0ubuntu7~20.04.2) focal; urgency=medium + + * No change rebuild in security pocket. LP: #1914279. + + -- Dimitri John Ledkov Thu, 29 Apr 2021 16:05:27 +0100 + +bcmwl (6.30.223.271+bdcom-0ubuntu7~20.04.1) focal; urgency=medium + + * debian/dkms.conf.in, + debian/patches/0028-add-support-for-linux-5.6.patch (LP: #1872908): + - Add support for Linux 5.6. + + -- Alberto Milone Mon, 04 May 2020 13:23:19 +0200 + bcmwl (6.30.223.271+bdcom-0ubuntu5) eoan; urgency=medium * debian/dkms.conf.in, diff -u bcmwl-6.30.223.271+bdcom/debian/dkms.conf.in bcmwl-6.30.223.271+bdcom/debian/dkms.conf.in --- bcmwl-6.30.223.271+bdcom/debian/dkms.conf.in +++ bcmwl-6.30.223.271+bdcom/debian/dkms.conf.in @@ -19,4 +19,6 @@ PATCH[11]="0026-add-support-for-Linux-4.15.patch" PATCH[12]="0027-add-support-for-linux-5.1.patch" +PATCH[13]="0028-add-support-for-linux-5.6.patch" +PATCH[14]="0029-Update-for-set_fs-removal-in-Linux-5.10.patch" #PATCH_MATCH[6]="^3.[10-11]" AUTOINSTALL="yes" only in patch2: unchanged: --- bcmwl-6.30.223.271+bdcom.orig/debian/patches/0028-add-support-for-linux-5.6.patch +++ bcmwl-6.30.223.271+bdcom/debian/patches/0028-add-support-for-linux-5.6.patch @@ -0,0 +1,81 @@ +From 03dc9777612be477618f14bf600538f1eb96c0df Mon Sep 17 00:00:00 2001 +From: Alberto Milone +Date: Mon, 4 May 2020 13:17:19 +0200 +Subject: [PATCH 1/1] Add support for linux 5.6 + +Original patch: +https://git.archlinux.org/svntogit/community.git/commit/trunk?h=packages/broadcom-wl-dkms&id=e78ab887e946418baac2abcaad24b9df19f22945 + +Signed-off-by: Alberto Milone +--- + src/shared/linux_osl.c | 4 ++++ + src/wl/sys/wl_linux.c | 15 +++++++++++++++ + 2 files changed, 19 insertions(+) + +diff --git a/src/shared/linux_osl.c b/src/shared/linux_osl.c +index 6157d18..c6d1aed 100644 +--- a/src/shared/linux_osl.c ++++ b/src/shared/linux_osl.c +@@ -942,7 +942,11 @@ osl_getcycles(void) + void * + osl_reg_map(uint32 pa, uint size) + { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) ++ return (ioremap((unsigned long)pa, (unsigned long)size)); ++#else + return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); ++#endif + } + + void +diff --git a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c +index 0d05100..8aa60f4 100644 +--- a/src/wl/sys/wl_linux.c ++++ b/src/wl/sys/wl_linux.c +@@ -582,7 +582,11 @@ wl_attach(uint16 vendor, uint16 device, ulong regs, + } + wl->bcm_bustype = bustype; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) ++ if ((wl->regsva = ioremap(dev->base_addr, PCI_BAR0_WINSZ)) == NULL) { ++#else + if ((wl->regsva = ioremap_nocache(dev->base_addr, PCI_BAR0_WINSZ)) == NULL) { ++#endif + WL_ERROR(("wl%d: ioremap() failed\n", unit)); + goto fail; + } +@@ -772,7 +776,11 @@ 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); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) ++ bar1_addr = (uchar *)ioremap(pci_resource_start(pdev, 2), ++#else + bar1_addr = (uchar *)ioremap_nocache(pci_resource_start(pdev, 2), ++#endif + 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 +3343,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) +-- +2.25.1 + only in patch2: unchanged: --- bcmwl-6.30.223.271+bdcom.orig/debian/patches/0029-Update-for-set_fs-removal-in-Linux-5.10.patch +++ bcmwl-6.30.223.271+bdcom/debian/patches/0029-Update-for-set_fs-removal-in-Linux-5.10.patch @@ -0,0 +1,194 @@ +From 91bfe09c1239d916195f53380b56361f631f74b2 Mon Sep 17 00:00:00 2001 +From: Seth Forshee +Date: Fri, 12 Mar 2021 08:32:26 -0600 +Subject: [PATCH] Update for set_fs() removal in Linux 5.10 + +The driver uses set_fs() to allow internal use of ioctls with +kernel memory instead of userspace memory. This is always for the +SIOCDEVPRIVATE ioctl, so add an internal function to handle these +operations without any copy_(to|from0_user calls. + +Signed-off-by: Seth Forshee +--- + src/wl/sys/wl_cfg80211_hybrid.c | 26 ++------------------- + src/wl/sys/wl_iw.c | 25 ++------------------- + src/wl/sys/wl_linux.c | 40 ++++++++++++++++++++++++++++----- + src/wl/sys/wl_linux.h | 3 +++ + 4 files changed, 42 insertions(+), 52 deletions(-) + +diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c +index 5f74e66b147b..dcc18ce5ec61 100644 +--- a/src/wl/sys/wl_cfg80211_hybrid.c ++++ b/src/wl/sys/wl_cfg80211_hybrid.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #define EVENT_TYPE(e) dtoh32((e)->event_type) + #define EVENT_FLAGS(e) dtoh16((e)->flags) +@@ -444,30 +445,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_kernel(dev, cmd, arg, len); + } + + static s32 +diff --git a/src/wl/sys/wl_iw.c b/src/wl/sys/wl_iw.c +index c4c610bbcf73..41436cee044c 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 + #include ++#include + + 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_kernel(*dev, cmd, arg, len); + } + + static int +diff --git a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c +index 2bcc8cda1550..d5d49fb761f6 100644 +--- a/src/wl/sys/wl_linux.c ++++ b/src/wl/sys/wl_linux.c +@@ -1659,10 +1659,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; +@@ -1683,7 +1680,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)); +@@ -1696,6 +1693,39 @@ done2: + return (OSL_ERROR(bcmerror)); + } + ++/* ++ * SIOCDEVPRIVATE ioctl support for internal driver use, when no userspace ++ * memory copies are required. ++ */ ++int ++wlc_ioctl_kernel(struct net_device *dev, uint cmd, void *buf, uint 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; ++ ++ 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 5b1048e5af46..26516b871a4c 100644 +--- a/src/wl/sys/wl_linux.h ++++ b/src/wl/sys/wl_linux.h +@@ -21,6 +21,8 @@ + #ifndef _wl_linux_h_ + #define _wl_linux_h_ + ++#include ++#include + #include + + typedef struct wl_timer { +@@ -187,6 +189,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_kernel(struct net_device *dev, uint cmd, void *buf, uint len); + extern struct net_device * wl_netdev_get(wl_info_t *wl); + + #endif +-- +2.30.0 +