OSDN Git Service

net: wireless: wl: update broadcom-sta hybrid driver
authorMauro Rossi <issor.oruam@gmail.com>
Wed, 2 Dec 2015 01:28:33 +0000 (02:28 +0100)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 2 Dec 2015 16:32:01 +0000 (00:32 +0800)
Changes to support latest broadcom wl driver ver. 6.30.223.271

wl.patch and linux-recent.patch were updated as instructed here:
https://aur.archlinux.org/packages/broadcom-wl-ck/

001-null-pointer-fix.patch is kernel version independent
and goes to wl.patch

For kernel < 4.3 former linux-recent.patch wouldn't need to be applied,
but 002-rdtscl.patch is kernel >= 4.3 dependent,
so it's the only change needed in the new linux-recent.patch

In this way android-x86 kernel builiding script,
i.e. build/core/tasks/kernel.mk, will just need to update
new broadcom tar.gz archive file name in WL_SRC definition

drivers/net/wireless/wl/linux-recent.patch
drivers/net/wireless/wl/wl.patch

index 6563e87..b45e3bd 100644 (file)
---- a/src/wl/sys/wl_cfg80211_hybrid.c  2014-06-26 12:42:08.000000000 +0200
-+++ b/src/wl/sys/wl_cfg80211_hybrid.c  2015-04-13 13:20:08.140013177 +0200
-@@ -63,8 +63,13 @@
- static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
-            struct cfg80211_ibss_params *params);
- static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
- static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
-            struct net_device *dev, u8 *mac, struct station_info *sinfo);
-+#else
-+static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
-+           struct net_device *dev, const u8 *mac, struct station_info *sinfo);
-+#endif
- static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
-            struct net_device *dev, bool enabled, s32 timeout);
- static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
-@@ -1387,7 +1392,7 @@
-       key_endian_to_host(&key);
-       params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
--      memcpy(params.key, key.data, params.key_len);
-+      memcpy((char *)params.key, key.data, params.key_len);
-       if ((err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
-               return err;
-@@ -1421,9 +1426,15 @@
-       return err;
- }
+--- a/src/shared/linux_osl.c
++++ b/src/shared/linux_osl.c
+@@ -932,7 +932,11 @@
+       uint cycles;
  
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
- static s32
- wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
-                         u8 *mac, struct station_info *sinfo)
-+#else
-+static s32
-+wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
-+                        const u8 *mac, struct station_info *sinfo)
-+#endif
- {
-       struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
-       scb_val_t scb_val;
-@@ -1441,7 +1452,11 @@
-               WL_DBG(("Could not get rate (%d)\n", err));
-       } else {
-               rate = dtoh32(rate);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
-               sinfo->filled |= STATION_INFO_TX_BITRATE;
-+#else
-+              sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
-+#endif
-               sinfo->txrate.legacy = rate * 5;
-               WL_DBG(("Rate %d Mbps\n", (rate / 2)));
-       }
-@@ -1454,7 +1469,11 @@
-                       return err;
-               }
-               rssi = dtoh32(scb_val.val);
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
-               sinfo->filled |= STATION_INFO_SIGNAL;
+ #if defined(__i386__)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
++      cycles = (u32)rdtsc();
 +#else
-+              sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+       rdtscl(cycles);
 +#endif
