PageRenderTime 94ms CodeModel.GetById 2ms app.highlight 77ms RepoModel.GetById 1ms app.codeStats 1ms

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

https://bitbucket.org/morfic/smdk4412
C | 2156 lines | 1791 code | 298 blank | 67 comment | 412 complexity | 08a5a5e06bb9ca42b262f5cd2bc1182f MD5 | raw file

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

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