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 796872 2018-12-27 08:23:42Z $
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 */
75 * Android private command strings, PLEASE define new private commands here
76 * so they can be updated easily in the future (if needed)
79 #define CMD_START "START"
80 #define CMD_STOP "STOP"
81 #define CMD_SCAN_ACTIVE "SCAN-ACTIVE"
82 #define CMD_SCAN_PASSIVE "SCAN-PASSIVE"
83 #define CMD_RSSI "RSSI"
84 #define CMD_LINKSPEED "LINKSPEED"
85 #define CMD_RXFILTER_START "RXFILTER-START"
86 #define CMD_RXFILTER_STOP "RXFILTER-STOP"
87 #define CMD_RXFILTER_ADD "RXFILTER-ADD"
88 #define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE"
89 #define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START"
90 #define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP"
91 #define CMD_BTCOEXMODE "BTCOEXMODE"
92 #define CMD_SETSUSPENDOPT "SETSUSPENDOPT"
93 #define CMD_SETSUSPENDMODE "SETSUSPENDMODE"
94 #define CMD_SETDTIM_IN_SUSPEND "SET_DTIM_IN_SUSPEND"
95 #define CMD_MAXDTIM_IN_SUSPEND "MAX_DTIM_IN_SUSPEND"
96 #define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR"
97 #define CMD_SETFWPATH "SETFWPATH"
98 #define CMD_SETBAND "SETBAND"
99 #define CMD_GETBAND "GETBAND"
100 #define CMD_COUNTRY "COUNTRY"
101 #define CMD_P2P_SET_NOA "P2P_SET_NOA"
102 #if !defined WL_ENABLE_P2P_IF
103 #define CMD_P2P_GET_NOA "P2P_GET_NOA"
104 #endif /* WL_ENABLE_P2P_IF */
105 #define CMD_P2P_SD_OFFLOAD "P2P_SD_"
106 #define CMD_P2P_LISTEN_OFFLOAD "P2P_LO_"
107 #define CMD_P2P_SET_PS "P2P_SET_PS"
108 #define CMD_P2P_ECSA "P2P_ECSA"
109 #define CMD_P2P_INC_BW "P2P_INCREASE_BW"
110 #define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE"
111 #define CMD_SETROAMMODE "SETROAMMODE"
112 #define CMD_SETIBSSBEACONOUIDATA "SETIBSSBEACONOUIDATA"
113 #define CMD_MIRACAST "MIRACAST"
115 #define CMD_NAN "NAN_"
117 #define CMD_COUNTRY_DELIMITER "/"
119 #if defined(WL_SUPPORT_AUTO_CHANNEL)
120 #define CMD_GET_BEST_CHANNELS "GET_BEST_CHANNELS"
121 #endif /* WL_SUPPORT_AUTO_CHANNEL */
123 #define CMD_80211_MODE "MODE" /* 802.11 mode a/b/g/n/ac */
124 #define CMD_CHANSPEC "CHANSPEC"
125 #define CMD_DATARATE "DATARATE"
126 #define CMD_ASSOC_CLIENTS "ASSOCLIST"
127 #define CMD_SET_CSA "SETCSA"
128 #ifdef WL_SUPPORT_AUTO_CHANNEL
129 #define CMD_SET_HAPD_AUTO_CHANNEL "HAPD_AUTO_CHANNEL"
130 #endif /* WL_SUPPORT_AUTO_CHANNEL */
131 #ifdef CUSTOMER_HW4_PRIVATE_CMD
132 #ifdef SUPPORT_HIDDEN_AP
133 /* Hostapd private command */
134 #define CMD_SET_HAPD_MAX_NUM_STA "HAPD_MAX_NUM_STA"
135 #define CMD_SET_HAPD_SSID "HAPD_SSID"
136 #define CMD_SET_HAPD_HIDE_SSID "HAPD_HIDE_SSID"
137 #endif /* SUPPORT_HIDDEN_AP */
138 #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
139 #define CMD_HAPD_STA_DISASSOC "HAPD_STA_DISASSOC"
140 #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
141 #ifdef SUPPORT_SET_LPC
142 #define CMD_HAPD_LPC_ENABLED "HAPD_LPC_ENABLED"
143 #endif /* SUPPORT_SET_LPC */
144 #ifdef SUPPORT_TRIGGER_HANG_EVENT
145 #define CMD_TEST_FORCE_HANG "TEST_FORCE_HANG"
146 #endif /* SUPPORT_TRIGGER_HANG_EVENT */
148 #define CMD_LTECX_SET "LTECOEX"
149 #endif /* SUPPORT_LTECX */
150 #ifdef TEST_TX_POWER_CONTROL
151 #define CMD_TEST_SET_TX_POWER "TEST_SET_TX_POWER"
152 #define CMD_TEST_GET_TX_POWER "TEST_GET_TX_POWER"
153 #endif /* TEST_TX_POWER_CONTROL */
154 #define CMD_SARLIMIT_TX_CONTROL "SET_TX_POWER_CALLING"
155 #ifdef SUPPORT_SET_TID
156 #define CMD_SET_TID "SET_TID"
157 #define CMD_GET_TID "GET_TID"
158 #endif /* SUPPORT_SET_TID */
159 #ifdef APSTA_RESTRICTED_CHANNEL
160 #define CMD_SET_INDOOR_CHANNELS "SET_INDOOR_CHANNELS"
161 #define CMD_GET_INDOOR_CHANNELS "GET_INDOOR_CHANNELS"
162 #endif /* APSTA_RESTRICTED_CHANNEL */
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 */
288 #ifdef APSTA_RESTRICTED_CHANNEL
289 #define CMD_SET_INDOOR_CHANNELS "SET_INDOOR_CHANNELS"
290 #define CMD_GET_INDOOR_CHANNELS "GET_INDOOR_CHANNELS"
291 #endif /* APSTA_RESTRICTED_CHANNEL */
293 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
296 #define CMD_GET_FTKEY "GET_FTKEY"
300 #define CMD_SETIBSSTXFAILEVENT "SETIBSSTXFAILEVENT"
301 #define CMD_GET_IBSS_PEER_INFO "GETIBSSPEERINFO"
302 #define CMD_GET_IBSS_PEER_INFO_ALL "GETIBSSPEERINFOALL"
303 #define CMD_SETIBSSROUTETABLE "SETIBSSROUTETABLE"
304 #define CMD_SETIBSSAMPDU "SETIBSSAMPDU"
305 #define CMD_SETIBSSANTENNAMODE "SETIBSSANTENNAMODE"
308 #define CMD_ROAM_OFFLOAD "SETROAMOFFLOAD"
309 #define CMD_INTERFACE_CREATE "INTERFACE_CREATE"
310 #define CMD_INTERFACE_DELETE "INTERFACE_DELETE"
311 #define CMD_GET_LINK_STATUS "GETLINKSTATUS"
313 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
314 #define CMD_GET_BSS_INFO "GETBSSINFO"
315 #define CMD_GET_ASSOC_REJECT_INFO "GETASSOCREJECTINFO"
316 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
317 #define CMD_GET_STA_INFO "GETSTAINFO"
319 /* related with CMD_GET_LINK_STATUS */
320 #define WL_ANDROID_LINK_VHT 0x01
321 #define WL_ANDROID_LINK_MIMO 0x02
322 #define WL_ANDROID_LINK_AP_VHT_SUPPORT 0x04
323 #define WL_ANDROID_LINK_AP_MIMO_SUPPORT 0x08
325 #ifdef P2PRESP_WFDIE_SRC
326 #define CMD_P2P_SET_WFDIE_RESP "P2P_SET_WFDIE_RESP"
327 #define CMD_P2P_GET_WFDIE_RESP "P2P_GET_WFDIE_RESP"
328 #endif /* P2PRESP_WFDIE_SRC */
330 #define CMD_DFS_AP_MOVE "DFS_AP_MOVE"
331 #define CMD_WBTEXT_ENABLE "WBTEXT_ENABLE"
332 #define CMD_WBTEXT_PROFILE_CONFIG "WBTEXT_PROFILE_CONFIG"
333 #define CMD_WBTEXT_WEIGHT_CONFIG "WBTEXT_WEIGHT_CONFIG"
334 #define CMD_WBTEXT_TABLE_CONFIG "WBTEXT_TABLE_CONFIG"
335 #define CMD_WBTEXT_DELTA_CONFIG "WBTEXT_DELTA_CONFIG"
336 #define CMD_WBTEXT_BTM_TIMER_THRESHOLD "WBTEXT_BTM_TIMER_THRESHOLD"
337 #define CMD_WBTEXT_BTM_DELTA "WBTEXT_BTM_DELTA"
340 #define CMD_ADD_WFDS_HASH "ADD_WFDS_HASH"
341 #define CMD_DEL_WFDS_HASH "DEL_WFDS_HASH"
345 #define CMD_RPSMODE "RPSMODE"
346 #endif /* SET_RPS_CPUS */
348 #ifdef BT_WIFI_HANDOVER
349 #define CMD_TBOW_TEARDOWN "TBOW_TEARDOWN"
350 #endif /* BT_WIFI_HANDOVER */
352 #ifdef DYNAMIC_MUMIMO_CONTROL
353 #define CMD_GET_MURX_BFE_CAP "GET_MURX_BFE_CAP"
354 #define CMD_SET_MURX_BFE_CAP "SET_MURX_BFE_CAP"
355 #define CMD_GET_BSS_SUPPORT_MUMIMO "GET_BSS_SUPPORT_MUMIMO"
356 #endif /* DYNAMIC_MUMIMO_CONTROL */
358 #ifdef SUPPORT_RSSI_SUM_REPORT
359 #define CMD_SET_RSSI_LOGGING "SET_RSSI_LOGGING"
360 #define CMD_GET_RSSI_LOGGING "GET_RSSI_LOGGING"
361 #define CMD_GET_RSSI_PER_ANT "GET_RSSI_PER_ANT"
362 #endif /* SUPPORT_RSSI_SUM_REPORT */
364 #define CMD_GET_SNR "GET_SNR"
366 #ifdef SUPPORT_SET_CAC
367 #define CMD_ENABLE_CAC "ENABLE_CAC"
368 #endif /* SUPPORT_SET_CAC */
370 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
371 #define CMD_SET_AP_BEACONRATE "SET_AP_BEACONRATE"
372 #define CMD_GET_AP_BASICRATE "GET_AP_BASICRATE"
373 #endif /* SUPPORT_AP_HIGHER_BEACONRATE */
375 #ifdef SUPPORT_AP_RADIO_PWRSAVE
376 #define CMD_SET_AP_RPS "SET_AP_RPS"
377 #define CMD_GET_AP_RPS "GET_AP_RPS"
378 #define CMD_SET_AP_RPS_PARAMS "SET_AP_RPS_PARAMS"
379 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
381 /* miracast related definition */
382 #define MIRACAST_MODE_OFF 0
383 #define MIRACAST_MODE_SOURCE 1
384 #define MIRACAST_MODE_SINK 2
386 #ifdef CONNECTION_STATISTICS
387 #define CMD_GET_CONNECTION_STATS "GET_CONNECTION_STATS"
389 struct connection_stats
{
404 #endif /* CONNECTION_STATISTICS */
407 #define CMD_SET_LQCM_ENABLE "SET_LQCM_ENABLE"
408 #define CMD_GET_LQCM_REPORT "GET_LQCM_REPORT"
411 static LIST_HEAD(miracast_resume_list
);
412 static u8 miracast_cur_mode
;
415 #define CMD_NEW_DEBUG_PRINT_DUMP "DEBUG_DUMP"
416 #define SUBCMD_UNWANTED "UNWANTED"
417 #define SUBCMD_DISCONNECTED "DISCONNECTED"
418 void dhd_log_dump_trigger(dhd_pub_t
*dhdp
, int subcmd
);
419 #endif /* DHD_LOG_DUMP */
421 #ifdef DHD_HANG_SEND_UP_TEST
422 #define CMD_MAKE_HANG "MAKE_HANG"
423 #endif /* CMD_DHD_HANG_SEND_UP_TEST */
424 #ifdef DHD_DEBUG_UART
425 extern bool dhd_debug_uart_is_running(struct net_device
*dev
);
426 #endif /* DHD_DEBUG_UART */
434 struct list_head list
;
437 #if defined(BCMFW_ROAM_ENABLE)
438 #define CMD_SET_ROAMPREF "SET_ROAMPREF"
440 #define MAX_NUM_SUITES 10
441 #define WIDTH_AKM_SUITE 8
442 #define JOIN_PREF_RSSI_LEN 0x02
443 #define JOIN_PREF_RSSI_SIZE 4 /* RSSI pref header size in bytes */
444 #define JOIN_PREF_WPA_HDR_SIZE 4 /* WPA pref header size in bytes */
445 #define JOIN_PREF_WPA_TUPLE_SIZE 12 /* Tuple size in bytes */
446 #define JOIN_PREF_MAX_WPA_TUPLES 16
447 #define MAX_BUF_SIZE (JOIN_PREF_RSSI_SIZE + JOIN_PREF_WPA_HDR_SIZE + \
448 (JOIN_PREF_WPA_TUPLE_SIZE * JOIN_PREF_MAX_WPA_TUPLES))
449 #endif /* BCMFW_ROAM_ENABLE */
451 #define CMD_DEBUG_VERBOSE "DEBUG_VERBOSE"
454 #define CMD_NATOE "NATOE"
456 #define NATOE_MAX_PORT_NUM 65535
458 /* natoe command info structure */
459 typedef struct wl_natoe_cmd_info
{
460 uint8
*command
; /* pointer to the actual command */
461 uint16 tot_len
; /* total length of the command */
462 uint16 bytes_written
; /* Bytes written for get response */
463 } wl_natoe_cmd_info_t
;
465 typedef struct wl_natoe_sub_cmd wl_natoe_sub_cmd_t
;
466 typedef int (natoe_cmd_handler_t
)(struct net_device
*dev
,
467 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
469 struct wl_natoe_sub_cmd
{
471 uint8 version
; /* cmd version */
472 uint16 id
; /* id for the dongle f/w switch/case */
473 uint16 type
; /* base type of argument */
474 natoe_cmd_handler_t
*handler
; /* cmd handler */
477 #define WL_ANDROID_NATOE_FUNC(suffix) wl_android_natoe_subcmd_ ##suffix
478 static int wl_android_process_natoe_cmd(struct net_device
*dev
,
479 char *command
, int total_len
);
480 static int wl_android_natoe_subcmd_enable(struct net_device
*dev
,
481 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
482 static int wl_android_natoe_subcmd_config_ips(struct net_device
*dev
,
483 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
484 static int wl_android_natoe_subcmd_config_ports(struct net_device
*dev
,
485 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
486 static int wl_android_natoe_subcmd_dbg_stats(struct net_device
*dev
,
487 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
488 static int wl_android_natoe_subcmd_tbl_cnt(struct net_device
*dev
,
489 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
);
491 static const wl_natoe_sub_cmd_t natoe_cmd_list
[] = {
492 /* wl natoe enable [0/1] or new: "wl natoe [0/1]" */
493 {"enable", 0x01, WL_NATOE_CMD_ENABLE
,
494 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(enable
)
496 {"config_ips", 0x01, WL_NATOE_CMD_CONFIG_IPS
,
497 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(config_ips
)
499 {"config_ports", 0x01, WL_NATOE_CMD_CONFIG_PORTS
,
500 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(config_ports
)
502 {"stats", 0x01, WL_NATOE_CMD_DBG_STATS
,
503 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(dbg_stats
)
505 {"tbl_cnt", 0x01, WL_NATOE_CMD_TBL_CNT
,
506 IOVT_BUFFER
, WL_ANDROID_NATOE_FUNC(tbl_cnt
)
508 {NULL
, 0, 0, 0, NULL
}
511 #endif /* WL_NATOE */
513 #ifdef SET_PCIE_IRQ_CPU_CORE
514 #define CMD_PCIE_IRQ_CORE "PCIE_IRQ_CORE"
515 #endif /* SET_PCIE_IRQ_CPU_CORE */
517 #ifdef WLADPS_PRIVATE_CMD
518 #define CMD_SET_ADPS "SET_ADPS"
519 #define CMD_GET_ADPS "GET_ADPS"
520 #endif /* WLADPS_PRIVATE_CMD */
522 #ifdef DHD_PKT_LOGGING
523 #define CMD_PKTLOG_FILTER_ENABLE "PKTLOG_FILTER_ENABLE"
524 #define CMD_PKTLOG_FILTER_DISABLE "PKTLOG_FILTER_DISABLE"
525 #define CMD_PKTLOG_FILTER_PATTERN_ENABLE "PKTLOG_FILTER_PATTERN_ENABLE"
526 #define CMD_PKTLOG_FILTER_PATTERN_DISABLE "PKTLOG_FILTER_PATTERN_DISABLE"
527 #define CMD_PKTLOG_FILTER_ADD "PKTLOG_FILTER_ADD"
528 #define CMD_PKTLOG_FILTER_INFO "PKTLOG_FILTER_INFO"
529 #define CMD_PKTLOG_START "PKTLOG_START"
530 #define CMD_PKTLOG_STOP "PKTLOG_STOP"
531 #define CMD_PKTLOG_FILTER_EXIST "PKTLOG_FILTER_EXIST"
532 #define CMD_PKTLOG_MINMIZE_ENABLE "PKTLOG_MINMIZE_ENABLE"
533 #define CMD_PKTLOG_MINMIZE_DISABLE "PKTLOG_MINMIZE_DISABLE"
534 #define CMD_PKTLOG_CHANGE_SIZE "PKTLOG_CHANGE_SIZE"
535 #endif /* DHD_PKT_LOGGING */
537 #ifdef DHD_EVENT_LOG_FILTER
538 #define CMD_EWP_FILTER "EWP_FILTER"
539 #endif /* DHD_EVENT_LOG_FILTER */
542 static s32
wl_genl_handle_msg(struct sk_buff
*skb
, struct genl_info
*info
);
543 static int wl_genl_init(void);
544 static int wl_genl_deinit(void);
546 extern struct net init_net
;
547 /* attribute policy: defines which attribute has which type (e.g int, char * etc)
548 * possible values defined in net/netlink.h
550 static struct nla_policy wl_genl_policy
[BCM_GENL_ATTR_MAX
+ 1] = {
551 [BCM_GENL_ATTR_STRING
] = { .type
= NLA_NUL_STRING
},
552 [BCM_GENL_ATTR_MSG
] = { .type
= NLA_BINARY
},
555 #define WL_GENL_VER 1
556 /* family definition */
557 static struct genl_family wl_genl_family
= {
558 .id
= GENL_ID_GENERATE
, /* Genetlink would generate the ID */
560 .name
= "bcm-genl", /* Netlink I/F for Android */
561 .version
= WL_GENL_VER
, /* Version Number */
562 .maxattr
= BCM_GENL_ATTR_MAX
,
565 /* commands: mapping between the command enumeration and the actual function */
566 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
567 struct genl_ops wl_genl_ops
[] = {
569 .cmd
= BCM_GENL_CMD_MSG
,
571 .policy
= wl_genl_policy
,
572 .doit
= wl_genl_handle_msg
,
577 struct genl_ops wl_genl_ops
= {
578 .cmd
= BCM_GENL_CMD_MSG
,
580 .policy
= wl_genl_policy
,
581 .doit
= wl_genl_handle_msg
,
585 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
587 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
588 static struct genl_multicast_group wl_genl_mcast
[] = {
589 { .name
= "bcm-genl-mcast", },
592 static struct genl_multicast_group wl_genl_mcast
= {
593 .id
= GENL_ID_GENERATE
, /* Genetlink would generate the ID */
594 .name
= "bcm-genl-mcast",
596 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
600 #define LQCM_ENAB_MASK 0x000000FF /* LQCM enable flag mask */
601 #define LQCM_TX_INDEX_MASK 0x0000FF00 /* LQCM tx index mask */
602 #define LQCM_RX_INDEX_MASK 0x00FF0000 /* LQCM rx index mask */
604 #define LQCM_TX_INDEX_SHIFT 8 /* LQCM tx index shift */
605 #define LQCM_RX_INDEX_SHIFT 16 /* LQCM rx index shift */
606 #endif /* SUPPORT_LQCM */
609 * Extern function declarations (TODO: move them to dhd_linux.h)
611 int dhd_net_bus_devreset(struct net_device
*dev
, uint8 flag
);
612 int dhd_dev_init_ioctl(struct net_device
*dev
);
614 int wl_cfg80211_get_p2p_dev_addr(struct net_device
*net
, struct ether_addr
*p2pdev_addr
);
615 int wl_cfg80211_set_btcoex_dhcp(struct net_device
*dev
, dhd_pub_t
*dhd
, char *command
);
617 int wl_cfg80211_set_wes_mode(int mode
);
618 int wl_cfg80211_get_wes_mode(void);
619 #endif /* WES_SUPPORT */
621 int wl_cfg80211_get_p2p_dev_addr(struct net_device
*net
, struct ether_addr
*p2pdev_addr
)
623 int wl_cfg80211_set_p2p_noa(struct net_device
*net
, char* buf
, int len
)
625 int wl_cfg80211_get_p2p_noa(struct net_device
*net
, char* buf
, int len
)
627 int wl_cfg80211_set_p2p_ps(struct net_device
*net
, char* buf
, int len
)
629 int wl_cfg80211_set_p2p_ecsa(struct net_device
*net
, char* buf
, int len
)
631 int wl_cfg80211_increase_p2p_bw(struct net_device
*net
, char* buf
, int len
)
633 #endif /* WK_CFG80211 */
635 static int wl_android_wbtext(struct net_device
*dev
, char *command
, int total_len
);
636 static int wl_cfg80211_wbtext_btm_timer_threshold(struct net_device
*dev
,
637 char *command
, int total_len
);
638 static int wl_cfg80211_wbtext_btm_delta(struct net_device
*dev
,
639 char *command
, int total_len
);
643 extern int get_roamscan_mode(struct net_device
*dev
, int *mode
);
644 extern int set_roamscan_mode(struct net_device
*dev
, int mode
);
645 extern int get_roamscan_channel_list(struct net_device
*dev
,
646 unsigned char channels
[], int n_channels
);
647 extern int set_roamscan_channel_list(struct net_device
*dev
, unsigned char n
,
648 unsigned char channels
[], int ioctl_ver
);
649 #endif /* WES_SUPPORT */
650 #ifdef ROAM_CHANNEL_CACHE
651 extern void wl_update_roamscan_cache_by_band(struct net_device
*dev
, int band
);
652 #endif /* ROAM_CHANNEL_CACHE */
654 #ifdef ENABLE_4335BT_WAR
655 extern int bcm_bt_lock(int cookie
);
656 extern void bcm_bt_unlock(int cookie
);
657 static int lock_cookie_wifi
= 'W' | 'i'<<8 | 'F'<<16 | 'i'<<24; /* cookie is "WiFi" */
658 #endif /* ENABLE_4335BT_WAR */
660 extern bool ap_fw_loaded
;
661 extern char iface_name
[IFNAMSIZ
];
662 #ifdef DHD_PM_CONTROL_FROM_FILE
663 extern bool g_pm_control
;
664 #endif /* DHD_PM_CONTROL_FROM_FILE */
667 * Local (static) functions and variables
670 /* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first
671 * time (only) in dhd_open, subsequential wifi on will be handled by
674 static int g_wifi_on
= TRUE
;
677 * Local (static) function definitions
681 static int wl_android_set_wfds_hash(
682 struct net_device
*dev
, char *command
, bool enable
)
685 wl_p2p_wfds_hash_t
*wfds_hash
= NULL
;
687 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
689 smbuf
= (char *)MALLOC(cfg
->osh
, WLC_IOCTL_MAXLEN
);
691 DHD_ERROR(("%s: failed to allocated memory %d bytes\n",
692 __FUNCTION__
, WLC_IOCTL_MAXLEN
));
697 wfds_hash
= (wl_p2p_wfds_hash_t
*)(command
+ strlen(CMD_ADD_WFDS_HASH
) + 1);
698 error
= wldev_iovar_setbuf(dev
, "p2p_add_wfds_hash", wfds_hash
,
699 sizeof(wl_p2p_wfds_hash_t
), smbuf
, WLC_IOCTL_MAXLEN
, NULL
);
702 wfds_hash
= (wl_p2p_wfds_hash_t
*)(command
+ strlen(CMD_DEL_WFDS_HASH
) + 1);
703 error
= wldev_iovar_setbuf(dev
, "p2p_del_wfds_hash", wfds_hash
,
704 sizeof(wl_p2p_wfds_hash_t
), smbuf
, WLC_IOCTL_MAXLEN
, NULL
);
708 DHD_ERROR(("%s: failed to %s, error=%d\n", __FUNCTION__
, command
, error
));
712 MFREE(cfg
->osh
, smbuf
, WLC_IOCTL_MAXLEN
);
718 static int wl_android_get_link_speed(struct net_device
*net
, char *command
, int total_len
)
724 error
= wldev_get_link_speed(net
, &link_speed
);
726 DHD_ERROR(("Get linkspeed failed \n"));
730 /* Convert Kbps to Android Mbps */
731 link_speed
= link_speed
/ 1000;
732 bytes_written
= snprintf(command
, total_len
, "LinkSpeed %d", link_speed
);
733 DHD_INFO(("%s: command result is %s\n", __FUNCTION__
, command
));
734 return bytes_written
;
737 static int wl_android_get_rssi(struct net_device
*net
, char *command
, int total_len
)
739 wlc_ssid_t ssid
= {0, {0}};
740 int bytes_written
= 0;
744 struct net_device
*target_ndev
= net
;
745 #ifdef WL_VIRTUAL_APSTA
747 struct bcm_cfg80211
*cfg
;
748 #endif /* WL_VIRTUAL_APSTA */
750 delim
= strchr(command
, ' ');
751 /* For Ap mode rssi command would be
752 * driver rssi <sta_mac_addr>
758 * driver rssi <sta_mac_addr>
760 DHD_TRACE(("%s: cmd:%s\n", __FUNCTION__
, delim
));
761 /* skip space from delim after finding char */
763 if (!(bcm_ether_atoe((delim
), &scbval
.ea
))) {
764 DHD_ERROR(("%s:address err\n", __FUNCTION__
));
767 scbval
.val
= htod32(0);
768 DHD_TRACE(("%s: address:"MACDBG
, __FUNCTION__
, MAC2STRDBG(scbval
.ea
.octet
)));
769 #ifdef WL_VIRTUAL_APSTA
770 /* RSDB AP may have another virtual interface
771 * In this case, format of private command is as following,
772 * DRIVER rssi <sta_mac_addr> <AP interface name>
775 /* Current position is start of MAC address string */
777 delim
= strchr(pos
, ' ');
779 /* skip space from delim after finding char */
781 if (strnlen(delim
, IFNAMSIZ
)) {
782 cfg
= wl_get_cfg(net
);
783 target_ndev
= wl_get_ap_netdev(cfg
, delim
);
784 if (target_ndev
== NULL
)
788 #endif /* WL_VIRTUAL_APSTA */
792 memset(&scbval
, 0, sizeof(scb_val_t
));
795 error
= wldev_get_rssi(target_ndev
, &scbval
);
799 error
= wldev_get_ssid(target_ndev
, &ssid
);
802 if ((ssid
.SSID_len
== 0) || (ssid
.SSID_len
> DOT11_MAX_SSID_LEN
)) {
803 DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__
));
804 } else if (total_len
<= ssid
.SSID_len
) {
807 memcpy(command
, ssid
.SSID
, ssid
.SSID_len
);
808 bytes_written
= ssid
.SSID_len
;
810 if ((total_len
- bytes_written
) < (strlen(" rssi -XXX") + 1))
813 bytes_written
+= scnprintf(&command
[bytes_written
], total_len
- bytes_written
,
814 " rssi %d", scbval
.val
);
815 command
[bytes_written
] = '\0';
817 DHD_TRACE(("%s: command result is %s (%d)\n", __FUNCTION__
, command
, bytes_written
));
818 return bytes_written
;
821 static int wl_android_set_suspendopt(struct net_device
*dev
, char *command
)
827 suspend_flag
= *(command
+ strlen(CMD_SETSUSPENDOPT
) + 1) - '0';
829 if (suspend_flag
!= 0) {
832 ret_now
= net_os_set_suspend_disable(dev
, suspend_flag
);
834 if (ret_now
!= suspend_flag
) {
835 if (!(ret
= net_os_set_suspend(dev
, ret_now
, 1))) {
836 DHD_INFO(("%s: Suspend Flag %d -> %d\n",
837 __FUNCTION__
, ret_now
, suspend_flag
));
839 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
846 static int wl_android_set_suspendmode(struct net_device
*dev
, char *command
)
850 #if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(DHD_USE_EARLYSUSPEND)
853 suspend_flag
= *(command
+ strlen(CMD_SETSUSPENDMODE
) + 1) - '0';
854 if (suspend_flag
!= 0)
857 if (!(ret
= net_os_set_suspend(dev
, suspend_flag
, 0)))
858 DHD_INFO(("%s: Suspend Mode %d\n", __FUNCTION__
, suspend_flag
));
860 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
866 int wl_android_get_80211_mode(struct net_device
*dev
, char *command
, int total_len
)
870 int bytes_written
= 0;
872 error
= wldev_get_mode(dev
, mode
, sizeof(mode
));
876 DHD_INFO(("%s: mode:%s\n", __FUNCTION__
, mode
));
877 bytes_written
= snprintf(command
, total_len
, "%s %s", CMD_80211_MODE
, mode
);
878 DHD_INFO(("%s: command:%s EXIT\n", __FUNCTION__
, command
));
879 return bytes_written
;
884 wl_chspec_driver_to_host(chanspec_t chanspec
);
885 int wl_android_get_chanspec(struct net_device
*dev
, char *command
, int total_len
)
888 int bytes_written
= 0;
899 error
= wldev_iovar_getint(dev
, "chanspec", &chsp
);
903 chanspec
= wl_chspec_driver_to_host(chsp
);
904 DHD_INFO(("%s:return value of chanspec:%x\n", __FUNCTION__
, chanspec
));
906 channel
= chanspec
& WL_CHANSPEC_CHAN_MASK
;
907 band
= chanspec
& WL_CHANSPEC_BAND_MASK
;
908 bw
= chanspec
& WL_CHANSPEC_BW_MASK
;
910 DHD_INFO(("%s:channel:%d band:%d bandwidth:%d\n", __FUNCTION__
, channel
, band
, bw
));
912 if (bw
== WL_CHANSPEC_BW_80
)
913 bw
= WL_CH_BANDWIDTH_80MHZ
;
914 else if (bw
== WL_CHANSPEC_BW_40
)
915 bw
= WL_CH_BANDWIDTH_40MHZ
;
916 else if (bw
== WL_CHANSPEC_BW_20
)
917 bw
= WL_CH_BANDWIDTH_20MHZ
;
919 bw
= WL_CH_BANDWIDTH_20MHZ
;
921 if (bw
== WL_CH_BANDWIDTH_40MHZ
) {
922 if (CHSPEC_SB_UPPER(chanspec
)) {
923 channel
+= CH_10MHZ_APART
;
925 channel
-= CH_10MHZ_APART
;
928 else if (bw
== WL_CH_BANDWIDTH_80MHZ
) {
929 sb
= chanspec
& WL_CHANSPEC_CTL_SB_MASK
;
930 if (sb
== WL_CHANSPEC_CTL_SB_LL
) {
931 channel
-= (CH_10MHZ_APART
+ CH_20MHZ_APART
);
932 } else if (sb
== WL_CHANSPEC_CTL_SB_LU
) {
933 channel
-= CH_10MHZ_APART
;
934 } else if (sb
== WL_CHANSPEC_CTL_SB_UL
) {
935 channel
+= CH_10MHZ_APART
;
937 /* WL_CHANSPEC_CTL_SB_UU */
938 channel
+= (CH_10MHZ_APART
+ CH_20MHZ_APART
);
941 bytes_written
= snprintf(command
, total_len
, "%s channel %d band %s bw %d", CMD_CHANSPEC
,
942 channel
, band
== WL_CHANSPEC_BAND_5G
? "5G":"2G", bw
);
944 DHD_INFO(("%s: command:%s EXIT\n", __FUNCTION__
, command
));
945 return bytes_written
;
949 /* returns current datarate datarate returned from firmware are in 500kbps */
950 int wl_android_get_datarate(struct net_device
*dev
, char *command
, int total_len
)
954 int bytes_written
= 0;
956 error
= wldev_get_datarate(dev
, &datarate
);
960 DHD_INFO(("%s:datarate:%d\n", __FUNCTION__
, datarate
));
962 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_DATARATE
, (datarate
/2));
963 return bytes_written
;
965 int wl_android_get_assoclist(struct net_device
*dev
, char *command
, int total_len
)
968 int bytes_written
= 0;
971 char mac_buf
[MAX_NUM_OF_ASSOCLIST
*
972 sizeof(struct ether_addr
) + sizeof(uint
)] = {0};
973 struct maclist
*assoc_maclist
= (struct maclist
*)mac_buf
;
975 DHD_TRACE(("%s: ENTER\n", __FUNCTION__
));
977 assoc_maclist
->count
= htod32(MAX_NUM_OF_ASSOCLIST
);
979 error
= wldev_ioctl_get(dev
, WLC_GET_ASSOCLIST
, assoc_maclist
, sizeof(mac_buf
));
983 assoc_maclist
->count
= dtoh32(assoc_maclist
->count
);
984 bytes_written
= snprintf(command
, total_len
, "%s listcount: %d Stations:",
985 CMD_ASSOC_CLIENTS
, assoc_maclist
->count
);
987 for (i
= 0; i
< assoc_maclist
->count
; i
++) {
988 len
= snprintf(command
+ bytes_written
, total_len
- bytes_written
, " " MACDBG
,
989 MAC2STRDBG(assoc_maclist
->ea
[i
].octet
));
990 /* A return value of '(total_len - bytes_written)' or more means that the
991 * output was truncated
993 if ((len
> 0) && (len
< (total_len
- bytes_written
))) {
994 bytes_written
+= len
;
996 DHD_ERROR(("%s: Insufficient buffer %d, bytes_written %d\n",
997 __FUNCTION__
, total_len
, bytes_written
));
1002 return bytes_written
;
1005 wl_chspec_host_to_driver(chanspec_t chanspec
);
1006 static int wl_android_set_csa(struct net_device
*dev
, char *command
)
1009 char smbuf
[WLC_IOCTL_SMLEN
];
1010 wl_chan_switch_t csa_arg
;
1014 DHD_INFO(("%s: command:%s\n", __FUNCTION__
, command
));
1016 command
= (command
+ strlen(CMD_SET_CSA
));
1017 /* Order is mode, count channel */
1019 DHD_ERROR(("%s:error missing arguments\n", __FUNCTION__
));
1022 csa_arg
.mode
= bcm_atoi(command
);
1024 if (csa_arg
.mode
!= 0 && csa_arg
.mode
!= 1) {
1025 DHD_ERROR(("Invalid mode\n"));
1030 DHD_ERROR(("%s:error missing count\n", __FUNCTION__
));
1034 csa_arg
.count
= bcm_atoi(command
);
1040 DHD_ERROR(("%s:error missing channel\n", __FUNCTION__
));
1044 chnsp
= wf_chspec_aton(command
);
1046 DHD_ERROR(("%s:chsp is not correct\n", __FUNCTION__
));
1049 chnsp
= wl_chspec_host_to_driver(chnsp
);
1050 csa_arg
.chspec
= chnsp
;
1052 if (chnsp
& WL_CHANSPEC_BAND_5G
) {
1053 u32 chanspec
= chnsp
;
1054 err
= wldev_iovar_getint(dev
, "per_chan_info", &chanspec
);
1056 if ((chanspec
& WL_CHAN_RADAR
) || (chanspec
& WL_CHAN_PASSIVE
)) {
1057 DHD_ERROR(("Channel is radar sensitive\n"));
1060 if (chanspec
== 0) {
1061 DHD_ERROR(("Invalid hw channel\n"));
1065 DHD_ERROR(("does not support per_chan_info\n"));
1068 DHD_INFO(("non radar sensitivity\n"));
1070 error
= wldev_iovar_setbuf(dev
, "csa", &csa_arg
, sizeof(csa_arg
),
1071 smbuf
, sizeof(smbuf
), NULL
);
1073 DHD_ERROR(("%s:set csa failed:%d\n", __FUNCTION__
, error
));
1080 wl_android_set_bcn_li_dtim(struct net_device
*dev
, char *command
)
1085 dtim
= *(command
+ strlen(CMD_SETDTIM_IN_SUSPEND
) + 1) - '0';
1087 if (dtim
> (MAX_DTIM_ALLOWED_INTERVAL
/ MAX_DTIM_SKIP_BEACON_INTERVAL
)) {
1088 DHD_ERROR(("%s: failed, invalid dtim %d\n",
1089 __FUNCTION__
, dtim
));
1093 if (!(ret
= net_os_set_suspend_bcn_li_dtim(dev
, dtim
))) {
1094 DHD_TRACE(("%s: SET bcn_li_dtim in suspend %d\n",
1095 __FUNCTION__
, dtim
));
1097 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
1104 wl_android_set_max_dtim(struct net_device
*dev
, char *command
)
1109 dtim_flag
= *(command
+ strlen(CMD_MAXDTIM_IN_SUSPEND
) + 1) - '0';
1111 if (!(ret
= net_os_set_max_dtim_enable(dev
, dtim_flag
))) {
1112 DHD_TRACE(("%s: use Max bcn_li_dtim in suspend %s\n",
1113 __FUNCTION__
, (dtim_flag
? "Enable" : "Disable")));
1115 DHD_ERROR(("%s: failed %d\n", __FUNCTION__
, ret
));
1121 static int wl_android_get_band(struct net_device
*dev
, char *command
, int total_len
)
1127 error
= wldev_get_band(dev
, &band
);
1130 bytes_written
= snprintf(command
, total_len
, "Band %d", band
);
1131 return bytes_written
;
1134 #ifdef CUSTOMER_HW4_PRIVATE_CMD
1136 static bool wl_android_check_wbtext(struct net_device
*dev
)
1138 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
1139 return dhdp
->wbtext_support
;
1142 static int wl_android_set_roam_trigger(
1143 struct net_device
*dev
, char* command
)
1145 int roam_trigger
[2] = {0, 0};
1149 if (wl_android_check_wbtext(dev
)) {
1150 WL_ERR(("blocked to set roam trigger. try with setting roam profile\n"));
1155 sscanf(command
, "%*s %10d", &roam_trigger
[0]);
1156 if (roam_trigger
[0] >= 0) {
1157 WL_ERR(("wrong roam trigger value (%d)\n", roam_trigger
[0]));
1161 roam_trigger
[1] = WLC_BAND_ALL
;
1162 error
= wldev_ioctl_set(dev
, WLC_SET_ROAM_TRIGGER
, roam_trigger
,
1163 sizeof(roam_trigger
));
1164 if (error
!= BCME_OK
) {
1165 WL_ERR(("failed to set roam trigger (%d)\n", error
));
1172 static int wl_android_get_roam_trigger(
1173 struct net_device
*dev
, char *command
, int total_len
)
1175 int bytes_written
, error
;
1176 int roam_trigger
[2] = {0, 0};
1179 chanspec_t chanspec
;
1181 struct wl_roam_prof_band_v2 rp
;
1182 char smbuf
[WLC_IOCTL_SMLEN
];
1184 error
= wldev_iovar_getint(dev
, "chanspec", &chsp
);
1185 if (error
!= BCME_OK
) {
1186 WL_ERR(("failed to get chanspec (%d)\n", error
));
1190 chanspec
= wl_chspec_driver_to_host(chsp
);
1191 band
= chanspec
& WL_CHANSPEC_BAND_MASK
;
1192 if (band
== WL_CHANSPEC_BAND_5G
)
1197 if (wl_android_check_wbtext(dev
)) {
1198 rp
.ver
= WL_MAX_ROAM_PROF_VER
;
1201 error
= wldev_iovar_getbuf(dev
, "roam_prof", &rp
, sizeof(rp
),
1202 smbuf
, sizeof(smbuf
), NULL
);
1203 if (error
!= BCME_OK
) {
1204 WL_ERR(("failed to get roam profile (%d)\n", error
));
1207 memcpy(&rp
, smbuf
, sizeof(struct wl_roam_prof_band_v2
));
1208 for (i
= 0; i
< WL_MAX_ROAM_PROF_BRACKETS
; i
++) {
1209 if (rp
.roam_prof
[i
].channel_usage
== 0) {
1210 roam_trigger
[0] = rp
.roam_prof
[i
].roam_trigger
;
1214 if (roam_trigger
[0] == 0) {
1215 WL_ERR(("roam trigger was not set properly\n"));
1219 roam_trigger
[1] = band
;
1220 error
= wldev_ioctl_get(dev
, WLC_GET_ROAM_TRIGGER
, roam_trigger
,
1221 sizeof(roam_trigger
));
1222 if (error
!= BCME_OK
) {
1223 WL_ERR(("failed to get roam trigger (%d)\n", error
));
1228 bytes_written
= snprintf(command
, total_len
, "%s %d",
1229 CMD_ROAMTRIGGER_GET
, roam_trigger
[0]);
1231 return bytes_written
;
1234 int wl_android_set_roam_delta(
1235 struct net_device
*dev
, char* command
)
1239 sscanf(command
, "%*s %10d", &roam_delta
[0]);
1240 roam_delta
[1] = WLC_BAND_ALL
;
1242 return wldev_ioctl_set(dev
, WLC_SET_ROAM_DELTA
, roam_delta
,
1243 sizeof(roam_delta
));
1246 static int wl_android_get_roam_delta(
1247 struct net_device
*dev
, char *command
, int total_len
)
1250 int roam_delta
[2] = {0, 0};
1252 roam_delta
[1] = WLC_BAND_2G
;
1253 if (wldev_ioctl_get(dev
, WLC_GET_ROAM_DELTA
, roam_delta
,
1254 sizeof(roam_delta
))) {
1255 roam_delta
[1] = WLC_BAND_5G
;
1256 if (wldev_ioctl_get(dev
, WLC_GET_ROAM_DELTA
, roam_delta
,
1257 sizeof(roam_delta
)))
1261 bytes_written
= snprintf(command
, total_len
, "%s %d",
1262 CMD_ROAMDELTA_GET
, roam_delta
[0]);
1264 return bytes_written
;
1267 int wl_android_set_roam_scan_period(
1268 struct net_device
*dev
, char* command
)
1270 int roam_scan_period
= 0;
1272 sscanf(command
, "%*s %10d", &roam_scan_period
);
1273 return wldev_ioctl_set(dev
, WLC_SET_ROAM_SCAN_PERIOD
, &roam_scan_period
,
1274 sizeof(roam_scan_period
));
1277 static int wl_android_get_roam_scan_period(
1278 struct net_device
*dev
, char *command
, int total_len
)
1281 int roam_scan_period
= 0;
1283 if (wldev_ioctl_get(dev
, WLC_GET_ROAM_SCAN_PERIOD
, &roam_scan_period
,
1284 sizeof(roam_scan_period
)))
1287 bytes_written
= snprintf(command
, total_len
, "%s %d",
1288 CMD_ROAMSCANPERIOD_GET
, roam_scan_period
);
1290 return bytes_written
;
1293 int wl_android_set_full_roam_scan_period(
1294 struct net_device
*dev
, char* command
, int total_len
)
1297 int full_roam_scan_period
= 0;
1298 char smbuf
[WLC_IOCTL_SMLEN
];
1300 sscanf(command
+sizeof("SETFULLROAMSCANPERIOD"), "%d", &full_roam_scan_period
);
1301 WL_TRACE(("fullroamperiod = %d\n", full_roam_scan_period
));
1303 error
= wldev_iovar_setbuf(dev
, "fullroamperiod", &full_roam_scan_period
,
1304 sizeof(full_roam_scan_period
), smbuf
, sizeof(smbuf
), NULL
);
1306 DHD_ERROR(("Failed to set full roam scan period, error = %d\n", error
));
1312 static int wl_android_get_full_roam_scan_period(
1313 struct net_device
*dev
, char *command
, int total_len
)
1317 int full_roam_scan_period
= 0;
1319 error
= wldev_iovar_getint(dev
, "fullroamperiod", &full_roam_scan_period
);
1322 DHD_ERROR(("%s: get full roam scan period failed code %d\n",
1326 DHD_INFO(("%s: get full roam scan period %d\n", __func__
, full_roam_scan_period
));
1329 bytes_written
= snprintf(command
, total_len
, "%s %d",
1330 CMD_FULLROAMSCANPERIOD_GET
, full_roam_scan_period
);
1332 return bytes_written
;
1335 int wl_android_set_country_rev(
1336 struct net_device
*dev
, char* command
)
1339 wl_country_t cspec
= {{0}, 0, {0} };
1340 char country_code
[WLC_CNTRY_BUF_SZ
];
1341 char smbuf
[WLC_IOCTL_SMLEN
];
1344 memset(country_code
, 0, sizeof(country_code
));
1345 sscanf(command
+sizeof("SETCOUNTRYREV"), "%3s %10d", country_code
, &rev
);
1346 WL_TRACE(("country_code = %s, rev = %d\n", country_code
, rev
));
1348 memcpy(cspec
.country_abbrev
, country_code
, sizeof(country_code
));
1349 memcpy(cspec
.ccode
, country_code
, sizeof(country_code
));
1352 error
= wldev_iovar_setbuf(dev
, "country", (char *)&cspec
,
1353 sizeof(cspec
), smbuf
, sizeof(smbuf
), NULL
);
1356 DHD_ERROR(("%s: set country '%s/%d' failed code %d\n",
1357 __FUNCTION__
, cspec
.ccode
, cspec
.rev
, error
));
1359 dhd_bus_country_set(dev
, &cspec
, true);
1360 DHD_INFO(("%s: set country '%s/%d'\n",
1361 __FUNCTION__
, cspec
.ccode
, cspec
.rev
));
1367 static int wl_android_get_country_rev(
1368 struct net_device
*dev
, char *command
, int total_len
)
1372 char smbuf
[WLC_IOCTL_SMLEN
];
1375 error
= wldev_iovar_getbuf(dev
, "country", NULL
, 0, smbuf
,
1376 sizeof(smbuf
), NULL
);
1379 DHD_ERROR(("%s: get country failed code %d\n",
1380 __FUNCTION__
, error
));
1383 memcpy(&cspec
, smbuf
, sizeof(cspec
));
1384 DHD_INFO(("%s: get country '%c%c %d'\n",
1385 __FUNCTION__
, cspec
.ccode
[0], cspec
.ccode
[1], cspec
.rev
));
1388 bytes_written
= snprintf(command
, total_len
, "%s %c%c %d",
1389 CMD_COUNTRYREV_GET
, cspec
.ccode
[0], cspec
.ccode
[1], cspec
.rev
);
1391 return bytes_written
;
1393 #endif /* ROAM_API */
1396 int wl_android_get_roam_scan_control(struct net_device
*dev
, char *command
, int total_len
)
1399 int bytes_written
= 0;
1402 error
= get_roamscan_mode(dev
, &mode
);
1404 DHD_ERROR(("%s: Failed to get Scan Control, error = %d\n", __FUNCTION__
, error
));
1408 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETROAMSCANCONTROL
, mode
);
1410 return bytes_written
;
1413 int wl_android_set_roam_scan_control(struct net_device
*dev
, char *command
)
1418 if (sscanf(command
, "%*s %d", &mode
) != 1) {
1419 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1423 error
= set_roamscan_mode(dev
, mode
);
1425 DHD_ERROR(("%s: Failed to set Scan Control %d, error = %d\n",
1426 __FUNCTION__
, mode
, error
));
1433 int wl_android_get_roam_scan_channels(struct net_device
*dev
, char *command
, int total_len
)
1435 int bytes_written
= 0;
1436 unsigned char channels
[MAX_ROAM_CHANNEL
] = {0};
1437 int channel_cnt
= 0;
1441 channel_cnt
= get_roamscan_channel_list(dev
, channels
, MAX_ROAM_CHANNEL
);
1442 bytes_written
= snprintf(command
, total_len
, "%s %d",
1443 CMD_GETROAMSCANCHANNELS
, channel_cnt
);
1444 buf_avail
= total_len
- bytes_written
;
1445 for (i
= 0; i
< channel_cnt
; i
++) {
1446 /* A return value of 'buf_avail' or more means that the output was truncated */
1447 len
= snprintf(command
+ bytes_written
, buf_avail
, " %d", channels
[i
]);
1448 if (len
>= buf_avail
) {
1449 WL_ERR(("%s: Insufficient memory, %d bytes\n", __FUNCTION__
, total_len
));
1453 /* 'buf_avail' decremented by number of bytes written */
1455 bytes_written
+= len
;
1457 WL_INFORM(("%s: %s\n", __FUNCTION__
, command
));
1458 return bytes_written
;
1461 int wl_android_set_roam_scan_channels(struct net_device
*dev
, char *command
)
1464 unsigned char *p
= (unsigned char *)(command
+ strlen(CMD_SETROAMSCANCHANNELS
) + 1);
1465 int get_ioctl_version
= wl_cfg80211_get_ioctl_version();
1466 error
= set_roamscan_channel_list(dev
, p
[0], &p
[1], get_ioctl_version
);
1468 DHD_ERROR(("%s: Failed to set Scan Channels %d, error = %d\n",
1469 __FUNCTION__
, p
[0], error
));
1476 int wl_android_get_scan_channel_time(struct net_device
*dev
, char *command
, int total_len
)
1479 int bytes_written
= 0;
1482 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_CHANNEL_TIME
, &time
, sizeof(time
));
1484 DHD_ERROR(("%s: Failed to get Scan Channel Time, error = %d\n",
1485 __FUNCTION__
, error
));
1489 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANCHANNELTIME
, time
);
1491 return bytes_written
;
1494 int wl_android_set_scan_channel_time(struct net_device
*dev
, char *command
)
1499 if (sscanf(command
, "%*s %d", &time
) != 1) {
1500 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1503 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1504 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_CHANNEL_TIME
, time
);
1505 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_CHANNEL_TIME
, &time
, sizeof(time
));
1506 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1508 DHD_ERROR(("%s: Failed to set Scan Channel Time %d, error = %d\n",
1509 __FUNCTION__
, time
, error
));
1517 wl_android_get_scan_unassoc_time(struct net_device
*dev
, char *command
, int total_len
)
1520 int bytes_written
= 0;
1523 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_UNASSOC_TIME
, &time
, sizeof(time
));
1525 DHD_ERROR(("%s: Failed to get Scan Unassoc Time, error = %d\n",
1526 __FUNCTION__
, error
));
1530 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANUNASSOCTIME
, time
);
1532 return bytes_written
;
1536 wl_android_set_scan_unassoc_time(struct net_device
*dev
, char *command
)
1541 if (sscanf(command
, "%*s %d", &time
) != 1) {
1542 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1545 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1546 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_UNASSOC_TIME
, time
);
1547 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_UNASSOC_TIME
, &time
, sizeof(time
));
1548 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1550 DHD_ERROR(("%s: Failed to set Scan Unassoc Time %d, error = %d\n",
1551 __FUNCTION__
, time
, error
));
1559 wl_android_get_scan_passive_time(struct net_device
*dev
, char *command
, int total_len
)
1562 int bytes_written
= 0;
1565 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_PASSIVE_TIME
, &time
, sizeof(time
));
1567 DHD_ERROR(("%s: Failed to get Scan Passive Time, error = %d\n",
1568 __FUNCTION__
, error
));
1572 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANPASSIVETIME
, time
);
1574 return bytes_written
;
1578 wl_android_set_scan_passive_time(struct net_device
*dev
, char *command
)
1583 if (sscanf(command
, "%*s %d", &time
) != 1) {
1584 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1587 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1588 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_PASSIVE_TIME
, time
);
1589 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_PASSIVE_TIME
, &time
, sizeof(time
));
1590 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1592 DHD_ERROR(("%s: Failed to set Scan Passive Time %d, error = %d\n",
1593 __FUNCTION__
, time
, error
));
1600 int wl_android_get_scan_home_time(struct net_device
*dev
, char *command
, int total_len
)
1603 int bytes_written
= 0;
1606 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_HOME_TIME
, &time
, sizeof(time
));
1608 DHD_ERROR(("Failed to get Scan Home Time, error = %d\n", error
));
1612 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANHOMETIME
, time
);
1614 return bytes_written
;
1617 int wl_android_set_scan_home_time(struct net_device
*dev
, char *command
)
1622 if (sscanf(command
, "%*s %d", &time
) != 1) {
1623 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1626 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1627 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_HOME_TIME
, time
);
1628 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_HOME_TIME
, &time
, sizeof(time
));
1629 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1631 DHD_ERROR(("%s: Failed to set Scan Home Time %d, error = %d\n",
1632 __FUNCTION__
, time
, error
));
1639 int wl_android_get_scan_home_away_time(struct net_device
*dev
, char *command
, int total_len
)
1642 int bytes_written
= 0;
1645 error
= wldev_iovar_getint(dev
, "scan_home_away_time", &time
);
1647 DHD_ERROR(("%s: Failed to get Scan Home Away Time, error = %d\n",
1648 __FUNCTION__
, error
));
1652 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANHOMEAWAYTIME
, time
);
1654 return bytes_written
;
1657 int wl_android_set_scan_home_away_time(struct net_device
*dev
, char *command
)
1662 if (sscanf(command
, "%*s %d", &time
) != 1) {
1663 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1666 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1667 wl_cfg80211_custom_scan_time(dev
, WL_CUSTOM_SCAN_HOME_AWAY_TIME
, time
);
1668 error
= wldev_iovar_setint(dev
, "scan_home_away_time", time
);
1669 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1671 DHD_ERROR(("%s: Failed to set Scan Home Away Time %d, error = %d\n",
1672 __FUNCTION__
, time
, error
));
1679 int wl_android_get_scan_nprobes(struct net_device
*dev
, char *command
, int total_len
)
1682 int bytes_written
= 0;
1685 error
= wldev_ioctl_get(dev
, WLC_GET_SCAN_NPROBES
, &num
, sizeof(num
));
1687 DHD_ERROR(("%s: Failed to get Scan NProbes, error = %d\n", __FUNCTION__
, error
));
1691 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETSCANNPROBES
, num
);
1693 return bytes_written
;
1696 int wl_android_set_scan_nprobes(struct net_device
*dev
, char *command
)
1701 if (sscanf(command
, "%*s %d", &num
) != 1) {
1702 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1706 error
= wldev_ioctl_set(dev
, WLC_SET_SCAN_NPROBES
, &num
, sizeof(num
));
1708 DHD_ERROR(("%s: Failed to set Scan NProbes %d, error = %d\n",
1709 __FUNCTION__
, num
, error
));
1716 int wl_android_get_scan_dfs_channel_mode(struct net_device
*dev
, char *command
, int total_len
)
1719 int bytes_written
= 0;
1721 int scan_passive_time
= 0;
1723 error
= wldev_iovar_getint(dev
, "scan_passive_time", &scan_passive_time
);
1725 DHD_ERROR(("%s: Failed to get Passive Time, error = %d\n", __FUNCTION__
, error
));
1729 if (scan_passive_time
== 0) {
1735 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETDFSSCANMODE
, mode
);
1737 return bytes_written
;
1740 int wl_android_set_scan_dfs_channel_mode(struct net_device
*dev
, char *command
)
1744 int scan_passive_time
= 0;
1746 if (sscanf(command
, "%*s %d", &mode
) != 1) {
1747 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1752 scan_passive_time
= DHD_SCAN_PASSIVE_TIME
;
1753 } else if (mode
== 0) {
1754 scan_passive_time
= 0;
1756 DHD_ERROR(("%s: Failed to set Scan DFS channel mode %d, error = %d\n",
1757 __FUNCTION__
, mode
, error
));
1760 error
= wldev_iovar_setint(dev
, "scan_passive_time", scan_passive_time
);
1762 DHD_ERROR(("%s: Failed to set Scan Passive Time %d, error = %d\n",
1763 __FUNCTION__
, scan_passive_time
, error
));
1770 #define JOINPREFFER_BUF_SIZE 12
1773 wl_android_set_join_prefer(struct net_device
*dev
, char *command
)
1775 int error
= BCME_OK
;
1776 char smbuf
[WLC_IOCTL_SMLEN
];
1777 uint8 buf
[JOINPREFFER_BUF_SIZE
];
1783 char commandp
[WLC_IOCTL_SMLEN
];
1784 char clear
[] = { 0x01, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00 };
1787 pcmd
= command
+ strlen(CMD_SETJOINPREFER
) + 1;
1788 total_len_left
= strlen(pcmd
);
1790 memset(buf
, 0, sizeof(buf
));
1792 if (total_len_left
!= JOINPREFFER_BUF_SIZE
<< 1) {
1793 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
1797 /* Store the MSB first, as required by join_pref */
1798 for (i
= 0; i
< JOINPREFFER_BUF_SIZE
; i
++) {
1801 buf
[i
] = (uint8
)simple_strtoul(hex
, NULL
, 16);
1805 /* No coexistance between 11kv and join pref */
1806 if (wl_android_check_wbtext(dev
)) {
1807 memset(commandp
, 0, sizeof(commandp
));
1808 if (memcmp(buf
, clear
, sizeof(buf
)) == 0) {
1809 snprintf(commandp
, WLC_IOCTL_SMLEN
, "WBTEXT_ENABLE 1");
1811 snprintf(commandp
, WLC_IOCTL_SMLEN
, "WBTEXT_ENABLE 0");
1813 if ((error
= wl_android_wbtext(dev
, commandp
, WLC_IOCTL_SMLEN
)) != BCME_OK
) {
1814 DHD_ERROR(("Failed to set WBTEXT = %d\n", error
));
1820 prhex("join pref", (uint8
*)buf
, JOINPREFFER_BUF_SIZE
);
1821 error
= wldev_iovar_setbuf(dev
, "join_pref", buf
, JOINPREFFER_BUF_SIZE
,
1822 smbuf
, sizeof(smbuf
), NULL
);
1824 DHD_ERROR(("Failed to set join_pref, error = %d\n", error
));
1830 int wl_android_send_action_frame(struct net_device
*dev
, char *command
, int total_len
)
1833 android_wifi_af_params_t
*params
= NULL
;
1834 wl_action_frame_t
*action_frame
= NULL
;
1835 wl_af_params_t
*af_params
= NULL
;
1837 struct ether_addr tmp_bssid
;
1838 int tmp_channel
= 0;
1839 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
1842 (strlen(CMD_SENDACTIONFRAME
) + 1 + sizeof(android_wifi_af_params_t
))) {
1843 DHD_ERROR(("%s: Invalid parameters \n", __FUNCTION__
));
1844 goto send_action_frame_out
;
1847 params
= (android_wifi_af_params_t
*)(command
+ strlen(CMD_SENDACTIONFRAME
) + 1);
1849 if ((uint16
)params
->len
> ANDROID_WIFI_ACTION_FRAME_SIZE
) {
1850 DHD_ERROR(("%s: Requested action frame len was out of range(%d)\n",
1851 __FUNCTION__
, params
->len
));
1852 goto send_action_frame_out
;
1855 smbuf
= (char *)MALLOC(cfg
->osh
, WLC_IOCTL_MAXLEN
);
1856 if (smbuf
== NULL
) {
1857 DHD_ERROR(("%s: failed to allocated memory %d bytes\n",
1858 __FUNCTION__
, WLC_IOCTL_MAXLEN
));
1859 goto send_action_frame_out
;
1862 af_params
= (wl_af_params_t
*)MALLOCZ(cfg
->osh
, WL_WIFI_AF_PARAMS_SIZE
);
1863 if (af_params
== NULL
) {
1864 DHD_ERROR(("%s: unable to allocate frame\n", __FUNCTION__
));
1865 goto send_action_frame_out
;
1868 memset(&tmp_bssid
, 0, ETHER_ADDR_LEN
);
1869 if (bcm_ether_atoe((const char *)params
->bssid
, (struct ether_addr
*)&tmp_bssid
) == 0) {
1870 memset(&tmp_bssid
, 0, ETHER_ADDR_LEN
);
1872 error
= wldev_ioctl_get(dev
, WLC_GET_BSSID
, &tmp_bssid
, ETHER_ADDR_LEN
);
1874 memset(&tmp_bssid
, 0, ETHER_ADDR_LEN
);
1875 DHD_ERROR(("%s: failed to get bssid, error=%d\n", __FUNCTION__
, error
));
1876 goto send_action_frame_out
;
1880 if (params
->channel
< 0) {
1881 struct channel_info ci
;
1882 memset(&ci
, 0, sizeof(ci
));
1883 error
= wldev_ioctl_get(dev
, WLC_GET_CHANNEL
, &ci
, sizeof(ci
));
1885 DHD_ERROR(("%s: failed to get channel, error=%d\n", __FUNCTION__
, error
));
1886 goto send_action_frame_out
;
1889 tmp_channel
= ci
.hw_channel
;
1892 tmp_channel
= params
->channel
;
1895 af_params
->channel
= tmp_channel
;
1896 af_params
->dwell_time
= params
->dwell_time
;
1897 memcpy(&af_params
->BSSID
, &tmp_bssid
, ETHER_ADDR_LEN
);
1898 action_frame
= &af_params
->action_frame
;
1900 action_frame
->packetId
= 0;
1901 memcpy(&action_frame
->da
, &tmp_bssid
, ETHER_ADDR_LEN
);
1902 action_frame
->len
= (uint16
)params
->len
;
1903 memcpy(action_frame
->data
, params
->data
, action_frame
->len
);
1905 error
= wldev_iovar_setbuf(dev
, "actframe", af_params
,
1906 sizeof(wl_af_params_t
), smbuf
, WLC_IOCTL_MAXLEN
, NULL
);
1908 DHD_ERROR(("%s: failed to set action frame, error=%d\n", __FUNCTION__
, error
));
1911 send_action_frame_out
:
1913 MFREE(cfg
->osh
, af_params
, WL_WIFI_AF_PARAMS_SIZE
);
1917 MFREE(cfg
->osh
, smbuf
, WLC_IOCTL_MAXLEN
);
1926 int wl_android_reassoc(struct net_device
*dev
, char *command
, int total_len
)
1929 android_wifi_reassoc_params_t
*params
= NULL
;
1933 wl_reassoc_params_t reassoc_params
;
1936 (strlen(CMD_REASSOC
) + 1 + sizeof(android_wifi_reassoc_params_t
))) {
1937 DHD_ERROR(("%s: Invalid parameters \n", __FUNCTION__
));
1940 params
= (android_wifi_reassoc_params_t
*)(command
+ strlen(CMD_REASSOC
) + 1);
1942 memset(&reassoc_params
, 0, WL_REASSOC_PARAMS_FIXED_SIZE
);
1944 if (bcm_ether_atoe((const char *)params
->bssid
,
1945 (struct ether_addr
*)&reassoc_params
.bssid
) == 0) {
1946 DHD_ERROR(("%s: Invalid bssid \n", __FUNCTION__
));
1950 if (params
->channel
< 0) {
1951 DHD_ERROR(("%s: Invalid Channel \n", __FUNCTION__
));
1955 reassoc_params
.chanspec_num
= 1;
1957 channel
= params
->channel
;
1958 #ifdef D11AC_IOTYPES
1959 if (wl_cfg80211_get_ioctl_version() == 1) {
1960 band
= ((channel
<= CH_MAX_2G_CHANNEL
) ?
1961 WL_LCHANSPEC_BAND_2G
: WL_LCHANSPEC_BAND_5G
);
1962 reassoc_params
.chanspec_list
[0] = channel
|
1963 band
| WL_LCHANSPEC_BW_20
| WL_LCHANSPEC_CTL_SB_NONE
;
1966 band
= ((channel
<= CH_MAX_2G_CHANNEL
) ? WL_CHANSPEC_BAND_2G
: WL_CHANSPEC_BAND_5G
);
1967 reassoc_params
.chanspec_list
[0] = channel
| band
| WL_CHANSPEC_BW_20
;
1970 band
= ((channel
<= CH_MAX_2G_CHANNEL
) ? WL_CHANSPEC_BAND_2G
: WL_CHANSPEC_BAND_5G
);
1971 reassoc_params
.chanspec_list
[0] = channel
|
1972 band
| WL_CHANSPEC_BW_20
| WL_CHANSPEC_CTL_SB_NONE
;
1973 #endif /* D11AC_IOTYPES */
1974 params_size
= WL_REASSOC_PARAMS_FIXED_SIZE
+ sizeof(chanspec_t
);
1976 error
= wldev_ioctl_set(dev
, WLC_REASSOC
, &reassoc_params
, params_size
);
1978 DHD_ERROR(("%s: failed to reassoc, error=%d\n", __FUNCTION__
, error
));
1984 int wl_android_get_wes_mode(struct net_device
*dev
, char *command
, int total_len
)
1986 int bytes_written
= 0;
1989 mode
= wl_cfg80211_get_wes_mode();
1991 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETWESMODE
, mode
);
1993 return bytes_written
;
1996 int wl_android_set_wes_mode(struct net_device
*dev
, char *command
)
2001 char commandp
[WLC_IOCTL_SMLEN
];
2004 if (sscanf(command
, "%*s %d", &mode
) != 1) {
2005 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
2009 error
= wl_cfg80211_set_wes_mode(mode
);
2011 DHD_ERROR(("%s: Failed to set WES Mode %d, error = %d\n",
2012 __FUNCTION__
, mode
, error
));
2017 /* No coexistance between 11kv and FMC */
2018 if (wl_android_check_wbtext(dev
)) {
2019 memset(commandp
, 0, sizeof(commandp
));
2021 snprintf(commandp
, WLC_IOCTL_SMLEN
, "WBTEXT_ENABLE 1");
2023 snprintf(commandp
, WLC_IOCTL_SMLEN
, "WBTEXT_ENABLE 0");
2025 if ((error
= wl_android_wbtext(dev
, commandp
, WLC_IOCTL_SMLEN
)) != BCME_OK
) {
2026 DHD_ERROR(("Failed to set WBTEXT = %d\n", error
));
2035 int wl_android_get_okc_mode(struct net_device
*dev
, char *command
, int total_len
)
2038 int bytes_written
= 0;
2041 error
= wldev_iovar_getint(dev
, "okc_enable", &mode
);
2043 DHD_ERROR(("%s: Failed to get OKC Mode, error = %d\n", __FUNCTION__
, error
));
2047 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GETOKCMODE
, mode
);
2049 return bytes_written
;
2052 int wl_android_set_okc_mode(struct net_device
*dev
, char *command
)
2057 if (sscanf(command
, "%*s %d", &mode
) != 1) {
2058 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
2062 error
= wldev_iovar_setint(dev
, "okc_enable", mode
);
2064 DHD_ERROR(("%s: Failed to set OKC Mode %d, error = %d\n",
2065 __FUNCTION__
, mode
, error
));
2072 wl_android_set_pmk(struct net_device
*dev
, char *command
, int total_len
)
2076 char smbuf
[WLC_IOCTL_SMLEN
];
2081 if (total_len
< (strlen("SET_PMK ") + 32)) {
2082 DHD_ERROR(("%s: Invalid argument\n", __FUNCTION__
));
2085 bzero(pmk
, sizeof(pmk
));
2086 memcpy((char *)pmk
, command
+ strlen("SET_PMK "), 32);
2087 error
= wldev_iovar_setbuf(dev
, "okc_info_pmk", pmk
, 32, smbuf
, sizeof(smbuf
), NULL
);
2089 DHD_ERROR(("Failed to set PMK for OKC, error = %d\n", error
));
2092 DHD_ERROR(("PMK is "));
2093 for (i
= 0; i
< 32; i
++)
2094 DHD_ERROR(("%02X ", pmk
[i
]));
2102 wl_android_okc_enable(struct net_device
*dev
, char *command
)
2105 char okc_enable
= 0;
2107 okc_enable
= command
[strlen(CMD_OKC_ENABLE
) + 1] - '0';
2108 error
= wldev_iovar_setint(dev
, "okc_enable", okc_enable
);
2110 DHD_ERROR(("Failed to %s OKC, error = %d\n",
2111 okc_enable
? "enable" : "disable", error
));
2116 #endif /* WES_SUPPORT */
2118 int wl_android_tdls_reset(struct net_device
*dev
)
2121 ret
= dhd_tdls_enable(dev
, false, false, NULL
);
2123 DHD_ERROR(("Disable tdls failed. %d\n", ret
));
2126 ret
= dhd_tdls_enable(dev
, true, true, NULL
);
2128 DHD_ERROR(("enable tdls failed. %d\n", ret
));
2134 #ifdef FCC_PWR_LIMIT_2G
2136 wl_android_set_fcc_pwr_limit_2g(struct net_device
*dev
, char *command
)
2141 sscanf(command
+sizeof("SET_FCC_CHANNEL"), "%d", &enable
);
2143 if ((enable
!= CUSTOMER_HW4_ENABLE
) && (enable
!= CUSTOMER_HW4_DISABLE
)) {
2144 DHD_ERROR(("%s: Invalid data\n", __FUNCTION__
));
2148 CUSTOMER_HW4_EN_CONVERT(enable
);
2150 DHD_ERROR(("%s: fccpwrlimit2g set (%d)\n", __FUNCTION__
, enable
));
2151 error
= wldev_iovar_setint(dev
, "fccpwrlimit2g", enable
);
2153 DHD_ERROR(("%s: fccpwrlimit2g set returned (%d)\n", __FUNCTION__
, error
));
2161 wl_android_get_fcc_pwr_limit_2g(struct net_device
*dev
, char *command
, int total_len
)
2165 int bytes_written
= 0;
2167 error
= wldev_iovar_getint(dev
, "fccpwrlimit2g", &enable
);
2169 DHD_ERROR(("%s: fccpwrlimit2g get error (%d)\n", __FUNCTION__
, error
));
2172 DHD_ERROR(("%s: fccpwrlimit2g get (%d)\n", __FUNCTION__
, enable
));
2174 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_FCC_PWR_LIMIT_2G
, enable
);
2176 return bytes_written
;
2178 #endif /* FCC_PWR_LIMIT_2G */
2181 wl_cfg80211_get_sta_info(struct net_device
*dev
, char* command
, int total_len
)
2183 int bytes_written
= -1, ret
= 0;
2184 char *pcmd
= command
;
2186 sta_info_v4_t
*sta
= NULL
;
2187 const wl_cnt_wlc_t
* wlc_cnt
= NULL
;
2188 struct ether_addr mac
;
2190 /* Client information */
2194 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
2196 #ifdef BIGDATA_SOFTAP
2198 int get_bigdata_softap
= FALSE
;
2199 wl_ap_sta_data_t
*sta_data
= NULL
;
2200 struct bcm_cfg80211
*bcm_cfg
= wl_get_cfg(dev
);
2201 #endif /* BIGDATA_SOFTAP */
2203 WL_DBG(("%s\n", command
));
2205 iovar_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MAXLEN
);
2206 if (iovar_buf
== NULL
) {
2207 DHD_ERROR(("%s: failed to allocated memory %d bytes\n",
2208 __FUNCTION__
, WLC_IOCTL_MAXLEN
));
2212 str
= bcmstrtok(&pcmd
, " ", NULL
);
2214 str
= bcmstrtok(&pcmd
, " ", NULL
);
2215 /* If GETSTAINFO subcmd name is not provided, return error */
2217 WL_ERR(("GETSTAINFO subcmd not provided %s\n", __FUNCTION__
));
2221 memset(&mac
, 0, ETHER_ADDR_LEN
);
2222 if ((bcm_ether_atoe((str
), &mac
))) {
2223 /* get the sta info */
2224 ret
= wldev_iovar_getbuf(dev
, "sta_info",
2225 (struct ether_addr
*)mac
.octet
,
2226 ETHER_ADDR_LEN
, iovar_buf
, WLC_IOCTL_SMLEN
, NULL
);
2227 #ifdef BIGDATA_SOFTAP
2228 get_bigdata_softap
= TRUE
;
2229 #endif /* BIGDATA_SOFTAP */
2231 WL_ERR(("Get sta_info ERR %d\n", ret
));
2232 #ifndef BIGDATA_SOFTAP
2236 #endif /* BIGDATA_SOFTAP */
2239 sta
= (sta_info_v4_t
*)iovar_buf
;
2240 if (dtoh16(sta
->ver
) != WL_STA_VER_4
) {
2241 WL_ERR(("sta_info struct version mismatch, "
2242 "host ver : %d, fw ver : %d\n", WL_STA_VER_4
,
2246 cap
= dtoh16(sta
->cap
);
2247 rxrtry
= dtoh32(sta
->rx_pkts_retried
);
2248 rxmulti
= dtoh32(sta
->rx_mcast_pkts
);
2249 } else if ((!strncmp(str
, "all", 3)) || (!strncmp(str
, "ALL", 3))) {
2250 /* get counters info */
2251 ret
= wldev_iovar_getbuf(dev
, "counters", NULL
, 0,
2252 iovar_buf
, WLC_IOCTL_MAXLEN
, NULL
);
2253 if (unlikely(ret
)) {
2254 WL_ERR(("counters error (%d) - size = %zu\n",
2255 ret
, sizeof(wl_cnt_wlc_t
)));
2258 ret
= wl_cntbuf_to_xtlv_format(NULL
, iovar_buf
, WL_CNTBUF_MAX_SIZE
, 0);
2259 if (ret
!= BCME_OK
) {
2260 WL_ERR(("wl_cntbuf_to_xtlv_format ERR %d\n", ret
));
2263 if (!(wlc_cnt
= GET_WLCCNT_FROM_CNTBUF(iovar_buf
))) {
2264 WL_ERR(("wlc_cnt NULL!\n"));
2268 rxrtry
= dtoh32(wlc_cnt
->rxrtry
);
2269 rxmulti
= dtoh32(wlc_cnt
->rxmulti
);
2271 WL_ERR(("Get address fail\n"));
2275 WL_ERR(("Command ERR\n"));
2279 #ifdef BIGDATA_SOFTAP
2281 if (get_bigdata_softap
) {
2282 WL_ERR(("mac " MACDBG
" \n", MAC2STRDBG((char*)&mac
)));
2283 if (wl_get_ap_stadata(bcm_cfg
, &mac
, &data
) == BCME_OK
) {
2284 sta_data
= (wl_ap_sta_data_t
*)data
;
2285 bytes_written
= snprintf(command
, total_len
,
2286 "%s %s Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d "
2287 "CAP=%04x "MACOUI
" %d %s %d %d %d %d %d %d\n",
2288 CMD_GET_STA_INFO
, str
, rxrtry
, rxmulti
, cap
,
2289 MACOUI2STR((char*)&sta_data
->mac
),
2291 wf_chspec_to_bw_str(sta_data
->chanspec
),
2292 sta_data
->rssi
, sta_data
->rate
,
2293 sta_data
->mode_80211
, sta_data
->nss
, sta_data
->mimo
,
2294 sta_data
->reason_code
);
2295 WL_ERR_KERN(("command %s\n", command
));
2299 #endif /* BIGDATA_SOFTAP */
2300 bytes_written
= snprintf(command
, total_len
,
2301 "%s %s Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d CAP=%04x\n",
2302 CMD_GET_STA_INFO
, str
, rxrtry
, rxmulti
, cap
);
2304 WL_DBG(("%s", command
));
2308 MFREE(cfg
->osh
, iovar_buf
, WLC_IOCTL_MAXLEN
);
2311 return bytes_written
;
2313 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
2316 static int wl_android_wbtext(struct net_device
*dev
, char *command
, int total_len
)
2318 int error
= BCME_OK
, argc
= 0;
2319 int data
, bytes_written
;
2320 int roam_trigger
[2];
2321 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
2323 argc
= sscanf(command
+sizeof(CMD_WBTEXT_ENABLE
), "%d", &data
);
2325 error
= wldev_iovar_getint(dev
, "wnm_bsstrans_resp", &data
);
2327 DHD_ERROR(("%s: Failed to set wbtext error = %d\n",
2328 __FUNCTION__
, error
));
2331 bytes_written
= snprintf(command
, total_len
, "WBTEXT %s\n",
2332 (data
== WL_BSSTRANS_POLICY_PRODUCT_WBTEXT
)?
2333 "ENABLED" : "DISABLED");
2334 return bytes_written
;
2337 data
= WL_BSSTRANS_POLICY_PRODUCT_WBTEXT
;
2340 if ((error
= wldev_iovar_setint(dev
, "wnm_bsstrans_resp", data
)) != BCME_OK
) {
2341 DHD_ERROR(("%s: Failed to set wbtext error = %d\n",
2342 __FUNCTION__
, error
));
2347 /* reset roam_prof when wbtext is on */
2348 if ((error
= wl_cfg80211_wbtext_set_default(dev
)) != BCME_OK
) {
2351 dhdp
->wbtext_support
= TRUE
;
2353 /* reset legacy roam trigger when wbtext is off */
2354 roam_trigger
[0] = DEFAULT_ROAM_TRIGGER_VALUE
;
2355 roam_trigger
[1] = WLC_BAND_ALL
;
2356 if ((error
= wldev_ioctl_set(dev
, WLC_SET_ROAM_TRIGGER
, roam_trigger
,
2357 sizeof(roam_trigger
))) != BCME_OK
) {
2358 DHD_ERROR(("%s: Failed to reset roam trigger = %d\n",
2359 __FUNCTION__
, error
));
2362 dhdp
->wbtext_support
= FALSE
;
2368 static int wl_cfg80211_wbtext_btm_timer_threshold(struct net_device
*dev
,
2369 char *command
, int total_len
)
2371 int error
= BCME_OK
, argc
= 0;
2372 int data
, bytes_written
;
2374 argc
= sscanf(command
, CMD_WBTEXT_BTM_TIMER_THRESHOLD
" %d\n", &data
);
2376 error
= wldev_iovar_getint(dev
, "wnm_bsstrans_timer_threshold", &data
);
2378 WL_ERR(("Failed to get wnm_bsstrans_timer_threshold (%d)\n", error
));
2381 bytes_written
= snprintf(command
, total_len
, "%d\n", data
);
2382 return bytes_written
;
2384 if ((error
= wldev_iovar_setint(dev
, "wnm_bsstrans_timer_threshold",
2385 data
)) != BCME_OK
) {
2386 WL_ERR(("Failed to set wnm_bsstrans_timer_threshold (%d)\n", error
));
2393 static int wl_cfg80211_wbtext_btm_delta(struct net_device
*dev
,
2394 char *command
, int total_len
)
2396 int error
= BCME_OK
, argc
= 0;
2397 int data
= 0, bytes_written
;
2399 argc
= sscanf(command
, CMD_WBTEXT_BTM_DELTA
" %d\n", &data
);
2401 error
= wldev_iovar_getint(dev
, "wnm_btmdelta", &data
);
2403 WL_ERR(("Failed to get wnm_btmdelta (%d)\n", error
));
2406 bytes_written
= snprintf(command
, total_len
, "%d\n", data
);
2407 return bytes_written
;
2409 if ((error
= wldev_iovar_setint(dev
, "wnm_btmdelta",
2410 data
)) != BCME_OK
) {
2411 WL_ERR(("Failed to set wnm_btmdelta (%d)\n", error
));
2421 #define PNO_PARAM_SIZE 50
2422 #define VALUE_SIZE 50
2423 #define LIMIT_STR_FMT ("%50s %50s")
2425 wls_parse_batching_cmd(struct net_device
*dev
, char *command
, int total_len
)
2428 uint i
, tokens
, len_remain
;
2429 char *pos
, *pos2
, *token
, *token2
, *delim
;
2430 char param
[PNO_PARAM_SIZE
+1], value
[VALUE_SIZE
+1];
2431 struct dhd_pno_batch_params batch_params
;
2433 DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__
, command
, total_len
));
2434 len_remain
= total_len
;
2435 if (len_remain
> (strlen(CMD_WLS_BATCHING
) + 1)) {
2436 pos
= command
+ strlen(CMD_WLS_BATCHING
) + 1;
2437 len_remain
-= strlen(CMD_WLS_BATCHING
) + 1;
2439 WL_ERR(("%s: No arguments, total_len %d\n", __FUNCTION__
, total_len
));
2443 memset(&batch_params
, 0, sizeof(struct dhd_pno_batch_params
));
2444 if (!strncmp(pos
, PNO_BATCHING_SET
, strlen(PNO_BATCHING_SET
))) {
2445 if (len_remain
> (strlen(PNO_BATCHING_SET
) + 1)) {
2446 pos
+= strlen(PNO_BATCHING_SET
) + 1;
2448 WL_ERR(("%s: %s missing arguments, total_len %d\n",
2449 __FUNCTION__
, PNO_BATCHING_SET
, total_len
));
2453 while ((token
= strsep(&pos
, PNO_PARAMS_DELIMETER
)) != NULL
) {
2454 memset(param
, 0, sizeof(param
));
2455 memset(value
, 0, sizeof(value
));
2456 if (token
== NULL
|| !*token
)
2460 delim
= strchr(token
, PNO_PARAM_VALUE_DELLIMETER
);
2464 tokens
= sscanf(token
, LIMIT_STR_FMT
, param
, value
);
2465 if (!strncmp(param
, PNO_PARAM_SCANFREQ
, strlen(PNO_PARAM_SCANFREQ
))) {
2466 batch_params
.scan_fr
= simple_strtol(value
, NULL
, 0);
2467 DHD_PNO(("scan_freq : %d\n", batch_params
.scan_fr
));
2468 } else if (!strncmp(param
, PNO_PARAM_BESTN
, strlen(PNO_PARAM_BESTN
))) {
2469 batch_params
.bestn
= simple_strtol(value
, NULL
, 0);
2470 DHD_PNO(("bestn : %d\n", batch_params
.bestn
));
2471 } else if (!strncmp(param
, PNO_PARAM_MSCAN
, strlen(PNO_PARAM_MSCAN
))) {
2472 batch_params
.mscan
= simple_strtol(value
, NULL
, 0);
2473 DHD_PNO(("mscan : %d\n", batch_params
.mscan
));
2474 } else if (!strncmp(param
, PNO_PARAM_CHANNEL
, strlen(PNO_PARAM_CHANNEL
))) {
2477 tokens
= sscanf(value
, "<%s>", value
);
2480 DHD_ERROR(("%s : invalid format for channel"
2481 " <> params\n", __FUNCTION__
));
2484 while ((token2
= strsep(&pos2
,
2485 PNO_PARAM_CHANNEL_DELIMETER
)) != NULL
) {
2486 if (token2
== NULL
|| !*token2
)
2488 if (*token2
== '\0')
2490 if (*token2
== 'A' || *token2
== 'B') {
2491 batch_params
.band
= (*token2
== 'A')?
2492 WLC_BAND_5G
: WLC_BAND_2G
;
2493 DHD_PNO(("band : %s\n",
2494 (*token2
== 'A')? "A" : "B"));
2496 if ((batch_params
.nchan
>= WL_NUMCHANNELS
) ||
2497 (i
>= WL_NUMCHANNELS
)) {
2498 DHD_ERROR(("Too many nchan %d\n",
2499 batch_params
.nchan
));
2500 err
= BCME_BUFTOOSHORT
;
2503 batch_params
.chan_list
[i
++] =
2504 simple_strtol(token2
, NULL
, 0);
2505 batch_params
.nchan
++;
2506 DHD_PNO(("channel :%d\n",
2507 batch_params
.chan_list
[i
-1]));
2510 } else if (!strncmp(param
, PNO_PARAM_RTT
, strlen(PNO_PARAM_RTT
))) {
2511 batch_params
.rtt
= simple_strtol(value
, NULL
, 0);
2512 DHD_PNO(("rtt : %d\n", batch_params
.rtt
));
2514 DHD_ERROR(("%s : unknown param: %s\n", __FUNCTION__
, param
));
2519 err
= dhd_dev_pno_set_for_batch(dev
, &batch_params
);
2521 DHD_ERROR(("failed to configure batch scan\n"));
2523 memset(command
, 0, total_len
);
2524 err
= snprintf(command
, total_len
, "%d", err
);
2526 } else if (!strncmp(pos
, PNO_BATCHING_GET
, strlen(PNO_BATCHING_GET
))) {
2527 err
= dhd_dev_pno_get_for_batch(dev
, command
, total_len
);
2529 DHD_ERROR(("failed to getting batching results\n"));
2531 err
= strlen(command
);
2533 } else if (!strncmp(pos
, PNO_BATCHING_STOP
, strlen(PNO_BATCHING_STOP
))) {
2534 err
= dhd_dev_pno_stop_for_batch(dev
);
2536 DHD_ERROR(("failed to stop batching scan\n"));
2538 memset(command
, 0, total_len
);
2539 err
= snprintf(command
, total_len
, "OK");
2542 DHD_ERROR(("%s : unknown command\n", __FUNCTION__
));
2549 #ifndef WL_SCHED_SCAN
2550 static int wl_android_set_pno_setup(struct net_device
*dev
, char *command
, int total_len
)
2552 wlc_ssid_ext_t ssids_local
[MAX_PFN_LIST_COUNT
];
2555 cmd_tlv_t
*cmd_tlv_temp
;
2560 int pno_freq_expo_max
= 0;
2562 #ifdef PNO_SET_DEBUG
2564 char pno_in_example
[] = {
2565 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
2569 'd', 'l', 'i', 'n', 'k',
2581 #endif /* PNO_SET_DEBUG */
2582 DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__
, command
, total_len
));
2584 if (total_len
< (strlen(CMD_PNOSETUP_SET
) + sizeof(cmd_tlv_t
))) {
2585 DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__
, total_len
));
2588 #ifdef PNO_SET_DEBUG
2589 memcpy(command
, pno_in_example
, sizeof(pno_in_example
));
2590 total_len
= sizeof(pno_in_example
);
2592 str_ptr
= command
+ strlen(CMD_PNOSETUP_SET
);
2593 tlv_size_left
= total_len
- strlen(CMD_PNOSETUP_SET
);
2595 cmd_tlv_temp
= (cmd_tlv_t
*)str_ptr
;
2596 memset(ssids_local
, 0, sizeof(ssids_local
));
2598 if ((cmd_tlv_temp
->prefix
== PNO_TLV_PREFIX
) &&
2599 (cmd_tlv_temp
->version
== PNO_TLV_VERSION
) &&
2600 (cmd_tlv_temp
->subtype
== PNO_TLV_SUBTYPE_LEGACY_PNO
)) {
2602 str_ptr
+= sizeof(cmd_tlv_t
);
2603 tlv_size_left
-= sizeof(cmd_tlv_t
);
2605 if ((nssid
= wl_parse_ssid_list_tlv(&str_ptr
, ssids_local
,
2606 MAX_PFN_LIST_COUNT
, &tlv_size_left
)) <= 0) {
2607 DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid
));
2610 if ((str_ptr
[0] != PNO_TLV_TYPE_TIME
) || (tlv_size_left
<= 1)) {
2611 DHD_ERROR(("%s scan duration corrupted field size %d\n",
2612 __FUNCTION__
, tlv_size_left
));
2616 pno_time
= simple_strtoul(str_ptr
, &str_ptr
, 16);
2617 DHD_PNO(("%s: pno_time=%d\n", __FUNCTION__
, pno_time
));
2619 if (str_ptr
[0] != 0) {
2620 if ((str_ptr
[0] != PNO_TLV_FREQ_REPEAT
)) {
2621 DHD_ERROR(("%s pno repeat : corrupted field\n",
2626 pno_repeat
= simple_strtoul(str_ptr
, &str_ptr
, 16);
2627 DHD_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__
, pno_repeat
));
2628 if (str_ptr
[0] != PNO_TLV_FREQ_EXPO_MAX
) {
2629 DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n",
2634 pno_freq_expo_max
= simple_strtoul(str_ptr
, &str_ptr
, 16);
2635 DHD_PNO(("%s: pno_freq_expo_max=%d\n",
2636 __FUNCTION__
, pno_freq_expo_max
));
2640 DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__
));
2644 res
= dhd_dev_pno_set_for_ssid(dev
, ssids_local
, nssid
, pno_time
, pno_repeat
,
2645 pno_freq_expo_max
, NULL
, 0);
2649 #endif /* !WL_SCHED_SCAN */
2650 #endif /* PNO_SUPPORT */
2652 static int wl_android_get_p2p_dev_addr(struct net_device
*ndev
, char *command
, int total_len
)
2655 struct ether_addr p2pdev_addr
;
2657 #define MAC_ADDR_STR_LEN 18
2658 if (total_len
< MAC_ADDR_STR_LEN
) {
2659 DHD_ERROR(("%s: buflen %d is less than p2p dev addr\n",
2660 __FUNCTION__
, total_len
));
2664 ret
= wl_cfg80211_get_p2p_dev_addr(ndev
, &p2pdev_addr
);
2666 DHD_ERROR(("%s Failed to get p2p dev addr\n", __FUNCTION__
));
2669 return (snprintf(command
, total_len
, MACF
, ETHERP_TO_MACF(&p2pdev_addr
)));
2673 static int wl_android_get_cckm_rn(struct net_device
*dev
, char *command
)
2677 WL_TRACE(("%s:wl_android_get_cckm_rn\n", dev
->name
));
2679 error
= wldev_iovar_getint(dev
, "cckm_rn", &rn
);
2680 if (unlikely(error
)) {
2681 WL_ERR(("wl_android_get_cckm_rn error (%d)\n", error
));
2684 memcpy(command
, &rn
, sizeof(int));
2690 wl_android_set_cckm_krk(struct net_device
*dev
, char *command
, int total_len
)
2692 int error
, key_len
, skip_len
;
2693 unsigned char key
[CCKM_KRK_LEN
+ CCKM_BTK_LEN
];
2694 char iovar_buf
[WLC_IOCTL_SMLEN
];
2696 WL_TRACE(("%s: wl_iw_set_cckm_krk\n", dev
->name
));
2698 skip_len
= strlen("set cckm_krk")+1;
2700 if (total_len
< (skip_len
+ CCKM_KRK_LEN
)) {
2704 if (total_len
>= skip_len
+ CCKM_KRK_LEN
+ CCKM_BTK_LEN
) {
2705 key_len
= CCKM_KRK_LEN
+ CCKM_BTK_LEN
;
2707 key_len
= CCKM_KRK_LEN
;
2710 memset(iovar_buf
, 0, sizeof(iovar_buf
));
2711 memcpy(key
, command
+skip_len
, key_len
);
2713 WL_DBG(("CCKM KRK-BTK (%d/%d) :\n", key_len
, total_len
));
2714 if (wl_dbg_level
& WL_DBG_DBG
) {
2715 prhex(NULL
, key
, key_len
);
2718 error
= wldev_iovar_setbuf(dev
, "cckm_krk", key
, key_len
,
2719 iovar_buf
, WLC_IOCTL_SMLEN
, NULL
);
2720 if (unlikely(error
)) {
2721 WL_ERR((" cckm_krk set error (%d)\n", error
));
2727 static int wl_android_get_assoc_res_ies(struct net_device
*dev
, char *command
, int total_len
)
2730 u8 buf
[WL_ASSOC_INFO_MAX
];
2731 wl_assoc_info_t assoc_info
;
2732 u32 resp_ies_len
= 0;
2733 int bytes_written
= 0;
2735 WL_TRACE(("%s: wl_iw_get_assoc_res_ies\n", dev
->name
));
2737 error
= wldev_iovar_getbuf(dev
, "assoc_info", NULL
, 0, buf
, WL_ASSOC_INFO_MAX
, NULL
);
2738 if (unlikely(error
)) {
2739 WL_ERR(("could not get assoc info (%d)\n", error
));
2743 memcpy(&assoc_info
, buf
, sizeof(wl_assoc_info_t
));
2744 assoc_info
.req_len
= htod32(assoc_info
.req_len
);
2745 assoc_info
.resp_len
= htod32(assoc_info
.resp_len
);
2746 assoc_info
.flags
= htod32(assoc_info
.flags
);
2748 if (assoc_info
.resp_len
) {
2749 resp_ies_len
= assoc_info
.resp_len
- sizeof(struct dot11_assoc_resp
);
2752 if (total_len
< (sizeof(u32
) + resp_ies_len
)) {
2753 WL_ERR(("%s: Insufficient memory, %d bytes\n",
2754 __FUNCTION__
, total_len
));
2757 /* first 4 bytes are ie len */
2758 memcpy(command
, &resp_ies_len
, sizeof(u32
));
2759 bytes_written
= sizeof(u32
);
2761 /* get the association resp IE's if there are any */
2763 error
= wldev_iovar_getbuf(dev
, "assoc_resp_ies", NULL
, 0,
2764 buf
, WL_ASSOC_INFO_MAX
, NULL
);
2765 if (unlikely(error
)) {
2766 WL_ERR(("could not get assoc resp_ies (%d)\n", error
));
2770 memcpy(command
+sizeof(u32
), buf
, resp_ies_len
);
2771 bytes_written
+= resp_ies_len
;
2773 return bytes_written
;
2779 wl_android_set_ap_mac_list(struct net_device
*dev
, int macmode
, struct maclist
*maclist
)
2783 char mac_buf
[MAX_NUM_OF_ASSOCLIST
*
2784 sizeof(struct ether_addr
) + sizeof(uint
)] = {0};
2785 struct maclist
*assoc_maclist
= (struct maclist
*)mac_buf
;
2787 /* set filtering mode */
2788 if ((ret
= wldev_ioctl_set(dev
, WLC_SET_MACMODE
, &macmode
, sizeof(macmode
)) != 0)) {
2789 DHD_ERROR(("%s : WLC_SET_MACMODE error=%d\n", __FUNCTION__
, ret
));
2792 if (macmode
!= MACLIST_MODE_DISABLED
) {
2793 /* set the MAC filter list */
2794 if ((ret
= wldev_ioctl_set(dev
, WLC_SET_MACLIST
, maclist
,
2795 sizeof(int) + sizeof(struct ether_addr
) * maclist
->count
)) != 0) {
2796 DHD_ERROR(("%s : WLC_SET_MACLIST error=%d\n", __FUNCTION__
, ret
));
2799 /* get the current list of associated STAs */
2800 assoc_maclist
->count
= MAX_NUM_OF_ASSOCLIST
;
2801 if ((ret
= wldev_ioctl_get(dev
, WLC_GET_ASSOCLIST
, assoc_maclist
,
2802 sizeof(mac_buf
))) != 0) {
2803 DHD_ERROR(("%s : WLC_GET_ASSOCLIST error=%d\n", __FUNCTION__
, ret
));
2806 /* do we have any STA associated? */
2807 if (assoc_maclist
->count
) {
2808 /* iterate each associated STA */
2809 for (i
= 0; i
< assoc_maclist
->count
; i
++) {
2811 /* compare with each entry */
2812 for (j
= 0; j
< maclist
->count
; j
++) {
2813 DHD_INFO(("%s : associated="MACDBG
" list="MACDBG
"\n",
2814 __FUNCTION__
, MAC2STRDBG(assoc_maclist
->ea
[i
].octet
),
2815 MAC2STRDBG(maclist
->ea
[j
].octet
)));
2816 if (memcmp(assoc_maclist
->ea
[i
].octet
,
2817 maclist
->ea
[j
].octet
, ETHER_ADDR_LEN
) == 0) {
2822 /* do conditional deauth */
2823 /* "if not in the allow list" or "if in the deny list" */
2824 if ((macmode
== MACLIST_MODE_ALLOW
&& !match
) ||
2825 (macmode
== MACLIST_MODE_DENY
&& match
)) {
2828 scbval
.val
= htod32(1);
2829 memcpy(&scbval
.ea
, &assoc_maclist
->ea
[i
],
2831 if ((ret
= wldev_ioctl_set(dev
,
2832 WLC_SCB_DEAUTHENTICATE_FOR_REASON
,
2833 &scbval
, sizeof(scb_val_t
))) != 0)
2834 DHD_ERROR(("%s WLC_SCB_DEAUTHENTICATE error=%d\n",
2835 __FUNCTION__
, ret
));
2844 * HAPD_MAC_FILTER mac_mode mac_cnt mac_addr1 mac_addr2
2848 wl_android_set_mac_address_filter(struct net_device
*dev
, char* str
)
2853 int macmode
= MACLIST_MODE_DISABLED
;
2854 struct maclist
*list
;
2855 char eabuf
[ETHER_ADDR_STR_LEN
];
2857 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
2859 /* string should look like below (macmode/macnum/maclist) */
2860 /* 1 2 00:11:22:33:44:55 00:11:22:33:44:ff */
2862 /* get the MAC filter mode */
2863 token
= strsep((char**)&str
, " ");
2867 macmode
= bcm_atoi(token
);
2869 if (macmode
< MACLIST_MODE_DISABLED
|| macmode
> MACLIST_MODE_ALLOW
) {
2870 DHD_ERROR(("%s : invalid macmode %d\n", __FUNCTION__
, macmode
));
2874 token
= strsep((char**)&str
, " ");
2878 macnum
= bcm_atoi(token
);
2879 if (macnum
< 0 || macnum
> MAX_NUM_MAC_FILT
) {
2880 DHD_ERROR(("%s : invalid number of MAC address entries %d\n",
2881 __FUNCTION__
, macnum
));
2884 /* allocate memory for the MAC list */
2885 list
= (struct maclist
*) MALLOCZ(cfg
->osh
, sizeof(int) +
2886 sizeof(struct ether_addr
) * macnum
);
2888 DHD_ERROR(("%s : failed to allocate memory\n", __FUNCTION__
));
2891 /* prepare the MAC list */
2892 list
->count
= htod32(macnum
);
2893 bzero((char *)eabuf
, ETHER_ADDR_STR_LEN
);
2894 for (i
= 0; i
< list
->count
; i
++) {
2895 token
= strsep((char**)&str
, " ");
2896 if (token
== NULL
) {
2897 DHD_ERROR(("%s : No mac address present\n", __FUNCTION__
));
2901 strncpy(eabuf
, token
, ETHER_ADDR_STR_LEN
- 1);
2902 if (!(ret
= bcm_ether_atoe(eabuf
, &list
->ea
[i
]))) {
2903 DHD_ERROR(("%s : mac parsing err index=%d, addr=%s\n",
2904 __FUNCTION__
, i
, eabuf
));
2908 DHD_INFO(("%s : %d/%d MACADDR=%s", __FUNCTION__
, i
, list
->count
, eabuf
));
2914 if ((ret
= wl_android_set_ap_mac_list(dev
, macmode
, list
)) != 0)
2915 DHD_ERROR(("%s : Setting MAC list failed error=%d\n", __FUNCTION__
, ret
));
2918 MFREE(cfg
->osh
, list
, sizeof(int) + sizeof(struct ether_addr
) * macnum
);
2924 * Global function definitions (declared in wl_android.h)
2927 int wl_android_wifi_on(struct net_device
*dev
)
2930 int retry
= POWERUP_MAX_RETRY
;
2932 DHD_ERROR(("%s in\n", __FUNCTION__
));
2934 DHD_ERROR(("%s: dev is null\n", __FUNCTION__
));
2938 dhd_net_if_lock(dev
);
2941 dhd_net_wifi_platform_set_power(dev
, TRUE
, WIFI_TURNON_DELAY
);
2943 ret
= dhd_net_bus_resume(dev
, 0);
2944 #endif /* BCMSDIO */
2946 ret
= dhd_net_bus_devreset(dev
, FALSE
);
2947 #endif /* BCMPCIE */
2951 DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n",
2954 dhd_net_bus_devreset(dev
, TRUE
);
2955 #endif /* BCMPCIE */
2956 dhd_net_wifi_platform_set_power(dev
, FALSE
, WIFI_TURNOFF_DELAY
);
2957 } while (retry
-- > 0);
2959 DHD_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n"));
2963 ret
= dhd_net_bus_devreset(dev
, FALSE
);
2964 dhd_net_bus_resume(dev
, 1);
2965 #endif /* BCMSDIO */
2969 if (dhd_dev_init_ioctl(dev
) < 0) {
2973 #endif /* !BCMPCIE */
2978 dhd_net_if_unlock(dev
);
2983 int wl_android_wifi_off(struct net_device
*dev
, bool on_failure
)
2987 DHD_ERROR(("%s in\n", __FUNCTION__
));
2989 DHD_TRACE(("%s: dev is null\n", __FUNCTION__
));
2993 #if defined(BCMPCIE) && defined(DHD_DEBUG_UART)
2994 ret
= dhd_debug_uart_is_running(dev
);
2996 DHD_ERROR(("%s - Debug UART App is running\n", __FUNCTION__
));
2999 #endif /* BCMPCIE && DHD_DEBUG_UART */
3000 dhd_net_if_lock(dev
);
3001 if (g_wifi_on
|| on_failure
) {
3002 #if defined(BCMSDIO) || defined(BCMPCIE)
3003 ret
= dhd_net_bus_devreset(dev
, TRUE
);
3005 dhd_net_bus_suspend(dev
);
3006 #endif /* BCMSDIO */
3007 #endif /* BCMSDIO || BCMPCIE */
3008 dhd_net_wifi_platform_set_power(dev
, FALSE
, WIFI_TURNOFF_DELAY
);
3011 dhd_net_if_unlock(dev
);
3016 static int wl_android_set_fwpath(struct net_device
*net
, char *command
, int total_len
)
3018 if ((strlen(command
) - strlen(CMD_SETFWPATH
)) > MOD_PARAM_PATHLEN
)
3020 return dhd_net_set_fw_path(net
, command
+ strlen(CMD_SETFWPATH
) + 1);
3023 #ifdef CONNECTION_STATISTICS
3025 wl_chanim_stats(struct net_device
*dev
, u8
*chan_idle
)
3028 wl_chanim_stats_t
*list
;
3029 /* Parameter _and_ returned buffer of chanim_stats. */
3030 wl_chanim_stats_t param
;
3031 u8 result
[WLC_IOCTL_SMLEN
];
3032 chanim_stats_t
*stats
;
3034 memset(¶m
, 0, sizeof(param
));
3036 param
.buflen
= htod32(sizeof(wl_chanim_stats_t
));
3037 param
.count
= htod32(WL_CHANIM_COUNT_ONE
);
3039 if ((err
= wldev_iovar_getbuf(dev
, "chanim_stats", (char*)¶m
, sizeof(wl_chanim_stats_t
),
3040 (char*)result
, sizeof(result
), 0)) < 0) {
3041 WL_ERR(("Failed to get chanim results %d \n", err
));
3045 list
= (wl_chanim_stats_t
*)result
;
3047 list
->buflen
= dtoh32(list
->buflen
);
3048 list
->version
= dtoh32(list
->version
);
3049 list
->count
= dtoh32(list
->count
);
3051 if (list
->buflen
== 0) {
3054 } else if (list
->version
!= WL_CHANIM_STATS_VERSION
) {
3055 WL_ERR(("Sorry, firmware has wl_chanim_stats version %d "
3056 "but driver supports only version %d.\n",
3057 list
->version
, WL_CHANIM_STATS_VERSION
));
3062 stats
= list
->stats
;
3063 stats
->glitchcnt
= dtoh32(stats
->glitchcnt
);
3064 stats
->badplcp
= dtoh32(stats
->badplcp
);
3065 stats
->chanspec
= dtoh16(stats
->chanspec
);
3066 stats
->timestamp
= dtoh32(stats
->timestamp
);
3067 stats
->chan_idle
= dtoh32(stats
->chan_idle
);
3069 WL_INFORM(("chanspec: 0x%4x glitch: %d badplcp: %d idle: %d timestamp: %d\n",
3070 stats
->chanspec
, stats
->glitchcnt
, stats
->badplcp
, stats
->chan_idle
,
3073 *chan_idle
= stats
->chan_idle
;
3079 wl_android_get_connection_stats(struct net_device
*dev
, char *command
, int total_len
)
3081 static char iovar_buf
[WLC_IOCTL_MAXLEN
];
3082 const wl_cnt_wlc_t
* wlc_cnt
= NULL
;
3083 #ifndef DISABLE_IF_COUNTERS
3084 wl_if_stats_t
* if_stats
= NULL
;
3085 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3086 #endif /* DISABLE_IF_COUNTERS */
3089 struct connection_stats
*output
;
3090 unsigned int bufsize
= 0;
3091 int bytes_written
= -1;
3094 WL_INFORM(("%s: enter Get Connection Stats\n", __FUNCTION__
));
3096 if (total_len
<= 0) {
3097 WL_ERR(("%s: invalid buffer size %d\n", __FUNCTION__
, total_len
));
3101 bufsize
= total_len
;
3102 if (bufsize
< sizeof(struct connection_stats
)) {
3103 WL_ERR(("%s: not enough buffer size, provided=%u, requires=%zu\n",
3104 __FUNCTION__
, bufsize
,
3105 sizeof(struct connection_stats
)));
3109 output
= (struct connection_stats
*)command
;
3111 #ifndef DISABLE_IF_COUNTERS
3112 if_stats
= (wl_if_stats_t
*)MALLOCZ(cfg
->osh
, sizeof(*if_stats
));
3113 if (if_stats
== NULL
) {
3114 WL_ERR(("%s(%d): MALLOCZ failed\n", __FUNCTION__
, __LINE__
));
3117 memset(if_stats
, 0, sizeof(*if_stats
));
3119 if (FW_SUPPORTED(dhdp
, ifst
)) {
3120 ret
= wl_cfg80211_ifstats_counters(dev
, if_stats
);
3122 ret
= wldev_iovar_getbuf(dev
, "if_counters", NULL
, 0,
3123 (char *)if_stats
, sizeof(*if_stats
), NULL
);
3127 WL_ERR(("%s: if_counters not supported ret=%d\n",
3128 __FUNCTION__
, ret
));
3130 /* In case if_stats IOVAR is not supported, get information from counters. */
3131 #endif /* DISABLE_IF_COUNTERS */
3132 ret
= wldev_iovar_getbuf(dev
, "counters", NULL
, 0,
3133 iovar_buf
, WLC_IOCTL_MAXLEN
, NULL
);
3134 if (unlikely(ret
)) {
3135 WL_ERR(("counters error (%d) - size = %zu\n", ret
, sizeof(wl_cnt_wlc_t
)));
3138 ret
= wl_cntbuf_to_xtlv_format(NULL
, iovar_buf
, WL_CNTBUF_MAX_SIZE
, 0);
3139 if (ret
!= BCME_OK
) {
3140 WL_ERR(("%s wl_cntbuf_to_xtlv_format ERR %d\n",
3141 __FUNCTION__
, ret
));
3145 if (!(wlc_cnt
= GET_WLCCNT_FROM_CNTBUF(iovar_buf
))) {
3146 WL_ERR(("%s wlc_cnt NULL!\n", __FUNCTION__
));
3150 output
->txframe
= dtoh32(wlc_cnt
->txframe
);
3151 output
->txbyte
= dtoh32(wlc_cnt
->txbyte
);
3152 output
->txerror
= dtoh32(wlc_cnt
->txerror
);
3153 output
->rxframe
= dtoh32(wlc_cnt
->rxframe
);
3154 output
->rxbyte
= dtoh32(wlc_cnt
->rxbyte
);
3155 output
->txfail
= dtoh32(wlc_cnt
->txfail
);
3156 output
->txretry
= dtoh32(wlc_cnt
->txretry
);
3157 output
->txretrie
= dtoh32(wlc_cnt
->txretrie
);
3158 output
->txrts
= dtoh32(wlc_cnt
->txrts
);
3159 output
->txnocts
= dtoh32(wlc_cnt
->txnocts
);
3160 output
->txexptime
= dtoh32(wlc_cnt
->txexptime
);
3161 #ifndef DISABLE_IF_COUNTERS
3163 /* Populate from if_stats. */
3164 if (dtoh16(if_stats
->version
) > WL_IF_STATS_T_VERSION
) {
3165 WL_ERR(("%s: incorrect version of wl_if_stats_t, expected=%u got=%u\n",
3166 __FUNCTION__
, WL_IF_STATS_T_VERSION
, if_stats
->version
));
3170 output
->txframe
= (uint32
)dtoh64(if_stats
->txframe
);
3171 output
->txbyte
= (uint32
)dtoh64(if_stats
->txbyte
);
3172 output
->txerror
= (uint32
)dtoh64(if_stats
->txerror
);
3173 output
->rxframe
= (uint32
)dtoh64(if_stats
->rxframe
);
3174 output
->rxbyte
= (uint32
)dtoh64(if_stats
->rxbyte
);
3175 output
->txfail
= (uint32
)dtoh64(if_stats
->txfail
);
3176 output
->txretry
= (uint32
)dtoh64(if_stats
->txretry
);
3177 output
->txretrie
= (uint32
)dtoh64(if_stats
->txretrie
);
3178 if (dtoh16(if_stats
->length
) > OFFSETOF(wl_if_stats_t
, txexptime
)) {
3179 output
->txexptime
= (uint32
)dtoh64(if_stats
->txexptime
);
3180 output
->txrts
= (uint32
)dtoh64(if_stats
->txrts
);
3181 output
->txnocts
= (uint32
)dtoh64(if_stats
->txnocts
);
3183 output
->txexptime
= 0;
3185 output
->txnocts
= 0;
3188 #endif /* DISABLE_IF_COUNTERS */
3190 /* link_speed is in kbps */
3191 ret
= wldev_get_link_speed(dev
, &link_speed
);
3192 if (ret
|| link_speed
< 0) {
3193 WL_ERR(("%s: wldev_get_link_speed() failed, ret=%d, speed=%d\n",
3194 __FUNCTION__
, ret
, link_speed
));
3198 output
->txrate
= link_speed
;
3200 /* Channel idle ratio. */
3201 if (wl_chanim_stats(dev
, &(output
->chan_idle
)) < 0) {
3202 output
->chan_idle
= 0;
3205 bytes_written
= sizeof(struct connection_stats
);
3208 #ifndef DISABLE_IF_COUNTERS
3210 MFREE(cfg
->osh
, if_stats
, sizeof(*if_stats
));
3212 #endif /* DISABLE_IF_COUNTERS */
3214 return bytes_written
;
3216 #endif /* CONNECTION_STATISTICS */
3220 wl_android_process_natoe_cmd(struct net_device
*dev
, char *command
, int total_len
)
3222 int ret
= BCME_ERROR
;
3223 char *pcmd
= command
;
3225 wl_natoe_cmd_info_t cmd_info
;
3226 const wl_natoe_sub_cmd_t
*natoe_cmd
= &natoe_cmd_list
[0];
3228 /* skip to cmd name after "natoe" */
3229 str
= bcmstrtok(&pcmd
, " ", NULL
);
3231 /* If natoe subcmd name is not provided, return error */
3232 if (*pcmd
== '\0') {
3233 WL_ERR(("natoe subcmd not provided %s\n", __FUNCTION__
));
3238 /* get the natoe command name to str */
3239 str
= bcmstrtok(&pcmd
, " ", NULL
);
3241 while (natoe_cmd
->name
!= NULL
) {
3242 if (strcmp(natoe_cmd
->name
, str
) == 0) {
3243 /* dispacth cmd to appropriate handler */
3244 if (natoe_cmd
->handler
) {
3245 cmd_info
.command
= command
;
3246 cmd_info
.tot_len
= total_len
;
3247 ret
= natoe_cmd
->handler(dev
, natoe_cmd
, pcmd
, &cmd_info
);
3257 wlu_natoe_set_vars_cbfn(void *ctx
, uint8
*data
, uint16 type
, uint16 len
)
3260 wl_natoe_cmd_info_t
*cmd_info
= (wl_natoe_cmd_info_t
*)ctx
;
3261 uint8
*command
= cmd_info
->command
;
3262 uint16 total_len
= cmd_info
->tot_len
;
3263 uint16 bytes_written
= 0;
3265 UNUSED_PARAMETER(len
);
3269 case WL_NATOE_XTLV_ENABLE
:
3271 bytes_written
= snprintf(command
, total_len
, "natoe: %s\n",
3272 *data
?"enabled":"disabled");
3273 cmd_info
->bytes_written
= bytes_written
;
3277 case WL_NATOE_XTLV_CONFIG_IPS
:
3279 wl_natoe_config_ips_t
*config_ips
;
3282 config_ips
= (wl_natoe_config_ips_t
*)data
;
3283 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->sta_ip
, buf
);
3284 bytes_written
= snprintf(command
, total_len
, "sta ip: %s\n", buf
);
3285 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->sta_netmask
, buf
);
3286 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3287 "sta netmask: %s\n", buf
);
3288 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->sta_router_ip
, buf
);
3289 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3290 "sta router ip: %s\n", buf
);
3291 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->sta_dnsip
, buf
);
3292 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3293 "sta dns ip: %s\n", buf
);
3294 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->ap_ip
, buf
);
3295 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3296 "ap ip: %s\n", buf
);
3297 bcm_ip_ntoa((struct ipv4_addr
*)&config_ips
->ap_netmask
, buf
);
3298 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3299 "ap netmask: %s\n", buf
);
3300 cmd_info
->bytes_written
= bytes_written
;
3304 case WL_NATOE_XTLV_CONFIG_PORTS
:
3306 wl_natoe_ports_config_t
*ports_config
;
3308 ports_config
= (wl_natoe_ports_config_t
*)data
;
3309 bytes_written
= snprintf(command
, total_len
, "starting port num: %d\n",
3310 dtoh16(ports_config
->start_port_num
));
3311 bytes_written
+= snprintf(command
+ bytes_written
, total_len
,
3312 "number of ports: %d\n", dtoh16(ports_config
->no_of_ports
));
3313 cmd_info
->bytes_written
= bytes_written
;
3317 case WL_NATOE_XTLV_DBG_STATS
:
3319 char *stats_dump
= (char *)data
;
3321 bytes_written
= snprintf(command
, total_len
, "%s\n", stats_dump
);
3322 cmd_info
->bytes_written
= bytes_written
;
3326 case WL_NATOE_XTLV_TBL_CNT
:
3328 bytes_written
= snprintf(command
, total_len
, "natoe max tbl entries: %d\n",
3329 dtoh32(*(uint32
*)data
));
3330 cmd_info
->bytes_written
= bytes_written
;
3343 * --- common for all natoe get commands ----
3346 wl_natoe_get_ioctl(struct net_device
*dev
, wl_natoe_ioc_t
*natoe_ioc
,
3347 uint16 iocsz
, uint8
*buf
, uint16 buflen
, wl_natoe_cmd_info_t
*cmd_info
)
3349 /* for gets we only need to pass ioc header */
3350 wl_natoe_ioc_t
*iocresp
= (wl_natoe_ioc_t
*)buf
;
3353 /* send getbuf natoe iovar */
3354 res
= wldev_iovar_getbuf(dev
, "natoe", natoe_ioc
, iocsz
, buf
,
3357 /* check the response buff */
3358 if ((res
== BCME_OK
)) {
3359 /* scans ioctl tlvbuf f& invokes the cbfn for processing */
3360 res
= bcm_unpack_xtlv_buf(cmd_info
, iocresp
->data
, iocresp
->len
,
3361 BCM_XTLV_OPTION_ALIGN32
, wlu_natoe_set_vars_cbfn
);
3363 if (res
== BCME_OK
) {
3364 res
= cmd_info
->bytes_written
;
3369 DHD_ERROR(("%s: get command failed code %d\n", __FUNCTION__
, res
));
3377 wl_android_natoe_subcmd_enable(struct net_device
*dev
, const wl_natoe_sub_cmd_t
*cmd
,
3378 char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3381 wl_natoe_ioc_t
*natoe_ioc
;
3382 char *pcmd
= command
;
3383 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
;
3384 uint16 buflen
= WL_NATOE_IOC_BUFSZ
;
3385 bcm_xtlv_t
*pxtlv
= NULL
;
3386 char *ioctl_buf
= NULL
;
3387 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3389 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
3391 WL_ERR(("ioctl memory alloc failed\n"));
3395 /* alloc mem for ioctl headr + tlv data */
3396 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3398 WL_ERR(("ioctl header memory alloc failed\n"));
3399 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3403 /* make up natoe cmd ioctl header */
3404 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3405 natoe_ioc
->id
= htod16(cmd
->id
);
3406 natoe_ioc
->len
= htod16(WL_NATOE_IOC_BUFSZ
);
3407 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3409 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3410 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3411 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3412 WLC_IOCTL_MEDLEN
, cmd_info
);
3413 if (ret
!= BCME_OK
) {
3414 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3418 uint8 val
= bcm_atoi(pcmd
);
3420 /* buflen is max tlv data we can write, it will be decremented as we pack */
3421 /* save buflen at start */
3422 uint16 buflen_at_start
= buflen
;
3424 /* we'll adjust final ioc size at the end */
3425 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
, &buflen
, WL_NATOE_XTLV_ENABLE
,
3426 sizeof(uint8
), &val
, BCM_XTLV_OPTION_ALIGN32
);
3428 if (ret
!= BCME_OK
) {
3433 /* adjust iocsz to the end of last data record */
3434 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3435 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3437 ret
= wldev_iovar_setbuf(dev
, "natoe",
3438 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
3439 if (ret
!= BCME_OK
) {
3440 WL_ERR(("Fail to set iovar %d\n", ret
));
3446 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3447 MFREE(cfg
->osh
, natoe_ioc
, iocsz
);
3453 wl_android_natoe_subcmd_config_ips(struct net_device
*dev
,
3454 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3457 wl_natoe_config_ips_t config_ips
;
3458 wl_natoe_ioc_t
*natoe_ioc
;
3459 char *pcmd
= command
;
3461 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
;
3462 uint16 buflen
= WL_NATOE_IOC_BUFSZ
;
3463 bcm_xtlv_t
*pxtlv
= NULL
;
3464 char *ioctl_buf
= NULL
;
3465 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3467 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
3469 WL_ERR(("ioctl memory alloc failed\n"));
3473 /* alloc mem for ioctl headr + tlv data */
3474 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3476 WL_ERR(("ioctl header memory alloc failed\n"));
3477 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3481 /* make up natoe cmd ioctl header */
3482 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3483 natoe_ioc
->id
= htod16(cmd
->id
);
3484 natoe_ioc
->len
= htod16(WL_NATOE_IOC_BUFSZ
);
3485 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3487 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3488 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3489 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3490 WLC_IOCTL_MEDLEN
, cmd_info
);
3491 if (ret
!= BCME_OK
) {
3492 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3496 /* buflen is max tlv data we can write, it will be decremented as we pack */
3497 /* save buflen at start */
3498 uint16 buflen_at_start
= buflen
;
3500 memset(&config_ips
, 0, sizeof(config_ips
));
3502 str
= bcmstrtok(&pcmd
, " ", NULL
);
3503 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.sta_ip
)) {
3504 WL_ERR(("Invalid STA IP addr %s\n", str
));
3509 str
= bcmstrtok(&pcmd
, " ", NULL
);
3510 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.sta_netmask
)) {
3511 WL_ERR(("Invalid STA netmask %s\n", str
));
3516 str
= bcmstrtok(&pcmd
, " ", NULL
);
3517 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.sta_router_ip
)) {
3518 WL_ERR(("Invalid STA router IP addr %s\n", str
));
3523 str
= bcmstrtok(&pcmd
, " ", NULL
);
3524 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.sta_dnsip
)) {
3525 WL_ERR(("Invalid STA DNS IP addr %s\n", str
));
3530 str
= bcmstrtok(&pcmd
, " ", NULL
);
3531 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.ap_ip
)) {
3532 WL_ERR(("Invalid AP IP addr %s\n", str
));
3537 str
= bcmstrtok(&pcmd
, " ", NULL
);
3538 if (!str
|| !bcm_atoipv4(str
, (struct ipv4_addr
*)&config_ips
.ap_netmask
)) {
3539 WL_ERR(("Invalid AP netmask %s\n", str
));
3544 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
,
3545 &buflen
, WL_NATOE_XTLV_CONFIG_IPS
, sizeof(config_ips
),
3546 &config_ips
, BCM_XTLV_OPTION_ALIGN32
);
3548 if (ret
!= BCME_OK
) {
3553 /* adjust iocsz to the end of last data record */
3554 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3555 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3557 ret
= wldev_iovar_setbuf(dev
, "natoe",
3558 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
3559 if (ret
!= BCME_OK
) {
3560 WL_ERR(("Fail to set iovar %d\n", ret
));
3566 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3567 MFREE(cfg
->osh
, natoe_ioc
, sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
);
3573 wl_android_natoe_subcmd_config_ports(struct net_device
*dev
,
3574 const wl_natoe_sub_cmd_t
*cmd
, char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3577 wl_natoe_ports_config_t ports_config
;
3578 wl_natoe_ioc_t
*natoe_ioc
;
3579 char *pcmd
= command
;
3581 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
;
3582 uint16 buflen
= WL_NATOE_IOC_BUFSZ
;
3583 bcm_xtlv_t
*pxtlv
= NULL
;
3584 char *ioctl_buf
= NULL
;
3585 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3587 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
3589 WL_ERR(("ioctl memory alloc failed\n"));
3593 /* alloc mem for ioctl headr + tlv data */
3594 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3596 WL_ERR(("ioctl header memory alloc failed\n"));
3597 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3601 /* make up natoe cmd ioctl header */
3602 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3603 natoe_ioc
->id
= htod16(cmd
->id
);
3604 natoe_ioc
->len
= htod16(WL_NATOE_IOC_BUFSZ
);
3605 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3607 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3608 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3609 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3610 WLC_IOCTL_MEDLEN
, cmd_info
);
3611 if (ret
!= BCME_OK
) {
3612 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3616 /* buflen is max tlv data we can write, it will be decremented as we pack */
3617 /* save buflen at start */
3618 uint16 buflen_at_start
= buflen
;
3620 memset(&ports_config
, 0, sizeof(ports_config
));
3622 str
= bcmstrtok(&pcmd
, " ", NULL
);
3624 WL_ERR(("Invalid port string %s\n", str
));
3628 ports_config
.start_port_num
= htod16(bcm_atoi(str
));
3630 str
= bcmstrtok(&pcmd
, " ", NULL
);
3632 WL_ERR(("Invalid port string %s\n", str
));
3636 ports_config
.no_of_ports
= htod16(bcm_atoi(str
));
3638 if ((uint32
)(ports_config
.start_port_num
+ ports_config
.no_of_ports
) >
3639 NATOE_MAX_PORT_NUM
) {
3640 WL_ERR(("Invalid port configuration\n"));
3644 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
,
3645 &buflen
, WL_NATOE_XTLV_CONFIG_PORTS
, sizeof(ports_config
),
3646 &ports_config
, BCM_XTLV_OPTION_ALIGN32
);
3648 if (ret
!= BCME_OK
) {
3653 /* adjust iocsz to the end of last data record */
3654 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3655 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3657 ret
= wldev_iovar_setbuf(dev
, "natoe",
3658 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
3659 if (ret
!= BCME_OK
) {
3660 WL_ERR(("Fail to set iovar %d\n", ret
));
3666 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3667 MFREE(cfg
->osh
, natoe_ioc
, sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
);
3673 wl_android_natoe_subcmd_dbg_stats(struct net_device
*dev
, const wl_natoe_sub_cmd_t
*cmd
,
3674 char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3677 wl_natoe_ioc_t
*natoe_ioc
;
3678 char *pcmd
= command
;
3679 uint16 kflags
= in_atomic() ? GFP_ATOMIC
: GFP_KERNEL
;
3680 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_DBG_STATS_BUFSZ
;
3681 uint16 buflen
= WL_NATOE_DBG_STATS_BUFSZ
;
3682 bcm_xtlv_t
*pxtlv
= NULL
;
3683 char *ioctl_buf
= NULL
;
3684 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3686 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MAXLEN
);
3688 WL_ERR(("ioctl memory alloc failed\n"));
3692 /* alloc mem for ioctl headr + tlv data */
3693 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3695 WL_ERR(("ioctl header memory alloc failed\n"));
3696 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MAXLEN
);
3700 /* make up natoe cmd ioctl header */
3701 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3702 natoe_ioc
->id
= htod16(cmd
->id
);
3703 natoe_ioc
->len
= htod16(WL_NATOE_DBG_STATS_BUFSZ
);
3704 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3706 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3707 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3708 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3709 WLC_IOCTL_MAXLEN
, cmd_info
);
3710 if (ret
!= BCME_OK
) {
3711 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3715 uint8 val
= bcm_atoi(pcmd
);
3717 /* buflen is max tlv data we can write, it will be decremented as we pack */
3718 /* save buflen at start */
3719 uint16 buflen_at_start
= buflen
;
3721 /* we'll adjust final ioc size at the end */
3722 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
, &buflen
, WL_NATOE_XTLV_ENABLE
,
3723 sizeof(uint8
), &val
, BCM_XTLV_OPTION_ALIGN32
);
3725 if (ret
!= BCME_OK
) {
3730 /* adjust iocsz to the end of last data record */
3731 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3732 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3734 ret
= wldev_iovar_setbuf(dev
, "natoe",
3735 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MAXLEN
, NULL
);
3736 if (ret
!= BCME_OK
) {
3737 WL_ERR(("Fail to set iovar %d\n", ret
));
3743 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MAXLEN
);
3744 MFREE(cfg
->osh
, natoe_ioc
, sizeof(*natoe_ioc
) + WL_NATOE_DBG_STATS_BUFSZ
);
3750 wl_android_natoe_subcmd_tbl_cnt(struct net_device
*dev
, const wl_natoe_sub_cmd_t
*cmd
,
3751 char *command
, wl_natoe_cmd_info_t
*cmd_info
)
3754 wl_natoe_ioc_t
*natoe_ioc
;
3755 char *pcmd
= command
;
3756 uint16 kflags
= in_atomic() ? GFP_ATOMIC
: GFP_KERNEL
;
3757 uint16 iocsz
= sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
;
3758 uint16 buflen
= WL_NATOE_IOC_BUFSZ
;
3759 bcm_xtlv_t
*pxtlv
= NULL
;
3760 char *ioctl_buf
= NULL
;
3761 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3763 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
3765 WL_ERR(("ioctl memory alloc failed\n"));
3769 /* alloc mem for ioctl headr + tlv data */
3770 natoe_ioc
= (wl_natoe_ioc_t
*)MALLOCZ(cfg
->osh
, iocsz
);
3772 WL_ERR(("ioctl header memory alloc failed\n"));
3773 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3777 /* make up natoe cmd ioctl header */
3778 natoe_ioc
->version
= htod16(WL_NATOE_IOCTL_VERSION
);
3779 natoe_ioc
->id
= htod16(cmd
->id
);
3780 natoe_ioc
->len
= htod16(WL_NATOE_IOC_BUFSZ
);
3781 pxtlv
= (bcm_xtlv_t
*)natoe_ioc
->data
;
3783 if(*pcmd
== WL_IOCTL_ACTION_GET
) { /* get */
3784 iocsz
= sizeof(*natoe_ioc
) + sizeof(*pxtlv
);
3785 ret
= wl_natoe_get_ioctl(dev
, natoe_ioc
, iocsz
, ioctl_buf
,
3786 WLC_IOCTL_MEDLEN
, cmd_info
);
3787 if (ret
!= BCME_OK
) {
3788 WL_ERR(("Fail to get iovar %s\n", __FUNCTION__
));
3792 uint32 val
= bcm_atoi(pcmd
);
3794 /* buflen is max tlv data we can write, it will be decremented as we pack */
3795 /* save buflen at start */
3796 uint16 buflen_at_start
= buflen
;
3798 /* we'll adjust final ioc size at the end */
3799 ret
= bcm_pack_xtlv_entry((uint8
**)&pxtlv
, &buflen
, WL_NATOE_XTLV_TBL_CNT
,
3800 sizeof(uint32
), &val
, BCM_XTLV_OPTION_ALIGN32
);
3802 if (ret
!= BCME_OK
) {
3807 /* adjust iocsz to the end of last data record */
3808 natoe_ioc
->len
= (buflen_at_start
- buflen
);
3809 iocsz
= sizeof(*natoe_ioc
) + natoe_ioc
->len
;
3811 ret
= wldev_iovar_setbuf(dev
, "natoe",
3812 natoe_ioc
, iocsz
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
3813 if (ret
!= BCME_OK
) {
3814 WL_ERR(("Fail to set iovar %d\n", ret
));
3820 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
3821 MFREE(cfg
->osh
, natoe_ioc
, sizeof(*natoe_ioc
) + WL_NATOE_IOC_BUFSZ
);
3826 #endif /* WL_NATOE */
3828 #ifdef CUSTOMER_HW4_PRIVATE_CMD
3829 #ifdef SUPPORT_AMPDU_MPDU_CMD
3830 /* CMD_AMPDU_MPDU */
3832 wl_android_set_ampdu_mpdu(struct net_device
*dev
, const char* string_num
)
3837 ampdu_mpdu
= bcm_atoi(string_num
);
3839 if (ampdu_mpdu
> 32) {
3840 DHD_ERROR(("%s : ampdu_mpdu MAX value is 32.\n", __FUNCTION__
));
3844 DHD_ERROR(("%s : ampdu_mpdu = %d\n", __FUNCTION__
, ampdu_mpdu
));
3845 err
= wldev_iovar_setint(dev
, "ampdu_mpdu", ampdu_mpdu
);
3847 DHD_ERROR(("%s : ampdu_mpdu set error. %d\n", __FUNCTION__
, err
));
3853 #endif /* SUPPORT_AMPDU_MPDU_CMD */
3854 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
3856 #if defined(WL_SUPPORT_AUTO_CHANNEL)
3857 /* SoftAP feature */
3858 #define APCS_BAND_2G_LEGACY1 20
3859 #define APCS_BAND_2G_LEGACY2 0
3860 #define APCS_BAND_AUTO "band=auto"
3861 #define APCS_BAND_2G "band=2g"
3862 #define APCS_BAND_5G "band=5g"
3863 #define APCS_MAX_2G_CHANNELS 11
3864 #define APCS_MAX_RETRY 10
3865 #define APCS_DEFAULT_2G_CH 1
3866 #define APCS_DEFAULT_5G_CH 149
3868 wl_android_set_auto_channel(struct net_device
*dev
, const char* cmd_str
,
3869 char* command
, int total_len
)
3877 uint32 band
= WLC_BAND_2G
;
3879 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
3882 WL_INFORM(("Command: %s len:%d \n", cmd_str
, (int)strlen(cmd_str
)));
3883 if (strncmp(cmd_str
, APCS_BAND_AUTO
, strlen(APCS_BAND_AUTO
)) == 0) {
3884 band
= WLC_BAND_AUTO
;
3885 } else if (strncmp(cmd_str
, APCS_BAND_5G
, strlen(APCS_BAND_5G
)) == 0) {
3887 } else if (strncmp(cmd_str
, APCS_BAND_2G
, strlen(APCS_BAND_2G
)) == 0) {
3891 * For backward compatibility: Some platforms used to issue argument 20 or 0
3892 * to enforce the 2G channel selection
3894 channel
= bcm_atoi(cmd_str
);
3895 if ((channel
== APCS_BAND_2G_LEGACY1
) ||
3896 (channel
== APCS_BAND_2G_LEGACY2
)) {
3899 WL_ERR(("Invalid argument\n"));
3904 /* If no argument is provided, default to 2G */
3905 WL_ERR(("No argument given default to 2.4G scan\n"));
3908 WL_INFORM(("HAPD_AUTO_CHANNEL = %d, band=%d \n", channel
, band
));
3910 /* If STA is connected, return is STA channel, else ACS can be issued,
3911 * set spect to 0 and proceed with ACS
3913 channel
= wl_cfg80211_get_sta_channel(cfg
);
3915 channel
= (channel
<= CH_MAX_2G_CHANNEL
) ?
3916 channel
: APCS_DEFAULT_2G_CH
;
3920 ret
= wldev_ioctl_get(dev
, WLC_GET_SPECT_MANAGMENT
, &spect
, sizeof(spect
));
3922 WL_ERR(("ACS: error getting the spect, ret=%d\n", ret
));
3927 ret
= wl_cfg80211_set_spect(dev
, 0);
3929 WL_ERR(("ACS: error while setting spect, ret=%d\n", ret
));
3934 reqbuf
= (u8
*)MALLOCZ(cfg
->osh
, CHANSPEC_BUF_SIZE
);
3935 if (reqbuf
== NULL
) {
3936 WL_ERR(("failed to allocate chanspec buffer\n"));
3940 if (band
== WLC_BAND_AUTO
) {
3941 WL_DBG(("ACS full channel scan \n"));
3942 reqbuf
[0] = htod32(0);
3943 } else if (band
== WLC_BAND_5G
) {
3944 WL_DBG(("ACS 5G band scan \n"));
3945 if ((ret
= wl_cfg80211_get_chanspecs_5g(dev
, reqbuf
, CHANSPEC_BUF_SIZE
)) < 0) {
3946 WL_ERR(("ACS 5g chanspec retreival failed! \n"));
3949 } else if (band
== WLC_BAND_2G
) {
3951 * If channel argument is not provided/ argument 20 is provided,
3952 * Restrict channel to 2GHz, 20MHz BW, No SB
3954 WL_DBG(("ACS 2G band scan \n"));
3955 if ((ret
= wl_cfg80211_get_chanspecs_2g(dev
, reqbuf
, CHANSPEC_BUF_SIZE
)) < 0) {
3956 WL_ERR(("ACS 2g chanspec retreival failed! \n"));
3960 WL_ERR(("ACS: No band chosen\n"));
3964 buf_size
= (band
== WLC_BAND_AUTO
) ? sizeof(int) : CHANSPEC_BUF_SIZE
;
3965 ret
= wldev_ioctl_set(dev
, WLC_START_CHANNEL_SEL
, (void *)reqbuf
,
3968 WL_ERR(("can't start auto channel scan, err = %d\n", ret
));
3973 /* Wait for auto channel selection, max 3000 ms */
3974 if ((band
== WLC_BAND_2G
) || (band
== WLC_BAND_5G
)) {
3978 * Full channel scan at the minimum takes 1.2secs
3979 * even with parallel scan. max wait time: 3500ms
3984 retry
= APCS_MAX_RETRY
;
3986 ret
= wldev_ioctl_get(dev
, WLC_GET_CHANNEL_SEL
, &chosen
,
3991 chosen
= dtoh32(chosen
);
3997 #ifdef D11AC_IOTYPES
3998 if (wl_cfg80211_get_ioctl_version() == 1) {
3999 channel
= LCHSPEC_CHANNEL((chanspec_t
)chosen
);
4001 channel
= CHSPEC_CHANNEL((chanspec_t
)chosen
);
4004 channel
= CHSPEC_CHANNEL((chanspec_t
)chosen
);
4005 #endif /* D11AC_IOTYPES */
4006 apcs_band
= (band
== WLC_BAND_AUTO
) ? WLC_BAND_2G
: band
;
4007 chosen_band
= (channel
<= CH_MAX_2G_CHANNEL
) ? WLC_BAND_2G
: WLC_BAND_5G
;
4008 if (apcs_band
== chosen_band
) {
4009 WL_ERR(("selected channel = %d\n", channel
));
4013 WL_DBG(("%d tried, ret = %d, chosen = 0x%x\n",
4014 (APCS_MAX_RETRY
- retry
), ret
, chosen
));
4019 if ((retry
== 0) || (ret
< 0)) {
4020 /* On failure, fallback to a default channel */
4021 if ((band
== WLC_BAND_5G
)) {
4022 channel
= APCS_DEFAULT_5G_CH
;
4024 channel
= APCS_DEFAULT_2G_CH
;
4026 WL_ERR(("ACS failed. Fall back to default channel (%d) \n", channel
));
4030 if ((ret
= wl_cfg80211_set_spect(dev
, spect
) < 0)) {
4031 WL_ERR(("ACS: error while setting spect\n"));
4036 MFREE(cfg
->osh
, reqbuf
, CHANSPEC_BUF_SIZE
);
4040 ret
= snprintf(command
, total_len
, "%d", channel
);
4041 WL_INFORM(("command result is %s \n", command
));
4046 #endif /* WL_SUPPORT_AUTO_CHANNEL */
4048 #ifdef CUSTOMER_HW4_PRIVATE_CMD
4049 #ifdef SUPPORT_HIDDEN_AP
4051 wl_android_set_max_num_sta(struct net_device
*dev
, const char* string_num
)
4055 max_assoc
= bcm_atoi(string_num
);
4056 WL_INFORM(("HAPD_MAX_NUM_STA = %d\n", max_assoc
));
4057 wldev_iovar_setint(dev
, "maxassoc", max_assoc
);
4058 WL_INFORM(("Conigured maxassoc = %d\n", max_assoc
));
4063 wl_android_set_ssid(struct net_device
*dev
, const char* hapd_ssid
)
4068 ssid
.SSID_len
= strlen(hapd_ssid
);
4069 if (ssid
.SSID_len
== 0) {
4070 WL_ERR(("%s : No SSID\n", __FUNCTION__
));
4073 if (ssid
.SSID_len
> DOT11_MAX_SSID_LEN
) {
4074 ssid
.SSID_len
= DOT11_MAX_SSID_LEN
;
4075 WL_ERR(("%s : Too long SSID Length %zu\n", __FUNCTION__
, strlen(hapd_ssid
)));
4077 bcm_strncpy_s(ssid
.SSID
, sizeof(ssid
.SSID
), hapd_ssid
, ssid
.SSID_len
);
4078 DHD_INFO(("%s: HAPD_SSID = %s\n", __FUNCTION__
, ssid
.SSID
));
4079 ret
= wldev_ioctl_set(dev
, WLC_SET_SSID
, &ssid
, sizeof(wlc_ssid_t
));
4081 WL_ERR(("%s : WLC_SET_SSID Error:%d\n", __FUNCTION__
, ret
));
4088 wl_android_set_hide_ssid(struct net_device
*dev
, const char* string_num
)
4093 hide_ssid
= bcm_atoi(string_num
);
4094 DHD_INFO(("%s: HAPD_HIDE_SSID = %d\n", __FUNCTION__
, hide_ssid
));
4097 wldev_iovar_setint(dev
, "closednet", enable
);
4100 #endif /* SUPPORT_HIDDEN_AP */
4102 #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
4104 wl_android_sta_diassoc(struct net_device
*dev
, const char* straddr
)
4109 DHD_INFO(("%s: deauth STA %s\n", __FUNCTION__
, straddr
));
4111 /* Unspecified reason */
4112 scbval
.val
= htod32(1);
4114 if (bcm_ether_atoe(straddr
, &scbval
.ea
) == 0) {
4115 DHD_ERROR(("%s: Invalid station MAC Address!!!\n", __FUNCTION__
));
4119 DHD_ERROR(("%s: deauth STA: "MACDBG
" scb_val.val %d\n", __FUNCTION__
,
4120 MAC2STRDBG(scbval
.ea
.octet
), scbval
.val
));
4122 error
= wldev_ioctl_set(dev
, WLC_SCB_DEAUTHENTICATE_FOR_REASON
, &scbval
,
4125 DHD_ERROR(("Fail to DEAUTH station, error = %d\n", error
));
4130 #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
4132 #ifdef SUPPORT_SET_LPC
4134 wl_android_set_lpc(struct net_device
*dev
, const char* string_num
)
4136 int lpc_enabled
, ret
;
4139 lpc_enabled
= bcm_atoi(string_num
);
4140 DHD_INFO(("%s : HAPD_LPC_ENABLED = %d\n", __FUNCTION__
, lpc_enabled
));
4142 ret
= wldev_ioctl_set(dev
, WLC_DOWN
, &val
, sizeof(s32
));
4144 DHD_ERROR(("WLC_DOWN error %d\n", ret
));
4146 wldev_iovar_setint(dev
, "lpc", lpc_enabled
);
4148 ret
= wldev_ioctl_set(dev
, WLC_UP
, &val
, sizeof(s32
));
4150 DHD_ERROR(("WLC_UP error %d\n", ret
));
4154 #endif /* SUPPORT_SET_LPC */
4157 wl_android_ch_res_rl(struct net_device
*dev
, bool change
)
4162 printk("%s enter\n", __FUNCTION__
);
4170 error
= wldev_ioctl_set(dev
, WLC_SET_SRL
, &srl
, sizeof(s32
));
4172 DHD_ERROR(("Failed to set SRL, error = %d\n", error
));
4174 #ifndef CUSTOM_LONG_RETRY_LIMIT
4175 error
= wldev_ioctl_set(dev
, WLC_SET_LRL
, &lrl
, sizeof(s32
));
4177 DHD_ERROR(("Failed to set LRL, error = %d\n", error
));
4179 #endif /* CUSTOM_LONG_RETRY_LIMIT */
4183 #ifdef SUPPORT_LTECX
4184 #define DEFAULT_WLANRX_PROT 1
4185 #define DEFAULT_LTERX_PROT 0
4186 #define DEFAULT_LTETX_ADV 1200
4189 wl_android_set_ltecx(struct net_device
*dev
, const char* string_num
)
4194 chan_bitmap
= bcm_strtoul(string_num
, NULL
, 16);
4196 DHD_INFO(("%s : LTECOEX 0x%x\n", __FUNCTION__
, chan_bitmap
));
4199 ret
= wldev_iovar_setint(dev
, "mws_coex_bitmap", chan_bitmap
);
4201 DHD_ERROR(("mws_coex_bitmap error %d\n", ret
));
4204 ret
= wldev_iovar_setint(dev
, "mws_wlanrx_prot", DEFAULT_WLANRX_PROT
);
4206 DHD_ERROR(("mws_wlanrx_prot error %d\n", ret
));
4209 ret
= wldev_iovar_setint(dev
, "mws_lterx_prot", DEFAULT_LTERX_PROT
);
4211 DHD_ERROR(("mws_lterx_prot error %d\n", ret
));
4214 ret
= wldev_iovar_setint(dev
, "mws_ltetx_adv", DEFAULT_LTETX_ADV
);
4216 DHD_ERROR(("mws_ltetx_adv error %d\n", ret
));
4219 ret
= wldev_iovar_setint(dev
, "mws_coex_bitmap", chan_bitmap
);
4221 if (ret
== BCME_UNSUPPORTED
) {
4222 DHD_ERROR(("LTECX_CHAN_BITMAP is UNSUPPORTED\n"));
4224 DHD_ERROR(("LTECX_CHAN_BITMAP error %d\n", ret
));
4230 #endif /* SUPPORT_LTECX */
4234 wl_android_rmc_enable(struct net_device
*net
, int rmc_enable
)
4238 err
= wldev_iovar_setint(net
, "rmc_ackreq", rmc_enable
);
4239 if (err
!= BCME_OK
) {
4240 DHD_ERROR(("%s: rmc_ackreq, error = %d\n", __FUNCTION__
, err
));
4246 wl_android_rmc_set_leader(struct net_device
*dev
, const char* straddr
)
4248 int error
= BCME_OK
;
4249 char smbuf
[WLC_IOCTL_SMLEN
];
4250 wl_rmc_entry_t rmc_entry
;
4251 DHD_INFO(("%s: Set new RMC leader %s\n", __FUNCTION__
, straddr
));
4253 memset(&rmc_entry
, 0, sizeof(wl_rmc_entry_t
));
4254 if (!bcm_ether_atoe(straddr
, &rmc_entry
.addr
)) {
4255 if (strlen(straddr
) == 1 && bcm_atoi(straddr
) == 0) {
4256 DHD_INFO(("%s: Set auto leader selection mode\n", __FUNCTION__
));
4257 memset(&rmc_entry
, 0, sizeof(wl_rmc_entry_t
));
4259 DHD_ERROR(("%s: No valid mac address provided\n",
4265 error
= wldev_iovar_setbuf(dev
, "rmc_ar", &rmc_entry
, sizeof(wl_rmc_entry_t
),
4266 smbuf
, sizeof(smbuf
), NULL
);
4268 if (error
!= BCME_OK
) {
4269 DHD_ERROR(("%s: Unable to set RMC leader, error = %d\n",
4270 __FUNCTION__
, error
));
4276 static int wl_android_set_rmc_event(struct net_device
*dev
, char *command
)
4281 if (sscanf(command
, CMD_SET_RMC_EVENT
" %d", &pid
) <= 0) {
4282 WL_ERR(("Failed to get Parameter from : %s\n", command
));
4286 /* set pid, and if the event was happened, let's send a notification through netlink */
4287 wl_cfg80211_set_rmc_pid(dev
, pid
);
4289 WL_DBG(("RMC pid=%d\n", pid
));
4293 #endif /* WL_RELMCAST */
4295 int wl_android_get_singlecore_scan(struct net_device
*dev
, char *command
, int total_len
)
4298 int bytes_written
= 0;
4301 error
= wldev_iovar_getint(dev
, "scan_ps", &mode
);
4303 DHD_ERROR(("%s: Failed to get single core scan Mode, error = %d\n",
4304 __FUNCTION__
, error
));
4308 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_SCSCAN
, mode
);
4310 return bytes_written
;
4313 int wl_android_set_singlecore_scan(struct net_device
*dev
, char *command
)
4318 if (sscanf(command
, "%*s %d", &mode
) != 1) {
4319 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
4323 error
= wldev_iovar_setint(dev
, "scan_ps", mode
);
4325 DHD_ERROR(("%s[1]: Failed to set Mode %d, error = %d\n",
4326 __FUNCTION__
, mode
, error
));
4332 #ifdef TEST_TX_POWER_CONTROL
4334 wl_android_set_tx_power(struct net_device
*dev
, const char* string_num
)
4338 enum nl80211_tx_power_setting type
;
4340 dbm
= bcm_atoi(string_num
);
4343 DHD_ERROR(("%s: dbm is negative...\n", __FUNCTION__
));
4348 type
= NL80211_TX_POWER_AUTOMATIC
;
4350 type
= NL80211_TX_POWER_FIXED
;
4352 err
= wl_set_tx_power(dev
, type
, dbm
);
4353 if (unlikely(err
)) {
4354 DHD_ERROR(("%s: error (%d)\n", __FUNCTION__
, err
));
4362 wl_android_get_tx_power(struct net_device
*dev
, char *command
, int total_len
)
4368 err
= wl_get_tx_power(dev
, &dbm
);
4369 if (unlikely(err
)) {
4370 DHD_ERROR(("%s: error (%d)\n", __FUNCTION__
, err
));
4374 bytes_written
= snprintf(command
, total_len
, "%s %d",
4375 CMD_TEST_GET_TX_POWER
, dbm
);
4377 DHD_ERROR(("%s: GET_TX_POWER: dBm=%d\n", __FUNCTION__
, dbm
));
4379 return bytes_written
;
4381 #endif /* TEST_TX_POWER_CONTROL */
4384 wl_android_set_sarlimit_txctrl(struct net_device
*dev
, const char* string_num
)
4388 s32 mode
= bcm_atoi(string_num
);
4390 /* As Samsung specific and their requirement, '0' means activate sarlimit
4391 * and '-1' means back to normal state (deactivate sarlimit)
4393 if (mode
>= 0 && mode
< 3) {
4394 DHD_INFO(("%s: SAR limit control activated mode = %d\n", __FUNCTION__
, mode
));
4396 } else if (mode
== -1) {
4397 DHD_INFO(("%s: SAR limit control deactivated\n", __FUNCTION__
));
4403 err
= wldev_iovar_setint(dev
, "sar_enable", setval
);
4404 if (unlikely(err
)) {
4405 DHD_ERROR(("%s: error (%d)\n", __FUNCTION__
, err
));
4411 #ifdef SUPPORT_SET_TID
4413 wl_android_set_tid(struct net_device
*dev
, char* command
)
4415 int err
= BCME_ERROR
;
4416 char *pos
= command
;
4421 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
4424 WL_ERR(("dhd is NULL\n"));
4428 WL_DBG(("%s: command[%s]\n", __FUNCTION__
, command
));
4431 token
= bcmstrtok(&pos
, " ", NULL
);
4433 token
= bcmstrtok(&pos
, " ", NULL
);
4435 WL_ERR(("Invalid arguments\n"));
4439 mode
= bcm_atoi(token
);
4441 if (mode
< SET_TID_OFF
|| mode
> SET_TID_BASED_ON_UID
) {
4442 WL_ERR(("Invalid arguments, mode %d\n", mode
));
4447 token
= bcmstrtok(&pos
, " ", NULL
);
4449 WL_ERR(("Invalid arguments for target uid\n"));
4453 uid
= bcm_atoi(token
);
4455 token
= bcmstrtok(&pos
, " ", NULL
);
4457 WL_ERR(("Invalid arguments for target tid\n"));
4461 prio
= bcm_atoi(token
);
4462 if (prio
>= 0 && prio
<= MAXPRIO
) {
4463 dhdp
->tid_mode
= mode
;
4464 dhdp
->target_uid
= uid
;
4465 dhdp
->target_tid
= prio
;
4467 WL_ERR(("Invalid arguments, prio %d\n", prio
));
4471 dhdp
->tid_mode
= SET_TID_OFF
;
4472 dhdp
->target_uid
= 0;
4473 dhdp
->target_tid
= 0;
4476 WL_DBG(("%s mode [%d], uid [%d], tid [%d]\n", __FUNCTION__
,
4477 dhdp
->tid_mode
, dhdp
->target_uid
, dhdp
->target_tid
));
4484 wl_android_get_tid(struct net_device
*dev
, char* command
, int total_len
)
4486 int bytes_written
= BCME_ERROR
;
4487 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
4490 WL_ERR(("dhd is NULL\n"));
4491 return bytes_written
;
4494 bytes_written
= snprintf(command
, total_len
, "mode %d uid %d tid %d",
4495 dhdp
->tid_mode
, dhdp
->target_uid
, dhdp
->target_tid
);
4497 WL_DBG(("%s: command results %s\n", __FUNCTION__
, command
));
4499 return bytes_written
;
4501 #endif /* SUPPORT_SET_TID */
4502 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
4504 int wl_android_set_roam_mode(struct net_device
*dev
, char *command
)
4509 if (sscanf(command
, "%*s %d", &mode
) != 1) {
4510 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
4514 error
= wldev_iovar_setint(dev
, "roam_off", mode
);
4516 DHD_ERROR(("%s: Failed to set roaming Mode %d, error = %d\n",
4517 __FUNCTION__
, mode
, error
));
4521 DHD_ERROR(("%s: succeeded to set roaming Mode %d, error = %d\n",
4522 __FUNCTION__
, mode
, error
));
4526 int wl_android_set_ibss_beacon_ouidata(struct net_device
*dev
, char *command
, int total_len
)
4528 char ie_buf
[VNDR_IE_MAX_LEN
];
4529 char *ioctl_buf
= NULL
;
4532 int ielen
= 0, datalen
= 0, idx
= 0, tot_len
= 0;
4533 vndr_ie_setbuf_t
*vndr_ie
= NULL
;
4536 s32 err
= BCME_OK
, bssidx
;
4537 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
4539 /* Check the VSIE (Vendor Specific IE) which was added.
4540 * If exist then send IOVAR to delete it
4542 if (wl_cfg80211_ibss_vsie_delete(dev
) != BCME_OK
) {
4546 if (total_len
< (strlen(CMD_SETIBSSBEACONOUIDATA
) + 1)) {
4547 WL_ERR(("error. total_len:%d\n", total_len
));
4551 pcmd
= command
+ strlen(CMD_SETIBSSBEACONOUIDATA
) + 1;
4552 for (idx
= 0; idx
< DOT11_OUI_LEN
; idx
++) {
4553 if (*pcmd
== '\0') {
4554 WL_ERR(("error while parsing OUI.\n"));
4559 ie_buf
[idx
] = (uint8
)simple_strtoul(hex
, NULL
, 16);
4562 while ((*pcmd
!= '\0') && (idx
< VNDR_IE_MAX_LEN
)) {
4565 ie_buf
[idx
++] = (uint8
)simple_strtoul(hex
, NULL
, 16);
4570 WL_ERR(("error. vndr ie len:%d\n", datalen
));
4574 tot_len
= (int)(sizeof(vndr_ie_setbuf_t
) + (datalen
- 1));
4575 vndr_ie
= (vndr_ie_setbuf_t
*)MALLOCZ(cfg
->osh
, tot_len
);
4577 WL_ERR(("IE memory alloc failed\n"));
4580 /* Copy the vndr_ie SET command ("add"/"del") to the buffer */
4581 strncpy(vndr_ie
->cmd
, "add", VNDR_IE_CMD_LEN
- 1);
4582 vndr_ie
->cmd
[VNDR_IE_CMD_LEN
- 1] = '\0';
4584 /* Set the IE count - the buffer contains only 1 IE */
4585 iecount
= htod32(1);
4586 memcpy((void *)&vndr_ie
->vndr_ie_buffer
.iecount
, &iecount
, sizeof(s32
));
4588 /* Set packet flag to indicate that BEACON's will contain this IE */
4589 pktflag
= htod32(VNDR_IE_BEACON_FLAG
| VNDR_IE_PRBRSP_FLAG
);
4590 memcpy((void *)&vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].pktflag
, &pktflag
,
4593 vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.id
= (uchar
) DOT11_MNG_PROPR_ID
;
4595 memcpy(&vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.oui
, &ie_buf
,
4597 memcpy(&vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.data
,
4598 &ie_buf
[DOT11_OUI_LEN
], datalen
);
4600 ielen
= DOT11_OUI_LEN
+ datalen
;
4601 vndr_ie
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.len
= (uchar
) ielen
;
4603 ioctl_buf
= (char *)MALLOC(cfg
->osh
, WLC_IOCTL_MEDLEN
);
4605 WL_ERR(("ioctl memory alloc failed\n"));
4607 MFREE(cfg
->osh
, vndr_ie
, tot_len
);
4611 memset(ioctl_buf
, 0, WLC_IOCTL_MEDLEN
); /* init the buffer */
4612 if ((bssidx
= wl_get_bssidx_by_wdev(cfg
, dev
->ieee80211_ptr
)) < 0) {
4613 WL_ERR(("Find index failed\n"));
4617 err
= wldev_iovar_setbuf_bsscfg(dev
, "vndr_ie", vndr_ie
, tot_len
, ioctl_buf
,
4618 WLC_IOCTL_MEDLEN
, bssidx
, &cfg
->ioctl_buf_sync
);
4620 if (err
!= BCME_OK
) {
4623 MFREE(cfg
->osh
, vndr_ie
, tot_len
);
4627 /* do NOT free 'vndr_ie' for the next process */
4628 wl_cfg80211_ibss_vsie_set_buffer(dev
, vndr_ie
, tot_len
);
4632 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
4638 #if defined(BCMFW_ROAM_ENABLE)
4640 wl_android_set_roampref(struct net_device
*dev
, char *command
, int total_len
)
4643 char smbuf
[WLC_IOCTL_SMLEN
];
4644 uint8 buf
[MAX_BUF_SIZE
];
4647 int num_ucipher_suites
= 0;
4648 int num_akm_suites
= 0;
4649 wpa_suite_t ucipher_suites
[MAX_NUM_SUITES
];
4650 wpa_suite_t akm_suites
[MAX_NUM_SUITES
];
4652 int total_bytes
= 0;
4657 pcmd
= command
+ strlen(CMD_SET_ROAMPREF
) + 1;
4658 total_len_left
= total_len
- strlen(CMD_SET_ROAMPREF
) + 1;
4660 num_akm_suites
= simple_strtoul(pcmd
, NULL
, 16);
4661 if (num_akm_suites
> MAX_NUM_SUITES
) {
4662 DHD_ERROR(("too many AKM suites = %d\n", num_akm_suites
));
4666 /* Increment for number of AKM suites field + space */
4668 total_len_left
-= 3;
4670 /* check to make sure pcmd does not overrun */
4671 if (total_len_left
< (num_akm_suites
* WIDTH_AKM_SUITE
))
4674 memset(buf
, 0, sizeof(buf
));
4675 memset(akm_suites
, 0, sizeof(akm_suites
));
4676 memset(ucipher_suites
, 0, sizeof(ucipher_suites
));
4678 /* Save the AKM suites passed in the command */
4679 for (i
= 0; i
< num_akm_suites
; i
++) {
4680 /* Store the MSB first, as required by join_pref */
4681 for (j
= 0; j
< 4; j
++) {
4684 buf
[j
] = (uint8
)simple_strtoul(hex
, NULL
, 16);
4686 memcpy((uint8
*)&akm_suites
[i
], buf
, sizeof(uint32
));
4689 total_len_left
-= (num_akm_suites
* WIDTH_AKM_SUITE
);
4690 num_ucipher_suites
= simple_strtoul(pcmd
, NULL
, 16);
4691 /* Increment for number of cipher suites field + space */
4693 total_len_left
-= 3;
4695 if (total_len_left
< (num_ucipher_suites
* WIDTH_AKM_SUITE
))
4698 /* Save the cipher suites passed in the command */
4699 for (i
= 0; i
< num_ucipher_suites
; i
++) {
4700 /* Store the MSB first, as required by join_pref */
4701 for (j
= 0; j
< 4; j
++) {
4704 buf
[j
] = (uint8
)simple_strtoul(hex
, NULL
, 16);
4706 memcpy((uint8
*)&ucipher_suites
[i
], buf
, sizeof(uint32
));
4709 /* Join preference for RSSI
4710 * Type : 1 byte (0x01)
4711 * Length : 1 byte (0x02)
4712 * Value : 2 bytes (reserved)
4714 *pref
++ = WL_JOIN_PREF_RSSI
;
4715 *pref
++ = JOIN_PREF_RSSI_LEN
;
4719 /* Join preference for WPA
4720 * Type : 1 byte (0x02)
4721 * Length : 1 byte (not used)
4722 * Value : (variable length)
4724 * count : 1 byte (no of tuples)
4732 num_tuples
= num_akm_suites
* num_ucipher_suites
;
4733 if (num_tuples
!= 0) {
4734 if (num_tuples
<= JOIN_PREF_MAX_WPA_TUPLES
) {
4735 *pref
++ = WL_JOIN_PREF_WPA
;
4738 *pref
++ = (uint8
)num_tuples
;
4739 total_bytes
= JOIN_PREF_RSSI_SIZE
+ JOIN_PREF_WPA_HDR_SIZE
+
4740 (JOIN_PREF_WPA_TUPLE_SIZE
* num_tuples
);
4742 DHD_ERROR(("%s: Too many wpa configs for join_pref \n", __FUNCTION__
));
4746 /* No WPA config, configure only RSSI preference */
4747 total_bytes
= JOIN_PREF_RSSI_SIZE
;
4750 /* akm-ucipher-mcipher tuples in the format required for join_pref */
4751 for (i
= 0; i
< num_ucipher_suites
; i
++) {
4752 for (j
= 0; j
< num_akm_suites
; j
++) {
4753 memcpy(pref
, (uint8
*)&akm_suites
[j
], WPA_SUITE_LEN
);
4754 pref
+= WPA_SUITE_LEN
;
4755 memcpy(pref
, (uint8
*)&ucipher_suites
[i
], WPA_SUITE_LEN
);
4756 pref
+= WPA_SUITE_LEN
;
4757 /* Set to 0 to match any available multicast cipher */
4758 memset(pref
, 0, WPA_SUITE_LEN
);
4759 pref
+= WPA_SUITE_LEN
;
4763 prhex("join pref", (uint8
*)buf
, total_bytes
);
4764 error
= wldev_iovar_setbuf(dev
, "join_pref", buf
, total_bytes
, smbuf
, sizeof(smbuf
), NULL
);
4766 DHD_ERROR(("Failed to set join_pref, error = %d\n", error
));
4770 #endif /* defined(BCMFW_ROAM_ENABLE */
4773 wl_android_iolist_add(struct net_device
*dev
, struct list_head
*head
, struct io_cfg
*config
)
4775 struct io_cfg
*resume_cfg
;
4777 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
4779 resume_cfg
= (struct io_cfg
*)MALLOCZ(cfg
->osh
, sizeof(struct io_cfg
));
4783 if (config
->iovar
) {
4784 ret
= wldev_iovar_getint(dev
, config
->iovar
, &resume_cfg
->param
);
4786 DHD_ERROR(("%s: Failed to get current %s value\n",
4787 __FUNCTION__
, config
->iovar
));
4791 ret
= wldev_iovar_setint(dev
, config
->iovar
, config
->param
);
4793 DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__
,
4794 config
->iovar
, config
->param
));
4798 resume_cfg
->iovar
= config
->iovar
;
4800 resume_cfg
->arg
= MALLOCZ(cfg
->osh
, config
->len
);
4801 if (!resume_cfg
->arg
) {
4805 ret
= wldev_ioctl_get(dev
, config
->ioctl
, resume_cfg
->arg
, config
->len
);
4807 DHD_ERROR(("%s: Failed to get ioctl %d\n", __FUNCTION__
,
4811 ret
= wldev_ioctl_set(dev
, config
->ioctl
+ 1, config
->arg
, config
->len
);
4813 DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__
,
4814 config
->iovar
, config
->param
));
4817 if (config
->ioctl
+ 1 == WLC_SET_PM
)
4818 wl_cfg80211_update_power_mode(dev
);
4819 resume_cfg
->ioctl
= config
->ioctl
;
4820 resume_cfg
->len
= config
->len
;
4823 list_add(&resume_cfg
->list
, head
);
4827 MFREE(cfg
->osh
, resume_cfg
->arg
, config
->len
);
4828 MFREE(cfg
->osh
, resume_cfg
, sizeof(struct io_cfg
));
4833 wl_android_iolist_resume(struct net_device
*dev
, struct list_head
*head
)
4835 struct io_cfg
*config
;
4836 struct list_head
*cur
, *q
;
4838 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
4840 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
4841 #pragma GCC diagnostic push
4842 #pragma GCC diagnostic ignored "-Wcast-qual"
4844 list_for_each_safe(cur
, q
, head
) {
4845 config
= list_entry(cur
, struct io_cfg
, list
);
4846 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
4847 #pragma GCC diagnostic pop
4849 if (config
->iovar
) {
4851 ret
= wldev_iovar_setint(dev
, config
->iovar
,
4855 ret
= wldev_ioctl_set(dev
, config
->ioctl
+ 1,
4856 config
->arg
, config
->len
);
4857 if (config
->ioctl
+ 1 == WLC_SET_PM
)
4858 wl_cfg80211_update_power_mode(dev
);
4859 MFREE(cfg
->osh
, config
->arg
, config
->len
);
4862 MFREE(cfg
->osh
, config
, sizeof(struct io_cfg
));
4866 wl_android_set_miracast(struct net_device
*dev
, char *command
)
4870 struct io_cfg config
;
4872 if (sscanf(command
, "%*s %d", &mode
) != 1) {
4873 DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__
));
4877 DHD_INFO(("%s: enter miracast mode %d\n", __FUNCTION__
, mode
));
4879 if (miracast_cur_mode
== mode
) {
4883 wl_android_iolist_resume(dev
, &miracast_resume_list
);
4884 miracast_cur_mode
= MIRACAST_MODE_OFF
;
4885 memset((void *)&config
, 0, sizeof(config
));
4887 case MIRACAST_MODE_SOURCE
:
4888 #ifdef MIRACAST_MCHAN_ALGO
4889 /* setting mchan_algo to platform specific value */
4890 config
.iovar
= "mchan_algo";
4892 ret
= wldev_ioctl_get(dev
, WLC_GET_BCNPRD
, &val
, sizeof(int));
4893 if (!ret
&& val
> 100) {
4895 DHD_ERROR(("%s: Connected station's beacon interval: "
4896 "%d and set mchan_algo to %d \n",
4897 __FUNCTION__
, val
, config
.param
));
4899 config
.param
= MIRACAST_MCHAN_ALGO
;
4901 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
4905 #endif /* MIRACAST_MCHAN_ALGO */
4907 #ifdef MIRACAST_MCHAN_BW
4908 /* setting mchan_bw to platform specific value */
4909 config
.iovar
= "mchan_bw";
4910 config
.param
= MIRACAST_MCHAN_BW
;
4911 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
4915 #endif /* MIRACAST_MCHAN_BW */
4917 #ifdef MIRACAST_AMPDU_SIZE
4918 /* setting apmdu to platform specific value */
4919 config
.iovar
= "ampdu_mpdu";
4920 config
.param
= MIRACAST_AMPDU_SIZE
;
4921 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
4925 #endif /* MIRACAST_AMPDU_SIZE */
4927 /* Source mode shares most configurations with sink mode.
4928 * Fall through here to avoid code duplication
4930 case MIRACAST_MODE_SINK
:
4931 /* disable internal roaming */
4932 config
.iovar
= "roam_off";
4936 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
4942 ret
= wldev_ioctl_get(dev
, WLC_GET_PM
, &val
, sizeof(val
));
4947 if (val
!= PM_OFF
) {
4949 config
.iovar
= NULL
;
4950 config
.ioctl
= WLC_GET_PM
;
4952 config
.len
= sizeof(int);
4953 ret
= wl_android_iolist_add(dev
, &miracast_resume_list
, &config
);
4959 case MIRACAST_MODE_OFF
:
4963 miracast_cur_mode
= mode
;
4968 DHD_ERROR(("%s: turnoff miracast mode because of err%d\n", __FUNCTION__
, ret
));
4969 wl_android_iolist_resume(dev
, &miracast_resume_list
);
4973 #define NETLINK_OXYGEN 30
4974 #define AIBSS_BEACON_TIMEOUT 10
4976 static struct sock
*nl_sk
= NULL
;
4978 static void wl_netlink_recv(struct sk_buff
*skb
)
4980 WL_ERR(("netlink_recv called\n"));
4983 static int wl_netlink_init(void)
4985 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4986 struct netlink_kernel_cfg cfg
= {
4987 .input
= wl_netlink_recv
,
4991 if (nl_sk
!= NULL
) {
4992 WL_ERR(("nl_sk already exist\n"));
4996 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
4997 nl_sk
= netlink_kernel_create(&init_net
, NETLINK_OXYGEN
,
4998 0, wl_netlink_recv
, NULL
, THIS_MODULE
);
4999 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
5000 nl_sk
= netlink_kernel_create(&init_net
, NETLINK_OXYGEN
, THIS_MODULE
, &cfg
);
5002 nl_sk
= netlink_kernel_create(&init_net
, NETLINK_OXYGEN
, &cfg
);
5005 if (nl_sk
== NULL
) {
5006 WL_ERR(("nl_sk is not ready\n"));
5013 static void wl_netlink_deinit(void)
5016 netlink_kernel_release(nl_sk
);
5022 wl_netlink_send_msg(int pid
, int type
, int seq
, const void *data
, size_t size
)
5024 struct sk_buff
*skb
= NULL
;
5025 struct nlmsghdr
*nlh
= NULL
;
5028 if (nl_sk
== NULL
) {
5029 WL_ERR(("nl_sk was not initialized\n"));
5033 skb
= alloc_skb(NLMSG_SPACE(size
), GFP_ATOMIC
);
5035 WL_ERR(("failed to allocate memory\n"));
5039 nlh
= nlmsg_put(skb
, 0, 0, 0, size
, 0);
5041 WL_ERR(("failed to build nlmsg, skb_tailroom:%d, nlmsg_total_size:%d\n",
5042 skb_tailroom(skb
), nlmsg_total_size(size
)));
5047 memcpy(nlmsg_data(nlh
), data
, size
);
5048 nlh
->nlmsg_seq
= seq
;
5049 nlh
->nlmsg_type
= type
;
5051 /* netlink_unicast() takes ownership of the skb and frees it itself. */
5052 ret
= netlink_unicast(nl_sk
, skb
, pid
, 0);
5053 WL_DBG(("netlink_unicast() pid=%d, ret=%d\n", pid
, ret
));
5060 static int wl_android_set_ibss_txfail_event(struct net_device
*dev
, char *command
, int total_len
)
5065 aibss_txfail_config_t txfail_config
= {0, 0, 0, 0, 0};
5066 char smbuf
[WLC_IOCTL_SMLEN
];
5068 if (sscanf(command
, CMD_SETIBSSTXFAILEVENT
" %d %d", &retry
, &pid
) <= 0) {
5069 WL_ERR(("Failed to get Parameter from : %s\n", command
));
5073 /* set pid, and if the event was happened, let's send a notification through netlink */
5074 wl_cfg80211_set_txfail_pid(dev
, pid
);
5077 /* using same pid for RMC, AIBSS shares same pid with RMC and it is set once */
5078 wl_cfg80211_set_rmc_pid(dev
, pid
);
5079 #endif /* WL_RELMCAST */
5081 /* If retry value is 0, it disables the functionality for TX Fail. */
5083 txfail_config
.max_tx_retry
= retry
;
5084 txfail_config
.bcn_timeout
= 0; /* 0 : disable tx fail from beacon */
5086 txfail_config
.version
= AIBSS_TXFAIL_CONFIG_VER_0
;
5087 txfail_config
.len
= sizeof(txfail_config
);
5089 err
= wldev_iovar_setbuf(dev
, "aibss_txfail_config", (void *) &txfail_config
,
5090 sizeof(aibss_txfail_config_t
), smbuf
, WLC_IOCTL_SMLEN
, NULL
);
5091 WL_DBG(("retry=%d, pid=%d, err=%d\n", retry
, pid
, err
));
5093 return ((err
== 0)?total_len
:err
);
5096 static int wl_android_get_ibss_peer_info(struct net_device
*dev
, char *command
,
5097 int total_len
, bool bAll
)
5100 int bytes_written
= 0;
5102 bss_peer_list_info_t peer_list_info
;
5103 bss_peer_info_t
*peer_info
;
5106 struct ether_addr mac_ea
;
5107 char *str
= command
;
5108 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5110 WL_DBG(("get ibss peer info(%s)\n", bAll
?"true":"false"));
5113 if (bcmstrtok(&str
, " ", NULL
) == NULL
) {
5114 WL_ERR(("invalid command\n"));
5118 if (!str
|| !bcm_ether_atoe(str
, &mac_ea
)) {
5119 WL_ERR(("invalid MAC address\n"));
5124 buf
= MALLOC(cfg
->osh
, WLC_IOCTL_MAXLEN
);
5126 WL_ERR(("MALLOC failed\n"));
5130 error
= wldev_iovar_getbuf(dev
, "bss_peer_info", NULL
, 0, buf
, WLC_IOCTL_MAXLEN
, NULL
);
5131 if (unlikely(error
)) {
5132 WL_ERR(("could not get ibss peer info (%d)\n", error
));
5133 MFREE(cfg
->osh
, buf
, WLC_IOCTL_MAXLEN
);
5137 memcpy(&peer_list_info
, buf
, sizeof(peer_list_info
));
5138 peer_list_info
.version
= htod16(peer_list_info
.version
);
5139 peer_list_info
.bss_peer_info_len
= htod16(peer_list_info
.bss_peer_info_len
);
5140 peer_list_info
.count
= htod32(peer_list_info
.count
);
5142 WL_DBG(("ver:%d, len:%d, count:%d\n", peer_list_info
.version
,
5143 peer_list_info
.bss_peer_info_len
, peer_list_info
.count
));
5145 if (peer_list_info
.count
> 0) {
5147 bytes_written
+= snprintf(&command
[bytes_written
], total_len
, "%u ",
5148 peer_list_info
.count
);
5150 peer_info
= (bss_peer_info_t
*) ((char *)buf
+ BSS_PEER_LIST_INFO_FIXED_LEN
);
5152 for (i
= 0; i
< peer_list_info
.count
; i
++) {
5154 WL_DBG(("index:%d rssi:%d, tx:%u, rx:%u\n", i
, peer_info
->rssi
,
5155 peer_info
->tx_rate
, peer_info
->rx_rate
));
5158 memcmp(&mac_ea
, &peer_info
->ea
, sizeof(struct ether_addr
)) == 0) {
5162 if (bAll
|| found
) {
5163 bytes_written
+= snprintf(&command
[bytes_written
],
5164 total_len
- bytes_written
,
5165 MACF
" %u %d ", ETHER_TO_MACF(peer_info
->ea
),
5166 peer_info
->tx_rate
/1000, peer_info
->rssi
);
5167 if (bytes_written
>= total_len
) {
5168 WL_ERR(("%s: Insufficient memory, %d bytes\n",
5169 __FUNCTION__
, total_len
));
5178 peer_info
= (bss_peer_info_t
*)((char *)peer_info
+sizeof(bss_peer_info_t
));
5182 WL_ERR(("could not get ibss peer info : no item\n"));
5184 WL_DBG(("command(%u):%s\n", total_len
, command
));
5185 WL_DBG(("bytes_written:%d\n", bytes_written
));
5187 MFREE(cfg
->osh
, buf
, WLC_IOCTL_MAXLEN
);
5188 return bytes_written
;
5191 int wl_android_set_ibss_routetable(struct net_device
*dev
, char *command
)
5194 char *pcmd
= command
;
5196 ibss_route_tbl_t
*route_tbl
= NULL
;
5197 char *ioctl_buf
= NULL
;
5199 uint32 route_tbl_len
;
5203 struct ipv4_addr dipaddr
;
5204 struct ether_addr ea
;
5205 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5207 route_tbl_len
= sizeof(ibss_route_tbl_t
) +
5208 (MAX_IBSS_ROUTE_TBL_ENTRY
- 1) * sizeof(ibss_route_entry_t
);
5209 route_tbl
= (ibss_route_tbl_t
*)MALLOCZ(cfg
->osh
, route_tbl_len
);
5211 WL_ERR(("Route TBL alloc failed\n"));
5214 ioctl_buf
= (char *)MALLOCZ(cfg
->osh
, WLC_IOCTL_MEDLEN
);
5216 WL_ERR(("ioctl memory alloc failed\n"));
5218 MFREE(cfg
->osh
, route_tbl
, route_tbl_len
);
5222 memset(ioctl_buf
, 0, WLC_IOCTL_MEDLEN
);
5225 str
= bcmstrtok(&pcmd
, " ", NULL
);
5228 str
= bcmstrtok(&pcmd
, " ", NULL
);
5230 WL_ERR(("Invalid number parameter %s\n", str
));
5234 entries
= bcm_strtoul(str
, &endptr
, 0);
5235 if (*endptr
!= '\0') {
5236 WL_ERR(("Invalid number parameter %s\n", str
));
5240 if (entries
> MAX_IBSS_ROUTE_TBL_ENTRY
) {
5241 WL_ERR(("Invalid entries number %u\n", entries
));
5246 WL_INFORM(("Routing table count:%u\n", entries
));
5247 route_tbl
->num_entry
= entries
;
5249 for (i
= 0; i
< entries
; i
++) {
5250 str
= bcmstrtok(&pcmd
, " ", NULL
);
5251 if (!str
|| !bcm_atoipv4(str
, &dipaddr
)) {
5252 WL_ERR(("Invalid ip string %s\n", str
));
5257 str
= bcmstrtok(&pcmd
, " ", NULL
);
5258 if (!str
|| !bcm_ether_atoe(str
, &ea
)) {
5259 WL_ERR(("Invalid ethernet string %s\n", str
));
5263 bcopy(&dipaddr
, &route_tbl
->route_entry
[i
].ipv4_addr
, IPV4_ADDR_LEN
);
5264 bcopy(&ea
, &route_tbl
->route_entry
[i
].nexthop
, ETHER_ADDR_LEN
);
5267 route_tbl_len
= sizeof(ibss_route_tbl_t
) +
5268 ((!entries
?0:(entries
- 1)) * sizeof(ibss_route_entry_t
));
5269 err
= wldev_iovar_setbuf(dev
, "ibss_route_tbl",
5270 route_tbl
, route_tbl_len
, ioctl_buf
, WLC_IOCTL_MEDLEN
, NULL
);
5271 if (err
!= BCME_OK
) {
5272 WL_ERR(("Fail to set iovar %d\n", err
));
5278 MFREE(cfg
->osh
, route_tbl
, sizeof(ibss_route_tbl_t
) +
5279 (MAX_IBSS_ROUTE_TBL_ENTRY
- 1) * sizeof(ibss_route_entry_t
));
5282 MFREE(cfg
->osh
, ioctl_buf
, WLC_IOCTL_MEDLEN
);
5289 wl_android_set_ibss_ampdu(struct net_device
*dev
, char *command
, int total_len
)
5291 char *pcmd
= command
;
5292 char *str
= NULL
, *endptr
= NULL
;
5293 struct ampdu_aggr aggr
;
5294 char smbuf
[WLC_IOCTL_SMLEN
];
5297 int wme_AC2PRIO
[AC_COUNT
][2] = {
5298 {PRIO_8021D_VO
, PRIO_8021D_NC
}, /* AC_VO - 3 */
5299 {PRIO_8021D_CL
, PRIO_8021D_VI
}, /* AC_VI - 2 */
5300 {PRIO_8021D_BK
, PRIO_8021D_NONE
}, /* AC_BK - 1 */
5301 {PRIO_8021D_BE
, PRIO_8021D_EE
}}; /* AC_BE - 0 */
5303 WL_DBG(("set ibss ampdu:%s\n", command
));
5305 memset(&aggr
, 0, sizeof(aggr
));
5306 /* Cofigure all priorities */
5307 aggr
.conf_TID_bmap
= NBITMASK(NUMPRIO
);
5309 /* acquire parameters */
5311 str
= bcmstrtok(&pcmd
, " ", NULL
);
5313 for (idx
= 0; idx
< AC_COUNT
; idx
++) {
5315 str
= bcmstrtok(&pcmd
, " ", NULL
);
5317 WL_ERR(("Invalid parameter : %s\n", pcmd
));
5320 on
= bcm_strtoul(str
, &endptr
, 0) ? TRUE
: FALSE
;
5321 if (*endptr
!= '\0') {
5322 WL_ERR(("Invalid number format %s\n", str
));
5326 setbit(&aggr
.enab_TID_bmap
, wme_AC2PRIO
[idx
][0]);
5327 setbit(&aggr
.enab_TID_bmap
, wme_AC2PRIO
[idx
][1]);
5331 err
= wldev_iovar_setbuf(dev
, "ampdu_txaggr", (void *)&aggr
,
5332 sizeof(aggr
), smbuf
, WLC_IOCTL_SMLEN
, NULL
);
5334 return ((err
== 0) ? total_len
: err
);
5337 int wl_android_set_ibss_antenna(struct net_device
*dev
, char *command
, int total_len
)
5339 char *pcmd
= command
;
5341 int txchain
, rxchain
;
5344 WL_DBG(("set ibss antenna:%s\n", command
));
5346 /* acquire parameters */
5348 str
= bcmstrtok(&pcmd
, " ", NULL
);
5351 str
= bcmstrtok(&pcmd
, " ", NULL
);
5353 WL_ERR(("Invalid parameter : %s\n", pcmd
));
5356 txchain
= bcm_atoi(str
);
5359 str
= bcmstrtok(&pcmd
, " ", NULL
);
5361 WL_ERR(("Invalid parameter : %s\n", pcmd
));
5364 rxchain
= bcm_atoi(str
);
5366 err
= wldev_iovar_setint(dev
, "txchain", txchain
);
5369 err
= wldev_iovar_setint(dev
, "rxchain", rxchain
);
5370 return ((err
== 0)?total_len
:err
);
5372 #endif /* WLAIBSS */
5374 int wl_keep_alive_set(struct net_device
*dev
, char* extra
)
5376 wl_mkeep_alive_pkt_t mkeep_alive_pkt
;
5378 uint period_msec
= 0;
5380 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5382 if (extra
== NULL
) {
5383 DHD_ERROR(("%s: extra is NULL\n", __FUNCTION__
));
5386 if (sscanf(extra
, "%d", &period_msec
) != 1) {
5387 DHD_ERROR(("%s: sscanf error. check period_msec value\n", __FUNCTION__
));
5390 DHD_ERROR(("%s: period_msec is %d\n", __FUNCTION__
, period_msec
));
5392 memset(&mkeep_alive_pkt
, 0, sizeof(wl_mkeep_alive_pkt_t
));
5394 mkeep_alive_pkt
.period_msec
= period_msec
;
5395 mkeep_alive_pkt
.version
= htod16(WL_MKEEP_ALIVE_VERSION
);
5396 mkeep_alive_pkt
.length
= htod16(WL_MKEEP_ALIVE_FIXED_LEN
);
5398 /* Setup keep alive zero for null packet generation */
5399 mkeep_alive_pkt
.keep_alive_id
= 0;
5400 mkeep_alive_pkt
.len_bytes
= 0;
5402 buf
= (char *)MALLOC(cfg
->osh
, WLC_IOCTL_SMLEN
);
5404 DHD_ERROR(("%s: buffer alloc failed\n", __FUNCTION__
));
5407 ret
= wldev_iovar_setbuf(dev
, "mkeep_alive", (char *)&mkeep_alive_pkt
,
5408 WL_MKEEP_ALIVE_FIXED_LEN
, buf
, WLC_IOCTL_SMLEN
, NULL
);
5410 DHD_ERROR(("%s:keep_alive set failed:%d\n", __FUNCTION__
, ret
));
5412 DHD_TRACE(("%s:keep_alive set ok\n", __FUNCTION__
));
5413 MFREE(cfg
->osh
, buf
, WLC_IOCTL_SMLEN
);
5416 #ifdef P2PRESP_WFDIE_SRC
5417 static int wl_android_get_wfdie_resp(struct net_device
*dev
, char *command
, int total_len
)
5420 int bytes_written
= 0;
5421 int only_resp_wfdsrc
= 0;
5423 error
= wldev_iovar_getint(dev
, "p2p_only_resp_wfdsrc", &only_resp_wfdsrc
);
5425 DHD_ERROR(("%s: Failed to get the mode for only_resp_wfdsrc, error = %d\n",
5426 __FUNCTION__
, error
));
5430 bytes_written
= snprintf(command
, total_len
, "%s %d",
5431 CMD_P2P_GET_WFDIE_RESP
, only_resp_wfdsrc
);
5433 return bytes_written
;
5436 static int wl_android_set_wfdie_resp(struct net_device
*dev
, int only_resp_wfdsrc
)
5440 error
= wldev_iovar_setint(dev
, "p2p_only_resp_wfdsrc", only_resp_wfdsrc
);
5442 DHD_ERROR(("%s: Failed to set only_resp_wfdsrc %d, error = %d\n",
5443 __FUNCTION__
, only_resp_wfdsrc
, error
));
5449 #endif /* P2PRESP_WFDIE_SRC */
5451 #ifdef BT_WIFI_HANDOVER
5453 wl_tbow_teardown(struct net_device
*dev
)
5456 char buf
[WLC_IOCTL_SMLEN
];
5457 tbow_setup_netinfo_t netinfo
;
5458 memset(&netinfo
, 0, sizeof(netinfo
));
5459 netinfo
.opmode
= TBOW_HO_MODE_TEARDOWN
;
5461 err
= wldev_iovar_setbuf_bsscfg(dev
, "tbow_doho", &netinfo
,
5462 sizeof(tbow_setup_netinfo_t
), buf
, WLC_IOCTL_SMLEN
, 0, NULL
);
5464 WL_ERR(("tbow_doho iovar error %d\n", err
));
5469 #endif /* BT_WIFI_HANOVER */
5473 wl_android_set_rps_cpus(struct net_device
*dev
, char *command
)
5477 enable
= command
[strlen(CMD_RPSMODE
) + 1] - '0';
5478 error
= dhd_rps_cpus_enable(dev
, enable
);
5480 #if defined(DHDTCPACK_SUPPRESS) && defined(BCMPCIE) && defined(WL_CFG80211)
5482 void *dhdp
= wl_cfg80211_get_dhdp(net
);
5484 DHD_TRACE(("%s : set ack suppress. TCPACK_SUP_HOLD.\n", __FUNCTION__
));
5485 dhd_tcpack_suppress_set(dhdp
, TCPACK_SUP_HOLD
);
5487 DHD_TRACE(("%s : clear ack suppress.\n", __FUNCTION__
));
5488 dhd_tcpack_suppress_set(dhdp
, TCPACK_SUP_OFF
);
5491 #endif /* DHDTCPACK_SUPPRESS && BCMPCIE && WL_CFG80211 */
5495 #endif /* SET_RPS_CPUS */
5497 static int wl_android_get_link_status(struct net_device
*dev
, char *command
,
5500 int bytes_written
, error
, result
= 0, single_stream
, stf
= -1, i
, nss
= 0, mcs_map
;
5504 int datalen
= sizeof(uint32
) + sizeof(wl_bss_info_t
);
5507 memset(buf
, 0, datalen
);
5508 /* get BSS information */
5509 *(u32
*) buf
= htod32(datalen
);
5510 error
= wldev_ioctl_get(dev
, WLC_GET_BSS_INFO
, (void *)buf
, datalen
);
5511 if (unlikely(error
)) {
5512 WL_ERR(("Could not get bss info %d\n", error
));
5516 bi
= (wl_bss_info_t
*) (buf
+ sizeof(uint32
));
5518 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++) {
5519 if (bi
->BSSID
.octet
[i
] > 0) {
5524 if (i
== ETHER_ADDR_LEN
) {
5525 WL_DBG(("No BSSID\n"));
5529 /* check VHT capability at beacon */
5531 if (CHSPEC_IS5G(bi
->chanspec
)) {
5532 result
|= WL_ANDROID_LINK_AP_VHT_SUPPORT
;
5536 /* get a rspec (radio spectrum) rate */
5537 error
= wldev_iovar_getint(dev
, "nrate", &rspec
);
5538 if (unlikely(error
) || rspec
== 0) {
5539 WL_ERR(("get link status error (%d)\n", error
));
5543 encode
= (rspec
& WL_RSPEC_ENCODING_MASK
);
5544 txexp
= (rspec
& WL_RSPEC_TXEXP_MASK
) >> WL_RSPEC_TXEXP_SHIFT
;
5547 case WL_RSPEC_ENCODE_HT
:
5548 /* check Rx MCS Map for HT */
5549 for (i
= 0; i
< MAX_STREAMS_SUPPORTED
; i
++) {
5551 if (i
== MAX_STREAMS_SUPPORTED
-1) {
5554 if (bi
->basic_mcs
[i
] & bitmap
) {
5559 case WL_RSPEC_ENCODE_VHT
:
5560 /* check Rx MCS Map for VHT */
5561 for (i
= 1; i
<= VHT_CAP_MCS_MAP_NSS_MAX
; i
++) {
5562 mcs_map
= VHT_MCS_MAP_GET_MCS_PER_SS(i
, dtoh16(bi
->vht_rxmcsmap
));
5563 if (mcs_map
!= VHT_CAP_MCS_MAP_NONE
) {
5570 /* check MIMO capability with nss in beacon */
5572 result
|= WL_ANDROID_LINK_AP_MIMO_SUPPORT
;
5575 single_stream
= (encode
== WL_RSPEC_ENCODE_RATE
) ||
5576 ((encode
== WL_RSPEC_ENCODE_HT
) && (rspec
& WL_RSPEC_HT_MCS_MASK
) < 8) ||
5577 ((encode
== WL_RSPEC_ENCODE_VHT
) &&
5578 ((rspec
& WL_RSPEC_VHT_NSS_MASK
) >> WL_RSPEC_VHT_NSS_SHIFT
) == 1);
5581 if ((rspec
& WL_RSPEC_STBC
) && single_stream
) {
5582 stf
= OLD_NRATE_STF_STBC
;
5584 stf
= (single_stream
) ? OLD_NRATE_STF_SISO
: OLD_NRATE_STF_SDM
;
5586 } else if (txexp
== 1 && single_stream
) {
5587 stf
= OLD_NRATE_STF_CDD
;
5590 /* check 11ac (VHT) */
5591 if (encode
== WL_RSPEC_ENCODE_VHT
) {
5592 if (CHSPEC_IS5G(bi
->chanspec
)) {
5593 result
|= WL_ANDROID_LINK_VHT
;
5598 if (result
& WL_ANDROID_LINK_AP_MIMO_SUPPORT
) {
5600 case OLD_NRATE_STF_SISO
:
5602 case OLD_NRATE_STF_CDD
:
5603 case OLD_NRATE_STF_STBC
:
5604 result
|= WL_ANDROID_LINK_MIMO
;
5606 case OLD_NRATE_STF_SDM
:
5607 if (!single_stream
) {
5608 result
|= WL_ANDROID_LINK_MIMO
;
5614 WL_DBG(("%s:result=%d, stf=%d, single_stream=%d, mcs map=%d\n",
5615 __FUNCTION__
, result
, stf
, single_stream
, nss
));
5617 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_LINK_STATUS
, result
);
5619 return bytes_written
;
5622 #ifdef P2P_LISTEN_OFFLOADING
5625 wl_cfg80211_p2plo_deinit(struct bcm_cfg80211
*cfg
)
5629 int p2plo_pause
= 0;
5630 dhd_pub_t
*dhd
= NULL
;
5631 if (!cfg
|| !cfg
->p2p
) {
5632 WL_ERR(("Wl %p or cfg->p2p %p is null\n",
5633 cfg
, cfg
? cfg
->p2p
: 0));
5637 dhd
= (dhd_pub_t
*)(cfg
->pub
);
5639 WL_ERR(("bus is already down\n"));
5643 bssidx
= wl_to_p2p_bss_bssidx(cfg
, P2PAPI_BSSCFG_DEVICE
);
5644 ret
= wldev_iovar_setbuf_bsscfg(bcmcfg_to_prmry_ndev(cfg
),
5645 "p2po_stop", (void*)&p2plo_pause
, sizeof(p2plo_pause
),
5646 cfg
->ioctl_buf
, WLC_IOCTL_SMLEN
, bssidx
, &cfg
->ioctl_buf_sync
);
5648 WL_ERR(("p2po_stop Failed :%d\n", ret
));
5654 wl_cfg80211_p2plo_listen_start(struct net_device
*dev
, u8
*buf
, int len
)
5656 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5657 s32 bssidx
= wl_to_p2p_bss_bssidx(cfg
, P2PAPI_BSSCFG_DEVICE
);
5658 wl_p2plo_listen_t p2plo_listen
;
5664 if (WL_DRV_STATUS_SENDING_AF_FRM_EXT(cfg
)) {
5665 WL_ERR(("Sending Action Frames. Try it again.\n"));
5669 if (wl_get_drv_status_all(cfg
, SCANNING
)) {
5670 WL_ERR(("Scanning already\n"));
5674 if (wl_get_drv_status(cfg
, SCAN_ABORTING
, dev
)) {
5675 WL_ERR(("Scanning being aborted\n"));
5679 if (wl_get_p2p_status(cfg
, DISC_IN_PROGRESS
)) {
5680 WL_ERR(("p2p listen offloading already running\n"));
5684 /* Just in case if it is not enabled */
5685 if ((ret
= wl_cfgp2p_enable_discovery(cfg
, dev
, NULL
, 0)) < 0) {
5686 WL_ERR(("cfgp2p_enable discovery failed"));
5690 bzero(&p2plo_listen
, sizeof(wl_p2plo_listen_t
));
5693 sscanf(buf
, " %10d %10d %10d %10d", &channel
, &period
, &interval
, &count
);
5694 if ((channel
== 0) || (period
== 0) ||
5695 (interval
== 0) || (count
== 0)) {
5696 WL_ERR(("Wrong argument %d/%d/%d/%d \n",
5697 channel
, period
, interval
, count
));
5701 p2plo_listen
.period
= period
;
5702 p2plo_listen
.interval
= interval
;
5703 p2plo_listen
.count
= count
;
5705 WL_ERR(("channel:%d period:%d, interval:%d count:%d\n",
5706 channel
, period
, interval
, count
));
5708 WL_ERR(("Argument len is wrong.\n"));
5713 if ((ret
= wldev_iovar_setbuf_bsscfg(dev
, "p2po_listen_channel", (void*)&channel
,
5714 sizeof(channel
), cfg
->ioctl_buf
, WLC_IOCTL_SMLEN
,
5715 bssidx
, &cfg
->ioctl_buf_sync
)) < 0) {
5716 WL_ERR(("p2po_listen_channel Failed :%d\n", ret
));
5720 if ((ret
= wldev_iovar_setbuf_bsscfg(dev
, "p2po_listen", (void*)&p2plo_listen
,
5721 sizeof(wl_p2plo_listen_t
), cfg
->ioctl_buf
, WLC_IOCTL_SMLEN
,
5722 bssidx
, &cfg
->ioctl_buf_sync
)) < 0) {
5723 WL_ERR(("p2po_listen Failed :%d\n", ret
));
5727 wl_set_p2p_status(cfg
, DISC_IN_PROGRESS
);
5732 wl_cfg80211_p2plo_listen_stop(struct net_device
*dev
)
5734 struct bcm_cfg80211
*cfg
= wl_get_cfg(dev
);
5735 s32 bssidx
= wl_to_p2p_bss_bssidx(cfg
, P2PAPI_BSSCFG_DEVICE
);
5738 if ((ret
= wldev_iovar_setbuf_bsscfg(dev
, "p2po_stop", NULL
,
5739 0, cfg
->ioctl_buf
, WLC_IOCTL_SMLEN
,
5740 bssidx
, &cfg
->ioctl_buf_sync
)) < 0) {
5741 WL_ERR(("p2po_stop Failed :%d\n", ret
));
5750 wl_cfg80211_p2plo_offload(struct net_device
*dev
, char *cmd
, char* buf
, int len
)
5754 WL_ERR(("Entry cmd:%s arg_len:%d \n", cmd
, len
));
5756 if (strncmp(cmd
, "P2P_LO_START", strlen("P2P_LO_START")) == 0) {
5757 ret
= wl_cfg80211_p2plo_listen_start(dev
, buf
, len
);
5758 } else if (strncmp(cmd
, "P2P_LO_STOP", strlen("P2P_LO_STOP")) == 0) {
5759 ret
= wl_cfg80211_p2plo_listen_stop(dev
);
5761 WL_ERR(("Request for Unsupported CMD:%s \n", buf
));
5766 #endif /* P2P_LISTEN_OFFLOADING */
5768 #ifdef DYNAMIC_MUMIMO_CONTROL
5770 wl_android_get_murx_bfe_cap(struct net_device
*dev
, char *command
, int total_len
)
5774 int bytes_written
= 0;
5776 /* Now there is only single interface */
5777 err
= wl_get_murx_bfe_cap(dev
, &cap
);
5778 if (unlikely(err
)) {
5779 WL_ERR(("Failed to get murx_bfe_cap, error = %d\n", err
));
5783 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_MURX_BFE_CAP
, cap
);
5785 return bytes_written
;
5789 wl_android_set_murx_bfe_cap(struct net_device
*dev
, int val
)
5793 err
= wl_set_murx_bfe_cap(dev
, val
, TRUE
);
5794 if (unlikely(err
)) {
5795 WL_ERR(("Failed to set murx_bfe_cap to %d, error = %d\n", val
, err
));
5802 wl_android_get_bss_support_mumimo(struct net_device
*dev
, char *command
, int total_len
)
5805 int bytes_written
= 0;
5807 val
= wl_check_bss_support_mumimo(dev
);
5808 bytes_written
= snprintf(command
, total_len
, "%s %d", CMD_GET_BSS_SUPPORT_MUMIMO
, val
);
5810 return bytes_written
;
5812 #endif /* DYNAMIC_MUMIMO_CONTROL */
5814 #ifdef SUPPORT_RSSI_SUM_REPORT
5816 wl_android_get_rssi_per_ant(struct net_device
*dev
, char *command
, int total_len
)
5818 wl_rssi_ant_mimo_t rssi_ant_mimo
;
5819 char *ifname
= NULL
;
5820 char *peer_mac
= NULL
;
5821 char *mimo_cmd
= "mimo";
5824 int bytes_written
= 0;
5825 bool mimo_rssi
= FALSE
;
5827 memset(&rssi_ant_mimo
, 0, sizeof(wl_rssi_ant_mimo_t
));
5829 * STA I/F: DRIVER GET_RSSI_PER_ANT <ifname> <mimo>
5830 * AP/GO I/F: DRIVER GET_RSSI_PER_ANT <ifname> <Peer MAC addr> <mimo>
5835 token
= bcmstrtok(&pos
, " ", NULL
);
5837 /* get the interface name */
5838 token
= bcmstrtok(&pos
, " ", NULL
);
5840 WL_ERR(("Invalid arguments\n"));
5845 /* Optional: Check the MIMO RSSI mode or peer MAC address */
5846 token
= bcmstrtok(&pos
, " ", NULL
);
5848 /* Check the MIMO RSSI mode */
5849 if (strncmp(token
, mimo_cmd
, strlen(mimo_cmd
)) == 0) {
5856 /* Optional: Check the MIMO RSSI mode - RSSI sum across antennas */
5857 token
= bcmstrtok(&pos
, " ", NULL
);
5858 if (token
&& strncmp(token
, mimo_cmd
, strlen(mimo_cmd
)) == 0) {
5862 err
= wl_get_rssi_per_ant(dev
, ifname
, peer_mac
, &rssi_ant_mimo
);
5863 if (unlikely(err
)) {
5864 WL_ERR(("Failed to get RSSI info, err=%d\n", err
));
5868 /* Parse the results */
5869 WL_DBG(("ifname %s, version %d, count %d, mimo rssi %d\n",
5870 ifname
, rssi_ant_mimo
.version
, rssi_ant_mimo
.count
, mimo_rssi
));
5872 WL_DBG(("MIMO RSSI: %d\n", rssi_ant_mimo
.rssi_sum
));
5873 bytes_written
= snprintf(command
, total_len
, "%s MIMO %d",
5874 CMD_GET_RSSI_PER_ANT
, rssi_ant_mimo
.rssi_sum
);
5877 bytes_written
= snprintf(command
, total_len
, "%s PER_ANT ", CMD_GET_RSSI_PER_ANT
);
5878 for (cnt
= 0; cnt
< rssi_ant_mimo
.count
; cnt
++) {
5879 WL_DBG(("RSSI[%d]: %d\n", cnt
, rssi_ant_mimo
.rssi_ant
[cnt
]));
5880 bytes_written
= snprintf(command
, total_len
, "%d ",
5881 rssi_ant_mimo
.rssi_ant
[cnt
]);
5885 return bytes_written
;
5889 wl_android_set_rssi_logging(struct net_device
*dev
, char *command
, int total_len
)
5891 rssilog_set_param_t set_param
;
5895 memset(&set_param
, 0, sizeof(rssilog_set_param_t
));
5897 * DRIVER SET_RSSI_LOGGING <enable/disable> <RSSI Threshold> <Time Threshold>
5902 token
= bcmstrtok(&pos
, " ", NULL
);
5904 /* enable/disable */
5905 token
= bcmstrtok(&pos
, " ", NULL
);
5907 WL_ERR(("Invalid arguments\n"));
5910 set_param
.enable
= bcm_atoi(token
);
5912 /* RSSI Threshold */
5913 token
= bcmstrtok(&pos
, " ", NULL
);
5915 WL_ERR(("Invalid arguments\n"));
5918 set_param
.rssi_threshold
= bcm_atoi(token
);
5920 /* Time Threshold */
5921 token
= bcmstrtok(&pos
, " ", NULL
);
5923 WL_ERR(("Invalid arguments\n"));
5926 set_param
.time_threshold
= bcm_atoi(token
);
5928 WL_DBG(("enable %d, RSSI threshold %d, Time threshold %d\n", set_param
.enable
,
5929 set_param
.rssi_threshold
, set_param
.time_threshold
));
5931 err
= wl_set_rssi_logging(dev
, (void *)&set_param
);
5932 if (unlikely(err
)) {
5933 WL_ERR(("Failed to configure RSSI logging: enable %d, RSSI Threshold %d,"
5934 " Time Threshold %d\n", set_param
.enable
, set_param
.rssi_threshold
,
5935 set_param
.time_threshold
));
5942 wl_android_get_rssi_logging(struct net_device
*dev
, char *command
, int total_len
)
5944 rssilog_get_param_t get_param
;
5946 int bytes_written
= 0;
5948 err
= wl_get_rssi_logging(dev
, (void *)&get_param
);
5949 if (unlikely(err
)) {
5950 WL_ERR(("Failed to get RSSI logging info\n"));
5954 WL_DBG(("report_count %d, enable %d, rssi_threshold %d, time_threshold %d\n",
5955 get_param
.report_count
, get_param
.enable
, get_param
.rssi_threshold
,
5956 get_param
.time_threshold
));
5958 /* Parse the parameter */
5959 if (!get_param
.enable
) {
5960 WL_DBG(("RSSI LOGGING: Feature is disables\n"));
5961 bytes_written
= snprintf(command
, total_len
,
5962 "%s FEATURE DISABLED\n", CMD_GET_RSSI_LOGGING
);
5963 } else if (get_param
.enable
&
5964 (RSSILOG_FLAG_FEATURE_SW
| RSSILOG_FLAG_REPORT_READY
)) {
5965 if (!get_param
.report_count
) {
5966 WL_DBG(("[PASS] RSSI difference across antennas is within"
5967 " threshold limits\n"));
5968 bytes_written
= snprintf(command
, total_len
, "%s PASS\n",
5969 CMD_GET_RSSI_LOGGING
);
5971 WL_DBG(("[FAIL] RSSI difference across antennas found "
5972 "to be greater than %3d dB\n", get_param
.rssi_threshold
));
5973 WL_DBG(("[FAIL] RSSI difference check have failed for "
5974 "%d out of %d times\n", get_param
.report_count
,
5975 get_param
.time_threshold
));
5976 WL_DBG(("[FAIL] RSSI difference is being monitored once "
5977 "per second, for a %d secs window\n", get_param
.time_threshold
));
5978 bytes_written
= snprintf(command
, total_len
, "%s FAIL - RSSI Threshold "
5979 "%d dBm for %d out of %d times\n", CMD_GET_RSSI_LOGGING
,
5980 get_param
.rssi_threshold
, get_param
.report_count
,
5981 get_param
.time_threshold
);
5984 WL_DBG(("[BUSY] Reprot is not ready\n"));
5985 bytes_written
= snprintf(command
, total_len
, "%s BUSY - NOT READY\n",
5986 CMD_GET_RSSI_LOGGING
);
5989 return bytes_written
;
5991 #endif /* SUPPORT_RSSI_SUM_REPORT */
5993 #ifdef SET_PCIE_IRQ_CPU_CORE
5995 wl_android_set_irq_cpucore(struct net_device
*net
, int affinity_cmd
)
5997 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(net
);
5999 WL_ERR(("dhd is NULL\n"));
6003 if (affinity_cmd
< PCIE_IRQ_AFFINITY_OFF
|| affinity_cmd
> PCIE_IRQ_AFFINITY_LAST
) {
6004 WL_ERR(("Wrong Affinity cmds:%d, %s\n", affinity_cmd
, __FUNCTION__
));
6008 dhd_set_irq_cpucore(dhdp
, affinity_cmd
);
6010 #endif /* SET_PCIE_IRQ_CPU_CORE */
6014 wl_android_lqcm_enable(struct net_device
*net
, int lqcm_enable
)
6018 err
= wldev_iovar_setint(net
, "lqcm", lqcm_enable
);
6019 if (err
!= BCME_OK
) {
6020 WL_ERR(("failed to set lqcm enable %d, error = %d\n", lqcm_enable
, err
));
6027 wl_android_get_lqcm_report(struct net_device
*dev
, char *command
, int total_len
)
6029 int bytes_written
, err
= 0;
6030 uint32 lqcm_report
= 0;
6031 uint32 lqcm_enable
, tx_lqcm_idx
, rx_lqcm_idx
;
6033 err
= wldev_iovar_getint(dev
, "lqcm", &lqcm_report
);
6034 if (err
!= BCME_OK
) {
6035 WL_ERR(("failed to get lqcm report, error = %d\n", err
));
6038 lqcm_enable
= lqcm_report
& LQCM_ENAB_MASK
;
6039 tx_lqcm_idx
= (lqcm_report
& LQCM_TX_INDEX_MASK
) >> LQCM_TX_INDEX_SHIFT
;
6040 rx_lqcm_idx
= (lqcm_report
& LQCM_RX_INDEX_MASK
) >> LQCM_RX_INDEX_SHIFT
;
6042 WL_ERR(("lqcm report EN:%d, TX:%d, RX:%d\n", lqcm_enable
, tx_lqcm_idx
, rx_lqcm_idx
));
6044 bytes_written
= snprintf(command
, total_len
, "%s %d",
6045 CMD_GET_LQCM_REPORT
, lqcm_report
);
6047 return bytes_written
;
6049 #endif /* SUPPORT_LQCM */
6052 wl_android_get_snr(struct net_device
*dev
, char *command
, int total_len
)
6054 int bytes_written
, error
= 0;
6057 error
= wldev_iovar_getint(dev
, "snr", &snr
);
6059 DHD_ERROR(("%s: Failed to get SNR %d, error = %d\n",
6060 __FUNCTION__
, snr
, error
));
6064 bytes_written
= snprintf(command
, total_len
, "snr %d", snr
);
6065 DHD_INFO(("%s: command result is %s\n", __FUNCTION__
, command
));
6066 return bytes_written
;
6069 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
6071 wl_android_set_ap_beaconrate(struct net_device
*dev
, char *command
)
6075 char *ifname
= NULL
;
6079 * DRIVER SET_AP_BEACONRATE <rate> <ifname>
6084 token
= bcmstrtok(&pos
, " ", NULL
);
6087 token
= bcmstrtok(&pos
, " ", NULL
);
6090 rate
= bcm_atoi(token
);
6092 /* get the interface name */
6093 token
= bcmstrtok(&pos
, " ", NULL
);
6098 WL_DBG(("rate %d, ifacename %s\n", rate
, ifname
));
6100 err
= wl_set_ap_beacon_rate(dev
, rate
, ifname
);
6101 if (unlikely(err
)) {
6102 WL_ERR(("Failed to set ap beacon rate to %d, error = %d\n", rate
, err
));
6108 int wl_android_get_ap_basicrate(struct net_device
*dev
, char *command
, int total_len
)
6111 char *ifname
= NULL
;
6112 int bytes_written
= 0;
6114 * DRIVER GET_AP_BASICRATE <ifname>
6119 token
= bcmstrtok(&pos
, " ", NULL
);
6121 /* get the interface name */
6122 token
= bcmstrtok(&pos
, " ", NULL
);
6127 WL_DBG(("ifacename %s\n", ifname
));
6129 bytes_written
= wl_get_ap_basic_rate(dev
, command
, ifname
, total_len
);
6130 if (bytes_written
< 1) {
6131 WL_ERR(("Failed to get ap basic rate, error = %d\n", bytes_written
));
6135 return bytes_written
;
6137 #endif /* SUPPORT_AP_HIGHER_BEACONRATE */
6139 #ifdef SUPPORT_AP_RADIO_PWRSAVE
6141 wl_android_get_ap_rps(struct net_device
*dev
, char *command
, int total_len
)
6144 char *ifname
= NULL
;
6145 int bytes_written
= 0;
6146 char name
[IFNAMSIZ
];
6148 * DRIVER GET_AP_RPS <ifname>
6153 token
= bcmstrtok(&pos
, " ", NULL
);
6155 /* get the interface name */
6156 token
= bcmstrtok(&pos
, " ", NULL
);
6161 strncpy(name
, ifname
, IFNAMSIZ
);
6162 name
[IFNAMSIZ
-1] = '\0';
6163 WL_DBG(("ifacename %s\n", name
));
6165 bytes_written
= wl_get_ap_rps(dev
, command
, name
, total_len
);
6166 if (bytes_written
< 1) {
6167 WL_ERR(("Failed to get rps, error = %d\n", bytes_written
));
6171 return bytes_written
;
6176 wl_android_set_ap_rps(struct net_device
*dev
, char *command
, int total_len
)
6180 char *ifname
= NULL
;
6182 char name
[IFNAMSIZ
];
6185 * DRIVER SET_AP_RPS <0/1> <ifname>
6190 token
= bcmstrtok(&pos
, " ", NULL
);
6193 token
= bcmstrtok(&pos
, " ", NULL
);
6196 enable
= bcm_atoi(token
);
6198 /* get the interface name */
6199 token
= bcmstrtok(&pos
, " ", NULL
);
6204 strncpy(name
, ifname
, IFNAMSIZ
);
6205 name
[IFNAMSIZ
-1] = '\0';
6206 WL_DBG(("enable %d, ifacename %s\n", enable
, name
));
6208 err
= wl_set_ap_rps(dev
, enable
? TRUE
: FALSE
, name
);
6209 if (unlikely(err
)) {
6210 WL_ERR(("Failed to set rps, enable %d, error = %d\n", enable
, err
));
6217 wl_android_set_ap_rps_params(struct net_device
*dev
, char *command
, int total_len
)
6221 char *ifname
= NULL
;
6223 char name
[IFNAMSIZ
];
6225 memset(&rps
, 0, sizeof(rps
));
6227 * DRIVER SET_AP_RPS_PARAMS <pps> <level> <quiettime> <assoccheck> <ifname>
6232 token
= bcmstrtok(&pos
, " ", NULL
);
6235 token
= bcmstrtok(&pos
, " ", NULL
);
6238 rps
.pps
= bcm_atoi(token
);
6241 token
= bcmstrtok(&pos
, " ", NULL
);
6244 rps
.level
= bcm_atoi(token
);
6247 token
= bcmstrtok(&pos
, " ", NULL
);
6250 rps
.quiet_time
= bcm_atoi(token
);
6252 /* sta assoc check */
6253 token
= bcmstrtok(&pos
, " ", NULL
);
6256 rps
.sta_assoc_check
= bcm_atoi(token
);
6258 /* get the interface name */
6259 token
= bcmstrtok(&pos
, " ", NULL
);
6263 strncpy(name
, ifname
, IFNAMSIZ
);
6264 name
[IFNAMSIZ
-1] = '\0';
6266 WL_DBG(("pps %d, level %d, quiettime %d, sta_assoc_check %d, "
6267 "ifacename %s\n", rps
.pps
, rps
.level
, rps
.quiet_time
,
6268 rps
.sta_assoc_check
, name
));
6270 err
= wl_update_ap_rps_params(dev
, &rps
, name
);
6271 if (unlikely(err
)) {
6272 WL_ERR(("Failed to update rps, pps %d, level %d, quiettime %d, "
6273 "sta_assoc_check %d, err = %d\n", rps
.pps
, rps
.level
, rps
.quiet_time
,
6274 rps
.sta_assoc_check
, err
));
6279 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
6281 #if defined(DHD_HANG_SEND_UP_TEST)
6283 wl_android_make_hang_with_reason(struct net_device
*dev
, const char *string_num
)
6285 dhd_make_hang_with_reason(dev
, string_num
);
6287 #endif /* DHD_HANG_SEND_UP_TEST */
6289 #ifdef DHD_PKT_LOGGING
6291 wl_android_pktlog_filter_enable(struct net_device
*dev
, char *command
, int total_len
)
6293 int bytes_written
= 0;
6294 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6295 dhd_pktlog_filter_t
*filter
;
6298 if (!dhdp
|| !dhdp
->pktlog
) {
6299 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6300 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6304 filter
= dhdp
->pktlog
->pktlog_filter
;
6306 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_TXPKT_CASE
, TRUE
);
6307 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_TXSTATUS_CASE
, TRUE
);
6308 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_RXPKT_CASE
, TRUE
);
6310 if (err
== BCME_OK
) {
6311 bytes_written
= snprintf(command
, total_len
, "OK");
6312 DHD_ERROR(("%s: pktlog filter enable success\n", __FUNCTION__
));
6314 DHD_ERROR(("%s: pktlog filter enable fail\n", __FUNCTION__
));
6318 return bytes_written
;
6322 wl_android_pktlog_filter_disable(struct net_device
*dev
, char *command
, int total_len
)
6324 int bytes_written
= 0;
6325 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6326 dhd_pktlog_filter_t
*filter
;
6329 if (!dhdp
|| !dhdp
->pktlog
) {
6330 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6331 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6335 filter
= dhdp
->pktlog
->pktlog_filter
;
6337 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_TXPKT_CASE
, FALSE
);
6338 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_TXSTATUS_CASE
, FALSE
);
6339 err
= dhd_pktlog_filter_enable(filter
, PKTLOG_RXPKT_CASE
, FALSE
);
6341 if (err
== BCME_OK
) {
6342 bytes_written
= snprintf(command
, total_len
, "OK");
6343 DHD_ERROR(("%s: pktlog filter disable success\n", __FUNCTION__
));
6345 DHD_ERROR(("%s: pktlog filter disable fail\n", __FUNCTION__
));
6349 return bytes_written
;
6353 wl_android_pktlog_filter_pattern_enable(struct net_device
*dev
, char *command
, int total_len
)
6355 int bytes_written
= 0;
6356 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6357 dhd_pktlog_filter_t
*filter
;
6360 if (!dhdp
|| !dhdp
->pktlog
) {
6361 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6362 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6366 filter
= dhdp
->pktlog
->pktlog_filter
;
6368 if (strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE
) + 1 > total_len
) {
6372 err
= dhd_pktlog_filter_pattern_enable(filter
,
6373 command
+ strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE
) + 1, TRUE
);
6375 if (err
== BCME_OK
) {
6376 bytes_written
= snprintf(command
, total_len
, "OK");
6377 DHD_ERROR(("%s: pktlog filter pattern enable success\n", __FUNCTION__
));
6379 DHD_ERROR(("%s: pktlog filter pattern enable fail\n", __FUNCTION__
));
6383 return bytes_written
;
6387 wl_android_pktlog_filter_pattern_disable(struct net_device
*dev
, char *command
, int total_len
)
6389 int bytes_written
= 0;
6390 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6391 dhd_pktlog_filter_t
*filter
;
6394 if (!dhdp
|| !dhdp
->pktlog
) {
6395 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6396 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6400 filter
= dhdp
->pktlog
->pktlog_filter
;
6402 if (strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE
) + 1 > total_len
) {
6406 err
= dhd_pktlog_filter_pattern_enable(filter
,
6407 command
+ strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE
) + 1, FALSE
);
6409 if (err
== BCME_OK
) {
6410 bytes_written
= snprintf(command
, total_len
, "OK");
6411 DHD_ERROR(("%s: pktlog filter pattern disable success\n", __FUNCTION__
));
6413 DHD_ERROR(("%s: pktlog filter pattern disable fail\n", __FUNCTION__
));
6417 return bytes_written
;
6421 wl_android_pktlog_filter_add(struct net_device
*dev
, char *command
, int total_len
)
6423 int bytes_written
= 0;
6424 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6425 dhd_pktlog_filter_t
*filter
;
6428 if (!dhdp
|| !dhdp
->pktlog
) {
6429 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6430 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6434 filter
= dhdp
->pktlog
->pktlog_filter
;
6436 if (strlen(CMD_PKTLOG_FILTER_ADD
) + 1 > total_len
) {
6440 err
= dhd_pktlog_filter_add(filter
, command
+ strlen(CMD_PKTLOG_FILTER_ADD
) + 1);
6442 if (err
== BCME_OK
) {
6443 bytes_written
= snprintf(command
, total_len
, "OK");
6444 DHD_ERROR(("%s: pktlog filter add success\n", __FUNCTION__
));
6446 DHD_ERROR(("%s: pktlog filter add fail\n", __FUNCTION__
));
6450 return bytes_written
;
6454 wl_android_pktlog_filter_info(struct net_device
*dev
, char *command
, int total_len
)
6456 int bytes_written
= 0;
6457 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6458 dhd_pktlog_filter_t
*filter
;
6461 if (!dhdp
|| !dhdp
->pktlog
) {
6462 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6463 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6467 filter
= dhdp
->pktlog
->pktlog_filter
;
6469 err
= dhd_pktlog_filter_info(filter
);
6471 if (err
== BCME_OK
) {
6472 bytes_written
= snprintf(command
, total_len
, "OK");
6473 DHD_ERROR(("%s: pktlog filter info success\n", __FUNCTION__
));
6475 DHD_ERROR(("%s: pktlog filter info fail\n", __FUNCTION__
));
6479 return bytes_written
;
6483 wl_android_pktlog_start(struct net_device
*dev
, char *command
, int total_len
)
6485 int bytes_written
= 0;
6486 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6488 if (!dhdp
|| !dhdp
->pktlog
) {
6489 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6490 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6494 if (!dhdp
->pktlog
->tx_pktlog_ring
|| !dhdp
->pktlog
->rx_pktlog_ring
) {
6495 DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
6496 __FUNCTION__
, dhdp
->pktlog
->tx_pktlog_ring
, dhdp
->pktlog
->rx_pktlog_ring
));
6500 dhdp
->pktlog
->tx_pktlog_ring
->start
= TRUE
;
6501 dhdp
->pktlog
->rx_pktlog_ring
->start
= TRUE
;
6503 bytes_written
= snprintf(command
, total_len
, "OK");
6505 DHD_ERROR(("%s: pktlog start success\n", __FUNCTION__
));
6507 return bytes_written
;
6511 wl_android_pktlog_stop(struct net_device
*dev
, char *command
, int total_len
)
6513 int bytes_written
= 0;
6514 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6516 if (!dhdp
|| !dhdp
->pktlog
) {
6517 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6518 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6522 if (!dhdp
->pktlog
->tx_pktlog_ring
|| !dhdp
->pktlog
->rx_pktlog_ring
) {
6523 DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
6524 __FUNCTION__
, dhdp
->pktlog
->tx_pktlog_ring
, dhdp
->pktlog
->rx_pktlog_ring
));
6528 dhdp
->pktlog
->tx_pktlog_ring
->start
= FALSE
;
6529 dhdp
->pktlog
->rx_pktlog_ring
->start
= FALSE
;
6531 bytes_written
= snprintf(command
, total_len
, "OK");
6533 DHD_ERROR(("%s: pktlog stop success\n", __FUNCTION__
));
6535 return bytes_written
;
6539 wl_android_pktlog_filter_exist(struct net_device
*dev
, char *command
, int total_len
)
6541 int bytes_written
= 0;
6542 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6543 dhd_pktlog_filter_t
*filter
;
6547 if (!dhdp
|| !dhdp
->pktlog
) {
6548 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6549 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6553 filter
= dhdp
->pktlog
->pktlog_filter
;
6555 if (strlen(CMD_PKTLOG_FILTER_EXIST
) + 1 > total_len
) {
6559 exist
= dhd_pktlog_filter_existed(filter
, command
+ strlen(CMD_PKTLOG_FILTER_EXIST
) + 1,
6563 bytes_written
= snprintf(command
, total_len
, "TRUE");
6564 DHD_ERROR(("%s: pktlog filter pattern id: %d is existed\n", __FUNCTION__
, id
));
6566 bytes_written
= snprintf(command
, total_len
, "FALSE");
6567 DHD_ERROR(("%s: pktlog filter pattern id: %d is not existed\n", __FUNCTION__
, id
));
6570 return bytes_written
;
6574 wl_android_pktlog_minmize_enable(struct net_device
*dev
, char *command
, int total_len
)
6576 int bytes_written
= 0;
6577 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6579 if (!dhdp
|| !dhdp
->pktlog
) {
6580 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6581 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6585 if (!dhdp
->pktlog
->tx_pktlog_ring
|| !dhdp
->pktlog
->rx_pktlog_ring
) {
6586 DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
6587 __FUNCTION__
, dhdp
->pktlog
->tx_pktlog_ring
, dhdp
->pktlog
->rx_pktlog_ring
));
6591 dhdp
->pktlog
->tx_pktlog_ring
->pktlog_minmize
= TRUE
;
6592 dhdp
->pktlog
->rx_pktlog_ring
->pktlog_minmize
= TRUE
;
6594 bytes_written
= snprintf(command
, total_len
, "OK");
6596 DHD_ERROR(("%s: pktlog pktlog_minmize enable\n", __FUNCTION__
));
6598 return bytes_written
;
6602 wl_android_pktlog_minmize_disable(struct net_device
*dev
, char *command
, int total_len
)
6604 int bytes_written
= 0;
6605 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6607 if (!dhdp
|| !dhdp
->pktlog
) {
6608 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6609 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6613 if (!dhdp
->pktlog
->tx_pktlog_ring
|| !dhdp
->pktlog
->rx_pktlog_ring
) {
6614 DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
6615 __FUNCTION__
, dhdp
->pktlog
->tx_pktlog_ring
, dhdp
->pktlog
->rx_pktlog_ring
));
6619 dhdp
->pktlog
->tx_pktlog_ring
->pktlog_minmize
= FALSE
;
6620 dhdp
->pktlog
->rx_pktlog_ring
->pktlog_minmize
= FALSE
;
6622 bytes_written
= snprintf(command
, total_len
, "OK");
6624 DHD_ERROR(("%s: pktlog pktlog_minmize disable\n", __FUNCTION__
));
6626 return bytes_written
;
6630 wl_android_pktlog_change_size(struct net_device
*dev
, char *command
, int total_len
)
6632 int bytes_written
= 0;
6633 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6637 if (!dhdp
|| !dhdp
->pktlog
) {
6638 DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
6639 __FUNCTION__
, dhdp
, (dhdp
? dhdp
->pktlog
: NULL
)));
6643 if (strlen(CMD_PKTLOG_CHANGE_SIZE
) + 1 > total_len
) {
6647 size
= bcm_strtoul(command
+ strlen(CMD_PKTLOG_CHANGE_SIZE
) + 1, NULL
, 0);
6649 dhdp
->pktlog
->tx_pktlog_ring
=
6650 dhd_pktlog_ring_change_size(dhdp
->pktlog
->tx_pktlog_ring
, size
);
6651 if (!dhdp
->pktlog
->tx_pktlog_ring
) {
6655 dhdp
->pktlog
->rx_pktlog_ring
=
6656 dhd_pktlog_ring_change_size(dhdp
->pktlog
->rx_pktlog_ring
, size
);
6657 if (!dhdp
->pktlog
->tx_pktlog_ring
) {
6661 if (err
== BCME_OK
) {
6662 bytes_written
= snprintf(command
, total_len
, "OK");
6663 DHD_ERROR(("%s: pktlog change size success\n", __FUNCTION__
));
6665 DHD_ERROR(("%s: pktlog change size fail\n", __FUNCTION__
));
6669 return bytes_written
;
6671 #endif /* DHD_PKT_LOGGING */
6673 #ifdef DHD_EVENT_LOG_FILTER
6674 uint32
dhd_event_log_filter_serialize(dhd_pub_t
*dhdp
, char *buf
, uint32 tot_len
, int type
);
6676 wl_android_ewp_filter(struct net_device
*dev
, char *command
, uint32 tot_len
)
6678 uint32 bytes_written
= 0;
6680 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6682 if (!dhdp
|| !command
) {
6683 DHD_ERROR(("%s(): dhdp=%p \n", __FUNCTION__
, dhdp
));
6687 /* NEED TO GET TYPE if EXIST */
6690 bytes_written
+= dhd_event_log_filter_serialize(dhdp
,
6691 &command
[bytes_written
], tot_len
- bytes_written
, type
);
6693 return (int)bytes_written
;
6695 #endif /* DHD_EVENT_LOG_FILTER */
6697 int wl_android_priv_cmd(struct net_device
*net
, struct ifreq
*ifr
)
6699 #define PRIVATE_COMMAND_MAX_LEN 8192
6700 #define PRIVATE_COMMAND_DEF_LEN 4096
6702 char *command
= NULL
;
6703 int bytes_written
= 0;
6704 android_wifi_priv_cmd priv_cmd
;
6706 struct bcm_cfg80211
*cfg
= wl_get_cfg(net
);
6708 net_os_wake_lock(net
);
6710 if (!capable(CAP_NET_ADMIN
)) {
6715 if (!ifr
->ifr_data
) {
6720 #ifdef CONFIG_COMPAT
6721 if (is_compat_task()) {
6722 compat_android_wifi_priv_cmd compat_priv_cmd
;
6723 if (copy_from_user(&compat_priv_cmd
, ifr
->ifr_data
,
6724 sizeof(compat_android_wifi_priv_cmd
))) {
6729 priv_cmd
.buf
= compat_ptr(compat_priv_cmd
.buf
);
6730 priv_cmd
.used_len
= compat_priv_cmd
.used_len
;
6731 priv_cmd
.total_len
= compat_priv_cmd
.total_len
;
6733 #endif /* CONFIG_COMPAT */
6735 if (copy_from_user(&priv_cmd
, ifr
->ifr_data
, sizeof(android_wifi_priv_cmd
))) {
6740 if ((priv_cmd
.total_len
> PRIVATE_COMMAND_MAX_LEN
) || (priv_cmd
.total_len
< 0)) {
6741 DHD_ERROR(("%s: buf length invalid:%d\n", __FUNCTION__
,
6742 priv_cmd
.total_len
));
6747 buf_size
= max(priv_cmd
.total_len
, PRIVATE_COMMAND_DEF_LEN
);
6748 command
= (char *)MALLOC(cfg
->osh
, (buf_size
+ 1));
6750 DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__
));
6754 if (copy_from_user(command
, priv_cmd
.buf
, priv_cmd
.total_len
)) {
6758 command
[priv_cmd
.total_len
] = '\0';
6760 DHD_ERROR(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__
, command
, ifr
->ifr_name
));
6762 bytes_written
= wl_handle_private_cmd(net
, command
, priv_cmd
.total_len
);
6763 if (bytes_written
>= 0) {
6764 if ((bytes_written
== 0) && (priv_cmd
.total_len
> 0)) {
6767 if (bytes_written
>= priv_cmd
.total_len
) {
6768 DHD_ERROR(("%s: err. bytes_written:%d >= total_len:%d, buf_size:%d\n",
6769 __FUNCTION__
, bytes_written
, priv_cmd
.total_len
, buf_size
));
6771 ret
= BCME_BUFTOOSHORT
;
6775 priv_cmd
.used_len
= bytes_written
;
6776 if (copy_to_user(priv_cmd
.buf
, command
, bytes_written
)) {
6777 DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__
));
6782 /* Propagate the error */
6783 ret
= bytes_written
;
6787 net_os_wake_unlock(net
);
6788 MFREE(cfg
->osh
, command
, (buf_size
+ 1));
6791 #ifdef WLADPS_PRIVATE_CMD
6793 wl_android_set_adps_mode(struct net_device
*dev
, const char* string_num
)
6795 int err
= 0, adps_mode
;
6796 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(dev
);
6797 #ifdef DHD_PM_CONTROL_FROM_FILE
6801 #endif /* DHD_PM_CONTROL_FROM_FILE */
6803 adps_mode
= bcm_atoi(string_num
);
6804 WL_ERR(("%s: SET_ADPS %d\n", __FUNCTION__
, adps_mode
));
6806 if ((adps_mode
< 0) && (1 < adps_mode
)) {
6807 WL_ERR(("%s: Invalid value %d.\n", __FUNCTION__
, adps_mode
));
6811 err
= dhd_enable_adps(dhdp
, adps_mode
);
6812 if (err
!= BCME_OK
) {
6813 WL_ERR(("failed to set adps mode %d, error = %d\n", adps_mode
, err
));
6819 wl_android_get_adps_mode(
6820 struct net_device
*dev
, char *command
, int total_len
)
6822 int bytes_written
, err
= 0;
6824 char buf
[WLC_IOCTL_SMLEN
];
6826 bcm_iov_buf_t iov_buf
;
6827 bcm_iov_buf_t
*ptr
= NULL
;
6828 wl_adps_params_v1_t
*data
= NULL
;
6830 uint8
*pdata
= NULL
;
6831 uint8 band
, mode
= 0;
6833 memset(&iov_buf
, 0, sizeof(iov_buf
));
6835 len
= OFFSETOF(bcm_iov_buf_t
, data
) + sizeof(band
);
6837 iov_buf
.version
= WL_ADPS_IOV_VER
;
6838 iov_buf
.len
= sizeof(band
);
6839 iov_buf
.id
= WL_ADPS_IOV_MODE
;
6841 pdata
= (uint8
*)&iov_buf
.data
;
6843 for (band
= 1; band
<= MAX_BANDS
; band
++) {
6845 err
= wldev_iovar_getbuf(dev
, "adps", &iov_buf
, len
,
6846 buf
, WLC_IOCTL_SMLEN
, NULL
);
6847 if (err
!= BCME_OK
) {
6848 WL_ERR(("%s fail to get adps band %d(%d).\n",
6849 __FUNCTION__
, band
, err
));
6852 ptr
= (bcm_iov_buf_t
*) buf
;
6853 data
= (wl_adps_params_v1_t
*) ptr
->data
;
6860 bytes_written
= snprintf(command
, total_len
, "%s %d",
6861 CMD_GET_ADPS
, mode
);
6862 return bytes_written
;
6864 #endif /* WLADPS_PRIVATE_CMD */
6867 wl_handle_private_cmd(struct net_device
*net
, char *command
, u32 cmd_len
)
6869 int bytes_written
= 0;
6870 android_wifi_priv_cmd priv_cmd
;
6872 bzero(&priv_cmd
, sizeof(android_wifi_priv_cmd
));
6873 priv_cmd
.total_len
= cmd_len
;
6875 if (strnicmp(command
, CMD_START
, strlen(CMD_START
)) == 0) {
6876 DHD_INFO(("%s, Received regular START command\n", __FUNCTION__
));
6877 #ifdef SUPPORT_DEEP_SLEEP
6878 trigger_deep_sleep
= 1;
6881 bytes_written
= dhd_net_bus_get(net
);
6883 bytes_written
= wl_android_wifi_on(net
);
6884 #endif /* BT_OVER_SDIO */
6885 #endif /* SUPPORT_DEEP_SLEEP */
6887 else if (strnicmp(command
, CMD_SETFWPATH
, strlen(CMD_SETFWPATH
)) == 0) {
6888 bytes_written
= wl_android_set_fwpath(net
, command
, priv_cmd
.total_len
);
6892 DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface is down\n",
6893 __FUNCTION__
, command
));
6897 if (strnicmp(command
, CMD_STOP
, strlen(CMD_STOP
)) == 0) {
6898 #ifdef SUPPORT_DEEP_SLEEP
6899 trigger_deep_sleep
= 1;
6902 bytes_written
= dhd_net_bus_put(net
);
6904 bytes_written
= wl_android_wifi_off(net
, FALSE
);
6905 #endif /* BT_OVER_SDIO */
6906 #endif /* SUPPORT_DEEP_SLEEP */
6908 else if (strnicmp(command
, CMD_SCAN_ACTIVE
, strlen(CMD_SCAN_ACTIVE
)) == 0) {
6909 wl_cfg80211_set_passive_scan(net
, command
);
6911 else if (strnicmp(command
, CMD_SCAN_PASSIVE
, strlen(CMD_SCAN_PASSIVE
)) == 0) {
6912 wl_cfg80211_set_passive_scan(net
, command
);
6914 else if (strnicmp(command
, CMD_RSSI
, strlen(CMD_RSSI
)) == 0) {
6915 bytes_written
= wl_android_get_rssi(net
, command
, priv_cmd
.total_len
);
6917 else if (strnicmp(command
, CMD_LINKSPEED
, strlen(CMD_LINKSPEED
)) == 0) {
6918 bytes_written
= wl_android_get_link_speed(net
, command
, priv_cmd
.total_len
);
6920 #ifdef PKT_FILTER_SUPPORT
6921 else if (strnicmp(command
, CMD_RXFILTER_START
, strlen(CMD_RXFILTER_START
)) == 0) {
6922 bytes_written
= net_os_enable_packet_filter(net
, 1);
6924 else if (strnicmp(command
, CMD_RXFILTER_STOP
, strlen(CMD_RXFILTER_STOP
)) == 0) {
6925 bytes_written
= net_os_enable_packet_filter(net
, 0);
6927 else if (strnicmp(command
, CMD_RXFILTER_ADD
, strlen(CMD_RXFILTER_ADD
)) == 0) {
6928 int filter_num
= *(command
+ strlen(CMD_RXFILTER_ADD
) + 1) - '0';
6929 bytes_written
= net_os_rxfilter_add_remove(net
, TRUE
, filter_num
);
6931 else if (strnicmp(command
, CMD_RXFILTER_REMOVE
, strlen(CMD_RXFILTER_REMOVE
)) == 0) {
6932 int filter_num
= *(command
+ strlen(CMD_RXFILTER_REMOVE
) + 1) - '0';
6933 bytes_written
= net_os_rxfilter_add_remove(net
, FALSE
, filter_num
);
6935 #endif /* PKT_FILTER_SUPPORT */
6936 else if (strnicmp(command
, CMD_BTCOEXSCAN_START
, strlen(CMD_BTCOEXSCAN_START
)) == 0) {
6937 /* TBD: BTCOEXSCAN-START */
6939 else if (strnicmp(command
, CMD_BTCOEXSCAN_STOP
, strlen(CMD_BTCOEXSCAN_STOP
)) == 0) {
6940 /* TBD: BTCOEXSCAN-STOP */
6942 else if (strnicmp(command
, CMD_BTCOEXMODE
, strlen(CMD_BTCOEXMODE
)) == 0) {
6944 void *dhdp
= wl_cfg80211_get_dhdp(net
);
6945 bytes_written
= wl_cfg80211_set_btcoex_dhcp(net
, dhdp
, command
);
6947 #ifdef PKT_FILTER_SUPPORT
6948 uint mode
= *(command
+ strlen(CMD_BTCOEXMODE
) + 1) - '0';
6951 net_os_enable_packet_filter(net
, 0); /* DHCP starts */
6953 net_os_enable_packet_filter(net
, 1); /* DHCP ends */
6954 #endif /* PKT_FILTER_SUPPORT */
6955 #endif /* WL_CFG80211 */
6957 else if (strnicmp(command
, CMD_SETSUSPENDOPT
, strlen(CMD_SETSUSPENDOPT
)) == 0) {
6958 bytes_written
= wl_android_set_suspendopt(net
, command
);
6960 else if (strnicmp(command
, CMD_SETSUSPENDMODE
, strlen(CMD_SETSUSPENDMODE
)) == 0) {
6961 bytes_written
= wl_android_set_suspendmode(net
, command
);
6963 else if (strnicmp(command
, CMD_SETDTIM_IN_SUSPEND
, strlen(CMD_SETDTIM_IN_SUSPEND
)) == 0) {
6964 bytes_written
= wl_android_set_bcn_li_dtim(net
, command
);
6966 else if (strnicmp(command
, CMD_MAXDTIM_IN_SUSPEND
, strlen(CMD_MAXDTIM_IN_SUSPEND
)) == 0) {
6967 bytes_written
= wl_android_set_max_dtim(net
, command
);
6969 else if (strnicmp(command
, CMD_SETBAND
, strlen(CMD_SETBAND
)) == 0) {
6970 uint band
= *(command
+ strlen(CMD_SETBAND
) + 1) - '0';
6971 #ifdef WL_HOST_BAND_MGMT
6973 if ((ret
= wl_cfg80211_set_band(net
, band
)) < 0) {
6974 if (ret
== BCME_UNSUPPORTED
) {
6975 /* If roam_var is unsupported, fallback to the original method */
6976 WL_ERR(("WL_HOST_BAND_MGMT defined, "
6977 "but roam_band iovar unsupported in the firmware\n"));
6982 if (((ret
== 0) && (band
== WLC_BAND_AUTO
)) || (ret
== BCME_UNSUPPORTED
)) {
6983 /* Apply if roam_band iovar is not supported or band setting is AUTO */
6984 bytes_written
= wldev_set_band(net
, band
);
6987 bytes_written
= wl_cfg80211_set_if_band(net
, band
);
6988 #endif /* WL_HOST_BAND_MGMT */
6989 #ifdef ROAM_CHANNEL_CACHE
6990 wl_update_roamscan_cache_by_band(net
, band
);
6991 #endif /* ROAM_CHANNEL_CACHE */
6993 else if (strnicmp(command
, CMD_GETBAND
, strlen(CMD_GETBAND
)) == 0) {
6994 bytes_written
= wl_android_get_band(net
, command
, priv_cmd
.total_len
);
6997 #ifndef CUSTOMER_SET_COUNTRY
6998 /* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */
6999 else if (strnicmp(command
, CMD_COUNTRY
, strlen(CMD_COUNTRY
)) == 0) {
7003 * DRIVER COUNTRY US/7
7005 char *country_code
= command
+ strlen(CMD_COUNTRY
) + 1;
7006 char *rev_info_delim
= country_code
+ 2; /* 2 bytes of country code */
7008 struct wireless_dev
*wdev
= ndev_to_wdev(net
);
7009 struct wiphy
*wiphy
= wdev
->wiphy
;
7010 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(net
);
7012 BCM_REFERENCE(dhdp
);
7013 if (CHECK_IS_BLOB(dhdp
) && !CHECK_IS_MULT_REGREV(dhdp
)) {
7015 } else if ((rev_info_delim
) &&
7016 (strnicmp(rev_info_delim
, CMD_COUNTRY_DELIMITER
,
7017 strlen(CMD_COUNTRY_DELIMITER
)) == 0) &&
7018 (rev_info_delim
+ 1)) {
7019 revinfo
= bcm_atoi(rev_info_delim
+ 1);
7022 if (wl_check_dongle_idle(wiphy
) != TRUE
) {
7023 DHD_ERROR(("FW is busy to check dongle idle\n"));
7027 bytes_written
= wldev_set_country(net
, country_code
, true, true, revinfo
);
7028 #ifdef CUSTOMER_HW4_PRIVATE_CMD
7029 #ifdef FCC_PWR_LIMIT_2G
7030 if (wldev_iovar_setint(net
, "fccpwrlimit2g", FALSE
)) {
7031 DHD_ERROR(("%s: fccpwrlimit2g deactivation is failed\n", __FUNCTION__
));
7033 DHD_ERROR(("%s: fccpwrlimit2g is deactivated\n", __FUNCTION__
));
7035 #endif /* FCC_PWR_LIMIT_2G */
7036 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
7038 #endif /* CUSTOMER_SET_COUNTRY */
7039 #endif /* WL_CFG80211 */
7040 else if (strnicmp(command
, CMD_SET_CSA
, strlen(CMD_SET_CSA
)) == 0) {
7041 bytes_written
= wl_android_set_csa(net
, command
);
7042 } else if (strnicmp(command
, CMD_80211_MODE
, strlen(CMD_80211_MODE
)) == 0) {
7043 bytes_written
= wl_android_get_80211_mode(net
, command
, priv_cmd
.total_len
);
7044 } else if (strnicmp(command
, CMD_CHANSPEC
, strlen(CMD_CHANSPEC
)) == 0) {
7045 bytes_written
= wl_android_get_chanspec(net
, command
, priv_cmd
.total_len
);
7046 } else if (strnicmp(command
, CMD_DATARATE
, strlen(CMD_DATARATE
)) == 0) {
7047 bytes_written
= wl_android_get_datarate(net
, command
, priv_cmd
.total_len
);
7048 } else if (strnicmp(command
, CMD_ASSOC_CLIENTS
, strlen(CMD_ASSOC_CLIENTS
)) == 0) {
7049 bytes_written
= wl_android_get_assoclist(net
, command
, priv_cmd
.total_len
);
7052 #ifdef CUSTOMER_HW4_PRIVATE_CMD
7054 else if (strnicmp(command
, CMD_ROAMTRIGGER_SET
,
7055 strlen(CMD_ROAMTRIGGER_SET
)) == 0) {
7056 bytes_written
= wl_android_set_roam_trigger(net
, command
);
7057 } else if (strnicmp(command
, CMD_ROAMTRIGGER_GET
,
7058 strlen(CMD_ROAMTRIGGER_GET
)) == 0) {
7059 bytes_written
= wl_android_get_roam_trigger(net
, command
,
7060 priv_cmd
.total_len
);
7061 } else if (strnicmp(command
, CMD_ROAMDELTA_SET
,
7062 strlen(CMD_ROAMDELTA_SET
)) == 0) {
7063 bytes_written
= wl_android_set_roam_delta(net
, command
);
7064 } else if (strnicmp(command
, CMD_ROAMDELTA_GET
,
7065 strlen(CMD_ROAMDELTA_GET
)) == 0) {
7066 bytes_written
= wl_android_get_roam_delta(net
, command
,
7067 priv_cmd
.total_len
);
7068 } else if (strnicmp(command
, CMD_ROAMSCANPERIOD_SET
,
7069 strlen(CMD_ROAMSCANPERIOD_SET
)) == 0) {
7070 bytes_written
= wl_android_set_roam_scan_period(net
, command
);
7071 } else if (strnicmp(command
, CMD_ROAMSCANPERIOD_GET
,
7072 strlen(CMD_ROAMSCANPERIOD_GET
)) == 0) {
7073 bytes_written
= wl_android_get_roam_scan_period(net
, command
,
7074 priv_cmd
.total_len
);
7075 } else if (strnicmp(command
, CMD_FULLROAMSCANPERIOD_SET
,
7076 strlen(CMD_FULLROAMSCANPERIOD_SET
)) == 0) {
7077 bytes_written
= wl_android_set_full_roam_scan_period(net
, command
,
7078 priv_cmd
.total_len
);
7079 } else if (strnicmp(command
, CMD_FULLROAMSCANPERIOD_GET
,
7080 strlen(CMD_FULLROAMSCANPERIOD_GET
)) == 0) {
7081 bytes_written
= wl_android_get_full_roam_scan_period(net
, command
,
7082 priv_cmd
.total_len
);
7083 } else if (strnicmp(command
, CMD_COUNTRYREV_SET
,
7084 strlen(CMD_COUNTRYREV_SET
)) == 0) {
7085 bytes_written
= wl_android_set_country_rev(net
, command
);
7086 #ifdef FCC_PWR_LIMIT_2G
7087 if (wldev_iovar_setint(net
, "fccpwrlimit2g", FALSE
)) {
7088 DHD_ERROR(("%s: fccpwrlimit2g deactivation is failed\n", __FUNCTION__
));
7090 DHD_ERROR(("%s: fccpwrlimit2g is deactivated\n", __FUNCTION__
));
7092 #endif /* FCC_PWR_LIMIT_2G */
7093 } else if (strnicmp(command
, CMD_COUNTRYREV_GET
,
7094 strlen(CMD_COUNTRYREV_GET
)) == 0) {
7095 bytes_written
= wl_android_get_country_rev(net
, command
,
7096 priv_cmd
.total_len
);
7098 #endif /* ROAM_API */
7100 else if (strnicmp(command
, CMD_GETROAMSCANCONTROL
, strlen(CMD_GETROAMSCANCONTROL
)) == 0) {
7101 bytes_written
= wl_android_get_roam_scan_control(net
, command
, priv_cmd
.total_len
);
7103 else if (strnicmp(command
, CMD_SETROAMSCANCONTROL
, strlen(CMD_SETROAMSCANCONTROL
)) == 0) {
7104 bytes_written
= wl_android_set_roam_scan_control(net
, command
);
7106 else if (strnicmp(command
, CMD_GETROAMSCANCHANNELS
, strlen(CMD_GETROAMSCANCHANNELS
)) == 0) {
7107 bytes_written
= wl_android_get_roam_scan_channels(net
, command
, priv_cmd
.total_len
);
7109 else if (strnicmp(command
, CMD_SETROAMSCANCHANNELS
, strlen(CMD_SETROAMSCANCHANNELS
)) == 0) {
7110 bytes_written
= wl_android_set_roam_scan_channels(net
, command
);
7112 else if (strnicmp(command
, CMD_SENDACTIONFRAME
, strlen(CMD_SENDACTIONFRAME
)) == 0) {
7113 bytes_written
= wl_android_send_action_frame(net
, command
, priv_cmd
.total_len
);
7115 else if (strnicmp(command
, CMD_REASSOC
, strlen(CMD_REASSOC
)) == 0) {
7116 bytes_written
= wl_android_reassoc(net
, command
, priv_cmd
.total_len
);
7118 else if (strnicmp(command
, CMD_GETSCANCHANNELTIME
, strlen(CMD_GETSCANCHANNELTIME
)) == 0) {
7119 bytes_written
= wl_android_get_scan_channel_time(net
, command
, priv_cmd
.total_len
);
7121 else if (strnicmp(command
, CMD_SETSCANCHANNELTIME
, strlen(CMD_SETSCANCHANNELTIME
)) == 0) {
7122 bytes_written
= wl_android_set_scan_channel_time(net
, command
);
7124 else if (strnicmp(command
, CMD_GETSCANUNASSOCTIME
, strlen(CMD_GETSCANUNASSOCTIME
)) == 0) {
7125 bytes_written
= wl_android_get_scan_unassoc_time(net
, command
, priv_cmd
.total_len
);
7127 else if (strnicmp(command
, CMD_SETSCANUNASSOCTIME
, strlen(CMD_SETSCANUNASSOCTIME
)) == 0) {
7128 bytes_written
= wl_android_set_scan_unassoc_time(net
, command
);
7130 else if (strnicmp(command
, CMD_GETSCANPASSIVETIME
, strlen(CMD_GETSCANPASSIVETIME
)) == 0) {
7131 bytes_written
= wl_android_get_scan_passive_time(net
, command
, priv_cmd
.total_len
);
7133 else if (strnicmp(command
, CMD_SETSCANPASSIVETIME
, strlen(CMD_SETSCANPASSIVETIME
)) == 0) {
7134 bytes_written
= wl_android_set_scan_passive_time(net
, command
);
7136 else if (strnicmp(command
, CMD_GETSCANHOMETIME
, strlen(CMD_GETSCANHOMETIME
)) == 0) {
7137 bytes_written
= wl_android_get_scan_home_time(net
, command
, priv_cmd
.total_len
);
7139 else if (strnicmp(command
, CMD_SETSCANHOMETIME
, strlen(CMD_SETSCANHOMETIME
)) == 0) {
7140 bytes_written
= wl_android_set_scan_home_time(net
, command
);
7142 else if (strnicmp(command
, CMD_GETSCANHOMEAWAYTIME
, strlen(CMD_GETSCANHOMEAWAYTIME
)) == 0) {
7143 bytes_written
= wl_android_get_scan_home_away_time(net
, command
,
7144 priv_cmd
.total_len
);
7146 else if (strnicmp(command
, CMD_SETSCANHOMEAWAYTIME
, strlen(CMD_SETSCANHOMEAWAYTIME
)) == 0) {
7147 bytes_written
= wl_android_set_scan_home_away_time(net
, command
);
7149 else if (strnicmp(command
, CMD_GETSCANNPROBES
, strlen(CMD_GETSCANNPROBES
)) == 0) {
7150 bytes_written
= wl_android_get_scan_nprobes(net
, command
, priv_cmd
.total_len
);
7152 else if (strnicmp(command
, CMD_SETSCANNPROBES
, strlen(CMD_SETSCANNPROBES
)) == 0) {
7153 bytes_written
= wl_android_set_scan_nprobes(net
, command
);
7155 else if (strnicmp(command
, CMD_GETDFSSCANMODE
, strlen(CMD_GETDFSSCANMODE
)) == 0) {
7156 bytes_written
= wl_android_get_scan_dfs_channel_mode(net
, command
,
7157 priv_cmd
.total_len
);
7159 else if (strnicmp(command
, CMD_SETDFSSCANMODE
, strlen(CMD_SETDFSSCANMODE
)) == 0) {
7160 bytes_written
= wl_android_set_scan_dfs_channel_mode(net
, command
);
7162 else if (strnicmp(command
, CMD_SETJOINPREFER
, strlen(CMD_SETJOINPREFER
)) == 0) {
7163 bytes_written
= wl_android_set_join_prefer(net
, command
);
7165 else if (strnicmp(command
, CMD_GETWESMODE
, strlen(CMD_GETWESMODE
)) == 0) {
7166 bytes_written
= wl_android_get_wes_mode(net
, command
, priv_cmd
.total_len
);
7168 else if (strnicmp(command
, CMD_SETWESMODE
, strlen(CMD_SETWESMODE
)) == 0) {
7169 bytes_written
= wl_android_set_wes_mode(net
, command
);
7171 else if (strnicmp(command
, CMD_GETOKCMODE
, strlen(CMD_GETOKCMODE
)) == 0) {
7172 bytes_written
= wl_android_get_okc_mode(net
, command
, priv_cmd
.total_len
);
7174 else if (strnicmp(command
, CMD_SETOKCMODE
, strlen(CMD_SETOKCMODE
)) == 0) {
7175 bytes_written
= wl_android_set_okc_mode(net
, command
);
7177 else if (strnicmp(command
, CMD_OKC_SET_PMK
, strlen(CMD_OKC_SET_PMK
)) == 0) {
7178 bytes_written
= wl_android_set_pmk(net
, command
, priv_cmd
.total_len
);
7180 else if (strnicmp(command
, CMD_OKC_ENABLE
, strlen(CMD_OKC_ENABLE
)) == 0) {
7181 bytes_written
= wl_android_okc_enable(net
, command
);
7183 #endif /* WES_SUPPORT */
7185 else if (strnicmp(command
, CMD_TDLS_RESET
, strlen(CMD_TDLS_RESET
)) == 0) {
7186 bytes_written
= wl_android_tdls_reset(net
);
7189 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
7192 else if (strnicmp(command
, CMD_PNOSSIDCLR_SET
, strlen(CMD_PNOSSIDCLR_SET
)) == 0) {
7193 #if defined(SUPPORT_RANDOM_MAC_SCAN)
7194 wl_cfg80211_set_random_mac(net
, FALSE
);
7195 #endif /* SUPPORT_RANDOM_MAC_SCAN */
7196 bytes_written
= dhd_dev_pno_stop_for_ssid(net
);
7198 #ifndef WL_SCHED_SCAN
7199 else if (strnicmp(command
, CMD_PNOSETUP_SET
, strlen(CMD_PNOSETUP_SET
)) == 0) {
7200 #if defined(SUPPORT_RANDOM_MAC_SCAN)
7201 int res
= BCME_ERROR
;
7202 res
= wl_cfg80211_set_random_mac(net
, TRUE
);
7203 if (res
< 0 && res
!= BCME_UNSUPPORTED
) {
7204 DHD_ERROR(("%s : failed to set random mac for PNO scan, %d\n",
7205 __FUNCTION__
, res
));
7207 #endif /* SUPPORT_RANDOM_MAC_SCAN */
7208 bytes_written
= wl_android_set_pno_setup(net
, command
, priv_cmd
.total_len
);
7210 #endif /* !WL_SCHED_SCAN */
7211 else if (strnicmp(command
, CMD_PNOENABLE_SET
, strlen(CMD_PNOENABLE_SET
)) == 0) {
7212 int enable
= *(command
+ strlen(CMD_PNOENABLE_SET
) + 1) - '0';
7213 bytes_written
= (enable
)? 0 : dhd_dev_pno_stop_for_ssid(net
);
7215 else if (strnicmp(command
, CMD_WLS_BATCHING
, strlen(CMD_WLS_BATCHING
)) == 0) {
7216 bytes_written
= wls_parse_batching_cmd(net
, command
, priv_cmd
.total_len
);
7218 #endif /* PNO_SUPPORT */
7219 else if (strnicmp(command
, CMD_P2P_DEV_ADDR
, strlen(CMD_P2P_DEV_ADDR
)) == 0) {
7220 bytes_written
= wl_android_get_p2p_dev_addr(net
, command
, priv_cmd
.total_len
);
7222 else if (strnicmp(command
, CMD_P2P_SET_NOA
, strlen(CMD_P2P_SET_NOA
)) == 0) {
7223 int skip
= strlen(CMD_P2P_SET_NOA
) + 1;
7224 bytes_written
= wl_cfg80211_set_p2p_noa(net
, command
+ skip
,
7225 priv_cmd
.total_len
- skip
);
7227 #ifdef P2P_LISTEN_OFFLOADING
7228 else if (strnicmp(command
, CMD_P2P_LISTEN_OFFLOAD
, strlen(CMD_P2P_LISTEN_OFFLOAD
)) == 0) {
7229 u8
*sub_command
= strchr(command
, ' ');
7230 bytes_written
= wl_cfg80211_p2plo_offload(net
, command
, sub_command
,
7231 sub_command
? strlen(sub_command
) : 0);
7233 #endif /* P2P_LISTEN_OFFLOADING */
7234 #if !defined WL_ENABLE_P2P_IF
7235 else if (strnicmp(command
, CMD_P2P_GET_NOA
, strlen(CMD_P2P_GET_NOA
)) == 0) {
7236 bytes_written
= wl_cfg80211_get_p2p_noa(net
, command
, priv_cmd
.total_len
);
7238 #endif /* WL_ENABLE_P2P_IF */
7239 else if (strnicmp(command
, CMD_P2P_SET_PS
, strlen(CMD_P2P_SET_PS
)) == 0) {
7240 int skip
= strlen(CMD_P2P_SET_PS
) + 1;
7241 bytes_written
= wl_cfg80211_set_p2p_ps(net
, command
+ skip
,
7242 priv_cmd
.total_len
- skip
);
7244 else if (strnicmp(command
, CMD_P2P_ECSA
, strlen(CMD_P2P_ECSA
)) == 0) {
7245 int skip
= strlen(CMD_P2P_ECSA
) + 1;
7246 bytes_written
= wl_cfg80211_set_p2p_ecsa(net
, command
+ skip
,
7247 priv_cmd
.total_len
- skip
);
7249 else if (strnicmp(command
, CMD_P2P_INC_BW
, strlen(CMD_P2P_INC_BW
)) == 0) {
7250 int skip
= strlen(CMD_P2P_INC_BW
) + 1;
7251 bytes_written
= wl_cfg80211_increase_p2p_bw(net
,
7252 command
+ skip
, priv_cmd
.total_len
- skip
);
7255 else if (strnicmp(command
, CMD_SET_AP_WPS_P2P_IE
,
7256 strlen(CMD_SET_AP_WPS_P2P_IE
)) == 0) {
7257 int skip
= strlen(CMD_SET_AP_WPS_P2P_IE
) + 3;
7258 bytes_written
= wl_cfg80211_set_wps_p2p_ie(net
, command
+ skip
,
7259 priv_cmd
.total_len
- skip
, *(command
+ skip
- 2) - '0');
7262 else if (strnicmp(command
, CMD_GET_FTKEY
, strlen(CMD_GET_FTKEY
)) == 0) {
7263 bytes_written
= wl_cfg80211_get_fbt_key(net
, command
, priv_cmd
.total_len
);
7266 #endif /* WL_CFG80211 */
7268 else if (strnicmp(command
, CMD_GETCCKM_RN
, strlen(CMD_GETCCKM_RN
)) == 0) {
7269 bytes_written
= wl_android_get_cckm_rn(net
, command
);
7271 else if (strnicmp(command
, CMD_SETCCKM_KRK
, strlen(CMD_SETCCKM_KRK
)) == 0) {
7272 bytes_written
= wl_android_set_cckm_krk(net
, command
, priv_cmd
.total_len
);
7274 else if (strnicmp(command
, CMD_GET_ASSOC_RES_IES
, strlen(CMD_GET_ASSOC_RES_IES
)) == 0) {
7275 bytes_written
= wl_android_get_assoc_res_ies(net
, command
, priv_cmd
.total_len
);
7278 #if defined(WL_SUPPORT_AUTO_CHANNEL)
7279 else if (strnicmp(command
, CMD_GET_BEST_CHANNELS
,
7280 strlen(CMD_GET_BEST_CHANNELS
)) == 0) {
7281 bytes_written
= wl_cfg80211_get_best_channels(net
, command
,
7282 priv_cmd
.total_len
);
7284 #endif /* WL_SUPPORT_AUTO_CHANNEL */
7285 #if defined(WL_SUPPORT_AUTO_CHANNEL)
7286 else if (strnicmp(command
, CMD_SET_HAPD_AUTO_CHANNEL
,
7287 strlen(CMD_SET_HAPD_AUTO_CHANNEL
)) == 0) {
7288 int skip
= strlen(CMD_SET_HAPD_AUTO_CHANNEL
) + 1;
7289 bytes_written
= wl_android_set_auto_channel(net
, (const char*)command
+skip
, command
,
7290 priv_cmd
.total_len
);
7292 #endif /* WL_SUPPORT_AUTO_CHANNEL */
7293 #ifdef CUSTOMER_HW4_PRIVATE_CMD
7294 #ifdef SUPPORT_AMPDU_MPDU_CMD
7295 /* CMD_AMPDU_MPDU */
7296 else if (strnicmp(command
, CMD_AMPDU_MPDU
, strlen(CMD_AMPDU_MPDU
)) == 0) {
7297 int skip
= strlen(CMD_AMPDU_MPDU
) + 1;
7298 bytes_written
= wl_android_set_ampdu_mpdu(net
, (const char*)command
+skip
);
7300 #endif /* SUPPORT_AMPDU_MPDU_CMD */
7301 #if defined(SUPPORT_HIDDEN_AP)
7302 else if (strnicmp(command
, CMD_SET_HAPD_MAX_NUM_STA
,
7303 strlen(CMD_SET_HAPD_MAX_NUM_STA
)) == 0) {
7304 int skip
= strlen(CMD_SET_HAPD_MAX_NUM_STA
) + 3;
7305 wl_android_set_max_num_sta(net
, (const char*)command
+skip
);
7307 else if (strnicmp(command
, CMD_SET_HAPD_SSID
,
7308 strlen(CMD_SET_HAPD_SSID
)) == 0) {
7309 int skip
= strlen(CMD_SET_HAPD_SSID
) + 3;
7310 wl_android_set_ssid(net
, (const char*)command
+skip
);
7312 else if (strnicmp(command
, CMD_SET_HAPD_HIDE_SSID
,
7313 strlen(CMD_SET_HAPD_HIDE_SSID
)) == 0) {
7314 int skip
= strlen(CMD_SET_HAPD_HIDE_SSID
) + 3;
7315 wl_android_set_hide_ssid(net
, (const char*)command
+skip
);
7317 #endif /* SUPPORT_HIDDEN_AP */
7318 #ifdef SUPPORT_SOFTAP_SINGL_DISASSOC
7319 else if (strnicmp(command
, CMD_HAPD_STA_DISASSOC
,
7320 strlen(CMD_HAPD_STA_DISASSOC
)) == 0) {
7321 int skip
= strlen(CMD_HAPD_STA_DISASSOC
) + 1;
7322 wl_android_sta_diassoc(net
, (const char*)command
+skip
);
7324 #endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */
7325 #ifdef SUPPORT_SET_LPC
7326 else if (strnicmp(command
, CMD_HAPD_LPC_ENABLED
,
7327 strlen(CMD_HAPD_LPC_ENABLED
)) == 0) {
7328 int skip
= strlen(CMD_HAPD_LPC_ENABLED
) + 3;
7329 wl_android_set_lpc(net
, (const char*)command
+skip
);
7331 #endif /* SUPPORT_SET_LPC */
7332 #ifdef SUPPORT_TRIGGER_HANG_EVENT
7333 else if (strnicmp(command
, CMD_TEST_FORCE_HANG
,
7334 strlen(CMD_TEST_FORCE_HANG
)) == 0) {
7335 int skip
= strlen(CMD_TEST_FORCE_HANG
) + 1;
7336 net_os_send_hang_message_reason(net
, (const char*)command
+skip
);
7338 #endif /* SUPPORT_TRIGGER_HANG_EVENT */
7339 else if (strnicmp(command
, CMD_CHANGE_RL
, strlen(CMD_CHANGE_RL
)) == 0)
7340 bytes_written
= wl_android_ch_res_rl(net
, true);
7341 else if (strnicmp(command
, CMD_RESTORE_RL
, strlen(CMD_RESTORE_RL
)) == 0)
7342 bytes_written
= wl_android_ch_res_rl(net
, false);
7343 #ifdef SUPPORT_LTECX
7344 else if (strnicmp(command
, CMD_LTECX_SET
, strlen(CMD_LTECX_SET
)) == 0) {
7345 int skip
= strlen(CMD_LTECX_SET
) + 1;
7346 bytes_written
= wl_android_set_ltecx(net
, (const char*)command
+skip
);
7348 #endif /* SUPPORT_LTECX */
7350 else if (strnicmp(command
, CMD_SET_RMC_ENABLE
, strlen(CMD_SET_RMC_ENABLE
)) == 0) {
7351 int rmc_enable
= *(command
+ strlen(CMD_SET_RMC_ENABLE
) + 1) - '0';
7352 bytes_written
= wl_android_rmc_enable(net
, rmc_enable
);
7354 else if (strnicmp(command
, CMD_SET_RMC_TXRATE
, strlen(CMD_SET_RMC_TXRATE
)) == 0) {
7356 sscanf(command
, "%*s %10d", &rmc_txrate
);
7357 bytes_written
= wldev_iovar_setint(net
, "rmc_txrate", rmc_txrate
* 2);
7359 else if (strnicmp(command
, CMD_SET_RMC_ACTPERIOD
, strlen(CMD_SET_RMC_ACTPERIOD
)) == 0) {
7361 sscanf(command
, "%*s %10d", &actperiod
);
7362 bytes_written
= wldev_iovar_setint(net
, "rmc_actf_time", actperiod
);
7364 else if (strnicmp(command
, CMD_SET_RMC_IDLEPERIOD
, strlen(CMD_SET_RMC_IDLEPERIOD
)) == 0) {
7366 sscanf(command
, "%*s %10d", &acktimeout
);
7368 bytes_written
= wldev_iovar_setint(net
, "rmc_acktmo", acktimeout
);
7370 else if (strnicmp(command
, CMD_SET_RMC_LEADER
, strlen(CMD_SET_RMC_LEADER
)) == 0) {
7371 int skip
= strlen(CMD_SET_RMC_LEADER
) + 1;
7372 bytes_written
= wl_android_rmc_set_leader(net
, (const char*)command
+skip
);
7374 else if (strnicmp(command
, CMD_SET_RMC_EVENT
,
7375 strlen(CMD_SET_RMC_EVENT
)) == 0) {
7376 bytes_written
= wl_android_set_rmc_event(net
, command
);
7378 #endif /* WL_RELMCAST */
7379 else if (strnicmp(command
, CMD_GET_SCSCAN
, strlen(CMD_GET_SCSCAN
)) == 0) {
7380 bytes_written
= wl_android_get_singlecore_scan(net
, command
, priv_cmd
.total_len
);
7382 else if (strnicmp(command
, CMD_SET_SCSCAN
, strlen(CMD_SET_SCSCAN
)) == 0) {
7383 bytes_written
= wl_android_set_singlecore_scan(net
, command
);
7385 #ifdef TEST_TX_POWER_CONTROL
7386 else if (strnicmp(command
, CMD_TEST_SET_TX_POWER
,
7387 strlen(CMD_TEST_SET_TX_POWER
)) == 0) {
7388 int skip
= strlen(CMD_TEST_SET_TX_POWER
) + 1;
7389 wl_android_set_tx_power(net
, (const char*)command
+skip
);
7391 else if (strnicmp(command
, CMD_TEST_GET_TX_POWER
,
7392 strlen(CMD_TEST_GET_TX_POWER
)) == 0) {
7393 wl_android_get_tx_power(net
, command
, priv_cmd
.total_len
);
7395 #endif /* TEST_TX_POWER_CONTROL */
7396 else if (strnicmp(command
, CMD_SARLIMIT_TX_CONTROL
,
7397 strlen(CMD_SARLIMIT_TX_CONTROL
)) == 0) {
7398 int skip
= strlen(CMD_SARLIMIT_TX_CONTROL
) + 1;
7399 wl_android_set_sarlimit_txctrl(net
, (const char*)command
+skip
);
7401 #ifdef SUPPORT_SET_TID
7402 else if (strnicmp(command
, CMD_SET_TID
, strlen(CMD_SET_TID
)) == 0) {
7403 bytes_written
= wl_android_set_tid(net
, command
);
7405 else if (strnicmp(command
, CMD_GET_TID
, strlen(CMD_GET_TID
)) == 0) {
7406 bytes_written
= wl_android_get_tid(net
, command
, priv_cmd
.total_len
);
7408 #endif /* SUPPORT_SET_TID */
7409 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
7410 else if (strnicmp(command
, CMD_HAPD_MAC_FILTER
, strlen(CMD_HAPD_MAC_FILTER
)) == 0) {
7411 int skip
= strlen(CMD_HAPD_MAC_FILTER
) + 1;
7412 wl_android_set_mac_address_filter(net
, command
+skip
);
7414 else if (strnicmp(command
, CMD_SETROAMMODE
, strlen(CMD_SETROAMMODE
)) == 0)
7415 bytes_written
= wl_android_set_roam_mode(net
, command
);
7416 #if defined(BCMFW_ROAM_ENABLE)
7417 else if (strnicmp(command
, CMD_SET_ROAMPREF
, strlen(CMD_SET_ROAMPREF
)) == 0) {
7418 bytes_written
= wl_android_set_roampref(net
, command
, priv_cmd
.total_len
);
7420 #endif /* BCMFW_ROAM_ENABLE */
7421 else if (strnicmp(command
, CMD_MIRACAST
, strlen(CMD_MIRACAST
)) == 0)
7422 bytes_written
= wl_android_set_miracast(net
, command
);
7423 else if (strnicmp(command
, CMD_SETIBSSBEACONOUIDATA
, strlen(CMD_SETIBSSBEACONOUIDATA
)) == 0)
7424 bytes_written
= wl_android_set_ibss_beacon_ouidata(net
,
7425 command
, priv_cmd
.total_len
);
7427 else if (strnicmp(command
, CMD_SETIBSSTXFAILEVENT
,
7428 strlen(CMD_SETIBSSTXFAILEVENT
)) == 0)
7429 bytes_written
= wl_android_set_ibss_txfail_event(net
, command
, priv_cmd
.total_len
);
7430 else if (strnicmp(command
, CMD_GET_IBSS_PEER_INFO_ALL
,
7431 strlen(CMD_GET_IBSS_PEER_INFO_ALL
)) == 0)
7432 bytes_written
= wl_android_get_ibss_peer_info(net
, command
, priv_cmd
.total_len
,
7434 else if (strnicmp(command
, CMD_GET_IBSS_PEER_INFO
,
7435 strlen(CMD_GET_IBSS_PEER_INFO
)) == 0)
7436 bytes_written
= wl_android_get_ibss_peer_info(net
, command
, priv_cmd
.total_len
,
7438 else if (strnicmp(command
, CMD_SETIBSSROUTETABLE
,
7439 strlen(CMD_SETIBSSROUTETABLE
)) == 0)
7440 bytes_written
= wl_android_set_ibss_routetable(net
, command
);
7441 else if (strnicmp(command
, CMD_SETIBSSAMPDU
, strlen(CMD_SETIBSSAMPDU
)) == 0)
7442 bytes_written
= wl_android_set_ibss_ampdu(net
, command
, priv_cmd
.total_len
);
7443 else if (strnicmp(command
, CMD_SETIBSSANTENNAMODE
, strlen(CMD_SETIBSSANTENNAMODE
)) == 0)
7444 bytes_written
= wl_android_set_ibss_antenna(net
, command
, priv_cmd
.total_len
);
7445 #endif /* WLAIBSS */
7446 else if (strnicmp(command
, CMD_KEEP_ALIVE
, strlen(CMD_KEEP_ALIVE
)) == 0) {
7447 int skip
= strlen(CMD_KEEP_ALIVE
) + 1;
7448 bytes_written
= wl_keep_alive_set(net
, command
+ skip
);
7450 else if (strnicmp(command
, CMD_ROAM_OFFLOAD
, strlen(CMD_ROAM_OFFLOAD
)) == 0) {
7451 int enable
= *(command
+ strlen(CMD_ROAM_OFFLOAD
) + 1) - '0';
7452 bytes_written
= wl_cfg80211_enable_roam_offload(net
, enable
);
7454 else if (strnicmp(command
, CMD_INTERFACE_CREATE
, strlen(CMD_INTERFACE_CREATE
)) == 0) {
7455 char *name
= (command
+ strlen(CMD_INTERFACE_CREATE
) +1);
7456 WL_INFORM(("Creating %s interface\n", name
));
7457 if (wl_cfg80211_add_if(wl_get_cfg(net
), net
, WL_IF_TYPE_STA
,
7458 name
, NULL
) == NULL
) {
7459 bytes_written
= -ENODEV
;
7461 /* Return success */
7465 else if (strnicmp(command
, CMD_INTERFACE_DELETE
, strlen(CMD_INTERFACE_DELETE
)) == 0) {
7466 char *name
= (command
+ strlen(CMD_INTERFACE_DELETE
) +1);
7467 WL_INFORM(("Deleteing %s interface\n", name
));
7468 bytes_written
= wl_cfg80211_del_if(wl_get_cfg(net
), net
, NULL
, name
);
7470 else if (strnicmp(command
, CMD_GET_LINK_STATUS
, strlen(CMD_GET_LINK_STATUS
)) == 0) {
7471 bytes_written
= wl_android_get_link_status(net
, command
, priv_cmd
.total_len
);
7473 #ifdef P2PRESP_WFDIE_SRC
7474 else if (strnicmp(command
, CMD_P2P_SET_WFDIE_RESP
,
7475 strlen(CMD_P2P_SET_WFDIE_RESP
)) == 0) {
7476 int mode
= *(command
+ strlen(CMD_P2P_SET_WFDIE_RESP
) + 1) - '0';
7477 bytes_written
= wl_android_set_wfdie_resp(net
, mode
);
7478 } else if (strnicmp(command
, CMD_P2P_GET_WFDIE_RESP
,
7479 strlen(CMD_P2P_GET_WFDIE_RESP
)) == 0) {
7480 bytes_written
= wl_android_get_wfdie_resp(net
, command
, priv_cmd
.total_len
);
7482 #endif /* P2PRESP_WFDIE_SRC */
7483 else if (strnicmp(command
, CMD_DFS_AP_MOVE
, strlen(CMD_DFS_AP_MOVE
)) == 0) {
7484 char *data
= (command
+ strlen(CMD_DFS_AP_MOVE
) +1);
7485 bytes_written
= wl_cfg80211_dfs_ap_move(net
, data
, command
, priv_cmd
.total_len
);
7488 else if (strnicmp(command
, CMD_WBTEXT_ENABLE
, strlen(CMD_WBTEXT_ENABLE
)) == 0) {
7489 bytes_written
= wl_android_wbtext(net
, command
, priv_cmd
.total_len
);
7491 else if (strnicmp(command
, CMD_WBTEXT_PROFILE_CONFIG
,
7492 strlen(CMD_WBTEXT_PROFILE_CONFIG
)) == 0) {
7493 char *data
= (command
+ strlen(CMD_WBTEXT_PROFILE_CONFIG
) + 1);
7494 bytes_written
= wl_cfg80211_wbtext_config(net
, data
, command
, priv_cmd
.total_len
);
7496 else if (strnicmp(command
, CMD_WBTEXT_WEIGHT_CONFIG
,
7497 strlen(CMD_WBTEXT_WEIGHT_CONFIG
)) == 0) {
7498 char *data
= (command
+ strlen(CMD_WBTEXT_WEIGHT_CONFIG
) + 1);
7499 bytes_written
= wl_cfg80211_wbtext_weight_config(net
, data
,
7500 command
, priv_cmd
.total_len
);
7502 else if (strnicmp(command
, CMD_WBTEXT_TABLE_CONFIG
,
7503 strlen(CMD_WBTEXT_TABLE_CONFIG
)) == 0) {
7504 char *data
= (command
+ strlen(CMD_WBTEXT_TABLE_CONFIG
) + 1);
7505 bytes_written
= wl_cfg80211_wbtext_table_config(net
, data
,
7506 command
, priv_cmd
.total_len
);
7508 else if (strnicmp(command
, CMD_WBTEXT_DELTA_CONFIG
,
7509 strlen(CMD_WBTEXT_DELTA_CONFIG
)) == 0) {
7510 char *data
= (command
+ strlen(CMD_WBTEXT_DELTA_CONFIG
) + 1);
7511 bytes_written
= wl_cfg80211_wbtext_delta_config(net
, data
,
7512 command
, priv_cmd
.total_len
);
7514 else if (strnicmp(command
, CMD_WBTEXT_BTM_TIMER_THRESHOLD
,
7515 strlen(CMD_WBTEXT_BTM_TIMER_THRESHOLD
)) == 0) {
7516 bytes_written
= wl_cfg80211_wbtext_btm_timer_threshold(net
, command
,
7517 priv_cmd
.total_len
);
7519 else if (strnicmp(command
, CMD_WBTEXT_BTM_DELTA
,
7520 strlen(CMD_WBTEXT_BTM_DELTA
)) == 0) {
7521 bytes_written
= wl_cfg80211_wbtext_btm_delta(net
, command
,
7522 priv_cmd
.total_len
);
7526 else if (strnicmp(command
, CMD_RPSMODE
, strlen(CMD_RPSMODE
)) == 0) {
7527 bytes_written
= wl_android_set_rps_cpus(net
, command
);
7529 #endif /* SET_RPS_CPUS */
7531 else if (strnicmp(command
, CMD_ADD_WFDS_HASH
, strlen(CMD_ADD_WFDS_HASH
)) == 0) {
7532 bytes_written
= wl_android_set_wfds_hash(net
, command
, 1);
7534 else if (strnicmp(command
, CMD_DEL_WFDS_HASH
, strlen(CMD_DEL_WFDS_HASH
)) == 0) {
7535 bytes_written
= wl_android_set_wfds_hash(net
, command
, 0);
7538 #ifdef BT_WIFI_HANDOVER
7539 else if (strnicmp(command
, CMD_TBOW_TEARDOWN
, strlen(CMD_TBOW_TEARDOWN
)) == 0) {
7540 bytes_written
= wl_tbow_teardown(net
);
7542 #endif /* BT_WIFI_HANDOVER */
7543 #ifdef CUSTOMER_HW4_PRIVATE_CMD
7544 #ifdef FCC_PWR_LIMIT_2G
7545 else if (strnicmp(command
, CMD_GET_FCC_PWR_LIMIT_2G
,
7546 strlen(CMD_GET_FCC_PWR_LIMIT_2G
)) == 0) {
7547 bytes_written
= wl_android_get_fcc_pwr_limit_2g(net
, command
, priv_cmd
.total_len
);
7549 else if (strnicmp(command
, CMD_SET_FCC_PWR_LIMIT_2G
,
7550 strlen(CMD_SET_FCC_PWR_LIMIT_2G
)) == 0) {
7551 bytes_written
= wl_android_set_fcc_pwr_limit_2g(net
, command
);
7553 #endif /* FCC_PWR_LIMIT_2G */
7554 else if (strnicmp(command
, CMD_GET_STA_INFO
, strlen(CMD_GET_STA_INFO
)) == 0) {
7555 bytes_written
= wl_cfg80211_get_sta_info(net
, command
, priv_cmd
.total_len
);
7557 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
7558 #ifdef DYNAMIC_MUMIMO_CONTROL
7559 else if (strnicmp(command
, CMD_GET_MURX_BFE_CAP
,
7560 strlen(CMD_GET_MURX_BFE_CAP
)) == 0) {
7561 bytes_written
= wl_android_get_murx_bfe_cap(net
, command
, priv_cmd
.total_len
);
7563 else if (strnicmp(command
, CMD_SET_MURX_BFE_CAP
,
7564 strlen(CMD_SET_MURX_BFE_CAP
)) == 0) {
7565 uint val
= *(command
+ strlen(CMD_SET_MURX_BFE_CAP
) + 1) - '0';
7566 bytes_written
= wl_android_set_murx_bfe_cap(net
, val
);
7568 else if (strnicmp(command
, CMD_GET_BSS_SUPPORT_MUMIMO
,
7569 strlen(CMD_GET_BSS_SUPPORT_MUMIMO
)) == 0) {
7570 bytes_written
= wl_android_get_bss_support_mumimo(net
, command
, priv_cmd
.total_len
);
7572 #endif /* DYNAMIC_MUMIMO_CONTROL */
7573 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
7574 else if (strnicmp(command
, CMD_GET_AP_BASICRATE
, strlen(CMD_GET_AP_BASICRATE
)) == 0) {
7575 bytes_written
= wl_android_get_ap_basicrate(net
, command
, priv_cmd
.total_len
);
7577 else if (strnicmp(command
, CMD_SET_AP_BEACONRATE
, strlen(CMD_SET_AP_BEACONRATE
)) == 0) {
7578 bytes_written
= wl_android_set_ap_beaconrate(net
, command
);
7580 #endif /* SUPPORT_AP_HIGHER_BEACONRATE */
7581 #ifdef SUPPORT_AP_RADIO_PWRSAVE
7582 else if (strnicmp(command
, CMD_SET_AP_RPS_PARAMS
, strlen(CMD_SET_AP_RPS_PARAMS
)) == 0) {
7583 bytes_written
= wl_android_set_ap_rps_params(net
, command
, priv_cmd
.total_len
);
7585 else if (strnicmp(command
, CMD_SET_AP_RPS
, strlen(CMD_SET_AP_RPS
)) == 0) {
7586 bytes_written
= wl_android_set_ap_rps(net
, command
, priv_cmd
.total_len
);
7588 else if (strnicmp(command
, CMD_GET_AP_RPS
, strlen(CMD_GET_AP_RPS
)) == 0) {
7589 bytes_written
= wl_android_get_ap_rps(net
, command
, priv_cmd
.total_len
);
7591 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
7592 #ifdef SUPPORT_RSSI_SUM_REPORT
7593 else if (strnicmp(command
, CMD_SET_RSSI_LOGGING
, strlen(CMD_SET_RSSI_LOGGING
)) == 0) {
7594 bytes_written
= wl_android_set_rssi_logging(net
, command
, priv_cmd
.total_len
);
7596 else if (strnicmp(command
, CMD_GET_RSSI_LOGGING
, strlen(CMD_GET_RSSI_LOGGING
)) == 0) {
7597 bytes_written
= wl_android_get_rssi_logging(net
, command
, priv_cmd
.total_len
);
7599 else if (strnicmp(command
, CMD_GET_RSSI_PER_ANT
, strlen(CMD_GET_RSSI_PER_ANT
)) == 0) {
7600 bytes_written
= wl_android_get_rssi_per_ant(net
, command
, priv_cmd
.total_len
);
7602 #endif /* SUPPORT_RSSI_SUM_REPORT */
7603 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
7604 else if (strnicmp(command
, CMD_GET_BSS_INFO
, strlen(CMD_GET_BSS_INFO
)) == 0) {
7605 bytes_written
= wl_cfg80211_get_bss_info(net
, command
, priv_cmd
.total_len
);
7607 else if (strnicmp(command
, CMD_GET_ASSOC_REJECT_INFO
, strlen(CMD_GET_ASSOC_REJECT_INFO
))
7609 bytes_written
= wl_cfg80211_get_connect_failed_status(net
, command
,
7610 priv_cmd
.total_len
);
7612 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
7613 #if defined(SUPPORT_RANDOM_MAC_SCAN)
7614 else if (strnicmp(command
, ENABLE_RANDOM_MAC
, strlen(ENABLE_RANDOM_MAC
)) == 0) {
7615 bytes_written
= wl_cfg80211_set_random_mac(net
, TRUE
);
7616 } else if (strnicmp(command
, DISABLE_RANDOM_MAC
, strlen(DISABLE_RANDOM_MAC
)) == 0) {
7617 bytes_written
= wl_cfg80211_set_random_mac(net
, FALSE
);
7619 #endif /* SUPPORT_RANDOM_MAC_SCAN */
7621 else if (strnicmp(command
, CMD_NATOE
, strlen(CMD_NATOE
)) == 0) {
7622 bytes_written
= wl_android_process_natoe_cmd(net
, command
,
7623 priv_cmd
.total_len
);
7625 #endif /* WL_NATOE */
7626 #ifdef CONNECTION_STATISTICS
7627 else if (strnicmp(command
, CMD_GET_CONNECTION_STATS
,
7628 strlen(CMD_GET_CONNECTION_STATS
)) == 0) {
7629 bytes_written
= wl_android_get_connection_stats(net
, command
,
7630 priv_cmd
.total_len
);
7634 else if (strnicmp(command
, CMD_NEW_DEBUG_PRINT_DUMP
,
7635 strlen(CMD_NEW_DEBUG_PRINT_DUMP
)) == 0) {
7636 dhd_pub_t
*dhdp
= wl_cfg80211_get_dhdp(net
);
7637 /* check whether it has more command */
7638 if (strnicmp(command
+ strlen(CMD_NEW_DEBUG_PRINT_DUMP
), " ", 1) == 0) {
7639 /* compare unwanted/disconnected command */
7640 if (strnicmp(command
+ strlen(CMD_NEW_DEBUG_PRINT_DUMP
) + 1,
7641 SUBCMD_UNWANTED
, strlen(SUBCMD_UNWANTED
)) == 0) {
7642 dhd_log_dump_trigger(dhdp
, CMD_UNWANTED
);
7643 } else if (strnicmp(command
+ strlen(CMD_NEW_DEBUG_PRINT_DUMP
) + 1,
7644 SUBCMD_DISCONNECTED
, strlen(SUBCMD_DISCONNECTED
)) == 0) {
7645 dhd_log_dump_trigger(dhdp
, CMD_DISCONNECTED
);
7647 dhd_log_dump_trigger(dhdp
, CMD_DEFAULT
);
7650 dhd_log_dump_trigger(dhdp
, CMD_DEFAULT
);
7653 #endif /* DHD_LOG_DUMP */
7654 #ifdef SET_PCIE_IRQ_CPU_CORE
7655 else if (strnicmp(command
, CMD_PCIE_IRQ_CORE
, strlen(CMD_PCIE_IRQ_CORE
)) == 0) {
7656 int affinity_cmd
= *(command
+ strlen(CMD_PCIE_IRQ_CORE
) + 1) - '0';
7657 wl_android_set_irq_cpucore(net
, affinity_cmd
);
7659 #endif /* SET_PCIE_IRQ_CPU_CORE */
7660 #if defined(DHD_HANG_SEND_UP_TEST)
7661 else if (strnicmp(command
, CMD_MAKE_HANG
, strlen(CMD_MAKE_HANG
)) == 0) {
7662 int skip
= strlen(CMD_MAKE_HANG
) + 1;
7663 wl_android_make_hang_with_reason(net
, (const char*)command
+skip
);
7665 #endif /* DHD_HANG_SEND_UP_TEST */
7667 else if (strnicmp(command
, CMD_SET_LQCM_ENABLE
, strlen(CMD_SET_LQCM_ENABLE
)) == 0) {
7668 int lqcm_enable
= *(command
+ strlen(CMD_SET_LQCM_ENABLE
) + 1) - '0';
7669 bytes_written
= wl_android_lqcm_enable(net
, lqcm_enable
);
7671 else if (strnicmp(command
, CMD_GET_LQCM_REPORT
,
7672 strlen(CMD_GET_LQCM_REPORT
)) == 0) {
7673 bytes_written
= wl_android_get_lqcm_report(net
, command
,
7674 priv_cmd
.total_len
);
7677 else if (strnicmp(command
, CMD_GET_SNR
, strlen(CMD_GET_SNR
)) == 0) {
7678 bytes_written
= wl_android_get_snr(net
, command
, priv_cmd
.total_len
);
7680 #ifdef WLADPS_PRIVATE_CMD
7681 else if (strnicmp(command
, CMD_SET_ADPS
, strlen(CMD_SET_ADPS
)) == 0) {
7682 int skip
= strlen(CMD_SET_ADPS
) + 1;
7683 bytes_written
= wl_android_set_adps_mode(net
, (const char*)command
+skip
);
7685 else if (strnicmp(command
, CMD_GET_ADPS
, strlen(CMD_GET_ADPS
)) == 0) {
7686 bytes_written
= wl_android_get_adps_mode(net
, command
, priv_cmd
.total_len
);
7688 #endif /* WLADPS_PRIVATE_CMD */
7689 #ifdef DHD_PKT_LOGGING
7690 else if (strnicmp(command
, CMD_PKTLOG_FILTER_ENABLE
,
7691 strlen(CMD_PKTLOG_FILTER_ENABLE
)) == 0) {
7692 bytes_written
= wl_android_pktlog_filter_enable(net
, command
, priv_cmd
.total_len
);
7694 else if (strnicmp(command
, CMD_PKTLOG_FILTER_DISABLE
,
7695 strlen(CMD_PKTLOG_FILTER_DISABLE
)) == 0) {
7696 bytes_written
= wl_android_pktlog_filter_disable(net
, command
, priv_cmd
.total_len
);
7698 else if (strnicmp(command
, CMD_PKTLOG_FILTER_PATTERN_ENABLE
,
7699 strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE
)) == 0) {
7701 wl_android_pktlog_filter_pattern_enable(net
, command
, priv_cmd
.total_len
);
7703 else if (strnicmp(command
, CMD_PKTLOG_FILTER_PATTERN_DISABLE
,
7704 strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE
)) == 0) {
7706 wl_android_pktlog_filter_pattern_disable(net
, command
, priv_cmd
.total_len
);
7708 else if (strnicmp(command
, CMD_PKTLOG_FILTER_ADD
, strlen(CMD_PKTLOG_FILTER_ADD
)) == 0) {
7709 bytes_written
= wl_android_pktlog_filter_add(net
, command
, priv_cmd
.total_len
);
7711 else if (strnicmp(command
, CMD_PKTLOG_FILTER_INFO
, strlen(CMD_PKTLOG_FILTER_INFO
)) == 0) {
7712 bytes_written
= wl_android_pktlog_filter_info(net
, command
, priv_cmd
.total_len
);
7714 else if (strnicmp(command
, CMD_PKTLOG_START
, strlen(CMD_PKTLOG_START
)) == 0) {
7715 bytes_written
= wl_android_pktlog_start(net
, command
, priv_cmd
.total_len
);
7717 else if (strnicmp(command
, CMD_PKTLOG_STOP
, strlen(CMD_PKTLOG_STOP
)) == 0) {
7718 bytes_written
= wl_android_pktlog_stop(net
, command
, priv_cmd
.total_len
);
7720 else if (strnicmp(command
, CMD_PKTLOG_FILTER_EXIST
, strlen(CMD_PKTLOG_FILTER_EXIST
)) == 0) {
7721 bytes_written
= wl_android_pktlog_filter_exist(net
, command
, priv_cmd
.total_len
);
7723 else if (strnicmp(command
, CMD_PKTLOG_MINMIZE_ENABLE
,
7724 strlen(CMD_PKTLOG_MINMIZE_ENABLE
)) == 0) {
7725 bytes_written
= wl_android_pktlog_minmize_enable(net
, command
, priv_cmd
.total_len
);
7727 else if (strnicmp(command
, CMD_PKTLOG_MINMIZE_DISABLE
,
7728 strlen(CMD_PKTLOG_MINMIZE_DISABLE
)) == 0) {
7729 bytes_written
= wl_android_pktlog_minmize_disable(net
, command
, priv_cmd
.total_len
);
7731 else if (strnicmp(command
, CMD_PKTLOG_CHANGE_SIZE
,
7732 strlen(CMD_PKTLOG_CHANGE_SIZE
)) == 0) {
7733 bytes_written
= wl_android_pktlog_change_size(net
, command
, priv_cmd
.total_len
);
7735 #endif /* DHD_PKT_LOGGING */
7736 else if (strnicmp(command
, CMD_DEBUG_VERBOSE
, strlen(CMD_DEBUG_VERBOSE
)) == 0) {
7737 int verbose_level
= *(command
+ strlen(CMD_DEBUG_VERBOSE
) + 1) - '0';
7738 bytes_written
= wl_cfg80211_set_dbg_verbose(net
, verbose_level
);
7740 #ifdef DHD_EVENT_LOG_FILTER
7741 else if (strnicmp(command
, CMD_EWP_FILTER
,
7742 strlen(CMD_EWP_FILTER
)) == 0) {
7743 bytes_written
= wl_android_ewp_filter(net
, command
, priv_cmd
.total_len
);
7745 #endif /* DHD_EVENT_LOG_FILTER */
7746 #ifdef APSTA_RESTRICTED_CHANNEL
7747 else if (strnicmp(command
, CMD_GET_INDOOR_CHANNELS
,
7748 strlen(CMD_GET_INDOOR_CHANNELS
)) == 0) {
7749 bytes_written
= wl_cfg80211_get_indoor_channels(net
, command
, priv_cmd
.total_len
);
7750 DHD_INFO(("Selected Indoor Channels - %s\n", command
));
7752 else if (strnicmp(command
, CMD_SET_INDOOR_CHANNELS
,
7753 strlen(CMD_SET_INDOOR_CHANNELS
)) == 0) {
7754 bytes_written
= wl_cfg80211_set_indoor_channels(net
, command
, priv_cmd
.total_len
);
7756 #endif /* APSTA_RESTRICTED_CHANNEL */
7757 #ifdef SUPPORT_SET_CAC
7758 else if (strnicmp(command
, CMD_ENABLE_CAC
, strlen(CMD_ENABLE_CAC
)) == 0) {
7759 int enable
= *(command
+ strlen(CMD_ENABLE_CAC
) + 1) - '0';
7760 bytes_written
= wl_cfg80211_enable_cac(net
, enable
);
7762 #endif /* SUPPORT_SET_CAC */
7764 DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command
));
7765 bytes_written
= scnprintf(command
, sizeof("FAIL"), "FAIL");
7768 return bytes_written
;
7771 int wl_android_init(void)
7775 #ifdef ENABLE_INSMOD_NO_FW_LOAD
7776 dhd_download_fw_on_driverload
= FALSE
;
7777 #endif /* ENABLE_INSMOD_NO_FW_LOAD */
7778 if (!iface_name
[0]) {
7779 memset(iface_name
, 0, IFNAMSIZ
);
7780 bcm_strncpy_s(iface_name
, IFNAMSIZ
, "wlan", IFNAMSIZ
);
7783 #ifdef CUSTOMER_HW4_DEBUG
7785 #endif /* CUSTOMER_HW4_DEBUG */
7795 int wl_android_exit(void)
7798 struct io_cfg
*cur
, *q
;
7802 #endif /* WL_GENL */
7803 wl_netlink_deinit();
7805 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
7806 #pragma GCC diagnostic push
7807 #pragma GCC diagnostic ignored "-Wcast-qual"
7809 list_for_each_entry_safe(cur
, q
, &miracast_resume_list
, list
) {
7810 list_del(&cur
->list
);
7813 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
7814 #pragma GCC diagnostic pop
7820 void wl_android_post_init(void)
7823 #ifdef ENABLE_4335BT_WAR
7824 bcm_bt_unlock(lock_cookie_wifi
);
7825 printk("%s: btlock released\n", __FUNCTION__
);
7826 #endif /* ENABLE_4335BT_WAR */
7828 if (!dhd_download_fw_on_driverload
)
7833 /* Generic Netlink Initializaiton */
7834 static int wl_genl_init(void)
7838 WL_DBG(("GEN Netlink Init\n\n"));
7840 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
7841 /* register new family */
7842 ret
= genl_register_family(&wl_genl_family
);
7846 /* register functions (commands) of the new family */
7847 ret
= genl_register_ops(&wl_genl_family
, &wl_genl_ops
);
7849 WL_ERR(("register ops failed: %i\n", ret
));
7850 genl_unregister_family(&wl_genl_family
);
7854 ret
= genl_register_mc_group(&wl_genl_family
, &wl_genl_mcast
);
7856 ret
= genl_register_family_with_ops_groups(&wl_genl_family
, wl_genl_ops
, wl_genl_mcast
);
7857 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
7859 WL_ERR(("register mc_group failed: %i\n", ret
));
7860 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
7861 genl_unregister_ops(&wl_genl_family
, &wl_genl_ops
);
7863 genl_unregister_family(&wl_genl_family
);
7870 WL_ERR(("Registering Netlink failed!!\n"));
7874 /* Generic netlink deinit */
7875 static int wl_genl_deinit(void)
7878 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
7879 if (genl_unregister_ops(&wl_genl_family
, &wl_genl_ops
) < 0)
7880 WL_ERR(("Unregister wl_genl_ops failed\n"));
7882 if (genl_unregister_family(&wl_genl_family
) < 0)
7883 WL_ERR(("Unregister wl_genl_ops failed\n"));
7888 s32
wl_event_to_bcm_event(u16 event_type
)
7892 switch (event_type
) {
7893 case WLC_E_SERVICE_FOUND
:
7894 event
= BCM_E_SVC_FOUND
;
7896 case WLC_E_P2PO_ADD_DEVICE
:
7897 event
= BCM_E_DEV_FOUND
;
7899 case WLC_E_P2PO_DEL_DEVICE
:
7900 event
= BCM_E_DEV_LOST
;
7902 /* Above events are supported from BCM Supp ver 47 Onwards */
7903 #ifdef BT_WIFI_HANDOVER
7904 case WLC_E_BT_WIFI_HANDOVER_REQ
:
7905 event
= BCM_E_DEV_BT_WIFI_HO_REQ
;
7907 #endif /* BT_WIFI_HANDOVER */
7910 WL_ERR(("Event not supported\n"));
7918 struct net_device
*ndev
,
7926 struct sk_buff
*skb
;
7929 bcm_event_hdr_t
*hdr
= NULL
;
7930 int mcast
= 1; /* By default sent as mutlicast type */
7932 u8
*ptr
= NULL
, *p
= NULL
;
7933 u32 tot_len
= sizeof(bcm_event_hdr_t
) + subhdr_len
+ len
;
7934 u16 kflags
= in_atomic() ? GFP_ATOMIC
: GFP_KERNEL
;
7935 struct bcm_cfg80211
*cfg
= wl_get_cfg(ndev
);
7937 WL_DBG(("Enter \n"));
7939 /* Decide between STRING event and Data event */
7940 if (event_type
== 0)
7941 attr_type
= BCM_GENL_ATTR_STRING
;
7943 attr_type
= BCM_GENL_ATTR_MSG
;
7945 skb
= genlmsg_new(NLMSG_GOODSIZE
, kflags
);
7951 msg
= genlmsg_put(skb
, 0, 0, &wl_genl_family
, 0, BCM_GENL_CMD_MSG
);
7957 if (attr_type
== BCM_GENL_ATTR_STRING
) {
7958 /* Add a BCM_GENL_MSG attribute. Since it is specified as a string.
7959 * make sure it is null terminated
7961 if (subhdr
|| subhdr_len
) {
7962 WL_ERR(("No sub hdr support for the ATTR STRING type \n"));
7967 ret
= nla_put_string(skb
, BCM_GENL_ATTR_STRING
, buf
);
7969 WL_ERR(("nla_put_string failed\n"));
7975 /* Create a single buffer for all */
7976 p
= ptr
= (u8
*)MALLOCZ(cfg
->osh
, tot_len
);
7979 WL_ERR(("ENOMEM!!\n"));
7983 /* Include the bcm event header */
7984 hdr
= (bcm_event_hdr_t
*)ptr
;
7985 hdr
->event_type
= wl_event_to_bcm_event(event_type
);
7986 hdr
->len
= len
+ subhdr_len
;
7987 ptr
+= sizeof(bcm_event_hdr_t
);
7989 /* Copy subhdr (if any) */
7990 if (subhdr
&& subhdr_len
) {
7991 memcpy(ptr
, subhdr
, subhdr_len
);
7997 memcpy(ptr
, buf
, len
);
8000 ret
= nla_put(skb
, BCM_GENL_ATTR_MSG
, tot_len
, p
);
8002 WL_ERR(("nla_put_string failed\n"));
8009 /* finalize the message */
8010 genlmsg_end(skb
, msg
);
8011 /* NETLINK_CB(skb).dst_group = 1; */
8013 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
8014 if ((err
= genlmsg_multicast(skb
, 0, wl_genl_mcast
.id
, GFP_ATOMIC
)) < 0)
8016 if ((err
= genlmsg_multicast(&wl_genl_family
, skb
, 0, 0, GFP_ATOMIC
)) < 0)
8018 WL_ERR(("genlmsg_multicast for attr(%d) failed. Error:%d \n",
8021 WL_DBG(("Multicast msg sent successfully. attr_type:%d len:%d \n",
8022 attr_type
, tot_len
));
8024 NETLINK_CB(skb
).dst_group
= 0; /* Not in multicast group */
8026 /* finalize the message */
8027 genlmsg_end(skb
, msg
);
8029 /* send the message back */
8030 if (genlmsg_unicast(&init_net
, skb
, pid
) < 0)
8031 WL_ERR(("genlmsg_unicast failed\n"));
8036 MFREE(cfg
->osh
, p
, tot_len
);
8046 struct sk_buff
*skb
,
8047 struct genl_info
*info
)
8052 WL_DBG(("Enter \n"));
8058 na
= info
->attrs
[BCM_GENL_ATTR_MSG
];
8060 WL_ERR(("nlattribute NULL\n"));
8064 data
= (char *)nla_data(na
);
8066 WL_ERR(("Invalid data\n"));
8069 /* Handle the data */
8070 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) || defined(WL_COMPAT_WIRELESS)
8071 WL_DBG(("%s: Data received from pid (%d) \n", __func__
,
8074 WL_DBG(("%s: Data received from pid (%d) \n", __func__
,
8076 #endif /* (LINUX_VERSION < VERSION(3, 7, 0) || WL_COMPAT_WIRELESS */
8081 #endif /* WL_GENL */
8083 int wl_fatal_error(void * wl
, int rc
)
8088 #if defined(BT_OVER_SDIO)
8090 wl_android_set_wifi_on_flag(bool enable
)
8094 #endif /* BT_OVER_SDIO */
8098 wl_cfg80211_register_static_if(struct bcm_cfg80211
*cfg
, u16 iftype
, char *ifname
)
8100 struct net_device
*ndev
;
8101 struct wireless_dev
*wdev
= NULL
;
8102 int ifidx
= WL_STATIC_IFIDX
; /* Register ndev with a reserved ifidx */
8103 u8 mac_addr
[ETH_ALEN
];
8104 struct net_device
*primary_ndev
;
8106 WL_INFORM_MEM(("[STATIC_IF] Enter (%s) iftype:%d\n", ifname
, iftype
));
8109 WL_ERR(("cfg null\n"));
8113 /* Use primary mac with locally admin bit set */
8114 primary_ndev
= bcmcfg_to_prmry_ndev(cfg
);
8115 memcpy(mac_addr
, primary_ndev
->dev_addr
, ETH_ALEN
);
8116 mac_addr
[0] |= 0x02;
8118 ndev
= wl_cfg80211_allocate_if(cfg
, ifidx
, ifname
, mac_addr
,
8119 WL_BSSIDX_MAX
, NULL
);
8120 if (unlikely(!ndev
)) {
8121 WL_ERR(("Failed to allocate static_if\n"));
8124 wdev
= (struct wireless_dev
*)MALLOCZ(cfg
->osh
, sizeof(*wdev
));
8125 if (unlikely(!wdev
)) {
8126 WL_ERR(("Failed to allocate wdev for static_if\n"));
8130 wdev
->wiphy
= cfg
->wdev
->wiphy
;
8131 wdev
->iftype
= iftype
;
8133 ndev
->ieee80211_ptr
= wdev
;
8134 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
8135 wdev
->netdev
= ndev
;
8137 if (wl_cfg80211_register_if(cfg
, ifidx
,
8138 ndev
, TRUE
) != BCME_OK
) {
8139 WL_ERR(("ndev registration failed!\n"));
8143 cfg
->static_ndev
= ndev
;
8144 cfg
->static_ndev_state
= NDEV_STATE_OS_IF_CREATED
;
8145 wl_cfg80211_update_iflist_info(cfg
, ndev
, ifidx
, NULL
, WL_BSSIDX_MAX
,
8146 ifname
, NDEV_STATE_OS_IF_CREATED
);
8147 WL_INFORM_MEM(("Static I/F (%s) Registered\n", ndev
->name
));
8151 wl_cfg80211_remove_if(cfg
, ifidx
, ndev
, false);
8156 wl_cfg80211_unregister_static_if(struct bcm_cfg80211
*cfg
)
8158 WL_INFORM_MEM(("[STATIC_IF] Enter\n"));
8159 if (!cfg
|| !cfg
->static_ndev
) {
8160 WL_ERR(("invalid input\n"));
8164 /* wdev free will happen from notifier context */
8165 /* free_netdev(cfg->static_ndev);
8167 unregister_netdev(cfg
->static_ndev
);
8171 wl_cfg80211_static_if_open(struct net_device
*net
)
8173 struct wireless_dev
*wdev
= NULL
;
8174 struct bcm_cfg80211
*cfg
= wl_get_cfg(net
);
8175 struct net_device
*primary_ndev
= bcmcfg_to_prmry_ndev(cfg
);
8176 u16 iftype
= net
->ieee80211_ptr
? net
->ieee80211_ptr
->iftype
: 0;
8177 u16 wl_iftype
, wl_mode
;
8179 WL_INFORM_MEM(("[STATIC_IF] dev_open ndev %p and wdev %p\n", net
, net
->ieee80211_ptr
));
8180 ASSERT(cfg
->static_ndev
== net
);
8182 if (cfg80211_to_wl_iftype(iftype
, &wl_iftype
, &wl_mode
) < 0) {
8185 if (cfg
->static_ndev_state
!= NDEV_STATE_FW_IF_CREATED
) {
8186 wdev
= wl_cfg80211_add_if(cfg
, primary_ndev
, wl_iftype
, net
->name
, NULL
);
8187 ASSERT(wdev
== net
->ieee80211_ptr
);
8189 WL_INFORM_MEM(("Fw IF for static netdev already created\n"));
8196 wl_cfg80211_static_if_close(struct net_device
*net
)
8199 struct bcm_cfg80211
*cfg
= wl_get_cfg(net
);
8200 struct net_device
*primary_ndev
= bcmcfg_to_prmry_ndev(cfg
);
8202 if (cfg
->static_ndev_state
== NDEV_STATE_FW_IF_CREATED
) {
8203 ret
= wl_cfg80211_del_if(cfg
, primary_ndev
, net
->ieee80211_ptr
, net
->name
);
8204 if (unlikely(ret
)) {
8205 WL_ERR(("Del iface failed for static_if %d\n", ret
));
8212 wl_cfg80211_post_static_ifcreate(struct bcm_cfg80211
*cfg
,
8213 wl_if_event_info
*event
, u8
*addr
, s32 iface_type
)
8215 struct net_device
*new_ndev
= NULL
;
8216 struct wireless_dev
*wdev
= NULL
;
8218 WL_INFORM_MEM(("Updating static iface after Fw IF create \n"));
8219 new_ndev
= cfg
->static_ndev
;
8222 wdev
= new_ndev
->ieee80211_ptr
;
8224 wdev
->iftype
= iface_type
;
8225 memcpy(new_ndev
->dev_addr
, addr
, ETH_ALEN
);
8228 cfg
->static_ndev_state
= NDEV_STATE_FW_IF_CREATED
;
8229 wl_cfg80211_update_iflist_info(cfg
, new_ndev
, event
->ifidx
, addr
, event
->bssidx
,
8230 event
->name
, NDEV_STATE_FW_IF_CREATED
);
8234 wl_cfg80211_post_static_ifdel(struct bcm_cfg80211
*cfg
, struct net_device
*ndev
)
8236 cfg
->static_ndev_state
= NDEV_STATE_FW_IF_DELETED
;
8237 wl_cfg80211_update_iflist_info(cfg
, ndev
, WL_STATIC_IFIDX
, NULL
,
8238 WL_BSSIDX_MAX
, NULL
, NDEV_STATE_FW_IF_DELETED
);
8239 wl_cfg80211_clear_per_bss_ies(cfg
, ndev
->ieee80211_ptr
);
8240 wl_dealloc_netinfo_by_wdev(cfg
, ndev
->ieee80211_ptr
);
8243 #endif /* WL_STATIC_IF */