broadcom-wl.linux-recent.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. --- a/src/wl/sys/wl_cfg80211_hybrid.c 2014-06-26 12:42:08.000000000 +0200
  2. +++ b/src/wl/sys/wl_cfg80211_hybrid.c 2015-01-22 01:43:25.378920452 +0100
  3. @@ -63,8 +63,13 @@
  4. static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
  5. struct cfg80211_ibss_params *params);
  6. static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
  7. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
  8. static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
  9. struct net_device *dev, u8 *mac, struct station_info *sinfo);
  10. +#else
  11. +static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
  12. + struct net_device *dev, const u8 *mac, struct station_info *sinfo);
  13. +#endif
  14. static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
  15. struct net_device *dev, bool enabled, s32 timeout);
  16. static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
  17. @@ -1387,7 +1392,7 @@
  18. key_endian_to_host(&key);
  19. params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
  20. - memcpy(params.key, key.data, params.key_len);
  21. + memcpy((char *)params.key, key.data, params.key_len);
  22. if ((err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
  23. return err;
  24. @@ -1421,9 +1426,15 @@
  25. return err;
  26. }
  27. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
  28. static s32
  29. wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
  30. u8 *mac, struct station_info *sinfo)
  31. +#else
  32. +static s32
  33. +wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
  34. + const u8 *mac, struct station_info *sinfo)
  35. +#endif
  36. {
  37. struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
  38. scb_val_t scb_val;
  39. @@ -2010,9 +2021,15 @@
  40. notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
  41. notify_ielen = le32_to_cpu(bi->ie_length);
  42. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
  43. cbss = cfg80211_inform_bss(wiphy, channel, (const u8 *)(bi->BSSID.octet),
  44. 0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int,
  45. (const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
  46. +#else
  47. + cbss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, (const u8 *)(bi->BSSID.octet),
  48. + 0, beacon_proberesp->capab_info, beacon_proberesp->beacon_int,
  49. + (const u8 *)notify_ie, notify_ielen, signal, GFP_KERNEL);
  50. +#endif
  51. if (unlikely(!cbss))
  52. return -ENOMEM;
  53. @@ -2071,7 +2088,26 @@
  54. wl_get_assoc_ies(wl);
  55. memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
  56. wl_update_bss_info(wl);
  57. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
  58. + {
  59. + struct wl_bss_info *bi;
  60. + u16 bss_info_channel;
  61. + struct ieee80211_channel *channel;
  62. + u32 freq;
  63. +
  64. + bi = (struct wl_bss_info *)(wl->extra_buf + 4);
  65. + bss_info_channel = bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
  66. +
  67. + freq = ieee80211_channel_to_frequency(bss_info_channel,
  68. + (bss_info_channel <= CH_MAX_2G_CHANNEL) ?
  69. + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
  70. +
  71. + channel = ieee80211_get_channel(wl_to_wiphy(wl), freq);
  72. + cfg80211_ibss_joined(ndev, (u8 *)&wl->bssid, channel, GFP_KERNEL);
  73. + }
  74. +#else
  75. cfg80211_ibss_joined(ndev, (u8 *)&wl->bssid, GFP_KERNEL);
  76. +#endif
  77. set_bit(WL_STATUS_CONNECTED, &wl->status);
  78. wl->profile->active = true;
  79. }
  80. @@ -2629,7 +2665,15 @@
  81. void wl_cfg80211_detach(struct net_device *ndev)
  82. {
  83. - struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
  84. + struct wl_cfg80211_priv *wl;
  85. + struct wireless_dev *wdev;
  86. +
  87. + wdev = ndev->ieee80211_ptr;
  88. + if (wdev == NULL) {
  89. + printk(KERN_ERR "[%s()] in ndev=%p: IEEE80211ptr=%p\n", __FUNCTION__, ndev, wdev);
  90. + return;
  91. + }
  92. + wl = ndev_to_wl(ndev);
  93. wl_deinit_cfg80211_priv(wl);
  94. wl_free_wdev(wl);
  95. --- a/src/wl/sys/wl_dbg.h 2014-06-26 12:42:08.000000000 +0200
  96. +++ b/src/wl/sys/wl_dbg.h 2015-01-22 01:43:25.379920462 +0100
  97. @@ -55,10 +55,12 @@
  98. #define WL_NONE(args)
  99. +#define FORCE_TRACE_LEVEL(fmt, ...) do { printk(KERN_ERR fmt, ## __VA_ARGS__); } while (0) /* ## is GCC specific syntax to remove comma when single arg */
  100. +
  101. #ifdef BCMDBG_ERR
  102. #define WL_ERROR(args) WL_PRINT(args)
  103. #else
  104. -#define WL_ERROR(args)
  105. +#define WL_ERROR(args) FORCE_TRACE_LEVEL args
  106. #endif
  107. #define WL_TRACE(args)
  108. #define WL_APSTA_UPDN(args)
  109. --- a/src/wl/sys/wl_linux.c 2014-06-26 12:42:08.000000000 +0200
  110. +++ b/src/wl/sys/wl_linux.c 2015-01-22 01:44:58.580453805 +0100
  111. @@ -878,7 +878,7 @@
  112. static SIMPLE_DEV_PM_OPS(wl_pm_ops, wl_suspend, wl_resume);
  113. #endif
  114. -static struct pci_driver wl_pci_driver = {
  115. +static struct pci_driver wl_pci_driver __refdata = {
  116. .name = "wl",
  117. .probe = wl_pci_probe,
  118. .remove = __devexit_p(wl_remove),
  119. @@ -1270,6 +1270,7 @@
  120. MFREE(wl->osh, wlif->dev, sizeof(struct net_device));
  121. #else
  122. free_netdev(wlif->dev);
  123. + wlif->dev = NULL;
  124. #endif
  125. }
  126. @@ -1307,7 +1308,12 @@
  127. dev->priv = priv_link;
  128. #else
  129. +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0))
  130. dev = alloc_netdev(sizeof(priv_link_t), intf_name, ether_setup);
  131. +#else
  132. + dev = alloc_netdev(sizeof(priv_link_t), intf_name, NET_NAME_UNKNOWN,
  133. + ether_setup);
  134. +#endif
  135. if (!dev) {
  136. WL_ERROR(("wl%d: %s: alloc_netdev failed\n",
  137. (wl->pub)?wl->pub->unit:wlif->subunit, __FUNCTION__));
  138. @@ -1651,11 +1657,7 @@
  139. }
  140. WL_LOCK(wl);
  141. - if (!capable(CAP_NET_ADMIN)) {
  142. - bcmerror = BCME_EPERM;
  143. - } else {
  144. - bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
  145. - }
  146. + bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
  147. WL_UNLOCK(wl);
  148. done1:
  149. @@ -2157,8 +2159,8 @@
  150. wlif = WL_DEV_IF(dev);
  151. wl = WL_INFO(dev);
  152. + skb->prev = NULL;
  153. if (WL_ALL_PASSIVE_ENAB(wl) || (WL_RTR() && WL_CONFIG_SMP())) {
  154. - skb->prev = NULL;
  155. TXQ_LOCK(wl);
  156. @@ -2455,8 +2457,10 @@
  157. p80211msg_t *phdr;
  158. len = sizeof(p80211msg_t) + oskb->len - D11_PHY_HDR_LEN;
  159. - if ((skb = dev_alloc_skb(len)) == NULL)
  160. + if ((skb = dev_alloc_skb(len)) == NULL) {
  161. + WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
  162. return;
  163. + }
  164. skb_put(skb, len);
  165. phdr = (p80211msg_t*)skb->data;
  166. @@ -2535,8 +2539,10 @@
  167. rtap_len = sizeof(wl_radiotap_ht_brcm_2_t);
  168. len = rtap_len + (oskb->len - D11_PHY_HDR_LEN);
  169. - if ((skb = dev_alloc_skb(len)) == NULL)
  170. + if ((skb = dev_alloc_skb(len)) == NULL) {
  171. + WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
  172. return;
  173. + }
  174. skb_put(skb, len);
  175. @@ -2664,8 +2670,10 @@
  176. len += amsdu_len;
  177. }
  178. - if ((skb = dev_alloc_skb(len)) == NULL)
  179. + if ((skb = dev_alloc_skb(len)) == NULL) {
  180. + WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
  181. return;
  182. + }
  183. skb_put(skb, len);
  184. @@ -2990,7 +2998,7 @@
  185. }
  186. void
  187. -wl_set_monitor(wl_info_t *wl, int val)
  188. +wl_set_monitor(wl_info_t *wl, int val) /* public => is called by wlc_hybrid.o_shipped */
  189. {
  190. const char *devname;
  191. wl_if_t *wlif;
  192. @@ -3224,42 +3232,75 @@
  193. #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  194. static int
  195. wl_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
  196. +{
  197. + wl_info_t * wl = (wl_info_t *)data;
  198. #else
  199. static ssize_t
  200. -wl_proc_read(struct file *filp, char __user *buffer, size_t length, loff_t *data)
  201. -#endif
  202. +wl_proc_read(struct file *filp, char __user *buffer, size_t length, loff_t *offp)
  203. {
  204. - wl_info_t * wl = (wl_info_t *)data;
  205. - int to_user;
  206. - int len;
  207. + wl_info_t * wl = PDE_DATA(file_inode(filp));
  208. +#endif
  209. + int bcmerror, len;
  210. + int to_user = 0;
  211. + char tmp[8];
  212. #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  213. if (offset > 0) {
  214. *eof = 1;
  215. return 0;
  216. }
  217. +#else
  218. + if (*offp > 0) { /* for example, stop: cat /proc/brcm_monitor0 */
  219. + return 0; /* 0 <=> EOF */
  220. + }
  221. #endif
  222. - if (!length) {
  223. - WL_ERROR(("%s: Not enough return buf space\n", __FUNCTION__));
  224. - return 0;
  225. - }
  226. WL_LOCK(wl);
  227. - wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL);
  228. - len = sprintf(buffer, "%d\n", to_user);
  229. - WL_UNLOCK(wl);
  230. - return len;
  231. + bcmerror = wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL);
  232. + WL_UNLOCK(wl);
  233. +
  234. + if (bcmerror != BCME_OK) {
  235. + WL_ERROR(("%s: GET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
  236. + return -EIO;
  237. + }
  238. +
  239. + len = snprintf(tmp, ARRAY_SIZE(tmp), "%d\n", to_user);
  240. + tmp[ARRAY_SIZE(tmp) - 1] = '\0';
  241. + if (len >= ARRAY_SIZE(tmp)) {
  242. + printk(KERN_ERR "%s:%d [%s()] output would be truncated (ret=%d)!", __FILE__, __LINE__, __FUNCTION__, len);
  243. + return -ERANGE;
  244. + }
  245. + else if (len < 0) {
  246. + printk(KERN_ERR "%s:%d [%s()] unable to convert value (ret=%d)!", __FILE__, __LINE__, __FUNCTION__, len);
  247. + return len;
  248. + }
  249. + if (length < len) {
  250. + printk(KERN_ERR "%s:%d [%s()] user buffer is too small (at least=%d ; user=%d)!", __FILE__, __LINE__, __FUNCTION__, len, (int)length);
  251. + return -EMSGSIZE;
  252. + }
  253. + if (copy_to_user(buffer, tmp, len) != 0) {
  254. + printk(KERN_ERR "%s:%d [%s()] unable to copy data!", __FILE__, __LINE__, __FUNCTION__);
  255. + return -EFAULT;
  256. + }
  257. +
  258. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  259. + *offp += len;
  260. +#endif
  261. +
  262. + return len;
  263. }
  264. #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  265. static int
  266. wl_proc_write(struct file *filp, const char *buff, unsigned long length, void *data)
  267. +{
  268. + wl_info_t * wl = (wl_info_t *)data;
  269. #else
  270. static ssize_t
  271. -wl_proc_write(struct file *filp, const char __user *buff, size_t length, loff_t *data)
  272. -#endif
  273. +wl_proc_write(struct file *filp, const char __user *buff, size_t length, loff_t *offp)
  274. {
  275. - wl_info_t * wl = (wl_info_t *)data;
  276. + wl_info_t * wl = PDE_DATA(file_inode(filp));
  277. +#endif
  278. int from_user = 0;
  279. int bcmerror;
  280. @@ -3270,7 +3311,11 @@
  281. }
  282. if (copy_from_user(&from_user, buff, 1)) {
  283. WL_ERROR(("%s: copy from user failed\n", __FUNCTION__));
  284. - return -EIO;
  285. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  286. + return -EIO;
  287. +#else
  288. + return -EFAULT;
  289. +#endif
  290. }
  291. if (from_user >= 0x30)
  292. @@ -3280,10 +3325,15 @@
  293. bcmerror = wlc_ioctl(wl->wlc, WLC_SET_MONITOR, &from_user, sizeof(int), NULL);
  294. WL_UNLOCK(wl);
  295. - if (bcmerror < 0) {
  296. + if (bcmerror != BCME_OK) {
  297. WL_ERROR(("%s: SET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
  298. return -EIO;
  299. }
  300. +
  301. +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && 0 /* no need to update offset because this file should only trigger action... */
  302. + *offp += length;
  303. +#endif
  304. +
  305. return length;
  306. }
  307. @@ -3304,8 +3354,8 @@
  308. if ((wl->proc_entry = create_proc_entry(tmp, 0644, NULL)) == NULL) {
  309. WL_ERROR(("%s: create_proc_entry %s failed\n", __FUNCTION__, tmp));
  310. #else
  311. - if ((wl->proc_entry = proc_create(tmp, 0644, NULL, &wl_fops)) == NULL) {
  312. - WL_ERROR(("%s: proc_create %s failed\n", __FUNCTION__, tmp));
  313. + if ((wl->proc_entry = proc_create_data(tmp, 0644, NULL, &wl_fops, wl)) == NULL) {
  314. + WL_ERROR(("%s: proc_create_data %s failed\n", __FUNCTION__, tmp));
  315. #endif
  316. ASSERT(0);
  317. return -1;