PageRenderTime 9ms CodeModel.GetById 4ms app.highlight 105ms RepoModel.GetById 2ms 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

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