.. | .. |
---|
1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
---|
2 | 1 | /* |
---|
3 | 2 | * Linux cfg80211 driver - Android related functions |
---|
4 | 3 | * |
---|
5 | | - * Copyright (C) 1999-2019, Broadcom Corporation |
---|
6 | | - * |
---|
| 4 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
---|
| 5 | + * |
---|
| 6 | + * Copyright (C) 1999-2017, Broadcom Corporation |
---|
| 7 | + * |
---|
7 | 8 | * Unless you and Broadcom execute a separate written software license |
---|
8 | 9 | * agreement governing use of this software, this software is licensed to you |
---|
9 | 10 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
---|
10 | 11 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
---|
11 | 12 | * following added to such license: |
---|
12 | | - * |
---|
| 13 | + * |
---|
13 | 14 | * As a special exception, the copyright holders of this software give you |
---|
14 | 15 | * permission to link this software with independent modules, and to copy and |
---|
15 | 16 | * distribute the resulting executable under terms of your choice, provided that |
---|
.. | .. |
---|
17 | 18 | * the license of that module. An independent module is a module which is not |
---|
18 | 19 | * derived from this software. The special exception does not apply to any |
---|
19 | 20 | * modifications of the software. |
---|
20 | | - * |
---|
| 21 | + * |
---|
21 | 22 | * Notwithstanding the above, under no circumstances may you combine this |
---|
22 | 23 | * software in any way with any other Broadcom software provided under a license |
---|
23 | 24 | * other than the GPL, without Broadcom's express prior written consent. |
---|
.. | .. |
---|
25 | 26 | * |
---|
26 | 27 | * <<Broadcom-WL-IPTag/Open:>> |
---|
27 | 28 | * |
---|
28 | | - * $Id: wl_android.c 674374 2017-10-20 07:38:00Z $ |
---|
| 29 | + * $Id: wl_android.c 814826 2019-04-15 05:25:59Z $ |
---|
29 | 30 | */ |
---|
30 | 31 | |
---|
| 32 | +#include <linux/string.h> |
---|
31 | 33 | #include <linux/module.h> |
---|
32 | 34 | #include <linux/netdevice.h> |
---|
33 | 35 | #include <net/netlink.h> |
---|
34 | | -#ifdef CONFIG_COMPAT |
---|
35 | | -#include <linux/compat.h> |
---|
36 | | -#endif |
---|
37 | 36 | |
---|
38 | 37 | #include <wl_android.h> |
---|
39 | 38 | #include <wldev_common.h> |
---|
40 | 39 | #include <wlioctl.h> |
---|
41 | 40 | #include <wlioctl_utils.h> |
---|
42 | 41 | #include <bcmutils.h> |
---|
| 42 | +#include <bcmstdlib_s.h> |
---|
43 | 43 | #include <linux_osl.h> |
---|
44 | 44 | #include <dhd_dbg.h> |
---|
45 | 45 | #include <dngl_stats.h> |
---|
46 | 46 | #include <dhd.h> |
---|
47 | | -#include <proto/bcmip.h> |
---|
| 47 | +#include <bcmip.h> |
---|
48 | 48 | #ifdef PNO_SUPPORT |
---|
49 | 49 | #include <dhd_pno.h> |
---|
50 | | -#endif |
---|
| 50 | +#endif // endif |
---|
51 | 51 | #ifdef BCMSDIO |
---|
52 | 52 | #include <bcmsdbus.h> |
---|
53 | | -#endif |
---|
| 53 | +#endif // endif |
---|
54 | 54 | #ifdef WL_CFG80211 |
---|
55 | 55 | #include <wl_cfg80211.h> |
---|
56 | | -#endif |
---|
| 56 | +#include <wl_cfgscan.h> |
---|
| 57 | +#endif // endif |
---|
57 | 58 | #ifdef WL_NAN |
---|
58 | 59 | #include <wl_cfgnan.h> |
---|
59 | 60 | #endif /* WL_NAN */ |
---|
60 | 61 | #ifdef DHDTCPACK_SUPPRESS |
---|
61 | 62 | #include <dhd_ip.h> |
---|
62 | 63 | #endif /* DHDTCPACK_SUPPRESS */ |
---|
| 64 | +#include <bcmwifi_rspec.h> |
---|
| 65 | +#include <bcmwifi_channels.h> |
---|
| 66 | +#include <dhd_linux.h> |
---|
| 67 | +#include <bcmiov.h> |
---|
| 68 | +#ifdef DHD_PKT_LOGGING |
---|
| 69 | +#include <dhd_pktlog.h> |
---|
| 70 | +#endif /* DHD_PKT_LOGGING */ |
---|
| 71 | +#ifdef WL_BCNRECV |
---|
| 72 | +#include <wl_cfgvendor.h> |
---|
| 73 | +#include <brcm_nl80211.h> |
---|
| 74 | +#endif /* WL_BCNRECV */ |
---|
| 75 | +#ifdef WL_MBO |
---|
| 76 | +#include <mbo.h> |
---|
| 77 | +#endif /* WL_MBO */ |
---|
63 | 78 | |
---|
| 79 | +#ifdef DHD_BANDSTEER |
---|
| 80 | +#include <dhd_bandsteer.h> |
---|
| 81 | +#endif /* DHD_BANDSTEER */ |
---|
| 82 | + |
---|
| 83 | +#ifdef WL_STATIC_IF |
---|
| 84 | +#define WL_BSSIDX_MAX 16 |
---|
| 85 | +#endif /* WL_STATIC_IF */ |
---|
64 | 86 | /* |
---|
65 | 87 | * Android private command strings, PLEASE define new private commands here |
---|
66 | 88 | * so they can be updated easily in the future (if needed) |
---|
.. | .. |
---|
68 | 90 | |
---|
69 | 91 | #define CMD_START "START" |
---|
70 | 92 | #define CMD_STOP "STOP" |
---|
71 | | -#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" |
---|
72 | | -#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" |
---|
73 | | -#define CMD_RSSI "RSSI" |
---|
74 | | -#define CMD_LINKSPEED "LINKSPEED" |
---|
| 93 | + |
---|
75 | 94 | #define CMD_RXFILTER_START "RXFILTER-START" |
---|
76 | 95 | #define CMD_RXFILTER_STOP "RXFILTER-STOP" |
---|
77 | 96 | #define CMD_RXFILTER_ADD "RXFILTER-ADD" |
---|
.. | .. |
---|
81 | 100 | #define CMD_BTCOEXMODE "BTCOEXMODE" |
---|
82 | 101 | #define CMD_SETSUSPENDOPT "SETSUSPENDOPT" |
---|
83 | 102 | #define CMD_SETSUSPENDMODE "SETSUSPENDMODE" |
---|
| 103 | +#define CMD_SETDTIM_IN_SUSPEND "SET_DTIM_IN_SUSPEND" |
---|
| 104 | +#define CMD_MAXDTIM_IN_SUSPEND "MAX_DTIM_IN_SUSPEND" |
---|
| 105 | +#define CMD_DISDTIM_IN_SUSPEND "DISABLE_DTIM_IN_SUSPEND" |
---|
84 | 106 | #define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" |
---|
85 | 107 | #define CMD_SETFWPATH "SETFWPATH" |
---|
86 | 108 | #define CMD_SETBAND "SETBAND" |
---|
87 | 109 | #define CMD_GETBAND "GETBAND" |
---|
88 | 110 | #define CMD_COUNTRY "COUNTRY" |
---|
| 111 | +#define CMD_CHANNELS_IN_CC "CHANNELS_IN_CC" |
---|
89 | 112 | #define CMD_P2P_SET_NOA "P2P_SET_NOA" |
---|
| 113 | +#define CMD_BLOCKASSOC "BLOCKASSOC" |
---|
90 | 114 | #if !defined WL_ENABLE_P2P_IF |
---|
91 | 115 | #define CMD_P2P_GET_NOA "P2P_GET_NOA" |
---|
92 | 116 | #endif /* WL_ENABLE_P2P_IF */ |
---|
93 | 117 | #define CMD_P2P_SD_OFFLOAD "P2P_SD_" |
---|
| 118 | +#define CMD_P2P_LISTEN_OFFLOAD "P2P_LO_" |
---|
94 | 119 | #define CMD_P2P_SET_PS "P2P_SET_PS" |
---|
95 | 120 | #define CMD_P2P_ECSA "P2P_ECSA" |
---|
| 121 | +#define CMD_P2P_INC_BW "P2P_INCREASE_BW" |
---|
96 | 122 | #define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" |
---|
97 | 123 | #define CMD_SETROAMMODE "SETROAMMODE" |
---|
98 | 124 | #define CMD_SETIBSSBEACONOUIDATA "SETIBSSBEACONOUIDATA" |
---|
.. | .. |
---|
101 | 127 | #define CMD_NAN "NAN_" |
---|
102 | 128 | #endif /* WL_NAN */ |
---|
103 | 129 | #define CMD_COUNTRY_DELIMITER "/" |
---|
104 | | -#ifdef WL11ULB |
---|
105 | | -#define CMD_ULB_MODE "ULB_MODE" |
---|
106 | | -#define CMD_ULB_BW "ULB_BW" |
---|
107 | | -#endif /* WL11ULB */ |
---|
108 | 130 | |
---|
109 | 131 | #if defined(WL_SUPPORT_AUTO_CHANNEL) |
---|
110 | 132 | #define CMD_GET_BEST_CHANNELS "GET_BEST_CHANNELS" |
---|
111 | 133 | #endif /* WL_SUPPORT_AUTO_CHANNEL */ |
---|
112 | 134 | |
---|
113 | | -#define CMD_80211_MODE "MODE" /* 802.11 mode a/b/g/n/ac */ |
---|
114 | 135 | #define CMD_CHANSPEC "CHANSPEC" |
---|
115 | | -#define CMD_DATARATE "DATARATE" |
---|
116 | | -#define CMD_ASSOC_CLIENTS "ASSOCLIST" |
---|
117 | 136 | #define CMD_SET_CSA "SETCSA" |
---|
| 137 | +#define CMD_RSDB_MODE "RSDB_MODE" |
---|
118 | 138 | #ifdef WL_SUPPORT_AUTO_CHANNEL |
---|
119 | 139 | #define CMD_SET_HAPD_AUTO_CHANNEL "HAPD_AUTO_CHANNEL" |
---|
120 | 140 | #endif /* WL_SUPPORT_AUTO_CHANNEL */ |
---|
| 141 | +#ifdef CUSTOMER_HW4_PRIVATE_CMD |
---|
| 142 | +/* Hostapd private command */ |
---|
| 143 | +#ifdef SUPPORT_SOFTAP_SINGL_DISASSOC |
---|
| 144 | +#define CMD_HAPD_STA_DISASSOC "HAPD_STA_DISASSOC" |
---|
| 145 | +#endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */ |
---|
| 146 | +#ifdef SUPPORT_SET_LPC |
---|
| 147 | +#define CMD_HAPD_LPC_ENABLED "HAPD_LPC_ENABLED" |
---|
| 148 | +#endif /* SUPPORT_SET_LPC */ |
---|
| 149 | +#ifdef SUPPORT_TRIGGER_HANG_EVENT |
---|
| 150 | +#define CMD_TEST_FORCE_HANG "TEST_FORCE_HANG" |
---|
| 151 | +#endif /* SUPPORT_TRIGGER_HANG_EVENT */ |
---|
| 152 | +#ifdef SUPPORT_LTECX |
---|
| 153 | +#define CMD_LTECX_SET "LTECOEX" |
---|
| 154 | +#endif /* SUPPORT_LTECX */ |
---|
| 155 | +#ifdef TEST_TX_POWER_CONTROL |
---|
| 156 | +#define CMD_TEST_SET_TX_POWER "TEST_SET_TX_POWER" |
---|
| 157 | +#define CMD_TEST_GET_TX_POWER "TEST_GET_TX_POWER" |
---|
| 158 | +#endif /* TEST_TX_POWER_CONTROL */ |
---|
| 159 | +#define CMD_SARLIMIT_TX_CONTROL "SET_TX_POWER_CALLING" |
---|
| 160 | +#ifdef SUPPORT_SET_TID |
---|
| 161 | +#define CMD_SET_TID "SET_TID" |
---|
| 162 | +#define CMD_GET_TID "GET_TID" |
---|
| 163 | +#endif /* SUPPORT_SET_TID */ |
---|
| 164 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
121 | 165 | #define CMD_KEEP_ALIVE "KEEPALIVE" |
---|
122 | | - |
---|
123 | | -/* CCX Private Commands */ |
---|
124 | | - |
---|
| 166 | +#ifdef SUPPORT_HIDDEN_AP |
---|
| 167 | +#define CMD_SET_HAPD_MAX_NUM_STA "MAX_NUM_STA" |
---|
| 168 | +#define CMD_SET_HAPD_SSID "HAPD_SSID" |
---|
| 169 | +#define CMD_SET_HAPD_HIDE_SSID "HIDE_SSID" |
---|
| 170 | +#endif /* SUPPORT_HIDDEN_AP */ |
---|
125 | 171 | #ifdef PNO_SUPPORT |
---|
126 | 172 | #define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" |
---|
127 | 173 | #define CMD_PNOSETUP_SET "PNOSETUP " |
---|
.. | .. |
---|
130 | 176 | #define CMD_WLS_BATCHING "WLS_BATCHING" |
---|
131 | 177 | #endif /* PNO_SUPPORT */ |
---|
132 | 178 | |
---|
133 | | -#define CMD_OKC_SET_PMK "SET_PMK" |
---|
134 | | -#define CMD_OKC_ENABLE "OKC_ENABLE" |
---|
| 179 | +#define CMD_ADDIE "ADD_IE" |
---|
| 180 | +#define CMD_DELIE "DEL_IE" |
---|
135 | 181 | |
---|
136 | | -#define CMD_HAPD_MAC_FILTER "HAPD_MAC_FILTER" |
---|
| 182 | +#if defined(CUSTOMER_HW4_PRIVATE_CMD) || defined(IGUANA_LEGACY_CHIPS) |
---|
| 183 | + |
---|
| 184 | +#ifdef ROAM_API |
---|
| 185 | +#define CMD_ROAMTRIGGER_SET "SETROAMTRIGGER" |
---|
| 186 | +#define CMD_ROAMTRIGGER_GET "GETROAMTRIGGER" |
---|
| 187 | +#define CMD_ROAMDELTA_SET "SETROAMDELTA" |
---|
| 188 | +#define CMD_ROAMDELTA_GET "GETROAMDELTA" |
---|
| 189 | +#define CMD_ROAMSCANPERIOD_SET "SETROAMSCANPERIOD" |
---|
| 190 | +#define CMD_ROAMSCANPERIOD_GET "GETROAMSCANPERIOD" |
---|
| 191 | +#define CMD_FULLROAMSCANPERIOD_SET "SETFULLROAMSCANPERIOD" |
---|
| 192 | +#define CMD_FULLROAMSCANPERIOD_GET "GETFULLROAMSCANPERIOD" |
---|
| 193 | +#endif /* ROAM_API */ |
---|
| 194 | + |
---|
| 195 | +#if defined(SUPPORT_RANDOM_MAC_SCAN) |
---|
| 196 | +#define ENABLE_RANDOM_MAC "ENABLE_RANDOM_MAC" |
---|
| 197 | +#define DISABLE_RANDOM_MAC "DISABLE_RANDOM_MAC" |
---|
| 198 | +#endif /* SUPPORT_RANDOM_MAC_SCAN */ |
---|
| 199 | + |
---|
| 200 | +#ifdef WES_SUPPORT |
---|
| 201 | +#define CMD_GETROAMSCANCONTROL "GETROAMSCANCONTROL" |
---|
| 202 | +#define CMD_SETROAMSCANCONTROL "SETROAMSCANCONTROL" |
---|
| 203 | +#define CMD_GETROAMSCANCHANNELS "GETROAMSCANCHANNELS" |
---|
| 204 | +#define CMD_SETROAMSCANCHANNELS "SETROAMSCANCHANNELS" |
---|
| 205 | + |
---|
| 206 | +#define CMD_GETSCANCHANNELTIME "GETSCANCHANNELTIME" |
---|
| 207 | +#define CMD_SETSCANCHANNELTIME "SETSCANCHANNELTIME" |
---|
| 208 | +#define CMD_GETSCANUNASSOCTIME "GETSCANUNASSOCTIME" |
---|
| 209 | +#define CMD_SETSCANUNASSOCTIME "SETSCANUNASSOCTIME" |
---|
| 210 | +#define CMD_GETSCANPASSIVETIME "GETSCANPASSIVETIME" |
---|
| 211 | +#define CMD_SETSCANPASSIVETIME "SETSCANPASSIVETIME" |
---|
| 212 | +#define CMD_GETSCANHOMETIME "GETSCANHOMETIME" |
---|
| 213 | +#define CMD_SETSCANHOMETIME "SETSCANHOMETIME" |
---|
| 214 | +#define CMD_GETSCANHOMEAWAYTIME "GETSCANHOMEAWAYTIME" |
---|
| 215 | +#define CMD_SETSCANHOMEAWAYTIME "SETSCANHOMEAWAYTIME" |
---|
| 216 | +#define CMD_GETSCANNPROBES "GETSCANNPROBES" |
---|
| 217 | +#define CMD_SETSCANNPROBES "SETSCANNPROBES" |
---|
| 218 | +#define CMD_GETDFSSCANMODE "GETDFSSCANMODE" |
---|
| 219 | +#define CMD_SETDFSSCANMODE "SETDFSSCANMODE" |
---|
| 220 | +#define CMD_SETJOINPREFER "SETJOINPREFER" |
---|
| 221 | + |
---|
| 222 | +#define CMD_SENDACTIONFRAME "SENDACTIONFRAME" |
---|
| 223 | +#define CMD_REASSOC "REASSOC" |
---|
| 224 | + |
---|
| 225 | +#define CMD_GETWESMODE "GETWESMODE" |
---|
| 226 | +#define CMD_SETWESMODE "SETWESMODE" |
---|
| 227 | + |
---|
| 228 | +#define CMD_GETOKCMODE "GETOKCMODE" |
---|
| 229 | +#define CMD_SETOKCMODE "SETOKCMODE" |
---|
| 230 | + |
---|
| 231 | +#define CMD_OKC_SET_PMK "SET_PMK" |
---|
| 232 | +#define CMD_OKC_ENABLE "OKC_ENABLE" |
---|
| 233 | + |
---|
| 234 | +typedef struct android_wifi_reassoc_params { |
---|
| 235 | + unsigned char bssid[18]; |
---|
| 236 | + int channel; |
---|
| 237 | +} android_wifi_reassoc_params_t; |
---|
| 238 | + |
---|
| 239 | +#define ANDROID_WIFI_REASSOC_PARAMS_SIZE sizeof(struct android_wifi_reassoc_params) |
---|
| 240 | + |
---|
| 241 | +#define ANDROID_WIFI_ACTION_FRAME_SIZE 1040 |
---|
| 242 | + |
---|
| 243 | +typedef struct android_wifi_af_params { |
---|
| 244 | + unsigned char bssid[18]; |
---|
| 245 | + int channel; |
---|
| 246 | + int dwell_time; |
---|
| 247 | + int len; |
---|
| 248 | + unsigned char data[ANDROID_WIFI_ACTION_FRAME_SIZE]; |
---|
| 249 | +} android_wifi_af_params_t; |
---|
| 250 | + |
---|
| 251 | +#define ANDROID_WIFI_AF_PARAMS_SIZE sizeof(struct android_wifi_af_params) |
---|
| 252 | +#endif /* WES_SUPPORT */ |
---|
| 253 | +#ifdef SUPPORT_AMPDU_MPDU_CMD |
---|
| 254 | +#define CMD_AMPDU_MPDU "AMPDU_MPDU" |
---|
| 255 | +#endif /* SUPPORT_AMPDU_MPDU_CMD */ |
---|
| 256 | + |
---|
| 257 | +#define CMD_CHANGE_RL "CHANGE_RL" |
---|
| 258 | +#define CMD_RESTORE_RL "RESTORE_RL" |
---|
| 259 | + |
---|
| 260 | +#define CMD_SET_RMC_ENABLE "SETRMCENABLE" |
---|
| 261 | +#define CMD_SET_RMC_TXRATE "SETRMCTXRATE" |
---|
| 262 | +#define CMD_SET_RMC_ACTPERIOD "SETRMCACTIONPERIOD" |
---|
| 263 | +#define CMD_SET_RMC_IDLEPERIOD "SETRMCIDLEPERIOD" |
---|
| 264 | +#define CMD_SET_RMC_LEADER "SETRMCLEADER" |
---|
| 265 | +#define CMD_SET_RMC_EVENT "SETRMCEVENT" |
---|
| 266 | + |
---|
| 267 | +#define CMD_SET_SCSCAN "SETSINGLEANT" |
---|
| 268 | +#define CMD_GET_SCSCAN "GETSINGLEANT" |
---|
| 269 | +#ifdef WLTDLS |
---|
| 270 | +#define CMD_TDLS_RESET "TDLS_RESET" |
---|
| 271 | +#endif /* WLTDLS */ |
---|
| 272 | + |
---|
| 273 | +#ifdef CONFIG_SILENT_ROAM |
---|
| 274 | +#define CMD_SROAM_TURN_ON "SROAMTURNON" |
---|
| 275 | +#define CMD_SROAM_SET_INFO "SROAMSETINFO" |
---|
| 276 | +#define CMD_SROAM_GET_INFO "SROAMGETINFO" |
---|
| 277 | +#endif /* CONFIG_SILENT_ROAM */ |
---|
| 278 | + |
---|
| 279 | +#define CMD_SET_DISCONNECT_IES "SET_DISCONNECT_IES" |
---|
| 280 | + |
---|
| 281 | +#ifdef FCC_PWR_LIMIT_2G |
---|
| 282 | +#define CMD_GET_FCC_PWR_LIMIT_2G "GET_FCC_CHANNEL" |
---|
| 283 | +#define CMD_SET_FCC_PWR_LIMIT_2G "SET_FCC_CHANNEL" |
---|
| 284 | +/* CUSTOMER_HW4's value differs from BRCM FW value for enable/disable */ |
---|
| 285 | +#define CUSTOMER_HW4_ENABLE 0 |
---|
| 286 | +#define CUSTOMER_HW4_DISABLE -1 |
---|
| 287 | +#define CUSTOMER_HW4_EN_CONVERT(i) (i += 1) |
---|
| 288 | +#endif /* FCC_PWR_LIMIT_2G */ |
---|
| 289 | + |
---|
| 290 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
137 | 291 | |
---|
138 | 292 | #ifdef WLFBT |
---|
139 | 293 | #define CMD_GET_FTKEY "GET_FTKEY" |
---|
140 | | -#endif |
---|
| 294 | +#endif // endif |
---|
141 | 295 | |
---|
| 296 | +#ifdef WLAIBSS |
---|
| 297 | +#define CMD_SETIBSSTXFAILEVENT "SETIBSSTXFAILEVENT" |
---|
| 298 | +#define CMD_GET_IBSS_PEER_INFO "GETIBSSPEERINFO" |
---|
| 299 | +#define CMD_GET_IBSS_PEER_INFO_ALL "GETIBSSPEERINFOALL" |
---|
| 300 | +#define CMD_SETIBSSROUTETABLE "SETIBSSROUTETABLE" |
---|
| 301 | +#define CMD_SETIBSSAMPDU "SETIBSSAMPDU" |
---|
| 302 | +#define CMD_SETIBSSANTENNAMODE "SETIBSSANTENNAMODE" |
---|
| 303 | +#endif /* WLAIBSS */ |
---|
142 | 304 | |
---|
143 | 305 | #define CMD_ROAM_OFFLOAD "SETROAMOFFLOAD" |
---|
144 | | -#define CMD_ROAM_OFFLOAD_APLIST "SETROAMOFFLAPLIST" |
---|
145 | 306 | #define CMD_INTERFACE_CREATE "INTERFACE_CREATE" |
---|
146 | 307 | #define CMD_INTERFACE_DELETE "INTERFACE_DELETE" |
---|
| 308 | +#define CMD_GET_LINK_STATUS "GETLINKSTATUS" |
---|
| 309 | + |
---|
| 310 | +#if defined(DHD_ENABLE_BIGDATA_LOGGING) |
---|
| 311 | +#define CMD_GET_BSS_INFO "GETBSSINFO" |
---|
| 312 | +#define CMD_GET_ASSOC_REJECT_INFO "GETASSOCREJECTINFO" |
---|
| 313 | +#endif /* DHD_ENABLE_BIGDATA_LOGGING */ |
---|
| 314 | +#define CMD_GET_STA_INFO "GETSTAINFO" |
---|
| 315 | + |
---|
| 316 | +/* related with CMD_GET_LINK_STATUS */ |
---|
| 317 | +#define WL_ANDROID_LINK_VHT 0x01 |
---|
| 318 | +#define WL_ANDROID_LINK_MIMO 0x02 |
---|
| 319 | +#define WL_ANDROID_LINK_AP_VHT_SUPPORT 0x04 |
---|
| 320 | +#define WL_ANDROID_LINK_AP_MIMO_SUPPORT 0x08 |
---|
147 | 321 | |
---|
148 | 322 | #ifdef P2PRESP_WFDIE_SRC |
---|
149 | 323 | #define CMD_P2P_SET_WFDIE_RESP "P2P_SET_WFDIE_RESP" |
---|
.. | .. |
---|
156 | 330 | #define CMD_WBTEXT_WEIGHT_CONFIG "WBTEXT_WEIGHT_CONFIG" |
---|
157 | 331 | #define CMD_WBTEXT_TABLE_CONFIG "WBTEXT_TABLE_CONFIG" |
---|
158 | 332 | #define CMD_WBTEXT_DELTA_CONFIG "WBTEXT_DELTA_CONFIG" |
---|
| 333 | +#define CMD_WBTEXT_BTM_TIMER_THRESHOLD "WBTEXT_BTM_TIMER_THRESHOLD" |
---|
| 334 | +#define CMD_WBTEXT_BTM_DELTA "WBTEXT_BTM_DELTA" |
---|
| 335 | +#define CMD_WBTEXT_ESTM_ENABLE "WBTEXT_ESTM_ENABLE" |
---|
| 336 | + |
---|
| 337 | +#ifdef WBTEXT |
---|
| 338 | +#define CMD_WBTEXT_PROFILE_CONFIG "WBTEXT_PROFILE_CONFIG" |
---|
| 339 | +#define CMD_WBTEXT_WEIGHT_CONFIG "WBTEXT_WEIGHT_CONFIG" |
---|
| 340 | +#define CMD_WBTEXT_TABLE_CONFIG "WBTEXT_TABLE_CONFIG" |
---|
| 341 | +#define CMD_WBTEXT_DELTA_CONFIG "WBTEXT_DELTA_CONFIG" |
---|
| 342 | +#define DEFAULT_WBTEXT_PROFILE_A_V2 "a -70 -75 70 10 -75 -128 0 10" |
---|
| 343 | +#define DEFAULT_WBTEXT_PROFILE_B_V2 "b -60 -75 70 10 -75 -128 0 10" |
---|
| 344 | +#define DEFAULT_WBTEXT_PROFILE_A_V3 "a -70 -75 70 10 -75 -128 0 10" |
---|
| 345 | +#define DEFAULT_WBTEXT_PROFILE_B_V3 "b -60 -75 70 10 -75 -128 0 10" |
---|
| 346 | +#define DEFAULT_WBTEXT_WEIGHT_RSSI_A "RSSI a 65" |
---|
| 347 | +#define DEFAULT_WBTEXT_WEIGHT_RSSI_B "RSSI b 65" |
---|
| 348 | +#define DEFAULT_WBTEXT_WEIGHT_CU_A "CU a 35" |
---|
| 349 | +#define DEFAULT_WBTEXT_WEIGHT_CU_B "CU b 35" |
---|
| 350 | +#define DEFAULT_WBTEXT_WEIGHT_ESTM_DL_A "ESTM_DL a 70" |
---|
| 351 | +#define DEFAULT_WBTEXT_WEIGHT_ESTM_DL_B "ESTM_DL b 70" |
---|
| 352 | +#ifdef WBTEXT_SCORE_V2 |
---|
| 353 | +#define DEFAULT_WBTEXT_TABLE_RSSI_A "RSSI a 0 55 100 55 60 90 \ |
---|
| 354 | +60 70 60 70 80 20 80 128 20" |
---|
| 355 | +#define DEFAULT_WBTEXT_TABLE_RSSI_B "RSSI b 0 55 100 55 60 90 \ |
---|
| 356 | +60 70 60 70 80 20 80 128 20" |
---|
| 357 | +#define DEFAULT_WBTEXT_TABLE_CU_A "CU a 0 30 100 30 80 20 \ |
---|
| 358 | +80 100 20" |
---|
| 359 | +#define DEFAULT_WBTEXT_TABLE_CU_B "CU b 0 10 100 10 70 20 \ |
---|
| 360 | +70 100 20" |
---|
| 361 | +#else |
---|
| 362 | +#define DEFAULT_WBTEXT_TABLE_RSSI_A "RSSI a 0 55 100 55 60 90 \ |
---|
| 363 | +60 65 70 65 70 50 70 128 20" |
---|
| 364 | +#define DEFAULT_WBTEXT_TABLE_RSSI_B "RSSI b 0 55 100 55 60 90 \ |
---|
| 365 | +60 65 70 65 70 50 70 128 20" |
---|
| 366 | +#define DEFAULT_WBTEXT_TABLE_CU_A "CU a 0 30 100 30 50 90 \ |
---|
| 367 | +50 60 70 60 80 50 80 100 20" |
---|
| 368 | +#define DEFAULT_WBTEXT_TABLE_CU_B "CU b 0 10 100 10 25 90 \ |
---|
| 369 | +25 40 70 40 70 50 70 100 20" |
---|
| 370 | +#endif /* WBTEXT_SCORE_V2 */ |
---|
| 371 | +#endif /* WBTEXT */ |
---|
| 372 | + |
---|
| 373 | +#define BUFSZ 8 |
---|
| 374 | +#define BUFSZN BUFSZ + 1 |
---|
| 375 | + |
---|
| 376 | +#define _S(x) #x |
---|
| 377 | +#define S(x) _S(x) |
---|
| 378 | + |
---|
| 379 | +#define MAXBANDS 2 /**< Maximum #of bands */ |
---|
| 380 | +#define BAND_2G_INDEX 0 |
---|
| 381 | +#define BAND_5G_INDEX 0 |
---|
| 382 | + |
---|
| 383 | +typedef union { |
---|
| 384 | + wl_roam_prof_band_v1_t v1; |
---|
| 385 | + wl_roam_prof_band_v2_t v2; |
---|
| 386 | + wl_roam_prof_band_v3_t v3; |
---|
| 387 | +} wl_roamprof_band_t; |
---|
159 | 388 | |
---|
160 | 389 | #ifdef WLWFDS |
---|
161 | 390 | #define CMD_ADD_WFDS_HASH "ADD_WFDS_HASH" |
---|
.. | .. |
---|
170 | 399 | #define CMD_TBOW_TEARDOWN "TBOW_TEARDOWN" |
---|
171 | 400 | #endif /* BT_WIFI_HANDOVER */ |
---|
172 | 401 | |
---|
| 402 | +#define CMD_MURX_BFE_CAP "MURX_BFE_CAP" |
---|
| 403 | + |
---|
| 404 | +#ifdef SUPPORT_RSSI_SUM_REPORT |
---|
| 405 | +#define CMD_SET_RSSI_LOGGING "SET_RSSI_LOGGING" |
---|
| 406 | +#define CMD_GET_RSSI_LOGGING "GET_RSSI_LOGGING" |
---|
| 407 | +#define CMD_GET_RSSI_PER_ANT "GET_RSSI_PER_ANT" |
---|
| 408 | +#endif /* SUPPORT_RSSI_SUM_REPORT */ |
---|
| 409 | + |
---|
| 410 | +#define CMD_GET_SNR "GET_SNR" |
---|
| 411 | + |
---|
| 412 | +#ifdef SUPPORT_AP_HIGHER_BEACONRATE |
---|
| 413 | +#define CMD_SET_AP_BEACONRATE "SET_AP_BEACONRATE" |
---|
| 414 | +#define CMD_GET_AP_BASICRATE "GET_AP_BASICRATE" |
---|
| 415 | +#endif /* SUPPORT_AP_HIGHER_BEACONRATE */ |
---|
| 416 | + |
---|
| 417 | +#ifdef SUPPORT_AP_RADIO_PWRSAVE |
---|
| 418 | +#define CMD_SET_AP_RPS "SET_AP_RPS" |
---|
| 419 | +#define CMD_GET_AP_RPS "GET_AP_RPS" |
---|
| 420 | +#define CMD_SET_AP_RPS_PARAMS "SET_AP_RPS_PARAMS" |
---|
| 421 | +#endif /* SUPPORT_AP_RADIO_PWRSAVE */ |
---|
| 422 | + |
---|
| 423 | +#ifdef DHD_BANDSTEER |
---|
| 424 | +#define CMD_BANDSTEER "BANDSTEER" |
---|
| 425 | +#define CMD_BANDSTEER_TRIGGER "TRIGGER_BANDSTEER" |
---|
| 426 | +#endif /* DHD_BANDSTEER */ |
---|
173 | 427 | /* miracast related definition */ |
---|
174 | 428 | #define MIRACAST_MODE_OFF 0 |
---|
175 | 429 | #define MIRACAST_MODE_SOURCE 1 |
---|
176 | 430 | #define MIRACAST_MODE_SINK 2 |
---|
177 | 431 | |
---|
178 | | -#ifndef MIRACAST_AMPDU_SIZE |
---|
179 | | -#define MIRACAST_AMPDU_SIZE 8 |
---|
180 | | -#endif |
---|
| 432 | +#define CMD_CHANNEL_WIDTH "CHANNEL_WIDTH" |
---|
| 433 | +#define CMD_TRANSITION_DISABLE "TRANSITION_DISABLE" |
---|
| 434 | +#define CMD_SAE_PWE "SAE_PWE" |
---|
| 435 | +#define CMD_MAXASSOC "MAXASSOC" |
---|
181 | 436 | |
---|
182 | | -#ifndef MIRACAST_MCHAN_ALGO |
---|
183 | | -#define MIRACAST_MCHAN_ALGO 1 |
---|
184 | | -#endif |
---|
185 | | - |
---|
186 | | -#ifndef MIRACAST_MCHAN_BW |
---|
187 | | -#define MIRACAST_MCHAN_BW 25 |
---|
188 | | -#endif |
---|
| 437 | +#ifdef ENABLE_HOGSQS |
---|
| 438 | +#define CMD_AP_HOGSQS "HOGSQS" |
---|
| 439 | +#endif /* ENABLE_HOGSQS */ |
---|
189 | 440 | |
---|
190 | 441 | #ifdef CONNECTION_STATISTICS |
---|
191 | 442 | #define CMD_GET_CONNECTION_STATS "GET_CONNECTION_STATS" |
---|
.. | .. |
---|
207 | 458 | }; |
---|
208 | 459 | #endif /* CONNECTION_STATISTICS */ |
---|
209 | 460 | |
---|
| 461 | +#define CMD_SCAN_PROTECT_BSS "SCAN_PROTECT_BSS" |
---|
| 462 | + |
---|
| 463 | +#ifdef SUPPORT_LQCM |
---|
| 464 | +#define CMD_SET_LQCM_ENABLE "SET_LQCM_ENABLE" |
---|
| 465 | +#define CMD_GET_LQCM_REPORT "GET_LQCM_REPORT" |
---|
| 466 | +#endif // endif |
---|
| 467 | + |
---|
210 | 468 | static LIST_HEAD(miracast_resume_list); |
---|
211 | 469 | static u8 miracast_cur_mode; |
---|
| 470 | + |
---|
| 471 | +#ifdef DHD_LOG_DUMP |
---|
| 472 | +#define CMD_NEW_DEBUG_PRINT_DUMP "DEBUG_DUMP" |
---|
| 473 | +#define SUBCMD_UNWANTED "UNWANTED" |
---|
| 474 | +#define SUBCMD_DISCONNECTED "DISCONNECTED" |
---|
| 475 | +void dhd_log_dump_trigger(dhd_pub_t *dhdp, int subcmd); |
---|
| 476 | +#endif /* DHD_LOG_DUMP */ |
---|
| 477 | + |
---|
| 478 | +#ifdef DHD_STATUS_LOGGING |
---|
| 479 | +#define CMD_DUMP_STATUS_LOG "DUMP_STAT_LOG" |
---|
| 480 | +#define CMD_QUERY_STATUS_LOG "QUERY_STAT_LOG" |
---|
| 481 | +#endif /* DHD_STATUS_LOGGING */ |
---|
| 482 | + |
---|
| 483 | +#ifdef DHD_HANG_SEND_UP_TEST |
---|
| 484 | +#define CMD_MAKE_HANG "MAKE_HANG" |
---|
| 485 | +#endif /* CMD_DHD_HANG_SEND_UP_TEST */ |
---|
| 486 | +#ifdef DHD_DEBUG_UART |
---|
| 487 | +extern bool dhd_debug_uart_is_running(struct net_device *dev); |
---|
| 488 | +#endif /* DHD_DEBUG_UART */ |
---|
212 | 489 | |
---|
213 | 490 | struct io_cfg { |
---|
214 | 491 | s8 *iovar; |
---|
.. | .. |
---|
218 | 495 | u32 len; |
---|
219 | 496 | struct list_head list; |
---|
220 | 497 | }; |
---|
| 498 | + |
---|
| 499 | +typedef enum { |
---|
| 500 | + HEAD_SAR_BACKOFF_DISABLE = -1, |
---|
| 501 | + HEAD_SAR_BACKOFF_ENABLE = 0, |
---|
| 502 | + GRIP_SAR_BACKOFF_DISABLE, |
---|
| 503 | + GRIP_SAR_BACKOFF_ENABLE, |
---|
| 504 | + NR_mmWave_SAR_BACKOFF_DISABLE, |
---|
| 505 | + NR_mmWave_SAR_BACKOFF_ENABLE, |
---|
| 506 | + NR_Sub6_SAR_BACKOFF_DISABLE, |
---|
| 507 | + NR_Sub6_SAR_BACKOFF_ENABLE, |
---|
| 508 | + SAR_BACKOFF_DISABLE_ALL |
---|
| 509 | +} sar_modes; |
---|
221 | 510 | |
---|
222 | 511 | #if defined(BCMFW_ROAM_ENABLE) |
---|
223 | 512 | #define CMD_SET_ROAMPREF "SET_ROAMPREF" |
---|
.. | .. |
---|
233 | 522 | (JOIN_PREF_WPA_TUPLE_SIZE * JOIN_PREF_MAX_WPA_TUPLES)) |
---|
234 | 523 | #endif /* BCMFW_ROAM_ENABLE */ |
---|
235 | 524 | |
---|
| 525 | +#define CMD_DEBUG_VERBOSE "DEBUG_VERBOSE" |
---|
| 526 | +#ifdef WL_NATOE |
---|
236 | 527 | |
---|
| 528 | +#define CMD_NATOE "NATOE" |
---|
| 529 | + |
---|
| 530 | +#define NATOE_MAX_PORT_NUM 65535 |
---|
| 531 | + |
---|
| 532 | +/* natoe command info structure */ |
---|
| 533 | +typedef struct wl_natoe_cmd_info { |
---|
| 534 | + uint8 *command; /* pointer to the actual command */ |
---|
| 535 | + uint16 tot_len; /* total length of the command */ |
---|
| 536 | + uint16 bytes_written; /* Bytes written for get response */ |
---|
| 537 | +} wl_natoe_cmd_info_t; |
---|
| 538 | + |
---|
| 539 | +typedef struct wl_natoe_sub_cmd wl_natoe_sub_cmd_t; |
---|
| 540 | +typedef int (natoe_cmd_handler_t)(struct net_device *dev, |
---|
| 541 | + const wl_natoe_sub_cmd_t *cmd, char *command, wl_natoe_cmd_info_t *cmd_info); |
---|
| 542 | + |
---|
| 543 | +struct wl_natoe_sub_cmd { |
---|
| 544 | + char *name; |
---|
| 545 | + uint8 version; /* cmd version */ |
---|
| 546 | + uint16 id; /* id for the dongle f/w switch/case */ |
---|
| 547 | + uint16 type; /* base type of argument */ |
---|
| 548 | + natoe_cmd_handler_t *handler; /* cmd handler */ |
---|
| 549 | +}; |
---|
| 550 | + |
---|
| 551 | +#define WL_ANDROID_NATOE_FUNC(suffix) wl_android_natoe_subcmd_ ##suffix |
---|
| 552 | +static int wl_android_process_natoe_cmd(struct net_device *dev, |
---|
| 553 | + char *command, int total_len); |
---|
| 554 | +static int wl_android_natoe_subcmd_enable(struct net_device *dev, |
---|
| 555 | + const wl_natoe_sub_cmd_t *cmd, char *command, wl_natoe_cmd_info_t *cmd_info); |
---|
| 556 | +static int wl_android_natoe_subcmd_config_ips(struct net_device *dev, |
---|
| 557 | + const wl_natoe_sub_cmd_t *cmd, char *command, wl_natoe_cmd_info_t *cmd_info); |
---|
| 558 | +static int wl_android_natoe_subcmd_config_ports(struct net_device *dev, |
---|
| 559 | + const wl_natoe_sub_cmd_t *cmd, char *command, wl_natoe_cmd_info_t *cmd_info); |
---|
| 560 | +static int wl_android_natoe_subcmd_dbg_stats(struct net_device *dev, |
---|
| 561 | + const wl_natoe_sub_cmd_t *cmd, char *command, wl_natoe_cmd_info_t *cmd_info); |
---|
| 562 | +static int wl_android_natoe_subcmd_tbl_cnt(struct net_device *dev, |
---|
| 563 | + const wl_natoe_sub_cmd_t *cmd, char *command, wl_natoe_cmd_info_t *cmd_info); |
---|
| 564 | + |
---|
| 565 | +static const wl_natoe_sub_cmd_t natoe_cmd_list[] = { |
---|
| 566 | + /* wl natoe enable [0/1] or new: "wl natoe [0/1]" */ |
---|
| 567 | + {"enable", 0x01, WL_NATOE_CMD_ENABLE, |
---|
| 568 | + IOVT_BUFFER, WL_ANDROID_NATOE_FUNC(enable) |
---|
| 569 | + }, |
---|
| 570 | + {"config_ips", 0x01, WL_NATOE_CMD_CONFIG_IPS, |
---|
| 571 | + IOVT_BUFFER, WL_ANDROID_NATOE_FUNC(config_ips) |
---|
| 572 | + }, |
---|
| 573 | + {"config_ports", 0x01, WL_NATOE_CMD_CONFIG_PORTS, |
---|
| 574 | + IOVT_BUFFER, WL_ANDROID_NATOE_FUNC(config_ports) |
---|
| 575 | + }, |
---|
| 576 | + {"stats", 0x01, WL_NATOE_CMD_DBG_STATS, |
---|
| 577 | + IOVT_BUFFER, WL_ANDROID_NATOE_FUNC(dbg_stats) |
---|
| 578 | + }, |
---|
| 579 | + {"tbl_cnt", 0x01, WL_NATOE_CMD_TBL_CNT, |
---|
| 580 | + IOVT_BUFFER, WL_ANDROID_NATOE_FUNC(tbl_cnt) |
---|
| 581 | + }, |
---|
| 582 | + {NULL, 0, 0, 0, NULL} |
---|
| 583 | +}; |
---|
| 584 | + |
---|
| 585 | +#endif /* WL_NATOE */ |
---|
| 586 | + |
---|
| 587 | +static int |
---|
| 588 | +wl_android_get_channel_list(struct net_device *dev, char *command, int total_len); |
---|
| 589 | + |
---|
| 590 | +#ifdef SET_PCIE_IRQ_CPU_CORE |
---|
| 591 | +#define CMD_PCIE_IRQ_CORE "PCIE_IRQ_CORE" |
---|
| 592 | +#endif /* SET_PCIE_IRQ_CPU_CORE */ |
---|
| 593 | + |
---|
| 594 | +#ifdef WLADPS_PRIVATE_CMD |
---|
| 595 | +#define CMD_SET_ADPS "SET_ADPS" |
---|
| 596 | +#define CMD_GET_ADPS "GET_ADPS" |
---|
| 597 | +#endif /* WLADPS_PRIVATE_CMD */ |
---|
| 598 | + |
---|
| 599 | +#ifdef DHD_PKT_LOGGING |
---|
| 600 | +#define CMD_PKTLOG_FILTER_ENABLE "PKTLOG_FILTER_ENABLE" |
---|
| 601 | +#define CMD_PKTLOG_FILTER_DISABLE "PKTLOG_FILTER_DISABLE" |
---|
| 602 | +#define CMD_PKTLOG_FILTER_PATTERN_ENABLE "PKTLOG_FILTER_PATTERN_ENABLE" |
---|
| 603 | +#define CMD_PKTLOG_FILTER_PATTERN_DISABLE "PKTLOG_FILTER_PATTERN_DISABLE" |
---|
| 604 | +#define CMD_PKTLOG_FILTER_ADD "PKTLOG_FILTER_ADD" |
---|
| 605 | +#define CMD_PKTLOG_FILTER_DEL "PKTLOG_FILTER_DEL" |
---|
| 606 | +#define CMD_PKTLOG_FILTER_INFO "PKTLOG_FILTER_INFO" |
---|
| 607 | +#define CMD_PKTLOG_START "PKTLOG_START" |
---|
| 608 | +#define CMD_PKTLOG_STOP "PKTLOG_STOP" |
---|
| 609 | +#define CMD_PKTLOG_FILTER_EXIST "PKTLOG_FILTER_EXIST" |
---|
| 610 | +#define CMD_PKTLOG_MINMIZE_ENABLE "PKTLOG_MINMIZE_ENABLE" |
---|
| 611 | +#define CMD_PKTLOG_MINMIZE_DISABLE "PKTLOG_MINMIZE_DISABLE" |
---|
| 612 | +#define CMD_PKTLOG_CHANGE_SIZE "PKTLOG_CHANGE_SIZE" |
---|
| 613 | +#endif /* DHD_PKT_LOGGING */ |
---|
| 614 | + |
---|
| 615 | +#ifdef DHD_EVENT_LOG_FILTER |
---|
| 616 | +#define CMD_EWP_FILTER "EWP_FILTER" |
---|
| 617 | +#endif /* DHD_EVENT_LOG_FILTER */ |
---|
| 618 | + |
---|
| 619 | +#ifdef WL_BCNRECV |
---|
| 620 | +#define CMD_BEACON_RECV "BEACON_RECV" |
---|
| 621 | +#endif /* WL_BCNRECV */ |
---|
| 622 | +#ifdef WL_CAC_TS |
---|
| 623 | +#define CMD_CAC_TSPEC "CAC_TSPEC" |
---|
| 624 | +#endif /* WL_CAC_TS */ |
---|
| 625 | +#ifdef WL_CHAN_UTIL |
---|
| 626 | +#define CMD_GET_CHAN_UTIL "GET_CU" |
---|
| 627 | +#endif /* WL_CHAN_UTIL */ |
---|
| 628 | + |
---|
| 629 | +/* drv command info structure */ |
---|
| 630 | +typedef struct wl_drv_cmd_info { |
---|
| 631 | + uint8 *command; /* pointer to the actual command */ |
---|
| 632 | + uint16 tot_len; /* total length of the command */ |
---|
| 633 | + uint16 bytes_written; /* Bytes written for get response */ |
---|
| 634 | +} wl_drv_cmd_info_t; |
---|
| 635 | + |
---|
| 636 | +typedef struct wl_drv_sub_cmd wl_drv_sub_cmd_t; |
---|
| 637 | +typedef int (drv_cmd_handler_t)(struct net_device *dev, |
---|
| 638 | + const wl_drv_sub_cmd_t *cmd, char *command, wl_drv_cmd_info_t *cmd_info); |
---|
| 639 | + |
---|
| 640 | +struct wl_drv_sub_cmd { |
---|
| 641 | + char *name; |
---|
| 642 | + uint8 version; /* cmd version */ |
---|
| 643 | + uint16 id; /* id for the dongle f/w switch/case */ |
---|
| 644 | + uint16 type; /* base type of argument */ |
---|
| 645 | + drv_cmd_handler_t *handler; /* cmd handler */ |
---|
| 646 | +}; |
---|
| 647 | + |
---|
| 648 | +#ifdef WL_MBO |
---|
| 649 | + |
---|
| 650 | +#define CMD_MBO "MBO" |
---|
| 651 | +enum { |
---|
| 652 | + WL_MBO_CMD_NON_CHAN_PREF = 1, |
---|
| 653 | + WL_MBO_CMD_CELL_DATA_CAP = 2 |
---|
| 654 | +}; |
---|
| 655 | +#define WL_ANDROID_MBO_FUNC(suffix) wl_android_mbo_subcmd_ ##suffix |
---|
| 656 | + |
---|
| 657 | +static int wl_android_process_mbo_cmd(struct net_device *dev, |
---|
| 658 | + char *command, int total_len); |
---|
| 659 | +static int wl_android_mbo_subcmd_cell_data_cap(struct net_device *dev, |
---|
| 660 | + const wl_drv_sub_cmd_t *cmd, char *command, wl_drv_cmd_info_t *cmd_info); |
---|
| 661 | +static int wl_android_mbo_subcmd_non_pref_chan(struct net_device *dev, |
---|
| 662 | + const wl_drv_sub_cmd_t *cmd, char *command, wl_drv_cmd_info_t *cmd_info); |
---|
| 663 | + |
---|
| 664 | +static const wl_drv_sub_cmd_t mbo_cmd_list[] = { |
---|
| 665 | + {"non_pref_chan", 0x01, WL_MBO_CMD_NON_CHAN_PREF, |
---|
| 666 | + IOVT_BUFFER, WL_ANDROID_MBO_FUNC(non_pref_chan) |
---|
| 667 | + }, |
---|
| 668 | + {"cell_data_cap", 0x01, WL_MBO_CMD_CELL_DATA_CAP, |
---|
| 669 | + IOVT_BUFFER, WL_ANDROID_MBO_FUNC(cell_data_cap) |
---|
| 670 | + }, |
---|
| 671 | + {NULL, 0, 0, 0, NULL} |
---|
| 672 | +}; |
---|
| 673 | + |
---|
| 674 | +#endif /* WL_MBO */ |
---|
| 675 | + |
---|
| 676 | +#ifdef WL_GENL |
---|
| 677 | +static s32 wl_genl_handle_msg(struct sk_buff *skb, struct genl_info *info); |
---|
| 678 | +static int wl_genl_init(void); |
---|
| 679 | +static int wl_genl_deinit(void); |
---|
| 680 | + |
---|
| 681 | +extern struct net init_net; |
---|
| 682 | +/* attribute policy: defines which attribute has which type (e.g int, char * etc) |
---|
| 683 | + * possible values defined in net/netlink.h |
---|
| 684 | + */ |
---|
| 685 | +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) |
---|
| 686 | +static struct nla_policy wl_genl_policy[BCM_GENL_ATTR_MAX + 1] = { |
---|
| 687 | + [BCM_GENL_ATTR_STRING] = { .type = NLA_NUL_STRING }, |
---|
| 688 | + [BCM_GENL_ATTR_MSG] = { .type = NLA_BINARY }, |
---|
| 689 | +}; |
---|
| 690 | +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) */ |
---|
| 691 | + |
---|
| 692 | +#define WL_GENL_VER 1 |
---|
| 693 | +/* family definition */ |
---|
| 694 | +static struct genl_family wl_genl_family = { |
---|
| 695 | +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) |
---|
| 696 | + .id = GENL_ID_GENERATE, /* Genetlink would generate the ID */ |
---|
| 697 | +#endif // endif |
---|
| 698 | + .hdrsize = 0, |
---|
| 699 | + .name = "bcm-genl", /* Netlink I/F for Android */ |
---|
| 700 | + .version = WL_GENL_VER, /* Version Number */ |
---|
| 701 | + .maxattr = BCM_GENL_ATTR_MAX, |
---|
| 702 | +}; |
---|
| 703 | + |
---|
| 704 | +/* commands: mapping between the command enumeration and the actual function */ |
---|
| 705 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) |
---|
| 706 | +struct genl_ops wl_genl_ops[] = { |
---|
| 707 | + { |
---|
| 708 | + .cmd = BCM_GENL_CMD_MSG, |
---|
| 709 | + .flags = 0, |
---|
| 710 | +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) |
---|
| 711 | + .policy = wl_genl_policy, |
---|
| 712 | +#else |
---|
| 713 | + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
---|
| 714 | +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) */ |
---|
| 715 | + .doit = wl_genl_handle_msg, |
---|
| 716 | + .dumpit = NULL, |
---|
| 717 | + }, |
---|
| 718 | +}; |
---|
| 719 | +#else |
---|
| 720 | +struct genl_ops wl_genl_ops = { |
---|
| 721 | + .cmd = BCM_GENL_CMD_MSG, |
---|
| 722 | + .flags = 0, |
---|
| 723 | + .policy = wl_genl_policy, |
---|
| 724 | + .doit = wl_genl_handle_msg, |
---|
| 725 | + .dumpit = NULL, |
---|
| 726 | + |
---|
| 727 | +}; |
---|
| 728 | +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */ |
---|
| 729 | + |
---|
| 730 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) |
---|
| 731 | +static struct genl_multicast_group wl_genl_mcast[] = { |
---|
| 732 | + { .name = "bcm-genl-mcast", }, |
---|
| 733 | +}; |
---|
| 734 | +#else |
---|
| 735 | +static struct genl_multicast_group wl_genl_mcast = { |
---|
| 736 | + .id = GENL_ID_GENERATE, /* Genetlink would generate the ID */ |
---|
| 737 | + .name = "bcm-genl-mcast", |
---|
| 738 | +}; |
---|
| 739 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */ |
---|
| 740 | +#endif /* WL_GENL */ |
---|
| 741 | + |
---|
| 742 | +#ifdef SUPPORT_LQCM |
---|
| 743 | +#define LQCM_ENAB_MASK 0x000000FF /* LQCM enable flag mask */ |
---|
| 744 | +#define LQCM_TX_INDEX_MASK 0x0000FF00 /* LQCM tx index mask */ |
---|
| 745 | +#define LQCM_RX_INDEX_MASK 0x00FF0000 /* LQCM rx index mask */ |
---|
| 746 | + |
---|
| 747 | +#define LQCM_TX_INDEX_SHIFT 8 /* LQCM tx index shift */ |
---|
| 748 | +#define LQCM_RX_INDEX_SHIFT 16 /* LQCM rx index shift */ |
---|
| 749 | +#endif /* SUPPORT_LQCM */ |
---|
| 750 | + |
---|
| 751 | +#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS |
---|
| 752 | +#define NUMBER_SEQUENTIAL_PRIVCMD_ERRORS 7 |
---|
| 753 | +static int priv_cmd_errors = 0; |
---|
| 754 | +#endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */ |
---|
237 | 755 | |
---|
238 | 756 | /** |
---|
239 | 757 | * Extern function declarations (TODO: move them to dhd_linux.h) |
---|
.. | .. |
---|
243 | 761 | #ifdef WL_CFG80211 |
---|
244 | 762 | int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); |
---|
245 | 763 | int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, dhd_pub_t *dhd, char *command); |
---|
| 764 | +#ifdef WES_SUPPORT |
---|
| 765 | +int wl_cfg80211_set_wes_mode(int mode); |
---|
| 766 | +int wl_cfg80211_get_wes_mode(void); |
---|
| 767 | +#endif /* WES_SUPPORT */ |
---|
246 | 768 | #else |
---|
247 | 769 | int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr) |
---|
248 | 770 | { return 0; } |
---|
.. | .. |
---|
254 | 776 | { return 0; } |
---|
255 | 777 | int wl_cfg80211_set_p2p_ecsa(struct net_device *net, char* buf, int len) |
---|
256 | 778 | { return 0; } |
---|
| 779 | +int wl_cfg80211_increase_p2p_bw(struct net_device *net, char* buf, int len) |
---|
| 780 | +{ return 0; } |
---|
257 | 781 | #endif /* WK_CFG80211 */ |
---|
258 | | - |
---|
| 782 | +#ifdef WBTEXT |
---|
| 783 | +static int wl_android_wbtext(struct net_device *dev, char *command, int total_len); |
---|
| 784 | +static int wl_cfg80211_wbtext_btm_timer_threshold(struct net_device *dev, |
---|
| 785 | + char *command, int total_len); |
---|
| 786 | +static int wl_cfg80211_wbtext_btm_delta(struct net_device *dev, |
---|
| 787 | + char *command, int total_len); |
---|
| 788 | +static int wl_cfg80211_wbtext_estm_enable(struct net_device *dev, |
---|
| 789 | + char *command, int total_len); |
---|
| 790 | +static int wlc_wbtext_get_roam_prof(struct net_device *ndev, wl_roamprof_band_t *rp, |
---|
| 791 | + uint8 band, uint8 *roam_prof_ver, uint8 *roam_prof_size); |
---|
| 792 | +#endif /* WBTEXT */ |
---|
| 793 | +#ifdef WES_SUPPORT |
---|
| 794 | +/* wl_roam.c */ |
---|
| 795 | +extern int get_roamscan_mode(struct net_device *dev, int *mode); |
---|
| 796 | +extern int set_roamscan_mode(struct net_device *dev, int mode); |
---|
| 797 | +extern int get_roamscan_channel_list(struct net_device *dev, |
---|
| 798 | + unsigned char channels[], int n_channels); |
---|
| 799 | +extern int set_roamscan_channel_list(struct net_device *dev, unsigned char n, |
---|
| 800 | + unsigned char channels[], int ioctl_ver); |
---|
| 801 | +#endif /* WES_SUPPORT */ |
---|
| 802 | +#ifdef ROAM_CHANNEL_CACHE |
---|
| 803 | +extern void wl_update_roamscan_cache_by_band(struct net_device *dev, int band); |
---|
| 804 | +#endif /* ROAM_CHANNEL_CACHE */ |
---|
259 | 805 | |
---|
260 | 806 | #ifdef ENABLE_4335BT_WAR |
---|
261 | 807 | extern int bcm_bt_lock(int cookie); |
---|
.. | .. |
---|
265 | 811 | |
---|
266 | 812 | extern bool ap_fw_loaded; |
---|
267 | 813 | extern char iface_name[IFNAMSIZ]; |
---|
| 814 | +#ifdef DHD_PM_CONTROL_FROM_FILE |
---|
| 815 | +extern bool g_pm_control; |
---|
| 816 | +#endif /* DHD_PM_CONTROL_FROM_FILE */ |
---|
| 817 | + |
---|
| 818 | +/* private command support for restoring roam/scan parameters */ |
---|
| 819 | +#ifdef SUPPORT_RESTORE_SCAN_PARAMS |
---|
| 820 | +#define CMD_RESTORE_SCAN_PARAMS "RESTORE_SCAN_PARAMS" |
---|
| 821 | + |
---|
| 822 | +typedef int (*PRIV_CMD_HANDLER) (struct net_device *dev, char *command); |
---|
| 823 | +typedef int (*PRIV_CMD_HANDLER_WITH_LEN) (struct net_device *dev, char *command, int total_len); |
---|
| 824 | + |
---|
| 825 | +enum { |
---|
| 826 | + RESTORE_TYPE_UNSPECIFIED = 0, |
---|
| 827 | + RESTORE_TYPE_PRIV_CMD = 1, |
---|
| 828 | + RESTORE_TYPE_PRIV_CMD_WITH_LEN = 2 |
---|
| 829 | +}; |
---|
| 830 | + |
---|
| 831 | +typedef struct android_restore_scan_params { |
---|
| 832 | + char command[64]; |
---|
| 833 | + int parameter; |
---|
| 834 | + int cmd_type; |
---|
| 835 | + union { |
---|
| 836 | + PRIV_CMD_HANDLER cmd_handler; |
---|
| 837 | + PRIV_CMD_HANDLER_WITH_LEN cmd_handler_w_len; |
---|
| 838 | + }; |
---|
| 839 | +} android_restore_scan_params_t; |
---|
| 840 | + |
---|
| 841 | +/* function prototypes of private command handler */ |
---|
| 842 | +static int wl_android_set_roam_trigger(struct net_device *dev, char* command); |
---|
| 843 | +int wl_android_set_roam_delta(struct net_device *dev, char* command); |
---|
| 844 | +int wl_android_set_roam_scan_period(struct net_device *dev, char* command); |
---|
| 845 | +int wl_android_set_full_roam_scan_period(struct net_device *dev, char* command, int total_len); |
---|
| 846 | +int wl_android_set_roam_scan_control(struct net_device *dev, char *command); |
---|
| 847 | +int wl_android_set_scan_channel_time(struct net_device *dev, char *command); |
---|
| 848 | +int wl_android_set_scan_home_time(struct net_device *dev, char *command); |
---|
| 849 | +int wl_android_set_scan_home_away_time(struct net_device *dev, char *command); |
---|
| 850 | +int wl_android_set_scan_nprobes(struct net_device *dev, char *command); |
---|
| 851 | +static int wl_android_set_band(struct net_device *dev, char *command); |
---|
| 852 | +int wl_android_set_scan_dfs_channel_mode(struct net_device *dev, char *command); |
---|
| 853 | +int wl_android_set_wes_mode(struct net_device *dev, char *command); |
---|
| 854 | +int wl_android_set_okc_mode(struct net_device *dev, char *command); |
---|
| 855 | + |
---|
| 856 | +/* default values */ |
---|
| 857 | +#ifdef ROAM_API |
---|
| 858 | +#define DEFAULT_ROAM_TIRGGER -75 |
---|
| 859 | +#define DEFAULT_ROAM_DELTA 10 |
---|
| 860 | +#define DEFAULT_ROAMSCANPERIOD 10 |
---|
| 861 | +#define DEFAULT_FULLROAMSCANPERIOD_SET 120 |
---|
| 862 | +#endif /* ROAM_API */ |
---|
| 863 | +#ifdef WES_SUPPORT |
---|
| 864 | +#define DEFAULT_ROAMSCANCONTROL 0 |
---|
| 865 | +#define DEFAULT_SCANCHANNELTIME 40 |
---|
| 866 | +#ifdef BCM4361_CHIP |
---|
| 867 | +#define DEFAULT_SCANHOMETIME 60 |
---|
| 868 | +#else |
---|
| 869 | +#define DEFAULT_SCANHOMETIME 45 |
---|
| 870 | +#endif /* BCM4361_CHIP */ |
---|
| 871 | +#define DEFAULT_SCANHOMEAWAYTIME 100 |
---|
| 872 | +#define DEFAULT_SCANPROBES 2 |
---|
| 873 | +#define DEFAULT_DFSSCANMODE 1 |
---|
| 874 | +#define DEFAULT_WESMODE 0 |
---|
| 875 | +#define DEFAULT_OKCMODE 1 |
---|
| 876 | +#endif /* WES_SUPPORT */ |
---|
| 877 | +#define DEFAULT_BAND 0 |
---|
| 878 | +#ifdef WBTEXT |
---|
| 879 | +#define DEFAULT_WBTEXT_ENABLE 1 |
---|
| 880 | +#endif /* WBTEXT */ |
---|
| 881 | + |
---|
| 882 | +/* restoring parameter list, please don't change order */ |
---|
| 883 | +static android_restore_scan_params_t restore_params[] = |
---|
| 884 | +{ |
---|
| 885 | +/* wbtext need to be disabled while updating roam/scan parameters */ |
---|
| 886 | +#ifdef WBTEXT |
---|
| 887 | + { CMD_WBTEXT_ENABLE, 0, RESTORE_TYPE_PRIV_CMD_WITH_LEN, |
---|
| 888 | + .cmd_handler_w_len = wl_android_wbtext}, |
---|
| 889 | +#endif /* WBTEXT */ |
---|
| 890 | +#ifdef ROAM_API |
---|
| 891 | + { CMD_ROAMTRIGGER_SET, DEFAULT_ROAM_TIRGGER, |
---|
| 892 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_roam_trigger}, |
---|
| 893 | + { CMD_ROAMDELTA_SET, DEFAULT_ROAM_DELTA, |
---|
| 894 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_roam_delta}, |
---|
| 895 | + { CMD_ROAMSCANPERIOD_SET, DEFAULT_ROAMSCANPERIOD, |
---|
| 896 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_roam_scan_period}, |
---|
| 897 | + { CMD_FULLROAMSCANPERIOD_SET, DEFAULT_FULLROAMSCANPERIOD_SET, |
---|
| 898 | + RESTORE_TYPE_PRIV_CMD_WITH_LEN, |
---|
| 899 | + .cmd_handler_w_len = wl_android_set_full_roam_scan_period}, |
---|
| 900 | +#endif /* ROAM_API */ |
---|
| 901 | +#ifdef WES_SUPPORT |
---|
| 902 | + { CMD_SETROAMSCANCONTROL, DEFAULT_ROAMSCANCONTROL, |
---|
| 903 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_roam_scan_control}, |
---|
| 904 | + { CMD_SETSCANCHANNELTIME, DEFAULT_SCANCHANNELTIME, |
---|
| 905 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_scan_channel_time}, |
---|
| 906 | + { CMD_SETSCANHOMETIME, DEFAULT_SCANHOMETIME, |
---|
| 907 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_scan_home_time}, |
---|
| 908 | + { CMD_GETSCANHOMEAWAYTIME, DEFAULT_SCANHOMEAWAYTIME, |
---|
| 909 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_scan_home_away_time}, |
---|
| 910 | + { CMD_SETSCANNPROBES, DEFAULT_SCANPROBES, |
---|
| 911 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_scan_nprobes}, |
---|
| 912 | + { CMD_SETDFSSCANMODE, DEFAULT_DFSSCANMODE, |
---|
| 913 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_scan_dfs_channel_mode}, |
---|
| 914 | + { CMD_SETWESMODE, DEFAULT_WESMODE, |
---|
| 915 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_wes_mode}, |
---|
| 916 | + { CMD_SETOKCMODE, DEFAULT_OKCMODE, |
---|
| 917 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_okc_mode}, |
---|
| 918 | +#endif /* WES_SUPPORT */ |
---|
| 919 | + { CMD_SETBAND, DEFAULT_BAND, |
---|
| 920 | + RESTORE_TYPE_PRIV_CMD, .cmd_handler = wl_android_set_band}, |
---|
| 921 | +#ifdef WBTEXT |
---|
| 922 | + { CMD_WBTEXT_ENABLE, DEFAULT_WBTEXT_ENABLE, |
---|
| 923 | + RESTORE_TYPE_PRIV_CMD_WITH_LEN, .cmd_handler_w_len = wl_android_wbtext}, |
---|
| 924 | +#endif /* WBTEXT */ |
---|
| 925 | + { "\0", 0, RESTORE_TYPE_UNSPECIFIED, .cmd_handler = NULL} |
---|
| 926 | +}; |
---|
| 927 | +#endif /* SUPPORT_RESTORE_SCAN_PARAMS */ |
---|
268 | 928 | |
---|
269 | 929 | /** |
---|
270 | 930 | * Local (static) functions and variables |
---|
.. | .. |
---|
280 | 940 | * Local (static) function definitions |
---|
281 | 941 | */ |
---|
282 | 942 | |
---|
| 943 | +static int |
---|
| 944 | +wl_android_set_channel_width(struct net_device *dev, char *command, int total_len) |
---|
| 945 | +{ |
---|
| 946 | + u32 channel_width = 0; |
---|
| 947 | + struct wireless_dev *wdev = dev->ieee80211_ptr; |
---|
| 948 | + struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *)wiphy_priv(wdev->wiphy); |
---|
| 949 | + command = (command + strlen(CMD_CHANNEL_WIDTH)); |
---|
| 950 | + command++; |
---|
| 951 | + channel_width = bcm_atoi(command); |
---|
| 952 | + if (channel_width == 80) |
---|
| 953 | + wl_set_chanwidth_by_netdev(cfg, dev, WL_CHANSPEC_BW_80); |
---|
| 954 | + else if (channel_width == 40) |
---|
| 955 | + wl_set_chanwidth_by_netdev(cfg, dev, WL_CHANSPEC_BW_40); |
---|
| 956 | + else if (channel_width == 20) |
---|
| 957 | + wl_set_chanwidth_by_netdev(cfg, dev, WL_CHANSPEC_BW_20); |
---|
| 958 | + else |
---|
| 959 | + return 0; |
---|
| 960 | + DHD_INFO(("%s : channel width = %d\n", __FUNCTION__, channel_width)); |
---|
| 961 | + return 0; |
---|
| 962 | +} |
---|
| 963 | + |
---|
| 964 | +#ifdef ENABLE_HOGSQS |
---|
| 965 | +#define M_HOGSQS_DURATION (M_HOGSQS_CFG + 0x2) |
---|
| 966 | +#define M_HOGSQS_DUR_THR (M_HOGSQS_CFG + 0x4) |
---|
| 967 | +#define M_HOGSQS_STAT (M_HOGSQS_CFG + 0x6) |
---|
| 968 | +#define M_HOGSQS_TXCFE_DET_CNT (M_HOGSQS_CFG + 0xe) |
---|
| 969 | +static int |
---|
| 970 | +wl_android_hogsqs(struct net_device *dev, char *command, int total_len) |
---|
| 971 | +{ |
---|
| 972 | + int ret = 0, bytes_written = 0; |
---|
| 973 | + s32 value = 0; |
---|
| 974 | + uint32 reg = 0; |
---|
| 975 | + uint32 set_val = 0; |
---|
| 976 | + uint32 set_val2 = 0; |
---|
| 977 | + char *pos = command; |
---|
| 978 | + char *pos2 = NULL; |
---|
| 979 | + |
---|
| 980 | + if (*(command + strlen(CMD_AP_HOGSQS)) == '\0') { |
---|
| 981 | + DHD_ERROR(("%s: Error argument is required on %s \n", __FUNCTION__, CMD_AP_HOGSQS)); |
---|
| 982 | + return -EINVAL; |
---|
| 983 | + } else { |
---|
| 984 | + pos = pos + strlen(CMD_AP_HOGSQS) + 1; |
---|
| 985 | + if (!strncmp(pos, "cfg", strlen("cfg"))) { |
---|
| 986 | + reg = M_HOGSQS_CFG; |
---|
| 987 | + pos2 = pos + strlen("cfg"); |
---|
| 988 | + } else if (!strncmp(pos, "duration", strlen("duration"))) { |
---|
| 989 | + reg = M_HOGSQS_DURATION; |
---|
| 990 | + pos2 = pos + strlen("duration"); |
---|
| 991 | + } else if (!strncmp(pos, "durth", strlen("durth"))) { |
---|
| 992 | + reg = M_HOGSQS_DUR_THR; |
---|
| 993 | + pos2 = pos + strlen("durth"); |
---|
| 994 | + } else if (!strncmp(pos, "count", strlen("count"))) { |
---|
| 995 | + reg = M_HOGSQS_TXCFE_DET_CNT; |
---|
| 996 | + pos2 = pos + strlen("count"); |
---|
| 997 | + } else { |
---|
| 998 | + DHD_ERROR(("%s: Error wrong argument is on %s \n", __FUNCTION__, |
---|
| 999 | + CMD_AP_HOGSQS)); |
---|
| 1000 | + return -EINVAL; |
---|
| 1001 | + } |
---|
| 1002 | + value = reg; |
---|
| 1003 | + |
---|
| 1004 | + if (*pos2 == '\0') { |
---|
| 1005 | + /* Get operation */ |
---|
| 1006 | + ret = wldev_iovar_getint(dev, "hogsqs", &value); |
---|
| 1007 | + if (ret) { |
---|
| 1008 | + DHD_ERROR(("%s: Failed to get hogsqs\n", __FUNCTION__)); |
---|
| 1009 | + return -EINVAL; |
---|
| 1010 | + } |
---|
| 1011 | + |
---|
| 1012 | + if (reg == M_HOGSQS_TXCFE_DET_CNT) |
---|
| 1013 | + bytes_written = snprintf(command, total_len, " %s 0x%x/0x%x", |
---|
| 1014 | + CMD_AP_HOGSQS, (value&0x00FF), ((value&0xFF00)>> 8)); |
---|
| 1015 | + else |
---|
| 1016 | + bytes_written = snprintf(command, total_len, " %s 0x%x", |
---|
| 1017 | + CMD_AP_HOGSQS, value); |
---|
| 1018 | + |
---|
| 1019 | + return bytes_written; |
---|
| 1020 | + } else { |
---|
| 1021 | + /* Set operation */ |
---|
| 1022 | + pos2 = pos2 + 1; |
---|
| 1023 | + set_val = (uint32)simple_strtol(pos2, NULL, 0); |
---|
| 1024 | + |
---|
| 1025 | + set_val2 = (reg & 0xFFFF) << 16; |
---|
| 1026 | + set_val2 |= set_val; |
---|
| 1027 | + |
---|
| 1028 | + ret = wldev_iovar_setint(dev, "hogsqs", set_val2); |
---|
| 1029 | + if (ret != BCME_OK) { |
---|
| 1030 | + DHD_ERROR(("%s: hogsqs set returned (%d)\n", __FUNCTION__, ret)); |
---|
| 1031 | + return BCME_ERROR; |
---|
| 1032 | + } |
---|
| 1033 | + } |
---|
| 1034 | + } |
---|
| 1035 | + return 0; |
---|
| 1036 | +} |
---|
| 1037 | +#endif /* ENABLE_HOGSQS */ |
---|
| 1038 | + |
---|
| 1039 | +/* The wl_android_scan_protect_bss function does both SET/GET based on parameters passed */ |
---|
| 1040 | +static int wl_android_scan_protect_bss(struct net_device * dev, char * command, int total_len) |
---|
| 1041 | +{ |
---|
| 1042 | + int ret = 0, result = 0, bytes_written = 0; |
---|
| 1043 | + |
---|
| 1044 | + if (*(command + strlen(CMD_SCAN_PROTECT_BSS)) == '\0') { |
---|
| 1045 | + ret = wldev_iovar_getint(dev, "scan_protect_bss", &result); |
---|
| 1046 | + if (ret) { |
---|
| 1047 | + DHD_ERROR(("%s: Failed to get scan_protect_bss\n", __FUNCTION__)); |
---|
| 1048 | + return ret; |
---|
| 1049 | + } |
---|
| 1050 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_SCAN_PROTECT_BSS, result); |
---|
| 1051 | + return bytes_written; |
---|
| 1052 | + } |
---|
| 1053 | + command = (command + strlen(CMD_SCAN_PROTECT_BSS)); |
---|
| 1054 | + command++; |
---|
| 1055 | + result = bcm_atoi(command); |
---|
| 1056 | + |
---|
| 1057 | + DHD_INFO(("%s : scan_protect_bss = %d\n", __FUNCTION__, result)); |
---|
| 1058 | + ret = wldev_iovar_setint(dev, "scan_protect_bss", result); |
---|
| 1059 | + if (ret) { |
---|
| 1060 | + DHD_ERROR(("%s: Failed to set result to %d\n", __FUNCTION__, result)); |
---|
| 1061 | + return ret; |
---|
| 1062 | + } |
---|
| 1063 | + return 0; |
---|
| 1064 | +} |
---|
| 1065 | + |
---|
| 1066 | +#ifdef DHD_BANDSTEER |
---|
| 1067 | +static int |
---|
| 1068 | +wl_android_set_bandsteer(struct net_device *dev, char *command, int total_len) |
---|
| 1069 | +{ |
---|
| 1070 | + char *iftype; |
---|
| 1071 | + char *token1, *context1 = NULL; |
---|
| 1072 | + int val; |
---|
| 1073 | + int ret = 0; |
---|
| 1074 | + |
---|
| 1075 | + struct wireless_dev *__wdev = (struct wireless_dev *)(dev)->ieee80211_ptr; |
---|
| 1076 | + struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *)wiphy_priv(__wdev->wiphy); |
---|
| 1077 | + |
---|
| 1078 | + command = (command + strlen(CMD_BANDSTEER)); |
---|
| 1079 | + command++; |
---|
| 1080 | + token1 = command; |
---|
| 1081 | + |
---|
| 1082 | + iftype = bcmstrtok(&token1, " ", context1); |
---|
| 1083 | + val = bcm_atoi(token1); |
---|
| 1084 | + |
---|
| 1085 | + if (val < 0 || val > 1) { |
---|
| 1086 | + DHD_ERROR(("%s : invalid val\n", __FUNCTION__)); |
---|
| 1087 | + return -1; |
---|
| 1088 | + } |
---|
| 1089 | + |
---|
| 1090 | + if (!strncmp(iftype, "p2p", 3)) { |
---|
| 1091 | + cfg->ap_bs = 0; |
---|
| 1092 | + cfg->p2p_bs = 1; |
---|
| 1093 | + |
---|
| 1094 | + if (val) { |
---|
| 1095 | + ret = dhd_bandsteer_module_init(dev, cfg->ap_bs, cfg->p2p_bs); |
---|
| 1096 | + if (ret == BCME_ERROR) { |
---|
| 1097 | + DHD_ERROR(("%s: Failed to enable %s bandsteer\n", __FUNCTION__, |
---|
| 1098 | + cfg->ap_bs ? "ap":"p2p")); |
---|
| 1099 | + return ret; |
---|
| 1100 | + } else { |
---|
| 1101 | + DHD_ERROR(("%s: Successfully enabled %s bandsteer\n", __FUNCTION__, |
---|
| 1102 | + cfg->ap_bs ? "ap":"p2p")); |
---|
| 1103 | + } |
---|
| 1104 | + } else { |
---|
| 1105 | + ret = dhd_bandsteer_module_deinit(dev, cfg->ap_bs, cfg->p2p_bs); |
---|
| 1106 | + if (ret == BCME_ERROR) { |
---|
| 1107 | + DHD_ERROR(("%s: Failed to disable %s bandsteer\n", __FUNCTION__, |
---|
| 1108 | + cfg->ap_bs ? "ap":"p2p")); |
---|
| 1109 | + return ret; |
---|
| 1110 | + } else { |
---|
| 1111 | + DHD_ERROR(("%s: Successfully disabled %s bandsteer\n", __FUNCTION__, |
---|
| 1112 | + cfg->ap_bs ? "ap":"p2p")); |
---|
| 1113 | + } |
---|
| 1114 | + } |
---|
| 1115 | + } else if (!strncmp(iftype, "ap", 2)) { |
---|
| 1116 | + cfg->ap_bs = 1; |
---|
| 1117 | + cfg->p2p_bs = 0; |
---|
| 1118 | + |
---|
| 1119 | + if (val) { |
---|
| 1120 | + ret = dhd_bandsteer_module_init(dev, cfg->ap_bs, cfg->p2p_bs); |
---|
| 1121 | + if (ret == BCME_ERROR) { |
---|
| 1122 | + DHD_ERROR(("%s: Failed to enable %s bandsteer\n", __FUNCTION__, |
---|
| 1123 | + cfg->ap_bs ? "ap":"p2p")); |
---|
| 1124 | + return ret; |
---|
| 1125 | + } else { |
---|
| 1126 | + DHD_ERROR(("%s: Successfully enabled %s bandsteer\n", __FUNCTION__, |
---|
| 1127 | + cfg->ap_bs ? "ap":"p2p")); |
---|
| 1128 | + } |
---|
| 1129 | + } else { |
---|
| 1130 | + ret = dhd_bandsteer_module_deinit(dev, cfg->ap_bs, cfg->p2p_bs); |
---|
| 1131 | + if (ret == BCME_ERROR) { |
---|
| 1132 | + DHD_ERROR(("%s: Failed to disable %s bandsteer\n", __FUNCTION__, |
---|
| 1133 | + cfg->ap_bs ? "ap":"p2p")); |
---|
| 1134 | + return ret; |
---|
| 1135 | + } else { |
---|
| 1136 | + DHD_ERROR(("%s: Successfully disabled %s bandsteer\n", __FUNCTION__, |
---|
| 1137 | + cfg->ap_bs ? "ap":"p2p")); |
---|
| 1138 | + } |
---|
| 1139 | + } |
---|
| 1140 | + } else if (!strncmp(iftype, "1", 1)) { |
---|
| 1141 | + cfg->ap_bs = 1; |
---|
| 1142 | + cfg->p2p_bs = 1; |
---|
| 1143 | + ret = dhd_bandsteer_module_init(dev, cfg->ap_bs, cfg->p2p_bs); |
---|
| 1144 | + if (ret == BCME_ERROR) { |
---|
| 1145 | + DHD_ERROR(("%s: Failed to enable bandsteer\n", __FUNCTION__)); |
---|
| 1146 | + return ret; |
---|
| 1147 | + } else { |
---|
| 1148 | + DHD_ERROR(("%s: Successfully enabled bandsteer\n", __FUNCTION__)); |
---|
| 1149 | + } |
---|
| 1150 | + } else if (!strncmp(iftype, "0", 1)) { |
---|
| 1151 | + cfg->ap_bs = 1; |
---|
| 1152 | + cfg->p2p_bs = 1; |
---|
| 1153 | + ret = dhd_bandsteer_module_deinit(dev, cfg->ap_bs, cfg->p2p_bs); |
---|
| 1154 | + if (ret == BCME_ERROR) { |
---|
| 1155 | + DHD_ERROR(("%s: Failed to diable bandsteer\n", __FUNCTION__)); |
---|
| 1156 | + return ret; |
---|
| 1157 | + } else { |
---|
| 1158 | + DHD_ERROR(("%s: Successfully disabled bandsteer\n", __FUNCTION__)); |
---|
| 1159 | + } |
---|
| 1160 | + } else { |
---|
| 1161 | + DHD_ERROR(("%s: Invalid bandsteer iftype\n", __FUNCTION__)); |
---|
| 1162 | + return -1; |
---|
| 1163 | + } |
---|
| 1164 | + return ret; |
---|
| 1165 | +} |
---|
| 1166 | +#endif /* DHD_BANDSTEER */ |
---|
| 1167 | + |
---|
| 1168 | +static int |
---|
| 1169 | +wl_android_set_maxassoc_limit(struct net_device *dev, char *command, int total_len) |
---|
| 1170 | +{ |
---|
| 1171 | + int ret = 0, max_assoc = 0, bytes_written = 0; |
---|
| 1172 | + |
---|
| 1173 | + if (*(command + strlen(CMD_MAXASSOC)) == '\0') { |
---|
| 1174 | + ret = wldev_iovar_getint(dev, "maxassoc", &max_assoc); |
---|
| 1175 | + if (ret) { |
---|
| 1176 | + DHD_ERROR(("%s: Failed to get maxassoc limit\n", __FUNCTION__)); |
---|
| 1177 | + return ret; |
---|
| 1178 | + } |
---|
| 1179 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_MAXASSOC, max_assoc); |
---|
| 1180 | + return bytes_written; |
---|
| 1181 | + } |
---|
| 1182 | + command = (command + strlen(CMD_MAXASSOC)); |
---|
| 1183 | + command++; |
---|
| 1184 | + max_assoc = bcm_atoi(command); |
---|
| 1185 | + |
---|
| 1186 | + DHD_INFO(("%s : maxassoc limit = %d\n", __FUNCTION__, max_assoc)); |
---|
| 1187 | + ret = wldev_iovar_setint(dev, "maxassoc", max_assoc); |
---|
| 1188 | + if (ret) { |
---|
| 1189 | + DHD_ERROR(("%s: Failed to set maxassoc limit to %d\n", __FUNCTION__, max_assoc)); |
---|
| 1190 | + return ret; |
---|
| 1191 | + } |
---|
| 1192 | + return 0; |
---|
| 1193 | +} |
---|
| 1194 | + |
---|
283 | 1195 | #ifdef WLWFDS |
---|
284 | 1196 | static int wl_android_set_wfds_hash( |
---|
285 | | - struct net_device *dev, char *command, int total_len, bool enable) |
---|
| 1197 | + struct net_device *dev, char *command, bool enable) |
---|
286 | 1198 | { |
---|
287 | 1199 | int error = 0; |
---|
288 | 1200 | wl_p2p_wfds_hash_t *wfds_hash = NULL; |
---|
289 | 1201 | char *smbuf = NULL; |
---|
290 | | - smbuf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL); |
---|
| 1202 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
291 | 1203 | |
---|
| 1204 | + smbuf = (char *)MALLOC(cfg->osh, WLC_IOCTL_MAXLEN); |
---|
292 | 1205 | if (smbuf == NULL) { |
---|
293 | | - DHD_ERROR(("%s: failed to allocated memory %d bytes\n", |
---|
294 | | - __FUNCTION__, WLC_IOCTL_MAXLEN)); |
---|
| 1206 | + DHD_ERROR(("wl_android_set_wfds_hash: failed to allocated memory %d bytes\n", |
---|
| 1207 | + WLC_IOCTL_MAXLEN)); |
---|
295 | 1208 | return -ENOMEM; |
---|
296 | 1209 | } |
---|
297 | 1210 | |
---|
.. | .. |
---|
307 | 1220 | } |
---|
308 | 1221 | |
---|
309 | 1222 | if (error) { |
---|
310 | | - DHD_ERROR(("%s: failed to %s, error=%d\n", __FUNCTION__, command, error)); |
---|
| 1223 | + DHD_ERROR(("wl_android_set_wfds_hash: failed to %s, error=%d\n", command, error)); |
---|
311 | 1224 | } |
---|
312 | 1225 | |
---|
313 | | - if (smbuf) |
---|
314 | | - kfree(smbuf); |
---|
| 1226 | + if (smbuf) { |
---|
| 1227 | + MFREE(cfg->osh, smbuf, WLC_IOCTL_MAXLEN); |
---|
| 1228 | + } |
---|
315 | 1229 | return error; |
---|
316 | 1230 | } |
---|
317 | 1231 | #endif /* WLWFDS */ |
---|
318 | 1232 | |
---|
319 | | -static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len) |
---|
320 | | -{ |
---|
321 | | - int link_speed; |
---|
322 | | - int bytes_written; |
---|
323 | | - int error; |
---|
324 | | - |
---|
325 | | - error = wldev_get_link_speed(net, &link_speed); |
---|
326 | | - if (error) { |
---|
327 | | - DHD_ERROR(("Get linkspeed failed \n")); |
---|
328 | | - return -1; |
---|
329 | | - } |
---|
330 | | - |
---|
331 | | - /* Convert Kbps to Android Mbps */ |
---|
332 | | - link_speed = link_speed / 1000; |
---|
333 | | - bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed); |
---|
334 | | - DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command)); |
---|
335 | | - return bytes_written; |
---|
336 | | -} |
---|
337 | | - |
---|
338 | | -static int wl_android_get_rssi(struct net_device *net, char *command, int total_len) |
---|
339 | | -{ |
---|
340 | | - wlc_ssid_t ssid = {0}; |
---|
341 | | - int bytes_written = 0; |
---|
342 | | - int error = 0; |
---|
343 | | - scb_val_t scbval; |
---|
344 | | - char *delim = NULL; |
---|
345 | | - |
---|
346 | | - delim = strchr(command, ' '); |
---|
347 | | - /* For Ap mode rssi command would be |
---|
348 | | - * driver rssi <sta_mac_addr> |
---|
349 | | - * for STA/GC mode |
---|
350 | | - * driver rssi |
---|
351 | | - */ |
---|
352 | | - if (delim) { |
---|
353 | | - /* Ap/GO mode |
---|
354 | | - * driver rssi <sta_mac_addr> |
---|
355 | | - */ |
---|
356 | | - DHD_TRACE(("%s: cmd:%s\n", __FUNCTION__, delim)); |
---|
357 | | - /* skip space from delim after finding char */ |
---|
358 | | - delim++; |
---|
359 | | - if (!(bcm_ether_atoe((delim), &scbval.ea))) |
---|
360 | | - { |
---|
361 | | - DHD_ERROR(("%s:address err\n", __FUNCTION__)); |
---|
362 | | - return -1; |
---|
363 | | - } |
---|
364 | | - scbval.val = htod32(0); |
---|
365 | | - DHD_TRACE(("%s: address:"MACDBG, __FUNCTION__, MAC2STRDBG(scbval.ea.octet))); |
---|
366 | | - } |
---|
367 | | - else { |
---|
368 | | - /* STA/GC mode */ |
---|
369 | | - memset(&scbval, 0, sizeof(scb_val_t)); |
---|
370 | | - } |
---|
371 | | - |
---|
372 | | - error = wldev_get_rssi(net, &scbval); |
---|
373 | | - if (error) |
---|
374 | | - return -1; |
---|
375 | | - |
---|
376 | | - error = wldev_get_ssid(net, &ssid); |
---|
377 | | - if (error) |
---|
378 | | - return -1; |
---|
379 | | - if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) { |
---|
380 | | - DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__)); |
---|
381 | | - } else { |
---|
382 | | - memcpy(command, ssid.SSID, ssid.SSID_len); |
---|
383 | | - bytes_written = ssid.SSID_len; |
---|
384 | | - } |
---|
385 | | - bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", scbval.val); |
---|
386 | | - DHD_TRACE(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written)); |
---|
387 | | - return bytes_written; |
---|
388 | | -} |
---|
389 | | - |
---|
390 | | -static int wl_android_set_suspendopt(struct net_device *dev, char *command, int total_len) |
---|
| 1233 | +static int wl_android_set_suspendopt(struct net_device *dev, char *command) |
---|
391 | 1234 | { |
---|
392 | 1235 | int suspend_flag; |
---|
393 | 1236 | int ret_now; |
---|
394 | 1237 | int ret = 0; |
---|
395 | 1238 | |
---|
396 | | - suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0'; |
---|
| 1239 | + suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0'; |
---|
397 | 1240 | |
---|
398 | | - if (suspend_flag != 0) |
---|
399 | | - suspend_flag = 1; |
---|
400 | | - ret_now = net_os_set_suspend_disable(dev, suspend_flag); |
---|
| 1241 | + if (suspend_flag != 0) { |
---|
| 1242 | + suspend_flag = 1; |
---|
| 1243 | + } |
---|
| 1244 | + ret_now = net_os_set_suspend_disable(dev, suspend_flag); |
---|
401 | 1245 | |
---|
402 | | - if (ret_now != suspend_flag) { |
---|
403 | | - if (!(ret = net_os_set_suspend(dev, ret_now, 1))) |
---|
404 | | - DHD_INFO(("%s: Suspend Flag %d -> %d\n", |
---|
405 | | - __FUNCTION__, ret_now, suspend_flag)); |
---|
406 | | - else |
---|
407 | | - DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); |
---|
| 1246 | + if (ret_now != suspend_flag) { |
---|
| 1247 | + if (!(ret = net_os_set_suspend(dev, ret_now, 1))) { |
---|
| 1248 | + DHD_INFO(("wl_android_set_suspendopt: Suspend Flag %d -> %d\n", |
---|
| 1249 | + ret_now, suspend_flag)); |
---|
| 1250 | + } else { |
---|
| 1251 | + DHD_ERROR(("wl_android_set_suspendopt: failed %d\n", ret)); |
---|
408 | 1252 | } |
---|
| 1253 | + } |
---|
| 1254 | + |
---|
409 | 1255 | return ret; |
---|
410 | 1256 | } |
---|
411 | 1257 | |
---|
412 | | -static int wl_android_set_suspendmode(struct net_device *dev, char *command, int total_len) |
---|
| 1258 | +static int wl_android_set_suspendmode(struct net_device *dev, char *command) |
---|
413 | 1259 | { |
---|
414 | 1260 | int ret = 0; |
---|
415 | 1261 | |
---|
.. | .. |
---|
421 | 1267 | suspend_flag = 1; |
---|
422 | 1268 | |
---|
423 | 1269 | if (!(ret = net_os_set_suspend(dev, suspend_flag, 0))) |
---|
424 | | - DHD_INFO(("%s: Suspend Mode %d\n", __FUNCTION__, suspend_flag)); |
---|
| 1270 | + DHD_INFO(("wl_android_set_suspendmode: Suspend Mode %d\n", suspend_flag)); |
---|
425 | 1271 | else |
---|
426 | | - DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); |
---|
427 | | -#endif |
---|
| 1272 | + DHD_ERROR(("wl_android_set_suspendmode: failed %d\n", ret)); |
---|
| 1273 | +#endif // endif |
---|
428 | 1274 | |
---|
429 | 1275 | return ret; |
---|
430 | | -} |
---|
431 | | - |
---|
432 | | -int wl_android_get_80211_mode(struct net_device *dev, char *command, int total_len) |
---|
433 | | -{ |
---|
434 | | - uint8 mode[4]; |
---|
435 | | - int error = 0; |
---|
436 | | - int bytes_written = 0; |
---|
437 | | - |
---|
438 | | - error = wldev_get_mode(dev, mode); |
---|
439 | | - if (error) |
---|
440 | | - return -1; |
---|
441 | | - |
---|
442 | | - DHD_INFO(("%s: mode:%s\n", __FUNCTION__, mode)); |
---|
443 | | - bytes_written = snprintf(command, total_len, "%s %s", CMD_80211_MODE, mode); |
---|
444 | | - DHD_INFO(("%s: command:%s EXIT\n", __FUNCTION__, command)); |
---|
445 | | - return bytes_written; |
---|
446 | | - |
---|
447 | 1276 | } |
---|
448 | 1277 | |
---|
449 | 1278 | extern chanspec_t |
---|
.. | .. |
---|
467 | 1296 | return -1; |
---|
468 | 1297 | |
---|
469 | 1298 | chanspec = wl_chspec_driver_to_host(chsp); |
---|
470 | | - DHD_INFO(("%s:return value of chanspec:%x\n", __FUNCTION__, chanspec)); |
---|
| 1299 | + DHD_INFO(("wl_android_get_80211_mode: return value of chanspec:%x\n", chanspec)); |
---|
471 | 1300 | |
---|
472 | 1301 | channel = chanspec & WL_CHANSPEC_CHAN_MASK; |
---|
473 | 1302 | band = chanspec & WL_CHANSPEC_BAND_MASK; |
---|
474 | 1303 | bw = chanspec & WL_CHANSPEC_BW_MASK; |
---|
475 | 1304 | |
---|
476 | | - DHD_INFO(("%s:channel:%d band:%d bandwidth:%d\n", __FUNCTION__, channel, band, bw)); |
---|
| 1305 | + DHD_INFO(("wl_android_get_80211_mode: channel:%d band:%d bandwidth:%d\n", |
---|
| 1306 | + channel, band, bw)); |
---|
477 | 1307 | |
---|
478 | 1308 | if (bw == WL_CHANSPEC_BW_80) |
---|
479 | 1309 | bw = WL_CH_BANDWIDTH_80MHZ; |
---|
.. | .. |
---|
507 | 1337 | bytes_written = snprintf(command, total_len, "%s channel %d band %s bw %d", CMD_CHANSPEC, |
---|
508 | 1338 | channel, band == WL_CHANSPEC_BAND_5G ? "5G":"2G", bw); |
---|
509 | 1339 | |
---|
510 | | - DHD_INFO(("%s: command:%s EXIT\n", __FUNCTION__, command)); |
---|
| 1340 | + DHD_INFO(("wl_android_get_chanspec: command:%s EXIT\n", command)); |
---|
511 | 1341 | return bytes_written; |
---|
512 | 1342 | |
---|
| 1343 | +} |
---|
| 1344 | + |
---|
| 1345 | +/* returns whether rsdb supported or not */ |
---|
| 1346 | +int wl_android_get_rsdb_mode(struct net_device *dev, char *command, int total_len) |
---|
| 1347 | +{ |
---|
| 1348 | + int bytes_written = 0; |
---|
| 1349 | + dhd_pub_t *dhd = wl_cfg80211_get_dhdp(dev); |
---|
| 1350 | + int rsdb_mode = 0; |
---|
| 1351 | + |
---|
| 1352 | + if (FW_SUPPORTED(dhd, rsdb)) { |
---|
| 1353 | + rsdb_mode = 1; |
---|
| 1354 | + } |
---|
| 1355 | + DHD_INFO(("wl_android_get_rsdb_mode: rsdb_mode:%d\n", rsdb_mode)); |
---|
| 1356 | + |
---|
| 1357 | + bytes_written = snprintf(command, total_len, "%d", rsdb_mode); |
---|
| 1358 | + return bytes_written; |
---|
513 | 1359 | } |
---|
514 | 1360 | |
---|
515 | 1361 | /* returns current datarate datarate returned from firmware are in 500kbps */ |
---|
516 | | -int wl_android_get_datarate(struct net_device *dev, char *command, int total_len) |
---|
| 1362 | +static int wl_android_get_channel_list(struct net_device *dev, char *command, int total_len) |
---|
517 | 1363 | { |
---|
518 | | - int error = 0; |
---|
519 | | - int datarate = 0; |
---|
520 | | - int bytes_written = 0; |
---|
521 | 1364 | |
---|
522 | | - error = wldev_get_datarate(dev, &datarate); |
---|
523 | | - if (error) |
---|
| 1365 | + int error = 0, len = 0, i; |
---|
| 1366 | + char smbuf[WLC_IOCTL_SMLEN] = {0}; |
---|
| 1367 | + wl_channels_in_country_t *cic; |
---|
| 1368 | + char band[2]; |
---|
| 1369 | + char *pos = command; |
---|
| 1370 | + |
---|
| 1371 | + cic = (wl_channels_in_country_t *)smbuf; |
---|
| 1372 | + |
---|
| 1373 | + pos = pos + strlen(CMD_CHANNELS_IN_CC) + 1; |
---|
| 1374 | + |
---|
| 1375 | + sscanf(pos, "%s %s", cic->country_abbrev, band); |
---|
| 1376 | + DHD_INFO(("%s:country %s and mode %s \n", __FUNCTION__, cic->country_abbrev, band)); |
---|
| 1377 | + len = strlen(cic->country_abbrev); |
---|
| 1378 | + if ((len > 3) || (len < 2)) { |
---|
| 1379 | + DHD_ERROR(("%s :invalid country abbrev\n", __FUNCTION__)); |
---|
524 | 1380 | return -1; |
---|
525 | | - |
---|
526 | | - DHD_INFO(("%s:datarate:%d\n", __FUNCTION__, datarate)); |
---|
527 | | - |
---|
528 | | - bytes_written = snprintf(command, total_len, "%s %d", CMD_DATARATE, (datarate/2)); |
---|
529 | | - return bytes_written; |
---|
530 | | -} |
---|
531 | | -int wl_android_get_assoclist(struct net_device *dev, char *command, int total_len) |
---|
532 | | -{ |
---|
533 | | - int error = 0; |
---|
534 | | - int bytes_written = 0; |
---|
535 | | - uint i; |
---|
536 | | - char mac_buf[MAX_NUM_OF_ASSOCLIST * |
---|
537 | | - sizeof(struct ether_addr) + sizeof(uint)] = {0}; |
---|
538 | | - struct maclist *assoc_maclist = (struct maclist *)mac_buf; |
---|
539 | | - |
---|
540 | | - DHD_TRACE(("%s: ENTER\n", __FUNCTION__)); |
---|
541 | | - |
---|
542 | | - assoc_maclist->count = htod32(MAX_NUM_OF_ASSOCLIST); |
---|
543 | | - |
---|
544 | | - error = wldev_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, sizeof(mac_buf), false); |
---|
545 | | - if (error) |
---|
546 | | - return -1; |
---|
547 | | - |
---|
548 | | - assoc_maclist->count = dtoh32(assoc_maclist->count); |
---|
549 | | - bytes_written = snprintf(command, total_len, "%s listcount: %d Stations:", |
---|
550 | | - CMD_ASSOC_CLIENTS, assoc_maclist->count); |
---|
551 | | - |
---|
552 | | - for (i = 0; i < assoc_maclist->count; i++) { |
---|
553 | | - bytes_written += snprintf(command + bytes_written, total_len, " " MACDBG, |
---|
554 | | - MAC2STRDBG(assoc_maclist->ea[i].octet)); |
---|
555 | 1381 | } |
---|
556 | | - return bytes_written; |
---|
557 | 1382 | |
---|
| 1383 | + if (!strcmp(band, "a") || !strcmp(band, "A")) |
---|
| 1384 | + cic->band = WLC_BAND_5G; |
---|
| 1385 | + else if (!strcmp(band, "b") || !strcmp(band, "B")) |
---|
| 1386 | + cic->band = WLC_BAND_2G; |
---|
| 1387 | + else { |
---|
| 1388 | + DHD_ERROR(("%s: unsupported band: \n", __FUNCTION__)); |
---|
| 1389 | + return -1; |
---|
| 1390 | + } |
---|
| 1391 | + |
---|
| 1392 | + cic->count = 0; |
---|
| 1393 | + cic->buflen = WL_EXTRA_BUF_MAX; |
---|
| 1394 | + |
---|
| 1395 | + error = wldev_ioctl_get(dev, WLC_GET_CHANNELS_IN_COUNTRY, cic, sizeof(smbuf)); |
---|
| 1396 | + if (error) { |
---|
| 1397 | + DHD_ERROR(("%s :Failed to get channels \n", __FUNCTION__)); |
---|
| 1398 | + return -1; |
---|
| 1399 | + } |
---|
| 1400 | + |
---|
| 1401 | + if (cic->count == 0) |
---|
| 1402 | + return -1; |
---|
| 1403 | + |
---|
| 1404 | + for (i = 0; i < (cic->count); i++) { |
---|
| 1405 | + pos += snprintf(pos, total_len, " %d", (cic->channel[i])); |
---|
| 1406 | + } |
---|
| 1407 | + return (pos - command); |
---|
558 | 1408 | } |
---|
| 1409 | + |
---|
| 1410 | +int wl_android_block_associations(struct net_device *dev, char *command, int total_len) |
---|
| 1411 | +{ |
---|
| 1412 | + |
---|
| 1413 | + int enable_blockassoc = 0, bytes_written = 0, ret = 0; |
---|
| 1414 | + |
---|
| 1415 | + if (*(command + strlen(CMD_BLOCKASSOC)) == '\0') { |
---|
| 1416 | + ret = wldev_iovar_getint(dev, "block_assoc", &enable_blockassoc); |
---|
| 1417 | + if (ret != BCME_OK) { |
---|
| 1418 | + DHD_ERROR(("%s: Failed to get status of block_assoc error(%d)\n", __FUNCTION__, ret)); |
---|
| 1419 | + return ret; |
---|
| 1420 | + } |
---|
| 1421 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_BLOCKASSOC, enable_blockassoc); |
---|
| 1422 | + return bytes_written; |
---|
| 1423 | + } |
---|
| 1424 | + command = (command + strlen(CMD_BLOCKASSOC)); |
---|
| 1425 | + command++; |
---|
| 1426 | + enable_blockassoc = bcm_atoi(command); |
---|
| 1427 | + DHD_INFO(("%s: Block associations in AP mode = %d\n", __FUNCTION__, enable_blockassoc)); |
---|
| 1428 | + ret = wldev_iovar_setint(dev, "block_assoc", enable_blockassoc); |
---|
| 1429 | + if (ret != BCME_OK){ |
---|
| 1430 | + DHD_ERROR(("%s: Failed to set block_assoc in AP mode %d\n", __FUNCTION__, ret)); |
---|
| 1431 | + return ret; |
---|
| 1432 | + } |
---|
| 1433 | + |
---|
| 1434 | + return 0; |
---|
| 1435 | +} |
---|
| 1436 | + |
---|
559 | 1437 | extern chanspec_t |
---|
560 | 1438 | wl_chspec_host_to_driver(chanspec_t chanspec); |
---|
561 | | -static int wl_android_set_csa(struct net_device *dev, char *command, int total_len) |
---|
| 1439 | +static int wl_android_set_csa(struct net_device *dev, char *command) |
---|
562 | 1440 | { |
---|
563 | 1441 | int error = 0; |
---|
564 | 1442 | char smbuf[WLC_IOCTL_SMLEN]; |
---|
565 | 1443 | wl_chan_switch_t csa_arg; |
---|
566 | 1444 | u32 chnsp = 0; |
---|
567 | 1445 | int err = 0; |
---|
| 1446 | + char *str, str_chan[8]; |
---|
| 1447 | + uint default_bw = WL_CHANSPEC_BW_20; |
---|
| 1448 | +#if !defined(DISALBE_11H) && defined(DHD_NOSCAN_DURING_CSA) |
---|
| 1449 | + struct wireless_dev *wdev = dev->ieee80211_ptr; |
---|
| 1450 | + struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *)wiphy_priv(wdev->wiphy); |
---|
| 1451 | +#endif // endif |
---|
568 | 1452 | |
---|
569 | | - DHD_INFO(("%s: command:%s\n", __FUNCTION__, command)); |
---|
| 1453 | + DHD_INFO(("wl_android_set_csa: command:%s\n", command)); |
---|
| 1454 | + |
---|
| 1455 | +#if !defined(DISALBE_11H) && defined(DHD_NOSCAN_DURING_CSA) |
---|
| 1456 | + if (!(wdev->iftype == NL80211_IFTYPE_AP || wdev->iftype == NL80211_IFTYPE_P2P_GO)) { |
---|
| 1457 | + DHD_ERROR(("%s:error csa is for only AP/AGO mode(%d)\n", __FUNCTION__, |
---|
| 1458 | + wdev->iftype)); |
---|
| 1459 | + return -1; |
---|
| 1460 | + } |
---|
| 1461 | +#endif // endif |
---|
| 1462 | + |
---|
| 1463 | + /* |
---|
| 1464 | + * SETCSA driver command provides support for AP/AGO to switch its channel |
---|
| 1465 | + * as well as connected STAs channel. This command will send CSA frame and |
---|
| 1466 | + * based on this connected STA will switch to channel which we will pass in |
---|
| 1467 | + * CSA frame. |
---|
| 1468 | + * Usage: |
---|
| 1469 | + * > IFNAME=<group_iface_name> DRIVER SETCSA mode count channel frame_type |
---|
| 1470 | + * > IFNAME=<group_iface_name> DRIVER SETCSA 0 10 1 u |
---|
| 1471 | + * If no frame type is specified, frame_type=0 (Broadcast frame type) |
---|
| 1472 | + */ |
---|
570 | 1473 | |
---|
571 | 1474 | command = (command + strlen(CMD_SET_CSA)); |
---|
572 | 1475 | /* Order is mode, count channel */ |
---|
573 | 1476 | if (!*++command) { |
---|
574 | | - DHD_ERROR(("%s:error missing arguments\n", __FUNCTION__)); |
---|
| 1477 | + DHD_ERROR(("wl_android_set_csa:error missing arguments\n")); |
---|
575 | 1478 | return -1; |
---|
576 | 1479 | } |
---|
577 | 1480 | csa_arg.mode = bcm_atoi(command); |
---|
.. | .. |
---|
582 | 1485 | } |
---|
583 | 1486 | |
---|
584 | 1487 | if (!*++command) { |
---|
585 | | - DHD_ERROR(("%s:error missing count\n", __FUNCTION__)); |
---|
| 1488 | + DHD_ERROR(("wl_android_set_csa: error missing count\n")); |
---|
586 | 1489 | return -1; |
---|
587 | 1490 | } |
---|
588 | 1491 | command++; |
---|
.. | .. |
---|
590 | 1493 | |
---|
591 | 1494 | csa_arg.reg = 0; |
---|
592 | 1495 | csa_arg.chspec = 0; |
---|
593 | | - command += 2; |
---|
594 | | - if (!*command) { |
---|
595 | | - DHD_ERROR(("%s:error missing channel\n", __FUNCTION__)); |
---|
| 1496 | + |
---|
| 1497 | + str = strchr(command, ' '); |
---|
| 1498 | + if (str == NULL) { |
---|
| 1499 | + DHD_ERROR(("wl_android_set_csa: error missing channel\n")); |
---|
596 | 1500 | return -1; |
---|
597 | 1501 | } |
---|
| 1502 | + command = ++str; |
---|
598 | 1503 | |
---|
599 | | - chnsp = wf_chspec_aton(command); |
---|
600 | | - if (chnsp == 0) { |
---|
601 | | - DHD_ERROR(("%s:chsp is not correct\n", __FUNCTION__)); |
---|
| 1504 | + str = strchr(command, ' '); |
---|
| 1505 | + if (str != NULL){ |
---|
| 1506 | + strncpy(str_chan, command, (str-command)); |
---|
| 1507 | + }else { |
---|
| 1508 | + strncpy(str_chan, command, strlen(command)); |
---|
| 1509 | + } |
---|
| 1510 | + |
---|
| 1511 | + /* Get current chanspec to retrieve the current bandwidth */ |
---|
| 1512 | + error = wldev_iovar_getint(dev, "chanspec", &chnsp); |
---|
| 1513 | + if (error == BCME_OK) { |
---|
| 1514 | + chnsp = wl_chspec_driver_to_host(chnsp); |
---|
| 1515 | + /* Use current bandwidth as default if it is not specified in cmd string */ |
---|
| 1516 | + default_bw = chnsp & WL_CHANSPEC_BW_MASK; |
---|
| 1517 | + } |
---|
| 1518 | + |
---|
| 1519 | + chnsp = wf_chspec_aton_ex(str_chan, default_bw); |
---|
| 1520 | + |
---|
| 1521 | + if (chnsp == 0) { |
---|
| 1522 | + DHD_ERROR(("wl_android_set_csa:chsp is not correct\n")); |
---|
602 | 1523 | return -1; |
---|
603 | 1524 | } |
---|
604 | 1525 | chnsp = wl_chspec_host_to_driver(chnsp); |
---|
605 | 1526 | csa_arg.chspec = chnsp; |
---|
606 | 1527 | |
---|
| 1528 | + /* csa action frame type */ |
---|
| 1529 | + if (str != NULL){ |
---|
| 1530 | + if (strcmp(++str, "u") == 0) { |
---|
| 1531 | + csa_arg.frame_type = CSA_UNICAST_ACTION_FRAME; |
---|
| 1532 | + } else { |
---|
| 1533 | + DHD_ERROR(("%s:error: invalid frame type: %s\n", |
---|
| 1534 | + __FUNCTION__, command)); |
---|
| 1535 | + return -1; |
---|
| 1536 | + } |
---|
| 1537 | + } else { |
---|
| 1538 | + csa_arg.frame_type = CSA_BROADCAST_ACTION_FRAME; |
---|
| 1539 | + } |
---|
| 1540 | + |
---|
607 | 1541 | if (chnsp & WL_CHANSPEC_BAND_5G) { |
---|
608 | | - u32 chanspec = chnsp; |
---|
| 1542 | + u32 chanspec = wf_chspec_ctlchan(chnsp); |
---|
609 | 1543 | err = wldev_iovar_getint(dev, "per_chan_info", &chanspec); |
---|
610 | 1544 | if (!err) { |
---|
611 | 1545 | if ((chanspec & WL_CHAN_RADAR) || (chanspec & WL_CHAN_PASSIVE)) { |
---|
.. | .. |
---|
623 | 1557 | DHD_INFO(("non radar sensitivity\n")); |
---|
624 | 1558 | } |
---|
625 | 1559 | error = wldev_iovar_setbuf(dev, "csa", &csa_arg, sizeof(csa_arg), |
---|
626 | | - smbuf, sizeof(smbuf), NULL); |
---|
| 1560 | + smbuf, sizeof(smbuf), NULL); |
---|
627 | 1561 | if (error) { |
---|
628 | | - DHD_ERROR(("%s:set csa failed:%d\n", __FUNCTION__, error)); |
---|
| 1562 | + DHD_ERROR(("wl_android_set_csa:set csa failed:%d\n", error)); |
---|
629 | 1563 | return -1; |
---|
630 | 1564 | } |
---|
| 1565 | + |
---|
| 1566 | +#if !defined(DISALBE_11H) && defined(DHD_NOSCAN_DURING_CSA) |
---|
| 1567 | + cfg->in_csa = TRUE; |
---|
| 1568 | + mod_timer(&cfg->csa_timeout, jiffies + msecs_to_jiffies(100 * (csa_arg.count+2))); |
---|
| 1569 | +#endif // endif |
---|
631 | 1570 | return 0; |
---|
632 | 1571 | } |
---|
| 1572 | + |
---|
| 1573 | +static int |
---|
| 1574 | +wl_android_set_bcn_li_dtim(struct net_device *dev, char *command) |
---|
| 1575 | +{ |
---|
| 1576 | + int ret = 0; |
---|
| 1577 | + int dtim; |
---|
| 1578 | + |
---|
| 1579 | + dtim = *(command + strlen(CMD_SETDTIM_IN_SUSPEND) + 1) - '0'; |
---|
| 1580 | + |
---|
| 1581 | + if (dtim > (MAX_DTIM_ALLOWED_INTERVAL / MAX_DTIM_SKIP_BEACON_INTERVAL)) { |
---|
| 1582 | + DHD_ERROR(("%s: failed, invalid dtim %d\n", |
---|
| 1583 | + __FUNCTION__, dtim)); |
---|
| 1584 | + return BCME_ERROR; |
---|
| 1585 | + } |
---|
| 1586 | + |
---|
| 1587 | + if (!(ret = net_os_set_suspend_bcn_li_dtim(dev, dtim))) { |
---|
| 1588 | + DHD_TRACE(("%s: SET bcn_li_dtim in suspend %d\n", |
---|
| 1589 | + __FUNCTION__, dtim)); |
---|
| 1590 | + } else { |
---|
| 1591 | + DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); |
---|
| 1592 | + } |
---|
| 1593 | + |
---|
| 1594 | + return ret; |
---|
| 1595 | +} |
---|
| 1596 | + |
---|
| 1597 | +static int |
---|
| 1598 | +wl_android_set_max_dtim(struct net_device *dev, char *command) |
---|
| 1599 | +{ |
---|
| 1600 | + int ret = 0; |
---|
| 1601 | + int dtim_flag; |
---|
| 1602 | + |
---|
| 1603 | + dtim_flag = *(command + strlen(CMD_MAXDTIM_IN_SUSPEND) + 1) - '0'; |
---|
| 1604 | + |
---|
| 1605 | + if (!(ret = net_os_set_max_dtim_enable(dev, dtim_flag))) { |
---|
| 1606 | + DHD_TRACE(("wl_android_set_max_dtim: use Max bcn_li_dtim in suspend %s\n", |
---|
| 1607 | + (dtim_flag ? "Enable" : "Disable"))); |
---|
| 1608 | + } else { |
---|
| 1609 | + DHD_ERROR(("wl_android_set_max_dtim: failed %d\n", ret)); |
---|
| 1610 | + } |
---|
| 1611 | + |
---|
| 1612 | + return ret; |
---|
| 1613 | +} |
---|
| 1614 | + |
---|
| 1615 | +#ifdef DISABLE_DTIM_IN_SUSPEND |
---|
| 1616 | +static int |
---|
| 1617 | +wl_android_set_disable_dtim_in_suspend(struct net_device *dev, char *command) |
---|
| 1618 | +{ |
---|
| 1619 | + int ret = 0; |
---|
| 1620 | + int dtim_flag; |
---|
| 1621 | + |
---|
| 1622 | + dtim_flag = *(command + strlen(CMD_DISDTIM_IN_SUSPEND) + 1) - '0'; |
---|
| 1623 | + |
---|
| 1624 | + if (!(ret = net_os_set_disable_dtim_in_suspend(dev, dtim_flag))) { |
---|
| 1625 | + DHD_TRACE(("wl_android_set_disable_dtim_in_suspend: " |
---|
| 1626 | + "use Disable bcn_li_dtim in suspend %s\n", |
---|
| 1627 | + (dtim_flag ? "Enable" : "Disable"))); |
---|
| 1628 | + } else { |
---|
| 1629 | + DHD_ERROR(("wl_android_set_disable_dtim_in_suspend: failed %d\n", ret)); |
---|
| 1630 | + } |
---|
| 1631 | + |
---|
| 1632 | + return ret; |
---|
| 1633 | +} |
---|
| 1634 | +#endif /* DISABLE_DTIM_IN_SUSPEND */ |
---|
| 1635 | + |
---|
633 | 1636 | static int wl_android_get_band(struct net_device *dev, char *command, int total_len) |
---|
634 | 1637 | { |
---|
635 | 1638 | uint band; |
---|
.. | .. |
---|
643 | 1646 | return bytes_written; |
---|
644 | 1647 | } |
---|
645 | 1648 | |
---|
646 | | -static int wl_android_wbtext(struct net_device *dev, char *command, int total_len) |
---|
| 1649 | +static int |
---|
| 1650 | +wl_android_set_band(struct net_device *dev, char *command) |
---|
647 | 1651 | { |
---|
648 | 1652 | int error = 0; |
---|
649 | | - int data; |
---|
| 1653 | + uint band = *(command + strlen(CMD_SETBAND) + 1) - '0'; |
---|
| 1654 | +#ifdef WL_HOST_BAND_MGMT |
---|
| 1655 | + int ret = 0; |
---|
| 1656 | + if ((ret = wl_cfg80211_set_band(dev, band)) < 0) { |
---|
| 1657 | + if (ret == BCME_UNSUPPORTED) { |
---|
| 1658 | + /* If roam_var is unsupported, fallback to the original method */ |
---|
| 1659 | + WL_ERR(("WL_HOST_BAND_MGMT defined, " |
---|
| 1660 | + "but roam_band iovar unsupported in the firmware\n")); |
---|
| 1661 | + } else { |
---|
| 1662 | + error = -1; |
---|
| 1663 | + } |
---|
| 1664 | + } |
---|
| 1665 | + if (((ret == 0) && (band == WLC_BAND_AUTO)) || (ret == BCME_UNSUPPORTED)) { |
---|
| 1666 | + /* Apply if roam_band iovar is not supported or band setting is AUTO */ |
---|
| 1667 | + error = wldev_set_band(dev, band); |
---|
| 1668 | + } |
---|
| 1669 | +#else |
---|
| 1670 | + error = wl_cfg80211_set_if_band(dev, band); |
---|
| 1671 | +#endif /* WL_HOST_BAND_MGMT */ |
---|
| 1672 | +#ifdef ROAM_CHANNEL_CACHE |
---|
| 1673 | + wl_update_roamscan_cache_by_band(dev, band); |
---|
| 1674 | +#endif /* ROAM_CHANNEL_CACHE */ |
---|
| 1675 | + return error; |
---|
| 1676 | +} |
---|
650 | 1677 | |
---|
651 | | - sscanf(command+sizeof("WBTEXT_ENABLE"), "%d", &data); |
---|
| 1678 | +static int wl_android_add_vendor_ie(struct net_device *dev, char *command, int total_len) |
---|
| 1679 | +{ |
---|
| 1680 | + char ie_buf[VNDR_IE_MAX_LEN]; |
---|
| 1681 | + char *ioctl_buf = NULL; |
---|
| 1682 | + char hex[] = "XX"; |
---|
| 1683 | + char *pcmd = NULL; |
---|
| 1684 | + int ielen = 0, datalen = 0, idx = 0, tot_len = 0; |
---|
| 1685 | + vndr_ie_setbuf_t *vndr_ie = NULL; |
---|
| 1686 | + s32 iecount; |
---|
| 1687 | + uint32 pktflag; |
---|
| 1688 | + gfp_t kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; |
---|
| 1689 | + s32 err = BCME_OK; |
---|
652 | 1690 | |
---|
653 | | - if (data) |
---|
654 | | - data = WL_BSSTRANS_POLICY_PRODUCT; |
---|
| 1691 | + /* |
---|
| 1692 | + * ADD_IE driver command provides support for addition of vendor elements |
---|
| 1693 | + * to different management frames via wpa_cli |
---|
| 1694 | + * Usage: |
---|
| 1695 | + * Create softap/AGO |
---|
| 1696 | + * wpa_cli> IFNAME=<group_iface_name> DRIVER ADD_IE <flag> <OUI> <DATA> |
---|
| 1697 | + * Here Flag is 802.11 Mgmt packet flags values |
---|
| 1698 | + * Beacon: 0 |
---|
| 1699 | + * Probe Rsp: 1 |
---|
| 1700 | + * Assoc Rsp: 2 |
---|
| 1701 | + * Auth Rsp: 4 |
---|
| 1702 | + * Probe Req: 8 |
---|
| 1703 | + * Assoc Req: 16 |
---|
| 1704 | + * E.g |
---|
| 1705 | + * wpa_cli> IFNAME=bcm0 DRIVER ADD_IE 1 998877 1122334455667788 |
---|
| 1706 | + */ |
---|
| 1707 | + pcmd = command + strlen(CMD_ADDIE) + 1; |
---|
| 1708 | + pktflag = simple_strtoul(pcmd, &pcmd, 16); |
---|
| 1709 | + pcmd = pcmd + 1; |
---|
655 | 1710 | |
---|
656 | | - error = wldev_iovar_setint(dev, "wnm_bsstrans_resp", data); |
---|
| 1711 | + for (idx = 0; idx < DOT11_OUI_LEN; idx++) { |
---|
| 1712 | + hex[0] = *pcmd++; |
---|
| 1713 | + hex[1] = *pcmd++; |
---|
| 1714 | + ie_buf[idx] = (uint8)simple_strtoul(hex, NULL, 16); |
---|
| 1715 | + } |
---|
| 1716 | + pcmd++; |
---|
| 1717 | + while ((*pcmd != '\0') && (idx < VNDR_IE_MAX_LEN)) { |
---|
| 1718 | + hex[0] = *pcmd++; |
---|
| 1719 | + hex[1] = *pcmd++; |
---|
| 1720 | + ie_buf[idx++] = (uint8)simple_strtoul(hex, NULL, 16); |
---|
| 1721 | + datalen++; |
---|
| 1722 | + } |
---|
| 1723 | + |
---|
| 1724 | + tot_len = sizeof(vndr_ie_setbuf_t) + (datalen - 1); |
---|
| 1725 | + |
---|
| 1726 | + if (tot_len > VNDR_IE_MAX_LEN) { |
---|
| 1727 | + WL_ERR(("Invalid IE total length %d\n", tot_len)); |
---|
| 1728 | + return -ENOMEM; |
---|
| 1729 | + } |
---|
| 1730 | + |
---|
| 1731 | + vndr_ie = (vndr_ie_setbuf_t *) kzalloc(tot_len, kflags); |
---|
| 1732 | + if (!vndr_ie) { |
---|
| 1733 | + WL_ERR(("IE memory alloc failed\n")); |
---|
| 1734 | + return -ENOMEM; |
---|
| 1735 | + } |
---|
| 1736 | + /* Copy the vndr_ie SET command ("add"/"del") to the buffer */ |
---|
| 1737 | + strncpy(vndr_ie->cmd, "add", VNDR_IE_CMD_LEN - 1); |
---|
| 1738 | + vndr_ie->cmd[VNDR_IE_CMD_LEN - 1] = '\0'; |
---|
| 1739 | + |
---|
| 1740 | + /* Set the IE count - the buffer contains only 1 IE */ |
---|
| 1741 | + iecount = htod32(1); |
---|
| 1742 | + memcpy((void *)&vndr_ie->vndr_ie_buffer.iecount, &iecount, sizeof(s32)); |
---|
| 1743 | + |
---|
| 1744 | + /* Set packet flag to indicate the appropriate frame will contain this IE */ |
---|
| 1745 | + pktflag = htod32(1<<pktflag); |
---|
| 1746 | + memcpy((void *)&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag, |
---|
| 1747 | + sizeof(u32)); |
---|
| 1748 | + |
---|
| 1749 | + /* Set the IE ID */ |
---|
| 1750 | + vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = (uchar) DOT11_MNG_PROPR_ID; |
---|
| 1751 | + |
---|
| 1752 | + /* Set the OUI */ |
---|
| 1753 | + memcpy(&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, &ie_buf, |
---|
| 1754 | + DOT11_OUI_LEN); |
---|
| 1755 | + /* Set the Data */ |
---|
| 1756 | + memcpy(&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data, |
---|
| 1757 | + &ie_buf[DOT11_OUI_LEN], datalen); |
---|
| 1758 | + |
---|
| 1759 | + ielen = DOT11_OUI_LEN + datalen; |
---|
| 1760 | + vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len = (uchar) ielen; |
---|
| 1761 | + |
---|
| 1762 | + ioctl_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); |
---|
| 1763 | + if (!ioctl_buf) { |
---|
| 1764 | + WL_ERR(("ioctl memory alloc failed\n")); |
---|
| 1765 | + if (vndr_ie) { |
---|
| 1766 | + kfree(vndr_ie); |
---|
| 1767 | + } |
---|
| 1768 | + return -ENOMEM; |
---|
| 1769 | + } |
---|
| 1770 | + memset(ioctl_buf, 0, WLC_IOCTL_MEDLEN); /* init the buffer */ |
---|
| 1771 | + err = wldev_iovar_setbuf(dev, "vndr_ie", vndr_ie, tot_len, ioctl_buf, |
---|
| 1772 | + WLC_IOCTL_MEDLEN, NULL); |
---|
| 1773 | + |
---|
| 1774 | + if (err != BCME_OK) { |
---|
| 1775 | + err = -EINVAL; |
---|
| 1776 | + } |
---|
| 1777 | + |
---|
| 1778 | + if (vndr_ie) { |
---|
| 1779 | + kfree(vndr_ie); |
---|
| 1780 | + } |
---|
| 1781 | + |
---|
| 1782 | + if (ioctl_buf) { |
---|
| 1783 | + kfree(ioctl_buf); |
---|
| 1784 | + } |
---|
| 1785 | + |
---|
| 1786 | + return err; |
---|
| 1787 | +} |
---|
| 1788 | + |
---|
| 1789 | +static int wl_android_del_vendor_ie(struct net_device *dev, char *command, int total_len) |
---|
| 1790 | +{ |
---|
| 1791 | + char ie_buf[VNDR_IE_MAX_LEN]; |
---|
| 1792 | + char *ioctl_buf = NULL; |
---|
| 1793 | + char hex[] = "XX"; |
---|
| 1794 | + char *pcmd = NULL; |
---|
| 1795 | + int ielen = 0, datalen = 0, idx = 0, tot_len = 0; |
---|
| 1796 | + vndr_ie_setbuf_t *vndr_ie = NULL; |
---|
| 1797 | + s32 iecount; |
---|
| 1798 | + uint32 pktflag; |
---|
| 1799 | + gfp_t kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; |
---|
| 1800 | + s32 err = BCME_OK; |
---|
| 1801 | + |
---|
| 1802 | + /* |
---|
| 1803 | + * DEL_IE driver command provides support for deletoon of vendor elements |
---|
| 1804 | + * from different management frames via wpa_cli |
---|
| 1805 | + * Usage: |
---|
| 1806 | + * Create softap/AGO |
---|
| 1807 | + * wpa_cli> IFNAME=<group_iface_name> DRIVER DEL_IE <flag> <OUI> <DATA> |
---|
| 1808 | + * Here Flag is 802.11 Mgmt packet flags values |
---|
| 1809 | + * Beacon: 1 |
---|
| 1810 | + * Probe Rsp: 2 |
---|
| 1811 | + * Assoc Rsp: 4 |
---|
| 1812 | + * Auth Rsp: 8 |
---|
| 1813 | + * Probe Req: 16 |
---|
| 1814 | + * Assoc Req: 32 |
---|
| 1815 | + * E.g |
---|
| 1816 | + * wpa_cli> IFNAME=bcm0 DRIVER DEL_IE 1 998877 1122334455667788 |
---|
| 1817 | + */ |
---|
| 1818 | + pcmd = command + strlen(CMD_DELIE) + 1; |
---|
| 1819 | + |
---|
| 1820 | + pktflag = simple_strtoul(pcmd, &pcmd, 16); |
---|
| 1821 | + pcmd = pcmd + 1; |
---|
| 1822 | + |
---|
| 1823 | + for (idx = 0; idx < DOT11_OUI_LEN; idx++) { |
---|
| 1824 | + hex[0] = *pcmd++; |
---|
| 1825 | + hex[1] = *pcmd++; |
---|
| 1826 | + ie_buf[idx] = (uint8)simple_strtoul(hex, NULL, 16); |
---|
| 1827 | + } |
---|
| 1828 | + pcmd++; |
---|
| 1829 | + while ((*pcmd != '\0') && (idx < VNDR_IE_MAX_LEN)) { |
---|
| 1830 | + hex[0] = *pcmd++; |
---|
| 1831 | + hex[1] = *pcmd++; |
---|
| 1832 | + ie_buf[idx++] = (uint8)simple_strtoul(hex, NULL, 16); |
---|
| 1833 | + datalen++; |
---|
| 1834 | + } |
---|
| 1835 | + |
---|
| 1836 | + tot_len = sizeof(vndr_ie_setbuf_t) + (datalen - 1); |
---|
| 1837 | + if (tot_len > VNDR_IE_MAX_LEN) { |
---|
| 1838 | + WL_ERR(("Invalid IE total length %d\n", tot_len)); |
---|
| 1839 | + return -ENOMEM; |
---|
| 1840 | + } |
---|
| 1841 | + vndr_ie = (vndr_ie_setbuf_t *) kzalloc(tot_len, kflags); |
---|
| 1842 | + if (!vndr_ie) { |
---|
| 1843 | + WL_ERR(("IE memory alloc failed\n")); |
---|
| 1844 | + return -ENOMEM; |
---|
| 1845 | + } |
---|
| 1846 | + /* Copy the vndr_ie SET command ("add"/"del") to the buffer */ |
---|
| 1847 | + strncpy(vndr_ie->cmd, "del", VNDR_IE_CMD_LEN - 1); |
---|
| 1848 | + vndr_ie->cmd[VNDR_IE_CMD_LEN - 1] = '\0'; |
---|
| 1849 | + |
---|
| 1850 | + /* Set the IE count - the buffer contains only 1 IE */ |
---|
| 1851 | + iecount = htod32(1); |
---|
| 1852 | + memcpy((void *)&vndr_ie->vndr_ie_buffer.iecount, &iecount, sizeof(s32)); |
---|
| 1853 | + |
---|
| 1854 | + /* Set packet flag to indicate the appropriate frame will contain this IE */ |
---|
| 1855 | + pktflag = htod32(1<<(pktflag-1)); |
---|
| 1856 | + memcpy((void *)&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag, |
---|
| 1857 | + sizeof(u32)); |
---|
| 1858 | + |
---|
| 1859 | + /* Set the IE ID */ |
---|
| 1860 | + vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = (uchar) DOT11_MNG_PROPR_ID; |
---|
| 1861 | + |
---|
| 1862 | + /* Set the OUI */ |
---|
| 1863 | + memcpy(&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, &ie_buf, |
---|
| 1864 | + DOT11_OUI_LEN); |
---|
| 1865 | + |
---|
| 1866 | + /* Set the Data */ |
---|
| 1867 | + memcpy(&vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data, |
---|
| 1868 | + &ie_buf[DOT11_OUI_LEN], datalen); |
---|
| 1869 | + |
---|
| 1870 | + ielen = DOT11_OUI_LEN + datalen; |
---|
| 1871 | + vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len = (uchar) ielen; |
---|
| 1872 | + |
---|
| 1873 | + ioctl_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); |
---|
| 1874 | + if (!ioctl_buf) { |
---|
| 1875 | + WL_ERR(("ioctl memory alloc failed\n")); |
---|
| 1876 | + if (vndr_ie) { |
---|
| 1877 | + kfree(vndr_ie); |
---|
| 1878 | + } |
---|
| 1879 | + return -ENOMEM; |
---|
| 1880 | + } |
---|
| 1881 | + memset(ioctl_buf, 0, WLC_IOCTL_MEDLEN); /* init the buffer */ |
---|
| 1882 | + err = wldev_iovar_setbuf(dev, "vndr_ie", vndr_ie, tot_len, ioctl_buf, |
---|
| 1883 | + WLC_IOCTL_MEDLEN, NULL); |
---|
| 1884 | + |
---|
| 1885 | + if (err != BCME_OK) { |
---|
| 1886 | + err = -EINVAL; |
---|
| 1887 | + } |
---|
| 1888 | + |
---|
| 1889 | + if (vndr_ie) { |
---|
| 1890 | + kfree(vndr_ie); |
---|
| 1891 | + } |
---|
| 1892 | + |
---|
| 1893 | + if (ioctl_buf) { |
---|
| 1894 | + kfree(ioctl_buf); |
---|
| 1895 | + } |
---|
| 1896 | + return err; |
---|
| 1897 | +} |
---|
| 1898 | + |
---|
| 1899 | +#if defined(CUSTOMER_HW4_PRIVATE_CMD) || defined(IGUANA_LEGACY_CHIPS) |
---|
| 1900 | +#ifdef ROAM_API |
---|
| 1901 | +static bool wl_android_check_wbtext(struct net_device *dev) |
---|
| 1902 | +{ |
---|
| 1903 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 1904 | + return dhdp->wbtext_support; |
---|
| 1905 | +} |
---|
| 1906 | + |
---|
| 1907 | +static int wl_android_set_roam_trigger( |
---|
| 1908 | + struct net_device *dev, char* command) |
---|
| 1909 | +{ |
---|
| 1910 | + int roam_trigger[2] = {0, 0}; |
---|
| 1911 | + int error; |
---|
| 1912 | + |
---|
| 1913 | +#ifdef WBTEXT |
---|
| 1914 | + if (wl_android_check_wbtext(dev)) { |
---|
| 1915 | + WL_ERR(("blocked to set roam trigger. try with setting roam profile\n")); |
---|
| 1916 | + return BCME_ERROR; |
---|
| 1917 | + } |
---|
| 1918 | +#endif /* WBTEXT */ |
---|
| 1919 | + |
---|
| 1920 | + sscanf(command, "%*s %10d", &roam_trigger[0]); |
---|
| 1921 | + if (roam_trigger[0] >= 0) { |
---|
| 1922 | + WL_ERR(("wrong roam trigger value (%d)\n", roam_trigger[0])); |
---|
| 1923 | + return BCME_ERROR; |
---|
| 1924 | + } |
---|
| 1925 | + |
---|
| 1926 | + roam_trigger[1] = WLC_BAND_ALL; |
---|
| 1927 | + error = wldev_ioctl_set(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, |
---|
| 1928 | + sizeof(roam_trigger)); |
---|
| 1929 | + if (error != BCME_OK) { |
---|
| 1930 | + WL_ERR(("failed to set roam trigger (%d)\n", error)); |
---|
| 1931 | + return BCME_ERROR; |
---|
| 1932 | + } |
---|
| 1933 | + |
---|
| 1934 | + return BCME_OK; |
---|
| 1935 | +} |
---|
| 1936 | + |
---|
| 1937 | +static int wl_android_get_roam_trigger( |
---|
| 1938 | + struct net_device *dev, char *command, int total_len) |
---|
| 1939 | +{ |
---|
| 1940 | + int bytes_written, error; |
---|
| 1941 | + int roam_trigger[2] = {0, 0}; |
---|
| 1942 | + uint16 band = 0; |
---|
| 1943 | + int chsp = {0}; |
---|
| 1944 | + chanspec_t chanspec; |
---|
| 1945 | +#ifdef WBTEXT |
---|
| 1946 | + int i; |
---|
| 1947 | + wl_roamprof_band_t rp; |
---|
| 1948 | + uint8 roam_prof_ver = 0, roam_prof_size = 0; |
---|
| 1949 | +#endif /* WBTEXT */ |
---|
| 1950 | + |
---|
| 1951 | + error = wldev_iovar_getint(dev, "chanspec", &chsp); |
---|
| 1952 | + if (error != BCME_OK) { |
---|
| 1953 | + WL_ERR(("failed to get chanspec (%d)\n", error)); |
---|
| 1954 | + return BCME_ERROR; |
---|
| 1955 | + } |
---|
| 1956 | + |
---|
| 1957 | + chanspec = wl_chspec_driver_to_host(chsp); |
---|
| 1958 | + band = chanspec & WL_CHANSPEC_BAND_MASK; |
---|
| 1959 | + if (band == WL_CHANSPEC_BAND_5G) |
---|
| 1960 | + band = WLC_BAND_5G; |
---|
| 1961 | + else |
---|
| 1962 | + band = WLC_BAND_2G; |
---|
| 1963 | + |
---|
| 1964 | + if (wl_android_check_wbtext(dev)) { |
---|
| 1965 | +#ifdef WBTEXT |
---|
| 1966 | + memset_s(&rp, sizeof(rp), 0, sizeof(rp)); |
---|
| 1967 | + if ((error = wlc_wbtext_get_roam_prof(dev, &rp, band, &roam_prof_ver, |
---|
| 1968 | + &roam_prof_size))) { |
---|
| 1969 | + WL_ERR(("Getting roam_profile failed with err=%d \n", error)); |
---|
| 1970 | + return -EINVAL; |
---|
| 1971 | + } |
---|
| 1972 | + switch (roam_prof_ver) { |
---|
| 1973 | + case WL_ROAM_PROF_VER_1: |
---|
| 1974 | + { |
---|
| 1975 | + for (i = 0; i < WL_MAX_ROAM_PROF_BRACKETS; i++) { |
---|
| 1976 | + if (rp.v2.roam_prof[i].channel_usage == 0) { |
---|
| 1977 | + roam_trigger[0] = rp.v2.roam_prof[i].roam_trigger; |
---|
| 1978 | + break; |
---|
| 1979 | + } |
---|
| 1980 | + } |
---|
| 1981 | + } |
---|
| 1982 | + break; |
---|
| 1983 | + case WL_ROAM_PROF_VER_2: |
---|
| 1984 | + { |
---|
| 1985 | + for (i = 0; i < WL_MAX_ROAM_PROF_BRACKETS; i++) { |
---|
| 1986 | + if (rp.v3.roam_prof[i].channel_usage == 0) { |
---|
| 1987 | + roam_trigger[0] = rp.v3.roam_prof[i].roam_trigger; |
---|
| 1988 | + break; |
---|
| 1989 | + } |
---|
| 1990 | + } |
---|
| 1991 | + } |
---|
| 1992 | + break; |
---|
| 1993 | + default: |
---|
| 1994 | + WL_ERR(("bad version = %d \n", roam_prof_ver)); |
---|
| 1995 | + return BCME_VERSION; |
---|
| 1996 | + } |
---|
| 1997 | +#endif /* WBTEXT */ |
---|
| 1998 | + if (roam_trigger[0] == 0) { |
---|
| 1999 | + WL_ERR(("roam trigger was not set properly\n")); |
---|
| 2000 | + return BCME_ERROR; |
---|
| 2001 | + } |
---|
| 2002 | + } else { |
---|
| 2003 | + roam_trigger[1] = band; |
---|
| 2004 | + error = wldev_ioctl_get(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, |
---|
| 2005 | + sizeof(roam_trigger)); |
---|
| 2006 | + if (error != BCME_OK) { |
---|
| 2007 | + WL_ERR(("failed to get roam trigger (%d)\n", error)); |
---|
| 2008 | + return BCME_ERROR; |
---|
| 2009 | + } |
---|
| 2010 | + } |
---|
| 2011 | + |
---|
| 2012 | + bytes_written = snprintf(command, total_len, "%s %d", |
---|
| 2013 | + CMD_ROAMTRIGGER_GET, roam_trigger[0]); |
---|
| 2014 | + |
---|
| 2015 | + return bytes_written; |
---|
| 2016 | +} |
---|
| 2017 | + |
---|
| 2018 | +int wl_android_set_roam_delta( |
---|
| 2019 | + struct net_device *dev, char* command) |
---|
| 2020 | +{ |
---|
| 2021 | + int roam_delta[2]; |
---|
| 2022 | + |
---|
| 2023 | + sscanf(command, "%*s %10d", &roam_delta[0]); |
---|
| 2024 | + roam_delta[1] = WLC_BAND_ALL; |
---|
| 2025 | + |
---|
| 2026 | + return wldev_ioctl_set(dev, WLC_SET_ROAM_DELTA, roam_delta, |
---|
| 2027 | + sizeof(roam_delta)); |
---|
| 2028 | +} |
---|
| 2029 | + |
---|
| 2030 | +static int wl_android_get_roam_delta( |
---|
| 2031 | + struct net_device *dev, char *command, int total_len) |
---|
| 2032 | +{ |
---|
| 2033 | + int bytes_written; |
---|
| 2034 | + int roam_delta[2] = {0, 0}; |
---|
| 2035 | + |
---|
| 2036 | + roam_delta[1] = WLC_BAND_2G; |
---|
| 2037 | + if (wldev_ioctl_get(dev, WLC_GET_ROAM_DELTA, roam_delta, |
---|
| 2038 | + sizeof(roam_delta))) { |
---|
| 2039 | + roam_delta[1] = WLC_BAND_5G; |
---|
| 2040 | + if (wldev_ioctl_get(dev, WLC_GET_ROAM_DELTA, roam_delta, |
---|
| 2041 | + sizeof(roam_delta))) |
---|
| 2042 | + return -1; |
---|
| 2043 | + } |
---|
| 2044 | + |
---|
| 2045 | + bytes_written = snprintf(command, total_len, "%s %d", |
---|
| 2046 | + CMD_ROAMDELTA_GET, roam_delta[0]); |
---|
| 2047 | + |
---|
| 2048 | + return bytes_written; |
---|
| 2049 | +} |
---|
| 2050 | + |
---|
| 2051 | +int wl_android_set_roam_scan_period( |
---|
| 2052 | + struct net_device *dev, char* command) |
---|
| 2053 | +{ |
---|
| 2054 | + int roam_scan_period = 0; |
---|
| 2055 | + |
---|
| 2056 | + sscanf(command, "%*s %10d", &roam_scan_period); |
---|
| 2057 | + return wldev_ioctl_set(dev, WLC_SET_ROAM_SCAN_PERIOD, &roam_scan_period, |
---|
| 2058 | + sizeof(roam_scan_period)); |
---|
| 2059 | +} |
---|
| 2060 | + |
---|
| 2061 | +static int wl_android_get_roam_scan_period( |
---|
| 2062 | + struct net_device *dev, char *command, int total_len) |
---|
| 2063 | +{ |
---|
| 2064 | + int bytes_written; |
---|
| 2065 | + int roam_scan_period = 0; |
---|
| 2066 | + |
---|
| 2067 | + if (wldev_ioctl_get(dev, WLC_GET_ROAM_SCAN_PERIOD, &roam_scan_period, |
---|
| 2068 | + sizeof(roam_scan_period))) |
---|
| 2069 | + return -1; |
---|
| 2070 | + |
---|
| 2071 | + bytes_written = snprintf(command, total_len, "%s %d", |
---|
| 2072 | + CMD_ROAMSCANPERIOD_GET, roam_scan_period); |
---|
| 2073 | + |
---|
| 2074 | + return bytes_written; |
---|
| 2075 | +} |
---|
| 2076 | + |
---|
| 2077 | +int wl_android_set_full_roam_scan_period( |
---|
| 2078 | + struct net_device *dev, char* command, int total_len) |
---|
| 2079 | +{ |
---|
| 2080 | + int error = 0; |
---|
| 2081 | + int full_roam_scan_period = 0; |
---|
| 2082 | + char smbuf[WLC_IOCTL_SMLEN]; |
---|
| 2083 | + |
---|
| 2084 | + sscanf(command+sizeof("SETFULLROAMSCANPERIOD"), "%d", &full_roam_scan_period); |
---|
| 2085 | + WL_TRACE(("fullroamperiod = %d\n", full_roam_scan_period)); |
---|
| 2086 | + |
---|
| 2087 | + error = wldev_iovar_setbuf(dev, "fullroamperiod", &full_roam_scan_period, |
---|
| 2088 | + sizeof(full_roam_scan_period), smbuf, sizeof(smbuf), NULL); |
---|
657 | 2089 | if (error) { |
---|
658 | | - DHD_ERROR(("%s: Failed to set wnm_bsstrans_resp error = %d\n", |
---|
659 | | - __FUNCTION__, error)); |
---|
| 2090 | + DHD_ERROR(("Failed to set full roam scan period, error = %d\n", error)); |
---|
| 2091 | + } |
---|
| 2092 | + |
---|
| 2093 | + return error; |
---|
| 2094 | +} |
---|
| 2095 | + |
---|
| 2096 | +static int wl_android_get_full_roam_scan_period( |
---|
| 2097 | + struct net_device *dev, char *command, int total_len) |
---|
| 2098 | +{ |
---|
| 2099 | + int error; |
---|
| 2100 | + int bytes_written; |
---|
| 2101 | + int full_roam_scan_period = 0; |
---|
| 2102 | + |
---|
| 2103 | + error = wldev_iovar_getint(dev, "fullroamperiod", &full_roam_scan_period); |
---|
| 2104 | + |
---|
| 2105 | + if (error) { |
---|
| 2106 | + DHD_ERROR(("%s: get full roam scan period failed code %d\n", |
---|
| 2107 | + __func__, error)); |
---|
| 2108 | + return -1; |
---|
| 2109 | + } else { |
---|
| 2110 | + DHD_INFO(("%s: get full roam scan period %d\n", __func__, full_roam_scan_period)); |
---|
| 2111 | + } |
---|
| 2112 | + |
---|
| 2113 | + bytes_written = snprintf(command, total_len, "%s %d", |
---|
| 2114 | + CMD_FULLROAMSCANPERIOD_GET, full_roam_scan_period); |
---|
| 2115 | + |
---|
| 2116 | + return bytes_written; |
---|
| 2117 | +} |
---|
| 2118 | + |
---|
| 2119 | +#endif /* ROAM_API */ |
---|
| 2120 | + |
---|
| 2121 | +#ifdef WES_SUPPORT |
---|
| 2122 | +int wl_android_get_roam_scan_control(struct net_device *dev, char *command, int total_len) |
---|
| 2123 | +{ |
---|
| 2124 | + int error = 0; |
---|
| 2125 | + int bytes_written = 0; |
---|
| 2126 | + int mode = 0; |
---|
| 2127 | + |
---|
| 2128 | + error = get_roamscan_mode(dev, &mode); |
---|
| 2129 | + if (error) { |
---|
| 2130 | + DHD_ERROR(("wl_android_get_roam_scan_control: Failed to get Scan Control," |
---|
| 2131 | + " error = %d\n", error)); |
---|
| 2132 | + return -1; |
---|
| 2133 | + } |
---|
| 2134 | + |
---|
| 2135 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETROAMSCANCONTROL, mode); |
---|
| 2136 | + |
---|
| 2137 | + return bytes_written; |
---|
| 2138 | +} |
---|
| 2139 | + |
---|
| 2140 | +int wl_android_set_roam_scan_control(struct net_device *dev, char *command) |
---|
| 2141 | +{ |
---|
| 2142 | + int error = 0; |
---|
| 2143 | + int mode = 0; |
---|
| 2144 | + |
---|
| 2145 | + if (sscanf(command, "%*s %d", &mode) != 1) { |
---|
| 2146 | + DHD_ERROR(("wl_android_set_roam_scan_control: Failed to get Parameter\n")); |
---|
| 2147 | + return -1; |
---|
| 2148 | + } |
---|
| 2149 | + |
---|
| 2150 | + error = set_roamscan_mode(dev, mode); |
---|
| 2151 | + if (error) { |
---|
| 2152 | + DHD_ERROR(("wl_android_set_roam_scan_control: Failed to set Scan Control %d," |
---|
| 2153 | + " error = %d\n", |
---|
| 2154 | + mode, error)); |
---|
| 2155 | + return -1; |
---|
| 2156 | + } |
---|
| 2157 | + |
---|
| 2158 | + return 0; |
---|
| 2159 | +} |
---|
| 2160 | + |
---|
| 2161 | +int wl_android_get_roam_scan_channels(struct net_device *dev, char *command, int total_len) |
---|
| 2162 | +{ |
---|
| 2163 | + int bytes_written = 0; |
---|
| 2164 | + unsigned char channels[MAX_ROAM_CHANNEL] = {0}; |
---|
| 2165 | + int channel_cnt = 0; |
---|
| 2166 | + int i = 0; |
---|
| 2167 | + int buf_avail, len; |
---|
| 2168 | + |
---|
| 2169 | + channel_cnt = get_roamscan_channel_list(dev, channels, MAX_ROAM_CHANNEL); |
---|
| 2170 | + bytes_written = snprintf(command, total_len, "%s %d", |
---|
| 2171 | + CMD_GETROAMSCANCHANNELS, channel_cnt); |
---|
| 2172 | + buf_avail = total_len - bytes_written; |
---|
| 2173 | + for (i = 0; i < channel_cnt; i++) { |
---|
| 2174 | + /* A return value of 'buf_avail' or more means that the output was truncated */ |
---|
| 2175 | + len = snprintf(command + bytes_written, buf_avail, " %d", channels[i]); |
---|
| 2176 | + if (len >= buf_avail) { |
---|
| 2177 | + WL_ERR(("wl_android_get_roam_scan_channels: Insufficient memory," |
---|
| 2178 | + " %d bytes\n", |
---|
| 2179 | + total_len)); |
---|
| 2180 | + bytes_written = -1; |
---|
| 2181 | + break; |
---|
| 2182 | + } |
---|
| 2183 | + /* 'buf_avail' decremented by number of bytes written */ |
---|
| 2184 | + buf_avail -= len; |
---|
| 2185 | + bytes_written += len; |
---|
| 2186 | + } |
---|
| 2187 | + WL_INFORM(("wl_android_get_roam_scan_channels: %s\n", command)); |
---|
| 2188 | + return bytes_written; |
---|
| 2189 | +} |
---|
| 2190 | + |
---|
| 2191 | +int wl_android_set_roam_scan_channels(struct net_device *dev, char *command) |
---|
| 2192 | +{ |
---|
| 2193 | + int error = 0; |
---|
| 2194 | + unsigned char *p = (unsigned char *)(command + strlen(CMD_SETROAMSCANCHANNELS) + 1); |
---|
| 2195 | + int get_ioctl_version = wl_cfg80211_get_ioctl_version(); |
---|
| 2196 | + error = set_roamscan_channel_list(dev, p[0], &p[1], get_ioctl_version); |
---|
| 2197 | + if (error) { |
---|
| 2198 | + DHD_ERROR(("wl_android_set_roam_scan_channels: Failed to set Scan Channels %d," |
---|
| 2199 | + " error = %d\n", |
---|
| 2200 | + p[0], error)); |
---|
| 2201 | + return -1; |
---|
| 2202 | + } |
---|
| 2203 | + |
---|
| 2204 | + return 0; |
---|
| 2205 | +} |
---|
| 2206 | + |
---|
| 2207 | +int wl_android_get_scan_channel_time(struct net_device *dev, char *command, int total_len) |
---|
| 2208 | +{ |
---|
| 2209 | + int error = 0; |
---|
| 2210 | + int bytes_written = 0; |
---|
| 2211 | + int time = 0; |
---|
| 2212 | + |
---|
| 2213 | + error = wldev_ioctl_get(dev, WLC_GET_SCAN_CHANNEL_TIME, &time, sizeof(time)); |
---|
| 2214 | + if (error) { |
---|
| 2215 | + DHD_ERROR(("wl_android_get_scan_channel_time: Failed to get Scan Channel Time," |
---|
| 2216 | + " error = %d\n", |
---|
| 2217 | + error)); |
---|
| 2218 | + return -1; |
---|
| 2219 | + } |
---|
| 2220 | + |
---|
| 2221 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANCHANNELTIME, time); |
---|
| 2222 | + |
---|
| 2223 | + return bytes_written; |
---|
| 2224 | +} |
---|
| 2225 | + |
---|
| 2226 | +int wl_android_set_scan_channel_time(struct net_device *dev, char *command) |
---|
| 2227 | +{ |
---|
| 2228 | + int error = 0; |
---|
| 2229 | + int time = 0; |
---|
| 2230 | + |
---|
| 2231 | + if (sscanf(command, "%*s %d", &time) != 1) { |
---|
| 2232 | + DHD_ERROR(("wl_android_set_scan_channel_time: Failed to get Parameter\n")); |
---|
| 2233 | + return -1; |
---|
| 2234 | + } |
---|
| 2235 | +#ifdef CUSTOMER_SCAN_TIMEOUT_SETTING |
---|
| 2236 | + wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_CHANNEL_TIME, time); |
---|
| 2237 | + error = wldev_ioctl_set(dev, WLC_SET_SCAN_CHANNEL_TIME, &time, sizeof(time)); |
---|
| 2238 | +#endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */ |
---|
| 2239 | + if (error) { |
---|
| 2240 | + DHD_ERROR(("wl_android_set_scan_channel_time: Failed to set Scan Channel Time %d," |
---|
| 2241 | + " error = %d\n", |
---|
| 2242 | + time, error)); |
---|
| 2243 | + return -1; |
---|
| 2244 | + } |
---|
| 2245 | + |
---|
| 2246 | + return 0; |
---|
| 2247 | +} |
---|
| 2248 | + |
---|
| 2249 | +int |
---|
| 2250 | +wl_android_get_scan_unassoc_time(struct net_device *dev, char *command, int total_len) |
---|
| 2251 | +{ |
---|
| 2252 | + int error = 0; |
---|
| 2253 | + int bytes_written = 0; |
---|
| 2254 | + int time = 0; |
---|
| 2255 | + |
---|
| 2256 | + error = wldev_ioctl_get(dev, WLC_GET_SCAN_UNASSOC_TIME, &time, sizeof(time)); |
---|
| 2257 | + if (error) { |
---|
| 2258 | + DHD_ERROR(("wl_android_get_scan_unassoc_time: Failed to get Scan Unassoc" |
---|
| 2259 | + " Time, error = %d\n", |
---|
| 2260 | + error)); |
---|
| 2261 | + return -1; |
---|
| 2262 | + } |
---|
| 2263 | + |
---|
| 2264 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANUNASSOCTIME, time); |
---|
| 2265 | + |
---|
| 2266 | + return bytes_written; |
---|
| 2267 | +} |
---|
| 2268 | + |
---|
| 2269 | +int |
---|
| 2270 | +wl_android_set_scan_unassoc_time(struct net_device *dev, char *command) |
---|
| 2271 | +{ |
---|
| 2272 | + int error = 0; |
---|
| 2273 | + int time = 0; |
---|
| 2274 | + |
---|
| 2275 | + if (sscanf(command, "%*s %d", &time) != 1) { |
---|
| 2276 | + DHD_ERROR(("wl_android_set_scan_unassoc_time: Failed to get Parameter\n")); |
---|
| 2277 | + return -1; |
---|
| 2278 | + } |
---|
| 2279 | +#ifdef CUSTOMER_SCAN_TIMEOUT_SETTING |
---|
| 2280 | + wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_UNASSOC_TIME, time); |
---|
| 2281 | + error = wldev_ioctl_set(dev, WLC_SET_SCAN_UNASSOC_TIME, &time, sizeof(time)); |
---|
| 2282 | +#endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */ |
---|
| 2283 | + if (error) { |
---|
| 2284 | + DHD_ERROR(("wl_android_set_scan_unassoc_time: Failed to set Scan Unassoc Time %d," |
---|
| 2285 | + " error = %d\n", |
---|
| 2286 | + time, error)); |
---|
| 2287 | + return -1; |
---|
| 2288 | + } |
---|
| 2289 | + |
---|
| 2290 | + return 0; |
---|
| 2291 | +} |
---|
| 2292 | + |
---|
| 2293 | +int |
---|
| 2294 | +wl_android_get_scan_passive_time(struct net_device *dev, char *command, int total_len) |
---|
| 2295 | +{ |
---|
| 2296 | + int error = 0; |
---|
| 2297 | + int bytes_written = 0; |
---|
| 2298 | + int time = 0; |
---|
| 2299 | + |
---|
| 2300 | + error = wldev_ioctl_get(dev, WLC_GET_SCAN_PASSIVE_TIME, &time, sizeof(time)); |
---|
| 2301 | + if (error) { |
---|
| 2302 | + DHD_ERROR(("wl_android_get_scan_passive_time: Failed to get Scan Passive Time," |
---|
| 2303 | + " error = %d\n", |
---|
| 2304 | + error)); |
---|
| 2305 | + return -1; |
---|
| 2306 | + } |
---|
| 2307 | + |
---|
| 2308 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANPASSIVETIME, time); |
---|
| 2309 | + |
---|
| 2310 | + return bytes_written; |
---|
| 2311 | +} |
---|
| 2312 | + |
---|
| 2313 | +int |
---|
| 2314 | +wl_android_set_scan_passive_time(struct net_device *dev, char *command) |
---|
| 2315 | +{ |
---|
| 2316 | + int error = 0; |
---|
| 2317 | + int time = 0; |
---|
| 2318 | + |
---|
| 2319 | + if (sscanf(command, "%*s %d", &time) != 1) { |
---|
| 2320 | + DHD_ERROR(("wl_android_set_scan_passive_time: Failed to get Parameter\n")); |
---|
| 2321 | + return -1; |
---|
| 2322 | + } |
---|
| 2323 | +#ifdef CUSTOMER_SCAN_TIMEOUT_SETTING |
---|
| 2324 | + wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_PASSIVE_TIME, time); |
---|
| 2325 | + error = wldev_ioctl_set(dev, WLC_SET_SCAN_PASSIVE_TIME, &time, sizeof(time)); |
---|
| 2326 | +#endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */ |
---|
| 2327 | + if (error) { |
---|
| 2328 | + DHD_ERROR(("wl_android_set_scan_passive_time: Failed to set Scan Passive Time %d," |
---|
| 2329 | + " error = %d\n", |
---|
| 2330 | + time, error)); |
---|
| 2331 | + return -1; |
---|
| 2332 | + } |
---|
| 2333 | + |
---|
| 2334 | + return 0; |
---|
| 2335 | +} |
---|
| 2336 | + |
---|
| 2337 | +int wl_android_get_scan_home_time(struct net_device *dev, char *command, int total_len) |
---|
| 2338 | +{ |
---|
| 2339 | + int error = 0; |
---|
| 2340 | + int bytes_written = 0; |
---|
| 2341 | + int time = 0; |
---|
| 2342 | + |
---|
| 2343 | + error = wldev_ioctl_get(dev, WLC_GET_SCAN_HOME_TIME, &time, sizeof(time)); |
---|
| 2344 | + if (error) { |
---|
| 2345 | + DHD_ERROR(("Failed to get Scan Home Time, error = %d\n", error)); |
---|
| 2346 | + return -1; |
---|
| 2347 | + } |
---|
| 2348 | + |
---|
| 2349 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANHOMETIME, time); |
---|
| 2350 | + |
---|
| 2351 | + return bytes_written; |
---|
| 2352 | +} |
---|
| 2353 | + |
---|
| 2354 | +int wl_android_set_scan_home_time(struct net_device *dev, char *command) |
---|
| 2355 | +{ |
---|
| 2356 | + int error = 0; |
---|
| 2357 | + int time = 0; |
---|
| 2358 | + |
---|
| 2359 | + if (sscanf(command, "%*s %d", &time) != 1) { |
---|
| 2360 | + DHD_ERROR(("wl_android_set_scan_home_time: Failed to get Parameter\n")); |
---|
| 2361 | + return -1; |
---|
| 2362 | + } |
---|
| 2363 | +#ifdef CUSTOMER_SCAN_TIMEOUT_SETTING |
---|
| 2364 | + wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_HOME_TIME, time); |
---|
| 2365 | + error = wldev_ioctl_set(dev, WLC_SET_SCAN_HOME_TIME, &time, sizeof(time)); |
---|
| 2366 | +#endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */ |
---|
| 2367 | + if (error) { |
---|
| 2368 | + DHD_ERROR(("wl_android_set_scan_home_time: Failed to set Scan Home Time %d," |
---|
| 2369 | + " error = %d\n", |
---|
| 2370 | + time, error)); |
---|
| 2371 | + return -1; |
---|
| 2372 | + } |
---|
| 2373 | + |
---|
| 2374 | + return 0; |
---|
| 2375 | +} |
---|
| 2376 | + |
---|
| 2377 | +int wl_android_get_scan_home_away_time(struct net_device *dev, char *command, int total_len) |
---|
| 2378 | +{ |
---|
| 2379 | + int error = 0; |
---|
| 2380 | + int bytes_written = 0; |
---|
| 2381 | + int time = 0; |
---|
| 2382 | + |
---|
| 2383 | + error = wldev_iovar_getint(dev, "scan_home_away_time", &time); |
---|
| 2384 | + if (error) { |
---|
| 2385 | + DHD_ERROR(("wl_android_get_scan_home_away_time: Failed to get Scan Home Away Time," |
---|
| 2386 | + " error = %d\n", |
---|
| 2387 | + error)); |
---|
| 2388 | + return -1; |
---|
| 2389 | + } |
---|
| 2390 | + |
---|
| 2391 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANHOMEAWAYTIME, time); |
---|
| 2392 | + |
---|
| 2393 | + return bytes_written; |
---|
| 2394 | +} |
---|
| 2395 | + |
---|
| 2396 | +int wl_android_set_scan_home_away_time(struct net_device *dev, char *command) |
---|
| 2397 | +{ |
---|
| 2398 | + int error = 0; |
---|
| 2399 | + int time = 0; |
---|
| 2400 | + |
---|
| 2401 | + if (sscanf(command, "%*s %d", &time) != 1) { |
---|
| 2402 | + DHD_ERROR(("wl_android_set_scan_home_away_time: Failed to get Parameter\n")); |
---|
| 2403 | + return -1; |
---|
| 2404 | + } |
---|
| 2405 | +#ifdef CUSTOMER_SCAN_TIMEOUT_SETTING |
---|
| 2406 | + wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_HOME_AWAY_TIME, time); |
---|
| 2407 | + error = wldev_iovar_setint(dev, "scan_home_away_time", time); |
---|
| 2408 | +#endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */ |
---|
| 2409 | + if (error) { |
---|
| 2410 | + DHD_ERROR(("wl_android_set_scan_home_away_time: Failed to set Scan Home Away" |
---|
| 2411 | + " Time %d, error = %d\n", |
---|
| 2412 | + time, error)); |
---|
| 2413 | + return -1; |
---|
| 2414 | + } |
---|
| 2415 | + |
---|
| 2416 | + return 0; |
---|
| 2417 | +} |
---|
| 2418 | + |
---|
| 2419 | +int wl_android_get_scan_nprobes(struct net_device *dev, char *command, int total_len) |
---|
| 2420 | +{ |
---|
| 2421 | + int error = 0; |
---|
| 2422 | + int bytes_written = 0; |
---|
| 2423 | + int num = 0; |
---|
| 2424 | + |
---|
| 2425 | + error = wldev_ioctl_get(dev, WLC_GET_SCAN_NPROBES, &num, sizeof(num)); |
---|
| 2426 | + if (error) { |
---|
| 2427 | + DHD_ERROR(("wl_android_get_scan_nprobes: Failed to get Scan NProbes," |
---|
| 2428 | + " error = %d\n", error)); |
---|
| 2429 | + return -1; |
---|
| 2430 | + } |
---|
| 2431 | + |
---|
| 2432 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETSCANNPROBES, num); |
---|
| 2433 | + |
---|
| 2434 | + return bytes_written; |
---|
| 2435 | +} |
---|
| 2436 | + |
---|
| 2437 | +int wl_android_set_scan_nprobes(struct net_device *dev, char *command) |
---|
| 2438 | +{ |
---|
| 2439 | + int error = 0; |
---|
| 2440 | + int num = 0; |
---|
| 2441 | + |
---|
| 2442 | + if (sscanf(command, "%*s %d", &num) != 1) { |
---|
| 2443 | + DHD_ERROR(("wl_android_set_scan_nprobes: Failed to get Parameter\n")); |
---|
| 2444 | + return -1; |
---|
| 2445 | + } |
---|
| 2446 | + |
---|
| 2447 | + error = wldev_ioctl_set(dev, WLC_SET_SCAN_NPROBES, &num, sizeof(num)); |
---|
| 2448 | + if (error) { |
---|
| 2449 | + DHD_ERROR(("wl_android_set_scan_nprobes: Failed to set Scan NProbes %d," |
---|
| 2450 | + " error = %d\n", |
---|
| 2451 | + num, error)); |
---|
| 2452 | + return -1; |
---|
| 2453 | + } |
---|
| 2454 | + |
---|
| 2455 | + return 0; |
---|
| 2456 | +} |
---|
| 2457 | + |
---|
| 2458 | +int wl_android_get_scan_dfs_channel_mode(struct net_device *dev, char *command, int total_len) |
---|
| 2459 | +{ |
---|
| 2460 | + int error = 0; |
---|
| 2461 | + int bytes_written = 0; |
---|
| 2462 | + int mode = 0; |
---|
| 2463 | + int scan_passive_time = 0; |
---|
| 2464 | + |
---|
| 2465 | + error = wldev_iovar_getint(dev, "scan_passive_time", &scan_passive_time); |
---|
| 2466 | + if (error) { |
---|
| 2467 | + DHD_ERROR(("wl_android_get_scan_dfs_channel_mode: Failed to get Passive Time," |
---|
| 2468 | + " error = %d\n", error)); |
---|
| 2469 | + return -1; |
---|
| 2470 | + } |
---|
| 2471 | + |
---|
| 2472 | + if (scan_passive_time == 0) { |
---|
| 2473 | + mode = 0; |
---|
| 2474 | + } else { |
---|
| 2475 | + mode = 1; |
---|
| 2476 | + } |
---|
| 2477 | + |
---|
| 2478 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETDFSSCANMODE, mode); |
---|
| 2479 | + |
---|
| 2480 | + return bytes_written; |
---|
| 2481 | +} |
---|
| 2482 | + |
---|
| 2483 | +int wl_android_set_scan_dfs_channel_mode(struct net_device *dev, char *command) |
---|
| 2484 | +{ |
---|
| 2485 | + int error = 0; |
---|
| 2486 | + int mode = 0; |
---|
| 2487 | + int scan_passive_time = 0; |
---|
| 2488 | + |
---|
| 2489 | + if (sscanf(command, "%*s %d", &mode) != 1) { |
---|
| 2490 | + DHD_ERROR(("wl_android_set_scan_dfs_channel_mode: Failed to get Parameter\n")); |
---|
| 2491 | + return -1; |
---|
| 2492 | + } |
---|
| 2493 | + |
---|
| 2494 | + if (mode == 1) { |
---|
| 2495 | + scan_passive_time = DHD_SCAN_PASSIVE_TIME; |
---|
| 2496 | + } else if (mode == 0) { |
---|
| 2497 | + scan_passive_time = 0; |
---|
| 2498 | + } else { |
---|
| 2499 | + DHD_ERROR(("wl_android_set_scan_dfs_channel_mode: Failed to set Scan DFS" |
---|
| 2500 | + " channel mode %d, error = %d\n", |
---|
| 2501 | + mode, error)); |
---|
| 2502 | + return -1; |
---|
| 2503 | + } |
---|
| 2504 | + error = wldev_iovar_setint(dev, "scan_passive_time", scan_passive_time); |
---|
| 2505 | + if (error) { |
---|
| 2506 | + DHD_ERROR(("wl_android_set_scan_dfs_channel_mode: Failed to set Scan" |
---|
| 2507 | + " Passive Time %d, error = %d\n", |
---|
| 2508 | + scan_passive_time, error)); |
---|
| 2509 | + return -1; |
---|
| 2510 | + } |
---|
| 2511 | + |
---|
| 2512 | + return 0; |
---|
| 2513 | +} |
---|
| 2514 | + |
---|
| 2515 | +#define JOINPREFFER_BUF_SIZE 12 |
---|
| 2516 | + |
---|
| 2517 | +static int |
---|
| 2518 | +wl_android_set_join_prefer(struct net_device *dev, char *command) |
---|
| 2519 | +{ |
---|
| 2520 | + int error = BCME_OK; |
---|
| 2521 | + char smbuf[WLC_IOCTL_SMLEN]; |
---|
| 2522 | + uint8 buf[JOINPREFFER_BUF_SIZE]; |
---|
| 2523 | + char *pcmd; |
---|
| 2524 | + int total_len_left; |
---|
| 2525 | + int i; |
---|
| 2526 | + char hex[] = "XX"; |
---|
| 2527 | +#ifdef WBTEXT |
---|
| 2528 | + char commandp[WLC_IOCTL_SMLEN]; |
---|
| 2529 | + char clear[] = { 0x01, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00 }; |
---|
| 2530 | +#endif /* WBTEXT */ |
---|
| 2531 | + |
---|
| 2532 | + pcmd = command + strlen(CMD_SETJOINPREFER) + 1; |
---|
| 2533 | + total_len_left = strlen(pcmd); |
---|
| 2534 | + |
---|
| 2535 | + bzero(buf, sizeof(buf)); |
---|
| 2536 | + |
---|
| 2537 | + if (total_len_left != JOINPREFFER_BUF_SIZE << 1) { |
---|
| 2538 | + DHD_ERROR(("wl_android_set_join_prefer: Failed to get Parameter\n")); |
---|
| 2539 | + return BCME_ERROR; |
---|
| 2540 | + } |
---|
| 2541 | + |
---|
| 2542 | + /* Store the MSB first, as required by join_pref */ |
---|
| 2543 | + for (i = 0; i < JOINPREFFER_BUF_SIZE; i++) { |
---|
| 2544 | + hex[0] = *pcmd++; |
---|
| 2545 | + hex[1] = *pcmd++; |
---|
| 2546 | + buf[i] = (uint8)simple_strtoul(hex, NULL, 16); |
---|
| 2547 | + } |
---|
| 2548 | + |
---|
| 2549 | +#ifdef WBTEXT |
---|
| 2550 | + /* No coexistance between 11kv and join pref */ |
---|
| 2551 | + if (wl_android_check_wbtext(dev)) { |
---|
| 2552 | + bzero(commandp, sizeof(commandp)); |
---|
| 2553 | + if (memcmp(buf, clear, sizeof(buf)) == 0) { |
---|
| 2554 | + snprintf(commandp, WLC_IOCTL_SMLEN, "WBTEXT_ENABLE 1"); |
---|
| 2555 | + } else { |
---|
| 2556 | + snprintf(commandp, WLC_IOCTL_SMLEN, "WBTEXT_ENABLE 0"); |
---|
| 2557 | + } |
---|
| 2558 | + if ((error = wl_android_wbtext(dev, commandp, WLC_IOCTL_SMLEN)) != BCME_OK) { |
---|
| 2559 | + DHD_ERROR(("Failed to set WBTEXT = %d\n", error)); |
---|
| 2560 | + return error; |
---|
| 2561 | + } |
---|
| 2562 | + } |
---|
| 2563 | +#endif /* WBTEXT */ |
---|
| 2564 | + |
---|
| 2565 | + prhex("join pref", (uint8 *)buf, JOINPREFFER_BUF_SIZE); |
---|
| 2566 | + error = wldev_iovar_setbuf(dev, "join_pref", buf, JOINPREFFER_BUF_SIZE, |
---|
| 2567 | + smbuf, sizeof(smbuf), NULL); |
---|
| 2568 | + if (error) { |
---|
| 2569 | + DHD_ERROR(("Failed to set join_pref, error = %d\n", error)); |
---|
| 2570 | + } |
---|
| 2571 | + |
---|
| 2572 | + return error; |
---|
| 2573 | +} |
---|
| 2574 | + |
---|
| 2575 | +int wl_android_send_action_frame(struct net_device *dev, char *command, int total_len) |
---|
| 2576 | +{ |
---|
| 2577 | + int error = -1; |
---|
| 2578 | + android_wifi_af_params_t *params = NULL; |
---|
| 2579 | + wl_action_frame_t *action_frame = NULL; |
---|
| 2580 | + wl_af_params_t *af_params = NULL; |
---|
| 2581 | + char *smbuf = NULL; |
---|
| 2582 | + struct ether_addr tmp_bssid; |
---|
| 2583 | + int tmp_channel = 0; |
---|
| 2584 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 2585 | + |
---|
| 2586 | + if (total_len < |
---|
| 2587 | + (strlen(CMD_SENDACTIONFRAME) + 1 + sizeof(android_wifi_af_params_t))) { |
---|
| 2588 | + DHD_ERROR(("wl_android_send_action_frame: Invalid parameters \n")); |
---|
| 2589 | + goto send_action_frame_out; |
---|
| 2590 | + } |
---|
| 2591 | + |
---|
| 2592 | + params = (android_wifi_af_params_t *)(command + strlen(CMD_SENDACTIONFRAME) + 1); |
---|
| 2593 | + |
---|
| 2594 | + if ((uint16)params->len > ANDROID_WIFI_ACTION_FRAME_SIZE) { |
---|
| 2595 | + DHD_ERROR(("wl_android_send_action_frame: Requested action frame len" |
---|
| 2596 | + " was out of range(%d)\n", |
---|
| 2597 | + params->len)); |
---|
| 2598 | + goto send_action_frame_out; |
---|
| 2599 | + } |
---|
| 2600 | + |
---|
| 2601 | + smbuf = (char *)MALLOC(cfg->osh, WLC_IOCTL_MAXLEN); |
---|
| 2602 | + if (smbuf == NULL) { |
---|
| 2603 | + DHD_ERROR(("wl_android_send_action_frame: failed to allocated memory %d bytes\n", |
---|
| 2604 | + WLC_IOCTL_MAXLEN)); |
---|
| 2605 | + goto send_action_frame_out; |
---|
| 2606 | + } |
---|
| 2607 | + |
---|
| 2608 | + af_params = (wl_af_params_t *)MALLOCZ(cfg->osh, WL_WIFI_AF_PARAMS_SIZE); |
---|
| 2609 | + if (af_params == NULL) { |
---|
| 2610 | + DHD_ERROR(("wl_android_send_action_frame: unable to allocate frame\n")); |
---|
| 2611 | + goto send_action_frame_out; |
---|
| 2612 | + } |
---|
| 2613 | + |
---|
| 2614 | + bzero(&tmp_bssid, ETHER_ADDR_LEN); |
---|
| 2615 | + if (bcm_ether_atoe((const char *)params->bssid, (struct ether_addr *)&tmp_bssid) == 0) { |
---|
| 2616 | + bzero(&tmp_bssid, ETHER_ADDR_LEN); |
---|
| 2617 | + |
---|
| 2618 | + error = wldev_ioctl_get(dev, WLC_GET_BSSID, &tmp_bssid, ETHER_ADDR_LEN); |
---|
| 2619 | + if (error) { |
---|
| 2620 | + bzero(&tmp_bssid, ETHER_ADDR_LEN); |
---|
| 2621 | + DHD_ERROR(("wl_android_send_action_frame: failed to get bssid," |
---|
| 2622 | + " error=%d\n", error)); |
---|
| 2623 | + goto send_action_frame_out; |
---|
| 2624 | + } |
---|
| 2625 | + } |
---|
| 2626 | + |
---|
| 2627 | + if (params->channel < 0) { |
---|
| 2628 | + struct channel_info ci; |
---|
| 2629 | + bzero(&ci, sizeof(ci)); |
---|
| 2630 | + error = wldev_ioctl_get(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)); |
---|
| 2631 | + if (error) { |
---|
| 2632 | + DHD_ERROR(("wl_android_send_action_frame: failed to get channel," |
---|
| 2633 | + " error=%d\n", error)); |
---|
| 2634 | + goto send_action_frame_out; |
---|
| 2635 | + } |
---|
| 2636 | + |
---|
| 2637 | + tmp_channel = ci.hw_channel; |
---|
| 2638 | + } |
---|
| 2639 | + else { |
---|
| 2640 | + tmp_channel = params->channel; |
---|
| 2641 | + } |
---|
| 2642 | + |
---|
| 2643 | + af_params->channel = tmp_channel; |
---|
| 2644 | + af_params->dwell_time = params->dwell_time; |
---|
| 2645 | + memcpy(&af_params->BSSID, &tmp_bssid, ETHER_ADDR_LEN); |
---|
| 2646 | + action_frame = &af_params->action_frame; |
---|
| 2647 | + |
---|
| 2648 | + action_frame->packetId = 0; |
---|
| 2649 | + memcpy(&action_frame->da, &tmp_bssid, ETHER_ADDR_LEN); |
---|
| 2650 | + action_frame->len = (uint16)params->len; |
---|
| 2651 | + memcpy(action_frame->data, params->data, action_frame->len); |
---|
| 2652 | + |
---|
| 2653 | + error = wldev_iovar_setbuf(dev, "actframe", af_params, |
---|
| 2654 | + sizeof(wl_af_params_t), smbuf, WLC_IOCTL_MAXLEN, NULL); |
---|
| 2655 | + if (error) { |
---|
| 2656 | + DHD_ERROR(("wl_android_send_action_frame: failed to set action frame," |
---|
| 2657 | + " error=%d\n", error)); |
---|
| 2658 | + } |
---|
| 2659 | + |
---|
| 2660 | +send_action_frame_out: |
---|
| 2661 | + if (af_params) { |
---|
| 2662 | + MFREE(cfg->osh, af_params, WL_WIFI_AF_PARAMS_SIZE); |
---|
| 2663 | + } |
---|
| 2664 | + |
---|
| 2665 | + if (smbuf) { |
---|
| 2666 | + MFREE(cfg->osh, smbuf, WLC_IOCTL_MAXLEN); |
---|
| 2667 | + } |
---|
| 2668 | + |
---|
| 2669 | + if (error) |
---|
| 2670 | + return -1; |
---|
| 2671 | + else |
---|
| 2672 | + return 0; |
---|
| 2673 | +} |
---|
| 2674 | + |
---|
| 2675 | +int wl_android_reassoc(struct net_device *dev, char *command, int total_len) |
---|
| 2676 | +{ |
---|
| 2677 | + int error = 0; |
---|
| 2678 | + android_wifi_reassoc_params_t *params = NULL; |
---|
| 2679 | + uint band; |
---|
| 2680 | + chanspec_t channel; |
---|
| 2681 | + u32 params_size; |
---|
| 2682 | + wl_reassoc_params_t reassoc_params; |
---|
| 2683 | + |
---|
| 2684 | + if (total_len < |
---|
| 2685 | + (strlen(CMD_REASSOC) + 1 + sizeof(android_wifi_reassoc_params_t))) { |
---|
| 2686 | + DHD_ERROR(("wl_android_reassoc: Invalid parameters \n")); |
---|
| 2687 | + return -1; |
---|
| 2688 | + } |
---|
| 2689 | + params = (android_wifi_reassoc_params_t *)(command + strlen(CMD_REASSOC) + 1); |
---|
| 2690 | + |
---|
| 2691 | + bzero(&reassoc_params, WL_REASSOC_PARAMS_FIXED_SIZE); |
---|
| 2692 | + |
---|
| 2693 | + if (bcm_ether_atoe((const char *)params->bssid, |
---|
| 2694 | + (struct ether_addr *)&reassoc_params.bssid) == 0) { |
---|
| 2695 | + DHD_ERROR(("wl_android_reassoc: Invalid bssid \n")); |
---|
| 2696 | + return -1; |
---|
| 2697 | + } |
---|
| 2698 | + |
---|
| 2699 | + if (params->channel < 0) { |
---|
| 2700 | + DHD_ERROR(("wl_android_reassoc: Invalid Channel \n")); |
---|
| 2701 | + return -1; |
---|
| 2702 | + } |
---|
| 2703 | + |
---|
| 2704 | + reassoc_params.chanspec_num = 1; |
---|
| 2705 | + |
---|
| 2706 | + channel = params->channel; |
---|
| 2707 | +#ifdef D11AC_IOTYPES |
---|
| 2708 | + if (wl_cfg80211_get_ioctl_version() == 1) { |
---|
| 2709 | + band = ((channel <= CH_MAX_2G_CHANNEL) ? |
---|
| 2710 | + WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G); |
---|
| 2711 | + reassoc_params.chanspec_list[0] = channel | |
---|
| 2712 | + band | WL_LCHANSPEC_BW_20 | WL_LCHANSPEC_CTL_SB_NONE; |
---|
| 2713 | + } |
---|
| 2714 | + else { |
---|
| 2715 | + band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); |
---|
| 2716 | + reassoc_params.chanspec_list[0] = channel | band | WL_CHANSPEC_BW_20; |
---|
| 2717 | + } |
---|
| 2718 | +#else |
---|
| 2719 | + band = ((channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G); |
---|
| 2720 | + reassoc_params.chanspec_list[0] = channel | |
---|
| 2721 | + band | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; |
---|
| 2722 | +#endif /* D11AC_IOTYPES */ |
---|
| 2723 | + params_size = WL_REASSOC_PARAMS_FIXED_SIZE + sizeof(chanspec_t); |
---|
| 2724 | + |
---|
| 2725 | + error = wldev_ioctl_set(dev, WLC_REASSOC, &reassoc_params, params_size); |
---|
| 2726 | + if (error) { |
---|
| 2727 | + DHD_ERROR(("wl_android_reassoc: failed to reassoc, error=%d\n", error)); |
---|
| 2728 | + return -1; |
---|
| 2729 | + } |
---|
| 2730 | + return 0; |
---|
| 2731 | +} |
---|
| 2732 | + |
---|
| 2733 | +int wl_android_get_wes_mode(struct net_device *dev, char *command, int total_len) |
---|
| 2734 | +{ |
---|
| 2735 | + int bytes_written = 0; |
---|
| 2736 | + int mode = 0; |
---|
| 2737 | + |
---|
| 2738 | + mode = wl_cfg80211_get_wes_mode(); |
---|
| 2739 | + |
---|
| 2740 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETWESMODE, mode); |
---|
| 2741 | + |
---|
| 2742 | + return bytes_written; |
---|
| 2743 | +} |
---|
| 2744 | + |
---|
| 2745 | +int wl_android_set_wes_mode(struct net_device *dev, char *command) |
---|
| 2746 | +{ |
---|
| 2747 | + int error = 0; |
---|
| 2748 | + int mode = 0; |
---|
| 2749 | +#ifdef WBTEXT |
---|
| 2750 | + char commandp[WLC_IOCTL_SMLEN]; |
---|
| 2751 | +#endif /* WBTEXT */ |
---|
| 2752 | + |
---|
| 2753 | + if (sscanf(command, "%*s %d", &mode) != 1) { |
---|
| 2754 | + DHD_ERROR(("wl_android_set_wes_mode: Failed to get Parameter\n")); |
---|
| 2755 | + return -1; |
---|
| 2756 | + } |
---|
| 2757 | + |
---|
| 2758 | + error = wl_cfg80211_set_wes_mode(mode); |
---|
| 2759 | + if (error) { |
---|
| 2760 | + DHD_ERROR(("wl_android_set_wes_mode: Failed to set WES Mode %d, error = %d\n", |
---|
| 2761 | + mode, error)); |
---|
| 2762 | + return -1; |
---|
| 2763 | + } |
---|
| 2764 | + |
---|
| 2765 | +#ifdef WBTEXT |
---|
| 2766 | + /* No coexistance between 11kv and FMC */ |
---|
| 2767 | + if (wl_android_check_wbtext(dev)) { |
---|
| 2768 | + bzero(commandp, sizeof(commandp)); |
---|
| 2769 | + if (!mode) { |
---|
| 2770 | + snprintf(commandp, WLC_IOCTL_SMLEN, "WBTEXT_ENABLE 1"); |
---|
| 2771 | + } else { |
---|
| 2772 | + snprintf(commandp, WLC_IOCTL_SMLEN, "WBTEXT_ENABLE 0"); |
---|
| 2773 | + } |
---|
| 2774 | + if ((error = wl_android_wbtext(dev, commandp, WLC_IOCTL_SMLEN)) != BCME_OK) { |
---|
| 2775 | + DHD_ERROR(("Failed to set WBTEXT = %d\n", error)); |
---|
| 2776 | + return error; |
---|
| 2777 | + } |
---|
| 2778 | + } |
---|
| 2779 | +#endif /* WBTEXT */ |
---|
| 2780 | + |
---|
| 2781 | + return 0; |
---|
| 2782 | +} |
---|
| 2783 | + |
---|
| 2784 | +int wl_android_get_okc_mode(struct net_device *dev, char *command, int total_len) |
---|
| 2785 | +{ |
---|
| 2786 | + int error = 0; |
---|
| 2787 | + int bytes_written = 0; |
---|
| 2788 | + int mode = 0; |
---|
| 2789 | + |
---|
| 2790 | + error = wldev_iovar_getint(dev, "okc_enable", &mode); |
---|
| 2791 | + if (error) { |
---|
| 2792 | + DHD_ERROR(("wl_android_get_okc_mode: Failed to get OKC Mode, error = %d\n", error)); |
---|
| 2793 | + return -1; |
---|
| 2794 | + } |
---|
| 2795 | + |
---|
| 2796 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GETOKCMODE, mode); |
---|
| 2797 | + |
---|
| 2798 | + return bytes_written; |
---|
| 2799 | +} |
---|
| 2800 | + |
---|
| 2801 | +int wl_android_set_okc_mode(struct net_device *dev, char *command) |
---|
| 2802 | +{ |
---|
| 2803 | + int error = 0; |
---|
| 2804 | + int mode = 0; |
---|
| 2805 | + |
---|
| 2806 | + if (sscanf(command, "%*s %d", &mode) != 1) { |
---|
| 2807 | + DHD_ERROR(("wl_android_set_okc_mode: Failed to get Parameter\n")); |
---|
| 2808 | + return -1; |
---|
| 2809 | + } |
---|
| 2810 | + |
---|
| 2811 | + error = wldev_iovar_setint(dev, "okc_enable", mode); |
---|
| 2812 | + if (error) { |
---|
| 2813 | + DHD_ERROR(("wl_android_set_okc_mode: Failed to set OKC Mode %d, error = %d\n", |
---|
| 2814 | + mode, error)); |
---|
| 2815 | + return -1; |
---|
| 2816 | + } |
---|
| 2817 | + |
---|
| 2818 | + return error; |
---|
| 2819 | +} |
---|
| 2820 | +static int |
---|
| 2821 | +wl_android_set_pmk(struct net_device *dev, char *command, int total_len) |
---|
| 2822 | +{ |
---|
| 2823 | + uchar pmk[33]; |
---|
| 2824 | + int error = 0; |
---|
| 2825 | + char smbuf[WLC_IOCTL_SMLEN]; |
---|
| 2826 | + dhd_pub_t *dhdp; |
---|
| 2827 | +#ifdef OKC_DEBUG |
---|
| 2828 | + int i = 0; |
---|
| 2829 | +#endif // endif |
---|
| 2830 | + |
---|
| 2831 | + if (total_len < (strlen("SET_PMK ") + 32)) { |
---|
| 2832 | + DHD_ERROR(("wl_android_set_pmk: Invalid argument\n")); |
---|
| 2833 | + return -1; |
---|
| 2834 | + } |
---|
| 2835 | + |
---|
| 2836 | + dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 2837 | + if (!dhdp) { |
---|
| 2838 | + DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__)); |
---|
| 2839 | + return -1; |
---|
| 2840 | + } |
---|
| 2841 | + |
---|
| 2842 | + bzero(pmk, sizeof(pmk)); |
---|
| 2843 | + DHD_STATLOG_CTRL(dhdp, ST(INSTALL_OKC_PMK), dhd_net2idx(dhdp->info, dev), 0); |
---|
| 2844 | + memcpy((char *)pmk, command + strlen("SET_PMK "), 32); |
---|
| 2845 | + error = wldev_iovar_setbuf(dev, "okc_info_pmk", pmk, 32, smbuf, sizeof(smbuf), NULL); |
---|
| 2846 | + if (error) { |
---|
| 2847 | + DHD_ERROR(("Failed to set PMK for OKC, error = %d\n", error)); |
---|
| 2848 | + } |
---|
| 2849 | +#ifdef OKC_DEBUG |
---|
| 2850 | + DHD_ERROR(("PMK is ")); |
---|
| 2851 | + for (i = 0; i < 32; i++) |
---|
| 2852 | + DHD_ERROR(("%02X ", pmk[i])); |
---|
| 2853 | + |
---|
| 2854 | + DHD_ERROR(("\n")); |
---|
| 2855 | +#endif // endif |
---|
| 2856 | + return error; |
---|
| 2857 | +} |
---|
| 2858 | + |
---|
| 2859 | +static int |
---|
| 2860 | +wl_android_okc_enable(struct net_device *dev, char *command) |
---|
| 2861 | +{ |
---|
| 2862 | + int error = 0; |
---|
| 2863 | + char okc_enable = 0; |
---|
| 2864 | + |
---|
| 2865 | + okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0'; |
---|
| 2866 | + error = wldev_iovar_setint(dev, "okc_enable", okc_enable); |
---|
| 2867 | + if (error) { |
---|
| 2868 | + DHD_ERROR(("Failed to %s OKC, error = %d\n", |
---|
| 2869 | + okc_enable ? "enable" : "disable", error)); |
---|
| 2870 | + } |
---|
| 2871 | + |
---|
| 2872 | + return error; |
---|
| 2873 | +} |
---|
| 2874 | +#endif /* WES_SUPPORT */ |
---|
| 2875 | + |
---|
| 2876 | +#ifdef SUPPORT_RESTORE_SCAN_PARAMS |
---|
| 2877 | + static int |
---|
| 2878 | +wl_android_restore_scan_params(struct net_device *dev, char *command, int total_len) |
---|
| 2879 | +{ |
---|
| 2880 | + int error = 0; |
---|
| 2881 | + uint error_cnt = 0; |
---|
| 2882 | + int cnt = 0; |
---|
| 2883 | + char restore_command[WLC_IOCTL_SMLEN]; |
---|
| 2884 | + |
---|
| 2885 | + while (strlen(restore_params[cnt].command) > 0 && restore_params[cnt].cmd_handler) { |
---|
| 2886 | + sprintf(restore_command, "%s %d", restore_params[cnt].command, |
---|
| 2887 | + restore_params[cnt].parameter); |
---|
| 2888 | + if (restore_params[cnt].cmd_type == RESTORE_TYPE_PRIV_CMD) { |
---|
| 2889 | + error = restore_params[cnt].cmd_handler(dev, restore_command); |
---|
| 2890 | + } else if (restore_params[cnt].cmd_type == RESTORE_TYPE_PRIV_CMD_WITH_LEN) { |
---|
| 2891 | + error = restore_params[cnt].cmd_handler_w_len(dev, |
---|
| 2892 | + restore_command, total_len); |
---|
| 2893 | + } else { |
---|
| 2894 | + DHD_ERROR(("Unknown restore command handler\n")); |
---|
| 2895 | + error = -1; |
---|
| 2896 | + } |
---|
| 2897 | + if (error) { |
---|
| 2898 | + DHD_ERROR(("Failed to restore scan parameters %s, error : %d\n", |
---|
| 2899 | + restore_command, error)); |
---|
| 2900 | + error_cnt++; |
---|
| 2901 | + } |
---|
| 2902 | + cnt++; |
---|
| 2903 | + } |
---|
| 2904 | + if (error_cnt > 0) { |
---|
| 2905 | + DHD_ERROR(("Got %d error(s) while restoring scan parameters\n", |
---|
| 2906 | + error_cnt)); |
---|
| 2907 | + error = -1; |
---|
660 | 2908 | } |
---|
661 | 2909 | return error; |
---|
662 | 2910 | } |
---|
| 2911 | +#endif /* SUPPORT_RESTORE_SCAN_PARAMS */ |
---|
| 2912 | + |
---|
| 2913 | +#ifdef WLTDLS |
---|
| 2914 | +int wl_android_tdls_reset(struct net_device *dev) |
---|
| 2915 | +{ |
---|
| 2916 | + int ret = 0; |
---|
| 2917 | + ret = dhd_tdls_enable(dev, false, false, NULL); |
---|
| 2918 | + if (ret < 0) { |
---|
| 2919 | + DHD_ERROR(("Disable tdls failed. %d\n", ret)); |
---|
| 2920 | + return ret; |
---|
| 2921 | + } |
---|
| 2922 | + ret = dhd_tdls_enable(dev, true, true, NULL); |
---|
| 2923 | + if (ret < 0) { |
---|
| 2924 | + DHD_ERROR(("enable tdls failed. %d\n", ret)); |
---|
| 2925 | + return ret; |
---|
| 2926 | + } |
---|
| 2927 | + return 0; |
---|
| 2928 | +} |
---|
| 2929 | +#endif /* WLTDLS */ |
---|
| 2930 | + |
---|
| 2931 | +#ifdef CONFIG_SILENT_ROAM |
---|
| 2932 | +int |
---|
| 2933 | +wl_android_sroam_turn_on(struct net_device *dev, const char* turn) |
---|
| 2934 | +{ |
---|
| 2935 | + int ret = BCME_OK, sroam_mode; |
---|
| 2936 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 2937 | + |
---|
| 2938 | + sroam_mode = bcm_atoi(turn); |
---|
| 2939 | + dhdp->sroam_turn_on = sroam_mode; |
---|
| 2940 | + DHD_INFO(("%s Silent mode %s\n", __FUNCTION__, |
---|
| 2941 | + sroam_mode ? "enable" : "disable")); |
---|
| 2942 | + |
---|
| 2943 | + if (!sroam_mode) { |
---|
| 2944 | + ret = dhd_sroam_set_mon(dhdp, FALSE); |
---|
| 2945 | + if (ret) { |
---|
| 2946 | + DHD_ERROR(("%s Failed to Set sroam %d\n", |
---|
| 2947 | + __FUNCTION__, ret)); |
---|
| 2948 | + } |
---|
| 2949 | + } |
---|
| 2950 | + |
---|
| 2951 | + return ret; |
---|
| 2952 | +} |
---|
| 2953 | + |
---|
| 2954 | +int |
---|
| 2955 | +wl_android_sroam_set_info(struct net_device *dev, char *data, |
---|
| 2956 | + char *command, int total_len) |
---|
| 2957 | +{ |
---|
| 2958 | + int ret = BCME_OK; |
---|
| 2959 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 2960 | + size_t slen = strlen(data); |
---|
| 2961 | + u8 ioctl_buf[WLC_IOCTL_SMLEN]; |
---|
| 2962 | + wlc_sroam_t *psroam; |
---|
| 2963 | + wlc_sroam_info_t *sroam; |
---|
| 2964 | + uint sroamlen = sizeof(*sroam) + SROAM_HDRLEN; |
---|
| 2965 | + |
---|
| 2966 | + data[slen] = '\0'; |
---|
| 2967 | + psroam = (wlc_sroam_t *)MALLOCZ(dhdp->osh, sroamlen); |
---|
| 2968 | + if (!psroam) { |
---|
| 2969 | + WL_ERR(("%s Fail to malloc buffer\n", __FUNCTION__)); |
---|
| 2970 | + ret = BCME_NOMEM; |
---|
| 2971 | + goto done; |
---|
| 2972 | + } |
---|
| 2973 | + |
---|
| 2974 | + psroam->ver = WLC_SILENT_ROAM_CUR_VER; |
---|
| 2975 | + psroam->len = sizeof(*sroam); |
---|
| 2976 | + sroam = (wlc_sroam_info_t *)psroam->data; |
---|
| 2977 | + |
---|
| 2978 | + sroam->sroam_on = FALSE; |
---|
| 2979 | + if (*data && *data != '\0') { |
---|
| 2980 | + sroam->sroam_min_rssi = simple_strtol(data, &data, 10); |
---|
| 2981 | + WL_DBG(("1.Minimum RSSI %d\n", sroam->sroam_min_rssi)); |
---|
| 2982 | + data++; |
---|
| 2983 | + } |
---|
| 2984 | + if (*data && *data != '\0') { |
---|
| 2985 | + sroam->sroam_rssi_range = simple_strtol(data, &data, 10); |
---|
| 2986 | + WL_DBG(("2.RSSI Range %d\n", sroam->sroam_rssi_range)); |
---|
| 2987 | + data++; |
---|
| 2988 | + } |
---|
| 2989 | + if (*data && *data != '\0') { |
---|
| 2990 | + sroam->sroam_score_delta = simple_strtol(data, &data, 10); |
---|
| 2991 | + WL_DBG(("3.Score Delta %d\n", sroam->sroam_score_delta)); |
---|
| 2992 | + data++; |
---|
| 2993 | + } |
---|
| 2994 | + if (*data && *data != '\0') { |
---|
| 2995 | + sroam->sroam_period_time = simple_strtol(data, &data, 10); |
---|
| 2996 | + WL_DBG(("4.Sroam period %d\n", sroam->sroam_period_time)); |
---|
| 2997 | + data++; |
---|
| 2998 | + } |
---|
| 2999 | + if (*data && *data != '\0') { |
---|
| 3000 | + sroam->sroam_band = simple_strtol(data, &data, 10); |
---|
| 3001 | + WL_DBG(("5.Sroam Band %d\n", sroam->sroam_band)); |
---|
| 3002 | + data++; |
---|
| 3003 | + } |
---|
| 3004 | + if (*data && *data != '\0') { |
---|
| 3005 | + sroam->sroam_inact_cnt = simple_strtol(data, &data, 10); |
---|
| 3006 | + WL_DBG(("6.Inactivity Count %d\n", sroam->sroam_inact_cnt)); |
---|
| 3007 | + data++; |
---|
| 3008 | + } |
---|
| 3009 | + |
---|
| 3010 | + if (*data != '\0') { |
---|
| 3011 | + ret = BCME_BADARG; |
---|
| 3012 | + goto done; |
---|
| 3013 | + } |
---|
| 3014 | + |
---|
| 3015 | + ret = wldev_iovar_setbuf(dev, "sroam", psroam, sroamlen, ioctl_buf, |
---|
| 3016 | + sizeof(ioctl_buf), NULL); |
---|
| 3017 | + if (ret) { |
---|
| 3018 | + WL_ERR(("Failed to set silent roam info(%d)\n", ret)); |
---|
| 3019 | + goto done; |
---|
| 3020 | + } |
---|
| 3021 | +done: |
---|
| 3022 | + if (psroam) { |
---|
| 3023 | + MFREE(dhdp->osh, psroam, sroamlen); |
---|
| 3024 | + } |
---|
| 3025 | + |
---|
| 3026 | + return ret; |
---|
| 3027 | +} |
---|
| 3028 | + |
---|
| 3029 | +int |
---|
| 3030 | +wl_android_sroam_get_info(struct net_device *dev, char *command, int total_len) |
---|
| 3031 | +{ |
---|
| 3032 | + int ret = BCME_OK; |
---|
| 3033 | + int bytes_written = 0; |
---|
| 3034 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 3035 | + wlc_sroam_t *psroam; |
---|
| 3036 | + wlc_sroam_info_t *sroam; |
---|
| 3037 | + uint sroamlen = sizeof(*sroam) + SROAM_HDRLEN; |
---|
| 3038 | + |
---|
| 3039 | + psroam = (wlc_sroam_t *)MALLOCZ(dhdp->osh, sroamlen); |
---|
| 3040 | + if (!psroam) { |
---|
| 3041 | + WL_ERR(("%s Fail to malloc buffer\n", __FUNCTION__)); |
---|
| 3042 | + ret = BCME_NOMEM; |
---|
| 3043 | + goto done; |
---|
| 3044 | + } |
---|
| 3045 | + |
---|
| 3046 | + ret = wldev_iovar_getbuf(dev, "sroam", NULL, 0, psroam, sroamlen, NULL); |
---|
| 3047 | + if (ret) { |
---|
| 3048 | + WL_ERR(("Failed to get silent roam info(%d)\n", ret)); |
---|
| 3049 | + goto done; |
---|
| 3050 | + } |
---|
| 3051 | + |
---|
| 3052 | + if (psroam->ver != WLC_SILENT_ROAM_CUR_VER) { |
---|
| 3053 | + ret = BCME_VERSION; |
---|
| 3054 | + WL_ERR(("Ver(%d:%d). mismatch silent roam info(%d)\n", |
---|
| 3055 | + psroam->ver, WLC_SILENT_ROAM_CUR_VER, ret)); |
---|
| 3056 | + goto done; |
---|
| 3057 | + } |
---|
| 3058 | + |
---|
| 3059 | + sroam = (wlc_sroam_info_t *)psroam->data; |
---|
| 3060 | + bytes_written = snprintf(command, total_len, |
---|
| 3061 | + "%s %d %d %d %d %d %d %d\n", |
---|
| 3062 | + CMD_SROAM_GET_INFO, sroam->sroam_on, sroam->sroam_min_rssi, sroam->sroam_rssi_range, |
---|
| 3063 | + sroam->sroam_score_delta, sroam->sroam_period_time, sroam->sroam_band, |
---|
| 3064 | + sroam->sroam_inact_cnt); |
---|
| 3065 | + ret = bytes_written; |
---|
| 3066 | + |
---|
| 3067 | + WL_DBG(("%s", command)); |
---|
| 3068 | +done: |
---|
| 3069 | + if (psroam) { |
---|
| 3070 | + MFREE(dhdp->osh, psroam, sroamlen); |
---|
| 3071 | + } |
---|
| 3072 | + |
---|
| 3073 | + return ret; |
---|
| 3074 | +} |
---|
| 3075 | +#endif /* CONFIG_SILENT_ROAM */ |
---|
| 3076 | + |
---|
| 3077 | +static int |
---|
| 3078 | +get_int_bytes(uchar *oui_str, uchar *oui, int len) |
---|
| 3079 | +{ |
---|
| 3080 | + int idx; |
---|
| 3081 | + uchar val; |
---|
| 3082 | + uchar *src, *dest; |
---|
| 3083 | + char hexstr[3]; |
---|
| 3084 | + |
---|
| 3085 | + if ((oui_str == NULL) || (oui == NULL) || (len == 0)) { |
---|
| 3086 | + return BCME_BADARG; |
---|
| 3087 | + } |
---|
| 3088 | + src = oui_str; |
---|
| 3089 | + dest = oui; |
---|
| 3090 | + |
---|
| 3091 | + for (idx = 0; idx < len; idx++) { |
---|
| 3092 | + if (*src == '\0') { |
---|
| 3093 | + *dest = '\0'; |
---|
| 3094 | + break; |
---|
| 3095 | + } |
---|
| 3096 | + hexstr[0] = src[0]; |
---|
| 3097 | + hexstr[1] = src[1]; |
---|
| 3098 | + hexstr[2] = '\0'; |
---|
| 3099 | + |
---|
| 3100 | + val = (uchar)bcm_strtoul(hexstr, NULL, 16); |
---|
| 3101 | + if (val == (uchar)-1) { |
---|
| 3102 | + return BCME_ERROR; |
---|
| 3103 | + } |
---|
| 3104 | + *dest++ = val; |
---|
| 3105 | + src += 2; |
---|
| 3106 | + } |
---|
| 3107 | + return BCME_OK; |
---|
| 3108 | +} |
---|
| 3109 | + |
---|
| 3110 | +#define TAG_BYTE 0 |
---|
| 3111 | +static int |
---|
| 3112 | +wl_android_set_disconnect_ies(struct net_device *dev, char *command) |
---|
| 3113 | +{ |
---|
| 3114 | + int cmd_prefix_len = 0; |
---|
| 3115 | + char ie_len = 0; |
---|
| 3116 | + int hex_ie_len = 0; |
---|
| 3117 | + int total_len = 0; |
---|
| 3118 | + int max_len = 0; |
---|
| 3119 | + int cmd_len = 0; |
---|
| 3120 | + uchar disassoc_ie[VNDR_IE_MAX_LEN] = {0}; |
---|
| 3121 | + s32 bssidx = 0; |
---|
| 3122 | + struct bcm_cfg80211 *cfg = NULL; |
---|
| 3123 | + s32 ret = 0; |
---|
| 3124 | + cfg = wl_get_cfg(dev); |
---|
| 3125 | + |
---|
| 3126 | + cmd_prefix_len = strlen("SET_DISCONNECT_IES "); |
---|
| 3127 | + cmd_len = strlen(command); |
---|
| 3128 | + /* |
---|
| 3129 | + * <CMD> + <IES in HEX format> |
---|
| 3130 | + * IES in hex format has to be in following format |
---|
| 3131 | + * First byte = Tag, Second Byte = len and rest of |
---|
| 3132 | + * bytes will be value. For ex: SET_DISCONNECT_IES dd0411223344 |
---|
| 3133 | + * tag = dd, len =04. Total IEs len = len + 2 |
---|
| 3134 | + */ |
---|
| 3135 | + WL_DBG(("cmd recv = %s\n", command)); |
---|
| 3136 | + max_len = MIN(cmd_len, VNDR_IE_MAX_LEN); |
---|
| 3137 | + /* Validate IEs len */ |
---|
| 3138 | + get_int_bytes(&command[cmd_prefix_len + 2], &ie_len, 1); |
---|
| 3139 | + WL_INFORM_MEM(("ie_len = %d \n", ie_len)); |
---|
| 3140 | + if (ie_len <= 0 || ie_len > max_len) { |
---|
| 3141 | + ret = BCME_BADLEN; |
---|
| 3142 | + return ret; |
---|
| 3143 | + } |
---|
| 3144 | + |
---|
| 3145 | + /* Total len in hex is sum of double binary len, tag and len byte */ |
---|
| 3146 | + hex_ie_len = (ie_len * 2) + 4; |
---|
| 3147 | + total_len = cmd_prefix_len + hex_ie_len; |
---|
| 3148 | + if (command[total_len] != '\0' || (cmd_len != total_len)) { |
---|
| 3149 | + WL_ERR(("command recv not matching with len, command = %s" |
---|
| 3150 | + "total_len = %d, cmd_len = %d\n", command, total_len, cmd_len)); |
---|
| 3151 | + ret = BCME_BADARG; |
---|
| 3152 | + return ret; |
---|
| 3153 | + } |
---|
| 3154 | + |
---|
| 3155 | + if ((bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr)) < 0) { |
---|
| 3156 | + WL_ERR(("Find index failed\n")); |
---|
| 3157 | + ret = -EINVAL; |
---|
| 3158 | + return ret; |
---|
| 3159 | + } |
---|
| 3160 | + |
---|
| 3161 | + /* Tag and len bytes are also part of total len of ies in binary */ |
---|
| 3162 | + ie_len = ie_len + 2; |
---|
| 3163 | + /* Convert IEs in binary */ |
---|
| 3164 | + get_int_bytes(&command[cmd_prefix_len], disassoc_ie, ie_len); |
---|
| 3165 | + if (disassoc_ie[TAG_BYTE] != 0xdd) { |
---|
| 3166 | + WL_ERR(("Wrong tag recv, tag = 0x%02x\n", disassoc_ie[TAG_BYTE])); |
---|
| 3167 | + ret = BCME_UNSUPPORTED; |
---|
| 3168 | + return ret; |
---|
| 3169 | + } |
---|
| 3170 | + |
---|
| 3171 | + ret = wl_cfg80211_set_mgmt_vndr_ies(cfg, |
---|
| 3172 | + ndev_to_cfgdev(dev), bssidx, VNDR_IE_DISASSOC_FLAG, disassoc_ie, ie_len); |
---|
| 3173 | + |
---|
| 3174 | + return ret; |
---|
| 3175 | +} |
---|
| 3176 | + |
---|
| 3177 | +#ifdef FCC_PWR_LIMIT_2G |
---|
| 3178 | +int |
---|
| 3179 | +wl_android_set_fcc_pwr_limit_2g(struct net_device *dev, char *command) |
---|
| 3180 | +{ |
---|
| 3181 | + int error = 0; |
---|
| 3182 | + int enable = 0; |
---|
| 3183 | + |
---|
| 3184 | + sscanf(command+sizeof("SET_FCC_CHANNEL"), "%d", &enable); |
---|
| 3185 | + |
---|
| 3186 | + if ((enable != CUSTOMER_HW4_ENABLE) && (enable != CUSTOMER_HW4_DISABLE)) { |
---|
| 3187 | + DHD_ERROR(("wl_android_set_fcc_pwr_limit_2g: Invalid data\n")); |
---|
| 3188 | + return BCME_ERROR; |
---|
| 3189 | + } |
---|
| 3190 | + |
---|
| 3191 | + CUSTOMER_HW4_EN_CONVERT(enable); |
---|
| 3192 | + |
---|
| 3193 | + DHD_ERROR(("wl_android_set_fcc_pwr_limit_2g: fccpwrlimit2g set (%d)\n", enable)); |
---|
| 3194 | + error = wldev_iovar_setint(dev, "fccpwrlimit2g", enable); |
---|
| 3195 | + if (error) { |
---|
| 3196 | + DHD_ERROR(("wl_android_set_fcc_pwr_limit_2g: fccpwrlimit2g" |
---|
| 3197 | + " set returned (%d)\n", error)); |
---|
| 3198 | + return BCME_ERROR; |
---|
| 3199 | + } |
---|
| 3200 | + |
---|
| 3201 | + return error; |
---|
| 3202 | +} |
---|
| 3203 | + |
---|
| 3204 | +int |
---|
| 3205 | +wl_android_get_fcc_pwr_limit_2g(struct net_device *dev, char *command, int total_len) |
---|
| 3206 | +{ |
---|
| 3207 | + int error = 0; |
---|
| 3208 | + int enable = 0; |
---|
| 3209 | + int bytes_written = 0; |
---|
| 3210 | + |
---|
| 3211 | + error = wldev_iovar_getint(dev, "fccpwrlimit2g", &enable); |
---|
| 3212 | + if (error) { |
---|
| 3213 | + DHD_ERROR(("wl_android_get_fcc_pwr_limit_2g: fccpwrlimit2g get" |
---|
| 3214 | + " error (%d)\n", error)); |
---|
| 3215 | + return BCME_ERROR; |
---|
| 3216 | + } |
---|
| 3217 | + DHD_ERROR(("wl_android_get_fcc_pwr_limit_2g: fccpwrlimit2g get (%d)\n", enable)); |
---|
| 3218 | + |
---|
| 3219 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GET_FCC_PWR_LIMIT_2G, enable); |
---|
| 3220 | + |
---|
| 3221 | + return bytes_written; |
---|
| 3222 | +} |
---|
| 3223 | +#endif /* FCC_PWR_LIMIT_2G */ |
---|
| 3224 | + |
---|
| 3225 | +s32 |
---|
| 3226 | +wl_cfg80211_get_sta_info(struct net_device *dev, char* command, int total_len) |
---|
| 3227 | +{ |
---|
| 3228 | + int bytes_written = -1, ret = 0; |
---|
| 3229 | + char *pcmd = command; |
---|
| 3230 | + char *str; |
---|
| 3231 | + sta_info_v4_t *sta = NULL; |
---|
| 3232 | + const wl_cnt_wlc_t* wlc_cnt = NULL; |
---|
| 3233 | + struct ether_addr mac; |
---|
| 3234 | + char *iovar_buf; |
---|
| 3235 | + /* Client information */ |
---|
| 3236 | + uint16 cap = 0; |
---|
| 3237 | + uint32 rxrtry = 0; |
---|
| 3238 | + uint32 rxmulti = 0; |
---|
| 3239 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 3240 | + |
---|
| 3241 | +#ifdef BIGDATA_SOFTAP |
---|
| 3242 | + void *data = NULL; |
---|
| 3243 | + int get_bigdata_softap = FALSE; |
---|
| 3244 | + wl_ap_sta_data_t *sta_data = NULL; |
---|
| 3245 | + struct bcm_cfg80211 *bcm_cfg = wl_get_cfg(dev); |
---|
| 3246 | +#endif /* BIGDATA_SOFTAP */ |
---|
| 3247 | + |
---|
| 3248 | + WL_DBG(("%s\n", command)); |
---|
| 3249 | + |
---|
| 3250 | + iovar_buf = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_MAXLEN); |
---|
| 3251 | + if (iovar_buf == NULL) { |
---|
| 3252 | + DHD_ERROR(("wl_cfg80211_get_sta_info: failed to allocated memory %d bytes\n", |
---|
| 3253 | + WLC_IOCTL_MAXLEN)); |
---|
| 3254 | + goto error; |
---|
| 3255 | + } |
---|
| 3256 | + |
---|
| 3257 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 3258 | + if (str) { |
---|
| 3259 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 3260 | + /* If GETSTAINFO subcmd name is not provided, return error */ |
---|
| 3261 | + if (str == NULL) { |
---|
| 3262 | + WL_ERR(("GETSTAINFO subcmd not provided wl_cfg80211_get_sta_info\n")); |
---|
| 3263 | + goto error; |
---|
| 3264 | + } |
---|
| 3265 | + |
---|
| 3266 | + bzero(&mac, ETHER_ADDR_LEN); |
---|
| 3267 | + if ((bcm_ether_atoe((str), &mac))) { |
---|
| 3268 | + /* get the sta info */ |
---|
| 3269 | + ret = wldev_iovar_getbuf(dev, "sta_info", |
---|
| 3270 | + (struct ether_addr *)mac.octet, |
---|
| 3271 | + ETHER_ADDR_LEN, iovar_buf, WLC_IOCTL_SMLEN, NULL); |
---|
| 3272 | +#ifdef BIGDATA_SOFTAP |
---|
| 3273 | + get_bigdata_softap = TRUE; |
---|
| 3274 | +#endif /* BIGDATA_SOFTAP */ |
---|
| 3275 | + if (ret < 0) { |
---|
| 3276 | + WL_ERR(("Get sta_info ERR %d\n", ret)); |
---|
| 3277 | +#ifndef BIGDATA_SOFTAP |
---|
| 3278 | + goto error; |
---|
| 3279 | +#else |
---|
| 3280 | + goto get_bigdata; |
---|
| 3281 | +#endif /* BIGDATA_SOFTAP */ |
---|
| 3282 | + } |
---|
| 3283 | + |
---|
| 3284 | + sta = (sta_info_v4_t *)iovar_buf; |
---|
| 3285 | + if (dtoh16(sta->ver) != WL_STA_VER_4) { |
---|
| 3286 | + WL_ERR(("sta_info struct version mismatch, " |
---|
| 3287 | + "host ver : %d, fw ver : %d\n", WL_STA_VER_4, |
---|
| 3288 | + dtoh16(sta->ver))); |
---|
| 3289 | + goto error; |
---|
| 3290 | + } |
---|
| 3291 | + cap = dtoh16(sta->cap); |
---|
| 3292 | + rxrtry = dtoh32(sta->rx_pkts_retried); |
---|
| 3293 | + rxmulti = dtoh32(sta->rx_mcast_pkts); |
---|
| 3294 | + } else if ((!strncmp(str, "all", 3)) || (!strncmp(str, "ALL", 3))) { |
---|
| 3295 | + /* get counters info */ |
---|
| 3296 | + ret = wldev_iovar_getbuf(dev, "counters", NULL, 0, |
---|
| 3297 | + iovar_buf, WLC_IOCTL_MAXLEN, NULL); |
---|
| 3298 | + if (unlikely(ret)) { |
---|
| 3299 | + WL_ERR(("counters error (%d) - size = %zu\n", |
---|
| 3300 | + ret, sizeof(wl_cnt_wlc_t))); |
---|
| 3301 | + goto error; |
---|
| 3302 | + } |
---|
| 3303 | + ret = wl_cntbuf_to_xtlv_format(NULL, iovar_buf, WL_CNTBUF_MAX_SIZE, 0); |
---|
| 3304 | + if (ret != BCME_OK) { |
---|
| 3305 | + WL_ERR(("wl_cntbuf_to_xtlv_format ERR %d\n", ret)); |
---|
| 3306 | + goto error; |
---|
| 3307 | + } |
---|
| 3308 | + if (!(wlc_cnt = GET_WLCCNT_FROM_CNTBUF(iovar_buf))) { |
---|
| 3309 | + WL_ERR(("wlc_cnt NULL!\n")); |
---|
| 3310 | + goto error; |
---|
| 3311 | + } |
---|
| 3312 | + |
---|
| 3313 | + rxrtry = dtoh32(wlc_cnt->rxrtry); |
---|
| 3314 | + rxmulti = dtoh32(wlc_cnt->rxmulti); |
---|
| 3315 | + } else { |
---|
| 3316 | + WL_ERR(("Get address fail\n")); |
---|
| 3317 | + goto error; |
---|
| 3318 | + } |
---|
| 3319 | + } else { |
---|
| 3320 | + WL_ERR(("Command ERR\n")); |
---|
| 3321 | + goto error; |
---|
| 3322 | + } |
---|
| 3323 | + |
---|
| 3324 | +#ifdef BIGDATA_SOFTAP |
---|
| 3325 | +get_bigdata: |
---|
| 3326 | + if (get_bigdata_softap) { |
---|
| 3327 | + WL_ERR(("mac " MACDBG" \n", MAC2STRDBG((char*)&mac))); |
---|
| 3328 | + if (wl_get_ap_stadata(bcm_cfg, &mac, &data) == BCME_OK) { |
---|
| 3329 | + sta_data = (wl_ap_sta_data_t *)data; |
---|
| 3330 | + bytes_written = snprintf(command, total_len, |
---|
| 3331 | + "%s %s Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d " |
---|
| 3332 | + "CAP=%04x "MACOUI" %d %s %d %d %d %d %d %d\n", |
---|
| 3333 | + CMD_GET_STA_INFO, str, rxrtry, rxmulti, cap, |
---|
| 3334 | + MACOUI2STR((char*)&sta_data->mac), |
---|
| 3335 | + sta_data->channel, |
---|
| 3336 | + wf_chspec_to_bw_str(sta_data->chanspec), |
---|
| 3337 | + sta_data->rssi, sta_data->rate, |
---|
| 3338 | + sta_data->mode_80211, sta_data->nss, sta_data->mimo, |
---|
| 3339 | + sta_data->reason_code); |
---|
| 3340 | + WL_ERR_KERN(("command %s\n", command)); |
---|
| 3341 | + goto error; |
---|
| 3342 | + } |
---|
| 3343 | + } |
---|
| 3344 | +#endif /* BIGDATA_SOFTAP */ |
---|
| 3345 | + bytes_written = snprintf(command, total_len, |
---|
| 3346 | + "%s %s Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d CAP=%04x\n", |
---|
| 3347 | + CMD_GET_STA_INFO, str, rxrtry, rxmulti, cap); |
---|
| 3348 | + |
---|
| 3349 | + WL_DBG(("%s", command)); |
---|
| 3350 | + |
---|
| 3351 | +error: |
---|
| 3352 | + if (iovar_buf) { |
---|
| 3353 | + MFREE(cfg->osh, iovar_buf, WLC_IOCTL_MAXLEN); |
---|
| 3354 | + |
---|
| 3355 | + } |
---|
| 3356 | + return bytes_written; |
---|
| 3357 | +} |
---|
| 3358 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
| 3359 | + |
---|
| 3360 | +#ifdef WBTEXT |
---|
| 3361 | +static int wl_android_wbtext(struct net_device *dev, char *command, int total_len) |
---|
| 3362 | +{ |
---|
| 3363 | + int error = BCME_OK, argc = 0; |
---|
| 3364 | + int data, bytes_written; |
---|
| 3365 | + int roam_trigger[2]; |
---|
| 3366 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 3367 | + |
---|
| 3368 | + argc = sscanf(command+sizeof(CMD_WBTEXT_ENABLE), "%d", &data); |
---|
| 3369 | + if (!argc) { |
---|
| 3370 | + error = wldev_iovar_getint(dev, "wnm_bsstrans_resp", &data); |
---|
| 3371 | + if (error) { |
---|
| 3372 | + DHD_ERROR(("wl_android_wbtext: Failed to set wbtext error = %d\n", |
---|
| 3373 | + error)); |
---|
| 3374 | + return error; |
---|
| 3375 | + } |
---|
| 3376 | + bytes_written = snprintf(command, total_len, "WBTEXT %s\n", |
---|
| 3377 | + (data == WL_BSSTRANS_POLICY_PRODUCT_WBTEXT)? |
---|
| 3378 | + "ENABLED" : "DISABLED"); |
---|
| 3379 | + return bytes_written; |
---|
| 3380 | + } else { |
---|
| 3381 | + if (data) { |
---|
| 3382 | + data = WL_BSSTRANS_POLICY_PRODUCT_WBTEXT; |
---|
| 3383 | + } |
---|
| 3384 | + |
---|
| 3385 | + if ((error = wldev_iovar_setint(dev, "wnm_bsstrans_resp", data)) != BCME_OK) { |
---|
| 3386 | + DHD_ERROR(("wl_android_wbtext: Failed to set wbtext error = %d\n", |
---|
| 3387 | + error)); |
---|
| 3388 | + return error; |
---|
| 3389 | + } |
---|
| 3390 | + |
---|
| 3391 | + if (data) { |
---|
| 3392 | + /* reset roam_prof when wbtext is on */ |
---|
| 3393 | + if ((error = wl_cfg80211_wbtext_set_default(dev)) != BCME_OK) { |
---|
| 3394 | + return error; |
---|
| 3395 | + } |
---|
| 3396 | + dhdp->wbtext_support = TRUE; |
---|
| 3397 | + } else { |
---|
| 3398 | + /* reset legacy roam trigger when wbtext is off */ |
---|
| 3399 | + roam_trigger[0] = DEFAULT_ROAM_TRIGGER_VALUE; |
---|
| 3400 | + roam_trigger[1] = WLC_BAND_ALL; |
---|
| 3401 | + if ((error = wldev_ioctl_set(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, |
---|
| 3402 | + sizeof(roam_trigger))) != BCME_OK) { |
---|
| 3403 | + DHD_ERROR(("wl_android_wbtext: Failed to reset roam trigger = %d\n", |
---|
| 3404 | + error)); |
---|
| 3405 | + return error; |
---|
| 3406 | + } |
---|
| 3407 | + dhdp->wbtext_support = FALSE; |
---|
| 3408 | + } |
---|
| 3409 | + } |
---|
| 3410 | + return error; |
---|
| 3411 | +} |
---|
| 3412 | + |
---|
| 3413 | +static int wl_cfg80211_wbtext_btm_timer_threshold(struct net_device *dev, |
---|
| 3414 | + char *command, int total_len) |
---|
| 3415 | +{ |
---|
| 3416 | + int error = BCME_OK, argc = 0; |
---|
| 3417 | + int data, bytes_written; |
---|
| 3418 | + |
---|
| 3419 | + argc = sscanf(command, CMD_WBTEXT_BTM_TIMER_THRESHOLD " %d\n", &data); |
---|
| 3420 | + if (!argc) { |
---|
| 3421 | + error = wldev_iovar_getint(dev, "wnm_bsstrans_timer_threshold", &data); |
---|
| 3422 | + if (error) { |
---|
| 3423 | + WL_ERR(("Failed to get wnm_bsstrans_timer_threshold (%d)\n", error)); |
---|
| 3424 | + return error; |
---|
| 3425 | + } |
---|
| 3426 | + bytes_written = snprintf(command, total_len, "%d\n", data); |
---|
| 3427 | + return bytes_written; |
---|
| 3428 | + } else { |
---|
| 3429 | + if ((error = wldev_iovar_setint(dev, "wnm_bsstrans_timer_threshold", |
---|
| 3430 | + data)) != BCME_OK) { |
---|
| 3431 | + WL_ERR(("Failed to set wnm_bsstrans_timer_threshold (%d)\n", error)); |
---|
| 3432 | + return error; |
---|
| 3433 | + } |
---|
| 3434 | + } |
---|
| 3435 | + return error; |
---|
| 3436 | +} |
---|
| 3437 | + |
---|
| 3438 | +static int wl_cfg80211_wbtext_btm_delta(struct net_device *dev, |
---|
| 3439 | + char *command, int total_len) |
---|
| 3440 | +{ |
---|
| 3441 | + int error = BCME_OK, argc = 0; |
---|
| 3442 | + int data = 0, bytes_written; |
---|
| 3443 | + |
---|
| 3444 | + argc = sscanf(command, CMD_WBTEXT_BTM_DELTA " %d\n", &data); |
---|
| 3445 | + if (!argc) { |
---|
| 3446 | + error = wldev_iovar_getint(dev, "wnm_btmdelta", &data); |
---|
| 3447 | + if (error) { |
---|
| 3448 | + WL_ERR(("Failed to get wnm_btmdelta (%d)\n", error)); |
---|
| 3449 | + return error; |
---|
| 3450 | + } |
---|
| 3451 | + bytes_written = snprintf(command, total_len, "%d\n", data); |
---|
| 3452 | + return bytes_written; |
---|
| 3453 | + } else { |
---|
| 3454 | + if ((error = wldev_iovar_setint(dev, "wnm_btmdelta", |
---|
| 3455 | + data)) != BCME_OK) { |
---|
| 3456 | + WL_ERR(("Failed to set wnm_btmdelta (%d)\n", error)); |
---|
| 3457 | + return error; |
---|
| 3458 | + } |
---|
| 3459 | + } |
---|
| 3460 | + return error; |
---|
| 3461 | +} |
---|
| 3462 | + |
---|
| 3463 | +static int wl_cfg80211_wbtext_estm_enable(struct net_device *dev, |
---|
| 3464 | + char *command, int total_len) |
---|
| 3465 | +{ |
---|
| 3466 | + int error = BCME_OK; |
---|
| 3467 | + int data = 0, bytes_written = 0; |
---|
| 3468 | + int wnmmask = 0; |
---|
| 3469 | + char *pcmd = command; |
---|
| 3470 | + |
---|
| 3471 | + bcmstrtok(&pcmd, " ", NULL); |
---|
| 3472 | + |
---|
| 3473 | + error = wldev_iovar_getint(dev, "wnm", &wnmmask); |
---|
| 3474 | + if (error) { |
---|
| 3475 | + WL_ERR(("Failed to get wnm_btmdelta (%d)\n", error)); |
---|
| 3476 | + return error; |
---|
| 3477 | + } |
---|
| 3478 | + WL_DBG(("wnmmask %x\n", wnmmask)); |
---|
| 3479 | + if (*pcmd == WL_IOCTL_ACTION_GET) { |
---|
| 3480 | + bytes_written = snprintf(command, total_len, "wbtext_estm_enable %d\n", |
---|
| 3481 | + (wnmmask & WL_WNM_ESTM) ? 1:0); |
---|
| 3482 | + return bytes_written; |
---|
| 3483 | + } else { |
---|
| 3484 | + data = bcm_atoi(pcmd); |
---|
| 3485 | + if (data == 0) { |
---|
| 3486 | + wnmmask &= ~WL_WNM_ESTM; |
---|
| 3487 | + } else { |
---|
| 3488 | + wnmmask |= WL_WNM_ESTM; |
---|
| 3489 | + } |
---|
| 3490 | + WL_DBG(("wnmmask %x\n", wnmmask)); |
---|
| 3491 | + if ((error = wldev_iovar_setint(dev, "wnm", wnmmask)) != BCME_OK) { |
---|
| 3492 | + WL_ERR(("Failed to set wnm mask (%d)\n", error)); |
---|
| 3493 | + return error; |
---|
| 3494 | + } |
---|
| 3495 | + } |
---|
| 3496 | + return error; |
---|
| 3497 | +} |
---|
| 3498 | +#endif /* WBTEXT */ |
---|
663 | 3499 | |
---|
664 | 3500 | #ifdef PNO_SUPPORT |
---|
665 | 3501 | #define PNO_PARAM_SIZE 50 |
---|
.. | .. |
---|
669 | 3505 | wls_parse_batching_cmd(struct net_device *dev, char *command, int total_len) |
---|
670 | 3506 | { |
---|
671 | 3507 | int err = BCME_OK; |
---|
672 | | - uint i, tokens; |
---|
| 3508 | + uint i, tokens, len_remain; |
---|
673 | 3509 | char *pos, *pos2, *token, *token2, *delim; |
---|
674 | | - char param[PNO_PARAM_SIZE], value[VALUE_SIZE]; |
---|
| 3510 | + char param[PNO_PARAM_SIZE+1], value[VALUE_SIZE+1]; |
---|
675 | 3511 | struct dhd_pno_batch_params batch_params; |
---|
676 | | - DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); |
---|
677 | | - if (total_len < strlen(CMD_WLS_BATCHING)) { |
---|
678 | | - DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len)); |
---|
| 3512 | + |
---|
| 3513 | + DHD_PNO(("wls_parse_batching_cmd: command=%s, len=%d\n", command, total_len)); |
---|
| 3514 | + len_remain = total_len; |
---|
| 3515 | + if (len_remain > (strlen(CMD_WLS_BATCHING) + 1)) { |
---|
| 3516 | + pos = command + strlen(CMD_WLS_BATCHING) + 1; |
---|
| 3517 | + len_remain -= strlen(CMD_WLS_BATCHING) + 1; |
---|
| 3518 | + } else { |
---|
| 3519 | + WL_ERR(("wls_parse_batching_cmd: No arguments, total_len %d\n", total_len)); |
---|
679 | 3520 | err = BCME_ERROR; |
---|
680 | 3521 | goto exit; |
---|
681 | 3522 | } |
---|
682 | | - pos = command + strlen(CMD_WLS_BATCHING) + 1; |
---|
683 | | - memset(&batch_params, 0, sizeof(struct dhd_pno_batch_params)); |
---|
684 | | - |
---|
| 3523 | + bzero(&batch_params, sizeof(struct dhd_pno_batch_params)); |
---|
685 | 3524 | if (!strncmp(pos, PNO_BATCHING_SET, strlen(PNO_BATCHING_SET))) { |
---|
686 | | - pos += strlen(PNO_BATCHING_SET) + 1; |
---|
| 3525 | + if (len_remain > (strlen(PNO_BATCHING_SET) + 1)) { |
---|
| 3526 | + pos += strlen(PNO_BATCHING_SET) + 1; |
---|
| 3527 | + } else { |
---|
| 3528 | + WL_ERR(("wls_parse_batching_cmd: %s missing arguments, total_len %d\n", |
---|
| 3529 | + PNO_BATCHING_SET, total_len)); |
---|
| 3530 | + err = BCME_ERROR; |
---|
| 3531 | + goto exit; |
---|
| 3532 | + } |
---|
687 | 3533 | while ((token = strsep(&pos, PNO_PARAMS_DELIMETER)) != NULL) { |
---|
688 | | - memset(param, 0, sizeof(param)); |
---|
689 | | - memset(value, 0, sizeof(value)); |
---|
| 3534 | + bzero(param, sizeof(param)); |
---|
| 3535 | + bzero(value, sizeof(value)); |
---|
690 | 3536 | if (token == NULL || !*token) |
---|
691 | 3537 | break; |
---|
692 | 3538 | if (*token == '\0') |
---|
.. | .. |
---|
711 | 3557 | tokens = sscanf(value, "<%s>", value); |
---|
712 | 3558 | if (tokens != 1) { |
---|
713 | 3559 | err = BCME_ERROR; |
---|
714 | | - DHD_ERROR(("%s : invalid format for channel" |
---|
715 | | - " <> params\n", __FUNCTION__)); |
---|
| 3560 | + DHD_ERROR(("wls_parse_batching_cmd: invalid format" |
---|
| 3561 | + " for channel" |
---|
| 3562 | + " <> params\n")); |
---|
716 | 3563 | goto exit; |
---|
717 | 3564 | } |
---|
718 | | - while ((token2 = strsep(&pos2, |
---|
719 | | - PNO_PARAM_CHANNEL_DELIMETER)) != NULL) { |
---|
| 3565 | + while ((token2 = strsep(&pos2, |
---|
| 3566 | + PNO_PARAM_CHANNEL_DELIMETER)) != NULL) { |
---|
720 | 3567 | if (token2 == NULL || !*token2) |
---|
721 | 3568 | break; |
---|
722 | 3569 | if (*token2 == '\0') |
---|
.. | .. |
---|
727 | 3574 | DHD_PNO(("band : %s\n", |
---|
728 | 3575 | (*token2 == 'A')? "A" : "B")); |
---|
729 | 3576 | } else { |
---|
| 3577 | + if ((batch_params.nchan >= WL_NUMCHANNELS) || |
---|
| 3578 | + (i >= WL_NUMCHANNELS)) { |
---|
| 3579 | + DHD_ERROR(("Too many nchan %d\n", |
---|
| 3580 | + batch_params.nchan)); |
---|
| 3581 | + err = BCME_BUFTOOSHORT; |
---|
| 3582 | + goto exit; |
---|
| 3583 | + } |
---|
730 | 3584 | batch_params.chan_list[i++] = |
---|
731 | | - simple_strtol(token2, NULL, 0); |
---|
| 3585 | + simple_strtol(token2, NULL, 0); |
---|
732 | 3586 | batch_params.nchan++; |
---|
733 | 3587 | DHD_PNO(("channel :%d\n", |
---|
734 | | - batch_params.chan_list[i-1])); |
---|
| 3588 | + batch_params.chan_list[i-1])); |
---|
735 | 3589 | } |
---|
736 | 3590 | } |
---|
737 | 3591 | } else if (!strncmp(param, PNO_PARAM_RTT, strlen(PNO_PARAM_RTT))) { |
---|
738 | 3592 | batch_params.rtt = simple_strtol(value, NULL, 0); |
---|
739 | 3593 | DHD_PNO(("rtt : %d\n", batch_params.rtt)); |
---|
740 | 3594 | } else { |
---|
741 | | - DHD_ERROR(("%s : unknown param: %s\n", __FUNCTION__, param)); |
---|
| 3595 | + DHD_ERROR(("wls_parse_batching_cmd : unknown param: %s\n", param)); |
---|
742 | 3596 | err = BCME_ERROR; |
---|
743 | 3597 | goto exit; |
---|
744 | 3598 | } |
---|
.. | .. |
---|
747 | 3601 | if (err < 0) { |
---|
748 | 3602 | DHD_ERROR(("failed to configure batch scan\n")); |
---|
749 | 3603 | } else { |
---|
750 | | - memset(command, 0, total_len); |
---|
| 3604 | + bzero(command, total_len); |
---|
751 | 3605 | err = snprintf(command, total_len, "%d", err); |
---|
752 | 3606 | } |
---|
753 | 3607 | } else if (!strncmp(pos, PNO_BATCHING_GET, strlen(PNO_BATCHING_GET))) { |
---|
.. | .. |
---|
762 | 3616 | if (err < 0) { |
---|
763 | 3617 | DHD_ERROR(("failed to stop batching scan\n")); |
---|
764 | 3618 | } else { |
---|
765 | | - memset(command, 0, total_len); |
---|
| 3619 | + bzero(command, total_len); |
---|
766 | 3620 | err = snprintf(command, total_len, "OK"); |
---|
767 | 3621 | } |
---|
768 | 3622 | } else { |
---|
769 | | - DHD_ERROR(("%s : unknown command\n", __FUNCTION__)); |
---|
| 3623 | + DHD_ERROR(("wls_parse_batching_cmd : unknown command\n")); |
---|
770 | 3624 | err = BCME_ERROR; |
---|
771 | 3625 | goto exit; |
---|
772 | 3626 | } |
---|
773 | 3627 | exit: |
---|
774 | 3628 | return err; |
---|
775 | 3629 | } |
---|
776 | | -#if !defined(WL_SCHED_SCAN) && defined(WL_WIRELESS_EXT) |
---|
| 3630 | +#ifndef WL_SCHED_SCAN |
---|
777 | 3631 | static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len) |
---|
778 | 3632 | { |
---|
779 | 3633 | wlc_ssid_ext_t ssids_local[MAX_PFN_LIST_COUNT]; |
---|
.. | .. |
---|
806 | 3660 | 0x00 |
---|
807 | 3661 | }; |
---|
808 | 3662 | #endif /* PNO_SET_DEBUG */ |
---|
809 | | - DHD_PNO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); |
---|
| 3663 | + DHD_PNO(("wl_android_set_pno_setup: command=%s, len=%d\n", command, total_len)); |
---|
810 | 3664 | |
---|
811 | 3665 | if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) { |
---|
812 | | - DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len)); |
---|
| 3666 | + DHD_ERROR(("wl_android_set_pno_setup: argument=%d less min size\n", total_len)); |
---|
813 | 3667 | goto exit_proc; |
---|
814 | 3668 | } |
---|
815 | 3669 | #ifdef PNO_SET_DEBUG |
---|
816 | 3670 | memcpy(command, pno_in_example, sizeof(pno_in_example)); |
---|
817 | 3671 | total_len = sizeof(pno_in_example); |
---|
818 | | -#endif |
---|
| 3672 | +#endif // endif |
---|
819 | 3673 | str_ptr = command + strlen(CMD_PNOSETUP_SET); |
---|
820 | 3674 | tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET); |
---|
821 | 3675 | |
---|
822 | 3676 | cmd_tlv_temp = (cmd_tlv_t *)str_ptr; |
---|
823 | | - memset(ssids_local, 0, sizeof(ssids_local)); |
---|
| 3677 | + bzero(ssids_local, sizeof(ssids_local)); |
---|
824 | 3678 | |
---|
825 | 3679 | if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && |
---|
826 | 3680 | (cmd_tlv_temp->version == PNO_TLV_VERSION) && |
---|
.. | .. |
---|
829 | 3683 | str_ptr += sizeof(cmd_tlv_t); |
---|
830 | 3684 | tlv_size_left -= sizeof(cmd_tlv_t); |
---|
831 | 3685 | |
---|
832 | | - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, |
---|
| 3686 | + if ((nssid = wl_parse_ssid_list_tlv(&str_ptr, ssids_local, |
---|
833 | 3687 | MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { |
---|
834 | 3688 | DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); |
---|
835 | 3689 | goto exit_proc; |
---|
836 | 3690 | } else { |
---|
837 | 3691 | if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { |
---|
838 | | - DHD_ERROR(("%s scan duration corrupted field size %d\n", |
---|
839 | | - __FUNCTION__, tlv_size_left)); |
---|
| 3692 | + DHD_ERROR(("wl_android_set_pno_setup: scan duration corrupted" |
---|
| 3693 | + " field size %d\n", |
---|
| 3694 | + tlv_size_left)); |
---|
840 | 3695 | goto exit_proc; |
---|
841 | 3696 | } |
---|
842 | 3697 | str_ptr++; |
---|
843 | 3698 | pno_time = simple_strtoul(str_ptr, &str_ptr, 16); |
---|
844 | | - DHD_PNO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); |
---|
| 3699 | + DHD_PNO(("wl_android_set_pno_setup: pno_time=%d\n", pno_time)); |
---|
845 | 3700 | |
---|
846 | 3701 | if (str_ptr[0] != 0) { |
---|
847 | 3702 | if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { |
---|
848 | | - DHD_ERROR(("%s pno repeat : corrupted field\n", |
---|
849 | | - __FUNCTION__)); |
---|
| 3703 | + DHD_ERROR(("wl_android_set_pno_setup: pno repeat:" |
---|
| 3704 | + " corrupted field\n")); |
---|
850 | 3705 | goto exit_proc; |
---|
851 | 3706 | } |
---|
852 | 3707 | str_ptr++; |
---|
853 | 3708 | pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); |
---|
854 | | - DHD_PNO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); |
---|
| 3709 | + DHD_PNO(("wl_android_set_pno_setup: got pno_repeat=%d\n", |
---|
| 3710 | + pno_repeat)); |
---|
855 | 3711 | if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { |
---|
856 | | - DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", |
---|
857 | | - __FUNCTION__)); |
---|
| 3712 | + DHD_ERROR(("wl_android_set_pno_setup: FREQ_EXPO_MAX" |
---|
| 3713 | + " corrupted field size\n")); |
---|
858 | 3714 | goto exit_proc; |
---|
859 | 3715 | } |
---|
860 | 3716 | str_ptr++; |
---|
861 | 3717 | pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); |
---|
862 | | - DHD_PNO(("%s: pno_freq_expo_max=%d\n", |
---|
863 | | - __FUNCTION__, pno_freq_expo_max)); |
---|
| 3718 | + DHD_PNO(("wl_android_set_pno_setup: pno_freq_expo_max=%d\n", |
---|
| 3719 | + pno_freq_expo_max)); |
---|
864 | 3720 | } |
---|
865 | 3721 | } |
---|
866 | 3722 | } else { |
---|
867 | | - DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); |
---|
| 3723 | + DHD_ERROR(("wl_android_set_pno_setup: get wrong TLV command\n")); |
---|
868 | 3724 | goto exit_proc; |
---|
869 | 3725 | } |
---|
870 | 3726 | |
---|
.. | .. |
---|
873 | 3729 | exit_proc: |
---|
874 | 3730 | return res; |
---|
875 | 3731 | } |
---|
876 | | -#endif /* !WL_SCHED_SCAN && OEM_ANDROID && WL_WIRELESS_EXT */ |
---|
| 3732 | +#endif /* !WL_SCHED_SCAN */ |
---|
877 | 3733 | #endif /* PNO_SUPPORT */ |
---|
878 | 3734 | |
---|
879 | 3735 | static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len) |
---|
880 | 3736 | { |
---|
881 | 3737 | int ret; |
---|
882 | | - int bytes_written = 0; |
---|
| 3738 | + struct ether_addr p2pdev_addr; |
---|
883 | 3739 | |
---|
884 | | - ret = wl_cfg80211_get_p2p_dev_addr(ndev, (struct ether_addr*)command); |
---|
885 | | - if (ret) |
---|
886 | | - return 0; |
---|
887 | | - bytes_written = sizeof(struct ether_addr); |
---|
888 | | - return bytes_written; |
---|
| 3740 | +#define MAC_ADDR_STR_LEN 18 |
---|
| 3741 | + if (total_len < MAC_ADDR_STR_LEN) { |
---|
| 3742 | + DHD_ERROR(("wl_android_get_p2p_dev_addr: buflen %d is less than p2p dev addr\n", |
---|
| 3743 | + total_len)); |
---|
| 3744 | + return -1; |
---|
| 3745 | + } |
---|
| 3746 | + |
---|
| 3747 | + ret = wl_cfg80211_get_p2p_dev_addr(ndev, &p2pdev_addr); |
---|
| 3748 | + if (ret) { |
---|
| 3749 | + DHD_ERROR(("wl_android_get_p2p_dev_addr: Failed to get p2p dev addr\n")); |
---|
| 3750 | + return -1; |
---|
| 3751 | + } |
---|
| 3752 | + return (snprintf(command, total_len, MACF, ETHERP_TO_MACF(&p2pdev_addr))); |
---|
889 | 3753 | } |
---|
890 | | - |
---|
891 | 3754 | |
---|
892 | 3755 | int |
---|
893 | 3756 | wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct maclist *maclist) |
---|
.. | .. |
---|
899 | 3762 | struct maclist *assoc_maclist = (struct maclist *)mac_buf; |
---|
900 | 3763 | |
---|
901 | 3764 | /* set filtering mode */ |
---|
902 | | - if ((ret = wldev_ioctl(dev, WLC_SET_MACMODE, &macmode, sizeof(macmode), true)) != 0) { |
---|
903 | | - DHD_ERROR(("%s : WLC_SET_MACMODE error=%d\n", __FUNCTION__, ret)); |
---|
| 3765 | + if ((ret = wldev_ioctl_set(dev, WLC_SET_MACMODE, &macmode, sizeof(macmode)) != 0)) { |
---|
| 3766 | + DHD_ERROR(("wl_android_set_ap_mac_list : WLC_SET_MACMODE error=%d\n", ret)); |
---|
904 | 3767 | return ret; |
---|
905 | 3768 | } |
---|
906 | 3769 | if (macmode != MACLIST_MODE_DISABLED) { |
---|
907 | 3770 | /* set the MAC filter list */ |
---|
908 | | - if ((ret = wldev_ioctl(dev, WLC_SET_MACLIST, maclist, |
---|
909 | | - sizeof(int) + sizeof(struct ether_addr) * maclist->count, true)) != 0) { |
---|
910 | | - DHD_ERROR(("%s : WLC_SET_MACLIST error=%d\n", __FUNCTION__, ret)); |
---|
| 3771 | + if ((ret = wldev_ioctl_set(dev, WLC_SET_MACLIST, maclist, |
---|
| 3772 | + sizeof(int) + sizeof(struct ether_addr) * maclist->count)) != 0) { |
---|
| 3773 | + DHD_ERROR(("wl_android_set_ap_mac_list : WLC_SET_MACLIST error=%d\n", ret)); |
---|
911 | 3774 | return ret; |
---|
912 | 3775 | } |
---|
913 | 3776 | /* get the current list of associated STAs */ |
---|
914 | 3777 | assoc_maclist->count = MAX_NUM_OF_ASSOCLIST; |
---|
915 | | - if ((ret = wldev_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, |
---|
916 | | - sizeof(mac_buf), false)) != 0) { |
---|
917 | | - DHD_ERROR(("%s : WLC_GET_ASSOCLIST error=%d\n", __FUNCTION__, ret)); |
---|
| 3778 | + if ((ret = wldev_ioctl_get(dev, WLC_GET_ASSOCLIST, assoc_maclist, |
---|
| 3779 | + sizeof(mac_buf))) != 0) { |
---|
| 3780 | + DHD_ERROR(("wl_android_set_ap_mac_list: WLC_GET_ASSOCLIST error=%d\n", |
---|
| 3781 | + ret)); |
---|
918 | 3782 | return ret; |
---|
919 | 3783 | } |
---|
920 | 3784 | /* do we have any STA associated? */ |
---|
.. | .. |
---|
924 | 3788 | match = 0; |
---|
925 | 3789 | /* compare with each entry */ |
---|
926 | 3790 | for (j = 0; j < maclist->count; j++) { |
---|
927 | | - DHD_INFO(("%s : associated="MACDBG " list="MACDBG "\n", |
---|
928 | | - __FUNCTION__, MAC2STRDBG(assoc_maclist->ea[i].octet), |
---|
| 3791 | + DHD_INFO(("wl_android_set_ap_mac_list: associated="MACDBG |
---|
| 3792 | + "list = "MACDBG "\n", |
---|
| 3793 | + MAC2STRDBG(assoc_maclist->ea[i].octet), |
---|
929 | 3794 | MAC2STRDBG(maclist->ea[j].octet))); |
---|
930 | 3795 | if (memcmp(assoc_maclist->ea[i].octet, |
---|
931 | 3796 | maclist->ea[j].octet, ETHER_ADDR_LEN) == 0) { |
---|
.. | .. |
---|
942 | 3807 | scbval.val = htod32(1); |
---|
943 | 3808 | memcpy(&scbval.ea, &assoc_maclist->ea[i], |
---|
944 | 3809 | ETHER_ADDR_LEN); |
---|
945 | | - if ((ret = wldev_ioctl(dev, |
---|
| 3810 | + if ((ret = wldev_ioctl_set(dev, |
---|
946 | 3811 | WLC_SCB_DEAUTHENTICATE_FOR_REASON, |
---|
947 | | - &scbval, sizeof(scb_val_t), true)) != 0) |
---|
948 | | - DHD_ERROR(("%s WLC_SCB_DEAUTHENTICATE error=%d\n", |
---|
949 | | - __FUNCTION__, ret)); |
---|
| 3812 | + &scbval, sizeof(scb_val_t))) != 0) |
---|
| 3813 | + DHD_ERROR(("wl_android_set_ap_mac_list:" |
---|
| 3814 | + " WLC_SCB_DEAUTHENTICATE" |
---|
| 3815 | + " error=%d\n", |
---|
| 3816 | + ret)); |
---|
950 | 3817 | } |
---|
951 | 3818 | } |
---|
952 | 3819 | } |
---|
.. | .. |
---|
958 | 3825 | * HAPD_MAC_FILTER mac_mode mac_cnt mac_addr1 mac_addr2 |
---|
959 | 3826 | * |
---|
960 | 3827 | */ |
---|
961 | | -static int |
---|
962 | | -wl_android_set_mac_address_filter(struct net_device *dev, const char* str) |
---|
963 | | -{ |
---|
964 | | - int i; |
---|
965 | | - int ret = 0; |
---|
966 | | - int macnum = 0; |
---|
967 | | - int macmode = MACLIST_MODE_DISABLED; |
---|
968 | | - struct maclist *list; |
---|
969 | | - char eabuf[ETHER_ADDR_STR_LEN]; |
---|
970 | | - char *token; |
---|
971 | | - |
---|
972 | | - /* string should look like below (macmode/macnum/maclist) */ |
---|
973 | | - /* 1 2 00:11:22:33:44:55 00:11:22:33:44:ff */ |
---|
974 | | - |
---|
975 | | - /* get the MAC filter mode */ |
---|
976 | | - token = strsep((char**)&str, " "); |
---|
977 | | - if (!token) { |
---|
978 | | - return -1; |
---|
979 | | - } |
---|
980 | | - macmode = bcm_atoi(token); |
---|
981 | | - |
---|
982 | | - if (macmode < MACLIST_MODE_DISABLED || macmode > MACLIST_MODE_ALLOW) { |
---|
983 | | - DHD_ERROR(("%s : invalid macmode %d\n", __FUNCTION__, macmode)); |
---|
984 | | - return -1; |
---|
985 | | - } |
---|
986 | | - |
---|
987 | | - token = strsep((char**)&str, " "); |
---|
988 | | - if (!token) { |
---|
989 | | - return -1; |
---|
990 | | - } |
---|
991 | | - macnum = bcm_atoi(token); |
---|
992 | | - if (macnum < 0 || macnum > MAX_NUM_MAC_FILT) { |
---|
993 | | - DHD_ERROR(("%s : invalid number of MAC address entries %d\n", |
---|
994 | | - __FUNCTION__, macnum)); |
---|
995 | | - return -1; |
---|
996 | | - } |
---|
997 | | - /* allocate memory for the MAC list */ |
---|
998 | | - list = (struct maclist*)kmalloc(sizeof(int) + |
---|
999 | | - sizeof(struct ether_addr) * macnum, GFP_KERNEL); |
---|
1000 | | - if (!list) { |
---|
1001 | | - DHD_ERROR(("%s : failed to allocate memory\n", __FUNCTION__)); |
---|
1002 | | - return -1; |
---|
1003 | | - } |
---|
1004 | | - /* prepare the MAC list */ |
---|
1005 | | - list->count = htod32(macnum); |
---|
1006 | | - bzero((char *)eabuf, ETHER_ADDR_STR_LEN); |
---|
1007 | | - for (i = 0; i < list->count; i++) { |
---|
1008 | | - strncpy(eabuf, strsep((char**)&str, " "), ETHER_ADDR_STR_LEN - 1); |
---|
1009 | | - if (!(ret = bcm_ether_atoe(eabuf, &list->ea[i]))) { |
---|
1010 | | - DHD_ERROR(("%s : mac parsing err index=%d, addr=%s\n", |
---|
1011 | | - __FUNCTION__, i, eabuf)); |
---|
1012 | | - list->count--; |
---|
1013 | | - break; |
---|
1014 | | - } |
---|
1015 | | - DHD_INFO(("%s : %d/%d MACADDR=%s", __FUNCTION__, i, list->count, eabuf)); |
---|
1016 | | - } |
---|
1017 | | - /* set the list */ |
---|
1018 | | - if ((ret = wl_android_set_ap_mac_list(dev, macmode, list)) != 0) |
---|
1019 | | - DHD_ERROR(("%s : Setting MAC list failed error=%d\n", __FUNCTION__, ret)); |
---|
1020 | | - |
---|
1021 | | - kfree(list); |
---|
1022 | | - |
---|
1023 | | - return 0; |
---|
1024 | | -} |
---|
1025 | | - |
---|
1026 | 3828 | /** |
---|
1027 | 3829 | * Global function definitions (declared in wl_android.h) |
---|
1028 | 3830 | */ |
---|
.. | .. |
---|
1032 | 3834 | int ret = 0; |
---|
1033 | 3835 | int retry = POWERUP_MAX_RETRY; |
---|
1034 | 3836 | |
---|
1035 | | - DHD_ERROR(("%s in\n", __FUNCTION__)); |
---|
| 3837 | + DHD_ERROR(("wl_android_wifi_on in\n")); |
---|
1036 | 3838 | if (!dev) { |
---|
1037 | | - DHD_ERROR(("%s: dev is null\n", __FUNCTION__)); |
---|
| 3839 | + DHD_ERROR(("wl_android_wifi_on: dev is null\n")); |
---|
1038 | 3840 | return -EINVAL; |
---|
1039 | 3841 | } |
---|
1040 | 3842 | |
---|
.. | .. |
---|
1060 | 3862 | } while (retry-- > 0); |
---|
1061 | 3863 | if (ret != 0) { |
---|
1062 | 3864 | DHD_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n")); |
---|
| 3865 | +#ifdef BCM_DETECT_TURN_ON_FAILURE |
---|
| 3866 | + BUG_ON(1); |
---|
| 3867 | +#endif /* BCM_DETECT_TURN_ON_FAILURE */ |
---|
1063 | 3868 | goto exit; |
---|
1064 | 3869 | } |
---|
1065 | 3870 | #ifdef BCMSDIO |
---|
.. | .. |
---|
1087 | 3892 | { |
---|
1088 | 3893 | int ret = 0; |
---|
1089 | 3894 | |
---|
1090 | | - DHD_ERROR(("%s in\n", __FUNCTION__)); |
---|
| 3895 | + DHD_ERROR(("wl_android_wifi_off in\n")); |
---|
1091 | 3896 | if (!dev) { |
---|
1092 | | - DHD_TRACE(("%s: dev is null\n", __FUNCTION__)); |
---|
| 3897 | + DHD_TRACE(("wl_android_wifi_off: dev is null\n")); |
---|
1093 | 3898 | return -EINVAL; |
---|
1094 | 3899 | } |
---|
1095 | 3900 | |
---|
| 3901 | +#if defined(BCMPCIE) && defined(DHD_DEBUG_UART) |
---|
| 3902 | + ret = dhd_debug_uart_is_running(dev); |
---|
| 3903 | + if (ret) { |
---|
| 3904 | + DHD_ERROR(("wl_android_wifi_off: - Debug UART App is running\n")); |
---|
| 3905 | + return -EBUSY; |
---|
| 3906 | + } |
---|
| 3907 | +#endif /* BCMPCIE && DHD_DEBUG_UART */ |
---|
1096 | 3908 | dhd_net_if_lock(dev); |
---|
1097 | 3909 | if (g_wifi_on || on_failure) { |
---|
1098 | 3910 | #if defined(BCMSDIO) || defined(BCMPCIE) |
---|
.. | .. |
---|
1127 | 3939 | u8 result[WLC_IOCTL_SMLEN]; |
---|
1128 | 3940 | chanim_stats_t *stats; |
---|
1129 | 3941 | |
---|
1130 | | - memset(¶m, 0, sizeof(param)); |
---|
| 3942 | + bzero(¶m, sizeof(param)); |
---|
1131 | 3943 | |
---|
1132 | 3944 | param.buflen = htod32(sizeof(wl_chanim_stats_t)); |
---|
1133 | 3945 | param.count = htod32(WL_CHANIM_COUNT_ONE); |
---|
.. | .. |
---|
1175 | 3987 | wl_android_get_connection_stats(struct net_device *dev, char *command, int total_len) |
---|
1176 | 3988 | { |
---|
1177 | 3989 | static char iovar_buf[WLC_IOCTL_MAXLEN]; |
---|
1178 | | - wl_cnt_wlc_t* wlc_cnt = NULL; |
---|
| 3990 | + const wl_cnt_wlc_t* wlc_cnt = NULL; |
---|
1179 | 3991 | #ifndef DISABLE_IF_COUNTERS |
---|
1180 | 3992 | wl_if_stats_t* if_stats = NULL; |
---|
| 3993 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 3994 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
1181 | 3995 | #endif /* DISABLE_IF_COUNTERS */ |
---|
1182 | 3996 | |
---|
1183 | 3997 | int link_speed = 0; |
---|
.. | .. |
---|
1186 | 4000 | int bytes_written = -1; |
---|
1187 | 4001 | int ret = 0; |
---|
1188 | 4002 | |
---|
1189 | | - WL_INFORM(("%s: enter Get Connection Stats\n", __FUNCTION__)); |
---|
| 4003 | + WL_INFORM(("wl_android_get_connection_stats: enter Get Connection Stats\n")); |
---|
1190 | 4004 | |
---|
1191 | 4005 | if (total_len <= 0) { |
---|
1192 | | - WL_ERR(("%s: invalid buffer size %d\n", __FUNCTION__, total_len)); |
---|
| 4006 | + WL_ERR(("wl_android_get_connection_stats: invalid buffer size %d\n", total_len)); |
---|
1193 | 4007 | goto error; |
---|
1194 | 4008 | } |
---|
1195 | 4009 | |
---|
1196 | 4010 | bufsize = total_len; |
---|
1197 | 4011 | if (bufsize < sizeof(struct connection_stats)) { |
---|
1198 | | - WL_ERR(("%s: not enough buffer size, provided=%u, requires=%zu\n", |
---|
1199 | | - __FUNCTION__, bufsize, |
---|
| 4012 | + WL_ERR(("wl_android_get_connection_stats: not enough buffer size, provided=%u," |
---|
| 4013 | + " requires=%zu\n", |
---|
| 4014 | + bufsize, |
---|
1200 | 4015 | sizeof(struct connection_stats))); |
---|
1201 | 4016 | goto error; |
---|
1202 | 4017 | } |
---|
.. | .. |
---|
1204 | 4019 | output = (struct connection_stats *)command; |
---|
1205 | 4020 | |
---|
1206 | 4021 | #ifndef DISABLE_IF_COUNTERS |
---|
1207 | | - if ((if_stats = kmalloc(sizeof(*if_stats), GFP_KERNEL)) == NULL) { |
---|
1208 | | - WL_ERR(("%s(%d): kmalloc failed\n", __FUNCTION__, __LINE__)); |
---|
| 4022 | + if_stats = (wl_if_stats_t *)MALLOCZ(cfg->osh, sizeof(*if_stats)); |
---|
| 4023 | + if (if_stats == NULL) { |
---|
| 4024 | + WL_ERR(("wl_android_get_connection_stats: MALLOCZ failed\n")); |
---|
1209 | 4025 | goto error; |
---|
1210 | 4026 | } |
---|
1211 | | - memset(if_stats, 0, sizeof(*if_stats)); |
---|
| 4027 | + bzero(if_stats, sizeof(*if_stats)); |
---|
| 4028 | + |
---|
| 4029 | + if (FW_SUPPORTED(dhdp, ifst)) { |
---|
| 4030 | + ret = wl_cfg80211_ifstats_counters(dev, if_stats); |
---|
| 4031 | + } else |
---|
| 4032 | + { |
---|
| 4033 | + ret = wldev_iovar_getbuf(dev, "if_counters", NULL, 0, |
---|
| 4034 | + (char *)if_stats, sizeof(*if_stats), NULL); |
---|
| 4035 | + } |
---|
1212 | 4036 | |
---|
1213 | 4037 | ret = wldev_iovar_getbuf(dev, "if_counters", NULL, 0, |
---|
1214 | 4038 | (char *)if_stats, sizeof(*if_stats), NULL); |
---|
1215 | 4039 | if (ret) { |
---|
1216 | | - WL_ERR(("%s: if_counters not supported ret=%d\n", |
---|
1217 | | - __FUNCTION__, ret)); |
---|
| 4040 | + WL_ERR(("wl_android_get_connection_stats: if_counters not supported ret=%d\n", |
---|
| 4041 | + ret)); |
---|
1218 | 4042 | |
---|
1219 | 4043 | /* In case if_stats IOVAR is not supported, get information from counters. */ |
---|
1220 | 4044 | #endif /* DISABLE_IF_COUNTERS */ |
---|
.. | .. |
---|
1226 | 4050 | } |
---|
1227 | 4051 | ret = wl_cntbuf_to_xtlv_format(NULL, iovar_buf, WL_CNTBUF_MAX_SIZE, 0); |
---|
1228 | 4052 | if (ret != BCME_OK) { |
---|
1229 | | - WL_ERR(("%s wl_cntbuf_to_xtlv_format ERR %d\n", |
---|
1230 | | - __FUNCTION__, ret)); |
---|
| 4053 | + WL_ERR(("wl_android_get_connection_stats:" |
---|
| 4054 | + " wl_cntbuf_to_xtlv_format ERR %d\n", |
---|
| 4055 | + ret)); |
---|
1231 | 4056 | goto error; |
---|
1232 | 4057 | } |
---|
1233 | 4058 | |
---|
1234 | 4059 | if (!(wlc_cnt = GET_WLCCNT_FROM_CNTBUF(iovar_buf))) { |
---|
1235 | | - WL_ERR(("%s wlc_cnt NULL!\n", __FUNCTION__)); |
---|
| 4060 | + WL_ERR(("wl_android_get_connection_stats: wlc_cnt NULL!\n")); |
---|
1236 | 4061 | goto error; |
---|
1237 | 4062 | } |
---|
1238 | 4063 | |
---|
.. | .. |
---|
1251 | 4076 | } else { |
---|
1252 | 4077 | /* Populate from if_stats. */ |
---|
1253 | 4078 | if (dtoh16(if_stats->version) > WL_IF_STATS_T_VERSION) { |
---|
1254 | | - WL_ERR(("%s: incorrect version of wl_if_stats_t, expected=%u got=%u\n", |
---|
1255 | | - __FUNCTION__, WL_IF_STATS_T_VERSION, if_stats->version)); |
---|
| 4079 | + WL_ERR(("wl_android_get_connection_stats: incorrect version of" |
---|
| 4080 | + " wl_if_stats_t," |
---|
| 4081 | + " expected=%u got=%u\n", |
---|
| 4082 | + WL_IF_STATS_T_VERSION, if_stats->version)); |
---|
1256 | 4083 | goto error; |
---|
1257 | 4084 | } |
---|
1258 | 4085 | |
---|
.. | .. |
---|
1279 | 4106 | /* link_speed is in kbps */ |
---|
1280 | 4107 | ret = wldev_get_link_speed(dev, &link_speed); |
---|
1281 | 4108 | if (ret || link_speed < 0) { |
---|
1282 | | - WL_ERR(("%s: wldev_get_link_speed() failed, ret=%d, speed=%d\n", |
---|
1283 | | - __FUNCTION__, ret, link_speed)); |
---|
| 4109 | + WL_ERR(("wl_android_get_connection_stats: wldev_get_link_speed()" |
---|
| 4110 | + " failed, ret=%d, speed=%d\n", |
---|
| 4111 | + ret, link_speed)); |
---|
1284 | 4112 | goto error; |
---|
1285 | 4113 | } |
---|
1286 | 4114 | |
---|
.. | .. |
---|
1296 | 4124 | error: |
---|
1297 | 4125 | #ifndef DISABLE_IF_COUNTERS |
---|
1298 | 4126 | if (if_stats) { |
---|
1299 | | - kfree(if_stats); |
---|
| 4127 | + MFREE(cfg->osh, if_stats, sizeof(*if_stats)); |
---|
1300 | 4128 | } |
---|
1301 | 4129 | #endif /* DISABLE_IF_COUNTERS */ |
---|
1302 | 4130 | |
---|
.. | .. |
---|
1304 | 4132 | } |
---|
1305 | 4133 | #endif /* CONNECTION_STATISTICS */ |
---|
1306 | 4134 | |
---|
| 4135 | +#ifdef WL_NATOE |
---|
1307 | 4136 | static int |
---|
1308 | | -wl_android_set_pmk(struct net_device *dev, char *command, int total_len) |
---|
| 4137 | +wl_android_process_natoe_cmd(struct net_device *dev, char *command, int total_len) |
---|
1309 | 4138 | { |
---|
1310 | | - uchar pmk[33]; |
---|
1311 | | - int error = 0; |
---|
1312 | | - char smbuf[WLC_IOCTL_SMLEN]; |
---|
1313 | | -#ifdef OKC_DEBUG |
---|
1314 | | - int i = 0; |
---|
1315 | | -#endif |
---|
| 4139 | + int ret = BCME_ERROR; |
---|
| 4140 | + char *pcmd = command; |
---|
| 4141 | + char *str = NULL; |
---|
| 4142 | + wl_natoe_cmd_info_t cmd_info; |
---|
| 4143 | + const wl_natoe_sub_cmd_t *natoe_cmd = &natoe_cmd_list[0]; |
---|
1316 | 4144 | |
---|
1317 | | - bzero(pmk, sizeof(pmk)); |
---|
1318 | | - memcpy((char *)pmk, command + strlen("SET_PMK "), 32); |
---|
1319 | | - error = wldev_iovar_setbuf(dev, "okc_info_pmk", pmk, 32, smbuf, sizeof(smbuf), NULL); |
---|
1320 | | - if (error) { |
---|
1321 | | - DHD_ERROR(("Failed to set PMK for OKC, error = %d\n", error)); |
---|
| 4145 | + /* skip to cmd name after "natoe" */ |
---|
| 4146 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4147 | + |
---|
| 4148 | + /* If natoe subcmd name is not provided, return error */ |
---|
| 4149 | + if (*pcmd == '\0') { |
---|
| 4150 | + WL_ERR(("natoe subcmd not provided wl_android_process_natoe_cmd\n")); |
---|
| 4151 | + ret = -EINVAL; |
---|
| 4152 | + return ret; |
---|
1322 | 4153 | } |
---|
1323 | | -#ifdef OKC_DEBUG |
---|
1324 | | - DHD_ERROR(("PMK is ")); |
---|
1325 | | - for (i = 0; i < 32; i++) |
---|
1326 | | - DHD_ERROR(("%02X ", pmk[i])); |
---|
1327 | 4154 | |
---|
1328 | | - DHD_ERROR(("\n")); |
---|
1329 | | -#endif |
---|
1330 | | - return error; |
---|
| 4155 | + /* get the natoe command name to str */ |
---|
| 4156 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4157 | + |
---|
| 4158 | + while (natoe_cmd->name != NULL) { |
---|
| 4159 | + if (strcmp(natoe_cmd->name, str) == 0) { |
---|
| 4160 | + /* dispacth cmd to appropriate handler */ |
---|
| 4161 | + if (natoe_cmd->handler) { |
---|
| 4162 | + cmd_info.command = command; |
---|
| 4163 | + cmd_info.tot_len = total_len; |
---|
| 4164 | + ret = natoe_cmd->handler(dev, natoe_cmd, pcmd, &cmd_info); |
---|
| 4165 | + } |
---|
| 4166 | + return ret; |
---|
| 4167 | + } |
---|
| 4168 | + natoe_cmd++; |
---|
| 4169 | + } |
---|
| 4170 | + return ret; |
---|
1331 | 4171 | } |
---|
1332 | 4172 | |
---|
1333 | 4173 | static int |
---|
1334 | | -wl_android_okc_enable(struct net_device *dev, char *command, int total_len) |
---|
| 4174 | +wlu_natoe_set_vars_cbfn(void *ctx, uint8 *data, uint16 type, uint16 len) |
---|
1335 | 4175 | { |
---|
1336 | | - int error = 0; |
---|
1337 | | - char okc_enable = 0; |
---|
| 4176 | + int res = BCME_OK; |
---|
| 4177 | + wl_natoe_cmd_info_t *cmd_info = (wl_natoe_cmd_info_t *)ctx; |
---|
| 4178 | + uint8 *command = cmd_info->command; |
---|
| 4179 | + uint16 total_len = cmd_info->tot_len; |
---|
| 4180 | + uint16 bytes_written = 0; |
---|
1338 | 4181 | |
---|
1339 | | - okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0'; |
---|
1340 | | - error = wldev_iovar_setint(dev, "okc_enable", okc_enable); |
---|
1341 | | - if (error) { |
---|
1342 | | - DHD_ERROR(("Failed to %s OKC, error = %d\n", |
---|
1343 | | - okc_enable ? "enable" : "disable", error)); |
---|
1344 | | - return error; |
---|
| 4182 | + UNUSED_PARAMETER(len); |
---|
| 4183 | + |
---|
| 4184 | + switch (type) { |
---|
| 4185 | + |
---|
| 4186 | + case WL_NATOE_XTLV_ENABLE: |
---|
| 4187 | + { |
---|
| 4188 | + bytes_written = snprintf(command, total_len, "natoe: %s\n", |
---|
| 4189 | + *data?"enabled":"disabled"); |
---|
| 4190 | + cmd_info->bytes_written = bytes_written; |
---|
| 4191 | + break; |
---|
1345 | 4192 | } |
---|
1346 | 4193 | |
---|
1347 | | - error = wldev_iovar_setint(dev, "ccx_enable", 0); |
---|
1348 | | - if (error) { |
---|
1349 | | - DHD_ERROR(("Failed to disable CCX %d\n", error)); |
---|
| 4194 | + case WL_NATOE_XTLV_CONFIG_IPS: |
---|
| 4195 | + { |
---|
| 4196 | + wl_natoe_config_ips_t *config_ips; |
---|
| 4197 | + uint8 buf[16]; |
---|
| 4198 | + |
---|
| 4199 | + config_ips = (wl_natoe_config_ips_t *)data; |
---|
| 4200 | + bcm_ip_ntoa((struct ipv4_addr *)&config_ips->sta_ip, buf); |
---|
| 4201 | + bytes_written = snprintf(command, total_len, "sta ip: %s\n", buf); |
---|
| 4202 | + bcm_ip_ntoa((struct ipv4_addr *)&config_ips->sta_netmask, buf); |
---|
| 4203 | + bytes_written += snprintf(command + bytes_written, total_len, |
---|
| 4204 | + "sta netmask: %s\n", buf); |
---|
| 4205 | + bcm_ip_ntoa((struct ipv4_addr *)&config_ips->sta_router_ip, buf); |
---|
| 4206 | + bytes_written += snprintf(command + bytes_written, total_len, |
---|
| 4207 | + "sta router ip: %s\n", buf); |
---|
| 4208 | + bcm_ip_ntoa((struct ipv4_addr *)&config_ips->sta_dnsip, buf); |
---|
| 4209 | + bytes_written += snprintf(command + bytes_written, total_len, |
---|
| 4210 | + "sta dns ip: %s\n", buf); |
---|
| 4211 | + bcm_ip_ntoa((struct ipv4_addr *)&config_ips->ap_ip, buf); |
---|
| 4212 | + bytes_written += snprintf(command + bytes_written, total_len, |
---|
| 4213 | + "ap ip: %s\n", buf); |
---|
| 4214 | + bcm_ip_ntoa((struct ipv4_addr *)&config_ips->ap_netmask, buf); |
---|
| 4215 | + bytes_written += snprintf(command + bytes_written, total_len, |
---|
| 4216 | + "ap netmask: %s\n", buf); |
---|
| 4217 | + cmd_info->bytes_written = bytes_written; |
---|
| 4218 | + break; |
---|
1350 | 4219 | } |
---|
1351 | 4220 | |
---|
1352 | | - return error; |
---|
| 4221 | + case WL_NATOE_XTLV_CONFIG_PORTS: |
---|
| 4222 | + { |
---|
| 4223 | + wl_natoe_ports_config_t *ports_config; |
---|
| 4224 | + |
---|
| 4225 | + ports_config = (wl_natoe_ports_config_t *)data; |
---|
| 4226 | + bytes_written = snprintf(command, total_len, "starting port num: %d\n", |
---|
| 4227 | + dtoh16(ports_config->start_port_num)); |
---|
| 4228 | + bytes_written += snprintf(command + bytes_written, total_len, |
---|
| 4229 | + "number of ports: %d\n", dtoh16(ports_config->no_of_ports)); |
---|
| 4230 | + cmd_info->bytes_written = bytes_written; |
---|
| 4231 | + break; |
---|
| 4232 | + } |
---|
| 4233 | + |
---|
| 4234 | + case WL_NATOE_XTLV_DBG_STATS: |
---|
| 4235 | + { |
---|
| 4236 | + char *stats_dump = (char *)data; |
---|
| 4237 | + |
---|
| 4238 | + bytes_written = snprintf(command, total_len, "%s\n", stats_dump); |
---|
| 4239 | + cmd_info->bytes_written = bytes_written; |
---|
| 4240 | + break; |
---|
| 4241 | + } |
---|
| 4242 | + |
---|
| 4243 | + case WL_NATOE_XTLV_TBL_CNT: |
---|
| 4244 | + { |
---|
| 4245 | + bytes_written = snprintf(command, total_len, "natoe max tbl entries: %d\n", |
---|
| 4246 | + dtoh32(*(uint32 *)data)); |
---|
| 4247 | + cmd_info->bytes_written = bytes_written; |
---|
| 4248 | + break; |
---|
| 4249 | + } |
---|
| 4250 | + |
---|
| 4251 | + default: |
---|
| 4252 | + /* ignore */ |
---|
| 4253 | + break; |
---|
| 4254 | + } |
---|
| 4255 | + |
---|
| 4256 | + return res; |
---|
1353 | 4257 | } |
---|
1354 | 4258 | |
---|
| 4259 | +/* |
---|
| 4260 | + * --- common for all natoe get commands ---- |
---|
| 4261 | + */ |
---|
| 4262 | +static int |
---|
| 4263 | +wl_natoe_get_ioctl(struct net_device *dev, wl_natoe_ioc_t *natoe_ioc, |
---|
| 4264 | + uint16 iocsz, uint8 *buf, uint16 buflen, wl_natoe_cmd_info_t *cmd_info) |
---|
| 4265 | +{ |
---|
| 4266 | + /* for gets we only need to pass ioc header */ |
---|
| 4267 | + wl_natoe_ioc_t *iocresp = (wl_natoe_ioc_t *)buf; |
---|
| 4268 | + int res; |
---|
1355 | 4269 | |
---|
| 4270 | + /* send getbuf natoe iovar */ |
---|
| 4271 | + res = wldev_iovar_getbuf(dev, "natoe", natoe_ioc, iocsz, buf, |
---|
| 4272 | + buflen, NULL); |
---|
1356 | 4273 | |
---|
| 4274 | + /* check the response buff */ |
---|
| 4275 | + if ((res == BCME_OK)) { |
---|
| 4276 | + /* scans ioctl tlvbuf f& invokes the cbfn for processing */ |
---|
| 4277 | + res = bcm_unpack_xtlv_buf(cmd_info, iocresp->data, iocresp->len, |
---|
| 4278 | + BCM_XTLV_OPTION_ALIGN32, wlu_natoe_set_vars_cbfn); |
---|
| 4279 | + |
---|
| 4280 | + if (res == BCME_OK) { |
---|
| 4281 | + res = cmd_info->bytes_written; |
---|
| 4282 | + } |
---|
| 4283 | + } |
---|
| 4284 | + else |
---|
| 4285 | + { |
---|
| 4286 | + DHD_ERROR(("wl_natoe_get_ioctl: get command failed code %d\n", res)); |
---|
| 4287 | + res = BCME_ERROR; |
---|
| 4288 | + } |
---|
| 4289 | + |
---|
| 4290 | + return res; |
---|
| 4291 | +} |
---|
| 4292 | + |
---|
| 4293 | +static int |
---|
| 4294 | +wl_android_natoe_subcmd_enable(struct net_device *dev, const wl_natoe_sub_cmd_t *cmd, |
---|
| 4295 | + char *command, wl_natoe_cmd_info_t *cmd_info) |
---|
| 4296 | +{ |
---|
| 4297 | + int ret = BCME_OK; |
---|
| 4298 | + wl_natoe_ioc_t *natoe_ioc; |
---|
| 4299 | + char *pcmd = command; |
---|
| 4300 | + uint16 iocsz = sizeof(*natoe_ioc) + WL_NATOE_IOC_BUFSZ; |
---|
| 4301 | + uint16 buflen = WL_NATOE_IOC_BUFSZ; |
---|
| 4302 | + bcm_xtlv_t *pxtlv = NULL; |
---|
| 4303 | + char *ioctl_buf = NULL; |
---|
| 4304 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 4305 | + |
---|
| 4306 | + ioctl_buf = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 4307 | + if (!ioctl_buf) { |
---|
| 4308 | + WL_ERR(("ioctl memory alloc failed\n")); |
---|
| 4309 | + return -ENOMEM; |
---|
| 4310 | + } |
---|
| 4311 | + |
---|
| 4312 | + /* alloc mem for ioctl headr + tlv data */ |
---|
| 4313 | + natoe_ioc = (wl_natoe_ioc_t *)MALLOCZ(cfg->osh, iocsz); |
---|
| 4314 | + if (!natoe_ioc) { |
---|
| 4315 | + WL_ERR(("ioctl header memory alloc failed\n")); |
---|
| 4316 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 4317 | + return -ENOMEM; |
---|
| 4318 | + } |
---|
| 4319 | + |
---|
| 4320 | + /* make up natoe cmd ioctl header */ |
---|
| 4321 | + natoe_ioc->version = htod16(WL_NATOE_IOCTL_VERSION); |
---|
| 4322 | + natoe_ioc->id = htod16(cmd->id); |
---|
| 4323 | + natoe_ioc->len = htod16(WL_NATOE_IOC_BUFSZ); |
---|
| 4324 | + pxtlv = (bcm_xtlv_t *)natoe_ioc->data; |
---|
| 4325 | + |
---|
| 4326 | + if(*pcmd == WL_IOCTL_ACTION_GET) { /* get */ |
---|
| 4327 | + iocsz = sizeof(*natoe_ioc) + sizeof(*pxtlv); |
---|
| 4328 | + ret = wl_natoe_get_ioctl(dev, natoe_ioc, iocsz, ioctl_buf, |
---|
| 4329 | + WLC_IOCTL_MEDLEN, cmd_info); |
---|
| 4330 | + if (ret != BCME_OK) { |
---|
| 4331 | + WL_ERR(("Fail to get iovar wl_android_natoe_subcmd_enable\n")); |
---|
| 4332 | + ret = -EINVAL; |
---|
| 4333 | + } |
---|
| 4334 | + } else { /* set */ |
---|
| 4335 | + uint8 val = bcm_atoi(pcmd); |
---|
| 4336 | + |
---|
| 4337 | + /* buflen is max tlv data we can write, it will be decremented as we pack */ |
---|
| 4338 | + /* save buflen at start */ |
---|
| 4339 | + uint16 buflen_at_start = buflen; |
---|
| 4340 | + |
---|
| 4341 | + /* we'll adjust final ioc size at the end */ |
---|
| 4342 | + ret = bcm_pack_xtlv_entry((uint8**)&pxtlv, &buflen, WL_NATOE_XTLV_ENABLE, |
---|
| 4343 | + sizeof(uint8), &val, BCM_XTLV_OPTION_ALIGN32); |
---|
| 4344 | + |
---|
| 4345 | + if (ret != BCME_OK) { |
---|
| 4346 | + ret = -EINVAL; |
---|
| 4347 | + goto exit; |
---|
| 4348 | + } |
---|
| 4349 | + |
---|
| 4350 | + /* adjust iocsz to the end of last data record */ |
---|
| 4351 | + natoe_ioc->len = (buflen_at_start - buflen); |
---|
| 4352 | + iocsz = sizeof(*natoe_ioc) + natoe_ioc->len; |
---|
| 4353 | + |
---|
| 4354 | + ret = wldev_iovar_setbuf(dev, "natoe", |
---|
| 4355 | + natoe_ioc, iocsz, ioctl_buf, WLC_IOCTL_MEDLEN, NULL); |
---|
| 4356 | + if (ret != BCME_OK) { |
---|
| 4357 | + WL_ERR(("Fail to set iovar %d\n", ret)); |
---|
| 4358 | + ret = -EINVAL; |
---|
| 4359 | + } |
---|
| 4360 | + } |
---|
| 4361 | + |
---|
| 4362 | +exit: |
---|
| 4363 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 4364 | + MFREE(cfg->osh, natoe_ioc, iocsz); |
---|
| 4365 | + |
---|
| 4366 | + return ret; |
---|
| 4367 | +} |
---|
| 4368 | + |
---|
| 4369 | +static int |
---|
| 4370 | +wl_android_natoe_subcmd_config_ips(struct net_device *dev, |
---|
| 4371 | + const wl_natoe_sub_cmd_t *cmd, char *command, wl_natoe_cmd_info_t *cmd_info) |
---|
| 4372 | +{ |
---|
| 4373 | + int ret = BCME_OK; |
---|
| 4374 | + wl_natoe_config_ips_t config_ips; |
---|
| 4375 | + wl_natoe_ioc_t *natoe_ioc; |
---|
| 4376 | + char *pcmd = command; |
---|
| 4377 | + char *str; |
---|
| 4378 | + uint16 iocsz = sizeof(*natoe_ioc) + WL_NATOE_IOC_BUFSZ; |
---|
| 4379 | + uint16 buflen = WL_NATOE_IOC_BUFSZ; |
---|
| 4380 | + bcm_xtlv_t *pxtlv = NULL; |
---|
| 4381 | + char *ioctl_buf = NULL; |
---|
| 4382 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 4383 | + |
---|
| 4384 | + ioctl_buf = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 4385 | + if (!ioctl_buf) { |
---|
| 4386 | + WL_ERR(("ioctl memory alloc failed\n")); |
---|
| 4387 | + return -ENOMEM; |
---|
| 4388 | + } |
---|
| 4389 | + |
---|
| 4390 | + /* alloc mem for ioctl headr + tlv data */ |
---|
| 4391 | + natoe_ioc = (wl_natoe_ioc_t *)MALLOCZ(cfg->osh, iocsz); |
---|
| 4392 | + if (!natoe_ioc) { |
---|
| 4393 | + WL_ERR(("ioctl header memory alloc failed\n")); |
---|
| 4394 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 4395 | + return -ENOMEM; |
---|
| 4396 | + } |
---|
| 4397 | + |
---|
| 4398 | + /* make up natoe cmd ioctl header */ |
---|
| 4399 | + natoe_ioc->version = htod16(WL_NATOE_IOCTL_VERSION); |
---|
| 4400 | + natoe_ioc->id = htod16(cmd->id); |
---|
| 4401 | + natoe_ioc->len = htod16(WL_NATOE_IOC_BUFSZ); |
---|
| 4402 | + pxtlv = (bcm_xtlv_t *)natoe_ioc->data; |
---|
| 4403 | + |
---|
| 4404 | + if(*pcmd == WL_IOCTL_ACTION_GET) { /* get */ |
---|
| 4405 | + iocsz = sizeof(*natoe_ioc) + sizeof(*pxtlv); |
---|
| 4406 | + ret = wl_natoe_get_ioctl(dev, natoe_ioc, iocsz, ioctl_buf, |
---|
| 4407 | + WLC_IOCTL_MEDLEN, cmd_info); |
---|
| 4408 | + if (ret != BCME_OK) { |
---|
| 4409 | + WL_ERR(("Fail to get iovar wl_android_natoe_subcmd_config_ips\n")); |
---|
| 4410 | + ret = -EINVAL; |
---|
| 4411 | + } |
---|
| 4412 | + } else { /* set */ |
---|
| 4413 | + /* buflen is max tlv data we can write, it will be decremented as we pack */ |
---|
| 4414 | + /* save buflen at start */ |
---|
| 4415 | + uint16 buflen_at_start = buflen; |
---|
| 4416 | + |
---|
| 4417 | + bzero(&config_ips, sizeof(config_ips)); |
---|
| 4418 | + |
---|
| 4419 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4420 | + if (!str || !bcm_atoipv4(str, (struct ipv4_addr *)&config_ips.sta_ip)) { |
---|
| 4421 | + WL_ERR(("Invalid STA IP addr %s\n", str)); |
---|
| 4422 | + ret = -EINVAL; |
---|
| 4423 | + goto exit; |
---|
| 4424 | + } |
---|
| 4425 | + |
---|
| 4426 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4427 | + if (!str || !bcm_atoipv4(str, (struct ipv4_addr *)&config_ips.sta_netmask)) { |
---|
| 4428 | + WL_ERR(("Invalid STA netmask %s\n", str)); |
---|
| 4429 | + ret = -EINVAL; |
---|
| 4430 | + goto exit; |
---|
| 4431 | + } |
---|
| 4432 | + |
---|
| 4433 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4434 | + if (!str || !bcm_atoipv4(str, (struct ipv4_addr *)&config_ips.sta_router_ip)) { |
---|
| 4435 | + WL_ERR(("Invalid STA router IP addr %s\n", str)); |
---|
| 4436 | + ret = -EINVAL; |
---|
| 4437 | + goto exit; |
---|
| 4438 | + } |
---|
| 4439 | + |
---|
| 4440 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4441 | + if (!str || !bcm_atoipv4(str, (struct ipv4_addr *)&config_ips.sta_dnsip)) { |
---|
| 4442 | + WL_ERR(("Invalid STA DNS IP addr %s\n", str)); |
---|
| 4443 | + ret = -EINVAL; |
---|
| 4444 | + goto exit; |
---|
| 4445 | + } |
---|
| 4446 | + |
---|
| 4447 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4448 | + if (!str || !bcm_atoipv4(str, (struct ipv4_addr *)&config_ips.ap_ip)) { |
---|
| 4449 | + WL_ERR(("Invalid AP IP addr %s\n", str)); |
---|
| 4450 | + ret = -EINVAL; |
---|
| 4451 | + goto exit; |
---|
| 4452 | + } |
---|
| 4453 | + |
---|
| 4454 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4455 | + if (!str || !bcm_atoipv4(str, (struct ipv4_addr *)&config_ips.ap_netmask)) { |
---|
| 4456 | + WL_ERR(("Invalid AP netmask %s\n", str)); |
---|
| 4457 | + ret = -EINVAL; |
---|
| 4458 | + goto exit; |
---|
| 4459 | + } |
---|
| 4460 | + |
---|
| 4461 | + ret = bcm_pack_xtlv_entry((uint8**)&pxtlv, |
---|
| 4462 | + &buflen, WL_NATOE_XTLV_CONFIG_IPS, sizeof(config_ips), |
---|
| 4463 | + &config_ips, BCM_XTLV_OPTION_ALIGN32); |
---|
| 4464 | + |
---|
| 4465 | + if (ret != BCME_OK) { |
---|
| 4466 | + ret = -EINVAL; |
---|
| 4467 | + goto exit; |
---|
| 4468 | + } |
---|
| 4469 | + |
---|
| 4470 | + /* adjust iocsz to the end of last data record */ |
---|
| 4471 | + natoe_ioc->len = (buflen_at_start - buflen); |
---|
| 4472 | + iocsz = sizeof(*natoe_ioc) + natoe_ioc->len; |
---|
| 4473 | + |
---|
| 4474 | + ret = wldev_iovar_setbuf(dev, "natoe", |
---|
| 4475 | + natoe_ioc, iocsz, ioctl_buf, WLC_IOCTL_MEDLEN, NULL); |
---|
| 4476 | + if (ret != BCME_OK) { |
---|
| 4477 | + WL_ERR(("Fail to set iovar %d\n", ret)); |
---|
| 4478 | + ret = -EINVAL; |
---|
| 4479 | + } |
---|
| 4480 | + } |
---|
| 4481 | + |
---|
| 4482 | +exit: |
---|
| 4483 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 4484 | + MFREE(cfg->osh, natoe_ioc, sizeof(*natoe_ioc) + WL_NATOE_IOC_BUFSZ); |
---|
| 4485 | + |
---|
| 4486 | + return ret; |
---|
| 4487 | +} |
---|
| 4488 | + |
---|
| 4489 | +static int |
---|
| 4490 | +wl_android_natoe_subcmd_config_ports(struct net_device *dev, |
---|
| 4491 | + const wl_natoe_sub_cmd_t *cmd, char *command, wl_natoe_cmd_info_t *cmd_info) |
---|
| 4492 | +{ |
---|
| 4493 | + int ret = BCME_OK; |
---|
| 4494 | + wl_natoe_ports_config_t ports_config; |
---|
| 4495 | + wl_natoe_ioc_t *natoe_ioc; |
---|
| 4496 | + char *pcmd = command; |
---|
| 4497 | + char *str; |
---|
| 4498 | + uint16 iocsz = sizeof(*natoe_ioc) + WL_NATOE_IOC_BUFSZ; |
---|
| 4499 | + uint16 buflen = WL_NATOE_IOC_BUFSZ; |
---|
| 4500 | + bcm_xtlv_t *pxtlv = NULL; |
---|
| 4501 | + char *ioctl_buf = NULL; |
---|
| 4502 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 4503 | + |
---|
| 4504 | + ioctl_buf = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 4505 | + if (!ioctl_buf) { |
---|
| 4506 | + WL_ERR(("ioctl memory alloc failed\n")); |
---|
| 4507 | + return -ENOMEM; |
---|
| 4508 | + } |
---|
| 4509 | + |
---|
| 4510 | + /* alloc mem for ioctl headr + tlv data */ |
---|
| 4511 | + natoe_ioc = (wl_natoe_ioc_t *)MALLOCZ(cfg->osh, iocsz); |
---|
| 4512 | + if (!natoe_ioc) { |
---|
| 4513 | + WL_ERR(("ioctl header memory alloc failed\n")); |
---|
| 4514 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 4515 | + return -ENOMEM; |
---|
| 4516 | + } |
---|
| 4517 | + |
---|
| 4518 | + /* make up natoe cmd ioctl header */ |
---|
| 4519 | + natoe_ioc->version = htod16(WL_NATOE_IOCTL_VERSION); |
---|
| 4520 | + natoe_ioc->id = htod16(cmd->id); |
---|
| 4521 | + natoe_ioc->len = htod16(WL_NATOE_IOC_BUFSZ); |
---|
| 4522 | + pxtlv = (bcm_xtlv_t *)natoe_ioc->data; |
---|
| 4523 | + |
---|
| 4524 | + if(*pcmd == WL_IOCTL_ACTION_GET) { /* get */ |
---|
| 4525 | + iocsz = sizeof(*natoe_ioc) + sizeof(*pxtlv); |
---|
| 4526 | + ret = wl_natoe_get_ioctl(dev, natoe_ioc, iocsz, ioctl_buf, |
---|
| 4527 | + WLC_IOCTL_MEDLEN, cmd_info); |
---|
| 4528 | + if (ret != BCME_OK) { |
---|
| 4529 | + WL_ERR(("Fail to get iovar wl_android_natoe_subcmd_config_ports\n")); |
---|
| 4530 | + ret = -EINVAL; |
---|
| 4531 | + } |
---|
| 4532 | + } else { /* set */ |
---|
| 4533 | + /* buflen is max tlv data we can write, it will be decremented as we pack */ |
---|
| 4534 | + /* save buflen at start */ |
---|
| 4535 | + uint16 buflen_at_start = buflen; |
---|
| 4536 | + |
---|
| 4537 | + bzero(&ports_config, sizeof(ports_config)); |
---|
| 4538 | + |
---|
| 4539 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4540 | + if (!str) { |
---|
| 4541 | + WL_ERR(("Invalid port string %s\n", str)); |
---|
| 4542 | + ret = -EINVAL; |
---|
| 4543 | + goto exit; |
---|
| 4544 | + } |
---|
| 4545 | + ports_config.start_port_num = htod16(bcm_atoi(str)); |
---|
| 4546 | + |
---|
| 4547 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4548 | + if (!str) { |
---|
| 4549 | + WL_ERR(("Invalid port string %s\n", str)); |
---|
| 4550 | + ret = -EINVAL; |
---|
| 4551 | + goto exit; |
---|
| 4552 | + } |
---|
| 4553 | + ports_config.no_of_ports = htod16(bcm_atoi(str)); |
---|
| 4554 | + |
---|
| 4555 | + if ((uint32)(ports_config.start_port_num + ports_config.no_of_ports) > |
---|
| 4556 | + NATOE_MAX_PORT_NUM) { |
---|
| 4557 | + WL_ERR(("Invalid port configuration\n")); |
---|
| 4558 | + ret = -EINVAL; |
---|
| 4559 | + goto exit; |
---|
| 4560 | + } |
---|
| 4561 | + ret = bcm_pack_xtlv_entry((uint8**)&pxtlv, |
---|
| 4562 | + &buflen, WL_NATOE_XTLV_CONFIG_PORTS, sizeof(ports_config), |
---|
| 4563 | + &ports_config, BCM_XTLV_OPTION_ALIGN32); |
---|
| 4564 | + |
---|
| 4565 | + if (ret != BCME_OK) { |
---|
| 4566 | + ret = -EINVAL; |
---|
| 4567 | + goto exit; |
---|
| 4568 | + } |
---|
| 4569 | + |
---|
| 4570 | + /* adjust iocsz to the end of last data record */ |
---|
| 4571 | + natoe_ioc->len = (buflen_at_start - buflen); |
---|
| 4572 | + iocsz = sizeof(*natoe_ioc) + natoe_ioc->len; |
---|
| 4573 | + |
---|
| 4574 | + ret = wldev_iovar_setbuf(dev, "natoe", |
---|
| 4575 | + natoe_ioc, iocsz, ioctl_buf, WLC_IOCTL_MEDLEN, NULL); |
---|
| 4576 | + if (ret != BCME_OK) { |
---|
| 4577 | + WL_ERR(("Fail to set iovar %d\n", ret)); |
---|
| 4578 | + ret = -EINVAL; |
---|
| 4579 | + } |
---|
| 4580 | + } |
---|
| 4581 | + |
---|
| 4582 | +exit: |
---|
| 4583 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 4584 | + MFREE(cfg->osh, natoe_ioc, sizeof(*natoe_ioc) + WL_NATOE_IOC_BUFSZ); |
---|
| 4585 | + |
---|
| 4586 | + return ret; |
---|
| 4587 | +} |
---|
| 4588 | + |
---|
| 4589 | +static int |
---|
| 4590 | +wl_android_natoe_subcmd_dbg_stats(struct net_device *dev, const wl_natoe_sub_cmd_t *cmd, |
---|
| 4591 | + char *command, wl_natoe_cmd_info_t *cmd_info) |
---|
| 4592 | +{ |
---|
| 4593 | + int ret = BCME_OK; |
---|
| 4594 | + wl_natoe_ioc_t *natoe_ioc; |
---|
| 4595 | + char *pcmd = command; |
---|
| 4596 | + gfp_t kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; |
---|
| 4597 | + uint16 iocsz = sizeof(*natoe_ioc) + WL_NATOE_DBG_STATS_BUFSZ; |
---|
| 4598 | + uint16 buflen = WL_NATOE_DBG_STATS_BUFSZ; |
---|
| 4599 | + bcm_xtlv_t *pxtlv = NULL; |
---|
| 4600 | + char *ioctl_buf = NULL; |
---|
| 4601 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 4602 | + |
---|
| 4603 | + ioctl_buf = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_MAXLEN); |
---|
| 4604 | + if (!ioctl_buf) { |
---|
| 4605 | + WL_ERR(("ioctl memory alloc failed\n")); |
---|
| 4606 | + return -ENOMEM; |
---|
| 4607 | + } |
---|
| 4608 | + |
---|
| 4609 | + /* alloc mem for ioctl headr + tlv data */ |
---|
| 4610 | + natoe_ioc = (wl_natoe_ioc_t *)MALLOCZ(cfg->osh, iocsz); |
---|
| 4611 | + if (!natoe_ioc) { |
---|
| 4612 | + WL_ERR(("ioctl header memory alloc failed\n")); |
---|
| 4613 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MAXLEN); |
---|
| 4614 | + return -ENOMEM; |
---|
| 4615 | + } |
---|
| 4616 | + |
---|
| 4617 | + /* make up natoe cmd ioctl header */ |
---|
| 4618 | + natoe_ioc->version = htod16(WL_NATOE_IOCTL_VERSION); |
---|
| 4619 | + natoe_ioc->id = htod16(cmd->id); |
---|
| 4620 | + natoe_ioc->len = htod16(WL_NATOE_DBG_STATS_BUFSZ); |
---|
| 4621 | + pxtlv = (bcm_xtlv_t *)natoe_ioc->data; |
---|
| 4622 | + |
---|
| 4623 | + if(*pcmd == WL_IOCTL_ACTION_GET) { /* get */ |
---|
| 4624 | + iocsz = sizeof(*natoe_ioc) + sizeof(*pxtlv); |
---|
| 4625 | + ret = wl_natoe_get_ioctl(dev, natoe_ioc, iocsz, ioctl_buf, |
---|
| 4626 | + WLC_IOCTL_MAXLEN, cmd_info); |
---|
| 4627 | + if (ret != BCME_OK) { |
---|
| 4628 | + WL_ERR(("Fail to get iovar wl_android_natoe_subcmd_dbg_stats\n")); |
---|
| 4629 | + ret = -EINVAL; |
---|
| 4630 | + } |
---|
| 4631 | + } else { /* set */ |
---|
| 4632 | + uint8 val = bcm_atoi(pcmd); |
---|
| 4633 | + |
---|
| 4634 | + /* buflen is max tlv data we can write, it will be decremented as we pack */ |
---|
| 4635 | + /* save buflen at start */ |
---|
| 4636 | + uint16 buflen_at_start = buflen; |
---|
| 4637 | + |
---|
| 4638 | + /* we'll adjust final ioc size at the end */ |
---|
| 4639 | + ret = bcm_pack_xtlv_entry((uint8**)&pxtlv, &buflen, WL_NATOE_XTLV_ENABLE, |
---|
| 4640 | + sizeof(uint8), &val, BCM_XTLV_OPTION_ALIGN32); |
---|
| 4641 | + |
---|
| 4642 | + if (ret != BCME_OK) { |
---|
| 4643 | + ret = -EINVAL; |
---|
| 4644 | + goto exit; |
---|
| 4645 | + } |
---|
| 4646 | + |
---|
| 4647 | + /* adjust iocsz to the end of last data record */ |
---|
| 4648 | + natoe_ioc->len = (buflen_at_start - buflen); |
---|
| 4649 | + iocsz = sizeof(*natoe_ioc) + natoe_ioc->len; |
---|
| 4650 | + |
---|
| 4651 | + ret = wldev_iovar_setbuf(dev, "natoe", |
---|
| 4652 | + natoe_ioc, iocsz, ioctl_buf, WLC_IOCTL_MAXLEN, NULL); |
---|
| 4653 | + if (ret != BCME_OK) { |
---|
| 4654 | + WL_ERR(("Fail to set iovar %d\n", ret)); |
---|
| 4655 | + ret = -EINVAL; |
---|
| 4656 | + } |
---|
| 4657 | + } |
---|
| 4658 | + |
---|
| 4659 | +exit: |
---|
| 4660 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MAXLEN); |
---|
| 4661 | + MFREE(cfg->osh, natoe_ioc, sizeof(*natoe_ioc) + WL_NATOE_DBG_STATS_BUFSZ); |
---|
| 4662 | + |
---|
| 4663 | + return ret; |
---|
| 4664 | +} |
---|
| 4665 | + |
---|
| 4666 | +static int |
---|
| 4667 | +wl_android_natoe_subcmd_tbl_cnt(struct net_device *dev, const wl_natoe_sub_cmd_t *cmd, |
---|
| 4668 | + char *command, wl_natoe_cmd_info_t *cmd_info) |
---|
| 4669 | +{ |
---|
| 4670 | + int ret = BCME_OK; |
---|
| 4671 | + wl_natoe_ioc_t *natoe_ioc; |
---|
| 4672 | + char *pcmd = command; |
---|
| 4673 | + gfp_t kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; |
---|
| 4674 | + uint16 iocsz = sizeof(*natoe_ioc) + WL_NATOE_IOC_BUFSZ; |
---|
| 4675 | + uint16 buflen = WL_NATOE_IOC_BUFSZ; |
---|
| 4676 | + bcm_xtlv_t *pxtlv = NULL; |
---|
| 4677 | + char *ioctl_buf = NULL; |
---|
| 4678 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 4679 | + |
---|
| 4680 | + ioctl_buf = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 4681 | + if (!ioctl_buf) { |
---|
| 4682 | + WL_ERR(("ioctl memory alloc failed\n")); |
---|
| 4683 | + return -ENOMEM; |
---|
| 4684 | + } |
---|
| 4685 | + |
---|
| 4686 | + /* alloc mem for ioctl headr + tlv data */ |
---|
| 4687 | + natoe_ioc = (wl_natoe_ioc_t *)MALLOCZ(cfg->osh, iocsz); |
---|
| 4688 | + if (!natoe_ioc) { |
---|
| 4689 | + WL_ERR(("ioctl header memory alloc failed\n")); |
---|
| 4690 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 4691 | + return -ENOMEM; |
---|
| 4692 | + } |
---|
| 4693 | + |
---|
| 4694 | + /* make up natoe cmd ioctl header */ |
---|
| 4695 | + natoe_ioc->version = htod16(WL_NATOE_IOCTL_VERSION); |
---|
| 4696 | + natoe_ioc->id = htod16(cmd->id); |
---|
| 4697 | + natoe_ioc->len = htod16(WL_NATOE_IOC_BUFSZ); |
---|
| 4698 | + pxtlv = (bcm_xtlv_t *)natoe_ioc->data; |
---|
| 4699 | + |
---|
| 4700 | + if(*pcmd == WL_IOCTL_ACTION_GET) { /* get */ |
---|
| 4701 | + iocsz = sizeof(*natoe_ioc) + sizeof(*pxtlv); |
---|
| 4702 | + ret = wl_natoe_get_ioctl(dev, natoe_ioc, iocsz, ioctl_buf, |
---|
| 4703 | + WLC_IOCTL_MEDLEN, cmd_info); |
---|
| 4704 | + if (ret != BCME_OK) { |
---|
| 4705 | + WL_ERR(("Fail to get iovar wl_android_natoe_subcmd_tbl_cnt\n")); |
---|
| 4706 | + ret = -EINVAL; |
---|
| 4707 | + } |
---|
| 4708 | + } else { /* set */ |
---|
| 4709 | + uint32 val = bcm_atoi(pcmd); |
---|
| 4710 | + |
---|
| 4711 | + /* buflen is max tlv data we can write, it will be decremented as we pack */ |
---|
| 4712 | + /* save buflen at start */ |
---|
| 4713 | + uint16 buflen_at_start = buflen; |
---|
| 4714 | + |
---|
| 4715 | + /* we'll adjust final ioc size at the end */ |
---|
| 4716 | + ret = bcm_pack_xtlv_entry((uint8**)&pxtlv, &buflen, WL_NATOE_XTLV_TBL_CNT, |
---|
| 4717 | + sizeof(uint32), &val, BCM_XTLV_OPTION_ALIGN32); |
---|
| 4718 | + |
---|
| 4719 | + if (ret != BCME_OK) { |
---|
| 4720 | + ret = -EINVAL; |
---|
| 4721 | + goto exit; |
---|
| 4722 | + } |
---|
| 4723 | + |
---|
| 4724 | + /* adjust iocsz to the end of last data record */ |
---|
| 4725 | + natoe_ioc->len = (buflen_at_start - buflen); |
---|
| 4726 | + iocsz = sizeof(*natoe_ioc) + natoe_ioc->len; |
---|
| 4727 | + |
---|
| 4728 | + ret = wldev_iovar_setbuf(dev, "natoe", |
---|
| 4729 | + natoe_ioc, iocsz, ioctl_buf, WLC_IOCTL_MEDLEN, NULL); |
---|
| 4730 | + if (ret != BCME_OK) { |
---|
| 4731 | + WL_ERR(("Fail to set iovar %d\n", ret)); |
---|
| 4732 | + ret = -EINVAL; |
---|
| 4733 | + } |
---|
| 4734 | + } |
---|
| 4735 | + |
---|
| 4736 | +exit: |
---|
| 4737 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 4738 | + MFREE(cfg->osh, natoe_ioc, sizeof(*natoe_ioc) + WL_NATOE_IOC_BUFSZ); |
---|
| 4739 | + |
---|
| 4740 | + return ret; |
---|
| 4741 | +} |
---|
| 4742 | + |
---|
| 4743 | +#endif /* WL_NATOE */ |
---|
| 4744 | + |
---|
| 4745 | +#ifdef WL_MBO |
---|
| 4746 | +static int |
---|
| 4747 | +wl_android_process_mbo_cmd(struct net_device *dev, char *command, int total_len) |
---|
| 4748 | +{ |
---|
| 4749 | + int ret = BCME_ERROR; |
---|
| 4750 | + char *pcmd = command; |
---|
| 4751 | + char *str = NULL; |
---|
| 4752 | + wl_drv_cmd_info_t cmd_info; |
---|
| 4753 | + const wl_drv_sub_cmd_t *mbo_cmd = &mbo_cmd_list[0]; |
---|
| 4754 | + |
---|
| 4755 | + /* skip to cmd name after "mbo" */ |
---|
| 4756 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4757 | + |
---|
| 4758 | + /* If mbo subcmd name is not provided, return error */ |
---|
| 4759 | + if (*pcmd == '\0') { |
---|
| 4760 | + WL_ERR(("mbo subcmd not provided %s\n", __FUNCTION__)); |
---|
| 4761 | + ret = -EINVAL; |
---|
| 4762 | + return ret; |
---|
| 4763 | + } |
---|
| 4764 | + |
---|
| 4765 | + /* get the mbo command name to str */ |
---|
| 4766 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 4767 | + |
---|
| 4768 | + while (mbo_cmd->name != NULL) { |
---|
| 4769 | + if (strnicmp(mbo_cmd->name, str, strlen(mbo_cmd->name)) == 0) { |
---|
| 4770 | + /* dispatch cmd to appropriate handler */ |
---|
| 4771 | + if (mbo_cmd->handler) { |
---|
| 4772 | + cmd_info.command = command; |
---|
| 4773 | + cmd_info.tot_len = total_len; |
---|
| 4774 | + ret = mbo_cmd->handler(dev, mbo_cmd, pcmd, &cmd_info); |
---|
| 4775 | + } |
---|
| 4776 | + return ret; |
---|
| 4777 | + } |
---|
| 4778 | + mbo_cmd++; |
---|
| 4779 | + } |
---|
| 4780 | + return ret; |
---|
| 4781 | +} |
---|
| 4782 | + |
---|
| 4783 | +static int |
---|
| 4784 | +wl_android_send_wnm_notif(struct net_device *dev, bcm_iov_buf_t *iov_buf, |
---|
| 4785 | + uint16 iov_buf_len, uint8 *iov_resp, uint16 iov_resp_len, uint8 sub_elem_type) |
---|
| 4786 | +{ |
---|
| 4787 | + int ret = BCME_OK; |
---|
| 4788 | + uint8 *pxtlv = NULL; |
---|
| 4789 | + uint16 iovlen = 0; |
---|
| 4790 | + uint16 buflen = 0, buflen_start = 0; |
---|
| 4791 | + |
---|
| 4792 | + memset_s(iov_buf, iov_buf_len, 0, iov_buf_len); |
---|
| 4793 | + iov_buf->version = WL_MBO_IOV_VERSION; |
---|
| 4794 | + iov_buf->id = WL_MBO_CMD_SEND_NOTIF; |
---|
| 4795 | + buflen = buflen_start = iov_buf_len - sizeof(bcm_iov_buf_t); |
---|
| 4796 | + pxtlv = (uint8 *)&iov_buf->data[0]; |
---|
| 4797 | + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_MBO_XTLV_SUB_ELEM_TYPE, |
---|
| 4798 | + sizeof(sub_elem_type), &sub_elem_type, BCM_XTLV_OPTION_ALIGN32); |
---|
| 4799 | + if (ret != BCME_OK) { |
---|
| 4800 | + return ret; |
---|
| 4801 | + } |
---|
| 4802 | + iov_buf->len = buflen_start - buflen; |
---|
| 4803 | + iovlen = sizeof(bcm_iov_buf_t) + iov_buf->len; |
---|
| 4804 | + ret = wldev_iovar_setbuf(dev, "mbo", |
---|
| 4805 | + iov_buf, iovlen, iov_resp, WLC_IOCTL_MAXLEN, NULL); |
---|
| 4806 | + if (ret != BCME_OK) { |
---|
| 4807 | + WL_ERR(("Fail to sent wnm notif %d\n", ret)); |
---|
| 4808 | + } |
---|
| 4809 | + return ret; |
---|
| 4810 | +} |
---|
| 4811 | + |
---|
| 4812 | +static int |
---|
| 4813 | +wl_android_mbo_resp_parse_cbfn(void *ctx, const uint8 *data, uint16 type, uint16 len) |
---|
| 4814 | +{ |
---|
| 4815 | + wl_drv_cmd_info_t *cmd_info = (wl_drv_cmd_info_t *)ctx; |
---|
| 4816 | + uint8 *command = cmd_info->command; |
---|
| 4817 | + uint16 total_len = cmd_info->tot_len; |
---|
| 4818 | + uint16 bytes_written = 0; |
---|
| 4819 | + |
---|
| 4820 | + UNUSED_PARAMETER(len); |
---|
| 4821 | + /* TODO: validate data value */ |
---|
| 4822 | + if (data == NULL) { |
---|
| 4823 | + WL_ERR(("%s: Bad argument !!\n", __FUNCTION__)); |
---|
| 4824 | + return -EINVAL; |
---|
| 4825 | + } |
---|
| 4826 | + switch (type) { |
---|
| 4827 | + case WL_MBO_XTLV_CELL_DATA_CAP: |
---|
| 4828 | + { |
---|
| 4829 | + bytes_written = snprintf(command, total_len, "cell_data_cap: %u\n", *data); |
---|
| 4830 | + cmd_info->bytes_written = bytes_written; |
---|
| 4831 | + } |
---|
| 4832 | + break; |
---|
| 4833 | + default: |
---|
| 4834 | + WL_ERR(("%s: Unknown tlv %u\n", __FUNCTION__, type)); |
---|
| 4835 | + } |
---|
| 4836 | + return BCME_OK; |
---|
| 4837 | +} |
---|
| 4838 | + |
---|
| 4839 | +static int |
---|
| 4840 | +wl_android_mbo_subcmd_cell_data_cap(struct net_device *dev, const wl_drv_sub_cmd_t *cmd, |
---|
| 4841 | + char *command, wl_drv_cmd_info_t *cmd_info) |
---|
| 4842 | +{ |
---|
| 4843 | + int ret = BCME_OK; |
---|
| 4844 | + uint8 *pxtlv = NULL; |
---|
| 4845 | + uint16 buflen = 0, buflen_start = 0; |
---|
| 4846 | + uint16 iovlen = 0; |
---|
| 4847 | + char *pcmd = command; |
---|
| 4848 | + bcm_iov_buf_t *iov_buf = NULL; |
---|
| 4849 | + bcm_iov_buf_t *p_resp = NULL; |
---|
| 4850 | + uint8 *iov_resp = NULL; |
---|
| 4851 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 4852 | + uint16 version; |
---|
| 4853 | + |
---|
| 4854 | + /* first get the configured value */ |
---|
| 4855 | + iov_buf = (bcm_iov_buf_t *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 4856 | + if (iov_buf == NULL) { |
---|
| 4857 | + ret = -ENOMEM; |
---|
| 4858 | + WL_ERR(("iov buf memory alloc exited\n")); |
---|
| 4859 | + goto exit; |
---|
| 4860 | + } |
---|
| 4861 | + iov_resp = (uint8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MAXLEN); |
---|
| 4862 | + if (iov_resp == NULL) { |
---|
| 4863 | + ret = -ENOMEM; |
---|
| 4864 | + WL_ERR(("iov resp memory alloc exited\n")); |
---|
| 4865 | + goto exit; |
---|
| 4866 | + } |
---|
| 4867 | + |
---|
| 4868 | + /* fill header */ |
---|
| 4869 | + iov_buf->version = WL_MBO_IOV_VERSION; |
---|
| 4870 | + iov_buf->id = WL_MBO_CMD_CELLULAR_DATA_CAP; |
---|
| 4871 | + |
---|
| 4872 | + ret = wldev_iovar_getbuf(dev, "mbo", iov_buf, WLC_IOCTL_MEDLEN, iov_resp, |
---|
| 4873 | + WLC_IOCTL_MAXLEN, |
---|
| 4874 | + NULL); |
---|
| 4875 | + if (ret != BCME_OK) { |
---|
| 4876 | + goto exit; |
---|
| 4877 | + } |
---|
| 4878 | + p_resp = (bcm_iov_buf_t *)iov_resp; |
---|
| 4879 | + |
---|
| 4880 | + /* get */ |
---|
| 4881 | + if (*pcmd == WL_IOCTL_ACTION_GET) { |
---|
| 4882 | + /* Check for version */ |
---|
| 4883 | + version = dtoh16(*(uint16 *)iov_resp); |
---|
| 4884 | + if (version != WL_MBO_IOV_VERSION) { |
---|
| 4885 | + ret = -EINVAL; |
---|
| 4886 | + } |
---|
| 4887 | + if (p_resp->id == WL_MBO_CMD_CELLULAR_DATA_CAP) { |
---|
| 4888 | + ret = bcm_unpack_xtlv_buf((void *)cmd_info, (uint8 *)p_resp->data, |
---|
| 4889 | + p_resp->len, BCM_XTLV_OPTION_ALIGN32, |
---|
| 4890 | + wl_android_mbo_resp_parse_cbfn); |
---|
| 4891 | + if (ret == BCME_OK) { |
---|
| 4892 | + ret = cmd_info->bytes_written; |
---|
| 4893 | + } |
---|
| 4894 | + } else { |
---|
| 4895 | + ret = -EINVAL; |
---|
| 4896 | + WL_ERR(("Mismatch: resp id %d req id %d\n", p_resp->id, cmd->id)); |
---|
| 4897 | + goto exit; |
---|
| 4898 | + } |
---|
| 4899 | + } else { |
---|
| 4900 | + uint8 cell_cap = bcm_atoi(pcmd); |
---|
| 4901 | + const uint8* old_cell_cap = NULL; |
---|
| 4902 | + uint16 len = 0; |
---|
| 4903 | + |
---|
| 4904 | + old_cell_cap = bcm_get_data_from_xtlv_buf((uint8 *)p_resp->data, p_resp->len, |
---|
| 4905 | + WL_MBO_XTLV_CELL_DATA_CAP, &len, BCM_XTLV_OPTION_ALIGN32); |
---|
| 4906 | + if (old_cell_cap && *old_cell_cap == cell_cap) { |
---|
| 4907 | + WL_ERR(("No change is cellular data capability\n")); |
---|
| 4908 | + /* No change in value */ |
---|
| 4909 | + goto exit; |
---|
| 4910 | + } |
---|
| 4911 | + |
---|
| 4912 | + buflen = buflen_start = WLC_IOCTL_MEDLEN - sizeof(bcm_iov_buf_t); |
---|
| 4913 | + |
---|
| 4914 | + if (cell_cap < MBO_CELL_DATA_CONN_AVAILABLE || |
---|
| 4915 | + cell_cap > MBO_CELL_DATA_CONN_NOT_CAPABLE) { |
---|
| 4916 | + WL_ERR(("wrong value %u\n", cell_cap)); |
---|
| 4917 | + ret = -EINVAL; |
---|
| 4918 | + goto exit; |
---|
| 4919 | + } |
---|
| 4920 | + pxtlv = (uint8 *)&iov_buf->data[0]; |
---|
| 4921 | + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_MBO_XTLV_CELL_DATA_CAP, |
---|
| 4922 | + sizeof(cell_cap), &cell_cap, BCM_XTLV_OPTION_ALIGN32); |
---|
| 4923 | + if (ret != BCME_OK) { |
---|
| 4924 | + goto exit; |
---|
| 4925 | + } |
---|
| 4926 | + iov_buf->len = buflen_start - buflen; |
---|
| 4927 | + iovlen = sizeof(bcm_iov_buf_t) + iov_buf->len; |
---|
| 4928 | + ret = wldev_iovar_setbuf(dev, "mbo", |
---|
| 4929 | + iov_buf, iovlen, iov_resp, WLC_IOCTL_MAXLEN, NULL); |
---|
| 4930 | + if (ret != BCME_OK) { |
---|
| 4931 | + WL_ERR(("Fail to set iovar %d\n", ret)); |
---|
| 4932 | + ret = -EINVAL; |
---|
| 4933 | + goto exit; |
---|
| 4934 | + } |
---|
| 4935 | + /* Skip for CUSTOMER_HW4 - WNM notification |
---|
| 4936 | + * for cellular data capability is handled by host |
---|
| 4937 | + */ |
---|
| 4938 | + /* send a WNM notification request to associated AP */ |
---|
| 4939 | + if (wl_get_drv_status(cfg, CONNECTED, dev)) { |
---|
| 4940 | + WL_INFORM(("Sending WNM Notif\n")); |
---|
| 4941 | + ret = wl_android_send_wnm_notif(dev, iov_buf, WLC_IOCTL_MEDLEN, |
---|
| 4942 | + iov_resp, WLC_IOCTL_MAXLEN, MBO_ATTR_CELL_DATA_CAP); |
---|
| 4943 | + if (ret != BCME_OK) { |
---|
| 4944 | + WL_ERR(("Fail to send WNM notification %d\n", ret)); |
---|
| 4945 | + ret = -EINVAL; |
---|
| 4946 | + } |
---|
| 4947 | + } |
---|
| 4948 | + } |
---|
| 4949 | +exit: |
---|
| 4950 | + if (iov_buf) { |
---|
| 4951 | + MFREE(cfg->osh, iov_buf, WLC_IOCTL_MEDLEN); |
---|
| 4952 | + } |
---|
| 4953 | + if (iov_resp) { |
---|
| 4954 | + MFREE(cfg->osh, iov_resp, WLC_IOCTL_MAXLEN); |
---|
| 4955 | + } |
---|
| 4956 | + return ret; |
---|
| 4957 | +} |
---|
| 4958 | + |
---|
| 4959 | +static int |
---|
| 4960 | +wl_android_mbo_non_pref_chan_parse_cbfn(void *ctx, const uint8 *data, uint16 type, uint16 len) |
---|
| 4961 | +{ |
---|
| 4962 | + wl_drv_cmd_info_t *cmd_info = (wl_drv_cmd_info_t *)ctx; |
---|
| 4963 | + uint8 *command = cmd_info->command + cmd_info->bytes_written; |
---|
| 4964 | + uint16 total_len = cmd_info->tot_len; |
---|
| 4965 | + uint16 bytes_written = 0; |
---|
| 4966 | + |
---|
| 4967 | + WL_DBG(("Total bytes written at begining %u\n", cmd_info->bytes_written)); |
---|
| 4968 | + UNUSED_PARAMETER(len); |
---|
| 4969 | + if (data == NULL) { |
---|
| 4970 | + WL_ERR(("%s: Bad argument !!\n", __FUNCTION__)); |
---|
| 4971 | + return -EINVAL; |
---|
| 4972 | + } |
---|
| 4973 | + switch (type) { |
---|
| 4974 | + case WL_MBO_XTLV_OPCLASS: |
---|
| 4975 | + { |
---|
| 4976 | + bytes_written = snprintf(command, total_len, "%u:", *data); |
---|
| 4977 | + WL_ERR(("wr %u %u\n", bytes_written, *data)); |
---|
| 4978 | + command += bytes_written; |
---|
| 4979 | + cmd_info->bytes_written += bytes_written; |
---|
| 4980 | + } |
---|
| 4981 | + break; |
---|
| 4982 | + case WL_MBO_XTLV_CHAN: |
---|
| 4983 | + { |
---|
| 4984 | + bytes_written = snprintf(command, total_len, "%u:", *data); |
---|
| 4985 | + WL_ERR(("wr %u\n", bytes_written)); |
---|
| 4986 | + command += bytes_written; |
---|
| 4987 | + cmd_info->bytes_written += bytes_written; |
---|
| 4988 | + } |
---|
| 4989 | + break; |
---|
| 4990 | + case WL_MBO_XTLV_PREFERENCE: |
---|
| 4991 | + { |
---|
| 4992 | + bytes_written = snprintf(command, total_len, "%u:", *data); |
---|
| 4993 | + WL_ERR(("wr %u\n", bytes_written)); |
---|
| 4994 | + command += bytes_written; |
---|
| 4995 | + cmd_info->bytes_written += bytes_written; |
---|
| 4996 | + } |
---|
| 4997 | + break; |
---|
| 4998 | + case WL_MBO_XTLV_REASON_CODE: |
---|
| 4999 | + { |
---|
| 5000 | + bytes_written = snprintf(command, total_len, "%u ", *data); |
---|
| 5001 | + WL_ERR(("wr %u\n", bytes_written)); |
---|
| 5002 | + command += bytes_written; |
---|
| 5003 | + cmd_info->bytes_written += bytes_written; |
---|
| 5004 | + } |
---|
| 5005 | + break; |
---|
| 5006 | + default: |
---|
| 5007 | + WL_ERR(("%s: Unknown tlv %u\n", __FUNCTION__, type)); |
---|
| 5008 | + } |
---|
| 5009 | + WL_DBG(("Total bytes written %u\n", cmd_info->bytes_written)); |
---|
| 5010 | + return BCME_OK; |
---|
| 5011 | +} |
---|
| 5012 | + |
---|
| 5013 | +static int |
---|
| 5014 | +wl_android_mbo_subcmd_non_pref_chan(struct net_device *dev, |
---|
| 5015 | + const wl_drv_sub_cmd_t *cmd, char *command, |
---|
| 5016 | + wl_drv_cmd_info_t *cmd_info) |
---|
| 5017 | +{ |
---|
| 5018 | + int ret = BCME_OK; |
---|
| 5019 | + uint8 *pxtlv = NULL; |
---|
| 5020 | + uint16 buflen = 0, buflen_start = 0; |
---|
| 5021 | + uint16 iovlen = 0; |
---|
| 5022 | + char *pcmd = command; |
---|
| 5023 | + bcm_iov_buf_t *iov_buf = NULL; |
---|
| 5024 | + bcm_iov_buf_t *p_resp = NULL; |
---|
| 5025 | + uint8 *iov_resp = NULL; |
---|
| 5026 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 5027 | + uint16 version; |
---|
| 5028 | + |
---|
| 5029 | + WL_ERR(("%s:%d\n", __FUNCTION__, __LINE__)); |
---|
| 5030 | + iov_buf = (bcm_iov_buf_t *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 5031 | + if (iov_buf == NULL) { |
---|
| 5032 | + ret = -ENOMEM; |
---|
| 5033 | + WL_ERR(("iov buf memory alloc exited\n")); |
---|
| 5034 | + goto exit; |
---|
| 5035 | + } |
---|
| 5036 | + iov_resp = (uint8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MAXLEN); |
---|
| 5037 | + if (iov_resp == NULL) { |
---|
| 5038 | + ret = -ENOMEM; |
---|
| 5039 | + WL_ERR(("iov resp memory alloc exited\n")); |
---|
| 5040 | + goto exit; |
---|
| 5041 | + } |
---|
| 5042 | + /* get */ |
---|
| 5043 | + if (*pcmd == WL_IOCTL_ACTION_GET) { |
---|
| 5044 | + /* fill header */ |
---|
| 5045 | + iov_buf->version = WL_MBO_IOV_VERSION; |
---|
| 5046 | + iov_buf->id = WL_MBO_CMD_LIST_CHAN_PREF; |
---|
| 5047 | + |
---|
| 5048 | + ret = wldev_iovar_getbuf(dev, "mbo", iov_buf, WLC_IOCTL_MEDLEN, iov_resp, |
---|
| 5049 | + WLC_IOCTL_MAXLEN, NULL); |
---|
| 5050 | + if (ret != BCME_OK) { |
---|
| 5051 | + goto exit; |
---|
| 5052 | + } |
---|
| 5053 | + p_resp = (bcm_iov_buf_t *)iov_resp; |
---|
| 5054 | + /* Check for version */ |
---|
| 5055 | + version = dtoh16(*(uint16 *)iov_resp); |
---|
| 5056 | + if (version != WL_MBO_IOV_VERSION) { |
---|
| 5057 | + WL_ERR(("Version mismatch. returned ver %u expected %u\n", |
---|
| 5058 | + version, WL_MBO_IOV_VERSION)); |
---|
| 5059 | + ret = -EINVAL; |
---|
| 5060 | + } |
---|
| 5061 | + if (p_resp->id == WL_MBO_CMD_LIST_CHAN_PREF) { |
---|
| 5062 | + ret = bcm_unpack_xtlv_buf((void *)cmd_info, (uint8 *)p_resp->data, |
---|
| 5063 | + p_resp->len, BCM_XTLV_OPTION_ALIGN32, |
---|
| 5064 | + wl_android_mbo_non_pref_chan_parse_cbfn); |
---|
| 5065 | + if (ret == BCME_OK) { |
---|
| 5066 | + ret = cmd_info->bytes_written; |
---|
| 5067 | + } |
---|
| 5068 | + } else { |
---|
| 5069 | + ret = -EINVAL; |
---|
| 5070 | + WL_ERR(("Mismatch: resp id %d req id %d\n", p_resp->id, cmd->id)); |
---|
| 5071 | + goto exit; |
---|
| 5072 | + } |
---|
| 5073 | + } else { |
---|
| 5074 | + char *str = pcmd; |
---|
| 5075 | + uint opcl = 0, ch = 0, pref = 0, rc = 0; |
---|
| 5076 | + |
---|
| 5077 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 5078 | + if (!(strnicmp(str, "set", 3)) || (!strnicmp(str, "clear", 5))) { |
---|
| 5079 | + /* delete all configurations */ |
---|
| 5080 | + iov_buf->version = WL_MBO_IOV_VERSION; |
---|
| 5081 | + iov_buf->id = WL_MBO_CMD_DEL_CHAN_PREF; |
---|
| 5082 | + iov_buf->len = 0; |
---|
| 5083 | + iovlen = sizeof(bcm_iov_buf_t) + iov_buf->len; |
---|
| 5084 | + ret = wldev_iovar_setbuf(dev, "mbo", |
---|
| 5085 | + iov_buf, iovlen, iov_resp, WLC_IOCTL_MAXLEN, NULL); |
---|
| 5086 | + if (ret != BCME_OK) { |
---|
| 5087 | + WL_ERR(("Fail to set iovar %d\n", ret)); |
---|
| 5088 | + ret = -EINVAL; |
---|
| 5089 | + goto exit; |
---|
| 5090 | + } |
---|
| 5091 | + } else { |
---|
| 5092 | + WL_ERR(("Unknown command %s\n", str)); |
---|
| 5093 | + goto exit; |
---|
| 5094 | + } |
---|
| 5095 | + /* parse non pref channel list */ |
---|
| 5096 | + if (strnicmp(str, "set", 3) == 0) { |
---|
| 5097 | + uint8 cnt = 0; |
---|
| 5098 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 5099 | + while (str != NULL) { |
---|
| 5100 | + ret = sscanf(str, "%u:%u:%u:%u", &opcl, &ch, &pref, &rc); |
---|
| 5101 | + WL_ERR(("buflen %u op %u, ch %u, pref %u rc %u\n", |
---|
| 5102 | + buflen, opcl, ch, pref, rc)); |
---|
| 5103 | + if (ret != 4) { |
---|
| 5104 | + WL_ERR(("Not all parameter presents\n")); |
---|
| 5105 | + ret = -EINVAL; |
---|
| 5106 | + } |
---|
| 5107 | + /* TODO: add a validation check here */ |
---|
| 5108 | + memset_s(iov_buf, WLC_IOCTL_MEDLEN, 0, WLC_IOCTL_MEDLEN); |
---|
| 5109 | + buflen = buflen_start = WLC_IOCTL_MEDLEN; |
---|
| 5110 | + pxtlv = (uint8 *)&iov_buf->data[0]; |
---|
| 5111 | + /* opclass */ |
---|
| 5112 | + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_MBO_XTLV_OPCLASS, |
---|
| 5113 | + sizeof(uint8), (uint8 *)&opcl, BCM_XTLV_OPTION_ALIGN32); |
---|
| 5114 | + if (ret != BCME_OK) { |
---|
| 5115 | + goto exit; |
---|
| 5116 | + } |
---|
| 5117 | + /* channel */ |
---|
| 5118 | + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_MBO_XTLV_CHAN, |
---|
| 5119 | + sizeof(uint8), (uint8 *)&ch, BCM_XTLV_OPTION_ALIGN32); |
---|
| 5120 | + if (ret != BCME_OK) { |
---|
| 5121 | + goto exit; |
---|
| 5122 | + } |
---|
| 5123 | + /* preference */ |
---|
| 5124 | + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_MBO_XTLV_PREFERENCE, |
---|
| 5125 | + sizeof(uint8), (uint8 *)&pref, BCM_XTLV_OPTION_ALIGN32); |
---|
| 5126 | + if (ret != BCME_OK) { |
---|
| 5127 | + goto exit; |
---|
| 5128 | + } |
---|
| 5129 | + /* reason */ |
---|
| 5130 | + ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_MBO_XTLV_REASON_CODE, |
---|
| 5131 | + sizeof(uint8), (uint8 *)&rc, BCM_XTLV_OPTION_ALIGN32); |
---|
| 5132 | + if (ret != BCME_OK) { |
---|
| 5133 | + goto exit; |
---|
| 5134 | + } |
---|
| 5135 | + WL_ERR(("len %u\n", (buflen_start - buflen))); |
---|
| 5136 | + /* Now set the new non pref channels */ |
---|
| 5137 | + iov_buf->version = WL_MBO_IOV_VERSION; |
---|
| 5138 | + iov_buf->id = WL_MBO_CMD_ADD_CHAN_PREF; |
---|
| 5139 | + iov_buf->len = buflen_start - buflen; |
---|
| 5140 | + iovlen = sizeof(bcm_iov_buf_t) + iov_buf->len; |
---|
| 5141 | + ret = wldev_iovar_setbuf(dev, "mbo", |
---|
| 5142 | + iov_buf, iovlen, iov_resp, WLC_IOCTL_MEDLEN, NULL); |
---|
| 5143 | + if (ret != BCME_OK) { |
---|
| 5144 | + WL_ERR(("Fail to set iovar %d\n", ret)); |
---|
| 5145 | + ret = -EINVAL; |
---|
| 5146 | + goto exit; |
---|
| 5147 | + } |
---|
| 5148 | + cnt++; |
---|
| 5149 | + if (cnt >= MBO_MAX_CHAN_PREF_ENTRIES) { |
---|
| 5150 | + break; |
---|
| 5151 | + } |
---|
| 5152 | + WL_ERR(("%d cnt %u\n", __LINE__, cnt)); |
---|
| 5153 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 5154 | + } |
---|
| 5155 | + } |
---|
| 5156 | + /* send a WNM notification request to associated AP */ |
---|
| 5157 | + if (wl_get_drv_status(cfg, CONNECTED, dev)) { |
---|
| 5158 | + WL_INFORM(("Sending WNM Notif\n")); |
---|
| 5159 | + ret = wl_android_send_wnm_notif(dev, iov_buf, WLC_IOCTL_MEDLEN, |
---|
| 5160 | + iov_resp, WLC_IOCTL_MAXLEN, MBO_ATTR_NON_PREF_CHAN_REPORT); |
---|
| 5161 | + if (ret != BCME_OK) { |
---|
| 5162 | + WL_ERR(("Fail to send WNM notification %d\n", ret)); |
---|
| 5163 | + ret = -EINVAL; |
---|
| 5164 | + } |
---|
| 5165 | + } |
---|
| 5166 | + } |
---|
| 5167 | +exit: |
---|
| 5168 | + if (iov_buf) { |
---|
| 5169 | + MFREE(cfg->osh, iov_buf, WLC_IOCTL_MEDLEN); |
---|
| 5170 | + } |
---|
| 5171 | + if (iov_resp) { |
---|
| 5172 | + MFREE(cfg->osh, iov_resp, WLC_IOCTL_MAXLEN); |
---|
| 5173 | + } |
---|
| 5174 | + return ret; |
---|
| 5175 | +} |
---|
| 5176 | +#endif /* WL_MBO */ |
---|
| 5177 | + |
---|
| 5178 | +#ifdef CUSTOMER_HW4_PRIVATE_CMD |
---|
| 5179 | +#ifdef SUPPORT_AMPDU_MPDU_CMD |
---|
| 5180 | +/* CMD_AMPDU_MPDU */ |
---|
| 5181 | +static int |
---|
| 5182 | +wl_android_set_ampdu_mpdu(struct net_device *dev, const char* string_num) |
---|
| 5183 | +{ |
---|
| 5184 | + int err = 0; |
---|
| 5185 | + int ampdu_mpdu; |
---|
| 5186 | + |
---|
| 5187 | + ampdu_mpdu = bcm_atoi(string_num); |
---|
| 5188 | + |
---|
| 5189 | + if (ampdu_mpdu > 32) { |
---|
| 5190 | + DHD_ERROR(("wl_android_set_ampdu_mpdu : ampdu_mpdu MAX value is 32.\n")); |
---|
| 5191 | + return -1; |
---|
| 5192 | + } |
---|
| 5193 | + |
---|
| 5194 | + DHD_ERROR(("wl_android_set_ampdu_mpdu : ampdu_mpdu = %d\n", ampdu_mpdu)); |
---|
| 5195 | + err = wldev_iovar_setint(dev, "ampdu_mpdu", ampdu_mpdu); |
---|
| 5196 | + if (err < 0) { |
---|
| 5197 | + DHD_ERROR(("wl_android_set_ampdu_mpdu : ampdu_mpdu set error. %d\n", err)); |
---|
| 5198 | + return -1; |
---|
| 5199 | + } |
---|
| 5200 | + |
---|
| 5201 | + return 0; |
---|
| 5202 | +} |
---|
| 5203 | +#endif /* SUPPORT_AMPDU_MPDU_CMD */ |
---|
| 5204 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
| 5205 | + |
---|
| 5206 | +#if defined(CONFIG_WLAN_BEYONDX) || defined(CONFIG_SEC_5GMODEL) |
---|
| 5207 | +extern int wl_cfg80211_send_msg_to_ril(void); |
---|
| 5208 | +extern void wl_cfg80211_register_dev_ril_bridge_event_notifier(void); |
---|
| 5209 | +extern void wl_cfg80211_unregister_dev_ril_bridge_event_notifier(void); |
---|
| 5210 | +extern int g_mhs_chan_for_cpcoex; |
---|
| 5211 | +#endif /* CONFIG_WLAN_BEYONDX || defined(CONFIG_SEC_5GMODEL) */ |
---|
| 5212 | + |
---|
| 5213 | +#if defined(WL_SUPPORT_AUTO_CHANNEL) |
---|
1357 | 5214 | /* SoftAP feature */ |
---|
1358 | 5215 | #define APCS_BAND_2G_LEGACY1 20 |
---|
1359 | 5216 | #define APCS_BAND_2G_LEGACY2 0 |
---|
.. | .. |
---|
1361 | 5218 | #define APCS_BAND_2G "band=2g" |
---|
1362 | 5219 | #define APCS_BAND_5G "band=5g" |
---|
1363 | 5220 | #define APCS_MAX_2G_CHANNELS 11 |
---|
1364 | | -#if defined(WL_SUPPORT_AUTO_CHANNEL) |
---|
| 5221 | +#define APCS_MAX_RETRY 10 |
---|
| 5222 | +#define APCS_DEFAULT_2G_CH 1 |
---|
| 5223 | +#define APCS_DEFAULT_5G_CH 149 |
---|
1365 | 5224 | static int |
---|
1366 | 5225 | wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str, |
---|
1367 | 5226 | char* command, int total_len) |
---|
.. | .. |
---|
1374 | 5233 | u8 *reqbuf = NULL; |
---|
1375 | 5234 | uint32 band = WLC_BAND_2G; |
---|
1376 | 5235 | uint32 buf_size; |
---|
| 5236 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
1377 | 5237 | |
---|
1378 | 5238 | if (cmd_str) { |
---|
1379 | | - DHD_INFO(("Command: %s len:%d \n", cmd_str, (int)strlen(cmd_str))); |
---|
| 5239 | + WL_INFORM(("Command: %s len:%d \n", cmd_str, (int)strlen(cmd_str))); |
---|
1380 | 5240 | if (strncmp(cmd_str, APCS_BAND_AUTO, strlen(APCS_BAND_AUTO)) == 0) { |
---|
1381 | 5241 | band = WLC_BAND_AUTO; |
---|
1382 | | - } else if (strncmp(cmd_str, APCS_BAND_5G, strlen(APCS_BAND_5G)) == 0) { |
---|
| 5242 | + } else if (strnicmp(cmd_str, APCS_BAND_5G, strlen(APCS_BAND_5G)) == 0) { |
---|
1383 | 5243 | band = WLC_BAND_5G; |
---|
1384 | | - } else if (strncmp(cmd_str, APCS_BAND_2G, strlen(APCS_BAND_2G)) == 0) { |
---|
| 5244 | + } else if (strnicmp(cmd_str, APCS_BAND_2G, strlen(APCS_BAND_2G)) == 0) { |
---|
1385 | 5245 | band = WLC_BAND_2G; |
---|
1386 | 5246 | } else { |
---|
1387 | 5247 | /* |
---|
.. | .. |
---|
1390 | 5250 | */ |
---|
1391 | 5251 | channel = bcm_atoi(cmd_str); |
---|
1392 | 5252 | if ((channel == APCS_BAND_2G_LEGACY1) || |
---|
1393 | | - (channel == APCS_BAND_2G_LEGACY2)) |
---|
| 5253 | + (channel == APCS_BAND_2G_LEGACY2)) { |
---|
1394 | 5254 | band = WLC_BAND_2G; |
---|
1395 | | - else { |
---|
1396 | | - DHD_ERROR(("ACS: Invalid argument\n")); |
---|
| 5255 | + } else { |
---|
| 5256 | + WL_ERR(("Invalid argument\n")); |
---|
1397 | 5257 | return -EINVAL; |
---|
1398 | 5258 | } |
---|
1399 | 5259 | } |
---|
1400 | 5260 | } else { |
---|
1401 | 5261 | /* If no argument is provided, default to 2G */ |
---|
1402 | | - DHD_ERROR(("%s: No argument given default to 2.4G scan", __func__)); |
---|
| 5262 | + WL_ERR(("No argument given default to 2.4G scan\n")); |
---|
1403 | 5263 | band = WLC_BAND_2G; |
---|
1404 | 5264 | } |
---|
1405 | | - DHD_INFO(("%s : HAPD_AUTO_CHANNEL = %d, band=%d \n", __FUNCTION__, channel, band)); |
---|
| 5265 | + WL_INFORM(("HAPD_AUTO_CHANNEL = %d, band=%d \n", channel, band)); |
---|
1406 | 5266 | |
---|
1407 | | - reqbuf = kzalloc(CHANSPEC_BUF_SIZE, GFP_KERNEL); |
---|
| 5267 | +#if defined(CONFIG_WLAN_BEYONDX) || defined(CONFIG_SEC_5GMODEL) |
---|
| 5268 | + wl_cfg80211_register_dev_ril_bridge_event_notifier(); |
---|
| 5269 | + if (band == WLC_BAND_2G) { |
---|
| 5270 | + wl_cfg80211_send_msg_to_ril(); |
---|
| 5271 | + |
---|
| 5272 | + if (g_mhs_chan_for_cpcoex) { |
---|
| 5273 | + channel = g_mhs_chan_for_cpcoex; |
---|
| 5274 | + g_mhs_chan_for_cpcoex = 0; |
---|
| 5275 | + goto done2; |
---|
| 5276 | + } |
---|
| 5277 | + } |
---|
| 5278 | + wl_cfg80211_unregister_dev_ril_bridge_event_notifier(); |
---|
| 5279 | +#endif /* CONFIG_WLAN_BEYONDX || defined(CONFIG_SEC_5GMODEL) */ |
---|
| 5280 | + |
---|
| 5281 | + /* If STA is connected, return is STA channel, else ACS can be issued, |
---|
| 5282 | + * set spect to 0 and proceed with ACS |
---|
| 5283 | + */ |
---|
| 5284 | + channel = wl_cfg80211_get_sta_channel(cfg); |
---|
| 5285 | + if (channel) { |
---|
| 5286 | + channel = (channel <= CH_MAX_2G_CHANNEL) ? |
---|
| 5287 | + channel : APCS_DEFAULT_2G_CH; |
---|
| 5288 | + goto done2; |
---|
| 5289 | + } |
---|
| 5290 | + |
---|
| 5291 | + ret = wldev_ioctl_get(dev, WLC_GET_SPECT_MANAGMENT, &spect, sizeof(spect)); |
---|
| 5292 | + if (ret) { |
---|
| 5293 | + WL_ERR(("ACS: error getting the spect, ret=%d\n", ret)); |
---|
| 5294 | + goto done; |
---|
| 5295 | + } |
---|
| 5296 | + |
---|
| 5297 | + if (spect > 0) { |
---|
| 5298 | + ret = wl_cfg80211_set_spect(dev, 0); |
---|
| 5299 | + if (ret < 0) { |
---|
| 5300 | + WL_ERR(("ACS: error while setting spect, ret=%d\n", ret)); |
---|
| 5301 | + goto done; |
---|
| 5302 | + } |
---|
| 5303 | + } |
---|
| 5304 | + |
---|
| 5305 | + reqbuf = (u8 *)MALLOCZ(cfg->osh, CHANSPEC_BUF_SIZE); |
---|
1408 | 5306 | if (reqbuf == NULL) { |
---|
1409 | 5307 | WL_ERR(("failed to allocate chanspec buffer\n")); |
---|
1410 | 5308 | return -ENOMEM; |
---|
1411 | 5309 | } |
---|
1412 | 5310 | |
---|
1413 | | - if ((ret = wldev_ioctl(dev, WLC_GET_SPECT_MANAGMENT, &spect, sizeof(spect), false)) < 0) { |
---|
1414 | | - WL_ERR(("ACS:error getting the spect\n")); |
---|
1415 | | - goto done; |
---|
1416 | | - } |
---|
1417 | | - |
---|
1418 | | - if (spect > 0) { |
---|
1419 | | - /* If STA is connected, return is STA channel, else ACS can be issued, |
---|
1420 | | - * set spect to 0 and proceed with ACS |
---|
1421 | | - */ |
---|
1422 | | - channel = 0; |
---|
1423 | | - if ((channel = wl_cfg80211_get_sta_channel(dev)) > 0) { |
---|
1424 | | - goto done2; |
---|
1425 | | - } else if ((ret = wl_cfg80211_set_spect(dev, 0) < 0)) { |
---|
1426 | | - WL_ERR(("ACS: error while setting spect\n")); |
---|
1427 | | - goto done; |
---|
1428 | | - } |
---|
1429 | | - } |
---|
1430 | | - |
---|
1431 | 5311 | if (band == WLC_BAND_AUTO) { |
---|
1432 | | - DHD_INFO(("%s: ACS full channel scan \n", __func__)); |
---|
| 5312 | + WL_DBG(("ACS full channel scan \n")); |
---|
1433 | 5313 | reqbuf[0] = htod32(0); |
---|
1434 | 5314 | } else if (band == WLC_BAND_5G) { |
---|
1435 | | - DHD_INFO(("%s: ACS 5G band scan \n", __func__)); |
---|
| 5315 | + WL_DBG(("ACS 5G band scan \n")); |
---|
1436 | 5316 | if ((ret = wl_cfg80211_get_chanspecs_5g(dev, reqbuf, CHANSPEC_BUF_SIZE)) < 0) { |
---|
1437 | 5317 | WL_ERR(("ACS 5g chanspec retreival failed! \n")); |
---|
1438 | 5318 | goto done; |
---|
.. | .. |
---|
1442 | 5322 | * If channel argument is not provided/ argument 20 is provided, |
---|
1443 | 5323 | * Restrict channel to 2GHz, 20MHz BW, No SB |
---|
1444 | 5324 | */ |
---|
1445 | | - DHD_INFO(("%s: ACS 2G band scan \n", __func__)); |
---|
| 5325 | + WL_DBG(("ACS 2G band scan \n")); |
---|
1446 | 5326 | if ((ret = wl_cfg80211_get_chanspecs_2g(dev, reqbuf, CHANSPEC_BUF_SIZE)) < 0) { |
---|
1447 | 5327 | WL_ERR(("ACS 2g chanspec retreival failed! \n")); |
---|
1448 | 5328 | goto done; |
---|
1449 | 5329 | } |
---|
1450 | 5330 | } else { |
---|
1451 | | - DHD_ERROR(("ACS: No band chosen\n")); |
---|
| 5331 | + WL_ERR(("ACS: No band chosen\n")); |
---|
1452 | 5332 | goto done2; |
---|
1453 | 5333 | } |
---|
1454 | 5334 | |
---|
1455 | 5335 | buf_size = (band == WLC_BAND_AUTO) ? sizeof(int) : CHANSPEC_BUF_SIZE; |
---|
1456 | | - ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf, |
---|
1457 | | - buf_size, true); |
---|
| 5336 | + ret = wldev_ioctl_set(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf, |
---|
| 5337 | + buf_size); |
---|
1458 | 5338 | if (ret < 0) { |
---|
1459 | | - DHD_ERROR(("%s: can't start auto channel scan, err = %d\n", |
---|
1460 | | - __FUNCTION__, ret)); |
---|
| 5339 | + WL_ERR(("can't start auto channel scan, err = %d\n", ret)); |
---|
1461 | 5340 | channel = 0; |
---|
1462 | 5341 | goto done; |
---|
1463 | 5342 | } |
---|
.. | .. |
---|
1473 | 5352 | OSL_SLEEP(1000); |
---|
1474 | 5353 | } |
---|
1475 | 5354 | |
---|
1476 | | - retry = 10; |
---|
| 5355 | + retry = APCS_MAX_RETRY; |
---|
1477 | 5356 | while (retry--) { |
---|
1478 | | - ret = wldev_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, |
---|
1479 | | - sizeof(chosen), false); |
---|
1480 | | - if (ret < 0 || dtoh32(chosen) == 0) { |
---|
1481 | | - DHD_INFO(("%s: %d tried, ret = %d, chosen = %d\n", |
---|
1482 | | - __FUNCTION__, (10 - retry), ret, chosen)); |
---|
1483 | | - OSL_SLEEP(250); |
---|
| 5357 | + ret = wldev_ioctl_get(dev, WLC_GET_CHANNEL_SEL, &chosen, |
---|
| 5358 | + sizeof(chosen)); |
---|
| 5359 | + if (ret < 0) { |
---|
| 5360 | + chosen = 0; |
---|
1484 | 5361 | } else { |
---|
1485 | | -#ifdef D11AC_IOTYPES |
---|
1486 | | - if (wl_cfg80211_get_ioctl_version() == 1) |
---|
1487 | | - channel = LCHSPEC_CHANNEL((u16)chosen); |
---|
1488 | | - else |
---|
1489 | | - channel = CHSPEC_CHANNEL((u16)chosen); |
---|
1490 | | -#else |
---|
1491 | | - channel = CHSPEC_CHANNEL((u16)chosen); |
---|
1492 | | -#endif /* D11AC_IOTYPES */ |
---|
1493 | | - DHD_ERROR(("%s: selected channel = %d\n", __FUNCTION__, channel)); |
---|
1494 | | - break; |
---|
| 5362 | + chosen = dtoh32(chosen); |
---|
1495 | 5363 | } |
---|
| 5364 | + |
---|
| 5365 | + if (chosen) { |
---|
| 5366 | + int chosen_band; |
---|
| 5367 | + int apcs_band; |
---|
| 5368 | +#ifdef D11AC_IOTYPES |
---|
| 5369 | + if (wl_cfg80211_get_ioctl_version() == 1) { |
---|
| 5370 | + channel = LCHSPEC_CHANNEL((chanspec_t)chosen); |
---|
| 5371 | + } else { |
---|
| 5372 | + channel = CHSPEC_CHANNEL((chanspec_t)chosen); |
---|
| 5373 | + } |
---|
| 5374 | +#else |
---|
| 5375 | + channel = CHSPEC_CHANNEL((chanspec_t)chosen); |
---|
| 5376 | +#endif /* D11AC_IOTYPES */ |
---|
| 5377 | + apcs_band = (band == WLC_BAND_AUTO) ? WLC_BAND_2G : band; |
---|
| 5378 | + chosen_band = (channel <= CH_MAX_2G_CHANNEL) ? WLC_BAND_2G : WLC_BAND_5G; |
---|
| 5379 | + if (apcs_band == chosen_band) { |
---|
| 5380 | + WL_ERR(("selected channel = %d\n", channel)); |
---|
| 5381 | + break; |
---|
| 5382 | + } |
---|
| 5383 | + } |
---|
| 5384 | + WL_DBG(("%d tried, ret = %d, chosen = 0x%x\n", |
---|
| 5385 | + (APCS_MAX_RETRY - retry), ret, chosen)); |
---|
| 5386 | + OSL_SLEEP(250); |
---|
1496 | 5387 | } |
---|
1497 | 5388 | |
---|
1498 | 5389 | done: |
---|
1499 | 5390 | if ((retry == 0) || (ret < 0)) { |
---|
1500 | 5391 | /* On failure, fallback to a default channel */ |
---|
1501 | | - if ((band == WLC_BAND_5G)) { |
---|
1502 | | - channel = 36; |
---|
| 5392 | + if (band == WLC_BAND_5G) { |
---|
| 5393 | + channel = APCS_DEFAULT_5G_CH; |
---|
1503 | 5394 | } else { |
---|
1504 | | - channel = 1; |
---|
| 5395 | + channel = APCS_DEFAULT_2G_CH; |
---|
1505 | 5396 | } |
---|
1506 | | - DHD_ERROR(("%s: ACS failed." |
---|
1507 | | - " Fall back to default channel (%d) \n", __FUNCTION__, channel)); |
---|
| 5397 | + WL_ERR(("ACS failed. Fall back to default channel (%d) \n", channel)); |
---|
1508 | 5398 | } |
---|
1509 | 5399 | done2: |
---|
1510 | | - if (spect) { |
---|
| 5400 | + if (spect > 0) { |
---|
1511 | 5401 | if ((ret = wl_cfg80211_set_spect(dev, spect) < 0)) { |
---|
1512 | 5402 | WL_ERR(("ACS: error while setting spect\n")); |
---|
1513 | 5403 | } |
---|
1514 | 5404 | } |
---|
1515 | | - if (reqbuf) |
---|
1516 | | - kfree(reqbuf); |
---|
| 5405 | + |
---|
| 5406 | + if (reqbuf) { |
---|
| 5407 | + MFREE(cfg->osh, reqbuf, CHANSPEC_BUF_SIZE); |
---|
| 5408 | + } |
---|
1517 | 5409 | |
---|
1518 | 5410 | if (channel) { |
---|
1519 | | - snprintf(command, 4, "%d", channel); |
---|
1520 | | - DHD_INFO(("%s: command result is %s \n", __FUNCTION__, command)); |
---|
1521 | | - return strlen(command); |
---|
1522 | | - } else { |
---|
1523 | | - return ret; |
---|
| 5411 | + ret = snprintf(command, total_len, "%d", channel); |
---|
| 5412 | + WL_INFORM(("command result is %s \n", command)); |
---|
1524 | 5413 | } |
---|
| 5414 | + |
---|
| 5415 | + return ret; |
---|
1525 | 5416 | } |
---|
1526 | 5417 | #endif /* WL_SUPPORT_AUTO_CHANNEL */ |
---|
1527 | 5418 | |
---|
| 5419 | +#ifdef SUPPORT_HIDDEN_AP |
---|
| 5420 | +static int |
---|
| 5421 | +wl_android_set_max_num_sta(struct net_device *dev, const char* string_num) |
---|
| 5422 | +{ |
---|
| 5423 | + int err = BCME_ERROR; |
---|
| 5424 | + int max_assoc; |
---|
1528 | 5425 | |
---|
1529 | | -int wl_android_set_roam_mode(struct net_device *dev, char *command, int total_len) |
---|
| 5426 | + max_assoc = bcm_atoi(string_num); |
---|
| 5427 | + DHD_INFO(("wl_android_set_max_num_sta : HAPD_MAX_NUM_STA = %d\n", max_assoc)); |
---|
| 5428 | + |
---|
| 5429 | + err = wldev_iovar_setint(dev, "maxassoc", max_assoc); |
---|
| 5430 | + if (err < 0) { |
---|
| 5431 | + WL_ERR(("failed to set maxassoc, error:%d\n", err)); |
---|
| 5432 | + } |
---|
| 5433 | + |
---|
| 5434 | + return err; |
---|
| 5435 | +} |
---|
| 5436 | + |
---|
| 5437 | +static int |
---|
| 5438 | +wl_android_set_ssid(struct net_device *dev, const char* hapd_ssid) |
---|
| 5439 | +{ |
---|
| 5440 | + wlc_ssid_t ssid; |
---|
| 5441 | + s32 ret; |
---|
| 5442 | + |
---|
| 5443 | + ssid.SSID_len = strlen(hapd_ssid); |
---|
| 5444 | + if (ssid.SSID_len == 0) { |
---|
| 5445 | + WL_ERR(("wl_android_set_ssids : No SSID\n")); |
---|
| 5446 | + return -1; |
---|
| 5447 | + } |
---|
| 5448 | + if (ssid.SSID_len > DOT11_MAX_SSID_LEN) { |
---|
| 5449 | + ssid.SSID_len = DOT11_MAX_SSID_LEN; |
---|
| 5450 | + WL_ERR(("wl_android_set_ssid : Too long SSID Length %zu\n", strlen(hapd_ssid))); |
---|
| 5451 | + } |
---|
| 5452 | + bcm_strncpy_s(ssid.SSID, sizeof(ssid.SSID), hapd_ssid, ssid.SSID_len); |
---|
| 5453 | + DHD_INFO(("wl_android_set_ssid: HAPD_SSID = %s\n", ssid.SSID)); |
---|
| 5454 | + ret = wldev_ioctl_set(dev, WLC_SET_SSID, &ssid, sizeof(wlc_ssid_t)); |
---|
| 5455 | + if (ret < 0) { |
---|
| 5456 | + WL_ERR(("wl_android_set_ssid : WLC_SET_SSID Error:%d\n", ret)); |
---|
| 5457 | + } |
---|
| 5458 | + return 1; |
---|
| 5459 | + |
---|
| 5460 | +} |
---|
| 5461 | + |
---|
| 5462 | +static int |
---|
| 5463 | +wl_android_set_hide_ssid(struct net_device *dev, const char* string_num) |
---|
| 5464 | +{ |
---|
| 5465 | + int hide_ssid; |
---|
| 5466 | + int enable = 0; |
---|
| 5467 | + int err = BCME_ERROR; |
---|
| 5468 | + |
---|
| 5469 | + hide_ssid = bcm_atoi(string_num); |
---|
| 5470 | + DHD_INFO(("wl_android_set_hide_ssid: HIDE_SSID = %d\n", hide_ssid)); |
---|
| 5471 | + if (hide_ssid) { |
---|
| 5472 | + enable = 1; |
---|
| 5473 | + } |
---|
| 5474 | + |
---|
| 5475 | + err = wldev_iovar_setint(dev, "closednet", enable); |
---|
| 5476 | + if (err < 0) { |
---|
| 5477 | + WL_ERR(("failed to set closednet, error:%d\n", err)); |
---|
| 5478 | + } |
---|
| 5479 | + |
---|
| 5480 | + return err; |
---|
| 5481 | +} |
---|
| 5482 | +#endif /* SUPPORT_HIDDEN_AP */ |
---|
| 5483 | + |
---|
| 5484 | +#ifdef CUSTOMER_HW4_PRIVATE_CMD |
---|
| 5485 | +#ifdef SUPPORT_SOFTAP_SINGL_DISASSOC |
---|
| 5486 | +static int |
---|
| 5487 | +wl_android_sta_diassoc(struct net_device *dev, const char* straddr) |
---|
| 5488 | +{ |
---|
| 5489 | + scb_val_t scbval; |
---|
| 5490 | + int error = 0; |
---|
| 5491 | + |
---|
| 5492 | + DHD_INFO(("wl_android_sta_diassoc: deauth STA %s\n", straddr)); |
---|
| 5493 | + |
---|
| 5494 | + /* Unspecified reason */ |
---|
| 5495 | + scbval.val = htod32(1); |
---|
| 5496 | + |
---|
| 5497 | + if (bcm_ether_atoe(straddr, &scbval.ea) == 0) { |
---|
| 5498 | + DHD_ERROR(("wl_android_sta_diassoc: Invalid station MAC Address!!!\n")); |
---|
| 5499 | + return -1; |
---|
| 5500 | + } |
---|
| 5501 | + |
---|
| 5502 | + DHD_ERROR(("wl_android_sta_diassoc: deauth STA: "MACDBG " scb_val.val %d\n", |
---|
| 5503 | + MAC2STRDBG(scbval.ea.octet), scbval.val)); |
---|
| 5504 | + |
---|
| 5505 | + error = wldev_ioctl_set(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, |
---|
| 5506 | + sizeof(scb_val_t)); |
---|
| 5507 | + if (error) { |
---|
| 5508 | + DHD_ERROR(("Fail to DEAUTH station, error = %d\n", error)); |
---|
| 5509 | + } |
---|
| 5510 | + |
---|
| 5511 | + return 1; |
---|
| 5512 | +} |
---|
| 5513 | +#endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */ |
---|
| 5514 | + |
---|
| 5515 | +#ifdef SUPPORT_SET_LPC |
---|
| 5516 | +static int |
---|
| 5517 | +wl_android_set_lpc(struct net_device *dev, const char* string_num) |
---|
| 5518 | +{ |
---|
| 5519 | + int lpc_enabled, ret; |
---|
| 5520 | + s32 val = 1; |
---|
| 5521 | + |
---|
| 5522 | + lpc_enabled = bcm_atoi(string_num); |
---|
| 5523 | + DHD_INFO(("wl_android_set_lpc: HAPD_LPC_ENABLED = %d\n", lpc_enabled)); |
---|
| 5524 | + |
---|
| 5525 | + ret = wldev_ioctl_set(dev, WLC_DOWN, &val, sizeof(s32)); |
---|
| 5526 | + if (ret < 0) |
---|
| 5527 | + DHD_ERROR(("WLC_DOWN error %d\n", ret)); |
---|
| 5528 | + |
---|
| 5529 | + wldev_iovar_setint(dev, "lpc", lpc_enabled); |
---|
| 5530 | + |
---|
| 5531 | + ret = wldev_ioctl_set(dev, WLC_UP, &val, sizeof(s32)); |
---|
| 5532 | + if (ret < 0) |
---|
| 5533 | + DHD_ERROR(("WLC_UP error %d\n", ret)); |
---|
| 5534 | + |
---|
| 5535 | + return 1; |
---|
| 5536 | +} |
---|
| 5537 | +#endif /* SUPPORT_SET_LPC */ |
---|
| 5538 | + |
---|
| 5539 | +static int |
---|
| 5540 | +wl_android_ch_res_rl(struct net_device *dev, bool change) |
---|
| 5541 | +{ |
---|
| 5542 | + int error = 0; |
---|
| 5543 | + s32 srl = 7; |
---|
| 5544 | + s32 lrl = 4; |
---|
| 5545 | + printk("wl_android_ch_res_rl: enter\n"); |
---|
| 5546 | + if (change) { |
---|
| 5547 | + srl = 4; |
---|
| 5548 | + lrl = 2; |
---|
| 5549 | + } |
---|
| 5550 | + |
---|
| 5551 | + BCM_REFERENCE(lrl); |
---|
| 5552 | + |
---|
| 5553 | + error = wldev_ioctl_set(dev, WLC_SET_SRL, &srl, sizeof(s32)); |
---|
| 5554 | + if (error) { |
---|
| 5555 | + DHD_ERROR(("Failed to set SRL, error = %d\n", error)); |
---|
| 5556 | + } |
---|
| 5557 | +#ifndef CUSTOM_LONG_RETRY_LIMIT |
---|
| 5558 | + error = wldev_ioctl_set(dev, WLC_SET_LRL, &lrl, sizeof(s32)); |
---|
| 5559 | + if (error) { |
---|
| 5560 | + DHD_ERROR(("Failed to set LRL, error = %d\n", error)); |
---|
| 5561 | + } |
---|
| 5562 | +#endif /* CUSTOM_LONG_RETRY_LIMIT */ |
---|
| 5563 | + return error; |
---|
| 5564 | +} |
---|
| 5565 | + |
---|
| 5566 | +#ifdef SUPPORT_LTECX |
---|
| 5567 | +#define DEFAULT_WLANRX_PROT 1 |
---|
| 5568 | +#define DEFAULT_LTERX_PROT 0 |
---|
| 5569 | +#define DEFAULT_LTETX_ADV 1200 |
---|
| 5570 | + |
---|
| 5571 | +static int |
---|
| 5572 | +wl_android_set_ltecx(struct net_device *dev, const char* string_num) |
---|
| 5573 | +{ |
---|
| 5574 | + uint16 chan_bitmap; |
---|
| 5575 | + int ret; |
---|
| 5576 | + |
---|
| 5577 | + chan_bitmap = bcm_strtoul(string_num, NULL, 16); |
---|
| 5578 | + |
---|
| 5579 | + DHD_INFO(("wl_android_set_ltecx: LTECOEX 0x%x\n", chan_bitmap)); |
---|
| 5580 | + |
---|
| 5581 | + if (chan_bitmap) { |
---|
| 5582 | + ret = wldev_iovar_setint(dev, "mws_coex_bitmap", chan_bitmap); |
---|
| 5583 | + if (ret < 0) { |
---|
| 5584 | + DHD_ERROR(("mws_coex_bitmap error %d\n", ret)); |
---|
| 5585 | + } |
---|
| 5586 | + |
---|
| 5587 | + ret = wldev_iovar_setint(dev, "mws_wlanrx_prot", DEFAULT_WLANRX_PROT); |
---|
| 5588 | + if (ret < 0) { |
---|
| 5589 | + DHD_ERROR(("mws_wlanrx_prot error %d\n", ret)); |
---|
| 5590 | + } |
---|
| 5591 | + |
---|
| 5592 | + ret = wldev_iovar_setint(dev, "mws_lterx_prot", DEFAULT_LTERX_PROT); |
---|
| 5593 | + if (ret < 0) { |
---|
| 5594 | + DHD_ERROR(("mws_lterx_prot error %d\n", ret)); |
---|
| 5595 | + } |
---|
| 5596 | + |
---|
| 5597 | + ret = wldev_iovar_setint(dev, "mws_ltetx_adv", DEFAULT_LTETX_ADV); |
---|
| 5598 | + if (ret < 0) { |
---|
| 5599 | + DHD_ERROR(("mws_ltetx_adv error %d\n", ret)); |
---|
| 5600 | + } |
---|
| 5601 | + } else { |
---|
| 5602 | + ret = wldev_iovar_setint(dev, "mws_coex_bitmap", chan_bitmap); |
---|
| 5603 | + if (ret < 0) { |
---|
| 5604 | + if (ret == BCME_UNSUPPORTED) { |
---|
| 5605 | + DHD_ERROR(("LTECX_CHAN_BITMAP is UNSUPPORTED\n")); |
---|
| 5606 | + } else { |
---|
| 5607 | + DHD_ERROR(("LTECX_CHAN_BITMAP error %d\n", ret)); |
---|
| 5608 | + } |
---|
| 5609 | + } |
---|
| 5610 | + } |
---|
| 5611 | + return 1; |
---|
| 5612 | +} |
---|
| 5613 | +#endif /* SUPPORT_LTECX */ |
---|
| 5614 | + |
---|
| 5615 | +#ifdef WL_RELMCAST |
---|
| 5616 | +static int |
---|
| 5617 | +wl_android_rmc_enable(struct net_device *net, int rmc_enable) |
---|
| 5618 | +{ |
---|
| 5619 | + int err; |
---|
| 5620 | + |
---|
| 5621 | + err = wldev_iovar_setint(net, "rmc_ackreq", rmc_enable); |
---|
| 5622 | + if (err != BCME_OK) { |
---|
| 5623 | + DHD_ERROR(("wl_android_rmc_enable: rmc_ackreq, error = %d\n", err)); |
---|
| 5624 | + } |
---|
| 5625 | + return err; |
---|
| 5626 | +} |
---|
| 5627 | + |
---|
| 5628 | +static int |
---|
| 5629 | +wl_android_rmc_set_leader(struct net_device *dev, const char* straddr) |
---|
| 5630 | +{ |
---|
| 5631 | + int error = BCME_OK; |
---|
| 5632 | + char smbuf[WLC_IOCTL_SMLEN]; |
---|
| 5633 | + wl_rmc_entry_t rmc_entry; |
---|
| 5634 | + DHD_INFO(("wl_android_rmc_set_leader: Set new RMC leader %s\n", straddr)); |
---|
| 5635 | + |
---|
| 5636 | + bzero(&rmc_entry, sizeof(wl_rmc_entry_t)); |
---|
| 5637 | + if (!bcm_ether_atoe(straddr, &rmc_entry.addr)) { |
---|
| 5638 | + if (strlen(straddr) == 1 && bcm_atoi(straddr) == 0) { |
---|
| 5639 | + DHD_INFO(("wl_android_rmc_set_leader: Set auto leader selection mode\n")); |
---|
| 5640 | + bzero(&rmc_entry, sizeof(wl_rmc_entry_t)); |
---|
| 5641 | + } else { |
---|
| 5642 | + DHD_ERROR(("wl_android_rmc_set_leader: No valid mac address provided\n")); |
---|
| 5643 | + return BCME_ERROR; |
---|
| 5644 | + } |
---|
| 5645 | + } |
---|
| 5646 | + |
---|
| 5647 | + error = wldev_iovar_setbuf(dev, "rmc_ar", &rmc_entry, sizeof(wl_rmc_entry_t), |
---|
| 5648 | + smbuf, sizeof(smbuf), NULL); |
---|
| 5649 | + |
---|
| 5650 | + if (error != BCME_OK) { |
---|
| 5651 | + DHD_ERROR(("wl_android_rmc_set_leader: Unable to set RMC leader, error = %d\n", |
---|
| 5652 | + error)); |
---|
| 5653 | + } |
---|
| 5654 | + |
---|
| 5655 | + return error; |
---|
| 5656 | +} |
---|
| 5657 | + |
---|
| 5658 | +static int wl_android_set_rmc_event(struct net_device *dev, char *command) |
---|
| 5659 | +{ |
---|
| 5660 | + int err = 0; |
---|
| 5661 | + int pid = 0; |
---|
| 5662 | + |
---|
| 5663 | + if (sscanf(command, CMD_SET_RMC_EVENT " %d", &pid) <= 0) { |
---|
| 5664 | + WL_ERR(("Failed to get Parameter from : %s\n", command)); |
---|
| 5665 | + return -1; |
---|
| 5666 | + } |
---|
| 5667 | + |
---|
| 5668 | + /* set pid, and if the event was happened, let's send a notification through netlink */ |
---|
| 5669 | + wl_cfg80211_set_rmc_pid(dev, pid); |
---|
| 5670 | + |
---|
| 5671 | + WL_DBG(("RMC pid=%d\n", pid)); |
---|
| 5672 | + |
---|
| 5673 | + return err; |
---|
| 5674 | +} |
---|
| 5675 | +#endif /* WL_RELMCAST */ |
---|
| 5676 | + |
---|
| 5677 | +int wl_android_get_singlecore_scan(struct net_device *dev, char *command, int total_len) |
---|
| 5678 | +{ |
---|
| 5679 | + int error = 0; |
---|
| 5680 | + int bytes_written = 0; |
---|
| 5681 | + int mode = 0; |
---|
| 5682 | + |
---|
| 5683 | + error = wldev_iovar_getint(dev, "scan_ps", &mode); |
---|
| 5684 | + if (error) { |
---|
| 5685 | + DHD_ERROR(("wl_android_get_singlecore_scan: Failed to get single core scan Mode," |
---|
| 5686 | + " error = %d\n", |
---|
| 5687 | + error)); |
---|
| 5688 | + return -1; |
---|
| 5689 | + } |
---|
| 5690 | + |
---|
| 5691 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GET_SCSCAN, mode); |
---|
| 5692 | + |
---|
| 5693 | + return bytes_written; |
---|
| 5694 | +} |
---|
| 5695 | + |
---|
| 5696 | +int wl_android_set_singlecore_scan(struct net_device *dev, char *command) |
---|
1530 | 5697 | { |
---|
1531 | 5698 | int error = 0; |
---|
1532 | 5699 | int mode = 0; |
---|
1533 | 5700 | |
---|
1534 | 5701 | if (sscanf(command, "%*s %d", &mode) != 1) { |
---|
1535 | | - DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__)); |
---|
| 5702 | + DHD_ERROR(("wl_android_set_singlecore_scan: Failed to get Parameter\n")); |
---|
| 5703 | + return -1; |
---|
| 5704 | + } |
---|
| 5705 | + |
---|
| 5706 | + error = wldev_iovar_setint(dev, "scan_ps", mode); |
---|
| 5707 | + if (error) { |
---|
| 5708 | + DHD_ERROR(("wl_android_set_singlecore_scan[1]: Failed to set Mode %d, error = %d\n", |
---|
| 5709 | + mode, error)); |
---|
| 5710 | + return -1; |
---|
| 5711 | + } |
---|
| 5712 | + |
---|
| 5713 | + return error; |
---|
| 5714 | +} |
---|
| 5715 | +#ifdef TEST_TX_POWER_CONTROL |
---|
| 5716 | +static int |
---|
| 5717 | +wl_android_set_tx_power(struct net_device *dev, const char* string_num) |
---|
| 5718 | +{ |
---|
| 5719 | + int err = 0; |
---|
| 5720 | + s32 dbm; |
---|
| 5721 | + enum nl80211_tx_power_setting type; |
---|
| 5722 | + |
---|
| 5723 | + dbm = bcm_atoi(string_num); |
---|
| 5724 | + |
---|
| 5725 | + if (dbm < -1) { |
---|
| 5726 | + DHD_ERROR(("wl_android_set_tx_power: dbm is negative...\n")); |
---|
| 5727 | + return -EINVAL; |
---|
| 5728 | + } |
---|
| 5729 | + |
---|
| 5730 | + if (dbm == -1) |
---|
| 5731 | + type = NL80211_TX_POWER_AUTOMATIC; |
---|
| 5732 | + else |
---|
| 5733 | + type = NL80211_TX_POWER_FIXED; |
---|
| 5734 | + |
---|
| 5735 | + err = wl_set_tx_power(dev, type, dbm); |
---|
| 5736 | + if (unlikely(err)) { |
---|
| 5737 | + DHD_ERROR(("wl_android_set_tx_power: error (%d)\n", err)); |
---|
| 5738 | + return err; |
---|
| 5739 | + } |
---|
| 5740 | + |
---|
| 5741 | + return 1; |
---|
| 5742 | +} |
---|
| 5743 | + |
---|
| 5744 | +static int |
---|
| 5745 | +wl_android_get_tx_power(struct net_device *dev, char *command, int total_len) |
---|
| 5746 | +{ |
---|
| 5747 | + int err; |
---|
| 5748 | + int bytes_written; |
---|
| 5749 | + s32 dbm = 0; |
---|
| 5750 | + |
---|
| 5751 | + err = wl_get_tx_power(dev, &dbm); |
---|
| 5752 | + if (unlikely(err)) { |
---|
| 5753 | + DHD_ERROR(("wl_android_get_tx_power: error (%d)\n", err)); |
---|
| 5754 | + return err; |
---|
| 5755 | + } |
---|
| 5756 | + |
---|
| 5757 | + bytes_written = snprintf(command, total_len, "%s %d", |
---|
| 5758 | + CMD_TEST_GET_TX_POWER, dbm); |
---|
| 5759 | + |
---|
| 5760 | + DHD_ERROR(("wl_android_get_tx_power: GET_TX_POWER: dBm=%d\n", dbm)); |
---|
| 5761 | + |
---|
| 5762 | + return bytes_written; |
---|
| 5763 | +} |
---|
| 5764 | +#endif /* TEST_TX_POWER_CONTROL */ |
---|
| 5765 | + |
---|
| 5766 | +static int |
---|
| 5767 | +wl_android_set_sarlimit_txctrl(struct net_device *dev, const char* string_num) |
---|
| 5768 | +{ |
---|
| 5769 | + int err = BCME_ERROR; |
---|
| 5770 | + int setval = 0; |
---|
| 5771 | + s32 mode = bcm_atoi(string_num); |
---|
| 5772 | + s32 mode_bit = 0; |
---|
| 5773 | + int enab = 0; |
---|
| 5774 | + |
---|
| 5775 | + /* As Samsung specific and their requirement, |
---|
| 5776 | + * the mode set as the following form. |
---|
| 5777 | + * -1 : HEAD SAR disabled |
---|
| 5778 | + * 0 : HEAD SAR enabled |
---|
| 5779 | + * 1 : GRIP SAR disabled |
---|
| 5780 | + * 2 : GRIP SAR enabled |
---|
| 5781 | + * 3 : NR mmWave SAR disabled |
---|
| 5782 | + * 4 : NR mmWave SAR enabled |
---|
| 5783 | + * 5 : NR Sub6 SAR disabled |
---|
| 5784 | + * 6 : NR Sub6 SAR enabled |
---|
| 5785 | + * 7 : SAR BACKOFF disabled all |
---|
| 5786 | + * The 'SAR BACKOFF disabled all' index should be the end of the mode. |
---|
| 5787 | + */ |
---|
| 5788 | + if ((mode < HEAD_SAR_BACKOFF_DISABLE) || (mode > SAR_BACKOFF_DISABLE_ALL)) { |
---|
| 5789 | + DHD_ERROR(("%s: Request for Unsupported:%d\n", __FUNCTION__, bcm_atoi(string_num))); |
---|
| 5790 | + err = BCME_RANGE; |
---|
| 5791 | + goto error; |
---|
| 5792 | + } |
---|
| 5793 | + |
---|
| 5794 | + mode_bit = mode + 1; |
---|
| 5795 | + enab = mode_bit % 2; |
---|
| 5796 | + mode_bit = mode_bit / 2; |
---|
| 5797 | + |
---|
| 5798 | + err = wldev_iovar_getint(dev, "sar_enable", &setval); |
---|
| 5799 | + if (unlikely(err)) { |
---|
| 5800 | + DHD_ERROR(("%s: Failed to get sar_enable - error (%d)\n", __FUNCTION__, err)); |
---|
| 5801 | + goto error; |
---|
| 5802 | + } |
---|
| 5803 | + |
---|
| 5804 | + if (mode == SAR_BACKOFF_DISABLE_ALL) { |
---|
| 5805 | + DHD_ERROR(("%s: SAR limit control all mode disable!\n", __FUNCTION__)); |
---|
| 5806 | + setval = 0; |
---|
| 5807 | + } else { |
---|
| 5808 | + DHD_ERROR(("%s: SAR limit control mode %d enab %d\n", |
---|
| 5809 | + __FUNCTION__, mode_bit, enab)); |
---|
| 5810 | + if (enab) { |
---|
| 5811 | + setval |= (1 << mode_bit); |
---|
| 5812 | + } else { |
---|
| 5813 | + setval &= ~(1 << mode_bit); |
---|
| 5814 | + } |
---|
| 5815 | + } |
---|
| 5816 | + |
---|
| 5817 | + err = wldev_iovar_setint(dev, "sar_enable", setval); |
---|
| 5818 | + if (unlikely(err)) { |
---|
| 5819 | + DHD_ERROR(("%s: Failed to set sar_enable - error (%d)\n", __FUNCTION__, err)); |
---|
| 5820 | + goto error; |
---|
| 5821 | + } |
---|
| 5822 | +error: |
---|
| 5823 | + return err; |
---|
| 5824 | +} |
---|
| 5825 | + |
---|
| 5826 | +#ifdef SUPPORT_SET_TID |
---|
| 5827 | +static int |
---|
| 5828 | +wl_android_set_tid(struct net_device *dev, char* command) |
---|
| 5829 | +{ |
---|
| 5830 | + int err = BCME_ERROR; |
---|
| 5831 | + char *pos = command; |
---|
| 5832 | + char *token = NULL; |
---|
| 5833 | + uint8 mode = 0; |
---|
| 5834 | + uint32 uid = 0; |
---|
| 5835 | + uint8 prio = 0; |
---|
| 5836 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 5837 | + |
---|
| 5838 | + if (!dhdp) { |
---|
| 5839 | + WL_ERR(("dhd is NULL\n")); |
---|
| 5840 | + return err; |
---|
| 5841 | + } |
---|
| 5842 | + |
---|
| 5843 | + WL_DBG(("%s: command[%s]\n", __FUNCTION__, command)); |
---|
| 5844 | + |
---|
| 5845 | + /* drop command */ |
---|
| 5846 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 5847 | + |
---|
| 5848 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 5849 | + if (!token) { |
---|
| 5850 | + WL_ERR(("Invalid arguments\n")); |
---|
| 5851 | + return err; |
---|
| 5852 | + } |
---|
| 5853 | + |
---|
| 5854 | + mode = bcm_atoi(token); |
---|
| 5855 | + |
---|
| 5856 | + if (mode < SET_TID_OFF || mode > SET_TID_BASED_ON_UID) { |
---|
| 5857 | + WL_ERR(("Invalid arguments, mode %d\n", mode)); |
---|
| 5858 | + return err; |
---|
| 5859 | + } |
---|
| 5860 | + |
---|
| 5861 | + if (mode) { |
---|
| 5862 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 5863 | + if (!token) { |
---|
| 5864 | + WL_ERR(("Invalid arguments for target uid\n")); |
---|
| 5865 | + return err; |
---|
| 5866 | + } |
---|
| 5867 | + |
---|
| 5868 | + uid = bcm_atoi(token); |
---|
| 5869 | + |
---|
| 5870 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 5871 | + if (!token) { |
---|
| 5872 | + WL_ERR(("Invalid arguments for target tid\n")); |
---|
| 5873 | + return err; |
---|
| 5874 | + } |
---|
| 5875 | + |
---|
| 5876 | + prio = bcm_atoi(token); |
---|
| 5877 | + if (prio >= 0 && prio <= MAXPRIO) { |
---|
| 5878 | + dhdp->tid_mode = mode; |
---|
| 5879 | + dhdp->target_uid = uid; |
---|
| 5880 | + dhdp->target_tid = prio; |
---|
| 5881 | + } else { |
---|
| 5882 | + WL_ERR(("Invalid arguments, prio %d\n", prio)); |
---|
| 5883 | + return err; |
---|
| 5884 | + } |
---|
| 5885 | + } else { |
---|
| 5886 | + dhdp->tid_mode = SET_TID_OFF; |
---|
| 5887 | + dhdp->target_uid = 0; |
---|
| 5888 | + dhdp->target_tid = 0; |
---|
| 5889 | + } |
---|
| 5890 | + |
---|
| 5891 | + WL_DBG(("%s mode [%d], uid [%d], tid [%d]\n", __FUNCTION__, |
---|
| 5892 | + dhdp->tid_mode, dhdp->target_uid, dhdp->target_tid)); |
---|
| 5893 | + |
---|
| 5894 | + err = BCME_OK; |
---|
| 5895 | + return err; |
---|
| 5896 | +} |
---|
| 5897 | + |
---|
| 5898 | +static int |
---|
| 5899 | +wl_android_get_tid(struct net_device *dev, char* command, int total_len) |
---|
| 5900 | +{ |
---|
| 5901 | + int bytes_written = BCME_ERROR; |
---|
| 5902 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 5903 | + |
---|
| 5904 | + if (!dhdp) { |
---|
| 5905 | + WL_ERR(("dhd is NULL\n")); |
---|
| 5906 | + return bytes_written; |
---|
| 5907 | + } |
---|
| 5908 | + |
---|
| 5909 | + bytes_written = snprintf(command, total_len, "mode %d uid %d tid %d", |
---|
| 5910 | + dhdp->tid_mode, dhdp->target_uid, dhdp->target_tid); |
---|
| 5911 | + |
---|
| 5912 | + WL_DBG(("%s: command results %s\n", __FUNCTION__, command)); |
---|
| 5913 | + |
---|
| 5914 | + return bytes_written; |
---|
| 5915 | +} |
---|
| 5916 | +#endif /* SUPPORT_SET_TID */ |
---|
| 5917 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
| 5918 | + |
---|
| 5919 | +int wl_android_set_roam_mode(struct net_device *dev, char *command) |
---|
| 5920 | +{ |
---|
| 5921 | + int error = 0; |
---|
| 5922 | + int mode = 0; |
---|
| 5923 | + |
---|
| 5924 | + if (sscanf(command, "%*s %d", &mode) != 1) { |
---|
| 5925 | + DHD_ERROR(("wl_android_set_roam_mode: Failed to get Parameter\n")); |
---|
1536 | 5926 | return -1; |
---|
1537 | 5927 | } |
---|
1538 | 5928 | |
---|
1539 | 5929 | error = wldev_iovar_setint(dev, "roam_off", mode); |
---|
1540 | 5930 | if (error) { |
---|
1541 | | - DHD_ERROR(("%s: Failed to set roaming Mode %d, error = %d\n", |
---|
1542 | | - __FUNCTION__, mode, error)); |
---|
| 5931 | + DHD_ERROR(("wl_android_set_roam_mode: Failed to set roaming Mode %d, error = %d\n", |
---|
| 5932 | + mode, error)); |
---|
1543 | 5933 | return -1; |
---|
1544 | 5934 | } |
---|
1545 | 5935 | else |
---|
1546 | | - DHD_ERROR(("%s: succeeded to set roaming Mode %d, error = %d\n", |
---|
1547 | | - __FUNCTION__, mode, error)); |
---|
| 5936 | + DHD_ERROR(("wl_android_set_roam_mode: succeeded to set roaming Mode %d," |
---|
| 5937 | + " error = %d\n", |
---|
| 5938 | + mode, error)); |
---|
1548 | 5939 | return 0; |
---|
1549 | 5940 | } |
---|
1550 | 5941 | |
---|
.. | .. |
---|
1558 | 5949 | vndr_ie_setbuf_t *vndr_ie = NULL; |
---|
1559 | 5950 | s32 iecount; |
---|
1560 | 5951 | uint32 pktflag; |
---|
1561 | | - u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; |
---|
1562 | | - s32 err = BCME_OK; |
---|
| 5952 | + s32 err = BCME_OK, bssidx; |
---|
| 5953 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
1563 | 5954 | |
---|
1564 | 5955 | /* Check the VSIE (Vendor Specific IE) which was added. |
---|
1565 | 5956 | * If exist then send IOVAR to delete it |
---|
.. | .. |
---|
1568 | 5959 | return -EINVAL; |
---|
1569 | 5960 | } |
---|
1570 | 5961 | |
---|
| 5962 | + if (total_len < (strlen(CMD_SETIBSSBEACONOUIDATA) + 1)) { |
---|
| 5963 | + WL_ERR(("error. total_len:%d\n", total_len)); |
---|
| 5964 | + return -EINVAL; |
---|
| 5965 | + } |
---|
| 5966 | + |
---|
1571 | 5967 | pcmd = command + strlen(CMD_SETIBSSBEACONOUIDATA) + 1; |
---|
1572 | 5968 | for (idx = 0; idx < DOT11_OUI_LEN; idx++) { |
---|
| 5969 | + if (*pcmd == '\0') { |
---|
| 5970 | + WL_ERR(("error while parsing OUI.\n")); |
---|
| 5971 | + return -EINVAL; |
---|
| 5972 | + } |
---|
1573 | 5973 | hex[0] = *pcmd++; |
---|
1574 | 5974 | hex[1] = *pcmd++; |
---|
1575 | 5975 | ie_buf[idx] = (uint8)simple_strtoul(hex, NULL, 16); |
---|
.. | .. |
---|
1581 | 5981 | ie_buf[idx++] = (uint8)simple_strtoul(hex, NULL, 16); |
---|
1582 | 5982 | datalen++; |
---|
1583 | 5983 | } |
---|
1584 | | - tot_len = sizeof(vndr_ie_setbuf_t) + (datalen - 1); |
---|
1585 | | - vndr_ie = (vndr_ie_setbuf_t *) kzalloc(tot_len, kflags); |
---|
| 5984 | + |
---|
| 5985 | + if (datalen <= 0) { |
---|
| 5986 | + WL_ERR(("error. vndr ie len:%d\n", datalen)); |
---|
| 5987 | + return -EINVAL; |
---|
| 5988 | + } |
---|
| 5989 | + |
---|
| 5990 | + tot_len = (int)(sizeof(vndr_ie_setbuf_t) + (datalen - 1)); |
---|
| 5991 | + vndr_ie = (vndr_ie_setbuf_t *)MALLOCZ(cfg->osh, tot_len); |
---|
1586 | 5992 | if (!vndr_ie) { |
---|
1587 | 5993 | WL_ERR(("IE memory alloc failed\n")); |
---|
1588 | 5994 | return -ENOMEM; |
---|
1589 | 5995 | } |
---|
1590 | 5996 | /* Copy the vndr_ie SET command ("add"/"del") to the buffer */ |
---|
1591 | | - strncpy(vndr_ie->cmd, "add", VNDR_IE_CMD_LEN - 1); |
---|
1592 | | - vndr_ie->cmd[VNDR_IE_CMD_LEN - 1] = '\0'; |
---|
| 5997 | + strlcpy(vndr_ie->cmd, "add", sizeof(vndr_ie->cmd)); |
---|
1593 | 5998 | |
---|
1594 | 5999 | /* Set the IE count - the buffer contains only 1 IE */ |
---|
1595 | 6000 | iecount = htod32(1); |
---|
.. | .. |
---|
1610 | 6015 | ielen = DOT11_OUI_LEN + datalen; |
---|
1611 | 6016 | vndr_ie->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len = (uchar) ielen; |
---|
1612 | 6017 | |
---|
1613 | | - ioctl_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL); |
---|
| 6018 | + ioctl_buf = (char *)MALLOC(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
1614 | 6019 | if (!ioctl_buf) { |
---|
1615 | 6020 | WL_ERR(("ioctl memory alloc failed\n")); |
---|
1616 | 6021 | if (vndr_ie) { |
---|
1617 | | - kfree(vndr_ie); |
---|
| 6022 | + MFREE(cfg->osh, vndr_ie, tot_len); |
---|
1618 | 6023 | } |
---|
1619 | 6024 | return -ENOMEM; |
---|
1620 | 6025 | } |
---|
1621 | | - memset(ioctl_buf, 0, WLC_IOCTL_MEDLEN); /* init the buffer */ |
---|
1622 | | - err = wldev_iovar_setbuf(dev, "ie", vndr_ie, tot_len, ioctl_buf, WLC_IOCTL_MEDLEN, NULL); |
---|
1623 | | - |
---|
1624 | | - |
---|
| 6026 | + bzero(ioctl_buf, WLC_IOCTL_MEDLEN); /* init the buffer */ |
---|
| 6027 | + if ((bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr)) < 0) { |
---|
| 6028 | + WL_ERR(("Find index failed\n")); |
---|
| 6029 | + err = BCME_ERROR; |
---|
| 6030 | + goto end; |
---|
| 6031 | + } |
---|
| 6032 | + err = wldev_iovar_setbuf_bsscfg(dev, "vndr_ie", vndr_ie, tot_len, ioctl_buf, |
---|
| 6033 | + WLC_IOCTL_MEDLEN, bssidx, &cfg->ioctl_buf_sync); |
---|
| 6034 | +end: |
---|
1625 | 6035 | if (err != BCME_OK) { |
---|
1626 | 6036 | err = -EINVAL; |
---|
1627 | 6037 | if (vndr_ie) { |
---|
1628 | | - kfree(vndr_ie); |
---|
| 6038 | + MFREE(cfg->osh, vndr_ie, tot_len); |
---|
1629 | 6039 | } |
---|
1630 | 6040 | } |
---|
1631 | 6041 | else { |
---|
1632 | 6042 | /* do NOT free 'vndr_ie' for the next process */ |
---|
1633 | | - wl_cfg80211_ibss_vsie_set_buffer(vndr_ie, tot_len); |
---|
| 6043 | + wl_cfg80211_ibss_vsie_set_buffer(dev, vndr_ie, tot_len); |
---|
1634 | 6044 | } |
---|
1635 | 6045 | |
---|
1636 | 6046 | if (ioctl_buf) { |
---|
1637 | | - kfree(ioctl_buf); |
---|
| 6047 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
1638 | 6048 | } |
---|
1639 | 6049 | |
---|
1640 | 6050 | return err; |
---|
.. | .. |
---|
1663 | 6073 | total_len_left = total_len - strlen(CMD_SET_ROAMPREF) + 1; |
---|
1664 | 6074 | |
---|
1665 | 6075 | num_akm_suites = simple_strtoul(pcmd, NULL, 16); |
---|
| 6076 | + if (num_akm_suites > MAX_NUM_SUITES) { |
---|
| 6077 | + DHD_ERROR(("too many AKM suites = %d\n", num_akm_suites)); |
---|
| 6078 | + return -1; |
---|
| 6079 | + } |
---|
| 6080 | + |
---|
1666 | 6081 | /* Increment for number of AKM suites field + space */ |
---|
1667 | 6082 | pcmd += 3; |
---|
1668 | 6083 | total_len_left -= 3; |
---|
.. | .. |
---|
1671 | 6086 | if (total_len_left < (num_akm_suites * WIDTH_AKM_SUITE)) |
---|
1672 | 6087 | return -1; |
---|
1673 | 6088 | |
---|
1674 | | - memset(buf, 0, sizeof(buf)); |
---|
1675 | | - memset(akm_suites, 0, sizeof(akm_suites)); |
---|
1676 | | - memset(ucipher_suites, 0, sizeof(ucipher_suites)); |
---|
| 6089 | + bzero(buf, sizeof(buf)); |
---|
| 6090 | + bzero(akm_suites, sizeof(akm_suites)); |
---|
| 6091 | + bzero(ucipher_suites, sizeof(ucipher_suites)); |
---|
1677 | 6092 | |
---|
1678 | 6093 | /* Save the AKM suites passed in the command */ |
---|
1679 | 6094 | for (i = 0; i < num_akm_suites; i++) { |
---|
.. | .. |
---|
1739 | 6154 | total_bytes = JOIN_PREF_RSSI_SIZE + JOIN_PREF_WPA_HDR_SIZE + |
---|
1740 | 6155 | (JOIN_PREF_WPA_TUPLE_SIZE * num_tuples); |
---|
1741 | 6156 | } else { |
---|
1742 | | - DHD_ERROR(("%s: Too many wpa configs for join_pref \n", __FUNCTION__)); |
---|
| 6157 | + DHD_ERROR(("wl_android_set_roampref: Too many wpa configs" |
---|
| 6158 | + " for join_pref \n")); |
---|
1743 | 6159 | return -1; |
---|
1744 | 6160 | } |
---|
1745 | 6161 | } else { |
---|
.. | .. |
---|
1755 | 6171 | memcpy(pref, (uint8 *)&ucipher_suites[i], WPA_SUITE_LEN); |
---|
1756 | 6172 | pref += WPA_SUITE_LEN; |
---|
1757 | 6173 | /* Set to 0 to match any available multicast cipher */ |
---|
1758 | | - memset(pref, 0, WPA_SUITE_LEN); |
---|
| 6174 | + bzero(pref, WPA_SUITE_LEN); |
---|
1759 | 6175 | pref += WPA_SUITE_LEN; |
---|
1760 | 6176 | } |
---|
1761 | 6177 | } |
---|
.. | .. |
---|
1774 | 6190 | { |
---|
1775 | 6191 | struct io_cfg *resume_cfg; |
---|
1776 | 6192 | s32 ret; |
---|
| 6193 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
1777 | 6194 | |
---|
1778 | | - resume_cfg = kzalloc(sizeof(struct io_cfg), GFP_KERNEL); |
---|
| 6195 | + resume_cfg = (struct io_cfg *)MALLOCZ(cfg->osh, sizeof(struct io_cfg)); |
---|
1779 | 6196 | if (!resume_cfg) |
---|
1780 | 6197 | return -ENOMEM; |
---|
1781 | 6198 | |
---|
1782 | 6199 | if (config->iovar) { |
---|
1783 | 6200 | ret = wldev_iovar_getint(dev, config->iovar, &resume_cfg->param); |
---|
1784 | 6201 | if (ret) { |
---|
1785 | | - DHD_ERROR(("%s: Failed to get current %s value\n", |
---|
1786 | | - __FUNCTION__, config->iovar)); |
---|
| 6202 | + DHD_ERROR(("wl_android_iolist_add: Failed to get current %s value\n", |
---|
| 6203 | + config->iovar)); |
---|
1787 | 6204 | goto error; |
---|
1788 | 6205 | } |
---|
1789 | 6206 | |
---|
1790 | 6207 | ret = wldev_iovar_setint(dev, config->iovar, config->param); |
---|
1791 | 6208 | if (ret) { |
---|
1792 | | - DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__, |
---|
| 6209 | + DHD_ERROR(("wl_android_iolist_add: Failed to set %s to %d\n", |
---|
1793 | 6210 | config->iovar, config->param)); |
---|
1794 | 6211 | goto error; |
---|
1795 | 6212 | } |
---|
1796 | 6213 | |
---|
1797 | 6214 | resume_cfg->iovar = config->iovar; |
---|
1798 | 6215 | } else { |
---|
1799 | | - resume_cfg->arg = kzalloc(config->len, GFP_KERNEL); |
---|
| 6216 | + resume_cfg->arg = MALLOCZ(cfg->osh, config->len); |
---|
1800 | 6217 | if (!resume_cfg->arg) { |
---|
1801 | 6218 | ret = -ENOMEM; |
---|
1802 | 6219 | goto error; |
---|
1803 | 6220 | } |
---|
1804 | | - ret = wldev_ioctl(dev, config->ioctl, resume_cfg->arg, config->len, false); |
---|
| 6221 | + ret = wldev_ioctl_get(dev, config->ioctl, resume_cfg->arg, config->len); |
---|
1805 | 6222 | if (ret) { |
---|
1806 | | - DHD_ERROR(("%s: Failed to get ioctl %d\n", __FUNCTION__, |
---|
| 6223 | + DHD_ERROR(("wl_android_iolist_add: Failed to get ioctl %d\n", |
---|
1807 | 6224 | config->ioctl)); |
---|
1808 | 6225 | goto error; |
---|
1809 | 6226 | } |
---|
1810 | | - ret = wldev_ioctl(dev, config->ioctl + 1, config->arg, config->len, true); |
---|
| 6227 | + ret = wldev_ioctl_set(dev, config->ioctl + 1, config->arg, config->len); |
---|
1811 | 6228 | if (ret) { |
---|
1812 | | - DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__, |
---|
| 6229 | + DHD_ERROR(("wl_android_iolist_add: Failed to set %s to %d\n", |
---|
1813 | 6230 | config->iovar, config->param)); |
---|
1814 | 6231 | goto error; |
---|
1815 | 6232 | } |
---|
.. | .. |
---|
1823 | 6240 | |
---|
1824 | 6241 | return 0; |
---|
1825 | 6242 | error: |
---|
1826 | | - kfree(resume_cfg->arg); |
---|
1827 | | - kfree(resume_cfg); |
---|
| 6243 | + MFREE(cfg->osh, resume_cfg->arg, config->len); |
---|
| 6244 | + MFREE(cfg->osh, resume_cfg, sizeof(struct io_cfg)); |
---|
1828 | 6245 | return ret; |
---|
1829 | 6246 | } |
---|
1830 | 6247 | |
---|
.. | .. |
---|
1834 | 6251 | struct io_cfg *config; |
---|
1835 | 6252 | struct list_head *cur, *q; |
---|
1836 | 6253 | s32 ret = 0; |
---|
1837 | | - |
---|
| 6254 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 6255 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
1838 | 6256 | list_for_each_safe(cur, q, head) { |
---|
1839 | 6257 | config = list_entry(cur, struct io_cfg, list); |
---|
| 6258 | + GCC_DIAGNOSTIC_POP(); |
---|
1840 | 6259 | if (config->iovar) { |
---|
1841 | 6260 | if (!ret) |
---|
1842 | 6261 | ret = wldev_iovar_setint(dev, config->iovar, |
---|
1843 | 6262 | config->param); |
---|
1844 | 6263 | } else { |
---|
1845 | 6264 | if (!ret) |
---|
1846 | | - ret = wldev_ioctl(dev, config->ioctl + 1, |
---|
1847 | | - config->arg, config->len, true); |
---|
| 6265 | + ret = wldev_ioctl_set(dev, config->ioctl + 1, |
---|
| 6266 | + config->arg, config->len); |
---|
1848 | 6267 | if (config->ioctl + 1 == WLC_SET_PM) |
---|
1849 | 6268 | wl_cfg80211_update_power_mode(dev); |
---|
1850 | | - kfree(config->arg); |
---|
| 6269 | + MFREE(cfg->osh, config->arg, config->len); |
---|
1851 | 6270 | } |
---|
1852 | 6271 | list_del(cur); |
---|
1853 | | - kfree(config); |
---|
| 6272 | + MFREE(cfg->osh, config, sizeof(struct io_cfg)); |
---|
1854 | 6273 | } |
---|
1855 | 6274 | } |
---|
1856 | | -#ifdef WL11ULB |
---|
1857 | 6275 | static int |
---|
1858 | | -wl_android_set_ulb_mode(struct net_device *dev, char *command, int total_len) |
---|
1859 | | -{ |
---|
1860 | | - int mode = 0; |
---|
1861 | | - |
---|
1862 | | - DHD_INFO(("set ulb mode (%s) \n", command)); |
---|
1863 | | - if (sscanf(command, "%*s %d", &mode) != 1) { |
---|
1864 | | - DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__)); |
---|
1865 | | - return -1; |
---|
1866 | | - } |
---|
1867 | | - return wl_cfg80211_set_ulb_mode(dev, mode); |
---|
1868 | | -} |
---|
1869 | | -static int |
---|
1870 | | -wl_android_set_ulb_bw(struct net_device *dev, char *command, int total_len) |
---|
1871 | | -{ |
---|
1872 | | - int bw = 0; |
---|
1873 | | - u8 *pos; |
---|
1874 | | - char *ifname = NULL; |
---|
1875 | | - DHD_INFO(("set ulb bw (%s) \n", command)); |
---|
1876 | | - |
---|
1877 | | - /* |
---|
1878 | | - * For sta/ap: IFNAME=<ifname> DRIVER ULB_BW <bw> ifname |
---|
1879 | | - * For p2p: IFNAME=wlan0 DRIVER ULB_BW <bw> p2p-dev-wlan0 |
---|
1880 | | - */ |
---|
1881 | | - if (total_len < strlen(CMD_ULB_BW) + 2) |
---|
1882 | | - return -EINVAL; |
---|
1883 | | - |
---|
1884 | | - pos = command + strlen(CMD_ULB_BW) + 1; |
---|
1885 | | - bw = bcm_atoi(pos); |
---|
1886 | | - |
---|
1887 | | - if ((strlen(pos) >= 5)) { |
---|
1888 | | - ifname = pos + 2; |
---|
1889 | | - } |
---|
1890 | | - |
---|
1891 | | - DHD_INFO(("[ULB] ifname:%s ulb_bw:%d \n", ifname, bw)); |
---|
1892 | | - return wl_cfg80211_set_ulb_bw(dev, bw, ifname); |
---|
1893 | | -} |
---|
1894 | | -#endif /* WL11ULB */ |
---|
1895 | | -static int |
---|
1896 | | -wl_android_set_miracast(struct net_device *dev, char *command, int total_len) |
---|
| 6276 | +wl_android_set_miracast(struct net_device *dev, char *command) |
---|
1897 | 6277 | { |
---|
1898 | 6278 | int mode, val = 0; |
---|
1899 | 6279 | int ret = 0; |
---|
1900 | 6280 | struct io_cfg config; |
---|
1901 | 6281 | |
---|
1902 | 6282 | if (sscanf(command, "%*s %d", &mode) != 1) { |
---|
1903 | | - DHD_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__)); |
---|
| 6283 | + DHD_ERROR(("wl_android_set_miracasts: Failed to get Parameter\n")); |
---|
1904 | 6284 | return -1; |
---|
1905 | 6285 | } |
---|
1906 | 6286 | |
---|
1907 | | - DHD_INFO(("%s: enter miracast mode %d\n", __FUNCTION__, mode)); |
---|
| 6287 | + DHD_INFO(("wl_android_set_miracast: enter miracast mode %d\n", mode)); |
---|
1908 | 6288 | |
---|
1909 | 6289 | if (miracast_cur_mode == mode) { |
---|
1910 | 6290 | return 0; |
---|
.. | .. |
---|
1913 | 6293 | wl_android_iolist_resume(dev, &miracast_resume_list); |
---|
1914 | 6294 | miracast_cur_mode = MIRACAST_MODE_OFF; |
---|
1915 | 6295 | |
---|
| 6296 | + bzero((void *)&config, sizeof(config)); |
---|
1916 | 6297 | switch (mode) { |
---|
1917 | 6298 | case MIRACAST_MODE_SOURCE: |
---|
| 6299 | +#ifdef MIRACAST_MCHAN_ALGO |
---|
1918 | 6300 | /* setting mchan_algo to platform specific value */ |
---|
1919 | 6301 | config.iovar = "mchan_algo"; |
---|
1920 | 6302 | |
---|
1921 | | - ret = wldev_ioctl(dev, WLC_GET_BCNPRD, &val, sizeof(int), false); |
---|
| 6303 | + ret = wldev_ioctl_get(dev, WLC_GET_BCNPRD, &val, sizeof(int)); |
---|
1922 | 6304 | if (!ret && val > 100) { |
---|
1923 | 6305 | config.param = 0; |
---|
1924 | | - DHD_ERROR(("%s: Connected station's beacon interval: " |
---|
| 6306 | + DHD_ERROR(("wl_android_set_miracast: Connected station's beacon interval: " |
---|
1925 | 6307 | "%d and set mchan_algo to %d \n", |
---|
1926 | | - __FUNCTION__, val, config.param)); |
---|
| 6308 | + val, config.param)); |
---|
1927 | 6309 | } else { |
---|
1928 | 6310 | config.param = MIRACAST_MCHAN_ALGO; |
---|
1929 | 6311 | } |
---|
.. | .. |
---|
1931 | 6313 | if (ret) { |
---|
1932 | 6314 | goto resume; |
---|
1933 | 6315 | } |
---|
| 6316 | +#endif /* MIRACAST_MCHAN_ALGO */ |
---|
1934 | 6317 | |
---|
| 6318 | +#ifdef MIRACAST_MCHAN_BW |
---|
1935 | 6319 | /* setting mchan_bw to platform specific value */ |
---|
1936 | 6320 | config.iovar = "mchan_bw"; |
---|
1937 | 6321 | config.param = MIRACAST_MCHAN_BW; |
---|
.. | .. |
---|
1939 | 6323 | if (ret) { |
---|
1940 | 6324 | goto resume; |
---|
1941 | 6325 | } |
---|
| 6326 | +#endif /* MIRACAST_MCHAN_BW */ |
---|
1942 | 6327 | |
---|
| 6328 | +#ifdef MIRACAST_AMPDU_SIZE |
---|
1943 | 6329 | /* setting apmdu to platform specific value */ |
---|
1944 | 6330 | config.iovar = "ampdu_mpdu"; |
---|
1945 | 6331 | config.param = MIRACAST_AMPDU_SIZE; |
---|
.. | .. |
---|
1947 | 6333 | if (ret) { |
---|
1948 | 6334 | goto resume; |
---|
1949 | 6335 | } |
---|
1950 | | - /* FALLTROUGH */ |
---|
| 6336 | +#endif /* MIRACAST_AMPDU_SIZE */ |
---|
| 6337 | + |
---|
1951 | 6338 | /* Source mode shares most configurations with sink mode. |
---|
1952 | 6339 | * Fall through here to avoid code duplication |
---|
1953 | 6340 | */ |
---|
| 6341 | + /* fall through */ |
---|
1954 | 6342 | case MIRACAST_MODE_SINK: |
---|
1955 | 6343 | /* disable internal roaming */ |
---|
1956 | 6344 | config.iovar = "roam_off"; |
---|
1957 | 6345 | config.param = 1; |
---|
| 6346 | + config.arg = NULL; |
---|
| 6347 | + config.len = 0; |
---|
1958 | 6348 | ret = wl_android_iolist_add(dev, &miracast_resume_list, &config); |
---|
1959 | 6349 | if (ret) { |
---|
1960 | 6350 | goto resume; |
---|
1961 | 6351 | } |
---|
1962 | 6352 | |
---|
1963 | 6353 | /* tunr off pm */ |
---|
1964 | | - ret = wldev_ioctl(dev, WLC_GET_PM, &val, sizeof(val), false); |
---|
| 6354 | + ret = wldev_ioctl_get(dev, WLC_GET_PM, &val, sizeof(val)); |
---|
1965 | 6355 | if (ret) { |
---|
1966 | 6356 | goto resume; |
---|
1967 | 6357 | } |
---|
.. | .. |
---|
1987 | 6377 | return 0; |
---|
1988 | 6378 | |
---|
1989 | 6379 | resume: |
---|
1990 | | - DHD_ERROR(("%s: turnoff miracast mode because of err%d\n", __FUNCTION__, ret)); |
---|
| 6380 | + DHD_ERROR(("wl_android_set_miracast: turnoff miracast mode because of err%d\n", ret)); |
---|
1991 | 6381 | wl_android_iolist_resume(dev, &miracast_resume_list); |
---|
1992 | 6382 | return ret; |
---|
1993 | 6383 | } |
---|
.. | .. |
---|
2008 | 6398 | struct netlink_kernel_cfg cfg = { |
---|
2009 | 6399 | .input = wl_netlink_recv, |
---|
2010 | 6400 | }; |
---|
2011 | | -#endif |
---|
| 6401 | +#endif // endif |
---|
2012 | 6402 | |
---|
2013 | 6403 | if (nl_sk != NULL) { |
---|
2014 | 6404 | WL_ERR(("nl_sk already exist\n")); |
---|
.. | .. |
---|
2022 | 6412 | nl_sk = netlink_kernel_create(&init_net, NETLINK_OXYGEN, THIS_MODULE, &cfg); |
---|
2023 | 6413 | #else |
---|
2024 | 6414 | nl_sk = netlink_kernel_create(&init_net, NETLINK_OXYGEN, &cfg); |
---|
2025 | | -#endif |
---|
| 6415 | +#endif // endif |
---|
2026 | 6416 | |
---|
2027 | 6417 | if (nl_sk == NULL) { |
---|
2028 | 6418 | WL_ERR(("nl_sk is not ready\n")); |
---|
.. | .. |
---|
2041 | 6431 | } |
---|
2042 | 6432 | |
---|
2043 | 6433 | s32 |
---|
2044 | | -wl_netlink_send_msg(int pid, int type, int seq, void *data, size_t size) |
---|
| 6434 | +wl_netlink_send_msg(int pid, int type, int seq, const void *data, size_t size) |
---|
2045 | 6435 | { |
---|
2046 | 6436 | struct sk_buff *skb = NULL; |
---|
2047 | 6437 | struct nlmsghdr *nlh = NULL; |
---|
.. | .. |
---|
2078 | 6468 | return ret; |
---|
2079 | 6469 | } |
---|
2080 | 6470 | |
---|
| 6471 | +#ifdef WLAIBSS |
---|
| 6472 | +static int wl_android_set_ibss_txfail_event(struct net_device *dev, char *command, int total_len) |
---|
| 6473 | +{ |
---|
| 6474 | + int err = 0; |
---|
| 6475 | + int retry = 0; |
---|
| 6476 | + int pid = 0; |
---|
| 6477 | + aibss_txfail_config_t txfail_config = {0, 0, 0, 0, 0}; |
---|
| 6478 | + char smbuf[WLC_IOCTL_SMLEN]; |
---|
2081 | 6479 | |
---|
2082 | | -int wl_keep_alive_set(struct net_device *dev, char* extra, int total_len) |
---|
| 6480 | + if (sscanf(command, CMD_SETIBSSTXFAILEVENT " %d %d", &retry, &pid) <= 0) { |
---|
| 6481 | + WL_ERR(("Failed to get Parameter from : %s\n", command)); |
---|
| 6482 | + return -1; |
---|
| 6483 | + } |
---|
| 6484 | + |
---|
| 6485 | + /* set pid, and if the event was happened, let's send a notification through netlink */ |
---|
| 6486 | + wl_cfg80211_set_txfail_pid(dev, pid); |
---|
| 6487 | + |
---|
| 6488 | +#ifdef WL_RELMCAST |
---|
| 6489 | + /* using same pid for RMC, AIBSS shares same pid with RMC and it is set once */ |
---|
| 6490 | + wl_cfg80211_set_rmc_pid(dev, pid); |
---|
| 6491 | +#endif /* WL_RELMCAST */ |
---|
| 6492 | + |
---|
| 6493 | + /* If retry value is 0, it disables the functionality for TX Fail. */ |
---|
| 6494 | + if (retry > 0) { |
---|
| 6495 | + txfail_config.max_tx_retry = retry; |
---|
| 6496 | + txfail_config.bcn_timeout = 0; /* 0 : disable tx fail from beacon */ |
---|
| 6497 | + } |
---|
| 6498 | + txfail_config.version = AIBSS_TXFAIL_CONFIG_VER_0; |
---|
| 6499 | + txfail_config.len = sizeof(txfail_config); |
---|
| 6500 | + |
---|
| 6501 | + err = wldev_iovar_setbuf(dev, "aibss_txfail_config", (void *) &txfail_config, |
---|
| 6502 | + sizeof(aibss_txfail_config_t), smbuf, WLC_IOCTL_SMLEN, NULL); |
---|
| 6503 | + WL_DBG(("retry=%d, pid=%d, err=%d\n", retry, pid, err)); |
---|
| 6504 | + |
---|
| 6505 | + return ((err == 0)?total_len:err); |
---|
| 6506 | +} |
---|
| 6507 | + |
---|
| 6508 | +static int wl_android_get_ibss_peer_info(struct net_device *dev, char *command, |
---|
| 6509 | + int total_len, bool bAll) |
---|
| 6510 | +{ |
---|
| 6511 | + int error; |
---|
| 6512 | + int bytes_written = 0; |
---|
| 6513 | + void *buf = NULL; |
---|
| 6514 | + bss_peer_list_info_t peer_list_info; |
---|
| 6515 | + bss_peer_info_t *peer_info; |
---|
| 6516 | + int i; |
---|
| 6517 | + bool found = false; |
---|
| 6518 | + struct ether_addr mac_ea; |
---|
| 6519 | + char *str = command; |
---|
| 6520 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 6521 | + |
---|
| 6522 | + WL_DBG(("get ibss peer info(%s)\n", bAll?"true":"false")); |
---|
| 6523 | + |
---|
| 6524 | + if (!bAll) { |
---|
| 6525 | + if (bcmstrtok(&str, " ", NULL) == NULL) { |
---|
| 6526 | + WL_ERR(("invalid command\n")); |
---|
| 6527 | + return -1; |
---|
| 6528 | + } |
---|
| 6529 | + |
---|
| 6530 | + if (!str || !bcm_ether_atoe(str, &mac_ea)) { |
---|
| 6531 | + WL_ERR(("invalid MAC address\n")); |
---|
| 6532 | + return -1; |
---|
| 6533 | + } |
---|
| 6534 | + } |
---|
| 6535 | + |
---|
| 6536 | + if ((buf = MALLOC(cfg->osh, WLC_IOCTL_MAXLEN)) == NULL) { |
---|
| 6537 | + WL_ERR(("kmalloc failed\n")); |
---|
| 6538 | + return -1; |
---|
| 6539 | + } |
---|
| 6540 | + |
---|
| 6541 | + error = wldev_iovar_getbuf(dev, "bss_peer_info", NULL, 0, buf, WLC_IOCTL_MAXLEN, NULL); |
---|
| 6542 | + if (unlikely(error)) { |
---|
| 6543 | + WL_ERR(("could not get ibss peer info (%d)\n", error)); |
---|
| 6544 | + MFREE(cfg->osh, buf, WLC_IOCTL_MAXLEN); |
---|
| 6545 | + return -1; |
---|
| 6546 | + } |
---|
| 6547 | + |
---|
| 6548 | + memcpy(&peer_list_info, buf, sizeof(peer_list_info)); |
---|
| 6549 | + peer_list_info.version = htod16(peer_list_info.version); |
---|
| 6550 | + peer_list_info.bss_peer_info_len = htod16(peer_list_info.bss_peer_info_len); |
---|
| 6551 | + peer_list_info.count = htod32(peer_list_info.count); |
---|
| 6552 | + |
---|
| 6553 | + WL_DBG(("ver:%d, len:%d, count:%d\n", peer_list_info.version, |
---|
| 6554 | + peer_list_info.bss_peer_info_len, peer_list_info.count)); |
---|
| 6555 | + |
---|
| 6556 | + if (peer_list_info.count > 0) { |
---|
| 6557 | + if (bAll) |
---|
| 6558 | + bytes_written += snprintf(&command[bytes_written], total_len, "%u ", |
---|
| 6559 | + peer_list_info.count); |
---|
| 6560 | + |
---|
| 6561 | + peer_info = (bss_peer_info_t *) ((char *)buf + BSS_PEER_LIST_INFO_FIXED_LEN); |
---|
| 6562 | + |
---|
| 6563 | + for (i = 0; i < peer_list_info.count; i++) { |
---|
| 6564 | + |
---|
| 6565 | + WL_DBG(("index:%d rssi:%d, tx:%u, rx:%u\n", i, peer_info->rssi, |
---|
| 6566 | + peer_info->tx_rate, peer_info->rx_rate)); |
---|
| 6567 | + |
---|
| 6568 | + if (!bAll && |
---|
| 6569 | + memcmp(&mac_ea, &peer_info->ea, sizeof(struct ether_addr)) == 0) { |
---|
| 6570 | + found = true; |
---|
| 6571 | + } |
---|
| 6572 | + |
---|
| 6573 | + if (bAll || found) { |
---|
| 6574 | + bytes_written += snprintf(&command[bytes_written], |
---|
| 6575 | + total_len - bytes_written, |
---|
| 6576 | + MACF" %u %d ", ETHER_TO_MACF(peer_info->ea), |
---|
| 6577 | + peer_info->tx_rate/1000, peer_info->rssi); |
---|
| 6578 | + if (bytes_written >= total_len) { |
---|
| 6579 | + WL_ERR(("wl_android_get_ibss_peer_info: Insufficient" |
---|
| 6580 | + " memory, %d bytes\n", |
---|
| 6581 | + total_len)); |
---|
| 6582 | + bytes_written = -1; |
---|
| 6583 | + break; |
---|
| 6584 | + } |
---|
| 6585 | + } |
---|
| 6586 | + |
---|
| 6587 | + if (found) |
---|
| 6588 | + break; |
---|
| 6589 | + |
---|
| 6590 | + peer_info = (bss_peer_info_t *)((char *)peer_info+sizeof(bss_peer_info_t)); |
---|
| 6591 | + } |
---|
| 6592 | + } |
---|
| 6593 | + else { |
---|
| 6594 | + WL_ERR(("could not get ibss peer info : no item\n")); |
---|
| 6595 | + } |
---|
| 6596 | + WL_DBG(("command(%u):%s\n", total_len, command)); |
---|
| 6597 | + WL_DBG(("bytes_written:%d\n", bytes_written)); |
---|
| 6598 | + |
---|
| 6599 | + MFREE(cfg->osh, buf, WLC_IOCTL_MAXLEN); |
---|
| 6600 | + return bytes_written; |
---|
| 6601 | +} |
---|
| 6602 | + |
---|
| 6603 | +int wl_android_set_ibss_routetable(struct net_device *dev, char *command) |
---|
| 6604 | +{ |
---|
| 6605 | + |
---|
| 6606 | + char *pcmd = command; |
---|
| 6607 | + char *str = NULL; |
---|
| 6608 | + ibss_route_tbl_t *route_tbl = NULL; |
---|
| 6609 | + char *ioctl_buf = NULL; |
---|
| 6610 | + s32 err = BCME_OK; |
---|
| 6611 | + uint32 route_tbl_len; |
---|
| 6612 | + uint32 entries; |
---|
| 6613 | + char *endptr; |
---|
| 6614 | + uint32 i = 0; |
---|
| 6615 | + struct ipv4_addr dipaddr; |
---|
| 6616 | + struct ether_addr ea; |
---|
| 6617 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 6618 | + |
---|
| 6619 | + route_tbl_len = sizeof(ibss_route_tbl_t) + |
---|
| 6620 | + (MAX_IBSS_ROUTE_TBL_ENTRY - 1) * sizeof(ibss_route_entry_t); |
---|
| 6621 | + route_tbl = (ibss_route_tbl_t *)MALLOCZ(cfg->osh, route_tbl_len); |
---|
| 6622 | + if (!route_tbl) { |
---|
| 6623 | + WL_ERR(("Route TBL alloc failed\n")); |
---|
| 6624 | + return -ENOMEM; |
---|
| 6625 | + } |
---|
| 6626 | + ioctl_buf = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 6627 | + if (!ioctl_buf) { |
---|
| 6628 | + WL_ERR(("ioctl memory alloc failed\n")); |
---|
| 6629 | + if (route_tbl) { |
---|
| 6630 | + MFREE(cfg->osh, route_tbl, route_tbl_len); |
---|
| 6631 | + } |
---|
| 6632 | + return -ENOMEM; |
---|
| 6633 | + } |
---|
| 6634 | + bzero(ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 6635 | + |
---|
| 6636 | + /* drop command */ |
---|
| 6637 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6638 | + |
---|
| 6639 | + /* get count */ |
---|
| 6640 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6641 | + if (!str) { |
---|
| 6642 | + WL_ERR(("Invalid number parameter %s\n", str)); |
---|
| 6643 | + err = -EINVAL; |
---|
| 6644 | + goto exit; |
---|
| 6645 | + } |
---|
| 6646 | + entries = bcm_strtoul(str, &endptr, 0); |
---|
| 6647 | + if (*endptr != '\0') { |
---|
| 6648 | + WL_ERR(("Invalid number parameter %s\n", str)); |
---|
| 6649 | + err = -EINVAL; |
---|
| 6650 | + goto exit; |
---|
| 6651 | + } |
---|
| 6652 | + if (entries > MAX_IBSS_ROUTE_TBL_ENTRY) { |
---|
| 6653 | + WL_ERR(("Invalid entries number %u\n", entries)); |
---|
| 6654 | + err = -EINVAL; |
---|
| 6655 | + goto exit; |
---|
| 6656 | + } |
---|
| 6657 | + |
---|
| 6658 | + WL_INFORM(("Routing table count:%u\n", entries)); |
---|
| 6659 | + route_tbl->num_entry = entries; |
---|
| 6660 | + |
---|
| 6661 | + for (i = 0; i < entries; i++) { |
---|
| 6662 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6663 | + if (!str || !bcm_atoipv4(str, &dipaddr)) { |
---|
| 6664 | + WL_ERR(("Invalid ip string %s\n", str)); |
---|
| 6665 | + err = -EINVAL; |
---|
| 6666 | + goto exit; |
---|
| 6667 | + } |
---|
| 6668 | + |
---|
| 6669 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6670 | + if (!str || !bcm_ether_atoe(str, &ea)) { |
---|
| 6671 | + WL_ERR(("Invalid ethernet string %s\n", str)); |
---|
| 6672 | + err = -EINVAL; |
---|
| 6673 | + goto exit; |
---|
| 6674 | + } |
---|
| 6675 | + bcopy(&dipaddr, &route_tbl->route_entry[i].ipv4_addr, IPV4_ADDR_LEN); |
---|
| 6676 | + bcopy(&ea, &route_tbl->route_entry[i].nexthop, ETHER_ADDR_LEN); |
---|
| 6677 | + } |
---|
| 6678 | + |
---|
| 6679 | + route_tbl_len = sizeof(ibss_route_tbl_t) + |
---|
| 6680 | + ((!entries?0:(entries - 1)) * sizeof(ibss_route_entry_t)); |
---|
| 6681 | + err = wldev_iovar_setbuf(dev, "ibss_route_tbl", |
---|
| 6682 | + route_tbl, route_tbl_len, ioctl_buf, WLC_IOCTL_MEDLEN, NULL); |
---|
| 6683 | + if (err != BCME_OK) { |
---|
| 6684 | + WL_ERR(("Fail to set iovar %d\n", err)); |
---|
| 6685 | + err = -EINVAL; |
---|
| 6686 | + } |
---|
| 6687 | + |
---|
| 6688 | +exit: |
---|
| 6689 | + if (route_tbl) { |
---|
| 6690 | + MFREE(cfg->osh, route_tbl, sizeof(ibss_route_tbl_t) + |
---|
| 6691 | + (MAX_IBSS_ROUTE_TBL_ENTRY - 1) * sizeof(ibss_route_entry_t)); |
---|
| 6692 | + } |
---|
| 6693 | + if (ioctl_buf) { |
---|
| 6694 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 6695 | + } |
---|
| 6696 | + return err; |
---|
| 6697 | + |
---|
| 6698 | +} |
---|
| 6699 | + |
---|
| 6700 | +int |
---|
| 6701 | +wl_android_set_ibss_ampdu(struct net_device *dev, char *command, int total_len) |
---|
| 6702 | +{ |
---|
| 6703 | + char *pcmd = command; |
---|
| 6704 | + char *str = NULL, *endptr = NULL; |
---|
| 6705 | + struct ampdu_aggr aggr; |
---|
| 6706 | + char smbuf[WLC_IOCTL_SMLEN]; |
---|
| 6707 | + int idx; |
---|
| 6708 | + int err = 0; |
---|
| 6709 | + int wme_AC2PRIO[AC_COUNT][2] = { |
---|
| 6710 | + {PRIO_8021D_VO, PRIO_8021D_NC}, /* AC_VO - 3 */ |
---|
| 6711 | + {PRIO_8021D_CL, PRIO_8021D_VI}, /* AC_VI - 2 */ |
---|
| 6712 | + {PRIO_8021D_BK, PRIO_8021D_NONE}, /* AC_BK - 1 */ |
---|
| 6713 | + {PRIO_8021D_BE, PRIO_8021D_EE}}; /* AC_BE - 0 */ |
---|
| 6714 | + |
---|
| 6715 | + WL_DBG(("set ibss ampdu:%s\n", command)); |
---|
| 6716 | + |
---|
| 6717 | + bzero(&aggr, sizeof(aggr)); |
---|
| 6718 | + /* Cofigure all priorities */ |
---|
| 6719 | + aggr.conf_TID_bmap = NBITMASK(NUMPRIO); |
---|
| 6720 | + |
---|
| 6721 | + /* acquire parameters */ |
---|
| 6722 | + /* drop command */ |
---|
| 6723 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6724 | + |
---|
| 6725 | + for (idx = 0; idx < AC_COUNT; idx++) { |
---|
| 6726 | + bool on; |
---|
| 6727 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6728 | + if (!str) { |
---|
| 6729 | + WL_ERR(("Invalid parameter : %s\n", pcmd)); |
---|
| 6730 | + return -EINVAL; |
---|
| 6731 | + } |
---|
| 6732 | + on = bcm_strtoul(str, &endptr, 0) ? TRUE : FALSE; |
---|
| 6733 | + if (*endptr != '\0') { |
---|
| 6734 | + WL_ERR(("Invalid number format %s\n", str)); |
---|
| 6735 | + return -EINVAL; |
---|
| 6736 | + } |
---|
| 6737 | + if (on) { |
---|
| 6738 | + setbit(&aggr.enab_TID_bmap, wme_AC2PRIO[idx][0]); |
---|
| 6739 | + setbit(&aggr.enab_TID_bmap, wme_AC2PRIO[idx][1]); |
---|
| 6740 | + } |
---|
| 6741 | + } |
---|
| 6742 | + |
---|
| 6743 | + err = wldev_iovar_setbuf(dev, "ampdu_txaggr", (void *)&aggr, |
---|
| 6744 | + sizeof(aggr), smbuf, WLC_IOCTL_SMLEN, NULL); |
---|
| 6745 | + |
---|
| 6746 | + return ((err == 0) ? total_len : err); |
---|
| 6747 | +} |
---|
| 6748 | + |
---|
| 6749 | +int wl_android_set_ibss_antenna(struct net_device *dev, char *command, int total_len) |
---|
| 6750 | +{ |
---|
| 6751 | + char *pcmd = command; |
---|
| 6752 | + char *str = NULL; |
---|
| 6753 | + int txchain, rxchain; |
---|
| 6754 | + int err = 0; |
---|
| 6755 | + |
---|
| 6756 | + WL_DBG(("set ibss antenna:%s\n", command)); |
---|
| 6757 | + |
---|
| 6758 | + /* acquire parameters */ |
---|
| 6759 | + /* drop command */ |
---|
| 6760 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6761 | + |
---|
| 6762 | + /* TX chain */ |
---|
| 6763 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6764 | + if (!str) { |
---|
| 6765 | + WL_ERR(("Invalid parameter : %s\n", pcmd)); |
---|
| 6766 | + return -EINVAL; |
---|
| 6767 | + } |
---|
| 6768 | + txchain = bcm_atoi(str); |
---|
| 6769 | + |
---|
| 6770 | + /* RX chain */ |
---|
| 6771 | + str = bcmstrtok(&pcmd, " ", NULL); |
---|
| 6772 | + if (!str) { |
---|
| 6773 | + WL_ERR(("Invalid parameter : %s\n", pcmd)); |
---|
| 6774 | + return -EINVAL; |
---|
| 6775 | + } |
---|
| 6776 | + rxchain = bcm_atoi(str); |
---|
| 6777 | + |
---|
| 6778 | + err = wldev_iovar_setint(dev, "txchain", txchain); |
---|
| 6779 | + if (err != 0) |
---|
| 6780 | + return err; |
---|
| 6781 | + err = wldev_iovar_setint(dev, "rxchain", rxchain); |
---|
| 6782 | + return ((err == 0)?total_len:err); |
---|
| 6783 | +} |
---|
| 6784 | +#endif /* WLAIBSS */ |
---|
| 6785 | + |
---|
| 6786 | +int wl_keep_alive_set(struct net_device *dev, char* extra) |
---|
2083 | 6787 | { |
---|
2084 | 6788 | wl_mkeep_alive_pkt_t mkeep_alive_pkt; |
---|
2085 | 6789 | int ret; |
---|
2086 | 6790 | uint period_msec = 0; |
---|
2087 | 6791 | char *buf; |
---|
| 6792 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
2088 | 6793 | |
---|
2089 | | - if (extra == NULL) |
---|
2090 | | - { |
---|
2091 | | - DHD_ERROR(("%s: extra is NULL\n", __FUNCTION__)); |
---|
| 6794 | + if (extra == NULL) { |
---|
| 6795 | + DHD_ERROR(("wl_keep_alive_set: extra is NULL\n")); |
---|
2092 | 6796 | return -1; |
---|
2093 | 6797 | } |
---|
2094 | | - if (sscanf(extra, "%d", &period_msec) != 1) |
---|
2095 | | - { |
---|
2096 | | - DHD_ERROR(("%s: sscanf error. check period_msec value\n", __FUNCTION__)); |
---|
| 6798 | + if (sscanf(extra, "%d", &period_msec) != 1) { |
---|
| 6799 | + DHD_ERROR(("wl_keep_alive_set: sscanf error. check period_msec value\n")); |
---|
2097 | 6800 | return -EINVAL; |
---|
2098 | 6801 | } |
---|
2099 | | - DHD_ERROR(("%s: period_msec is %d\n", __FUNCTION__, period_msec)); |
---|
| 6802 | + DHD_ERROR(("wl_keep_alive_set: period_msec is %d\n", period_msec)); |
---|
2100 | 6803 | |
---|
2101 | | - memset(&mkeep_alive_pkt, 0, sizeof(wl_mkeep_alive_pkt_t)); |
---|
| 6804 | + bzero(&mkeep_alive_pkt, sizeof(wl_mkeep_alive_pkt_t)); |
---|
2102 | 6805 | |
---|
2103 | 6806 | mkeep_alive_pkt.period_msec = period_msec; |
---|
2104 | 6807 | mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION); |
---|
.. | .. |
---|
2108 | 6811 | mkeep_alive_pkt.keep_alive_id = 0; |
---|
2109 | 6812 | mkeep_alive_pkt.len_bytes = 0; |
---|
2110 | 6813 | |
---|
2111 | | - buf = kmalloc(WLC_IOCTL_SMLEN, GFP_KERNEL); |
---|
| 6814 | + buf = (char *)MALLOC(cfg->osh, WLC_IOCTL_SMLEN); |
---|
2112 | 6815 | if (!buf) { |
---|
2113 | | - DHD_ERROR(("%s: buffer alloc failed\n", __FUNCTION__)); |
---|
| 6816 | + DHD_ERROR(("wl_keep_alive_set: buffer alloc failed\n")); |
---|
2114 | 6817 | return BCME_NOMEM; |
---|
2115 | 6818 | } |
---|
2116 | | - |
---|
2117 | 6819 | ret = wldev_iovar_setbuf(dev, "mkeep_alive", (char *)&mkeep_alive_pkt, |
---|
2118 | | - WL_MKEEP_ALIVE_FIXED_LEN, buf, WLC_IOCTL_SMLEN, NULL); |
---|
| 6820 | + WL_MKEEP_ALIVE_FIXED_LEN, buf, WLC_IOCTL_SMLEN, NULL); |
---|
2119 | 6821 | if (ret < 0) |
---|
2120 | | - DHD_ERROR(("%s:keep_alive set failed:%d\n", __FUNCTION__, ret)); |
---|
| 6822 | + DHD_ERROR(("wl_keep_alive_set:keep_alive set failed:%d\n", ret)); |
---|
2121 | 6823 | else |
---|
2122 | | - DHD_TRACE(("%s:keep_alive set ok\n", __FUNCTION__)); |
---|
2123 | | - kfree(buf); |
---|
| 6824 | + DHD_TRACE(("wl_keep_alive_set: keep_alive set ok\n")); |
---|
| 6825 | + MFREE(cfg->osh, buf, WLC_IOCTL_SMLEN); |
---|
2124 | 6826 | return ret; |
---|
2125 | 6827 | } |
---|
2126 | | - |
---|
2127 | | -static const char * |
---|
2128 | | -get_string_by_separator(char *result, int result_len, const char *src, char separator) |
---|
2129 | | -{ |
---|
2130 | | - char *end = result + result_len - 1; |
---|
2131 | | - while ((result != end) && (*src != separator) && (*src)) { |
---|
2132 | | - *result++ = *src++; |
---|
2133 | | - } |
---|
2134 | | - *result = 0; |
---|
2135 | | - if (*src == separator) { |
---|
2136 | | - ++src; |
---|
2137 | | - } |
---|
2138 | | - return src; |
---|
2139 | | -} |
---|
2140 | | - |
---|
2141 | | -int |
---|
2142 | | -wl_android_set_roam_offload_bssid_list(struct net_device *dev, const char *cmd) |
---|
2143 | | -{ |
---|
2144 | | - char sbuf[32]; |
---|
2145 | | - int i, cnt, size, err, ioctl_buf_len; |
---|
2146 | | - roamoffl_bssid_list_t *bssid_list; |
---|
2147 | | - const char *str = cmd; |
---|
2148 | | - char *ioctl_buf; |
---|
2149 | | - |
---|
2150 | | - str = get_string_by_separator(sbuf, 32, str, ','); |
---|
2151 | | - cnt = bcm_atoi(sbuf); |
---|
2152 | | - if (cnt < 0 || cnt >= MAX_ROAMOFFL_BSSID_NUM) { |
---|
2153 | | - WL_ERR(("BSSID List count (%d) invalid\n", cnt)); |
---|
2154 | | - return -EINVAL; |
---|
2155 | | - } |
---|
2156 | | - size = sizeof(int32) + sizeof(struct ether_addr) * cnt; |
---|
2157 | | - WL_ERR(("ROAM OFFLOAD BSSID LIST %d BSSIDs, size %d\n", cnt, size)); |
---|
2158 | | - bssid_list = kmalloc(size, GFP_KERNEL); |
---|
2159 | | - if (bssid_list == NULL) { |
---|
2160 | | - WL_ERR(("%s: memory alloc for bssid list(%d) failed\n", |
---|
2161 | | - __FUNCTION__, size)); |
---|
2162 | | - return -ENOMEM; |
---|
2163 | | - } |
---|
2164 | | - ioctl_buf_len = size + 64; |
---|
2165 | | - ioctl_buf = kmalloc(ioctl_buf_len, GFP_KERNEL); |
---|
2166 | | - if (ioctl_buf == NULL) { |
---|
2167 | | - WL_ERR(("%s: memory alloc for ioctl_buf(%d) failed\n", |
---|
2168 | | - __FUNCTION__, ioctl_buf_len)); |
---|
2169 | | - kfree(bssid_list); |
---|
2170 | | - return -ENOMEM; |
---|
2171 | | - } |
---|
2172 | | - |
---|
2173 | | - for (i = 0; i < cnt; i++) { |
---|
2174 | | - str = get_string_by_separator(sbuf, 32, str, ','); |
---|
2175 | | - bcm_ether_atoe(sbuf, &bssid_list->bssid[i]); |
---|
2176 | | - } |
---|
2177 | | - |
---|
2178 | | - bssid_list->cnt = (int32)cnt; |
---|
2179 | | - err = wldev_iovar_setbuf(dev, "roamoffl_bssid_list", |
---|
2180 | | - bssid_list, size, ioctl_buf, ioctl_buf_len, NULL); |
---|
2181 | | - kfree(bssid_list); |
---|
2182 | | - kfree(ioctl_buf); |
---|
2183 | | - |
---|
2184 | | - return err; |
---|
2185 | | -} |
---|
2186 | | - |
---|
2187 | 6828 | #ifdef P2PRESP_WFDIE_SRC |
---|
2188 | 6829 | static int wl_android_get_wfdie_resp(struct net_device *dev, char *command, int total_len) |
---|
2189 | 6830 | { |
---|
.. | .. |
---|
2193 | 6834 | |
---|
2194 | 6835 | error = wldev_iovar_getint(dev, "p2p_only_resp_wfdsrc", &only_resp_wfdsrc); |
---|
2195 | 6836 | if (error) { |
---|
2196 | | - DHD_ERROR(("%s: Failed to get the mode for only_resp_wfdsrc, error = %d\n", |
---|
2197 | | - __FUNCTION__, error)); |
---|
| 6837 | + DHD_ERROR(("wl_android_get_wfdie_resp: Failed to get the mode" |
---|
| 6838 | + " for only_resp_wfdsrc, error = %d\n", |
---|
| 6839 | + error)); |
---|
2198 | 6840 | return -1; |
---|
2199 | 6841 | } |
---|
2200 | 6842 | |
---|
.. | .. |
---|
2210 | 6852 | |
---|
2211 | 6853 | error = wldev_iovar_setint(dev, "p2p_only_resp_wfdsrc", only_resp_wfdsrc); |
---|
2212 | 6854 | if (error) { |
---|
2213 | | - DHD_ERROR(("%s: Failed to set only_resp_wfdsrc %d, error = %d\n", |
---|
2214 | | - __FUNCTION__, only_resp_wfdsrc, error)); |
---|
| 6855 | + DHD_ERROR(("wl_android_set_wfdie_resp: Failed to set only_resp_wfdsrc %d," |
---|
| 6856 | + " error = %d\n", |
---|
| 6857 | + only_resp_wfdsrc, error)); |
---|
2215 | 6858 | return -1; |
---|
2216 | 6859 | } |
---|
2217 | 6860 | |
---|
.. | .. |
---|
2221 | 6864 | |
---|
2222 | 6865 | #ifdef BT_WIFI_HANDOVER |
---|
2223 | 6866 | static int |
---|
2224 | | -wl_tbow_teardown(struct net_device *dev, char *command, int total_len) |
---|
| 6867 | +wl_tbow_teardown(struct net_device *dev) |
---|
2225 | 6868 | { |
---|
2226 | 6869 | int err = BCME_OK; |
---|
2227 | 6870 | char buf[WLC_IOCTL_SMLEN]; |
---|
2228 | 6871 | tbow_setup_netinfo_t netinfo; |
---|
2229 | | - memset(&netinfo, 0, sizeof(netinfo)); |
---|
| 6872 | + bzero(&netinfo, sizeof(netinfo)); |
---|
2230 | 6873 | netinfo.opmode = TBOW_HO_MODE_TEARDOWN; |
---|
2231 | 6874 | |
---|
2232 | 6875 | err = wldev_iovar_setbuf_bsscfg(dev, "tbow_doho", &netinfo, |
---|
2233 | 6876 | sizeof(tbow_setup_netinfo_t), buf, WLC_IOCTL_SMLEN, 0, NULL); |
---|
2234 | 6877 | if (err < 0) { |
---|
2235 | 6878 | WL_ERR(("tbow_doho iovar error %d\n", err)); |
---|
2236 | | - return err; |
---|
| 6879 | + return err; |
---|
2237 | 6880 | } |
---|
2238 | 6881 | return err; |
---|
2239 | 6882 | } |
---|
.. | .. |
---|
2241 | 6884 | |
---|
2242 | 6885 | #ifdef SET_RPS_CPUS |
---|
2243 | 6886 | static int |
---|
2244 | | -wl_android_set_rps_cpus(struct net_device *dev, char *command, int total_len) |
---|
| 6887 | +wl_android_set_rps_cpus(struct net_device *dev, char *command) |
---|
2245 | 6888 | { |
---|
2246 | 6889 | int error, enable; |
---|
2247 | 6890 | |
---|
.. | .. |
---|
2250 | 6893 | |
---|
2251 | 6894 | #if defined(DHDTCPACK_SUPPRESS) && defined(BCMPCIE) && defined(WL_CFG80211) |
---|
2252 | 6895 | if (!error) { |
---|
2253 | | - void *dhdp = wl_cfg80211_get_dhdp(); |
---|
| 6896 | + void *dhdp = wl_cfg80211_get_dhdp(net); |
---|
2254 | 6897 | if (enable) { |
---|
2255 | | - DHD_TRACE(("%s : set ack suppress. TCPACK_SUP_HOLD.\n", __FUNCTION__)); |
---|
| 6898 | + DHD_TRACE(("wl_android_set_rps_cpus: set ack suppress." |
---|
| 6899 | + " TCPACK_SUP_HOLD.\n")); |
---|
2256 | 6900 | dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_HOLD); |
---|
2257 | 6901 | } else { |
---|
2258 | | - DHD_TRACE(("%s : clear ack suppress.\n", __FUNCTION__)); |
---|
| 6902 | + DHD_TRACE(("wl_android_set_rps_cpus: clear ack suppress.\n")); |
---|
2259 | 6903 | dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_OFF); |
---|
2260 | 6904 | } |
---|
2261 | 6905 | } |
---|
.. | .. |
---|
2264 | 6908 | return error; |
---|
2265 | 6909 | } |
---|
2266 | 6910 | #endif /* SET_RPS_CPUS */ |
---|
2267 | | -int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) |
---|
| 6911 | + |
---|
| 6912 | +static int wl_android_get_link_status(struct net_device *dev, char *command, |
---|
| 6913 | + int total_len) |
---|
| 6914 | +{ |
---|
| 6915 | + int bytes_written, error, result = 0, single_stream, stf = -1, i, nss = 0, mcs_map; |
---|
| 6916 | + uint32 rspec; |
---|
| 6917 | + uint encode, txexp; |
---|
| 6918 | + wl_bss_info_t *bi; |
---|
| 6919 | + int datalen; |
---|
| 6920 | + char buf[sizeof(uint32) + sizeof(wl_bss_info_t)]; |
---|
| 6921 | + |
---|
| 6922 | + datalen = sizeof(uint32) + sizeof(wl_bss_info_t); |
---|
| 6923 | + |
---|
| 6924 | + bzero(buf, datalen); |
---|
| 6925 | + /* get BSS information */ |
---|
| 6926 | + *(u32 *) buf = htod32(datalen); |
---|
| 6927 | + error = wldev_ioctl_get(dev, WLC_GET_BSS_INFO, (void *)buf, datalen); |
---|
| 6928 | + if (unlikely(error)) { |
---|
| 6929 | + WL_ERR(("Could not get bss info %d\n", error)); |
---|
| 6930 | + return -1; |
---|
| 6931 | + } |
---|
| 6932 | + |
---|
| 6933 | + bi = (wl_bss_info_t*) (buf + sizeof(uint32)); |
---|
| 6934 | + |
---|
| 6935 | + for (i = 0; i < ETHER_ADDR_LEN; i++) { |
---|
| 6936 | + if (bi->BSSID.octet[i] > 0) { |
---|
| 6937 | + break; |
---|
| 6938 | + } |
---|
| 6939 | + } |
---|
| 6940 | + |
---|
| 6941 | + if (i == ETHER_ADDR_LEN) { |
---|
| 6942 | + WL_DBG(("No BSSID\n")); |
---|
| 6943 | + return -1; |
---|
| 6944 | + } |
---|
| 6945 | + |
---|
| 6946 | + /* check VHT capability at beacon */ |
---|
| 6947 | + if (bi->vht_cap) { |
---|
| 6948 | + if (CHSPEC_IS5G(bi->chanspec)) { |
---|
| 6949 | + result |= WL_ANDROID_LINK_AP_VHT_SUPPORT; |
---|
| 6950 | + } |
---|
| 6951 | + } |
---|
| 6952 | + |
---|
| 6953 | + /* get a rspec (radio spectrum) rate */ |
---|
| 6954 | + error = wldev_iovar_getint(dev, "nrate", &rspec); |
---|
| 6955 | + if (unlikely(error) || rspec == 0) { |
---|
| 6956 | + WL_ERR(("get link status error (%d)\n", error)); |
---|
| 6957 | + return -1; |
---|
| 6958 | + } |
---|
| 6959 | + |
---|
| 6960 | + encode = (rspec & WL_RSPEC_ENCODING_MASK); |
---|
| 6961 | + txexp = (rspec & WL_RSPEC_TXEXP_MASK) >> WL_RSPEC_TXEXP_SHIFT; |
---|
| 6962 | + |
---|
| 6963 | + switch (encode) { |
---|
| 6964 | + case WL_RSPEC_ENCODE_HT: |
---|
| 6965 | + /* check Rx MCS Map for HT */ |
---|
| 6966 | + for (i = 0; i < MAX_STREAMS_SUPPORTED; i++) { |
---|
| 6967 | + int8 bitmap = 0xFF; |
---|
| 6968 | + if (i == MAX_STREAMS_SUPPORTED-1) { |
---|
| 6969 | + bitmap = 0x7F; |
---|
| 6970 | + } |
---|
| 6971 | + if (bi->basic_mcs[i] & bitmap) { |
---|
| 6972 | + nss++; |
---|
| 6973 | + } |
---|
| 6974 | + } |
---|
| 6975 | + break; |
---|
| 6976 | + case WL_RSPEC_ENCODE_VHT: |
---|
| 6977 | + /* check Rx MCS Map for VHT */ |
---|
| 6978 | + for (i = 1; i <= VHT_CAP_MCS_MAP_NSS_MAX; i++) { |
---|
| 6979 | + mcs_map = VHT_MCS_MAP_GET_MCS_PER_SS(i, dtoh16(bi->vht_rxmcsmap)); |
---|
| 6980 | + if (mcs_map != VHT_CAP_MCS_MAP_NONE) { |
---|
| 6981 | + nss++; |
---|
| 6982 | + } |
---|
| 6983 | + } |
---|
| 6984 | + break; |
---|
| 6985 | + } |
---|
| 6986 | + |
---|
| 6987 | + /* check MIMO capability with nss in beacon */ |
---|
| 6988 | + if (nss > 1) { |
---|
| 6989 | + result |= WL_ANDROID_LINK_AP_MIMO_SUPPORT; |
---|
| 6990 | + } |
---|
| 6991 | + |
---|
| 6992 | + single_stream = (encode == WL_RSPEC_ENCODE_RATE) || |
---|
| 6993 | + ((encode == WL_RSPEC_ENCODE_HT) && (rspec & WL_RSPEC_HT_MCS_MASK) < 8) || |
---|
| 6994 | + ((encode == WL_RSPEC_ENCODE_VHT) && |
---|
| 6995 | + ((rspec & WL_RSPEC_VHT_NSS_MASK) >> WL_RSPEC_VHT_NSS_SHIFT) == 1); |
---|
| 6996 | + |
---|
| 6997 | + if (txexp == 0) { |
---|
| 6998 | + if ((rspec & WL_RSPEC_STBC) && single_stream) { |
---|
| 6999 | + stf = OLD_NRATE_STF_STBC; |
---|
| 7000 | + } else { |
---|
| 7001 | + stf = (single_stream) ? OLD_NRATE_STF_SISO : OLD_NRATE_STF_SDM; |
---|
| 7002 | + } |
---|
| 7003 | + } else if (txexp == 1 && single_stream) { |
---|
| 7004 | + stf = OLD_NRATE_STF_CDD; |
---|
| 7005 | + } |
---|
| 7006 | + |
---|
| 7007 | + /* check 11ac (VHT) */ |
---|
| 7008 | + if (encode == WL_RSPEC_ENCODE_VHT) { |
---|
| 7009 | + if (CHSPEC_IS5G(bi->chanspec)) { |
---|
| 7010 | + result |= WL_ANDROID_LINK_VHT; |
---|
| 7011 | + } |
---|
| 7012 | + } |
---|
| 7013 | + |
---|
| 7014 | + /* check MIMO */ |
---|
| 7015 | + if (result & WL_ANDROID_LINK_AP_MIMO_SUPPORT) { |
---|
| 7016 | + switch (stf) { |
---|
| 7017 | + case OLD_NRATE_STF_SISO: |
---|
| 7018 | + break; |
---|
| 7019 | + case OLD_NRATE_STF_CDD: |
---|
| 7020 | + case OLD_NRATE_STF_STBC: |
---|
| 7021 | + result |= WL_ANDROID_LINK_MIMO; |
---|
| 7022 | + break; |
---|
| 7023 | + case OLD_NRATE_STF_SDM: |
---|
| 7024 | + if (!single_stream) { |
---|
| 7025 | + result |= WL_ANDROID_LINK_MIMO; |
---|
| 7026 | + } |
---|
| 7027 | + break; |
---|
| 7028 | + } |
---|
| 7029 | + } |
---|
| 7030 | + |
---|
| 7031 | + WL_DBG(("%s:result=%d, stf=%d, single_stream=%d, mcs map=%d\n", |
---|
| 7032 | + __FUNCTION__, result, stf, single_stream, nss)); |
---|
| 7033 | + |
---|
| 7034 | + bytes_written = snprintf(command, total_len, "%s %d", CMD_GET_LINK_STATUS, result); |
---|
| 7035 | + |
---|
| 7036 | + return bytes_written; |
---|
| 7037 | +} |
---|
| 7038 | + |
---|
| 7039 | +#ifdef P2P_LISTEN_OFFLOADING |
---|
| 7040 | + |
---|
| 7041 | +s32 |
---|
| 7042 | +wl_cfg80211_p2plo_deinit(struct bcm_cfg80211 *cfg) |
---|
| 7043 | +{ |
---|
| 7044 | + s32 bssidx; |
---|
| 7045 | + int ret = 0; |
---|
| 7046 | + int p2plo_pause = 0; |
---|
| 7047 | + dhd_pub_t *dhd = NULL; |
---|
| 7048 | + if (!cfg || !cfg->p2p) { |
---|
| 7049 | + WL_ERR(("Wl %p or cfg->p2p %p is null\n", |
---|
| 7050 | + cfg, cfg ? cfg->p2p : 0)); |
---|
| 7051 | + return 0; |
---|
| 7052 | + } |
---|
| 7053 | + |
---|
| 7054 | + dhd = (dhd_pub_t *)(cfg->pub); |
---|
| 7055 | + if (!dhd->up) { |
---|
| 7056 | + WL_ERR(("bus is already down\n")); |
---|
| 7057 | + return ret; |
---|
| 7058 | + } |
---|
| 7059 | + |
---|
| 7060 | + bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); |
---|
| 7061 | + ret = wldev_iovar_setbuf_bsscfg(bcmcfg_to_prmry_ndev(cfg), |
---|
| 7062 | + "p2po_stop", (void*)&p2plo_pause, sizeof(p2plo_pause), |
---|
| 7063 | + cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync); |
---|
| 7064 | + if (ret < 0) { |
---|
| 7065 | + WL_ERR(("p2po_stop Failed :%d\n", ret)); |
---|
| 7066 | + } |
---|
| 7067 | + |
---|
| 7068 | + return ret; |
---|
| 7069 | +} |
---|
| 7070 | +s32 |
---|
| 7071 | +wl_cfg80211_p2plo_listen_start(struct net_device *dev, u8 *buf, int len) |
---|
| 7072 | +{ |
---|
| 7073 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 7074 | + s32 bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); |
---|
| 7075 | + wl_p2plo_listen_t p2plo_listen; |
---|
| 7076 | + int ret = -EAGAIN; |
---|
| 7077 | + int channel = 0; |
---|
| 7078 | + int period = 0; |
---|
| 7079 | + int interval = 0; |
---|
| 7080 | + int count = 0; |
---|
| 7081 | + if (WL_DRV_STATUS_SENDING_AF_FRM_EXT(cfg)) { |
---|
| 7082 | + WL_ERR(("Sending Action Frames. Try it again.\n")); |
---|
| 7083 | + goto exit; |
---|
| 7084 | + } |
---|
| 7085 | + |
---|
| 7086 | + if (wl_get_drv_status_all(cfg, SCANNING)) { |
---|
| 7087 | + WL_ERR(("Scanning already\n")); |
---|
| 7088 | + goto exit; |
---|
| 7089 | + } |
---|
| 7090 | + |
---|
| 7091 | + if (wl_get_drv_status(cfg, SCAN_ABORTING, dev)) { |
---|
| 7092 | + WL_ERR(("Scanning being aborted\n")); |
---|
| 7093 | + goto exit; |
---|
| 7094 | + } |
---|
| 7095 | + |
---|
| 7096 | + if (wl_get_p2p_status(cfg, DISC_IN_PROGRESS)) { |
---|
| 7097 | + WL_ERR(("p2p listen offloading already running\n")); |
---|
| 7098 | + goto exit; |
---|
| 7099 | + } |
---|
| 7100 | + |
---|
| 7101 | + /* Just in case if it is not enabled */ |
---|
| 7102 | + if ((ret = wl_cfgp2p_enable_discovery(cfg, dev, NULL, 0)) < 0) { |
---|
| 7103 | + WL_ERR(("cfgp2p_enable discovery failed")); |
---|
| 7104 | + goto exit; |
---|
| 7105 | + } |
---|
| 7106 | + |
---|
| 7107 | + bzero(&p2plo_listen, sizeof(wl_p2plo_listen_t)); |
---|
| 7108 | + |
---|
| 7109 | + if (len) { |
---|
| 7110 | + sscanf(buf, " %10d %10d %10d %10d", &channel, &period, &interval, &count); |
---|
| 7111 | + if ((channel == 0) || (period == 0) || |
---|
| 7112 | + (interval == 0) || (count == 0)) { |
---|
| 7113 | + WL_ERR(("Wrong argument %d/%d/%d/%d \n", |
---|
| 7114 | + channel, period, interval, count)); |
---|
| 7115 | + ret = -EAGAIN; |
---|
| 7116 | + goto exit; |
---|
| 7117 | + } |
---|
| 7118 | + p2plo_listen.period = period; |
---|
| 7119 | + p2plo_listen.interval = interval; |
---|
| 7120 | + p2plo_listen.count = count; |
---|
| 7121 | + |
---|
| 7122 | + WL_ERR(("channel:%d period:%d, interval:%d count:%d\n", |
---|
| 7123 | + channel, period, interval, count)); |
---|
| 7124 | + } else { |
---|
| 7125 | + WL_ERR(("Argument len is wrong.\n")); |
---|
| 7126 | + ret = -EAGAIN; |
---|
| 7127 | + goto exit; |
---|
| 7128 | + } |
---|
| 7129 | + |
---|
| 7130 | + if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_listen_channel", (void*)&channel, |
---|
| 7131 | + sizeof(channel), cfg->ioctl_buf, WLC_IOCTL_SMLEN, |
---|
| 7132 | + bssidx, &cfg->ioctl_buf_sync)) < 0) { |
---|
| 7133 | + WL_ERR(("p2po_listen_channel Failed :%d\n", ret)); |
---|
| 7134 | + goto exit; |
---|
| 7135 | + } |
---|
| 7136 | + |
---|
| 7137 | + if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_listen", (void*)&p2plo_listen, |
---|
| 7138 | + sizeof(wl_p2plo_listen_t), cfg->ioctl_buf, WLC_IOCTL_SMLEN, |
---|
| 7139 | + bssidx, &cfg->ioctl_buf_sync)) < 0) { |
---|
| 7140 | + WL_ERR(("p2po_listen Failed :%d\n", ret)); |
---|
| 7141 | + goto exit; |
---|
| 7142 | + } |
---|
| 7143 | + |
---|
| 7144 | + wl_set_p2p_status(cfg, DISC_IN_PROGRESS); |
---|
| 7145 | +exit : |
---|
| 7146 | + return ret; |
---|
| 7147 | +} |
---|
| 7148 | +s32 |
---|
| 7149 | +wl_cfg80211_p2plo_listen_stop(struct net_device *dev) |
---|
| 7150 | +{ |
---|
| 7151 | + struct bcm_cfg80211 *cfg = wl_get_cfg(dev); |
---|
| 7152 | + s32 bssidx = wl_to_p2p_bss_bssidx(cfg, P2PAPI_BSSCFG_DEVICE); |
---|
| 7153 | + int ret = -EAGAIN; |
---|
| 7154 | + |
---|
| 7155 | + if ((ret = wldev_iovar_setbuf_bsscfg(dev, "p2po_stop", NULL, |
---|
| 7156 | + 0, cfg->ioctl_buf, WLC_IOCTL_SMLEN, |
---|
| 7157 | + bssidx, &cfg->ioctl_buf_sync)) < 0) { |
---|
| 7158 | + WL_ERR(("p2po_stop Failed :%d\n", ret)); |
---|
| 7159 | + goto exit; |
---|
| 7160 | + } |
---|
| 7161 | + |
---|
| 7162 | +exit: |
---|
| 7163 | + return ret; |
---|
| 7164 | +} |
---|
| 7165 | + |
---|
| 7166 | +s32 |
---|
| 7167 | +wl_cfg80211_p2plo_offload(struct net_device *dev, char *cmd, char* buf, int len) |
---|
| 7168 | +{ |
---|
| 7169 | + int ret = 0; |
---|
| 7170 | + |
---|
| 7171 | + WL_ERR(("Entry cmd:%s arg_len:%d \n", cmd, len)); |
---|
| 7172 | + |
---|
| 7173 | + if (strncmp(cmd, "P2P_LO_START", strlen("P2P_LO_START")) == 0) { |
---|
| 7174 | + ret = wl_cfg80211_p2plo_listen_start(dev, buf, len); |
---|
| 7175 | + } else if (strncmp(cmd, "P2P_LO_STOP", strlen("P2P_LO_STOP")) == 0) { |
---|
| 7176 | + ret = wl_cfg80211_p2plo_listen_stop(dev); |
---|
| 7177 | + } else { |
---|
| 7178 | + WL_ERR(("Request for Unsupported CMD:%s \n", buf)); |
---|
| 7179 | + ret = -EINVAL; |
---|
| 7180 | + } |
---|
| 7181 | + return ret; |
---|
| 7182 | +} |
---|
| 7183 | +void |
---|
| 7184 | +wl_cfg80211_cancel_p2plo(struct bcm_cfg80211 *cfg) |
---|
| 7185 | +{ |
---|
| 7186 | + struct wireless_dev *wdev; |
---|
| 7187 | + if (!cfg) { |
---|
| 7188 | + return; |
---|
| 7189 | + } |
---|
| 7190 | + |
---|
| 7191 | + wdev = bcmcfg_to_p2p_wdev(cfg); |
---|
| 7192 | + |
---|
| 7193 | + if (wl_get_p2p_status(cfg, DISC_IN_PROGRESS)) { |
---|
| 7194 | + WL_INFORM_MEM(("P2P_FIND: Discovery offload is already in progress." |
---|
| 7195 | + "it aborted\n")); |
---|
| 7196 | + wl_clr_p2p_status(cfg, DISC_IN_PROGRESS); |
---|
| 7197 | + if (wdev != NULL) { |
---|
| 7198 | +#if defined(WL_CFG80211_P2P_DEV_IF) |
---|
| 7199 | + cfg80211_remain_on_channel_expired(wdev, |
---|
| 7200 | + cfg->last_roc_id, |
---|
| 7201 | + &cfg->remain_on_chan, GFP_KERNEL); |
---|
| 7202 | +#else |
---|
| 7203 | + cfg80211_remain_on_channel_expired(wdev, |
---|
| 7204 | + cfg->last_roc_id, |
---|
| 7205 | + &cfg->remain_on_chan, |
---|
| 7206 | + cfg->remain_on_chan_type, GFP_KERNEL); |
---|
| 7207 | +#endif /* WL_CFG80211_P2P_DEV_IF */ |
---|
| 7208 | + } |
---|
| 7209 | + wl_cfg80211_p2plo_deinit(cfg); |
---|
| 7210 | + } |
---|
| 7211 | +} |
---|
| 7212 | +#endif /* P2P_LISTEN_OFFLOADING */ |
---|
| 7213 | + |
---|
| 7214 | +#ifdef WL_MURX |
---|
| 7215 | +int |
---|
| 7216 | +wl_android_murx_bfe_cap(struct net_device *dev, int val) |
---|
| 7217 | +{ |
---|
| 7218 | + int err = BCME_OK; |
---|
| 7219 | + int iface_count = wl_cfg80211_iface_count(dev); |
---|
| 7220 | + struct ether_addr bssid; |
---|
| 7221 | + wl_reassoc_params_t params; |
---|
| 7222 | + |
---|
| 7223 | + if (iface_count > 1) { |
---|
| 7224 | + WL_ERR(("murx_bfe_cap change is not allowed when " |
---|
| 7225 | + "there are multiple interfaces\n")); |
---|
| 7226 | + return -EINVAL; |
---|
| 7227 | + } |
---|
| 7228 | + /* Now there is only single interface */ |
---|
| 7229 | + err = wldev_iovar_setint(dev, "murx_bfe_cap", val); |
---|
| 7230 | + if (unlikely(err)) { |
---|
| 7231 | + WL_ERR(("Failed to set murx_bfe_cap IOVAR to %d," |
---|
| 7232 | + "error %d\n", val, err)); |
---|
| 7233 | + return err; |
---|
| 7234 | + } |
---|
| 7235 | + |
---|
| 7236 | + /* If successful intiate a reassoc */ |
---|
| 7237 | + bzero(&bssid, ETHER_ADDR_LEN); |
---|
| 7238 | + if ((err = wldev_ioctl_get(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN)) < 0) { |
---|
| 7239 | + WL_ERR(("Failed to get bssid, error=%d\n", err)); |
---|
| 7240 | + return err; |
---|
| 7241 | + } |
---|
| 7242 | + |
---|
| 7243 | + bzero(¶ms, sizeof(wl_reassoc_params_t)); |
---|
| 7244 | + memcpy(¶ms.bssid, &bssid, ETHER_ADDR_LEN); |
---|
| 7245 | + |
---|
| 7246 | + if ((err = wldev_ioctl_set(dev, WLC_REASSOC, ¶ms, |
---|
| 7247 | + sizeof(wl_reassoc_params_t))) < 0) { |
---|
| 7248 | + WL_ERR(("reassoc failed err:%d \n", err)); |
---|
| 7249 | + } else { |
---|
| 7250 | + WL_DBG(("reassoc issued successfully\n")); |
---|
| 7251 | + } |
---|
| 7252 | + |
---|
| 7253 | + return err; |
---|
| 7254 | +} |
---|
| 7255 | +#endif /* WL_MURX */ |
---|
| 7256 | + |
---|
| 7257 | +#ifdef SUPPORT_RSSI_SUM_REPORT |
---|
| 7258 | +int |
---|
| 7259 | +wl_android_get_rssi_per_ant(struct net_device *dev, char *command, int total_len) |
---|
| 7260 | +{ |
---|
| 7261 | + wl_rssi_ant_mimo_t rssi_ant_mimo; |
---|
| 7262 | + char *ifname = NULL; |
---|
| 7263 | + char *peer_mac = NULL; |
---|
| 7264 | + char *mimo_cmd = "mimo"; |
---|
| 7265 | + char *pos, *token; |
---|
| 7266 | + int err = BCME_OK; |
---|
| 7267 | + int bytes_written = 0; |
---|
| 7268 | + bool mimo_rssi = FALSE; |
---|
| 7269 | + |
---|
| 7270 | + bzero(&rssi_ant_mimo, sizeof(wl_rssi_ant_mimo_t)); |
---|
| 7271 | + /* |
---|
| 7272 | + * STA I/F: DRIVER GET_RSSI_PER_ANT <ifname> <mimo> |
---|
| 7273 | + * AP/GO I/F: DRIVER GET_RSSI_PER_ANT <ifname> <Peer MAC addr> <mimo> |
---|
| 7274 | + */ |
---|
| 7275 | + pos = command; |
---|
| 7276 | + |
---|
| 7277 | + /* drop command */ |
---|
| 7278 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7279 | + |
---|
| 7280 | + /* get the interface name */ |
---|
| 7281 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7282 | + if (!token) { |
---|
| 7283 | + WL_ERR(("Invalid arguments\n")); |
---|
| 7284 | + return -EINVAL; |
---|
| 7285 | + } |
---|
| 7286 | + ifname = token; |
---|
| 7287 | + |
---|
| 7288 | + /* Optional: Check the MIMO RSSI mode or peer MAC address */ |
---|
| 7289 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7290 | + if (token) { |
---|
| 7291 | + /* Check the MIMO RSSI mode */ |
---|
| 7292 | + if (strncmp(token, mimo_cmd, strlen(mimo_cmd)) == 0) { |
---|
| 7293 | + mimo_rssi = TRUE; |
---|
| 7294 | + } else { |
---|
| 7295 | + peer_mac = token; |
---|
| 7296 | + } |
---|
| 7297 | + } |
---|
| 7298 | + |
---|
| 7299 | + /* Optional: Check the MIMO RSSI mode - RSSI sum across antennas */ |
---|
| 7300 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7301 | + if (token && strncmp(token, mimo_cmd, strlen(mimo_cmd)) == 0) { |
---|
| 7302 | + mimo_rssi = TRUE; |
---|
| 7303 | + } |
---|
| 7304 | + |
---|
| 7305 | + err = wl_get_rssi_per_ant(dev, ifname, peer_mac, &rssi_ant_mimo); |
---|
| 7306 | + if (unlikely(err)) { |
---|
| 7307 | + WL_ERR(("Failed to get RSSI info, err=%d\n", err)); |
---|
| 7308 | + return err; |
---|
| 7309 | + } |
---|
| 7310 | + |
---|
| 7311 | + /* Parse the results */ |
---|
| 7312 | + WL_DBG(("ifname %s, version %d, count %d, mimo rssi %d\n", |
---|
| 7313 | + ifname, rssi_ant_mimo.version, rssi_ant_mimo.count, mimo_rssi)); |
---|
| 7314 | + if (mimo_rssi) { |
---|
| 7315 | + WL_DBG(("MIMO RSSI: %d\n", rssi_ant_mimo.rssi_sum)); |
---|
| 7316 | + bytes_written = snprintf(command, total_len, "%s MIMO %d", |
---|
| 7317 | + CMD_GET_RSSI_PER_ANT, rssi_ant_mimo.rssi_sum); |
---|
| 7318 | + } else { |
---|
| 7319 | + int cnt; |
---|
| 7320 | + bytes_written = snprintf(command, total_len, "%s PER_ANT ", CMD_GET_RSSI_PER_ANT); |
---|
| 7321 | + for (cnt = 0; cnt < rssi_ant_mimo.count; cnt++) { |
---|
| 7322 | + WL_DBG(("RSSI[%d]: %d\n", cnt, rssi_ant_mimo.rssi_ant[cnt])); |
---|
| 7323 | + bytes_written = snprintf(command, total_len, "%d ", |
---|
| 7324 | + rssi_ant_mimo.rssi_ant[cnt]); |
---|
| 7325 | + } |
---|
| 7326 | + } |
---|
| 7327 | + |
---|
| 7328 | + return bytes_written; |
---|
| 7329 | +} |
---|
| 7330 | + |
---|
| 7331 | +int |
---|
| 7332 | +wl_android_set_rssi_logging(struct net_device *dev, char *command, int total_len) |
---|
| 7333 | +{ |
---|
| 7334 | + rssilog_set_param_t set_param; |
---|
| 7335 | + char *pos, *token; |
---|
| 7336 | + int err = BCME_OK; |
---|
| 7337 | + |
---|
| 7338 | + bzero(&set_param, sizeof(rssilog_set_param_t)); |
---|
| 7339 | + /* |
---|
| 7340 | + * DRIVER SET_RSSI_LOGGING <enable/disable> <RSSI Threshold> <Time Threshold> |
---|
| 7341 | + */ |
---|
| 7342 | + pos = command; |
---|
| 7343 | + |
---|
| 7344 | + /* drop command */ |
---|
| 7345 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7346 | + |
---|
| 7347 | + /* enable/disable */ |
---|
| 7348 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7349 | + if (!token) { |
---|
| 7350 | + WL_ERR(("Invalid arguments\n")); |
---|
| 7351 | + return -EINVAL; |
---|
| 7352 | + } |
---|
| 7353 | + set_param.enable = bcm_atoi(token); |
---|
| 7354 | + |
---|
| 7355 | + /* RSSI Threshold */ |
---|
| 7356 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7357 | + if (!token) { |
---|
| 7358 | + WL_ERR(("Invalid arguments\n")); |
---|
| 7359 | + return -EINVAL; |
---|
| 7360 | + } |
---|
| 7361 | + set_param.rssi_threshold = bcm_atoi(token); |
---|
| 7362 | + |
---|
| 7363 | + /* Time Threshold */ |
---|
| 7364 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7365 | + if (!token) { |
---|
| 7366 | + WL_ERR(("Invalid arguments\n")); |
---|
| 7367 | + return -EINVAL; |
---|
| 7368 | + } |
---|
| 7369 | + set_param.time_threshold = bcm_atoi(token); |
---|
| 7370 | + |
---|
| 7371 | + WL_DBG(("enable %d, RSSI threshold %d, Time threshold %d\n", set_param.enable, |
---|
| 7372 | + set_param.rssi_threshold, set_param.time_threshold)); |
---|
| 7373 | + |
---|
| 7374 | + err = wl_set_rssi_logging(dev, (void *)&set_param); |
---|
| 7375 | + if (unlikely(err)) { |
---|
| 7376 | + WL_ERR(("Failed to configure RSSI logging: enable %d, RSSI Threshold %d," |
---|
| 7377 | + " Time Threshold %d\n", set_param.enable, set_param.rssi_threshold, |
---|
| 7378 | + set_param.time_threshold)); |
---|
| 7379 | + } |
---|
| 7380 | + |
---|
| 7381 | + return err; |
---|
| 7382 | +} |
---|
| 7383 | + |
---|
| 7384 | +int |
---|
| 7385 | +wl_android_get_rssi_logging(struct net_device *dev, char *command, int total_len) |
---|
| 7386 | +{ |
---|
| 7387 | + rssilog_get_param_t get_param; |
---|
| 7388 | + int err = BCME_OK; |
---|
| 7389 | + int bytes_written = 0; |
---|
| 7390 | + |
---|
| 7391 | + err = wl_get_rssi_logging(dev, (void *)&get_param); |
---|
| 7392 | + if (unlikely(err)) { |
---|
| 7393 | + WL_ERR(("Failed to get RSSI logging info\n")); |
---|
| 7394 | + return BCME_ERROR; |
---|
| 7395 | + } |
---|
| 7396 | + |
---|
| 7397 | + WL_DBG(("report_count %d, enable %d, rssi_threshold %d, time_threshold %d\n", |
---|
| 7398 | + get_param.report_count, get_param.enable, get_param.rssi_threshold, |
---|
| 7399 | + get_param.time_threshold)); |
---|
| 7400 | + |
---|
| 7401 | + /* Parse the parameter */ |
---|
| 7402 | + if (!get_param.enable) { |
---|
| 7403 | + WL_DBG(("RSSI LOGGING: Feature is disables\n")); |
---|
| 7404 | + bytes_written = snprintf(command, total_len, |
---|
| 7405 | + "%s FEATURE DISABLED\n", CMD_GET_RSSI_LOGGING); |
---|
| 7406 | + } else if (get_param.enable & |
---|
| 7407 | + (RSSILOG_FLAG_FEATURE_SW | RSSILOG_FLAG_REPORT_READY)) { |
---|
| 7408 | + if (!get_param.report_count) { |
---|
| 7409 | + WL_DBG(("[PASS] RSSI difference across antennas is within" |
---|
| 7410 | + " threshold limits\n")); |
---|
| 7411 | + bytes_written = snprintf(command, total_len, "%s PASS\n", |
---|
| 7412 | + CMD_GET_RSSI_LOGGING); |
---|
| 7413 | + } else { |
---|
| 7414 | + WL_DBG(("[FAIL] RSSI difference across antennas found " |
---|
| 7415 | + "to be greater than %3d dB\n", get_param.rssi_threshold)); |
---|
| 7416 | + WL_DBG(("[FAIL] RSSI difference check have failed for " |
---|
| 7417 | + "%d out of %d times\n", get_param.report_count, |
---|
| 7418 | + get_param.time_threshold)); |
---|
| 7419 | + WL_DBG(("[FAIL] RSSI difference is being monitored once " |
---|
| 7420 | + "per second, for a %d secs window\n", get_param.time_threshold)); |
---|
| 7421 | + bytes_written = snprintf(command, total_len, "%s FAIL - RSSI Threshold " |
---|
| 7422 | + "%d dBm for %d out of %d times\n", CMD_GET_RSSI_LOGGING, |
---|
| 7423 | + get_param.rssi_threshold, get_param.report_count, |
---|
| 7424 | + get_param.time_threshold); |
---|
| 7425 | + } |
---|
| 7426 | + } else { |
---|
| 7427 | + WL_DBG(("[BUSY] Reprot is not ready\n")); |
---|
| 7428 | + bytes_written = snprintf(command, total_len, "%s BUSY - NOT READY\n", |
---|
| 7429 | + CMD_GET_RSSI_LOGGING); |
---|
| 7430 | + } |
---|
| 7431 | + |
---|
| 7432 | + return bytes_written; |
---|
| 7433 | +} |
---|
| 7434 | +#endif /* SUPPORT_RSSI_SUM_REPORT */ |
---|
| 7435 | + |
---|
| 7436 | +#ifdef SET_PCIE_IRQ_CPU_CORE |
---|
| 7437 | +void |
---|
| 7438 | +wl_android_set_irq_cpucore(struct net_device *net, int affinity_cmd) |
---|
| 7439 | +{ |
---|
| 7440 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(net); |
---|
| 7441 | + if (!dhdp) { |
---|
| 7442 | + WL_ERR(("dhd is NULL\n")); |
---|
| 7443 | + return; |
---|
| 7444 | + } |
---|
| 7445 | + |
---|
| 7446 | + if (affinity_cmd < PCIE_IRQ_AFFINITY_OFF || affinity_cmd > PCIE_IRQ_AFFINITY_LAST) { |
---|
| 7447 | + WL_ERR(("Wrong Affinity cmds:%d, %s\n", affinity_cmd, __FUNCTION__)); |
---|
| 7448 | + return; |
---|
| 7449 | + } |
---|
| 7450 | + |
---|
| 7451 | + dhd_set_irq_cpucore(dhdp, affinity_cmd); |
---|
| 7452 | +} |
---|
| 7453 | +#endif /* SET_PCIE_IRQ_CPU_CORE */ |
---|
| 7454 | + |
---|
| 7455 | +#ifdef SUPPORT_LQCM |
---|
| 7456 | +static int |
---|
| 7457 | +wl_android_lqcm_enable(struct net_device *net, int lqcm_enable) |
---|
| 7458 | +{ |
---|
| 7459 | + int err = 0; |
---|
| 7460 | + |
---|
| 7461 | + err = wldev_iovar_setint(net, "lqcm", lqcm_enable); |
---|
| 7462 | + if (err != BCME_OK) { |
---|
| 7463 | + WL_ERR(("failed to set lqcm enable %d, error = %d\n", lqcm_enable, err)); |
---|
| 7464 | + return -EIO; |
---|
| 7465 | + } |
---|
| 7466 | + return err; |
---|
| 7467 | +} |
---|
| 7468 | + |
---|
| 7469 | +static int |
---|
| 7470 | +wl_android_get_lqcm_report(struct net_device *dev, char *command, int total_len) |
---|
| 7471 | +{ |
---|
| 7472 | + int bytes_written, err = 0; |
---|
| 7473 | + uint32 lqcm_report = 0; |
---|
| 7474 | + uint32 lqcm_enable, tx_lqcm_idx, rx_lqcm_idx; |
---|
| 7475 | + |
---|
| 7476 | + err = wldev_iovar_getint(dev, "lqcm", &lqcm_report); |
---|
| 7477 | + if (err != BCME_OK) { |
---|
| 7478 | + WL_ERR(("failed to get lqcm report, error = %d\n", err)); |
---|
| 7479 | + return -EIO; |
---|
| 7480 | + } |
---|
| 7481 | + lqcm_enable = lqcm_report & LQCM_ENAB_MASK; |
---|
| 7482 | + tx_lqcm_idx = (lqcm_report & LQCM_TX_INDEX_MASK) >> LQCM_TX_INDEX_SHIFT; |
---|
| 7483 | + rx_lqcm_idx = (lqcm_report & LQCM_RX_INDEX_MASK) >> LQCM_RX_INDEX_SHIFT; |
---|
| 7484 | + |
---|
| 7485 | + WL_DBG(("lqcm report EN:%d, TX:%d, RX:%d\n", lqcm_enable, tx_lqcm_idx, rx_lqcm_idx)); |
---|
| 7486 | + |
---|
| 7487 | + bytes_written = snprintf(command, total_len, "%s %d", |
---|
| 7488 | + CMD_GET_LQCM_REPORT, lqcm_report); |
---|
| 7489 | + |
---|
| 7490 | + return bytes_written; |
---|
| 7491 | +} |
---|
| 7492 | +#endif /* SUPPORT_LQCM */ |
---|
| 7493 | + |
---|
| 7494 | +int |
---|
| 7495 | +wl_android_get_snr(struct net_device *dev, char *command, int total_len) |
---|
| 7496 | +{ |
---|
| 7497 | + int bytes_written, error = 0; |
---|
| 7498 | + s32 snr = 0; |
---|
| 7499 | + |
---|
| 7500 | + error = wldev_iovar_getint(dev, "snr", &snr); |
---|
| 7501 | + if (error) { |
---|
| 7502 | + DHD_ERROR(("wl_android_get_snr: Failed to get SNR %d, error = %d\n", |
---|
| 7503 | + snr, error)); |
---|
| 7504 | + return -EIO; |
---|
| 7505 | + } |
---|
| 7506 | + |
---|
| 7507 | + bytes_written = snprintf(command, total_len, "snr %d", snr); |
---|
| 7508 | + DHD_INFO(("wl_android_get_snr: command result is %s\n", command)); |
---|
| 7509 | + return bytes_written; |
---|
| 7510 | +} |
---|
| 7511 | + |
---|
| 7512 | +#ifdef SUPPORT_AP_HIGHER_BEACONRATE |
---|
| 7513 | +int |
---|
| 7514 | +wl_android_set_ap_beaconrate(struct net_device *dev, char *command) |
---|
| 7515 | +{ |
---|
| 7516 | + int rate = 0; |
---|
| 7517 | + char *pos, *token; |
---|
| 7518 | + char *ifname = NULL; |
---|
| 7519 | + int err = BCME_OK; |
---|
| 7520 | + |
---|
| 7521 | + /* |
---|
| 7522 | + * DRIVER SET_AP_BEACONRATE <rate> <ifname> |
---|
| 7523 | + */ |
---|
| 7524 | + pos = command; |
---|
| 7525 | + |
---|
| 7526 | + /* drop command */ |
---|
| 7527 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7528 | + |
---|
| 7529 | + /* Rate */ |
---|
| 7530 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7531 | + if (!token) |
---|
| 7532 | + return -EINVAL; |
---|
| 7533 | + rate = bcm_atoi(token); |
---|
| 7534 | + |
---|
| 7535 | + /* get the interface name */ |
---|
| 7536 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7537 | + if (!token) |
---|
| 7538 | + return -EINVAL; |
---|
| 7539 | + ifname = token; |
---|
| 7540 | + |
---|
| 7541 | + WL_DBG(("rate %d, ifacename %s\n", rate, ifname)); |
---|
| 7542 | + |
---|
| 7543 | + err = wl_set_ap_beacon_rate(dev, rate, ifname); |
---|
| 7544 | + if (unlikely(err)) { |
---|
| 7545 | + WL_ERR(("Failed to set ap beacon rate to %d, error = %d\n", rate, err)); |
---|
| 7546 | + } |
---|
| 7547 | + |
---|
| 7548 | + return err; |
---|
| 7549 | +} |
---|
| 7550 | + |
---|
| 7551 | +int wl_android_get_ap_basicrate(struct net_device *dev, char *command, int total_len) |
---|
| 7552 | +{ |
---|
| 7553 | + char *pos, *token; |
---|
| 7554 | + char *ifname = NULL; |
---|
| 7555 | + int bytes_written = 0; |
---|
| 7556 | + /* |
---|
| 7557 | + * DRIVER GET_AP_BASICRATE <ifname> |
---|
| 7558 | + */ |
---|
| 7559 | + pos = command; |
---|
| 7560 | + |
---|
| 7561 | + /* drop command */ |
---|
| 7562 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7563 | + |
---|
| 7564 | + /* get the interface name */ |
---|
| 7565 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7566 | + if (!token) |
---|
| 7567 | + return -EINVAL; |
---|
| 7568 | + ifname = token; |
---|
| 7569 | + |
---|
| 7570 | + WL_DBG(("ifacename %s\n", ifname)); |
---|
| 7571 | + |
---|
| 7572 | + bytes_written = wl_get_ap_basic_rate(dev, command, ifname, total_len); |
---|
| 7573 | + if (bytes_written < 1) { |
---|
| 7574 | + WL_ERR(("Failed to get ap basic rate, error = %d\n", bytes_written)); |
---|
| 7575 | + return -EPROTO; |
---|
| 7576 | + } |
---|
| 7577 | + |
---|
| 7578 | + return bytes_written; |
---|
| 7579 | +} |
---|
| 7580 | +#endif /* SUPPORT_AP_HIGHER_BEACONRATE */ |
---|
| 7581 | + |
---|
| 7582 | +#ifdef SUPPORT_AP_RADIO_PWRSAVE |
---|
| 7583 | +int |
---|
| 7584 | +wl_android_get_ap_rps(struct net_device *dev, char *command, int total_len) |
---|
| 7585 | +{ |
---|
| 7586 | + char *pos, *token; |
---|
| 7587 | + char *ifname = NULL; |
---|
| 7588 | + int bytes_written = 0; |
---|
| 7589 | + char name[IFNAMSIZ]; |
---|
| 7590 | + /* |
---|
| 7591 | + * DRIVER GET_AP_RPS <ifname> |
---|
| 7592 | + */ |
---|
| 7593 | + pos = command; |
---|
| 7594 | + |
---|
| 7595 | + /* drop command */ |
---|
| 7596 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7597 | + |
---|
| 7598 | + /* get the interface name */ |
---|
| 7599 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7600 | + if (!token) |
---|
| 7601 | + return -EINVAL; |
---|
| 7602 | + ifname = token; |
---|
| 7603 | + |
---|
| 7604 | + strlcpy(name, ifname, sizeof(name)); |
---|
| 7605 | + WL_DBG(("ifacename %s\n", name)); |
---|
| 7606 | + |
---|
| 7607 | + bytes_written = wl_get_ap_rps(dev, command, name, total_len); |
---|
| 7608 | + if (bytes_written < 1) { |
---|
| 7609 | + WL_ERR(("Failed to get rps, error = %d\n", bytes_written)); |
---|
| 7610 | + return -EPROTO; |
---|
| 7611 | + } |
---|
| 7612 | + |
---|
| 7613 | + return bytes_written; |
---|
| 7614 | + |
---|
| 7615 | +} |
---|
| 7616 | + |
---|
| 7617 | +int |
---|
| 7618 | +wl_android_set_ap_rps(struct net_device *dev, char *command, int total_len) |
---|
| 7619 | +{ |
---|
| 7620 | + int enable = 0; |
---|
| 7621 | + char *pos, *token; |
---|
| 7622 | + char *ifname = NULL; |
---|
| 7623 | + int err = BCME_OK; |
---|
| 7624 | + char name[IFNAMSIZ]; |
---|
| 7625 | + |
---|
| 7626 | + /* |
---|
| 7627 | + * DRIVER SET_AP_RPS <0/1> <ifname> |
---|
| 7628 | + */ |
---|
| 7629 | + pos = command; |
---|
| 7630 | + |
---|
| 7631 | + /* drop command */ |
---|
| 7632 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7633 | + |
---|
| 7634 | + /* Enable */ |
---|
| 7635 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7636 | + if (!token) |
---|
| 7637 | + return -EINVAL; |
---|
| 7638 | + enable = bcm_atoi(token); |
---|
| 7639 | + |
---|
| 7640 | + /* get the interface name */ |
---|
| 7641 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7642 | + if (!token) |
---|
| 7643 | + return -EINVAL; |
---|
| 7644 | + ifname = token; |
---|
| 7645 | + |
---|
| 7646 | + strlcpy(name, ifname, sizeof(name)); |
---|
| 7647 | + WL_DBG(("enable %d, ifacename %s\n", enable, name)); |
---|
| 7648 | + |
---|
| 7649 | + err = wl_set_ap_rps(dev, enable? TRUE: FALSE, name); |
---|
| 7650 | + if (unlikely(err)) { |
---|
| 7651 | + WL_ERR(("Failed to set rps, enable %d, error = %d\n", enable, err)); |
---|
| 7652 | + } |
---|
| 7653 | + |
---|
| 7654 | + return err; |
---|
| 7655 | +} |
---|
| 7656 | + |
---|
| 7657 | +int |
---|
| 7658 | +wl_android_set_ap_rps_params(struct net_device *dev, char *command, int total_len) |
---|
| 7659 | +{ |
---|
| 7660 | + ap_rps_info_t rps; |
---|
| 7661 | + char *pos, *token; |
---|
| 7662 | + char *ifname = NULL; |
---|
| 7663 | + int err = BCME_OK; |
---|
| 7664 | + char name[IFNAMSIZ]; |
---|
| 7665 | + |
---|
| 7666 | + bzero(&rps, sizeof(rps)); |
---|
| 7667 | + /* |
---|
| 7668 | + * DRIVER SET_AP_RPS_PARAMS <pps> <level> <quiettime> <assoccheck> <ifname> |
---|
| 7669 | + */ |
---|
| 7670 | + pos = command; |
---|
| 7671 | + |
---|
| 7672 | + /* drop command */ |
---|
| 7673 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7674 | + |
---|
| 7675 | + /* pps */ |
---|
| 7676 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7677 | + if (!token) |
---|
| 7678 | + return -EINVAL; |
---|
| 7679 | + rps.pps = bcm_atoi(token); |
---|
| 7680 | + |
---|
| 7681 | + /* level */ |
---|
| 7682 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7683 | + if (!token) |
---|
| 7684 | + return -EINVAL; |
---|
| 7685 | + rps.level = bcm_atoi(token); |
---|
| 7686 | + |
---|
| 7687 | + /* quiettime */ |
---|
| 7688 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7689 | + if (!token) |
---|
| 7690 | + return -EINVAL; |
---|
| 7691 | + rps.quiet_time = bcm_atoi(token); |
---|
| 7692 | + |
---|
| 7693 | + /* sta assoc check */ |
---|
| 7694 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7695 | + if (!token) |
---|
| 7696 | + return -EINVAL; |
---|
| 7697 | + rps.sta_assoc_check = bcm_atoi(token); |
---|
| 7698 | + |
---|
| 7699 | + /* get the interface name */ |
---|
| 7700 | + token = bcmstrtok(&pos, " ", NULL); |
---|
| 7701 | + if (!token) |
---|
| 7702 | + return -EINVAL; |
---|
| 7703 | + ifname = token; |
---|
| 7704 | + strlcpy(name, ifname, sizeof(name)); |
---|
| 7705 | + |
---|
| 7706 | + WL_DBG(("pps %d, level %d, quiettime %d, sta_assoc_check %d, " |
---|
| 7707 | + "ifacename %s\n", rps.pps, rps.level, rps.quiet_time, |
---|
| 7708 | + rps.sta_assoc_check, name)); |
---|
| 7709 | + |
---|
| 7710 | + err = wl_update_ap_rps_params(dev, &rps, name); |
---|
| 7711 | + if (unlikely(err)) { |
---|
| 7712 | + WL_ERR(("Failed to update rps, pps %d, level %d, quiettime %d, " |
---|
| 7713 | + "sta_assoc_check %d, err = %d\n", rps.pps, rps.level, rps.quiet_time, |
---|
| 7714 | + rps.sta_assoc_check, err)); |
---|
| 7715 | + } |
---|
| 7716 | + |
---|
| 7717 | + return err; |
---|
| 7718 | +} |
---|
| 7719 | +#endif /* SUPPORT_AP_RADIO_PWRSAVE */ |
---|
| 7720 | + |
---|
| 7721 | +#if defined(DHD_HANG_SEND_UP_TEST) |
---|
| 7722 | +void |
---|
| 7723 | +wl_android_make_hang_with_reason(struct net_device *dev, const char *string_num) |
---|
| 7724 | +{ |
---|
| 7725 | + dhd_make_hang_with_reason(dev, string_num); |
---|
| 7726 | +} |
---|
| 7727 | +#endif /* DHD_HANG_SEND_UP_TEST */ |
---|
| 7728 | + |
---|
| 7729 | +#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS |
---|
| 7730 | +static void |
---|
| 7731 | +wl_android_check_priv_cmd_errors(struct net_device *dev) |
---|
| 7732 | +{ |
---|
| 7733 | + dhd_pub_t *dhdp; |
---|
| 7734 | + int memdump_mode; |
---|
| 7735 | + |
---|
| 7736 | + if (!dev) { |
---|
| 7737 | + WL_ERR(("dev is NULL\n")); |
---|
| 7738 | + return; |
---|
| 7739 | + } |
---|
| 7740 | + |
---|
| 7741 | + dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 7742 | + if (!dhdp) { |
---|
| 7743 | + WL_ERR(("dhdp is NULL\n")); |
---|
| 7744 | + return; |
---|
| 7745 | + } |
---|
| 7746 | + |
---|
| 7747 | +#ifdef DHD_FW_COREDUMP |
---|
| 7748 | + memdump_mode = dhdp->memdump_enabled; |
---|
| 7749 | +#else |
---|
| 7750 | + /* Default enable if DHD doesn't support SOCRAM dump */ |
---|
| 7751 | + memdump_mode = 1; |
---|
| 7752 | +#endif /* DHD_FW_COREDUMP */ |
---|
| 7753 | + |
---|
| 7754 | + if (report_hang_privcmd_err) { |
---|
| 7755 | + priv_cmd_errors++; |
---|
| 7756 | + } else { |
---|
| 7757 | + priv_cmd_errors = 0; |
---|
| 7758 | + } |
---|
| 7759 | + |
---|
| 7760 | + /* Trigger HANG event only if memdump mode is enabled |
---|
| 7761 | + * due to customer's request |
---|
| 7762 | + */ |
---|
| 7763 | + if (memdump_mode == DUMP_MEMFILE_BUGON && |
---|
| 7764 | + (priv_cmd_errors > NUMBER_SEQUENTIAL_PRIVCMD_ERRORS)) { |
---|
| 7765 | + WL_ERR(("Send HANG event due to sequential private cmd errors\n")); |
---|
| 7766 | + priv_cmd_errors = 0; |
---|
| 7767 | +#ifdef DHD_FW_COREDUMP |
---|
| 7768 | + /* Take a SOCRAM dump */ |
---|
| 7769 | + dhdp->memdump_type = DUMP_TYPE_SEQUENTIAL_PRIVCMD_ERROR; |
---|
| 7770 | + dhd_common_socram_dump(dhdp); |
---|
| 7771 | +#endif /* DHD_FW_COREDUMP */ |
---|
| 7772 | + /* Send the HANG event to upper layer */ |
---|
| 7773 | + dhdp->hang_reason = HANG_REASON_SEQUENTIAL_PRIVCMD_ERROR; |
---|
| 7774 | + dhd_os_check_hang(dhdp, 0, -EREMOTEIO); |
---|
| 7775 | + } |
---|
| 7776 | +} |
---|
| 7777 | +#endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */ |
---|
| 7778 | + |
---|
| 7779 | +#ifdef DHD_PKT_LOGGING |
---|
| 7780 | +static int |
---|
| 7781 | +wl_android_pktlog_filter_enable(struct net_device *dev, char *command, int total_len) |
---|
| 7782 | +{ |
---|
| 7783 | + int bytes_written = 0; |
---|
| 7784 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 7785 | + dhd_pktlog_filter_t *filter; |
---|
| 7786 | + int err = BCME_OK; |
---|
| 7787 | + |
---|
| 7788 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 7789 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 7790 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 7791 | + return -EINVAL; |
---|
| 7792 | + } |
---|
| 7793 | + |
---|
| 7794 | + filter = dhdp->pktlog->pktlog_filter; |
---|
| 7795 | + |
---|
| 7796 | + err = dhd_pktlog_filter_enable(filter, PKTLOG_TXPKT_CASE, TRUE); |
---|
| 7797 | + err = dhd_pktlog_filter_enable(filter, PKTLOG_TXSTATUS_CASE, TRUE); |
---|
| 7798 | + err = dhd_pktlog_filter_enable(filter, PKTLOG_RXPKT_CASE, TRUE); |
---|
| 7799 | + |
---|
| 7800 | + if (err == BCME_OK) { |
---|
| 7801 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 7802 | + DHD_ERROR(("%s: pktlog filter enable success\n", __FUNCTION__)); |
---|
| 7803 | + } else { |
---|
| 7804 | + DHD_ERROR(("%s: pktlog filter enable fail\n", __FUNCTION__)); |
---|
| 7805 | + return BCME_ERROR; |
---|
| 7806 | + } |
---|
| 7807 | + |
---|
| 7808 | + return bytes_written; |
---|
| 7809 | +} |
---|
| 7810 | + |
---|
| 7811 | +static int |
---|
| 7812 | +wl_android_pktlog_filter_disable(struct net_device *dev, char *command, int total_len) |
---|
| 7813 | +{ |
---|
| 7814 | + int bytes_written = 0; |
---|
| 7815 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 7816 | + dhd_pktlog_filter_t *filter; |
---|
| 7817 | + int err = BCME_OK; |
---|
| 7818 | + |
---|
| 7819 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 7820 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 7821 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 7822 | + return -EINVAL; |
---|
| 7823 | + } |
---|
| 7824 | + |
---|
| 7825 | + filter = dhdp->pktlog->pktlog_filter; |
---|
| 7826 | + |
---|
| 7827 | + err = dhd_pktlog_filter_enable(filter, PKTLOG_TXPKT_CASE, FALSE); |
---|
| 7828 | + err = dhd_pktlog_filter_enable(filter, PKTLOG_TXSTATUS_CASE, FALSE); |
---|
| 7829 | + err = dhd_pktlog_filter_enable(filter, PKTLOG_RXPKT_CASE, FALSE); |
---|
| 7830 | + |
---|
| 7831 | + if (err == BCME_OK) { |
---|
| 7832 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 7833 | + DHD_ERROR(("%s: pktlog filter disable success\n", __FUNCTION__)); |
---|
| 7834 | + } else { |
---|
| 7835 | + DHD_ERROR(("%s: pktlog filter disable fail\n", __FUNCTION__)); |
---|
| 7836 | + return BCME_ERROR; |
---|
| 7837 | + } |
---|
| 7838 | + |
---|
| 7839 | + return bytes_written; |
---|
| 7840 | +} |
---|
| 7841 | + |
---|
| 7842 | +static int |
---|
| 7843 | +wl_android_pktlog_filter_pattern_enable(struct net_device *dev, char *command, int total_len) |
---|
| 7844 | +{ |
---|
| 7845 | + int bytes_written = 0; |
---|
| 7846 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 7847 | + dhd_pktlog_filter_t *filter; |
---|
| 7848 | + int err = BCME_OK; |
---|
| 7849 | + |
---|
| 7850 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 7851 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 7852 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 7853 | + return -EINVAL; |
---|
| 7854 | + } |
---|
| 7855 | + |
---|
| 7856 | + filter = dhdp->pktlog->pktlog_filter; |
---|
| 7857 | + |
---|
| 7858 | + if (strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE) + 1 > total_len) { |
---|
| 7859 | + return BCME_ERROR; |
---|
| 7860 | + } |
---|
| 7861 | + |
---|
| 7862 | + err = dhd_pktlog_filter_pattern_enable(filter, |
---|
| 7863 | + command + strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE) + 1, TRUE); |
---|
| 7864 | + |
---|
| 7865 | + if (err == BCME_OK) { |
---|
| 7866 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 7867 | + DHD_ERROR(("%s: pktlog filter pattern enable success\n", __FUNCTION__)); |
---|
| 7868 | + } else { |
---|
| 7869 | + DHD_ERROR(("%s: pktlog filter pattern enable fail\n", __FUNCTION__)); |
---|
| 7870 | + return BCME_ERROR; |
---|
| 7871 | + } |
---|
| 7872 | + |
---|
| 7873 | + return bytes_written; |
---|
| 7874 | +} |
---|
| 7875 | + |
---|
| 7876 | +static int |
---|
| 7877 | +wl_android_pktlog_filter_pattern_disable(struct net_device *dev, char *command, int total_len) |
---|
| 7878 | +{ |
---|
| 7879 | + int bytes_written = 0; |
---|
| 7880 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 7881 | + dhd_pktlog_filter_t *filter; |
---|
| 7882 | + int err = BCME_OK; |
---|
| 7883 | + |
---|
| 7884 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 7885 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 7886 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 7887 | + return -EINVAL; |
---|
| 7888 | + } |
---|
| 7889 | + |
---|
| 7890 | + filter = dhdp->pktlog->pktlog_filter; |
---|
| 7891 | + |
---|
| 7892 | + if (strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE) + 1 > total_len) { |
---|
| 7893 | + return BCME_ERROR; |
---|
| 7894 | + } |
---|
| 7895 | + |
---|
| 7896 | + err = dhd_pktlog_filter_pattern_enable(filter, |
---|
| 7897 | + command + strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE) + 1, FALSE); |
---|
| 7898 | + |
---|
| 7899 | + if (err == BCME_OK) { |
---|
| 7900 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 7901 | + DHD_ERROR(("%s: pktlog filter pattern disable success\n", __FUNCTION__)); |
---|
| 7902 | + } else { |
---|
| 7903 | + DHD_ERROR(("%s: pktlog filter pattern disable fail\n", __FUNCTION__)); |
---|
| 7904 | + return BCME_ERROR; |
---|
| 7905 | + } |
---|
| 7906 | + |
---|
| 7907 | + return bytes_written; |
---|
| 7908 | +} |
---|
| 7909 | + |
---|
| 7910 | +static int |
---|
| 7911 | +wl_android_pktlog_filter_add(struct net_device *dev, char *command, int total_len) |
---|
| 7912 | +{ |
---|
| 7913 | + int bytes_written = 0; |
---|
| 7914 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 7915 | + dhd_pktlog_filter_t *filter; |
---|
| 7916 | + int err = BCME_OK; |
---|
| 7917 | + |
---|
| 7918 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 7919 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 7920 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 7921 | + return -EINVAL; |
---|
| 7922 | + } |
---|
| 7923 | + |
---|
| 7924 | + filter = dhdp->pktlog->pktlog_filter; |
---|
| 7925 | + |
---|
| 7926 | + if (strlen(CMD_PKTLOG_FILTER_ADD) + 1 > total_len) { |
---|
| 7927 | + return BCME_ERROR; |
---|
| 7928 | + } |
---|
| 7929 | + |
---|
| 7930 | + err = dhd_pktlog_filter_add(filter, command + strlen(CMD_PKTLOG_FILTER_ADD) + 1); |
---|
| 7931 | + |
---|
| 7932 | + if (err == BCME_OK) { |
---|
| 7933 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 7934 | + DHD_ERROR(("%s: pktlog filter add success\n", __FUNCTION__)); |
---|
| 7935 | + } else { |
---|
| 7936 | + DHD_ERROR(("%s: pktlog filter add fail\n", __FUNCTION__)); |
---|
| 7937 | + return BCME_ERROR; |
---|
| 7938 | + } |
---|
| 7939 | + |
---|
| 7940 | + return bytes_written; |
---|
| 7941 | +} |
---|
| 7942 | + |
---|
| 7943 | +static int |
---|
| 7944 | +wl_android_pktlog_filter_del(struct net_device *dev, char *command, int total_len) |
---|
| 7945 | +{ |
---|
| 7946 | + int bytes_written = 0; |
---|
| 7947 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 7948 | + dhd_pktlog_filter_t *filter; |
---|
| 7949 | + int err = BCME_OK; |
---|
| 7950 | + |
---|
| 7951 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 7952 | + DHD_ERROR(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 7953 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 7954 | + return -EINVAL; |
---|
| 7955 | + } |
---|
| 7956 | + |
---|
| 7957 | + filter = dhdp->pktlog->pktlog_filter; |
---|
| 7958 | + |
---|
| 7959 | + if (strlen(CMD_PKTLOG_FILTER_DEL) + 1 > total_len) { |
---|
| 7960 | + DHD_PKT_LOG(("%s(): wrong cmd length %d found\n", |
---|
| 7961 | + __FUNCTION__, (int)strlen(CMD_PKTLOG_FILTER_DEL))); |
---|
| 7962 | + return BCME_ERROR; |
---|
| 7963 | + } |
---|
| 7964 | + |
---|
| 7965 | + err = dhd_pktlog_filter_del(filter, command + strlen(CMD_PKTLOG_FILTER_DEL) + 1); |
---|
| 7966 | + if (err == BCME_OK) { |
---|
| 7967 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 7968 | + DHD_ERROR(("%s: pktlog filter del success\n", __FUNCTION__)); |
---|
| 7969 | + } else { |
---|
| 7970 | + DHD_ERROR(("%s: pktlog filter del fail\n", __FUNCTION__)); |
---|
| 7971 | + return BCME_ERROR; |
---|
| 7972 | + } |
---|
| 7973 | + |
---|
| 7974 | + return bytes_written; |
---|
| 7975 | +} |
---|
| 7976 | + |
---|
| 7977 | +static int |
---|
| 7978 | +wl_android_pktlog_filter_info(struct net_device *dev, char *command, int total_len) |
---|
| 7979 | +{ |
---|
| 7980 | + int bytes_written = 0; |
---|
| 7981 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 7982 | + dhd_pktlog_filter_t *filter; |
---|
| 7983 | + int err = BCME_OK; |
---|
| 7984 | + |
---|
| 7985 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 7986 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 7987 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 7988 | + return -EINVAL; |
---|
| 7989 | + } |
---|
| 7990 | + |
---|
| 7991 | + filter = dhdp->pktlog->pktlog_filter; |
---|
| 7992 | + |
---|
| 7993 | + err = dhd_pktlog_filter_info(filter); |
---|
| 7994 | + |
---|
| 7995 | + if (err == BCME_OK) { |
---|
| 7996 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 7997 | + DHD_ERROR(("%s: pktlog filter info success\n", __FUNCTION__)); |
---|
| 7998 | + } else { |
---|
| 7999 | + DHD_ERROR(("%s: pktlog filter info fail\n", __FUNCTION__)); |
---|
| 8000 | + return BCME_ERROR; |
---|
| 8001 | + } |
---|
| 8002 | + |
---|
| 8003 | + return bytes_written; |
---|
| 8004 | +} |
---|
| 8005 | + |
---|
| 8006 | +static int |
---|
| 8007 | +wl_android_pktlog_start(struct net_device *dev, char *command, int total_len) |
---|
| 8008 | +{ |
---|
| 8009 | + int bytes_written = 0; |
---|
| 8010 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 8011 | + |
---|
| 8012 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 8013 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 8014 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 8015 | + return -EINVAL; |
---|
| 8016 | + } |
---|
| 8017 | + |
---|
| 8018 | + if (!dhdp->pktlog->pktlog_ring) { |
---|
| 8019 | + DHD_PKT_LOG(("%s(): pktlog_ring=%p\n", |
---|
| 8020 | + __FUNCTION__, dhdp->pktlog->pktlog_ring)); |
---|
| 8021 | + return -EINVAL; |
---|
| 8022 | + } |
---|
| 8023 | + |
---|
| 8024 | + atomic_set(&dhdp->pktlog->pktlog_ring->start, TRUE); |
---|
| 8025 | + |
---|
| 8026 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 8027 | + |
---|
| 8028 | + DHD_ERROR(("%s: pktlog start success\n", __FUNCTION__)); |
---|
| 8029 | + |
---|
| 8030 | + return bytes_written; |
---|
| 8031 | +} |
---|
| 8032 | + |
---|
| 8033 | +static int |
---|
| 8034 | +wl_android_pktlog_stop(struct net_device *dev, char *command, int total_len) |
---|
| 8035 | +{ |
---|
| 8036 | + int bytes_written = 0; |
---|
| 8037 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 8038 | + |
---|
| 8039 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 8040 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 8041 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 8042 | + return -EINVAL; |
---|
| 8043 | + } |
---|
| 8044 | + |
---|
| 8045 | + if (!dhdp->pktlog->pktlog_ring) { |
---|
| 8046 | + DHD_PKT_LOG(("%s(): _pktlog_ring=%p\n", |
---|
| 8047 | + __FUNCTION__, dhdp->pktlog->pktlog_ring)); |
---|
| 8048 | + return -EINVAL; |
---|
| 8049 | + } |
---|
| 8050 | + |
---|
| 8051 | + atomic_set(&dhdp->pktlog->pktlog_ring->start, FALSE); |
---|
| 8052 | + |
---|
| 8053 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 8054 | + |
---|
| 8055 | + DHD_ERROR(("%s: pktlog stop success\n", __FUNCTION__)); |
---|
| 8056 | + |
---|
| 8057 | + return bytes_written; |
---|
| 8058 | +} |
---|
| 8059 | + |
---|
| 8060 | +static int |
---|
| 8061 | +wl_android_pktlog_filter_exist(struct net_device *dev, char *command, int total_len) |
---|
| 8062 | +{ |
---|
| 8063 | + int bytes_written = 0; |
---|
| 8064 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 8065 | + dhd_pktlog_filter_t *filter; |
---|
| 8066 | + uint32 id; |
---|
| 8067 | + bool exist = FALSE; |
---|
| 8068 | + |
---|
| 8069 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 8070 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 8071 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 8072 | + return -EINVAL; |
---|
| 8073 | + } |
---|
| 8074 | + |
---|
| 8075 | + filter = dhdp->pktlog->pktlog_filter; |
---|
| 8076 | + |
---|
| 8077 | + if (strlen(CMD_PKTLOG_FILTER_EXIST) + 1 > total_len) { |
---|
| 8078 | + return BCME_ERROR; |
---|
| 8079 | + } |
---|
| 8080 | + |
---|
| 8081 | + exist = dhd_pktlog_filter_existed(filter, command + strlen(CMD_PKTLOG_FILTER_EXIST) + 1, |
---|
| 8082 | + &id); |
---|
| 8083 | + |
---|
| 8084 | + if (exist) { |
---|
| 8085 | + bytes_written = snprintf(command, total_len, "TRUE"); |
---|
| 8086 | + DHD_ERROR(("%s: pktlog filter pattern id: %d is existed\n", __FUNCTION__, id)); |
---|
| 8087 | + } else { |
---|
| 8088 | + bytes_written = snprintf(command, total_len, "FALSE"); |
---|
| 8089 | + DHD_ERROR(("%s: pktlog filter pattern id: %d is not existed\n", __FUNCTION__, id)); |
---|
| 8090 | + } |
---|
| 8091 | + |
---|
| 8092 | + return bytes_written; |
---|
| 8093 | +} |
---|
| 8094 | + |
---|
| 8095 | +static int |
---|
| 8096 | +wl_android_pktlog_minmize_enable(struct net_device *dev, char *command, int total_len) |
---|
| 8097 | +{ |
---|
| 8098 | + int bytes_written = 0; |
---|
| 8099 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 8100 | + |
---|
| 8101 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 8102 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 8103 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 8104 | + return -EINVAL; |
---|
| 8105 | + } |
---|
| 8106 | + |
---|
| 8107 | + if (!dhdp->pktlog->pktlog_ring) { |
---|
| 8108 | + DHD_PKT_LOG(("%s(): pktlog_ring=%p\n", |
---|
| 8109 | + __FUNCTION__, dhdp->pktlog->pktlog_ring)); |
---|
| 8110 | + return -EINVAL; |
---|
| 8111 | + } |
---|
| 8112 | + |
---|
| 8113 | + dhdp->pktlog->pktlog_ring->pktlog_minmize = TRUE; |
---|
| 8114 | + |
---|
| 8115 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 8116 | + |
---|
| 8117 | + DHD_ERROR(("%s: pktlog pktlog_minmize enable\n", __FUNCTION__)); |
---|
| 8118 | + |
---|
| 8119 | + return bytes_written; |
---|
| 8120 | +} |
---|
| 8121 | + |
---|
| 8122 | +static int |
---|
| 8123 | +wl_android_pktlog_minmize_disable(struct net_device *dev, char *command, int total_len) |
---|
| 8124 | +{ |
---|
| 8125 | + int bytes_written = 0; |
---|
| 8126 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 8127 | + |
---|
| 8128 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 8129 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 8130 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 8131 | + return -EINVAL; |
---|
| 8132 | + } |
---|
| 8133 | + |
---|
| 8134 | + if (!dhdp->pktlog->pktlog_ring) { |
---|
| 8135 | + DHD_PKT_LOG(("%s(): pktlog_ring=%p\n", |
---|
| 8136 | + __FUNCTION__, dhdp->pktlog->pktlog_ring)); |
---|
| 8137 | + return -EINVAL; |
---|
| 8138 | + } |
---|
| 8139 | + |
---|
| 8140 | + dhdp->pktlog->pktlog_ring->pktlog_minmize = FALSE; |
---|
| 8141 | + |
---|
| 8142 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 8143 | + |
---|
| 8144 | + DHD_ERROR(("%s: pktlog pktlog_minmize disable\n", __FUNCTION__)); |
---|
| 8145 | + |
---|
| 8146 | + return bytes_written; |
---|
| 8147 | +} |
---|
| 8148 | + |
---|
| 8149 | +static int |
---|
| 8150 | +wl_android_pktlog_change_size(struct net_device *dev, char *command, int total_len) |
---|
| 8151 | +{ |
---|
| 8152 | + int bytes_written = 0; |
---|
| 8153 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 8154 | + int err = BCME_OK; |
---|
| 8155 | + int size; |
---|
| 8156 | + |
---|
| 8157 | + if (!dhdp || !dhdp->pktlog) { |
---|
| 8158 | + DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n", |
---|
| 8159 | + __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL))); |
---|
| 8160 | + return -EINVAL; |
---|
| 8161 | + } |
---|
| 8162 | + |
---|
| 8163 | + if (strlen(CMD_PKTLOG_CHANGE_SIZE) + 1 > total_len) { |
---|
| 8164 | + return BCME_ERROR; |
---|
| 8165 | + } |
---|
| 8166 | + |
---|
| 8167 | + size = bcm_strtoul(command + strlen(CMD_PKTLOG_CHANGE_SIZE) + 1, NULL, 0); |
---|
| 8168 | + |
---|
| 8169 | + dhdp->pktlog->pktlog_ring = |
---|
| 8170 | + dhd_pktlog_ring_change_size(dhdp->pktlog->pktlog_ring, size); |
---|
| 8171 | + if (!dhdp->pktlog->pktlog_ring) { |
---|
| 8172 | + err = BCME_ERROR; |
---|
| 8173 | + } |
---|
| 8174 | + |
---|
| 8175 | + if (err == BCME_OK) { |
---|
| 8176 | + bytes_written = snprintf(command, total_len, "OK"); |
---|
| 8177 | + DHD_ERROR(("%s: pktlog change size success\n", __FUNCTION__)); |
---|
| 8178 | + } else { |
---|
| 8179 | + DHD_ERROR(("%s: pktlog change size fail\n", __FUNCTION__)); |
---|
| 8180 | + return BCME_ERROR; |
---|
| 8181 | + } |
---|
| 8182 | + |
---|
| 8183 | + return bytes_written; |
---|
| 8184 | +} |
---|
| 8185 | +#endif /* DHD_PKT_LOGGING */ |
---|
| 8186 | + |
---|
| 8187 | +#ifdef DHD_EVENT_LOG_FILTER |
---|
| 8188 | +uint32 dhd_event_log_filter_serialize(dhd_pub_t *dhdp, char *buf, uint32 tot_len, int type); |
---|
| 8189 | + |
---|
| 8190 | +#ifdef DHD_EWPR_VER2 |
---|
| 8191 | +uint32 dhd_event_log_filter_serialize_bit(dhd_pub_t *dhdp, char *buf, uint32 tot_len, |
---|
| 8192 | + int index1, int index2, int index3); |
---|
| 8193 | +#endif // endif |
---|
| 8194 | + |
---|
| 8195 | +static int |
---|
| 8196 | +wl_android_ewp_filter(struct net_device *dev, char *command, uint32 tot_len) |
---|
| 8197 | +{ |
---|
| 8198 | + uint32 bytes_written = 0; |
---|
| 8199 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 8200 | +#ifdef DHD_EWPR_VER2 |
---|
| 8201 | + int index1 = 0, index2 = 0, index3 = 0; |
---|
| 8202 | + unsigned char *index_str = (unsigned char *)(command + |
---|
| 8203 | + strlen(CMD_EWP_FILTER) + 1); |
---|
| 8204 | +#else |
---|
| 8205 | + int type = 0; |
---|
| 8206 | +#endif // endif |
---|
| 8207 | + |
---|
| 8208 | + if (!dhdp || !command) { |
---|
| 8209 | + DHD_ERROR(("%s(): dhdp=%p \n", __FUNCTION__, dhdp)); |
---|
| 8210 | + return -EINVAL; |
---|
| 8211 | + } |
---|
| 8212 | + |
---|
| 8213 | +#ifdef DHD_EWPR_VER2 |
---|
| 8214 | + if (strlen(command) > strlen(CMD_EWP_FILTER) + 1) { |
---|
| 8215 | + sscanf(index_str, "%10d %10d %10d", &index1, &index2, &index3); |
---|
| 8216 | + DHD_TRACE(("%s(): get index request: %d %d %d\n", __FUNCTION__, |
---|
| 8217 | + index1, index2, index3)); |
---|
| 8218 | + } |
---|
| 8219 | + bytes_written += dhd_event_log_filter_serialize_bit(dhdp, |
---|
| 8220 | + &command[bytes_written], tot_len - bytes_written, index1, index2, index3); |
---|
| 8221 | +#else |
---|
| 8222 | + /* NEED TO GET TYPE if EXIST */ |
---|
| 8223 | + type = 0; |
---|
| 8224 | + |
---|
| 8225 | + bytes_written += dhd_event_log_filter_serialize(dhdp, |
---|
| 8226 | + &command[bytes_written], tot_len - bytes_written, type); |
---|
| 8227 | +#endif // endif |
---|
| 8228 | + |
---|
| 8229 | + return (int)bytes_written; |
---|
| 8230 | +} |
---|
| 8231 | +#endif /* DHD_EVENT_LOG_FILTER */ |
---|
| 8232 | + |
---|
| 8233 | +int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr) |
---|
2268 | 8234 | { |
---|
2269 | 8235 | #define PRIVATE_COMMAND_MAX_LEN 8192 |
---|
| 8236 | +#define PRIVATE_COMMAND_DEF_LEN 4096 |
---|
2270 | 8237 | int ret = 0; |
---|
2271 | 8238 | char *command = NULL; |
---|
2272 | 8239 | int bytes_written = 0; |
---|
2273 | 8240 | android_wifi_priv_cmd priv_cmd; |
---|
| 8241 | + int buf_size = 0; |
---|
| 8242 | + struct bcm_cfg80211 *cfg = wl_get_cfg(net); |
---|
2274 | 8243 | |
---|
2275 | 8244 | net_os_wake_lock(net); |
---|
| 8245 | + |
---|
| 8246 | + if (!capable(CAP_NET_ADMIN)) { |
---|
| 8247 | + ret = -EPERM; |
---|
| 8248 | + goto exit; |
---|
| 8249 | + } |
---|
2276 | 8250 | |
---|
2277 | 8251 | if (!ifr->ifr_data) { |
---|
2278 | 8252 | ret = -EINVAL; |
---|
2279 | 8253 | goto exit; |
---|
2280 | 8254 | } |
---|
2281 | 8255 | |
---|
2282 | | -#ifdef CONFIG_COMPAT |
---|
2283 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)) |
---|
2284 | | - if (in_compat_syscall()) { |
---|
2285 | | -#else |
---|
2286 | | - if (is_compat_task()) { |
---|
2287 | | -#endif |
---|
2288 | | - compat_android_wifi_priv_cmd compat_priv_cmd; |
---|
2289 | | - if (copy_from_user(&compat_priv_cmd, ifr->ifr_data, |
---|
2290 | | - sizeof(compat_android_wifi_priv_cmd))) { |
---|
2291 | | - ret = -EFAULT; |
---|
2292 | | - goto exit; |
---|
2293 | | - |
---|
2294 | | - } |
---|
2295 | | - priv_cmd.buf = compat_ptr(compat_priv_cmd.buf); |
---|
2296 | | - priv_cmd.used_len = compat_priv_cmd.used_len; |
---|
2297 | | - priv_cmd.total_len = compat_priv_cmd.total_len; |
---|
2298 | | - } else |
---|
2299 | | -#endif /* CONFIG_COMPAT */ |
---|
2300 | 8256 | { |
---|
2301 | 8257 | if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { |
---|
2302 | 8258 | ret = -EFAULT; |
---|
.. | .. |
---|
2304 | 8260 | } |
---|
2305 | 8261 | } |
---|
2306 | 8262 | if ((priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN) || (priv_cmd.total_len < 0)) { |
---|
2307 | | - DHD_ERROR(("%s: too long priavte command\n", __FUNCTION__)); |
---|
| 8263 | + DHD_ERROR(("wl_android_priv_cmd: buf length invalid:%d\n", |
---|
| 8264 | + priv_cmd.total_len)); |
---|
2308 | 8265 | ret = -EINVAL; |
---|
2309 | 8266 | goto exit; |
---|
2310 | 8267 | } |
---|
2311 | | - command = kmalloc((priv_cmd.total_len + 1), GFP_KERNEL); |
---|
2312 | | - if (!command) |
---|
2313 | | - { |
---|
2314 | | - DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__)); |
---|
| 8268 | + |
---|
| 8269 | + buf_size = max(priv_cmd.total_len, PRIVATE_COMMAND_DEF_LEN); |
---|
| 8270 | + command = (char *)MALLOC(cfg->osh, (buf_size + 1)); |
---|
| 8271 | + if (!command) { |
---|
| 8272 | + DHD_ERROR(("wl_android_priv_cmd: failed to allocate memory\n")); |
---|
2315 | 8273 | ret = -ENOMEM; |
---|
2316 | 8274 | goto exit; |
---|
2317 | 8275 | } |
---|
.. | .. |
---|
2321 | 8279 | } |
---|
2322 | 8280 | command[priv_cmd.total_len] = '\0'; |
---|
2323 | 8281 | |
---|
2324 | | - DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name)); |
---|
| 8282 | + DHD_ERROR(("wl_android_priv_cmd: Android private cmd \"%s\" on %s\n", |
---|
| 8283 | + command, ifr->ifr_name)); |
---|
2325 | 8284 | |
---|
2326 | 8285 | bytes_written = wl_handle_private_cmd(net, command, priv_cmd.total_len); |
---|
2327 | 8286 | if (bytes_written >= 0) { |
---|
.. | .. |
---|
2329 | 8288 | command[0] = '\0'; |
---|
2330 | 8289 | } |
---|
2331 | 8290 | if (bytes_written >= priv_cmd.total_len) { |
---|
2332 | | - DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written)); |
---|
2333 | | - bytes_written = priv_cmd.total_len; |
---|
2334 | | - } else { |
---|
2335 | | - bytes_written++; |
---|
| 8291 | + DHD_ERROR(("wl_android_priv_cmd: err. bytes_written:%d >= total_len:%d," |
---|
| 8292 | + " buf_size:%d \n", bytes_written, priv_cmd.total_len, buf_size)); |
---|
| 8293 | + ret = BCME_BUFTOOSHORT; |
---|
| 8294 | + goto exit; |
---|
2336 | 8295 | } |
---|
| 8296 | + bytes_written++; |
---|
2337 | 8297 | priv_cmd.used_len = bytes_written; |
---|
2338 | 8298 | if (copy_to_user(priv_cmd.buf, command, bytes_written)) { |
---|
2339 | | - DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__)); |
---|
| 8299 | + DHD_ERROR(("wl_android_priv_cmd: failed to copy data to user buffer\n")); |
---|
2340 | 8300 | ret = -EFAULT; |
---|
2341 | 8301 | } |
---|
2342 | 8302 | } |
---|
.. | .. |
---|
2346 | 8306 | } |
---|
2347 | 8307 | |
---|
2348 | 8308 | exit: |
---|
2349 | | - net_os_wake_unlock(net); |
---|
2350 | | - if (command) { |
---|
2351 | | - kfree(command); |
---|
| 8309 | +#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS |
---|
| 8310 | + if (ret) { |
---|
| 8311 | + /* Avoid incrementing priv_cmd_errors in case of unsupported feature */ |
---|
| 8312 | + if (ret != BCME_UNSUPPORTED) { |
---|
| 8313 | + wl_android_check_priv_cmd_errors(net); |
---|
| 8314 | + } |
---|
| 8315 | + } else { |
---|
| 8316 | + priv_cmd_errors = 0; |
---|
2352 | 8317 | } |
---|
2353 | | - |
---|
| 8318 | +#endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */ |
---|
| 8319 | + net_os_wake_unlock(net); |
---|
| 8320 | + MFREE(cfg->osh, command, (buf_size + 1)); |
---|
2354 | 8321 | return ret; |
---|
2355 | 8322 | } |
---|
| 8323 | +#ifdef WLADPS_PRIVATE_CMD |
---|
| 8324 | +static int |
---|
| 8325 | +wl_android_set_adps_mode(struct net_device *dev, const char* string_num) |
---|
| 8326 | +{ |
---|
| 8327 | + int err = 0, adps_mode; |
---|
| 8328 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev); |
---|
| 8329 | +#ifdef DHD_PM_CONTROL_FROM_FILE |
---|
| 8330 | + if (g_pm_control) { |
---|
| 8331 | + return -EPERM; |
---|
| 8332 | + } |
---|
| 8333 | +#endif /* DHD_PM_CONTROL_FROM_FILE */ |
---|
| 8334 | + |
---|
| 8335 | + adps_mode = bcm_atoi(string_num); |
---|
| 8336 | + WL_ERR(("%s: SET_ADPS %d\n", __FUNCTION__, adps_mode)); |
---|
| 8337 | + |
---|
| 8338 | + if ((adps_mode < 0) && (1 < adps_mode)) { |
---|
| 8339 | + WL_ERR(("wl_android_set_adps_mode: Invalid value %d.\n", adps_mode)); |
---|
| 8340 | + return -EINVAL; |
---|
| 8341 | + } |
---|
| 8342 | + |
---|
| 8343 | + err = dhd_enable_adps(dhdp, adps_mode); |
---|
| 8344 | + if (err != BCME_OK) { |
---|
| 8345 | + WL_ERR(("failed to set adps mode %d, error = %d\n", adps_mode, err)); |
---|
| 8346 | + return -EIO; |
---|
| 8347 | + } |
---|
| 8348 | + return err; |
---|
| 8349 | +} |
---|
| 8350 | +static int |
---|
| 8351 | +wl_android_get_adps_mode( |
---|
| 8352 | + struct net_device *dev, char *command, int total_len) |
---|
| 8353 | +{ |
---|
| 8354 | + int bytes_written, err = 0; |
---|
| 8355 | + uint len; |
---|
| 8356 | + char buf[WLC_IOCTL_SMLEN]; |
---|
| 8357 | + |
---|
| 8358 | + bcm_iov_buf_t iov_buf; |
---|
| 8359 | + bcm_iov_buf_t *ptr = NULL; |
---|
| 8360 | + wl_adps_params_v1_t *data = NULL; |
---|
| 8361 | + |
---|
| 8362 | + uint8 *pdata = NULL; |
---|
| 8363 | + uint8 band, mode = 0; |
---|
| 8364 | + |
---|
| 8365 | + bzero(&iov_buf, sizeof(iov_buf)); |
---|
| 8366 | + |
---|
| 8367 | + len = OFFSETOF(bcm_iov_buf_t, data) + sizeof(band); |
---|
| 8368 | + |
---|
| 8369 | + iov_buf.version = WL_ADPS_IOV_VER; |
---|
| 8370 | + iov_buf.len = sizeof(band); |
---|
| 8371 | + iov_buf.id = WL_ADPS_IOV_MODE; |
---|
| 8372 | + |
---|
| 8373 | + pdata = (uint8 *)&iov_buf.data; |
---|
| 8374 | + |
---|
| 8375 | + for (band = 1; band <= MAX_BANDS; band++) { |
---|
| 8376 | + pdata[0] = band; |
---|
| 8377 | + err = wldev_iovar_getbuf(dev, "adps", &iov_buf, len, |
---|
| 8378 | + buf, WLC_IOCTL_SMLEN, NULL); |
---|
| 8379 | + if (err != BCME_OK) { |
---|
| 8380 | + WL_ERR(("wl_android_get_adps_mode fail to get adps band %d(%d).\n", |
---|
| 8381 | + band, err)); |
---|
| 8382 | + return -EIO; |
---|
| 8383 | + } |
---|
| 8384 | + ptr = (bcm_iov_buf_t *) buf; |
---|
| 8385 | + data = (wl_adps_params_v1_t *) ptr->data; |
---|
| 8386 | + mode = data->mode; |
---|
| 8387 | + if (mode != OFF) { |
---|
| 8388 | + break; |
---|
| 8389 | + } |
---|
| 8390 | + } |
---|
| 8391 | + |
---|
| 8392 | + bytes_written = snprintf(command, total_len, "%s %d", |
---|
| 8393 | + CMD_GET_ADPS, mode); |
---|
| 8394 | + return bytes_written; |
---|
| 8395 | +} |
---|
| 8396 | +#endif /* WLADPS_PRIVATE_CMD */ |
---|
| 8397 | + |
---|
| 8398 | +#ifdef WL_BCNRECV |
---|
| 8399 | +#define BCNRECV_ATTR_HDR_LEN 30 |
---|
| 8400 | +int |
---|
| 8401 | +wl_android_bcnrecv_event(struct net_device *ndev, uint attr_type, |
---|
| 8402 | + uint status, uint reason, uint8 *data, uint data_len) |
---|
| 8403 | +{ |
---|
| 8404 | + s32 err = BCME_OK; |
---|
| 8405 | + struct sk_buff *skb; |
---|
| 8406 | + gfp_t kflags; |
---|
| 8407 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 8408 | + struct wiphy *wiphy = bcmcfg_to_wiphy(cfg); |
---|
| 8409 | + uint len; |
---|
| 8410 | + |
---|
| 8411 | + len = BCNRECV_ATTR_HDR_LEN + data_len; |
---|
| 8412 | + |
---|
| 8413 | + kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; |
---|
| 8414 | + skb = CFG80211_VENDOR_EVENT_ALLOC(wiphy, ndev_to_wdev(ndev), len, |
---|
| 8415 | + BRCM_VENDOR_EVENT_BEACON_RECV, kflags); |
---|
| 8416 | + if (!skb) { |
---|
| 8417 | + WL_ERR(("skb alloc failed")); |
---|
| 8418 | + return -ENOMEM; |
---|
| 8419 | + } |
---|
| 8420 | + if ((attr_type == BCNRECV_ATTR_BCNINFO) && (data)) { |
---|
| 8421 | + /* send bcn info to upper layer */ |
---|
| 8422 | + nla_put(skb, BCNRECV_ATTR_BCNINFO, data_len, data); |
---|
| 8423 | + } else if (attr_type == BCNRECV_ATTR_STATUS) { |
---|
| 8424 | + nla_put_u32(skb, BCNRECV_ATTR_STATUS, status); |
---|
| 8425 | + if (reason) { |
---|
| 8426 | + nla_put_u32(skb, BCNRECV_ATTR_REASON, reason); |
---|
| 8427 | + } |
---|
| 8428 | + } else { |
---|
| 8429 | + WL_ERR(("UNKNOWN ATTR_TYPE. attr_type:%d\n", attr_type)); |
---|
| 8430 | + kfree_skb(skb); |
---|
| 8431 | + return -EINVAL; |
---|
| 8432 | + } |
---|
| 8433 | + cfg80211_vendor_event(skb, kflags); |
---|
| 8434 | + return err; |
---|
| 8435 | +} |
---|
| 8436 | + |
---|
| 8437 | +static int |
---|
| 8438 | +_wl_android_bcnrecv_start(struct bcm_cfg80211 *cfg, struct net_device *ndev, bool user_trigger) |
---|
| 8439 | +{ |
---|
| 8440 | + s32 err = BCME_OK; |
---|
| 8441 | + |
---|
| 8442 | + /* check any scan is in progress before beacon recv scan trigger IOVAR */ |
---|
| 8443 | + if (wl_get_drv_status_all(cfg, SCANNING)) { |
---|
| 8444 | + err = BCME_UNSUPPORTED; |
---|
| 8445 | + WL_ERR(("Scan in progress, Aborting beacon recv start, " |
---|
| 8446 | + "error:%d\n", err)); |
---|
| 8447 | + goto exit; |
---|
| 8448 | + } |
---|
| 8449 | + |
---|
| 8450 | + if (wl_get_p2p_status(cfg, SCANNING)) { |
---|
| 8451 | + err = BCME_UNSUPPORTED; |
---|
| 8452 | + WL_ERR(("P2P Scan in progress, Aborting beacon recv start, " |
---|
| 8453 | + "error:%d\n", err)); |
---|
| 8454 | + goto exit; |
---|
| 8455 | + } |
---|
| 8456 | + |
---|
| 8457 | + if (wl_get_drv_status(cfg, REMAINING_ON_CHANNEL, ndev)) { |
---|
| 8458 | + err = BCME_UNSUPPORTED; |
---|
| 8459 | + WL_ERR(("P2P remain on channel, Aborting beacon recv start, " |
---|
| 8460 | + "error:%d\n", err)); |
---|
| 8461 | + goto exit; |
---|
| 8462 | + } |
---|
| 8463 | + |
---|
| 8464 | + /* check STA is in connected state, Beacon recv required connected state |
---|
| 8465 | + * else exit from beacon recv scan |
---|
| 8466 | + */ |
---|
| 8467 | + if (!wl_get_drv_status(cfg, CONNECTED, ndev)) { |
---|
| 8468 | + err = BCME_UNSUPPORTED; |
---|
| 8469 | + WL_ERR(("STA is in not associated state error:%d\n", err)); |
---|
| 8470 | + goto exit; |
---|
| 8471 | + } |
---|
| 8472 | + |
---|
| 8473 | +#ifdef WL_NAN |
---|
| 8474 | + /* Check NAN is enabled, if enabled exit else continue */ |
---|
| 8475 | + if (wl_cfgnan_check_state(cfg)) { |
---|
| 8476 | + err = BCME_UNSUPPORTED; |
---|
| 8477 | + WL_ERR(("Nan is enabled, NAN+STA+FAKEAP concurrency is not supported\n")); |
---|
| 8478 | + goto exit; |
---|
| 8479 | + } |
---|
| 8480 | +#endif /* WL_NAN */ |
---|
| 8481 | + |
---|
| 8482 | + /* Triggering an sendup_bcn iovar */ |
---|
| 8483 | + err = wldev_iovar_setint(ndev, "sendup_bcn", 1); |
---|
| 8484 | + if (unlikely(err)) { |
---|
| 8485 | + WL_ERR(("sendup_bcn failed to set, error:%d\n", err)); |
---|
| 8486 | + } else { |
---|
| 8487 | + cfg->bcnrecv_info.bcnrecv_state = BEACON_RECV_STARTED; |
---|
| 8488 | + WL_INFORM_MEM(("bcnrecv started. user_trigger:%d\n", user_trigger)); |
---|
| 8489 | + if (user_trigger) { |
---|
| 8490 | + if ((err = wl_android_bcnrecv_event(ndev, BCNRECV_ATTR_STATUS, |
---|
| 8491 | + WL_BCNRECV_STARTED, 0, NULL, 0)) != BCME_OK) { |
---|
| 8492 | + WL_ERR(("failed to send bcnrecv event, error:%d\n", err)); |
---|
| 8493 | + } |
---|
| 8494 | + } |
---|
| 8495 | + } |
---|
| 8496 | +exit: |
---|
| 8497 | + /* |
---|
| 8498 | + * BCNRECV start request can be rejected from dongle |
---|
| 8499 | + * in various conditions. |
---|
| 8500 | + * Error code need to be overridden to BCME_UNSUPPORTED |
---|
| 8501 | + * to avoid hang event from continous private |
---|
| 8502 | + * command error |
---|
| 8503 | + */ |
---|
| 8504 | + if (err) { |
---|
| 8505 | + err = BCME_UNSUPPORTED; |
---|
| 8506 | + } |
---|
| 8507 | + return err; |
---|
| 8508 | +} |
---|
| 8509 | + |
---|
| 8510 | +int |
---|
| 8511 | +_wl_android_bcnrecv_stop(struct bcm_cfg80211 *cfg, struct net_device *ndev, uint reason) |
---|
| 8512 | +{ |
---|
| 8513 | + s32 err = BCME_OK; |
---|
| 8514 | + u32 status; |
---|
| 8515 | + |
---|
| 8516 | + /* Send sendup_bcn iovar for all cases except W_BCNRECV_ROAMABORT reason - |
---|
| 8517 | + * fw generates roam abort event after aborting the bcnrecv. |
---|
| 8518 | + */ |
---|
| 8519 | + if (reason != WL_BCNRECV_ROAMABORT) { |
---|
| 8520 | + /* Triggering an sendup_bcn iovar */ |
---|
| 8521 | + err = wldev_iovar_setint(ndev, "sendup_bcn", 0); |
---|
| 8522 | + if (unlikely(err)) { |
---|
| 8523 | + WL_ERR(("sendup_bcn failed to set error:%d\n", err)); |
---|
| 8524 | + goto exit; |
---|
| 8525 | + } |
---|
| 8526 | + } |
---|
| 8527 | + |
---|
| 8528 | + /* Send notification for all cases */ |
---|
| 8529 | + if (reason == WL_BCNRECV_SUSPEND) { |
---|
| 8530 | + cfg->bcnrecv_info.bcnrecv_state = BEACON_RECV_SUSPENDED; |
---|
| 8531 | + status = WL_BCNRECV_SUSPENDED; |
---|
| 8532 | + } else { |
---|
| 8533 | + cfg->bcnrecv_info.bcnrecv_state = BEACON_RECV_STOPPED; |
---|
| 8534 | + WL_INFORM_MEM(("bcnrecv stopped\n")); |
---|
| 8535 | + if (reason == WL_BCNRECV_USER_TRIGGER) { |
---|
| 8536 | + status = WL_BCNRECV_STOPPED; |
---|
| 8537 | + } else { |
---|
| 8538 | + status = WL_BCNRECV_ABORTED; |
---|
| 8539 | + } |
---|
| 8540 | + } |
---|
| 8541 | + if ((err = wl_android_bcnrecv_event(ndev, BCNRECV_ATTR_STATUS, status, |
---|
| 8542 | + reason, NULL, 0)) != BCME_OK) { |
---|
| 8543 | + WL_ERR(("failed to send bcnrecv event, error:%d\n", err)); |
---|
| 8544 | + } |
---|
| 8545 | +exit: |
---|
| 8546 | + return err; |
---|
| 8547 | +} |
---|
| 8548 | + |
---|
| 8549 | +static int |
---|
| 8550 | +wl_android_bcnrecv_start(struct bcm_cfg80211 *cfg, struct net_device *ndev) |
---|
| 8551 | +{ |
---|
| 8552 | + s32 err = BCME_OK; |
---|
| 8553 | + |
---|
| 8554 | + /* Adding scan_sync mutex to avoid race condition in b/w scan_req and bcn recv */ |
---|
| 8555 | + mutex_lock(&cfg->scan_sync); |
---|
| 8556 | + mutex_lock(&cfg->bcn_sync); |
---|
| 8557 | + err = _wl_android_bcnrecv_start(cfg, ndev, true); |
---|
| 8558 | + mutex_unlock(&cfg->bcn_sync); |
---|
| 8559 | + mutex_unlock(&cfg->scan_sync); |
---|
| 8560 | + return err; |
---|
| 8561 | +} |
---|
| 8562 | + |
---|
| 8563 | +int |
---|
| 8564 | +wl_android_bcnrecv_stop(struct net_device *ndev, uint reason) |
---|
| 8565 | +{ |
---|
| 8566 | + s32 err = BCME_OK; |
---|
| 8567 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 8568 | + |
---|
| 8569 | + mutex_lock(&cfg->bcn_sync); |
---|
| 8570 | + if ((cfg->bcnrecv_info.bcnrecv_state == BEACON_RECV_STARTED) || |
---|
| 8571 | + (cfg->bcnrecv_info.bcnrecv_state == BEACON_RECV_SUSPENDED)) { |
---|
| 8572 | + err = _wl_android_bcnrecv_stop(cfg, ndev, reason); |
---|
| 8573 | + } |
---|
| 8574 | + mutex_unlock(&cfg->bcn_sync); |
---|
| 8575 | + return err; |
---|
| 8576 | +} |
---|
| 8577 | + |
---|
| 8578 | +int |
---|
| 8579 | +wl_android_bcnrecv_suspend(struct net_device *ndev) |
---|
| 8580 | +{ |
---|
| 8581 | + s32 ret = BCME_OK; |
---|
| 8582 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 8583 | + |
---|
| 8584 | + mutex_lock(&cfg->bcn_sync); |
---|
| 8585 | + if (cfg->bcnrecv_info.bcnrecv_state == BEACON_RECV_STARTED) { |
---|
| 8586 | + WL_INFORM_MEM(("bcnrecv suspend\n")); |
---|
| 8587 | + ret = _wl_android_bcnrecv_stop(cfg, ndev, WL_BCNRECV_SUSPEND); |
---|
| 8588 | + } |
---|
| 8589 | + mutex_unlock(&cfg->bcn_sync); |
---|
| 8590 | + return ret; |
---|
| 8591 | +} |
---|
| 8592 | + |
---|
| 8593 | +int |
---|
| 8594 | +wl_android_bcnrecv_resume(struct net_device *ndev) |
---|
| 8595 | +{ |
---|
| 8596 | + s32 ret = BCME_OK; |
---|
| 8597 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 8598 | + |
---|
| 8599 | + /* Adding scan_sync mutex to avoid race condition in b/w scan_req and bcn recv */ |
---|
| 8600 | + mutex_lock(&cfg->scan_sync); |
---|
| 8601 | + mutex_lock(&cfg->bcn_sync); |
---|
| 8602 | + if (cfg->bcnrecv_info.bcnrecv_state == BEACON_RECV_SUSPENDED) { |
---|
| 8603 | + WL_INFORM_MEM(("bcnrecv resume\n")); |
---|
| 8604 | + ret = _wl_android_bcnrecv_start(cfg, ndev, false); |
---|
| 8605 | + } |
---|
| 8606 | + mutex_unlock(&cfg->bcn_sync); |
---|
| 8607 | + mutex_unlock(&cfg->scan_sync); |
---|
| 8608 | + return ret; |
---|
| 8609 | +} |
---|
| 8610 | + |
---|
| 8611 | +/* Beacon recv functionality code implementation */ |
---|
| 8612 | +int |
---|
| 8613 | +wl_android_bcnrecv_config(struct net_device *ndev, char *cmd_argv, int total_len) |
---|
| 8614 | +{ |
---|
| 8615 | + struct bcm_cfg80211 *cfg = NULL; |
---|
| 8616 | + uint err = BCME_OK; |
---|
| 8617 | + |
---|
| 8618 | + if (!ndev) { |
---|
| 8619 | + WL_ERR(("ndev is NULL\n")); |
---|
| 8620 | + return -EINVAL; |
---|
| 8621 | + } |
---|
| 8622 | + |
---|
| 8623 | + cfg = wl_get_cfg(ndev); |
---|
| 8624 | + if (!cfg) { |
---|
| 8625 | + WL_ERR(("cfg is NULL\n")); |
---|
| 8626 | + return -EINVAL; |
---|
| 8627 | + } |
---|
| 8628 | + |
---|
| 8629 | + /* sync commands from user space */ |
---|
| 8630 | + mutex_lock(&cfg->usr_sync); |
---|
| 8631 | + if (strncmp(cmd_argv, "start", strlen("start")) == 0) { |
---|
| 8632 | + WL_INFORM(("BCNRECV start\n")); |
---|
| 8633 | + err = wl_android_bcnrecv_start(cfg, ndev); |
---|
| 8634 | + if (err != BCME_OK) { |
---|
| 8635 | + WL_ERR(("Failed to process the start command, error:%d\n", err)); |
---|
| 8636 | + goto exit; |
---|
| 8637 | + } |
---|
| 8638 | + } else if (strncmp(cmd_argv, "stop", strlen("stop")) == 0) { |
---|
| 8639 | + WL_INFORM(("BCNRECV stop\n")); |
---|
| 8640 | + err = wl_android_bcnrecv_stop(ndev, WL_BCNRECV_USER_TRIGGER); |
---|
| 8641 | + if (err != BCME_OK) { |
---|
| 8642 | + WL_ERR(("Failed to stop the bcn recv, error:%d\n", err)); |
---|
| 8643 | + goto exit; |
---|
| 8644 | + } |
---|
| 8645 | + } else { |
---|
| 8646 | + err = BCME_ERROR; |
---|
| 8647 | + } |
---|
| 8648 | +exit: |
---|
| 8649 | + mutex_unlock(&cfg->usr_sync); |
---|
| 8650 | + return err; |
---|
| 8651 | +} |
---|
| 8652 | +#endif /* WL_BCNRECV */ |
---|
| 8653 | + |
---|
| 8654 | +#ifdef WL_CAC_TS |
---|
| 8655 | +/* CAC TSPEC functionality code implementation */ |
---|
| 8656 | +static void |
---|
| 8657 | +wl_android_update_tsinfo(uint8 access_category, tspec_arg_t *tspec_arg) |
---|
| 8658 | +{ |
---|
| 8659 | + uint8 tspec_id; |
---|
| 8660 | + /* Using direction as bidirectional by default */ |
---|
| 8661 | + uint8 direction = TSPEC_BI_DIRECTION; |
---|
| 8662 | + /* Using U-APSD as the default power save mode */ |
---|
| 8663 | + uint8 user_psb = TSPEC_UAPSD_PSB; |
---|
| 8664 | + uint8 ADDTS_AC2PRIO[4] = {PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_VI, PRIO_8021D_VO}; |
---|
| 8665 | + |
---|
| 8666 | + /* Map tspec_id from access category */ |
---|
| 8667 | + tspec_id = ADDTS_AC2PRIO[access_category]; |
---|
| 8668 | + |
---|
| 8669 | + /* Update the tsinfo */ |
---|
| 8670 | + tspec_arg->tsinfo.octets[0] = (uint8)(TSPEC_EDCA_ACCESS | direction | |
---|
| 8671 | + (tspec_id << TSPEC_TSINFO_TID_SHIFT)); |
---|
| 8672 | + tspec_arg->tsinfo.octets[1] = (uint8)((tspec_id << TSPEC_TSINFO_PRIO_SHIFT) | |
---|
| 8673 | + user_psb); |
---|
| 8674 | + tspec_arg->tsinfo.octets[2] = 0x00; |
---|
| 8675 | +} |
---|
| 8676 | + |
---|
| 8677 | +static s32 |
---|
| 8678 | +wl_android_handle_cac_action(struct bcm_cfg80211 * cfg, struct net_device * ndev, char * argv) |
---|
| 8679 | +{ |
---|
| 8680 | + tspec_arg_t tspec_arg; |
---|
| 8681 | + s32 err = BCME_ERROR; |
---|
| 8682 | + u8 ts_cmd[12] = "cac_addts"; |
---|
| 8683 | + uint8 access_category; |
---|
| 8684 | + s32 bssidx; |
---|
| 8685 | + |
---|
| 8686 | + /* Following handling is done only for the primary interface */ |
---|
| 8687 | + memset_s(&tspec_arg, sizeof(tspec_arg), 0, sizeof(tspec_arg)); |
---|
| 8688 | + if (strncmp(argv, "addts", strlen("addts")) == 0) { |
---|
| 8689 | + tspec_arg.version = TSPEC_ARG_VERSION; |
---|
| 8690 | + tspec_arg.length = sizeof(tspec_arg_t) - (2 * sizeof(uint16)); |
---|
| 8691 | + /* Read the params passed */ |
---|
| 8692 | + sscanf(argv, "%*s %hhu %hu %hu", &access_category, |
---|
| 8693 | + &tspec_arg.nom_msdu_size, &tspec_arg.surplus_bw); |
---|
| 8694 | + if ((access_category > TSPEC_MAX_ACCESS_CATEGORY) || |
---|
| 8695 | + ((tspec_arg.surplus_bw < TSPEC_MIN_SURPLUS_BW) || |
---|
| 8696 | + (tspec_arg.surplus_bw > TSPEC_MAX_SURPLUS_BW)) || |
---|
| 8697 | + (tspec_arg.nom_msdu_size > TSPEC_MAX_MSDU_SIZE)) { |
---|
| 8698 | + WL_ERR(("Invalid params access_category %hhu nom_msdu_size %hu" |
---|
| 8699 | + " surplus BW %hu\n", access_category, tspec_arg.nom_msdu_size, |
---|
| 8700 | + tspec_arg.surplus_bw)); |
---|
| 8701 | + return BCME_USAGE_ERROR; |
---|
| 8702 | + } |
---|
| 8703 | + |
---|
| 8704 | + /* Update tsinfo */ |
---|
| 8705 | + wl_android_update_tsinfo(access_category, &tspec_arg); |
---|
| 8706 | + /* Update other tspec parameters */ |
---|
| 8707 | + tspec_arg.dialog_token = TSPEC_DEF_DIALOG_TOKEN; |
---|
| 8708 | + tspec_arg.mean_data_rate = TSPEC_DEF_MEAN_DATA_RATE; |
---|
| 8709 | + tspec_arg.min_phy_rate = TSPEC_DEF_MIN_PHY_RATE; |
---|
| 8710 | + } else if (strncmp(argv, "delts", strlen("delts")) == 0) { |
---|
| 8711 | + snprintf(ts_cmd, sizeof(ts_cmd), "cac_delts"); |
---|
| 8712 | + tspec_arg.length = sizeof(tspec_arg_t) - (2 * sizeof(uint16)); |
---|
| 8713 | + tspec_arg.version = TSPEC_ARG_VERSION; |
---|
| 8714 | + /* Read the params passed */ |
---|
| 8715 | + sscanf(argv, "%*s %hhu", &access_category); |
---|
| 8716 | + |
---|
| 8717 | + if (access_category > TSPEC_MAX_ACCESS_CATEGORY) { |
---|
| 8718 | + WL_INFORM_MEM(("Invalide param, access_category %hhu\n", access_category)); |
---|
| 8719 | + return BCME_USAGE_ERROR; |
---|
| 8720 | + } |
---|
| 8721 | + /* Update tsinfo */ |
---|
| 8722 | + wl_android_update_tsinfo(access_category, &tspec_arg); |
---|
| 8723 | + } |
---|
| 8724 | + |
---|
| 8725 | + if ((bssidx = wl_get_bssidx_by_wdev(cfg, ndev->ieee80211_ptr)) < 0) { |
---|
| 8726 | + WL_ERR(("Find index failed\n")); |
---|
| 8727 | + err = BCME_ERROR; |
---|
| 8728 | + return err; |
---|
| 8729 | + } |
---|
| 8730 | + err = wldev_iovar_setbuf_bsscfg(ndev, ts_cmd, &tspec_arg, sizeof(tspec_arg), |
---|
| 8731 | + cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync); |
---|
| 8732 | + if (unlikely(err)) { |
---|
| 8733 | + WL_ERR(("%s error (%d)\n", ts_cmd, err)); |
---|
| 8734 | + } |
---|
| 8735 | + |
---|
| 8736 | + return err; |
---|
| 8737 | +} |
---|
| 8738 | + |
---|
| 8739 | +static s32 |
---|
| 8740 | +wl_android_cac_ts_config(struct net_device *ndev, char *cmd_argv, int total_len) |
---|
| 8741 | +{ |
---|
| 8742 | + struct bcm_cfg80211 *cfg = NULL; |
---|
| 8743 | + s32 err = BCME_OK; |
---|
| 8744 | + |
---|
| 8745 | + if (!ndev) { |
---|
| 8746 | + WL_ERR(("ndev is NULL\n")); |
---|
| 8747 | + return -EINVAL; |
---|
| 8748 | + } |
---|
| 8749 | + |
---|
| 8750 | + cfg = wl_get_cfg(ndev); |
---|
| 8751 | + if (!cfg) { |
---|
| 8752 | + WL_ERR(("cfg is NULL\n")); |
---|
| 8753 | + return -EINVAL; |
---|
| 8754 | + } |
---|
| 8755 | + |
---|
| 8756 | + /* Request supported only for primary interface */ |
---|
| 8757 | + if (ndev != bcmcfg_to_prmry_ndev(cfg)) { |
---|
| 8758 | + WL_ERR(("Request on non-primary interface\n")); |
---|
| 8759 | + return -1; |
---|
| 8760 | + } |
---|
| 8761 | + |
---|
| 8762 | + /* sync commands from user space */ |
---|
| 8763 | + mutex_lock(&cfg->usr_sync); |
---|
| 8764 | + err = wl_android_handle_cac_action(cfg, ndev, cmd_argv); |
---|
| 8765 | + mutex_unlock(&cfg->usr_sync); |
---|
| 8766 | + |
---|
| 8767 | + return err; |
---|
| 8768 | +} |
---|
| 8769 | +#endif /* WL_CAC_TS */ |
---|
| 8770 | + |
---|
| 8771 | +#ifdef WL_GET_CU |
---|
| 8772 | +/* Implementation to get channel usage from framework */ |
---|
| 8773 | +static s32 |
---|
| 8774 | +wl_android_get_channel_util(struct net_device *ndev, char *command, int total_len) |
---|
| 8775 | +{ |
---|
| 8776 | + s32 bytes_written, err = 0; |
---|
| 8777 | + wl_bssload_t bssload; |
---|
| 8778 | + u8 smbuf[WLC_IOCTL_SMLEN]; |
---|
| 8779 | + u8 chan_use_percentage = 0; |
---|
| 8780 | + |
---|
| 8781 | + if ((err = wldev_iovar_getbuf(ndev, "bssload_report", NULL, |
---|
| 8782 | + 0, smbuf, WLC_IOCTL_SMLEN, NULL))) { |
---|
| 8783 | + WL_ERR(("Getting bssload report failed with err=%d \n", err)); |
---|
| 8784 | + return err; |
---|
| 8785 | + } |
---|
| 8786 | + |
---|
| 8787 | + (void)memcpy_s(&bssload, sizeof(wl_bssload_t), smbuf, sizeof(wl_bssload_t)); |
---|
| 8788 | + /* Convert channel usage to percentage value */ |
---|
| 8789 | + chan_use_percentage = (bssload.chan_util * 100) / 255; |
---|
| 8790 | + |
---|
| 8791 | + bytes_written = snprintf(command, total_len, "CU %hhu", |
---|
| 8792 | + chan_use_percentage); |
---|
| 8793 | + WL_DBG(("Channel Utilization %u %u\n", bssload.chan_util, chan_use_percentage)); |
---|
| 8794 | + |
---|
| 8795 | + return bytes_written; |
---|
| 8796 | +} |
---|
| 8797 | +#endif /* WL_GET_CU */ |
---|
2356 | 8798 | |
---|
2357 | 8799 | int |
---|
2358 | 8800 | wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) |
---|
2359 | 8801 | { |
---|
2360 | 8802 | int bytes_written = 0; |
---|
2361 | | - android_wifi_priv_cmd priv_cmd = {0}; |
---|
| 8803 | + android_wifi_priv_cmd priv_cmd; |
---|
2362 | 8804 | |
---|
| 8805 | + bzero(&priv_cmd, sizeof(android_wifi_priv_cmd)); |
---|
2363 | 8806 | priv_cmd.total_len = cmd_len; |
---|
2364 | 8807 | |
---|
2365 | 8808 | if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) { |
---|
2366 | | - DHD_INFO(("%s, Received regular START command\n", __FUNCTION__)); |
---|
| 8809 | + DHD_INFO(("wl_handle_private_cmd, Received regular START command\n")); |
---|
| 8810 | +#ifdef SUPPORT_DEEP_SLEEP |
---|
| 8811 | + trigger_deep_sleep = 1; |
---|
| 8812 | +#else |
---|
| 8813 | +#ifdef BT_OVER_SDIO |
---|
| 8814 | + bytes_written = dhd_net_bus_get(net); |
---|
| 8815 | +#else |
---|
2367 | 8816 | bytes_written = wl_android_wifi_on(net); |
---|
| 8817 | +#endif /* BT_OVER_SDIO */ |
---|
| 8818 | +#endif /* SUPPORT_DEEP_SLEEP */ |
---|
2368 | 8819 | } |
---|
2369 | 8820 | else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) { |
---|
2370 | 8821 | bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len); |
---|
2371 | 8822 | } |
---|
2372 | 8823 | |
---|
2373 | 8824 | if (!g_wifi_on) { |
---|
2374 | | - DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface is down\n", |
---|
2375 | | - __FUNCTION__, command)); |
---|
| 8825 | + DHD_ERROR(("wl_handle_private_cmd: Ignore private cmd \"%s\" - iface is down\n", |
---|
| 8826 | + command)); |
---|
2376 | 8827 | return 0; |
---|
2377 | 8828 | } |
---|
2378 | 8829 | |
---|
2379 | 8830 | if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) { |
---|
| 8831 | +#ifdef SUPPORT_DEEP_SLEEP |
---|
| 8832 | + trigger_deep_sleep = 1; |
---|
| 8833 | +#else |
---|
| 8834 | +#ifdef BT_OVER_SDIO |
---|
| 8835 | + bytes_written = dhd_net_bus_put(net); |
---|
| 8836 | +#else |
---|
2380 | 8837 | bytes_written = wl_android_wifi_off(net, FALSE); |
---|
2381 | | - } |
---|
2382 | | - else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) { |
---|
2383 | | - wl_cfg80211_set_passive_scan(net, command); |
---|
2384 | | - } |
---|
2385 | | - else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) { |
---|
2386 | | - wl_cfg80211_set_passive_scan(net, command); |
---|
2387 | | - } |
---|
2388 | | - else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) { |
---|
2389 | | - bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len); |
---|
2390 | | - } |
---|
2391 | | - else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { |
---|
2392 | | - bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len); |
---|
| 8838 | +#endif /* BT_OVER_SDIO */ |
---|
| 8839 | +#endif /* SUPPORT_DEEP_SLEEP */ |
---|
2393 | 8840 | } |
---|
2394 | 8841 | #ifdef PKT_FILTER_SUPPORT |
---|
2395 | 8842 | else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) { |
---|
.. | .. |
---|
2415 | 8862 | } |
---|
2416 | 8863 | else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) { |
---|
2417 | 8864 | #ifdef WL_CFG80211 |
---|
2418 | | - void *dhdp = wl_cfg80211_get_dhdp(); |
---|
| 8865 | + void *dhdp = wl_cfg80211_get_dhdp(net); |
---|
2419 | 8866 | bytes_written = wl_cfg80211_set_btcoex_dhcp(net, dhdp, command); |
---|
2420 | 8867 | #else |
---|
2421 | 8868 | #ifdef PKT_FILTER_SUPPORT |
---|
.. | .. |
---|
2429 | 8876 | #endif /* WL_CFG80211 */ |
---|
2430 | 8877 | } |
---|
2431 | 8878 | else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { |
---|
2432 | | - bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); |
---|
| 8879 | + bytes_written = wl_android_set_suspendopt(net, command); |
---|
2433 | 8880 | } |
---|
2434 | 8881 | else if (strnicmp(command, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) { |
---|
2435 | | - bytes_written = wl_android_set_suspendmode(net, command, priv_cmd.total_len); |
---|
| 8882 | + bytes_written = wl_android_set_suspendmode(net, command); |
---|
2436 | 8883 | } |
---|
| 8884 | + else if (strnicmp(command, CMD_SETDTIM_IN_SUSPEND, strlen(CMD_SETDTIM_IN_SUSPEND)) == 0) { |
---|
| 8885 | + bytes_written = wl_android_set_bcn_li_dtim(net, command); |
---|
| 8886 | + } |
---|
| 8887 | + else if (strnicmp(command, CMD_MAXDTIM_IN_SUSPEND, strlen(CMD_MAXDTIM_IN_SUSPEND)) == 0) { |
---|
| 8888 | + bytes_written = wl_android_set_max_dtim(net, command); |
---|
| 8889 | + } |
---|
| 8890 | +#ifdef DISABLE_DTIM_IN_SUSPEND |
---|
| 8891 | + else if (strnicmp(command, CMD_DISDTIM_IN_SUSPEND, strlen(CMD_DISDTIM_IN_SUSPEND)) == 0) { |
---|
| 8892 | + bytes_written = wl_android_set_disable_dtim_in_suspend(net, command); |
---|
| 8893 | + } |
---|
| 8894 | +#endif /* DISABLE_DTIM_IN_SUSPEND */ |
---|
2437 | 8895 | else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { |
---|
2438 | | - uint band = *(command + strlen(CMD_SETBAND) + 1) - '0'; |
---|
2439 | | - bytes_written = wldev_set_band(net, band); |
---|
| 8896 | + bytes_written = wl_android_set_band(net, command); |
---|
2440 | 8897 | } |
---|
2441 | 8898 | else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { |
---|
2442 | 8899 | bytes_written = wl_android_get_band(net, command, priv_cmd.total_len); |
---|
2443 | 8900 | } |
---|
| 8901 | + else if (strnicmp(command, CMD_ADDIE, strlen(CMD_ADDIE)) == 0) { |
---|
| 8902 | + bytes_written = wl_android_add_vendor_ie(net, command, priv_cmd.total_len); |
---|
| 8903 | + } |
---|
| 8904 | + else if (strnicmp(command, CMD_DELIE, strlen(CMD_DELIE)) == 0) { |
---|
| 8905 | + bytes_written = wl_android_del_vendor_ie(net, command, priv_cmd.total_len); |
---|
| 8906 | + } |
---|
2444 | 8907 | #ifdef WL_CFG80211 |
---|
| 8908 | +#ifndef CUSTOMER_SET_COUNTRY |
---|
2445 | 8909 | /* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */ |
---|
2446 | 8910 | else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { |
---|
2447 | 8911 | /* |
---|
.. | .. |
---|
2452 | 8916 | char *country_code = command + strlen(CMD_COUNTRY) + 1; |
---|
2453 | 8917 | char *rev_info_delim = country_code + 2; /* 2 bytes of country code */ |
---|
2454 | 8918 | int revinfo = -1; |
---|
| 8919 | +#if defined(DHD_BLOB_EXISTENCE_CHECK) |
---|
| 8920 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(net); |
---|
| 8921 | + |
---|
| 8922 | + if (dhdp->is_blob) { |
---|
| 8923 | + revinfo = 0; |
---|
| 8924 | + } else |
---|
| 8925 | +#endif /* DHD_BLOB_EXISTENCE_CHECK */ |
---|
2455 | 8926 | if ((rev_info_delim) && |
---|
2456 | 8927 | (strnicmp(rev_info_delim, CMD_COUNTRY_DELIMITER, |
---|
2457 | 8928 | strlen(CMD_COUNTRY_DELIMITER)) == 0) && |
---|
2458 | 8929 | (rev_info_delim + 1)) { |
---|
2459 | 8930 | revinfo = bcm_atoi(rev_info_delim + 1); |
---|
2460 | 8931 | } |
---|
2461 | | - bytes_written = wldev_set_country(net, country_code, true, true, revinfo); |
---|
| 8932 | +#ifdef SAVE_CONNECTION_WHEN_CC_UPDATE |
---|
| 8933 | + wl_check_valid_channel_in_country(net, country_code, true); |
---|
| 8934 | + bytes_written = wl_cfg80211_set_country_code(net, country_code, |
---|
| 8935 | + true, false, revinfo); |
---|
| 8936 | + |
---|
| 8937 | + wl_update_ap_chandef(net); |
---|
| 8938 | +#else |
---|
| 8939 | + bytes_written = wl_cfg80211_set_country_code(net, country_code, |
---|
| 8940 | + true, true, revinfo); |
---|
| 8941 | +#endif // endif |
---|
| 8942 | +#ifdef CUSTOMER_HW4_PRIVATE_CMD |
---|
| 8943 | +#ifdef FCC_PWR_LIMIT_2G |
---|
| 8944 | + if (wldev_iovar_setint(net, "fccpwrlimit2g", FALSE)) { |
---|
| 8945 | + DHD_ERROR(("%s: fccpwrlimit2g deactivation is failed\n", __FUNCTION__)); |
---|
| 8946 | + } else { |
---|
| 8947 | + DHD_ERROR(("%s: fccpwrlimit2g is deactivated\n", __FUNCTION__)); |
---|
| 8948 | + } |
---|
| 8949 | +#endif /* FCC_PWR_LIMIT_2G */ |
---|
| 8950 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
2462 | 8951 | } |
---|
| 8952 | +#endif /* CUSTOMER_SET_COUNTRY */ |
---|
2463 | 8953 | #endif /* WL_CFG80211 */ |
---|
2464 | | - else if (strnicmp(command, CMD_SET_CSA, strlen(CMD_SET_CSA)) == 0) { |
---|
2465 | | - bytes_written = wl_android_set_csa(net, command, priv_cmd.total_len); |
---|
2466 | | - } else if (strnicmp(command, CMD_80211_MODE, strlen(CMD_80211_MODE)) == 0) { |
---|
2467 | | - bytes_written = wl_android_get_80211_mode(net, command, priv_cmd.total_len); |
---|
| 8954 | + else if (strnicmp(command, CMD_CHANNELS_IN_CC, strlen(CMD_CHANNELS_IN_CC)) == 0) { |
---|
| 8955 | + bytes_written = wl_android_get_channel_list(net, command, priv_cmd.total_len); |
---|
| 8956 | + } else if (strnicmp(command, CMD_SET_CSA, strlen(CMD_SET_CSA)) == 0) { |
---|
| 8957 | + bytes_written = wl_android_set_csa(net, command); |
---|
2468 | 8958 | } else if (strnicmp(command, CMD_CHANSPEC, strlen(CMD_CHANSPEC)) == 0) { |
---|
2469 | 8959 | bytes_written = wl_android_get_chanspec(net, command, priv_cmd.total_len); |
---|
2470 | | - } else if (strnicmp(command, CMD_DATARATE, strlen(CMD_DATARATE)) == 0) { |
---|
2471 | | - bytes_written = wl_android_get_datarate(net, command, priv_cmd.total_len); |
---|
2472 | | - } else if (strnicmp(command, CMD_ASSOC_CLIENTS, strlen(CMD_ASSOC_CLIENTS)) == 0) { |
---|
2473 | | - bytes_written = wl_android_get_assoclist(net, command, priv_cmd.total_len); |
---|
| 8960 | + } else if (strnicmp(command, CMD_BLOCKASSOC, strlen(CMD_BLOCKASSOC)) == 0) { |
---|
| 8961 | + bytes_written = wl_android_block_associations(net, command, priv_cmd.total_len); |
---|
| 8962 | + } |
---|
| 8963 | + else if (strnicmp(command, CMD_RSDB_MODE, strlen(CMD_RSDB_MODE)) == 0) { |
---|
| 8964 | + bytes_written = wl_android_get_rsdb_mode(net, command, priv_cmd.total_len); |
---|
2474 | 8965 | } |
---|
2475 | 8966 | |
---|
| 8967 | +#if defined(CUSTOMER_HW4_PRIVATE_CMD) || defined(IGUANA_LEGACY_CHIPS) |
---|
| 8968 | +#ifdef ROAM_API |
---|
| 8969 | + else if (strnicmp(command, CMD_ROAMTRIGGER_SET, |
---|
| 8970 | + strlen(CMD_ROAMTRIGGER_SET)) == 0) { |
---|
| 8971 | + bytes_written = wl_android_set_roam_trigger(net, command); |
---|
| 8972 | + } else if (strnicmp(command, CMD_ROAMTRIGGER_GET, |
---|
| 8973 | + strlen(CMD_ROAMTRIGGER_GET)) == 0) { |
---|
| 8974 | + bytes_written = wl_android_get_roam_trigger(net, command, |
---|
| 8975 | + priv_cmd.total_len); |
---|
| 8976 | + } else if (strnicmp(command, CMD_ROAMDELTA_SET, |
---|
| 8977 | + strlen(CMD_ROAMDELTA_SET)) == 0) { |
---|
| 8978 | + bytes_written = wl_android_set_roam_delta(net, command); |
---|
| 8979 | + } else if (strnicmp(command, CMD_ROAMDELTA_GET, |
---|
| 8980 | + strlen(CMD_ROAMDELTA_GET)) == 0) { |
---|
| 8981 | + bytes_written = wl_android_get_roam_delta(net, command, |
---|
| 8982 | + priv_cmd.total_len); |
---|
| 8983 | + } else if (strnicmp(command, CMD_ROAMSCANPERIOD_SET, |
---|
| 8984 | + strlen(CMD_ROAMSCANPERIOD_SET)) == 0) { |
---|
| 8985 | + bytes_written = wl_android_set_roam_scan_period(net, command); |
---|
| 8986 | + } else if (strnicmp(command, CMD_ROAMSCANPERIOD_GET, |
---|
| 8987 | + strlen(CMD_ROAMSCANPERIOD_GET)) == 0) { |
---|
| 8988 | + bytes_written = wl_android_get_roam_scan_period(net, command, |
---|
| 8989 | + priv_cmd.total_len); |
---|
| 8990 | + } else if (strnicmp(command, CMD_FULLROAMSCANPERIOD_SET, |
---|
| 8991 | + strlen(CMD_FULLROAMSCANPERIOD_SET)) == 0) { |
---|
| 8992 | + bytes_written = wl_android_set_full_roam_scan_period(net, command, |
---|
| 8993 | + priv_cmd.total_len); |
---|
| 8994 | + } else if (strnicmp(command, CMD_FULLROAMSCANPERIOD_GET, |
---|
| 8995 | + strlen(CMD_FULLROAMSCANPERIOD_GET)) == 0) { |
---|
| 8996 | + bytes_written = wl_android_get_full_roam_scan_period(net, command, |
---|
| 8997 | + priv_cmd.total_len); |
---|
| 8998 | + } |
---|
| 8999 | +#endif /* ROAM_API */ |
---|
| 9000 | +#ifdef WES_SUPPORT |
---|
| 9001 | + else if (strnicmp(command, CMD_GETROAMSCANCONTROL, strlen(CMD_GETROAMSCANCONTROL)) == 0) { |
---|
| 9002 | + bytes_written = wl_android_get_roam_scan_control(net, command, priv_cmd.total_len); |
---|
| 9003 | + } |
---|
| 9004 | + else if (strnicmp(command, CMD_SETROAMSCANCONTROL, strlen(CMD_SETROAMSCANCONTROL)) == 0) { |
---|
| 9005 | + bytes_written = wl_android_set_roam_scan_control(net, command); |
---|
| 9006 | + } |
---|
| 9007 | + else if (strnicmp(command, CMD_GETROAMSCANCHANNELS, strlen(CMD_GETROAMSCANCHANNELS)) == 0) { |
---|
| 9008 | + bytes_written = wl_android_get_roam_scan_channels(net, command, priv_cmd.total_len); |
---|
| 9009 | + } |
---|
| 9010 | + else if (strnicmp(command, CMD_SETROAMSCANCHANNELS, strlen(CMD_SETROAMSCANCHANNELS)) == 0) { |
---|
| 9011 | + bytes_written = wl_android_set_roam_scan_channels(net, command); |
---|
| 9012 | + } |
---|
| 9013 | + else if (strnicmp(command, CMD_SENDACTIONFRAME, strlen(CMD_SENDACTIONFRAME)) == 0) { |
---|
| 9014 | + bytes_written = wl_android_send_action_frame(net, command, priv_cmd.total_len); |
---|
| 9015 | + } |
---|
| 9016 | + else if (strnicmp(command, CMD_REASSOC, strlen(CMD_REASSOC)) == 0) { |
---|
| 9017 | + bytes_written = wl_android_reassoc(net, command, priv_cmd.total_len); |
---|
| 9018 | + } |
---|
| 9019 | + else if (strnicmp(command, CMD_GETSCANCHANNELTIME, strlen(CMD_GETSCANCHANNELTIME)) == 0) { |
---|
| 9020 | + bytes_written = wl_android_get_scan_channel_time(net, command, priv_cmd.total_len); |
---|
| 9021 | + } |
---|
| 9022 | + else if (strnicmp(command, CMD_SETSCANCHANNELTIME, strlen(CMD_SETSCANCHANNELTIME)) == 0) { |
---|
| 9023 | + bytes_written = wl_android_set_scan_channel_time(net, command); |
---|
| 9024 | + } |
---|
| 9025 | + else if (strnicmp(command, CMD_GETSCANUNASSOCTIME, strlen(CMD_GETSCANUNASSOCTIME)) == 0) { |
---|
| 9026 | + bytes_written = wl_android_get_scan_unassoc_time(net, command, priv_cmd.total_len); |
---|
| 9027 | + } |
---|
| 9028 | + else if (strnicmp(command, CMD_SETSCANUNASSOCTIME, strlen(CMD_SETSCANUNASSOCTIME)) == 0) { |
---|
| 9029 | + bytes_written = wl_android_set_scan_unassoc_time(net, command); |
---|
| 9030 | + } |
---|
| 9031 | + else if (strnicmp(command, CMD_GETSCANPASSIVETIME, strlen(CMD_GETSCANPASSIVETIME)) == 0) { |
---|
| 9032 | + bytes_written = wl_android_get_scan_passive_time(net, command, priv_cmd.total_len); |
---|
| 9033 | + } |
---|
| 9034 | + else if (strnicmp(command, CMD_SETSCANPASSIVETIME, strlen(CMD_SETSCANPASSIVETIME)) == 0) { |
---|
| 9035 | + bytes_written = wl_android_set_scan_passive_time(net, command); |
---|
| 9036 | + } |
---|
| 9037 | + else if (strnicmp(command, CMD_GETSCANHOMETIME, strlen(CMD_GETSCANHOMETIME)) == 0) { |
---|
| 9038 | + bytes_written = wl_android_get_scan_home_time(net, command, priv_cmd.total_len); |
---|
| 9039 | + } |
---|
| 9040 | + else if (strnicmp(command, CMD_SETSCANHOMETIME, strlen(CMD_SETSCANHOMETIME)) == 0) { |
---|
| 9041 | + bytes_written = wl_android_set_scan_home_time(net, command); |
---|
| 9042 | + } |
---|
| 9043 | + else if (strnicmp(command, CMD_GETSCANHOMEAWAYTIME, strlen(CMD_GETSCANHOMEAWAYTIME)) == 0) { |
---|
| 9044 | + bytes_written = wl_android_get_scan_home_away_time(net, command, |
---|
| 9045 | + priv_cmd.total_len); |
---|
| 9046 | + } |
---|
| 9047 | + else if (strnicmp(command, CMD_SETSCANHOMEAWAYTIME, strlen(CMD_SETSCANHOMEAWAYTIME)) == 0) { |
---|
| 9048 | + bytes_written = wl_android_set_scan_home_away_time(net, command); |
---|
| 9049 | + } |
---|
| 9050 | + else if (strnicmp(command, CMD_GETSCANNPROBES, strlen(CMD_GETSCANNPROBES)) == 0) { |
---|
| 9051 | + bytes_written = wl_android_get_scan_nprobes(net, command, priv_cmd.total_len); |
---|
| 9052 | + } |
---|
| 9053 | + else if (strnicmp(command, CMD_SETSCANNPROBES, strlen(CMD_SETSCANNPROBES)) == 0) { |
---|
| 9054 | + bytes_written = wl_android_set_scan_nprobes(net, command); |
---|
| 9055 | + } |
---|
| 9056 | + else if (strnicmp(command, CMD_GETDFSSCANMODE, strlen(CMD_GETDFSSCANMODE)) == 0) { |
---|
| 9057 | + bytes_written = wl_android_get_scan_dfs_channel_mode(net, command, |
---|
| 9058 | + priv_cmd.total_len); |
---|
| 9059 | + } |
---|
| 9060 | + else if (strnicmp(command, CMD_SETDFSSCANMODE, strlen(CMD_SETDFSSCANMODE)) == 0) { |
---|
| 9061 | + bytes_written = wl_android_set_scan_dfs_channel_mode(net, command); |
---|
| 9062 | + } |
---|
| 9063 | + else if (strnicmp(command, CMD_SETJOINPREFER, strlen(CMD_SETJOINPREFER)) == 0) { |
---|
| 9064 | + bytes_written = wl_android_set_join_prefer(net, command); |
---|
| 9065 | + } |
---|
| 9066 | + else if (strnicmp(command, CMD_GETWESMODE, strlen(CMD_GETWESMODE)) == 0) { |
---|
| 9067 | + bytes_written = wl_android_get_wes_mode(net, command, priv_cmd.total_len); |
---|
| 9068 | + } |
---|
| 9069 | + else if (strnicmp(command, CMD_SETWESMODE, strlen(CMD_SETWESMODE)) == 0) { |
---|
| 9070 | + bytes_written = wl_android_set_wes_mode(net, command); |
---|
| 9071 | + } |
---|
| 9072 | + else if (strnicmp(command, CMD_GETOKCMODE, strlen(CMD_GETOKCMODE)) == 0) { |
---|
| 9073 | + bytes_written = wl_android_get_okc_mode(net, command, priv_cmd.total_len); |
---|
| 9074 | + } |
---|
| 9075 | + else if (strnicmp(command, CMD_SETOKCMODE, strlen(CMD_SETOKCMODE)) == 0) { |
---|
| 9076 | + bytes_written = wl_android_set_okc_mode(net, command); |
---|
| 9077 | + } |
---|
| 9078 | + else if (strnicmp(command, CMD_OKC_SET_PMK, strlen(CMD_OKC_SET_PMK)) == 0) { |
---|
| 9079 | + bytes_written = wl_android_set_pmk(net, command, priv_cmd.total_len); |
---|
| 9080 | + } |
---|
| 9081 | + else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0) { |
---|
| 9082 | + bytes_written = wl_android_okc_enable(net, command); |
---|
| 9083 | + } |
---|
| 9084 | +#endif /* WES_SUPPORT */ |
---|
| 9085 | +#ifdef SUPPORT_RESTORE_SCAN_PARAMS |
---|
| 9086 | + else if (strnicmp(command, CMD_RESTORE_SCAN_PARAMS, strlen(CMD_RESTORE_SCAN_PARAMS)) == 0) { |
---|
| 9087 | + bytes_written = wl_android_restore_scan_params(net, command, priv_cmd.total_len); |
---|
| 9088 | + } |
---|
| 9089 | +#endif /* SUPPORT_RESTORE_SCAN_PARAMS */ |
---|
| 9090 | +#ifdef WLTDLS |
---|
| 9091 | + else if (strnicmp(command, CMD_TDLS_RESET, strlen(CMD_TDLS_RESET)) == 0) { |
---|
| 9092 | + bytes_written = wl_android_tdls_reset(net); |
---|
| 9093 | + } |
---|
| 9094 | +#endif /* WLTDLS */ |
---|
| 9095 | +#ifdef CONFIG_SILENT_ROAM |
---|
| 9096 | + else if (strnicmp(command, CMD_SROAM_TURN_ON, strlen(CMD_SROAM_TURN_ON)) == 0) { |
---|
| 9097 | + int skip = strlen(CMD_SROAM_TURN_ON) + 1; |
---|
| 9098 | + bytes_written = wl_android_sroam_turn_on(net, (const char*)command+skip); |
---|
| 9099 | + } |
---|
| 9100 | + else if (strnicmp(command, CMD_SROAM_SET_INFO, strlen(CMD_SROAM_SET_INFO)) == 0) { |
---|
| 9101 | + char *data = (command + strlen(CMD_SROAM_SET_INFO) + 1); |
---|
| 9102 | + bytes_written = wl_android_sroam_set_info(net, data, command, priv_cmd.total_len); |
---|
| 9103 | + } |
---|
| 9104 | + else if (strnicmp(command, CMD_SROAM_GET_INFO, strlen(CMD_SROAM_GET_INFO)) == 0) { |
---|
| 9105 | + bytes_written = wl_android_sroam_get_info(net, command, priv_cmd.total_len); |
---|
| 9106 | + } |
---|
| 9107 | +#endif /* CONFIG_SILENT_ROAM */ |
---|
| 9108 | + else if (strnicmp(command, CMD_SET_DISCONNECT_IES, strlen(CMD_SET_DISCONNECT_IES)) == 0) { |
---|
| 9109 | + bytes_written = wl_android_set_disconnect_ies(net, command); |
---|
| 9110 | + } |
---|
| 9111 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
2476 | 9112 | |
---|
2477 | 9113 | #ifdef PNO_SUPPORT |
---|
2478 | 9114 | else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { |
---|
2479 | 9115 | bytes_written = dhd_dev_pno_stop_for_ssid(net); |
---|
2480 | 9116 | } |
---|
2481 | | -#if !defined(WL_SCHED_SCAN) && defined(WL_WIRELESS_EXT) |
---|
| 9117 | +#ifndef WL_SCHED_SCAN |
---|
2482 | 9118 | else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { |
---|
2483 | 9119 | bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len); |
---|
2484 | 9120 | } |
---|
2485 | | -#endif /* !WL_SCHED_SCAN && OEM_ANDROID && WL_WIRELESS_EXT */ |
---|
| 9121 | +#endif /* !WL_SCHED_SCAN */ |
---|
2486 | 9122 | else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { |
---|
2487 | 9123 | int enable = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; |
---|
2488 | 9124 | bytes_written = (enable)? 0 : dhd_dev_pno_stop_for_ssid(net); |
---|
.. | .. |
---|
2499 | 9135 | bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, |
---|
2500 | 9136 | priv_cmd.total_len - skip); |
---|
2501 | 9137 | } |
---|
2502 | | -#ifdef WL_NAN |
---|
2503 | | - else if (strnicmp(command, CMD_NAN, strlen(CMD_NAN)) == 0) { |
---|
2504 | | - bytes_written = wl_cfg80211_nan_cmd_handler(net, command, |
---|
2505 | | - priv_cmd.total_len); |
---|
| 9138 | +#ifdef P2P_LISTEN_OFFLOADING |
---|
| 9139 | + else if (strnicmp(command, CMD_P2P_LISTEN_OFFLOAD, strlen(CMD_P2P_LISTEN_OFFLOAD)) == 0) { |
---|
| 9140 | + u8 *sub_command = strchr(command, ' '); |
---|
| 9141 | + bytes_written = wl_cfg80211_p2plo_offload(net, command, sub_command, |
---|
| 9142 | + sub_command ? strlen(sub_command) : 0); |
---|
2506 | 9143 | } |
---|
2507 | | -#endif /* WL_NAN */ |
---|
| 9144 | +#endif /* P2P_LISTEN_OFFLOADING */ |
---|
2508 | 9145 | #if !defined WL_ENABLE_P2P_IF |
---|
2509 | 9146 | else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) { |
---|
2510 | 9147 | bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); |
---|
.. | .. |
---|
2520 | 9157 | bytes_written = wl_cfg80211_set_p2p_ecsa(net, command + skip, |
---|
2521 | 9158 | priv_cmd.total_len - skip); |
---|
2522 | 9159 | } |
---|
| 9160 | + else if (strnicmp(command, CMD_P2P_INC_BW, strlen(CMD_P2P_INC_BW)) == 0) { |
---|
| 9161 | + int skip = strlen(CMD_P2P_INC_BW) + 1; |
---|
| 9162 | + bytes_written = wl_cfg80211_increase_p2p_bw(net, |
---|
| 9163 | + command + skip, priv_cmd.total_len - skip); |
---|
| 9164 | + } |
---|
2523 | 9165 | #ifdef WL_CFG80211 |
---|
2524 | 9166 | else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE, |
---|
2525 | 9167 | strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) { |
---|
.. | .. |
---|
2529 | 9171 | } |
---|
2530 | 9172 | #ifdef WLFBT |
---|
2531 | 9173 | else if (strnicmp(command, CMD_GET_FTKEY, strlen(CMD_GET_FTKEY)) == 0) { |
---|
2532 | | - wl_cfg80211_get_fbt_key(command); |
---|
2533 | | - bytes_written = FBT_KEYLEN; |
---|
| 9174 | + bytes_written = wl_cfg80211_get_fbt_key(net, command, priv_cmd.total_len); |
---|
2534 | 9175 | } |
---|
2535 | 9176 | #endif /* WLFBT */ |
---|
2536 | 9177 | #endif /* WL_CFG80211 */ |
---|
2537 | | - else if (strnicmp(command, CMD_OKC_SET_PMK, strlen(CMD_OKC_SET_PMK)) == 0) |
---|
2538 | | - bytes_written = wl_android_set_pmk(net, command, priv_cmd.total_len); |
---|
2539 | | - else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0) |
---|
2540 | | - bytes_written = wl_android_okc_enable(net, command, priv_cmd.total_len); |
---|
2541 | 9178 | #if defined(WL_SUPPORT_AUTO_CHANNEL) |
---|
2542 | 9179 | else if (strnicmp(command, CMD_GET_BEST_CHANNELS, |
---|
2543 | 9180 | strlen(CMD_GET_BEST_CHANNELS)) == 0) { |
---|
.. | .. |
---|
2553 | 9190 | priv_cmd.total_len); |
---|
2554 | 9191 | } |
---|
2555 | 9192 | #endif /* WL_SUPPORT_AUTO_CHANNEL */ |
---|
2556 | | - else if (strnicmp(command, CMD_HAPD_MAC_FILTER, strlen(CMD_HAPD_MAC_FILTER)) == 0) { |
---|
2557 | | - int skip = strlen(CMD_HAPD_MAC_FILTER) + 1; |
---|
2558 | | - wl_android_set_mac_address_filter(net, (const char*)command+skip); |
---|
| 9193 | +#ifdef CUSTOMER_HW4_PRIVATE_CMD |
---|
| 9194 | +#ifdef SUPPORT_AMPDU_MPDU_CMD |
---|
| 9195 | + /* CMD_AMPDU_MPDU */ |
---|
| 9196 | + else if (strnicmp(command, CMD_AMPDU_MPDU, strlen(CMD_AMPDU_MPDU)) == 0) { |
---|
| 9197 | + int skip = strlen(CMD_AMPDU_MPDU) + 1; |
---|
| 9198 | + bytes_written = wl_android_set_ampdu_mpdu(net, (const char*)command+skip); |
---|
2559 | 9199 | } |
---|
| 9200 | +#endif /* SUPPORT_AMPDU_MPDU_CMD */ |
---|
| 9201 | +#ifdef SUPPORT_SOFTAP_SINGL_DISASSOC |
---|
| 9202 | + else if (strnicmp(command, CMD_HAPD_STA_DISASSOC, |
---|
| 9203 | + strlen(CMD_HAPD_STA_DISASSOC)) == 0) { |
---|
| 9204 | + int skip = strlen(CMD_HAPD_STA_DISASSOC) + 1; |
---|
| 9205 | + wl_android_sta_diassoc(net, (const char*)command+skip); |
---|
| 9206 | + } |
---|
| 9207 | +#endif /* SUPPORT_SOFTAP_SINGL_DISASSOC */ |
---|
| 9208 | +#ifdef SUPPORT_SET_LPC |
---|
| 9209 | + else if (strnicmp(command, CMD_HAPD_LPC_ENABLED, |
---|
| 9210 | + strlen(CMD_HAPD_LPC_ENABLED)) == 0) { |
---|
| 9211 | + int skip = strlen(CMD_HAPD_LPC_ENABLED) + 3; |
---|
| 9212 | + wl_android_set_lpc(net, (const char*)command+skip); |
---|
| 9213 | + } |
---|
| 9214 | +#endif /* SUPPORT_SET_LPC */ |
---|
| 9215 | +#ifdef SUPPORT_TRIGGER_HANG_EVENT |
---|
| 9216 | + else if (strnicmp(command, CMD_TEST_FORCE_HANG, |
---|
| 9217 | + strlen(CMD_TEST_FORCE_HANG)) == 0) { |
---|
| 9218 | + int skip = strlen(CMD_TEST_FORCE_HANG) + 1; |
---|
| 9219 | + net_os_send_hang_message_reason(net, (const char*)command+skip); |
---|
| 9220 | + } |
---|
| 9221 | +#endif /* SUPPORT_TRIGGER_HANG_EVENT */ |
---|
| 9222 | + else if (strnicmp(command, CMD_CHANGE_RL, strlen(CMD_CHANGE_RL)) == 0) |
---|
| 9223 | + bytes_written = wl_android_ch_res_rl(net, true); |
---|
| 9224 | + else if (strnicmp(command, CMD_RESTORE_RL, strlen(CMD_RESTORE_RL)) == 0) |
---|
| 9225 | + bytes_written = wl_android_ch_res_rl(net, false); |
---|
| 9226 | +#ifdef SUPPORT_LTECX |
---|
| 9227 | + else if (strnicmp(command, CMD_LTECX_SET, strlen(CMD_LTECX_SET)) == 0) { |
---|
| 9228 | + int skip = strlen(CMD_LTECX_SET) + 1; |
---|
| 9229 | + bytes_written = wl_android_set_ltecx(net, (const char*)command+skip); |
---|
| 9230 | + } |
---|
| 9231 | +#endif /* SUPPORT_LTECX */ |
---|
| 9232 | +#ifdef WL_RELMCAST |
---|
| 9233 | + else if (strnicmp(command, CMD_SET_RMC_ENABLE, strlen(CMD_SET_RMC_ENABLE)) == 0) { |
---|
| 9234 | + int rmc_enable = *(command + strlen(CMD_SET_RMC_ENABLE) + 1) - '0'; |
---|
| 9235 | + bytes_written = wl_android_rmc_enable(net, rmc_enable); |
---|
| 9236 | + } |
---|
| 9237 | + else if (strnicmp(command, CMD_SET_RMC_TXRATE, strlen(CMD_SET_RMC_TXRATE)) == 0) { |
---|
| 9238 | + int rmc_txrate; |
---|
| 9239 | + sscanf(command, "%*s %10d", &rmc_txrate); |
---|
| 9240 | + bytes_written = wldev_iovar_setint(net, "rmc_txrate", rmc_txrate * 2); |
---|
| 9241 | + } |
---|
| 9242 | + else if (strnicmp(command, CMD_SET_RMC_ACTPERIOD, strlen(CMD_SET_RMC_ACTPERIOD)) == 0) { |
---|
| 9243 | + int actperiod; |
---|
| 9244 | + sscanf(command, "%*s %10d", &actperiod); |
---|
| 9245 | + bytes_written = wldev_iovar_setint(net, "rmc_actf_time", actperiod); |
---|
| 9246 | + } |
---|
| 9247 | + else if (strnicmp(command, CMD_SET_RMC_IDLEPERIOD, strlen(CMD_SET_RMC_IDLEPERIOD)) == 0) { |
---|
| 9248 | + int acktimeout; |
---|
| 9249 | + sscanf(command, "%*s %10d", &acktimeout); |
---|
| 9250 | + acktimeout *= 1000; |
---|
| 9251 | + bytes_written = wldev_iovar_setint(net, "rmc_acktmo", acktimeout); |
---|
| 9252 | + } |
---|
| 9253 | + else if (strnicmp(command, CMD_SET_RMC_LEADER, strlen(CMD_SET_RMC_LEADER)) == 0) { |
---|
| 9254 | + int skip = strlen(CMD_SET_RMC_LEADER) + 1; |
---|
| 9255 | + bytes_written = wl_android_rmc_set_leader(net, (const char*)command+skip); |
---|
| 9256 | + } |
---|
| 9257 | + else if (strnicmp(command, CMD_SET_RMC_EVENT, |
---|
| 9258 | + strlen(CMD_SET_RMC_EVENT)) == 0) { |
---|
| 9259 | + bytes_written = wl_android_set_rmc_event(net, command); |
---|
| 9260 | + } |
---|
| 9261 | +#endif /* WL_RELMCAST */ |
---|
| 9262 | + else if (strnicmp(command, CMD_GET_SCSCAN, strlen(CMD_GET_SCSCAN)) == 0) { |
---|
| 9263 | + bytes_written = wl_android_get_singlecore_scan(net, command, priv_cmd.total_len); |
---|
| 9264 | + } |
---|
| 9265 | + else if (strnicmp(command, CMD_SET_SCSCAN, strlen(CMD_SET_SCSCAN)) == 0) { |
---|
| 9266 | + bytes_written = wl_android_set_singlecore_scan(net, command); |
---|
| 9267 | + } |
---|
| 9268 | +#ifdef TEST_TX_POWER_CONTROL |
---|
| 9269 | + else if (strnicmp(command, CMD_TEST_SET_TX_POWER, |
---|
| 9270 | + strlen(CMD_TEST_SET_TX_POWER)) == 0) { |
---|
| 9271 | + int skip = strlen(CMD_TEST_SET_TX_POWER) + 1; |
---|
| 9272 | + wl_android_set_tx_power(net, (const char*)command+skip); |
---|
| 9273 | + } |
---|
| 9274 | + else if (strnicmp(command, CMD_TEST_GET_TX_POWER, |
---|
| 9275 | + strlen(CMD_TEST_GET_TX_POWER)) == 0) { |
---|
| 9276 | + wl_android_get_tx_power(net, command, priv_cmd.total_len); |
---|
| 9277 | + } |
---|
| 9278 | +#endif /* TEST_TX_POWER_CONTROL */ |
---|
| 9279 | + else if (strnicmp(command, CMD_SARLIMIT_TX_CONTROL, |
---|
| 9280 | + strlen(CMD_SARLIMIT_TX_CONTROL)) == 0) { |
---|
| 9281 | + int skip = strlen(CMD_SARLIMIT_TX_CONTROL) + 1; |
---|
| 9282 | + bytes_written = wl_android_set_sarlimit_txctrl(net, (const char*)command+skip); |
---|
| 9283 | + } |
---|
| 9284 | +#ifdef SUPPORT_SET_TID |
---|
| 9285 | + else if (strnicmp(command, CMD_SET_TID, strlen(CMD_SET_TID)) == 0) { |
---|
| 9286 | + bytes_written = wl_android_set_tid(net, command); |
---|
| 9287 | + } |
---|
| 9288 | + else if (strnicmp(command, CMD_GET_TID, strlen(CMD_GET_TID)) == 0) { |
---|
| 9289 | + bytes_written = wl_android_get_tid(net, command, priv_cmd.total_len); |
---|
| 9290 | + } |
---|
| 9291 | +#endif /* SUPPORT_SET_TID */ |
---|
| 9292 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
| 9293 | +#if defined(SUPPORT_HIDDEN_AP) |
---|
| 9294 | + else if (strnicmp(command, CMD_SET_HAPD_MAX_NUM_STA, |
---|
| 9295 | + strlen(CMD_SET_HAPD_MAX_NUM_STA)) == 0) { |
---|
| 9296 | + int skip = strlen(CMD_SET_HAPD_MAX_NUM_STA) + 3; |
---|
| 9297 | + wl_android_set_max_num_sta(net, (const char*)command+skip); |
---|
| 9298 | + } |
---|
| 9299 | + else if (strnicmp(command, CMD_SET_HAPD_SSID, |
---|
| 9300 | + strlen(CMD_SET_HAPD_SSID)) == 0) { |
---|
| 9301 | + int skip = strlen(CMD_SET_HAPD_SSID) + 3; |
---|
| 9302 | + wl_android_set_ssid(net, (const char*)command+skip); |
---|
| 9303 | + } |
---|
| 9304 | + else if (strnicmp(command, CMD_SET_HAPD_HIDE_SSID, |
---|
| 9305 | + strlen(CMD_SET_HAPD_HIDE_SSID)) == 0) { |
---|
| 9306 | + int skip = strlen(CMD_SET_HAPD_HIDE_SSID) + 1; |
---|
| 9307 | + wl_android_set_hide_ssid(net, (const char*)(command+skip)); |
---|
| 9308 | + } |
---|
| 9309 | +#endif /* SUPPORT_HIDDEN_AP */ |
---|
2560 | 9310 | else if (strnicmp(command, CMD_SETROAMMODE, strlen(CMD_SETROAMMODE)) == 0) |
---|
2561 | | - bytes_written = wl_android_set_roam_mode(net, command, priv_cmd.total_len); |
---|
| 9311 | + bytes_written = wl_android_set_roam_mode(net, command); |
---|
2562 | 9312 | #if defined(BCMFW_ROAM_ENABLE) |
---|
2563 | 9313 | else if (strnicmp(command, CMD_SET_ROAMPREF, strlen(CMD_SET_ROAMPREF)) == 0) { |
---|
2564 | 9314 | bytes_written = wl_android_set_roampref(net, command, priv_cmd.total_len); |
---|
2565 | 9315 | } |
---|
2566 | 9316 | #endif /* BCMFW_ROAM_ENABLE */ |
---|
2567 | 9317 | else if (strnicmp(command, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0) |
---|
2568 | | - bytes_written = wl_android_set_miracast(net, command, priv_cmd.total_len); |
---|
2569 | | -#ifdef WL11ULB |
---|
2570 | | - else if (strnicmp(command, CMD_ULB_MODE, strlen(CMD_ULB_MODE)) == 0) |
---|
2571 | | - bytes_written = wl_android_set_ulb_mode(net, command, priv_cmd.total_len); |
---|
2572 | | - else if (strnicmp(command, CMD_ULB_BW, strlen(CMD_ULB_BW)) == 0) |
---|
2573 | | - bytes_written = wl_android_set_ulb_bw(net, command, priv_cmd.total_len); |
---|
2574 | | -#endif /* WL11ULB */ |
---|
| 9318 | + bytes_written = wl_android_set_miracast(net, command); |
---|
2575 | 9319 | else if (strnicmp(command, CMD_SETIBSSBEACONOUIDATA, strlen(CMD_SETIBSSBEACONOUIDATA)) == 0) |
---|
2576 | 9320 | bytes_written = wl_android_set_ibss_beacon_ouidata(net, |
---|
2577 | 9321 | command, priv_cmd.total_len); |
---|
| 9322 | +#ifdef WLAIBSS |
---|
| 9323 | + else if (strnicmp(command, CMD_SETIBSSTXFAILEVENT, |
---|
| 9324 | + strlen(CMD_SETIBSSTXFAILEVENT)) == 0) |
---|
| 9325 | + bytes_written = wl_android_set_ibss_txfail_event(net, command, priv_cmd.total_len); |
---|
| 9326 | + else if (strnicmp(command, CMD_GET_IBSS_PEER_INFO_ALL, |
---|
| 9327 | + strlen(CMD_GET_IBSS_PEER_INFO_ALL)) == 0) |
---|
| 9328 | + bytes_written = wl_android_get_ibss_peer_info(net, command, priv_cmd.total_len, |
---|
| 9329 | + TRUE); |
---|
| 9330 | + else if (strnicmp(command, CMD_GET_IBSS_PEER_INFO, |
---|
| 9331 | + strlen(CMD_GET_IBSS_PEER_INFO)) == 0) |
---|
| 9332 | + bytes_written = wl_android_get_ibss_peer_info(net, command, priv_cmd.total_len, |
---|
| 9333 | + FALSE); |
---|
| 9334 | + else if (strnicmp(command, CMD_SETIBSSROUTETABLE, |
---|
| 9335 | + strlen(CMD_SETIBSSROUTETABLE)) == 0) |
---|
| 9336 | + bytes_written = wl_android_set_ibss_routetable(net, command); |
---|
| 9337 | + else if (strnicmp(command, CMD_SETIBSSAMPDU, strlen(CMD_SETIBSSAMPDU)) == 0) |
---|
| 9338 | + bytes_written = wl_android_set_ibss_ampdu(net, command, priv_cmd.total_len); |
---|
| 9339 | + else if (strnicmp(command, CMD_SETIBSSANTENNAMODE, strlen(CMD_SETIBSSANTENNAMODE)) == 0) |
---|
| 9340 | + bytes_written = wl_android_set_ibss_antenna(net, command, priv_cmd.total_len); |
---|
| 9341 | +#endif /* WLAIBSS */ |
---|
2578 | 9342 | else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) { |
---|
2579 | 9343 | int skip = strlen(CMD_KEEP_ALIVE) + 1; |
---|
2580 | | - bytes_written = wl_keep_alive_set(net, command + skip, priv_cmd.total_len - skip); |
---|
| 9344 | + bytes_written = wl_keep_alive_set(net, command + skip); |
---|
2581 | 9345 | } |
---|
2582 | 9346 | else if (strnicmp(command, CMD_ROAM_OFFLOAD, strlen(CMD_ROAM_OFFLOAD)) == 0) { |
---|
2583 | 9347 | int enable = *(command + strlen(CMD_ROAM_OFFLOAD) + 1) - '0'; |
---|
2584 | 9348 | bytes_written = wl_cfg80211_enable_roam_offload(net, enable); |
---|
2585 | 9349 | } |
---|
2586 | | - else if (strnicmp(command, CMD_ROAM_OFFLOAD_APLIST, strlen(CMD_ROAM_OFFLOAD_APLIST)) == 0) { |
---|
2587 | | - bytes_written = wl_android_set_roam_offload_bssid_list(net, |
---|
2588 | | - command + strlen(CMD_ROAM_OFFLOAD_APLIST) + 1); |
---|
2589 | | - } |
---|
2590 | | -#if defined(WL_VIRTUAL_APSTA) |
---|
2591 | 9350 | else if (strnicmp(command, CMD_INTERFACE_CREATE, strlen(CMD_INTERFACE_CREATE)) == 0) { |
---|
2592 | 9351 | char *name = (command + strlen(CMD_INTERFACE_CREATE) +1); |
---|
2593 | 9352 | WL_INFORM(("Creating %s interface\n", name)); |
---|
2594 | | - bytes_written = wl_cfg80211_interface_create(net, name); |
---|
| 9353 | + if (wl_cfg80211_add_if(wl_get_cfg(net), net, WL_IF_TYPE_STA, |
---|
| 9354 | + name, NULL) == NULL) { |
---|
| 9355 | + bytes_written = -ENODEV; |
---|
| 9356 | + } else { |
---|
| 9357 | + /* Return success */ |
---|
| 9358 | + bytes_written = 0; |
---|
| 9359 | + } |
---|
2595 | 9360 | } |
---|
2596 | 9361 | else if (strnicmp(command, CMD_INTERFACE_DELETE, strlen(CMD_INTERFACE_DELETE)) == 0) { |
---|
2597 | 9362 | char *name = (command + strlen(CMD_INTERFACE_DELETE) +1); |
---|
2598 | 9363 | WL_INFORM(("Deleteing %s interface\n", name)); |
---|
2599 | | - bytes_written = wl_cfg80211_interface_delete(net, name); |
---|
| 9364 | + bytes_written = wl_cfg80211_del_if(wl_get_cfg(net), net, NULL, name); |
---|
2600 | 9365 | } |
---|
2601 | | -#endif /* defined (WL_VIRTUAL_APSTA) */ |
---|
| 9366 | + else if (strnicmp(command, CMD_GET_LINK_STATUS, strlen(CMD_GET_LINK_STATUS)) == 0) { |
---|
| 9367 | + bytes_written = wl_android_get_link_status(net, command, priv_cmd.total_len); |
---|
| 9368 | + } |
---|
2602 | 9369 | #ifdef P2PRESP_WFDIE_SRC |
---|
2603 | 9370 | else if (strnicmp(command, CMD_P2P_SET_WFDIE_RESP, |
---|
2604 | 9371 | strlen(CMD_P2P_SET_WFDIE_RESP)) == 0) { |
---|
.. | .. |
---|
2613 | 9380 | char *data = (command + strlen(CMD_DFS_AP_MOVE) +1); |
---|
2614 | 9381 | bytes_written = wl_cfg80211_dfs_ap_move(net, data, command, priv_cmd.total_len); |
---|
2615 | 9382 | } |
---|
| 9383 | +#ifdef WBTEXT |
---|
2616 | 9384 | else if (strnicmp(command, CMD_WBTEXT_ENABLE, strlen(CMD_WBTEXT_ENABLE)) == 0) { |
---|
2617 | 9385 | bytes_written = wl_android_wbtext(net, command, priv_cmd.total_len); |
---|
2618 | 9386 | } |
---|
.. | .. |
---|
2639 | 9407 | bytes_written = wl_cfg80211_wbtext_delta_config(net, data, |
---|
2640 | 9408 | command, priv_cmd.total_len); |
---|
2641 | 9409 | } |
---|
| 9410 | + else if (strnicmp(command, CMD_WBTEXT_BTM_TIMER_THRESHOLD, |
---|
| 9411 | + strlen(CMD_WBTEXT_BTM_TIMER_THRESHOLD)) == 0) { |
---|
| 9412 | + bytes_written = wl_cfg80211_wbtext_btm_timer_threshold(net, command, |
---|
| 9413 | + priv_cmd.total_len); |
---|
| 9414 | + } |
---|
| 9415 | + else if (strnicmp(command, CMD_WBTEXT_BTM_DELTA, |
---|
| 9416 | + strlen(CMD_WBTEXT_BTM_DELTA)) == 0) { |
---|
| 9417 | + bytes_written = wl_cfg80211_wbtext_btm_delta(net, command, |
---|
| 9418 | + priv_cmd.total_len); |
---|
| 9419 | + } |
---|
| 9420 | + else if (strnicmp(command, CMD_WBTEXT_ESTM_ENABLE, |
---|
| 9421 | + strlen(CMD_WBTEXT_ESTM_ENABLE)) == 0) { |
---|
| 9422 | + bytes_written = wl_cfg80211_wbtext_estm_enable(net, command, |
---|
| 9423 | + priv_cmd.total_len); |
---|
| 9424 | + } |
---|
| 9425 | +#endif /* WBTEXT */ |
---|
2642 | 9426 | #ifdef SET_RPS_CPUS |
---|
2643 | 9427 | else if (strnicmp(command, CMD_RPSMODE, strlen(CMD_RPSMODE)) == 0) { |
---|
2644 | | - bytes_written = wl_android_set_rps_cpus(net, command, priv_cmd.total_len); |
---|
| 9428 | + bytes_written = wl_android_set_rps_cpus(net, command); |
---|
2645 | 9429 | } |
---|
2646 | 9430 | #endif /* SET_RPS_CPUS */ |
---|
2647 | 9431 | #ifdef WLWFDS |
---|
2648 | 9432 | else if (strnicmp(command, CMD_ADD_WFDS_HASH, strlen(CMD_ADD_WFDS_HASH)) == 0) { |
---|
2649 | | - bytes_written = wl_android_set_wfds_hash(net, command, priv_cmd.total_len, 1); |
---|
| 9433 | + bytes_written = wl_android_set_wfds_hash(net, command, 1); |
---|
2650 | 9434 | } |
---|
2651 | 9435 | else if (strnicmp(command, CMD_DEL_WFDS_HASH, strlen(CMD_DEL_WFDS_HASH)) == 0) { |
---|
2652 | | - bytes_written = wl_android_set_wfds_hash(net, command, priv_cmd.total_len, 0); |
---|
| 9436 | + bytes_written = wl_android_set_wfds_hash(net, command, 0); |
---|
2653 | 9437 | } |
---|
2654 | 9438 | #endif /* WLWFDS */ |
---|
2655 | 9439 | #ifdef BT_WIFI_HANDOVER |
---|
2656 | 9440 | else if (strnicmp(command, CMD_TBOW_TEARDOWN, strlen(CMD_TBOW_TEARDOWN)) == 0) { |
---|
2657 | | - bytes_written = wl_tbow_teardown(net, command, priv_cmd.total_len); |
---|
| 9441 | + bytes_written = wl_tbow_teardown(net); |
---|
2658 | 9442 | } |
---|
2659 | 9443 | #endif /* BT_WIFI_HANDOVER */ |
---|
| 9444 | +#ifdef CUSTOMER_HW4_PRIVATE_CMD |
---|
| 9445 | +#ifdef FCC_PWR_LIMIT_2G |
---|
| 9446 | + else if (strnicmp(command, CMD_GET_FCC_PWR_LIMIT_2G, |
---|
| 9447 | + strlen(CMD_GET_FCC_PWR_LIMIT_2G)) == 0) { |
---|
| 9448 | + bytes_written = wl_android_get_fcc_pwr_limit_2g(net, command, priv_cmd.total_len); |
---|
| 9449 | + } |
---|
| 9450 | + else if (strnicmp(command, CMD_SET_FCC_PWR_LIMIT_2G, |
---|
| 9451 | + strlen(CMD_SET_FCC_PWR_LIMIT_2G)) == 0) { |
---|
| 9452 | + bytes_written = wl_android_set_fcc_pwr_limit_2g(net, command); |
---|
| 9453 | + } |
---|
| 9454 | +#endif /* FCC_PWR_LIMIT_2G */ |
---|
| 9455 | + else if (strnicmp(command, CMD_GET_STA_INFO, strlen(CMD_GET_STA_INFO)) == 0) { |
---|
| 9456 | + bytes_written = wl_cfg80211_get_sta_info(net, command, priv_cmd.total_len); |
---|
| 9457 | + } |
---|
| 9458 | +#endif /* CUSTOMER_HW4_PRIVATE_CMD */ |
---|
| 9459 | + else if (strnicmp(command, CMD_MURX_BFE_CAP, |
---|
| 9460 | + strlen(CMD_MURX_BFE_CAP)) == 0) { |
---|
| 9461 | +#ifdef WL_MURX |
---|
| 9462 | + uint val = *(command + strlen(CMD_MURX_BFE_CAP) + 1) - '0'; |
---|
| 9463 | + bytes_written = wl_android_murx_bfe_cap(net, val); |
---|
| 9464 | +#else |
---|
| 9465 | + return BCME_UNSUPPORTED; |
---|
| 9466 | +#endif /* WL_MURX */ |
---|
| 9467 | + } |
---|
| 9468 | +#ifdef SUPPORT_AP_HIGHER_BEACONRATE |
---|
| 9469 | + else if (strnicmp(command, CMD_GET_AP_BASICRATE, strlen(CMD_GET_AP_BASICRATE)) == 0) { |
---|
| 9470 | + bytes_written = wl_android_get_ap_basicrate(net, command, priv_cmd.total_len); |
---|
| 9471 | + } |
---|
| 9472 | + else if (strnicmp(command, CMD_SET_AP_BEACONRATE, strlen(CMD_SET_AP_BEACONRATE)) == 0) { |
---|
| 9473 | + bytes_written = wl_android_set_ap_beaconrate(net, command); |
---|
| 9474 | + } |
---|
| 9475 | +#endif /* SUPPORT_AP_HIGHER_BEACONRATE */ |
---|
| 9476 | +#ifdef SUPPORT_AP_RADIO_PWRSAVE |
---|
| 9477 | + else if (strnicmp(command, CMD_SET_AP_RPS_PARAMS, strlen(CMD_SET_AP_RPS_PARAMS)) == 0) { |
---|
| 9478 | + bytes_written = wl_android_set_ap_rps_params(net, command, priv_cmd.total_len); |
---|
| 9479 | + } |
---|
| 9480 | + else if (strnicmp(command, CMD_SET_AP_RPS, strlen(CMD_SET_AP_RPS)) == 0) { |
---|
| 9481 | + bytes_written = wl_android_set_ap_rps(net, command, priv_cmd.total_len); |
---|
| 9482 | + } |
---|
| 9483 | + else if (strnicmp(command, CMD_GET_AP_RPS, strlen(CMD_GET_AP_RPS)) == 0) { |
---|
| 9484 | + bytes_written = wl_android_get_ap_rps(net, command, priv_cmd.total_len); |
---|
| 9485 | + } |
---|
| 9486 | +#endif /* SUPPORT_AP_RADIO_PWRSAVE */ |
---|
| 9487 | +#ifdef SUPPORT_RSSI_SUM_REPORT |
---|
| 9488 | + else if (strnicmp(command, CMD_SET_RSSI_LOGGING, strlen(CMD_SET_RSSI_LOGGING)) == 0) { |
---|
| 9489 | + bytes_written = wl_android_set_rssi_logging(net, command, priv_cmd.total_len); |
---|
| 9490 | + } |
---|
| 9491 | + else if (strnicmp(command, CMD_GET_RSSI_LOGGING, strlen(CMD_GET_RSSI_LOGGING)) == 0) { |
---|
| 9492 | + bytes_written = wl_android_get_rssi_logging(net, command, priv_cmd.total_len); |
---|
| 9493 | + } |
---|
| 9494 | + else if (strnicmp(command, CMD_GET_RSSI_PER_ANT, strlen(CMD_GET_RSSI_PER_ANT)) == 0) { |
---|
| 9495 | + bytes_written = wl_android_get_rssi_per_ant(net, command, priv_cmd.total_len); |
---|
| 9496 | + } |
---|
| 9497 | +#endif /* SUPPORT_RSSI_SUM_REPORT */ |
---|
| 9498 | +#if defined(DHD_ENABLE_BIGDATA_LOGGING) |
---|
| 9499 | + else if (strnicmp(command, CMD_GET_BSS_INFO, strlen(CMD_GET_BSS_INFO)) == 0) { |
---|
| 9500 | + bytes_written = wl_cfg80211_get_bss_info(net, command, priv_cmd.total_len); |
---|
| 9501 | + } |
---|
| 9502 | + else if (strnicmp(command, CMD_GET_ASSOC_REJECT_INFO, strlen(CMD_GET_ASSOC_REJECT_INFO)) |
---|
| 9503 | + == 0) { |
---|
| 9504 | + bytes_written = wl_cfg80211_get_connect_failed_status(net, command, |
---|
| 9505 | + priv_cmd.total_len); |
---|
| 9506 | + } |
---|
| 9507 | +#endif /* DHD_ENABLE_BIGDATA_LOGGING */ |
---|
| 9508 | +#if defined(SUPPORT_RANDOM_MAC_SCAN) |
---|
| 9509 | + else if (strnicmp(command, ENABLE_RANDOM_MAC, strlen(ENABLE_RANDOM_MAC)) == 0) { |
---|
| 9510 | + bytes_written = wl_cfg80211_set_random_mac(net, TRUE); |
---|
| 9511 | + } else if (strnicmp(command, DISABLE_RANDOM_MAC, strlen(DISABLE_RANDOM_MAC)) == 0) { |
---|
| 9512 | + bytes_written = wl_cfg80211_set_random_mac(net, FALSE); |
---|
| 9513 | + } |
---|
| 9514 | +#endif /* SUPPORT_RANDOM_MAC_SCAN */ |
---|
| 9515 | +#ifdef DHD_BANDSTEER |
---|
| 9516 | + else if (strnicmp(command, CMD_BANDSTEER, strlen(CMD_BANDSTEER)) == 0) { |
---|
| 9517 | + bytes_written = wl_android_set_bandsteer(net, command, priv_cmd.total_len); |
---|
| 9518 | + } |
---|
| 9519 | + else if (strnicmp(command, CMD_BANDSTEER_TRIGGER, strlen(CMD_BANDSTEER_TRIGGER)) == 0) { |
---|
| 9520 | + uint8 *p = command + strlen(CMD_BANDSTEER_TRIGGER)+1; |
---|
| 9521 | + struct ether_addr ea; |
---|
| 9522 | + char eabuf[ETHER_ADDR_STR_LEN]; |
---|
| 9523 | + bytes_written = 0; |
---|
| 9524 | + |
---|
| 9525 | + bzero((char *)eabuf, ETHER_ADDR_STR_LEN); |
---|
| 9526 | + strncpy(eabuf, p, ETHER_ADDR_STR_LEN - 1); |
---|
| 9527 | + |
---|
| 9528 | + if (!bcm_ether_atoe(eabuf, &ea)) { |
---|
| 9529 | + DHD_ERROR(("BANDSTEER: ERROR while parsing macaddr cmd %s - ignored\n", |
---|
| 9530 | + command)); |
---|
| 9531 | + return BCME_BADARG; |
---|
| 9532 | + } |
---|
| 9533 | + bytes_written = dhd_bandsteer_trigger_bandsteer(net, ea.octet); |
---|
| 9534 | + } |
---|
| 9535 | +#endif /* DHD_BANDSTEER */ |
---|
| 9536 | +#ifdef ENABLE_HOGSQS |
---|
| 9537 | + else if (strnicmp(command, CMD_AP_HOGSQS, strlen(CMD_AP_HOGSQS)) == 0) { |
---|
| 9538 | + bytes_written = wl_android_hogsqs(net, command, priv_cmd.total_len); |
---|
| 9539 | + } |
---|
| 9540 | +#endif /* ENABLE_HOGSQS */ |
---|
| 9541 | +#ifdef WL_NATOE |
---|
| 9542 | + else if (strnicmp(command, CMD_NATOE, strlen(CMD_NATOE)) == 0) { |
---|
| 9543 | + bytes_written = wl_android_process_natoe_cmd(net, command, |
---|
| 9544 | + priv_cmd.total_len); |
---|
| 9545 | + } |
---|
| 9546 | +#endif /* WL_NATOE */ |
---|
2660 | 9547 | #ifdef CONNECTION_STATISTICS |
---|
2661 | 9548 | else if (strnicmp(command, CMD_GET_CONNECTION_STATS, |
---|
2662 | 9549 | strlen(CMD_GET_CONNECTION_STATS)) == 0) { |
---|
2663 | 9550 | bytes_written = wl_android_get_connection_stats(net, command, |
---|
2664 | 9551 | priv_cmd.total_len); |
---|
2665 | 9552 | } |
---|
2666 | | -#endif |
---|
| 9553 | +#endif // endif |
---|
| 9554 | +#ifdef DHD_LOG_DUMP |
---|
| 9555 | + else if (strnicmp(command, CMD_NEW_DEBUG_PRINT_DUMP, |
---|
| 9556 | + strlen(CMD_NEW_DEBUG_PRINT_DUMP)) == 0) { |
---|
| 9557 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(net); |
---|
| 9558 | + /* check whether it has more command */ |
---|
| 9559 | + if (strnicmp(command + strlen(CMD_NEW_DEBUG_PRINT_DUMP), " ", 1) == 0) { |
---|
| 9560 | + /* compare unwanted/disconnected command */ |
---|
| 9561 | + if (strnicmp(command + strlen(CMD_NEW_DEBUG_PRINT_DUMP) + 1, |
---|
| 9562 | + SUBCMD_UNWANTED, strlen(SUBCMD_UNWANTED)) == 0) { |
---|
| 9563 | + dhd_log_dump_trigger(dhdp, CMD_UNWANTED); |
---|
| 9564 | + } else if (strnicmp(command + strlen(CMD_NEW_DEBUG_PRINT_DUMP) + 1, |
---|
| 9565 | + SUBCMD_DISCONNECTED, strlen(SUBCMD_DISCONNECTED)) == 0) { |
---|
| 9566 | + dhd_log_dump_trigger(dhdp, CMD_DISCONNECTED); |
---|
| 9567 | + } else { |
---|
| 9568 | + dhd_log_dump_trigger(dhdp, CMD_DEFAULT); |
---|
| 9569 | + } |
---|
| 9570 | + } else { |
---|
| 9571 | + dhd_log_dump_trigger(dhdp, CMD_DEFAULT); |
---|
| 9572 | + } |
---|
| 9573 | + } |
---|
| 9574 | +#endif /* DHD_LOG_DUMP */ |
---|
| 9575 | +#ifdef DHD_STATUS_LOGGING |
---|
| 9576 | + else if (strnicmp(command, CMD_DUMP_STATUS_LOG, strlen(CMD_DUMP_STATUS_LOG)) == 0) { |
---|
| 9577 | + dhd_statlog_dump_scr(wl_cfg80211_get_dhdp(net)); |
---|
| 9578 | + } |
---|
| 9579 | + else if (strnicmp(command, CMD_QUERY_STATUS_LOG, strlen(CMD_QUERY_STATUS_LOG)) == 0) { |
---|
| 9580 | + dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(net); |
---|
| 9581 | + bytes_written = dhd_statlog_query(dhdp, command, priv_cmd.total_len); |
---|
| 9582 | + } |
---|
| 9583 | +#endif /* DHD_STATUS_LOGGING */ |
---|
| 9584 | +#ifdef SET_PCIE_IRQ_CPU_CORE |
---|
| 9585 | + else if (strnicmp(command, CMD_PCIE_IRQ_CORE, strlen(CMD_PCIE_IRQ_CORE)) == 0) { |
---|
| 9586 | + int affinity_cmd = *(command + strlen(CMD_PCIE_IRQ_CORE) + 1) - '0'; |
---|
| 9587 | + wl_android_set_irq_cpucore(net, affinity_cmd); |
---|
| 9588 | + } |
---|
| 9589 | +#endif /* SET_PCIE_IRQ_CPU_CORE */ |
---|
| 9590 | +#if defined(DHD_HANG_SEND_UP_TEST) |
---|
| 9591 | + else if (strnicmp(command, CMD_MAKE_HANG, strlen(CMD_MAKE_HANG)) == 0) { |
---|
| 9592 | + int skip = strlen(CMD_MAKE_HANG) + 1; |
---|
| 9593 | + wl_android_make_hang_with_reason(net, (const char*)command+skip); |
---|
| 9594 | + } |
---|
| 9595 | +#endif /* DHD_HANG_SEND_UP_TEST */ |
---|
| 9596 | +#ifdef SUPPORT_LQCM |
---|
| 9597 | + else if (strnicmp(command, CMD_SET_LQCM_ENABLE, strlen(CMD_SET_LQCM_ENABLE)) == 0) { |
---|
| 9598 | + int lqcm_enable = *(command + strlen(CMD_SET_LQCM_ENABLE) + 1) - '0'; |
---|
| 9599 | + bytes_written = wl_android_lqcm_enable(net, lqcm_enable); |
---|
| 9600 | + } |
---|
| 9601 | + else if (strnicmp(command, CMD_GET_LQCM_REPORT, |
---|
| 9602 | + strlen(CMD_GET_LQCM_REPORT)) == 0) { |
---|
| 9603 | + bytes_written = wl_android_get_lqcm_report(net, command, |
---|
| 9604 | + priv_cmd.total_len); |
---|
| 9605 | + } |
---|
| 9606 | +#endif // endif |
---|
| 9607 | + else if (strnicmp(command, CMD_GET_SNR, strlen(CMD_GET_SNR)) == 0) { |
---|
| 9608 | + bytes_written = wl_android_get_snr(net, command, priv_cmd.total_len); |
---|
| 9609 | + } |
---|
| 9610 | +#ifdef WLADPS_PRIVATE_CMD |
---|
| 9611 | + else if (strnicmp(command, CMD_SET_ADPS, strlen(CMD_SET_ADPS)) == 0) { |
---|
| 9612 | + int skip = strlen(CMD_SET_ADPS) + 1; |
---|
| 9613 | + bytes_written = wl_android_set_adps_mode(net, (const char*)command+skip); |
---|
| 9614 | + } |
---|
| 9615 | + else if (strnicmp(command, CMD_GET_ADPS, strlen(CMD_GET_ADPS)) == 0) { |
---|
| 9616 | + bytes_written = wl_android_get_adps_mode(net, command, priv_cmd.total_len); |
---|
| 9617 | + } |
---|
| 9618 | +#endif /* WLADPS_PRIVATE_CMD */ |
---|
| 9619 | +#ifdef DHD_PKT_LOGGING |
---|
| 9620 | + else if (strnicmp(command, CMD_PKTLOG_FILTER_ENABLE, |
---|
| 9621 | + strlen(CMD_PKTLOG_FILTER_ENABLE)) == 0) { |
---|
| 9622 | + bytes_written = wl_android_pktlog_filter_enable(net, command, priv_cmd.total_len); |
---|
| 9623 | + } |
---|
| 9624 | + else if (strnicmp(command, CMD_PKTLOG_FILTER_DISABLE, |
---|
| 9625 | + strlen(CMD_PKTLOG_FILTER_DISABLE)) == 0) { |
---|
| 9626 | + bytes_written = wl_android_pktlog_filter_disable(net, command, priv_cmd.total_len); |
---|
| 9627 | + } |
---|
| 9628 | + else if (strnicmp(command, CMD_PKTLOG_FILTER_PATTERN_ENABLE, |
---|
| 9629 | + strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE)) == 0) { |
---|
| 9630 | + bytes_written = |
---|
| 9631 | + wl_android_pktlog_filter_pattern_enable(net, command, priv_cmd.total_len); |
---|
| 9632 | + } |
---|
| 9633 | + else if (strnicmp(command, CMD_PKTLOG_FILTER_PATTERN_DISABLE, |
---|
| 9634 | + strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE)) == 0) { |
---|
| 9635 | + bytes_written = |
---|
| 9636 | + wl_android_pktlog_filter_pattern_disable(net, command, priv_cmd.total_len); |
---|
| 9637 | + } |
---|
| 9638 | + else if (strnicmp(command, CMD_PKTLOG_FILTER_ADD, strlen(CMD_PKTLOG_FILTER_ADD)) == 0) { |
---|
| 9639 | + bytes_written = wl_android_pktlog_filter_add(net, command, priv_cmd.total_len); |
---|
| 9640 | + } |
---|
| 9641 | + else if (strnicmp(command, CMD_PKTLOG_FILTER_DEL, strlen(CMD_PKTLOG_FILTER_DEL)) == 0) { |
---|
| 9642 | + bytes_written = wl_android_pktlog_filter_del(net, command, priv_cmd.total_len); |
---|
| 9643 | + } |
---|
| 9644 | + else if (strnicmp(command, CMD_PKTLOG_FILTER_INFO, strlen(CMD_PKTLOG_FILTER_INFO)) == 0) { |
---|
| 9645 | + bytes_written = wl_android_pktlog_filter_info(net, command, priv_cmd.total_len); |
---|
| 9646 | + } |
---|
| 9647 | + else if (strnicmp(command, CMD_PKTLOG_START, strlen(CMD_PKTLOG_START)) == 0) { |
---|
| 9648 | + bytes_written = wl_android_pktlog_start(net, command, priv_cmd.total_len); |
---|
| 9649 | + } |
---|
| 9650 | + else if (strnicmp(command, CMD_PKTLOG_STOP, strlen(CMD_PKTLOG_STOP)) == 0) { |
---|
| 9651 | + bytes_written = wl_android_pktlog_stop(net, command, priv_cmd.total_len); |
---|
| 9652 | + } |
---|
| 9653 | + else if (strnicmp(command, CMD_PKTLOG_FILTER_EXIST, strlen(CMD_PKTLOG_FILTER_EXIST)) == 0) { |
---|
| 9654 | + bytes_written = wl_android_pktlog_filter_exist(net, command, priv_cmd.total_len); |
---|
| 9655 | + } |
---|
| 9656 | + else if (strnicmp(command, CMD_PKTLOG_MINMIZE_ENABLE, |
---|
| 9657 | + strlen(CMD_PKTLOG_MINMIZE_ENABLE)) == 0) { |
---|
| 9658 | + bytes_written = wl_android_pktlog_minmize_enable(net, command, priv_cmd.total_len); |
---|
| 9659 | + } |
---|
| 9660 | + else if (strnicmp(command, CMD_PKTLOG_MINMIZE_DISABLE, |
---|
| 9661 | + strlen(CMD_PKTLOG_MINMIZE_DISABLE)) == 0) { |
---|
| 9662 | + bytes_written = wl_android_pktlog_minmize_disable(net, command, priv_cmd.total_len); |
---|
| 9663 | + } |
---|
| 9664 | + else if (strnicmp(command, CMD_PKTLOG_CHANGE_SIZE, |
---|
| 9665 | + strlen(CMD_PKTLOG_CHANGE_SIZE)) == 0) { |
---|
| 9666 | + bytes_written = wl_android_pktlog_change_size(net, command, priv_cmd.total_len); |
---|
| 9667 | + } |
---|
| 9668 | +#endif /* DHD_PKT_LOGGING */ |
---|
| 9669 | + else if (strnicmp(command, CMD_DEBUG_VERBOSE, strlen(CMD_DEBUG_VERBOSE)) == 0) { |
---|
| 9670 | + int verbose_level = *(command + strlen(CMD_DEBUG_VERBOSE) + 1) - '0'; |
---|
| 9671 | + bytes_written = wl_cfg80211_set_dbg_verbose(net, verbose_level); |
---|
| 9672 | + } |
---|
| 9673 | +#ifdef DHD_EVENT_LOG_FILTER |
---|
| 9674 | + else if (strnicmp(command, CMD_EWP_FILTER, |
---|
| 9675 | + strlen(CMD_EWP_FILTER)) == 0) { |
---|
| 9676 | + bytes_written = wl_android_ewp_filter(net, command, priv_cmd.total_len); |
---|
| 9677 | + } |
---|
| 9678 | +#endif /* DHD_EVENT_LOG_FILTER */ |
---|
| 9679 | +#ifdef WL_BCNRECV |
---|
| 9680 | + else if (strnicmp(command, CMD_BEACON_RECV, |
---|
| 9681 | + strlen(CMD_BEACON_RECV)) == 0) { |
---|
| 9682 | + char *data = (command + strlen(CMD_BEACON_RECV) + 1); |
---|
| 9683 | + bytes_written = wl_android_bcnrecv_config(net, |
---|
| 9684 | + data, priv_cmd.total_len); |
---|
| 9685 | + } |
---|
| 9686 | +#endif /* WL_BCNRECV */ |
---|
| 9687 | +#ifdef WL_MBO |
---|
| 9688 | + else if (strnicmp(command, CMD_MBO, strlen(CMD_MBO)) == 0) { |
---|
| 9689 | + bytes_written = wl_android_process_mbo_cmd(net, command, |
---|
| 9690 | + priv_cmd.total_len); |
---|
| 9691 | + } |
---|
| 9692 | +#endif /* WL_MBO */ |
---|
| 9693 | +#ifdef WL_CAC_TS |
---|
| 9694 | + else if (strnicmp(command, CMD_CAC_TSPEC, |
---|
| 9695 | + strlen(CMD_CAC_TSPEC)) == 0) { |
---|
| 9696 | + char *data = (command + strlen(CMD_CAC_TSPEC) + 1); |
---|
| 9697 | + bytes_written = wl_android_cac_ts_config(net, |
---|
| 9698 | + data, priv_cmd.total_len); |
---|
| 9699 | + } |
---|
| 9700 | +#endif /* WL_CAC_TS */ |
---|
| 9701 | +#ifdef WL_GET_CU |
---|
| 9702 | + else if (strnicmp(command, CMD_GET_CHAN_UTIL, |
---|
| 9703 | + strlen(CMD_GET_CHAN_UTIL)) == 0) { |
---|
| 9704 | + bytes_written = wl_android_get_channel_util(net, |
---|
| 9705 | + command, priv_cmd.total_len); |
---|
| 9706 | + } |
---|
| 9707 | +#endif /* WL_GET_CU */ |
---|
| 9708 | + else if (strnicmp(command, CMD_CHANNEL_WIDTH, strlen(CMD_CHANNEL_WIDTH)) == 0) { |
---|
| 9709 | + bytes_written = wl_android_set_channel_width(net, command, priv_cmd.total_len); |
---|
| 9710 | + } |
---|
| 9711 | + else if (strnicmp(command, CMD_TRANSITION_DISABLE, strlen(CMD_TRANSITION_DISABLE)) == 0) { |
---|
| 9712 | + int transition_disabled = *(command + strlen(CMD_TRANSITION_DISABLE) + 1) - '0'; |
---|
| 9713 | + bytes_written = wl_cfg80211_set_transition_mode(net, transition_disabled); |
---|
| 9714 | + } |
---|
| 9715 | + else if (strnicmp(command, CMD_SAE_PWE, strlen(CMD_SAE_PWE)) == 0) { |
---|
| 9716 | + u8 sae_pwe = *(command + strlen(CMD_SAE_PWE) + 1) - '0'; |
---|
| 9717 | + bytes_written = wl_cfg80211_set_sae_pwe(net, sae_pwe); |
---|
| 9718 | + } |
---|
| 9719 | + else if (strnicmp(command, CMD_MAXASSOC, strlen(CMD_MAXASSOC)) == 0) { |
---|
| 9720 | + bytes_written = wl_android_set_maxassoc_limit(net, command, priv_cmd.total_len); |
---|
| 9721 | + } |
---|
| 9722 | + else if (strnicmp(command, CMD_SCAN_PROTECT_BSS, strlen(CMD_SCAN_PROTECT_BSS)) == 0) { |
---|
| 9723 | + bytes_written = wl_android_scan_protect_bss(net, command, priv_cmd.total_len); |
---|
| 9724 | + } |
---|
2667 | 9725 | else { |
---|
2668 | 9726 | DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command)); |
---|
2669 | | - snprintf(command, 5, "FAIL"); |
---|
2670 | | - bytes_written = strlen("FAIL"); |
---|
| 9727 | + bytes_written = scnprintf(command, sizeof("FAIL"), "FAIL"); |
---|
2671 | 9728 | } |
---|
2672 | 9729 | |
---|
2673 | 9730 | return bytes_written; |
---|
.. | .. |
---|
2681 | 9738 | dhd_download_fw_on_driverload = FALSE; |
---|
2682 | 9739 | #endif /* ENABLE_INSMOD_NO_FW_LOAD */ |
---|
2683 | 9740 | if (!iface_name[0]) { |
---|
2684 | | - memset(iface_name, 0, IFNAMSIZ); |
---|
| 9741 | + bzero(iface_name, IFNAMSIZ); |
---|
2685 | 9742 | bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ); |
---|
2686 | 9743 | } |
---|
2687 | 9744 | |
---|
| 9745 | +#ifdef CUSTOMER_HW4_DEBUG |
---|
| 9746 | + g_assert_type = 1; |
---|
| 9747 | +#endif /* CUSTOMER_HW4_DEBUG */ |
---|
| 9748 | + |
---|
| 9749 | +#ifdef WL_GENL |
---|
| 9750 | + wl_genl_init(); |
---|
| 9751 | +#endif // endif |
---|
2688 | 9752 | wl_netlink_init(); |
---|
2689 | 9753 | |
---|
2690 | 9754 | return ret; |
---|
.. | .. |
---|
2695 | 9759 | int ret = 0; |
---|
2696 | 9760 | struct io_cfg *cur, *q; |
---|
2697 | 9761 | |
---|
| 9762 | +#ifdef WL_GENL |
---|
| 9763 | + wl_genl_deinit(); |
---|
| 9764 | +#endif /* WL_GENL */ |
---|
2698 | 9765 | wl_netlink_deinit(); |
---|
2699 | 9766 | |
---|
| 9767 | + GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); |
---|
2700 | 9768 | list_for_each_entry_safe(cur, q, &miracast_resume_list, list) { |
---|
| 9769 | + GCC_DIAGNOSTIC_POP(); |
---|
2701 | 9770 | list_del(&cur->list); |
---|
2702 | 9771 | kfree(cur); |
---|
2703 | 9772 | } |
---|
.. | .. |
---|
2710 | 9779 | |
---|
2711 | 9780 | #ifdef ENABLE_4335BT_WAR |
---|
2712 | 9781 | bcm_bt_unlock(lock_cookie_wifi); |
---|
2713 | | - printk("%s: btlock released\n", __FUNCTION__); |
---|
| 9782 | + printk("wl_android_post_init: btlock released\n"); |
---|
2714 | 9783 | #endif /* ENABLE_4335BT_WAR */ |
---|
2715 | 9784 | |
---|
2716 | 9785 | if (!dhd_download_fw_on_driverload) |
---|
2717 | 9786 | g_wifi_on = FALSE; |
---|
2718 | 9787 | } |
---|
| 9788 | + |
---|
| 9789 | +#ifdef WL_GENL |
---|
| 9790 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) |
---|
| 9791 | +static int |
---|
| 9792 | +wl_genl_register_family_with_ops_groups(struct genl_family *family, |
---|
| 9793 | + const struct genl_ops *ops, size_t n_ops, |
---|
| 9794 | + const struct genl_multicast_group *mcgrps, |
---|
| 9795 | + size_t n_mcgrps) |
---|
| 9796 | +{ |
---|
| 9797 | + family->module = THIS_MODULE; |
---|
| 9798 | + family->ops = ops; |
---|
| 9799 | + family->n_ops = n_ops; |
---|
| 9800 | + family->mcgrps = mcgrps; |
---|
| 9801 | + family->n_mcgrps = n_mcgrps; |
---|
| 9802 | + return genl_register_family(family); |
---|
| 9803 | +} |
---|
| 9804 | +#endif // endif |
---|
| 9805 | + |
---|
| 9806 | +/* Generic Netlink Initializaiton */ |
---|
| 9807 | +static int wl_genl_init(void) |
---|
| 9808 | +{ |
---|
| 9809 | + int ret; |
---|
| 9810 | + |
---|
| 9811 | + WL_DBG(("GEN Netlink Init\n\n")); |
---|
| 9812 | + |
---|
| 9813 | +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) |
---|
| 9814 | + /* register new family */ |
---|
| 9815 | + ret = genl_register_family(&wl_genl_family); |
---|
| 9816 | + if (ret != 0) |
---|
| 9817 | + goto failure; |
---|
| 9818 | + |
---|
| 9819 | + /* register functions (commands) of the new family */ |
---|
| 9820 | + ret = genl_register_ops(&wl_genl_family, &wl_genl_ops); |
---|
| 9821 | + if (ret != 0) { |
---|
| 9822 | + WL_ERR(("register ops failed: %i\n", ret)); |
---|
| 9823 | + genl_unregister_family(&wl_genl_family); |
---|
| 9824 | + goto failure; |
---|
| 9825 | + } |
---|
| 9826 | + |
---|
| 9827 | + ret = genl_register_mc_group(&wl_genl_family, &wl_genl_mcast); |
---|
| 9828 | +#elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)) && \ |
---|
| 9829 | + (LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0))) |
---|
| 9830 | + ret = genl_register_family_with_ops_groups(&wl_genl_family, wl_genl_ops, wl_genl_mcast); |
---|
| 9831 | +#else |
---|
| 9832 | + ret = wl_genl_register_family_with_ops_groups(&wl_genl_family, wl_genl_ops, |
---|
| 9833 | + ARRAY_SIZE(wl_genl_ops), wl_genl_mcast, ARRAY_SIZE(wl_genl_mcast)); |
---|
| 9834 | +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */ |
---|
| 9835 | + if (ret != 0) { |
---|
| 9836 | + WL_ERR(("register mc_group failed: %i\n", ret)); |
---|
| 9837 | +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) |
---|
| 9838 | + genl_unregister_ops(&wl_genl_family, &wl_genl_ops); |
---|
| 9839 | +#endif // endif |
---|
| 9840 | + genl_unregister_family(&wl_genl_family); |
---|
| 9841 | + goto failure; |
---|
| 9842 | + } |
---|
| 9843 | + |
---|
| 9844 | + return 0; |
---|
| 9845 | + |
---|
| 9846 | +failure: |
---|
| 9847 | + WL_ERR(("Registering Netlink failed!!\n")); |
---|
| 9848 | + return -1; |
---|
| 9849 | +} |
---|
| 9850 | + |
---|
| 9851 | +/* Generic netlink deinit */ |
---|
| 9852 | +static int wl_genl_deinit(void) |
---|
| 9853 | +{ |
---|
| 9854 | + |
---|
| 9855 | +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) |
---|
| 9856 | + if (genl_unregister_ops(&wl_genl_family, &wl_genl_ops) < 0) |
---|
| 9857 | + WL_ERR(("Unregister wl_genl_ops failed\n")); |
---|
| 9858 | +#endif // endif |
---|
| 9859 | + if (genl_unregister_family(&wl_genl_family) < 0) |
---|
| 9860 | + WL_ERR(("Unregister wl_genl_ops failed\n")); |
---|
| 9861 | + |
---|
| 9862 | + return 0; |
---|
| 9863 | +} |
---|
| 9864 | + |
---|
| 9865 | +s32 wl_event_to_bcm_event(u16 event_type) |
---|
| 9866 | +{ |
---|
| 9867 | + u16 event = -1; |
---|
| 9868 | + |
---|
| 9869 | + switch (event_type) { |
---|
| 9870 | + case WLC_E_SERVICE_FOUND: |
---|
| 9871 | + event = BCM_E_SVC_FOUND; |
---|
| 9872 | + break; |
---|
| 9873 | + case WLC_E_P2PO_ADD_DEVICE: |
---|
| 9874 | + event = BCM_E_DEV_FOUND; |
---|
| 9875 | + break; |
---|
| 9876 | + case WLC_E_P2PO_DEL_DEVICE: |
---|
| 9877 | + event = BCM_E_DEV_LOST; |
---|
| 9878 | + break; |
---|
| 9879 | + /* Above events are supported from BCM Supp ver 47 Onwards */ |
---|
| 9880 | +#ifdef BT_WIFI_HANDOVER |
---|
| 9881 | + case WLC_E_BT_WIFI_HANDOVER_REQ: |
---|
| 9882 | + event = BCM_E_DEV_BT_WIFI_HO_REQ; |
---|
| 9883 | + break; |
---|
| 9884 | +#endif /* BT_WIFI_HANDOVER */ |
---|
| 9885 | + |
---|
| 9886 | + default: |
---|
| 9887 | + WL_ERR(("Event not supported\n")); |
---|
| 9888 | + } |
---|
| 9889 | + |
---|
| 9890 | + return event; |
---|
| 9891 | +} |
---|
| 9892 | + |
---|
| 9893 | +s32 |
---|
| 9894 | +wl_genl_send_msg( |
---|
| 9895 | + struct net_device *ndev, |
---|
| 9896 | + u32 event_type, |
---|
| 9897 | + const u8 *buf, |
---|
| 9898 | + u16 len, |
---|
| 9899 | + u8 *subhdr, |
---|
| 9900 | + u16 subhdr_len) |
---|
| 9901 | +{ |
---|
| 9902 | + int ret = 0; |
---|
| 9903 | + struct sk_buff *skb; |
---|
| 9904 | + void *msg; |
---|
| 9905 | + u32 attr_type = 0; |
---|
| 9906 | + bcm_event_hdr_t *hdr = NULL; |
---|
| 9907 | + int mcast = 1; /* By default sent as mutlicast type */ |
---|
| 9908 | + int pid = 0; |
---|
| 9909 | + u8 *ptr = NULL, *p = NULL; |
---|
| 9910 | + u32 tot_len = sizeof(bcm_event_hdr_t) + subhdr_len + len; |
---|
| 9911 | + gfp_t kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; |
---|
| 9912 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 9913 | + |
---|
| 9914 | + WL_DBG(("Enter \n")); |
---|
| 9915 | + |
---|
| 9916 | + /* Decide between STRING event and Data event */ |
---|
| 9917 | + if (event_type == 0) |
---|
| 9918 | + attr_type = BCM_GENL_ATTR_STRING; |
---|
| 9919 | + else |
---|
| 9920 | + attr_type = BCM_GENL_ATTR_MSG; |
---|
| 9921 | + |
---|
| 9922 | + skb = genlmsg_new(NLMSG_GOODSIZE, kflags); |
---|
| 9923 | + if (skb == NULL) { |
---|
| 9924 | + ret = -ENOMEM; |
---|
| 9925 | + goto out; |
---|
| 9926 | + } |
---|
| 9927 | + |
---|
| 9928 | + msg = genlmsg_put(skb, 0, 0, &wl_genl_family, 0, BCM_GENL_CMD_MSG); |
---|
| 9929 | + if (msg == NULL) { |
---|
| 9930 | + ret = -ENOMEM; |
---|
| 9931 | + goto out; |
---|
| 9932 | + } |
---|
| 9933 | + |
---|
| 9934 | + if (attr_type == BCM_GENL_ATTR_STRING) { |
---|
| 9935 | + /* Add a BCM_GENL_MSG attribute. Since it is specified as a string. |
---|
| 9936 | + * make sure it is null terminated |
---|
| 9937 | + */ |
---|
| 9938 | + if (subhdr || subhdr_len) { |
---|
| 9939 | + WL_ERR(("No sub hdr support for the ATTR STRING type \n")); |
---|
| 9940 | + ret = -EINVAL; |
---|
| 9941 | + goto out; |
---|
| 9942 | + } |
---|
| 9943 | + |
---|
| 9944 | + ret = nla_put_string(skb, BCM_GENL_ATTR_STRING, buf); |
---|
| 9945 | + if (ret != 0) { |
---|
| 9946 | + WL_ERR(("nla_put_string failed\n")); |
---|
| 9947 | + goto out; |
---|
| 9948 | + } |
---|
| 9949 | + } else { |
---|
| 9950 | + /* ATTR_MSG */ |
---|
| 9951 | + |
---|
| 9952 | + /* Create a single buffer for all */ |
---|
| 9953 | + p = ptr = (u8 *)MALLOCZ(cfg->osh, tot_len); |
---|
| 9954 | + if (!ptr) { |
---|
| 9955 | + ret = -ENOMEM; |
---|
| 9956 | + WL_ERR(("ENOMEM!!\n")); |
---|
| 9957 | + goto out; |
---|
| 9958 | + } |
---|
| 9959 | + |
---|
| 9960 | + /* Include the bcm event header */ |
---|
| 9961 | + hdr = (bcm_event_hdr_t *)ptr; |
---|
| 9962 | + hdr->event_type = wl_event_to_bcm_event(event_type); |
---|
| 9963 | + hdr->len = len + subhdr_len; |
---|
| 9964 | + ptr += sizeof(bcm_event_hdr_t); |
---|
| 9965 | + |
---|
| 9966 | + /* Copy subhdr (if any) */ |
---|
| 9967 | + if (subhdr && subhdr_len) { |
---|
| 9968 | + memcpy(ptr, subhdr, subhdr_len); |
---|
| 9969 | + ptr += subhdr_len; |
---|
| 9970 | + } |
---|
| 9971 | + |
---|
| 9972 | + /* Copy the data */ |
---|
| 9973 | + if (buf && len) { |
---|
| 9974 | + memcpy(ptr, buf, len); |
---|
| 9975 | + } |
---|
| 9976 | + |
---|
| 9977 | + ret = nla_put(skb, BCM_GENL_ATTR_MSG, tot_len, p); |
---|
| 9978 | + if (ret != 0) { |
---|
| 9979 | + WL_ERR(("nla_put_string failed\n")); |
---|
| 9980 | + goto out; |
---|
| 9981 | + } |
---|
| 9982 | + } |
---|
| 9983 | + |
---|
| 9984 | + if (mcast) { |
---|
| 9985 | + int err = 0; |
---|
| 9986 | + /* finalize the message */ |
---|
| 9987 | + genlmsg_end(skb, msg); |
---|
| 9988 | + /* NETLINK_CB(skb).dst_group = 1; */ |
---|
| 9989 | + |
---|
| 9990 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) |
---|
| 9991 | + if ((err = genlmsg_multicast(skb, 0, wl_genl_mcast.id, GFP_ATOMIC)) < 0) |
---|
| 9992 | +#else |
---|
| 9993 | + if ((err = genlmsg_multicast(&wl_genl_family, skb, 0, 0, GFP_ATOMIC)) < 0) |
---|
| 9994 | +#endif // endif |
---|
| 9995 | + WL_ERR(("genlmsg_multicast for attr(%d) failed. Error:%d \n", |
---|
| 9996 | + attr_type, err)); |
---|
| 9997 | + else |
---|
| 9998 | + WL_DBG(("Multicast msg sent successfully. attr_type:%d len:%d \n", |
---|
| 9999 | + attr_type, tot_len)); |
---|
| 10000 | + } else { |
---|
| 10001 | + NETLINK_CB(skb).dst_group = 0; /* Not in multicast group */ |
---|
| 10002 | + |
---|
| 10003 | + /* finalize the message */ |
---|
| 10004 | + genlmsg_end(skb, msg); |
---|
| 10005 | + |
---|
| 10006 | + /* send the message back */ |
---|
| 10007 | + if (genlmsg_unicast(&init_net, skb, pid) < 0) |
---|
| 10008 | + WL_ERR(("genlmsg_unicast failed\n")); |
---|
| 10009 | + } |
---|
| 10010 | + |
---|
| 10011 | +out: |
---|
| 10012 | + if (p) { |
---|
| 10013 | + MFREE(cfg->osh, p, tot_len); |
---|
| 10014 | + } |
---|
| 10015 | + if (ret) |
---|
| 10016 | + nlmsg_free(skb); |
---|
| 10017 | + |
---|
| 10018 | + return ret; |
---|
| 10019 | +} |
---|
| 10020 | + |
---|
| 10021 | +static s32 |
---|
| 10022 | +wl_genl_handle_msg( |
---|
| 10023 | + struct sk_buff *skb, |
---|
| 10024 | + struct genl_info *info) |
---|
| 10025 | +{ |
---|
| 10026 | + struct nlattr *na; |
---|
| 10027 | + u8 *data = NULL; |
---|
| 10028 | + |
---|
| 10029 | + WL_DBG(("Enter \n")); |
---|
| 10030 | + |
---|
| 10031 | + if (info == NULL) { |
---|
| 10032 | + return -EINVAL; |
---|
| 10033 | + } |
---|
| 10034 | + |
---|
| 10035 | + na = info->attrs[BCM_GENL_ATTR_MSG]; |
---|
| 10036 | + if (!na) { |
---|
| 10037 | + WL_ERR(("nlattribute NULL\n")); |
---|
| 10038 | + return -EINVAL; |
---|
| 10039 | + } |
---|
| 10040 | + |
---|
| 10041 | + data = (char *)nla_data(na); |
---|
| 10042 | + if (!data) { |
---|
| 10043 | + WL_ERR(("Invalid data\n")); |
---|
| 10044 | + return -EINVAL; |
---|
| 10045 | + } else { |
---|
| 10046 | + /* Handle the data */ |
---|
| 10047 | +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) || defined(WL_COMPAT_WIRELESS) |
---|
| 10048 | + WL_DBG(("%s: Data received from pid (%d) \n", __func__, |
---|
| 10049 | + info->snd_pid)); |
---|
| 10050 | +#else |
---|
| 10051 | + WL_DBG(("%s: Data received from pid (%d) \n", __func__, |
---|
| 10052 | + info->snd_portid)); |
---|
| 10053 | +#endif /* (LINUX_VERSION < VERSION(3, 7, 0) || WL_COMPAT_WIRELESS */ |
---|
| 10054 | + } |
---|
| 10055 | + |
---|
| 10056 | + return 0; |
---|
| 10057 | +} |
---|
| 10058 | +#endif /* WL_GENL */ |
---|
| 10059 | + |
---|
| 10060 | +int wl_fatal_error(void * wl, int rc) |
---|
| 10061 | +{ |
---|
| 10062 | + return FALSE; |
---|
| 10063 | +} |
---|
| 10064 | + |
---|
| 10065 | +#if defined(BT_OVER_SDIO) |
---|
| 10066 | +void |
---|
| 10067 | +wl_android_set_wifi_on_flag(bool enable) |
---|
| 10068 | +{ |
---|
| 10069 | + g_wifi_on = enable; |
---|
| 10070 | +} |
---|
| 10071 | +#endif /* BT_OVER_SDIO */ |
---|
| 10072 | + |
---|
| 10073 | +#ifdef WL_STATIC_IF |
---|
| 10074 | +struct net_device * |
---|
| 10075 | +wl_cfg80211_register_static_if(struct bcm_cfg80211 *cfg, u16 iftype, char *ifname, int ifidx) |
---|
| 10076 | +{ |
---|
| 10077 | + struct net_device *ndev; |
---|
| 10078 | + struct wireless_dev *wdev = NULL; |
---|
| 10079 | + u8 mac_addr[ETH_ALEN]; |
---|
| 10080 | + struct net_device *primary_ndev; |
---|
| 10081 | + |
---|
| 10082 | + WL_INFORM_MEM(("[STATIC_IF] Enter (%s) iftype:%d\n", ifname, iftype)); |
---|
| 10083 | + |
---|
| 10084 | + if (!cfg) { |
---|
| 10085 | + WL_ERR(("cfg null\n")); |
---|
| 10086 | + return NULL; |
---|
| 10087 | + } |
---|
| 10088 | + |
---|
| 10089 | + /* Use primary mac with locally admin bit set */ |
---|
| 10090 | + primary_ndev = bcmcfg_to_prmry_ndev(cfg); |
---|
| 10091 | + (void)memcpy_s(mac_addr, ETH_ALEN, primary_ndev->dev_addr, ETH_ALEN); |
---|
| 10092 | + mac_addr[0] |= 0x02; |
---|
| 10093 | + |
---|
| 10094 | + ndev = wl_cfg80211_allocate_if(cfg, ifidx, ifname, mac_addr, |
---|
| 10095 | + WL_BSSIDX_MAX, NULL); |
---|
| 10096 | + if (unlikely(!ndev)) { |
---|
| 10097 | + WL_ERR(("Failed to allocate static_if\n")); |
---|
| 10098 | + goto fail; |
---|
| 10099 | + } |
---|
| 10100 | + wdev = (struct wireless_dev *)MALLOCZ(cfg->osh, sizeof(*wdev)); |
---|
| 10101 | + if (unlikely(!wdev)) { |
---|
| 10102 | + WL_ERR(("Failed to allocate wdev for static_if\n")); |
---|
| 10103 | + goto fail; |
---|
| 10104 | + } |
---|
| 10105 | + |
---|
| 10106 | + wdev->wiphy = cfg->wdev->wiphy; |
---|
| 10107 | + wdev->iftype = iftype; |
---|
| 10108 | + |
---|
| 10109 | + ndev->ieee80211_ptr = wdev; |
---|
| 10110 | + SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); |
---|
| 10111 | + wdev->netdev = ndev; |
---|
| 10112 | + |
---|
| 10113 | + if (wl_cfg80211_register_if(cfg, ifidx, |
---|
| 10114 | + ndev, TRUE) != BCME_OK) { |
---|
| 10115 | + WL_ERR(("ndev registration failed!\n")); |
---|
| 10116 | + goto fail; |
---|
| 10117 | + } |
---|
| 10118 | + |
---|
| 10119 | + cfg->static_ndev[ifidx - DHD_MAX_IFS] = ndev; |
---|
| 10120 | + cfg->static_ndev_state[ifidx - DHD_MAX_IFS] = NDEV_STATE_OS_IF_CREATED; |
---|
| 10121 | + wl_cfg80211_update_iflist_info(cfg, ndev, ifidx, NULL, WL_BSSIDX_MAX, |
---|
| 10122 | + ifname, NDEV_STATE_OS_IF_CREATED); |
---|
| 10123 | + WL_INFORM_MEM(("Static I/F (%s) Registered\n", ndev->name)); |
---|
| 10124 | + return ndev; |
---|
| 10125 | + |
---|
| 10126 | +fail: |
---|
| 10127 | + wl_cfg80211_remove_if(cfg, ifidx, ndev, false); |
---|
| 10128 | + return NULL; |
---|
| 10129 | +} |
---|
| 10130 | + |
---|
| 10131 | +void |
---|
| 10132 | +wl_cfg80211_unregister_static_if(struct bcm_cfg80211 *cfg) |
---|
| 10133 | +{ |
---|
| 10134 | + int i = 0; |
---|
| 10135 | + WL_INFORM_MEM(("[STATIC_IF] Enter\n")); |
---|
| 10136 | + for (i = 0; i < DHD_NUM_STATIC_IFACES; i++) { |
---|
| 10137 | + if (!cfg || !cfg->static_ndev[i]) { |
---|
| 10138 | + WL_ERR(("invalid input\n")); |
---|
| 10139 | + continue; |
---|
| 10140 | + } |
---|
| 10141 | + |
---|
| 10142 | + /* wdev free will happen from notifier context */ |
---|
| 10143 | + /* free_netdev(cfg->static_ndev); |
---|
| 10144 | + */ |
---|
| 10145 | + unregister_netdev(cfg->static_ndev[i]); |
---|
| 10146 | + } |
---|
| 10147 | +} |
---|
| 10148 | + |
---|
| 10149 | +s32 |
---|
| 10150 | +wl_cfg80211_static_if_open(struct net_device *net) |
---|
| 10151 | +{ |
---|
| 10152 | + struct wireless_dev *wdev = NULL; |
---|
| 10153 | + struct bcm_cfg80211 *cfg = wl_get_cfg(net); |
---|
| 10154 | + struct net_device *primary_ndev = bcmcfg_to_prmry_ndev(cfg); |
---|
| 10155 | + u16 iftype = net->ieee80211_ptr ? net->ieee80211_ptr->iftype : 0; |
---|
| 10156 | + u16 wl_iftype, wl_mode; |
---|
| 10157 | + |
---|
| 10158 | + WL_INFORM_MEM(("[STATIC_IF] dev_open ndev %p and wdev %p\n", net, net->ieee80211_ptr)); |
---|
| 10159 | + ASSERT(is_static_iface(cfg, net)); |
---|
| 10160 | + |
---|
| 10161 | + if (cfg80211_to_wl_iftype(iftype, &wl_iftype, &wl_mode) < 0) { |
---|
| 10162 | + return BCME_ERROR; |
---|
| 10163 | + } |
---|
| 10164 | + if (static_if_ndev_get_state(cfg, net) != NDEV_STATE_FW_IF_CREATED) { |
---|
| 10165 | + wdev = wl_cfg80211_add_if(cfg, primary_ndev, wl_iftype, net->name, NULL); |
---|
| 10166 | + if (!wdev) { |
---|
| 10167 | + WL_ERR(("[STATIC_IF] wdev is NULL, can't proceed")); |
---|
| 10168 | + return BCME_ERROR; |
---|
| 10169 | + } |
---|
| 10170 | + } else { |
---|
| 10171 | + WL_INFORM_MEM(("Fw IF for static netdev already created\n")); |
---|
| 10172 | + } |
---|
| 10173 | + |
---|
| 10174 | + return BCME_OK; |
---|
| 10175 | +} |
---|
| 10176 | + |
---|
| 10177 | +s32 |
---|
| 10178 | +wl_cfg80211_static_if_close(struct net_device *net) |
---|
| 10179 | +{ |
---|
| 10180 | + int ret = BCME_OK; |
---|
| 10181 | + struct bcm_cfg80211 *cfg = wl_get_cfg(net); |
---|
| 10182 | + struct net_device *primary_ndev = bcmcfg_to_prmry_ndev(cfg); |
---|
| 10183 | + |
---|
| 10184 | + if (static_if_ndev_get_state(cfg, net) == NDEV_STATE_FW_IF_CREATED) { |
---|
| 10185 | + if (mutex_is_locked(&cfg->if_sync) == TRUE) { |
---|
| 10186 | + ret = _wl_cfg80211_del_if(cfg, primary_ndev, net->ieee80211_ptr, net->name); |
---|
| 10187 | + } else { |
---|
| 10188 | + ret = wl_cfg80211_del_if(cfg, primary_ndev, net->ieee80211_ptr, net->name); |
---|
| 10189 | + } |
---|
| 10190 | + |
---|
| 10191 | + if (unlikely(ret)) { |
---|
| 10192 | + WL_ERR(("Del iface failed for static_if %d\n", ret)); |
---|
| 10193 | + } |
---|
| 10194 | + } |
---|
| 10195 | + |
---|
| 10196 | + return ret; |
---|
| 10197 | +} |
---|
| 10198 | +struct net_device * |
---|
| 10199 | +wl_cfg80211_post_static_ifcreate(struct bcm_cfg80211 *cfg, |
---|
| 10200 | + wl_if_event_info *event, u8 *addr, s32 iface_type, const char *iface_name) |
---|
| 10201 | +{ |
---|
| 10202 | + struct net_device *new_ndev = NULL; |
---|
| 10203 | + struct wireless_dev *wdev = NULL; |
---|
| 10204 | + |
---|
| 10205 | + int iface_num = 0; |
---|
| 10206 | + /* Checks if iface number returned is valid or not */ |
---|
| 10207 | + if ((iface_num = get_iface_num(iface_name, cfg)) < 0) { |
---|
| 10208 | + return NULL; |
---|
| 10209 | + } |
---|
| 10210 | + |
---|
| 10211 | + WL_INFORM_MEM(("Updating static iface after Fw IF create \n")); |
---|
| 10212 | + |
---|
| 10213 | + new_ndev = cfg->static_ndev[iface_num]; |
---|
| 10214 | + if (new_ndev) { |
---|
| 10215 | + wdev = new_ndev->ieee80211_ptr; |
---|
| 10216 | + ASSERT(wdev); |
---|
| 10217 | + wdev->iftype = iface_type; |
---|
| 10218 | + (void)memcpy_s(new_ndev->dev_addr, ETH_ALEN, addr, ETH_ALEN); |
---|
| 10219 | + } |
---|
| 10220 | + |
---|
| 10221 | + cfg->static_ndev_state[iface_num] = NDEV_STATE_FW_IF_CREATED; |
---|
| 10222 | + wl_cfg80211_update_iflist_info(cfg, new_ndev, event->ifidx, addr, event->bssidx, |
---|
| 10223 | + event->name, NDEV_STATE_FW_IF_CREATED); |
---|
| 10224 | + return new_ndev; |
---|
| 10225 | +} |
---|
| 10226 | +s32 |
---|
| 10227 | +wl_cfg80211_post_static_ifdel(struct bcm_cfg80211 *cfg, struct net_device *ndev) |
---|
| 10228 | +{ |
---|
| 10229 | + int iface_num = 0; |
---|
| 10230 | + if ((iface_num = get_iface_num(ndev->name, cfg)) < 0) { |
---|
| 10231 | + return BCME_ERROR; |
---|
| 10232 | + } |
---|
| 10233 | + |
---|
| 10234 | + cfg->static_ndev_state[iface_num] = NDEV_STATE_FW_IF_DELETED; |
---|
| 10235 | + wl_cfg80211_update_iflist_info(cfg, ndev, (DHD_MAX_IFS + iface_num), NULL, |
---|
| 10236 | + WL_BSSIDX_MAX, NULL, NDEV_STATE_FW_IF_DELETED); |
---|
| 10237 | + wl_cfg80211_clear_per_bss_ies(cfg, ndev->ieee80211_ptr); |
---|
| 10238 | + wl_dealloc_netinfo_by_wdev(cfg, ndev->ieee80211_ptr); |
---|
| 10239 | + return BCME_OK; |
---|
| 10240 | +} |
---|
| 10241 | +#endif /* WL_STATIC_IF */ |
---|
| 10242 | + |
---|
| 10243 | +#ifdef WBTEXT |
---|
| 10244 | +static int |
---|
| 10245 | +wlc_wbtext_get_roam_prof(struct net_device *ndev, wl_roamprof_band_t *rp, |
---|
| 10246 | + uint8 band, uint8 *roam_prof_ver, uint8 *roam_prof_size) |
---|
| 10247 | +{ |
---|
| 10248 | + int err = BCME_OK; |
---|
| 10249 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 10250 | + u8 *ioctl_buf = NULL; |
---|
| 10251 | + |
---|
| 10252 | + ioctl_buf = (u8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 10253 | + if (unlikely(!ioctl_buf)) { |
---|
| 10254 | + WL_ERR(("%s: failed to allocate memory\n", __func__)); |
---|
| 10255 | + err = -ENOMEM; |
---|
| 10256 | + goto exit; |
---|
| 10257 | + } |
---|
| 10258 | + rp->v1.band = band; |
---|
| 10259 | + rp->v1.len = 0; |
---|
| 10260 | + /* Getting roam profile from fw */ |
---|
| 10261 | + if ((err = wldev_iovar_getbuf(ndev, "roam_prof", rp, sizeof(*rp), |
---|
| 10262 | + ioctl_buf, WLC_IOCTL_MEDLEN, NULL))) { |
---|
| 10263 | + WL_ERR(("Getting roam_profile failed with err=%d \n", err)); |
---|
| 10264 | + goto exit; |
---|
| 10265 | + } |
---|
| 10266 | + memcpy_s(rp, sizeof(*rp), ioctl_buf, sizeof(*rp)); |
---|
| 10267 | + /* roam_prof version get */ |
---|
| 10268 | + if (rp->v1.ver > WL_ROAM_PROF_VER_2) { |
---|
| 10269 | + WL_ERR(("bad version (=%d) in return data\n", rp->v1.ver)); |
---|
| 10270 | + err = BCME_VERSION; |
---|
| 10271 | + goto exit; |
---|
| 10272 | + } |
---|
| 10273 | + switch (rp->v1.ver) { |
---|
| 10274 | + case WL_ROAM_PROF_VER_0: |
---|
| 10275 | + { |
---|
| 10276 | + *roam_prof_size = sizeof(wl_roam_prof_v1_t); |
---|
| 10277 | + *roam_prof_ver = WL_ROAM_PROF_VER_0; |
---|
| 10278 | + } |
---|
| 10279 | + break; |
---|
| 10280 | + case WL_ROAM_PROF_VER_1: |
---|
| 10281 | + { |
---|
| 10282 | + *roam_prof_size = sizeof(wl_roam_prof_v2_t); |
---|
| 10283 | + *roam_prof_ver = WL_ROAM_PROF_VER_1; |
---|
| 10284 | + } |
---|
| 10285 | + break; |
---|
| 10286 | + case WL_ROAM_PROF_VER_2: |
---|
| 10287 | + { |
---|
| 10288 | + *roam_prof_size = sizeof(wl_roam_prof_v3_t); |
---|
| 10289 | + *roam_prof_ver = WL_ROAM_PROF_VER_2; |
---|
| 10290 | + } |
---|
| 10291 | + break; |
---|
| 10292 | + default: |
---|
| 10293 | + WL_ERR(("bad version = %d \n", rp->v1.ver)); |
---|
| 10294 | + err = BCME_VERSION; |
---|
| 10295 | + goto exit; |
---|
| 10296 | + } |
---|
| 10297 | + WL_DBG(("roam prof ver %u size %u\n", *roam_prof_ver, *roam_prof_size)); |
---|
| 10298 | + if ((rp->v1.len % *roam_prof_size) != 0) { |
---|
| 10299 | + WL_ERR(("bad length (=%d) in return data\n", rp->v1.len)); |
---|
| 10300 | + err = BCME_BADLEN; |
---|
| 10301 | + } |
---|
| 10302 | +exit: |
---|
| 10303 | + if (ioctl_buf) { |
---|
| 10304 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 10305 | + } |
---|
| 10306 | + return err; |
---|
| 10307 | +} |
---|
| 10308 | + |
---|
| 10309 | +s32 |
---|
| 10310 | +wl_cfg80211_wbtext_set_default(struct net_device *ndev) |
---|
| 10311 | +{ |
---|
| 10312 | + char *commandp = NULL; |
---|
| 10313 | + s32 ret = BCME_OK; |
---|
| 10314 | + char *data; |
---|
| 10315 | + u8 *ioctl_buf = NULL; |
---|
| 10316 | + wl_roamprof_band_t rp; |
---|
| 10317 | + uint8 bandidx = 0; |
---|
| 10318 | + int wnmmask = 0; |
---|
| 10319 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 10320 | + |
---|
| 10321 | + WL_DBG(("set wbtext to default\n")); |
---|
| 10322 | + |
---|
| 10323 | + commandp = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_SMLEN); |
---|
| 10324 | + if (unlikely(!commandp)) { |
---|
| 10325 | + WL_ERR(("%s: failed to allocate memory\n", __func__)); |
---|
| 10326 | + ret = -ENOMEM; |
---|
| 10327 | + goto exit; |
---|
| 10328 | + } |
---|
| 10329 | + ioctl_buf = (char *)MALLOCZ(cfg->osh, WLC_IOCTL_SMLEN); |
---|
| 10330 | + if (unlikely(!ioctl_buf)) { |
---|
| 10331 | + WL_ERR(("%s: failed to allocate memory\n", __func__)); |
---|
| 10332 | + ret = -ENOMEM; |
---|
| 10333 | + goto exit; |
---|
| 10334 | + } |
---|
| 10335 | + |
---|
| 10336 | + rp.v1.band = WLC_BAND_2G; |
---|
| 10337 | + rp.v1.len = 0; |
---|
| 10338 | + /* Getting roam profile from fw */ |
---|
| 10339 | + if ((ret = wldev_iovar_getbuf(ndev, "roam_prof", &rp, sizeof(rp), |
---|
| 10340 | + ioctl_buf, WLC_IOCTL_SMLEN, NULL))) { |
---|
| 10341 | + WL_ERR(("Getting roam_profile failed with err=%d \n", ret)); |
---|
| 10342 | + goto exit; |
---|
| 10343 | + } |
---|
| 10344 | + memcpy_s(&rp, sizeof(rp), ioctl_buf, sizeof(rp)); |
---|
| 10345 | + for (bandidx = 0; bandidx < MAXBANDS; bandidx++) { |
---|
| 10346 | + switch (rp.v1.ver) { |
---|
| 10347 | + case WL_ROAM_PROF_VER_1: |
---|
| 10348 | + { |
---|
| 10349 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10350 | + if (bandidx == BAND_5G_INDEX) { |
---|
| 10351 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10352 | + CMD_WBTEXT_PROFILE_CONFIG, |
---|
| 10353 | + DEFAULT_WBTEXT_PROFILE_A_V2); |
---|
| 10354 | + data = (commandp + strlen(CMD_WBTEXT_PROFILE_CONFIG) + 1); |
---|
| 10355 | + } else { |
---|
| 10356 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10357 | + CMD_WBTEXT_PROFILE_CONFIG, |
---|
| 10358 | + DEFAULT_WBTEXT_PROFILE_B_V2); |
---|
| 10359 | + data = (commandp + strlen(CMD_WBTEXT_PROFILE_CONFIG) + 1); |
---|
| 10360 | + } |
---|
| 10361 | + } |
---|
| 10362 | + break; |
---|
| 10363 | + case WL_ROAM_PROF_VER_2: |
---|
| 10364 | + { |
---|
| 10365 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10366 | + if (bandidx == BAND_5G_INDEX) { |
---|
| 10367 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10368 | + CMD_WBTEXT_PROFILE_CONFIG, |
---|
| 10369 | + DEFAULT_WBTEXT_PROFILE_A_V3); |
---|
| 10370 | + data = (commandp + strlen(CMD_WBTEXT_PROFILE_CONFIG) + 1); |
---|
| 10371 | + } else { |
---|
| 10372 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10373 | + CMD_WBTEXT_PROFILE_CONFIG, |
---|
| 10374 | + DEFAULT_WBTEXT_PROFILE_B_V3); |
---|
| 10375 | + data = (commandp + strlen(CMD_WBTEXT_PROFILE_CONFIG) + 1); |
---|
| 10376 | + } |
---|
| 10377 | + } |
---|
| 10378 | + break; |
---|
| 10379 | + default: |
---|
| 10380 | + WL_ERR(("No Support for roam prof ver = %d \n", rp.v1.ver)); |
---|
| 10381 | + ret = -EINVAL; |
---|
| 10382 | + goto exit; |
---|
| 10383 | + } |
---|
| 10384 | + /* set roam profile */ |
---|
| 10385 | + ret = wl_cfg80211_wbtext_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10386 | + if (ret != BCME_OK) { |
---|
| 10387 | + WL_ERR(("%s: Failed to set roam_prof %s error = %d\n", |
---|
| 10388 | + __FUNCTION__, data, ret)); |
---|
| 10389 | + goto exit; |
---|
| 10390 | + } |
---|
| 10391 | + } |
---|
| 10392 | + |
---|
| 10393 | + /* set RSSI weight */ |
---|
| 10394 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10395 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10396 | + CMD_WBTEXT_WEIGHT_CONFIG, DEFAULT_WBTEXT_WEIGHT_RSSI_A); |
---|
| 10397 | + data = (commandp + strlen(CMD_WBTEXT_WEIGHT_CONFIG) + 1); |
---|
| 10398 | + ret = wl_cfg80211_wbtext_weight_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10399 | + if (ret != BCME_OK) { |
---|
| 10400 | + WL_ERR(("%s: Failed to set weight config %s error = %d\n", |
---|
| 10401 | + __FUNCTION__, data, ret)); |
---|
| 10402 | + goto exit; |
---|
| 10403 | + } |
---|
| 10404 | + |
---|
| 10405 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10406 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10407 | + CMD_WBTEXT_WEIGHT_CONFIG, DEFAULT_WBTEXT_WEIGHT_RSSI_B); |
---|
| 10408 | + data = (commandp + strlen(CMD_WBTEXT_WEIGHT_CONFIG) + 1); |
---|
| 10409 | + ret = wl_cfg80211_wbtext_weight_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10410 | + if (ret != BCME_OK) { |
---|
| 10411 | + WL_ERR(("%s: Failed to set weight config %s error = %d\n", |
---|
| 10412 | + __FUNCTION__, data, ret)); |
---|
| 10413 | + goto exit; |
---|
| 10414 | + } |
---|
| 10415 | + |
---|
| 10416 | + /* set CU weight */ |
---|
| 10417 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10418 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10419 | + CMD_WBTEXT_WEIGHT_CONFIG, DEFAULT_WBTEXT_WEIGHT_CU_A); |
---|
| 10420 | + data = (commandp + strlen(CMD_WBTEXT_WEIGHT_CONFIG) + 1); |
---|
| 10421 | + ret = wl_cfg80211_wbtext_weight_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10422 | + if (ret != BCME_OK) { |
---|
| 10423 | + WL_ERR(("%s: Failed to set weight config %s error = %d\n", |
---|
| 10424 | + __FUNCTION__, data, ret)); |
---|
| 10425 | + goto exit; |
---|
| 10426 | + } |
---|
| 10427 | + |
---|
| 10428 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10429 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10430 | + CMD_WBTEXT_WEIGHT_CONFIG, DEFAULT_WBTEXT_WEIGHT_CU_B); |
---|
| 10431 | + data = (commandp + strlen(CMD_WBTEXT_WEIGHT_CONFIG) + 1); |
---|
| 10432 | + ret = wl_cfg80211_wbtext_weight_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10433 | + if (ret != BCME_OK) { |
---|
| 10434 | + WL_ERR(("%s: Failed to set weight config %s error = %d\n", |
---|
| 10435 | + __FUNCTION__, data, ret)); |
---|
| 10436 | + goto exit; |
---|
| 10437 | + } |
---|
| 10438 | + |
---|
| 10439 | + ret = wldev_iovar_getint(ndev, "wnm", &wnmmask); |
---|
| 10440 | + if (ret != BCME_OK) { |
---|
| 10441 | + WL_ERR(("%s: Failed to get wnmmask error = %d\n", __func__, ret)); |
---|
| 10442 | + goto exit; |
---|
| 10443 | + } |
---|
| 10444 | + /* set ESTM DL weight. */ |
---|
| 10445 | + if (wnmmask & WL_WNM_ESTM) { |
---|
| 10446 | + WL_ERR(("Setting ESTM wt\n")); |
---|
| 10447 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10448 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10449 | + CMD_WBTEXT_WEIGHT_CONFIG, DEFAULT_WBTEXT_WEIGHT_ESTM_DL_A); |
---|
| 10450 | + data = (commandp + strlen(CMD_WBTEXT_WEIGHT_CONFIG) + 1); |
---|
| 10451 | + ret = wl_cfg80211_wbtext_weight_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10452 | + if (ret != BCME_OK) { |
---|
| 10453 | + WL_ERR(("%s: Failed to set weight config %s error = %d\n", |
---|
| 10454 | + __FUNCTION__, data, ret)); |
---|
| 10455 | + goto exit; |
---|
| 10456 | + } |
---|
| 10457 | + |
---|
| 10458 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10459 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10460 | + CMD_WBTEXT_WEIGHT_CONFIG, DEFAULT_WBTEXT_WEIGHT_ESTM_DL_B); |
---|
| 10461 | + data = (commandp + strlen(CMD_WBTEXT_WEIGHT_CONFIG) + 1); |
---|
| 10462 | + ret = wl_cfg80211_wbtext_weight_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10463 | + if (ret != BCME_OK) { |
---|
| 10464 | + WL_ERR(("%s: Failed to set weight config %s error = %d\n", |
---|
| 10465 | + __FUNCTION__, data, ret)); |
---|
| 10466 | + goto exit; |
---|
| 10467 | + } |
---|
| 10468 | + } |
---|
| 10469 | + |
---|
| 10470 | + /* set RSSI table */ |
---|
| 10471 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10472 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10473 | + CMD_WBTEXT_TABLE_CONFIG, DEFAULT_WBTEXT_TABLE_RSSI_A); |
---|
| 10474 | + data = (commandp + strlen(CMD_WBTEXT_TABLE_CONFIG) + 1); |
---|
| 10475 | + ret = wl_cfg80211_wbtext_table_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10476 | + if (ret != BCME_OK) { |
---|
| 10477 | + WL_ERR(("%s: Failed to set RSSI table %s error = %d\n", |
---|
| 10478 | + __FUNCTION__, data, ret)); |
---|
| 10479 | + goto exit; |
---|
| 10480 | + } |
---|
| 10481 | + |
---|
| 10482 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10483 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10484 | + CMD_WBTEXT_TABLE_CONFIG, DEFAULT_WBTEXT_TABLE_RSSI_B); |
---|
| 10485 | + data = (commandp + strlen(CMD_WBTEXT_TABLE_CONFIG) + 1); |
---|
| 10486 | + ret = wl_cfg80211_wbtext_table_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10487 | + if (ret != BCME_OK) { |
---|
| 10488 | + WL_ERR(("%s: Failed to set RSSI table %s error = %d\n", |
---|
| 10489 | + __FUNCTION__, data, ret)); |
---|
| 10490 | + goto exit; |
---|
| 10491 | + } |
---|
| 10492 | + |
---|
| 10493 | + /* set CU table */ |
---|
| 10494 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10495 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10496 | + CMD_WBTEXT_TABLE_CONFIG, DEFAULT_WBTEXT_TABLE_CU_A); |
---|
| 10497 | + data = (commandp + strlen(CMD_WBTEXT_TABLE_CONFIG) + 1); |
---|
| 10498 | + ret = wl_cfg80211_wbtext_table_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10499 | + if (ret != BCME_OK) { |
---|
| 10500 | + WL_ERR(("%s: Failed to set CU table %s error = %d\n", |
---|
| 10501 | + __FUNCTION__, data, ret)); |
---|
| 10502 | + goto exit; |
---|
| 10503 | + } |
---|
| 10504 | + |
---|
| 10505 | + memset_s(commandp, WLC_IOCTL_SMLEN, 0, WLC_IOCTL_SMLEN); |
---|
| 10506 | + snprintf(commandp, WLC_IOCTL_SMLEN, "%s %s", |
---|
| 10507 | + CMD_WBTEXT_TABLE_CONFIG, DEFAULT_WBTEXT_TABLE_CU_B); |
---|
| 10508 | + data = (commandp + strlen(CMD_WBTEXT_TABLE_CONFIG) + 1); |
---|
| 10509 | + ret = wl_cfg80211_wbtext_table_config(ndev, data, commandp, WLC_IOCTL_SMLEN); |
---|
| 10510 | + if (ret != BCME_OK) { |
---|
| 10511 | + WL_ERR(("%s: Failed to set CU table %s error = %d\n", |
---|
| 10512 | + __FUNCTION__, data, ret)); |
---|
| 10513 | + goto exit; |
---|
| 10514 | + } |
---|
| 10515 | + |
---|
| 10516 | +exit: |
---|
| 10517 | + if (commandp) { |
---|
| 10518 | + MFREE(cfg->osh, commandp, WLC_IOCTL_SMLEN); |
---|
| 10519 | + } |
---|
| 10520 | + if (ioctl_buf) { |
---|
| 10521 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_SMLEN); |
---|
| 10522 | + } |
---|
| 10523 | + return ret; |
---|
| 10524 | +} |
---|
| 10525 | + |
---|
| 10526 | +s32 |
---|
| 10527 | +wl_cfg80211_wbtext_config(struct net_device *ndev, char *data, char *command, int total_len) |
---|
| 10528 | +{ |
---|
| 10529 | + uint i = 0; |
---|
| 10530 | + long int rssi_lower, roam_trigger; |
---|
| 10531 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 10532 | + wl_roamprof_band_t *rp = NULL; |
---|
| 10533 | + int err = -EINVAL, bytes_written = 0; |
---|
| 10534 | + size_t len = strlen(data); |
---|
| 10535 | + int rp_len = 0; |
---|
| 10536 | + u8 *ioctl_buf = NULL; |
---|
| 10537 | + uint8 roam_prof_size = 0, roam_prof_ver = 0, fs_per = 0, prof_cnt = 0; |
---|
| 10538 | + |
---|
| 10539 | + data[len] = '\0'; |
---|
| 10540 | + ioctl_buf = (u8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
---|
| 10541 | + if (unlikely(!ioctl_buf)) { |
---|
| 10542 | + WL_ERR(("%s: failed to allocate memory\n", __func__)); |
---|
| 10543 | + err = -ENOMEM; |
---|
| 10544 | + goto exit; |
---|
| 10545 | + } |
---|
| 10546 | + rp = (wl_roamprof_band_t *)MALLOCZ(cfg->osh, sizeof(*rp)); |
---|
| 10547 | + if (unlikely(!rp)) { |
---|
| 10548 | + WL_ERR(("%s: failed to allocate memory\n", __func__)); |
---|
| 10549 | + err = -ENOMEM; |
---|
| 10550 | + goto exit; |
---|
| 10551 | + } |
---|
| 10552 | + if (*data && (!strncmp(data, "b", 1))) { |
---|
| 10553 | + rp->v1.band = WLC_BAND_2G; |
---|
| 10554 | + } else if (*data && (!strncmp(data, "a", 1))) { |
---|
| 10555 | + rp->v1.band = WLC_BAND_5G; |
---|
| 10556 | + } else { |
---|
| 10557 | + err = snprintf(command, total_len, "Missing band\n"); |
---|
| 10558 | + goto exit; |
---|
| 10559 | + } |
---|
| 10560 | + data++; |
---|
| 10561 | + rp->v1.len = 0; |
---|
| 10562 | + /* Getting roam profile from fw */ |
---|
| 10563 | + if ((err = wldev_iovar_getbuf(ndev, "roam_prof", rp, sizeof(*rp), |
---|
| 10564 | + ioctl_buf, WLC_IOCTL_MEDLEN, NULL))) { |
---|
| 10565 | + WL_ERR(("Getting roam_profile failed with err=%d \n", err)); |
---|
| 10566 | + goto exit; |
---|
| 10567 | + } |
---|
| 10568 | + memcpy_s(rp, sizeof(*rp), ioctl_buf, sizeof(*rp)); |
---|
| 10569 | + /* roam_prof version get */ |
---|
| 10570 | + if (rp->v1.ver > WL_ROAM_PROF_VER_2) { |
---|
| 10571 | + WL_ERR(("bad version (=%d) in return data\n", rp->v1.ver)); |
---|
| 10572 | + err = -EINVAL; |
---|
| 10573 | + goto exit; |
---|
| 10574 | + } |
---|
| 10575 | + switch (rp->v1.ver) { |
---|
| 10576 | + case WL_ROAM_PROF_VER_0: |
---|
| 10577 | + { |
---|
| 10578 | + roam_prof_size = sizeof(wl_roam_prof_v1_t); |
---|
| 10579 | + roam_prof_ver = WL_ROAM_PROF_VER_0; |
---|
| 10580 | + } |
---|
| 10581 | + break; |
---|
| 10582 | + case WL_ROAM_PROF_VER_1: |
---|
| 10583 | + { |
---|
| 10584 | + roam_prof_size = sizeof(wl_roam_prof_v2_t); |
---|
| 10585 | + roam_prof_ver = WL_ROAM_PROF_VER_1; |
---|
| 10586 | + } |
---|
| 10587 | + break; |
---|
| 10588 | + case WL_ROAM_PROF_VER_2: |
---|
| 10589 | + { |
---|
| 10590 | + roam_prof_size = sizeof(wl_roam_prof_v3_t); |
---|
| 10591 | + roam_prof_ver = WL_ROAM_PROF_VER_2; |
---|
| 10592 | + } |
---|
| 10593 | + break; |
---|
| 10594 | + default: |
---|
| 10595 | + WL_ERR(("bad version = %d \n", rp->v1.ver)); |
---|
| 10596 | + goto exit; |
---|
| 10597 | + } |
---|
| 10598 | + WL_DBG(("roam prof ver %u size %u\n", roam_prof_ver, roam_prof_size)); |
---|
| 10599 | + if ((rp->v1.len % roam_prof_size) != 0) { |
---|
| 10600 | + WL_ERR(("bad length (=%d) in return data\n", rp->v1.len)); |
---|
| 10601 | + err = -EINVAL; |
---|
| 10602 | + goto exit; |
---|
| 10603 | + } |
---|
| 10604 | + for (i = 0; i < WL_MAX_ROAM_PROF_BRACKETS; i++) { |
---|
| 10605 | + /* printing contents of roam profile data from fw and exits |
---|
| 10606 | + * if code hits any of one of the below condtion. If remaining |
---|
| 10607 | + * length of buffer is less than roam profile size or |
---|
| 10608 | + * if there is no valid entry. |
---|
| 10609 | + */ |
---|
| 10610 | + if (((i * roam_prof_size) > rp->v1.len)) { |
---|
| 10611 | + break; |
---|
| 10612 | + } |
---|
| 10613 | + if (roam_prof_ver == WL_ROAM_PROF_VER_0) { |
---|
| 10614 | + fs_per = rp->v1.roam_prof[i].fullscan_period; |
---|
| 10615 | + } else if (roam_prof_ver == WL_ROAM_PROF_VER_1) { |
---|
| 10616 | + fs_per = rp->v2.roam_prof[i].fullscan_period; |
---|
| 10617 | + } else if (roam_prof_ver == WL_ROAM_PROF_VER_2) { |
---|
| 10618 | + fs_per = rp->v3.roam_prof[i].fullscan_period; |
---|
| 10619 | + } |
---|
| 10620 | + if (fs_per == 0) { |
---|
| 10621 | + break; |
---|
| 10622 | + } |
---|
| 10623 | + prof_cnt++; |
---|
| 10624 | + } |
---|
| 10625 | + |
---|
| 10626 | + if (!*data) { |
---|
| 10627 | + for (i = 0; (i < prof_cnt) && (i < WL_MAX_ROAM_PROF_BRACKETS); i++) { |
---|
| 10628 | + if (roam_prof_ver == WL_ROAM_PROF_VER_1) { |
---|
| 10629 | + bytes_written += snprintf(command+bytes_written, |
---|
| 10630 | + total_len - bytes_written, |
---|
| 10631 | + "RSSI[%d,%d] CU(trigger:%d%%: duration:%ds)\n", |
---|
| 10632 | + rp->v2.roam_prof[i].roam_trigger, |
---|
| 10633 | + rp->v2.roam_prof[i].rssi_lower, |
---|
| 10634 | + rp->v2.roam_prof[i].channel_usage, |
---|
| 10635 | + rp->v2.roam_prof[i].cu_avg_calc_dur); |
---|
| 10636 | + } else if (roam_prof_ver == WL_ROAM_PROF_VER_2) { |
---|
| 10637 | + bytes_written += snprintf(command+bytes_written, |
---|
| 10638 | + total_len - bytes_written, |
---|
| 10639 | + "RSSI[%d,%d] CU(trigger:%d%%: duration:%ds)\n", |
---|
| 10640 | + rp->v3.roam_prof[i].roam_trigger, |
---|
| 10641 | + rp->v3.roam_prof[i].rssi_lower, |
---|
| 10642 | + rp->v3.roam_prof[i].channel_usage, |
---|
| 10643 | + rp->v3.roam_prof[i].cu_avg_calc_dur); |
---|
| 10644 | + } |
---|
| 10645 | + } |
---|
| 10646 | + err = bytes_written; |
---|
| 10647 | + goto exit; |
---|
| 10648 | + } else { |
---|
| 10649 | + /* Do not set roam_prof from upper layer if fw doesn't have 2 rows */ |
---|
| 10650 | + if (prof_cnt != 2) { |
---|
| 10651 | + WL_ERR(("FW must have 2 rows to fill roam_prof\n")); |
---|
| 10652 | + err = -EINVAL; |
---|
| 10653 | + goto exit; |
---|
| 10654 | + } |
---|
| 10655 | + /* setting roam profile to fw */ |
---|
| 10656 | + data++; |
---|
| 10657 | + for (i = 0; i < WL_MAX_ROAM_PROF_BRACKETS; i++) { |
---|
| 10658 | + roam_trigger = simple_strtol(data, &data, 10); |
---|
| 10659 | + if (roam_trigger >= 0) { |
---|
| 10660 | + WL_ERR(("roam trigger[%d] value must be negative\n", i)); |
---|
| 10661 | + err = -EINVAL; |
---|
| 10662 | + goto exit; |
---|
| 10663 | + } |
---|
| 10664 | + data++; |
---|
| 10665 | + rssi_lower = simple_strtol(data, &data, 10); |
---|
| 10666 | + if (rssi_lower >= 0) { |
---|
| 10667 | + WL_ERR(("rssi lower[%d] value must be negative\n", i)); |
---|
| 10668 | + err = -EINVAL; |
---|
| 10669 | + goto exit; |
---|
| 10670 | + } |
---|
| 10671 | + if (roam_prof_ver == WL_ROAM_PROF_VER_1) { |
---|
| 10672 | + rp->v2.roam_prof[i].roam_trigger = roam_trigger; |
---|
| 10673 | + rp->v2.roam_prof[i].rssi_lower = rssi_lower; |
---|
| 10674 | + data++; |
---|
| 10675 | + rp->v2.roam_prof[i].channel_usage = simple_strtol(data, &data, 10); |
---|
| 10676 | + data++; |
---|
| 10677 | + rp->v2.roam_prof[i].cu_avg_calc_dur = |
---|
| 10678 | + simple_strtol(data, &data, 10); |
---|
| 10679 | + } |
---|
| 10680 | + if (roam_prof_ver == WL_ROAM_PROF_VER_2) { |
---|
| 10681 | + rp->v3.roam_prof[i].roam_trigger = roam_trigger; |
---|
| 10682 | + rp->v3.roam_prof[i].rssi_lower = rssi_lower; |
---|
| 10683 | + data++; |
---|
| 10684 | + rp->v3.roam_prof[i].channel_usage = simple_strtol(data, &data, 10); |
---|
| 10685 | + data++; |
---|
| 10686 | + rp->v3.roam_prof[i].cu_avg_calc_dur = |
---|
| 10687 | + simple_strtol(data, &data, 10); |
---|
| 10688 | + } |
---|
| 10689 | + |
---|
| 10690 | + rp_len += roam_prof_size; |
---|
| 10691 | + |
---|
| 10692 | + if (*data == '\0') { |
---|
| 10693 | + break; |
---|
| 10694 | + } |
---|
| 10695 | + data++; |
---|
| 10696 | + } |
---|
| 10697 | + if (i != 1) { |
---|
| 10698 | + WL_ERR(("Only two roam_prof rows supported.\n")); |
---|
| 10699 | + err = -EINVAL; |
---|
| 10700 | + goto exit; |
---|
| 10701 | + } |
---|
| 10702 | + rp->v1.len = rp_len; |
---|
| 10703 | + if ((err = wldev_iovar_setbuf(ndev, "roam_prof", rp, |
---|
| 10704 | + sizeof(*rp), cfg->ioctl_buf, WLC_IOCTL_MEDLEN, |
---|
| 10705 | + &cfg->ioctl_buf_sync)) < 0) { |
---|
| 10706 | + WL_ERR(("seting roam_profile failed with err %d\n", err)); |
---|
| 10707 | + } |
---|
| 10708 | + } |
---|
| 10709 | +exit: |
---|
| 10710 | + if (rp) { |
---|
| 10711 | + MFREE(cfg->osh, rp, sizeof(*rp)); |
---|
| 10712 | + } |
---|
| 10713 | + if (ioctl_buf) { |
---|
| 10714 | + MFREE(cfg->osh, ioctl_buf, WLC_IOCTL_MEDLEN); |
---|
| 10715 | + } |
---|
| 10716 | + return err; |
---|
| 10717 | +} |
---|
| 10718 | + |
---|
| 10719 | +int wl_cfg80211_wbtext_weight_config(struct net_device *ndev, char *data, |
---|
| 10720 | + char *command, int total_len) |
---|
| 10721 | +{ |
---|
| 10722 | + int bytes_written = 0, err = -EINVAL, argc = 0; |
---|
| 10723 | + char rssi[BUFSZN], band[BUFSZN], weight[BUFSZN]; |
---|
| 10724 | + char *endptr = NULL; |
---|
| 10725 | + wnm_bss_select_weight_cfg_t *bwcfg; |
---|
| 10726 | + u8 ioctl_buf[WLC_IOCTL_SMLEN]; |
---|
| 10727 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 10728 | + |
---|
| 10729 | + bwcfg = (wnm_bss_select_weight_cfg_t *)MALLOCZ(cfg->osh, sizeof(*bwcfg)); |
---|
| 10730 | + if (unlikely(!bwcfg)) { |
---|
| 10731 | + WL_ERR(("%s: failed to allocate memory\n", __func__)); |
---|
| 10732 | + err = -ENOMEM; |
---|
| 10733 | + goto exit; |
---|
| 10734 | + } |
---|
| 10735 | + bwcfg->version = WNM_BSSLOAD_MONITOR_VERSION; |
---|
| 10736 | + bwcfg->type = 0; |
---|
| 10737 | + bwcfg->weight = 0; |
---|
| 10738 | + |
---|
| 10739 | + argc = sscanf(data, "%"S(BUFSZ)"s %"S(BUFSZ)"s %"S(BUFSZ)"s", rssi, band, weight); |
---|
| 10740 | + |
---|
| 10741 | + if (!strcasecmp(rssi, "rssi")) |
---|
| 10742 | + bwcfg->type = WNM_BSS_SELECT_TYPE_RSSI; |
---|
| 10743 | + else if (!strcasecmp(rssi, "cu")) |
---|
| 10744 | + bwcfg->type = WNM_BSS_SELECT_TYPE_CU; |
---|
| 10745 | + else if (!strcasecmp(rssi, "estm_dl")) |
---|
| 10746 | + bwcfg->type = WNM_BSS_SELECT_TYPE_ESTM_DL; |
---|
| 10747 | + else { |
---|
| 10748 | + /* Usage DRIVER WBTEXT_WEIGHT_CONFIG <rssi/cu/estm_dl> <band> <weight> */ |
---|
| 10749 | + WL_ERR(("%s: Command usage error\n", __func__)); |
---|
| 10750 | + goto exit; |
---|
| 10751 | + } |
---|
| 10752 | + |
---|
| 10753 | + if (!strcasecmp(band, "a")) |
---|
| 10754 | + bwcfg->band = WLC_BAND_5G; |
---|
| 10755 | + else if (!strcasecmp(band, "b")) |
---|
| 10756 | + bwcfg->band = WLC_BAND_2G; |
---|
| 10757 | + else if (!strcasecmp(band, "all")) |
---|
| 10758 | + bwcfg->band = WLC_BAND_ALL; |
---|
| 10759 | + else { |
---|
| 10760 | + WL_ERR(("%s: Command usage error\n", __func__)); |
---|
| 10761 | + goto exit; |
---|
| 10762 | + } |
---|
| 10763 | + |
---|
| 10764 | + if (argc == 2) { |
---|
| 10765 | + /* If there is no data after band, getting wnm_bss_select_weight from fw */ |
---|
| 10766 | + if (bwcfg->band == WLC_BAND_ALL) { |
---|
| 10767 | + WL_ERR(("band option \"all\" is for set only, not get\n")); |
---|
| 10768 | + goto exit; |
---|
| 10769 | + } |
---|
| 10770 | + if ((err = wldev_iovar_getbuf(ndev, "wnm_bss_select_weight", bwcfg, |
---|
| 10771 | + sizeof(*bwcfg), |
---|
| 10772 | + ioctl_buf, sizeof(ioctl_buf), NULL))) { |
---|
| 10773 | + WL_ERR(("Getting wnm_bss_select_weight failed with err=%d \n", err)); |
---|
| 10774 | + goto exit; |
---|
| 10775 | + } |
---|
| 10776 | + memcpy(bwcfg, ioctl_buf, sizeof(*bwcfg)); |
---|
| 10777 | + bytes_written = snprintf(command, total_len, "%s %s weight = %d\n", |
---|
| 10778 | + (bwcfg->type == WNM_BSS_SELECT_TYPE_RSSI) ? "RSSI" : |
---|
| 10779 | + (bwcfg->type == WNM_BSS_SELECT_TYPE_CU) ? "CU": "ESTM_DL", |
---|
| 10780 | + (bwcfg->band == WLC_BAND_2G) ? "2G" : "5G", bwcfg->weight); |
---|
| 10781 | + err = bytes_written; |
---|
| 10782 | + goto exit; |
---|
| 10783 | + } else { |
---|
| 10784 | + /* if weight is non integer returns command usage error */ |
---|
| 10785 | + bwcfg->weight = simple_strtol(weight, &endptr, 0); |
---|
| 10786 | + if (*endptr != '\0') { |
---|
| 10787 | + WL_ERR(("%s: Command usage error", __func__)); |
---|
| 10788 | + goto exit; |
---|
| 10789 | + } |
---|
| 10790 | + /* setting weight for iovar wnm_bss_select_weight to fw */ |
---|
| 10791 | + if ((err = wldev_iovar_setbuf(ndev, "wnm_bss_select_weight", bwcfg, |
---|
| 10792 | + sizeof(*bwcfg), |
---|
| 10793 | + ioctl_buf, sizeof(ioctl_buf), NULL))) { |
---|
| 10794 | + WL_ERR(("setting wnm_bss_select_weight failed with err=%d\n", err)); |
---|
| 10795 | + } |
---|
| 10796 | + } |
---|
| 10797 | +exit: |
---|
| 10798 | + if (bwcfg) { |
---|
| 10799 | + MFREE(cfg->osh, bwcfg, sizeof(*bwcfg)); |
---|
| 10800 | + } |
---|
| 10801 | + return err; |
---|
| 10802 | +} |
---|
| 10803 | + |
---|
| 10804 | +/* WBTEXT_TUPLE_MIN_LEN_CHECK :strlen(low)+" "+strlen(high)+" "+strlen(factor) */ |
---|
| 10805 | +#define WBTEXT_TUPLE_MIN_LEN_CHECK 5 |
---|
| 10806 | + |
---|
| 10807 | +int wl_cfg80211_wbtext_table_config(struct net_device *ndev, char *data, |
---|
| 10808 | + char *command, int total_len) |
---|
| 10809 | +{ |
---|
| 10810 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 10811 | + int bytes_written = 0, err = -EINVAL; |
---|
| 10812 | + char rssi[BUFSZN], band[BUFSZN]; |
---|
| 10813 | + int btcfg_len = 0, i = 0, parsed_len = 0; |
---|
| 10814 | + wnm_bss_select_factor_cfg_t *btcfg; |
---|
| 10815 | + size_t slen = strlen(data); |
---|
| 10816 | + char *start_addr = NULL; |
---|
| 10817 | + u8 ioctl_buf[WLC_IOCTL_SMLEN]; |
---|
| 10818 | + |
---|
| 10819 | + data[slen] = '\0'; |
---|
| 10820 | + btcfg = (wnm_bss_select_factor_cfg_t *)MALLOCZ(cfg->osh, |
---|
| 10821 | + (sizeof(*btcfg) + sizeof(*btcfg) * WL_FACTOR_TABLE_MAX_LIMIT)); |
---|
| 10822 | + if (unlikely(!btcfg)) { |
---|
| 10823 | + WL_ERR(("%s: failed to allocate memory\n", __func__)); |
---|
| 10824 | + err = -ENOMEM; |
---|
| 10825 | + goto exit; |
---|
| 10826 | + } |
---|
| 10827 | + |
---|
| 10828 | + btcfg->version = WNM_BSS_SELECT_FACTOR_VERSION; |
---|
| 10829 | + btcfg->band = WLC_BAND_AUTO; |
---|
| 10830 | + btcfg->type = 0; |
---|
| 10831 | + btcfg->count = 0; |
---|
| 10832 | + |
---|
| 10833 | + sscanf(data, "%"S(BUFSZ)"s %"S(BUFSZ)"s", rssi, band); |
---|
| 10834 | + |
---|
| 10835 | + if (!strcasecmp(rssi, "rssi")) { |
---|
| 10836 | + btcfg->type = WNM_BSS_SELECT_TYPE_RSSI; |
---|
| 10837 | + } |
---|
| 10838 | + else if (!strcasecmp(rssi, "cu")) { |
---|
| 10839 | + btcfg->type = WNM_BSS_SELECT_TYPE_CU; |
---|
| 10840 | + } |
---|
| 10841 | + else { |
---|
| 10842 | + WL_ERR(("%s: Command usage error\n", __func__)); |
---|
| 10843 | + goto exit; |
---|
| 10844 | + } |
---|
| 10845 | + |
---|
| 10846 | + if (!strcasecmp(band, "a")) { |
---|
| 10847 | + btcfg->band = WLC_BAND_5G; |
---|
| 10848 | + } |
---|
| 10849 | + else if (!strcasecmp(band, "b")) { |
---|
| 10850 | + btcfg->band = WLC_BAND_2G; |
---|
| 10851 | + } |
---|
| 10852 | + else if (!strcasecmp(band, "all")) { |
---|
| 10853 | + btcfg->band = WLC_BAND_ALL; |
---|
| 10854 | + } |
---|
| 10855 | + else { |
---|
| 10856 | + WL_ERR(("%s: Command usage, Wrong band\n", __func__)); |
---|
| 10857 | + goto exit; |
---|
| 10858 | + } |
---|
| 10859 | + |
---|
| 10860 | + if ((slen - 1) == (strlen(rssi) + strlen(band))) { |
---|
| 10861 | + /* Getting factor table using iovar 'wnm_bss_select_table' from fw */ |
---|
| 10862 | + if ((err = wldev_iovar_getbuf(ndev, "wnm_bss_select_table", btcfg, |
---|
| 10863 | + sizeof(*btcfg), |
---|
| 10864 | + ioctl_buf, sizeof(ioctl_buf), NULL))) { |
---|
| 10865 | + WL_ERR(("Getting wnm_bss_select_table failed with err=%d \n", err)); |
---|
| 10866 | + goto exit; |
---|
| 10867 | + } |
---|
| 10868 | + memcpy(btcfg, ioctl_buf, sizeof(*btcfg)); |
---|
| 10869 | + memcpy(btcfg, ioctl_buf, (btcfg->count+1) * sizeof(*btcfg)); |
---|
| 10870 | + |
---|
| 10871 | + bytes_written += snprintf(command + bytes_written, total_len - bytes_written, |
---|
| 10872 | + "No of entries in table: %d\n", btcfg->count); |
---|
| 10873 | + bytes_written += snprintf(command + bytes_written, total_len - bytes_written, |
---|
| 10874 | + "%s factor table\n", |
---|
| 10875 | + (btcfg->type == WNM_BSS_SELECT_TYPE_RSSI) ? "RSSI" : "CU"); |
---|
| 10876 | + bytes_written += snprintf(command + bytes_written, total_len - bytes_written, |
---|
| 10877 | + "low\thigh\tfactor\n"); |
---|
| 10878 | + for (i = 0; i <= btcfg->count-1; i++) { |
---|
| 10879 | + bytes_written += snprintf(command + bytes_written, |
---|
| 10880 | + total_len - bytes_written, "%d\t%d\t%d\n", btcfg->params[i].low, |
---|
| 10881 | + btcfg->params[i].high, btcfg->params[i].factor); |
---|
| 10882 | + } |
---|
| 10883 | + err = bytes_written; |
---|
| 10884 | + goto exit; |
---|
| 10885 | + } else { |
---|
| 10886 | + uint16 len = (sizeof(wnm_bss_select_factor_params_t) * WL_FACTOR_TABLE_MAX_LIMIT); |
---|
| 10887 | + memset_s(btcfg->params, len, 0, len); |
---|
| 10888 | + data += (strlen(rssi) + strlen(band) + 2); |
---|
| 10889 | + start_addr = data; |
---|
| 10890 | + slen = slen - (strlen(rssi) + strlen(band) + 2); |
---|
| 10891 | + for (i = 0; i < WL_FACTOR_TABLE_MAX_LIMIT; i++) { |
---|
| 10892 | + if (parsed_len + WBTEXT_TUPLE_MIN_LEN_CHECK <= slen) { |
---|
| 10893 | + btcfg->params[i].low = simple_strtol(data, &data, 10); |
---|
| 10894 | + data++; |
---|
| 10895 | + btcfg->params[i].high = simple_strtol(data, &data, 10); |
---|
| 10896 | + data++; |
---|
| 10897 | + btcfg->params[i].factor = simple_strtol(data, &data, 10); |
---|
| 10898 | + btcfg->count++; |
---|
| 10899 | + if (*data == '\0') { |
---|
| 10900 | + break; |
---|
| 10901 | + } |
---|
| 10902 | + data++; |
---|
| 10903 | + parsed_len = data - start_addr; |
---|
| 10904 | + } else { |
---|
| 10905 | + WL_ERR(("%s:Command usage:less no of args\n", __func__)); |
---|
| 10906 | + goto exit; |
---|
| 10907 | + } |
---|
| 10908 | + } |
---|
| 10909 | + btcfg_len = sizeof(*btcfg) + ((btcfg->count) * sizeof(*btcfg)); |
---|
| 10910 | + if ((err = wldev_iovar_setbuf(ndev, "wnm_bss_select_table", btcfg, btcfg_len, |
---|
| 10911 | + cfg->ioctl_buf, WLC_IOCTL_MEDLEN, &cfg->ioctl_buf_sync)) < 0) { |
---|
| 10912 | + WL_ERR(("seting wnm_bss_select_table failed with err %d\n", err)); |
---|
| 10913 | + goto exit; |
---|
| 10914 | + } |
---|
| 10915 | + } |
---|
| 10916 | +exit: |
---|
| 10917 | + if (btcfg) { |
---|
| 10918 | + MFREE(cfg->osh, btcfg, |
---|
| 10919 | + (sizeof(*btcfg) + sizeof(*btcfg) * WL_FACTOR_TABLE_MAX_LIMIT)); |
---|
| 10920 | + } |
---|
| 10921 | + return err; |
---|
| 10922 | +} |
---|
| 10923 | + |
---|
| 10924 | +s32 |
---|
| 10925 | +wl_cfg80211_wbtext_delta_config(struct net_device *ndev, char *data, char *command, int total_len) |
---|
| 10926 | +{ |
---|
| 10927 | + uint i = 0; |
---|
| 10928 | + struct bcm_cfg80211 *cfg = wl_get_cfg(ndev); |
---|
| 10929 | + int err = -EINVAL, bytes_written = 0, argc = 0, val, len = 0; |
---|
| 10930 | + char delta[BUFSZN], band[BUFSZN], *endptr = NULL; |
---|
| 10931 | + wl_roamprof_band_t *rp = NULL; |
---|
| 10932 | + uint8 band_val = 0, roam_prof_size = 0, roam_prof_ver = 0; |
---|
| 10933 | + |
---|
| 10934 | + rp = (wl_roamprof_band_t *)MALLOCZ(cfg->osh, sizeof(*rp)); |
---|
| 10935 | + if (unlikely(!rp)) { |
---|
| 10936 | + WL_ERR(("%s: failed to allocate memory\n", __func__)); |
---|
| 10937 | + err = -ENOMEM; |
---|
| 10938 | + goto exit; |
---|
| 10939 | + } |
---|
| 10940 | + |
---|
| 10941 | + argc = sscanf(data, "%"S(BUFSZ)"s %"S(BUFSZ)"s", band, delta); |
---|
| 10942 | + if (!strcasecmp(band, "a")) |
---|
| 10943 | + band_val = WLC_BAND_5G; |
---|
| 10944 | + else if (!strcasecmp(band, "b")) |
---|
| 10945 | + band_val = WLC_BAND_2G; |
---|
| 10946 | + else { |
---|
| 10947 | + WL_ERR(("%s: Missing band\n", __func__)); |
---|
| 10948 | + goto exit; |
---|
| 10949 | + } |
---|
| 10950 | + if ((err = wlc_wbtext_get_roam_prof(ndev, rp, band_val, &roam_prof_ver, |
---|
| 10951 | + &roam_prof_size))) { |
---|
| 10952 | + WL_ERR(("Getting roam_profile failed with err=%d \n", err)); |
---|
| 10953 | + err = -EINVAL; |
---|
| 10954 | + goto exit; |
---|
| 10955 | + } |
---|
| 10956 | + if (argc == 2) { |
---|
| 10957 | + /* if delta is non integer returns command usage error */ |
---|
| 10958 | + val = simple_strtol(delta, &endptr, 0); |
---|
| 10959 | + if (*endptr != '\0') { |
---|
| 10960 | + WL_ERR(("%s: Command usage error", __func__)); |
---|
| 10961 | + goto exit; |
---|
| 10962 | + } |
---|
| 10963 | + for (i = 0; i < WL_MAX_ROAM_PROF_BRACKETS; i++) { |
---|
| 10964 | + /* |
---|
| 10965 | + * Checking contents of roam profile data from fw and exits |
---|
| 10966 | + * if code hits below condtion. If remaining length of buffer is |
---|
| 10967 | + * less than roam profile size or if there is no valid entry. |
---|
| 10968 | + */ |
---|
| 10969 | + if (((i * roam_prof_size) > rp->v1.len) || |
---|
| 10970 | + (rp->v1.roam_prof[i].fullscan_period == 0)) { |
---|
| 10971 | + break; |
---|
| 10972 | + } |
---|
| 10973 | + if (roam_prof_ver == WL_ROAM_PROF_VER_1) { |
---|
| 10974 | + if (rp->v2.roam_prof[i].channel_usage != 0) { |
---|
| 10975 | + rp->v2.roam_prof[i].roam_delta = val; |
---|
| 10976 | + } |
---|
| 10977 | + } else if (roam_prof_ver == WL_ROAM_PROF_VER_2) { |
---|
| 10978 | + if (rp->v3.roam_prof[i].channel_usage != 0) { |
---|
| 10979 | + rp->v3.roam_prof[i].roam_delta = val; |
---|
| 10980 | + } |
---|
| 10981 | + } |
---|
| 10982 | + len += roam_prof_size; |
---|
| 10983 | + } |
---|
| 10984 | + } |
---|
| 10985 | + else { |
---|
| 10986 | + if (rp->v2.roam_prof[0].channel_usage != 0) { |
---|
| 10987 | + bytes_written = snprintf(command, total_len, |
---|
| 10988 | + "%s Delta %d\n", (rp->v1.band == WLC_BAND_2G) ? "2G" : "5G", |
---|
| 10989 | + rp->v2.roam_prof[0].roam_delta); |
---|
| 10990 | + } |
---|
| 10991 | + err = bytes_written; |
---|
| 10992 | + goto exit; |
---|
| 10993 | + } |
---|
| 10994 | + rp->v1.len = len; |
---|
| 10995 | + if ((err = wldev_iovar_setbuf(ndev, "roam_prof", rp, |
---|
| 10996 | + sizeof(*rp), cfg->ioctl_buf, WLC_IOCTL_MEDLEN, |
---|
| 10997 | + &cfg->ioctl_buf_sync)) < 0) { |
---|
| 10998 | + WL_ERR(("seting roam_profile failed with err %d\n", err)); |
---|
| 10999 | + } |
---|
| 11000 | +exit : |
---|
| 11001 | + if (rp) { |
---|
| 11002 | + MFREE(cfg->osh, rp, sizeof(*rp)); |
---|
| 11003 | + } |
---|
| 11004 | + return err; |
---|
| 11005 | +} |
---|
| 11006 | +#endif /* WBTEXT */ |
---|