OSDN Git Service

Add support for Broadcom wl sta driver
authorChih-Wei Huang <cwhuang@linux.org.tw>
Thu, 6 Dec 2018 07:00:09 +0000 (15:00 +0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Thu, 6 Dec 2018 07:00:09 +0000 (15:00 +0800)
This will download Broadcom wl driver 6.30.223.271 and patch it
to build with the latest kernel.

Make sure you have a workable network on building.

wl/Android.mk [new file with mode: 0644]
wl/linux-411.patch [new file with mode: 0644]
wl/linux-412.patch [new file with mode: 0644]
wl/linux-415.patch [new file with mode: 0644]
wl/linux-48.patch [new file with mode: 0644]
wl/linux-recent.patch [new file with mode: 0644]
wl/wl.patch [new file with mode: 0644]

diff --git a/wl/Android.mk b/wl/Android.mk
new file mode 100644 (file)
index 0000000..6f2a347
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Copyright (C) 2018 The Android-x86 Open Source Project
+#
+# Licensed under the GNU General Public License Version 2 or later.
+# You may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.gnu.org/licenses/gpl.html
+#
+
+LOCAL_PATH := $(my-dir)
+LOCAL_MODULE := $(notdir $(LOCAL_PATH))
+EXTRA_KERNEL_MODULE_PATH_$(LOCAL_MODULE) := $(LOCAL_PATH)
+
+# parts of build/tasks/kernel.mk
+
+TARGET_KERNEL_ARCH ?= $(TARGET_ARCH)
+WL_PATH := $(TARGET_OUT_INTERMEDIATES)/kmodule/wl
+WL_SRC := $(WL_PATH)/hybrid-v35$(if $(filter x86,$(TARGET_KERNEL_ARCH)),,_64)-nodebug-pcoem-6_30_223_271.tar.gz
+WL_LIB := $(WL_PATH)/lib$(if $(filter x86,$(TARGET_KERNEL_ARCH)),32,64)
+
+WL_PATCHES := \
+       wl.patch \
+       linux-recent.patch \
+       linux-48.patch \
+       linux-411.patch \
+       linux-412.patch \
+       linux-415.patch \
+
+$(WL_SRC):
+       @echo Downloading $(@F)...
+       $(hide) mkdir -p $(@D) && curl -k https://docs.broadcom.com/docs-and-downloads/docs/linux_sta/$(@F) > $@
+
+$(WL_LIB): $(WL_SRC) $(addprefix $(LOCAL_PATH)/,$(WL_PATCHES))
+       $(hide) tar zxf $< -C $(@D) --overwrite -m && \
+               rm -rf $@ && mv $(@D)/lib $@ && touch $@ && \
+               cat $(filter %.patch,$^) | patch -p1 -d $(@D)
+
+$(WL_PATH): $(WL_LIB)
diff --git a/wl/linux-411.patch b/wl/linux-411.patch
new file mode 100644 (file)
index 0000000..b02847e
--- /dev/null
@@ -0,0 +1,52 @@
+diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c
+index a9671e2..da36405 100644
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -30,6 +30,9 @@
+ #include <linux/kthread.h>
+ #include <linux/netdevice.h>
+ #include <linux/ieee80211.h>
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
++#include <linux/sched/signal.h>
++#endif
+ #include <net/cfg80211.h>
+ #include <linux/nl80211.h>
+ #include <net/rtnetlink.h>
+diff --git a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c
+index 489c9f5..f8278ad 100644
+--- a/src/wl/sys/wl_linux.c
++++ b/src/wl/sys/wl_linux.c
+@@ -117,6 +117,9 @@
+ typedef struct priv_link {
+       wl_if_t *wlif;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
++      unsigned long last_rx;
++#endif
+ } priv_link_t;
+ #define WL_DEV_IF(dev)          ((wl_if_t*)((priv_link_t*)DEV_PRIV(dev))->wlif)
+@@ -2449,6 +2452,9 @@
+ {
+       struct sk_buff *oskb = (struct sk_buff *)p;
+       struct sk_buff *skb;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
++      priv_link_t *priv_link;
++#endif
+       uchar *pdata;
+       uint len;
+@@ -2915,7 +2921,13 @@
+       if (skb == NULL) return;
+       skb->dev = wl->monitor_dev;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
++      priv_link = MALLOC(wl->osh, sizeof(priv_link_t));
++      priv_link = netdev_priv(skb->dev);
++      priv_link->last_rx = jiffies;
++#else
+       skb->dev->last_rx = jiffies;
++#endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+       skb_reset_mac_header(skb);
+ #else
diff --git a/wl/linux-412.patch b/wl/linux-412.patch
new file mode 100644 (file)
index 0000000..e011fca
--- /dev/null
@@ -0,0 +1,68 @@
+diff --git a/src/wl/sys/wl_cfg80211_hybrid.c b/src/wl/sys/wl_cfg80211_hybrid.c
+index da36405..d3741eb 100644
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -53,7 +53,11 @@
+ #endif
+ static s32 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
++           enum nl80211_iftype type, struct vif_params *params);
++#else
+            enum nl80211_iftype type, u32 *flags, struct vif_params *params);
++#endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+ static s32
+ wl_cfg80211_scan(struct wiphy *wiphy,
+@@ -473,7 +477,11 @@
+ static s32
+ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
++                         enum nl80211_iftype type,
++#else
+                          enum nl80211_iftype type, u32 *flags,
++#endif
+    struct vif_params *params)
+ {
+       struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
+@@ -2369,6 +2377,20 @@
+                     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_bss *bss;
++      struct wlc_ssid *ssid;
++      ssid = &wl->profile->ssid;
++      bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
++      ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
++      struct cfg80211_roam_info roam_info = {
++              .bss = bss,
++              .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;
+       wl_get_assoc_ies(wl);
+@@ -2376,12 +2398,17 @@
+       memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
+       wl_update_bss_info(wl);
+       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/wl/linux-415.patch b/wl/linux-415.patch
new file mode 100644 (file)
index 0000000..7e6607c
--- /dev/null
@@ -0,0 +1,48 @@
+diff --git a/src/wl/sys/wl_linux.c b/src/wl/sys/wl_linux.c
+index 1270d6da22ba..ec120cf7d74c 100644
+--- a/src/wl/sys/wl_linux.c
++++ b/src/wl/sys/wl_linux.c
+@@ -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);
+@@ -2300,10 +2304,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);
+@@ -2355,9 +2366,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/wl/linux-48.patch b/wl/linux-48.patch
new file mode 100644 (file)
index 0000000..c5f7556
--- /dev/null
@@ -0,0 +1,52 @@
+Reference: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=839629
+
+--- a/src/wl/sys/wl_cfg80211_hybrid.c  2016-10-03 10:53:55.588036464 +0200
++++ b/src/wl/sys/wl_cfg80211_hybrid.c  2016-10-03 10:54:11.911695944 +0200
+@@ -2394,8 +2394,15 @@
+       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, true);     
++              cfg80211_scan_done(wl->scan_request, &info);
++#else
++              cfg80211_scan_done(wl->scan_request, true);
++#endif
+               wl->scan_request = NULL;
+       }
+@@ -2496,7 +2503,14 @@
+ 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();
+@@ -2921,7 +2935,14 @@
+       s32 err = 0;
+       if (wl->scan_request) {
+-              cfg80211_scan_done(wl->scan_request, true);     
++#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;
+       }
diff --git a/wl/linux-recent.patch b/wl/linux-recent.patch
new file mode 100644 (file)
index 0000000..3ff9f18
--- /dev/null
@@ -0,0 +1,38 @@
+--- a/src/shared/linux_osl.c
++++ b/src/shared/linux_osl.c
+@@ -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 
+--- a/src/wl/sys/wl_cfg80211_hybrid.c
++++ b/src/wl/sys/wl_cfg80211_hybrid.c
+@@ -235,6 +235,13 @@
+ };
+ #endif                                
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
++#define ieee80211_band nl80211_band
++#define IEEE80211_BAND_2GHZ NL80211_BAND_2GHZ
++#define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ
++#define IEEE80211_NUM_BANDS NUM_NL80211_BANDS
++#endif
++
+ #define CHAN2G(_channel, _freq, _flags) {                     \
+       .band                   = IEEE80211_BAND_2GHZ,          \
+       .center_freq            = (_freq),                      \
+@@ -1872,6 +1879,7 @@
+       }
+       set_wiphy_dev(wdev->wiphy, dev);
+       wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
++      wdev->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+       wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
+ #endif
diff --git a/wl/wl.patch b/wl/wl.patch
new file mode 100644 (file)
index 0000000..19812ee
--- /dev/null
@@ -0,0 +1,43 @@
+--- a/Makefile
++++ b/Makefile
+@@ -145,7 +145,7 @@
+ EXTRA_CFLAGS       += -Wno-date-time
+ endif
+-EXTRA_LDFLAGS      := $(src)/lib/wlc_hybrid.o_shipped
++EXTRA_LDFLAGS      := $(src)/lib$(if $(CONFIG_64BIT),64,32)/wlc_hybrid.o_shipped
+ KBASE              ?= /lib/modules/`uname -r`
+ KBUILD_DIR         ?= $(KBASE)/build
+--- a/src/wl/sys/wl_linux.c
++++ b/src/wl/sys/wl_linux.c
+@@ -217,7 +217,7 @@
+ #define to_str(s) #s
+ #define quote_str(s) to_str(s)
+-#define BRCM_WLAN_IFNAME eth%d
++#define BRCM_WLAN_IFNAME wlan%d
+ static char intf_name[IFNAMSIZ] = quote_str(BRCM_WLAN_IFNAME);
+@@ -2053,8 +2053,8 @@ wl_osl_pcie_rc(struct wl_info *wl, uint op, int param)
+ void
+ 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);
++      bcm_bprintf(b, "wl%d: version %s\n", wl->pub->unit,
++              EPI_VERSION_STR);
+ }
+ #if defined(BCMDBG)
+@@ -2165,8 +2165,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);