forked from mirrors/nixpkgs
e8dd1fa1d9
* broadcom: fix build 5.9 Patch to fix the build error for the 5.9 Linux kernel. * broadcom: swith 5.9 patch to Joan Bruguera's version Switch the current patch for 5.9 to Joan Bruguera's version which is cleaner and also works for 5.10
185 lines
4.6 KiB
Diff
185 lines
4.6 KiB
Diff
diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c
|
|
index 4b3298f..c45ad48 100644
|
|
--- a/src/wl/sys/wl_cfg80211_hybrid.c
|
|
+++ b/src/wl/sys/wl_cfg80211_hybrid.c
|
|
@@ -41,6 +41,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)
|
|
@@ -442,30 +443,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(KERNEL_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 9c3c74e..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(KERNEL_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 c990c70..5bb9480 100644
|
|
--- a/src/wl/sys/wl_linux.c
|
|
+++ b/src/wl/sys/wl_linux.c
|
|
@@ -1664,10 +1664,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;
|
|
@@ -1688,7 +1685,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));
|
|
@@ -1701,6 +1698,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"
|
|
|