PageRenderTime 95ms CodeModel.GetById 2ms app.highlight 79ms RepoModel.GetById 1ms app.codeStats 1ms

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

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

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