-               sinfo->signal = rssi;
-               WL_DBG(("RSSI %d dBm\n", rssi));
-       }
-@@ -2010,9 +2029,15 @@
-       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);
-+#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);
-+#endif
-       if (unlikely(!cbss))
-               return -ENOMEM;
-@@ -2071,7 +2096,26 @@
-                       wl_get_assoc_ies(wl);
-                       memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
-                       wl_update_bss_info(wl);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
-+                      {
-+                              struct wl_bss_info *bi;
-+                              u16 bss_info_channel;
-+                              struct ieee80211_channel *channel;
-+                              u32 freq;
-+
-+                              bi = (struct wl_bss_info *)(wl->extra_buf + 4);
-+                              bss_info_channel = bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
-+
-+                              freq = ieee80211_channel_to_frequency(bss_info_channel,
-+                                     (bss_info_channel <= CH_MAX_2G_CHANNEL) ?
-+                                     IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
-+
-+                              channel = ieee80211_get_channel(wl_to_wiphy(wl), freq);
-+                              cfg80211_ibss_joined(ndev, (u8 *)&wl->bssid, channel, GFP_KERNEL);
-+                      }
-+#else
-                       cfg80211_ibss_joined(ndev, (u8 *)&wl->bssid, GFP_KERNEL);
-+#endif
-                       set_bit(WL_STATUS_CONNECTED, &wl->status);
-                       wl->profile->active = true;
-               }
-@@ -2629,7 +2673,15 @@
- void wl_cfg80211_detach(struct net_device *ndev)
- {
--      struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
-+      struct wl_cfg80211_priv *wl;
-+      struct wireless_dev *wdev;
-+
-+      wdev = ndev->ieee80211_ptr;
-+      if (wdev == NULL) {
-+                printk(KERN_ERR "[%s()] in ndev=%p: IEEE80211ptr=%p\n", __FUNCTION__, ndev, wdev);
-+                return;
-+        }
-+      wl = ndev_to_wl(ndev);
-       wl_deinit_cfg80211_priv(wl);
-       wl_free_wdev(wl);
---- a/src/wl/sys/wl_dbg.h      2014-06-26 12:42:08.000000000 +0200
-+++ b/src/wl/sys/wl_dbg.h      2015-04-13 13:19:52.443345832 +0200
-@@ -55,10 +55,12 @@
- #define WL_NONE(args)
-+#define FORCE_TRACE_LEVEL(fmt, ...) do { printk(KERN_ERR fmt, ## __VA_ARGS__); } while (0) /* ## is GCC specific syntax to remove comma when single arg */
-+
- #ifdef BCMDBG_ERR
- #define       WL_ERROR(args)          WL_PRINT(args)
  #else
--#define       WL_ERROR(args)
-+#define       WL_ERROR(args)          FORCE_TRACE_LEVEL args
+       cycles = 0;
  #endif 
- #define       WL_TRACE(args)
- #define WL_APSTA_UPDN(args)
---- a/src/wl/sys/wl_linux.c    2014-06-26 12:42:08.000000000 +0200
-+++ b/src/wl/sys/wl_linux.c    2015-04-13 13:19:52.443345832 +0200
-@@ -878,7 +878,7 @@
- static SIMPLE_DEV_PM_OPS(wl_pm_ops, wl_suspend, wl_resume);
- #endif
--static struct pci_driver wl_pci_driver = {
-+static struct pci_driver wl_pci_driver __refdata = {
-       .name =         "wl",
-       .probe =        wl_pci_probe,
-       .remove =       __devexit_p(wl_remove),
-@@ -1270,6 +1270,7 @@
-               MFREE(wl->osh, wlif->dev, sizeof(struct net_device));
- #else
-               free_netdev(wlif->dev);
-+              wlif->dev = NULL;
- #endif 
-       }
-@@ -1307,7 +1308,12 @@
-       dev->priv = priv_link;
- #else
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
-       dev = alloc_netdev(sizeof(priv_link_t), intf_name, ether_setup);
-+#else
-+      dev = alloc_netdev(sizeof(priv_link_t), intf_name, NET_NAME_UNKNOWN,
-+                         ether_setup);
-+#endif
-       if (!dev) {
-               WL_ERROR(("wl%d: %s: alloc_netdev failed\n",
-                       (wl->pub)?wl->pub->unit:wlif->subunit, __FUNCTION__));
-@@ -1651,11 +1657,7 @@
-       }
-       WL_LOCK(wl);
--      if (!capable(CAP_NET_ADMIN)) {
--              bcmerror = BCME_EPERM;
--      } else {
--              bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
--      }
-+      bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
-       WL_UNLOCK(wl);
- done1:
-@@ -2157,8 +2159,8 @@
-       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);
-@@ -2455,8 +2457,10 @@
-               p80211msg_t *phdr;
-               len = sizeof(p80211msg_t) + oskb->len - D11_PHY_HDR_LEN;
--              if ((skb = dev_alloc_skb(len)) == NULL)
-+              if ((skb = dev_alloc_skb(len)) == NULL) {
-+                      WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
-                       return;
-+              }
-               skb_put(skb, len);
-               phdr = (p80211msg_t*)skb->data;
-@@ -2535,8 +2539,10 @@
-                       rtap_len = sizeof(wl_radiotap_ht_brcm_2_t);
-               len = rtap_len + (oskb->len - D11_PHY_HDR_LEN);
--              if ((skb = dev_alloc_skb(len)) == NULL)
-+              if ((skb = dev_alloc_skb(len)) == NULL) {
-+                      WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
-                       return;
-+              }
-               skb_put(skb, len);
-@@ -2664,8 +2670,10 @@
-                       len += amsdu_len;
-               }
--              if ((skb = dev_alloc_skb(len)) == NULL)
-+              if ((skb = dev_alloc_skb(len)) == NULL) {
-+                      WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
-                       return;
-+              }
-               skb_put(skb, len);
-@@ -2990,7 +2998,7 @@
- }
- void
--wl_set_monitor(wl_info_t *wl, int val)
-+wl_set_monitor(wl_info_t *wl, int val) /* public => is called by wlc_hybrid.o_shipped */
- {
-       const char *devname;
-       wl_if_t *wlif;
-@@ -3224,42 +3232,75 @@
- #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
- static int
- wl_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
-+{
-+      wl_info_t * wl = (wl_info_t *)data;
- #else
- static ssize_t
--wl_proc_read(struct file *filp, char __user *buffer, size_t length, loff_t *data)
--#endif
-+wl_proc_read(struct file *filp, char __user *buffer, size_t length, loff_t *offp)
- {
--      wl_info_t * wl = (wl_info_t *)data;
--      int to_user;
--      int len;
-+      wl_info_t * wl = PDE_DATA(file_inode(filp));
-+#endif
-+      int bcmerror, len;
-+      int to_user = 0;
-+      char tmp[8];
- #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
-       if (offset > 0) {
-               *eof = 1;
-               return 0;
-       }
-+#else
-+      if (*offp > 0) { /* for example, stop: cat /proc/brcm_monitor0 */
-+              return 0; /* 0 <=> EOF */
-+      }
- #endif
--      if (!length) {
--              WL_ERROR(("%s: Not enough return buf space\n", __FUNCTION__));
--              return 0;
--      }
-       WL_LOCK(wl);
--      wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL);
--      len = sprintf(buffer, "%d\n", to_user);
--      WL_UNLOCK(wl);
--      return len;
-+      bcmerror = wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL);
-+      WL_UNLOCK(wl);
-+
-+      if (bcmerror != BCME_OK) {
-+              WL_ERROR(("%s: GET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
-+              return -EIO;
-+      }
-+
-+      len = snprintf(tmp, ARRAY_SIZE(tmp), "%d\n", to_user);
-+      tmp[ARRAY_SIZE(tmp) - 1] = '\0';
-+      if (len >= ARRAY_SIZE(tmp)) {
-+              printk(KERN_ERR "%s:%d [%s()] output would be truncated (ret=%d)!", __FILE__, __LINE__, __FUNCTION__, len);
-+              return -ERANGE;
-+      }
-+      else if (len < 0) {
-+              printk(KERN_ERR "%s:%d [%s()] unable to convert value (ret=%d)!", __FILE__, __LINE__, __FUNCTION__, len);
-+              return len;
-+      }
-+      if (length < len) {
-+              printk(KERN_ERR "%s:%d [%s()] user buffer is too small (at least=%d ; user=%d)!", __FILE__, __LINE__, __FUNCTION__, len, (int)length);
-+              return -EMSGSIZE;
-+      }
-+      if (copy_to_user(buffer, tmp, len) != 0) {
-+              printk(KERN_ERR "%s:%d [%s()] unable to copy data!", __FILE__, __LINE__, __FUNCTION__);
-+              return -EFAULT;
-+      }
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
-+      *offp += len;
-+#endif
-+
-+      return len;
- }
- #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
- static int
- wl_proc_write(struct file *filp, const char *buff, unsigned long length, void *data)
-+{
-+      wl_info_t * wl = (wl_info_t *)data;
- #else
- static ssize_t
--wl_proc_write(struct file *filp, const char __user *buff, size_t length, loff_t *data)
--#endif
-+wl_proc_write(struct file *filp, const char __user *buff, size_t length, loff_t *offp)
- {
--      wl_info_t * wl = (wl_info_t *)data;
-+      wl_info_t * wl = PDE_DATA(file_inode(filp));
-+#endif
-       int from_user = 0;
-       int bcmerror;
-@@ -3270,7 +3311,11 @@
-       }
-       if (copy_from_user(&from_user, buff, 1)) {
-               WL_ERROR(("%s: copy from user failed\n", __FUNCTION__));
--              return -EIO;
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
-+              return -EIO;
-+#else
-+              return -EFAULT;
-+#endif
-       }
-       if (from_user >= 0x30)
-@@ -3280,10 +3325,15 @@
-       bcmerror = wlc_ioctl(wl->wlc, WLC_SET_MONITOR, &from_user, sizeof(int), NULL);
-       WL_UNLOCK(wl);
--      if (bcmerror < 0) {
-+      if (bcmerror != BCME_OK) {
-               WL_ERROR(("%s: SET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
-               return -EIO;
-       }
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && 0 /* no need to update offset because this file should only trigger action... */
-+      *offp += length;
-+#endif
-+
-       return length;
- }
-@@ -3304,8 +3354,8 @@
-       if ((wl->proc_entry = create_proc_entry(tmp, 0644, NULL)) == NULL) {
-               WL_ERROR(("%s: create_proc_entry %s failed\n", __FUNCTION__, tmp));
- #else
--      if ((wl->proc_entry = proc_create(tmp, 0644, NULL, &wl_fops)) == NULL) {
--              WL_ERROR(("%s: proc_create %s failed\n", __FUNCTION__, tmp));
-+      if ((wl->proc_entry = proc_create_data(tmp, 0644, NULL, &wl_fops, wl)) == NULL) {
-+              WL_ERROR(("%s: proc_create_data %s failed\n", __FUNCTION__, tmp));
- #endif
-               ASSERT(0);
-               return -1;
index 383e510..74c04d8 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/wl/Makefile
 +++ b/drivers/net/wireless/wl/Makefile
-@@ -126,7 +126,7 @@
+@@ -145,7 +145,7 @@
  EXTRA_CFLAGS       += -I$(src)/src/shared/bcmwifi/include
  #EXTRA_CFLAGS       += -DBCMDBG_ASSERT
  
@@ -11,7 +11,7 @@
  KBUILD_DIR         ?= $(KBASE)/build
 --- a/drivers/net/wireless/wl/src/wl/sys/wl_linux.c
 +++ b/drivers/net/wireless/wl/src/wl/sys/wl_linux.c
-@@ -235,7 +235,7 @@
+@@ -217,7 +217,7 @@
  #define to_str(s) #s
  #define quote_str(s) to_str(s)
  
  
  static char intf_name[IFNAMSIZ] = quote_str(BRCM_WLAN_IFNAME);
  
-diff --git a/drivers/net/wireless/wl/src/wl/sys/wl_linux.c b/drivers/net/wireless/wl/src/wl/sys/wl_linux.c
-index b23face..318ab63 100644
 --- a/drivers/net/wireless/wl/src/wl/sys/wl_linux.c
 +++ b/drivers/net/wireless/wl/src/wl/sys/wl_linux.c
-@@ -2045,8 +2045,8 @@ wl_osl_pcie_rc(struct wl_info *wl, uint op, int param)
+@@ -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)
  {
@@ -35,3 +33,16 @@ index b23face..318ab63 100644
  }
  
  #if defined(BCMDBG)
+--- a/drivers/net/wireless/wl/src/wl/sys/wl_linux.c
++++ b/drivers/net/wireless/wl/src/wl/sys/wl_linux.c
+@@ -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);
+