PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/net/wireless/bcmdhd/wl_android.c

https://bitbucket.org/droidzone/supernovan7100
C | 2122 lines | 1762 code | 293 blank | 67 comment | 404 complexity | 259b9d8c61a5079a7027088b399e3777 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Linux cfg80211 driver - Android related functions
  3. *
  4. * Copyright (C) 1999-2012, Broadcom Corporation
  5. *
  6. * Unless you and Broadcom execute a separate written software license
  7. * agreement governing use of this software, this software is licensed to you
  8. * under the terms of the GNU General Public License version 2 (the "GPL"),
  9. * available at http://www.broadcom.com/licenses/GPLv2.php, with the
  10. * following added to such license:
  11. *
  12. * As a special exception, the copyright holders of this software give you
  13. * permission to link this software with independent modules, and to copy and
  14. * distribute the resulting executable under terms of your choice, provided that
  15. * you also meet, for each linked independent module, the terms and conditions of
  16. * the license of that module. An independent module is a module which is not
  17. * derived from this software. The special exception does not apply to any
  18. * modifications of the software.
  19. *
  20. * Notwithstanding the above, under no circumstances may you combine this
  21. * software in any way with any other Broadcom software provided under a license
  22. * other than the GPL, without Broadcom's express prior written consent.
  23. *
  24. * $Id: wl_android.c 354184 2012-08-30 08:08:08Z $
  25. */
  26. #include <linux/module.h>
  27. #include <linux/netdevice.h>
  28. #include <wl_android.h>
  29. #include <wldev_common.h>
  30. #include <wlioctl.h>
  31. #include <bcmutils.h>
  32. #include <linux_osl.h>
  33. #include <dhd_dbg.h>
  34. #include <dngl_stats.h>
  35. #include <dhd.h>
  36. #include <bcmsdbus.h>
  37. #ifdef WL_CFG80211
  38. #include <wl_cfg80211.h>
  39. #endif
  40. #if defined(CONFIG_WIFI_CONTROL_FUNC)
  41. #include <linux/platform_device.h>
  42. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
  43. #include <linux/wlan_plat.h>
  44. #else
  45. #include <linux/wifi_tiwlan.h>
  46. #endif
  47. #endif /* CONFIG_WIFI_CONTROL_FUNC */
  48. /*
  49. * Android private command strings, PLEASE define new private commands here
  50. * so they can be updated easily in the future (if needed)
  51. */
  52. #define CMD_START "START"
  53. #define CMD_STOP "STOP"
  54. #define CMD_SCAN_ACTIVE "SCAN-ACTIVE"
  55. #define CMD_SCAN_PASSIVE "SCAN-PASSIVE"
  56. #define CMD_RSSI "RSSI"
  57. #define CMD_LINKSPEED "LINKSPEED"
  58. #define CMD_RXFILTER_START "RXFILTER-START"
  59. #define CMD_RXFILTER_STOP "RXFILTER-STOP"
  60. #define CMD_RXFILTER_ADD "RXFILTER-ADD"
  61. #define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE"
  62. #define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START"
  63. #define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP"
  64. #define CMD_BTCOEXMODE "BTCOEXMODE"
  65. #define CMD_SETSUSPENDOPT "SETSUSPENDOPT"
  66. #define CMD_SETSUSPENDMODE "SETSUSPENDMODE"
  67. #define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR"
  68. #define CMD_SETFWPATH "SETFWPATH"
  69. #define CMD_SETBAND "SETBAND"
  70. #define CMD_GETBAND "GETBAND"
  71. #define CMD_COUNTRY "COUNTRY"
  72. #define CMD_P2P_SET_NOA "P2P_SET_NOA"
  73. #if !defined WL_ENABLE_P2P_IF
  74. #define CMD_P2P_GET_NOA "P2P_GET_NOA"
  75. #endif
  76. #define CMD_P2P_SET_PS "P2P_SET_PS"
  77. #define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE"
  78. #if defined(SUPPORT_HIDDEN_AP)
  79. /* Hostapd private command */
  80. #define CMD_SET_HAPD_MAX_NUM_STA "HAPD_MAX_NUM_STA"
  81. #define CMD_SET_HAPD_SSID "HAPD_SSID"
  82. #define CMD_SET_HAPD_HIDE_SSID "HAPD_HIDE_SSID"
  83. #endif
  84. #if defined(SUPPORT_AUTO_CHANNEL)
  85. #define CMD_SET_HAPD_AUTO_CHANNEL "HAPD_AUTO_CHANNEL"
  86. #endif
  87. #if defined(SUPPORT_SOFTAP_SINGL_DISASSOC)
  88. #define CMD_HAPD_STA_DISASSOC "HAPD_STA_DISASSOC"
  89. #endif
  90. /* CCX Private Commands */
  91. #ifdef BCMCCX
  92. #define CMD_GETCCKM_RN "get cckm_rn"
  93. #define CMD_SETCCKM_KRK "set cckm_krk"
  94. #define CMD_GET_ASSOC_RES_IES "get assoc_res_ies"
  95. #endif
  96. #ifdef PNO_SUPPORT
  97. #define CMD_PNOSSIDCLR_SET "PNOSSIDCLR"
  98. #define CMD_PNOSETUP_SET "PNOSETUP "
  99. #define CMD_PNOENABLE_SET "PNOFORCE"
  100. #define CMD_PNODEBUG_SET "PNODEBUG"
  101. #define PNO_TLV_PREFIX 'S'
  102. #define PNO_TLV_VERSION '1'
  103. #define PNO_TLV_SUBVERSION '2'
  104. #define PNO_TLV_RESERVED '0'
  105. #define PNO_TLV_TYPE_SSID_IE 'S'
  106. #define PNO_TLV_TYPE_TIME 'T'
  107. #define PNO_TLV_FREQ_REPEAT 'R'
  108. #define PNO_TLV_FREQ_EXPO_MAX 'M'
  109. typedef struct cmd_tlv {
  110. char prefix;
  111. char version;
  112. char subver;
  113. char reserved;
  114. } cmd_tlv_t;
  115. #endif /* PNO_SUPPORT */
  116. #ifdef OKC_SUPPORT
  117. #define CMD_OKC_SET_PMK "SET_PMK"
  118. #define CMD_OKC_ENABLE "OKC_ENABLE"
  119. #endif
  120. #ifdef ROAM_API
  121. #define CMD_ROAMTRIGGER_SET "SETROAMTRIGGER"
  122. #define CMD_ROAMTRIGGER_GET "GETROAMTRIGGER"
  123. #define CMD_ROAMDELTA_SET "SETROAMDELTA"
  124. #define CMD_ROAMDELTA_GET "GETROAMDELTA"
  125. #define CMD_ROAMSCANPERIOD_SET "SETROAMSCANPERIOD"
  126. #define CMD_ROAMSCANPERIOD_GET "GETROAMSCANPERIOD"
  127. #define CMD_FULLROAMSCANPERIOD_SET "SETFULLROAMSCANPERIOD"
  128. #define CMD_FULLROAMSCANPERIOD_GET "GETFULLROAMSCANPERIOD"
  129. #define CMD_COUNTRYREV_SET "SETCOUNTRYREV"
  130. #define CMD_COUNTRYREV_GET "GETCOUNTRYREV"
  131. #endif /* ROAM_API */
  132. #if defined(CUSTOMER_HW4) && defined(WES_SUPPORT)
  133. #define CMD_GETROAMSCANCONTROL "GETROAMSCANCONTROL"
  134. #define CMD_SETROAMSCANCONTROL "SETROAMSCANCONTROL"
  135. #define CMD_GETROAMSCANCHANNELS "GETROAMSCANCHANNELS"
  136. #define CMD_SETROAMSCANCHANNELS "SETROAMSCANCHANNELS"
  137. #define CMD_GETSCANCHANNELTIME "GETSCANCHANNELTIME"
  138. #define CMD_SETSCANCHANNELTIME "SETSCANCHANNELTIME"
  139. #define CMD_GETSCANHOMETIME "GETSCANHOMETIME"
  140. #define CMD_SETSCANHOMETIME "SETSCANHOMETIME"
  141. #define CMD_GETSCANHOMEAWAYTIME "GETSCANHOMEAWAYTIME"
  142. #define CMD_SETSCANHOMEAWAYTIME "SETSCANHOMEAWAYTIME"
  143. #define CMD_GETSCANNPROBES "GETSCANNPROBES"
  144. #define CMD_SETSCANNPROBES "SETSCANNPROBES"
  145. #define CMD_SENDACTIONFRAME "SENDACTIONFRAME"
  146. #define CMD_REASSOC "REASSOC"
  147. #define CMD_GETWESMODE "GETWESMODE"
  148. #define CMD_SETWESMODE "SETWESMODE"
  149. #define CMD_GETOKCMODE "GETOKCMODE"
  150. #define CMD_SETOKCMODE "SETOKCMODE"
  151. #define ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS 100
  152. typedef struct android_wifi_reassoc_params {
  153. unsigned char bssid[18];
  154. int channel;
  155. } android_wifi_reassoc_params_t;
  156. #define ANDROID_WIFI_REASSOC_PARAMS_SIZE sizeof(struct android_wifi_reassoc_params)
  157. #define ANDROID_WIFI_ACTION_FRAME_SIZE 1040
  158. typedef struct android_wifi_af_params {
  159. unsigned char bssid[18];
  160. int channel;
  161. int dwell_time;
  162. int len;
  163. unsigned char data[ANDROID_WIFI_ACTION_FRAME_SIZE];
  164. } android_wifi_af_params_t;
  165. #define ANDROID_WIFI_AF_PARAMS_SIZE sizeof(struct android_wifi_af_params)
  166. #endif /* WES_SUPPORT */
  167. #ifdef SUPPORT_AMPDU_MPDU_CMD
  168. #define CMD_AMPDU_MPDU "AMPDU_MPDU"
  169. #endif /* SUPPORT_AMPDU_MPDU_CMD */
  170. #ifdef CUSTOMER_HW4
  171. #define CMD_CHANGE_RL "CHANGE_RL"
  172. #define CMD_RESTORE_RL "RESTORE_RL"
  173. #endif /* CUSTOMER_HW4 */
  174. typedef struct android_wifi_priv_cmd {
  175. char *buf;
  176. int used_len;
  177. int total_len;
  178. } android_wifi_priv_cmd;
  179. /**
  180. * Extern function declarations (TODO: move them to dhd_linux.h)
  181. */
  182. void dhd_customer_gpio_wlan_ctrl(int onoff);
  183. int dhd_dev_reset(struct net_device *dev, uint8 flag);
  184. int dhd_dev_init_ioctl(struct net_device *dev);
  185. #ifdef WL_CFG80211
  186. int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr);
  187. int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command);
  188. #if defined(CUSTOMER_HW4) && defined(WES_SUPPORT)
  189. int wl_cfg80211_set_wes_mode(int mode);
  190. int wl_cfg80211_get_wes_mode(void);
  191. int wl_cfg80211_get_ioctl_version(void);
  192. #endif
  193. #else
  194. int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
  195. { return 0; }
  196. int wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len)
  197. { return 0; }
  198. int wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len)
  199. { return 0; }
  200. int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len)
  201. { return 0; }
  202. #endif /* WL_CFG80211 */
  203. extern int dhd_os_check_if_up(void *dhdp);
  204. extern void *bcmsdh_get_drvdata(void);
  205. #if defined(CUSTOMER_HW4) && defined(WES_SUPPORT)
  206. /* wl_roam.c */
  207. extern int get_roamscan_mode(struct net_device *dev, int *mode);
  208. extern int set_roamscan_mode(struct net_device *dev, int mode);
  209. extern int get_roamscan_channel_list(struct net_device *dev, unsigned char channels[]);
  210. extern int set_roamscan_channel_list(struct net_device *dev, unsigned char n,
  211. unsigned char channels[], int ioctl_ver);
  212. #endif
  213. extern bool ap_fw_loaded;
  214. #if defined(CUSTOMER_HW2) || defined(CUSTOMER_HW4)
  215. extern char iface_name[IFNAMSIZ];
  216. #endif
  217. #ifndef WIFI_TURNOFF_DELAY
  218. #define WIFI_TURNOFF_DELAY 0
  219. #endif
  220. /**
  221. * Local (static) functions and variables
  222. */
  223. /* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first
  224. * time (only) in dhd_open, subsequential wifi on will be handled by
  225. * wl_android_wifi_on
  226. */
  227. static int g_wifi_on = TRUE;
  228. /**
  229. * Local (static) function definitions
  230. */
  231. static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len)
  232. {
  233. int link_speed;
  234. int bytes_written;
  235. int error;
  236. error = wldev_get_link_speed(net, &link_speed);
  237. if (error)
  238. return -1;
  239. /* Convert Kbps to Android Mbps */
  240. link_speed = link_speed / 1000;
  241. bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed);
  242. DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command));
  243. return bytes_written;
  244. }
  245. static int wl_android_get_rssi(struct net_device *net, char *command, int total_len)
  246. {
  247. wlc_ssid_t ssid = {0};
  248. int rssi;
  249. int bytes_written = 0;
  250. int error;
  251. error = wldev_get_rssi(net, &rssi);
  252. if (error)
  253. return -1;
  254. error = wldev_get_ssid(net, &ssid);
  255. if (error)
  256. return -1;
  257. if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) {
  258. DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__));
  259. } else {
  260. memcpy(command, ssid.SSID, ssid.SSID_len);
  261. bytes_written = ssid.SSID_len;
  262. }
  263. bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi);
  264. DHD_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written));
  265. return bytes_written;
  266. }
  267. static int wl_android_set_suspendopt(struct net_device *dev, char *command, int total_len)
  268. {
  269. int suspend_flag;
  270. int ret_now;
  271. int ret = 0;
  272. #ifdef CUSTOMER_HW4
  273. if (!dhd_download_fw_on_driverload) {
  274. #endif /* CUSTOMER_HW4 */
  275. suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0';
  276. if (suspend_flag != 0)
  277. suspend_flag = 1;
  278. ret_now = net_os_set_suspend_disable(dev, suspend_flag);
  279. if (ret_now != suspend_flag) {
  280. if (!(ret = net_os_set_suspend(dev, ret_now, 1)))
  281. DHD_INFO(("%s: Suspend Flag %d -> %d\n",
  282. __FUNCTION__, ret_now, suspend_flag));
  283. else
  284. DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret));
  285. }
  286. #ifdef CUSTOMER_HW4
  287. }
  288. #endif /* CUSTOMER_HW4 */
  289. return ret;
  290. }
  291. static int wl_android_set_suspendmode(struct net_device *dev, char *command, int total_len)
  292. {
  293. int ret = 0;
  294. #if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(DHD_USE_EARLYSUSPEND)
  295. int suspend_flag;
  296. suspend_flag = *(command + strlen(CMD_SETSUSPENDMODE) + 1) - '0';
  297. if (suspend_flag != 0)
  298. suspend_flag = 1;
  299. if (!(ret = net_os_set_suspend(dev, suspend_flag, 0)))
  300. DHD_INFO(("%s: Suspend Mode %d\n", __FUNCTION__, suspend_flag));
  301. else
  302. DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret));
  303. #endif
  304. return ret;
  305. }
  306. static int wl_android_get_band(struct net_device *dev, char *command, int total_len)
  307. {
  308. uint band;
  309. int bytes_written;
  310. int error;
  311. error = wldev_get_band(dev, &band);
  312. if (error)
  313. return -1;
  314. bytes_written = snprintf(command, total_len, "Band %d", band);
  315. return bytes_written;
  316. }
  317. #ifdef ROAM_API
  318. int wl_android_set_roam_trigger(
  319. struct net_device *dev, char* command, int total_len)
  320. {
  321. int roam_trigger[2];
  322. sscanf(command, "%*s %10d", &roam_trigger[0]);
  323. roam_trigger[1] = WLC_BAND_ALL;
  324. return wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
  325. sizeof(roam_trigger), 1);
  326. }
  327. static int wl_android_get_roam_trigger(
  328. struct net_device *dev, char *command, int total_len)
  329. {
  330. int bytes_written;
  331. int roam_trigger[2] = {0, 0};
  332. roam_trigger[1] = WLC_BAND_2G;
  333. if (wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger,
  334. sizeof(roam_trigger), 0)) {
  335. roam_trigger[1] = WLC_BAND_5G;
  336. if (wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger,
  337. sizeof(roam_trigger), 0))
  338. return -1;
  339. }
  340. bytes_written = snprintf(command, total_len, "%s %d",
  341. CMD_ROAMTRIGGER_GET, roam_trigger[0]);
  342. return bytes_written;
  343. }
  344. int wl_android_set_roam_delta(
  345. struct net_device *dev, char* command, int total_len)
  346. {
  347. int roam_delta[2];
  348. sscanf(command, "%*s %10d", &roam_delta[0]);
  349. roam_delta[1] = WLC_BAND_ALL;
  350. return wldev_ioctl(dev, WLC_SET_ROAM_DELTA, roam_delta,
  351. sizeof(roam_delta), 1);
  352. }
  353. static int wl_android_get_roam_delta(
  354. struct net_device *dev, char *command, int total_len)
  355. {
  356. int bytes_written;
  357. int roam_delta[2] = {0, 0};
  358. roam_delta[1] = WLC_BAND_2G;
  359. if (wldev_ioctl(dev, WLC_GET_ROAM_DELTA, roam_delta,
  360. sizeof(roam_delta), 0)) {
  361. roam_delta[1] = WLC_BAND_5G;
  362. if (wldev_ioctl(dev, WLC_GET_ROAM_DELTA, roam_delta,
  363. sizeof(roam_delta), 0))
  364. return -1;
  365. }
  366. bytes_written = snprintf(command, total_len, "%s %d",
  367. CMD_ROAMDELTA_GET, roam_delta[0]);
  368. return bytes_written;
  369. }
  370. int wl_android_set_roam_scan_period(
  371. struct net_device *dev, char* command, int total_len)
  372. {
  373. int roam_scan_period = 0;
  374. sscanf(command, "%*s %10d", &roam_scan_period);
  375. return wldev_ioctl(dev, WLC_SET_ROAM_SCAN_PERIOD, &roam_scan_period,
  376. sizeof(roam_scan_period), 1);
  377. }
  378. static int wl_android_get_roam_scan_period(
  379. struct net_device *dev, char *command, int total_len)
  380. {
  381. int bytes_written;
  382. int roam_scan_period = 0;
  383. if (wldev_ioctl(dev, WLC_GET_ROAM_SCAN_PERIOD, &roam_scan_period,
  384. sizeof(roam_scan_period), 0))
  385. return -1;
  386. bytes_written = snprintf(command, total_len, "%s %d",
  387. CMD_ROAMSCANPERIOD_GET, roam_scan_period);
  388. return bytes_written;
  389. }
  390. int wl_android_set_full_roam_scan_period(
  391. struct net_device *dev, char* command, int total_len)
  392. {
  393. int error = 0;
  394. int full_roam_scan_period = 0;
  395. char smbuf[WLC_IOCTL_SMLEN];
  396. sscanf(command+sizeof("SETFULLROAMSCANPERIOD"), "%d", &full_roam_scan_period);
  397. WL_TRACE(("%s: fullroamperiod = %d\n", __func__, full_roam_scan_period));
  398. error = wldev_iovar_setbuf(dev, "fullroamperiod", &full_roam_scan_period,
  399. sizeof(full_roam_scan_period), smbuf, sizeof(smbuf), NULL);
  400. if (error) {
  401. DHD_ERROR(("Failed to set full roam scan period, error = %d\n", error));
  402. }
  403. return error;
  404. }
  405. static int wl_android_get_full_roam_scan_period(
  406. struct net_device *dev, char *command, int total_len)
  407. {
  408. int error;
  409. int bytes_written;
  410. int full_roam_scan_period = 0;
  411. error = wldev_iovar_getint(dev, "fullroamperiod", &full_roam_scan_period);
  412. if (error) {
  413. DHD_ERROR(("%s: get full roam scan period failed code %d\n",
  414. __func__, error));
  415. return -1;
  416. } else {
  417. DHD_INFO(("%s: get full roam scan period %d\n", __func__, full_roam_scan_period));
  418. }
  419. bytes_written = snprintf(command, total_len, "%s %d",
  420. CMD_FULLROAMSCANPERIOD_GET, full_roam_scan_period);
  421. return bytes_written;
  422. }
  423. int wl_android_set_country_rev(
  424. struct net_device *dev, char* command, int total_len)
  425. {
  426. int error = 0;
  427. wl_country_t cspec = {{0}, 0, {0} };
  428. char country_code[WLC_CNTRY_BUF_SZ];
  429. char smbuf[WLC_IOCTL_SMLEN];
  430. int rev = 0;
  431. memset(country_code, 0, sizeof(country_code));
  432. sscanf(command+sizeof("SETCOUNTRYREV"), "%10s %10d", country_code, &rev);
  433. WL_TRACE(("%s: country_code = %s, rev = %d\n", __FUNCTION__,
  434. country_code, rev));
  435. memcpy(cspec.country_abbrev, country_code, sizeof(country_code));
  436. memcpy(cspec.ccode, country_code, sizeof(country_code));
  437. cspec.rev = rev;
  438. error = wldev_iovar_setbuf(dev, "country", (char *)&cspec,
  439. sizeof(cspec), smbuf, sizeof(smbuf), NULL);
  440. if (error) {
  441. DHD_ERROR(("%s: set country '%s/%d' failed code %d\n",
  442. __FUNCTION__, cspec.ccode, cspec.rev, error));
  443. } else {
  444. dhd_bus_country_set(dev, &cspec);
  445. DHD_INFO(("%s: set country '%s/%d'\n",
  446. __FUNCTION__, cspec.ccode, cspec.rev));
  447. }
  448. return error;
  449. }
  450. static int wl_android_get_country_rev(
  451. struct net_device *dev, char *command, int total_len)
  452. {
  453. int error;
  454. int bytes_written;
  455. char smbuf[WLC_IOCTL_SMLEN];
  456. wl_country_t cspec;
  457. error = wldev_iovar_getbuf(dev, "country", NULL, 0, smbuf,
  458. sizeof(smbuf), NULL);
  459. if (error) {
  460. DHD_ERROR(("%s: get country failed code %d\n",
  461. __FUNCTION__, error));
  462. return -1;
  463. } else {
  464. memcpy(&cspec, smbuf, sizeof(cspec));
  465. DHD_INFO(("%s: get country '%c%c %d'\n",
  466. __FUNCTION__, cspec.ccode[0], cspec.ccode[1], cspec.rev));
  467. }
  468. bytes_written = snprintf(command, total_len, "%s %c%c %d",
  469. CMD_COUNTRYREV_GET, cspec.ccode[0], cspec.ccode[1], cspec.rev);
  470. return bytes_written;
  471. }
  472. #endif /* ROAM_API */
  473. #if defined(CUSTOMER_HW4) && defined(WES_SUPPORT)
  474. int wl_android_get_roam_scan_control(struct net_device *dev, char *command, int total_len)
  475. {
  476. int error = 0;
  477. int bytes_written = 0;
  478. int mode = 0;
  479. error = get_roamscan_mode(dev, &mode);
  480. if (error) {
  481. DHD_ERROR(("%s: Failed to get Scan Control, error = %d\n", __FUNCTION__, error));
  482. return -1;
  483. }
  484. bytes_written = snprintf(command, total_len, "%s %d", CMD_GETROAMSCANCONTROL, mode);
  485. return bytes_written;
  486. }
  487. int wl_android_set_roam_scan_control(struct net_device *dev, char *command, int total_len)
  488. {
  489. int error = 0;
  490. int mode = 0;
  491. if (sscanf(command, "%*s %d", &mode) != 1) {
  492. DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
  493. return -1;
  494. }
  495. error = set_roamscan_mode(dev, mode);
  496. if (error) {
  497. DHD_ERROR(("%s: Failed to set Scan Control %d, error = %d\n",
  498. __FUNCTION__, mode, error));
  499. return -1;
  500. }
  501. return 0;
  502. }
  503. int wl_android_get_roam_scan_channels(struct net_device *dev, char *command, int total_len)
  504. {
  505. int bytes_written = 0;
  506. unsigned char channels[ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS] = {0};
  507. int channel_cnt = 0;
  508. char channel_info[10 + (ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS * 3)] = {0};
  509. int channel_info_len = 0;
  510. int i = 0;
  511. channel_cnt = get_roamscan_channel_list(dev, channels);
  512. channel_info_len += sprintf(&channel_info[channel_info_len], "%d ", channel_cnt);
  513. for (i = 0; i < channel_cnt; i++) {
  514. channel_info_len += sprintf(&channel_info[channel_info_len], "%d ", channels[i]);
  515. if (channel_info_len > (sizeof(channel_info) - 10))
  516. break;
  517. }
  518. channel_info_len += sprintf(&channel_info[channel_info_len], "%s", "\0");
  519. bytes_written = snprintf(command, total_len, "%s %s",
  520. CMD_GETROAMSCANCHANNELS, channel_info);
  521. return bytes_written;
  522. }
  523. int wl_android_set_roam_scan_channels(struct net_device *dev, char *command, int total_len)
  524. {
  525. int error = 0;
  526. unsigned char *p = (unsigned char *)(command + strlen(CMD_SETROAMSCANCHANNELS) + 1);
  527. int ioctl_version = wl_cfg80211_get_ioctl_version();
  528. error = set_roamscan_channel_list(dev, p[0], &p[1], ioctl_version);
  529. if (error) {
  530. DHD_ERROR(("%s: Failed to set Scan Channels %d, error = %d\n",
  531. __FUNCTION__, p[0], error));
  532. return -1;
  533. }
  534. return 0;
  535. }
  536. int wl_android_get_scan_channel_time(struct net_device *dev, char *command, int total_len)
  537. {
  538. int error = 0;
  539. int bytes_written = 0;
  540. int time = 0;
  541. error = wldev_ioctl(dev, WLC_GET_SCAN_CHANNEL_TIME, &time, sizeof(time), 0);
  542. if (error) {
  543. DHD_ERROR(("%s: Failed to get Scan Channel Time, error = %d\n",
  544. __FUNCTION__, error));
  545. return -1;
  546. }
  547. bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANCHANNELTIME, time);
  548. return bytes_written;
  549. }
  550. int wl_android_set_scan_channel_time(struct net_device *dev, char *command, int total_len)
  551. {
  552. int error = 0;
  553. int time = 0;
  554. if (sscanf(command, "%*s %d", &time) != 1) {
  555. DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
  556. return -1;
  557. }
  558. error = wldev_ioctl(dev, WLC_SET_SCAN_CHANNEL_TIME, &time, sizeof(time), 1);
  559. if (error) {
  560. DHD_ERROR(("%s: Failed to set Scan Channel Time %d, error = %d\n",
  561. __FUNCTION__, time, error));
  562. return -1;
  563. }
  564. return 0;
  565. }
  566. int wl_android_get_scan_home_time(struct net_device *dev, char *command, int total_len)
  567. {
  568. int error = 0;
  569. int bytes_written = 0;
  570. int time = 0;
  571. error = wldev_ioctl(dev, WLC_GET_SCAN_HOME_TIME, &time, sizeof(time), 0);
  572. if (error) {
  573. DHD_ERROR(("Failed to get Scan Home Time, error = %d\n", error));
  574. return -1;
  575. }
  576. bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANHOMETIME, time);
  577. return bytes_written;
  578. }
  579. int wl_android_set_scan_home_time(struct net_device *dev, char *command, int total_len)
  580. {
  581. int error = 0;
  582. int time = 0;
  583. if (sscanf(command, "%*s %d", &time) != 1) {
  584. DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
  585. return -1;
  586. }
  587. error = wldev_ioctl(dev, WLC_SET_SCAN_HOME_TIME, &time, sizeof(time), 1);
  588. if (error) {
  589. DHD_ERROR(("%s: Failed to set Scan Home Time %d, error = %d\n",
  590. __FUNCTION__, time, error));
  591. return -1;
  592. }
  593. return 0;
  594. }
  595. int wl_android_get_scan_home_away_time(struct net_device *dev, char *command, int total_len)
  596. {
  597. int error = 0;
  598. int bytes_written = 0;
  599. int time = 0;
  600. error = wldev_iovar_getint(dev, "scan_home_away_time", &time);
  601. if (error) {
  602. DHD_ERROR(("%s: Failed to get Scan Home Away Time, error = %d\n",
  603. __FUNCTION__, error));
  604. return -1;
  605. }
  606. bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANHOMEAWAYTIME, time);
  607. return bytes_written;
  608. }
  609. int wl_android_set_scan_home_away_time(struct net_device *dev, char *command, int total_len)
  610. {
  611. int error = 0;
  612. int time = 0;
  613. if (sscanf(command, "%*s %d", &time) != 1) {
  614. DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
  615. return -1;
  616. }
  617. error = wldev_iovar_setint(dev, "scan_home_away_time", time);
  618. if (error) {
  619. DHD_ERROR(("%s: Failed to set Scan Home Away Time %d, error = %d\n",
  620. __FUNCTION__, time, error));
  621. return -1;
  622. }
  623. return 0;
  624. }
  625. int wl_android_get_scan_nprobes(struct net_device *dev, char *command, int total_len)
  626. {
  627. int error = 0;
  628. int bytes_written = 0;
  629. int num = 0;
  630. error = wldev_ioctl(dev, WLC_GET_SCAN_NPROBES, &num, sizeof(num), 0);
  631. if (error) {
  632. DHD_ERROR(("%s: Failed to get Scan NProbes, error = %d\n", __FUNCTION__, error));
  633. return -1;
  634. }
  635. bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANNPROBES, num);
  636. return bytes_written;
  637. }
  638. int wl_android_set_scan_nprobes(struct net_device *dev, char *command, int total_len)
  639. {
  640. int error = 0;
  641. int num = 0;
  642. if (sscanf(command, "%*s %d", &num) != 1) {
  643. DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
  644. return -1;
  645. }
  646. error = wldev_ioctl(dev, WLC_SET_SCAN_NPROBES, &num, sizeof(num), 1);
  647. if (error) {
  648. DHD_ERROR(("%s: Failed to set Scan NProbes %d, error = %d\n",
  649. __FUNCTION__, num, error));
  650. return -1;
  651. }
  652. return 0;
  653. }
  654. int wl_android_send_action_frame(struct net_device *dev, char *command, int total_len)
  655. {
  656. int error = -1;
  657. android_wifi_af_params_t *params = NULL;
  658. wl_action_frame_t *action_frame = NULL;
  659. wl_af_params_t *af_params = NULL;
  660. char *smbuf = NULL;
  661. struct ether_addr tmp_bssid;
  662. int tmp_channel = 0;
  663. params = (android_wifi_af_params_t *)(command + strlen(CMD_SENDACTIONFRAME) + 1);
  664. if (params == NULL) {
  665. DHD_ERROR(("%s: Invalid params \n", __FUNCTION__));
  666. goto send_action_frame_out;
  667. }
  668. smbuf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
  669. if (smbuf == NULL) {
  670. DHD_ERROR(("%s: failed to allocated memory %d bytes\n",
  671. __FUNCTION__, WLC_IOCTL_MAXLEN));
  672. goto send_action_frame_out;
  673. }
  674. af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
  675. if (af_params == NULL)
  676. {
  677. DHD_ERROR(("%s: unable to allocate frame\n", __FUNCTION__));
  678. goto send_action_frame_out;
  679. }
  680. memset(&tmp_bssid, 0, ETHER_ADDR_LEN);
  681. if (bcm_ether_atoe((const char *)params->bssid, (struct ether_addr *)&tmp_bssid) == 0) {
  682. memset(&tmp_bssid, 0, ETHER_ADDR_LEN);
  683. error = wldev_ioctl(dev, WLC_GET_BSSID, &tmp_bssid, ETHER_ADDR_LEN, false);
  684. if (error) {
  685. memset(&tmp_bssid, 0, ETHER_ADDR_LEN);
  686. DHD_ERROR(("%s: failed to get bssid, error=%d\n", __FUNCTION__, error));
  687. goto send_action_frame_out;
  688. }
  689. }
  690. if (params->channel < 0) {
  691. struct channel_info ci;
  692. error = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci), false);
  693. if (error) {
  694. DHD_ERROR(("%s: failed to get channel, error=%d\n", __FUNCTION__, error));
  695. goto send_action_frame_out;
  696. }
  697. tmp_channel = ci.hw_channel;
  698. }
  699. else {
  700. tmp_channel = params->channel;
  701. }
  702. af_params->channel = tmp_channel;
  703. af_params->dwell_time = params->dwell_time;
  704. memcpy(&af_params->BSSID, &tmp_bssid, ETHER_ADDR_LEN);
  705. action_frame = &af_params->action_frame;
  706. action_frame->packetId = 0;
  707. memcpy(&action_frame->da, &tmp_bssid, ETHER_ADDR_LEN);
  708. action_frame->len = params->len;
  709. memcpy(action_frame->data, params->data, action_frame->len);
  710. error = wldev_iovar_setbuf(dev, "actframe", af_params,
  711. sizeof(wl_af_params_t), smbuf, WLC_IOCTL_MAXLEN, NULL);
  712. if (error) {
  713. DHD_ERROR(("%s: failed to set action frame, error=%d\n", __FUNCTION__, error));
  714. }
  715. send_action_frame_out:
  716. if (af_params)
  717. kfree(af_params);
  718. if (smbuf)
  719. kfree(smbuf);
  720. if (error)
  721. return -1;
  722. else
  723. return 0;
  724. }
  725. int wl_android_reassoc(struct net_device *dev, char *command, int total_len)
  726. {
  727. int error = 0;
  728. android_wifi_reassoc_params_t *params = NULL;
  729. uint band;
  730. chanspec_t channel;
  731. u32 params_size;
  732. wl_reassoc_params_t reassoc_params;
  733. params = (android_wifi_reassoc_params_t *)(command + strlen(CMD_REASSOC) + 1);
  734. if (params == NULL) {
  735. DHD_ERROR(("%s: Invalid params \n", __FUNCTION__));
  736. return -1;
  737. }
  738. memset(&reassoc_params, 0, WL_REASSOC_PARAMS_FIXED_SIZE);
  739. if (bcm_ether_atoe((const char *)params->bssid,
  740. (struct ether_addr *)&reassoc_params.bssid) == 0) {
  741. DHD_ERROR(("%s: Invalid bssid \n", __FUNCTION__));
  742. return -1;
  743. }
  744. if (params->channel < 0) {
  745. DHD_ERROR(("%s: Invalid Channel \n", __FUNCTION__));
  746. return -1;
  747. }
  748. reassoc_params.chanspec_num = 1;
  749. channel = params->channel;
  750. #ifdef D11AC_IOTYPES
  751. if (wl_cfg80211_get_ioctl_version() == 1) {
  752. band = ((channel <= CH_MAX_2G_CHANNEL) ?
  753. WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G);
  754. reassoc_params.chanspec_list[0] = channel |
  755. band | WL_LCHANSPEC_BW_20 | WL_LCHANSPEC_CTL_SB_NONE;
  756. }
  757. else {
  758. band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
  759. reassoc_params.chanspec_list[0] = channel | band | WL_LCHANSPEC_BW_20;
  760. }
  761. #else
  762. band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
  763. reassoc_params.chanspec_list[0] = channel |
  764. band | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
  765. #endif /* D11AC_IOTYPES */
  766. params_size = WL_REASSOC_PARAMS_FIXED_SIZE + sizeof(chanspec_t);
  767. error = wldev_ioctl(dev, WLC_REASSOC, &reassoc_params, params_size, true);
  768. if (error) {
  769. DHD_ERROR(("%s: failed to reassoc, error=%d\n", __FUNCTION__, error));
  770. }
  771. if (error)
  772. return -1;
  773. else
  774. return 0;
  775. }
  776. int wl_android_get_wes_mode(struct net_device *dev, char *command, int total_len)
  777. {
  778. int bytes_written = 0;
  779. int mode = 0;
  780. mode = wl_cfg80211_get_wes_mode();
  781. bytes_written = snprintf(command, total_len, "%s %d", CMD_GETWESMODE, mode);
  782. return bytes_written;
  783. }
  784. int wl_android_set_wes_mode(struct net_device *dev, char *command, int total_len)
  785. {
  786. int error = 0;
  787. int mode = 0;
  788. if (sscanf(command, "%*s %d", &mode) != 1) {
  789. DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
  790. return -1;
  791. }
  792. error = wl_cfg80211_set_wes_mode(mode);
  793. if (error) {
  794. DHD_ERROR(("%s: Failed to set WES Mode %d, error = %d\n",
  795. __FUNCTION__, mode, error));
  796. return -1;
  797. }
  798. return 0;
  799. }
  800. int wl_android_get_okc_mode(struct net_device *dev, char *command, int total_len)
  801. {
  802. int error = 0;
  803. int bytes_written = 0;
  804. int mode = 0;
  805. error = wldev_iovar_getint(dev, "okc_enable", &mode);
  806. if (error) {
  807. DHD_ERROR(("%s: Failed to get OKC Mode, error = %d\n", __FUNCTION__, error));
  808. return -1;
  809. }
  810. bytes_written = snprintf(command, total_len, "%s %d", CMD_GETOKCMODE, mode);
  811. return bytes_written;
  812. }
  813. int wl_android_set_okc_mode(struct net_device *dev, char *command, int total_len)
  814. {
  815. int error = 0;
  816. int mode = 0;
  817. if (sscanf(command, "%*s %d", &mode) != 1) {
  818. DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
  819. return -1;
  820. }
  821. error = wldev_iovar_setint(dev, "okc_enable", mode);
  822. if (error) {
  823. DHD_ERROR(("%s: Failed to set OKC Mode %d, error = %d\n",
  824. __FUNCTION__, mode, error));
  825. return -1;
  826. }
  827. return error;
  828. }
  829. #endif /* WES_SUPPORT */
  830. #ifdef PNO_SUPPORT
  831. static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len)
  832. {
  833. wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
  834. int res = -1;
  835. int nssid = 0;
  836. cmd_tlv_t *cmd_tlv_temp;
  837. char *str_ptr;
  838. int tlv_size_left;
  839. int pno_time = 0;
  840. int pno_repeat = 0;
  841. int pno_freq_expo_max = 0;
  842. #ifdef PNO_SET_DEBUG
  843. int i;
  844. char pno_in_example[] = {
  845. 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
  846. 'S', '1', '2', '0',
  847. 'S',
  848. 0x05,
  849. 'd', 'l', 'i', 'n', 'k',
  850. 'S',
  851. 0x04,
  852. 'G', 'O', 'O', 'G',
  853. 'T',
  854. '0', 'B',
  855. 'R',
  856. '2',
  857. 'M',
  858. '2',
  859. 0x00
  860. };
  861. #endif /* PNO_SET_DEBUG */
  862. DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
  863. if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) {
  864. DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len));
  865. goto exit_proc;
  866. }
  867. #ifdef PNO_SET_DEBUG
  868. memcpy(command, pno_in_example, sizeof(pno_in_example));
  869. for (i = 0; i < sizeof(pno_in_example); i++)
  870. printf("%02X ", command[i]);
  871. printf("\n");
  872. total_len = sizeof(pno_in_example);
  873. #endif
  874. str_ptr = command + strlen(CMD_PNOSETUP_SET);
  875. tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET);
  876. cmd_tlv_temp = (cmd_tlv_t *)str_ptr;
  877. memset(ssids_local, 0, sizeof(ssids_local));
  878. if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) &&
  879. (cmd_tlv_temp->version == PNO_TLV_VERSION) &&
  880. (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) {
  881. str_ptr += sizeof(cmd_tlv_t);
  882. tlv_size_left -= sizeof(cmd_tlv_t);
  883. if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local,
  884. MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) {
  885. DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid));
  886. goto exit_proc;
  887. } else {
  888. if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) {
  889. DHD_ERROR(("%s scan duration corrupted field size %d\n",
  890. __FUNCTION__, tlv_size_left));
  891. goto exit_proc;
  892. }
  893. str_ptr++;
  894. pno_time = simple_strtoul(str_ptr, &str_ptr, 16);
  895. DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time));
  896. if (str_ptr[0] != 0) {
  897. if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) {
  898. DHD_ERROR(("%s pno repeat : corrupted field\n",
  899. __FUNCTION__));
  900. goto exit_proc;
  901. }
  902. str_ptr++;
  903. pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16);
  904. DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat));
  905. if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) {
  906. DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n",
  907. __FUNCTION__));
  908. goto exit_proc;
  909. }
  910. str_ptr++;
  911. pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16);
  912. DHD_INFO(("%s: pno_freq_expo_max=%d\n",
  913. __FUNCTION__, pno_freq_expo_max));
  914. }
  915. }
  916. } else {
  917. DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__));
  918. goto exit_proc;
  919. }
  920. res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max);
  921. exit_proc:
  922. return res;
  923. }
  924. #endif /* PNO_SUPPORT */
  925. static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len)
  926. {
  927. int ret;
  928. int bytes_written = 0;
  929. ret = wl_cfg80211_get_p2p_dev_addr(ndev, (struct ether_addr*)command);
  930. if (ret)
  931. return 0;
  932. bytes_written = sizeof(struct ether_addr);
  933. return bytes_written;
  934. }
  935. #ifdef BCMCCX
  936. static int wl_android_get_cckm_rn(struct net_device *dev, char *command)
  937. {
  938. int error, rn;
  939. WL_TRACE(("%s:wl_android_get_cckm_rn\n", dev->name));
  940. error = wldev_iovar_getint(dev, "cckm_rn", &rn);
  941. if (unlikely(error)) {
  942. WL_ERR(("wl_android_get_cckm_rn error (%d)\n", error));
  943. return -1;
  944. }
  945. memcpy(command, &rn, sizeof(int));
  946. return sizeof(int);
  947. }
  948. static int wl_android_set_cckm_krk(struct net_device *dev, char *command)
  949. {
  950. int error;
  951. unsigned char key[16];
  952. static char iovar_buf[WLC_IOCTL_MEDLEN];
  953. WL_TRACE(("%s: wl_iw_set_cckm_krk\n", dev->name));
  954. memset(iovar_buf, 0, sizeof(iovar_buf));
  955. memcpy(key, command+strlen("set cckm_krk")+1, 16);
  956. error = wldev_iovar_setbuf(dev, "cckm_krk", key, sizeof(key),
  957. iovar_buf, WLC_IOCTL_MEDLEN, NULL);
  958. if (unlikely(error))
  959. {
  960. WL_ERR((" cckm_krk set error (%d)\n", error));
  961. return -1;
  962. }
  963. return 0;
  964. }
  965. static int wl_android_get_assoc_res_ies(struct net_device *dev, char *command)
  966. {
  967. int error;
  968. u8 buf[WL_ASSOC_INFO_MAX];
  969. wl_assoc_info_t assoc_info;
  970. u32 resp_ies_len = 0;
  971. int bytes_written = 0;
  972. WL_TRACE(("%s: wl_iw_get_assoc_res_ies\n", dev->name));
  973. error = wldev_iovar_getbuf(dev, "assoc_info", NULL, 0, buf, WL_ASSOC_INFO_MAX, NULL);
  974. if (unlikely(error)) {
  975. WL_ERR(("could not get assoc info (%d)\n", error));
  976. return -1;
  977. }
  978. memcpy(&assoc_info, buf, sizeof(wl_assoc_info_t));
  979. assoc_info.req_len = htod32(assoc_info.req_len);
  980. assoc_info.resp_len = htod32(assoc_info.resp_len);
  981. assoc_info.flags = htod32(assoc_info.flags);
  982. if (assoc_info.resp_len) {
  983. resp_ies_len = assoc_info.resp_len - sizeof(struct dot11_assoc_resp);
  984. }
  985. /* first 4 bytes are ie len */
  986. memcpy(command, &resp_ies_len, sizeof(u32));
  987. bytes_written = sizeof(u32);
  988. /* get the association resp IE's if there are any */
  989. if (resp_ies_len) {
  990. error = wldev_iovar_getbuf(dev, "assoc_resp_ies", NULL, 0,
  991. buf, WL_ASSOC_INFO_MAX, NULL);
  992. if (unlikely(error)) {
  993. WL_ERR(("could not get assoc resp_ies (%d)\n", error));
  994. return -1;
  995. }
  996. memcpy(command+sizeof(u32), buf, resp_ies_len);
  997. bytes_written += resp_ies_len;
  998. }
  999. return bytes_written;
  1000. }
  1001. #endif /* BCMCCX */
  1002. /**
  1003. * Global function definitions (declared in wl_android.h)
  1004. */
  1005. int wl_android_wifi_on(struct net_device *dev)
  1006. {
  1007. int ret = 0;
  1008. int retry = POWERUP_MAX_RETRY;
  1009. printk("%s in\n", __FUNCTION__);
  1010. if (!dev) {
  1011. DHD_ERROR(("%s: dev is null\n", __FUNCTION__));
  1012. return -EINVAL;
  1013. }
  1014. dhd_net_if_lock(dev);
  1015. if (!g_wifi_on) {
  1016. do {
  1017. dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
  1018. ret = sdioh_start(NULL, 0);
  1019. if (ret == 0)
  1020. break;
  1021. DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n",
  1022. retry+1));
  1023. dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
  1024. } while (retry-- >= 0);
  1025. if (ret != 0) {
  1026. DHD_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n"));
  1027. goto exit;
  1028. }
  1029. ret = dhd_dev_reset(dev, FALSE);
  1030. sdioh_start(NULL, 1);
  1031. if (!ret) {
  1032. if (dhd_dev_init_ioctl(dev) < 0)
  1033. ret = -EFAULT;
  1034. }
  1035. g_wifi_on = TRUE;
  1036. }
  1037. exit:
  1038. dhd_net_if_unlock(dev);
  1039. return ret;
  1040. }
  1041. int wl_android_wifi_off(struct net_device *dev)
  1042. {
  1043. int ret = 0;
  1044. printk("%s in\n", __FUNCTION__);
  1045. if (!dev) {
  1046. DHD_TRACE(("%s: dev is null\n", __FUNCTION__));
  1047. return -EINVAL;
  1048. }
  1049. dhd_net_if_lock(dev);
  1050. if (g_wifi_on) {
  1051. ret = dhd_dev_reset(dev, TRUE);
  1052. sdioh_stop(NULL);
  1053. dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
  1054. g_wifi_on = FALSE;
  1055. }
  1056. dhd_net_if_unlock(dev);
  1057. return ret;
  1058. }
  1059. static int wl_android_set_fwpath(struct net_device *net, char *command, int total_len)
  1060. {
  1061. if ((strlen(command) - strlen(CMD_SETFWPATH)) > MOD_PARAM_PATHLEN)
  1062. return -1;
  1063. bcm_strncpy_s(fw_path, sizeof(fw_path),
  1064. command + strlen(CMD_SETFWPATH) + 1, MOD_PARAM_PATHLEN - 1);
  1065. if (strstr(fw_path, "apsta") != NULL) {
  1066. DHD_INFO(("GOT APSTA FIRMWARE\n"));
  1067. ap_fw_loaded = TRUE;
  1068. } else {
  1069. DHD_INFO(("GOT STA FIRMWARE\n"));
  1070. ap_fw_loaded = FALSE;
  1071. }
  1072. return 0;
  1073. }
  1074. #if defined(SUPPORT_HIDDEN_AP)
  1075. static int
  1076. wl_android_set_max_num_sta(struct net_device *dev, const char* string_num)
  1077. {
  1078. int max_assoc;
  1079. max_assoc = bcm_atoi(string_num);
  1080. DHD_INFO(("%s : HAPD_MAX_NUM_STA = %d\n", __FUNCTION__, max_assoc));
  1081. wldev_iovar_setint(dev, "maxassoc", max_assoc);
  1082. return 1;
  1083. }
  1084. static int
  1085. wl_android_set_ssid(struct net_device *dev, const char* hapd_ssid)
  1086. {
  1087. wlc_ssid_t ssid;
  1088. s32 ret;
  1089. ssid.SSID_len = strlen(hapd_ssid);
  1090. bcm_strncpy_s(ssid.SSID, sizeof(ssid.SSID), hapd_ssid, ssid.SSID_len);
  1091. DHD_INFO(("%s: HAPD_SSID = %s\n", __FUNCTION__, ssid.SSID));
  1092. ret = wldev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(wlc_ssid_t), true);
  1093. if (ret < 0) {
  1094. DHD_ERROR(("%s : WLC_SET_SSID Error:%d\n", __FUNCTION__, ret));
  1095. }
  1096. return 1;
  1097. }
  1098. static int
  1099. wl_android_set_hide_ssid(struct net_device *dev, const char* string_num)
  1100. {
  1101. int hide_ssid;
  1102. int enable = 0;
  1103. hide_ssid = bcm_atoi(string_num);
  1104. DHD_INFO(("%s: HAPD_HIDE_SSID = %d\n", __FUNCTION__, hide_ssid));
  1105. if (hide_ssid)
  1106. enable = 1;
  1107. wldev_iovar_setint(dev, "closednet", enable);
  1108. return 1;
  1109. }
  1110. #endif /* SUPPORT_HIDDEN_AP */
  1111. #if defined(SUPPORT_AUTO_CHANNEL)
  1112. static int
  1113. wl_android_set_auto_channel(struct net_device *dev, const char* string_num,
  1114. char* command, int total_len)
  1115. {
  1116. int channel;
  1117. int chosen = 0;
  1118. int retry = 0;
  1119. int ret = 0;
  1120. /* Restrict channel to 1 - 7: 2GHz, 20MHz BW, No SB */
  1121. u32 req_buf[8] = {7, 0x2B01, 0x2B02, 0x2B03, 0x2B04, 0x2B05, 0x2B06,
  1122. 0x2B07};
  1123. /* Auto channel select */
  1124. wl_uint32_list_t request;
  1125. channel = bcm_atoi(string_num);
  1126. DHD_INFO(("%s : HAPD_AUTO_CHANNEL = %d\n", __FUNCTION__, channel));
  1127. if (channel == 20)
  1128. ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)&req_buf,
  1129. sizeof(req_buf), true);
  1130. else { /* channel == 0 */
  1131. request.count = htod32(0);
  1132. ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)&request,
  1133. sizeof(request), true);
  1134. }
  1135. if (ret < 0) {
  1136. DHD_ERROR(("%s: can't start auto channel scan, err = %d\n",
  1137. __FUNCTION__, ret));
  1138. channel = 0;
  1139. goto done;
  1140. }
  1141. /* Wait for auto channel selection, max 2500 ms */
  1142. bcm_mdelay(500);
  1143. retry = 10;
  1144. while (retry--) {
  1145. ret = wldev_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen),
  1146. false);
  1147. if (ret < 0 || dtoh32(chosen) == 0) {
  1148. DHD_INFO(("%s: %d tried, ret = %d, chosen = %d\n",
  1149. __FUNCTION__, (10 - retry), ret, chosen));
  1150. bcm_mdelay(200);
  1151. }
  1152. else {
  1153. channel = (u16)chosen & 0x00FF;
  1154. DHD_ERROR(("%s: selected channel = %d\n", __FUNCTION__, channel));
  1155. break;
  1156. }
  1157. }
  1158. if (retry == 0) {
  1159. DHD_ERROR(("%s: auto channel timed out, failed\n", __FUNCTION__));
  1160. channel = 0;
  1161. }
  1162. done:
  1163. snprintf(command, 4, "%d", channel);
  1164. DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command));
  1165. return 4;
  1166. }
  1167. #endif /* SUPPORT_AUTO_CHANNEL */
  1168. #if defined(SUPPORT_SOFTAP_SINGL_DISASSOC)
  1169. static int
  1170. wl_android_sta_diassoc(struct net_device *dev, const char* straddr)
  1171. {
  1172. scb_val_t scbval;
  1173. DHD_INFO(("%s: deauth STA %s\n", __FUNCTION__, straddr));
  1174. /* Unspecified reason */
  1175. scbval.val = htod32(1);
  1176. bcm_ether_atoe(straddr, &scbval.ea);
  1177. DHD_INFO(("%s: deauth STA: "MACDBG "\n", __FUNCTION__,
  1178. STR_TO_MACD(scbval.ea.octet)));
  1179. wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval,
  1180. sizeof(scb_val_t), true);
  1181. return 1;
  1182. }
  1183. #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
  1184. #ifdef OKC_SUPPORT
  1185. static int
  1186. wl_android_set_pmk(struct net_device *dev, char *command, int total_len)
  1187. {
  1188. uchar pmk[33];
  1189. int error = 0;
  1190. char smbuf[WLC_IOCTL_SMLEN];
  1191. #ifdef OKC_DEBUG
  1192. int i = 0;
  1193. #endif
  1194. bzero(pmk, sizeof(pmk));
  1195. memcpy((char *)pmk, command + strlen("SET_PMK "), 32);
  1196. error = wldev_iovar_setbuf(dev, "okc_info_pmk", pmk, 32, smbuf, sizeof(smbuf), NULL);
  1197. if (error) {
  1198. DHD_ERROR(("Failed to set PMK for OKC, error = %d\n", error));
  1199. }
  1200. #ifdef OKC_DEBUG
  1201. DHD_ERROR(("PMK is "));
  1202. for (i = 0; i < 32; i++)
  1203. DHD_ERROR(("%02X ", pmk[i]));
  1204. DHD_ERROR(("\n"));
  1205. #endif
  1206. return error;
  1207. }
  1208. static int
  1209. wl_android_okc_enable(struct net_device *dev, char *command, int total_len)
  1210. {
  1211. int error = 0;
  1212. char okc_enable = 0;
  1213. okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0';
  1214. error = wldev_iovar_setint(dev, "okc_enable", okc_enable);
  1215. if (error) {
  1216. DHD_ERROR(("Failed to %s OKC, error = %d\n",
  1217. okc_enable ? "enable" : "disable", error));
  1218. }
  1219. return error;
  1220. }
  1221. #endif /* OKC_ SUPPORT */
  1222. #ifdef CUSTOMER_HW4
  1223. static int
  1224. wl_android_ch_res_rl(struct net_device *dev, bool change)
  1225. {
  1226. int error = 0;
  1227. s32 srl = 7;
  1228. s32 lrl = 4;
  1229. printk("%s enter\n", __FUNCTION__);
  1230. if (change) {
  1231. srl = 4;
  1232. lrl = 2;
  1233. }
  1234. error = wldev_ioctl(dev, WLC_SET_SRL, &srl, sizeof(s32), true);
  1235. if (error) {
  1236. DHD_ERROR(("Failed to set SRL, error = %d\n", error));
  1237. }
  1238. error = wldev_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(s32), true);
  1239. if (error) {
  1240. DHD_ERROR(("Failed to set LRL, error = %d\n", error));
  1241. }
  1242. return error;
  1243. }
  1244. #endif /* CUSTOMER_HW4 */
  1245. #ifdef SUPPORT_AMPDU_MPDU_CMD
  1246. /* CMD_AMPDU_MPDU */
  1247. static int
  1248. wl_android_set_ampdu_mpdu(struct net_device *dev, const char* string_num)
  1249. {
  1250. int err = 0;
  1251. int ampdu_mpdu;
  1252. ampdu_mpdu = bcm_atoi(string_num);
  1253. if (ampdu_mpdu > 32) {
  1254. DHD_ERROR(("%s : ampdu_mpdu MAX value is 32.\n", __FUNCTION__));
  1255. return -1;
  1256. }
  1257. DHD_ERROR(("%s : ampdu_mpdu = %d\n", __FUNCTION__, ampdu_mpdu));
  1258. err = wldev_iovar_setint(dev, "ampdu_mpdu", ampdu_mpdu);
  1259. if (err < 0) {
  1260. DHD_ERROR(("%s : ampdu_mpdu set error. %d\n", __FUNCTION__, err));
  1261. return -1;
  1262. }
  1263. return 0;
  1264. }
  1265. #endif /* SUPPORT_AMPDU_MPDU_CMD */
  1266. int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
  1267. {
  1268. #define PRIVATE_COMMAND_MAX_LEN 8192
  1269. int ret = 0;
  1270. char *command = NULL;
  1271. int bytes_written = 0;
  1272. android_wifi_priv_cmd priv_cmd;
  1273. net_os_wake_lock(net);
  1274. if (!ifr->ifr_data) {
  1275. ret = -EINVAL;
  1276. goto exit;
  1277. }
  1278. if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) {
  1279. ret = -EFAULT;
  1280. goto exit;
  1281. }
  1282. if (priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN)
  1283. {
  1284. DHD_ERROR(("%s: too long priavte command\n", __FUNCTION__));
  1285. ret = -EINVAL;
  1286. }
  1287. command = kmalloc(priv_cmd.total_len, GFP_KERNEL);
  1288. if (!command)
  1289. {
  1290. DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__));
  1291. ret = -ENOMEM;
  1292. goto exit;
  1293. }
  1294. if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) {
  1295. ret = -EFAULT;
  1296. goto exit;
  1297. }
  1298. DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name));
  1299. if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) {
  1300. DHD_INFO(("%s, Received regular START command\n", __FUNCTION__));
  1301. #ifdef SUPPORT_DEEP_SLEEP
  1302. sleep_never = 1;
  1303. #else
  1304. bytes_written = wl_android_wifi_on(net);
  1305. #endif /* SUPPORT_DEEP_SLEEP */
  1306. }
  1307. else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) {
  1308. bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len);
  1309. }
  1310. if (!g_wifi_on) {
  1311. DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n",
  1312. __FUNCTION__, command, ifr->ifr_name));
  1313. ret = 0;
  1314. goto exit;
  1315. }
  1316. if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) {
  1317. #ifdef SUPPORT_DEEP_SLEEP
  1318. sleep_never = 1;
  1319. #else
  1320. bytes_written = wl_android_wifi_off(net);
  1321. #endif /* SUPPORT_DEEP_SLEEP */
  1322. }
  1323. else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) {
  1324. /* TBD: SCAN-ACTIVE */
  1325. }
  1326. else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) {
  1327. /* TBD: SCAN-PASSIVE */
  1328. }
  1329. else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
  1330. bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len);
  1331. }
  1332. else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) {
  1333. bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len);
  1334. }
  1335. #ifdef PKT_FILTER_SUPPORT
  1336. else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) {
  1337. bytes_written = net_os_enable_packet_filter(net, 1);
  1338. }
  1339. else if (strnicmp(command, CMD_RXFILTER_STOP, strlen(CMD_RXFILTER_STOP)) == 0) {
  1340. bytes_written = net_os_enable_packet_filter(net, 0);
  1341. }
  1342. else if (strnicmp(command, CMD_RXFILTER_ADD, strlen(CMD_RXFILTER_ADD)) == 0) {
  1343. int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0';
  1344. bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num);
  1345. }
  1346. else if (strnicmp(command, CMD_RXFILTER_REMOVE, strlen(CMD_RXFILTER_REMOVE)) == 0) {
  1347. int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0';
  1348. bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num);
  1349. }
  1350. #endif /* PKT_FILTER_SUPPORT */
  1351. else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) {
  1352. /* TBD: BTCOEXSCAN-START */
  1353. }
  1354. else if (strnicmp(command, CMD_BTCOEXSCAN_STOP, strlen(CMD_BTCOEXSCAN_STOP)) == 0) {
  1355. /* TBD: BTCOEXSCAN-STOP */
  1356. }
  1357. else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) {
  1358. #ifdef WL_CFG80211
  1359. bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command);
  1360. #else
  1361. #ifdef PKT_FILTER_SUPPORT
  1362. uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0';
  1363. if (mode == 1)
  1364. net_os_enable_packet_filter(net, 0); /* DHCP starts */
  1365. else
  1366. net_os_enable_packet_filter(net, 1); /* DHCP ends */
  1367. #endif /* PKT_FILTER_SUPPORT */
  1368. #endif /* WL_CFG80211 */
  1369. }
  1370. else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) {
  1371. bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len);
  1372. }
  1373. else if (strnicmp(command, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) {
  1374. bytes_written = wl_android_set_suspendmode(net, command, priv_cmd.total_len);
  1375. }
  1376. else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) {
  1377. uint band = *(command + strlen(CMD_SETBAND) + 1) - '0';
  1378. bytes_written = wldev_set_band(net, band);
  1379. }
  1380. else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) {
  1381. bytes_written = wl_android_get_band(net, command, priv_cmd.total_len);
  1382. }
  1383. #ifdef WL_CFG80211
  1384. #ifndef CUSTOMER_SET_COUNTRY
  1385. /* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */
  1386. else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
  1387. char *country_code = command + strlen(CMD_COUNTRY) + 1;
  1388. bytes_written = wldev_set_country(net, country_code);
  1389. }
  1390. #endif
  1391. #endif /* WL_CFG80211 */
  1392. #ifdef ROAM_API
  1393. else if (strnicmp(command, CMD_ROAMTRIGGER_SET,
  1394. strlen(CMD_ROAMTRIGGER_SET)) == 0) {
  1395. bytes_written = wl_android_set_roam_trigger(net, command,
  1396. priv_cmd.total_len);
  1397. } else if (strnicmp(command, CMD_ROAMTRIGGER_GET,
  1398. strlen(CMD_ROAMTRIGGER_GET)) == 0) {
  1399. bytes_written = wl_android_get_roam_trigger(net, command,
  1400. priv_cmd.total_len);
  1401. } else if (strnicmp(command, CMD_ROAMDELTA_SET,
  1402. strlen(CMD_ROAMDELTA_SET)) == 0) {
  1403. bytes_written = wl_android_set_roam_delta(net, command,
  1404. priv_cmd.total_len);
  1405. } else if (strnicmp(command, CMD_ROAMDELTA_GET,
  1406. strlen(CMD_ROAMDELTA_GET)) == 0) {
  1407. bytes_written = wl_android_get_roam_delta(net, command,
  1408. priv_cmd.total_len);
  1409. } else if (strnicmp(command, CMD_ROAMSCANPERIOD_SET,
  1410. strlen(CMD_ROAMSCANPERIOD_SET)) == 0) {
  1411. bytes_written = wl_android_set_roam_scan_period(net, command,
  1412. priv_cmd.total_len);
  1413. } else if (strnicmp(command, CMD_ROAMSCANPERIOD_GET,
  1414. strlen(CMD_ROAMSCANPERIOD_GET)) == 0) {
  1415. bytes_written = wl_android_get_roam_scan_period(net, command,
  1416. priv_cmd.total_len);
  1417. } else if (strnicmp(command, CMD_FULLROAMSCANPERIOD_SET,
  1418. strlen(CMD_FULLROAMSCANPERIOD_SET)) == 0) {
  1419. bytes_written = wl_android_set_full_roam_scan_period(net, command,
  1420. priv_cmd.total_len);
  1421. } else if (strnicmp(command, CMD_FULLROAMSCANPERIOD_GET,
  1422. strlen(CMD_FULLROAMSCANPERIOD_GET)) == 0) {
  1423. bytes_written = wl_android_get_full_roam_scan_period(net, command,
  1424. priv_cmd.total_len);
  1425. } else if (strnicmp(command, CMD_COUNTRYREV_SET,
  1426. strlen(CMD_COUNTRYREV_SET)) == 0) {
  1427. bytes_written = wl_android_set_country_rev(net, command,
  1428. priv_cmd.total_len);
  1429. wl_update_wiphybands(NULL);
  1430. } else if (strnicmp(command, CMD_COUNTRYREV_GET,
  1431. strlen(CMD_COUNTRYREV_GET)) == 0) {
  1432. bytes_written = wl_android_get_country_rev(net, command,
  1433. priv_cmd.total_len);
  1434. }
  1435. #endif /* ROAM_API */
  1436. #if defined(CUSTOMER_HW4) && defined(WES_SUPPORT)
  1437. else if (strnicmp(command, CMD_GETROAMSCANCONTROL, strlen(CMD_GETROAMSCANCONTROL)) == 0) {
  1438. bytes_written = wl_android_get_roam_scan_control(net, command, priv_cmd.total_len);
  1439. }
  1440. else if (strnicmp(command, CMD_SETROAMSCANCONTROL, strlen(CMD_SETROAMSCANCONTROL)) == 0) {
  1441. bytes_written = wl_android_set_roam_scan_control(net, command, priv_cmd.total_len);
  1442. }
  1443. else if (strnicmp(command, CMD_GETROAMSCANCHANNELS, strlen(CMD_GETROAMSCANCHANNELS)) == 0) {
  1444. bytes_written = wl_android_get_roam_scan_channels(net, command, priv_cmd.total_len);
  1445. }
  1446. else if (strnicmp(command, CMD_SETROAMSCANCHANNELS, strlen(CMD_SETROAMSCANCHANNELS)) == 0) {
  1447. bytes_written = wl_android_set_roam_scan_channels(net, command, priv_cmd.total_len);
  1448. }
  1449. else if (strnicmp(command, CMD_SENDACTIONFRAME, strlen(CMD_SENDACTIONFRAME)) == 0) {
  1450. bytes_written = wl_android_send_action_frame(net, command, priv_cmd.total_len);
  1451. }
  1452. else if (strnicmp(command, CMD_REASSOC, strlen(CMD_REASSOC)) == 0) {
  1453. bytes_written = wl_android_reassoc(net, command, priv_cmd.total_len);
  1454. }
  1455. else if (strnicmp(command, CMD_GETSCANCHANNELTIME, strlen(CMD_GETSCANCHANNELTIME)) == 0) {
  1456. bytes_written = wl_android_get_scan_channel_time(net, command, priv_cmd.total_len);
  1457. }
  1458. else if (strnicmp(command, CMD_SETSCANCHANNELTIME, strlen(CMD_SETSCANCHANNELTIME)) == 0) {
  1459. bytes_written = wl_android_set_scan_channel_time(net, command, priv_cmd.total_len);
  1460. }
  1461. else if (strnicmp(command, CMD_GETSCANHOMETIME, strlen(CMD_GETSCANHOMETIME)) == 0) {
  1462. bytes_written = wl_android_get_scan_home_time(net, command, priv_cmd.total_len);
  1463. }
  1464. else if (strnicmp(command, CMD_SETSCANHOMETIME, strlen(CMD_SETSCANHOMETIME)) == 0) {
  1465. bytes_written = wl_android_set_scan_home_time(net, command, priv_cmd.total_len);
  1466. }
  1467. else if (strnicmp(command, CMD_GETSCANHOMEAWAYTIME, strlen(CMD_GETSCANHOMEAWAYTIME)) == 0) {
  1468. bytes_written = wl_android_get_scan_home_away_time(net, command,
  1469. priv_cmd.total_len);
  1470. }
  1471. else if (strnicmp(command, CMD_SETSCANHOMEAWAYTIME, strlen(CMD_SETSCANHOMEAWAYTIME)) == 0) {
  1472. bytes_written = wl_android_set_scan_home_away_time(net, command,
  1473. priv_cmd.total_len);
  1474. }
  1475. else if (strnicmp(command, CMD_GETSCANNPROBES, strlen(CMD_GETSCANNPROBES)) == 0) {
  1476. bytes_written = wl_android_get_scan_nprobes(net, command, priv_cmd.total_len);
  1477. }
  1478. else if (strnicmp(command, CMD_SETSCANNPROBES, strlen(CMD_SETSCANNPROBES)) == 0) {
  1479. bytes_written = wl_android_set_scan_nprobes(net, command, priv_cmd.total_len);
  1480. }
  1481. else if (strnicmp(command, CMD_GETWESMODE, strlen(CMD_GETWESMODE)) == 0) {
  1482. bytes_written = wl_android_get_wes_mode(net, command, priv_cmd.total_len);
  1483. }
  1484. else if (strnicmp(command, CMD_SETWESMODE, strlen(CMD_SETWESMODE)) == 0) {
  1485. bytes_written = wl_android_set_wes_mode(net, command, priv_cmd.total_len);
  1486. }
  1487. else if (strnicmp(command, CMD_GETOKCMODE, strlen(CMD_GETOKCMODE)) == 0) {
  1488. bytes_written = wl_android_get_okc_mode(net, command, priv_cmd.total_len);
  1489. }
  1490. else if (strnicmp(command, CMD_SETOKCMODE, strlen(CMD_SETOKCMODE)) == 0) {
  1491. bytes_written = wl_android_set_okc_mode(net, command, priv_cmd.total_len);
  1492. }
  1493. #endif /* WES_SUPPORT */
  1494. #ifdef PNO_SUPPORT
  1495. else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) {
  1496. bytes_written = dhd_dev_pno_reset(net);
  1497. }
  1498. else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_P

Large files files are truncated, but you can click here to view the full file