2 * Linux cfg80211 driver - Android related functions
4 * Copyright (C) 1999-2019, Broadcom.
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:
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.
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.
25 * <<Broadcom-WL-IPTag/Open:>>
27 * $Id: wl_android.c 818247 2019-05-07 04:15:13Z $
30 #include <linux/module.h>
31 #include <linux/netdevice.h>
32 #include <net/netlink.h>
34 #include <linux/compat.h>
37 #include <wl_android.h>
38 #include <wldev_common.h>
39 #include <wlc_types.h>
41 #include <wlioctl_utils.h>
43 #include <linux_osl.h>
45 #include <dngl_stats.h>
55 #include <wl_cfg80211.h>
58 #include <wl_cfgnan.h>
60 #ifdef DHDTCPACK_SUPPRESS
62 #endif /* DHDTCPACK_SUPPRESS */
63 #include <bcmwifi_rspec.h>
64 #include <dhd_linux.h>
66 #ifdef DHD_PKT_LOGGING
67 #include <dhd_pktlog.h>
68 #endif /* DHD_PKT_LOGGING */
71 #define WL_BSSIDX_MAX 16
72 #endif /* WL_STATIC_IF */
74 #include <wl_cfgvendor.h>
75 #include <brcm_nl80211.h>
76 #endif /* WL_BCNRECV */
78 * Android private command strings, PLEASE define new private commands here
79 * so they can be updated easily in the future (if needed)
82 #define CMD_START "START"
83 #define CMD_STOP "STOP"
84 #define CMD_SCAN_ACTIVE "SCAN-ACTIVE"
85 #define CMD_SCAN_PASSIVE "SCAN-PASSIVE"
86 #define CMD_RSSI "RSSI"
87 #define CMD_LINKSPEED "LINKSPEED"
88 #define CMD_RXFILTER_START "RXFILTER-START"
89 #define CMD_RXFILTER_STOP "RXFILTER-STOP"
90 #define CMD_RXFILTER_ADD "RXFILTER-ADD"
91 #define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE"
92 #define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START"
93 #define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP"
94 #define CMD_BTCOEXMODE "BTCOEXMODE"
95 #define CMD_SETSUSPENDOPT "SETSUSPENDOPT"
96 #define CMD_SETSUSPENDMODE "SETSUSPENDMODE"
97 #define CMD_SETDTIM_IN_SUSPEND "SET_DTIM_IN_SUSPEND"
98 #define CMD_MAXDTIM_IN_SUSPEND "MAX_DTIM_IN_SUSPEND"
99 #define CMD_DISDTIM_IN_SUSPEND "DISABLE_DTIM_IN_SUSPEND"
100 #define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR"
101 #define CMD_SETFWPATH "SETFWPATH"
102 #define CMD_SETBAND "SETBAND"
103 #define CMD_GETBAND "GETBAND"
104 #define CMD_COUNTRY "COUNTRY"
105 #define CMD_P2P_SET_NOA "P2P_SET_NOA"
106 #if !defined WL_ENABLE_P2P_IF
107 #define CMD_P2P_GET_NOA "P2P_GET_NOA"
108 #endif /* WL_ENABLE_P2P_IF */
109 #define CMD_P2P_SD_OFFLOAD "P2P_SD_"
110 #define CMD_P2P_LISTEN_OFFLOAD "P2P_LO_"
111 #define CMD_P2P_SET_PS "P2P_SET_PS"
112 #define CMD_P2P_ECSA "P2P_ECSA"
113 #define CMD_P2P_INC_BW "P2P_INCREASE_BW"
114 #define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE"
115 #define CMD_SETROAMMODE "SETROAMMODE"
116 #define CMD_SETIBSSBEACONOUIDATA "SETIBSSBEACONOUIDATA"
117 #define CMD_MIRACAST "MIRACAST"
119 #define CMD_NAN "NAN_"
121 #define CMD_COUNTRY_DELIMITER "/"
123 #if defined(WL_SUPPORT_AUTO_CHANNEL)
124 #define CMD_GET_BEST_CHANNELS "GET_BEST_CHANNELS"
125 #endif /* WL_SUPPORT_AUTO_CHANNEL */
127 #define CMD_80211_MODE "MODE" /* 802.11 mode a/b/g/n/ac */
128 #define CMD_CHANSPEC "CHANSPEC"
129 #define CMD_DATARATE "DATARATE"
130 #define CMD_ASSOC_CLIENTS "ASSOCLIST"
131 #define CMD_SET_CSA "SETCSA"
132 #ifdef WL_SUPPORT_AUTO_CHANNEL
133 #define CMD_SET_HAPD_AUTO_CHANNEL "HAPD_AUTO_CHANNEL"
134 #endif /* WL_SUPPORT_AUTO_CHANNEL */
135 #ifdef CUSTOMER_HW4_PRIVATE_CMD
136 #ifdef SUPPORT_HIDDEN_AP
137 /* Hostapd private command */
138 #define CMD_SET_HAPD_MAX_NUM_STA "HAPD_MAX_NUM_STA"
139 #define CMD_SET_HAPD_SSID "HAPD_SSID"
140 #define CMD_SET_HAPD_HIDE_SSID "HAPD_HIDE_SSID"
141 #endif /* SUPPORT_HIDDEN_AP */
142 #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
143 #define CMD_HAPD_STA_DISASSOC "HAPD_STA_DISASSOC"
144 #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
145 #ifdef SUPPORT_SET_LPC
146 #define CMD_HAPD_LPC_ENABLED "HAPD_LPC_ENABLED"
147 #endif /* SUPPORT_SET_LPC */
148 #ifdef SUPPORT_TRIGGER_HANG_EVENT
149 #define CMD_TEST_FORCE_HANG "TEST_FORCE_HANG"
150 #endif /* SUPPORT_TRIGGER_HANG_EVENT */
152 #define CMD_LTECX_SET "LTECOEX"
153 #endif /* SUPPORT_LTECX */
154 #ifdef TEST_TX_POWER_CONTROL
155 #define CMD_TEST_SET_TX_POWER "TEST_SET_TX_POWER"
156 #define CMD_TEST_GET_TX_POWER "TEST_GET_TX_POWER"
157 #endif /* TEST_TX_POWER_CONTROL */
158 #define CMD_SARLIMIT_TX_CONTROL "SET_TX_POWER_CALLING"
159 #ifdef SUPPORT_SET_TID
160 #define CMD_SET_TID "SET_TID"
161 #define CMD_GET_TID "GET_TID"
162 #endif /* SUPPORT_SET_TID */
163 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
164 #define CMD_KEEP_ALIVE "KEEPALIVE"
167 /* CCX Private Commands */
168 #define CMD_GETCCKM_RN "get cckm_rn"
169 #define CMD_SETCCKM_KRK "set cckm_krk"
170 #define CMD_GET_ASSOC_RES_IES "get assoc_res_ies"
172 #define CCKM_KRK_LEN 16
173 #define CCKM_BTK_LEN 32
177 #define CMD_PNOSSIDCLR_SET "PNOSSIDCLR"
178 #define CMD_PNOSETUP_SET "PNOSETUP "
179 #define CMD_PNOENABLE_SET "PNOFORCE"
180 #define CMD_PNODEBUG_SET "PNODEBUG"
181 #define CMD_WLS_BATCHING "WLS_BATCHING"
182 #endif /* PNO_SUPPORT */
184 #define CMD_HAPD_MAC_FILTER "HAPD_MAC_FILTER"
186 #ifdef CUSTOMER_HW4_PRIVATE_CMD
189 #define CMD_ROAMTRIGGER_SET "SETROAMTRIGGER"
190 #define CMD_ROAMTRIGGER_GET "GETROAMTRIGGER"
191 #define CMD_ROAMDELTA_SET "SETROAMDELTA"
192 #define CMD_ROAMDELTA_GET "GETROAMDELTA"
193 #define CMD_ROAMSCANPERIOD_SET "SETROAMSCANPERIOD"
194 #define CMD_ROAMSCANPERIOD_GET "GETROAMSCANPERIOD"
195 #define CMD_FULLROAMSCANPERIOD_SET "SETFULLROAMSCANPERIOD"
196 #define CMD_FULLROAMSCANPERIOD_GET "GETFULLROAMSCANPERIOD"
197 #define CMD_COUNTRYREV_SET "SETCOUNTRYREV"
198 #define CMD_COUNTRYREV_GET "GETCOUNTRYREV"
199 #endif /* ROAM_API */
201 #if defined(SUPPORT_RANDOM_MAC_SCAN)
202 #define ENABLE_RANDOM_MAC "ENABLE_RANDOM_MAC"
203 #define DISABLE_RANDOM_MAC "DISABLE_RANDOM_MAC"
204 #endif /* SUPPORT_RANDOM_MAC_SCAN */
207 #define CMD_GETROAMSCANCONTROL "GETROAMSCANCONTROL"
208 #define CMD_SETROAMSCANCONTROL "SETROAMSCANCONTROL"
209 #define CMD_GETROAMSCANCHANNELS "GETROAMSCANCHANNELS"
210 #define CMD_SETROAMSCANCHANNELS "SETROAMSCANCHANNELS"
212 #define CMD_GETSCANCHANNELTIME "GETSCANCHANNELTIME"
213 #define CMD_SETSCANCHANNELTIME "SETSCANCHANNELTIME"
214 #define CMD_GETSCANUNASSOCTIME "GETSCANUNASSOCTIME"
215 #define CMD_SETSCANUNASSOCTIME "SETSCANUNASSOCTIME"
216 #define CMD_GETSCANPASSIVETIME "GETSCANPASSIVETIME"
217 #define CMD_SETSCANPASSIVETIME "SETSCANPASSIVETIME"
218 #define CMD_GETSCANHOMETIME "GETSCANHOMETIME"
219 #define CMD_SETSCANHOMETIME "SETSCANHOMETIME"
220 #define CMD_GETSCANHOMEAWAYTIME "GETSCANHOMEAWAYTIME"
221 #define CMD_SETSCANHOMEAWAYTIME "SETSCANHOMEAWAYTIME"
222 #define CMD_GETSCANNPROBES "GETSCANNPROBES"
223 #define CMD_SETSCANNPROBES "SETSCANNPROBES"
224 #define CMD_GETDFSSCANMODE "GETDFSSCANMODE"
225 #define CMD_SETDFSSCANMODE "SETDFSSCANMODE"
226 #define CMD_SETJOINPREFER "SETJOINPREFER"
228 #define CMD_SENDACTIONFRAME "SENDACTIONFRAME"
229 #define CMD_REASSOC "REASSOC"
231 #define CMD_GETWESMODE "GETWESMODE"
232 #define CMD_SETWESMODE "SETWESMODE"
234 #define CMD_GETOKCMODE "GETOKCMODE"
235 #define CMD_SETOKCMODE "SETOKCMODE"
237 #define CMD_OKC_SET_PMK "SET_PMK"
238 #define CMD_OKC_ENABLE "OKC_ENABLE"
240 typedef struct android_wifi_reassoc_params
{
241 unsigned char bssid
[18];
243 } android_wifi_reassoc_params_t
;
245 #define ANDROID_WIFI_REASSOC_PARAMS_SIZE sizeof(struct android_wifi_reassoc_params)
247 #define ANDROID_WIFI_ACTION_FRAME_SIZE 1040
249 typedef struct android_wifi_af_params
{
250 unsigned char bssid
[18];
254 unsigned char data
[ANDROID_WIFI_ACTION_FRAME_SIZE
];
255 } android_wifi_af_params_t
;
257 #define ANDROID_WIFI_AF_PARAMS_SIZE sizeof(struct android_wifi_af_params)
258 #endif /* WES_SUPPORT */
259 #ifdef SUPPORT_AMPDU_MPDU_CMD
260 #define CMD_AMPDU_MPDU "AMPDU_MPDU"
261 #endif /* SUPPORT_AMPDU_MPDU_CMD */
263 #define CMD_CHANGE_RL "CHANGE_RL"
264 #define CMD_RESTORE_RL "RESTORE_RL"
266 #define CMD_SET_RMC_ENABLE "SETRMCENABLE"
267 #define CMD_SET_RMC_TXRATE "SETRMCTXRATE"
268 #define CMD_SET_RMC_ACTPERIOD "SETRMCACTIONPERIOD"
269 #define CMD_SET_RMC_IDLEPERIOD "SETRMCIDLEPERIOD"
270 #define CMD_SET_RMC_LEADER "SETRMCLEADER"
271 #define CMD_SET_RMC_EVENT "SETRMCEVENT"
273 #define CMD_SET_SCSCAN "SETSINGLEANT"
274 #define CMD_GET_SCSCAN "GETSINGLEANT"
276 #define CMD_TDLS_RESET "TDLS_RESET"
279 #ifdef FCC_PWR_LIMIT_2G
280 #define CMD_GET_FCC_PWR_LIMIT_2G "GET_FCC_CHANNEL"
281 #define CMD_SET_FCC_PWR_LIMIT_2G "SET_FCC_CHANNEL"
282 /* CUSTOMER_HW4's value differs from BRCM FW value for enable/disable */
283 #define CUSTOMER_HW4_ENABLE 0
284 #define CUSTOMER_HW4_DISABLE -1
285 #define CUSTOMER_HW4_EN_CONVERT(i) (i += 1)
286 #endif /* FCC_PWR_LIMIT_2G */
287 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
290 #define CMD_GET_FTKEY "GET_FTKEY"
294 #define CMD_SETIBSSTXFAILEVENT "SETIBSSTXFAILEVENT"
295 #define CMD_GET_IBSS_PEER_INFO "GETIBSSPEERINFO"
296 #define CMD_GET_IBSS_PEER_INFO_ALL "GETIBSSPEERINFOALL"
297 #define CMD_SETIBSSROUTETABLE "SETIBSSROUTETABLE"
298 #define CMD_SETIBSSAMPDU "SETIBSSAMPDU"
299 #define CMD_SETIBSSANTENNAMODE "SETIBSSANTENNAMODE"
302 #define CMD_ROAM_OFFLOAD "SETROAMOFFLOAD"
303 #define CMD_INTERFACE_CREATE "INTERFACE_CREATE"
304 #define CMD_INTERFACE_DELETE "INTERFACE_DELETE"
305 #define CMD_GET_LINK_STATUS "GETLINKSTATUS"
307 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
308 #define CMD_GET_BSS_INFO "GETBSSINFO"
309 #define CMD_GET_ASSOC_REJECT_INFO "GETASSOCREJECTINFO"
310 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
311 #define CMD_GET_STA_INFO "GETSTAINFO"
313 /* related with CMD_GET_LINK_STATUS */
314 #define WL_ANDROID_LINK_VHT 0x01
315 #define WL_ANDROID_LINK_MIMO 0x02
316 #define WL_ANDROID_LINK_AP_VHT_SUPPORT 0x04
317 #define WL_ANDROID_LINK_AP_MIMO_SUPPORT 0x08
319 #ifdef P2PRESP_WFDIE_SRC
320 #define CMD_P2P_SET_WFDIE_RESP "P2P_SET_WFDIE_RESP"
321 #define CMD_P2P_GET_WFDIE_RESP "P2P_GET_WFDIE_RESP"
322 #endif /* P2PRESP_WFDIE_SRC */
324 #define CMD_DFS_AP_MOVE "DFS_AP_MOVE"
325 #define CMD_WBTEXT_ENABLE "WBTEXT_ENABLE"
326 #define CMD_WBTEXT_PROFILE_CONFIG "WBTEXT_PROFILE_CONFIG"
327 #define CMD_WBTEXT_WEIGHT_CONFIG "WBTEXT_WEIGHT_CONFIG"
328 #define CMD_WBTEXT_TABLE_CONFIG "WBTEXT_TABLE_CONFIG"
329 #define CMD_WBTEXT_DELTA_CONFIG "WBTEXT_DELTA_CONFIG"
330 #define CMD_WBTEXT_BTM_TIMER_THRESHOLD "WBTEXT_BTM_TIMER_THRESHOLD"
331 #define CMD_WBTEXT_BTM_DELTA "WBTEXT_BTM_DELTA"
334 #define CMD_ADD_WFDS_HASH "ADD_WFDS_HASH"
335 #define CMD_DEL_WFDS_HASH "DEL_WFDS_HASH"
339 #define CMD_RPSMODE "RPSMODE"
340 #endif /* SET_RPS_CPUS */
342 #ifdef BT_WIFI_HANDOVER
343 #define CMD_TBOW_TEARDOWN "TBOW_TEARDOWN"
344 #endif /* BT_WIFI_HANDOVER */
346 #ifdef DYNAMIC_MUMIMO_CONTROL
347 #define CMD_GET_MURX_BFE_CAP "GET_MURX_BFE_CAP"
348 #define CMD_SET_MURX_BFE_CAP "SET_MURX_BFE_CAP"
349 #define CMD_GET_BSS_SUPPORT_MUMIMO "GET_BSS_SUPPORT_MUMIMO"
350 #endif /* DYNAMIC_MUMIMO_CONTROL */
352 #ifdef SUPPORT_RSSI_SUM_REPORT
353 #define CMD_SET_RSSI_LOGGING "SET_RSSI_LOGGING"
354 #define CMD_GET_RSSI_LOGGING "GET_RSSI_LOGGING"
355 #define CMD_GET_RSSI_PER_ANT "GET_RSSI_PER_ANT"
356 #endif /* SUPPORT_RSSI_SUM_REPORT */
358 #ifdef APSTA_RESTRICTED_CHANNEL
359 #define CMD_SET_INDOOR_CHANNELS "SET_INDOOR_CHANNELS"
360 #define CMD_GET_INDOOR_CHANNELS "GET_INDOOR_CHANNELS"
361 #endif /* APSTA_RESTRICTED_CHANNEL */
363 #define CMD_GET_SNR "GET_SNR"
365 #ifdef SUPPORT_SET_CAC
366 #define CMD_ENABLE_CAC "ENABLE_CAC"
367 #endif /* SUPPORT_SET_CAC */
369 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
370 #define CMD_SET_AP_BEACONRATE "SET_AP_BEACONRATE"
371 #define CMD_GET_AP_BASICRATE "GET_AP_BASICRATE"
372 #endif /* SUPPORT_AP_HIGHER_BEACONRATE */
374 #ifdef SUPPORT_AP_RADIO_PWRSAVE
375 #define CMD_SET_AP_RPS "SET_AP_RPS"
376 #define CMD_GET_AP_RPS "GET_AP_RPS"
377 #define CMD_SET_AP_RPS_PARAMS "SET_AP_RPS_PARAMS"
378 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
380 /* miracast related definition */
381 #define MIRACAST_MODE_OFF 0
382 #define MIRACAST_MODE_SOURCE 1
383 #define MIRACAST_MODE_SINK 2
385 #ifdef CONNECTION_STATISTICS
386 #define CMD_GET_CONNECTION_STATS "GET_CONNECTION_STATS"
388 struct connection_stats
{
403 #endif /* CONNECTION_STATISTICS */
406 #define CMD_SET_LQCM_ENABLE "SET_LQCM_ENABLE"
407 #define CMD_GET_LQCM_REPORT "GET_LQCM_REPORT"
410 static LIST_HEAD(miracast_resume_list
);
411 static u8 miracast_cur_mode
;
414 #define CMD_NEW_DEBUG_PRINT_DUMP "DEBUG_DUMP"
415 #define SUBCMD_UNWANTED "UNWANTED"
416 #define SUBCMD_DISCONNECTED "DISCONNECTED"
417 void dhd_log_dump_trigger(dhd_pub_t
*dhdp
, int subcmd
);
418 #endif /* DHD_LOG_DUMP */
420 #ifdef DHD_HANG_SEND_UP_TEST
421 #define CMD_MAKE_HANG "MAKE_HANG"
422 #endif /* CMD_DHD_HANG_SEND_UP_TEST */
423 #ifdef DHD_DEBUG_UART
424 extern bool dhd_debug_uart_is_running(struct net_device
*dev
);
425 #endif /* DHD_DEBUG_UART */
433 struct list_head list
;
436 #if defined(BCMFW_ROAM_ENABLE)
437 #define CMD_SET_ROAMPREF "SET_ROAMPREF"
439 #define MAX_NUM_SUITES 10
440 #define WIDTH_AKM_SUITE 8
441 #define JOIN_PREF_RSSI_LEN 0x02
442 #define JOIN_PREF_RSSI_SIZE 4 /* RSSI pref header size in bytes */
443 #define JOIN_PREF_WPA_HDR_SIZE 4 /* WPA pref header size in bytes */
444 #define JOIN_PREF_WPA_TUPLE_SIZE 12 /* Tuple size in bytes */
445 #define JOIN_PREF_MAX_WPA_TUPLES 16
446 #define MAX_BUF_SIZE (JOIN_PREF_RSSI_SIZE + JOIN_PREF_WPA_HDR_SIZE + \
447 (JOIN_PREF_WPA_TUPLE_SIZE * JOIN_PREF_MAX_WPA_TUPLES))
448 #endif /* BCMFW_ROAM_ENABLE */
450 #define CMD_DEBUG_VERBOSE "DEBUG_VERBOSE"
453 #define CMD_NATOE "NATOE"
455 #define NATOE_MAX_PORT_NUM 65535
457 /* natoe command info structure */
458 typedef struct wl_natoe_cmd_info
{
459 uint8
*command
; /* pointer to the actual command */
460 uint16 tot_len
; /* total length of the command */
461 uint16 bytes_written
; /* Bytes written for get response */
462 } wl_natoe_cmd_info_t
;
464 typedef struct wl_natoe_sub_cmd wl_natoe_sub_cmd_t
;
465 typedef int (natoe_cmd_handler_t
)(struct net_device
*dev
,
466 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
468 struct wl_natoe_sub_cmd
{
470 uint8 version
; /* cmd version */
471 uint16 id
; /* id for the dongle f/w switch/case */
472 uint16 type
; /* base type of argument */
473 natoe_cmd_handler_t
*handler
; /* cmd handler */
476 #define WL_ANDROID_NATOE_FUNC(suffix) wl_android_natoe_subcmd_ ##suffix
477 static int wl_android_process_natoe_cmd(struct net_device
*dev
,
478 char *command
, int total_len
);
479 static int wl_android_natoe_subcmd_enable(struct net_device
*dev
,
480 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
481 static int wl_android_natoe_subcmd_config_ips(struct net_device
*dev
,
482 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
483 static int wl_android_natoe_subcmd_config_ports(struct net_device
*dev
,
484 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
485 static int wl_android_natoe_subcmd_dbg_stats(struct net_device
*dev
,
486 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
487 static int wl_android_natoe_subcmd_tbl_cnt(struct net_device
*dev
,
488 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
490 static const wl_natoe_sub_cmd_t natoe_cmd_list
[] = {
491 /* wl natoe enable [0/1] or new: "wl natoe [0/1]" */
492 {"enable", 0x01, WL_NATOE_CMD_ENABLE
,
493 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(enable
)
495 {"config_ips", 0x01, WL_NATOE_CMD_CONFIG_IPS
,
496 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(config_ips
)
498 {"config_ports", 0x01, WL_NATOE_CMD_CONFIG_PORTS
,
499 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(config_ports
)
501 {"stats", 0x01, WL_NATOE_CMD_DBG_STATS
,
502 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(dbg_stats
)
504 {"tbl_cnt", 0x01, WL_NATOE_CMD_TBL_CNT
,
505 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(tbl_cnt
)
507 {NULL
, 0, 0, 0, NULL
}
510 #endif /* WL_NATOE */
512 #ifdef SET_PCIE_IRQ_CPU_CORE
513 #define CMD_PCIE_IRQ_CORE "PCIE_IRQ_CORE"
514 #endif /* SET_PCIE_IRQ_CPU_CORE */
516 #ifdef WLADPS_PRIVATE_CMD
517 #define CMD_SET_ADPS "SET_ADPS"
518 #define CMD_GET_ADPS "GET_ADPS"
519 #endif /* WLADPS_PRIVATE_CMD */
521 #ifdef DHD_PKT_LOGGING
522 #define CMD_PKTLOG_FILTER_ENABLE "PKTLOG_FILTER_ENABLE"
523 #define CMD_PKTLOG_FILTER_DISABLE "PKTLOG_FILTER_DISABLE"
524 #define CMD_PKTLOG_FILTER_PATTERN_ENABLE "PKTLOG_FILTER_PATTERN_ENABLE"
525 #define CMD_PKTLOG_FILTER_PATTERN_DISABLE "PKTLOG_FILTER_PATTERN_DISABLE"
526 #define CMD_PKTLOG_FILTER_ADD "PKTLOG_FILTER_ADD"
527 #define CMD_PKTLOG_FILTER_INFO "PKTLOG_FILTER_INFO"
528 #define CMD_PKTLOG_START "PKTLOG_START"
529 #define CMD_PKTLOG_STOP "PKTLOG_STOP"
530 #define CMD_PKTLOG_FILTER_EXIST "PKTLOG_FILTER_EXIST"
531 #define CMD_PKTLOG_MINMIZE_ENABLE "PKTLOG_MINMIZE_ENABLE"
532 #define CMD_PKTLOG_MINMIZE_DISABLE "PKTLOG_MINMIZE_DISABLE"
533 #define CMD_PKTLOG_CHANGE_SIZE "PKTLOG_CHANGE_SIZE"
534 #endif /* DHD_PKT_LOGGING */
536 #ifdef DHD_EVENT_LOG_FILTER
537 #define CMD_EWP_FILTER "EWP_FILTER"
538 #endif /* DHD_EVENT_LOG_FILTER */
541 #define CMD_BEACON_RECV "BEACON_RECV"
542 #endif /* WL_BCNRECV */
545 static s32
wl_genl_handle_msg(struct sk_buff
*skb
, struct genl_info
*info
);
546 static int wl_genl_init(void);
547 static int wl_genl_deinit(void);
549 extern struct net init_net
;
550 /* attribute policy: defines which attribute has which type (e.g int, char * etc)
551 * possible values defined in net/netlink.h
553 static struct nla_policy wl_genl_policy
[BCM_GENL_ATTR_MAX
+ 1] = {
554 [BCM_GENL_ATTR_STRING
] = { .type
= NLA_NUL_STRING
},
555 [BCM_GENL_ATTR_MSG
] = { .type
= NLA_BINARY
},
558 #define WL_GENL_VER 1
559 /* family definition */
560 static struct genl_family wl_genl_family
= {
561 .id
= GENL_ID_GENERATE
, /* Genetlink would generate the ID */
563 .name
= "bcm-genl", /* Netlink I/F for Android */
564 .version
= WL_GENL_VER
, /* Version Number */
565 .maxattr
= BCM_GENL_ATTR_MAX
,
568 /* commands: mapping between the command enumeration and the actual function */
569 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
570 struct genl_ops wl_genl_ops
[] = {
572 .cmd
= BCM_GENL_CMD_MSG
,
574 .policy
= wl_genl_policy
,
575 .doit
= wl_genl_handle_msg
,
580 struct genl_ops wl_genl_ops
= {
581 .cmd
= BCM_GENL_CMD_MSG
,
583 .policy
= wl_genl_policy
,
584 .doit
= wl_genl_handle_msg
,
588 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
590 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
591 static struct genl_multicast_group wl_genl_mcast
[] = {
592 { .name
= "bcm-genl-mcast", },
595 static struct genl_multicast_group wl_genl_mcast
= {
596 .id
= GENL_ID_GENERATE
, /* Genetlink would generate the ID */
597 .name
= "bcm-genl-mcast",
599 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
603 #define LQCM_ENAB_MASK 0x000000FF /* LQCM enable flag mask */
604 #define LQCM_TX_INDEX_MASK 0x0000FF00 /* LQCM tx index mask */
605 #define LQCM_RX_INDEX_MASK 0x00FF0000 /* LQCM rx index mask */
607 #define LQCM_TX_INDEX_SHIFT 8 /* LQCM tx index shift */
608 #define LQCM_RX_INDEX_SHIFT 16 /* LQCM rx index shift */
609 #endif /* SUPPORT_LQCM */
611 #ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
612 #define NUMBER_SEQUENTIAL_PRIVCMD_ERRORS 7
613 static int priv_cmd_errors
= 0;
614 #endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
617 * Extern function declarations (TODO: move them to dhd_linux.h)
619 int dhd_net_bus_devreset(struct net_device
*dev
, uint8 flag
);
620 int dhd_dev_init_ioctl(struct net_device
*dev
);
622 int wl_cfg80211_get_p2p_dev_addr(struct net_device
*net
, struct ether_addr
*p2pdev_addr
);
623 int wl_cfg80211_set_btcoex_dhcp(struct net_device
*dev
, dhd_pub_t
*dhd
, char *command
);
625 int wl_cfg80211_set_wes_mode(int mode
);
626 int wl_cfg80211_get_wes_mode(void);
627 #endif /* WES_SUPPORT */
629 int wl_cfg80211_get_p2p_dev_addr(struct net_device
*net
, struct ether_addr
*p2pdev_addr
)
631 int wl_cfg80211_set_p2p_noa(struct net_device
*net
, char* buf
, int len
)
633 int wl_cfg80211_get_p2p_noa(struct net_device
*net
, char* buf
, int len
)
635 int wl_cfg80211_set_p2p_ps(struct net_device
*net
, char* buf
, int len
)
637 int wl_cfg80211_set_p2p_ecsa(struct net_device
*net
, char* buf
, int len
)
639 int wl_cfg80211_increase_p2p_bw(struct net_device
*net
, char* buf
, int len
)
641 #endif /* WK_CFG80211 */
643 static int wl_android_wbtext(struct net_device
*dev
, char *command
, int total_len
);
644 static int wl_cfg80211_wbtext_btm_timer_threshold(struct net_device
*dev
,
645 char *command
, int total_len
);
646 static int wl_cfg80211_wbtext_btm_delta(struct net_device
*dev
,
647 char *command
, int total_len
);
651 extern int get_roamscan_mode(struct net_device
*dev
, int *mode
);
652 extern int set_roamscan_mode(struct net_device
*dev
, int mode
);
653 extern int get_roamscan_channel_list(struct net_device
*dev
,
654 unsigned char channels
[], int n_channels
);
655 extern int set_roamscan_channel_list(struct net_device
*dev
, unsigned char n
,
656 unsigned char channels
[], int ioctl_ver
);
657 #endif /* WES_SUPPORT */
658 #ifdef ROAM_CHANNEL_CACHE
659 extern void wl_update_roamscan_cache_by_band(struct net_device
*dev
, int band
);
660 #endif /* ROAM_CHANNEL_CACHE */
662 #ifdef ENABLE_4335BT_WAR
663 extern int bcm_bt_lock(int cookie
);
664 extern void bcm_bt_unlock(int cookie
);
665 static int lock_cookie_wifi
= 'W' | 'i'<<8 | 'F'<<16 | 'i'<<24; /* cookie is "WiFi" */
666 #endif /* ENABLE_4335BT_WAR */
668 extern bool ap_fw_loaded
;
669 extern char iface_name
[IFNAMSIZ
];
670 #ifdef DHD_PM_CONTROL_FROM_FILE
671 extern bool g_pm_control
;
672 #endif /* DHD_PM_CONTROL_FROM_FILE */
674 /* private command support for restoring roam/scan parameters */
675 #ifdef SUPPORT_RESTORE_SCAN_PARAMS
676 #define CMD_RESTORE_SCAN_PARAMS "RESTORE_SCAN_PARAMS"
678 typedef int (*PRIV_CMD_HANDLER
) (struct net_device
*dev
, char *command
);
679 typedef int (*PRIV_CMD_HANDLER_WITH_LEN
) (struct net_device
*dev
, char *command
, int total_len
);
682 RESTORE_TYPE_UNSPECIFIED
= 0,
683 RESTORE_TYPE_PRIV_CMD
= 1,
684 RESTORE_TYPE_PRIV_CMD_WITH_LEN
= 2
687 typedef struct android_restore_scan_params
{
692 PRIV_CMD_HANDLER cmd_handler
;
693 PRIV_CMD_HANDLER_WITH_LEN cmd_handler_w_len
;
695 } android_restore_scan_params_t
;
697 /* function prototypes of private command handler */
698 static int wl_android_set_roam_trigger(struct net_device
*dev
, char* command
);
699 int wl_android_set_roam_delta(struct net_device
*dev
, char* command
);
700 int wl_android_set_roam_scan_period(struct net_device
*dev
, char* command
);
701 int wl_android_set_full_roam_scan_period(struct net_device
*dev
, char* command
, int total_len
);
702 int wl_android_set_roam_scan_control(struct net_device
*dev
, char *command
);
703 int wl_android_set_scan_channel_time(struct net_device
*dev
, char *command
);
704 int wl_android_set_scan_home_time(struct net_device
*dev
, char *command
);
705 int wl_android_set_scan_home_away_time(struct net_device
*dev
, char *command
);
706 int wl_android_set_scan_nprobes(struct net_device
*dev
, char *command
);
707 static int wl_android_set_band(struct net_device
*dev
, char *command
);
708 int wl_android_set_scan_dfs_channel_mode(struct net_device
*dev
, char *command
);
709 int wl_android_set_wes_mode(struct net_device
*dev
, char *command
);
710 int wl_android_set_okc_mode(struct net_device
*dev
, char *command
);
714 #define DEFAULT_ROAM_TIRGGER -75
715 #define DEFAULT_ROAM_DELTA 10
716 #define DEFAULT_ROAMSCANPERIOD 10
717 #define DEFAULT_FULLROAMSCANPERIOD_SET 120
718 #endif /* ROAM_API */
720 #define DEFAULT_ROAMSCANCONTROL 0
721 #define DEFAULT_SCANCHANNELTIME 40
723 #define DEFAULT_SCANHOMETIME 60
725 #define DEFAULT_SCANHOMETIME 45
726 #endif /* BCM4361_CHIP */
727 #define DEFAULT_SCANHOMEAWAYTIME 100
728 #define DEFAULT_SCANPROBES 2
729 #define DEFAULT_DFSSCANMODE 1
730 #define DEFAULT_WESMODE 0
731 #define DEFAULT_OKCMODE 1
732 #endif /* WES_SUPPORT */
733 #define DEFAULT_BAND 0
735 #define DEFAULT_WBTEXT_ENABLE 1
738 /* restoring parameter list, please don't change order */
739 static android_restore_scan_params_t restore_params
[] =
741 /* wbtext need to be disabled while updating roam/scan parameters */
743 { CMD_WBTEXT_ENABLE
, 0, RESTORE_TYPE_PRIV_CMD_WITH_LEN
,
744 .cmd_handler_w_len
= wl_android_wbtext
},
747 { CMD_ROAMTRIGGER_SET
, DEFAULT_ROAM_TIRGGER
,
748 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_roam_trigger
},
749 { CMD_ROAMDELTA_SET
, DEFAULT_ROAM_DELTA
,
750 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_roam_delta
},
751 { CMD_ROAMSCANPERIOD_SET
, DEFAULT_ROAMSCANPERIOD
,
752 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_roam_scan_period
},
753 { CMD_FULLROAMSCANPERIOD_SET
, DEFAULT_FULLROAMSCANPERIOD_SET
,
754 RESTORE_TYPE_PRIV_CMD_WITH_LEN
,
755 .cmd_handler_w_len
= wl_android_set_full_roam_scan_period
},
756 #endif /* ROAM_API */
758 { CMD_SETROAMSCANCONTROL
, DEFAULT_ROAMSCANCONTROL
,
759 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_roam_scan_control
},
760 { CMD_SETSCANCHANNELTIME
, DEFAULT_SCANCHANNELTIME
,
761 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_scan_channel_time
},
762 { CMD_SETSCANHOMETIME
, DEFAULT_SCANHOMETIME
,
763 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_scan_home_time
},
764 { CMD_GETSCANHOMEAWAYTIME
, DEFAULT_SCANHOMEAWAYTIME
,
765 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_scan_home_away_time
},
766 { CMD_SETSCANNPROBES
, DEFAULT_SCANPROBES
,
767 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_scan_nprobes
},
768 { CMD_SETDFSSCANMODE
, DEFAULT_DFSSCANMODE
,
769 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_scan_dfs_channel_mode
},
770 { CMD_SETWESMODE
, DEFAULT_WESMODE
,
771 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_wes_mode
},
772 { CMD_SETOKCMODE
, DEFAULT_OKCMODE
,
773 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_okc_mode
},
774 #endif /* WES_SUPPORT */
775 { CMD_SETBAND
, DEFAULT_BAND
,
776 RESTORE_TYPE_PRIV_CMD
, .cmd_handler
= wl_android_set_band
},
778 { CMD_WBTEXT_ENABLE
, DEFAULT_WBTEXT_ENABLE
,
779 RESTORE_TYPE_PRIV_CMD_WITH_LEN
, .cmd_handler_w_len
= wl_android_wbtext
},
781 { "\0", 0, RESTORE_TYPE_UNSPECIFIED
, .cmd_handler
= NULL
}
783 #endif /* SUPPORT_RESTORE_SCAN_PARAMS */
786 * Local (static) functions and variables
789 /* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first
790 * time (only) in dhd_open, subsequential wifi on will be handled by
793 static int g_wifi_on
= TRUE
;
796 * Local (static) function definitions
800 static int wl_android_set_wfds_hash(
801 struct net_device
*dev
, char *command
, bool enable
)
804 wl_p2p_wfds_hash_t
*wfds_hash
= NULL
;
806 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
808 smbuf
= (char *)MALLOC(cfg
->osh
, WLC_IOCTL_MAXLEN
);
810 DHD_ERROR(("%s: failed to allocated memory %d bytes\n",
811 __FUNCTION__
, WLC_IOCTL_MAXLEN
));
816 wfds_hash
= (wl_p2p_wfds_hash_t
*)(command
+ strlen(CMD_ADD_WFDS_HASH
) + 1);
817 error
= wldev_iovar_setbuf(dev
, "p2p_add_wfds_hash", wfds_hash
,
818 sizeof(wl_p2p_wfds_hash_t
), smbuf
, WLC_IOCTL_MAXLEN
, NULL
);
821 wfds_hash
= (wl_p2p_wfds_hash_t
*)(command
+ strlen(CMD_DEL_WFDS_HASH
) + 1);
822 error
= wldev_iovar_setbuf(dev
, "p2p_del_wfds_hash", wfds_hash
,
823 sizeof(wl_p2p_wfds_hash_t
), smbuf
, WLC_IOCTL_MAXLEN
, NULL
);
827 DHD_ERROR(("%s: failed to %s, error=%d\n", __FUNCTION__
, command
, error
));
831 MFREE(cfg
->osh
, smbuf
, WLC_IOCTL_MAXLEN
);
837 static int wl_android_get_link_speed(struct net_device
*net
, char *command
, int total_len
)
843 error
= wldev_get_link_speed(net
, &link_speed
);
845 DHD_ERROR(("Get linkspeed failed \n"));
849 /* Convert Kbps to Android Mbps */
850 link_speed
= link_speed
/ 1000;
851 bytes_written
= snprintf(command
, total_len
, "LinkSpeed %d", link_speed
);
852 DHD_INFO(("%s: command result is %s\n", __FUNCTION__
, command
));
853 return bytes_written
;
856 static int wl_android_get_rssi(struct net_device
*net
, char *command
, int total_len
)
858 wlc_ssid_t ssid
= {0, {0}};
859 int bytes_written
= 0;
863 struct net_device
*target_ndev
= net
;
864 #ifdef WL_VIRTUAL_APSTA
866 struct bcm_cfg80211
*cfg
;
867 #endif /* WL_VIRTUAL_APSTA */
869 delim
= strchr(command
, ' ');
870 /* For Ap mode rssi command would be
871 * driver rssi <sta_mac_addr>
877 * driver rssi <sta_mac_addr>
879 DHD_TRACE(("%s: cmd:%s\n", __FUNCTION__
, delim
));
880 /* skip space from delim after finding char */
882 if (!(bcm_ether_atoe((delim
), &scbval
.ea
))) {
883 DHD_ERROR(("%s:address err\n", __FUNCTION__
));
886 scbval
.val
= htod32(0);
887 DHD_TRACE(("%s: address:"MACDBG
, __FUNCTION__
, MAC2STRDBG(scbval
.ea
.octet
)));
888 #ifdef WL_VIRTUAL_APSTA
889 /* RSDB AP may have another virtual interface
890 * In this case, format of private command is as following,
891 * DRIVER rssi <sta_mac_addr> <AP interface name>
894 /* Current position is start of MAC address string */
896 delim
= strchr(pos
, ' ');
898 /* skip space from delim after finding char */
900 if (strnlen(delim
, IFNAMSIZ
)) {
901 cfg
= wl_get_cfg(net
);
902 target_ndev
= wl_get_ap_netdev(cfg
, delim
);
903 if (target_ndev
== NULL
)
907 #endif /* WL_VIRTUAL_APSTA */
911 memset(&scbval
, 0, sizeof(scb_val_t
));
914 error
= wldev_get_rssi(target_ndev
, &scbval
);
918 error
= wldev_get_ssid(target_ndev
, &ssid
);
921 if ((ssid
.SSID_len
== 0) || (ssid
.SSID_len
> DOT11_MAX_SSID_LEN
)) {
922 DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__
));
923 } else if (total_len
<= ssid
.SSID_len
) {
926 memcpy(command
, ssid
.SSID
, ssid
.SSID_len
);
927 bytes_written
= ssid
.SSID_len
;
929 if ((total_len
- bytes_written
) < (strlen(" rssi -XXX") + 1))
932 bytes_written
+= scnprintf(&command
[bytes_written
], total_len
- bytes_written
,
933 " rssi %d", scbval
.val
);
934 command
[bytes_written
] = '\0';
936 DHD_TRACE(("%s: command result is %s (%d)\n", __FUNCTION__
, command
, bytes_written
));
937 return bytes_written
;
940 static int wl_android_set_suspendopt(struct net_device
*dev
, char *command
)
946 suspend_flag
= *(command
+ strlen(CMD_SETSUSPENDOPT
) + 1) - '0';
948 if (suspend_flag
!= 0) {
951 ret_now
= net_os_set_suspend_disable(dev
, suspend_flag
);
953 if (ret_now
!= suspend_flag
) {
954 if (!(ret
= net_os_set_suspend(dev
, ret_now
, 1))) {
955 DHD_INFO(("%s: Suspend Flag %d -> %d\n",
956 __FUNCTION__
, ret_now
, suspend_flag
));
958 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
965 static int wl_android_set_suspendmode(struct net_device
*dev
, char *command
)
969 #if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(DHD_USE_EARLYSUSPEND)
972 suspend_flag
= *(command
+ strlen(CMD_SETSUSPENDMODE
) + 1) - '0';
973 if (suspend_flag
!= 0)
976 if (!(ret
= net_os_set_suspend(dev
, suspend_flag
, 0)))
977 DHD_INFO(("%s: Suspend Mode %d\n", __FUNCTION__
, suspend_flag
));
979 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
985 int wl_android_get_80211_mode(struct net_device
*dev
, char *command
, int total_len
)
989 int bytes_written
= 0;
991 error
= wldev_get_mode(dev
, mode
, sizeof(mode
));
995 DHD_INFO(("%s: mode:%s\n", __FUNCTION__
, mode
));
996 bytes_written
= snprintf(command
, total_len
, "%s %s", CMD_80211_MODE
, mode
);
997 DHD_INFO(("%s: command:%s EXIT\n", __FUNCTION__
, command
));
998 return bytes_written
;
1003 wl_chspec_driver_to_host(chanspec_t chanspec
);
1004 int wl_android_get_chanspec(struct net_device
*dev
, char *command
, int total_len
)
1007 int bytes_written
= 0;
1013 chanspec_t chanspec
;
1018 error
= wldev_iovar_getint(dev
, "chanspec", &chsp
);
1022 chanspec
= wl_chspec_driver_to_host(chsp
);
1023 DHD_INFO(("%s:return value of chanspec:%x\n", __FUNCTION__
, chanspec
));
1025 channel
= chanspec
& WL_CHANSPEC_CHAN_MASK
;
1026 band
= chanspec
& WL_CHANSPEC_BAND_MASK
;
1027 bw
= chanspec
& WL_CHANSPEC_BW_MASK
;
1029 DHD_INFO(("%s:channel:%d band:%d bandwidth:%d\n", __FUNCTION__
, channel
, band
, bw
));
1031 if (bw
== WL_CHANSPEC_BW_80
)
1032 bw
= WL_CH_BANDWIDTH_80MHZ
;
1033 else if (bw
== WL_CHANSPEC_BW_40
)
1034 bw
= WL_CH_BANDWIDTH_40MHZ
;
1035 else if (bw
== WL_CHANSPEC_BW_20
)
1036 bw
= WL_CH_BANDWIDTH_20MHZ
;
1038 bw
= WL_CH_BANDWIDTH_20MHZ
;
1040 if (bw
== WL_CH_BANDWIDTH_40MHZ
) {
1041 if (CHSPEC_SB_UPPER(chanspec
)) {
1042 channel
+= CH_10MHZ_APART
;
1044 channel
-= CH_10MHZ_APART
;
1047 else if (bw
== WL_CH_BANDWIDTH_80MHZ
) {
1048 sb
= chanspec
& WL_CHANSPEC_CTL_SB_MASK
;
1049 if (sb
== WL_CHANSPEC_CTL_SB_LL
) {
1050 channel
-= (CH_10MHZ_APART
+ CH_20MHZ_APART
);
1051 } else if (sb
== WL_CHANSPEC_CTL_SB_LU
) {
1052 channel
-= CH_10MHZ_APART
;
1053 } else if (sb
== WL_CHANSPEC_CTL_SB_UL
) {
1054 channel
+= CH_10MHZ_APART
;
1056 /* WL_CHANSPEC_CTL_SB_UU */
1057 channel
+= (CH_10MHZ_APART
+ CH_20MHZ_APART
);
1060 bytes_written
= snprintf(command
, total_len
, "%s channel %d band %s bw %d", CMD_CHANSPEC
,
1061 channel
, band
== WL_CHANSPEC_BAND_5G
? "5G":"2G", bw
);
1063 DHD_INFO(("%s: command:%s EXIT\n", __FUNCTION__
, command
));
1064 return bytes_written
;
1068 /* returns current datarate datarate returned from firmware are in 500kbps */
1069 int wl_android_get_datarate(struct net_device
*dev
, char *command
, int total_len
)
1073 int bytes_written
= 0;
1075 error
= wldev_get_datarate(dev
, &datarate
);
1079 DHD_INFO(("%s:datarate:%d\n", __FUNCTION__
, datarate
));
1081 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_DATARATE
, (datarate
/2));
1082 return bytes_written
;
1084 int wl_android_get_assoclist(struct net_device
*dev
, char *command
, int total_len
)
1087 int bytes_written
= 0;
1090 char mac_buf
[MAX_NUM_OF_ASSOCLIST
*
1091 sizeof(struct ether_addr
) + sizeof(uint
)] = {0};
1092 struct maclist
*assoc_maclist
= (struct maclist
*)mac_buf
;
1094 DHD_TRACE(("%s: ENTER\n", __FUNCTION__
));
1096 assoc_maclist
->count
= htod32(MAX_NUM_OF_ASSOCLIST
);
1098 error
= wldev_ioctl_get(dev
, WLC_GET_ASSOCLIST
, assoc_maclist
, sizeof(mac_buf
));
1102 assoc_maclist
->count
= dtoh32(assoc_maclist
->count
);
1103 bytes_written
= snprintf(command
, total_len
, "%s listcount: %d Stations:",
1104 CMD_ASSOC_CLIENTS
, assoc_maclist
->count
);
1106 for (i
= 0; i
< assoc_maclist
->count
; i
++) {
1107 len
= snprintf(command
+ bytes_written
, total_len
- bytes_written
, " " MACDBG
,
1108 MAC2STRDBG(assoc_maclist
->ea
[i
].octet
));
1109 /* A return value of '(total_len - bytes_written)' or more means that the
1110 * output was truncated
1112 if ((len
> 0) && (len
< (total_len
- bytes_written
))) {
1113 bytes_written
+= len
;
1115 DHD_ERROR(("%s: Insufficient buffer %d, bytes_written %d\n",
1116 __FUNCTION__
, total_len
, bytes_written
));
1121 return bytes_written
;
1124 wl_chspec_host_to_driver(chanspec_t chanspec
);
1125 static int wl_android_set_csa(struct net_device
*dev
, char *command
)
1128 char smbuf
[WLC_IOCTL_SMLEN
];
1129 wl_chan_switch_t csa_arg
;
1133 DHD_INFO(("%s: command:%s\n", __FUNCTION__
, command
));
1135 command
= (command
+ strlen(CMD_SET_CSA
));
1136 /* Order is mode, count channel */
1138 DHD_ERROR(("%s:error missing arguments\n", __FUNCTION__
));
1141 csa_arg
.mode
= bcm_atoi(command
);
1143 if (csa_arg
.mode
!= 0 && csa_arg
.mode
!= 1) {
1144 DHD_ERROR(("Invalid mode\n"));
1149 DHD_ERROR(("%s:error missing count\n", __FUNCTION__
));
1153 csa_arg
.count
= bcm_atoi(command
);
1159 DHD_ERROR(("%s:error missing channel\n", __FUNCTION__
));
1163 chnsp
= wf_chspec_aton(command
);
1165 DHD_ERROR(("%s:chsp is not correct\n", __FUNCTION__
));
1168 chnsp
= wl_chspec_host_to_driver(chnsp
);
1169 csa_arg
.chspec
= chnsp
;
1171 if (chnsp
& WL_CHANSPEC_BAND_5G
) {
1172 u32 chanspec
= chnsp
;
1173 err
= wldev_iovar_getint(dev
, "per_chan_info", &chanspec
);
1175 if ((chanspec
& WL_CHAN_RADAR
) || (chanspec
& WL_CHAN_PASSIVE
)) {
1176 DHD_ERROR(("Channel is radar sensitive\n"));
1179 if (chanspec
== 0) {
1180 DHD_ERROR(("Invalid hw channel\n"));
1184 DHD_ERROR(("does not support per_chan_info\n"));
1187 DHD_INFO(("non radar sensitivity\n"));
1189 error
= wldev_iovar_setbuf(dev
, "csa", &csa_arg
, sizeof(csa_arg
),
1190 smbuf
, sizeof(smbuf
), NULL
);
1192 DHD_ERROR(("%s:set csa failed:%d\n", __FUNCTION__
, error
));
1199 wl_android_set_bcn_li_dtim(struct net_device
*dev
, char *command
)
1204 dtim
= *(command
+ strlen(CMD_SETDTIM_IN_SUSPEND
) + 1) - '0';
1206 if (dtim
> (MAX_DTIM_ALLOWED_INTERVAL
/ MAX_DTIM_SKIP_BEACON_INTERVAL
)) {
1207 DHD_ERROR(("%s: failed, invalid dtim %d\n",
1208 __FUNCTION__
, dtim
));
1212 if (!(ret
= net_os_set_suspend_bcn_li_dtim(dev
, dtim
))) {
1213 DHD_TRACE(("%s: SET bcn_li_dtim in suspend %d\n",
1214 __FUNCTION__
, dtim
));
1216 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
1223 wl_android_set_max_dtim(struct net_device
*dev
, char *command
)
1228 dtim_flag
= *(command
+ strlen(CMD_MAXDTIM_IN_SUSPEND
) + 1) - '0';
1230 if (!(ret
= net_os_set_max_dtim_enable(dev
, dtim_flag
))) {
1231 DHD_TRACE(("%s: use Max bcn_li_dtim in suspend %s\n",
1232 __FUNCTION__
, (dtim_flag
? "Enable" : "Disable")));
1234 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
1241 wl_android_set_disable_dtim_in_suspend(struct net_device
*dev
, char *command
)
1246 dtim_flag
= *(command
+ strlen(CMD_DISDTIM_IN_SUSPEND
) + 1) - '0';
1248 if (!(ret
= net_os_set_disable_dtim_in_suspend(dev
, dtim_flag
))) {
1249 DHD_TRACE(("%s: use Disable bcn_li_dtim in suspend %s\n",
1250 __FUNCTION__
, (dtim_flag
? "Enable" : "Disable")));
1252 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
1258 static int wl_android_get_band(struct net_device
*dev
, char *command
, int total_len
)
1264 error
= wldev_get_band(dev
, &band
);
1267 bytes_written
= snprintf(command
, total_len
, "Band %d", band
);
1268 return bytes_written
;
1272 wl_android_set_band(struct net_device
*dev
, char *command
)
1275 uint band
= *(command
+ strlen(CMD_SETBAND
) + 1) - '0';
1276 #ifdef WL_HOST_BAND_MGMT
1278 if ((ret
= wl_cfg80211_set_band(dev
, band
)) < 0) {
1279 if (ret
== BCME_UNSUPPORTED
) {
1280 /* If roam_var is unsupported, fallback to the original method */
1281 WL_ERR(("WL_HOST_BAND_MGMT defined, "
1282 "but roam_band iovar unsupported in the firmware\n"));
1287 if (((ret
== 0) && (band
== WLC_BAND_AUTO
)) || (ret
== BCME_UNSUPPORTED
)) {
1288 /* Apply if roam_band iovar is not supported or band setting is AUTO */
1289 error
= wldev_set_band(dev
, band
);
1292 error
= wl_cfg80211_set_if_band(dev
, band
);
1293 #endif /* WL_HOST_BAND_MGMT */
1294 #ifdef ROAM_CHANNEL_CACHE
1295 wl_update_roamscan_cache_by_band(dev
, band
);
1296 #endif /* ROAM_CHANNEL_CACHE */
1300 #ifdef CUSTOMER_HW4_PRIVATE_CMD
1302 static bool wl_android_check_wbtext(struct net_device
*dev
)
1304 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
1305 return dhdp
->wbtext_support
;
1308 static int wl_android_set_roam_trigger(
1309 struct net_device
*dev
, char* command
)
1311 int roam_trigger
[2] = {0, 0};
1315 if (wl_android_check_wbtext(dev
)) {
1316 WL_ERR(("blocked to set roam trigger. try with setting roam profile\n"));
1321 sscanf(command
, "%*s %10d", &roam_trigger
[0]);
1322 if (roam_trigger
[0] >= 0) {
1323 WL_ERR(("wrong roam trigger value (%d)\n", roam_trigger
[0]));
1327 roam_trigger
[1] = WLC_BAND_ALL
;
1328 error
= wldev_ioctl_set(dev
, WLC_SET_ROAM_TRIGGER
, roam_trigger
,
1329 sizeof(roam_trigger
));
1330 if (error
!= BCME_OK
) {
1331 WL_ERR(("failed to set roam trigger (%d)\n", error
));
1338 static int wl_android_get_roam_trigger(
1339 struct net_device
*dev
, char *command
, int total_len
)
1341 int bytes_written
, error
;
1342 int roam_trigger
[2] = {0, 0};
1345 chanspec_t chanspec
;
1347 struct wl_roam_prof_band_v2 rp
;
1348 char smbuf
[WLC_IOCTL_SMLEN
];
1350 error
= wldev_iovar_getint(dev
, "chanspec", &chsp
);
1351 if (error
!= BCME_OK
) {
1352 WL_ERR(("failed to get chanspec (%d)\n", error
));
1356 chanspec
= wl_chspec_driver_to_host(chsp
);
1357 band
= chanspec
& WL_CHANSPEC_BAND_MASK
;
1358 if (band
== WL_CHANSPEC_BAND_5G
)
1363 if (wl_android_check_wbtext(dev
)) {
1364 rp
.ver
= WL_MAX_ROAM_PROF_VER
;
1367 error
= wldev_iovar_getbuf(dev
, "roam_prof", &rp
, sizeof(rp
),
1368 smbuf
, sizeof(smbuf
), NULL
);
1369 if (error
!= BCME_OK
) {
1370 WL_ERR(("failed to get roam profile (%d)\n", error
));
1373 memcpy(&rp
, smbuf
, sizeof(struct wl_roam_prof_band_v2
));
1374 for (i
= 0; i
< WL_MAX_ROAM_PROF_BRACKETS
; i
++) {
1375 if (rp
.roam_prof
[i
].channel_usage
== 0) {
1376 roam_trigger
[0] = rp
.roam_prof
[i
].roam_trigger
;
1380 if (roam_trigger
[0] == 0) {
1381 WL_ERR(("roam trigger was not set properly\n"));
1385 roam_trigger
[1] = band
;
1386 error
= wldev_ioctl_get(dev
, WLC_GET_ROAM_TRIGGER
, roam_trigger
,
1387 sizeof(roam_trigger
));
1388 if (error
!= BCME_OK
) {
1389 WL_ERR(("failed to get roam trigger (%d)\n", error
));
1394 bytes_written
= snprintf(command
, total_len
, "%s %d",
1395 CMD_ROAMTRIGGER_GET
, roam_trigger
[0]);
1397 return bytes_written
;
1400 int wl_android_set_roam_delta(
1401 struct net_device
*dev
, char* command
)
1405 sscanf(command
, "%*s %10d", &roam_delta
[0]);
1406 roam_delta
[1] = WLC_BAND_ALL
;
1408 return wldev_ioctl_set(dev
, WLC_SET_ROAM_DELTA
, roam_delta
,
1409 sizeof(roam_delta
));
1412 static int wl_android_get_roam_delta(
1413 struct net_device
*dev
, char *command
, int total_len
)
1416 int roam_delta
[2] = {0, 0};
1418 roam_delta
[1] = WLC_BAND_2G
;
1419 if (wldev_ioctl_get(dev
, WLC_GET_ROAM_DELTA
, roam_delta
,
1420 sizeof(roam_delta
))) {
1421 roam_delta
[1] = WLC_BAND_5G
;
1422 if (wldev_ioctl_get(dev
, WLC_GET_ROAM_DELTA
, roam_delta
,
1423 sizeof(roam_delta
)))
1427 bytes_written
= snprintf(command
, total_len
, "%s %d",
1428 CMD_ROAMDELTA_GET
, roam_delta
[0]);
1430 return bytes_written
;
1433 int wl_android_set_roam_scan_period(
1434 struct net_device
*dev
, char* command
)
1436 int roam_scan_period
= 0;
1438 sscanf(command
, "%*s %10d", &roam_scan_period
);
1439 return wldev_ioctl_set(dev
, WLC_SET_ROAM_SCAN_PERIOD
, &roam_scan_period
,
1440 sizeof(roam_scan_period
));
1443 static int wl_android_get_roam_scan_period(
1444 struct net_device
*dev
, char *command
, int total_len
)
1447 int roam_scan_period
= 0;
1449 if (wldev_ioctl_get(dev
, WLC_GET_ROAM_SCAN_PERIOD
, &roam_scan_period
,
1450 sizeof(roam_scan_period
)))
1453 bytes_written
= snprintf(command
, total_len
, "%s %d",
1454 CMD_ROAMSCANPERIOD_GET
, roam_scan_period
);
1456 return bytes_written
;
1459 int wl_android_set_full_roam_scan_period(
1460 struct net_device
*dev
, char* command
, int total_len
)
1463 int full_roam_scan_period
= 0;
1464 char smbuf
[WLC_IOCTL_SMLEN
];
1466 sscanf(command
+sizeof("SETFULLROAMSCANPERIOD"), "%d", &full_roam_scan_period
);
1467 WL_TRACE(("fullroamperiod = %d\n", full_roam_scan_period
));
1469 error
= wldev_iovar_setbuf(dev
, "fullroamperiod", &full_roam_scan_period
,
1470 sizeof(full_roam_scan_period
), smbuf
, sizeof(smbuf
), NULL
);
1472 DHD_ERROR(("Failed to set full roam scan period, error = %d\n", error
));
1478 static int wl_android_get_full_roam_scan_period(
1479 struct net_device
*dev
, char *command
, int total_len
)
1483 int full_roam_scan_period
= 0;
1485 error
= wldev_iovar_getint(dev
, "fullroamperiod", &full_roam_scan_period
);
1488 DHD_ERROR(("%s: get full roam scan period failed code %d\n",
1492 DHD_INFO(("%s: get full roam scan period %d\n", __func__
, full_roam_scan_period
));
1495 bytes_written
= snprintf(command
, total_len
, "%s %d",
1496 CMD_FULLROAMSCANPERIOD_GET
, full_roam_scan_period
);
1498 return bytes_written
;
1501 int wl_android_set_country_rev(
1502 struct net_device
*dev
, char* command
)
1505 wl_country_t cspec
= {{0}, 0, {0} };
1506 char country_code
[WLC_CNTRY_BUF_SZ
];
1507 char smbuf
[WLC_IOCTL_SMLEN
];
1510 memset(country_code
, 0, sizeof(country_code
));
1511 sscanf(command
+sizeof("SETCOUNTRYREV"), "%3s %10d", country_code
, &rev
);
1512 WL_TRACE(("country_code = %s, rev = %d\n", country_code
, rev
));
1514 memcpy(cspec
.country_abbrev
, country_code
, sizeof(country_code
));
1515 memcpy(cspec
.ccode
, country_code
, sizeof(country_code
));
1518 error
= wldev_iovar_setbuf(dev
, "country", (char *)&cspec
,
1519 sizeof(cspec
), smbuf
, sizeof(smbuf
), NULL
);
1522 DHD_ERROR(("%s: set country '%s/%d' failed code %d\n",
1523 __FUNCTION__
, cspec
.ccode
, cspec
.rev
, error
));
1525 dhd_bus_country_set(dev
, &cspec
, true);
1526 DHD_INFO(("%s: set country '%s/%d'\n",
1527 __FUNCTION__
, cspec
.ccode
, cspec
.rev
));
1533 static int wl_android_get_country_rev(
1534 struct net_device
*dev
, char *command
, int total_len
)
1538 char smbuf
[WLC_IOCTL_SMLEN
];
1541 error
= wldev_iovar_getbuf(dev
, "country", NULL
, 0, smbuf
,
1542 sizeof(smbuf
), NULL
);
1545 DHD_ERROR(("%s: get country failed code %d\n",
1546 __FUNCTION__
, error
));
1549 memcpy(&cspec
, smbuf
, sizeof(cspec
));
1550 DHD_INFO(("%s: get country '%c%c %d'\n",
1551 __FUNCTION__
, cspec
.ccode
[0], cspec
.ccode
[1], cspec
.rev
));
1554 bytes_written
= snprintf(command
, total_len
, "%s %c%c %d",
1555 CMD_COUNTRYREV_GET
, cspec
.ccode
[0], cspec
.ccode
[1], cspec
.rev
);
1557 return bytes_written
;
1559 #endif /* ROAM_API */
1562 int wl_android_get_roam_scan_control(struct net_device
*dev
, char *command
, int total_len
)
1565 int bytes_written
= 0;
1568 error
= get_roamscan_mode(dev
, &mode
);
1570 DHD_ERROR(("%s: Failed to get Scan Control, error = %d\n", __FUNCTION__
, error
));
1574 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETROAMSCANCONTROL
, mode
);
1576 return bytes_written
;
1579 int wl_android_set_roam_scan_control(struct net_device
*dev
, char *command
)
1584 if (sscanf(command
, "%*s %d", &mode
) != 1) {
1585 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1589 error
= set_roamscan_mode(dev
, mode
);
1591 DHD_ERROR(("%s: Failed to set Scan Control %d, error = %d\n",
1592 __FUNCTION__
, mode
, error
));
1599 int wl_android_get_roam_scan_channels(struct net_device
*dev
, char *command
, int total_len
)
1601 int bytes_written
= 0;
1602 unsigned char channels
[MAX_ROAM_CHANNEL
] = {0};
1603 int channel_cnt
= 0;
1607 channel_cnt
= get_roamscan_channel_list(dev
, channels
, MAX_ROAM_CHANNEL
);
1608 bytes_written
= snprintf(command
, total_len
, "%s %d",
1609 CMD_GETROAMSCANCHANNELS
, channel_cnt
);
1610 buf_avail
= total_len
- bytes_written
;
1611 for (i
= 0; i
< channel_cnt
; i
++) {
1612 /* A return value of 'buf_avail' or more means that the output was truncated */
1613 len
= snprintf(command
+ bytes_written
, buf_avail
, " %d", channels
[i
]);
1614 if (len
>= buf_avail
) {
1615 WL_ERR(("%s: Insufficient memory, %d bytes\n", __FUNCTION__
, total_len
));
1619 /* 'buf_avail' decremented by number of bytes written */
1621 bytes_written
+= len
;
1623 WL_INFORM(("%s: %s\n", __FUNCTION__
, command
));
1624 return bytes_written
;
1627 int wl_android_set_roam_scan_channels(struct net_device
*dev
, char *command
)
1630 unsigned char *p
= (unsigned char *)(command
+ strlen(CMD_SETROAMSCANCHANNELS
) + 1);
1631 int get_ioctl_version
= wl_cfg80211_get_ioctl_version();
1632 error
= set_roamscan_channel_list(dev
, p
[0], &p
[1], get_ioctl_version
);
1634 DHD_ERROR(("%s: Failed to set Scan Channels %d, error = %d\n",
1635 __FUNCTION__
, p
[0], error
));
1642 int wl_android_get_scan_channel_time(struct net_device
*dev
, char *command
, int total_len
)
1645 int bytes_written
= 0;
1648 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_CHANNEL_TIME
, &time
, sizeof(time
));
1650 DHD_ERROR(("%s: Failed to get Scan Channel Time, error = %d\n",
1651 __FUNCTION__
, error
));
1655 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANCHANNELTIME
, time
);
1657 return bytes_written
;
1660 int wl_android_set_scan_channel_time(struct net_device
*dev
, char *command
)
1665 if (sscanf(command
, "%*s %d", &time
) != 1) {
1666 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1669 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1670 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_CHANNEL_TIME
, time
);
1671 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_CHANNEL_TIME
, &time
, sizeof(time
));
1672 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1674 DHD_ERROR(("%s: Failed to set Scan Channel Time %d, error = %d\n",
1675 __FUNCTION__
, time
, error
));
1683 wl_android_get_scan_unassoc_time(struct net_device
*dev
, char *command
, int total_len
)
1686 int bytes_written
= 0;
1689 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_UNASSOC_TIME
, &time
, sizeof(time
));
1691 DHD_ERROR(("%s: Failed to get Scan Unassoc Time, error = %d\n",
1692 __FUNCTION__
, error
));
1696 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANUNASSOCTIME
, time
);
1698 return bytes_written
;
1702 wl_android_set_scan_unassoc_time(struct net_device
*dev
, char *command
)
1707 if (sscanf(command
, "%*s %d", &time
) != 1) {
1708 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1711 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1712 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_UNASSOC_TIME
, time
);
1713 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_UNASSOC_TIME
, &time
, sizeof(time
));
1714 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1716 DHD_ERROR(("%s: Failed to set Scan Unassoc Time %d, error = %d\n",
1717 __FUNCTION__
, time
, error
));
1725 wl_android_get_scan_passive_time(struct net_device
*dev
, char *command
, int total_len
)
1728 int bytes_written
= 0;
1731 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_PASSIVE_TIME
, &time
, sizeof(time
));
1733 DHD_ERROR(("%s: Failed to get Scan Passive Time, error = %d\n",
1734 __FUNCTION__
, error
));
1738 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANPASSIVETIME
, time
);
1740 return bytes_written
;
1744 wl_android_set_scan_passive_time(struct net_device
*dev
, char *command
)
1749 if (sscanf(command
, "%*s %d", &time
) != 1) {
1750 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1753 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1754 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_PASSIVE_TIME
, time
);
1755 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_PASSIVE_TIME
, &time
, sizeof(time
));
1756 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1758 DHD_ERROR(("%s: Failed to set Scan Passive Time %d, error = %d\n",
1759 __FUNCTION__
, time
, error
));
1766 int wl_android_get_scan_home_time(struct net_device
*dev
, char *command
, int total_len
)
1769 int bytes_written
= 0;
1772 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_HOME_TIME
, &time
, sizeof(time
));
1774 DHD_ERROR(("Failed to get Scan Home Time, error = %d\n", error
));
1778 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANHOMETIME
, time
);
1780 return bytes_written
;
1783 int wl_android_set_scan_home_time(struct net_device
*dev
, char *command
)
1788 if (sscanf(command
, "%*s %d", &time
) != 1) {
1789 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1792 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1793 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_HOME_TIME
, time
);
1794 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_HOME_TIME
, &time
, sizeof(time
));
1795 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1797 DHD_ERROR(("%s: Failed to set Scan Home Time %d, error = %d\n",
1798 __FUNCTION__
, time
, error
));
1805 int wl_android_get_scan_home_away_time(struct net_device
*dev
, char *command
, int total_len
)
1808 int bytes_written
= 0;
1811 error
= wldev_iovar_getint(dev
, "scan_home_away_time", &time
);
1813 DHD_ERROR(("%s: Failed to get Scan Home Away Time, error = %d\n",
1814 __FUNCTION__
, error
));
1818 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANHOMEAWAYTIME
, time
);
1820 return bytes_written
;
1823 int wl_android_set_scan_home_away_time(struct net_device
*dev
, char *command
)
1828 if (sscanf(command
, "%*s %d", &time
) != 1) {
1829 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1832 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1833 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_HOME_AWAY_TIME
, time
);
1834 error
= wldev_iovar_setint(dev
, "scan_home_away_time", time
);
1835 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1837 DHD_ERROR(("%s: Failed to set Scan Home Away Time %d, error = %d\n",
1838 __FUNCTION__
, time
, error
));
1845 int wl_android_get_scan_nprobes(struct net_device
*dev
, char *command
, int total_len
)
1848 int bytes_written
= 0;
1851 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_NPROBES
, &num
, sizeof(num
));
1853 DHD_ERROR(("%s: Failed to get Scan NProbes, error = %d\n", __FUNCTION__
, error
));
1857 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANNPROBES
, num
);
1859 return bytes_written
;
1862 int wl_android_set_scan_nprobes(struct net_device
*dev
, char *command
)
1867 if (sscanf(command
, "%*s %d", &num
) != 1) {
1868 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1872 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_NPROBES
, &num
, sizeof(num
));
1874 DHD_ERROR(("%s: Failed to set Scan NProbes %d, error = %d\n",
1875 __FUNCTION__
, num
, error
));
1882 int wl_android_get_scan_dfs_channel_mode(struct net_device
*dev
, char *command
, int total_len
)
1885 int bytes_written
= 0;
1887 int scan_passive_time
= 0;
1889 error
= wldev_iovar_getint(dev
, "scan_passive_time", &scan_passive_time
);
1891 DHD_ERROR(("%s: Failed to get Passive Time, error = %d\n", __FUNCTION__
, error
));
1895 if (scan_passive_time
== 0) {
1901 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETDFSSCANMODE
, mode
);
1903 return bytes_written
;
1906 int wl_android_set_scan_dfs_channel_mode(struct net_device
*dev
, char *command
)
1910 int scan_passive_time
= 0;
1912 if (sscanf(command
, "%*s %d", &mode
) != 1) {
1913 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1918 scan_passive_time
= DHD_SCAN_PASSIVE_TIME
;
1919 } else if (mode
== 0) {
1920 scan_passive_time
= 0;
1922 DHD_ERROR(("%s: Failed to set Scan DFS channel mode %d, error = %d\n",
1923 __FUNCTION__
, mode
, error
));
1926 error
= wldev_iovar_setint(dev
, "scan_passive_time", scan_passive_time
);
1928 DHD_ERROR(("%s: Failed to set Scan Passive Time %d, error = %d\n",
1929 __FUNCTION__
, scan_passive_time
, error
));
1936 #define JOINPREFFER_BUF_SIZE 12
1939 wl_android_set_join_prefer(struct net_device
*dev
, char *command
)
1941 int error
= BCME_OK
;
1942 char smbuf
[WLC_IOCTL_SMLEN
];
1943 uint8 buf
[JOINPREFFER_BUF_SIZE
];
1949 char commandp
[WLC_IOCTL_SMLEN
];
1950 char clear
[] = { 0x01, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00 };
1953 pcmd
= command
+ strlen(CMD_SETJOINPREFER
) + 1;
1954 total_len_left
= strlen(pcmd
);
1956 memset(buf
, 0, sizeof(buf
));
1958 if (total_len_left
!= JOINPREFFER_BUF_SIZE
<< 1) {
1959 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1963 /* Store the MSB first, as required by join_pref */
1964 for (i
= 0; i
< JOINPREFFER_BUF_SIZE
; i
++) {
1967 buf
[i
] = (uint8
)simple_strtoul(hex
, NULL
, 16);
1971 /* No coexistance between 11kv and join pref */
1972 if (wl_android_check_wbtext(dev
)) {
1973 memset(commandp
, 0, sizeof(commandp
));
1974 if (memcmp(buf
, clear
, sizeof(buf
)) == 0) {
1975 snprintf(commandp
, WLC_IOCTL_SMLEN
, "WBTEXT_ENABLE 1");
1977 snprintf(commandp
, WLC_IOCTL_SMLEN
, "WBTEXT_ENABLE 0");
1979 if ((error
= wl_android_wbtext(dev
, commandp
, WLC_IOCTL_SMLEN
)) != BCME_OK
) {
1980 DHD_ERROR(("Failed to set WBTEXT = %d\n", error
));
1986 prhex("join pref", (uint8
*)buf
, JOINPREFFER_BUF_SIZE
);
1987 error
= wldev_iovar_setbuf(dev
, "join_pref", buf
, JOINPREFFER_BUF_SIZE
,
1988 smbuf
, sizeof(smbuf
), NULL
);
1990 DHD_ERROR(("Failed to set join_pref, error = %d\n", error
));
1996 int wl_android_send_action_frame(struct net_device
*dev
, char *command
, int total_len
)
1999 android_wifi_af_params_t
*params
= NULL
;
2000 wl_action_frame_t
*action_frame
= NULL
;
2001 wl_af_params_t
*af_params
= NULL
;
2003 struct ether_addr tmp_bssid
;
2004 int tmp_channel
= 0;
2005 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
2008 (strlen(CMD_SENDACTIONFRAME
) + 1 + sizeof(android_wifi_af_params_t
))) {
2009 DHD_ERROR(("%s: Invalid parameters \n", __FUNCTION__
));
2010 goto send_action_frame_out
;
2013 params
= (android_wifi_af_params_t
*)(command
+ strlen(CMD_SENDACTIONFRAME
) + 1);
2015 if ((uint16
)params
->len
> ANDROID_WIFI_ACTION_FRAME_SIZE
) {
2016 DHD_ERROR(("%s: Requested action frame len was out of range(%d)\n",
2017 __FUNCTION__
, params
->len
));
2018 goto send_action_frame_out
;
2021 smbuf
= (char *)MALLOC(cfg
->osh
, WLC_IOCTL_MAXLEN
);
2022 if (smbuf
== NULL
) {
2023 DHD_ERROR(("%s: failed to allocated memory %d bytes\n",
2024 __FUNCTION__
, WLC_IOCTL_MAXLEN
));
2025 goto send_action_frame_out
;
2028 af_params
= (wl_af_params_t
*)MALLOCZ(cfg
->osh
, WL_WIFI_AF_PARAMS_SIZE
);
2029 if (af_params
== NULL
) {
2030 DHD_ERROR(("%s: unable to allocate frame\n", __FUNCTION__
));
2031 goto send_action_frame_out
;
2034 memset(&tmp_bssid
, 0, ETHER_ADDR_LEN
);
2035 if (bcm_ether_atoe((const char *)params
->bssid
, (struct ether_addr
*)&tmp_bssid
) == 0) {
2036 memset(&tmp_bssid
, 0, ETHER_ADDR_LEN
);
2038 error
= wldev_ioctl_get(dev
, WLC_GET_BSSID
, &tmp_bssid
, ETHER_ADDR_LEN
);
2040 memset(&tmp_bssid
, 0, ETHER_ADDR_LEN
);
2041 DHD_ERROR(("%s: failed to get bssid, error=%d\n", __FUNCTION__
, error
));
2042 goto send_action_frame_out
;
2046 if (params
->channel
< 0) {
2047 struct channel_info ci
;
2048 memset(&ci
, 0, sizeof(ci
));
2049 error
= wldev_ioctl_get(dev
, WLC_GET_CHANNEL
, &ci
, sizeof(ci
));
2051 DHD_ERROR(("%s: failed to get channel, error=%d\n", __FUNCTION__
, error
));
2052 goto send_action_frame_out
;
2055 tmp_channel
= ci
.hw_channel
;
2058 tmp_channel
= params
->channel
;
2061 af_params
->channel
= tmp_channel
;
2062 af_params
->dwell_time
= params
->dwell_time
;
2063 memcpy(&af_params
->BSSID
, &tmp_bssid
, ETHER_ADDR_LEN
);
2064 action_frame
= &af_params
->action_frame
;
2066 action_frame
->packetId
= 0;
2067 memcpy(&action_frame
->da
, &tmp_bssid
, ETHER_ADDR_LEN
);
2068 action_frame
->len
= (uint16
)params
->len
;
2069 memcpy(action_frame
->data
, params
->data
, action_frame
->len
);
2071 error
= wldev_iovar_setbuf(dev
, "actframe", af_params
,
2072 sizeof(wl_af_params_t
), smbuf
, WLC_IOCTL_MAXLEN
, NULL
);
2074 DHD_ERROR(("%s: failed to set action frame, error=%d\n", __FUNCTION__
, error
));
2077 send_action_frame_out
:
2079 MFREE(cfg
->osh
, af_params
, WL_WIFI_AF_PARAMS_SIZE
);
2083 MFREE(cfg
->osh
, smbuf
, WLC_IOCTL_MAXLEN
);
2092 int wl_android_reassoc(struct net_device
*dev
, char *command
, int total_len
)
2095 android_wifi_reassoc_params_t
*params
= NULL
;
2099 wl_reassoc_params_t reassoc_params
;
2102 (strlen(CMD_REASSOC
) + 1 + sizeof(android_wifi_reassoc_params_t
))) {
2103 DHD_ERROR(("%s: Invalid parameters \n", __FUNCTION__
));
2106 params
= (android_wifi_reassoc_params_t
*)(command
+ strlen(CMD_REASSOC
) + 1);
2108 memset(&reassoc_params
, 0, WL_REASSOC_PARAMS_FIXED_SIZE
);
2110 if (bcm_ether_atoe((const char *)params
->bssid
,
2111 (struct ether_addr
*)&reassoc_params
.bssid
) == 0) {
2112 DHD_ERROR(("%s: Invalid bssid \n", __FUNCTION__
));
2116 if (params
->channel
< 0) {
2117 DHD_ERROR(("%s: Invalid Channel \n", __FUNCTION__
));
2121 reassoc_params
.chanspec_num
= 1;
2123 channel
= params
->channel
;
2124 #ifdef D11AC_IOTYPES
2125 if (wl_cfg80211_get_ioctl_version() == 1) {
2126 band
= ((channel
<= CH_MAX_2G_CHANNEL
) ?
2127 WL_LCHANSPEC_BAND_2G
: WL_LCHANSPEC_BAND_5G
);
2128 reassoc_params
.chanspec_list
[0] = channel
|
2129 band
| WL_LCHANSPEC_BW_20
| WL_LCHANSPEC_CTL_SB_NONE
;
2132 band
= ((channel
<= CH_MAX_2G_CHANNEL
) ? WL_CHANSPEC_BAND_2G
: WL_CHANSPEC_BAND_5G
);
2133 reassoc_params
.chanspec_list
[0] = channel
| band
| WL_CHANSPEC_BW_20
;
2136 band
= ((channel
<= CH_MAX_2G_CHANNEL
) ? WL_CHANSPEC_BAND_2G
: WL_CHANSPEC_BAND_5G
);
2137 reassoc_params
.chanspec_list
[0] = channel
|
2138 band
| WL_CHANSPEC_BW_20
| WL_CHANSPEC_CTL_SB_NONE
;
2139 #endif /* D11AC_IOTYPES */
2140 params_size
= WL_REASSOC_PARAMS_FIXED_SIZE
+ sizeof(chanspec_t
);
2142 error
= wldev_ioctl_set(dev
, WLC_REASSOC
, &reassoc_params
, params_size
);
2144 DHD_ERROR(("%s: failed to reassoc, error=%d\n", __FUNCTION__
, error
));
2150 int wl_android_get_wes_mode(struct net_device
*dev
, char *command
, int total_len
)
2152 int bytes_written
= 0;
2155 mode
= wl_cfg80211_get_wes_mode();
2157 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETWESMODE
, mode
);
2159 return bytes_written
;
2162 int wl_android_set_wes_mode(struct net_device
*dev
, char *command
)
2167 char commandp
[WLC_IOCTL_SMLEN
];
2170 if (sscanf(command
, "%*s %d", &mode
) != 1) {
2171 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
2175 error
= wl_cfg80211_set_wes_mode(mode
);
2177 DHD_ERROR(("%s: Failed to set WES Mode %d, error = %d\n",
2178 __FUNCTION__
, mode
, error
));
2183 /* No coexistance between 11kv and FMC */
2184 if (wl_android_check_wbtext(dev
)) {
2185 memset(commandp
, 0, sizeof(commandp
));
2187 snprintf(commandp
, WLC_IOCTL_SMLEN
, "WBTEXT_ENABLE 1");
2189 snprintf(commandp
, WLC_IOCTL_SMLEN
, "WBTEXT_ENABLE 0");
2191 if ((error
= wl_android_wbtext(dev
, commandp
, WLC_IOCTL_SMLEN
)) != BCME_OK
) {
2192 DHD_ERROR(("Failed to set WBTEXT = %d\n", error
));
2201 int wl_android_get_okc_mode(struct net_device
*dev
, char *command
, int total_len
)
2204 int bytes_written
= 0;
2207 error
= wldev_iovar_getint(dev
, "okc_enable", &mode
);
2209 DHD_ERROR(("%s: Failed to get OKC Mode, error = %d\n", __FUNCTION__
, error
));
2213 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETOKCMODE
, mode
);
2215 return bytes_written
;
2218 int wl_android_set_okc_mode(struct net_device
*dev
, char *command
)
2223 if (sscanf(command
, "%*s %d", &mode
) != 1) {
2224 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
2228 error
= wldev_iovar_setint(dev
, "okc_enable", mode
);
2230 DHD_ERROR(("%s: Failed to set OKC Mode %d, error = %d\n",
2231 __FUNCTION__
, mode
, error
));
2238 wl_android_set_pmk(struct net_device
*dev
, char *command
, int total_len
)
2242 char smbuf
[WLC_IOCTL_SMLEN
];
2247 if (total_len
< (strlen("SET_PMK ") + 32)) {
2248 DHD_ERROR(("%s: Invalid argument\n", __FUNCTION__
));
2251 bzero(pmk
, sizeof(pmk
));
2252 memcpy((char *)pmk
, command
+ strlen("SET_PMK "), 32);
2253 error
= wldev_iovar_setbuf(dev
, "okc_info_pmk", pmk
, 32, smbuf
, sizeof(smbuf
), NULL
);
2255 DHD_ERROR(("Failed to set PMK for OKC, error = %d\n", error
));
2258 DHD_ERROR(("PMK is "));
2259 for (i
= 0; i
< 32; i
++)
2260 DHD_ERROR(("%02X ", pmk
[i
]));
2268 wl_android_okc_enable(struct net_device
*dev
, char *command
)
2271 char okc_enable
= 0;
2273 okc_enable
= command
[strlen(CMD_OKC_ENABLE
) + 1] - '0';
2274 error
= wldev_iovar_setint(dev
, "okc_enable", okc_enable
);
2276 DHD_ERROR(("Failed to %s OKC, error = %d\n",
2277 okc_enable
? "enable" : "disable", error
));
2282 #endif /* WES_SUPPORT */
2284 #ifdef SUPPORT_RESTORE_SCAN_PARAMS
2286 wl_android_restore_scan_params(struct net_device
*dev
, char *command
, int total_len
)
2291 char restore_command
[WLC_IOCTL_SMLEN
];
2293 while (strlen(restore_params
[cnt
].command
) > 0 && restore_params
[cnt
].cmd_handler
) {
2294 sprintf(restore_command
, "%s %d", restore_params
[cnt
].command
,
2295 restore_params
[cnt
].parameter
);
2296 printk("CNT : %d\n", cnt
);
2297 printk("COMMAND : %s\n", restore_command
);
2298 if (restore_params
[cnt
].cmd_type
== RESTORE_TYPE_PRIV_CMD
) {
2299 error
= restore_params
[cnt
].cmd_handler(dev
, restore_command
);
2300 } else if (restore_params
[cnt
].cmd_type
== RESTORE_TYPE_PRIV_CMD_WITH_LEN
) {
2301 error
= restore_params
[cnt
].cmd_handler_w_len(dev
,
2302 restore_command
, total_len
);
2304 DHD_ERROR(("Unknown restore command handler\n"));
2308 DHD_ERROR(("Failed to restore scan parameters %s, error : %d\n",
2309 restore_command
, error
));
2314 if (error_cnt
> 0) {
2315 DHD_ERROR(("Got %d error(s) while restoring scan parameters\n",
2321 #endif /* SUPPORT_RESTORE_SCAN_PARAMS */
2324 int wl_android_tdls_reset(struct net_device
*dev
)
2327 ret
= dhd_tdls_enable(dev
, false, false, NULL
);
2329 DHD_ERROR(("Disable tdls failed. %d\n", ret
));
2332 ret
= dhd_tdls_enable(dev
, true, true, NULL
);
2334 DHD_ERROR(("enable tdls failed. %d\n", ret
));
2340 #ifdef FCC_PWR_LIMIT_2G
2342 wl_android_set_fcc_pwr_limit_2g(struct net_device
*dev
, char *command
)
2347 sscanf(command
+sizeof("SET_FCC_CHANNEL"), "%d", &enable
);
2349 if ((enable
!= CUSTOMER_HW4_ENABLE
) && (enable
!= CUSTOMER_HW4_DISABLE
)) {
2350 DHD_ERROR(("%s: Invalid data\n", __FUNCTION__
));
2354 CUSTOMER_HW4_EN_CONVERT(enable
);
2356 DHD_ERROR(("%s: fccpwrlimit2g set (%d)\n", __FUNCTION__
, enable
));
2357 error
= wldev_iovar_setint(dev
, "fccpwrlimit2g", enable
);
2359 DHD_ERROR(("%s: fccpwrlimit2g set returned (%d)\n", __FUNCTION__
, error
));
2367 wl_android_get_fcc_pwr_limit_2g(struct net_device
*dev
, char *command
, int total_len
)
2371 int bytes_written
= 0;
2373 error
= wldev_iovar_getint(dev
, "fccpwrlimit2g", &enable
);
2375 DHD_ERROR(("%s: fccpwrlimit2g get error (%d)\n", __FUNCTION__
, error
));
2378 DHD_ERROR(("%s: fccpwrlimit2g get (%d)\n", __FUNCTION__
, enable
));
2380 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_FCC_PWR_LIMIT_2G
, enable
);
2382 return bytes_written
;
2384 #endif /* FCC_PWR_LIMIT_2G */
2387 wl_cfg80211_get_sta_info(struct net_device
*dev
, char* command
, int total_len
)
2389 int bytes_written
= -1, ret
= 0;
2390 char *pcmd
= command
;
2392 sta_info_v4_t
*sta
= NULL
;
2393 const wl_cnt_wlc_t
* wlc_cnt
= NULL
;
2394 struct ether_addr mac
;
2396 /* Client information */
2400 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
2402 #ifdef BIGDATA_SOFTAP
2404 int get_bigdata_softap
= FALSE
;
2405 wl_ap_sta_data_t
*sta_data
= NULL
;
2406 struct bcm_cfg80211
*bcm_cfg
= wl_get_cfg(dev
);
2407 #endif /* BIGDATA_SOFTAP */
2409 WL_DBG(("%s\n", command
));
2411 iovar_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MAXLEN
);
2412 if (iovar_buf
== NULL
) {
2413 DHD_ERROR(("%s: failed to allocated memory %d bytes\n",
2414 __FUNCTION__
, WLC_IOCTL_MAXLEN
));
2418 str
= bcmstrtok(&pcmd
, " ", NULL
);
2420 str
= bcmstrtok(&pcmd
, " ", NULL
);
2421 /* If GETSTAINFO subcmd name is not provided, return error */
2423 WL_ERR(("GETSTAINFO subcmd not provided %s\n", __FUNCTION__
));
2427 memset(&mac
, 0, ETHER_ADDR_LEN
);
2428 if ((bcm_ether_atoe((str
), &mac
))) {
2429 /* get the sta info */
2430 ret
= wldev_iovar_getbuf(dev
, "sta_info",
2431 (struct ether_addr
*)mac
.octet
,
2432 ETHER_ADDR_LEN
, iovar_buf
, WLC_IOCTL_SMLEN
, NULL
);
2433 #ifdef BIGDATA_SOFTAP
2434 get_bigdata_softap
= TRUE
;
2435 #endif /* BIGDATA_SOFTAP */
2437 WL_ERR(("Get sta_info ERR %d\n", ret
));
2438 #ifdef BIGDATA_SOFTAP
2441 /* In case framework assumes the BIGDATA_SOFTAP
2442 * is enabled in DHD, the return value causes
2443 * triggering HANG event.
2445 bytes_written
= BCME_UNSUPPORTED
;
2447 #endif /* BIGDATA_SOFTAP */
2450 sta
= (sta_info_v4_t
*)iovar_buf
;
2451 if (dtoh16(sta
->ver
) != WL_STA_VER_4
) {
2452 WL_ERR(("sta_info struct version mismatch, "
2453 "host ver : %d, fw ver : %d\n", WL_STA_VER_4
,
2457 cap
= dtoh16(sta
->cap
);
2458 rxrtry
= dtoh32(sta
->rx_pkts_retried
);
2459 rxmulti
= dtoh32(sta
->rx_mcast_pkts
);
2460 } else if ((!strncmp(str
, "all", 3)) || (!strncmp(str
, "ALL", 3))) {
2461 /* get counters info */
2462 ret
= wldev_iovar_getbuf(dev
, "counters", NULL
, 0,
2463 iovar_buf
, WLC_IOCTL_MAXLEN
, NULL
);
2464 if (unlikely(ret
)) {
2465 WL_ERR(("counters error (%d) - size = %zu\n",
2466 ret
, sizeof(wl_cnt_wlc_t
)));
2469 ret
= wl_cntbuf_to_xtlv_format(NULL
, iovar_buf
, WL_CNTBUF_MAX_SIZE
, 0);
2470 if (ret
!= BCME_OK
) {
2471 WL_ERR(("wl_cntbuf_to_xtlv_format ERR %d\n", ret
));
2474 if (!(wlc_cnt
= GET_WLCCNT_FROM_CNTBUF(iovar_buf
))) {
2475 WL_ERR(("wlc_cnt NULL!\n"));
2479 rxrtry
= dtoh32(wlc_cnt
->rxrtry
);
2480 rxmulti
= dtoh32(wlc_cnt
->rxmulti
);
2482 WL_ERR(("Get address fail\n"));
2486 WL_ERR(("Command ERR\n"));
2490 #ifdef BIGDATA_SOFTAP
2492 if (get_bigdata_softap
) {
2493 WL_ERR(("mac " MACDBG
" \n", MAC2STRDBG((char*)&mac
)));
2494 if (wl_get_ap_stadata(bcm_cfg
, &mac
, &data
) == BCME_OK
) {
2495 sta_data
= (wl_ap_sta_data_t
*)data
;
2496 bytes_written
= snprintf(command
, total_len
,
2497 "%s %s Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d "
2498 "CAP=%04x "MACOUI
" %d %s %d %d %d %d %d %d\n",
2499 CMD_GET_STA_INFO
, str
, rxrtry
, rxmulti
, cap
,
2500 MACOUI2STR((char*)&sta_data
->mac
),
2502 wf_chspec_to_bw_str(sta_data
->chanspec
),
2503 sta_data
->rssi
, sta_data
->rate
,
2504 sta_data
->mode_80211
, sta_data
->nss
, sta_data
->mimo
,
2505 sta_data
->reason_code
);
2506 WL_ERR_KERN(("command %s\n", command
));
2510 #endif /* BIGDATA_SOFTAP */
2511 bytes_written
= snprintf(command
, total_len
,
2512 "%s %s Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d CAP=%04x\n",
2513 CMD_GET_STA_INFO
, str
, rxrtry
, rxmulti
, cap
);
2515 WL_DBG(("%s", command
));
2519 MFREE(cfg
->osh
, iovar_buf
, WLC_IOCTL_MAXLEN
);
2522 return bytes_written
;
2524 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
2527 static int wl_android_wbtext(struct net_device
*dev
, char *command
, int total_len
)
2529 int error
= BCME_OK
, argc
= 0;
2530 int data
, bytes_written
;
2531 int roam_trigger
[2];
2532 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
2534 argc
= sscanf(command
+sizeof(CMD_WBTEXT_ENABLE
), "%d", &data
);
2536 error
= wldev_iovar_getint(dev
, "wnm_bsstrans_resp", &data
);
2538 DHD_ERROR(("%s: Failed to set wbtext error = %d\n",
2539 __FUNCTION__
, error
));
2542 bytes_written
= snprintf(command
, total_len
, "WBTEXT %s\n",
2543 (data
== WL_BSSTRANS_POLICY_PRODUCT_WBTEXT
)?
2544 "ENABLED" : "DISABLED");
2545 return bytes_written
;
2548 data
= WL_BSSTRANS_POLICY_PRODUCT_WBTEXT
;
2551 if ((error
= wldev_iovar_setint(dev
, "wnm_bsstrans_resp", data
)) != BCME_OK
) {
2552 DHD_ERROR(("%s: Failed to set wbtext error = %d\n",
2553 __FUNCTION__
, error
));
2558 /* reset roam_prof when wbtext is on */
2559 if ((error
= wl_cfg80211_wbtext_set_default(dev
)) != BCME_OK
) {
2562 dhdp
->wbtext_support
= TRUE
;
2564 /* reset legacy roam trigger when wbtext is off */
2565 roam_trigger
[0] = DEFAULT_ROAM_TRIGGER_VALUE
;
2566 roam_trigger
[1] = WLC_BAND_ALL
;
2567 if ((error
= wldev_ioctl_set(dev
, WLC_SET_ROAM_TRIGGER
, roam_trigger
,
2568 sizeof(roam_trigger
))) != BCME_OK
) {
2569 DHD_ERROR(("%s: Failed to reset roam trigger = %d\n",
2570 __FUNCTION__
, error
));
2573 dhdp
->wbtext_support
= FALSE
;
2579 static int wl_cfg80211_wbtext_btm_timer_threshold(struct net_device
*dev
,
2580 char *command
, int total_len
)
2582 int error
= BCME_OK
, argc
= 0;
2583 int data
, bytes_written
;
2585 argc
= sscanf(command
, CMD_WBTEXT_BTM_TIMER_THRESHOLD
" %d\n", &data
);
2587 error
= wldev_iovar_getint(dev
, "wnm_bsstrans_timer_threshold", &data
);
2589 WL_ERR(("Failed to get wnm_bsstrans_timer_threshold (%d)\n", error
));
2592 bytes_written
= snprintf(command
, total_len
, "%d\n", data
);
2593 return bytes_written
;
2595 if ((error
= wldev_iovar_setint(dev
, "wnm_bsstrans_timer_threshold",
2596 data
)) != BCME_OK
) {
2597 WL_ERR(("Failed to set wnm_bsstrans_timer_threshold (%d)\n", error
));
2604 static int wl_cfg80211_wbtext_btm_delta(struct net_device
*dev
,
2605 char *command
, int total_len
)
2607 int error
= BCME_OK
, argc
= 0;
2608 int data
= 0, bytes_written
;
2610 argc
= sscanf(command
, CMD_WBTEXT_BTM_DELTA
" %d\n", &data
);
2612 error
= wldev_iovar_getint(dev
, "wnm_btmdelta", &data
);
2614 WL_ERR(("Failed to get wnm_btmdelta (%d)\n", error
));
2617 bytes_written
= snprintf(command
, total_len
, "%d\n", data
);
2618 return bytes_written
;
2620 if ((error
= wldev_iovar_setint(dev
, "wnm_btmdelta",
2621 data
)) != BCME_OK
) {
2622 WL_ERR(("Failed to set wnm_btmdelta (%d)\n", error
));
2632 #define PNO_PARAM_SIZE 50
2633 #define VALUE_SIZE 50
2634 #define LIMIT_STR_FMT ("%50s %50s")
2636 wls_parse_batching_cmd(struct net_device
*dev
, char *command
, int total_len
)
2639 uint i
, tokens
, len_remain
;
2640 char *pos
, *pos2
, *token
, *token2
, *delim
;
2641 char param
[PNO_PARAM_SIZE
+1], value
[VALUE_SIZE
+1];
2642 struct dhd_pno_batch_params batch_params
;
2644 DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__
, command
, total_len
));
2645 len_remain
= total_len
;
2646 if (len_remain
> (strlen(CMD_WLS_BATCHING
) + 1)) {
2647 pos
= command
+ strlen(CMD_WLS_BATCHING
) + 1;
2648 len_remain
-= strlen(CMD_WLS_BATCHING
) + 1;
2650 WL_ERR(("%s: No arguments, total_len %d\n", __FUNCTION__
, total_len
));
2654 memset(&batch_params
, 0, sizeof(struct dhd_pno_batch_params
));
2655 if (!strncmp(pos
, PNO_BATCHING_SET
, strlen(PNO_BATCHING_SET
))) {
2656 if (len_remain
> (strlen(PNO_BATCHING_SET
) + 1)) {
2657 pos
+= strlen(PNO_BATCHING_SET
) + 1;
2659 WL_ERR(("%s: %s missing arguments, total_len %d\n",
2660 __FUNCTION__
, PNO_BATCHING_SET
, total_len
));
2664 while ((token
= strsep(&pos
, PNO_PARAMS_DELIMETER
)) != NULL
) {
2665 memset(param
, 0, sizeof(param
));
2666 memset(value
, 0, sizeof(value
));
2667 if (token
== NULL
|| !*token
)
2671 delim
= strchr(token
, PNO_PARAM_VALUE_DELLIMETER
);
2675 tokens
= sscanf(token
, LIMIT_STR_FMT
, param
, value
);
2676 if (!strncmp(param
, PNO_PARAM_SCANFREQ
, strlen(PNO_PARAM_SCANFREQ
))) {
2677 batch_params
.scan_fr
= simple_strtol(value
, NULL
, 0);
2678 DHD_PNO(("scan_freq : %d\n", batch_params
.scan_fr
));
2679 } else if (!strncmp(param
, PNO_PARAM_BESTN
, strlen(PNO_PARAM_BESTN
))) {
2680 batch_params
.bestn
= simple_strtol(value
, NULL
, 0);
2681 DHD_PNO(("bestn : %d\n", batch_params
.bestn
));
2682 } else if (!strncmp(param
, PNO_PARAM_MSCAN
, strlen(PNO_PARAM_MSCAN
))) {
2683 batch_params
.mscan
= simple_strtol(value
, NULL
, 0);
2684 DHD_PNO(("mscan : %d\n", batch_params
.mscan
));
2685 } else if (!strncmp(param
, PNO_PARAM_CHANNEL
, strlen(PNO_PARAM_CHANNEL
))) {
2688 tokens
= sscanf(value
, "<%s>", value
);
2691 DHD_ERROR(("%s : invalid format for channel"
2692 " <> params\n", __FUNCTION__
));
2695 while ((token2
= strsep(&pos2
,
2696 PNO_PARAM_CHANNEL_DELIMETER
)) != NULL
) {
2697 if (token2
== NULL
|| !*token2
)
2699 if (*token2
== '\0')
2701 if (*token2
== 'A' || *token2
== 'B') {
2702 batch_params
.band
= (*token2
== 'A')?
2703 WLC_BAND_5G
: WLC_BAND_2G
;
2704 DHD_PNO(("band : %s\n",
2705 (*token2
== 'A')? "A" : "B"));
2707 if ((batch_params
.nchan
>= WL_NUMCHANNELS
) ||
2708 (i
>= WL_NUMCHANNELS
)) {
2709 DHD_ERROR(("Too many nchan %d\n",
2710 batch_params
.nchan
));
2711 err
= BCME_BUFTOOSHORT
;
2714 batch_params
.chan_list
[i
++] =
2715 simple_strtol(token2
, NULL
, 0);
2716 batch_params
.nchan
++;
2717 DHD_PNO(("channel :%d\n",
2718 batch_params
.chan_list
[i
-1]));
2721 } else if (!strncmp(param
, PNO_PARAM_RTT
, strlen(PNO_PARAM_RTT
))) {
2722 batch_params
.rtt
= simple_strtol(value
, NULL
, 0);
2723 DHD_PNO(("rtt : %d\n", batch_params
.rtt
));
2725 DHD_ERROR(("%s : unknown param: %s\n", __FUNCTION__
, param
));
2730 err
= dhd_dev_pno_set_for_batch(dev
, &batch_params
);
2732 DHD_ERROR(("failed to configure batch scan\n"));
2734 memset(command
, 0, total_len
);
2735 err
= snprintf(command
, total_len
, "%d", err
);
2737 } else if (!strncmp(pos
, PNO_BATCHING_GET
, strlen(PNO_BATCHING_GET
))) {
2738 err
= dhd_dev_pno_get_for_batch(dev
, command
, total_len
);
2740 DHD_ERROR(("failed to getting batching results\n"));
2742 err
= strlen(command
);
2744 } else if (!strncmp(pos
, PNO_BATCHING_STOP
, strlen(PNO_BATCHING_STOP
))) {
2745 err
= dhd_dev_pno_stop_for_batch(dev
);
2747 DHD_ERROR(("failed to stop batching scan\n"));
2749 memset(command
, 0, total_len
);
2750 err
= snprintf(command
, total_len
, "OK");
2753 DHD_ERROR(("%s : unknown command\n", __FUNCTION__
));
2760 #ifndef WL_SCHED_SCAN
2761 static int wl_android_set_pno_setup(struct net_device
*dev
, char *command
, int total_len
)
2763 wlc_ssid_ext_t ssids_local
[MAX_PFN_LIST_COUNT
];
2766 cmd_tlv_t
*cmd_tlv_temp
;
2771 int pno_freq_expo_max
= 0;
2773 #ifdef PNO_SET_DEBUG
2775 char pno_in_example
[] = {
2776 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
2780 'd', 'l', 'i', 'n', 'k',
2792 #endif /* PNO_SET_DEBUG */
2793 DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__
, command
, total_len
));
2795 if (total_len
< (strlen(CMD_PNOSETUP_SET
) + sizeof(cmd_tlv_t
))) {
2796 DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__
, total_len
));
2799 #ifdef PNO_SET_DEBUG
2800 memcpy(command
, pno_in_example
, sizeof(pno_in_example
));
2801 total_len
= sizeof(pno_in_example
);
2803 str_ptr
= command
+ strlen(CMD_PNOSETUP_SET
);
2804 tlv_size_left
= total_len
- strlen(CMD_PNOSETUP_SET
);
2806 cmd_tlv_temp
= (cmd_tlv_t
*)str_ptr
;
2807 memset(ssids_local
, 0, sizeof(ssids_local
));
2809 if ((cmd_tlv_temp
->prefix
== PNO_TLV_PREFIX
) &&
2810 (cmd_tlv_temp
->version
== PNO_TLV_VERSION
) &&
2811 (cmd_tlv_temp
->subtype
== PNO_TLV_SUBTYPE_LEGACY_PNO
)) {
2813 str_ptr
+= sizeof(cmd_tlv_t
);
2814 tlv_size_left
-= sizeof(cmd_tlv_t
);
2816 if ((nssid
= wl_parse_ssid_list_tlv(&str_ptr
, ssids_local
,
2817 MAX_PFN_LIST_COUNT
, &tlv_size_left
)) <= 0) {
2818 DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid
));
2821 if ((str_ptr
[0] != PNO_TLV_TYPE_TIME
) || (tlv_size_left
<= 1)) {
2822 DHD_ERROR(("%s scan duration corrupted field size %d\n",
2823 __FUNCTION__
, tlv_size_left
));
2827 pno_time
= simple_strtoul(str_ptr
, &str_ptr
, 16);
2828 DHD_PNO(("%s: pno_time=%d\n", __FUNCTION__
, pno_time
));
2830 if (str_ptr
[0] != 0) {
2831 if ((str_ptr
[0] != PNO_TLV_FREQ_REPEAT
)) {
2832 DHD_ERROR(("%s pno repeat : corrupted field\n",
2837 pno_repeat
= simple_strtoul(str_ptr
, &str_ptr
, 16);
2838 DHD_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__
, pno_repeat
));
2839 if (str_ptr
[0] != PNO_TLV_FREQ_EXPO_MAX
) {
2840 DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n",
2845 pno_freq_expo_max
= simple_strtoul(str_ptr
, &str_ptr
, 16);
2846 DHD_PNO(("%s: pno_freq_expo_max=%d\n",
2847 __FUNCTION__
, pno_freq_expo_max
));
2851 DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__
));
2855 res
= dhd_dev_pno_set_for_ssid(dev
, ssids_local
, nssid
, pno_time
, pno_repeat
,
2856 pno_freq_expo_max
, NULL
, 0);
2860 #endif /* !WL_SCHED_SCAN */
2861 #endif /* PNO_SUPPORT */
2863 static int wl_android_get_p2p_dev_addr(struct net_device
*ndev
, char *command
, int total_len
)
2866 struct ether_addr p2pdev_addr
;
2868 #define MAC_ADDR_STR_LEN 18
2869 if (total_len
< MAC_ADDR_STR_LEN
) {
2870 DHD_ERROR(("%s: buflen %d is less than p2p dev addr\n",
2871 __FUNCTION__
, total_len
));
2875 ret
= wl_cfg80211_get_p2p_dev_addr(ndev
, &p2pdev_addr
);
2877 DHD_ERROR(("%s Failed to get p2p dev addr\n", __FUNCTION__
));
2880 return (snprintf(command
, total_len
, MACF
, ETHERP_TO_MACF(&p2pdev_addr
)));
2884 static int wl_android_get_cckm_rn(struct net_device
*dev
, char *command
)
2888 WL_TRACE(("%s:wl_android_get_cckm_rn\n", dev
->name
));
2890 error
= wldev_iovar_getint(dev
, "cckm_rn", &rn
);
2891 if (unlikely(error
)) {
2892 WL_ERR(("wl_android_get_cckm_rn error (%d)\n", error
));
2895 memcpy(command
, &rn
, sizeof(int));
2901 wl_android_set_cckm_krk(struct net_device
*dev
, char *command
, int total_len
)
2903 int error
, key_len
, skip_len
;
2904 unsigned char key
[CCKM_KRK_LEN
+ CCKM_BTK_LEN
];
2905 char iovar_buf
[WLC_IOCTL_SMLEN
];
2907 WL_TRACE(("%s: wl_iw_set_cckm_krk\n", dev
->name
));
2909 skip_len
= strlen("set cckm_krk")+1;
2911 if (total_len
< (skip_len
+ CCKM_KRK_LEN
)) {
2915 if (total_len
>= skip_len
+ CCKM_KRK_LEN
+ CCKM_BTK_LEN
) {
2916 key_len
= CCKM_KRK_LEN
+ CCKM_BTK_LEN
;
2918 key_len
= CCKM_KRK_LEN
;
2921 memset(iovar_buf
, 0, sizeof(iovar_buf
));
2922 memcpy(key
, command
+skip_len
, key_len
);
2924 WL_DBG(("CCKM KRK-BTK (%d/%d) :\n", key_len
, total_len
));
2925 if (wl_dbg_level
& WL_DBG_DBG
) {
2926 prhex(NULL
, key
, key_len
);
2929 error
= wldev_iovar_setbuf(dev
, "cckm_krk", key
, key_len
,
2930 iovar_buf
, WLC_IOCTL_SMLEN
, NULL
);
2931 if (unlikely(error
)) {
2932 WL_ERR((" cckm_krk set error (%d)\n", error
));
2938 static int wl_android_get_assoc_res_ies(struct net_device
*dev
, char *command
, int total_len
)
2941 u8 buf
[WL_ASSOC_INFO_MAX
];
2942 wl_assoc_info_t assoc_info
;
2943 u32 resp_ies_len
= 0;
2944 int bytes_written
= 0;
2946 WL_TRACE(("%s: wl_iw_get_assoc_res_ies\n", dev
->name
));
2948 error
= wldev_iovar_getbuf(dev
, "assoc_info", NULL
, 0, buf
, WL_ASSOC_INFO_MAX
, NULL
);
2949 if (unlikely(error
)) {
2950 WL_ERR(("could not get assoc info (%d)\n", error
));
2954 memcpy(&assoc_info
, buf
, sizeof(wl_assoc_info_t
));
2955 assoc_info
.req_len
= htod32(assoc_info
.req_len
);
2956 assoc_info
.resp_len
= htod32(assoc_info
.resp_len
);
2957 assoc_info
.flags
= htod32(assoc_info
.flags
);
2959 if (assoc_info
.resp_len
) {
2960 resp_ies_len
= assoc_info
.resp_len
- sizeof(struct dot11_assoc_resp
);
2963 if (total_len
< (sizeof(u32
) + resp_ies_len
)) {
2964 WL_ERR(("%s: Insufficient memory, %d bytes\n",
2965 __FUNCTION__
, total_len
));
2968 /* first 4 bytes are ie len */
2969 memcpy(command
, &resp_ies_len
, sizeof(u32
));
2970 bytes_written
= sizeof(u32
);
2972 /* get the association resp IE's if there are any */
2974 error
= wldev_iovar_getbuf(dev
, "assoc_resp_ies", NULL
, 0,
2975 buf
, WL_ASSOC_INFO_MAX
, NULL
);
2976 if (unlikely(error
)) {
2977 WL_ERR(("could not get assoc resp_ies (%d)\n", error
));
2981 memcpy(command
+sizeof(u32
), buf
, resp_ies_len
);
2982 bytes_written
+= resp_ies_len
;
2984 return bytes_written
;
2990 wl_android_set_ap_mac_list(struct net_device
*dev
, int macmode
, struct maclist
*maclist
)
2994 char mac_buf
[MAX_NUM_OF_ASSOCLIST
*
2995 sizeof(struct ether_addr
) + sizeof(uint
)] = {0};
2996 struct maclist
*assoc_maclist
= (struct maclist
*)mac_buf
;
2998 /* set filtering mode */
2999 if ((ret
= wldev_ioctl_set(dev
, WLC_SET_MACMODE
, &macmode
, sizeof(macmode
)) != 0)) {
3000 DHD_ERROR(("%s : WLC_SET_MACMODE error=%d\n", __FUNCTION__
, ret
));
3003 if (macmode
!= MACLIST_MODE_DISABLED
) {
3004 /* set the MAC filter list */
3005 if ((ret
= wldev_ioctl_set(dev
, WLC_SET_MACLIST
, maclist
,
3006 sizeof(int) + sizeof(struct ether_addr
) * maclist
->count
)) != 0) {
3007 DHD_ERROR(("%s : WLC_SET_MACLIST error=%d\n", __FUNCTION__
, ret
));
3010 /* get the current list of associated STAs */
3011 assoc_maclist
->count
= MAX_NUM_OF_ASSOCLIST
;
3012 if ((ret
= wldev_ioctl_get(dev
, WLC_GET_ASSOCLIST
, assoc_maclist
,
3013 sizeof(mac_buf
))) != 0) {
3014 DHD_ERROR(("%s : WLC_GET_ASSOCLIST error=%d\n", __FUNCTION__
, ret
));
3017 /* do we have any STA associated? */
3018 if (assoc_maclist
->count
) {
3019 /* iterate each associated STA */
3020 for (i
= 0; i
< assoc_maclist
->count
; i
++) {
3022 /* compare with each entry */
3023 for (j
= 0; j
< maclist
->count
; j
++) {
3024 DHD_INFO(("%s : associated="MACDBG
" list="MACDBG
"\n",
3025 __FUNCTION__
, MAC2STRDBG(assoc_maclist
->ea
[i
].octet
),
3026 MAC2STRDBG(maclist
->ea
[j
].octet
)));
3027 if (memcmp(assoc_maclist
->ea
[i
].octet
,
3028 maclist
->ea
[j
].octet
, ETHER_ADDR_LEN
) == 0) {
3033 /* do conditional deauth */
3034 /* "if not in the allow list" or "if in the deny list" */
3035 if ((macmode
== MACLIST_MODE_ALLOW
&& !match
) ||
3036 (macmode
== MACLIST_MODE_DENY
&& match
)) {
3039 scbval
.val
= htod32(1);
3040 memcpy(&scbval
.ea
, &assoc_maclist
->ea
[i
],
3042 if ((ret
= wldev_ioctl_set(dev
,
3043 WLC_SCB_DEAUTHENTICATE_FOR_REASON
,
3044 &scbval
, sizeof(scb_val_t
))) != 0)
3045 DHD_ERROR(("%s WLC_SCB_DEAUTHENTICATE error=%d\n",
3046 __FUNCTION__
, ret
));
3055 * HAPD_MAC_FILTER mac_mode mac_cnt mac_addr1 mac_addr2
3059 wl_android_set_mac_address_filter(struct net_device
*dev
, char* str
)
3064 int macmode
= MACLIST_MODE_DISABLED
;
3065 struct maclist
*list
;
3066 char eabuf
[ETHER_ADDR_STR_LEN
];
3068 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3070 /* string should look like below (macmode/macnum/maclist) */
3071 /* 1 2 00:11:22:33:44:55 00:11:22:33:44:ff */
3073 /* get the MAC filter mode */
3074 token
= strsep((char**)&str
, " ");
3078 macmode
= bcm_atoi(token
);
3080 if (macmode
< MACLIST_MODE_DISABLED
|| macmode
> MACLIST_MODE_ALLOW
) {
3081 DHD_ERROR(("%s : invalid macmode %d\n", __FUNCTION__
, macmode
));
3085 token
= strsep((char**)&str
, " ");
3089 macnum
= bcm_atoi(token
);
3090 if (macnum
< 0 || macnum
> MAX_NUM_MAC_FILT
) {
3091 DHD_ERROR(("%s : invalid number of MAC address entries %d\n",
3092 __FUNCTION__
, macnum
));
3095 /* allocate memory for the MAC list */
3096 list
= (struct maclist
*) MALLOCZ(cfg
->osh
, sizeof(int) +
3097 sizeof(struct ether_addr
) * macnum
);
3099 DHD_ERROR(("%s : failed to allocate memory\n", __FUNCTION__
));
3102 /* prepare the MAC list */
3103 list
->count
= htod32(macnum
);
3104 bzero((char *)eabuf
, ETHER_ADDR_STR_LEN
);
3105 for (i
= 0; i
< list
->count
; i
++) {
3106 token
= strsep((char**)&str
, " ");
3107 if (token
== NULL
) {
3108 DHD_ERROR(("%s : No mac address present\n", __FUNCTION__
));
3112 strncpy(eabuf
, token
, ETHER_ADDR_STR_LEN
- 1);
3113 if (!(ret
= bcm_ether_atoe(eabuf
, &list
->ea
[i
]))) {
3114 DHD_ERROR(("%s : mac parsing err index=%d, addr=%s\n",
3115 __FUNCTION__
, i
, eabuf
));
3119 DHD_INFO(("%s : %d/%d MACADDR=%s", __FUNCTION__
, i
, list
->count
, eabuf
));
3125 if ((ret
= wl_android_set_ap_mac_list(dev
, macmode
, list
)) != 0)
3126 DHD_ERROR(("%s : Setting MAC list failed error=%d\n", __FUNCTION__
, ret
));
3129 MFREE(cfg
->osh
, list
, sizeof(int) + sizeof(struct ether_addr
) * macnum
);
3135 * Global function definitions (declared in wl_android.h)
3138 int wl_android_wifi_on(struct net_device
*dev
)
3141 int retry
= POWERUP_MAX_RETRY
;
3143 DHD_ERROR(("%s in\n", __FUNCTION__
));
3145 DHD_ERROR(("%s: dev is null\n", __FUNCTION__
));
3149 dhd_net_if_lock(dev
);
3152 dhd_net_wifi_platform_set_power(dev
, TRUE
, WIFI_TURNON_DELAY
);
3154 ret
= dhd_net_bus_resume(dev
, 0);
3155 #endif /* BCMSDIO */
3157 ret
= dhd_net_bus_devreset(dev
, FALSE
);
3158 #endif /* BCMPCIE */
3162 DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n",
3165 dhd_net_bus_devreset(dev
, TRUE
);
3166 #endif /* BCMPCIE */
3167 dhd_net_wifi_platform_set_power(dev
, FALSE
, WIFI_TURNOFF_DELAY
);
3168 } while (retry
-- > 0);
3170 DHD_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n"));
3171 #ifdef BCM_DETECT_TURN_ON_FAILURE
3173 #endif /* BCM_DETECT_TURN_ON_FAILURE */
3177 ret
= dhd_net_bus_devreset(dev
, FALSE
);
3178 dhd_net_bus_resume(dev
, 1);
3179 #endif /* BCMSDIO */
3183 if (dhd_dev_init_ioctl(dev
) < 0) {
3187 #endif /* !BCMPCIE */
3192 dhd_net_if_unlock(dev
);
3197 int wl_android_wifi_off(struct net_device
*dev
, bool on_failure
)
3201 DHD_ERROR(("%s in\n", __FUNCTION__
));
3203 DHD_TRACE(("%s: dev is null\n", __FUNCTION__
));
3207 #if defined(BCMPCIE) && defined(DHD_DEBUG_UART)
3208 ret
= dhd_debug_uart_is_running(dev
);
3210 DHD_ERROR(("%s - Debug UART App is running\n", __FUNCTION__
));
3213 #endif /* BCMPCIE && DHD_DEBUG_UART */
3214 dhd_net_if_lock(dev
);
3215 if (g_wifi_on
|| on_failure
) {
3216 #if defined(BCMSDIO) || defined(BCMPCIE)
3217 ret
= dhd_net_bus_devreset(dev
, TRUE
);
3219 dhd_net_bus_suspend(dev
);
3220 #endif /* BCMSDIO */
3221 #endif /* BCMSDIO || BCMPCIE */
3222 dhd_net_wifi_platform_set_power(dev
, FALSE
, WIFI_TURNOFF_DELAY
);
3225 dhd_net_if_unlock(dev
);
3230 static int wl_android_set_fwpath(struct net_device
*net
, char *command
, int total_len
)
3232 if ((strlen(command
) - strlen(CMD_SETFWPATH
)) > MOD_PARAM_PATHLEN
)
3234 return dhd_net_set_fw_path(net
, command
+ strlen(CMD_SETFWPATH
) + 1);
3237 #ifdef CONNECTION_STATISTICS
3239 wl_chanim_stats(struct net_device
*dev
, u8
*chan_idle
)
3242 wl_chanim_stats_t
*list
;
3243 /* Parameter _and_ returned buffer of chanim_stats. */
3244 wl_chanim_stats_t param
;
3245 u8 result
[WLC_IOCTL_SMLEN
];
3246 chanim_stats_t
*stats
;
3248 memset(¶m
, 0, sizeof(param
));
3250 param
.buflen
= htod32(sizeof(wl_chanim_stats_t
));
3251 param
.count
= htod32(WL_CHANIM_COUNT_ONE
);
3253 if ((err
= wldev_iovar_getbuf(dev
, "chanim_stats", (char*)¶m
, sizeof(wl_chanim_stats_t
),
3254 (char*)result
, sizeof(result
), 0)) < 0) {
3255 WL_ERR(("Failed to get chanim results %d \n", err
));
3259 list
= (wl_chanim_stats_t
*)result
;
3261 list
->buflen
= dtoh32(list
->buflen
);
3262 list
->version
= dtoh32(list
->version
);
3263 list
->count
= dtoh32(list
->count
);
3265 if (list
->buflen
== 0) {
3268 } else if (list
->version
!= WL_CHANIM_STATS_VERSION
) {
3269 WL_ERR(("Sorry, firmware has wl_chanim_stats version %d "
3270 "but driver supports only version %d.\n",
3271 list
->version
, WL_CHANIM_STATS_VERSION
));
3276 stats
= list
->stats
;
3277 stats
->glitchcnt
= dtoh32(stats
->glitchcnt
);
3278 stats
->badplcp
= dtoh32(stats
->badplcp
);
3279 stats
->chanspec
= dtoh16(stats
->chanspec
);
3280 stats
->timestamp
= dtoh32(stats
->timestamp
);
3281 stats
->chan_idle
= dtoh32(stats
->chan_idle
);
3283 WL_INFORM(("chanspec: 0x%4x glitch: %d badplcp: %d idle: %d timestamp: %d\n",
3284 stats
->chanspec
, stats
->glitchcnt
, stats
->badplcp
, stats
->chan_idle
,
3287 *chan_idle
= stats
->chan_idle
;
3293 wl_android_get_connection_stats(struct net_device
*dev
, char *command
, int total_len
)
3295 static char iovar_buf
[WLC_IOCTL_MAXLEN
];
3296 const wl_cnt_wlc_t
* wlc_cnt
= NULL
;
3297 #ifndef DISABLE_IF_COUNTERS
3298 wl_if_stats_t
* if_stats
= NULL
;
3299 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3300 #endif /* DISABLE_IF_COUNTERS */
3303 struct connection_stats
*output
;
3304 unsigned int bufsize
= 0;
3305 int bytes_written
= -1;
3308 WL_INFORM(("%s: enter Get Connection Stats\n", __FUNCTION__
));
3310 if (total_len
<= 0) {
3311 WL_ERR(("%s: invalid buffer size %d\n", __FUNCTION__
, total_len
));
3315 bufsize
= total_len
;
3316 if (bufsize
< sizeof(struct connection_stats
)) {
3317 WL_ERR(("%s: not enough buffer size, provided=%u, requires=%zu\n",
3318 __FUNCTION__
, bufsize
,
3319 sizeof(struct connection_stats
)));
3323 output
= (struct connection_stats
*)command
;
3325 #ifndef DISABLE_IF_COUNTERS
3326 if_stats
= (wl_if_stats_t
*)MALLOCZ(cfg
->osh
, sizeof(*if_stats
));
3327 if (if_stats
== NULL
) {
3328 WL_ERR(("%s(%d): MALLOCZ failed\n", __FUNCTION__
, __LINE__
));
3331 memset(if_stats
, 0, sizeof(*if_stats
));
3333 if (FW_SUPPORTED(dhdp
, ifst
)) {
3334 ret
= wl_cfg80211_ifstats_counters(dev
, if_stats
);
3336 ret
= wldev_iovar_getbuf(dev
, "if_counters", NULL
, 0,
3337 (char *)if_stats
, sizeof(*if_stats
), NULL
);
3341 WL_ERR(("%s: if_counters not supported ret=%d\n",
3342 __FUNCTION__
, ret
));
3344 /* In case if_stats IOVAR is not supported, get information from counters. */
3345 #endif /* DISABLE_IF_COUNTERS */
3346 ret
= wldev_iovar_getbuf(dev
, "counters", NULL
, 0,
3347 iovar_buf
, WLC_IOCTL_MAXLEN
, NULL
);
3348 if (unlikely(ret
)) {
3349 WL_ERR(("counters error (%d) - size = %zu\n", ret
, sizeof(wl_cnt_wlc_t
)));
3352 ret
= wl_cntbuf_to_xtlv_format(NULL
, iovar_buf
, WL_CNTBUF_MAX_SIZE
, 0);
3353 if (ret
!= BCME_OK
) {
3354 WL_ERR(("%s wl_cntbuf_to_xtlv_format ERR %d\n",
3355 __FUNCTION__
, ret
));
3359 if (!(wlc_cnt
= GET_WLCCNT_FROM_CNTBUF(iovar_buf
))) {
3360 WL_ERR(("%s wlc_cnt NULL!\n", __FUNCTION__
));
3364 output
->txframe
= dtoh32(wlc_cnt
->txframe
);
3365 output
->txbyte
= dtoh32(wlc_cnt
->txbyte
);
3366 output
->txerror
= dtoh32(wlc_cnt
->txerror
);
3367 output
->rxframe
= dtoh32(wlc_cnt
->rxframe
);
3368 output
->rxbyte
= dtoh32(wlc_cnt
->rxbyte
);
3369 output
->txfail
= dtoh32(wlc_cnt
->txfail
);
3370 output
->txretry
= dtoh32(wlc_cnt
->txretry
);
3371 output
->txretrie
= dtoh32(wlc_cnt
->txretrie
);
3372 output
->txrts
= dtoh32(wlc_cnt
->txrts
);
3373 output
->txnocts
= dtoh32(wlc_cnt
->txnocts
);
3374 output
->txexptime
= dtoh32(wlc_cnt
->txexptime
);
3375 #ifndef DISABLE_IF_COUNTERS
3377 /* Populate from if_stats. */
3378 if (dtoh16(if_stats
->version
) > WL_IF_STATS_T_VERSION
) {
3379 WL_ERR(("%s: incorrect version of wl_if_stats_t, expected=%u got=%u\n",
3380 __FUNCTION__
, WL_IF_STATS_T_VERSION
, if_stats
->version
));
3384 output
->txframe
= (uint32
)dtoh64(if_stats
->txframe
);
3385 output
->txbyte
= (uint32
)dtoh64(if_stats
->txbyte
);
3386 output
->txerror
= (uint32
)dtoh64(if_stats
->txerror
);
3387 output
->rxframe
= (uint32
)dtoh64(if_stats
->rxframe
);
3388 output
->rxbyte
= (uint32
)dtoh64(if_stats
->rxbyte
);
3389 output
->txfail
= (uint32
)dtoh64(if_stats
->txfail
);
3390 output
->txretry
= (uint32
)dtoh64(if_stats
->txretry
);
3391 output
->txretrie
= (uint32
)dtoh64(if_stats
->txretrie
);
3392 if (dtoh16(if_stats
->length
) > OFFSETOF(wl_if_stats_t
, txexptime
)) {
3393 output
->txexptime
= (uint32
)dtoh64(if_stats
->txexptime
);
3394 output
->txrts
= (uint32
)dtoh64(if_stats
->txrts
);
3395 output
->txnocts
= (uint32
)dtoh64(if_stats
->txnocts
);
3397 output
->txexptime
= 0;
3399 output
->txnocts
= 0;
3402 #endif /* DISABLE_IF_COUNTERS */
3404 /* link_speed is in kbps */
3405 ret
= wldev_get_link_speed(dev
, &link_speed
);
3406 if (ret
|| link_speed
< 0) {
3407 WL_ERR(("%s: wldev_get_link_speed() failed, ret=%d, speed=%d\n",
3408 __FUNCTION__
, ret
, link_speed
));
3412 output
->txrate
= link_speed
;
3414 /* Channel idle ratio. */
3415 if (wl_chanim_stats(dev
, &(output
->chan_idle
)) < 0) {
3416 output
->chan_idle
= 0;
3419 bytes_written
= sizeof(struct connection_stats
);
3422 #ifndef DISABLE_IF_COUNTERS
3424 MFREE(cfg
->osh
, if_stats
, sizeof(*if_stats
));
3426 #endif /* DISABLE_IF_COUNTERS */
3428 return bytes_written
;
3430 #endif /* CONNECTION_STATISTICS */
3434 wl_android_process_natoe_cmd(struct net_device
*dev
, char *command
, int total_len
)
3436 int ret
= BCME_ERROR
;
3437 char *pcmd
= command
;
3439 wl_natoe_cmd_info_t cmd_info
;
3440 const wl_natoe_sub_cmd_t
*natoe_cmd
= &natoe_cmd_list
[0];
3442 /* skip to cmd name after "natoe" */
3443 str
= bcmstrtok(&pcmd
, " ", NULL
);
3445 /* If natoe subcmd name is not provided, return error */
3446 if (*pcmd
== '\0') {
3447 WL_ERR(("natoe subcmd not provided %s\n", __FUNCTION__
));
3452 /* get the natoe command name to str */
3453 str
= bcmstrtok(&pcmd
, " ", NULL
);
3455 while (natoe_cmd
->name
!= NULL
) {
3456 if (strcmp(natoe_cmd
->name
, str
) == 0) {
3457 /* dispacth cmd to appropriate handler */
3458 if (natoe_cmd
->handler
) {
3459 cmd_info
.command
= command
;
3460 cmd_info
.tot_len
= total_len
;
3461 ret
= natoe_cmd
->handler(dev
, natoe_cmd
, pcmd
, &cmd_info
);
3471 wlu_natoe_set_vars_cbfn(void *ctx
, uint8
*data
, uint16 type
, uint16 len
)
3474 wl_natoe_cmd_info_t
*cmd_info
= (wl_natoe_cmd_info_t
*)ctx
;
3475 uint8
*command
= cmd_info
->command
;
3476 uint16 total_len
= cmd_info
->tot_len
;
3477 uint16 bytes_written
= 0;
3479 UNUSED_PARAMETER(len
);
3483 case WL_NATOE_XTLV_ENABLE
:
3485 bytes_written
= snprintf(command
, total_len
, "natoe: %s\n",
3486 *data
?"enabled":"disabled");
3487 cmd_info
->bytes_written
= bytes_written
;
3491 case WL_NATOE_XTLV_CONFIG_IPS
:
3493 wl_natoe_config_ips_t
*config_ips
;
3496 config_ips
= (wl_natoe_config_ips_t
*)data
;
3497 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->sta_ip
, buf
);
3498 bytes_written
= snprintf(command
, total_len
, "sta ip: %s\n", buf
);
3499 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->sta_netmask
, buf
);
3500 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3501 "sta netmask: %s\n", buf
);
3502 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->sta_router_ip
, buf
);
3503 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3504 "sta router ip: %s\n", buf
);
3505 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->sta_dnsip
, buf
);
3506 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3507 "sta dns ip: %s\n", buf
);
3508 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->ap_ip
, buf
);
3509 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3510 "ap ip: %s\n", buf
);
3511 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->ap_netmask
, buf
);
3512 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3513 "ap netmask: %s\n", buf
);
3514 cmd_info
->bytes_written
= bytes_written
;
3518 case WL_NATOE_XTLV_CONFIG_PORTS
:
3520 wl_natoe_ports_config_t
*ports_config
;
3522 ports_config
= (wl_natoe_ports_config_t
*)data
;
3523 bytes_written
= snprintf(command
, total_len
, "starting port num: %d\n",
3524 dtoh16(ports_config
->start_port_num
));
3525 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3526 "number of ports: %d\n", dtoh16(ports_config
->no_of_ports
));
3527 cmd_info
->bytes_written
= bytes_written
;
3531 case WL_NATOE_XTLV_DBG_STATS
:
3533 char *stats_dump
= (char *)data
;
3535 bytes_written
= snprintf(command
, total_len
, "%s\n", stats_dump
);
3536 cmd_info
->bytes_written
= bytes_written
;
3540 case WL_NATOE_XTLV_TBL_CNT
:
3542 bytes_written
= snprintf(command
, total_len
, "natoe max tbl entries: %d\n",
3543 dtoh32(*(uint32
*)data
));
3544 cmd_info
->bytes_written
= bytes_written
;
3557 * --- common for all natoe get commands ----
3560 wl_natoe_get_ioctl(struct net_device
*dev
, wl_natoe_ioc_t
*natoe_ioc
,
3561 uint16 iocsz
, uint8
*buf
, uint16 buflen
, wl_natoe_cmd_info_t
*cmd_info
)
3563 /* for gets we only need to pass ioc header */
3564 wl_natoe_ioc_t
*iocresp
= (wl_natoe_ioc_t
*)buf
;
3567 /* send getbuf natoe iovar */
3568 res
= wldev_iovar_getbuf(dev
, "natoe", natoe_ioc
, iocsz
, buf
,
3571 /* check the response buff */
3572 if ((res
== BCME_OK
)) {
3573 /* scans ioctl tlvbuf f& invokes the cbfn for processing */
3574 res
= bcm_unpack_xtlv_buf(cmd_info
, iocresp
->data
, iocresp
->len
,
3575 BCM_XTLV_OPTION_ALIGN32
, wlu_natoe_set_vars_cbfn
);
3577 if (res
== BCME_OK
) {
3578 res
= cmd_info
->bytes_written
;
3583 DHD_ERROR(("%s: get command failed code %d\n", __FUNCTION__
, res
));
3591 wl_android_natoe_subcmd_enable(struct net_device
*dev
, const wl_natoe_sub_cmd_t
*cmd
,
3592 char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3595 wl_natoe_ioc_t
*natoe_ioc
;
3596 char *pcmd
= command
;
3597 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
;
3598 uint16 buflen
= WL_NATOE_IOC_BUFSZ
;
3599 bcm_xtlv_t
*pxtlv
= NULL
;
3600 char *ioctl_buf
= NULL
;
3601 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3603 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
3605 WL_ERR(("ioctl memory alloc failed\n"));
3609 /* alloc mem for ioctl headr + tlv data */
3610 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3612 WL_ERR(("ioctl header memory alloc failed\n"));
3613 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3617 /* make up natoe cmd ioctl header */
3618 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3619 natoe_ioc
->id
= htod16(cmd
->id
);
3620 natoe_ioc
->len
= htod16(WL_NATOE_IOC_BUFSZ
);
3621 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3623 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3624 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3625 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3626 WLC_IOCTL_MEDLEN
, cmd_info
);
3627 if (ret
!= BCME_OK
) {
3628 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3632 uint8 val
= bcm_atoi(pcmd
);
3634 /* buflen is max tlv data we can write, it will be decremented as we pack */
3635 /* save buflen at start */
3636 uint16 buflen_at_start
= buflen
;
3638 /* we'll adjust final ioc size at the end */
3639 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
, &buflen
, WL_NATOE_XTLV_ENABLE
,
3640 sizeof(uint8
), &val
, BCM_XTLV_OPTION_ALIGN32
);
3642 if (ret
!= BCME_OK
) {
3647 /* adjust iocsz to the end of last data record */
3648 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3649 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3651 ret
= wldev_iovar_setbuf(dev
, "natoe",
3652 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
3653 if (ret
!= BCME_OK
) {
3654 WL_ERR(("Fail to set iovar %d\n", ret
));
3660 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3661 MFREE(cfg
->osh
, natoe_ioc
, iocsz
);
3667 wl_android_natoe_subcmd_config_ips(struct net_device
*dev
,
3668 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3671 wl_natoe_config_ips_t config_ips
;
3672 wl_natoe_ioc_t
*natoe_ioc
;
3673 char *pcmd
= command
;
3675 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
;
3676 uint16 buflen
= WL_NATOE_IOC_BUFSZ
;
3677 bcm_xtlv_t
*pxtlv
= NULL
;
3678 char *ioctl_buf
= NULL
;
3679 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3681 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
3683 WL_ERR(("ioctl memory alloc failed\n"));
3687 /* alloc mem for ioctl headr + tlv data */
3688 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3690 WL_ERR(("ioctl header memory alloc failed\n"));
3691 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3695 /* make up natoe cmd ioctl header */
3696 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3697 natoe_ioc
->id
= htod16(cmd
->id
);
3698 natoe_ioc
->len
= htod16(WL_NATOE_IOC_BUFSZ
);
3699 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3701 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3702 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3703 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3704 WLC_IOCTL_MEDLEN
, cmd_info
);
3705 if (ret
!= BCME_OK
) {
3706 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3710 /* buflen is max tlv data we can write, it will be decremented as we pack */
3711 /* save buflen at start */
3712 uint16 buflen_at_start
= buflen
;
3714 memset(&config_ips
, 0, sizeof(config_ips
));
3716 str
= bcmstrtok(&pcmd
, " ", NULL
);
3717 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.sta_ip
)) {
3718 WL_ERR(("Invalid STA IP addr %s\n", str
));
3723 str
= bcmstrtok(&pcmd
, " ", NULL
);
3724 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.sta_netmask
)) {
3725 WL_ERR(("Invalid STA netmask %s\n", str
));
3730 str
= bcmstrtok(&pcmd
, " ", NULL
);
3731 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.sta_router_ip
)) {
3732 WL_ERR(("Invalid STA router IP addr %s\n", str
));
3737 str
= bcmstrtok(&pcmd
, " ", NULL
);
3738 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.sta_dnsip
)) {
3739 WL_ERR(("Invalid STA DNS IP addr %s\n", str
));
3744 str
= bcmstrtok(&pcmd
, " ", NULL
);
3745 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.ap_ip
)) {
3746 WL_ERR(("Invalid AP IP addr %s\n", str
));
3751 str
= bcmstrtok(&pcmd
, " ", NULL
);
3752 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.ap_netmask
)) {
3753 WL_ERR(("Invalid AP netmask %s\n", str
));
3758 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
,
3759 &buflen
, WL_NATOE_XTLV_CONFIG_IPS
, sizeof(config_ips
),
3760 &config_ips
, BCM_XTLV_OPTION_ALIGN32
);
3762 if (ret
!= BCME_OK
) {
3767 /* adjust iocsz to the end of last data record */
3768 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3769 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3771 ret
= wldev_iovar_setbuf(dev
, "natoe",
3772 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
3773 if (ret
!= BCME_OK
) {
3774 WL_ERR(("Fail to set iovar %d\n", ret
));
3780 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3781 MFREE(cfg
->osh
, natoe_ioc
, sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
);
3787 wl_android_natoe_subcmd_config_ports(struct net_device
*dev
,
3788 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3791 wl_natoe_ports_config_t ports_config
;
3792 wl_natoe_ioc_t
*natoe_ioc
;
3793 char *pcmd
= command
;
3795 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
;
3796 uint16 buflen
= WL_NATOE_IOC_BUFSZ
;
3797 bcm_xtlv_t
*pxtlv
= NULL
;
3798 char *ioctl_buf
= NULL
;
3799 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3801 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
3803 WL_ERR(("ioctl memory alloc failed\n"));
3807 /* alloc mem for ioctl headr + tlv data */
3808 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3810 WL_ERR(("ioctl header memory alloc failed\n"));
3811 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3815 /* make up natoe cmd ioctl header */
3816 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3817 natoe_ioc
->id
= htod16(cmd
->id
);
3818 natoe_ioc
->len
= htod16(WL_NATOE_IOC_BUFSZ
);
3819 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3821 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3822 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3823 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3824 WLC_IOCTL_MEDLEN
, cmd_info
);
3825 if (ret
!= BCME_OK
) {
3826 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3830 /* buflen is max tlv data we can write, it will be decremented as we pack */
3831 /* save buflen at start */
3832 uint16 buflen_at_start
= buflen
;
3834 memset(&ports_config
, 0, sizeof(ports_config
));
3836 str
= bcmstrtok(&pcmd
, " ", NULL
);
3838 WL_ERR(("Invalid port string %s\n", str
));
3842 ports_config
.start_port_num
= htod16(bcm_atoi(str
));
3844 str
= bcmstrtok(&pcmd
, " ", NULL
);
3846 WL_ERR(("Invalid port string %s\n", str
));
3850 ports_config
.no_of_ports
= htod16(bcm_atoi(str
));
3852 if ((uint32
)(ports_config
.start_port_num
+ ports_config
.no_of_ports
) >
3853 NATOE_MAX_PORT_NUM
) {
3854 WL_ERR(("Invalid port configuration\n"));
3858 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
,
3859 &buflen
, WL_NATOE_XTLV_CONFIG_PORTS
, sizeof(ports_config
),
3860 &ports_config
, BCM_XTLV_OPTION_ALIGN32
);
3862 if (ret
!= BCME_OK
) {
3867 /* adjust iocsz to the end of last data record */
3868 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3869 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3871 ret
= wldev_iovar_setbuf(dev
, "natoe",
3872 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
3873 if (ret
!= BCME_OK
) {
3874 WL_ERR(("Fail to set iovar %d\n", ret
));
3880 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3881 MFREE(cfg
->osh
, natoe_ioc
, sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
);
3887 wl_android_natoe_subcmd_dbg_stats(struct net_device
*dev
, const wl_natoe_sub_cmd_t
*cmd
,
3888 char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3891 wl_natoe_ioc_t
*natoe_ioc
;
3892 char *pcmd
= command
;
3893 uint16 kflags
= in_atomic() ? GFP_ATOMIC
: GFP_KERNEL
;
3894 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_DBG_STATS_BUFSZ
;
3895 uint16 buflen
= WL_NATOE_DBG_STATS_BUFSZ
;
3896 bcm_xtlv_t
*pxtlv
= NULL
;
3897 char *ioctl_buf
= NULL
;
3898 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3900 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MAXLEN
);
3902 WL_ERR(("ioctl memory alloc failed\n"));
3906 /* alloc mem for ioctl headr + tlv data */
3907 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3909 WL_ERR(("ioctl header memory alloc failed\n"));
3910 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MAXLEN
);
3914 /* make up natoe cmd ioctl header */
3915 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3916 natoe_ioc
->id
= htod16(cmd
->id
);
3917 natoe_ioc
->len
= htod16(WL_NATOE_DBG_STATS_BUFSZ
);
3918 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3920 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3921 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3922 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3923 WLC_IOCTL_MAXLEN
, cmd_info
);
3924 if (ret
!= BCME_OK
) {
3925 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3929 uint8 val
= bcm_atoi(pcmd
);
3931 /* buflen is max tlv data we can write, it will be decremented as we pack */
3932 /* save buflen at start */
3933 uint16 buflen_at_start
= buflen
;
3935 /* we'll adjust final ioc size at the end */
3936 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
, &buflen
, WL_NATOE_XTLV_ENABLE
,
3937 sizeof(uint8
), &val
, BCM_XTLV_OPTION_ALIGN32
);
3939 if (ret
!= BCME_OK
) {
3944 /* adjust iocsz to the end of last data record */
3945 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3946 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3948 ret
= wldev_iovar_setbuf(dev
, "natoe",
3949 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MAXLEN
, NULL
);
3950 if (ret
!= BCME_OK
) {
3951 WL_ERR(("Fail to set iovar %d\n", ret
));
3957 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MAXLEN
);
3958 MFREE(cfg
->osh
, natoe_ioc
, sizeof(*natoe_ioc
) + WL_NATOE_DBG_STATS_BUFSZ
);
3964 wl_android_natoe_subcmd_tbl_cnt(struct net_device
*dev
, const wl_natoe_sub_cmd_t
*cmd
,
3965 char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3968 wl_natoe_ioc_t
*natoe_ioc
;
3969 char *pcmd
= command
;
3970 uint16 kflags
= in_atomic() ? GFP_ATOMIC
: GFP_KERNEL
;
3971 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
;
3972 uint16 buflen
= WL_NATOE_IOC_BUFSZ
;
3973 bcm_xtlv_t
*pxtlv
= NULL
;
3974 char *ioctl_buf
= NULL
;
3975 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3977 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
3979 WL_ERR(("ioctl memory alloc failed\n"));
3983 /* alloc mem for ioctl headr + tlv data */
3984 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3986 WL_ERR(("ioctl header memory alloc failed\n"));
3987 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3991 /* make up natoe cmd ioctl header */
3992 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3993 natoe_ioc
->id
= htod16(cmd
->id
);
3994 natoe_ioc
->len
= htod16(WL_NATOE_IOC_BUFSZ
);
3995 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3997 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3998 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3999 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
4000 WLC_IOCTL_MEDLEN
, cmd_info
);
4001 if (ret
!= BCME_OK
) {
4002 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
4006 uint32 val
= bcm_atoi(pcmd
);
4008 /* buflen is max tlv data we can write, it will be decremented as we pack */
4009 /* save buflen at start */
4010 uint16 buflen_at_start
= buflen
;
4012 /* we'll adjust final ioc size at the end */
4013 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
, &buflen
, WL_NATOE_XTLV_TBL_CNT
,
4014 sizeof(uint32
), &val
, BCM_XTLV_OPTION_ALIGN32
);
4016 if (ret
!= BCME_OK
) {
4021 /* adjust iocsz to the end of last data record */
4022 natoe_ioc
->len
= (buflen_at_start
- buflen
);
4023 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
4025 ret
= wldev_iovar_setbuf(dev
, "natoe",
4026 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
4027 if (ret
!= BCME_OK
) {
4028 WL_ERR(("Fail to set iovar %d\n", ret
));
4034 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
4035 MFREE(cfg
->osh
, natoe_ioc
, sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
);
4040 #endif /* WL_NATOE */
4042 #ifdef CUSTOMER_HW4_PRIVATE_CMD
4043 #ifdef SUPPORT_AMPDU_MPDU_CMD
4044 /* CMD_AMPDU_MPDU */
4046 wl_android_set_ampdu_mpdu(struct net_device
*dev
, const char* string_num
)
4051 ampdu_mpdu
= bcm_atoi(string_num
);
4053 if (ampdu_mpdu
> 32) {
4054 DHD_ERROR(("%s : ampdu_mpdu MAX value is 32.\n", __FUNCTION__
));
4058 DHD_ERROR(("%s : ampdu_mpdu = %d\n", __FUNCTION__
, ampdu_mpdu
));
4059 err
= wldev_iovar_setint(dev
, "ampdu_mpdu", ampdu_mpdu
);
4061 DHD_ERROR(("%s : ampdu_mpdu set error. %d\n", __FUNCTION__
, err
));
4067 #endif /* SUPPORT_AMPDU_MPDU_CMD */
4068 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
4070 #if defined(WL_SUPPORT_AUTO_CHANNEL)
4071 /* SoftAP feature */
4072 #define APCS_BAND_2G_LEGACY1 20
4073 #define APCS_BAND_2G_LEGACY2 0
4074 #define APCS_BAND_AUTO "band=auto"
4075 #define APCS_BAND_2G "band=2g"
4076 #define APCS_BAND_5G "band=5g"
4077 #define APCS_MAX_2G_CHANNELS 11
4078 #define APCS_MAX_RETRY 10
4079 #define APCS_DEFAULT_2G_CH 1
4080 #define APCS_DEFAULT_5G_CH 149
4082 wl_android_set_auto_channel(struct net_device
*dev
, const char* cmd_str
,
4083 char* command
, int total_len
)
4091 uint32 band
= WLC_BAND_2G
;
4093 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
4096 WL_INFORM(("Command: %s len:%d \n", cmd_str
, (int)strlen(cmd_str
)));
4097 if (strncmp(cmd_str
, APCS_BAND_AUTO
, strlen(APCS_BAND_AUTO
)) == 0) {
4098 band
= WLC_BAND_AUTO
;
4099 } else if (strncmp(cmd_str
, APCS_BAND_5G
, strlen(APCS_BAND_5G
)) == 0) {
4101 } else if (strncmp(cmd_str
, APCS_BAND_2G
, strlen(APCS_BAND_2G
)) == 0) {
4105 * For backward compatibility: Some platforms used to issue argument 20 or 0
4106 * to enforce the 2G channel selection
4108 channel
= bcm_atoi(cmd_str
);
4109 if ((channel
== APCS_BAND_2G_LEGACY1
) ||
4110 (channel
== APCS_BAND_2G_LEGACY2
)) {
4113 WL_ERR(("Invalid argument\n"));
4118 /* If no argument is provided, default to 2G */
4119 WL_ERR(("No argument given default to 2.4G scan\n"));
4122 WL_INFORM(("HAPD_AUTO_CHANNEL = %d, band=%d \n", channel
, band
));
4124 /* If STA is connected, return is STA channel, else ACS can be issued,
4125 * set spect to 0 and proceed with ACS
4127 channel
= wl_cfg80211_get_sta_channel(cfg
);
4129 channel
= (channel
<= CH_MAX_2G_CHANNEL
) ?
4130 channel
: APCS_DEFAULT_2G_CH
;
4134 ret
= wldev_ioctl_get(dev
, WLC_GET_SPECT_MANAGMENT
, &spect
, sizeof(spect
));
4136 WL_ERR(("ACS: error getting the spect, ret=%d\n", ret
));
4141 ret
= wl_cfg80211_set_spect(dev
, 0);
4143 WL_ERR(("ACS: error while setting spect, ret=%d\n", ret
));
4148 reqbuf
= (u8
*)MALLOCZ(cfg
->osh
, CHANSPEC_BUF_SIZE
);
4149 if (reqbuf
== NULL
) {
4150 WL_ERR(("failed to allocate chanspec buffer\n"));
4154 if (band
== WLC_BAND_AUTO
) {
4155 WL_DBG(("ACS full channel scan \n"));
4156 reqbuf
[0] = htod32(0);
4157 } else if (band
== WLC_BAND_5G
) {
4158 WL_DBG(("ACS 5G band scan \n"));
4159 if ((ret
= wl_cfg80211_get_chanspecs_5g(dev
, reqbuf
, CHANSPEC_BUF_SIZE
)) < 0) {
4160 WL_ERR(("ACS 5g chanspec retreival failed! \n"));
4163 } else if (band
== WLC_BAND_2G
) {
4165 * If channel argument is not provided/ argument 20 is provided,
4166 * Restrict channel to 2GHz, 20MHz BW, No SB
4168 WL_DBG(("ACS 2G band scan \n"));
4169 if ((ret
= wl_cfg80211_get_chanspecs_2g(dev
, reqbuf
, CHANSPEC_BUF_SIZE
)) < 0) {
4170 WL_ERR(("ACS 2g chanspec retreival failed! \n"));
4174 WL_ERR(("ACS: No band chosen\n"));
4178 buf_size
= (band
== WLC_BAND_AUTO
) ? sizeof(int) : CHANSPEC_BUF_SIZE
;
4179 ret
= wldev_ioctl_set(dev
, WLC_START_CHANNEL_SEL
, (void *)reqbuf
,
4182 WL_ERR(("can't start auto channel scan, err = %d\n", ret
));
4187 /* Wait for auto channel selection, max 3000 ms */
4188 if ((band
== WLC_BAND_2G
) || (band
== WLC_BAND_5G
)) {
4192 * Full channel scan at the minimum takes 1.2secs
4193 * even with parallel scan. max wait time: 3500ms
4198 retry
= APCS_MAX_RETRY
;
4200 ret
= wldev_ioctl_get(dev
, WLC_GET_CHANNEL_SEL
, &chosen
,
4205 chosen
= dtoh32(chosen
);
4211 #ifdef D11AC_IOTYPES
4212 if (wl_cfg80211_get_ioctl_version() == 1) {
4213 channel
= LCHSPEC_CHANNEL((chanspec_t
)chosen
);
4215 channel
= CHSPEC_CHANNEL((chanspec_t
)chosen
);
4218 channel
= CHSPEC_CHANNEL((chanspec_t
)chosen
);
4219 #endif /* D11AC_IOTYPES */
4220 apcs_band
= (band
== WLC_BAND_AUTO
) ? WLC_BAND_2G
: band
;
4221 chosen_band
= (channel
<= CH_MAX_2G_CHANNEL
) ? WLC_BAND_2G
: WLC_BAND_5G
;
4222 if (apcs_band
== chosen_band
) {
4223 WL_ERR(("selected channel = %d\n", channel
));
4227 WL_DBG(("%d tried, ret = %d, chosen = 0x%x\n",
4228 (APCS_MAX_RETRY
- retry
), ret
, chosen
));
4233 if ((retry
== 0) || (ret
< 0)) {
4234 /* On failure, fallback to a default channel */
4235 if (band
== WLC_BAND_5G
) {
4236 channel
= APCS_DEFAULT_5G_CH
;
4238 channel
= APCS_DEFAULT_2G_CH
;
4240 WL_ERR(("ACS failed. Fall back to default channel (%d) \n", channel
));
4244 if ((ret
= wl_cfg80211_set_spect(dev
, spect
) < 0)) {
4245 WL_ERR(("ACS: error while setting spect\n"));
4250 MFREE(cfg
->osh
, reqbuf
, CHANSPEC_BUF_SIZE
);
4254 ret
= snprintf(command
, total_len
, "%d", channel
);
4255 WL_INFORM(("command result is %s \n", command
));
4260 #endif /* WL_SUPPORT_AUTO_CHANNEL */
4262 #ifdef CUSTOMER_HW4_PRIVATE_CMD
4263 #ifdef SUPPORT_HIDDEN_AP
4265 wl_android_set_max_num_sta(struct net_device
*dev
, const char* string_num
)
4269 max_assoc
= bcm_atoi(string_num
);
4270 WL_INFORM(("HAPD_MAX_NUM_STA = %d\n", max_assoc
));
4271 wldev_iovar_setint(dev
, "maxassoc", max_assoc
);
4272 WL_INFORM(("Conigured maxassoc = %d\n", max_assoc
));
4277 wl_android_set_ssid(struct net_device
*dev
, const char* hapd_ssid
)
4282 ssid
.SSID_len
= strlen(hapd_ssid
);
4283 if (ssid
.SSID_len
== 0) {
4284 WL_ERR(("%s : No SSID\n", __FUNCTION__
));
4287 if (ssid
.SSID_len
> DOT11_MAX_SSID_LEN
) {
4288 ssid
.SSID_len
= DOT11_MAX_SSID_LEN
;
4289 WL_ERR(("%s : Too long SSID Length %zu\n", __FUNCTION__
, strlen(hapd_ssid
)));
4291 bcm_strncpy_s(ssid
.SSID
, sizeof(ssid
.SSID
), hapd_ssid
, ssid
.SSID_len
);
4292 DHD_INFO(("%s: HAPD_SSID = %s\n", __FUNCTION__
, ssid
.SSID
));
4293 ret
= wldev_ioctl_set(dev
, WLC_SET_SSID
, &ssid
, sizeof(wlc_ssid_t
));
4295 WL_ERR(("%s : WLC_SET_SSID Error:%d\n", __FUNCTION__
, ret
));
4302 wl_android_set_hide_ssid(struct net_device
*dev
, const char* string_num
)
4307 hide_ssid
= bcm_atoi(string_num
);
4308 DHD_INFO(("%s: HAPD_HIDE_SSID = %d\n", __FUNCTION__
, hide_ssid
));
4311 wldev_iovar_setint(dev
, "closednet", enable
);
4314 #endif /* SUPPORT_HIDDEN_AP */
4316 #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
4318 wl_android_sta_diassoc(struct net_device
*dev
, const char* straddr
)
4323 DHD_INFO(("%s: deauth STA %s\n", __FUNCTION__
, straddr
));
4325 /* Unspecified reason */
4326 scbval
.val
= htod32(1);
4328 if (bcm_ether_atoe(straddr
, &scbval
.ea
) == 0) {
4329 DHD_ERROR(("%s: Invalid station MAC Address!!!\n", __FUNCTION__
));
4333 DHD_ERROR(("%s: deauth STA: "MACDBG
" scb_val.val %d\n", __FUNCTION__
,
4334 MAC2STRDBG(scbval
.ea
.octet
), scbval
.val
));
4336 error
= wldev_ioctl_set(dev
, WLC_SCB_DEAUTHENTICATE_FOR_REASON
, &scbval
,
4339 DHD_ERROR(("Fail to DEAUTH station, error = %d\n", error
));
4344 #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
4346 #ifdef SUPPORT_SET_LPC
4348 wl_android_set_lpc(struct net_device
*dev
, const char* string_num
)
4350 int lpc_enabled
, ret
;
4353 lpc_enabled
= bcm_atoi(string_num
);
4354 DHD_INFO(("%s : HAPD_LPC_ENABLED = %d\n", __FUNCTION__
, lpc_enabled
));
4356 ret
= wldev_ioctl_set(dev
, WLC_DOWN
, &val
, sizeof(s32
));
4358 DHD_ERROR(("WLC_DOWN error %d\n", ret
));
4360 wldev_iovar_setint(dev
, "lpc", lpc_enabled
);
4362 ret
= wldev_ioctl_set(dev
, WLC_UP
, &val
, sizeof(s32
));
4364 DHD_ERROR(("WLC_UP error %d\n", ret
));
4368 #endif /* SUPPORT_SET_LPC */
4371 wl_android_ch_res_rl(struct net_device
*dev
, bool change
)
4376 printk("%s enter\n", __FUNCTION__
);
4384 error
= wldev_ioctl_set(dev
, WLC_SET_SRL
, &srl
, sizeof(s32
));
4386 DHD_ERROR(("Failed to set SRL, error = %d\n", error
));
4388 #ifndef CUSTOM_LONG_RETRY_LIMIT
4389 error
= wldev_ioctl_set(dev
, WLC_SET_LRL
, &lrl
, sizeof(s32
));
4391 DHD_ERROR(("Failed to set LRL, error = %d\n", error
));
4393 #endif /* CUSTOM_LONG_RETRY_LIMIT */
4397 #ifdef SUPPORT_LTECX
4398 #define DEFAULT_WLANRX_PROT 1
4399 #define DEFAULT_LTERX_PROT 0
4400 #define DEFAULT_LTETX_ADV 1200
4403 wl_android_set_ltecx(struct net_device
*dev
, const char* string_num
)
4408 chan_bitmap
= bcm_strtoul(string_num
, NULL
, 16);
4410 DHD_INFO(("%s : LTECOEX 0x%x\n", __FUNCTION__
, chan_bitmap
));
4413 ret
= wldev_iovar_setint(dev
, "mws_coex_bitmap", chan_bitmap
);
4415 DHD_ERROR(("mws_coex_bitmap error %d\n", ret
));
4418 ret
= wldev_iovar_setint(dev
, "mws_wlanrx_prot", DEFAULT_WLANRX_PROT
);
4420 DHD_ERROR(("mws_wlanrx_prot error %d\n", ret
));
4423 ret
= wldev_iovar_setint(dev
, "mws_lterx_prot", DEFAULT_LTERX_PROT
);
4425 DHD_ERROR(("mws_lterx_prot error %d\n", ret
));
4428 ret
= wldev_iovar_setint(dev
, "mws_ltetx_adv", DEFAULT_LTETX_ADV
);
4430 DHD_ERROR(("mws_ltetx_adv error %d\n", ret
));
4433 ret
= wldev_iovar_setint(dev
, "mws_coex_bitmap", chan_bitmap
);
4435 if (ret
== BCME_UNSUPPORTED
) {
4436 DHD_ERROR(("LTECX_CHAN_BITMAP is UNSUPPORTED\n"));
4438 DHD_ERROR(("LTECX_CHAN_BITMAP error %d\n", ret
));
4444 #endif /* SUPPORT_LTECX */
4448 wl_android_rmc_enable(struct net_device
*net
, int rmc_enable
)
4452 err
= wldev_iovar_setint(net
, "rmc_ackreq", rmc_enable
);
4453 if (err
!= BCME_OK
) {
4454 DHD_ERROR(("%s: rmc_ackreq, error = %d\n", __FUNCTION__
, err
));
4460 wl_android_rmc_set_leader(struct net_device
*dev
, const char* straddr
)
4462 int error
= BCME_OK
;
4463 char smbuf
[WLC_IOCTL_SMLEN
];
4464 wl_rmc_entry_t rmc_entry
;
4465 DHD_INFO(("%s: Set new RMC leader %s\n", __FUNCTION__
, straddr
));
4467 memset(&rmc_entry
, 0, sizeof(wl_rmc_entry_t
));
4468 if (!bcm_ether_atoe(straddr
, &rmc_entry
.addr
)) {
4469 if (strlen(straddr
) == 1 && bcm_atoi(straddr
) == 0) {
4470 DHD_INFO(("%s: Set auto leader selection mode\n", __FUNCTION__
));
4471 memset(&rmc_entry
, 0, sizeof(wl_rmc_entry_t
));
4473 DHD_ERROR(("%s: No valid mac address provided\n",
4479 error
= wldev_iovar_setbuf(dev
, "rmc_ar", &rmc_entry
, sizeof(wl_rmc_entry_t
),
4480 smbuf
, sizeof(smbuf
), NULL
);
4482 if (error
!= BCME_OK
) {
4483 DHD_ERROR(("%s: Unable to set RMC leader, error = %d\n",
4484 __FUNCTION__
, error
));
4490 static int wl_android_set_rmc_event(struct net_device
*dev
, char *command
)
4495 if (sscanf(command
, CMD_SET_RMC_EVENT
" %d", &pid
) <= 0) {
4496 WL_ERR(("Failed to get Parameter from : %s\n", command
));
4500 /* set pid, and if the event was happened, let's send a notification through netlink */
4501 wl_cfg80211_set_rmc_pid(dev
, pid
);
4503 WL_DBG(("RMC pid=%d\n", pid
));
4507 #endif /* WL_RELMCAST */
4509 int wl_android_get_singlecore_scan(struct net_device
*dev
, char *command
, int total_len
)
4512 int bytes_written
= 0;
4515 error
= wldev_iovar_getint(dev
, "scan_ps", &mode
);
4517 DHD_ERROR(("%s: Failed to get single core scan Mode, error = %d\n",
4518 __FUNCTION__
, error
));
4522 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_SCSCAN
, mode
);
4524 return bytes_written
;
4527 int wl_android_set_singlecore_scan(struct net_device
*dev
, char *command
)
4532 if (sscanf(command
, "%*s %d", &mode
) != 1) {
4533 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
4537 error
= wldev_iovar_setint(dev
, "scan_ps", mode
);
4539 DHD_ERROR(("%s[1]: Failed to set Mode %d, error = %d\n",
4540 __FUNCTION__
, mode
, error
));
4546 #ifdef TEST_TX_POWER_CONTROL
4548 wl_android_set_tx_power(struct net_device
*dev
, const char* string_num
)
4552 enum nl80211_tx_power_setting type
;
4554 dbm
= bcm_atoi(string_num
);
4557 DHD_ERROR(("%s: dbm is negative...\n", __FUNCTION__
));
4562 type
= NL80211_TX_POWER_AUTOMATIC
;
4564 type
= NL80211_TX_POWER_FIXED
;
4566 err
= wl_set_tx_power(dev
, type
, dbm
);
4567 if (unlikely(err
)) {
4568 DHD_ERROR(("%s: error (%d)\n", __FUNCTION__
, err
));
4576 wl_android_get_tx_power(struct net_device
*dev
, char *command
, int total_len
)
4582 err
= wl_get_tx_power(dev
, &dbm
);
4583 if (unlikely(err
)) {
4584 DHD_ERROR(("%s: error (%d)\n", __FUNCTION__
, err
));
4588 bytes_written
= snprintf(command
, total_len
, "%s %d",
4589 CMD_TEST_GET_TX_POWER
, dbm
);
4591 DHD_ERROR(("%s: GET_TX_POWER: dBm=%d\n", __FUNCTION__
, dbm
));
4593 return bytes_written
;
4595 #endif /* TEST_TX_POWER_CONTROL */
4598 wl_android_set_sarlimit_txctrl(struct net_device
*dev
, const char* string_num
)
4602 s32 mode
= bcm_atoi(string_num
);
4604 /* As Samsung specific and their requirement, '0' means activate sarlimit
4605 * and '-1' means back to normal state (deactivate sarlimit)
4607 if (mode
>= 0 && mode
< 3) {
4608 DHD_INFO(("%s: SAR limit control activated mode = %d\n", __FUNCTION__
, mode
));
4610 } else if (mode
== -1) {
4611 DHD_INFO(("%s: SAR limit control deactivated\n", __FUNCTION__
));
4617 err
= wldev_iovar_setint(dev
, "sar_enable", setval
);
4618 if (unlikely(err
)) {
4619 DHD_ERROR(("%s: error (%d)\n", __FUNCTION__
, err
));
4625 #ifdef SUPPORT_SET_TID
4627 wl_android_set_tid(struct net_device
*dev
, char* command
)
4629 int err
= BCME_ERROR
;
4630 char *pos
= command
;
4635 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
4638 WL_ERR(("dhd is NULL\n"));
4642 WL_DBG(("%s: command[%s]\n", __FUNCTION__
, command
));
4645 token
= bcmstrtok(&pos
, " ", NULL
);
4647 token
= bcmstrtok(&pos
, " ", NULL
);
4649 WL_ERR(("Invalid arguments\n"));
4653 mode
= bcm_atoi(token
);
4655 if (mode
< SET_TID_OFF
|| mode
> SET_TID_BASED_ON_UID
) {
4656 WL_ERR(("Invalid arguments, mode %d\n", mode
));
4661 token
= bcmstrtok(&pos
, " ", NULL
);
4663 WL_ERR(("Invalid arguments for target uid\n"));
4667 uid
= bcm_atoi(token
);
4669 token
= bcmstrtok(&pos
, " ", NULL
);
4671 WL_ERR(("Invalid arguments for target tid\n"));
4675 prio
= bcm_atoi(token
);
4676 if (prio
>= 0 && prio
<= MAXPRIO
) {
4677 dhdp
->tid_mode
= mode
;
4678 dhdp
->target_uid
= uid
;
4679 dhdp
->target_tid
= prio
;
4681 WL_ERR(("Invalid arguments, prio %d\n", prio
));
4685 dhdp
->tid_mode
= SET_TID_OFF
;
4686 dhdp
->target_uid
= 0;
4687 dhdp
->target_tid
= 0;
4690 WL_DBG(("%s mode [%d], uid [%d], tid [%d]\n", __FUNCTION__
,
4691 dhdp
->tid_mode
, dhdp
->target_uid
, dhdp
->target_tid
));
4698 wl_android_get_tid(struct net_device
*dev
, char* command
, int total_len
)
4700 int bytes_written
= BCME_ERROR
;
4701 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
4704 WL_ERR(("dhd is NULL\n"));
4705 return bytes_written
;
4708 bytes_written
= snprintf(command
, total_len
, "mode %d uid %d tid %d",
4709 dhdp
->tid_mode
, dhdp
->target_uid
, dhdp
->target_tid
);
4711 WL_DBG(("%s: command results %s\n", __FUNCTION__
, command
));
4713 return bytes_written
;
4715 #endif /* SUPPORT_SET_TID */
4716 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
4718 int wl_android_set_roam_mode(struct net_device
*dev
, char *command
)
4723 if (sscanf(command
, "%*s %d", &mode
) != 1) {
4724 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
4728 error
= wldev_iovar_setint(dev
, "roam_off", mode
);
4730 DHD_ERROR(("%s: Failed to set roaming Mode %d, error = %d\n",
4731 __FUNCTION__
, mode
, error
));
4735 DHD_ERROR(("%s: succeeded to set roaming Mode %d, error = %d\n",
4736 __FUNCTION__
, mode
, error
));
4740 int wl_android_set_ibss_beacon_ouidata(struct net_device
*dev
, char *command
, int total_len
)
4742 char ie_buf
[VNDR_IE_MAX_LEN
];
4743 char *ioctl_buf
= NULL
;
4746 int ielen
= 0, datalen
= 0, idx
= 0, tot_len
= 0;
4747 vndr_ie_setbuf_t
*vndr_ie
= NULL
;
4750 s32 err
= BCME_OK
, bssidx
;
4751 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
4753 /* Check the VSIE (Vendor Specific IE) which was added.
4754 * If exist then send IOVAR to delete it
4756 if (wl_cfg80211_ibss_vsie_delete(dev
) != BCME_OK
) {
4760 if (total_len
< (strlen(CMD_SETIBSSBEACONOUIDATA
) + 1)) {
4761 WL_ERR(("error. total_len:%d\n", total_len
));
4765 pcmd
= command
+ strlen(CMD_SETIBSSBEACONOUIDATA
) + 1;
4766 for (idx
= 0; idx
< DOT11_OUI_LEN
; idx
++) {
4767 if (*pcmd
== '\0') {
4768 WL_ERR(("error while parsing OUI.\n"));
4773 ie_buf
[idx
] = (uint8
)simple_strtoul(hex
, NULL
, 16);
4776 while ((*pcmd
!= '\0') && (idx
< VNDR_IE_MAX_LEN
)) {
4779 ie_buf
[idx
++] = (uint8
)simple_strtoul(hex
, NULL
, 16);
4784 WL_ERR(("error. vndr ie len:%d\n", datalen
));
4788 tot_len
= (int)(sizeof(vndr_ie_setbuf_t
) + (datalen
- 1));
4789 vndr_ie
= (vndr_ie_setbuf_t
*)MALLOCZ(cfg
->osh
, tot_len
);
4791 WL_ERR(("IE memory alloc failed\n"));
4794 /* Copy the vndr_ie SET command ("add"/"del") to the buffer */
4795 strncpy(vndr_ie
->cmd
, "add", VNDR_IE_CMD_LEN
- 1);
4796 vndr_ie
->cmd
[VNDR_IE_CMD_LEN
- 1] = '\0';
4798 /* Set the IE count - the buffer contains only 1 IE */
4799 iecount
= htod32(1);
4800 memcpy((void *)&vndr_ie
->vndr_ie_buffer
.iecount
, &iecount
, sizeof(s32
));
4802 /* Set packet flag to indicate that BEACON's will contain this IE */
4803 pktflag
= htod32(VNDR_IE_BEACON_FLAG
| VNDR_IE_PRBRSP_FLAG
);
4804 memcpy((void *)&vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].pktflag
, &pktflag
,
4807 vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.id
= (uchar
) DOT11_MNG_PROPR_ID
;
4809 memcpy(&vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.oui
, &ie_buf
,
4811 memcpy(&vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.data
,
4812 &ie_buf
[DOT11_OUI_LEN
], datalen
);
4814 ielen
= DOT11_OUI_LEN
+ datalen
;
4815 vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.len
= (uchar
) ielen
;
4817 ioctl_buf
= (char *)MALLOC(cfg
->osh
, WLC_IOCTL_MEDLEN
);
4819 WL_ERR(("ioctl memory alloc failed\n"));
4821 MFREE(cfg
->osh
, vndr_ie
, tot_len
);
4825 memset(ioctl_buf
, 0, WLC_IOCTL_MEDLEN
); /* init the buffer */
4826 if ((bssidx
= wl_get_bssidx_by_wdev(cfg
, dev
->ieee80211_ptr
)) < 0) {
4827 WL_ERR(("Find index failed\n"));
4831 err
= wldev_iovar_setbuf_bsscfg(dev
, "vndr_ie", vndr_ie
, tot_len
, ioctl_buf
,
4832 WLC_IOCTL_MEDLEN
, bssidx
, &cfg
->ioctl_buf_sync
);
4834 if (err
!= BCME_OK
) {
4837 MFREE(cfg
->osh
, vndr_ie
, tot_len
);
4841 /* do NOT free 'vndr_ie' for the next process */
4842 wl_cfg80211_ibss_vsie_set_buffer(dev
, vndr_ie
, tot_len
);
4846 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
4852 #if defined(BCMFW_ROAM_ENABLE)
4854 wl_android_set_roampref(struct net_device
*dev
, char *command
, int total_len
)
4857 char smbuf
[WLC_IOCTL_SMLEN
];
4858 uint8 buf
[MAX_BUF_SIZE
];
4861 int num_ucipher_suites
= 0;
4862 int num_akm_suites
= 0;
4863 wpa_suite_t ucipher_suites
[MAX_NUM_SUITES
];
4864 wpa_suite_t akm_suites
[MAX_NUM_SUITES
];
4866 int total_bytes
= 0;
4871 pcmd
= command
+ strlen(CMD_SET_ROAMPREF
) + 1;
4872 total_len_left
= total_len
- strlen(CMD_SET_ROAMPREF
) + 1;
4874 num_akm_suites
= simple_strtoul(pcmd
, NULL
, 16);
4875 if (num_akm_suites
> MAX_NUM_SUITES
) {
4876 DHD_ERROR(("too many AKM suites = %d\n", num_akm_suites
));
4880 /* Increment for number of AKM suites field + space */
4882 total_len_left
-= 3;
4884 /* check to make sure pcmd does not overrun */
4885 if (total_len_left
< (num_akm_suites
* WIDTH_AKM_SUITE
))
4888 memset(buf
, 0, sizeof(buf
));
4889 memset(akm_suites
, 0, sizeof(akm_suites
));
4890 memset(ucipher_suites
, 0, sizeof(ucipher_suites
));
4892 /* Save the AKM suites passed in the command */
4893 for (i
= 0; i
< num_akm_suites
; i
++) {
4894 /* Store the MSB first, as required by join_pref */
4895 for (j
= 0; j
< 4; j
++) {
4898 buf
[j
] = (uint8
)simple_strtoul(hex
, NULL
, 16);
4900 memcpy((uint8
*)&akm_suites
[i
], buf
, sizeof(uint32
));
4903 total_len_left
-= (num_akm_suites
* WIDTH_AKM_SUITE
);
4904 num_ucipher_suites
= simple_strtoul(pcmd
, NULL
, 16);
4905 /* Increment for number of cipher suites field + space */
4907 total_len_left
-= 3;
4909 if (total_len_left
< (num_ucipher_suites
* WIDTH_AKM_SUITE
))
4912 /* Save the cipher suites passed in the command */
4913 for (i
= 0; i
< num_ucipher_suites
; i
++) {
4914 /* Store the MSB first, as required by join_pref */
4915 for (j
= 0; j
< 4; j
++) {
4918 buf
[j
] = (uint8
)simple_strtoul(hex
, NULL
, 16);
4920 memcpy((uint8
*)&ucipher_suites
[i
], buf
, sizeof(uint32
));
4923 /* Join preference for RSSI
4924 * Type : 1 byte (0x01)
4925 * Length : 1 byte (0x02)
4926 * Value : 2 bytes (reserved)
4928 *pref
++ = WL_JOIN_PREF_RSSI
;
4929 *pref
++ = JOIN_PREF_RSSI_LEN
;
4933 /* Join preference for WPA
4934 * Type : 1 byte (0x02)
4935 * Length : 1 byte (not used)
4936 * Value : (variable length)
4938 * count : 1 byte (no of tuples)
4946 num_tuples
= num_akm_suites
* num_ucipher_suites
;
4947 if (num_tuples
!= 0) {
4948 if (num_tuples
<= JOIN_PREF_MAX_WPA_TUPLES
) {
4949 *pref
++ = WL_JOIN_PREF_WPA
;
4952 *pref
++ = (uint8
)num_tuples
;
4953 total_bytes
= JOIN_PREF_RSSI_SIZE
+ JOIN_PREF_WPA_HDR_SIZE
+
4954 (JOIN_PREF_WPA_TUPLE_SIZE
* num_tuples
);
4956 DHD_ERROR(("%s: Too many wpa configs for join_pref \n", __FUNCTION__
));
4960 /* No WPA config, configure only RSSI preference */
4961 total_bytes
= JOIN_PREF_RSSI_SIZE
;
4964 /* akm-ucipher-mcipher tuples in the format required for join_pref */
4965 for (i
= 0; i
< num_ucipher_suites
; i
++) {
4966 for (j
= 0; j
< num_akm_suites
; j
++) {
4967 memcpy(pref
, (uint8
*)&akm_suites
[j
], WPA_SUITE_LEN
);
4968 pref
+= WPA_SUITE_LEN
;
4969 memcpy(pref
, (uint8
*)&ucipher_suites
[i
], WPA_SUITE_LEN
);
4970 pref
+= WPA_SUITE_LEN
;
4971 /* Set to 0 to match any available multicast cipher */
4972 memset(pref
, 0, WPA_SUITE_LEN
);
4973 pref
+= WPA_SUITE_LEN
;
4977 prhex("join pref", (uint8
*)buf
, total_bytes
);
4978 error
= wldev_iovar_setbuf(dev
, "join_pref", buf
, total_bytes
, smbuf
, sizeof(smbuf
), NULL
);
4980 DHD_ERROR(("Failed to set join_pref, error = %d\n", error
));
4984 #endif /* defined(BCMFW_ROAM_ENABLE */
4987 wl_android_iolist_add(struct net_device
*dev
, struct list_head
*head
, struct io_cfg
*config
)
4989 struct io_cfg
*resume_cfg
;
4991 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
4993 resume_cfg
= (struct io_cfg
*)MALLOCZ(cfg
->osh
, sizeof(struct io_cfg
));
4997 if (config
->iovar
) {
4998 ret
= wldev_iovar_getint(dev
, config
->iovar
, &resume_cfg
->param
);
5000 DHD_ERROR(("%s: Failed to get current %s value\n",
5001 __FUNCTION__
, config
->iovar
));
5005 ret
= wldev_iovar_setint(dev
, config
->iovar
, config
->param
);
5007 DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__
,
5008 config
->iovar
, config
->param
));
5012 resume_cfg
->iovar
= config
->iovar
;
5014 resume_cfg
->arg
= MALLOCZ(cfg
->osh
, config
->len
);
5015 if (!resume_cfg
->arg
) {
5019 ret
= wldev_ioctl_get(dev
, config
->ioctl
, resume_cfg
->arg
, config
->len
);
5021 DHD_ERROR(("%s: Failed to get ioctl %d\n", __FUNCTION__
,
5025 ret
= wldev_ioctl_set(dev
, config
->ioctl
+ 1, config
->arg
, config
->len
);
5027 DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__
,
5028 config
->iovar
, config
->param
));
5031 if (config
->ioctl
+ 1 == WLC_SET_PM
)
5032 wl_cfg80211_update_power_mode(dev
);
5033 resume_cfg
->ioctl
= config
->ioctl
;
5034 resume_cfg
->len
= config
->len
;
5037 list_add(&resume_cfg
->list
, head
);
5041 MFREE(cfg
->osh
, resume_cfg
->arg
, config
->len
);
5042 MFREE(cfg
->osh
, resume_cfg
, sizeof(struct io_cfg
));
5047 wl_android_iolist_resume(struct net_device
*dev
, struct list_head
*head
)
5049 struct io_cfg
*config
;
5050 struct list_head
*cur
, *q
;
5052 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5054 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
5055 #pragma GCC diagnostic push
5056 #pragma GCC diagnostic ignored "-Wcast-qual"
5058 list_for_each_safe(cur
, q
, head
) {
5059 config
= list_entry(cur
, struct io_cfg
, list
);
5060 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
5061 #pragma GCC diagnostic pop
5063 if (config
->iovar
) {
5065 ret
= wldev_iovar_setint(dev
, config
->iovar
,
5069 ret
= wldev_ioctl_set(dev
, config
->ioctl
+ 1,
5070 config
->arg
, config
->len
);
5071 if (config
->ioctl
+ 1 == WLC_SET_PM
)
5072 wl_cfg80211_update_power_mode(dev
);
5073 MFREE(cfg
->osh
, config
->arg
, config
->len
);
5076 MFREE(cfg
->osh
, config
, sizeof(struct io_cfg
));
5080 wl_android_set_miracast(struct net_device
*dev
, char *command
)
5084 struct io_cfg config
;
5086 if (sscanf(command
, "%*s %d", &mode
) != 1) {
5087 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
5091 DHD_INFO(("%s: enter miracast mode %d\n", __FUNCTION__
, mode
));
5093 if (miracast_cur_mode
== mode
) {
5097 wl_android_iolist_resume(dev
, &miracast_resume_list
);
5098 miracast_cur_mode
= MIRACAST_MODE_OFF
;
5099 memset((void *)&config
, 0, sizeof(config
));
5101 case MIRACAST_MODE_SOURCE
:
5102 #ifdef MIRACAST_MCHAN_ALGO
5103 /* setting mchan_algo to platform specific value */
5104 config
.iovar
= "mchan_algo";
5106 ret
= wldev_ioctl_get(dev
, WLC_GET_BCNPRD
, &val
, sizeof(int));
5107 if (!ret
&& val
> 100) {
5109 DHD_ERROR(("%s: Connected station's beacon interval: "
5110 "%d and set mchan_algo to %d \n",
5111 __FUNCTION__
, val
, config
.param
));
5113 config
.param
= MIRACAST_MCHAN_ALGO
;
5115 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
5119 #endif /* MIRACAST_MCHAN_ALGO */
5121 #ifdef MIRACAST_MCHAN_BW
5122 /* setting mchan_bw to platform specific value */
5123 config
.iovar
= "mchan_bw";
5124 config
.param
= MIRACAST_MCHAN_BW
;
5125 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
5129 #endif /* MIRACAST_MCHAN_BW */
5131 #ifdef MIRACAST_AMPDU_SIZE
5132 /* setting apmdu to platform specific value */
5133 config
.iovar
= "ampdu_mpdu";
5134 config
.param
= MIRACAST_AMPDU_SIZE
;
5135 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
5139 #endif /* MIRACAST_AMPDU_SIZE */
5141 /* Source mode shares most configurations with sink mode.
5142 * Fall through here to avoid code duplication
5144 case MIRACAST_MODE_SINK
:
5145 /* disable internal roaming */
5146 config
.iovar
= "roam_off";
5150 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
5156 ret
= wldev_ioctl_get(dev
, WLC_GET_PM
, &val
, sizeof(val
));
5161 if (val
!= PM_OFF
) {
5163 config
.iovar
= NULL
;
5164 config
.ioctl
= WLC_GET_PM
;
5166 config
.len
= sizeof(int);
5167 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
5173 case MIRACAST_MODE_OFF
:
5177 miracast_cur_mode
= mode
;
5182 DHD_ERROR(("%s: turnoff miracast mode because of err%d\n", __FUNCTION__
, ret
));
5183 wl_android_iolist_resume(dev
, &miracast_resume_list
);
5187 #define NETLINK_OXYGEN 30
5188 #define AIBSS_BEACON_TIMEOUT 10
5190 static struct sock
*nl_sk
= NULL
;
5192 static void wl_netlink_recv(struct sk_buff
*skb
)
5194 WL_ERR(("netlink_recv called\n"));
5197 static int wl_netlink_init(void)
5199 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5200 struct netlink_kernel_cfg cfg
= {
5201 .input
= wl_netlink_recv
,
5205 if (nl_sk
!= NULL
) {
5206 WL_ERR(("nl_sk already exist\n"));
5210 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
5211 nl_sk
= netlink_kernel_create(&init_net
, NETLINK_OXYGEN
,
5212 0, wl_netlink_recv
, NULL
, THIS_MODULE
);
5213 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
5214 nl_sk
= netlink_kernel_create(&init_net
, NETLINK_OXYGEN
, THIS_MODULE
, &cfg
);
5216 nl_sk
= netlink_kernel_create(&init_net
, NETLINK_OXYGEN
, &cfg
);
5219 if (nl_sk
== NULL
) {
5220 WL_ERR(("nl_sk is not ready\n"));
5227 static void wl_netlink_deinit(void)
5230 netlink_kernel_release(nl_sk
);
5236 wl_netlink_send_msg(int pid
, int type
, int seq
, const void *data
, size_t size
)
5238 struct sk_buff
*skb
= NULL
;
5239 struct nlmsghdr
*nlh
= NULL
;
5242 if (nl_sk
== NULL
) {
5243 WL_ERR(("nl_sk was not initialized\n"));
5247 skb
= alloc_skb(NLMSG_SPACE(size
), GFP_ATOMIC
);
5249 WL_ERR(("failed to allocate memory\n"));
5253 nlh
= nlmsg_put(skb
, 0, 0, 0, size
, 0);
5255 WL_ERR(("failed to build nlmsg, skb_tailroom:%d, nlmsg_total_size:%d\n",
5256 skb_tailroom(skb
), nlmsg_total_size(size
)));
5261 memcpy(nlmsg_data(nlh
), data
, size
);
5262 nlh
->nlmsg_seq
= seq
;
5263 nlh
->nlmsg_type
= type
;
5265 /* netlink_unicast() takes ownership of the skb and frees it itself. */
5266 ret
= netlink_unicast(nl_sk
, skb
, pid
, 0);
5267 WL_DBG(("netlink_unicast() pid=%d, ret=%d\n", pid
, ret
));
5274 static int wl_android_set_ibss_txfail_event(struct net_device
*dev
, char *command
, int total_len
)
5279 aibss_txfail_config_t txfail_config
= {0, 0, 0, 0, 0};
5280 char smbuf
[WLC_IOCTL_SMLEN
];
5282 if (sscanf(command
, CMD_SETIBSSTXFAILEVENT
" %d %d", &retry
, &pid
) <= 0) {
5283 WL_ERR(("Failed to get Parameter from : %s\n", command
));
5287 /* set pid, and if the event was happened, let's send a notification through netlink */
5288 wl_cfg80211_set_txfail_pid(dev
, pid
);
5291 /* using same pid for RMC, AIBSS shares same pid with RMC and it is set once */
5292 wl_cfg80211_set_rmc_pid(dev
, pid
);
5293 #endif /* WL_RELMCAST */
5295 /* If retry value is 0, it disables the functionality for TX Fail. */
5297 txfail_config
.max_tx_retry
= retry
;
5298 txfail_config
.bcn_timeout
= 0; /* 0 : disable tx fail from beacon */
5300 txfail_config
.version
= AIBSS_TXFAIL_CONFIG_VER_0
;
5301 txfail_config
.len
= sizeof(txfail_config
);
5303 err
= wldev_iovar_setbuf(dev
, "aibss_txfail_config", (void *) &txfail_config
,
5304 sizeof(aibss_txfail_config_t
), smbuf
, WLC_IOCTL_SMLEN
, NULL
);
5305 WL_DBG(("retry=%d, pid=%d, err=%d\n", retry
, pid
, err
));
5307 return ((err
== 0)?total_len
:err
);
5310 static int wl_android_get_ibss_peer_info(struct net_device
*dev
, char *command
,
5311 int total_len
, bool bAll
)
5314 int bytes_written
= 0;
5316 bss_peer_list_info_t peer_list_info
;
5317 bss_peer_info_t
*peer_info
;
5320 struct ether_addr mac_ea
;
5321 char *str
= command
;
5322 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5324 WL_DBG(("get ibss peer info(%s)\n", bAll
?"true":"false"));
5327 if (bcmstrtok(&str
, " ", NULL
) == NULL
) {
5328 WL_ERR(("invalid command\n"));
5332 if (!str
|| !bcm_ether_atoe(str
, &mac_ea
)) {
5333 WL_ERR(("invalid MAC address\n"));
5338 buf
= MALLOC(cfg
->osh
, WLC_IOCTL_MAXLEN
);
5340 WL_ERR(("MALLOC failed\n"));
5344 error
= wldev_iovar_getbuf(dev
, "bss_peer_info", NULL
, 0, buf
, WLC_IOCTL_MAXLEN
, NULL
);
5345 if (unlikely(error
)) {
5346 WL_ERR(("could not get ibss peer info (%d)\n", error
));
5347 MFREE(cfg
->osh
, buf
, WLC_IOCTL_MAXLEN
);
5351 memcpy(&peer_list_info
, buf
, sizeof(peer_list_info
));
5352 peer_list_info
.version
= htod16(peer_list_info
.version
);
5353 peer_list_info
.bss_peer_info_len
= htod16(peer_list_info
.bss_peer_info_len
);
5354 peer_list_info
.count
= htod32(peer_list_info
.count
);
5356 WL_DBG(("ver:%d, len:%d, count:%d\n", peer_list_info
.version
,
5357 peer_list_info
.bss_peer_info_len
, peer_list_info
.count
));
5359 if (peer_list_info
.count
> 0) {
5361 bytes_written
+= snprintf(&command
[bytes_written
], total_len
, "%u ",
5362 peer_list_info
.count
);
5364 peer_info
= (bss_peer_info_t
*) ((char *)buf
+ BSS_PEER_LIST_INFO_FIXED_LEN
);
5366 for (i
= 0; i
< peer_list_info
.count
; i
++) {
5368 WL_DBG(("index:%d rssi:%d, tx:%u, rx:%u\n", i
, peer_info
->rssi
,
5369 peer_info
->tx_rate
, peer_info
->rx_rate
));
5372 memcmp(&mac_ea
, &peer_info
->ea
, sizeof(struct ether_addr
)) == 0) {
5376 if (bAll
|| found
) {
5377 bytes_written
+= snprintf(&command
[bytes_written
],
5378 total_len
- bytes_written
,
5379 MACF
" %u %d ", ETHER_TO_MACF(peer_info
->ea
),
5380 peer_info
->tx_rate
/1000, peer_info
->rssi
);
5381 if (bytes_written
>= total_len
) {
5382 WL_ERR(("%s: Insufficient memory, %d bytes\n",
5383 __FUNCTION__
, total_len
));
5392 peer_info
= (bss_peer_info_t
*)((char *)peer_info
+sizeof(bss_peer_info_t
));
5396 WL_ERR(("could not get ibss peer info : no item\n"));
5398 WL_DBG(("command(%u):%s\n", total_len
, command
));
5399 WL_DBG(("bytes_written:%d\n", bytes_written
));
5401 MFREE(cfg
->osh
, buf
, WLC_IOCTL_MAXLEN
);
5402 return bytes_written
;
5405 int wl_android_set_ibss_routetable(struct net_device
*dev
, char *command
)
5408 char *pcmd
= command
;
5410 ibss_route_tbl_t
*route_tbl
= NULL
;
5411 char *ioctl_buf
= NULL
;
5413 uint32 route_tbl_len
;
5417 struct ipv4_addr dipaddr
;
5418 struct ether_addr ea
;
5419 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5421 route_tbl_len
= sizeof(ibss_route_tbl_t
) +
5422 (MAX_IBSS_ROUTE_TBL_ENTRY
- 1) * sizeof(ibss_route_entry_t
);
5423 route_tbl
= (ibss_route_tbl_t
*)MALLOCZ(cfg
->osh
, route_tbl_len
);
5425 WL_ERR(("Route TBL alloc failed\n"));
5428 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
5430 WL_ERR(("ioctl memory alloc failed\n"));
5432 MFREE(cfg
->osh
, route_tbl
, route_tbl_len
);
5436 memset(ioctl_buf
, 0, WLC_IOCTL_MEDLEN
);
5439 str
= bcmstrtok(&pcmd
, " ", NULL
);
5442 str
= bcmstrtok(&pcmd
, " ", NULL
);
5444 WL_ERR(("Invalid number parameter %s\n", str
));
5448 entries
= bcm_strtoul(str
, &endptr
, 0);
5449 if (*endptr
!= '\0') {
5450 WL_ERR(("Invalid number parameter %s\n", str
));
5454 if (entries
> MAX_IBSS_ROUTE_TBL_ENTRY
) {
5455 WL_ERR(("Invalid entries number %u\n", entries
));
5460 WL_INFORM(("Routing table count:%u\n", entries
));
5461 route_tbl
->num_entry
= entries
;
5463 for (i
= 0; i
< entries
; i
++) {
5464 str
= bcmstrtok(&pcmd
, " ", NULL
);
5465 if (!str
|| !bcm_atoipv4(str
, &dipaddr
)) {
5466 WL_ERR(("Invalid ip string %s\n", str
));
5471 str
= bcmstrtok(&pcmd
, " ", NULL
);
5472 if (!str
|| !bcm_ether_atoe(str
, &ea
)) {
5473 WL_ERR(("Invalid ethernet string %s\n", str
));
5477 bcopy(&dipaddr
, &route_tbl
->route_entry
[i
].ipv4_addr
, IPV4_ADDR_LEN
);
5478 bcopy(&ea
, &route_tbl
->route_entry
[i
].nexthop
, ETHER_ADDR_LEN
);
5481 route_tbl_len
= sizeof(ibss_route_tbl_t
) +
5482 ((!entries
?0:(entries
- 1)) * sizeof(ibss_route_entry_t
));
5483 err
= wldev_iovar_setbuf(dev
, "ibss_route_tbl",
5484 route_tbl
, route_tbl_len
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
5485 if (err
!= BCME_OK
) {
5486 WL_ERR(("Fail to set iovar %d\n", err
));
5492 MFREE(cfg
->osh
, route_tbl
, sizeof(ibss_route_tbl_t
) +
5493 (MAX_IBSS_ROUTE_TBL_ENTRY
- 1) * sizeof(ibss_route_entry_t
));
5496 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
5503 wl_android_set_ibss_ampdu(struct net_device
*dev
, char *command
, int total_len
)
5505 char *pcmd
= command
;
5506 char *str
= NULL
, *endptr
= NULL
;
5507 struct ampdu_aggr aggr
;
5508 char smbuf
[WLC_IOCTL_SMLEN
];
5511 int wme_AC2PRIO
[AC_COUNT
][2] = {
5512 {PRIO_8021D_VO
, PRIO_8021D_NC
}, /* AC_VO - 3 */
5513 {PRIO_8021D_CL
, PRIO_8021D_VI
}, /* AC_VI - 2 */
5514 {PRIO_8021D_BK
, PRIO_8021D_NONE
}, /* AC_BK - 1 */
5515 {PRIO_8021D_BE
, PRIO_8021D_EE
}}; /* AC_BE - 0 */
5517 WL_DBG(("set ibss ampdu:%s\n", command
));
5519 memset(&aggr
, 0, sizeof(aggr
));
5520 /* Cofigure all priorities */
5521 aggr
.conf_TID_bmap
= NBITMASK(NUMPRIO
);
5523 /* acquire parameters */
5525 str
= bcmstrtok(&pcmd
, " ", NULL
);
5527 for (idx
= 0; idx
< AC_COUNT
; idx
++) {
5529 str
= bcmstrtok(&pcmd
, " ", NULL
);
5531 WL_ERR(("Invalid parameter : %s\n", pcmd
));
5534 on
= bcm_strtoul(str
, &endptr
, 0) ? TRUE
: FALSE
;
5535 if (*endptr
!= '\0') {
5536 WL_ERR(("Invalid number format %s\n", str
));
5540 setbit(&aggr
.enab_TID_bmap
, wme_AC2PRIO
[idx
][0]);
5541 setbit(&aggr
.enab_TID_bmap
, wme_AC2PRIO
[idx
][1]);
5545 err
= wldev_iovar_setbuf(dev
, "ampdu_txaggr", (void *)&aggr
,
5546 sizeof(aggr
), smbuf
, WLC_IOCTL_SMLEN
, NULL
);
5548 return ((err
== 0) ? total_len
: err
);
5551 int wl_android_set_ibss_antenna(struct net_device
*dev
, char *command
, int total_len
)
5553 char *pcmd
= command
;
5555 int txchain
, rxchain
;
5558 WL_DBG(("set ibss antenna:%s\n", command
));
5560 /* acquire parameters */
5562 str
= bcmstrtok(&pcmd
, " ", NULL
);
5565 str
= bcmstrtok(&pcmd
, " ", NULL
);
5567 WL_ERR(("Invalid parameter : %s\n", pcmd
));
5570 txchain
= bcm_atoi(str
);
5573 str
= bcmstrtok(&pcmd
, " ", NULL
);
5575 WL_ERR(("Invalid parameter : %s\n", pcmd
));
5578 rxchain
= bcm_atoi(str
);
5580 err
= wldev_iovar_setint(dev
, "txchain", txchain
);
5583 err
= wldev_iovar_setint(dev
, "rxchain", rxchain
);
5584 return ((err
== 0)?total_len
:err
);
5586 #endif /* WLAIBSS */
5588 int wl_keep_alive_set(struct net_device
*dev
, char* extra
)
5590 wl_mkeep_alive_pkt_t mkeep_alive_pkt
;
5592 uint period_msec
= 0;
5594 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5596 if (extra
== NULL
) {
5597 DHD_ERROR(("%s: extra is NULL\n", __FUNCTION__
));
5600 if (sscanf(extra
, "%d", &period_msec
) != 1) {
5601 DHD_ERROR(("%s: sscanf error. check period_msec value\n", __FUNCTION__
));
5604 DHD_ERROR(("%s: period_msec is %d\n", __FUNCTION__
, period_msec
));
5606 memset(&mkeep_alive_pkt
, 0, sizeof(wl_mkeep_alive_pkt_t
));
5608 mkeep_alive_pkt
.period_msec
= period_msec
;
5609 mkeep_alive_pkt
.version
= htod16(WL_MKEEP_ALIVE_VERSION
);
5610 mkeep_alive_pkt
.length
= htod16(WL_MKEEP_ALIVE_FIXED_LEN
);
5612 /* Setup keep alive zero for null packet generation */
5613 mkeep_alive_pkt
.keep_alive_id
= 0;
5614 mkeep_alive_pkt
.len_bytes
= 0;
5616 buf
= (char *)MALLOC(cfg
->osh
, WLC_IOCTL_SMLEN
);
5618 DHD_ERROR(("%s: buffer alloc failed\n", __FUNCTION__
));
5621 ret
= wldev_iovar_setbuf(dev
, "mkeep_alive", (char *)&mkeep_alive_pkt
,
5622 WL_MKEEP_ALIVE_FIXED_LEN
, buf
, WLC_IOCTL_SMLEN
, NULL
);
5624 DHD_ERROR(("%s:keep_alive set failed:%d\n", __FUNCTION__
, ret
));
5626 DHD_TRACE(("%s:keep_alive set ok\n", __FUNCTION__
));
5627 MFREE(cfg
->osh
, buf
, WLC_IOCTL_SMLEN
);
5630 #ifdef P2PRESP_WFDIE_SRC
5631 static int wl_android_get_wfdie_resp(struct net_device
*dev
, char *command
, int total_len
)
5634 int bytes_written
= 0;
5635 int only_resp_wfdsrc
= 0;
5637 error
= wldev_iovar_getint(dev
, "p2p_only_resp_wfdsrc", &only_resp_wfdsrc
);
5639 DHD_ERROR(("%s: Failed to get the mode for only_resp_wfdsrc, error = %d\n",
5640 __FUNCTION__
, error
));
5644 bytes_written
= snprintf(command
, total_len
, "%s %d",
5645 CMD_P2P_GET_WFDIE_RESP
, only_resp_wfdsrc
);
5647 return bytes_written
;
5650 static int wl_android_set_wfdie_resp(struct net_device
*dev
, int only_resp_wfdsrc
)
5654 error
= wldev_iovar_setint(dev
, "p2p_only_resp_wfdsrc", only_resp_wfdsrc
);
5656 DHD_ERROR(("%s: Failed to set only_resp_wfdsrc %d, error = %d\n",
5657 __FUNCTION__
, only_resp_wfdsrc
, error
));
5663 #endif /* P2PRESP_WFDIE_SRC */
5665 #ifdef BT_WIFI_HANDOVER
5667 wl_tbow_teardown(struct net_device
*dev
)
5670 char buf
[WLC_IOCTL_SMLEN
];
5671 tbow_setup_netinfo_t netinfo
;
5672 memset(&netinfo
, 0, sizeof(netinfo
));
5673 netinfo
.opmode
= TBOW_HO_MODE_TEARDOWN
;
5675 err
= wldev_iovar_setbuf_bsscfg(dev
, "tbow_doho", &netinfo
,
5676 sizeof(tbow_setup_netinfo_t
), buf
, WLC_IOCTL_SMLEN
, 0, NULL
);
5678 WL_ERR(("tbow_doho iovar error %d\n", err
));
5683 #endif /* BT_WIFI_HANOVER */
5687 wl_android_set_rps_cpus(struct net_device
*dev
, char *command
)
5691 enable
= command
[strlen(CMD_RPSMODE
) + 1] - '0';
5692 error
= dhd_rps_cpus_enable(dev
, enable
);
5694 #if defined(DHDTCPACK_SUPPRESS) && defined(BCMPCIE) && defined(WL_CFG80211)
5696 void *dhdp
= wl_cfg80211_get_dhdp(net
);
5698 DHD_TRACE(("%s : set ack suppress. TCPACK_SUP_HOLD.\n", __FUNCTION__
));
5699 dhd_tcpack_suppress_set(dhdp
, TCPACK_SUP_HOLD
);
5701 DHD_TRACE(("%s : clear ack suppress.\n", __FUNCTION__
));
5702 dhd_tcpack_suppress_set(dhdp
, TCPACK_SUP_OFF
);
5705 #endif /* DHDTCPACK_SUPPRESS && BCMPCIE && WL_CFG80211 */
5709 #endif /* SET_RPS_CPUS */
5711 static int wl_android_get_link_status(struct net_device
*dev
, char *command
,
5714 int bytes_written
, error
, result
= 0, single_stream
, stf
= -1, i
, nss
= 0, mcs_map
;
5718 int datalen
= sizeof(uint32
) + sizeof(wl_bss_info_t
);
5721 memset(buf
, 0, datalen
);
5722 /* get BSS information */
5723 *(u32
*) buf
= htod32(datalen
);
5724 error
= wldev_ioctl_get(dev
, WLC_GET_BSS_INFO
, (void *)buf
, datalen
);
5725 if (unlikely(error
)) {
5726 WL_ERR(("Could not get bss info %d\n", error
));
5730 bi
= (wl_bss_info_t
*) (buf
+ sizeof(uint32
));
5732 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++) {
5733 if (bi
->BSSID
.octet
[i
] > 0) {
5738 if (i
== ETHER_ADDR_LEN
) {
5739 WL_DBG(("No BSSID\n"));
5743 /* check VHT capability at beacon */
5745 if (CHSPEC_IS5G(bi
->chanspec
)) {
5746 result
|= WL_ANDROID_LINK_AP_VHT_SUPPORT
;
5750 /* get a rspec (radio spectrum) rate */
5751 error
= wldev_iovar_getint(dev
, "nrate", &rspec
);
5752 if (unlikely(error
) || rspec
== 0) {
5753 WL_ERR(("get link status error (%d)\n", error
));
5757 encode
= (rspec
& WL_RSPEC_ENCODING_MASK
);
5758 txexp
= (rspec
& WL_RSPEC_TXEXP_MASK
) >> WL_RSPEC_TXEXP_SHIFT
;
5761 case WL_RSPEC_ENCODE_HT
:
5762 /* check Rx MCS Map for HT */
5763 for (i
= 0; i
< MAX_STREAMS_SUPPORTED
; i
++) {
5765 if (i
== MAX_STREAMS_SUPPORTED
-1) {
5768 if (bi
->basic_mcs
[i
] & bitmap
) {
5773 case WL_RSPEC_ENCODE_VHT
:
5774 /* check Rx MCS Map for VHT */
5775 for (i
= 1; i
<= VHT_CAP_MCS_MAP_NSS_MAX
; i
++) {
5776 mcs_map
= VHT_MCS_MAP_GET_MCS_PER_SS(i
, dtoh16(bi
->vht_rxmcsmap
));
5777 if (mcs_map
!= VHT_CAP_MCS_MAP_NONE
) {
5784 /* check MIMO capability with nss in beacon */
5786 result
|= WL_ANDROID_LINK_AP_MIMO_SUPPORT
;
5789 single_stream
= (encode
== WL_RSPEC_ENCODE_RATE
) ||
5790 ((encode
== WL_RSPEC_ENCODE_HT
) && (rspec
& WL_RSPEC_HT_MCS_MASK
) < 8) ||
5791 ((encode
== WL_RSPEC_ENCODE_VHT
) &&
5792 ((rspec
& WL_RSPEC_VHT_NSS_MASK
) >> WL_RSPEC_VHT_NSS_SHIFT
) == 1);
5795 if ((rspec
& WL_RSPEC_STBC
) && single_stream
) {
5796 stf
= OLD_NRATE_STF_STBC
;
5798 stf
= (single_stream
) ? OLD_NRATE_STF_SISO
: OLD_NRATE_STF_SDM
;
5800 } else if (txexp
== 1 && single_stream
) {
5801 stf
= OLD_NRATE_STF_CDD
;
5804 /* check 11ac (VHT) */
5805 if (encode
== WL_RSPEC_ENCODE_VHT
) {
5806 if (CHSPEC_IS5G(bi
->chanspec
)) {
5807 result
|= WL_ANDROID_LINK_VHT
;
5812 if (result
& WL_ANDROID_LINK_AP_MIMO_SUPPORT
) {
5814 case OLD_NRATE_STF_SISO
:
5816 case OLD_NRATE_STF_CDD
:
5817 case OLD_NRATE_STF_STBC
:
5818 result
|= WL_ANDROID_LINK_MIMO
;
5820 case OLD_NRATE_STF_SDM
:
5821 if (!single_stream
) {
5822 result
|= WL_ANDROID_LINK_MIMO
;
5828 WL_DBG(("%s:result=%d, stf=%d, single_stream=%d, mcs map=%d\n",
5829 __FUNCTION__
, result
, stf
, single_stream
, nss
));
5831 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_LINK_STATUS
, result
);
5833 return bytes_written
;
5836 #ifdef P2P_LISTEN_OFFLOADING
5839 wl_cfg80211_p2plo_deinit(struct bcm_cfg80211
*cfg
)
5843 dhd_pub_t
*dhd
= NULL
;
5844 if (!cfg
|| !cfg
->p2p
) {
5845 WL_ERR(("Wl %p or cfg->p2p %p is null\n",
5846 cfg
, cfg
? cfg
->p2p
: 0));
5850 dhd
= (dhd_pub_t
*)(cfg
->pub
);
5852 WL_ERR(("bus is already down\n"));
5856 bssidx
= wl_to_p2p_bss_bssidx(cfg
, P2PAPI_BSSCFG_DEVICE
);
5857 ret
= wldev_iovar_setbuf_bsscfg(bcmcfg_to_prmry_ndev(cfg
),
5858 "p2po_stop", NULL
, 0,
5859 cfg
->ioctl_buf
, WLC_IOCTL_SMLEN
, bssidx
, &cfg
->ioctl_buf_sync
);
5861 WL_ERR(("p2po_stop Failed :%d\n", ret
));
5867 wl_cfg80211_p2plo_listen_start(struct net_device
*dev
, u8
*buf
, int len
)
5869 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5870 s32 bssidx
= wl_to_p2p_bss_bssidx(cfg
, P2PAPI_BSSCFG_DEVICE
);
5871 wl_p2plo_listen_t p2plo_listen
;
5877 if (WL_DRV_STATUS_SENDING_AF_FRM_EXT(cfg
)) {
5878 WL_ERR(("Sending Action Frames. Try it again.\n"));
5882 if (wl_get_drv_status_all(cfg
, SCANNING
)) {
5883 WL_ERR(("Scanning already\n"));
5887 if (wl_get_drv_status(cfg
, SCAN_ABORTING
, dev
)) {
5888 WL_ERR(("Scanning being aborted\n"));
5892 if (wl_get_p2p_status(cfg
, DISC_IN_PROGRESS
)) {
5893 WL_ERR(("p2p listen offloading already running\n"));
5897 /* Just in case if it is not enabled */
5898 if ((ret
= wl_cfgp2p_enable_discovery(cfg
, dev
, NULL
, 0)) < 0) {
5899 WL_ERR(("cfgp2p_enable discovery failed"));
5903 bzero(&p2plo_listen
, sizeof(wl_p2plo_listen_t
));
5906 sscanf(buf
, " %10d %10d %10d %10d", &channel
, &period
, &interval
, &count
);
5907 if ((channel
== 0) || (period
== 0) ||
5908 (interval
== 0) || (count
== 0)) {
5909 WL_ERR(("Wrong argument %d/%d/%d/%d \n",
5910 channel
, period
, interval
, count
));
5914 p2plo_listen
.period
= period
;
5915 p2plo_listen
.interval
= interval
;
5916 p2plo_listen
.count
= count
;
5918 WL_ERR(("channel:%d period:%d, interval:%d count:%d\n",
5919 channel
, period
, interval
, count
));
5921 WL_ERR(("Argument len is wrong.\n"));
5926 if ((ret
= wldev_iovar_setbuf_bsscfg(dev
, "p2po_listen_channel", (void*)&channel
,
5927 sizeof(channel
), cfg
->ioctl_buf
, WLC_IOCTL_SMLEN
,
5928 bssidx
, &cfg
->ioctl_buf_sync
)) < 0) {
5929 WL_ERR(("p2po_listen_channel Failed :%d\n", ret
));
5933 if ((ret
= wldev_iovar_setbuf_bsscfg(dev
, "p2po_listen", (void*)&p2plo_listen
,
5934 sizeof(wl_p2plo_listen_t
), cfg
->ioctl_buf
, WLC_IOCTL_SMLEN
,
5935 bssidx
, &cfg
->ioctl_buf_sync
)) < 0) {
5936 WL_ERR(("p2po_listen Failed :%d\n", ret
));
5940 wl_set_p2p_status(cfg
, DISC_IN_PROGRESS
);
5945 wl_cfg80211_p2plo_listen_stop(struct net_device
*dev
)
5947 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5948 s32 bssidx
= wl_to_p2p_bss_bssidx(cfg
, P2PAPI_BSSCFG_DEVICE
);
5951 if ((ret
= wldev_iovar_setbuf_bsscfg(dev
, "p2po_stop", NULL
,
5952 0, cfg
->ioctl_buf
, WLC_IOCTL_SMLEN
,
5953 bssidx
, &cfg
->ioctl_buf_sync
)) < 0) {
5954 WL_ERR(("p2po_stop Failed :%d\n", ret
));
5963 wl_cfg80211_p2plo_offload(struct net_device
*dev
, char *cmd
, char* buf
, int len
)
5967 WL_ERR(("Entry cmd:%s arg_len:%d \n", cmd
, len
));
5969 if (strncmp(cmd
, "P2P_LO_START", strlen("P2P_LO_START")) == 0) {
5970 ret
= wl_cfg80211_p2plo_listen_start(dev
, buf
, len
);
5971 } else if (strncmp(cmd
, "P2P_LO_STOP", strlen("P2P_LO_STOP")) == 0) {
5972 ret
= wl_cfg80211_p2plo_listen_stop(dev
);
5974 WL_ERR(("Request for Unsupported CMD:%s \n", buf
));
5980 wl_cfg80211_cancel_p2plo(struct bcm_cfg80211
*cfg
)
5982 struct wireless_dev
*wdev
;
5987 wdev
= bcmcfg_to_p2p_wdev(cfg
);
5989 if (wl_get_p2p_status(cfg
, DISC_IN_PROGRESS
)) {
5990 WL_INFORM_MEM(("P2P_FIND: Discovery offload is already in progress."
5992 wl_clr_p2p_status(cfg
, DISC_IN_PROGRESS
);
5994 #if defined(WL_CFG80211_P2P_DEV_IF)
5995 cfg80211_remain_on_channel_expired(wdev
,
5997 &cfg
->remain_on_chan
, GFP_KERNEL
);
5999 cfg80211_remain_on_channel_expired(wdev
,
6001 &cfg
->remain_on_chan
,
6002 cfg
->remain_on_chan_type
, GFP_KERNEL
);
6003 #endif /* WL_CFG80211_P2P_DEV_IF */
6005 wl_cfg80211_p2plo_deinit(cfg
);
6008 #endif /* P2P_LISTEN_OFFLOADING */
6010 #ifdef DYNAMIC_MUMIMO_CONTROL
6012 wl_android_get_murx_bfe_cap(struct net_device
*dev
, char *command
, int total_len
)
6016 int bytes_written
= 0;
6018 /* Now there is only single interface */
6019 err
= wl_get_murx_bfe_cap(dev
, &cap
);
6020 if (unlikely(err
)) {
6021 WL_ERR(("Failed to get murx_bfe_cap, error = %d\n", err
));
6025 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_MURX_BFE_CAP
, cap
);
6027 return bytes_written
;
6031 wl_android_set_murx_bfe_cap(struct net_device
*dev
, int val
)
6035 err
= wl_set_murx_bfe_cap(dev
, val
, TRUE
);
6036 if (unlikely(err
)) {
6037 WL_ERR(("Failed to set murx_bfe_cap to %d, error = %d\n", val
, err
));
6044 wl_android_get_bss_support_mumimo(struct net_device
*dev
, char *command
, int total_len
)
6047 int bytes_written
= 0;
6049 val
= wl_check_bss_support_mumimo(dev
);
6050 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_BSS_SUPPORT_MUMIMO
, val
);
6052 return bytes_written
;
6054 #endif /* DYNAMIC_MUMIMO_CONTROL */
6056 #ifdef SUPPORT_RSSI_SUM_REPORT
6058 wl_android_get_rssi_per_ant(struct net_device
*dev
, char *command
, int total_len
)
6060 wl_rssi_ant_mimo_t rssi_ant_mimo
;
6061 char *ifname
= NULL
;
6062 char *peer_mac
= NULL
;
6063 char *mimo_cmd
= "mimo";
6066 int bytes_written
= 0;
6067 bool mimo_rssi
= FALSE
;
6069 memset(&rssi_ant_mimo
, 0, sizeof(wl_rssi_ant_mimo_t
));
6071 * STA I/F: DRIVER GET_RSSI_PER_ANT <ifname> <mimo>
6072 * AP/GO I/F: DRIVER GET_RSSI_PER_ANT <ifname> <Peer MAC addr> <mimo>
6077 token
= bcmstrtok(&pos
, " ", NULL
);
6079 /* get the interface name */
6080 token
= bcmstrtok(&pos
, " ", NULL
);
6082 WL_ERR(("Invalid arguments\n"));
6087 /* Optional: Check the MIMO RSSI mode or peer MAC address */
6088 token
= bcmstrtok(&pos
, " ", NULL
);
6090 /* Check the MIMO RSSI mode */
6091 if (strncmp(token
, mimo_cmd
, strlen(mimo_cmd
)) == 0) {
6098 /* Optional: Check the MIMO RSSI mode - RSSI sum across antennas */
6099 token
= bcmstrtok(&pos
, " ", NULL
);
6100 if (token
&& strncmp(token
, mimo_cmd
, strlen(mimo_cmd
)) == 0) {
6104 err
= wl_get_rssi_per_ant(dev
, ifname
, peer_mac
, &rssi_ant_mimo
);
6105 if (unlikely(err
)) {
6106 WL_ERR(("Failed to get RSSI info, err=%d\n", err
));
6110 /* Parse the results */
6111 WL_DBG(("ifname %s, version %d, count %d, mimo rssi %d\n",
6112 ifname
, rssi_ant_mimo
.version
, rssi_ant_mimo
.count
, mimo_rssi
));
6114 WL_DBG(("MIMO RSSI: %d\n", rssi_ant_mimo
.rssi_sum
));
6115 bytes_written
= snprintf(command
, total_len
, "%s MIMO %d",
6116 CMD_GET_RSSI_PER_ANT
, rssi_ant_mimo
.rssi_sum
);
6119 bytes_written
= snprintf(command
, total_len
, "%s PER_ANT ", CMD_GET_RSSI_PER_ANT
);
6120 for (cnt
= 0; cnt
< rssi_ant_mimo
.count
; cnt
++) {
6121 WL_DBG(("RSSI[%d]: %d\n", cnt
, rssi_ant_mimo
.rssi_ant
[cnt
]));
6122 bytes_written
= snprintf(command
, total_len
, "%d ",
6123 rssi_ant_mimo
.rssi_ant
[cnt
]);
6127 return bytes_written
;
6131 wl_android_set_rssi_logging(struct net_device
*dev
, char *command
, int total_len
)
6133 rssilog_set_param_t set_param
;
6137 memset(&set_param
, 0, sizeof(rssilog_set_param_t
));
6139 * DRIVER SET_RSSI_LOGGING <enable/disable> <RSSI Threshold> <Time Threshold>
6144 token
= bcmstrtok(&pos
, " ", NULL
);
6146 /* enable/disable */
6147 token
= bcmstrtok(&pos
, " ", NULL
);
6149 WL_ERR(("Invalid arguments\n"));
6152 set_param
.enable
= bcm_atoi(token
);
6154 /* RSSI Threshold */
6155 token
= bcmstrtok(&pos
, " ", NULL
);
6157 WL_ERR(("Invalid arguments\n"));
6160 set_param
.rssi_threshold
= bcm_atoi(token
);
6162 /* Time Threshold */
6163 token
= bcmstrtok(&pos
, " ", NULL
);
6165 WL_ERR(("Invalid arguments\n"));
6168 set_param
.time_threshold
= bcm_atoi(token
);
6170 WL_DBG(("enable %d, RSSI threshold %d, Time threshold %d\n", set_param
.enable
,
6171 set_param
.rssi_threshold
, set_param
.time_threshold
));
6173 err
= wl_set_rssi_logging(dev
, (void *)&set_param
);
6174 if (unlikely(err
)) {
6175 WL_ERR(("Failed to configure RSSI logging: enable %d, RSSI Threshold %d,"
6176 " Time Threshold %d\n", set_param
.enable
, set_param
.rssi_threshold
,
6177 set_param
.time_threshold
));
6184 wl_android_get_rssi_logging(struct net_device
*dev
, char *command
, int total_len
)
6186 rssilog_get_param_t get_param
;
6188 int bytes_written
= 0;
6190 err
= wl_get_rssi_logging(dev
, (void *)&get_param
);
6191 if (unlikely(err
)) {
6192 WL_ERR(("Failed to get RSSI logging info\n"));
6196 WL_DBG(("report_count %d, enable %d, rssi_threshold %d, time_threshold %d\n",
6197 get_param
.report_count
, get_param
.enable
, get_param
.rssi_threshold
,
6198 get_param
.time_threshold
));
6200 /* Parse the parameter */
6201 if (!get_param
.enable
) {
6202 WL_DBG(("RSSI LOGGING: Feature is disables\n"));
6203 bytes_written
= snprintf(command
, total_len
,
6204 "%s FEATURE DISABLED\n", CMD_GET_RSSI_LOGGING
);
6205 } else if (get_param
.enable
&
6206 (RSSILOG_FLAG_FEATURE_SW
| RSSILOG_FLAG_REPORT_READY
)) {
6207 if (!get_param
.report_count
) {
6208 WL_DBG(("[PASS] RSSI difference across antennas is within"
6209 " threshold limits\n"));
6210 bytes_written
= snprintf(command
, total_len
, "%s PASS\n",
6211 CMD_GET_RSSI_LOGGING
);
6213 WL_DBG(("[FAIL] RSSI difference across antennas found "
6214 "to be greater than %3d dB\n", get_param
.rssi_threshold
));
6215 WL_DBG(("[FAIL] RSSI difference check have failed for "
6216 "%d out of %d times\n", get_param
.report_count
,
6217 get_param
.time_threshold
));
6218 WL_DBG(("[FAIL] RSSI difference is being monitored once "
6219 "per second, for a %d secs window\n", get_param
.time_threshold
));
6220 bytes_written
= snprintf(command
, total_len
, "%s FAIL - RSSI Threshold "
6221 "%d dBm for %d out of %d times\n", CMD_GET_RSSI_LOGGING
,
6222 get_param
.rssi_threshold
, get_param
.report_count
,
6223 get_param
.time_threshold
);
6226 WL_DBG(("[BUSY] Reprot is not ready\n"));
6227 bytes_written
= snprintf(command
, total_len
, "%s BUSY - NOT READY\n",
6228 CMD_GET_RSSI_LOGGING
);
6231 return bytes_written
;
6233 #endif /* SUPPORT_RSSI_SUM_REPORT */
6235 #ifdef SET_PCIE_IRQ_CPU_CORE
6237 wl_android_set_irq_cpucore(struct net_device
*net
, int affinity_cmd
)
6239 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(net
);
6241 WL_ERR(("dhd is NULL\n"));
6245 if (affinity_cmd
< PCIE_IRQ_AFFINITY_OFF
|| affinity_cmd
> PCIE_IRQ_AFFINITY_LAST
) {
6246 WL_ERR(("Wrong Affinity cmds:%d, %s\n", affinity_cmd
, __FUNCTION__
));
6250 dhd_set_irq_cpucore(dhdp
, affinity_cmd
);
6252 #endif /* SET_PCIE_IRQ_CPU_CORE */
6256 wl_android_lqcm_enable(struct net_device
*net
, int lqcm_enable
)
6260 err
= wldev_iovar_setint(net
, "lqcm", lqcm_enable
);
6261 if (err
!= BCME_OK
) {
6262 WL_ERR(("failed to set lqcm enable %d, error = %d\n", lqcm_enable
, err
));
6269 wl_android_get_lqcm_report(struct net_device
*dev
, char *command
, int total_len
)
6271 int bytes_written
, err
= 0;
6272 uint32 lqcm_report
= 0;
6273 uint32 lqcm_enable
, tx_lqcm_idx
, rx_lqcm_idx
;
6275 err
= wldev_iovar_getint(dev
, "lqcm", &lqcm_report
);
6276 if (err
!= BCME_OK
) {
6277 WL_ERR(("failed to get lqcm report, error = %d\n", err
));
6280 lqcm_enable
= lqcm_report
& LQCM_ENAB_MASK
;
6281 tx_lqcm_idx
= (lqcm_report
& LQCM_TX_INDEX_MASK
) >> LQCM_TX_INDEX_SHIFT
;
6282 rx_lqcm_idx
= (lqcm_report
& LQCM_RX_INDEX_MASK
) >> LQCM_RX_INDEX_SHIFT
;
6284 WL_DBG(("lqcm report EN:%d, TX:%d, RX:%d\n", lqcm_enable
, tx_lqcm_idx
, rx_lqcm_idx
));
6286 bytes_written
= snprintf(command
, total_len
, "%s %d",
6287 CMD_GET_LQCM_REPORT
, lqcm_report
);
6289 return bytes_written
;
6291 #endif /* SUPPORT_LQCM */
6294 wl_android_get_snr(struct net_device
*dev
, char *command
, int total_len
)
6296 int bytes_written
, error
= 0;
6299 error
= wldev_iovar_getint(dev
, "snr", &snr
);
6301 DHD_ERROR(("%s: Failed to get SNR %d, error = %d\n",
6302 __FUNCTION__
, snr
, error
));
6306 bytes_written
= snprintf(command
, total_len
, "snr %d", snr
);
6307 DHD_INFO(("%s: command result is %s\n", __FUNCTION__
, command
));
6308 return bytes_written
;
6311 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
6313 wl_android_set_ap_beaconrate(struct net_device
*dev
, char *command
)
6317 char *ifname
= NULL
;
6321 * DRIVER SET_AP_BEACONRATE <rate> <ifname>
6326 token
= bcmstrtok(&pos
, " ", NULL
);
6329 token
= bcmstrtok(&pos
, " ", NULL
);
6332 rate
= bcm_atoi(token
);
6334 /* get the interface name */
6335 token
= bcmstrtok(&pos
, " ", NULL
);
6340 WL_DBG(("rate %d, ifacename %s\n", rate
, ifname
));
6342 err
= wl_set_ap_beacon_rate(dev
, rate
, ifname
);
6343 if (unlikely(err
)) {
6344 WL_ERR(("Failed to set ap beacon rate to %d, error = %d\n", rate
, err
));
6350 int wl_android_get_ap_basicrate(struct net_device
*dev
, char *command
, int total_len
)
6353 char *ifname
= NULL
;
6354 int bytes_written
= 0;
6356 * DRIVER GET_AP_BASICRATE <ifname>
6361 token
= bcmstrtok(&pos
, " ", NULL
);
6363 /* get the interface name */
6364 token
= bcmstrtok(&pos
, " ", NULL
);
6369 WL_DBG(("ifacename %s\n", ifname
));
6371 bytes_written
= wl_get_ap_basic_rate(dev
, command
, ifname
, total_len
);
6372 if (bytes_written
< 1) {
6373 WL_ERR(("Failed to get ap basic rate, error = %d\n", bytes_written
));
6377 return bytes_written
;
6379 #endif /* SUPPORT_AP_HIGHER_BEACONRATE */
6381 #ifdef SUPPORT_AP_RADIO_PWRSAVE
6383 wl_android_get_ap_rps(struct net_device
*dev
, char *command
, int total_len
)
6386 char *ifname
= NULL
;
6387 int bytes_written
= 0;
6388 char name
[IFNAMSIZ
];
6390 * DRIVER GET_AP_RPS <ifname>
6395 token
= bcmstrtok(&pos
, " ", NULL
);
6397 /* get the interface name */
6398 token
= bcmstrtok(&pos
, " ", NULL
);
6403 strncpy(name
, ifname
, IFNAMSIZ
);
6404 name
[IFNAMSIZ
-1] = '\0';
6405 WL_DBG(("ifacename %s\n", name
));
6407 bytes_written
= wl_get_ap_rps(dev
, command
, name
, total_len
);
6408 if (bytes_written
< 1) {
6409 WL_ERR(("Failed to get rps, error = %d\n", bytes_written
));
6413 return bytes_written
;
6418 wl_android_set_ap_rps(struct net_device
*dev
, char *command
, int total_len
)
6422 char *ifname
= NULL
;
6424 char name
[IFNAMSIZ
];
6427 * DRIVER SET_AP_RPS <0/1> <ifname>
6432 token
= bcmstrtok(&pos
, " ", NULL
);
6435 token
= bcmstrtok(&pos
, " ", NULL
);
6438 enable
= bcm_atoi(token
);
6440 /* get the interface name */
6441 token
= bcmstrtok(&pos
, " ", NULL
);
6446 strncpy(name
, ifname
, IFNAMSIZ
);
6447 name
[IFNAMSIZ
-1] = '\0';
6448 WL_DBG(("enable %d, ifacename %s\n", enable
, name
));
6450 err
= wl_set_ap_rps(dev
, enable
? TRUE
: FALSE
, name
);
6451 if (unlikely(err
)) {
6452 WL_ERR(("Failed to set rps, enable %d, error = %d\n", enable
, err
));
6459 wl_android_set_ap_rps_params(struct net_device
*dev
, char *command
, int total_len
)
6463 char *ifname
= NULL
;
6465 char name
[IFNAMSIZ
];
6467 memset(&rps
, 0, sizeof(rps
));
6469 * DRIVER SET_AP_RPS_PARAMS <pps> <level> <quiettime> <assoccheck> <ifname>
6474 token
= bcmstrtok(&pos
, " ", NULL
);
6477 token
= bcmstrtok(&pos
, " ", NULL
);
6480 rps
.pps
= bcm_atoi(token
);
6483 token
= bcmstrtok(&pos
, " ", NULL
);
6486 rps
.level
= bcm_atoi(token
);
6489 token
= bcmstrtok(&pos
, " ", NULL
);
6492 rps
.quiet_time
= bcm_atoi(token
);
6494 /* sta assoc check */
6495 token
= bcmstrtok(&pos
, " ", NULL
);
6498 rps
.sta_assoc_check
= bcm_atoi(token
);
6500 /* get the interface name */
6501 token
= bcmstrtok(&pos
, " ", NULL
);
6505 strncpy(name
, ifname
, IFNAMSIZ
);
6506 name
[IFNAMSIZ
-1] = '\0';
6508 WL_DBG(("pps %d, level %d, quiettime %d, sta_assoc_check %d, "
6509 "ifacename %s\n", rps
.pps
, rps
.level
, rps
.quiet_time
,
6510 rps
.sta_assoc_check
, name
));
6512 err
= wl_update_ap_rps_params(dev
, &rps
, name
);
6513 if (unlikely(err
)) {
6514 WL_ERR(("Failed to update rps, pps %d, level %d, quiettime %d, "
6515 "sta_assoc_check %d, err = %d\n", rps
.pps
, rps
.level
, rps
.quiet_time
,
6516 rps
.sta_assoc_check
, err
));
6521 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
6523 #if defined(DHD_HANG_SEND_UP_TEST)
6525 wl_android_make_hang_with_reason(struct net_device
*dev
, const char *string_num
)
6527 dhd_make_hang_with_reason(dev
, string_num
);
6529 #endif /* DHD_HANG_SEND_UP_TEST */
6531 #ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
6533 wl_android_check_priv_cmd_errors(struct net_device
*dev
)
6539 WL_ERR(("dev is NULL\n"));
6543 dhdp
= wl_cfg80211_get_dhdp(dev
);
6545 WL_ERR(("dhdp is NULL\n"));
6549 #ifdef DHD_FW_COREDUMP
6550 memdump_mode
= dhdp
->memdump_enabled
;
6552 /* Default enable if DHD doesn't support SOCRAM dump */
6554 #endif /* DHD_FW_COREDUMP */
6556 if (report_hang_privcmd_err
) {
6559 priv_cmd_errors
= 0;
6562 /* Trigger HANG event only if memdump mode is enabled
6563 * due to customer's request
6565 if (memdump_mode
&& (priv_cmd_errors
> NUMBER_SEQUENTIAL_PRIVCMD_ERRORS
)) {
6566 WL_ERR(("Send HANG event due to sequential private cmd errors\n"));
6567 priv_cmd_errors
= 0;
6568 #ifdef DHD_FW_COREDUMP
6569 /* Take a SOCRAM dump */
6570 dhdp
->memdump_type
= DUMP_TYPE_SEQUENTIAL_PRIVCMD_ERROR
;
6571 dhd_common_socram_dump(dhdp
);
6572 #endif /* DHD_FW_COREDUMP */
6573 /* Send the HANG event to upper layer */
6574 dhdp
->hang_reason
= HANG_REASON_SEQUENTIAL_PRIVCMD_ERROR
;
6575 dhd_os_check_hang(dhdp
, 0, -EREMOTEIO
);
6578 #endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
6580 #ifdef DHD_PKT_LOGGING
6582 wl_android_pktlog_filter_enable(struct net_device
*dev
, char *command
, int total_len
)
6584 int bytes_written
= 0;
6585 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6586 dhd_pktlog_filter_t
*filter
;
6589 if (!dhdp
|| !dhdp
->pktlog
) {
6590 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6591 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6595 filter
= dhdp
->pktlog
->pktlog_filter
;
6597 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_TXPKT_CASE
, TRUE
);
6598 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_TXSTATUS_CASE
, TRUE
);
6599 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_RXPKT_CASE
, TRUE
);
6601 if (err
== BCME_OK
) {
6602 bytes_written
= snprintf(command
, total_len
, "OK");
6603 DHD_ERROR(("%s: pktlog filter enable success\n", __FUNCTION__
));
6605 DHD_ERROR(("%s: pktlog filter enable fail\n", __FUNCTION__
));
6609 return bytes_written
;
6613 wl_android_pktlog_filter_disable(struct net_device
*dev
, char *command
, int total_len
)
6615 int bytes_written
= 0;
6616 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6617 dhd_pktlog_filter_t
*filter
;
6620 if (!dhdp
|| !dhdp
->pktlog
) {
6621 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6622 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6626 filter
= dhdp
->pktlog
->pktlog_filter
;
6628 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_TXPKT_CASE
, FALSE
);
6629 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_TXSTATUS_CASE
, FALSE
);
6630 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_RXPKT_CASE
, FALSE
);
6632 if (err
== BCME_OK
) {
6633 bytes_written
= snprintf(command
, total_len
, "OK");
6634 DHD_ERROR(("%s: pktlog filter disable success\n", __FUNCTION__
));
6636 DHD_ERROR(("%s: pktlog filter disable fail\n", __FUNCTION__
));
6640 return bytes_written
;
6644 wl_android_pktlog_filter_pattern_enable(struct net_device
*dev
, char *command
, int total_len
)
6646 int bytes_written
= 0;
6647 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6648 dhd_pktlog_filter_t
*filter
;
6651 if (!dhdp
|| !dhdp
->pktlog
) {
6652 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6653 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6657 filter
= dhdp
->pktlog
->pktlog_filter
;
6659 if (strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE
) + 1 > total_len
) {
6663 err
= dhd_pktlog_filter_pattern_enable(filter
,
6664 command
+ strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE
) + 1, TRUE
);
6666 if (err
== BCME_OK
) {
6667 bytes_written
= snprintf(command
, total_len
, "OK");
6668 DHD_ERROR(("%s: pktlog filter pattern enable success\n", __FUNCTION__
));
6670 DHD_ERROR(("%s: pktlog filter pattern enable fail\n", __FUNCTION__
));
6674 return bytes_written
;
6678 wl_android_pktlog_filter_pattern_disable(struct net_device
*dev
, char *command
, int total_len
)
6680 int bytes_written
= 0;
6681 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6682 dhd_pktlog_filter_t
*filter
;
6685 if (!dhdp
|| !dhdp
->pktlog
) {
6686 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6687 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6691 filter
= dhdp
->pktlog
->pktlog_filter
;
6693 if (strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE
) + 1 > total_len
) {
6697 err
= dhd_pktlog_filter_pattern_enable(filter
,
6698 command
+ strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE
) + 1, FALSE
);
6700 if (err
== BCME_OK
) {
6701 bytes_written
= snprintf(command
, total_len
, "OK");
6702 DHD_ERROR(("%s: pktlog filter pattern disable success\n", __FUNCTION__
));
6704 DHD_ERROR(("%s: pktlog filter pattern disable fail\n", __FUNCTION__
));
6708 return bytes_written
;
6712 wl_android_pktlog_filter_add(struct net_device
*dev
, char *command
, int total_len
)
6714 int bytes_written
= 0;
6715 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6716 dhd_pktlog_filter_t
*filter
;
6719 if (!dhdp
|| !dhdp
->pktlog
) {
6720 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6721 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6725 filter
= dhdp
->pktlog
->pktlog_filter
;
6727 if (strlen(CMD_PKTLOG_FILTER_ADD
) + 1 > total_len
) {
6731 err
= dhd_pktlog_filter_add(filter
, command
+ strlen(CMD_PKTLOG_FILTER_ADD
) + 1);
6733 if (err
== BCME_OK
) {
6734 bytes_written
= snprintf(command
, total_len
, "OK");
6735 DHD_ERROR(("%s: pktlog filter add success\n", __FUNCTION__
));
6737 DHD_ERROR(("%s: pktlog filter add fail\n", __FUNCTION__
));
6741 return bytes_written
;
6745 wl_android_pktlog_filter_info(struct net_device
*dev
, char *command
, int total_len
)
6747 int bytes_written
= 0;
6748 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6749 dhd_pktlog_filter_t
*filter
;
6752 if (!dhdp
|| !dhdp
->pktlog
) {
6753 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6754 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6758 filter
= dhdp
->pktlog
->pktlog_filter
;
6760 err
= dhd_pktlog_filter_info(filter
);
6762 if (err
== BCME_OK
) {
6763 bytes_written
= snprintf(command
, total_len
, "OK");
6764 DHD_ERROR(("%s: pktlog filter info success\n", __FUNCTION__
));
6766 DHD_ERROR(("%s: pktlog filter info fail\n", __FUNCTION__
));
6770 return bytes_written
;
6774 wl_android_pktlog_start(struct net_device
*dev
, char *command
, int total_len
)
6776 int bytes_written
= 0;
6777 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6779 if (!dhdp
|| !dhdp
->pktlog
) {
6780 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6781 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6785 if (!dhdp
->pktlog
->tx_pktlog_ring
|| !dhdp
->pktlog
->rx_pktlog_ring
) {
6786 DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
6787 __FUNCTION__
, dhdp
->pktlog
->tx_pktlog_ring
, dhdp
->pktlog
->rx_pktlog_ring
));
6791 dhdp
->pktlog
->tx_pktlog_ring
->start
= TRUE
;
6792 dhdp
->pktlog
->rx_pktlog_ring
->start
= TRUE
;
6794 bytes_written
= snprintf(command
, total_len
, "OK");
6796 DHD_ERROR(("%s: pktlog start success\n", __FUNCTION__
));
6798 return bytes_written
;
6802 wl_android_pktlog_stop(struct net_device
*dev
, char *command
, int total_len
)
6804 int bytes_written
= 0;
6805 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6807 if (!dhdp
|| !dhdp
->pktlog
) {
6808 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6809 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6813 if (!dhdp
->pktlog
->tx_pktlog_ring
|| !dhdp
->pktlog
->rx_pktlog_ring
) {
6814 DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
6815 __FUNCTION__
, dhdp
->pktlog
->tx_pktlog_ring
, dhdp
->pktlog
->rx_pktlog_ring
));
6819 dhdp
->pktlog
->tx_pktlog_ring
->start
= FALSE
;
6820 dhdp
->pktlog
->rx_pktlog_ring
->start
= FALSE
;
6822 bytes_written
= snprintf(command
, total_len
, "OK");
6824 DHD_ERROR(("%s: pktlog stop success\n", __FUNCTION__
));
6826 return bytes_written
;
6830 wl_android_pktlog_filter_exist(struct net_device
*dev
, char *command
, int total_len
)
6832 int bytes_written
= 0;
6833 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6834 dhd_pktlog_filter_t
*filter
;
6838 if (!dhdp
|| !dhdp
->pktlog
) {
6839 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6840 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6844 filter
= dhdp
->pktlog
->pktlog_filter
;
6846 if (strlen(CMD_PKTLOG_FILTER_EXIST
) + 1 > total_len
) {
6850 exist
= dhd_pktlog_filter_existed(filter
, command
+ strlen(CMD_PKTLOG_FILTER_EXIST
) + 1,
6854 bytes_written
= snprintf(command
, total_len
, "TRUE");
6855 DHD_ERROR(("%s: pktlog filter pattern id: %d is existed\n", __FUNCTION__
, id
));
6857 bytes_written
= snprintf(command
, total_len
, "FALSE");
6858 DHD_ERROR(("%s: pktlog filter pattern id: %d is not existed\n", __FUNCTION__
, id
));
6861 return bytes_written
;
6865 wl_android_pktlog_minmize_enable(struct net_device
*dev
, char *command
, int total_len
)
6867 int bytes_written
= 0;
6868 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6870 if (!dhdp
|| !dhdp
->pktlog
) {
6871 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6872 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6876 if (!dhdp
->pktlog
->tx_pktlog_ring
|| !dhdp
->pktlog
->rx_pktlog_ring
) {
6877 DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
6878 __FUNCTION__
, dhdp
->pktlog
->tx_pktlog_ring
, dhdp
->pktlog
->rx_pktlog_ring
));
6882 dhdp
->pktlog
->tx_pktlog_ring
->pktlog_minmize
= TRUE
;
6883 dhdp
->pktlog
->rx_pktlog_ring
->pktlog_minmize
= TRUE
;
6885 bytes_written
= snprintf(command
, total_len
, "OK");
6887 DHD_ERROR(("%s: pktlog pktlog_minmize enable\n", __FUNCTION__
));
6889 return bytes_written
;
6893 wl_android_pktlog_minmize_disable(struct net_device
*dev
, char *command
, int total_len
)
6895 int bytes_written
= 0;
6896 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6898 if (!dhdp
|| !dhdp
->pktlog
) {
6899 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6900 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6904 if (!dhdp
->pktlog
->tx_pktlog_ring
|| !dhdp
->pktlog
->rx_pktlog_ring
) {
6905 DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
6906 __FUNCTION__
, dhdp
->pktlog
->tx_pktlog_ring
, dhdp
->pktlog
->rx_pktlog_ring
));
6910 dhdp
->pktlog
->tx_pktlog_ring
->pktlog_minmize
= FALSE
;
6911 dhdp
->pktlog
->rx_pktlog_ring
->pktlog_minmize
= FALSE
;
6913 bytes_written
= snprintf(command
, total_len
, "OK");
6915 DHD_ERROR(("%s: pktlog pktlog_minmize disable\n", __FUNCTION__
));
6917 return bytes_written
;
6921 wl_android_pktlog_change_size(struct net_device
*dev
, char *command
, int total_len
)
6923 int bytes_written
= 0;
6924 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6928 if (!dhdp
|| !dhdp
->pktlog
) {
6929 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6930 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6934 if (strlen(CMD_PKTLOG_CHANGE_SIZE
) + 1 > total_len
) {
6938 size
= bcm_strtoul(command
+ strlen(CMD_PKTLOG_CHANGE_SIZE
) + 1, NULL
, 0);
6940 dhdp
->pktlog
->tx_pktlog_ring
=
6941 dhd_pktlog_ring_change_size(dhdp
->pktlog
->tx_pktlog_ring
, size
);
6942 if (!dhdp
->pktlog
->tx_pktlog_ring
) {
6946 dhdp
->pktlog
->rx_pktlog_ring
=
6947 dhd_pktlog_ring_change_size(dhdp
->pktlog
->rx_pktlog_ring
, size
);
6948 if (!dhdp
->pktlog
->tx_pktlog_ring
) {
6952 if (err
== BCME_OK
) {
6953 bytes_written
= snprintf(command
, total_len
, "OK");
6954 DHD_ERROR(("%s: pktlog change size success\n", __FUNCTION__
));
6956 DHD_ERROR(("%s: pktlog change size fail\n", __FUNCTION__
));
6960 return bytes_written
;
6962 #endif /* DHD_PKT_LOGGING */
6964 #ifdef DHD_EVENT_LOG_FILTER
6965 uint32
dhd_event_log_filter_serialize(dhd_pub_t
*dhdp
, char *buf
, uint32 tot_len
, int type
);
6967 wl_android_ewp_filter(struct net_device
*dev
, char *command
, uint32 tot_len
)
6969 uint32 bytes_written
= 0;
6971 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6973 if (!dhdp
|| !command
) {
6974 DHD_ERROR(("%s(): dhdp=%p \n", __FUNCTION__
, dhdp
));
6978 /* NEED TO GET TYPE if EXIST */
6981 bytes_written
+= dhd_event_log_filter_serialize(dhdp
,
6982 &command
[bytes_written
], tot_len
- bytes_written
, type
);
6984 return (int)bytes_written
;
6986 #endif /* DHD_EVENT_LOG_FILTER */
6988 int wl_android_priv_cmd(struct net_device
*net
, struct ifreq
*ifr
)
6990 #define PRIVATE_COMMAND_MAX_LEN 8192
6991 #define PRIVATE_COMMAND_DEF_LEN 4096
6993 char *command
= NULL
;
6994 int bytes_written
= 0;
6995 android_wifi_priv_cmd priv_cmd
;
6997 struct bcm_cfg80211
*cfg
= wl_get_cfg(net
);
6999 net_os_wake_lock(net
);
7001 if (!capable(CAP_NET_ADMIN
)) {
7006 if (!ifr
->ifr_data
) {
7011 #ifdef CONFIG_COMPAT
7012 if (is_compat_task()) {
7013 compat_android_wifi_priv_cmd compat_priv_cmd
;
7014 if (copy_from_user(&compat_priv_cmd
, ifr
->ifr_data
,
7015 sizeof(compat_android_wifi_priv_cmd
))) {
7020 priv_cmd
.buf
= compat_ptr(compat_priv_cmd
.buf
);
7021 priv_cmd
.used_len
= compat_priv_cmd
.used_len
;
7022 priv_cmd
.total_len
= compat_priv_cmd
.total_len
;
7024 #endif /* CONFIG_COMPAT */
7026 if (copy_from_user(&priv_cmd
, ifr
->ifr_data
, sizeof(android_wifi_priv_cmd
))) {
7031 if ((priv_cmd
.total_len
> PRIVATE_COMMAND_MAX_LEN
) || (priv_cmd
.total_len
< 0)) {
7032 DHD_ERROR(("%s: buf length invalid:%d\n", __FUNCTION__
,
7033 priv_cmd
.total_len
));
7038 buf_size
= max(priv_cmd
.total_len
, PRIVATE_COMMAND_DEF_LEN
);
7039 command
= (char *)MALLOC(cfg
->osh
, (buf_size
+ 1));
7041 DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__
));
7045 if (copy_from_user(command
, priv_cmd
.buf
, priv_cmd
.total_len
)) {
7049 command
[priv_cmd
.total_len
] = '\0';
7051 DHD_ERROR(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__
, command
, ifr
->ifr_name
));
7053 bytes_written
= wl_handle_private_cmd(net
, command
, priv_cmd
.total_len
);
7054 if (bytes_written
>= 0) {
7055 if ((bytes_written
== 0) && (priv_cmd
.total_len
> 0)) {
7058 if (bytes_written
>= priv_cmd
.total_len
) {
7059 DHD_ERROR(("%s: err. bytes_written:%d >= total_len:%d, buf_size:%d\n",
7060 __FUNCTION__
, bytes_written
, priv_cmd
.total_len
, buf_size
));
7062 ret
= BCME_BUFTOOSHORT
;
7066 priv_cmd
.used_len
= bytes_written
;
7067 if (copy_to_user(priv_cmd
.buf
, command
, bytes_written
)) {
7068 DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__
));
7073 /* Propagate the error */
7074 ret
= bytes_written
;
7078 #ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
7080 /* Avoid incrementing priv_cmd_errors in case of unsupported feature */
7081 if (ret
!= BCME_UNSUPPORTED
) {
7082 wl_android_check_priv_cmd_errors(net
);
7085 priv_cmd_errors
= 0;
7087 #endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
7088 net_os_wake_unlock(net
);
7089 MFREE(cfg
->osh
, command
, (buf_size
+ 1));
7092 #ifdef WLADPS_PRIVATE_CMD
7094 wl_android_set_adps_mode(struct net_device
*dev
, const char* string_num
)
7096 int err
= 0, adps_mode
;
7097 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
7098 #ifdef DHD_PM_CONTROL_FROM_FILE
7102 #endif /* DHD_PM_CONTROL_FROM_FILE */
7104 adps_mode
= bcm_atoi(string_num
);
7105 WL_ERR(("%s: SET_ADPS %d\n", __FUNCTION__
, adps_mode
));
7107 if ((adps_mode
< 0) && (1 < adps_mode
)) {
7108 WL_ERR(("%s: Invalid value %d.\n", __FUNCTION__
, adps_mode
));
7112 err
= dhd_enable_adps(dhdp
, adps_mode
);
7113 if (err
!= BCME_OK
) {
7114 WL_ERR(("failed to set adps mode %d, error = %d\n", adps_mode
, err
));
7120 wl_android_get_adps_mode(
7121 struct net_device
*dev
, char *command
, int total_len
)
7123 int bytes_written
, err
= 0;
7125 char buf
[WLC_IOCTL_SMLEN
];
7127 bcm_iov_buf_t iov_buf
;
7128 bcm_iov_buf_t
*ptr
= NULL
;
7129 wl_adps_params_v1_t
*data
= NULL
;
7131 uint8
*pdata
= NULL
;
7132 uint8 band
, mode
= 0;
7134 memset(&iov_buf
, 0, sizeof(iov_buf
));
7136 len
= OFFSETOF(bcm_iov_buf_t
, data
) + sizeof(band
);
7138 iov_buf
.version
= WL_ADPS_IOV_VER
;
7139 iov_buf
.len
= sizeof(band
);
7140 iov_buf
.id
= WL_ADPS_IOV_MODE
;
7142 pdata
= (uint8
*)&iov_buf
.data
;
7144 for (band
= 1; band
<= MAX_BANDS
; band
++) {
7146 err
= wldev_iovar_getbuf(dev
, "adps", &iov_buf
, len
,
7147 buf
, WLC_IOCTL_SMLEN
, NULL
);
7148 if (err
!= BCME_OK
) {
7149 WL_ERR(("%s fail to get adps band %d(%d).\n",
7150 __FUNCTION__
, band
, err
));
7153 ptr
= (bcm_iov_buf_t
*) buf
;
7154 data
= (wl_adps_params_v1_t
*) ptr
->data
;
7161 bytes_written
= snprintf(command
, total_len
, "%s %d",
7162 CMD_GET_ADPS
, mode
);
7163 return bytes_written
;
7165 #endif /* WLADPS_PRIVATE_CMD */
7168 #define BCNRECV_ATTR_HDR_LEN 30
7170 wl_android_bcnrecv_event(struct net_device
*ndev
, uint attr_type
,
7171 uint status
, uint reason
, uint8
*data
, uint data_len
)
7174 struct sk_buff
*skb
;
7176 struct bcm_cfg80211
*cfg
= wl_get_cfg(ndev
);
7177 struct wiphy
*wiphy
= bcmcfg_to_wiphy(cfg
);
7180 len
= BCNRECV_ATTR_HDR_LEN
+ data_len
;
7182 kflags
= in_atomic() ? GFP_ATOMIC
: GFP_KERNEL
;
7183 skb
= CFG80211_VENDOR_EVENT_ALLOC(wiphy
, ndev_to_wdev(ndev
), len
,
7184 BRCM_VENDOR_EVENT_BEACON_RECV
, kflags
);
7186 WL_ERR(("skb alloc failed"));
7189 if ((attr_type
== BCNRECV_ATTR_BCNINFO
) && (data
)) {
7190 /* send bcn info to upper layer */
7191 nla_put(skb
, BCNRECV_ATTR_BCNINFO
, data_len
, data
);
7192 } else if (attr_type
== BCNRECV_ATTR_STATUS
) {
7193 nla_put_u32(skb
, BCNRECV_ATTR_STATUS
, status
);
7195 nla_put_u32(skb
, BCNRECV_ATTR_REASON
, reason
);
7198 WL_ERR(("UNKNOWN ATTR_TYPE. attr_type:%d\n", attr_type
));
7202 cfg80211_vendor_event(skb
, kflags
);
7207 _wl_android_bcnrecv_start(struct bcm_cfg80211
*cfg
, struct net_device
*ndev
, bool user_trigger
)
7211 /* check any scan is in progress before beacon recv scan trigger IOVAR */
7212 if (wl_get_drv_status_all(cfg
, SCANNING
)) {
7213 err
= BCME_UNSUPPORTED
;
7214 WL_ERR(("Scan in progress, Aborting beacon recv start, "
7215 "error:%d\n", err
));
7219 if (wl_get_p2p_status(cfg
, SCANNING
)) {
7220 err
= BCME_UNSUPPORTED
;
7221 WL_ERR(("P2P Scan in progress, Aborting beacon recv start, "
7222 "error:%d\n", err
));
7226 if (wl_get_drv_status(cfg
, REMAINING_ON_CHANNEL
, ndev
)) {
7227 err
= BCME_UNSUPPORTED
;
7228 WL_ERR(("P2P remain on channel, Aborting beacon recv start, "
7229 "error:%d\n", err
));
7233 /* check STA is in connected state, Beacon recv required connected state
7234 * else exit from beacon recv scan
7236 if (!wl_get_drv_status(cfg
, CONNECTED
, ndev
)) {
7237 err
= BCME_UNSUPPORTED
;
7238 WL_ERR(("STA is in not associated state error:%d\n", err
));
7243 /* Check NAN is enabled, if enabled exit else continue */
7244 if (wl_cfgnan_check_state(cfg
)) {
7245 err
= BCME_UNSUPPORTED
;
7246 WL_ERR(("Nan is enabled, NAN+STA+FAKEAP concurrency is not supported\n"));
7251 /* Triggering an sendup_bcn iovar */
7252 err
= wldev_iovar_setint(ndev
, "sendup_bcn", 1);
7253 if (unlikely(err
)) {
7254 WL_ERR(("sendup_bcn failed to set, error:%d\n", err
));
7256 cfg
->bcnrecv_info
.bcnrecv_state
= BEACON_RECV_STARTED
;
7257 WL_INFORM_MEM(("bcnrecv started\n"));
7259 WL_INFORM_MEM(("BCN-RECV-STARTED"));
7260 if ((err
= wl_android_bcnrecv_event(ndev
, BCNRECV_ATTR_STATUS
,
7261 WL_BCNRECV_STARTED
, 0, NULL
, 0)) != BCME_OK
) {
7262 WL_ERR(("failed to send bcnrecv event, error:%d\n", err
));
7268 * BCNRECV start request can be rejected from dongle
7269 * in various conditions.
7270 * Error code need to be overridden to BCME_UNSUPPORTED
7271 * to avoid hang event from continous private
7275 err
= BCME_UNSUPPORTED
;
7281 _wl_android_bcnrecv_stop(struct bcm_cfg80211
*cfg
, struct net_device
*ndev
, uint reason
)
7286 /* Send sendup_bcn iovar for all cases except W_BCNRECV_ROAMABORT reason -
7287 * fw generates roam abort event after aborting the bcnrecv.
7289 if (reason
!= WL_BCNRECV_ROAMABORT
) {
7290 /* Triggering an sendup_bcn iovar */
7291 err
= wldev_iovar_setint(ndev
, "sendup_bcn", 0);
7292 if (unlikely(err
)) {
7293 WL_ERR(("sendup_bcn failed to set error:%d\n", err
));
7298 /* Send notification for all cases */
7299 if (reason
== WL_BCNRECV_SUSPEND
) {
7300 cfg
->bcnrecv_info
.bcnrecv_state
= BEACON_RECV_SUSPENDED
;
7301 status
= WL_BCNRECV_SUSPENDED
;
7303 cfg
->bcnrecv_info
.bcnrecv_state
= BEACON_RECV_STOPPED
;
7304 WL_INFORM_MEM(("bcnrecv stopped\n"));
7305 if (reason
== WL_BCNRECV_USER_TRIGGER
) {
7306 status
= WL_BCNRECV_STOPPED
;
7308 status
= WL_BCNRECV_ABORTED
;
7311 if ((err
= wl_android_bcnrecv_event(ndev
, BCNRECV_ATTR_STATUS
, status
,
7312 reason
, NULL
, 0)) != BCME_OK
) {
7313 WL_ERR(("failed to send bcnrecv event, error:%d\n", err
));
7320 wl_android_bcnrecv_start(struct bcm_cfg80211
*cfg
, struct net_device
*ndev
)
7324 /* Adding scan_sync mutex to avoid race condition in b/w scan_req and bcn recv */
7325 mutex_lock(&cfg
->scan_sync
);
7326 mutex_lock(&cfg
->bcn_sync
);
7327 err
= _wl_android_bcnrecv_start(cfg
, ndev
, true);
7328 mutex_unlock(&cfg
->bcn_sync
);
7329 mutex_unlock(&cfg
->scan_sync
);
7334 wl_android_bcnrecv_stop(struct net_device
*ndev
, uint reason
)
7337 struct bcm_cfg80211
*cfg
= wl_get_cfg(ndev
);
7339 mutex_lock(&cfg
->bcn_sync
);
7340 if ((cfg
->bcnrecv_info
.bcnrecv_state
== BEACON_RECV_STARTED
) ||
7341 (cfg
->bcnrecv_info
.bcnrecv_state
== BEACON_RECV_SUSPENDED
)) {
7342 err
= _wl_android_bcnrecv_stop(cfg
, ndev
, reason
);
7344 mutex_unlock(&cfg
->bcn_sync
);
7349 wl_android_bcnrecv_suspend(struct net_device
*ndev
)
7352 struct bcm_cfg80211
*cfg
= wl_get_cfg(ndev
);
7354 mutex_lock(&cfg
->bcn_sync
);
7355 if (cfg
->bcnrecv_info
.bcnrecv_state
== BEACON_RECV_STARTED
) {
7356 WL_INFORM_MEM(("bcnrecv suspend\n"));
7357 ret
= _wl_android_bcnrecv_stop(cfg
, ndev
, WL_BCNRECV_SUSPEND
);
7359 mutex_unlock(&cfg
->bcn_sync
);
7364 wl_android_bcnrecv_resume(struct net_device
*ndev
)
7367 struct bcm_cfg80211
*cfg
= wl_get_cfg(ndev
);
7369 /* Adding scan_sync mutex to avoid race condition in b/w scan_req and bcn recv */
7370 mutex_lock(&cfg
->scan_sync
);
7371 mutex_lock(&cfg
->bcn_sync
);
7372 if (cfg
->bcnrecv_info
.bcnrecv_state
== BEACON_RECV_SUSPENDED
) {
7373 WL_INFORM_MEM(("bcnrecv resume\n"));
7374 ret
= _wl_android_bcnrecv_start(cfg
, ndev
, false);
7376 mutex_unlock(&cfg
->bcn_sync
);
7377 mutex_unlock(&cfg
->scan_sync
);
7381 /* Beacon recv functionality code implementation */
7383 wl_android_bcnrecv_config(struct net_device
*ndev
, char *cmd_argv
, int total_len
)
7385 struct bcm_cfg80211
*cfg
= NULL
;
7389 WL_ERR(("ndev is NULL\n"));
7393 cfg
= wl_get_cfg(ndev
);
7395 WL_ERR(("cfg is NULL\n"));
7399 /* sync commands from user space */
7400 mutex_lock(&cfg
->usr_sync
);
7401 if (strncmp(cmd_argv
, "start", strlen("start")) == 0) {
7402 WL_INFORM(("BCNRECV start\n"));
7403 err
= wl_android_bcnrecv_start(cfg
, ndev
);
7404 if (err
!= BCME_OK
) {
7405 WL_ERR(("Failed to process the start command, error:%d\n", err
));
7408 } else if (strncmp(cmd_argv
, "stop", strlen("stop")) == 0) {
7409 WL_INFORM(("BCNRECV stop\n"));
7410 err
= wl_android_bcnrecv_stop(ndev
, WL_BCNRECV_USER_TRIGGER
);
7411 if (err
!= BCME_OK
) {
7412 WL_ERR(("Failed to stop the bcn recv, error:%d\n", err
));
7419 mutex_unlock(&cfg
->usr_sync
);
7422 #endif /* WL_BCNRECV */
7425 wl_handle_private_cmd(struct net_device
*net
, char *command
, u32 cmd_len
)
7427 int bytes_written
= 0;
7428 android_wifi_priv_cmd priv_cmd
;
7430 bzero(&priv_cmd
, sizeof(android_wifi_priv_cmd
));
7431 priv_cmd
.total_len
= cmd_len
;
7433 if (strnicmp(command
, CMD_START
, strlen(CMD_START
)) == 0) {
7434 DHD_INFO(("%s, Received regular START command\n", __FUNCTION__
));
7435 #ifdef SUPPORT_DEEP_SLEEP
7436 trigger_deep_sleep
= 1;
7439 bytes_written
= dhd_net_bus_get(net
);
7441 bytes_written
= wl_android_wifi_on(net
);
7442 #endif /* BT_OVER_SDIO */
7443 #endif /* SUPPORT_DEEP_SLEEP */
7445 else if (strnicmp(command
, CMD_SETFWPATH
, strlen(CMD_SETFWPATH
)) == 0) {
7446 bytes_written
= wl_android_set_fwpath(net
, command
, priv_cmd
.total_len
);
7450 DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface is down\n",
7451 __FUNCTION__
, command
));
7455 if (strnicmp(command
, CMD_STOP
, strlen(CMD_STOP
)) == 0) {
7456 #ifdef SUPPORT_DEEP_SLEEP
7457 trigger_deep_sleep
= 1;
7460 bytes_written
= dhd_net_bus_put(net
);
7462 bytes_written
= wl_android_wifi_off(net
, FALSE
);
7463 #endif /* BT_OVER_SDIO */
7464 #endif /* SUPPORT_DEEP_SLEEP */
7466 else if (strnicmp(command
, CMD_SCAN_ACTIVE
, strlen(CMD_SCAN_ACTIVE
)) == 0) {
7467 wl_cfg80211_set_passive_scan(net
, command
);
7469 else if (strnicmp(command
, CMD_SCAN_PASSIVE
, strlen(CMD_SCAN_PASSIVE
)) == 0) {
7470 wl_cfg80211_set_passive_scan(net
, command
);
7472 else if (strnicmp(command
, CMD_RSSI
, strlen(CMD_RSSI
)) == 0) {
7473 bytes_written
= wl_android_get_rssi(net
, command
, priv_cmd
.total_len
);
7475 else if (strnicmp(command
, CMD_LINKSPEED
, strlen(CMD_LINKSPEED
)) == 0) {
7476 bytes_written
= wl_android_get_link_speed(net
, command
, priv_cmd
.total_len
);
7478 #ifdef PKT_FILTER_SUPPORT
7479 else if (strnicmp(command
, CMD_RXFILTER_START
, strlen(CMD_RXFILTER_START
)) == 0) {
7480 bytes_written
= net_os_enable_packet_filter(net
, 1);
7482 else if (strnicmp(command
, CMD_RXFILTER_STOP
, strlen(CMD_RXFILTER_STOP
)) == 0) {
7483 bytes_written
= net_os_enable_packet_filter(net
, 0);
7485 else if (strnicmp(command
, CMD_RXFILTER_ADD
, strlen(CMD_RXFILTER_ADD
)) == 0) {
7486 int filter_num
= *(command
+ strlen(CMD_RXFILTER_ADD
) + 1) - '0';
7487 bytes_written
= net_os_rxfilter_add_remove(net
, TRUE
, filter_num
);
7489 else if (strnicmp(command
, CMD_RXFILTER_REMOVE
, strlen(CMD_RXFILTER_REMOVE
)) == 0) {
7490 int filter_num
= *(command
+ strlen(CMD_RXFILTER_REMOVE
) + 1) - '0';
7491 bytes_written
= net_os_rxfilter_add_remove(net
, FALSE
, filter_num
);
7493 #endif /* PKT_FILTER_SUPPORT */
7494 else if (strnicmp(command
, CMD_BTCOEXSCAN_START
, strlen(CMD_BTCOEXSCAN_START
)) == 0) {
7495 /* TBD: BTCOEXSCAN-START */
7497 else if (strnicmp(command
, CMD_BTCOEXSCAN_STOP
, strlen(CMD_BTCOEXSCAN_STOP
)) == 0) {
7498 /* TBD: BTCOEXSCAN-STOP */
7500 else if (strnicmp(command
, CMD_BTCOEXMODE
, strlen(CMD_BTCOEXMODE
)) == 0) {
7502 void *dhdp
= wl_cfg80211_get_dhdp(net
);
7503 bytes_written
= wl_cfg80211_set_btcoex_dhcp(net
, dhdp
, command
);
7505 #ifdef PKT_FILTER_SUPPORT
7506 uint mode
= *(command
+ strlen(CMD_BTCOEXMODE
) + 1) - '0';
7509 net_os_enable_packet_filter(net
, 0); /* DHCP starts */
7511 net_os_enable_packet_filter(net
, 1); /* DHCP ends */
7512 #endif /* PKT_FILTER_SUPPORT */
7513 #endif /* WL_CFG80211 */
7515 else if (strnicmp(command
, CMD_SETSUSPENDOPT
, strlen(CMD_SETSUSPENDOPT
)) == 0) {
7516 bytes_written
= wl_android_set_suspendopt(net
, command
);
7518 else if (strnicmp(command
, CMD_SETSUSPENDMODE
, strlen(CMD_SETSUSPENDMODE
)) == 0) {
7519 bytes_written
= wl_android_set_suspendmode(net
, command
);
7521 else if (strnicmp(command
, CMD_SETDTIM_IN_SUSPEND
, strlen(CMD_SETDTIM_IN_SUSPEND
)) == 0) {
7522 bytes_written
= wl_android_set_bcn_li_dtim(net
, command
);
7524 else if (strnicmp(command
, CMD_MAXDTIM_IN_SUSPEND
, strlen(CMD_MAXDTIM_IN_SUSPEND
)) == 0) {
7525 bytes_written
= wl_android_set_max_dtim(net
, command
);
7527 else if (strnicmp(command
, CMD_DISDTIM_IN_SUSPEND
, strlen(CMD_DISDTIM_IN_SUSPEND
)) == 0) {
7528 bytes_written
= wl_android_set_disable_dtim_in_suspend(net
, command
);
7530 else if (strnicmp(command
, CMD_SETBAND
, strlen(CMD_SETBAND
)) == 0) {
7531 bytes_written
= wl_android_set_band(net
, command
);
7533 else if (strnicmp(command
, CMD_GETBAND
, strlen(CMD_GETBAND
)) == 0) {
7534 bytes_written
= wl_android_get_band(net
, command
, priv_cmd
.total_len
);
7537 #ifndef CUSTOMER_SET_COUNTRY
7538 /* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */
7539 else if (strnicmp(command
, CMD_COUNTRY
, strlen(CMD_COUNTRY
)) == 0) {
7543 * DRIVER COUNTRY US/7
7545 char *country_code
= command
+ strlen(CMD_COUNTRY
) + 1;
7546 char *rev_info_delim
= country_code
+ 2; /* 2 bytes of country code */
7548 struct wireless_dev
*wdev
= ndev_to_wdev(net
);
7549 struct wiphy
*wiphy
= wdev
->wiphy
;
7550 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(net
);
7552 BCM_REFERENCE(dhdp
);
7553 if (CHECK_IS_BLOB(dhdp
) && !CHECK_IS_MULT_REGREV(dhdp
)) {
7555 } else if ((rev_info_delim
) &&
7556 (strnicmp(rev_info_delim
, CMD_COUNTRY_DELIMITER
,
7557 strlen(CMD_COUNTRY_DELIMITER
)) == 0) &&
7558 (rev_info_delim
+ 1)) {
7559 revinfo
= bcm_atoi(rev_info_delim
+ 1);
7562 if (wl_check_dongle_idle(wiphy
) != TRUE
) {
7563 DHD_ERROR(("FW is busy to check dongle idle\n"));
7567 bytes_written
= wldev_set_country(net
, country_code
, true, true, revinfo
);
7568 #ifdef CUSTOMER_HW4_PRIVATE_CMD
7569 #ifdef FCC_PWR_LIMIT_2G
7570 if (wldev_iovar_setint(net
, "fccpwrlimit2g", FALSE
)) {
7571 DHD_ERROR(("%s: fccpwrlimit2g deactivation is failed\n", __FUNCTION__
));
7573 DHD_ERROR(("%s: fccpwrlimit2g is deactivated\n", __FUNCTION__
));
7575 #endif /* FCC_PWR_LIMIT_2G */
7576 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
7578 #endif /* CUSTOMER_SET_COUNTRY */
7579 #endif /* WL_CFG80211 */
7580 else if (strnicmp(command
, CMD_SET_CSA
, strlen(CMD_SET_CSA
)) == 0) {
7581 bytes_written
= wl_android_set_csa(net
, command
);
7582 } else if (strnicmp(command
, CMD_80211_MODE
, strlen(CMD_80211_MODE
)) == 0) {
7583 bytes_written
= wl_android_get_80211_mode(net
, command
, priv_cmd
.total_len
);
7584 } else if (strnicmp(command
, CMD_CHANSPEC
, strlen(CMD_CHANSPEC
)) == 0) {
7585 bytes_written
= wl_android_get_chanspec(net
, command
, priv_cmd
.total_len
);
7586 } else if (strnicmp(command
, CMD_DATARATE
, strlen(CMD_DATARATE
)) == 0) {
7587 bytes_written
= wl_android_get_datarate(net
, command
, priv_cmd
.total_len
);
7588 } else if (strnicmp(command
, CMD_ASSOC_CLIENTS
, strlen(CMD_ASSOC_CLIENTS
)) == 0) {
7589 bytes_written
= wl_android_get_assoclist(net
, command
, priv_cmd
.total_len
);
7592 #ifdef CUSTOMER_HW4_PRIVATE_CMD
7594 else if (strnicmp(command
, CMD_ROAMTRIGGER_SET
,
7595 strlen(CMD_ROAMTRIGGER_SET
)) == 0) {
7596 bytes_written
= wl_android_set_roam_trigger(net
, command
);
7597 } else if (strnicmp(command
, CMD_ROAMTRIGGER_GET
,
7598 strlen(CMD_ROAMTRIGGER_GET
)) == 0) {
7599 bytes_written
= wl_android_get_roam_trigger(net
, command
,
7600 priv_cmd
.total_len
);
7601 } else if (strnicmp(command
, CMD_ROAMDELTA_SET
,
7602 strlen(CMD_ROAMDELTA_SET
)) == 0) {
7603 bytes_written
= wl_android_set_roam_delta(net
, command
);
7604 } else if (strnicmp(command
, CMD_ROAMDELTA_GET
,
7605 strlen(CMD_ROAMDELTA_GET
)) == 0) {
7606 bytes_written
= wl_android_get_roam_delta(net
, command
,
7607 priv_cmd
.total_len
);
7608 } else if (strnicmp(command
, CMD_ROAMSCANPERIOD_SET
,
7609 strlen(CMD_ROAMSCANPERIOD_SET
)) == 0) {
7610 bytes_written
= wl_android_set_roam_scan_period(net
, command
);
7611 } else if (strnicmp(command
, CMD_ROAMSCANPERIOD_GET
,
7612 strlen(CMD_ROAMSCANPERIOD_GET
)) == 0) {
7613 bytes_written
= wl_android_get_roam_scan_period(net
, command
,
7614 priv_cmd
.total_len
);
7615 } else if (strnicmp(command
, CMD_FULLROAMSCANPERIOD_SET
,
7616 strlen(CMD_FULLROAMSCANPERIOD_SET
)) == 0) {
7617 bytes_written
= wl_android_set_full_roam_scan_period(net
, command
,
7618 priv_cmd
.total_len
);
7619 } else if (strnicmp(command
, CMD_FULLROAMSCANPERIOD_GET
,
7620 strlen(CMD_FULLROAMSCANPERIOD_GET
)) == 0) {
7621 bytes_written
= wl_android_get_full_roam_scan_period(net
, command
,
7622 priv_cmd
.total_len
);
7623 } else if (strnicmp(command
, CMD_COUNTRYREV_SET
,
7624 strlen(CMD_COUNTRYREV_SET
)) == 0) {
7625 bytes_written
= wl_android_set_country_rev(net
, command
);
7626 #ifdef FCC_PWR_LIMIT_2G
7627 if (wldev_iovar_setint(net
, "fccpwrlimit2g", FALSE
)) {
7628 DHD_ERROR(("%s: fccpwrlimit2g deactivation is failed\n", __FUNCTION__
));
7630 DHD_ERROR(("%s: fccpwrlimit2g is deactivated\n", __FUNCTION__
));
7632 #endif /* FCC_PWR_LIMIT_2G */
7633 } else if (strnicmp(command
, CMD_COUNTRYREV_GET
,
7634 strlen(CMD_COUNTRYREV_GET
)) == 0) {
7635 bytes_written
= wl_android_get_country_rev(net
, command
,
7636 priv_cmd
.total_len
);
7638 #endif /* ROAM_API */
7640 else if (strnicmp(command
, CMD_GETROAMSCANCONTROL
, strlen(CMD_GETROAMSCANCONTROL
)) == 0) {
7641 bytes_written
= wl_android_get_roam_scan_control(net
, command
, priv_cmd
.total_len
);
7643 else if (strnicmp(command
, CMD_SETROAMSCANCONTROL
, strlen(CMD_SETROAMSCANCONTROL
)) == 0) {
7644 bytes_written
= wl_android_set_roam_scan_control(net
, command
);
7646 else if (strnicmp(command
, CMD_GETROAMSCANCHANNELS
, strlen(CMD_GETROAMSCANCHANNELS
)) == 0) {
7647 bytes_written
= wl_android_get_roam_scan_channels(net
, command
, priv_cmd
.total_len
);
7649 else if (strnicmp(command
, CMD_SETROAMSCANCHANNELS
, strlen(CMD_SETROAMSCANCHANNELS
)) == 0) {
7650 bytes_written
= wl_android_set_roam_scan_channels(net
, command
);
7652 else if (strnicmp(command
, CMD_SENDACTIONFRAME
, strlen(CMD_SENDACTIONFRAME
)) == 0) {
7653 bytes_written
= wl_android_send_action_frame(net
, command
, priv_cmd
.total_len
);
7655 else if (strnicmp(command
, CMD_REASSOC
, strlen(CMD_REASSOC
)) == 0) {
7656 bytes_written
= wl_android_reassoc(net
, command
, priv_cmd
.total_len
);
7658 else if (strnicmp(command
, CMD_GETSCANCHANNELTIME
, strlen(CMD_GETSCANCHANNELTIME
)) == 0) {
7659 bytes_written
= wl_android_get_scan_channel_time(net
, command
, priv_cmd
.total_len
);
7661 else if (strnicmp(command
, CMD_SETSCANCHANNELTIME
, strlen(CMD_SETSCANCHANNELTIME
)) == 0) {
7662 bytes_written
= wl_android_set_scan_channel_time(net
, command
);
7664 else if (strnicmp(command
, CMD_GETSCANUNASSOCTIME
, strlen(CMD_GETSCANUNASSOCTIME
)) == 0) {
7665 bytes_written
= wl_android_get_scan_unassoc_time(net
, command
, priv_cmd
.total_len
);
7667 else if (strnicmp(command
, CMD_SETSCANUNASSOCTIME
, strlen(CMD_SETSCANUNASSOCTIME
)) == 0) {
7668 bytes_written
= wl_android_set_scan_unassoc_time(net
, command
);
7670 else if (strnicmp(command
, CMD_GETSCANPASSIVETIME
, strlen(CMD_GETSCANPASSIVETIME
)) == 0) {
7671 bytes_written
= wl_android_get_scan_passive_time(net
, command
, priv_cmd
.total_len
);
7673 else if (strnicmp(command
, CMD_SETSCANPASSIVETIME
, strlen(CMD_SETSCANPASSIVETIME
)) == 0) {
7674 bytes_written
= wl_android_set_scan_passive_time(net
, command
);
7676 else if (strnicmp(command
, CMD_GETSCANHOMETIME
, strlen(CMD_GETSCANHOMETIME
)) == 0) {
7677 bytes_written
= wl_android_get_scan_home_time(net
, command
, priv_cmd
.total_len
);
7679 else if (strnicmp(command
, CMD_SETSCANHOMETIME
, strlen(CMD_SETSCANHOMETIME
)) == 0) {
7680 bytes_written
= wl_android_set_scan_home_time(net
, command
);
7682 else if (strnicmp(command
, CMD_GETSCANHOMEAWAYTIME
, strlen(CMD_GETSCANHOMEAWAYTIME
)) == 0) {
7683 bytes_written
= wl_android_get_scan_home_away_time(net
, command
,
7684 priv_cmd
.total_len
);
7686 else if (strnicmp(command
, CMD_SETSCANHOMEAWAYTIME
, strlen(CMD_SETSCANHOMEAWAYTIME
)) == 0) {
7687 bytes_written
= wl_android_set_scan_home_away_time(net
, command
);
7689 else if (strnicmp(command
, CMD_GETSCANNPROBES
, strlen(CMD_GETSCANNPROBES
)) == 0) {
7690 bytes_written
= wl_android_get_scan_nprobes(net
, command
, priv_cmd
.total_len
);
7692 else if (strnicmp(command
, CMD_SETSCANNPROBES
, strlen(CMD_SETSCANNPROBES
)) == 0) {
7693 bytes_written
= wl_android_set_scan_nprobes(net
, command
);
7695 else if (strnicmp(command
, CMD_GETDFSSCANMODE
, strlen(CMD_GETDFSSCANMODE
)) == 0) {
7696 bytes_written
= wl_android_get_scan_dfs_channel_mode(net
, command
,
7697 priv_cmd
.total_len
);
7699 else if (strnicmp(command
, CMD_SETDFSSCANMODE
, strlen(CMD_SETDFSSCANMODE
)) == 0) {
7700 bytes_written
= wl_android_set_scan_dfs_channel_mode(net
, command
);
7702 else if (strnicmp(command
, CMD_SETJOINPREFER
, strlen(CMD_SETJOINPREFER
)) == 0) {
7703 bytes_written
= wl_android_set_join_prefer(net
, command
);
7705 else if (strnicmp(command
, CMD_GETWESMODE
, strlen(CMD_GETWESMODE
)) == 0) {
7706 bytes_written
= wl_android_get_wes_mode(net
, command
, priv_cmd
.total_len
);
7708 else if (strnicmp(command
, CMD_SETWESMODE
, strlen(CMD_SETWESMODE
)) == 0) {
7709 bytes_written
= wl_android_set_wes_mode(net
, command
);
7711 else if (strnicmp(command
, CMD_GETOKCMODE
, strlen(CMD_GETOKCMODE
)) == 0) {
7712 bytes_written
= wl_android_get_okc_mode(net
, command
, priv_cmd
.total_len
);
7714 else if (strnicmp(command
, CMD_SETOKCMODE
, strlen(CMD_SETOKCMODE
)) == 0) {
7715 bytes_written
= wl_android_set_okc_mode(net
, command
);
7717 else if (strnicmp(command
, CMD_OKC_SET_PMK
, strlen(CMD_OKC_SET_PMK
)) == 0) {
7718 bytes_written
= wl_android_set_pmk(net
, command
, priv_cmd
.total_len
);
7720 else if (strnicmp(command
, CMD_OKC_ENABLE
, strlen(CMD_OKC_ENABLE
)) == 0) {
7721 bytes_written
= wl_android_okc_enable(net
, command
);
7723 #endif /* WES_SUPPORT */
7724 #ifdef SUPPORT_RESTORE_SCAN_PARAMS
7725 else if (strnicmp(command
, CMD_RESTORE_SCAN_PARAMS
, strlen(CMD_RESTORE_SCAN_PARAMS
)) == 0) {
7726 bytes_written
= wl_android_restore_scan_params(net
, command
, priv_cmd
.total_len
);
7728 #endif /* SUPPORT_RESTORE_SCAN_PARAMS */
7730 else if (strnicmp(command
, CMD_TDLS_RESET
, strlen(CMD_TDLS_RESET
)) == 0) {
7731 bytes_written
= wl_android_tdls_reset(net
);
7734 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
7737 else if (strnicmp(command
, CMD_PNOSSIDCLR_SET
, strlen(CMD_PNOSSIDCLR_SET
)) == 0) {
7738 #if defined(SUPPORT_RANDOM_MAC_SCAN)
7739 wl_cfg80211_set_random_mac(net
, FALSE
);
7740 #endif /* SUPPORT_RANDOM_MAC_SCAN */
7741 bytes_written
= dhd_dev_pno_stop_for_ssid(net
);
7743 #ifndef WL_SCHED_SCAN
7744 else if (strnicmp(command
, CMD_PNOSETUP_SET
, strlen(CMD_PNOSETUP_SET
)) == 0) {
7745 #if defined(SUPPORT_RANDOM_MAC_SCAN)
7746 int res
= BCME_ERROR
;
7747 res
= wl_cfg80211_set_random_mac(net
, TRUE
);
7748 if (res
< 0 && res
!= BCME_UNSUPPORTED
) {
7749 DHD_ERROR(("%s : failed to set random mac for PNO scan, %d\n",
7750 __FUNCTION__
, res
));
7752 #endif /* SUPPORT_RANDOM_MAC_SCAN */
7753 bytes_written
= wl_android_set_pno_setup(net
, command
, priv_cmd
.total_len
);
7755 #endif /* !WL_SCHED_SCAN */
7756 else if (strnicmp(command
, CMD_PNOENABLE_SET
, strlen(CMD_PNOENABLE_SET
)) == 0) {
7757 int enable
= *(command
+ strlen(CMD_PNOENABLE_SET
) + 1) - '0';
7758 bytes_written
= (enable
)? 0 : dhd_dev_pno_stop_for_ssid(net
);
7760 else if (strnicmp(command
, CMD_WLS_BATCHING
, strlen(CMD_WLS_BATCHING
)) == 0) {
7761 bytes_written
= wls_parse_batching_cmd(net
, command
, priv_cmd
.total_len
);
7763 #endif /* PNO_SUPPORT */
7764 else if (strnicmp(command
, CMD_P2P_DEV_ADDR
, strlen(CMD_P2P_DEV_ADDR
)) == 0) {
7765 bytes_written
= wl_android_get_p2p_dev_addr(net
, command
, priv_cmd
.total_len
);
7767 else if (strnicmp(command
, CMD_P2P_SET_NOA
, strlen(CMD_P2P_SET_NOA
)) == 0) {
7768 int skip
= strlen(CMD_P2P_SET_NOA
) + 1;
7769 bytes_written
= wl_cfg80211_set_p2p_noa(net
, command
+ skip
,
7770 priv_cmd
.total_len
- skip
);
7772 #ifdef P2P_LISTEN_OFFLOADING
7773 else if (strnicmp(command
, CMD_P2P_LISTEN_OFFLOAD
, strlen(CMD_P2P_LISTEN_OFFLOAD
)) == 0) {
7774 u8
*sub_command
= strchr(command
, ' ');
7775 bytes_written
= wl_cfg80211_p2plo_offload(net
, command
, sub_command
,
7776 sub_command
? strlen(sub_command
) : 0);
7778 #endif /* P2P_LISTEN_OFFLOADING */
7779 #if !defined WL_ENABLE_P2P_IF
7780 else if (strnicmp(command
, CMD_P2P_GET_NOA
, strlen(CMD_P2P_GET_NOA
)) == 0) {
7781 bytes_written
= wl_cfg80211_get_p2p_noa(net
, command
, priv_cmd
.total_len
);
7783 #endif /* WL_ENABLE_P2P_IF */
7784 else if (strnicmp(command
, CMD_P2P_SET_PS
, strlen(CMD_P2P_SET_PS
)) == 0) {
7785 int skip
= strlen(CMD_P2P_SET_PS
) + 1;
7786 bytes_written
= wl_cfg80211_set_p2p_ps(net
, command
+ skip
,
7787 priv_cmd
.total_len
- skip
);
7789 else if (strnicmp(command
, CMD_P2P_ECSA
, strlen(CMD_P2P_ECSA
)) == 0) {
7790 int skip
= strlen(CMD_P2P_ECSA
) + 1;
7791 bytes_written
= wl_cfg80211_set_p2p_ecsa(net
, command
+ skip
,
7792 priv_cmd
.total_len
- skip
);
7794 else if (strnicmp(command
, CMD_P2P_INC_BW
, strlen(CMD_P2P_INC_BW
)) == 0) {
7795 int skip
= strlen(CMD_P2P_INC_BW
) + 1;
7796 bytes_written
= wl_cfg80211_increase_p2p_bw(net
,
7797 command
+ skip
, priv_cmd
.total_len
- skip
);
7800 else if (strnicmp(command
, CMD_SET_AP_WPS_P2P_IE
,
7801 strlen(CMD_SET_AP_WPS_P2P_IE
)) == 0) {
7802 int skip
= strlen(CMD_SET_AP_WPS_P2P_IE
) + 3;
7803 bytes_written
= wl_cfg80211_set_wps_p2p_ie(net
, command
+ skip
,
7804 priv_cmd
.total_len
- skip
, *(command
+ skip
- 2) - '0');
7807 else if (strnicmp(command
, CMD_GET_FTKEY
, strlen(CMD_GET_FTKEY
)) == 0) {
7808 bytes_written
= wl_cfg80211_get_fbt_key(net
, command
, priv_cmd
.total_len
);
7811 #endif /* WL_CFG80211 */
7813 else if (strnicmp(command
, CMD_GETCCKM_RN
, strlen(CMD_GETCCKM_RN
)) == 0) {
7814 bytes_written
= wl_android_get_cckm_rn(net
, command
);
7816 else if (strnicmp(command
, CMD_SETCCKM_KRK
, strlen(CMD_SETCCKM_KRK
)) == 0) {
7817 bytes_written
= wl_android_set_cckm_krk(net
, command
, priv_cmd
.total_len
);
7819 else if (strnicmp(command
, CMD_GET_ASSOC_RES_IES
, strlen(CMD_GET_ASSOC_RES_IES
)) == 0) {
7820 bytes_written
= wl_android_get_assoc_res_ies(net
, command
, priv_cmd
.total_len
);
7823 #if defined(WL_SUPPORT_AUTO_CHANNEL)
7824 else if (strnicmp(command
, CMD_GET_BEST_CHANNELS
,
7825 strlen(CMD_GET_BEST_CHANNELS
)) == 0) {
7826 bytes_written
= wl_cfg80211_get_best_channels(net
, command
,
7827 priv_cmd
.total_len
);
7829 #endif /* WL_SUPPORT_AUTO_CHANNEL */
7830 #if defined(WL_SUPPORT_AUTO_CHANNEL)
7831 else if (strnicmp(command
, CMD_SET_HAPD_AUTO_CHANNEL
,
7832 strlen(CMD_SET_HAPD_AUTO_CHANNEL
)) == 0) {
7833 int skip
= strlen(CMD_SET_HAPD_AUTO_CHANNEL
) + 1;
7834 bytes_written
= wl_android_set_auto_channel(net
, (const char*)command
+skip
, command
,
7835 priv_cmd
.total_len
);
7837 #endif /* WL_SUPPORT_AUTO_CHANNEL */
7838 #ifdef CUSTOMER_HW4_PRIVATE_CMD
7839 #ifdef SUPPORT_AMPDU_MPDU_CMD
7840 /* CMD_AMPDU_MPDU */
7841 else if (strnicmp(command
, CMD_AMPDU_MPDU
, strlen(CMD_AMPDU_MPDU
)) == 0) {
7842 int skip
= strlen(CMD_AMPDU_MPDU
) + 1;
7843 bytes_written
= wl_android_set_ampdu_mpdu(net
, (const char*)command
+skip
);
7845 #endif /* SUPPORT_AMPDU_MPDU_CMD */
7846 #if defined(SUPPORT_HIDDEN_AP)
7847 else if (strnicmp(command
, CMD_SET_HAPD_MAX_NUM_STA
,
7848 strlen(CMD_SET_HAPD_MAX_NUM_STA
)) == 0) {
7849 int skip
= strlen(CMD_SET_HAPD_MAX_NUM_STA
) + 3;
7850 wl_android_set_max_num_sta(net
, (const char*)command
+skip
);
7852 else if (strnicmp(command
, CMD_SET_HAPD_SSID
,
7853 strlen(CMD_SET_HAPD_SSID
)) == 0) {
7854 int skip
= strlen(CMD_SET_HAPD_SSID
) + 3;
7855 wl_android_set_ssid(net
, (const char*)command
+skip
);
7857 else if (strnicmp(command
, CMD_SET_HAPD_HIDE_SSID
,
7858 strlen(CMD_SET_HAPD_HIDE_SSID
)) == 0) {
7859 int skip
= strlen(CMD_SET_HAPD_HIDE_SSID
) + 3;
7860 wl_android_set_hide_ssid(net
, (const char*)command
+skip
);
7862 #endif /* SUPPORT_HIDDEN_AP */
7863 #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
7864 else if (strnicmp(command
, CMD_HAPD_STA_DISASSOC
,
7865 strlen(CMD_HAPD_STA_DISASSOC
)) == 0) {
7866 int skip
= strlen(CMD_HAPD_STA_DISASSOC
) + 1;
7867 wl_android_sta_diassoc(net
, (const char*)command
+skip
);
7869 #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
7870 #ifdef SUPPORT_SET_LPC
7871 else if (strnicmp(command
, CMD_HAPD_LPC_ENABLED
,
7872 strlen(CMD_HAPD_LPC_ENABLED
)) == 0) {
7873 int skip
= strlen(CMD_HAPD_LPC_ENABLED
) + 3;
7874 wl_android_set_lpc(net
, (const char*)command
+skip
);
7876 #endif /* SUPPORT_SET_LPC */
7877 #ifdef SUPPORT_TRIGGER_HANG_EVENT
7878 else if (strnicmp(command
, CMD_TEST_FORCE_HANG
,
7879 strlen(CMD_TEST_FORCE_HANG
)) == 0) {
7880 int skip
= strlen(CMD_TEST_FORCE_HANG
) + 1;
7881 net_os_send_hang_message_reason(net
, (const char*)command
+skip
);
7883 #endif /* SUPPORT_TRIGGER_HANG_EVENT */
7884 else if (strnicmp(command
, CMD_CHANGE_RL
, strlen(CMD_CHANGE_RL
)) == 0)
7885 bytes_written
= wl_android_ch_res_rl(net
, true);
7886 else if (strnicmp(command
, CMD_RESTORE_RL
, strlen(CMD_RESTORE_RL
)) == 0)
7887 bytes_written
= wl_android_ch_res_rl(net
, false);
7888 #ifdef SUPPORT_LTECX
7889 else if (strnicmp(command
, CMD_LTECX_SET
, strlen(CMD_LTECX_SET
)) == 0) {
7890 int skip
= strlen(CMD_LTECX_SET
) + 1;
7891 bytes_written
= wl_android_set_ltecx(net
, (const char*)command
+skip
);
7893 #endif /* SUPPORT_LTECX */
7895 else if (strnicmp(command
, CMD_SET_RMC_ENABLE
, strlen(CMD_SET_RMC_ENABLE
)) == 0) {
7896 int rmc_enable
= *(command
+ strlen(CMD_SET_RMC_ENABLE
) + 1) - '0';
7897 bytes_written
= wl_android_rmc_enable(net
, rmc_enable
);
7899 else if (strnicmp(command
, CMD_SET_RMC_TXRATE
, strlen(CMD_SET_RMC_TXRATE
)) == 0) {
7901 sscanf(command
, "%*s %10d", &rmc_txrate
);
7902 bytes_written
= wldev_iovar_setint(net
, "rmc_txrate", rmc_txrate
* 2);
7904 else if (strnicmp(command
, CMD_SET_RMC_ACTPERIOD
, strlen(CMD_SET_RMC_ACTPERIOD
)) == 0) {
7906 sscanf(command
, "%*s %10d", &actperiod
);
7907 bytes_written
= wldev_iovar_setint(net
, "rmc_actf_time", actperiod
);
7909 else if (strnicmp(command
, CMD_SET_RMC_IDLEPERIOD
, strlen(CMD_SET_RMC_IDLEPERIOD
)) == 0) {
7911 sscanf(command
, "%*s %10d", &acktimeout
);
7913 bytes_written
= wldev_iovar_setint(net
, "rmc_acktmo", acktimeout
);
7915 else if (strnicmp(command
, CMD_SET_RMC_LEADER
, strlen(CMD_SET_RMC_LEADER
)) == 0) {
7916 int skip
= strlen(CMD_SET_RMC_LEADER
) + 1;
7917 bytes_written
= wl_android_rmc_set_leader(net
, (const char*)command
+skip
);
7919 else if (strnicmp(command
, CMD_SET_RMC_EVENT
,
7920 strlen(CMD_SET_RMC_EVENT
)) == 0) {
7921 bytes_written
= wl_android_set_rmc_event(net
, command
);
7923 #endif /* WL_RELMCAST */
7924 else if (strnicmp(command
, CMD_GET_SCSCAN
, strlen(CMD_GET_SCSCAN
)) == 0) {
7925 bytes_written
= wl_android_get_singlecore_scan(net
, command
, priv_cmd
.total_len
);
7927 else if (strnicmp(command
, CMD_SET_SCSCAN
, strlen(CMD_SET_SCSCAN
)) == 0) {
7928 bytes_written
= wl_android_set_singlecore_scan(net
, command
);
7930 #ifdef TEST_TX_POWER_CONTROL
7931 else if (strnicmp(command
, CMD_TEST_SET_TX_POWER
,
7932 strlen(CMD_TEST_SET_TX_POWER
)) == 0) {
7933 int skip
= strlen(CMD_TEST_SET_TX_POWER
) + 1;
7934 wl_android_set_tx_power(net
, (const char*)command
+skip
);
7936 else if (strnicmp(command
, CMD_TEST_GET_TX_POWER
,
7937 strlen(CMD_TEST_GET_TX_POWER
)) == 0) {
7938 wl_android_get_tx_power(net
, command
, priv_cmd
.total_len
);
7940 #endif /* TEST_TX_POWER_CONTROL */
7941 else if (strnicmp(command
, CMD_SARLIMIT_TX_CONTROL
,
7942 strlen(CMD_SARLIMIT_TX_CONTROL
)) == 0) {
7943 int skip
= strlen(CMD_SARLIMIT_TX_CONTROL
) + 1;
7944 wl_android_set_sarlimit_txctrl(net
, (const char*)command
+skip
);
7946 #ifdef SUPPORT_SET_TID
7947 else if (strnicmp(command
, CMD_SET_TID
, strlen(CMD_SET_TID
)) == 0) {
7948 bytes_written
= wl_android_set_tid(net
, command
);
7950 else if (strnicmp(command
, CMD_GET_TID
, strlen(CMD_GET_TID
)) == 0) {
7951 bytes_written
= wl_android_get_tid(net
, command
, priv_cmd
.total_len
);
7953 #endif /* SUPPORT_SET_TID */
7954 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
7955 else if (strnicmp(command
, CMD_HAPD_MAC_FILTER
, strlen(CMD_HAPD_MAC_FILTER
)) == 0) {
7956 int skip
= strlen(CMD_HAPD_MAC_FILTER
) + 1;
7957 wl_android_set_mac_address_filter(net
, command
+skip
);
7959 else if (strnicmp(command
, CMD_SETROAMMODE
, strlen(CMD_SETROAMMODE
)) == 0)
7960 bytes_written
= wl_android_set_roam_mode(net
, command
);
7961 #if defined(BCMFW_ROAM_ENABLE)
7962 else if (strnicmp(command
, CMD_SET_ROAMPREF
, strlen(CMD_SET_ROAMPREF
)) == 0) {
7963 bytes_written
= wl_android_set_roampref(net
, command
, priv_cmd
.total_len
);
7965 #endif /* BCMFW_ROAM_ENABLE */
7966 else if (strnicmp(command
, CMD_MIRACAST
, strlen(CMD_MIRACAST
)) == 0)
7967 bytes_written
= wl_android_set_miracast(net
, command
);
7968 else if (strnicmp(command
, CMD_SETIBSSBEACONOUIDATA
, strlen(CMD_SETIBSSBEACONOUIDATA
)) == 0)
7969 bytes_written
= wl_android_set_ibss_beacon_ouidata(net
,
7970 command
, priv_cmd
.total_len
);
7972 else if (strnicmp(command
, CMD_SETIBSSTXFAILEVENT
,
7973 strlen(CMD_SETIBSSTXFAILEVENT
)) == 0)
7974 bytes_written
= wl_android_set_ibss_txfail_event(net
, command
, priv_cmd
.total_len
);
7975 else if (strnicmp(command
, CMD_GET_IBSS_PEER_INFO_ALL
,
7976 strlen(CMD_GET_IBSS_PEER_INFO_ALL
)) == 0)
7977 bytes_written
= wl_android_get_ibss_peer_info(net
, command
, priv_cmd
.total_len
,
7979 else if (strnicmp(command
, CMD_GET_IBSS_PEER_INFO
,
7980 strlen(CMD_GET_IBSS_PEER_INFO
)) == 0)
7981 bytes_written
= wl_android_get_ibss_peer_info(net
, command
, priv_cmd
.total_len
,
7983 else if (strnicmp(command
, CMD_SETIBSSROUTETABLE
,
7984 strlen(CMD_SETIBSSROUTETABLE
)) == 0)
7985 bytes_written
= wl_android_set_ibss_routetable(net
, command
);
7986 else if (strnicmp(command
, CMD_SETIBSSAMPDU
, strlen(CMD_SETIBSSAMPDU
)) == 0)
7987 bytes_written
= wl_android_set_ibss_ampdu(net
, command
, priv_cmd
.total_len
);
7988 else if (strnicmp(command
, CMD_SETIBSSANTENNAMODE
, strlen(CMD_SETIBSSANTENNAMODE
)) == 0)
7989 bytes_written
= wl_android_set_ibss_antenna(net
, command
, priv_cmd
.total_len
);
7990 #endif /* WLAIBSS */
7991 else if (strnicmp(command
, CMD_KEEP_ALIVE
, strlen(CMD_KEEP_ALIVE
)) == 0) {
7992 int skip
= strlen(CMD_KEEP_ALIVE
) + 1;
7993 bytes_written
= wl_keep_alive_set(net
, command
+ skip
);
7995 else if (strnicmp(command
, CMD_ROAM_OFFLOAD
, strlen(CMD_ROAM_OFFLOAD
)) == 0) {
7996 int enable
= *(command
+ strlen(CMD_ROAM_OFFLOAD
) + 1) - '0';
7997 bytes_written
= wl_cfg80211_enable_roam_offload(net
, enable
);
7999 else if (strnicmp(command
, CMD_INTERFACE_CREATE
, strlen(CMD_INTERFACE_CREATE
)) == 0) {
8000 char *name
= (command
+ strlen(CMD_INTERFACE_CREATE
) +1);
8001 WL_INFORM(("Creating %s interface\n", name
));
8002 if (wl_cfg80211_add_if(wl_get_cfg(net
), net
, WL_IF_TYPE_STA
,
8003 name
, NULL
) == NULL
) {
8004 bytes_written
= -ENODEV
;
8006 /* Return success */
8010 else if (strnicmp(command
, CMD_INTERFACE_DELETE
, strlen(CMD_INTERFACE_DELETE
)) == 0) {
8011 char *name
= (command
+ strlen(CMD_INTERFACE_DELETE
) +1);
8012 WL_INFORM(("Deleteing %s interface\n", name
));
8013 bytes_written
= wl_cfg80211_del_if(wl_get_cfg(net
), net
, NULL
, name
);
8015 else if (strnicmp(command
, CMD_GET_LINK_STATUS
, strlen(CMD_GET_LINK_STATUS
)) == 0) {
8016 bytes_written
= wl_android_get_link_status(net
, command
, priv_cmd
.total_len
);
8018 #ifdef P2PRESP_WFDIE_SRC
8019 else if (strnicmp(command
, CMD_P2P_SET_WFDIE_RESP
,
8020 strlen(CMD_P2P_SET_WFDIE_RESP
)) == 0) {
8021 int mode
= *(command
+ strlen(CMD_P2P_SET_WFDIE_RESP
) + 1) - '0';
8022 bytes_written
= wl_android_set_wfdie_resp(net
, mode
);
8023 } else if (strnicmp(command
, CMD_P2P_GET_WFDIE_RESP
,
8024 strlen(CMD_P2P_GET_WFDIE_RESP
)) == 0) {
8025 bytes_written
= wl_android_get_wfdie_resp(net
, command
, priv_cmd
.total_len
);
8027 #endif /* P2PRESP_WFDIE_SRC */
8028 else if (strnicmp(command
, CMD_DFS_AP_MOVE
, strlen(CMD_DFS_AP_MOVE
)) == 0) {
8029 char *data
= (command
+ strlen(CMD_DFS_AP_MOVE
) +1);
8030 bytes_written
= wl_cfg80211_dfs_ap_move(net
, data
, command
, priv_cmd
.total_len
);
8033 else if (strnicmp(command
, CMD_WBTEXT_ENABLE
, strlen(CMD_WBTEXT_ENABLE
)) == 0) {
8034 bytes_written
= wl_android_wbtext(net
, command
, priv_cmd
.total_len
);
8036 else if (strnicmp(command
, CMD_WBTEXT_PROFILE_CONFIG
,
8037 strlen(CMD_WBTEXT_PROFILE_CONFIG
)) == 0) {
8038 char *data
= (command
+ strlen(CMD_WBTEXT_PROFILE_CONFIG
) + 1);
8039 bytes_written
= wl_cfg80211_wbtext_config(net
, data
, command
, priv_cmd
.total_len
);
8041 else if (strnicmp(command
, CMD_WBTEXT_WEIGHT_CONFIG
,
8042 strlen(CMD_WBTEXT_WEIGHT_CONFIG
)) == 0) {
8043 char *data
= (command
+ strlen(CMD_WBTEXT_WEIGHT_CONFIG
) + 1);
8044 bytes_written
= wl_cfg80211_wbtext_weight_config(net
, data
,
8045 command
, priv_cmd
.total_len
);
8047 else if (strnicmp(command
, CMD_WBTEXT_TABLE_CONFIG
,
8048 strlen(CMD_WBTEXT_TABLE_CONFIG
)) == 0) {
8049 char *data
= (command
+ strlen(CMD_WBTEXT_TABLE_CONFIG
) + 1);
8050 bytes_written
= wl_cfg80211_wbtext_table_config(net
, data
,
8051 command
, priv_cmd
.total_len
);
8053 else if (strnicmp(command
, CMD_WBTEXT_DELTA_CONFIG
,
8054 strlen(CMD_WBTEXT_DELTA_CONFIG
)) == 0) {
8055 char *data
= (command
+ strlen(CMD_WBTEXT_DELTA_CONFIG
) + 1);
8056 bytes_written
= wl_cfg80211_wbtext_delta_config(net
, data
,
8057 command
, priv_cmd
.total_len
);
8059 else if (strnicmp(command
, CMD_WBTEXT_BTM_TIMER_THRESHOLD
,
8060 strlen(CMD_WBTEXT_BTM_TIMER_THRESHOLD
)) == 0) {
8061 bytes_written
= wl_cfg80211_wbtext_btm_timer_threshold(net
, command
,
8062 priv_cmd
.total_len
);
8064 else if (strnicmp(command
, CMD_WBTEXT_BTM_DELTA
,
8065 strlen(CMD_WBTEXT_BTM_DELTA
)) == 0) {
8066 bytes_written
= wl_cfg80211_wbtext_btm_delta(net
, command
,
8067 priv_cmd
.total_len
);
8071 else if (strnicmp(command
, CMD_RPSMODE
, strlen(CMD_RPSMODE
)) == 0) {
8072 bytes_written
= wl_android_set_rps_cpus(net
, command
);
8074 #endif /* SET_RPS_CPUS */
8076 else if (strnicmp(command
, CMD_ADD_WFDS_HASH
, strlen(CMD_ADD_WFDS_HASH
)) == 0) {
8077 bytes_written
= wl_android_set_wfds_hash(net
, command
, 1);
8079 else if (strnicmp(command
, CMD_DEL_WFDS_HASH
, strlen(CMD_DEL_WFDS_HASH
)) == 0) {
8080 bytes_written
= wl_android_set_wfds_hash(net
, command
, 0);
8083 #ifdef BT_WIFI_HANDOVER
8084 else if (strnicmp(command
, CMD_TBOW_TEARDOWN
, strlen(CMD_TBOW_TEARDOWN
)) == 0) {
8085 bytes_written
= wl_tbow_teardown(net
);
8087 #endif /* BT_WIFI_HANDOVER */
8088 #ifdef CUSTOMER_HW4_PRIVATE_CMD
8089 #ifdef FCC_PWR_LIMIT_2G
8090 else if (strnicmp(command
, CMD_GET_FCC_PWR_LIMIT_2G
,
8091 strlen(CMD_GET_FCC_PWR_LIMIT_2G
)) == 0) {
8092 bytes_written
= wl_android_get_fcc_pwr_limit_2g(net
, command
, priv_cmd
.total_len
);
8094 else if (strnicmp(command
, CMD_SET_FCC_PWR_LIMIT_2G
,
8095 strlen(CMD_SET_FCC_PWR_LIMIT_2G
)) == 0) {
8096 bytes_written
= wl_android_set_fcc_pwr_limit_2g(net
, command
);
8098 #endif /* FCC_PWR_LIMIT_2G */
8099 else if (strnicmp(command
, CMD_GET_STA_INFO
, strlen(CMD_GET_STA_INFO
)) == 0) {
8100 bytes_written
= wl_cfg80211_get_sta_info(net
, command
, priv_cmd
.total_len
);
8102 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
8103 #ifdef DYNAMIC_MUMIMO_CONTROL
8104 else if (strnicmp(command
, CMD_GET_MURX_BFE_CAP
,
8105 strlen(CMD_GET_MURX_BFE_CAP
)) == 0) {
8106 bytes_written
= wl_android_get_murx_bfe_cap(net
, command
, priv_cmd
.total_len
);
8108 else if (strnicmp(command
, CMD_SET_MURX_BFE_CAP
,
8109 strlen(CMD_SET_MURX_BFE_CAP
)) == 0) {
8110 uint val
= *(command
+ strlen(CMD_SET_MURX_BFE_CAP
) + 1) - '0';
8111 bytes_written
= wl_android_set_murx_bfe_cap(net
, val
);
8113 else if (strnicmp(command
, CMD_GET_BSS_SUPPORT_MUMIMO
,
8114 strlen(CMD_GET_BSS_SUPPORT_MUMIMO
)) == 0) {
8115 bytes_written
= wl_android_get_bss_support_mumimo(net
, command
, priv_cmd
.total_len
);
8117 #endif /* DYNAMIC_MUMIMO_CONTROL */
8118 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
8119 else if (strnicmp(command
, CMD_GET_AP_BASICRATE
, strlen(CMD_GET_AP_BASICRATE
)) == 0) {
8120 bytes_written
= wl_android_get_ap_basicrate(net
, command
, priv_cmd
.total_len
);
8122 else if (strnicmp(command
, CMD_SET_AP_BEACONRATE
, strlen(CMD_SET_AP_BEACONRATE
)) == 0) {
8123 bytes_written
= wl_android_set_ap_beaconrate(net
, command
);
8125 #endif /* SUPPORT_AP_HIGHER_BEACONRATE */
8126 #ifdef SUPPORT_AP_RADIO_PWRSAVE
8127 else if (strnicmp(command
, CMD_SET_AP_RPS_PARAMS
, strlen(CMD_SET_AP_RPS_PARAMS
)) == 0) {
8128 bytes_written
= wl_android_set_ap_rps_params(net
, command
, priv_cmd
.total_len
);
8130 else if (strnicmp(command
, CMD_SET_AP_RPS
, strlen(CMD_SET_AP_RPS
)) == 0) {
8131 bytes_written
= wl_android_set_ap_rps(net
, command
, priv_cmd
.total_len
);
8133 else if (strnicmp(command
, CMD_GET_AP_RPS
, strlen(CMD_GET_AP_RPS
)) == 0) {
8134 bytes_written
= wl_android_get_ap_rps(net
, command
, priv_cmd
.total_len
);
8136 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
8137 #ifdef SUPPORT_RSSI_SUM_REPORT
8138 else if (strnicmp(command
, CMD_SET_RSSI_LOGGING
, strlen(CMD_SET_RSSI_LOGGING
)) == 0) {
8139 bytes_written
= wl_android_set_rssi_logging(net
, command
, priv_cmd
.total_len
);
8141 else if (strnicmp(command
, CMD_GET_RSSI_LOGGING
, strlen(CMD_GET_RSSI_LOGGING
)) == 0) {
8142 bytes_written
= wl_android_get_rssi_logging(net
, command
, priv_cmd
.total_len
);
8144 else if (strnicmp(command
, CMD_GET_RSSI_PER_ANT
, strlen(CMD_GET_RSSI_PER_ANT
)) == 0) {
8145 bytes_written
= wl_android_get_rssi_per_ant(net
, command
, priv_cmd
.total_len
);
8147 #endif /* SUPPORT_RSSI_SUM_REPORT */
8148 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
8149 else if (strnicmp(command
, CMD_GET_BSS_INFO
, strlen(CMD_GET_BSS_INFO
)) == 0) {
8150 bytes_written
= wl_cfg80211_get_bss_info(net
, command
, priv_cmd
.total_len
);
8152 else if (strnicmp(command
, CMD_GET_ASSOC_REJECT_INFO
, strlen(CMD_GET_ASSOC_REJECT_INFO
))
8154 bytes_written
= wl_cfg80211_get_connect_failed_status(net
, command
,
8155 priv_cmd
.total_len
);
8157 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
8158 #if defined(SUPPORT_RANDOM_MAC_SCAN)
8159 else if (strnicmp(command
, ENABLE_RANDOM_MAC
, strlen(ENABLE_RANDOM_MAC
)) == 0) {
8160 bytes_written
= wl_cfg80211_set_random_mac(net
, TRUE
);
8161 } else if (strnicmp(command
, DISABLE_RANDOM_MAC
, strlen(DISABLE_RANDOM_MAC
)) == 0) {
8162 bytes_written
= wl_cfg80211_set_random_mac(net
, FALSE
);
8164 #endif /* SUPPORT_RANDOM_MAC_SCAN */
8166 else if (strnicmp(command
, CMD_NATOE
, strlen(CMD_NATOE
)) == 0) {
8167 bytes_written
= wl_android_process_natoe_cmd(net
, command
,
8168 priv_cmd
.total_len
);
8170 #endif /* WL_NATOE */
8171 #ifdef CONNECTION_STATISTICS
8172 else if (strnicmp(command
, CMD_GET_CONNECTION_STATS
,
8173 strlen(CMD_GET_CONNECTION_STATS
)) == 0) {
8174 bytes_written
= wl_android_get_connection_stats(net
, command
,
8175 priv_cmd
.total_len
);
8179 else if (strnicmp(command
, CMD_NEW_DEBUG_PRINT_DUMP
,
8180 strlen(CMD_NEW_DEBUG_PRINT_DUMP
)) == 0) {
8181 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(net
);
8182 /* check whether it has more command */
8183 if (strnicmp(command
+ strlen(CMD_NEW_DEBUG_PRINT_DUMP
), " ", 1) == 0) {
8184 /* compare unwanted/disconnected command */
8185 if (strnicmp(command
+ strlen(CMD_NEW_DEBUG_PRINT_DUMP
) + 1,
8186 SUBCMD_UNWANTED
, strlen(SUBCMD_UNWANTED
)) == 0) {
8187 dhd_log_dump_trigger(dhdp
, CMD_UNWANTED
);
8188 } else if (strnicmp(command
+ strlen(CMD_NEW_DEBUG_PRINT_DUMP
) + 1,
8189 SUBCMD_DISCONNECTED
, strlen(SUBCMD_DISCONNECTED
)) == 0) {
8190 dhd_log_dump_trigger(dhdp
, CMD_DISCONNECTED
);
8192 dhd_log_dump_trigger(dhdp
, CMD_DEFAULT
);
8195 dhd_log_dump_trigger(dhdp
, CMD_DEFAULT
);
8198 #endif /* DHD_LOG_DUMP */
8199 #ifdef SET_PCIE_IRQ_CPU_CORE
8200 else if (strnicmp(command
, CMD_PCIE_IRQ_CORE
, strlen(CMD_PCIE_IRQ_CORE
)) == 0) {
8201 int affinity_cmd
= *(command
+ strlen(CMD_PCIE_IRQ_CORE
) + 1) - '0';
8202 wl_android_set_irq_cpucore(net
, affinity_cmd
);
8204 #endif /* SET_PCIE_IRQ_CPU_CORE */
8205 #if defined(DHD_HANG_SEND_UP_TEST)
8206 else if (strnicmp(command
, CMD_MAKE_HANG
, strlen(CMD_MAKE_HANG
)) == 0) {
8207 int skip
= strlen(CMD_MAKE_HANG
) + 1;
8208 wl_android_make_hang_with_reason(net
, (const char*)command
+skip
);
8210 #endif /* DHD_HANG_SEND_UP_TEST */
8212 else if (strnicmp(command
, CMD_SET_LQCM_ENABLE
, strlen(CMD_SET_LQCM_ENABLE
)) == 0) {
8213 int lqcm_enable
= *(command
+ strlen(CMD_SET_LQCM_ENABLE
) + 1) - '0';
8214 bytes_written
= wl_android_lqcm_enable(net
, lqcm_enable
);
8216 else if (strnicmp(command
, CMD_GET_LQCM_REPORT
,
8217 strlen(CMD_GET_LQCM_REPORT
)) == 0) {
8218 bytes_written
= wl_android_get_lqcm_report(net
, command
,
8219 priv_cmd
.total_len
);
8222 else if (strnicmp(command
, CMD_GET_SNR
, strlen(CMD_GET_SNR
)) == 0) {
8223 bytes_written
= wl_android_get_snr(net
, command
, priv_cmd
.total_len
);
8225 #ifdef WLADPS_PRIVATE_CMD
8226 else if (strnicmp(command
, CMD_SET_ADPS
, strlen(CMD_SET_ADPS
)) == 0) {
8227 int skip
= strlen(CMD_SET_ADPS
) + 1;
8228 bytes_written
= wl_android_set_adps_mode(net
, (const char*)command
+skip
);
8230 else if (strnicmp(command
, CMD_GET_ADPS
, strlen(CMD_GET_ADPS
)) == 0) {
8231 bytes_written
= wl_android_get_adps_mode(net
, command
, priv_cmd
.total_len
);
8233 #endif /* WLADPS_PRIVATE_CMD */
8234 #ifdef DHD_PKT_LOGGING
8235 else if (strnicmp(command
, CMD_PKTLOG_FILTER_ENABLE
,
8236 strlen(CMD_PKTLOG_FILTER_ENABLE
)) == 0) {
8237 bytes_written
= wl_android_pktlog_filter_enable(net
, command
, priv_cmd
.total_len
);
8239 else if (strnicmp(command
, CMD_PKTLOG_FILTER_DISABLE
,
8240 strlen(CMD_PKTLOG_FILTER_DISABLE
)) == 0) {
8241 bytes_written
= wl_android_pktlog_filter_disable(net
, command
, priv_cmd
.total_len
);
8243 else if (strnicmp(command
, CMD_PKTLOG_FILTER_PATTERN_ENABLE
,
8244 strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE
)) == 0) {
8246 wl_android_pktlog_filter_pattern_enable(net
, command
, priv_cmd
.total_len
);
8248 else if (strnicmp(command
, CMD_PKTLOG_FILTER_PATTERN_DISABLE
,
8249 strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE
)) == 0) {
8251 wl_android_pktlog_filter_pattern_disable(net
, command
, priv_cmd
.total_len
);
8253 else if (strnicmp(command
, CMD_PKTLOG_FILTER_ADD
, strlen(CMD_PKTLOG_FILTER_ADD
)) == 0) {
8254 bytes_written
= wl_android_pktlog_filter_add(net
, command
, priv_cmd
.total_len
);
8256 else if (strnicmp(command
, CMD_PKTLOG_FILTER_INFO
, strlen(CMD_PKTLOG_FILTER_INFO
)) == 0) {
8257 bytes_written
= wl_android_pktlog_filter_info(net
, command
, priv_cmd
.total_len
);
8259 else if (strnicmp(command
, CMD_PKTLOG_START
, strlen(CMD_PKTLOG_START
)) == 0) {
8260 bytes_written
= wl_android_pktlog_start(net
, command
, priv_cmd
.total_len
);
8262 else if (strnicmp(command
, CMD_PKTLOG_STOP
, strlen(CMD_PKTLOG_STOP
)) == 0) {
8263 bytes_written
= wl_android_pktlog_stop(net
, command
, priv_cmd
.total_len
);
8265 else if (strnicmp(command
, CMD_PKTLOG_FILTER_EXIST
, strlen(CMD_PKTLOG_FILTER_EXIST
)) == 0) {
8266 bytes_written
= wl_android_pktlog_filter_exist(net
, command
, priv_cmd
.total_len
);
8268 else if (strnicmp(command
, CMD_PKTLOG_MINMIZE_ENABLE
,
8269 strlen(CMD_PKTLOG_MINMIZE_ENABLE
)) == 0) {
8270 bytes_written
= wl_android_pktlog_minmize_enable(net
, command
, priv_cmd
.total_len
);
8272 else if (strnicmp(command
, CMD_PKTLOG_MINMIZE_DISABLE
,
8273 strlen(CMD_PKTLOG_MINMIZE_DISABLE
)) == 0) {
8274 bytes_written
= wl_android_pktlog_minmize_disable(net
, command
, priv_cmd
.total_len
);
8276 else if (strnicmp(command
, CMD_PKTLOG_CHANGE_SIZE
,
8277 strlen(CMD_PKTLOG_CHANGE_SIZE
)) == 0) {
8278 bytes_written
= wl_android_pktlog_change_size(net
, command
, priv_cmd
.total_len
);
8280 #endif /* DHD_PKT_LOGGING */
8281 else if (strnicmp(command
, CMD_DEBUG_VERBOSE
, strlen(CMD_DEBUG_VERBOSE
)) == 0) {
8282 int verbose_level
= *(command
+ strlen(CMD_DEBUG_VERBOSE
) + 1) - '0';
8283 bytes_written
= wl_cfg80211_set_dbg_verbose(net
, verbose_level
);
8285 #ifdef DHD_EVENT_LOG_FILTER
8286 else if (strnicmp(command
, CMD_EWP_FILTER
,
8287 strlen(CMD_EWP_FILTER
)) == 0) {
8288 bytes_written
= wl_android_ewp_filter(net
, command
, priv_cmd
.total_len
);
8290 #endif /* DHD_EVENT_LOG_FILTER */
8291 #ifdef APSTA_RESTRICTED_CHANNEL
8292 else if (strnicmp(command
, CMD_GET_INDOOR_CHANNELS
,
8293 strlen(CMD_GET_INDOOR_CHANNELS
)) == 0) {
8294 bytes_written
= wl_cfg80211_get_indoor_channels(net
, command
, priv_cmd
.total_len
);
8295 DHD_INFO(("Selected Indoor Channels - %s\n", command
));
8297 else if (strnicmp(command
, CMD_SET_INDOOR_CHANNELS
,
8298 strlen(CMD_SET_INDOOR_CHANNELS
)) == 0) {
8299 bytes_written
= wl_cfg80211_set_indoor_channels(net
, command
, priv_cmd
.total_len
);
8301 #endif /* APSTA_RESTRICTED_CHANNEL */
8302 #ifdef SUPPORT_SET_CAC
8303 else if (strnicmp(command
, CMD_ENABLE_CAC
, strlen(CMD_ENABLE_CAC
)) == 0) {
8304 int enable
= *(command
+ strlen(CMD_ENABLE_CAC
) + 1) - '0';
8305 bytes_written
= wl_cfg80211_enable_cac(net
, enable
);
8307 #endif /* SUPPORT_SET_CAC */
8309 else if (strnicmp(command
, CMD_BEACON_RECV
,
8310 strlen(CMD_BEACON_RECV
)) == 0) {
8311 char *data
= (command
+ strlen(CMD_BEACON_RECV
) + 1);
8312 bytes_written
= wl_android_bcnrecv_config(net
,
8313 data
, priv_cmd
.total_len
);
8315 #endif /* WL_BCNRECV */
8317 DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command
));
8318 bytes_written
= scnprintf(command
, sizeof("FAIL"), "FAIL");
8321 return bytes_written
;
8324 int wl_android_init(void)
8328 #ifdef ENABLE_INSMOD_NO_FW_LOAD
8329 dhd_download_fw_on_driverload
= FALSE
;
8330 #endif /* ENABLE_INSMOD_NO_FW_LOAD */
8331 if (!iface_name
[0]) {
8332 memset(iface_name
, 0, IFNAMSIZ
);
8333 bcm_strncpy_s(iface_name
, IFNAMSIZ
, "wlan", IFNAMSIZ
);
8336 #ifdef CUSTOMER_HW4_DEBUG
8338 #endif /* CUSTOMER_HW4_DEBUG */
8348 int wl_android_exit(void)
8351 struct io_cfg
*cur
, *q
;
8355 #endif /* WL_GENL */
8356 wl_netlink_deinit();
8358 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
8359 #pragma GCC diagnostic push
8360 #pragma GCC diagnostic ignored "-Wcast-qual"
8362 list_for_each_entry_safe(cur
, q
, &miracast_resume_list
, list
) {
8363 list_del(&cur
->list
);
8366 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
8367 #pragma GCC diagnostic pop
8373 void wl_android_post_init(void)
8376 #ifdef ENABLE_4335BT_WAR
8377 bcm_bt_unlock(lock_cookie_wifi
);
8378 printk("%s: btlock released\n", __FUNCTION__
);
8379 #endif /* ENABLE_4335BT_WAR */
8381 if (!dhd_download_fw_on_driverload
)
8386 /* Generic Netlink Initializaiton */
8387 static int wl_genl_init(void)
8391 WL_DBG(("GEN Netlink Init\n\n"));
8393 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
8394 /* register new family */
8395 ret
= genl_register_family(&wl_genl_family
);
8399 /* register functions (commands) of the new family */
8400 ret
= genl_register_ops(&wl_genl_family
, &wl_genl_ops
);
8402 WL_ERR(("register ops failed: %i\n", ret
));
8403 genl_unregister_family(&wl_genl_family
);
8407 ret
= genl_register_mc_group(&wl_genl_family
, &wl_genl_mcast
);
8409 ret
= genl_register_family_with_ops_groups(&wl_genl_family
, wl_genl_ops
, wl_genl_mcast
);
8410 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
8412 WL_ERR(("register mc_group failed: %i\n", ret
));
8413 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
8414 genl_unregister_ops(&wl_genl_family
, &wl_genl_ops
);
8416 genl_unregister_family(&wl_genl_family
);
8423 WL_ERR(("Registering Netlink failed!!\n"));
8427 /* Generic netlink deinit */
8428 static int wl_genl_deinit(void)
8431 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
8432 if (genl_unregister_ops(&wl_genl_family
, &wl_genl_ops
) < 0)
8433 WL_ERR(("Unregister wl_genl_ops failed\n"));
8435 if (genl_unregister_family(&wl_genl_family
) < 0)
8436 WL_ERR(("Unregister wl_genl_ops failed\n"));
8441 s32
wl_event_to_bcm_event(u16 event_type
)
8445 switch (event_type
) {
8446 case WLC_E_SERVICE_FOUND
:
8447 event
= BCM_E_SVC_FOUND
;
8449 case WLC_E_P2PO_ADD_DEVICE
:
8450 event
= BCM_E_DEV_FOUND
;
8452 case WLC_E_P2PO_DEL_DEVICE
:
8453 event
= BCM_E_DEV_LOST
;
8455 /* Above events are supported from BCM Supp ver 47 Onwards */
8456 #ifdef BT_WIFI_HANDOVER
8457 case WLC_E_BT_WIFI_HANDOVER_REQ
:
8458 event
= BCM_E_DEV_BT_WIFI_HO_REQ
;
8460 #endif /* BT_WIFI_HANDOVER */
8463 WL_ERR(("Event not supported\n"));
8471 struct net_device
*ndev
,
8479 struct sk_buff
*skb
;
8482 bcm_event_hdr_t
*hdr
= NULL
;
8483 int mcast
= 1; /* By default sent as mutlicast type */
8485 u8
*ptr
= NULL
, *p
= NULL
;
8486 u32 tot_len
= sizeof(bcm_event_hdr_t
) + subhdr_len
+ len
;
8488 struct bcm_cfg80211
*cfg
= wl_get_cfg(ndev
);
8490 kflags
= in_atomic() ? GFP_ATOMIC
: GFP_KERNEL
;
8492 WL_DBG(("Enter \n"));
8494 /* Decide between STRING event and Data event */
8495 if (event_type
== 0)
8496 attr_type
= BCM_GENL_ATTR_STRING
;
8498 attr_type
= BCM_GENL_ATTR_MSG
;
8500 skb
= genlmsg_new(NLMSG_GOODSIZE
, kflags
);
8506 msg
= genlmsg_put(skb
, 0, 0, &wl_genl_family
, 0, BCM_GENL_CMD_MSG
);
8512 if (attr_type
== BCM_GENL_ATTR_STRING
) {
8513 /* Add a BCM_GENL_MSG attribute. Since it is specified as a string.
8514 * make sure it is null terminated
8516 if (subhdr
|| subhdr_len
) {
8517 WL_ERR(("No sub hdr support for the ATTR STRING type \n"));
8522 ret
= nla_put_string(skb
, BCM_GENL_ATTR_STRING
, buf
);
8524 WL_ERR(("nla_put_string failed\n"));
8530 /* Create a single buffer for all */
8531 p
= ptr
= (u8
*)MALLOCZ(cfg
->osh
, tot_len
);
8534 WL_ERR(("ENOMEM!!\n"));
8538 /* Include the bcm event header */
8539 hdr
= (bcm_event_hdr_t
*)ptr
;
8540 hdr
->event_type
= wl_event_to_bcm_event(event_type
);
8541 hdr
->len
= len
+ subhdr_len
;
8542 ptr
+= sizeof(bcm_event_hdr_t
);
8544 /* Copy subhdr (if any) */
8545 if (subhdr
&& subhdr_len
) {
8546 memcpy(ptr
, subhdr
, subhdr_len
);
8552 memcpy(ptr
, buf
, len
);
8555 ret
= nla_put(skb
, BCM_GENL_ATTR_MSG
, tot_len
, p
);
8557 WL_ERR(("nla_put_string failed\n"));
8564 /* finalize the message */
8565 genlmsg_end(skb
, msg
);
8566 /* NETLINK_CB(skb).dst_group = 1; */
8568 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
8569 if ((err
= genlmsg_multicast(skb
, 0, wl_genl_mcast
.id
, GFP_ATOMIC
)) < 0)
8571 if ((err
= genlmsg_multicast(&wl_genl_family
, skb
, 0, 0, GFP_ATOMIC
)) < 0)
8573 WL_ERR(("genlmsg_multicast for attr(%d) failed. Error:%d \n",
8576 WL_DBG(("Multicast msg sent successfully. attr_type:%d len:%d \n",
8577 attr_type
, tot_len
));
8579 NETLINK_CB(skb
).dst_group
= 0; /* Not in multicast group */
8581 /* finalize the message */
8582 genlmsg_end(skb
, msg
);
8584 /* send the message back */
8585 if (genlmsg_unicast(&init_net
, skb
, pid
) < 0)
8586 WL_ERR(("genlmsg_unicast failed\n"));
8591 MFREE(cfg
->osh
, p
, tot_len
);
8601 struct sk_buff
*skb
,
8602 struct genl_info
*info
)
8607 WL_DBG(("Enter \n"));
8613 na
= info
->attrs
[BCM_GENL_ATTR_MSG
];
8615 WL_ERR(("nlattribute NULL\n"));
8619 data
= (char *)nla_data(na
);
8621 WL_ERR(("Invalid data\n"));
8624 /* Handle the data */
8625 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) || defined(WL_COMPAT_WIRELESS)
8626 WL_DBG(("%s: Data received from pid (%d) \n", __func__
,
8629 WL_DBG(("%s: Data received from pid (%d) \n", __func__
,
8631 #endif /* (LINUX_VERSION < VERSION(3, 7, 0) || WL_COMPAT_WIRELESS */
8636 #endif /* WL_GENL */
8638 int wl_fatal_error(void * wl
, int rc
)
8643 #if defined(BT_OVER_SDIO)
8645 wl_android_set_wifi_on_flag(bool enable
)
8649 #endif /* BT_OVER_SDIO */
8653 wl_cfg80211_register_static_if(struct bcm_cfg80211
*cfg
, u16 iftype
, char *ifname
)
8655 struct net_device
*ndev
;
8656 struct wireless_dev
*wdev
= NULL
;
8657 int ifidx
= WL_STATIC_IFIDX
; /* Register ndev with a reserved ifidx */
8658 u8 mac_addr
[ETH_ALEN
];
8659 struct net_device
*primary_ndev
;
8661 WL_INFORM_MEM(("[STATIC_IF] Enter (%s) iftype:%d\n", ifname
, iftype
));
8664 WL_ERR(("cfg null\n"));
8668 /* Use primary mac with locally admin bit set */
8669 primary_ndev
= bcmcfg_to_prmry_ndev(cfg
);
8670 memcpy(mac_addr
, primary_ndev
->dev_addr
, ETH_ALEN
);
8671 mac_addr
[0] |= 0x02;
8673 ndev
= wl_cfg80211_allocate_if(cfg
, ifidx
, ifname
, mac_addr
,
8674 WL_BSSIDX_MAX
, NULL
);
8675 if (unlikely(!ndev
)) {
8676 WL_ERR(("Failed to allocate static_if\n"));
8679 wdev
= (struct wireless_dev
*)MALLOCZ(cfg
->osh
, sizeof(*wdev
));
8680 if (unlikely(!wdev
)) {
8681 WL_ERR(("Failed to allocate wdev for static_if\n"));
8685 wdev
->wiphy
= cfg
->wdev
->wiphy
;
8686 wdev
->iftype
= iftype
;
8688 ndev
->ieee80211_ptr
= wdev
;
8689 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
8690 wdev
->netdev
= ndev
;
8692 if (wl_cfg80211_register_if(cfg
, ifidx
,
8693 ndev
, TRUE
) != BCME_OK
) {
8694 WL_ERR(("ndev registration failed!\n"));
8698 cfg
->static_ndev
= ndev
;
8699 cfg
->static_ndev_state
= NDEV_STATE_OS_IF_CREATED
;
8700 wl_cfg80211_update_iflist_info(cfg
, ndev
, ifidx
, NULL
, WL_BSSIDX_MAX
,
8701 ifname
, NDEV_STATE_OS_IF_CREATED
);
8702 WL_INFORM_MEM(("Static I/F (%s) Registered\n", ndev
->name
));
8706 wl_cfg80211_remove_if(cfg
, ifidx
, ndev
, false);
8711 wl_cfg80211_unregister_static_if(struct bcm_cfg80211
*cfg
)
8713 WL_INFORM_MEM(("[STATIC_IF] Enter\n"));
8714 if (!cfg
|| !cfg
->static_ndev
) {
8715 WL_ERR(("invalid input\n"));
8719 /* wdev free will happen from notifier context */
8720 /* free_netdev(cfg->static_ndev);
8722 unregister_netdev(cfg
->static_ndev
);
8726 wl_cfg80211_static_if_open(struct net_device
*net
)
8728 struct wireless_dev
*wdev
= NULL
;
8729 struct bcm_cfg80211
*cfg
= wl_get_cfg(net
);
8730 struct net_device
*primary_ndev
= bcmcfg_to_prmry_ndev(cfg
);
8731 u16 iftype
= net
->ieee80211_ptr
? net
->ieee80211_ptr
->iftype
: 0;
8732 u16 wl_iftype
, wl_mode
;
8734 WL_INFORM_MEM(("[STATIC_IF] dev_open ndev %p and wdev %p\n", net
, net
->ieee80211_ptr
));
8735 ASSERT(cfg
->static_ndev
== net
);
8737 if (cfg80211_to_wl_iftype(iftype
, &wl_iftype
, &wl_mode
) < 0) {
8740 if (cfg
->static_ndev_state
!= NDEV_STATE_FW_IF_CREATED
) {
8741 wdev
= wl_cfg80211_add_if(cfg
, primary_ndev
, wl_iftype
, net
->name
, NULL
);
8742 ASSERT(wdev
== net
->ieee80211_ptr
);
8744 WL_INFORM_MEM(("Fw IF for static netdev already created\n"));
8751 wl_cfg80211_static_if_close(struct net_device
*net
)
8754 struct bcm_cfg80211
*cfg
= wl_get_cfg(net
);
8755 struct net_device
*primary_ndev
= bcmcfg_to_prmry_ndev(cfg
);
8757 if (cfg
->static_ndev_state
== NDEV_STATE_FW_IF_CREATED
) {
8758 ret
= wl_cfg80211_del_if(cfg
, primary_ndev
, net
->ieee80211_ptr
, net
->name
);
8759 if (unlikely(ret
)) {
8760 WL_ERR(("Del iface failed for static_if %d\n", ret
));
8767 wl_cfg80211_post_static_ifcreate(struct bcm_cfg80211
*cfg
,
8768 wl_if_event_info
*event
, u8
*addr
, s32 iface_type
)
8770 struct net_device
*new_ndev
= NULL
;
8771 struct wireless_dev
*wdev
= NULL
;
8773 WL_INFORM_MEM(("Updating static iface after Fw IF create \n"));
8774 new_ndev
= cfg
->static_ndev
;
8777 wdev
= new_ndev
->ieee80211_ptr
;
8779 wdev
->iftype
= iface_type
;
8780 memcpy(new_ndev
->dev_addr
, addr
, ETH_ALEN
);
8783 cfg
->static_ndev_state
= NDEV_STATE_FW_IF_CREATED
;
8784 wl_cfg80211_update_iflist_info(cfg
, new_ndev
, event
->ifidx
, addr
, event
->bssidx
,
8785 event
->name
, NDEV_STATE_FW_IF_CREATED
);
8789 wl_cfg80211_post_static_ifdel(struct bcm_cfg80211
*cfg
, struct net_device
*ndev
)
8791 cfg
->static_ndev_state
= NDEV_STATE_FW_IF_DELETED
;
8792 wl_cfg80211_update_iflist_info(cfg
, ndev
, WL_STATIC_IFIDX
, NULL
,
8793 WL_BSSIDX_MAX
, NULL
, NDEV_STATE_FW_IF_DELETED
);
8794 wl_cfg80211_clear_per_bss_ies(cfg
, ndev
->ieee80211_ptr
);
8795 wl_dealloc_netinfo_by_wdev(cfg
, ndev
->ieee80211_ptr
);
8798 #endif /* WL_STATIC_IF */