]>
Commit | Line | Data |
---|---|---|
e215a871 CL |
1 | #include <linux/slab.h> |
2 | #include <linux/time.h> | |
3 | #include <linux/kthread.h> | |
4 | #include <linux/delay.h> | |
c5c77ba1 | 5 | #include "host_interface.h" |
c5c77ba1 | 6 | #include "coreconfigurator.h" |
5366012d | 7 | #include "wilc_wlan_if.h" |
f23eb98b | 8 | #include "wilc_msgqueue.h" |
281dd5ac | 9 | #include <linux/etherdevice.h> |
d5382219 | 10 | #include "wilc_wfi_netdevice.h" |
c5c77ba1 | 11 | |
63d03e47 | 12 | extern u8 connecting; |
c5c77ba1 | 13 | |
da711eb6 | 14 | extern struct timer_list hDuringIpTimer; |
c5c77ba1 | 15 | |
63d03e47 | 16 | extern u8 g_wilc_initialized; |
c5c77ba1 | 17 | |
9eac3a15 CL |
18 | #define HOST_IF_MSG_SCAN 0 |
19 | #define HOST_IF_MSG_CONNECT 1 | |
20 | #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2 | |
21 | #define HOST_IF_MSG_KEY 3 | |
22 | #define HOST_IF_MSG_RCVD_NTWRK_INFO 4 | |
23 | #define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5 | |
24 | #define HOST_IF_MSG_CFG_PARAMS 6 | |
25 | #define HOST_IF_MSG_SET_CHANNEL 7 | |
26 | #define HOST_IF_MSG_DISCONNECT 8 | |
27 | #define HOST_IF_MSG_GET_RSSI 9 | |
28 | #define HOST_IF_MSG_GET_CHNL 10 | |
29 | #define HOST_IF_MSG_ADD_BEACON 11 | |
30 | #define HOST_IF_MSG_DEL_BEACON 12 | |
31 | #define HOST_IF_MSG_ADD_STATION 13 | |
32 | #define HOST_IF_MSG_DEL_STATION 14 | |
33 | #define HOST_IF_MSG_EDIT_STATION 15 | |
34 | #define HOST_IF_MSG_SCAN_TIMER_FIRED 16 | |
35 | #define HOST_IF_MSG_CONNECT_TIMER_FIRED 17 | |
36 | #define HOST_IF_MSG_POWER_MGMT 18 | |
37 | #define HOST_IF_MSG_GET_INACTIVETIME 19 | |
38 | #define HOST_IF_MSG_REMAIN_ON_CHAN 20 | |
39 | #define HOST_IF_MSG_REGISTER_FRAME 21 | |
40 | #define HOST_IF_MSG_LISTEN_TIMER_FIRED 22 | |
41 | #define HOST_IF_MSG_GET_LINKSPEED 23 | |
42 | #define HOST_IF_MSG_SET_WFIDRV_HANDLER 24 | |
43 | #define HOST_IF_MSG_SET_MAC_ADDRESS 25 | |
44 | #define HOST_IF_MSG_GET_MAC_ADDRESS 26 | |
45 | #define HOST_IF_MSG_SET_OPERATION_MODE 27 | |
46 | #define HOST_IF_MSG_SET_IPADDRESS 28 | |
47 | #define HOST_IF_MSG_GET_IPADDRESS 29 | |
48 | #define HOST_IF_MSG_FLUSH_CONNECT 30 | |
49 | #define HOST_IF_MSG_GET_STATISTICS 31 | |
50 | #define HOST_IF_MSG_SET_MULTICAST_FILTER 32 | |
51 | #define HOST_IF_MSG_ADD_BA_SESSION 33 | |
52 | #define HOST_IF_MSG_DEL_BA_SESSION 34 | |
53 | #define HOST_IF_MSG_Q_IDLE 35 | |
54 | #define HOST_IF_MSG_DEL_ALL_STA 36 | |
55 | #define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS 34 | |
56 | #define HOST_IF_MSG_EXIT 100 | |
d85f5326 | 57 | |
e54d5b75 CL |
58 | #define HOST_IF_SCAN_TIMEOUT 4000 |
59 | #define HOST_IF_CONNECT_TIMEOUT 9500 | |
c5c77ba1 | 60 | |
e54d5b75 CL |
61 | #define BA_SESSION_DEFAULT_BUFFER_SIZE 16 |
62 | #define BA_SESSION_DEFAULT_TIMEOUT 1000 | |
63 | #define BLOCK_ACK_REQ_SIZE 0x14 | |
9f3295a2 | 64 | #define FALSE_FRMWR_CHANNEL 100 |
c5c77ba1 | 65 | |
361ff841 | 66 | struct cfg_param_attr { |
221371e5 | 67 | struct cfg_param_val cfg_attr_info; |
361ff841 | 68 | }; |
c5c77ba1 | 69 | |
4372d3d3 | 70 | struct host_if_wpa_attr { |
124968fc | 71 | u8 *key; |
248080aa | 72 | const u8 *mac_addr; |
0e74c009 | 73 | u8 *seq; |
dacc594d | 74 | u8 seq_len; |
e2dfbac5 | 75 | u8 index; |
6acf2919 | 76 | u8 key_len; |
7b2ebb28 | 77 | u8 mode; |
4372d3d3 | 78 | }; |
c5c77ba1 | 79 | |
c276c44a | 80 | struct host_if_wep_attr { |
e5538d34 | 81 | u8 *key; |
d520e355 | 82 | u8 key_len; |
259b3aa6 | 83 | u8 index; |
b5eaff12 | 84 | u8 mode; |
7fa252e7 | 85 | enum AUTHTYPE auth_type; |
c276c44a | 86 | }; |
c5c77ba1 | 87 | |
40cc2c90 | 88 | union host_if_key_attr { |
2ed7a2fb | 89 | struct host_if_wep_attr wep; |
e3501a4d | 90 | struct host_if_wpa_attr wpa; |
610e3868 | 91 | struct host_if_pmkid_attr pmkid; |
40cc2c90 | 92 | }; |
c5c77ba1 | 93 | |
c98387a5 | 94 | struct key_attr { |
8e9f427a | 95 | enum KEY_TYPE type; |
0d17e382 | 96 | u8 action; |
73b2e381 | 97 | union host_if_key_attr attr; |
c98387a5 | 98 | }; |
c5c77ba1 | 99 | |
c476feb8 | 100 | struct scan_attr { |
42568898 | 101 | u8 src; |
1e276c88 | 102 | u8 type; |
82eeb0ad | 103 | u8 *ch_freq_list; |
f97bd9ca | 104 | u8 ch_list_len; |
d6f19aa5 | 105 | u8 *ies; |
7b1f76cd | 106 | size_t ies_len; |
c17c6da6 | 107 | wilc_scan_result result; |
5f2b50c8 | 108 | void *arg; |
629b9ca0 | 109 | struct hidden_network hidden_network; |
c476feb8 | 110 | }; |
c5c77ba1 | 111 | |
120ae593 | 112 | struct connect_attr { |
9254db07 | 113 | u8 *bssid; |
f7bbd9cf | 114 | u8 *ssid; |
8b3c9fa6 | 115 | size_t ssid_len; |
2ea158c4 | 116 | u8 *ies; |
b59d5c5b | 117 | size_t ies_len; |
a64fd677 | 118 | u8 security; |
6abcc11d | 119 | wilc_connect_result result; |
8f38db89 | 120 | void *arg; |
61b4fd02 | 121 | enum AUTHTYPE auth_type; |
0d1527e6 | 122 | u8 ch; |
f2bed2ca | 123 | void *params; |
120ae593 | 124 | }; |
c5c77ba1 | 125 | |
f23a9eab | 126 | struct rcvd_async_info { |
33722ac7 | 127 | u8 *buffer; |
f94f4889 | 128 | u32 len; |
f23a9eab | 129 | }; |
c5c77ba1 | 130 | |
94bdfe42 | 131 | struct channel_attr { |
730ee059 | 132 | u8 set_ch; |
326b323d | 133 | }; |
c5c77ba1 | 134 | |
7f33fecd | 135 | struct beacon_attr { |
12262dda | 136 | u32 interval; |
e76ab770 | 137 | u32 dtim_period; |
51c66185 | 138 | u32 head_len; |
8ce528b9 | 139 | u8 *head; |
030c57e2 | 140 | u32 tail_len; |
7dbcb6d3 | 141 | u8 *tail; |
902362b1 | 142 | }; |
c5c77ba1 | 143 | |
641210ac | 144 | struct set_multicast { |
bae636eb | 145 | bool enabled; |
adab2f71 | 146 | u32 cnt; |
641210ac | 147 | }; |
c5c77ba1 | 148 | |
b4e644e4 | 149 | struct del_all_sta { |
e51b9216 | 150 | u8 del_all_sta[MAX_NUM_STA][ETH_ALEN]; |
8ba1803f | 151 | u8 assoc_sta; |
b4e644e4 | 152 | }; |
c5c77ba1 | 153 | |
fb93a1e1 | 154 | struct del_sta { |
e4839d39 | 155 | u8 mac_addr[ETH_ALEN]; |
fb93a1e1 | 156 | }; |
c5c77ba1 | 157 | |
5a008f1c | 158 | struct power_mgmt_param { |
33c70c1b | 159 | bool enabled; |
937918ff | 160 | u32 timeout; |
5a008f1c | 161 | }; |
c5c77ba1 | 162 | |
15191eaf | 163 | struct set_ip_addr { |
78675be5 | 164 | u8 *ip_addr; |
63d03e47 | 165 | u8 idx; |
15191eaf | 166 | }; |
c5c77ba1 | 167 | |
3d1eac04 | 168 | struct sta_inactive_t { |
63d03e47 | 169 | u8 mac[6]; |
3d1eac04 | 170 | }; |
ae4dfa57 | 171 | |
dfc7663b | 172 | union message_body { |
4528bdb5 | 173 | struct scan_attr scan_info; |
3f501971 | 174 | struct connect_attr con_info; |
02d19460 | 175 | struct rcvd_net_info net_info; |
66add622 | 176 | struct rcvd_async_info async_info; |
18990bfe | 177 | struct key_attr key_info; |
a2340c36 | 178 | struct cfg_param_attr cfg_info; |
ffd6dbc8 | 179 | struct channel_attr channel_info; |
a98491e5 | 180 | struct beacon_attr beacon_info; |
ca8f47f8 | 181 | struct add_sta_param add_sta_info; |
889c25be | 182 | struct del_sta del_sta_info; |
4a930962 | 183 | struct add_sta_param edit_sta_info; |
49e1f81b | 184 | struct power_mgmt_param pwr_mgmt_info; |
66bac7f2 | 185 | struct sta_inactive_t mac_info; |
fb2d65ed | 186 | struct set_ip_addr ip_info; |
5e4377e6 | 187 | struct drv_handler drv; |
a079cf4d | 188 | struct set_multicast multicast_info; |
00c4630e | 189 | struct op_mode mode; |
15326e28 | 190 | struct set_mac_addr set_mac_info; |
a5848695 | 191 | struct get_mac_addr get_mac_info; |
c833b474 | 192 | struct ba_session_info session_info; |
070d365c | 193 | struct remain_ch remain_on_ch; |
5c4008db | 194 | struct reg_frame reg_frame; |
e60831e9 | 195 | char *data; |
b0c1e80e | 196 | struct del_all_sta del_all_sta_info; |
dfc7663b | 197 | }; |
c5c77ba1 | 198 | |
3a8c41b5 | 199 | struct host_if_msg { |
ae4dfa57 LK |
200 | u16 id; |
201 | union message_body body; | |
2482a79f | 202 | struct host_if_drv *drv; |
3a8c41b5 | 203 | }; |
c5c77ba1 | 204 | |
e0a12217 | 205 | struct join_bss_param { |
c5c77ba1 | 206 | BSSTYPE_T bss_type; |
63d03e47 | 207 | u8 dtim_period; |
d85f5326 CL |
208 | u16 beacon_period; |
209 | u16 cap_info; | |
63d03e47 | 210 | u8 au8bssid[6]; |
576917ad | 211 | char ssid[MAX_SSID_LEN]; |
619d27b8 | 212 | u8 ssid_len; |
63d03e47 GKH |
213 | u8 supp_rates[MAX_RATES_SUPPORTED + 1]; |
214 | u8 ht_capable; | |
215 | u8 wmm_cap; | |
216 | u8 uapsd_cap; | |
72ed4dc7 | 217 | bool rsn_found; |
63d03e47 GKH |
218 | u8 rsn_grp_policy; |
219 | u8 mode_802_11i; | |
220 | u8 rsn_pcip_policy[3]; | |
221 | u8 rsn_auth_policy[3]; | |
222 | u8 rsn_cap[2]; | |
4e4467fd | 223 | u32 tsf; |
7a8d51d7 | 224 | u8 noa_enabled; |
d72b33ca | 225 | u8 opp_enabled; |
99b66945 | 226 | u8 ct_window; |
c21047ed | 227 | u8 cnt; |
cc179008 | 228 | u8 idx; |
109e6cab | 229 | u8 duration[4]; |
1d8b76b3 | 230 | u8 interval[4]; |
4be55e22 | 231 | u8 start_time[4]; |
e0a12217 | 232 | }; |
c5c77ba1 | 233 | |
441dc609 LK |
234 | static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1]; |
235 | struct host_if_drv *terminated_handle; | |
f2fc9f6e | 236 | bool g_obtainingIP; |
63d03e47 | 237 | u8 P2P_LISTEN_STATE; |
c2115d8e | 238 | static struct task_struct *hif_thread_handler; |
cb067dcf | 239 | static WILC_MsgQueueHandle hif_msg_q; |
834e0cb0 | 240 | static struct semaphore hif_sema_thread; |
413f930e | 241 | static struct semaphore hif_sema_driver; |
2d25af87 | 242 | static struct semaphore hif_sema_wait_response; |
17225002 | 243 | static struct semaphore hif_sema_deinit; |
24aadb8b | 244 | static struct timer_list periodic_rssi; |
c5c77ba1 | 245 | |
fb70e9f5 | 246 | u8 multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; |
c5c77ba1 | 247 | |
a633c0b5 | 248 | static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE]; |
c5c77ba1 | 249 | |
f64321c6 | 250 | static bool scan_while_connected; |
c5c77ba1 | 251 | |
144b7b23 | 252 | static s8 rssi; |
75327a02 | 253 | static s8 link_speed; |
95ebb0ff | 254 | static u8 ch_no; |
078b1e98 | 255 | static u8 set_ip[2][4]; |
1e75d01c | 256 | static u8 get_ip[2][4]; |
ad26906f | 257 | static u32 inactive_time; |
a74c7bf8 | 258 | static u8 del_beacon; |
7178aed8 | 259 | static u32 clients_count; |
c5c77ba1 | 260 | |
ef599194 | 261 | static u8 *join_req; |
48ce2465 | 262 | u8 *info_element; |
23047d5b | 263 | static u8 mode_11i; |
fba4989e | 264 | u8 auth_type; |
0626baaa | 265 | u32 join_req_size; |
5e0e7c2e | 266 | static u32 info_element_size; |
23fba59d | 267 | static struct host_if_drv *join_req_drv; |
c5c77ba1 JK |
268 | #define REAL_JOIN_REQ 0 |
269 | #define FLUSHED_JOIN_REQ 1 | |
ae4dfa57 | 270 | #define FLUSHED_BYTE_POS 79 |
c5c77ba1 | 271 | |
c5c77ba1 | 272 | static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo); |
c5c77ba1 | 273 | |
c5c77ba1 JK |
274 | extern int linux_wlan_get_num_conn_ifcs(void); |
275 | ||
441dc609 | 276 | static int add_handler_in_list(struct host_if_drv *handler) |
d42ab083 JK |
277 | { |
278 | int i; | |
279 | ||
280 | for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) { | |
281 | if (!wfidrv_list[i]) { | |
282 | wfidrv_list[i] = handler; | |
283 | return 0; | |
284 | } | |
285 | } | |
286 | ||
287 | return -ENOBUFS; | |
288 | } | |
289 | ||
441dc609 | 290 | static int remove_handler_in_list(struct host_if_drv *handler) |
d42ab083 JK |
291 | { |
292 | int i; | |
293 | ||
294 | for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) { | |
295 | if (wfidrv_list[i] == handler) { | |
296 | wfidrv_list[i] = NULL; | |
297 | return 0; | |
298 | } | |
299 | } | |
300 | ||
301 | return -EINVAL; | |
302 | } | |
303 | ||
441dc609 | 304 | static int get_id_from_handler(struct host_if_drv *handler) |
d42ab083 JK |
305 | { |
306 | int i; | |
307 | ||
308 | if (!handler) | |
309 | return 0; | |
310 | ||
311 | for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) { | |
312 | if (wfidrv_list[i] == handler) | |
313 | return i; | |
314 | } | |
315 | ||
316 | return 0; | |
317 | } | |
318 | ||
441dc609 | 319 | static struct host_if_drv *get_handler_from_id(int id) |
d42ab083 | 320 | { |
6ae9ac0b | 321 | if (id <= 0 || id >= ARRAY_SIZE(wfidrv_list)) |
d42ab083 JK |
322 | return NULL; |
323 | return wfidrv_list[id]; | |
324 | } | |
325 | ||
3eec50cf | 326 | static s32 handle_set_channel(struct host_if_drv *hif_drv, |
9cf7878c | 327 | struct channel_attr *hif_set_ch) |
c5c77ba1 | 328 | { |
31390eec | 329 | s32 result = 0; |
45102f83 | 330 | struct wid wid; |
c5c77ba1 | 331 | |
45102f83 LK |
332 | wid.id = (u16)WID_CURRENT_CHANNEL; |
333 | wid.type = WID_CHAR; | |
9cf7878c | 334 | wid.val = (char *)&hif_set_ch->set_ch; |
45102f83 | 335 | wid.size = sizeof(char); |
c5c77ba1 JK |
336 | |
337 | PRINT_D(HOSTINF_DBG, "Setting channel\n"); | |
ae4dfa57 | 338 | |
45102f83 | 339 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 340 | get_id_from_handler(hif_drv)); |
31390eec LK |
341 | |
342 | if (result) { | |
c5c77ba1 | 343 | PRINT_ER("Failed to set channel\n"); |
24db713f | 344 | return -EINVAL; |
c5c77ba1 JK |
345 | } |
346 | ||
31390eec | 347 | return result; |
c5c77ba1 | 348 | } |
ae4dfa57 | 349 | |
23f2badd LK |
350 | static s32 handle_set_wfi_drv_handler(struct host_if_drv *hif_drv, |
351 | struct drv_handler *hif_drv_handler) | |
c5c77ba1 | 352 | { |
31390eec | 353 | s32 result = 0; |
45102f83 | 354 | struct wid wid; |
c5c77ba1 | 355 | |
45102f83 LK |
356 | wid.id = (u16)WID_SET_DRV_HANDLER; |
357 | wid.type = WID_INT; | |
6b73c744 | 358 | wid.val = (s8 *)&hif_drv_handler->handler; |
45102f83 | 359 | wid.size = sizeof(u32); |
c5c77ba1 | 360 | |
6b73c744 | 361 | result = send_config_pkt(SET_CFG, &wid, 1, hif_drv_handler->handler); |
c5c77ba1 | 362 | |
a4ab1ade | 363 | if (!hif_drv) |
27ff2168 | 364 | up(&hif_sema_driver); |
c5c77ba1 | 365 | |
31390eec | 366 | if (result) { |
c5c77ba1 | 367 | PRINT_ER("Failed to set driver handler\n"); |
24db713f | 368 | return -EINVAL; |
c5c77ba1 JK |
369 | } |
370 | ||
31390eec | 371 | return result; |
c5c77ba1 JK |
372 | } |
373 | ||
97b5c591 LK |
374 | static s32 handle_set_operation_mode(struct host_if_drv *hif_drv, |
375 | struct op_mode *hif_op_mode) | |
c5c77ba1 | 376 | { |
31390eec | 377 | s32 result = 0; |
45102f83 | 378 | struct wid wid; |
c5c77ba1 | 379 | |
45102f83 LK |
380 | wid.id = (u16)WID_SET_OPERATION_MODE; |
381 | wid.type = WID_INT; | |
acff1d71 | 382 | wid.val = (s8 *)&hif_op_mode->mode; |
45102f83 | 383 | wid.size = sizeof(u32); |
c5c77ba1 | 384 | |
45102f83 | 385 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 386 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 387 | |
acff1d71 | 388 | if ((hif_op_mode->mode) == IDLE_MODE) |
27ff2168 | 389 | up(&hif_sema_driver); |
c5c77ba1 | 390 | |
31390eec | 391 | if (result) { |
c5c77ba1 | 392 | PRINT_ER("Failed to set driver handler\n"); |
24db713f | 393 | return -EINVAL; |
c5c77ba1 JK |
394 | } |
395 | ||
31390eec | 396 | return result; |
c5c77ba1 JK |
397 | } |
398 | ||
a6e6d48b | 399 | s32 handle_set_ip_address(struct host_if_drv *hif_drv, u8 *ip_addr, u8 idx) |
c5c77ba1 | 400 | { |
31390eec | 401 | s32 result = 0; |
45102f83 | 402 | struct wid wid; |
ebc57d19 | 403 | char firmware_ip_addr[4] = {0}; |
c5c77ba1 | 404 | |
a6527c3b LK |
405 | if (ip_addr[0] < 192) |
406 | ip_addr[0] = 0; | |
c5c77ba1 | 407 | |
a6527c3b LK |
408 | PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set IP = %pI4\n", |
409 | idx, ip_addr); | |
c5c77ba1 | 410 | |
a6527c3b | 411 | memcpy(set_ip[idx], ip_addr, IP_ALEN); |
c5c77ba1 | 412 | |
45102f83 LK |
413 | wid.id = (u16)WID_IP_ADDRESS; |
414 | wid.type = WID_STR; | |
a6527c3b | 415 | wid.val = (u8 *)ip_addr; |
45102f83 | 416 | wid.size = IP_ALEN; |
c5c77ba1 | 417 | |
45102f83 | 418 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 419 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 420 | |
ebc57d19 | 421 | host_int_get_ipaddress(hif_drv, firmware_ip_addr, idx); |
c5c77ba1 | 422 | |
31390eec | 423 | if (result) { |
24db713f LK |
424 | PRINT_ER("Failed to set IP address\n"); |
425 | return -EINVAL; | |
c5c77ba1 JK |
426 | } |
427 | ||
24db713f | 428 | PRINT_INFO(HOSTINF_DBG, "IP address set\n"); |
c5c77ba1 | 429 | |
31390eec | 430 | return result; |
c5c77ba1 JK |
431 | } |
432 | ||
d4516952 | 433 | s32 handle_get_ip_address(struct host_if_drv *hif_drv, u8 idx) |
c5c77ba1 | 434 | { |
31390eec | 435 | s32 result = 0; |
45102f83 | 436 | struct wid wid; |
c5c77ba1 | 437 | |
45102f83 LK |
438 | wid.id = (u16)WID_IP_ADDRESS; |
439 | wid.type = WID_STR; | |
440 | wid.val = kmalloc(IP_ALEN, GFP_KERNEL); | |
441 | wid.size = IP_ALEN; | |
c5c77ba1 | 442 | |
45102f83 | 443 | result = send_config_pkt(GET_CFG, &wid, 1, |
8c8360b3 | 444 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 445 | |
45102f83 | 446 | PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val); |
c5c77ba1 | 447 | |
45102f83 | 448 | memcpy(get_ip[idx], wid.val, IP_ALEN); |
c5c77ba1 | 449 | |
45102f83 | 450 | kfree(wid.val); |
c5c77ba1 | 451 | |
1e75d01c | 452 | if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0) |
078b1e98 | 453 | host_int_setup_ipaddress(hif_drv, set_ip[idx], idx); |
c5c77ba1 | 454 | |
31390eec | 455 | if (result != 0) { |
c5c77ba1 | 456 | PRINT_ER("Failed to get IP address\n"); |
24db713f | 457 | return -EINVAL; |
c5c77ba1 JK |
458 | } |
459 | ||
24db713f | 460 | PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d\n", idx); |
1e75d01c | 461 | PRINT_INFO(HOSTINF_DBG, "%pI4\n", get_ip[idx]); |
24db713f | 462 | PRINT_INFO(HOSTINF_DBG, "\n"); |
c5c77ba1 | 463 | |
31390eec | 464 | return result; |
c5c77ba1 JK |
465 | } |
466 | ||
a8267421 LK |
467 | static s32 handle_set_mac_address(struct host_if_drv *hif_drv, |
468 | struct set_mac_addr *set_mac_addr) | |
c5c77ba1 | 469 | { |
31390eec | 470 | s32 result = 0; |
45102f83 | 471 | struct wid wid; |
f3052587 | 472 | u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL); |
c09389ac | 473 | |
91109e11 | 474 | if (!mac_buf) { |
c5c77ba1 | 475 | PRINT_ER("No buffer to send mac address\n"); |
e6e12661 | 476 | return -EFAULT; |
c5c77ba1 | 477 | } |
090dbb10 | 478 | memcpy(mac_buf, set_mac_addr->mac_addr, ETH_ALEN); |
c5c77ba1 | 479 | |
45102f83 LK |
480 | wid.id = (u16)WID_MAC_ADDR; |
481 | wid.type = WID_STR; | |
482 | wid.val = mac_buf; | |
483 | wid.size = ETH_ALEN; | |
484 | PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val); | |
ae4dfa57 | 485 | |
45102f83 | 486 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 487 | get_id_from_handler(hif_drv)); |
31390eec | 488 | if (result) { |
c5c77ba1 | 489 | PRINT_ER("Failed to set mac address\n"); |
31390eec | 490 | result = -EFAULT; |
c5c77ba1 JK |
491 | } |
492 | ||
49188af2 | 493 | kfree(mac_buf); |
31390eec | 494 | return result; |
c5c77ba1 JK |
495 | } |
496 | ||
b3bf8fd9 LK |
497 | static s32 handle_get_mac_address(struct host_if_drv *hif_drv, |
498 | struct get_mac_addr *get_mac_addr) | |
c5c77ba1 | 499 | { |
31390eec | 500 | s32 result = 0; |
45102f83 | 501 | struct wid wid; |
c5c77ba1 | 502 | |
45102f83 LK |
503 | wid.id = (u16)WID_MAC_ADDR; |
504 | wid.type = WID_STR; | |
7f0ee9a6 | 505 | wid.val = get_mac_addr->mac_addr; |
45102f83 | 506 | wid.size = ETH_ALEN; |
c5c77ba1 | 507 | |
45102f83 | 508 | result = send_config_pkt(GET_CFG, &wid, 1, |
8c8360b3 | 509 | get_id_from_handler(hif_drv)); |
31390eec LK |
510 | |
511 | if (result) { | |
c5c77ba1 | 512 | PRINT_ER("Failed to get mac address\n"); |
31390eec | 513 | result = -EFAULT; |
c5c77ba1 | 514 | } |
2d25af87 | 515 | up(&hif_sema_wait_response); |
c5c77ba1 | 516 | |
31390eec | 517 | return result; |
c5c77ba1 JK |
518 | } |
519 | ||
dc276664 LK |
520 | static s32 handle_cfg_param(struct host_if_drv *hif_drv, |
521 | struct cfg_param_attr *cfg_param_attr) | |
c5c77ba1 | 522 | { |
31390eec | 523 | s32 result = 0; |
13ca52ad | 524 | struct wid wid_list[32]; |
540c3e88 | 525 | u8 wid_cnt = 0; |
c5c77ba1 | 526 | |
33110ad7 | 527 | down(&hif_drv->sem_cfg_values); |
c5c77ba1 | 528 | |
c5c77ba1 JK |
529 | PRINT_D(HOSTINF_DBG, "Setting CFG params\n"); |
530 | ||
02ae2bdf LK |
531 | if (cfg_param_attr->cfg_attr_info.flag & BSS_TYPE) { |
532 | if (cfg_param_attr->cfg_attr_info.bss_type < 6) { | |
540c3e88 LK |
533 | wid_list[wid_cnt].id = WID_BSS_TYPE; |
534 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.bss_type; | |
535 | wid_list[wid_cnt].type = WID_CHAR; | |
536 | wid_list[wid_cnt].size = sizeof(char); | |
02ae2bdf | 537 | hif_drv->cfg_values.bss_type = (u8)cfg_param_attr->cfg_attr_info.bss_type; |
c5c77ba1 | 538 | } else { |
24db713f | 539 | PRINT_ER("check value 6 over\n"); |
31390eec | 540 | result = -EINVAL; |
24db713f | 541 | goto ERRORHANDLER; |
c5c77ba1 | 542 | } |
540c3e88 | 543 | wid_cnt++; |
c5c77ba1 | 544 | } |
02ae2bdf LK |
545 | if (cfg_param_attr->cfg_attr_info.flag & AUTH_TYPE) { |
546 | if (cfg_param_attr->cfg_attr_info.auth_type == 1 || | |
547 | cfg_param_attr->cfg_attr_info.auth_type == 2 || | |
548 | cfg_param_attr->cfg_attr_info.auth_type == 5) { | |
540c3e88 LK |
549 | wid_list[wid_cnt].id = WID_AUTH_TYPE; |
550 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_type; | |
551 | wid_list[wid_cnt].type = WID_CHAR; | |
552 | wid_list[wid_cnt].size = sizeof(char); | |
02ae2bdf | 553 | hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->cfg_attr_info.auth_type; |
c5c77ba1 | 554 | } else { |
24db713f | 555 | PRINT_ER("Impossible value \n"); |
31390eec | 556 | result = -EINVAL; |
24db713f | 557 | goto ERRORHANDLER; |
c5c77ba1 | 558 | } |
540c3e88 | 559 | wid_cnt++; |
c5c77ba1 | 560 | } |
02ae2bdf LK |
561 | if (cfg_param_attr->cfg_attr_info.flag & AUTHEN_TIMEOUT) { |
562 | if (cfg_param_attr->cfg_attr_info.auth_timeout > 0 && | |
563 | cfg_param_attr->cfg_attr_info.auth_timeout < 65536) { | |
540c3e88 LK |
564 | wid_list[wid_cnt].id = WID_AUTH_TIMEOUT; |
565 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.auth_timeout; | |
566 | wid_list[wid_cnt].type = WID_SHORT; | |
567 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 568 | hif_drv->cfg_values.auth_timeout = cfg_param_attr->cfg_attr_info.auth_timeout; |
c5c77ba1 | 569 | } else { |
24db713f | 570 | PRINT_ER("Range(1 ~ 65535) over\n"); |
31390eec | 571 | result = -EINVAL; |
24db713f | 572 | goto ERRORHANDLER; |
c5c77ba1 | 573 | } |
540c3e88 | 574 | wid_cnt++; |
c5c77ba1 | 575 | } |
02ae2bdf LK |
576 | if (cfg_param_attr->cfg_attr_info.flag & POWER_MANAGEMENT) { |
577 | if (cfg_param_attr->cfg_attr_info.power_mgmt_mode < 5) { | |
540c3e88 LK |
578 | wid_list[wid_cnt].id = WID_POWER_MANAGEMENT; |
579 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.power_mgmt_mode; | |
580 | wid_list[wid_cnt].type = WID_CHAR; | |
581 | wid_list[wid_cnt].size = sizeof(char); | |
02ae2bdf | 582 | hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->cfg_attr_info.power_mgmt_mode; |
c5c77ba1 | 583 | } else { |
24db713f | 584 | PRINT_ER("Invalide power mode\n"); |
31390eec | 585 | result = -EINVAL; |
24db713f | 586 | goto ERRORHANDLER; |
c5c77ba1 | 587 | } |
540c3e88 | 588 | wid_cnt++; |
c5c77ba1 | 589 | } |
02ae2bdf LK |
590 | if (cfg_param_attr->cfg_attr_info.flag & RETRY_SHORT) { |
591 | if (cfg_param_attr->cfg_attr_info.short_retry_limit > 0 && | |
592 | cfg_param_attr->cfg_attr_info.short_retry_limit < 256) { | |
540c3e88 LK |
593 | wid_list[wid_cnt].id = WID_SHORT_RETRY_LIMIT; |
594 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_retry_limit; | |
595 | wid_list[wid_cnt].type = WID_SHORT; | |
596 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 597 | hif_drv->cfg_values.short_retry_limit = cfg_param_attr->cfg_attr_info.short_retry_limit; |
c5c77ba1 | 598 | } else { |
24db713f | 599 | PRINT_ER("Range(1~256) over\n"); |
31390eec | 600 | result = -EINVAL; |
24db713f | 601 | goto ERRORHANDLER; |
c5c77ba1 | 602 | } |
540c3e88 | 603 | wid_cnt++; |
c5c77ba1 | 604 | } |
02ae2bdf LK |
605 | if (cfg_param_attr->cfg_attr_info.flag & RETRY_LONG) { |
606 | if (cfg_param_attr->cfg_attr_info.long_retry_limit > 0 && | |
607 | cfg_param_attr->cfg_attr_info.long_retry_limit < 256) { | |
540c3e88 LK |
608 | wid_list[wid_cnt].id = WID_LONG_RETRY_LIMIT; |
609 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.long_retry_limit; | |
610 | wid_list[wid_cnt].type = WID_SHORT; | |
611 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 612 | hif_drv->cfg_values.long_retry_limit = cfg_param_attr->cfg_attr_info.long_retry_limit; |
c5c77ba1 | 613 | } else { |
24db713f | 614 | PRINT_ER("Range(1~256) over\n"); |
31390eec | 615 | result = -EINVAL; |
24db713f | 616 | goto ERRORHANDLER; |
c5c77ba1 | 617 | } |
540c3e88 | 618 | wid_cnt++; |
c5c77ba1 | 619 | } |
02ae2bdf LK |
620 | if (cfg_param_attr->cfg_attr_info.flag & FRAG_THRESHOLD) { |
621 | if (cfg_param_attr->cfg_attr_info.frag_threshold > 255 && | |
622 | cfg_param_attr->cfg_attr_info.frag_threshold < 7937) { | |
540c3e88 LK |
623 | wid_list[wid_cnt].id = WID_FRAG_THRESHOLD; |
624 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.frag_threshold; | |
625 | wid_list[wid_cnt].type = WID_SHORT; | |
626 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 627 | hif_drv->cfg_values.frag_threshold = cfg_param_attr->cfg_attr_info.frag_threshold; |
c5c77ba1 | 628 | } else { |
24db713f | 629 | PRINT_ER("Threshold Range fail\n"); |
31390eec | 630 | result = -EINVAL; |
24db713f | 631 | goto ERRORHANDLER; |
c5c77ba1 | 632 | } |
540c3e88 | 633 | wid_cnt++; |
c5c77ba1 | 634 | } |
02ae2bdf LK |
635 | if (cfg_param_attr->cfg_attr_info.flag & RTS_THRESHOLD) { |
636 | if (cfg_param_attr->cfg_attr_info.rts_threshold > 255 && | |
637 | cfg_param_attr->cfg_attr_info.rts_threshold < 65536) { | |
540c3e88 LK |
638 | wid_list[wid_cnt].id = WID_RTS_THRESHOLD; |
639 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.rts_threshold; | |
640 | wid_list[wid_cnt].type = WID_SHORT; | |
641 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 642 | hif_drv->cfg_values.rts_threshold = cfg_param_attr->cfg_attr_info.rts_threshold; |
c5c77ba1 | 643 | } else { |
24db713f | 644 | PRINT_ER("Threshold Range fail\n"); |
31390eec | 645 | result = -EINVAL; |
24db713f | 646 | goto ERRORHANDLER; |
c5c77ba1 | 647 | } |
540c3e88 | 648 | wid_cnt++; |
c5c77ba1 | 649 | } |
02ae2bdf LK |
650 | if (cfg_param_attr->cfg_attr_info.flag & PREAMBLE) { |
651 | if (cfg_param_attr->cfg_attr_info.preamble_type < 3) { | |
540c3e88 LK |
652 | wid_list[wid_cnt].id = WID_PREAMBLE; |
653 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.preamble_type; | |
654 | wid_list[wid_cnt].type = WID_CHAR; | |
655 | wid_list[wid_cnt].size = sizeof(char); | |
02ae2bdf | 656 | hif_drv->cfg_values.preamble_type = cfg_param_attr->cfg_attr_info.preamble_type; |
c5c77ba1 | 657 | } else { |
24db713f | 658 | PRINT_ER("Preamle Range(0~2) over\n"); |
31390eec | 659 | result = -EINVAL; |
24db713f | 660 | goto ERRORHANDLER; |
c5c77ba1 | 661 | } |
540c3e88 | 662 | wid_cnt++; |
c5c77ba1 | 663 | } |
02ae2bdf LK |
664 | if (cfg_param_attr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) { |
665 | if (cfg_param_attr->cfg_attr_info.short_slot_allowed < 2) { | |
540c3e88 LK |
666 | wid_list[wid_cnt].id = WID_SHORT_SLOT_ALLOWED; |
667 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.short_slot_allowed; | |
668 | wid_list[wid_cnt].type = WID_CHAR; | |
669 | wid_list[wid_cnt].size = sizeof(char); | |
02ae2bdf | 670 | hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->cfg_attr_info.short_slot_allowed; |
c5c77ba1 | 671 | } else { |
24db713f | 672 | PRINT_ER("Short slot(2) over\n"); |
31390eec | 673 | result = -EINVAL; |
24db713f | 674 | goto ERRORHANDLER; |
c5c77ba1 | 675 | } |
540c3e88 | 676 | wid_cnt++; |
c5c77ba1 | 677 | } |
02ae2bdf LK |
678 | if (cfg_param_attr->cfg_attr_info.flag & TXOP_PROT_DISABLE) { |
679 | if (cfg_param_attr->cfg_attr_info.txop_prot_disabled < 2) { | |
540c3e88 LK |
680 | wid_list[wid_cnt].id = WID_11N_TXOP_PROT_DISABLE; |
681 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.txop_prot_disabled; | |
682 | wid_list[wid_cnt].type = WID_CHAR; | |
683 | wid_list[wid_cnt].size = sizeof(char); | |
02ae2bdf | 684 | hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->cfg_attr_info.txop_prot_disabled; |
c5c77ba1 | 685 | } else { |
24db713f | 686 | PRINT_ER("TXOP prot disable\n"); |
31390eec | 687 | result = -EINVAL; |
24db713f | 688 | goto ERRORHANDLER; |
c5c77ba1 | 689 | } |
540c3e88 | 690 | wid_cnt++; |
c5c77ba1 | 691 | } |
02ae2bdf LK |
692 | if (cfg_param_attr->cfg_attr_info.flag & BEACON_INTERVAL) { |
693 | if (cfg_param_attr->cfg_attr_info.beacon_interval > 0 && | |
694 | cfg_param_attr->cfg_attr_info.beacon_interval < 65536) { | |
540c3e88 LK |
695 | wid_list[wid_cnt].id = WID_BEACON_INTERVAL; |
696 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.beacon_interval; | |
697 | wid_list[wid_cnt].type = WID_SHORT; | |
698 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 699 | hif_drv->cfg_values.beacon_interval = cfg_param_attr->cfg_attr_info.beacon_interval; |
c5c77ba1 | 700 | } else { |
24db713f | 701 | PRINT_ER("Beacon interval(1~65535) fail\n"); |
31390eec | 702 | result = -EINVAL; |
24db713f | 703 | goto ERRORHANDLER; |
c5c77ba1 | 704 | } |
540c3e88 | 705 | wid_cnt++; |
c5c77ba1 | 706 | } |
02ae2bdf LK |
707 | if (cfg_param_attr->cfg_attr_info.flag & DTIM_PERIOD) { |
708 | if (cfg_param_attr->cfg_attr_info.dtim_period > 0 && | |
709 | cfg_param_attr->cfg_attr_info.dtim_period < 256) { | |
540c3e88 LK |
710 | wid_list[wid_cnt].id = WID_DTIM_PERIOD; |
711 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.dtim_period; | |
712 | wid_list[wid_cnt].type = WID_CHAR; | |
713 | wid_list[wid_cnt].size = sizeof(char); | |
02ae2bdf | 714 | hif_drv->cfg_values.dtim_period = cfg_param_attr->cfg_attr_info.dtim_period; |
c5c77ba1 | 715 | } else { |
24db713f | 716 | PRINT_ER("DTIM range(1~255) fail\n"); |
31390eec | 717 | result = -EINVAL; |
24db713f | 718 | goto ERRORHANDLER; |
c5c77ba1 | 719 | } |
540c3e88 | 720 | wid_cnt++; |
c5c77ba1 | 721 | } |
02ae2bdf LK |
722 | if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY) { |
723 | if (cfg_param_attr->cfg_attr_info.site_survey_enabled < 3) { | |
540c3e88 LK |
724 | wid_list[wid_cnt].id = WID_SITE_SURVEY; |
725 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_enabled; | |
726 | wid_list[wid_cnt].type = WID_CHAR; | |
727 | wid_list[wid_cnt].size = sizeof(char); | |
02ae2bdf | 728 | hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->cfg_attr_info.site_survey_enabled; |
c5c77ba1 | 729 | } else { |
24db713f | 730 | PRINT_ER("Site survey disable\n"); |
31390eec | 731 | result = -EINVAL; |
24db713f | 732 | goto ERRORHANDLER; |
c5c77ba1 | 733 | } |
540c3e88 | 734 | wid_cnt++; |
c5c77ba1 | 735 | } |
02ae2bdf LK |
736 | if (cfg_param_attr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) { |
737 | if (cfg_param_attr->cfg_attr_info.site_survey_scan_time > 0 && | |
738 | cfg_param_attr->cfg_attr_info.site_survey_scan_time < 65536) { | |
540c3e88 LK |
739 | wid_list[wid_cnt].id = WID_SITE_SURVEY_SCAN_TIME; |
740 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.site_survey_scan_time; | |
741 | wid_list[wid_cnt].type = WID_SHORT; | |
742 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 743 | hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->cfg_attr_info.site_survey_scan_time; |
c5c77ba1 | 744 | } else { |
24db713f | 745 | PRINT_ER("Site survey scan time(1~65535) over\n"); |
31390eec | 746 | result = -EINVAL; |
24db713f | 747 | goto ERRORHANDLER; |
c5c77ba1 | 748 | } |
540c3e88 | 749 | wid_cnt++; |
c5c77ba1 | 750 | } |
02ae2bdf LK |
751 | if (cfg_param_attr->cfg_attr_info.flag & ACTIVE_SCANTIME) { |
752 | if (cfg_param_attr->cfg_attr_info.active_scan_time > 0 && | |
753 | cfg_param_attr->cfg_attr_info.active_scan_time < 65536) { | |
540c3e88 LK |
754 | wid_list[wid_cnt].id = WID_ACTIVE_SCAN_TIME; |
755 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.active_scan_time; | |
756 | wid_list[wid_cnt].type = WID_SHORT; | |
757 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 758 | hif_drv->cfg_values.active_scan_time = cfg_param_attr->cfg_attr_info.active_scan_time; |
c5c77ba1 | 759 | } else { |
24db713f | 760 | PRINT_ER("Active scan time(1~65535) over\n"); |
31390eec | 761 | result = -EINVAL; |
24db713f | 762 | goto ERRORHANDLER; |
c5c77ba1 | 763 | } |
540c3e88 | 764 | wid_cnt++; |
c5c77ba1 | 765 | } |
02ae2bdf LK |
766 | if (cfg_param_attr->cfg_attr_info.flag & PASSIVE_SCANTIME) { |
767 | if (cfg_param_attr->cfg_attr_info.passive_scan_time > 0 && | |
768 | cfg_param_attr->cfg_attr_info.passive_scan_time < 65536) { | |
540c3e88 LK |
769 | wid_list[wid_cnt].id = WID_PASSIVE_SCAN_TIME; |
770 | wid_list[wid_cnt].val = (s8 *)&cfg_param_attr->cfg_attr_info.passive_scan_time; | |
771 | wid_list[wid_cnt].type = WID_SHORT; | |
772 | wid_list[wid_cnt].size = sizeof(u16); | |
02ae2bdf | 773 | hif_drv->cfg_values.passive_scan_time = cfg_param_attr->cfg_attr_info.passive_scan_time; |
c5c77ba1 | 774 | } else { |
24db713f | 775 | PRINT_ER("Passive scan time(1~65535) over\n"); |
31390eec | 776 | result = -EINVAL; |
24db713f | 777 | goto ERRORHANDLER; |
c5c77ba1 | 778 | } |
540c3e88 | 779 | wid_cnt++; |
c5c77ba1 | 780 | } |
02ae2bdf LK |
781 | if (cfg_param_attr->cfg_attr_info.flag & CURRENT_TX_RATE) { |
782 | enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->cfg_attr_info.curr_tx_rate; | |
c09389ac | 783 | |
c5c77ba1 JK |
784 | if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 |
785 | || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 | |
786 | || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 | |
787 | || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 | |
788 | || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 | |
789 | || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) { | |
540c3e88 LK |
790 | wid_list[wid_cnt].id = WID_CURRENT_TX_RATE; |
791 | wid_list[wid_cnt].val = (s8 *)&curr_tx_rate; | |
792 | wid_list[wid_cnt].type = WID_SHORT; | |
793 | wid_list[wid_cnt].size = sizeof(u16); | |
ace303f0 | 794 | hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate; |
c5c77ba1 | 795 | } else { |
24db713f | 796 | PRINT_ER("out of TX rate\n"); |
31390eec | 797 | result = -EINVAL; |
24db713f | 798 | goto ERRORHANDLER; |
c5c77ba1 | 799 | } |
540c3e88 | 800 | wid_cnt++; |
c5c77ba1 | 801 | } |
31390eec | 802 | |
540c3e88 | 803 | result = send_config_pkt(SET_CFG, wid_list, wid_cnt, |
8c8360b3 | 804 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 805 | |
31390eec | 806 | if (result) |
c5c77ba1 JK |
807 | PRINT_ER("Error in setting CFG params\n"); |
808 | ||
24db713f | 809 | ERRORHANDLER: |
33110ad7 | 810 | up(&hif_drv->sem_cfg_values); |
31390eec | 811 | return result; |
c5c77ba1 JK |
812 | } |
813 | ||
3b840e49 | 814 | static void Handle_wait_msg_q_empty(void) |
c5c77ba1 | 815 | { |
c5c77ba1 | 816 | g_wilc_initialized = 0; |
2d25af87 | 817 | up(&hif_sema_wait_response); |
c5c77ba1 JK |
818 | } |
819 | ||
a4ab1ade | 820 | static s32 Handle_Scan(struct host_if_drv *hif_drv, |
c476feb8 | 821 | struct scan_attr *pstrHostIFscanAttr) |
c5c77ba1 | 822 | { |
31390eec | 823 | s32 result = 0; |
e9e0c260 | 824 | struct wid strWIDList[5]; |
4e4467fd CL |
825 | u32 u32WidsCount = 0; |
826 | u32 i; | |
63d03e47 GKH |
827 | u8 *pu8Buffer; |
828 | u8 valuesize = 0; | |
829 | u8 *pu8HdnNtwrksWidVal = NULL; | |
c5c77ba1 JK |
830 | |
831 | PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); | |
b60005a8 | 832 | PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->hif_state); |
c5c77ba1 | 833 | |
bc801855 | 834 | hif_drv->usr_scan_req.scan_result = pstrHostIFscanAttr->result; |
66eaea30 | 835 | hif_drv->usr_scan_req.arg = pstrHostIFscanAttr->arg; |
c5c77ba1 | 836 | |
b60005a8 LK |
837 | if ((hif_drv->hif_state >= HOST_IF_SCANNING) && |
838 | (hif_drv->hif_state < HOST_IF_CONNECTED)) { | |
839 | PRINT_D(GENERIC_DBG, "Don't scan already in [%d] state\n", | |
840 | hif_drv->hif_state); | |
24db713f | 841 | PRINT_ER("Already scan\n"); |
31390eec | 842 | result = -EBUSY; |
24db713f | 843 | goto ERRORHANDLER; |
c5c77ba1 JK |
844 | } |
845 | ||
c5c77ba1 JK |
846 | if (g_obtainingIP || connecting) { |
847 | PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); | |
24db713f | 848 | PRINT_ER("Don't do obss scan\n"); |
31390eec | 849 | result = -EBUSY; |
24db713f | 850 | goto ERRORHANDLER; |
c5c77ba1 | 851 | } |
c5c77ba1 JK |
852 | |
853 | PRINT_D(HOSTINF_DBG, "Setting SCAN params\n"); | |
854 | ||
f79756ee | 855 | hif_drv->usr_scan_req.rcvd_ch_cnt = 0; |
c5c77ba1 | 856 | |
daaf16ba | 857 | strWIDList[u32WidsCount].id = (u16)WID_SSID_PROBE_REQ; |
416d8321 | 858 | strWIDList[u32WidsCount].type = WID_STR; |
c5c77ba1 | 859 | |
629b9ca0 LK |
860 | for (i = 0; i < pstrHostIFscanAttr->hidden_network.u8ssidnum; i++) |
861 | valuesize += ((pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen) + 1); | |
f3052587 | 862 | pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL); |
900bb4a6 | 863 | strWIDList[u32WidsCount].val = pu8HdnNtwrksWidVal; |
91109e11 | 864 | if (strWIDList[u32WidsCount].val) { |
900bb4a6 | 865 | pu8Buffer = strWIDList[u32WidsCount].val; |
c5c77ba1 | 866 | |
629b9ca0 | 867 | *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.u8ssidnum; |
c5c77ba1 | 868 | |
629b9ca0 | 869 | PRINT_D(HOSTINF_DBG, "In Handle_ProbeRequest number of ssid %d\n", pstrHostIFscanAttr->hidden_network.u8ssidnum); |
c5c77ba1 | 870 | |
629b9ca0 LK |
871 | for (i = 0; i < pstrHostIFscanAttr->hidden_network.u8ssidnum; i++) { |
872 | *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen; | |
873 | memcpy(pu8Buffer, pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen); | |
874 | pu8Buffer += pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen; | |
c5c77ba1 JK |
875 | } |
876 | ||
2fd3e443 | 877 | strWIDList[u32WidsCount].size = (s32)(valuesize + 1); |
c5c77ba1 JK |
878 | u32WidsCount++; |
879 | } | |
880 | ||
c5c77ba1 | 881 | { |
daaf16ba | 882 | strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_PROBE; |
416d8321 | 883 | strWIDList[u32WidsCount].type = WID_BIN_DATA; |
d6f19aa5 | 884 | strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ies; |
7b1f76cd | 885 | strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ies_len; |
c5c77ba1 JK |
886 | u32WidsCount++; |
887 | } | |
888 | ||
daaf16ba | 889 | strWIDList[u32WidsCount].id = WID_SCAN_TYPE; |
416d8321 | 890 | strWIDList[u32WidsCount].type = WID_CHAR; |
2fd3e443 | 891 | strWIDList[u32WidsCount].size = sizeof(char); |
bafaa696 | 892 | strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->type; |
c5c77ba1 JK |
893 | u32WidsCount++; |
894 | ||
daaf16ba | 895 | strWIDList[u32WidsCount].id = WID_SCAN_CHANNEL_LIST; |
416d8321 | 896 | strWIDList[u32WidsCount].type = WID_BIN_DATA; |
c5c77ba1 | 897 | |
91109e11 LK |
898 | if (pstrHostIFscanAttr->ch_freq_list && |
899 | pstrHostIFscanAttr->ch_list_len > 0) { | |
c5c77ba1 JK |
900 | int i; |
901 | ||
f97bd9ca | 902 | for (i = 0; i < pstrHostIFscanAttr->ch_list_len; i++) { |
82eeb0ad LK |
903 | if (pstrHostIFscanAttr->ch_freq_list[i] > 0) |
904 | pstrHostIFscanAttr->ch_freq_list[i] = pstrHostIFscanAttr->ch_freq_list[i] - 1; | |
c5c77ba1 JK |
905 | } |
906 | } | |
907 | ||
82eeb0ad | 908 | strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ch_freq_list; |
f97bd9ca | 909 | strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ch_list_len; |
c5c77ba1 JK |
910 | u32WidsCount++; |
911 | ||
daaf16ba | 912 | strWIDList[u32WidsCount].id = WID_START_SCAN_REQ; |
416d8321 | 913 | strWIDList[u32WidsCount].type = WID_CHAR; |
2fd3e443 | 914 | strWIDList[u32WidsCount].size = sizeof(char); |
bafaa696 | 915 | strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->src; |
c5c77ba1 JK |
916 | u32WidsCount++; |
917 | ||
b60005a8 | 918 | if (hif_drv->hif_state == HOST_IF_CONNECTED) |
ca8540e4 | 919 | scan_while_connected = true; |
b60005a8 | 920 | else if (hif_drv->hif_state == HOST_IF_IDLE) |
ca8540e4 | 921 | scan_while_connected = false; |
c5c77ba1 | 922 | |
31390eec | 923 | result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, |
8c8360b3 | 924 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 925 | |
31390eec | 926 | if (result) |
c5c77ba1 | 927 | PRINT_ER("Failed to send scan paramters config packet\n"); |
24db713f | 928 | else |
c5c77ba1 | 929 | PRINT_D(HOSTINF_DBG, "Successfully sent SCAN params config packet\n"); |
c5c77ba1 | 930 | |
24db713f | 931 | ERRORHANDLER: |
31390eec | 932 | if (result) { |
13b313e4 | 933 | del_timer(&hif_drv->scan_timer); |
a4ab1ade | 934 | Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED); |
c5c77ba1 JK |
935 | } |
936 | ||
95f840fb SB |
937 | kfree(pstrHostIFscanAttr->ch_freq_list); |
938 | pstrHostIFscanAttr->ch_freq_list = NULL; | |
c5c77ba1 | 939 | |
95f840fb SB |
940 | kfree(pstrHostIFscanAttr->ies); |
941 | pstrHostIFscanAttr->ies = NULL; | |
942 | kfree(pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo); | |
943 | pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo = NULL; | |
c5c77ba1 | 944 | |
95f840fb | 945 | kfree(pu8HdnNtwrksWidVal); |
c5c77ba1 | 946 | |
31390eec | 947 | return result; |
c5c77ba1 JK |
948 | } |
949 | ||
a4ab1ade TC |
950 | static s32 Handle_ScanDone(struct host_if_drv *hif_drv, |
951 | enum scan_event enuEvent) | |
c5c77ba1 | 952 | { |
31390eec | 953 | s32 result = 0; |
63d03e47 | 954 | u8 u8abort_running_scan; |
45102f83 | 955 | struct wid wid; |
c5c77ba1 | 956 | |
c5c77ba1 JK |
957 | PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n"); |
958 | ||
c5c77ba1 JK |
959 | if (enuEvent == SCAN_EVENT_ABORTED) { |
960 | PRINT_D(GENERIC_DBG, "Abort running scan\n"); | |
961 | u8abort_running_scan = 1; | |
45102f83 LK |
962 | wid.id = (u16)WID_ABORT_RUNNING_SCAN; |
963 | wid.type = WID_CHAR; | |
964 | wid.val = (s8 *)&u8abort_running_scan; | |
965 | wid.size = sizeof(char); | |
c5c77ba1 | 966 | |
45102f83 | 967 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 968 | get_id_from_handler(hif_drv)); |
31390eec LK |
969 | |
970 | if (result) { | |
c5c77ba1 | 971 | PRINT_ER("Failed to set abort running scan\n"); |
31390eec | 972 | result = -EFAULT; |
c5c77ba1 JK |
973 | } |
974 | } | |
975 | ||
a4ab1ade | 976 | if (!hif_drv) { |
c5c77ba1 | 977 | PRINT_ER("Driver handler is NULL\n"); |
31390eec | 978 | return result; |
c5c77ba1 JK |
979 | } |
980 | ||
bc801855 LK |
981 | if (hif_drv->usr_scan_req.scan_result) { |
982 | hif_drv->usr_scan_req.scan_result(enuEvent, NULL, | |
66eaea30 | 983 | hif_drv->usr_scan_req.arg, NULL); |
bc801855 | 984 | hif_drv->usr_scan_req.scan_result = NULL; |
c5c77ba1 JK |
985 | } |
986 | ||
31390eec | 987 | return result; |
c5c77ba1 JK |
988 | } |
989 | ||
63d03e47 | 990 | u8 u8ConnectedSSID[6] = {0}; |
a4ab1ade | 991 | static s32 Handle_Connect(struct host_if_drv *hif_drv, |
120ae593 | 992 | struct connect_attr *pstrHostIFconnectAttr) |
c5c77ba1 | 993 | { |
31390eec | 994 | s32 result = 0; |
e9e0c260 | 995 | struct wid strWIDList[8]; |
4e4467fd | 996 | u32 u32WidsCount = 0, dummyval = 0; |
63d03e47 | 997 | u8 *pu8CurrByte = NULL; |
e0a12217 | 998 | struct join_bss_param *ptstrJoinBssParam; |
c5c77ba1 JK |
999 | |
1000 | PRINT_D(GENERIC_DBG, "Handling connect request\n"); | |
1001 | ||
9254db07 | 1002 | if (memcmp(pstrHostIFconnectAttr->bssid, u8ConnectedSSID, ETH_ALEN) == 0) { |
31390eec | 1003 | result = 0; |
c5c77ba1 | 1004 | PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n"); |
31390eec | 1005 | return result; |
c5c77ba1 JK |
1006 | } |
1007 | ||
1008 | PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n"); | |
1009 | ||
f2bed2ca | 1010 | ptstrJoinBssParam = (struct join_bss_param *)pstrHostIFconnectAttr->params; |
91109e11 | 1011 | if (!ptstrJoinBssParam) { |
c5c77ba1 | 1012 | PRINT_ER("Required BSSID not found\n"); |
31390eec | 1013 | result = -ENOENT; |
24db713f | 1014 | goto ERRORHANDLER; |
c5c77ba1 | 1015 | } |
c5c77ba1 | 1016 | |
91109e11 | 1017 | if (pstrHostIFconnectAttr->bssid) { |
f8b17132 LK |
1018 | hif_drv->usr_conn_req.pu8bssid = kmalloc(6, GFP_KERNEL); |
1019 | memcpy(hif_drv->usr_conn_req.pu8bssid, pstrHostIFconnectAttr->bssid, 6); | |
c5c77ba1 JK |
1020 | } |
1021 | ||
74ab5e45 | 1022 | hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len; |
91109e11 | 1023 | if (pstrHostIFconnectAttr->ssid) { |
f8b17132 LK |
1024 | hif_drv->usr_conn_req.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL); |
1025 | memcpy(hif_drv->usr_conn_req.pu8ssid, | |
8c8360b3 LK |
1026 | pstrHostIFconnectAttr->ssid, |
1027 | pstrHostIFconnectAttr->ssid_len); | |
f8b17132 | 1028 | hif_drv->usr_conn_req.pu8ssid[pstrHostIFconnectAttr->ssid_len] = '\0'; |
c5c77ba1 JK |
1029 | } |
1030 | ||
331ed080 | 1031 | hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len; |
91109e11 | 1032 | if (pstrHostIFconnectAttr->ies) { |
a3b2f4b9 LK |
1033 | hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL); |
1034 | memcpy(hif_drv->usr_conn_req.ies, | |
8c8360b3 LK |
1035 | pstrHostIFconnectAttr->ies, |
1036 | pstrHostIFconnectAttr->ies_len); | |
c5c77ba1 JK |
1037 | } |
1038 | ||
f8b17132 | 1039 | hif_drv->usr_conn_req.u8security = pstrHostIFconnectAttr->security; |
7d069728 | 1040 | hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type; |
33bfb198 | 1041 | hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result; |
73abaa49 | 1042 | hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg; |
c5c77ba1 | 1043 | |
daaf16ba | 1044 | strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT; |
416d8321 | 1045 | strWIDList[u32WidsCount].type = WID_INT; |
2fd3e443 | 1046 | strWIDList[u32WidsCount].size = sizeof(u32); |
900bb4a6 | 1047 | strWIDList[u32WidsCount].val = (s8 *)(&(dummyval)); |
c5c77ba1 JK |
1048 | u32WidsCount++; |
1049 | ||
daaf16ba | 1050 | strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT; |
416d8321 | 1051 | strWIDList[u32WidsCount].type = WID_INT; |
2fd3e443 | 1052 | strWIDList[u32WidsCount].size = sizeof(u32); |
900bb4a6 | 1053 | strWIDList[u32WidsCount].val = (s8 *)(&(dummyval)); |
c5c77ba1 JK |
1054 | u32WidsCount++; |
1055 | ||
daaf16ba | 1056 | strWIDList[u32WidsCount].id = WID_FAILED_COUNT; |
416d8321 | 1057 | strWIDList[u32WidsCount].type = WID_INT; |
2fd3e443 | 1058 | strWIDList[u32WidsCount].size = sizeof(u32); |
900bb4a6 | 1059 | strWIDList[u32WidsCount].val = (s8 *)(&(dummyval)); |
c5c77ba1 JK |
1060 | u32WidsCount++; |
1061 | ||
c5c77ba1 | 1062 | { |
daaf16ba | 1063 | strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE; |
416d8321 | 1064 | strWIDList[u32WidsCount].type = WID_BIN_DATA; |
a3b2f4b9 | 1065 | strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies; |
331ed080 | 1066 | strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len; |
c5c77ba1 JK |
1067 | u32WidsCount++; |
1068 | ||
f7bbd9cf | 1069 | if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) { |
331ed080 | 1070 | info_element_size = hif_drv->usr_conn_req.ies_len; |
dfef7b84 | 1071 | info_element = kmalloc(info_element_size, GFP_KERNEL); |
a3b2f4b9 | 1072 | memcpy(info_element, hif_drv->usr_conn_req.ies, |
dfef7b84 | 1073 | info_element_size); |
c5c77ba1 JK |
1074 | } |
1075 | } | |
daaf16ba | 1076 | strWIDList[u32WidsCount].id = (u16)WID_11I_MODE; |
416d8321 | 1077 | strWIDList[u32WidsCount].type = WID_CHAR; |
2fd3e443 | 1078 | strWIDList[u32WidsCount].size = sizeof(char); |
f8b17132 | 1079 | strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.u8security; |
c5c77ba1 JK |
1080 | u32WidsCount++; |
1081 | ||
f7bbd9cf | 1082 | if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) |
f8b17132 | 1083 | mode_11i = hif_drv->usr_conn_req.u8security; |
c5c77ba1 | 1084 | |
f8b17132 | 1085 | PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", hif_drv->usr_conn_req.u8security); |
c5c77ba1 | 1086 | |
daaf16ba | 1087 | strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE; |
416d8321 | 1088 | strWIDList[u32WidsCount].type = WID_CHAR; |
2fd3e443 | 1089 | strWIDList[u32WidsCount].size = sizeof(char); |
7d069728 | 1090 | strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type; |
c5c77ba1 JK |
1091 | u32WidsCount++; |
1092 | ||
f7bbd9cf | 1093 | if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) |
7d069728 | 1094 | auth_type = (u8)hif_drv->usr_conn_req.auth_type; |
c5c77ba1 | 1095 | |
7d069728 LK |
1096 | PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", |
1097 | hif_drv->usr_conn_req.auth_type); | |
c5c77ba1 | 1098 | PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n", |
f8b17132 | 1099 | hif_drv->usr_conn_req.pu8ssid, pstrHostIFconnectAttr->ch); |
c5c77ba1 | 1100 | |
daaf16ba | 1101 | strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED; |
416d8321 | 1102 | strWIDList[u32WidsCount].type = WID_STR; |
ae4dfa57 | 1103 | strWIDList[u32WidsCount].size = 112; |
900bb4a6 | 1104 | strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL); |
c5c77ba1 | 1105 | |
f7bbd9cf | 1106 | if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) { |
0626baaa LK |
1107 | join_req_size = strWIDList[u32WidsCount].size; |
1108 | join_req = kmalloc(join_req_size, GFP_KERNEL); | |
c5c77ba1 | 1109 | } |
91109e11 | 1110 | if (!strWIDList[u32WidsCount].val) { |
31390eec | 1111 | result = -EFAULT; |
24db713f LK |
1112 | goto ERRORHANDLER; |
1113 | } | |
c5c77ba1 | 1114 | |
900bb4a6 | 1115 | pu8CurrByte = strWIDList[u32WidsCount].val; |
c5c77ba1 | 1116 | |
91109e11 | 1117 | if (pstrHostIFconnectAttr->ssid) { |
8b3c9fa6 LK |
1118 | memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len); |
1119 | pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0'; | |
c5c77ba1 JK |
1120 | } |
1121 | pu8CurrByte += MAX_SSID_LEN; | |
c5c77ba1 | 1122 | *(pu8CurrByte++) = INFRASTRUCTURE; |
ae4dfa57 | 1123 | |
0d1527e6 LK |
1124 | if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) { |
1125 | *(pu8CurrByte++) = pstrHostIFconnectAttr->ch; | |
c5c77ba1 JK |
1126 | } else { |
1127 | PRINT_ER("Channel out of range\n"); | |
1128 | *(pu8CurrByte++) = 0xFF; | |
1129 | } | |
c5c77ba1 JK |
1130 | *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF; |
1131 | *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF; | |
1132 | PRINT_D(HOSTINF_DBG, "* Cap Info %0x*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8))); | |
1133 | ||
91109e11 | 1134 | if (pstrHostIFconnectAttr->bssid) |
9254db07 | 1135 | memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6); |
c5c77ba1 JK |
1136 | pu8CurrByte += 6; |
1137 | ||
c0f52fba TC |
1138 | if (pstrHostIFconnectAttr->bssid) |
1139 | memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6); | |
1140 | pu8CurrByte += 6; | |
1141 | ||
c5c77ba1 JK |
1142 | *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF; |
1143 | *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF; | |
1144 | PRINT_D(HOSTINF_DBG, "* Beacon Period %d*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8))); | |
c5c77ba1 JK |
1145 | *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period; |
1146 | PRINT_D(HOSTINF_DBG, "* DTIM Period %d*\n", (*(pu8CurrByte - 1))); | |
ae4dfa57 | 1147 | |
d00d2ba3 | 1148 | memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1); |
c5c77ba1 JK |
1149 | pu8CurrByte += (MAX_RATES_SUPPORTED + 1); |
1150 | ||
c5c77ba1 JK |
1151 | *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap; |
1152 | PRINT_D(HOSTINF_DBG, "* wmm cap%d*\n", (*(pu8CurrByte - 1))); | |
c5c77ba1 JK |
1153 | *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap; |
1154 | ||
c5c77ba1 | 1155 | *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable; |
ff06982c | 1156 | hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable; |
c5c77ba1 | 1157 | |
c5c77ba1 JK |
1158 | *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found; |
1159 | PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1)); | |
c5c77ba1 JK |
1160 | *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy; |
1161 | PRINT_D(HOSTINF_DBG, "* rsn group policy %0x*\n", (*(pu8CurrByte - 1))); | |
c5c77ba1 JK |
1162 | *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i; |
1163 | PRINT_D(HOSTINF_DBG, "* mode_802_11i %d*\n", (*(pu8CurrByte - 1))); | |
ae4dfa57 | 1164 | |
d00d2ba3 | 1165 | memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy)); |
c5c77ba1 JK |
1166 | pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy); |
1167 | ||
d00d2ba3 | 1168 | memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy)); |
c5c77ba1 JK |
1169 | pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy); |
1170 | ||
d00d2ba3 | 1171 | memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap)); |
c5c77ba1 JK |
1172 | pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap); |
1173 | ||
c5c77ba1 | 1174 | *(pu8CurrByte++) = REAL_JOIN_REQ; |
7a8d51d7 | 1175 | *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled; |
c5c77ba1 | 1176 | |
7a8d51d7 | 1177 | if (ptstrJoinBssParam->noa_enabled) { |
c5c77ba1 JK |
1178 | PRINT_D(HOSTINF_DBG, "NOA present\n"); |
1179 | ||
1180 | *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF; | |
1181 | *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF; | |
1182 | *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF; | |
1183 | *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF; | |
1184 | ||
d72b33ca | 1185 | *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled; |
cc179008 | 1186 | *(pu8CurrByte++) = ptstrJoinBssParam->idx; |
c5c77ba1 | 1187 | |
d72b33ca | 1188 | if (ptstrJoinBssParam->opp_enabled) |
99b66945 | 1189 | *(pu8CurrByte++) = ptstrJoinBssParam->ct_window; |
c5c77ba1 | 1190 | |
c21047ed | 1191 | *(pu8CurrByte++) = ptstrJoinBssParam->cnt; |
c5c77ba1 | 1192 | |
109e6cab LK |
1193 | memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration)); |
1194 | pu8CurrByte += sizeof(ptstrJoinBssParam->duration); | |
c5c77ba1 | 1195 | |
1d8b76b3 LK |
1196 | memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval)); |
1197 | pu8CurrByte += sizeof(ptstrJoinBssParam->interval); | |
c5c77ba1 | 1198 | |
4be55e22 LK |
1199 | memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time)); |
1200 | pu8CurrByte += sizeof(ptstrJoinBssParam->start_time); | |
c5c77ba1 JK |
1201 | } else |
1202 | PRINT_D(HOSTINF_DBG, "NOA not present\n"); | |
c5c77ba1 | 1203 | |
900bb4a6 | 1204 | pu8CurrByte = strWIDList[u32WidsCount].val; |
c5c77ba1 | 1205 | u32WidsCount++; |
c5c77ba1 | 1206 | |
f7bbd9cf | 1207 | if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) { |
0626baaa | 1208 | memcpy(join_req, pu8CurrByte, join_req_size); |
870515c1 | 1209 | join_req_drv = hif_drv; |
c5c77ba1 JK |
1210 | } |
1211 | ||
1212 | PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n"); | |
1213 | ||
91109e11 | 1214 | if (pstrHostIFconnectAttr->bssid) { |
9254db07 | 1215 | memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->bssid, ETH_ALEN); |
c5c77ba1 | 1216 | |
9254db07 | 1217 | PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->bssid); |
310a28fd | 1218 | PRINT_D(GENERIC_DBG, "save bssid = %pM\n", u8ConnectedSSID); |
c5c77ba1 JK |
1219 | } |
1220 | ||
31390eec | 1221 | result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, |
8c8360b3 | 1222 | get_id_from_handler(hif_drv)); |
31390eec | 1223 | if (result) { |
24db713f | 1224 | PRINT_ER("failed to send config packet\n"); |
31390eec | 1225 | result = -EFAULT; |
24db713f | 1226 | goto ERRORHANDLER; |
c5c77ba1 JK |
1227 | } else { |
1228 | PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n"); | |
b60005a8 | 1229 | hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP; |
c5c77ba1 | 1230 | } |
c5c77ba1 | 1231 | |
24db713f | 1232 | ERRORHANDLER: |
31390eec | 1233 | if (result) { |
c5c77ba1 JK |
1234 | tstrConnectInfo strConnectInfo; |
1235 | ||
81a59506 | 1236 | del_timer(&hif_drv->connect_timer); |
c5c77ba1 JK |
1237 | |
1238 | PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n"); | |
1239 | ||
2cc46837 | 1240 | memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); |
c5c77ba1 | 1241 | |
91109e11 LK |
1242 | if (pstrHostIFconnectAttr->result) { |
1243 | if (pstrHostIFconnectAttr->bssid) | |
9254db07 | 1244 | memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->bssid, 6); |
c5c77ba1 | 1245 | |
91109e11 | 1246 | if (pstrHostIFconnectAttr->ies) { |
b59d5c5b LK |
1247 | strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->ies_len; |
1248 | strConnectInfo.pu8ReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL); | |
d00d2ba3 | 1249 | memcpy(strConnectInfo.pu8ReqIEs, |
8c8360b3 LK |
1250 | pstrHostIFconnectAttr->ies, |
1251 | pstrHostIFconnectAttr->ies_len); | |
c5c77ba1 JK |
1252 | } |
1253 | ||
6abcc11d | 1254 | pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP, |
c5c77ba1 JK |
1255 | &strConnectInfo, |
1256 | MAC_DISCONNECTED, | |
1257 | NULL, | |
8f38db89 | 1258 | pstrHostIFconnectAttr->arg); |
b60005a8 | 1259 | hif_drv->hif_state = HOST_IF_IDLE; |
95f840fb SB |
1260 | kfree(strConnectInfo.pu8ReqIEs); |
1261 | strConnectInfo.pu8ReqIEs = NULL; | |
c5c77ba1 JK |
1262 | |
1263 | } else { | |
03b2d5e7 | 1264 | PRINT_ER("Connect callback function pointer is NULL\n"); |
c5c77ba1 JK |
1265 | } |
1266 | } | |
1267 | ||
1268 | PRINT_D(HOSTINF_DBG, "Deallocating connection parameters\n"); | |
95f840fb SB |
1269 | kfree(pstrHostIFconnectAttr->bssid); |
1270 | pstrHostIFconnectAttr->bssid = NULL; | |
c5c77ba1 | 1271 | |
95f840fb SB |
1272 | kfree(pstrHostIFconnectAttr->ssid); |
1273 | pstrHostIFconnectAttr->ssid = NULL; | |
c5c77ba1 | 1274 | |
95f840fb SB |
1275 | kfree(pstrHostIFconnectAttr->ies); |
1276 | pstrHostIFconnectAttr->ies = NULL; | |
c5c77ba1 | 1277 | |
95f840fb | 1278 | kfree(pu8CurrByte); |
31390eec | 1279 | return result; |
c5c77ba1 JK |
1280 | } |
1281 | ||
a4ab1ade | 1282 | static s32 Handle_FlushConnect(struct host_if_drv *hif_drv) |
c5c77ba1 | 1283 | { |
31390eec | 1284 | s32 result = 0; |
e9e0c260 | 1285 | struct wid strWIDList[5]; |
4e4467fd | 1286 | u32 u32WidsCount = 0; |
63d03e47 | 1287 | u8 *pu8CurrByte = NULL; |
c5c77ba1 | 1288 | |
daaf16ba | 1289 | strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE; |
416d8321 | 1290 | strWIDList[u32WidsCount].type = WID_BIN_DATA; |
48ce2465 | 1291 | strWIDList[u32WidsCount].val = info_element; |
dfef7b84 | 1292 | strWIDList[u32WidsCount].size = info_element_size; |
c5c77ba1 JK |
1293 | u32WidsCount++; |
1294 | ||
daaf16ba | 1295 | strWIDList[u32WidsCount].id = (u16)WID_11I_MODE; |
416d8321 | 1296 | strWIDList[u32WidsCount].type = WID_CHAR; |
2fd3e443 | 1297 | strWIDList[u32WidsCount].size = sizeof(char); |
1bd9d44c | 1298 | strWIDList[u32WidsCount].val = (s8 *)(&(mode_11i)); |
c5c77ba1 JK |
1299 | u32WidsCount++; |
1300 | ||
daaf16ba | 1301 | strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE; |
416d8321 | 1302 | strWIDList[u32WidsCount].type = WID_CHAR; |
2fd3e443 | 1303 | strWIDList[u32WidsCount].size = sizeof(char); |
fba4989e | 1304 | strWIDList[u32WidsCount].val = (s8 *)(&auth_type); |
c5c77ba1 JK |
1305 | u32WidsCount++; |
1306 | ||
daaf16ba | 1307 | strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED; |
416d8321 | 1308 | strWIDList[u32WidsCount].type = WID_STR; |
0626baaa | 1309 | strWIDList[u32WidsCount].size = join_req_size; |
044a6410 | 1310 | strWIDList[u32WidsCount].val = (s8 *)join_req; |
900bb4a6 | 1311 | pu8CurrByte = strWIDList[u32WidsCount].val; |
c5c77ba1 JK |
1312 | |
1313 | pu8CurrByte += FLUSHED_BYTE_POS; | |
1314 | *(pu8CurrByte) = FLUSHED_JOIN_REQ; | |
1315 | ||
1316 | u32WidsCount++; | |
1317 | ||
31390eec | 1318 | result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, |
8c8360b3 | 1319 | get_id_from_handler(join_req_drv)); |
31390eec | 1320 | if (result) { |
24db713f | 1321 | PRINT_ER("failed to send config packet\n"); |
31390eec | 1322 | result = -EINVAL; |
c5c77ba1 JK |
1323 | } |
1324 | ||
31390eec | 1325 | return result; |
c5c77ba1 JK |
1326 | } |
1327 | ||
a4ab1ade | 1328 | static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv) |
c5c77ba1 | 1329 | { |
31390eec | 1330 | s32 result = 0; |
c5c77ba1 | 1331 | tstrConnectInfo strConnectInfo; |
45102f83 | 1332 | struct wid wid; |
d85f5326 | 1333 | u16 u16DummyReasonCode = 0; |
c5c77ba1 | 1334 | |
a4ab1ade | 1335 | if (!hif_drv) { |
c5c77ba1 | 1336 | PRINT_ER("Driver handler is NULL\n"); |
31390eec | 1337 | return result; |
c5c77ba1 JK |
1338 | } |
1339 | ||
b60005a8 | 1340 | hif_drv->hif_state = HOST_IF_IDLE; |
c5c77ba1 | 1341 | |
ca8540e4 | 1342 | scan_while_connected = false; |
c5c77ba1 | 1343 | |
2cc46837 | 1344 | memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); |
c5c77ba1 | 1345 | |
33bfb198 | 1346 | if (hif_drv->usr_conn_req.conn_result) { |
f8b17132 | 1347 | if (hif_drv->usr_conn_req.pu8bssid) { |
d00d2ba3 | 1348 | memcpy(strConnectInfo.au8bssid, |
f8b17132 | 1349 | hif_drv->usr_conn_req.pu8bssid, 6); |
c5c77ba1 JK |
1350 | } |
1351 | ||
a3b2f4b9 | 1352 | if (hif_drv->usr_conn_req.ies) { |
331ed080 LK |
1353 | strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ies_len; |
1354 | strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL); | |
d00d2ba3 | 1355 | memcpy(strConnectInfo.pu8ReqIEs, |
a3b2f4b9 | 1356 | hif_drv->usr_conn_req.ies, |
331ed080 | 1357 | hif_drv->usr_conn_req.ies_len); |
c5c77ba1 JK |
1358 | } |
1359 | ||
33bfb198 LK |
1360 | hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP, |
1361 | &strConnectInfo, | |
1362 | MAC_DISCONNECTED, | |
1363 | NULL, | |
73abaa49 | 1364 | hif_drv->usr_conn_req.arg); |
c5c77ba1 | 1365 | |
95f840fb SB |
1366 | kfree(strConnectInfo.pu8ReqIEs); |
1367 | strConnectInfo.pu8ReqIEs = NULL; | |
c5c77ba1 | 1368 | } else { |
03b2d5e7 | 1369 | PRINT_ER("Connect callback function pointer is NULL\n"); |
c5c77ba1 JK |
1370 | } |
1371 | ||
45102f83 LK |
1372 | wid.id = (u16)WID_DISCONNECT; |
1373 | wid.type = WID_CHAR; | |
1374 | wid.val = (s8 *)&u16DummyReasonCode; | |
1375 | wid.size = sizeof(char); | |
c5c77ba1 JK |
1376 | |
1377 | PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); | |
1378 | ||
45102f83 | 1379 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 1380 | get_id_from_handler(hif_drv)); |
31390eec | 1381 | if (result) |
c5c77ba1 | 1382 | PRINT_ER("Failed to send dissconect config packet\n"); |
c5c77ba1 | 1383 | |
74ab5e45 | 1384 | hif_drv->usr_conn_req.ssid_len = 0; |
f8b17132 LK |
1385 | kfree(hif_drv->usr_conn_req.pu8ssid); |
1386 | kfree(hif_drv->usr_conn_req.pu8bssid); | |
331ed080 | 1387 | hif_drv->usr_conn_req.ies_len = 0; |
a3b2f4b9 | 1388 | kfree(hif_drv->usr_conn_req.ies); |
c5c77ba1 | 1389 | |
281dd5ac | 1390 | eth_zero_addr(u8ConnectedSSID); |
ae4dfa57 | 1391 | |
91109e11 | 1392 | if (join_req && join_req_drv == hif_drv) { |
044a6410 LK |
1393 | kfree(join_req); |
1394 | join_req = NULL; | |
c5c77ba1 | 1395 | } |
48ce2465 | 1396 | |
91109e11 | 1397 | if (info_element && join_req_drv == hif_drv) { |
48ce2465 LK |
1398 | kfree(info_element); |
1399 | info_element = NULL; | |
c5c77ba1 JK |
1400 | } |
1401 | ||
31390eec | 1402 | return result; |
c5c77ba1 JK |
1403 | } |
1404 | ||
a4ab1ade | 1405 | static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv, |
3bbd59f5 | 1406 | struct rcvd_net_info *pstrRcvdNetworkInfo) |
c5c77ba1 | 1407 | { |
4e4467fd | 1408 | u32 i; |
72ed4dc7 | 1409 | bool bNewNtwrkFound; |
31390eec | 1410 | s32 result = 0; |
c5c77ba1 JK |
1411 | tstrNetworkInfo *pstrNetworkInfo = NULL; |
1412 | void *pJoinParams = NULL; | |
1413 | ||
72ed4dc7 | 1414 | bNewNtwrkFound = true; |
c5c77ba1 JK |
1415 | PRINT_INFO(HOSTINF_DBG, "Handling received network info\n"); |
1416 | ||
bc801855 | 1417 | if (hif_drv->usr_scan_req.scan_result) { |
c5c77ba1 | 1418 | PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n"); |
b021b80b | 1419 | parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo); |
91109e11 | 1420 | if ((!pstrNetworkInfo) || |
bc801855 | 1421 | (!hif_drv->usr_scan_req.scan_result)) { |
24db713f | 1422 | PRINT_ER("driver is null\n"); |
31390eec | 1423 | result = -EINVAL; |
24db713f | 1424 | goto done; |
c5c77ba1 JK |
1425 | } |
1426 | ||
f79756ee | 1427 | for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) { |
af973f30 | 1428 | if ((hif_drv->usr_scan_req.net_info[i].au8bssid) && |
91109e11 | 1429 | (pstrNetworkInfo->au8bssid)) { |
af973f30 | 1430 | if (memcmp(hif_drv->usr_scan_req.net_info[i].au8bssid, |
8c8360b3 | 1431 | pstrNetworkInfo->au8bssid, 6) == 0) { |
af973f30 | 1432 | if (pstrNetworkInfo->s8rssi <= hif_drv->usr_scan_req.net_info[i].s8rssi) { |
c5c77ba1 JK |
1433 | PRINT_D(HOSTINF_DBG, "Network previously discovered\n"); |
1434 | goto done; | |
1435 | } else { | |
af973f30 | 1436 | hif_drv->usr_scan_req.net_info[i].s8rssi = pstrNetworkInfo->s8rssi; |
72ed4dc7 | 1437 | bNewNtwrkFound = false; |
c5c77ba1 JK |
1438 | break; |
1439 | } | |
1440 | } | |
1441 | } | |
1442 | } | |
1443 | ||
047e6646 | 1444 | if (bNewNtwrkFound) { |
c5c77ba1 JK |
1445 | PRINT_D(HOSTINF_DBG, "New network found\n"); |
1446 | ||
f79756ee LK |
1447 | if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) { |
1448 | hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].s8rssi = pstrNetworkInfo->s8rssi; | |
c5c77ba1 | 1449 | |
f79756ee | 1450 | if (hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].au8bssid && |
91109e11 | 1451 | pstrNetworkInfo->au8bssid) { |
f79756ee | 1452 | memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].au8bssid, |
8c8360b3 | 1453 | pstrNetworkInfo->au8bssid, 6); |
c5c77ba1 | 1454 | |
f79756ee | 1455 | hif_drv->usr_scan_req.rcvd_ch_cnt++; |
c5c77ba1 | 1456 | |
72ed4dc7 | 1457 | pstrNetworkInfo->bNewNetwork = true; |
c5c77ba1 | 1458 | pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo); |
c5c77ba1 | 1459 | |
bc801855 | 1460 | hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, |
66eaea30 | 1461 | hif_drv->usr_scan_req.arg, |
bc801855 | 1462 | pJoinParams); |
c5c77ba1 JK |
1463 | } |
1464 | } else { | |
03b2d5e7 | 1465 | PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit\n"); |
c5c77ba1 JK |
1466 | } |
1467 | } else { | |
72ed4dc7 | 1468 | pstrNetworkInfo->bNewNetwork = false; |
bc801855 | 1469 | hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo, |
66eaea30 | 1470 | hif_drv->usr_scan_req.arg, NULL); |
c5c77ba1 JK |
1471 | } |
1472 | } | |
1473 | ||
c5c77ba1 | 1474 | done: |
95f840fb SB |
1475 | kfree(pstrRcvdNetworkInfo->buffer); |
1476 | pstrRcvdNetworkInfo->buffer = NULL; | |
c5c77ba1 | 1477 | |
91109e11 | 1478 | if (pstrNetworkInfo) { |
c5c77ba1 | 1479 | DeallocateNetworkInfo(pstrNetworkInfo); |
b1413b60 | 1480 | pstrNetworkInfo = NULL; |
c5c77ba1 JK |
1481 | } |
1482 | ||
31390eec | 1483 | return result; |
c5c77ba1 JK |
1484 | } |
1485 | ||
a4ab1ade | 1486 | static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv, |
f23a9eab | 1487 | struct rcvd_async_info *pstrRcvdGnrlAsyncInfo) |
c5c77ba1 | 1488 | { |
31390eec | 1489 | s32 result = 0; |
63d03e47 GKH |
1490 | u8 u8MsgType = 0; |
1491 | u8 u8MsgID = 0; | |
d85f5326 CL |
1492 | u16 u16MsgLen = 0; |
1493 | u16 u16WidID = (u16)WID_NIL; | |
63d03e47 GKH |
1494 | u8 u8WidLen = 0; |
1495 | u8 u8MacStatus; | |
1496 | u8 u8MacStatusReasonCode; | |
1497 | u8 u8MacStatusAdditionalInfo; | |
c5c77ba1 JK |
1498 | tstrConnectInfo strConnectInfo; |
1499 | tstrDisconnectNotifInfo strDisconnectNotifInfo; | |
e6e12661 | 1500 | s32 s32Err = 0; |
78c87591 | 1501 | |
a4ab1ade | 1502 | if (!hif_drv) { |
c5c77ba1 | 1503 | PRINT_ER("Driver handler is NULL\n"); |
234837de LK |
1504 | return -ENODEV; |
1505 | } | |
b60005a8 LK |
1506 | PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", |
1507 | hif_drv->hif_state, pstrRcvdGnrlAsyncInfo->buffer[7]); | |
c5c77ba1 | 1508 | |
b60005a8 LK |
1509 | if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || |
1510 | (hif_drv->hif_state == HOST_IF_CONNECTED) || | |
bc801855 | 1511 | hif_drv->usr_scan_req.scan_result) { |
91109e11 | 1512 | if (!pstrRcvdGnrlAsyncInfo->buffer || |
33bfb198 | 1513 | !hif_drv->usr_conn_req.conn_result) { |
24db713f LK |
1514 | PRINT_ER("driver is null\n"); |
1515 | return -EINVAL; | |
c5c77ba1 JK |
1516 | } |
1517 | ||
33722ac7 | 1518 | u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0]; |
c5c77ba1 | 1519 | |
c5c77ba1 JK |
1520 | if ('I' != u8MsgType) { |
1521 | PRINT_ER("Received Message format incorrect.\n"); | |
24db713f | 1522 | return -EFAULT; |
c5c77ba1 JK |
1523 | } |
1524 | ||
33722ac7 LK |
1525 | u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1]; |
1526 | u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]); | |
1527 | u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]); | |
1528 | u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6]; | |
1529 | u8MacStatus = pstrRcvdGnrlAsyncInfo->buffer[7]; | |
1530 | u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8]; | |
1531 | u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9]; | |
c5c77ba1 | 1532 | PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); |
b60005a8 | 1533 | if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { |
4e4467fd | 1534 | u32 u32RcvdAssocRespInfoLen; |
c5c77ba1 JK |
1535 | tstrConnectRespInfo *pstrConnectRespInfo = NULL; |
1536 | ||
1537 | PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo); | |
1538 | ||
2cc46837 | 1539 | memset(&strConnectInfo, 0, sizeof(tstrConnectInfo)); |
c5c77ba1 JK |
1540 | |
1541 | if (u8MacStatus == MAC_CONNECTED) { | |
a633c0b5 | 1542 | memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE); |
c5c77ba1 | 1543 | |
a4ab1ade | 1544 | host_int_get_assoc_res_info(hif_drv, |
a633c0b5 | 1545 | rcv_assoc_resp, |
c5c77ba1 JK |
1546 | MAX_ASSOC_RESP_FRAME_SIZE, |
1547 | &u32RcvdAssocRespInfoLen); | |
1548 | ||
1549 | PRINT_INFO(HOSTINF_DBG, "Received association response with length = %d\n", u32RcvdAssocRespInfoLen); | |
1550 | ||
1551 | if (u32RcvdAssocRespInfoLen != 0) { | |
c5c77ba1 | 1552 | PRINT_D(HOSTINF_DBG, "Parsing association response\n"); |
a633c0b5 | 1553 | s32Err = ParseAssocRespInfo(rcv_assoc_resp, u32RcvdAssocRespInfoLen, |
c5c77ba1 JK |
1554 | &pstrConnectRespInfo); |
1555 | if (s32Err) { | |
03b2d5e7 | 1556 | PRINT_ER("ParseAssocRespInfo() returned error %d\n", s32Err); |
c5c77ba1 | 1557 | } else { |
c5c77ba1 JK |
1558 | strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus; |
1559 | ||
1560 | if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) { | |
1561 | PRINT_INFO(HOSTINF_DBG, "Association response received : Successful connection status\n"); | |
91109e11 | 1562 | if (pstrConnectRespInfo->pu8RespIEs) { |
c5c77ba1 | 1563 | strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen; |
f3052587 | 1564 | strConnectInfo.pu8RespIEs = kmalloc(pstrConnectRespInfo->u16RespIEsLen, GFP_KERNEL); |
d00d2ba3 | 1565 | memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs, |
c5c77ba1 JK |
1566 | pstrConnectRespInfo->u16RespIEsLen); |
1567 | } | |
1568 | } | |
1569 | ||
91109e11 | 1570 | if (pstrConnectRespInfo) { |
c5c77ba1 JK |
1571 | DeallocateAssocRespInfo(pstrConnectRespInfo); |
1572 | pstrConnectRespInfo = NULL; | |
1573 | } | |
1574 | } | |
1575 | } | |
1576 | } | |
1577 | ||
c5c77ba1 JK |
1578 | if ((u8MacStatus == MAC_CONNECTED) && |
1579 | (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) { | |
03b2d5e7 | 1580 | PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n"); |
281dd5ac | 1581 | eth_zero_addr(u8ConnectedSSID); |
c5c77ba1 JK |
1582 | |
1583 | } else if (u8MacStatus == MAC_DISCONNECTED) { | |
1584 | PRINT_ER("Received MAC status is MAC_DISCONNECTED\n"); | |
281dd5ac | 1585 | eth_zero_addr(u8ConnectedSSID); |
c5c77ba1 JK |
1586 | } |
1587 | ||
f8b17132 | 1588 | if (hif_drv->usr_conn_req.pu8bssid) { |
c5c77ba1 | 1589 | PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n"); |
f8b17132 | 1590 | memcpy(strConnectInfo.au8bssid, hif_drv->usr_conn_req.pu8bssid, 6); |
c5c77ba1 JK |
1591 | |
1592 | if ((u8MacStatus == MAC_CONNECTED) && | |
1593 | (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { | |
2a4eded9 | 1594 | memcpy(hif_drv->assoc_bssid, |
f8b17132 | 1595 | hif_drv->usr_conn_req.pu8bssid, ETH_ALEN); |
c5c77ba1 JK |
1596 | } |
1597 | } | |
1598 | ||
a3b2f4b9 | 1599 | if (hif_drv->usr_conn_req.ies) { |
331ed080 LK |
1600 | strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ies_len; |
1601 | strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL); | |
d00d2ba3 | 1602 | memcpy(strConnectInfo.pu8ReqIEs, |
a3b2f4b9 | 1603 | hif_drv->usr_conn_req.ies, |
331ed080 | 1604 | hif_drv->usr_conn_req.ies_len); |
c5c77ba1 JK |
1605 | } |
1606 | ||
81a59506 | 1607 | del_timer(&hif_drv->connect_timer); |
33bfb198 LK |
1608 | hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP, |
1609 | &strConnectInfo, | |
1610 | u8MacStatus, | |
1611 | NULL, | |
73abaa49 | 1612 | hif_drv->usr_conn_req.arg); |
c5c77ba1 | 1613 | |
c5c77ba1 JK |
1614 | if ((u8MacStatus == MAC_CONNECTED) && |
1615 | (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) { | |
a4ab1ade | 1616 | host_int_set_power_mgmt(hif_drv, 0, 0); |
c5c77ba1 JK |
1617 | |
1618 | PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n"); | |
b60005a8 | 1619 | hif_drv->hif_state = HOST_IF_CONNECTED; |
c5c77ba1 | 1620 | |
c5c77ba1 | 1621 | PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n"); |
72ed4dc7 | 1622 | g_obtainingIP = true; |
9eb06643 GKH |
1623 | mod_timer(&hDuringIpTimer, |
1624 | jiffies + msecs_to_jiffies(10000)); | |
c5c77ba1 JK |
1625 | } else { |
1626 | PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus); | |
b60005a8 | 1627 | hif_drv->hif_state = HOST_IF_IDLE; |
ca8540e4 | 1628 | scan_while_connected = false; |
c5c77ba1 JK |
1629 | } |
1630 | ||
95f840fb SB |
1631 | kfree(strConnectInfo.pu8RespIEs); |
1632 | strConnectInfo.pu8RespIEs = NULL; | |
c5c77ba1 | 1633 | |
95f840fb SB |
1634 | kfree(strConnectInfo.pu8ReqIEs); |
1635 | strConnectInfo.pu8ReqIEs = NULL; | |
74ab5e45 | 1636 | hif_drv->usr_conn_req.ssid_len = 0; |
f8b17132 LK |
1637 | kfree(hif_drv->usr_conn_req.pu8ssid); |
1638 | kfree(hif_drv->usr_conn_req.pu8bssid); | |
331ed080 | 1639 | hif_drv->usr_conn_req.ies_len = 0; |
a3b2f4b9 | 1640 | kfree(hif_drv->usr_conn_req.ies); |
c5c77ba1 | 1641 | } else if ((u8MacStatus == MAC_DISCONNECTED) && |
b60005a8 | 1642 | (hif_drv->hif_state == HOST_IF_CONNECTED)) { |
c5c77ba1 JK |
1643 | PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n"); |
1644 | ||
2cc46837 | 1645 | memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); |
c5c77ba1 | 1646 | |
bc801855 | 1647 | if (hif_drv->usr_scan_req.scan_result) { |
03b2d5e7 | 1648 | PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n"); |
13b313e4 | 1649 | del_timer(&hif_drv->scan_timer); |
a4ab1ade | 1650 | Handle_ScanDone((void *)hif_drv, SCAN_EVENT_ABORTED); |
c5c77ba1 JK |
1651 | } |
1652 | ||
1653 | strDisconnectNotifInfo.u16reason = 0; | |
1654 | strDisconnectNotifInfo.ie = NULL; | |
1655 | strDisconnectNotifInfo.ie_len = 0; | |
1656 | ||
33bfb198 | 1657 | if (hif_drv->usr_conn_req.conn_result) { |
72ed4dc7 | 1658 | g_obtainingIP = false; |
a4ab1ade | 1659 | host_int_set_power_mgmt(hif_drv, 0, 0); |
c5c77ba1 | 1660 | |
33bfb198 LK |
1661 | hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, |
1662 | NULL, | |
1663 | 0, | |
1664 | &strDisconnectNotifInfo, | |
73abaa49 | 1665 | hif_drv->usr_conn_req.arg); |
c5c77ba1 | 1666 | } else { |
03b2d5e7 | 1667 | PRINT_ER("Connect result callback function is NULL\n"); |
c5c77ba1 JK |
1668 | } |
1669 | ||
2a4eded9 | 1670 | eth_zero_addr(hif_drv->assoc_bssid); |
c5c77ba1 | 1671 | |
74ab5e45 | 1672 | hif_drv->usr_conn_req.ssid_len = 0; |
f8b17132 LK |
1673 | kfree(hif_drv->usr_conn_req.pu8ssid); |
1674 | kfree(hif_drv->usr_conn_req.pu8bssid); | |
331ed080 | 1675 | hif_drv->usr_conn_req.ies_len = 0; |
a3b2f4b9 | 1676 | kfree(hif_drv->usr_conn_req.ies); |
c5c77ba1 | 1677 | |
91109e11 | 1678 | if (join_req && join_req_drv == hif_drv) { |
044a6410 LK |
1679 | kfree(join_req); |
1680 | join_req = NULL; | |
c5c77ba1 | 1681 | } |
48ce2465 | 1682 | |
91109e11 | 1683 | if (info_element && join_req_drv == hif_drv) { |
48ce2465 LK |
1684 | kfree(info_element); |
1685 | info_element = NULL; | |
c5c77ba1 JK |
1686 | } |
1687 | ||
b60005a8 | 1688 | hif_drv->hif_state = HOST_IF_IDLE; |
ca8540e4 | 1689 | scan_while_connected = false; |
c5c77ba1 JK |
1690 | |
1691 | } else if ((u8MacStatus == MAC_DISCONNECTED) && | |
bc801855 | 1692 | (hif_drv->usr_scan_req.scan_result)) { |
c5c77ba1 | 1693 | PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n"); |
03b2d5e7 | 1694 | PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n"); |
ae4dfa57 | 1695 | |
13b313e4 | 1696 | del_timer(&hif_drv->scan_timer); |
bc801855 | 1697 | if (hif_drv->usr_scan_req.scan_result) |
a4ab1ade | 1698 | Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED); |
c5c77ba1 | 1699 | } |
c5c77ba1 JK |
1700 | } |
1701 | ||
95f840fb SB |
1702 | kfree(pstrRcvdGnrlAsyncInfo->buffer); |
1703 | pstrRcvdGnrlAsyncInfo->buffer = NULL; | |
c5c77ba1 | 1704 | |
31390eec | 1705 | return result; |
c5c77ba1 JK |
1706 | } |
1707 | ||
a4ab1ade | 1708 | static int Handle_Key(struct host_if_drv *hif_drv, |
c98387a5 | 1709 | struct key_attr *pstrHostIFkeyAttr) |
c5c77ba1 | 1710 | { |
31390eec | 1711 | s32 result = 0; |
45102f83 | 1712 | struct wid wid; |
e9e0c260 | 1713 | struct wid strWIDList[5]; |
63d03e47 GKH |
1714 | u8 i; |
1715 | u8 *pu8keybuf; | |
ca356ada CL |
1716 | s8 s8idxarray[1]; |
1717 | s8 ret = 0; | |
c5c77ba1 | 1718 | |
8e9f427a | 1719 | switch (pstrHostIFkeyAttr->type) { |
c5c77ba1 JK |
1720 | case WEP: |
1721 | ||
0d17e382 | 1722 | if (pstrHostIFkeyAttr->action & ADDKEY_AP) { |
c5c77ba1 | 1723 | PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); |
bafaa696 | 1724 | PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", pstrHostIFkeyAttr->attr.wep.index); |
daaf16ba | 1725 | strWIDList[0].id = (u16)WID_11I_MODE; |
416d8321 | 1726 | strWIDList[0].type = WID_CHAR; |
2fd3e443 | 1727 | strWIDList[0].size = sizeof(char); |
bafaa696 | 1728 | strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode; |
c5c77ba1 | 1729 | |
daaf16ba | 1730 | strWIDList[1].id = WID_AUTH_TYPE; |
416d8321 | 1731 | strWIDList[1].type = WID_CHAR; |
2fd3e443 | 1732 | strWIDList[1].size = sizeof(char); |
bafaa696 | 1733 | strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type; |
c5c77ba1 | 1734 | |
daaf16ba | 1735 | strWIDList[2].id = (u16)WID_KEY_ID; |
416d8321 | 1736 | strWIDList[2].type = WID_CHAR; |
c5c77ba1 | 1737 | |
bafaa696 | 1738 | strWIDList[2].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index; |
2fd3e443 | 1739 | strWIDList[2].size = sizeof(char); |
c5c77ba1 | 1740 | |
543f5b13 SB |
1741 | pu8keybuf = kmemdup(pstrHostIFkeyAttr->attr.wep.key, |
1742 | pstrHostIFkeyAttr->attr.wep.key_len, | |
1743 | GFP_KERNEL); | |
c5c77ba1 JK |
1744 | |
1745 | if (pu8keybuf == NULL) { | |
1746 | PRINT_ER("No buffer to send Key\n"); | |
9081987d | 1747 | return -ENOMEM; |
c5c77ba1 JK |
1748 | } |
1749 | ||
73b2e381 | 1750 | kfree(pstrHostIFkeyAttr->attr.wep.key); |
c5c77ba1 | 1751 | |
daaf16ba | 1752 | strWIDList[3].id = (u16)WID_WEP_KEY_VALUE; |
416d8321 | 1753 | strWIDList[3].type = WID_STR; |
73b2e381 | 1754 | strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len; |
900bb4a6 | 1755 | strWIDList[3].val = (s8 *)pu8keybuf; |
c5c77ba1 | 1756 | |
31390eec | 1757 | result = send_config_pkt(SET_CFG, strWIDList, 4, |
8c8360b3 | 1758 | get_id_from_handler(hif_drv)); |
49188af2 | 1759 | kfree(pu8keybuf); |
c5c77ba1 | 1760 | } |
c5c77ba1 | 1761 | |
0d17e382 | 1762 | if (pstrHostIFkeyAttr->action & ADDKEY) { |
c5c77ba1 | 1763 | PRINT_D(HOSTINF_DBG, "Handling WEP key\n"); |
73b2e381 | 1764 | pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL); |
91109e11 | 1765 | if (!pu8keybuf) { |
c5c77ba1 | 1766 | PRINT_ER("No buffer to send Key\n"); |
9081987d | 1767 | return -ENOMEM; |
c5c77ba1 | 1768 | } |
73b2e381 LK |
1769 | pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index; |
1770 | memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1); | |
1771 | memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key, | |
8c8360b3 | 1772 | pstrHostIFkeyAttr->attr.wep.key_len); |
73b2e381 | 1773 | kfree(pstrHostIFkeyAttr->attr.wep.key); |
c5c77ba1 | 1774 | |
45102f83 LK |
1775 | wid.id = (u16)WID_ADD_WEP_KEY; |
1776 | wid.type = WID_STR; | |
1777 | wid.val = (s8 *)pu8keybuf; | |
1778 | wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2; | |
c5c77ba1 | 1779 | |
45102f83 | 1780 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 1781 | get_id_from_handler(hif_drv)); |
49188af2 | 1782 | kfree(pu8keybuf); |
0d17e382 | 1783 | } else if (pstrHostIFkeyAttr->action & REMOVEKEY) { |
c5c77ba1 | 1784 | PRINT_D(HOSTINF_DBG, "Removing key\n"); |
45102f83 LK |
1785 | wid.id = (u16)WID_REMOVE_WEP_KEY; |
1786 | wid.type = WID_STR; | |
c5c77ba1 | 1787 | |
73b2e381 | 1788 | s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index; |
45102f83 LK |
1789 | wid.val = s8idxarray; |
1790 | wid.size = 1; | |
c5c77ba1 | 1791 | |
45102f83 | 1792 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 1793 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 1794 | } else { |
45102f83 LK |
1795 | wid.id = (u16)WID_KEY_ID; |
1796 | wid.type = WID_CHAR; | |
1797 | wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index; | |
1798 | wid.size = sizeof(char); | |
c5c77ba1 JK |
1799 | |
1800 | PRINT_D(HOSTINF_DBG, "Setting default key index\n"); | |
1801 | ||
45102f83 | 1802 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 1803 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 1804 | } |
9ea47133 | 1805 | up(&hif_drv->sem_test_key_block); |
c5c77ba1 JK |
1806 | break; |
1807 | ||
5cd8f7ae | 1808 | case WPA_RX_GTK: |
0d17e382 | 1809 | if (pstrHostIFkeyAttr->action & ADDKEY_AP) { |
b156f1ed | 1810 | pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL); |
91109e11 | 1811 | if (!pu8keybuf) { |
c5c77ba1 | 1812 | PRINT_ER("No buffer to send RxGTK Key\n"); |
9081987d | 1813 | ret = -ENOMEM; |
c5c77ba1 JK |
1814 | goto _WPARxGtk_end_case_; |
1815 | } | |
1816 | ||
91109e11 | 1817 | if (pstrHostIFkeyAttr->attr.wpa.seq) |
0e74c009 | 1818 | memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8); |
c5c77ba1 | 1819 | |
e2dfbac5 | 1820 | memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1); |
6acf2919 | 1821 | memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1); |
124968fc | 1822 | memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key, |
8c8360b3 | 1823 | pstrHostIFkeyAttr->attr.wpa.key_len); |
c5c77ba1 | 1824 | |
daaf16ba | 1825 | strWIDList[0].id = (u16)WID_11I_MODE; |
416d8321 | 1826 | strWIDList[0].type = WID_CHAR; |
2fd3e443 | 1827 | strWIDList[0].size = sizeof(char); |
bafaa696 | 1828 | strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode; |
c5c77ba1 | 1829 | |
daaf16ba | 1830 | strWIDList[1].id = (u16)WID_ADD_RX_GTK; |
416d8321 | 1831 | strWIDList[1].type = WID_STR; |
900bb4a6 | 1832 | strWIDList[1].val = (s8 *)pu8keybuf; |
2fd3e443 | 1833 | strWIDList[1].size = RX_MIC_KEY_MSG_LEN; |
c5c77ba1 | 1834 | |
31390eec | 1835 | result = send_config_pkt(SET_CFG, strWIDList, 2, |
8c8360b3 | 1836 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 1837 | |
49188af2 | 1838 | kfree(pu8keybuf); |
9ea47133 | 1839 | up(&hif_drv->sem_test_key_block); |
c5c77ba1 JK |
1840 | } |
1841 | ||
0d17e382 | 1842 | if (pstrHostIFkeyAttr->action & ADDKEY) { |
c5c77ba1 JK |
1843 | PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n"); |
1844 | ||
b156f1ed | 1845 | pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL); |
c5c77ba1 JK |
1846 | if (pu8keybuf == NULL) { |
1847 | PRINT_ER("No buffer to send RxGTK Key\n"); | |
9081987d | 1848 | ret = -ENOMEM; |
c5c77ba1 JK |
1849 | goto _WPARxGtk_end_case_; |
1850 | } | |
1851 | ||
b60005a8 | 1852 | if (hif_drv->hif_state == HOST_IF_CONNECTED) |
2a4eded9 | 1853 | memcpy(pu8keybuf, hif_drv->assoc_bssid, ETH_ALEN); |
78174ada | 1854 | else |
b60005a8 | 1855 | PRINT_ER("Couldn't handle WPARxGtk while state is not HOST_IF_CONNECTED\n"); |
c5c77ba1 | 1856 | |
0e74c009 | 1857 | memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8); |
e2dfbac5 | 1858 | memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1); |
6acf2919 | 1859 | memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1); |
124968fc | 1860 | memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key, |
8c8360b3 | 1861 | pstrHostIFkeyAttr->attr.wpa.key_len); |
c5c77ba1 | 1862 | |
45102f83 LK |
1863 | wid.id = (u16)WID_ADD_RX_GTK; |
1864 | wid.type = WID_STR; | |
1865 | wid.val = (s8 *)pu8keybuf; | |
1866 | wid.size = RX_MIC_KEY_MSG_LEN; | |
c5c77ba1 | 1867 | |
45102f83 | 1868 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 1869 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 1870 | |
49188af2 | 1871 | kfree(pu8keybuf); |
9ea47133 | 1872 | up(&hif_drv->sem_test_key_block); |
c5c77ba1 JK |
1873 | } |
1874 | _WPARxGtk_end_case_: | |
124968fc | 1875 | kfree(pstrHostIFkeyAttr->attr.wpa.key); |
0e74c009 | 1876 | kfree(pstrHostIFkeyAttr->attr.wpa.seq); |
9081987d | 1877 | if (ret) |
c5c77ba1 JK |
1878 | return ret; |
1879 | ||
1880 | break; | |
1881 | ||
2141fe39 | 1882 | case WPA_PTK: |
0d17e382 | 1883 | if (pstrHostIFkeyAttr->action & ADDKEY_AP) { |
f3052587 | 1884 | pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL); |
91109e11 | 1885 | if (!pu8keybuf) { |
c5c77ba1 | 1886 | PRINT_ER("No buffer to send PTK Key\n"); |
9081987d | 1887 | ret = -ENOMEM; |
c5c77ba1 | 1888 | goto _WPAPtk_end_case_; |
c5c77ba1 JK |
1889 | } |
1890 | ||
248080aa | 1891 | memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6); |
e2dfbac5 | 1892 | memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1); |
6acf2919 | 1893 | memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1); |
124968fc | 1894 | memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key, |
8c8360b3 | 1895 | pstrHostIFkeyAttr->attr.wpa.key_len); |
c5c77ba1 | 1896 | |
daaf16ba | 1897 | strWIDList[0].id = (u16)WID_11I_MODE; |
416d8321 | 1898 | strWIDList[0].type = WID_CHAR; |
2fd3e443 | 1899 | strWIDList[0].size = sizeof(char); |
bafaa696 | 1900 | strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode; |
c5c77ba1 | 1901 | |
daaf16ba | 1902 | strWIDList[1].id = (u16)WID_ADD_PTK; |
416d8321 | 1903 | strWIDList[1].type = WID_STR; |
900bb4a6 | 1904 | strWIDList[1].val = (s8 *)pu8keybuf; |
2fd3e443 | 1905 | strWIDList[1].size = PTK_KEY_MSG_LEN + 1; |
c5c77ba1 | 1906 | |
31390eec | 1907 | result = send_config_pkt(SET_CFG, strWIDList, 2, |
8c8360b3 | 1908 | get_id_from_handler(hif_drv)); |
49188af2 | 1909 | kfree(pu8keybuf); |
9ea47133 | 1910 | up(&hif_drv->sem_test_key_block); |
c5c77ba1 | 1911 | } |
0d17e382 | 1912 | if (pstrHostIFkeyAttr->action & ADDKEY) { |
f3052587 | 1913 | pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL); |
91109e11 | 1914 | if (!pu8keybuf) { |
c5c77ba1 | 1915 | PRINT_ER("No buffer to send PTK Key\n"); |
9081987d | 1916 | ret = -ENOMEM; |
c5c77ba1 | 1917 | goto _WPAPtk_end_case_; |
c5c77ba1 JK |
1918 | } |
1919 | ||
248080aa | 1920 | memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6); |
6acf2919 | 1921 | memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1); |
124968fc | 1922 | memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key, |
8c8360b3 | 1923 | pstrHostIFkeyAttr->attr.wpa.key_len); |
c5c77ba1 | 1924 | |
45102f83 LK |
1925 | wid.id = (u16)WID_ADD_PTK; |
1926 | wid.type = WID_STR; | |
1927 | wid.val = (s8 *)pu8keybuf; | |
1928 | wid.size = PTK_KEY_MSG_LEN; | |
c5c77ba1 | 1929 | |
45102f83 | 1930 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 1931 | get_id_from_handler(hif_drv)); |
49188af2 | 1932 | kfree(pu8keybuf); |
9ea47133 | 1933 | up(&hif_drv->sem_test_key_block); |
c5c77ba1 JK |
1934 | } |
1935 | ||
1936 | _WPAPtk_end_case_: | |
124968fc | 1937 | kfree(pstrHostIFkeyAttr->attr.wpa.key); |
9081987d | 1938 | if (ret) |
c5c77ba1 JK |
1939 | return ret; |
1940 | ||
1941 | break; | |
1942 | ||
c5c77ba1 JK |
1943 | case PMKSA: |
1944 | ||
1945 | PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n"); | |
1946 | ||
73b2e381 | 1947 | pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL); |
91109e11 | 1948 | if (!pu8keybuf) { |
c5c77ba1 | 1949 | PRINT_ER("No buffer to send PMKSA Key\n"); |
9081987d | 1950 | return -ENOMEM; |
c5c77ba1 JK |
1951 | } |
1952 | ||
73b2e381 | 1953 | pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid; |
c5c77ba1 | 1954 | |
73b2e381 LK |
1955 | for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) { |
1956 | memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN); | |
1957 | memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN); | |
c5c77ba1 JK |
1958 | } |
1959 | ||
45102f83 LK |
1960 | wid.id = (u16)WID_PMKID_INFO; |
1961 | wid.type = WID_STR; | |
1962 | wid.val = (s8 *)pu8keybuf; | |
1963 | wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1; | |
c5c77ba1 | 1964 | |
45102f83 | 1965 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 1966 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 1967 | |
49188af2 | 1968 | kfree(pu8keybuf); |
c5c77ba1 JK |
1969 | break; |
1970 | } | |
1971 | ||
31390eec | 1972 | if (result) |
c5c77ba1 JK |
1973 | PRINT_ER("Failed to send key config packet\n"); |
1974 | ||
31390eec | 1975 | return result; |
c5c77ba1 JK |
1976 | } |
1977 | ||
a4ab1ade | 1978 | static void Handle_Disconnect(struct host_if_drv *hif_drv) |
c5c77ba1 | 1979 | { |
45102f83 | 1980 | struct wid wid; |
c5c77ba1 | 1981 | |
31390eec | 1982 | s32 result = 0; |
d85f5326 | 1983 | u16 u16DummyReasonCode = 0; |
c5c77ba1 | 1984 | |
45102f83 LK |
1985 | wid.id = (u16)WID_DISCONNECT; |
1986 | wid.type = WID_CHAR; | |
1987 | wid.val = (s8 *)&u16DummyReasonCode; | |
1988 | wid.size = sizeof(char); | |
c5c77ba1 | 1989 | |
c5c77ba1 JK |
1990 | PRINT_D(HOSTINF_DBG, "Sending disconnect request\n"); |
1991 | ||
72ed4dc7 | 1992 | g_obtainingIP = false; |
a4ab1ade | 1993 | host_int_set_power_mgmt(hif_drv, 0, 0); |
c5c77ba1 | 1994 | |
281dd5ac | 1995 | eth_zero_addr(u8ConnectedSSID); |
c5c77ba1 | 1996 | |
45102f83 | 1997 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 1998 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 1999 | |
31390eec | 2000 | if (result) { |
c5c77ba1 | 2001 | PRINT_ER("Failed to send dissconect config packet\n"); |
c5c77ba1 JK |
2002 | } else { |
2003 | tstrDisconnectNotifInfo strDisconnectNotifInfo; | |
2004 | ||
2cc46837 | 2005 | memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo)); |
c5c77ba1 JK |
2006 | |
2007 | strDisconnectNotifInfo.u16reason = 0; | |
2008 | strDisconnectNotifInfo.ie = NULL; | |
2009 | strDisconnectNotifInfo.ie_len = 0; | |
2010 | ||
bc801855 | 2011 | if (hif_drv->usr_scan_req.scan_result) { |
13b313e4 | 2012 | del_timer(&hif_drv->scan_timer); |
33bfb198 LK |
2013 | hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, |
2014 | NULL, | |
2015 | hif_drv->usr_scan_req.arg, | |
2016 | NULL); | |
bc801855 | 2017 | hif_drv->usr_scan_req.scan_result = NULL; |
c5c77ba1 JK |
2018 | } |
2019 | ||
33bfb198 | 2020 | if (hif_drv->usr_conn_req.conn_result) { |
b60005a8 | 2021 | if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { |
c5c77ba1 | 2022 | PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n"); |
81a59506 | 2023 | del_timer(&hif_drv->connect_timer); |
c5c77ba1 JK |
2024 | } |
2025 | ||
33bfb198 LK |
2026 | hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, |
2027 | NULL, | |
2028 | 0, | |
2029 | &strDisconnectNotifInfo, | |
73abaa49 | 2030 | hif_drv->usr_conn_req.arg); |
c5c77ba1 | 2031 | } else { |
33bfb198 | 2032 | PRINT_ER("usr_conn_req.conn_result = NULL\n"); |
c5c77ba1 JK |
2033 | } |
2034 | ||
ca8540e4 | 2035 | scan_while_connected = false; |
c5c77ba1 | 2036 | |
b60005a8 | 2037 | hif_drv->hif_state = HOST_IF_IDLE; |
c5c77ba1 | 2038 | |
2a4eded9 | 2039 | eth_zero_addr(hif_drv->assoc_bssid); |
c5c77ba1 | 2040 | |
74ab5e45 | 2041 | hif_drv->usr_conn_req.ssid_len = 0; |
f8b17132 LK |
2042 | kfree(hif_drv->usr_conn_req.pu8ssid); |
2043 | kfree(hif_drv->usr_conn_req.pu8bssid); | |
331ed080 | 2044 | hif_drv->usr_conn_req.ies_len = 0; |
a3b2f4b9 | 2045 | kfree(hif_drv->usr_conn_req.ies); |
c5c77ba1 | 2046 | |
91109e11 | 2047 | if (join_req && join_req_drv == hif_drv) { |
044a6410 LK |
2048 | kfree(join_req); |
2049 | join_req = NULL; | |
c5c77ba1 | 2050 | } |
48ce2465 | 2051 | |
91109e11 | 2052 | if (info_element && join_req_drv == hif_drv) { |
48ce2465 LK |
2053 | kfree(info_element); |
2054 | info_element = NULL; | |
c5c77ba1 | 2055 | } |
c5c77ba1 JK |
2056 | } |
2057 | ||
e55e4967 | 2058 | up(&hif_drv->sem_test_disconn_block); |
c5c77ba1 JK |
2059 | } |
2060 | ||
a4ab1ade | 2061 | void resolve_disconnect_aberration(struct host_if_drv *hif_drv) |
c5c77ba1 | 2062 | { |
a4ab1ade | 2063 | if (!hif_drv) |
c5c77ba1 | 2064 | return; |
b60005a8 LK |
2065 | if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || |
2066 | (hif_drv->hif_state == HOST_IF_CONNECTING)) { | |
c5c77ba1 | 2067 | PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n"); |
a4ab1ade | 2068 | host_int_disconnect(hif_drv, 1); |
c5c77ba1 JK |
2069 | } |
2070 | } | |
c5c77ba1 | 2071 | |
a4ab1ade | 2072 | static s32 Handle_GetChnl(struct host_if_drv *hif_drv) |
c5c77ba1 | 2073 | { |
31390eec | 2074 | s32 result = 0; |
45102f83 | 2075 | struct wid wid; |
78c87591 | 2076 | |
45102f83 LK |
2077 | wid.id = (u16)WID_CURRENT_CHANNEL; |
2078 | wid.type = WID_CHAR; | |
2079 | wid.val = (s8 *)&ch_no; | |
2080 | wid.size = sizeof(char); | |
c5c77ba1 JK |
2081 | |
2082 | PRINT_D(HOSTINF_DBG, "Getting channel value\n"); | |
2083 | ||
45102f83 | 2084 | result = send_config_pkt(GET_CFG, &wid, 1, |
8c8360b3 | 2085 | get_id_from_handler(hif_drv)); |
ae4dfa57 | 2086 | |
31390eec | 2087 | if (result) { |
c5c77ba1 | 2088 | PRINT_ER("Failed to get channel number\n"); |
31390eec | 2089 | result = -EFAULT; |
c5c77ba1 JK |
2090 | } |
2091 | ||
4ea90008 | 2092 | up(&hif_drv->sem_get_chnl); |
c5c77ba1 | 2093 | |
31390eec | 2094 | return result; |
c5c77ba1 JK |
2095 | } |
2096 | ||
a4ab1ade | 2097 | static void Handle_GetRssi(struct host_if_drv *hif_drv) |
c5c77ba1 | 2098 | { |
31390eec | 2099 | s32 result = 0; |
45102f83 | 2100 | struct wid wid; |
c5c77ba1 | 2101 | |
45102f83 LK |
2102 | wid.id = (u16)WID_RSSI; |
2103 | wid.type = WID_CHAR; | |
2104 | wid.val = &rssi; | |
2105 | wid.size = sizeof(char); | |
c5c77ba1 | 2106 | |
c5c77ba1 JK |
2107 | PRINT_D(HOSTINF_DBG, "Getting RSSI value\n"); |
2108 | ||
45102f83 | 2109 | result = send_config_pkt(GET_CFG, &wid, 1, |
8c8360b3 | 2110 | get_id_from_handler(hif_drv)); |
31390eec | 2111 | if (result) { |
c5c77ba1 | 2112 | PRINT_ER("Failed to get RSSI value\n"); |
31390eec | 2113 | result = -EFAULT; |
c5c77ba1 JK |
2114 | } |
2115 | ||
7e111f9e | 2116 | up(&hif_drv->sem_get_rssi); |
c5c77ba1 JK |
2117 | } |
2118 | ||
a4ab1ade | 2119 | static void Handle_GetLinkspeed(struct host_if_drv *hif_drv) |
c5c77ba1 | 2120 | { |
31390eec | 2121 | s32 result = 0; |
45102f83 | 2122 | struct wid wid; |
c5c77ba1 | 2123 | |
75327a02 | 2124 | link_speed = 0; |
c5c77ba1 | 2125 | |
45102f83 LK |
2126 | wid.id = (u16)WID_LINKSPEED; |
2127 | wid.type = WID_CHAR; | |
2128 | wid.val = &link_speed; | |
2129 | wid.size = sizeof(char); | |
ae4dfa57 | 2130 | |
c5c77ba1 JK |
2131 | PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n"); |
2132 | ||
45102f83 | 2133 | result = send_config_pkt(GET_CFG, &wid, 1, |
8c8360b3 | 2134 | get_id_from_handler(hif_drv)); |
31390eec | 2135 | if (result) { |
c5c77ba1 | 2136 | PRINT_ER("Failed to get LINKSPEED value\n"); |
31390eec | 2137 | result = -EFAULT; |
c5c77ba1 JK |
2138 | } |
2139 | ||
bc34da66 | 2140 | up(&hif_drv->sem_get_link_speed); |
c5c77ba1 JK |
2141 | } |
2142 | ||
a4ab1ade | 2143 | s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) |
c5c77ba1 | 2144 | { |
e9e0c260 | 2145 | struct wid strWIDList[5]; |
31390eec | 2146 | u32 u32WidsCount = 0, result = 0; |
c5c77ba1 | 2147 | |
daaf16ba | 2148 | strWIDList[u32WidsCount].id = WID_LINKSPEED; |
416d8321 | 2149 | strWIDList[u32WidsCount].type = WID_CHAR; |
2fd3e443 | 2150 | strWIDList[u32WidsCount].size = sizeof(char); |
5babeecb | 2151 | strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->link_speed; |
c5c77ba1 JK |
2152 | u32WidsCount++; |
2153 | ||
daaf16ba | 2154 | strWIDList[u32WidsCount].id = WID_RSSI; |
416d8321 | 2155 | strWIDList[u32WidsCount].type = WID_CHAR; |
2fd3e443 | 2156 | strWIDList[u32WidsCount].size = sizeof(char); |
00c8dfcf | 2157 | strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rssi; |
c5c77ba1 JK |
2158 | u32WidsCount++; |
2159 | ||
daaf16ba | 2160 | strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT; |
416d8321 | 2161 | strWIDList[u32WidsCount].type = WID_INT; |
2fd3e443 | 2162 | strWIDList[u32WidsCount].size = sizeof(u32); |
7e84ff4e | 2163 | strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_cnt; |
c5c77ba1 JK |
2164 | u32WidsCount++; |
2165 | ||
daaf16ba | 2166 | strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT; |
416d8321 | 2167 | strWIDList[u32WidsCount].type = WID_INT; |
2fd3e443 | 2168 | strWIDList[u32WidsCount].size = sizeof(u32); |
9b99274a | 2169 | strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rx_cnt; |
c5c77ba1 JK |
2170 | u32WidsCount++; |
2171 | ||
daaf16ba | 2172 | strWIDList[u32WidsCount].id = WID_FAILED_COUNT; |
416d8321 | 2173 | strWIDList[u32WidsCount].type = WID_INT; |
2fd3e443 | 2174 | strWIDList[u32WidsCount].size = sizeof(u32); |
54160376 | 2175 | strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt; |
c5c77ba1 JK |
2176 | u32WidsCount++; |
2177 | ||
31390eec | 2178 | result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount, |
8c8360b3 | 2179 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 2180 | |
31390eec | 2181 | if (result) |
c5c77ba1 | 2182 | PRINT_ER("Failed to send scan paramters config packet\n"); |
24db713f | 2183 | |
2d25af87 | 2184 | up(&hif_sema_wait_response); |
c5c77ba1 | 2185 | return 0; |
c5c77ba1 JK |
2186 | } |
2187 | ||
a4ab1ade | 2188 | static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv, |
3d1eac04 | 2189 | struct sta_inactive_t *strHostIfStaInactiveT) |
c5c77ba1 | 2190 | { |
31390eec | 2191 | s32 result = 0; |
63d03e47 | 2192 | u8 *stamac; |
45102f83 | 2193 | struct wid wid; |
c5c77ba1 | 2194 | |
45102f83 LK |
2195 | wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME; |
2196 | wid.type = WID_STR; | |
2197 | wid.size = ETH_ALEN; | |
2198 | wid.val = kmalloc(wid.size, GFP_KERNEL); | |
c5c77ba1 | 2199 | |
45102f83 | 2200 | stamac = wid.val; |
d00d2ba3 | 2201 | memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN); |
c5c77ba1 | 2202 | |
c5c77ba1 JK |
2203 | PRINT_D(CFG80211_DBG, "SETING STA inactive time\n"); |
2204 | ||
45102f83 | 2205 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2206 | get_id_from_handler(hif_drv)); |
ae4dfa57 | 2207 | |
31390eec | 2208 | if (result) { |
c5c77ba1 | 2209 | PRINT_ER("Failed to SET incative time\n"); |
24db713f | 2210 | return -EFAULT; |
c5c77ba1 JK |
2211 | } |
2212 | ||
45102f83 LK |
2213 | wid.id = (u16)WID_GET_INACTIVE_TIME; |
2214 | wid.type = WID_INT; | |
2215 | wid.val = (s8 *)&inactive_time; | |
2216 | wid.size = sizeof(u32); | |
c5c77ba1 | 2217 | |
45102f83 | 2218 | result = send_config_pkt(GET_CFG, &wid, 1, |
8c8360b3 | 2219 | get_id_from_handler(hif_drv)); |
ae4dfa57 | 2220 | |
31390eec | 2221 | if (result) { |
c5c77ba1 | 2222 | PRINT_ER("Failed to get incative time\n"); |
24db713f | 2223 | return -EFAULT; |
c5c77ba1 JK |
2224 | } |
2225 | ||
ad26906f | 2226 | PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", inactive_time); |
c5c77ba1 | 2227 | |
569a3c67 | 2228 | up(&hif_drv->sem_inactive_time); |
c5c77ba1 | 2229 | |
31390eec | 2230 | return result; |
c5c77ba1 JK |
2231 | } |
2232 | ||
a4ab1ade | 2233 | static void Handle_AddBeacon(struct host_if_drv *hif_drv, |
7f33fecd | 2234 | struct beacon_attr *pstrSetBeaconParam) |
c5c77ba1 | 2235 | { |
31390eec | 2236 | s32 result = 0; |
45102f83 | 2237 | struct wid wid; |
63d03e47 | 2238 | u8 *pu8CurrByte; |
78c87591 | 2239 | |
c5c77ba1 JK |
2240 | PRINT_D(HOSTINF_DBG, "Adding BEACON\n"); |
2241 | ||
45102f83 LK |
2242 | wid.id = (u16)WID_ADD_BEACON; |
2243 | wid.type = WID_BIN; | |
2244 | wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16; | |
2245 | wid.val = kmalloc(wid.size, GFP_KERNEL); | |
2246 | if (!wid.val) | |
24db713f | 2247 | goto ERRORHANDLER; |
c5c77ba1 | 2248 | |
45102f83 | 2249 | pu8CurrByte = wid.val; |
12262dda LK |
2250 | *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF); |
2251 | *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF); | |
2252 | *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF); | |
2253 | *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF); | |
c5c77ba1 | 2254 | |
e76ab770 LK |
2255 | *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF); |
2256 | *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF); | |
2257 | *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF); | |
2258 | *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF); | |
c5c77ba1 | 2259 | |
51c66185 LK |
2260 | *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF); |
2261 | *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF); | |
2262 | *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF); | |
2263 | *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF); | |
c5c77ba1 | 2264 | |
8ce528b9 | 2265 | memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len); |
51c66185 | 2266 | pu8CurrByte += pstrSetBeaconParam->head_len; |
c5c77ba1 | 2267 | |
030c57e2 LK |
2268 | *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF); |
2269 | *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF); | |
2270 | *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF); | |
2271 | *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF); | |
c5c77ba1 | 2272 | |
7dbcb6d3 LK |
2273 | if (pstrSetBeaconParam->tail > 0) |
2274 | memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len); | |
030c57e2 | 2275 | pu8CurrByte += pstrSetBeaconParam->tail_len; |
c5c77ba1 | 2276 | |
45102f83 | 2277 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2278 | get_id_from_handler(hif_drv)); |
31390eec | 2279 | if (result) |
c5c77ba1 | 2280 | PRINT_ER("Failed to send add beacon config packet\n"); |
c5c77ba1 | 2281 | |
24db713f | 2282 | ERRORHANDLER: |
45102f83 | 2283 | kfree(wid.val); |
8ce528b9 | 2284 | kfree(pstrSetBeaconParam->head); |
7dbcb6d3 | 2285 | kfree(pstrSetBeaconParam->tail); |
c5c77ba1 JK |
2286 | } |
2287 | ||
a4ab1ade | 2288 | static void Handle_DelBeacon(struct host_if_drv *hif_drv) |
c5c77ba1 | 2289 | { |
31390eec | 2290 | s32 result = 0; |
45102f83 | 2291 | struct wid wid; |
63d03e47 | 2292 | u8 *pu8CurrByte; |
78c87591 | 2293 | |
45102f83 LK |
2294 | wid.id = (u16)WID_DEL_BEACON; |
2295 | wid.type = WID_CHAR; | |
2296 | wid.size = sizeof(char); | |
2297 | wid.val = &del_beacon; | |
c5c77ba1 | 2298 | |
45102f83 | 2299 | if (!wid.val) |
24db713f | 2300 | return; |
c5c77ba1 | 2301 | |
45102f83 | 2302 | pu8CurrByte = wid.val; |
c5c77ba1 JK |
2303 | |
2304 | PRINT_D(HOSTINF_DBG, "Deleting BEACON\n"); | |
c5c77ba1 | 2305 | |
45102f83 | 2306 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2307 | get_id_from_handler(hif_drv)); |
31390eec | 2308 | if (result) |
c5c77ba1 | 2309 | PRINT_ER("Failed to send delete beacon config packet\n"); |
c5c77ba1 JK |
2310 | } |
2311 | ||
6a89ba9c TC |
2312 | static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer, |
2313 | struct add_sta_param *pstrStationParam) | |
c5c77ba1 | 2314 | { |
63d03e47 | 2315 | u8 *pu8CurrByte; |
c5c77ba1 JK |
2316 | |
2317 | pu8CurrByte = pu8Buffer; | |
2318 | ||
2319 | PRINT_D(HOSTINF_DBG, "Packing STA params\n"); | |
2353c388 | 2320 | memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN); |
c5c77ba1 JK |
2321 | pu8CurrByte += ETH_ALEN; |
2322 | ||
4101eb8a LK |
2323 | *pu8CurrByte++ = pstrStationParam->aid & 0xFF; |
2324 | *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF; | |
c5c77ba1 | 2325 | |
e734223c LK |
2326 | *pu8CurrByte++ = pstrStationParam->rates_len; |
2327 | if (pstrStationParam->rates_len > 0) | |
a622e016 | 2328 | memcpy(pu8CurrByte, pstrStationParam->rates, |
e734223c LK |
2329 | pstrStationParam->rates_len); |
2330 | pu8CurrByte += pstrStationParam->rates_len; | |
c5c77ba1 | 2331 | |
22520120 | 2332 | *pu8CurrByte++ = pstrStationParam->ht_supported; |
0d073f69 LK |
2333 | *pu8CurrByte++ = pstrStationParam->ht_capa_info & 0xFF; |
2334 | *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF; | |
c5c77ba1 | 2335 | |
fba1f2d2 | 2336 | *pu8CurrByte++ = pstrStationParam->ht_ampdu_params; |
5ebbf4f7 LK |
2337 | memcpy(pu8CurrByte, pstrStationParam->ht_supp_mcs_set, |
2338 | WILC_SUPP_MCS_SET_SIZE); | |
c5c77ba1 JK |
2339 | pu8CurrByte += WILC_SUPP_MCS_SET_SIZE; |
2340 | ||
223741d7 LK |
2341 | *pu8CurrByte++ = pstrStationParam->ht_ext_params & 0xFF; |
2342 | *pu8CurrByte++ = (pstrStationParam->ht_ext_params >> 8) & 0xFF; | |
c5c77ba1 | 2343 | |
74fe73cf LK |
2344 | *pu8CurrByte++ = pstrStationParam->ht_tx_bf_cap & 0xFF; |
2345 | *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 8) & 0xFF; | |
2346 | *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 16) & 0xFF; | |
2347 | *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 24) & 0xFF; | |
c5c77ba1 | 2348 | |
a486baff | 2349 | *pu8CurrByte++ = pstrStationParam->ht_ante_sel; |
c5c77ba1 | 2350 | |
f676e17a LK |
2351 | *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF; |
2352 | *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF; | |
c5c77ba1 | 2353 | |
67ab64e4 LK |
2354 | *pu8CurrByte++ = pstrStationParam->flags_set & 0xFF; |
2355 | *pu8CurrByte++ = (pstrStationParam->flags_set >> 8) & 0xFF; | |
c5c77ba1 JK |
2356 | |
2357 | return pu8CurrByte - pu8Buffer; | |
2358 | } | |
2359 | ||
a4ab1ade | 2360 | static void Handle_AddStation(struct host_if_drv *hif_drv, |
6a89ba9c | 2361 | struct add_sta_param *pstrStationParam) |
c5c77ba1 | 2362 | { |
31390eec | 2363 | s32 result = 0; |
45102f83 | 2364 | struct wid wid; |
63d03e47 | 2365 | u8 *pu8CurrByte; |
78c87591 | 2366 | |
c5c77ba1 | 2367 | PRINT_D(HOSTINF_DBG, "Handling add station\n"); |
45102f83 LK |
2368 | wid.id = (u16)WID_ADD_STA; |
2369 | wid.type = WID_BIN; | |
e734223c | 2370 | wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len; |
c5c77ba1 | 2371 | |
45102f83 LK |
2372 | wid.val = kmalloc(wid.size, GFP_KERNEL); |
2373 | if (!wid.val) | |
24db713f | 2374 | goto ERRORHANDLER; |
c5c77ba1 | 2375 | |
45102f83 | 2376 | pu8CurrByte = wid.val; |
c5c77ba1 JK |
2377 | pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); |
2378 | ||
45102f83 | 2379 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2380 | get_id_from_handler(hif_drv)); |
31390eec | 2381 | if (result != 0) |
c5c77ba1 | 2382 | PRINT_ER("Failed to send add station config packet\n"); |
c5c77ba1 | 2383 | |
24db713f | 2384 | ERRORHANDLER: |
a622e016 | 2385 | kfree(pstrStationParam->rates); |
45102f83 | 2386 | kfree(wid.val); |
c5c77ba1 JK |
2387 | } |
2388 | ||
a4ab1ade | 2389 | static void Handle_DelAllSta(struct host_if_drv *hif_drv, |
b4e644e4 | 2390 | struct del_all_sta *pstrDelAllStaParam) |
c5c77ba1 | 2391 | { |
31390eec | 2392 | s32 result = 0; |
45102f83 | 2393 | struct wid wid; |
63d03e47 | 2394 | u8 *pu8CurrByte; |
63d03e47 | 2395 | u8 i; |
3703480b | 2396 | u8 au8Zero_Buff[6] = {0}; |
78c87591 | 2397 | |
45102f83 LK |
2398 | wid.id = (u16)WID_DEL_ALL_STA; |
2399 | wid.type = WID_STR; | |
2400 | wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1; | |
c5c77ba1 | 2401 | |
03b2d5e7 | 2402 | PRINT_D(HOSTINF_DBG, "Handling delete station\n"); |
c5c77ba1 | 2403 | |
45102f83 LK |
2404 | wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL); |
2405 | if (!wid.val) | |
24db713f | 2406 | goto ERRORHANDLER; |
c5c77ba1 | 2407 | |
45102f83 | 2408 | pu8CurrByte = wid.val; |
c5c77ba1 | 2409 | |
8ba1803f | 2410 | *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta; |
c5c77ba1 JK |
2411 | |
2412 | for (i = 0; i < MAX_NUM_STA; i++) { | |
e51b9216 LK |
2413 | if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN)) |
2414 | memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN); | |
c5c77ba1 JK |
2415 | else |
2416 | continue; | |
2417 | ||
2418 | pu8CurrByte += ETH_ALEN; | |
2419 | } | |
2420 | ||
45102f83 | 2421 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2422 | get_id_from_handler(hif_drv)); |
31390eec | 2423 | if (result) |
83cc9be5 | 2424 | PRINT_ER("Failed to send add station config packet\n"); |
c5c77ba1 | 2425 | |
24db713f | 2426 | ERRORHANDLER: |
45102f83 | 2427 | kfree(wid.val); |
c5c77ba1 | 2428 | |
2d25af87 | 2429 | up(&hif_sema_wait_response); |
c5c77ba1 JK |
2430 | } |
2431 | ||
a4ab1ade | 2432 | static void Handle_DelStation(struct host_if_drv *hif_drv, |
fb93a1e1 | 2433 | struct del_sta *pstrDelStaParam) |
c5c77ba1 | 2434 | { |
31390eec | 2435 | s32 result = 0; |
45102f83 | 2436 | struct wid wid; |
63d03e47 | 2437 | u8 *pu8CurrByte; |
c5c77ba1 | 2438 | |
45102f83 LK |
2439 | wid.id = (u16)WID_REMOVE_STA; |
2440 | wid.type = WID_BIN; | |
2441 | wid.size = ETH_ALEN; | |
c5c77ba1 | 2442 | |
03b2d5e7 | 2443 | PRINT_D(HOSTINF_DBG, "Handling delete station\n"); |
c5c77ba1 | 2444 | |
45102f83 LK |
2445 | wid.val = kmalloc(wid.size, GFP_KERNEL); |
2446 | if (!wid.val) | |
24db713f | 2447 | goto ERRORHANDLER; |
c5c77ba1 | 2448 | |
45102f83 | 2449 | pu8CurrByte = wid.val; |
c5c77ba1 | 2450 | |
e4839d39 | 2451 | memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN); |
c5c77ba1 | 2452 | |
45102f83 | 2453 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2454 | get_id_from_handler(hif_drv)); |
31390eec | 2455 | if (result) |
83cc9be5 | 2456 | PRINT_ER("Failed to send add station config packet\n"); |
c5c77ba1 | 2457 | |
24db713f | 2458 | ERRORHANDLER: |
45102f83 | 2459 | kfree(wid.val); |
c5c77ba1 JK |
2460 | } |
2461 | ||
a4ab1ade | 2462 | static void Handle_EditStation(struct host_if_drv *hif_drv, |
6a89ba9c | 2463 | struct add_sta_param *pstrStationParam) |
c5c77ba1 | 2464 | { |
31390eec | 2465 | s32 result = 0; |
45102f83 | 2466 | struct wid wid; |
63d03e47 | 2467 | u8 *pu8CurrByte; |
c5c77ba1 | 2468 | |
45102f83 LK |
2469 | wid.id = (u16)WID_EDIT_STA; |
2470 | wid.type = WID_BIN; | |
e734223c | 2471 | wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len; |
c5c77ba1 JK |
2472 | |
2473 | PRINT_D(HOSTINF_DBG, "Handling edit station\n"); | |
45102f83 LK |
2474 | wid.val = kmalloc(wid.size, GFP_KERNEL); |
2475 | if (!wid.val) | |
24db713f | 2476 | goto ERRORHANDLER; |
c5c77ba1 | 2477 | |
45102f83 | 2478 | pu8CurrByte = wid.val; |
c5c77ba1 JK |
2479 | pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam); |
2480 | ||
45102f83 | 2481 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2482 | get_id_from_handler(hif_drv)); |
31390eec | 2483 | if (result) |
c5c77ba1 | 2484 | PRINT_ER("Failed to send edit station config packet\n"); |
c5c77ba1 | 2485 | |
24db713f | 2486 | ERRORHANDLER: |
a622e016 | 2487 | kfree(pstrStationParam->rates); |
45102f83 | 2488 | kfree(wid.val); |
c5c77ba1 | 2489 | } |
c5c77ba1 | 2490 | |
a4ab1ade | 2491 | static int Handle_RemainOnChan(struct host_if_drv *hif_drv, |
2f9c03f5 | 2492 | struct remain_ch *pstrHostIfRemainOnChan) |
c5c77ba1 | 2493 | { |
31390eec | 2494 | s32 result = 0; |
63d03e47 | 2495 | u8 u8remain_on_chan_flag; |
45102f83 | 2496 | struct wid wid; |
c5c77ba1 | 2497 | |
5beef2ca | 2498 | if (!hif_drv->remain_on_ch_pending) { |
c5cc4b12 | 2499 | hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg; |
bfb62abc | 2500 | hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired; |
5e5f7916 | 2501 | hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready; |
839ab709 | 2502 | hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch; |
9d764e38 | 2503 | hif_drv->remain_on_ch.id = pstrHostIfRemainOnChan->id; |
c5c77ba1 | 2504 | } else { |
839ab709 | 2505 | pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch; |
c5c77ba1 JK |
2506 | } |
2507 | ||
bc801855 | 2508 | if (hif_drv->usr_scan_req.scan_result) { |
c5c77ba1 | 2509 | PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n"); |
5beef2ca | 2510 | hif_drv->remain_on_ch_pending = 1; |
31390eec | 2511 | result = -EBUSY; |
24db713f | 2512 | goto ERRORHANDLER; |
c5c77ba1 | 2513 | } |
b60005a8 | 2514 | if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) { |
c5c77ba1 | 2515 | PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n"); |
31390eec | 2516 | result = -EBUSY; |
24db713f | 2517 | goto ERRORHANDLER; |
c5c77ba1 JK |
2518 | } |
2519 | ||
c5c77ba1 JK |
2520 | if (g_obtainingIP || connecting) { |
2521 | PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n"); | |
31390eec | 2522 | result = -EBUSY; |
24db713f | 2523 | goto ERRORHANDLER; |
c5c77ba1 | 2524 | } |
c5c77ba1 | 2525 | |
839ab709 LK |
2526 | PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", |
2527 | pstrHostIfRemainOnChan->ch); | |
c5c77ba1 | 2528 | |
72ed4dc7 | 2529 | u8remain_on_chan_flag = true; |
45102f83 LK |
2530 | wid.id = (u16)WID_REMAIN_ON_CHAN; |
2531 | wid.type = WID_STR; | |
2532 | wid.size = 2; | |
2533 | wid.val = kmalloc(wid.size, GFP_KERNEL); | |
2534 | if (!wid.val) { | |
31390eec | 2535 | result = -ENOMEM; |
24db713f LK |
2536 | goto ERRORHANDLER; |
2537 | } | |
c5c77ba1 | 2538 | |
45102f83 | 2539 | wid.val[0] = u8remain_on_chan_flag; |
839ab709 | 2540 | wid.val[1] = (s8)pstrHostIfRemainOnChan->ch; |
c5c77ba1 | 2541 | |
45102f83 | 2542 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2543 | get_id_from_handler(hif_drv)); |
31390eec | 2544 | if (result != 0) |
c5c77ba1 | 2545 | PRINT_ER("Failed to set remain on channel\n"); |
c5c77ba1 | 2546 | |
24db713f | 2547 | ERRORHANDLER: |
c5c77ba1 JK |
2548 | { |
2549 | P2P_LISTEN_STATE = 1; | |
cc2d7e9e LK |
2550 | hif_drv->remain_on_ch_timer.data = (unsigned long)hif_drv; |
2551 | mod_timer(&hif_drv->remain_on_ch_timer, | |
9eb06643 GKH |
2552 | jiffies + |
2553 | msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration)); | |
c5c77ba1 | 2554 | |
5e5f7916 | 2555 | if (hif_drv->remain_on_ch.ready) |
c5cc4b12 | 2556 | hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg); |
c5c77ba1 | 2557 | |
5beef2ca LK |
2558 | if (hif_drv->remain_on_ch_pending) |
2559 | hif_drv->remain_on_ch_pending = 0; | |
c5c77ba1 | 2560 | } |
31390eec LK |
2561 | |
2562 | return result; | |
c5c77ba1 JK |
2563 | } |
2564 | ||
a4ab1ade | 2565 | static int Handle_RegisterFrame(struct host_if_drv *hif_drv, |
bc37c5df | 2566 | struct reg_frame *pstrHostIfRegisterFrame) |
c5c77ba1 | 2567 | { |
31390eec | 2568 | s32 result = 0; |
45102f83 | 2569 | struct wid wid; |
63d03e47 | 2570 | u8 *pu8CurrByte; |
c5c77ba1 | 2571 | |
6abf8681 LK |
2572 | PRINT_D(HOSTINF_DBG, "Handling frame register : %d FrameType: %d\n", |
2573 | pstrHostIfRegisterFrame->reg, | |
d5f654ca | 2574 | pstrHostIfRegisterFrame->frame_type); |
c5c77ba1 | 2575 | |
45102f83 LK |
2576 | wid.id = (u16)WID_REGISTER_FRAME; |
2577 | wid.type = WID_STR; | |
2578 | wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL); | |
2579 | if (!wid.val) | |
24db713f | 2580 | return -ENOMEM; |
c5c77ba1 | 2581 | |
45102f83 | 2582 | pu8CurrByte = wid.val; |
c5c77ba1 | 2583 | |
6abf8681 | 2584 | *pu8CurrByte++ = pstrHostIfRegisterFrame->reg; |
bcb410bb | 2585 | *pu8CurrByte++ = pstrHostIfRegisterFrame->reg_id; |
d5f654ca | 2586 | memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16)); |
c5c77ba1 | 2587 | |
45102f83 | 2588 | wid.size = sizeof(u16) + 2; |
c5c77ba1 | 2589 | |
45102f83 | 2590 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2591 | get_id_from_handler(hif_drv)); |
31390eec | 2592 | if (result) { |
c5c77ba1 | 2593 | PRINT_ER("Failed to frame register config packet\n"); |
31390eec | 2594 | result = -EINVAL; |
c5c77ba1 JK |
2595 | } |
2596 | ||
31390eec | 2597 | return result; |
c5c77ba1 JK |
2598 | } |
2599 | ||
a4ab1ade | 2600 | static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv, |
2f9c03f5 | 2601 | struct remain_ch *pstrHostIfRemainOnChan) |
c5c77ba1 | 2602 | { |
63d03e47 | 2603 | u8 u8remain_on_chan_flag; |
45102f83 | 2604 | struct wid wid; |
31390eec | 2605 | s32 result = 0; |
c5c77ba1 JK |
2606 | |
2607 | PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n"); | |
2608 | ||
c5c77ba1 | 2609 | if (P2P_LISTEN_STATE) { |
72ed4dc7 | 2610 | u8remain_on_chan_flag = false; |
45102f83 LK |
2611 | wid.id = (u16)WID_REMAIN_ON_CHAN; |
2612 | wid.type = WID_STR; | |
2613 | wid.size = 2; | |
2614 | wid.val = kmalloc(wid.size, GFP_KERNEL); | |
c5c77ba1 | 2615 | |
45102f83 | 2616 | if (!wid.val) |
c5c77ba1 | 2617 | PRINT_ER("Failed to allocate memory\n"); |
c5c77ba1 | 2618 | |
45102f83 LK |
2619 | wid.val[0] = u8remain_on_chan_flag; |
2620 | wid.val[1] = FALSE_FRMWR_CHANNEL; | |
c5c77ba1 | 2621 | |
45102f83 | 2622 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2623 | get_id_from_handler(hif_drv)); |
31390eec | 2624 | if (result != 0) { |
c5c77ba1 JK |
2625 | PRINT_ER("Failed to set remain on channel\n"); |
2626 | goto _done_; | |
2627 | } | |
2628 | ||
bfb62abc | 2629 | if (hif_drv->remain_on_ch.expired) { |
c5cc4b12 | 2630 | hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg, |
9d764e38 | 2631 | pstrHostIfRemainOnChan->id); |
c5c77ba1 JK |
2632 | } |
2633 | P2P_LISTEN_STATE = 0; | |
2634 | } else { | |
2635 | PRINT_D(GENERIC_DBG, "Not in listen state\n"); | |
31390eec | 2636 | result = -EFAULT; |
c5c77ba1 JK |
2637 | } |
2638 | ||
2639 | _done_: | |
31390eec | 2640 | return result; |
c5c77ba1 JK |
2641 | } |
2642 | ||
93dee8ee | 2643 | static void ListenTimerCB(unsigned long arg) |
c5c77ba1 | 2644 | { |
31390eec | 2645 | s32 result = 0; |
143eb95a | 2646 | struct host_if_msg msg; |
a4ab1ade | 2647 | struct host_if_drv *hif_drv = (struct host_if_drv *)arg; |
ae4dfa57 | 2648 | |
cc2d7e9e | 2649 | del_timer(&hif_drv->remain_on_ch_timer); |
c5c77ba1 | 2650 | |
143eb95a | 2651 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 2652 | msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; |
a4ab1ade | 2653 | msg.drv = hif_drv; |
9d764e38 | 2654 | msg.body.remain_on_ch.id = hif_drv->remain_on_ch.id; |
c5c77ba1 | 2655 | |
31390eec LK |
2656 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
2657 | if (result) | |
24db713f | 2658 | PRINT_ER("wilc_mq_send fail\n"); |
c5c77ba1 | 2659 | } |
c5c77ba1 | 2660 | |
a4ab1ade | 2661 | static void Handle_PowerManagement(struct host_if_drv *hif_drv, |
5a008f1c | 2662 | struct power_mgmt_param *strPowerMgmtParam) |
c5c77ba1 | 2663 | { |
31390eec | 2664 | s32 result = 0; |
45102f83 | 2665 | struct wid wid; |
ca356ada | 2666 | s8 s8PowerMode; |
78c87591 | 2667 | |
45102f83 | 2668 | wid.id = (u16)WID_POWER_MANAGEMENT; |
c5c77ba1 | 2669 | |
047e6646 | 2670 | if (strPowerMgmtParam->enabled) |
c5c77ba1 | 2671 | s8PowerMode = MIN_FAST_PS; |
78174ada | 2672 | else |
c5c77ba1 | 2673 | s8PowerMode = NO_POWERSAVE; |
c5c77ba1 | 2674 | PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode); |
45102f83 LK |
2675 | wid.val = &s8PowerMode; |
2676 | wid.size = sizeof(char); | |
c5c77ba1 JK |
2677 | |
2678 | PRINT_D(HOSTINF_DBG, "Handling Power Management\n"); | |
2679 | ||
45102f83 | 2680 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2681 | get_id_from_handler(hif_drv)); |
31390eec | 2682 | if (result) |
c5c77ba1 | 2683 | PRINT_ER("Failed to send power management config packet\n"); |
c5c77ba1 JK |
2684 | } |
2685 | ||
a4ab1ade | 2686 | static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv, |
641210ac | 2687 | struct set_multicast *strHostIfSetMulti) |
c5c77ba1 | 2688 | { |
31390eec | 2689 | s32 result = 0; |
45102f83 | 2690 | struct wid wid; |
63d03e47 | 2691 | u8 *pu8CurrByte; |
c5c77ba1 JK |
2692 | |
2693 | PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n"); | |
2694 | ||
45102f83 LK |
2695 | wid.id = (u16)WID_SETUP_MULTICAST_FILTER; |
2696 | wid.type = WID_BIN; | |
2697 | wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN); | |
2698 | wid.val = kmalloc(wid.size, GFP_KERNEL); | |
2699 | if (!wid.val) | |
24db713f | 2700 | goto ERRORHANDLER; |
c5c77ba1 | 2701 | |
45102f83 | 2702 | pu8CurrByte = wid.val; |
bae636eb LK |
2703 | *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF); |
2704 | *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF); | |
2705 | *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF); | |
2706 | *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF); | |
c5c77ba1 | 2707 | |
adab2f71 LK |
2708 | *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF); |
2709 | *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF); | |
2710 | *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF); | |
2711 | *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF); | |
c5c77ba1 | 2712 | |
adab2f71 | 2713 | if ((strHostIfSetMulti->cnt) > 0) |
fb70e9f5 LK |
2714 | memcpy(pu8CurrByte, multicast_mac_addr_list, |
2715 | ((strHostIfSetMulti->cnt) * ETH_ALEN)); | |
c5c77ba1 | 2716 | |
45102f83 | 2717 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2718 | get_id_from_handler(hif_drv)); |
31390eec | 2719 | if (result) |
c5c77ba1 | 2720 | PRINT_ER("Failed to send setup multicast config packet\n"); |
c5c77ba1 | 2721 | |
24db713f | 2722 | ERRORHANDLER: |
45102f83 | 2723 | kfree(wid.val); |
c5c77ba1 JK |
2724 | } |
2725 | ||
a4ab1ade | 2726 | static s32 Handle_AddBASession(struct host_if_drv *hif_drv, |
54265472 | 2727 | struct ba_session_info *strHostIfBASessionInfo) |
c5c77ba1 | 2728 | { |
31390eec | 2729 | s32 result = 0; |
45102f83 | 2730 | struct wid wid; |
c5c77ba1 JK |
2731 | int AddbaTimeout = 100; |
2732 | char *ptr = NULL; | |
c5c77ba1 | 2733 | |
03b2d5e7 | 2734 | PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n", |
3fc4999e LK |
2735 | strHostIfBASessionInfo->bssid[0], |
2736 | strHostIfBASessionInfo->bssid[1], | |
2737 | strHostIfBASessionInfo->bssid[2], | |
277c2130 | 2738 | strHostIfBASessionInfo->buf_size, |
23d0bfaa | 2739 | strHostIfBASessionInfo->time_out, |
16c9b391 | 2740 | strHostIfBASessionInfo->tid); |
c5c77ba1 | 2741 | |
45102f83 LK |
2742 | wid.id = (u16)WID_11E_P_ACTION_REQ; |
2743 | wid.type = WID_STR; | |
2744 | wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL); | |
2745 | wid.size = BLOCK_ACK_REQ_SIZE; | |
2746 | ptr = wid.val; | |
c5c77ba1 JK |
2747 | *ptr++ = 0x14; |
2748 | *ptr++ = 0x3; | |
2749 | *ptr++ = 0x0; | |
3fc4999e | 2750 | memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); |
c5c77ba1 | 2751 | ptr += ETH_ALEN; |
16c9b391 | 2752 | *ptr++ = strHostIfBASessionInfo->tid; |
c5c77ba1 | 2753 | *ptr++ = 1; |
277c2130 LK |
2754 | *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); |
2755 | *ptr++ = ((strHostIfBASessionInfo->buf_size >> 16) & 0xFF); | |
23d0bfaa LK |
2756 | *ptr++ = (strHostIfBASessionInfo->time_out & 0xFF); |
2757 | *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF); | |
c5c77ba1 JK |
2758 | *ptr++ = (AddbaTimeout & 0xFF); |
2759 | *ptr++ = ((AddbaTimeout >> 16) & 0xFF); | |
c5c77ba1 | 2760 | *ptr++ = 8; |
c5c77ba1 JK |
2761 | *ptr++ = 0; |
2762 | ||
45102f83 | 2763 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2764 | get_id_from_handler(hif_drv)); |
31390eec | 2765 | if (result) |
c5c77ba1 JK |
2766 | PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n"); |
2767 | ||
45102f83 LK |
2768 | wid.id = (u16)WID_11E_P_ACTION_REQ; |
2769 | wid.type = WID_STR; | |
2770 | wid.size = 15; | |
2771 | ptr = wid.val; | |
c5c77ba1 JK |
2772 | *ptr++ = 15; |
2773 | *ptr++ = 7; | |
2774 | *ptr++ = 0x2; | |
3fc4999e | 2775 | memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); |
c5c77ba1 | 2776 | ptr += ETH_ALEN; |
16c9b391 | 2777 | *ptr++ = strHostIfBASessionInfo->tid; |
c5c77ba1 | 2778 | *ptr++ = 8; |
277c2130 | 2779 | *ptr++ = (strHostIfBASessionInfo->buf_size & 0xFF); |
23d0bfaa | 2780 | *ptr++ = ((strHostIfBASessionInfo->time_out >> 16) & 0xFF); |
c5c77ba1 | 2781 | *ptr++ = 3; |
45102f83 | 2782 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2783 | get_id_from_handler(hif_drv)); |
c5c77ba1 | 2784 | |
45102f83 | 2785 | kfree(wid.val); |
c5c77ba1 | 2786 | |
31390eec | 2787 | return result; |
c5c77ba1 JK |
2788 | } |
2789 | ||
a4ab1ade | 2790 | static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv, |
54265472 | 2791 | struct ba_session_info *strHostIfBASessionInfo) |
c5c77ba1 | 2792 | { |
31390eec | 2793 | s32 result = 0; |
45102f83 | 2794 | struct wid wid; |
c5c77ba1 | 2795 | char *ptr = NULL; |
c5c77ba1 | 2796 | |
03b2d5e7 | 2797 | PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n", |
3fc4999e LK |
2798 | strHostIfBASessionInfo->bssid[0], |
2799 | strHostIfBASessionInfo->bssid[1], | |
2800 | strHostIfBASessionInfo->bssid[2], | |
16c9b391 | 2801 | strHostIfBASessionInfo->tid); |
c5c77ba1 | 2802 | |
45102f83 LK |
2803 | wid.id = (u16)WID_DEL_ALL_RX_BA; |
2804 | wid.type = WID_STR; | |
2805 | wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL); | |
2806 | wid.size = BLOCK_ACK_REQ_SIZE; | |
2807 | ptr = wid.val; | |
c5c77ba1 JK |
2808 | *ptr++ = 0x14; |
2809 | *ptr++ = 0x3; | |
2810 | *ptr++ = 0x2; | |
3fc4999e | 2811 | memcpy(ptr, strHostIfBASessionInfo->bssid, ETH_ALEN); |
c5c77ba1 | 2812 | ptr += ETH_ALEN; |
16c9b391 | 2813 | *ptr++ = strHostIfBASessionInfo->tid; |
c5c77ba1 | 2814 | *ptr++ = 0; |
ae4dfa57 | 2815 | *ptr++ = 32; |
c5c77ba1 | 2816 | |
45102f83 | 2817 | result = send_config_pkt(SET_CFG, &wid, 1, |
8c8360b3 | 2818 | get_id_from_handler(hif_drv)); |
31390eec | 2819 | if (result) |
c5c77ba1 JK |
2820 | PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n"); |
2821 | ||
45102f83 | 2822 | kfree(wid.val); |
c5c77ba1 | 2823 | |
2d25af87 | 2824 | up(&hif_sema_wait_response); |
c5c77ba1 | 2825 | |
31390eec | 2826 | return result; |
c5c77ba1 JK |
2827 | } |
2828 | ||
1999bd52 | 2829 | static int hostIFthread(void *pvArg) |
c5c77ba1 | 2830 | { |
4e4467fd | 2831 | u32 u32Ret; |
143eb95a | 2832 | struct host_if_msg msg; |
a4ab1ade | 2833 | struct host_if_drv *hif_drv; |
c5c77ba1 | 2834 | |
143eb95a | 2835 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
2836 | |
2837 | while (1) { | |
cb067dcf | 2838 | wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret); |
a4ab1ade | 2839 | hif_drv = (struct host_if_drv *)msg.drv; |
a9f812a6 | 2840 | if (msg.id == HOST_IF_MSG_EXIT) { |
c5c77ba1 JK |
2841 | PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n"); |
2842 | break; | |
2843 | } | |
2844 | ||
c5c77ba1 JK |
2845 | if ((!g_wilc_initialized)) { |
2846 | PRINT_D(GENERIC_DBG, "--WAIT--"); | |
80e29c7a | 2847 | usleep_range(200 * 1000, 200 * 1000); |
cb067dcf | 2848 | wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
2849 | continue; |
2850 | } | |
2851 | ||
91109e11 | 2852 | if (msg.id == HOST_IF_MSG_CONNECT && |
bc801855 | 2853 | hif_drv->usr_scan_req.scan_result) { |
c5c77ba1 | 2854 | PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n"); |
cb067dcf | 2855 | wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
80e29c7a | 2856 | usleep_range(2 * 1000, 2 * 1000); |
c5c77ba1 JK |
2857 | continue; |
2858 | } | |
2859 | ||
a9f812a6 | 2860 | switch (msg.id) { |
c5c77ba1 JK |
2861 | case HOST_IF_MSG_Q_IDLE: |
2862 | Handle_wait_msg_q_empty(); | |
2863 | break; | |
2864 | ||
2865 | case HOST_IF_MSG_SCAN: | |
2482a79f | 2866 | Handle_Scan(msg.drv, &msg.body.scan_info); |
c5c77ba1 JK |
2867 | break; |
2868 | ||
2869 | case HOST_IF_MSG_CONNECT: | |
2482a79f | 2870 | Handle_Connect(msg.drv, &msg.body.con_info); |
c5c77ba1 JK |
2871 | break; |
2872 | ||
c5c77ba1 | 2873 | case HOST_IF_MSG_FLUSH_CONNECT: |
2482a79f | 2874 | Handle_FlushConnect(msg.drv); |
c5c77ba1 JK |
2875 | break; |
2876 | ||
2877 | case HOST_IF_MSG_RCVD_NTWRK_INFO: | |
2482a79f | 2878 | Handle_RcvdNtwrkInfo(msg.drv, &msg.body.net_info); |
c5c77ba1 JK |
2879 | break; |
2880 | ||
2881 | case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO: | |
2482a79f | 2882 | Handle_RcvdGnrlAsyncInfo(msg.drv, &msg.body.async_info); |
c5c77ba1 JK |
2883 | break; |
2884 | ||
2885 | case HOST_IF_MSG_KEY: | |
2482a79f | 2886 | Handle_Key(msg.drv, &msg.body.key_info); |
c5c77ba1 JK |
2887 | break; |
2888 | ||
2889 | case HOST_IF_MSG_CFG_PARAMS: | |
dc276664 | 2890 | handle_cfg_param(msg.drv, &msg.body.cfg_info); |
c5c77ba1 JK |
2891 | break; |
2892 | ||
2893 | case HOST_IF_MSG_SET_CHANNEL: | |
3eec50cf | 2894 | handle_set_channel(msg.drv, &msg.body.channel_info); |
c5c77ba1 JK |
2895 | break; |
2896 | ||
2897 | case HOST_IF_MSG_DISCONNECT: | |
2482a79f | 2898 | Handle_Disconnect(msg.drv); |
c5c77ba1 JK |
2899 | break; |
2900 | ||
2901 | case HOST_IF_MSG_RCVD_SCAN_COMPLETE: | |
13b313e4 | 2902 | del_timer(&hif_drv->scan_timer); |
c5c77ba1 JK |
2903 | PRINT_D(HOSTINF_DBG, "scan completed successfully\n"); |
2904 | ||
2b9d5b48 | 2905 | if (!linux_wlan_get_num_conn_ifcs()) |
1b721bf0 | 2906 | chip_sleep_manually(); |
c5c77ba1 | 2907 | |
2482a79f | 2908 | Handle_ScanDone(msg.drv, SCAN_EVENT_DONE); |
c5c77ba1 | 2909 | |
5beef2ca | 2910 | if (hif_drv->remain_on_ch_pending) |
2482a79f | 2911 | Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch); |
c5c77ba1 JK |
2912 | |
2913 | break; | |
2914 | ||
2915 | case HOST_IF_MSG_GET_RSSI: | |
2482a79f | 2916 | Handle_GetRssi(msg.drv); |
c5c77ba1 JK |
2917 | break; |
2918 | ||
2919 | case HOST_IF_MSG_GET_LINKSPEED: | |
2482a79f | 2920 | Handle_GetLinkspeed(msg.drv); |
c5c77ba1 JK |
2921 | break; |
2922 | ||
2923 | case HOST_IF_MSG_GET_STATISTICS: | |
03e7b9c4 | 2924 | Handle_GetStatistics(msg.drv, (struct rf_info *)msg.body.data); |
c5c77ba1 JK |
2925 | break; |
2926 | ||
2927 | case HOST_IF_MSG_GET_CHNL: | |
2482a79f | 2928 | Handle_GetChnl(msg.drv); |
c5c77ba1 JK |
2929 | break; |
2930 | ||
c5c77ba1 | 2931 | case HOST_IF_MSG_ADD_BEACON: |
2482a79f | 2932 | Handle_AddBeacon(msg.drv, &msg.body.beacon_info); |
c5c77ba1 JK |
2933 | break; |
2934 | ||
2935 | case HOST_IF_MSG_DEL_BEACON: | |
2482a79f | 2936 | Handle_DelBeacon(msg.drv); |
c5c77ba1 JK |
2937 | break; |
2938 | ||
2939 | case HOST_IF_MSG_ADD_STATION: | |
2482a79f | 2940 | Handle_AddStation(msg.drv, &msg.body.add_sta_info); |
c5c77ba1 JK |
2941 | break; |
2942 | ||
2943 | case HOST_IF_MSG_DEL_STATION: | |
2482a79f | 2944 | Handle_DelStation(msg.drv, &msg.body.del_sta_info); |
c5c77ba1 JK |
2945 | break; |
2946 | ||
2947 | case HOST_IF_MSG_EDIT_STATION: | |
2482a79f | 2948 | Handle_EditStation(msg.drv, &msg.body.edit_sta_info); |
c5c77ba1 JK |
2949 | break; |
2950 | ||
2951 | case HOST_IF_MSG_GET_INACTIVETIME: | |
2482a79f | 2952 | Handle_Get_InActiveTime(msg.drv, &msg.body.mac_info); |
c5c77ba1 JK |
2953 | break; |
2954 | ||
c5c77ba1 JK |
2955 | case HOST_IF_MSG_SCAN_TIMER_FIRED: |
2956 | PRINT_D(HOSTINF_DBG, "Scan Timeout\n"); | |
2957 | ||
2482a79f | 2958 | Handle_ScanDone(msg.drv, SCAN_EVENT_ABORTED); |
c5c77ba1 JK |
2959 | break; |
2960 | ||
2961 | case HOST_IF_MSG_CONNECT_TIMER_FIRED: | |
03b2d5e7 | 2962 | PRINT_D(HOSTINF_DBG, "Connect Timeout\n"); |
2482a79f | 2963 | Handle_ConnectTimeout(msg.drv); |
c5c77ba1 JK |
2964 | break; |
2965 | ||
2966 | case HOST_IF_MSG_POWER_MGMT: | |
2482a79f | 2967 | Handle_PowerManagement(msg.drv, &msg.body.pwr_mgmt_info); |
c5c77ba1 JK |
2968 | break; |
2969 | ||
2970 | case HOST_IF_MSG_SET_WFIDRV_HANDLER: | |
23f2badd | 2971 | handle_set_wfi_drv_handler(msg.drv, &msg.body.drv); |
c5c77ba1 JK |
2972 | break; |
2973 | ||
2974 | case HOST_IF_MSG_SET_OPERATION_MODE: | |
97b5c591 | 2975 | handle_set_operation_mode(msg.drv, &msg.body.mode); |
c5c77ba1 JK |
2976 | break; |
2977 | ||
2978 | case HOST_IF_MSG_SET_IPADDRESS: | |
2979 | PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); | |
a6e6d48b LK |
2980 | handle_set_ip_address(msg.drv, |
2981 | msg.body.ip_info.ip_addr, | |
2982 | msg.body.ip_info.idx); | |
c5c77ba1 JK |
2983 | break; |
2984 | ||
2985 | case HOST_IF_MSG_GET_IPADDRESS: | |
2986 | PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n"); | |
d4516952 | 2987 | handle_get_ip_address(msg.drv, msg.body.ip_info.idx); |
c5c77ba1 JK |
2988 | break; |
2989 | ||
c5c77ba1 | 2990 | case HOST_IF_MSG_SET_MAC_ADDRESS: |
a8267421 LK |
2991 | handle_set_mac_address(msg.drv, |
2992 | &msg.body.set_mac_info); | |
c5c77ba1 JK |
2993 | break; |
2994 | ||
c5c77ba1 | 2995 | case HOST_IF_MSG_GET_MAC_ADDRESS: |
b3bf8fd9 LK |
2996 | handle_get_mac_address(msg.drv, |
2997 | &msg.body.get_mac_info); | |
c5c77ba1 JK |
2998 | break; |
2999 | ||
c5c77ba1 JK |
3000 | case HOST_IF_MSG_REMAIN_ON_CHAN: |
3001 | PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n"); | |
2482a79f | 3002 | Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch); |
c5c77ba1 JK |
3003 | break; |
3004 | ||
3005 | case HOST_IF_MSG_REGISTER_FRAME: | |
3006 | PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n"); | |
2482a79f | 3007 | Handle_RegisterFrame(msg.drv, &msg.body.reg_frame); |
c5c77ba1 JK |
3008 | break; |
3009 | ||
3010 | case HOST_IF_MSG_LISTEN_TIMER_FIRED: | |
2482a79f | 3011 | Handle_ListenStateExpired(msg.drv, &msg.body.remain_on_ch); |
c5c77ba1 JK |
3012 | break; |
3013 | ||
c5c77ba1 JK |
3014 | case HOST_IF_MSG_SET_MULTICAST_FILTER: |
3015 | PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n"); | |
2482a79f | 3016 | Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info); |
c5c77ba1 JK |
3017 | break; |
3018 | ||
c5c77ba1 | 3019 | case HOST_IF_MSG_ADD_BA_SESSION: |
2482a79f | 3020 | Handle_AddBASession(msg.drv, &msg.body.session_info); |
c5c77ba1 JK |
3021 | break; |
3022 | ||
3023 | case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS: | |
2482a79f | 3024 | Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info); |
c5c77ba1 JK |
3025 | break; |
3026 | ||
3027 | case HOST_IF_MSG_DEL_ALL_STA: | |
2482a79f | 3028 | Handle_DelAllSta(msg.drv, &msg.body.del_all_sta_info); |
c5c77ba1 JK |
3029 | break; |
3030 | ||
3031 | default: | |
03b2d5e7 | 3032 | PRINT_ER("[Host Interface] undefined Received Msg ID\n"); |
c5c77ba1 JK |
3033 | break; |
3034 | } | |
3035 | } | |
3036 | ||
3037 | PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n"); | |
834e0cb0 | 3038 | up(&hif_sema_thread); |
1999bd52 | 3039 | return 0; |
c5c77ba1 JK |
3040 | } |
3041 | ||
93dee8ee | 3042 | static void TimerCB_Scan(unsigned long arg) |
c5c77ba1 | 3043 | { |
93dee8ee | 3044 | void *pvArg = (void *)arg; |
143eb95a | 3045 | struct host_if_msg msg; |
c5c77ba1 | 3046 | |
143eb95a | 3047 | memset(&msg, 0, sizeof(struct host_if_msg)); |
2482a79f | 3048 | msg.drv = pvArg; |
a9f812a6 | 3049 | msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED; |
c5c77ba1 | 3050 | |
cb067dcf | 3051 | wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
3052 | } |
3053 | ||
93dee8ee | 3054 | static void TimerCB_Connect(unsigned long arg) |
c5c77ba1 | 3055 | { |
93dee8ee | 3056 | void *pvArg = (void *)arg; |
143eb95a | 3057 | struct host_if_msg msg; |
c5c77ba1 | 3058 | |
143eb95a | 3059 | memset(&msg, 0, sizeof(struct host_if_msg)); |
2482a79f | 3060 | msg.drv = pvArg; |
a9f812a6 | 3061 | msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED; |
c5c77ba1 | 3062 | |
cb067dcf | 3063 | wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
3064 | } |
3065 | ||
a4ab1ade | 3066 | s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress) |
c5c77ba1 | 3067 | { |
45102f83 | 3068 | struct wid wid; |
c5c77ba1 | 3069 | |
45102f83 LK |
3070 | wid.id = (u16)WID_REMOVE_KEY; |
3071 | wid.type = WID_STR; | |
3072 | wid.val = (s8 *)pu8StaAddress; | |
3073 | wid.size = 6; | |
c5c77ba1 | 3074 | |
b68d820b | 3075 | return 0; |
c5c77ba1 JK |
3076 | } |
3077 | ||
a4ab1ade | 3078 | int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index) |
c5c77ba1 | 3079 | { |
9e5e8b44 | 3080 | int result = 0; |
143eb95a | 3081 | struct host_if_msg msg; |
c5c77ba1 | 3082 | |
a4ab1ade | 3083 | if (!hif_drv) { |
9e5e8b44 | 3084 | result = -EFAULT; |
24db713f | 3085 | PRINT_ER("Failed to send setup multicast config packet\n"); |
9e5e8b44 | 3086 | return result; |
24db713f | 3087 | } |
c5c77ba1 | 3088 | |
143eb95a | 3089 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3090 | |
a9f812a6 | 3091 | msg.id = HOST_IF_MSG_KEY; |
8e9f427a | 3092 | msg.body.key_info.type = WEP; |
0d17e382 | 3093 | msg.body.key_info.action = REMOVEKEY; |
a4ab1ade | 3094 | msg.drv = hif_drv; |
73b2e381 | 3095 | msg.body.key_info.attr.wep.index = index; |
c5c77ba1 | 3096 | |
cb067dcf | 3097 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
9e5e8b44 | 3098 | if (result) |
03b2d5e7 | 3099 | PRINT_ER("Error in sending message queue : Request to remove WEP key\n"); |
9ea47133 | 3100 | down(&hif_drv->sem_test_key_block); |
c5c77ba1 | 3101 | |
9e5e8b44 | 3102 | return result; |
c5c77ba1 JK |
3103 | } |
3104 | ||
df8b4830 | 3105 | int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index) |
c5c77ba1 | 3106 | { |
5b41c7c9 | 3107 | int result = 0; |
143eb95a | 3108 | struct host_if_msg msg; |
c5c77ba1 | 3109 | |
a4ab1ade | 3110 | if (!hif_drv) { |
31390eec | 3111 | result = -EFAULT; |
24db713f | 3112 | PRINT_ER("driver is null\n"); |
31390eec | 3113 | return result; |
24db713f | 3114 | } |
c5c77ba1 | 3115 | |
143eb95a | 3116 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3117 | |
a9f812a6 | 3118 | msg.id = HOST_IF_MSG_KEY; |
8e9f427a | 3119 | msg.body.key_info.type = WEP; |
0d17e382 | 3120 | msg.body.key_info.action = DEFAULTKEY; |
a4ab1ade | 3121 | msg.drv = hif_drv; |
e91d0349 | 3122 | msg.body.key_info.attr.wep.index = index; |
c5c77ba1 | 3123 | |
31390eec LK |
3124 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3125 | if (result) | |
c5c77ba1 | 3126 | PRINT_ER("Error in sending message queue : Default key index\n"); |
9ea47133 | 3127 | down(&hif_drv->sem_test_key_block); |
c5c77ba1 | 3128 | |
31390eec | 3129 | return result; |
c5c77ba1 JK |
3130 | } |
3131 | ||
66b8cb89 | 3132 | int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv, |
fba778b1 | 3133 | const u8 *key, |
dbc53194 | 3134 | u8 len, |
0b2cc3e5 | 3135 | u8 index) |
c5c77ba1 | 3136 | { |
66b8cb89 | 3137 | int result = 0; |
143eb95a | 3138 | struct host_if_msg msg; |
c5c77ba1 | 3139 | |
a4ab1ade | 3140 | if (!hif_drv) { |
24db713f | 3141 | PRINT_ER("driver is null\n"); |
77178807 | 3142 | return -EFAULT; |
24db713f | 3143 | } |
c5c77ba1 | 3144 | |
143eb95a | 3145 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3146 | |
a9f812a6 | 3147 | msg.id = HOST_IF_MSG_KEY; |
8e9f427a | 3148 | msg.body.key_info.type = WEP; |
0d17e382 | 3149 | msg.body.key_info.action = ADDKEY; |
a4ab1ade | 3150 | msg.drv = hif_drv; |
1cc0c328 CL |
3151 | msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL); |
3152 | if (!msg.body.key_info.attr.wep.key) | |
3153 | return -ENOMEM; | |
3154 | ||
dbc53194 | 3155 | msg.body.key_info.attr.wep.key_len = len; |
0b2cc3e5 | 3156 | msg.body.key_info.attr.wep.index = index; |
c5c77ba1 | 3157 | |
31390eec LK |
3158 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3159 | if (result) | |
c5c77ba1 | 3160 | PRINT_ER("Error in sending message queue :WEP Key\n"); |
9ea47133 | 3161 | down(&hif_drv->sem_test_key_block); |
c5c77ba1 | 3162 | |
31390eec | 3163 | return result; |
c5c77ba1 JK |
3164 | } |
3165 | ||
641c20a6 | 3166 | int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv, |
8111725a | 3167 | const u8 *key, |
a5389b07 | 3168 | u8 len, |
a76dc953 | 3169 | u8 index, |
730a28da | 3170 | u8 mode, |
ff3bce2f | 3171 | enum AUTHTYPE auth_type) |
c5c77ba1 | 3172 | { |
641c20a6 | 3173 | int result = 0; |
143eb95a | 3174 | struct host_if_msg msg; |
fd741461 | 3175 | int i; |
c5c77ba1 | 3176 | |
a4ab1ade | 3177 | if (!hif_drv) { |
24db713f | 3178 | PRINT_ER("driver is null\n"); |
77178807 | 3179 | return -EFAULT; |
24db713f | 3180 | } |
c5c77ba1 | 3181 | |
143eb95a | 3182 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
3183 | |
3184 | if (INFO) { | |
a5389b07 | 3185 | for (i = 0; i < len; i++) |
8111725a | 3186 | PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", key[i]); |
c5c77ba1 | 3187 | } |
a9f812a6 | 3188 | msg.id = HOST_IF_MSG_KEY; |
8e9f427a | 3189 | msg.body.key_info.type = WEP; |
0d17e382 | 3190 | msg.body.key_info.action = ADDKEY_AP; |
a4ab1ade | 3191 | msg.drv = hif_drv; |
58eabd68 CL |
3192 | msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL); |
3193 | if (!msg.body.key_info.attr.wep.key) | |
3194 | return -ENOMEM; | |
3195 | ||
a5389b07 | 3196 | msg.body.key_info.attr.wep.key_len = len; |
a76dc953 | 3197 | msg.body.key_info.attr.wep.index = index; |
730a28da | 3198 | msg.body.key_info.attr.wep.mode = mode; |
ff3bce2f | 3199 | msg.body.key_info.attr.wep.auth_type = auth_type; |
ae4dfa57 | 3200 | |
31390eec | 3201 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
c5c77ba1 | 3202 | |
31390eec | 3203 | if (result) |
c5c77ba1 | 3204 | PRINT_ER("Error in sending message queue :WEP Key\n"); |
9ea47133 | 3205 | down(&hif_drv->sem_test_key_block); |
c5c77ba1 | 3206 | |
31390eec | 3207 | return result; |
c5c77ba1 | 3208 | } |
108b3439 | 3209 | |
a4ab1ade TC |
3210 | s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk, |
3211 | u8 u8PtkKeylen, const u8 *mac_addr, | |
3212 | const u8 *pu8RxMic, const u8 *pu8TxMic, | |
3213 | u8 mode, u8 u8Ciphermode, u8 u8Idx) | |
c5c77ba1 | 3214 | { |
31390eec | 3215 | s32 result = 0; |
143eb95a | 3216 | struct host_if_msg msg; |
63d03e47 | 3217 | u8 u8KeyLen = u8PtkKeylen; |
4e4467fd | 3218 | u32 i; |
78c87591 | 3219 | |
a4ab1ade | 3220 | if (!hif_drv) { |
24db713f | 3221 | PRINT_ER("driver is null\n"); |
77178807 | 3222 | return -EFAULT; |
24db713f | 3223 | } |
91109e11 LK |
3224 | |
3225 | if (pu8RxMic) | |
c5c77ba1 | 3226 | u8KeyLen += RX_MIC_KEY_LEN; |
91109e11 LK |
3227 | |
3228 | if (pu8TxMic) | |
c5c77ba1 | 3229 | u8KeyLen += TX_MIC_KEY_LEN; |
c5c77ba1 | 3230 | |
143eb95a | 3231 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3232 | |
a9f812a6 | 3233 | msg.id = HOST_IF_MSG_KEY; |
2141fe39 | 3234 | msg.body.key_info.type = WPA_PTK; |
c5c77ba1 | 3235 | if (mode == AP_MODE) { |
0d17e382 | 3236 | msg.body.key_info.action = ADDKEY_AP; |
e2dfbac5 | 3237 | msg.body.key_info.attr.wpa.index = u8Idx; |
c5c77ba1 | 3238 | } |
c5c77ba1 | 3239 | if (mode == STATION_MODE) |
0d17e382 | 3240 | msg.body.key_info.action = ADDKEY; |
c5c77ba1 | 3241 | |
124968fc LK |
3242 | msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL); |
3243 | memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen); | |
c5c77ba1 | 3244 | |
91109e11 | 3245 | if (pu8RxMic) { |
124968fc | 3246 | memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN); |
c5c77ba1 JK |
3247 | if (INFO) { |
3248 | for (i = 0; i < RX_MIC_KEY_LEN; i++) | |
3249 | PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]); | |
3250 | } | |
3251 | } | |
91109e11 | 3252 | if (pu8TxMic) { |
124968fc | 3253 | memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN); |
c5c77ba1 JK |
3254 | if (INFO) { |
3255 | for (i = 0; i < TX_MIC_KEY_LEN; i++) | |
3256 | PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]); | |
3257 | } | |
3258 | } | |
3259 | ||
6acf2919 | 3260 | msg.body.key_info.attr.wpa.key_len = u8KeyLen; |
248080aa | 3261 | msg.body.key_info.attr.wpa.mac_addr = mac_addr; |
7b2ebb28 | 3262 | msg.body.key_info.attr.wpa.mode = u8Ciphermode; |
a4ab1ade | 3263 | msg.drv = hif_drv; |
c5c77ba1 | 3264 | |
31390eec | 3265 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
c5c77ba1 | 3266 | |
31390eec | 3267 | if (result) |
c5c77ba1 JK |
3268 | PRINT_ER("Error in sending message queue: PTK Key\n"); |
3269 | ||
9ea47133 | 3270 | down(&hif_drv->sem_test_key_block); |
c5c77ba1 | 3271 | |
31390eec | 3272 | return result; |
c5c77ba1 JK |
3273 | } |
3274 | ||
a4ab1ade TC |
3275 | s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk, |
3276 | u8 u8GtkKeylen, u8 u8KeyIdx, | |
3277 | u32 u32KeyRSClen, const u8 *KeyRSC, | |
3278 | const u8 *pu8RxMic, const u8 *pu8TxMic, | |
3279 | u8 mode, u8 u8Ciphermode) | |
c5c77ba1 | 3280 | { |
31390eec | 3281 | s32 result = 0; |
143eb95a | 3282 | struct host_if_msg msg; |
63d03e47 | 3283 | u8 u8KeyLen = u8GtkKeylen; |
c5c77ba1 | 3284 | |
a4ab1ade | 3285 | if (!hif_drv) { |
24db713f | 3286 | PRINT_ER("driver is null\n"); |
77178807 | 3287 | return -EFAULT; |
24db713f | 3288 | } |
143eb95a | 3289 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3290 | |
91109e11 | 3291 | if (pu8RxMic) |
c5c77ba1 | 3292 | u8KeyLen += RX_MIC_KEY_LEN; |
91109e11 LK |
3293 | |
3294 | if (pu8TxMic) | |
c5c77ba1 | 3295 | u8KeyLen += TX_MIC_KEY_LEN; |
91109e11 LK |
3296 | |
3297 | if (KeyRSC) { | |
0e74c009 LK |
3298 | msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL); |
3299 | memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen); | |
c5c77ba1 JK |
3300 | } |
3301 | ||
a9f812a6 | 3302 | msg.id = HOST_IF_MSG_KEY; |
5cd8f7ae | 3303 | msg.body.key_info.type = WPA_RX_GTK; |
a4ab1ade | 3304 | msg.drv = hif_drv; |
c5c77ba1 | 3305 | |
c5c77ba1 | 3306 | if (mode == AP_MODE) { |
0d17e382 | 3307 | msg.body.key_info.action = ADDKEY_AP; |
7b2ebb28 | 3308 | msg.body.key_info.attr.wpa.mode = u8Ciphermode; |
c5c77ba1 | 3309 | } |
c5c77ba1 | 3310 | if (mode == STATION_MODE) |
0d17e382 | 3311 | msg.body.key_info.action = ADDKEY; |
c5c77ba1 | 3312 | |
124968fc LK |
3313 | msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL); |
3314 | memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen); | |
c5c77ba1 | 3315 | |
d1666e2a LK |
3316 | if (pu8RxMic) |
3317 | memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, | |
3318 | RX_MIC_KEY_LEN); | |
91109e11 | 3319 | |
d1666e2a LK |
3320 | if (pu8TxMic) |
3321 | memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, | |
3322 | TX_MIC_KEY_LEN); | |
c5c77ba1 | 3323 | |
e2dfbac5 | 3324 | msg.body.key_info.attr.wpa.index = u8KeyIdx; |
6acf2919 | 3325 | msg.body.key_info.attr.wpa.key_len = u8KeyLen; |
dacc594d | 3326 | msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen; |
c5c77ba1 | 3327 | |
31390eec LK |
3328 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3329 | if (result) | |
c5c77ba1 | 3330 | PRINT_ER("Error in sending message queue: RX GTK\n"); |
ae4dfa57 | 3331 | |
9ea47133 | 3332 | down(&hif_drv->sem_test_key_block); |
c5c77ba1 | 3333 | |
31390eec | 3334 | return result; |
c5c77ba1 | 3335 | } |
c5c77ba1 | 3336 | |
a4ab1ade | 3337 | s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray) |
c5c77ba1 | 3338 | { |
31390eec | 3339 | s32 result = 0; |
143eb95a | 3340 | struct host_if_msg msg; |
4e4467fd | 3341 | u32 i; |
c5c77ba1 | 3342 | |
a4ab1ade | 3343 | if (!hif_drv) { |
24db713f | 3344 | PRINT_ER("driver is null\n"); |
77178807 | 3345 | return -EFAULT; |
24db713f | 3346 | } |
c5c77ba1 | 3347 | |
143eb95a | 3348 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3349 | |
a9f812a6 | 3350 | msg.id = HOST_IF_MSG_KEY; |
8e9f427a | 3351 | msg.body.key_info.type = PMKSA; |
0d17e382 | 3352 | msg.body.key_info.action = ADDKEY; |
a4ab1ade | 3353 | msg.drv = hif_drv; |
c5c77ba1 JK |
3354 | |
3355 | for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) { | |
8c8360b3 LK |
3356 | memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid, |
3357 | &pu8PmkidInfoArray->pmkidlist[i].bssid, ETH_ALEN); | |
3358 | memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid, | |
3359 | &pu8PmkidInfoArray->pmkidlist[i].pmkid, PMKID_LEN); | |
c5c77ba1 JK |
3360 | } |
3361 | ||
31390eec LK |
3362 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3363 | if (result) | |
c5c77ba1 JK |
3364 | PRINT_ER(" Error in sending messagequeue: PMKID Info\n"); |
3365 | ||
31390eec | 3366 | return result; |
c5c77ba1 JK |
3367 | } |
3368 | ||
a4ab1ade TC |
3369 | s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv, |
3370 | u8 *pu8PmkidInfoArray, | |
3371 | u32 u32PmkidInfoLen) | |
c5c77ba1 | 3372 | { |
45102f83 | 3373 | struct wid wid; |
c5c77ba1 | 3374 | |
45102f83 LK |
3375 | wid.id = (u16)WID_PMKID_INFO; |
3376 | wid.type = WID_STR; | |
3377 | wid.size = u32PmkidInfoLen; | |
3378 | wid.val = pu8PmkidInfoArray; | |
c5c77ba1 | 3379 | |
b68d820b | 3380 | return 0; |
c5c77ba1 JK |
3381 | } |
3382 | ||
a4ab1ade TC |
3383 | s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv, |
3384 | u8 *pu8PassPhrase, | |
3385 | u8 u8Psklength) | |
c5c77ba1 | 3386 | { |
45102f83 | 3387 | struct wid wid; |
c5c77ba1 | 3388 | |
c5c77ba1 | 3389 | if ((u8Psklength > 7) && (u8Psklength < 65)) { |
45102f83 LK |
3390 | wid.id = (u16)WID_11I_PSK; |
3391 | wid.type = WID_STR; | |
3392 | wid.val = pu8PassPhrase; | |
3393 | wid.size = u8Psklength; | |
c5c77ba1 JK |
3394 | } |
3395 | ||
b68d820b | 3396 | return 0; |
c5c77ba1 | 3397 | } |
ae4dfa57 | 3398 | |
e5f35244 | 3399 | s32 hif_get_mac_address(struct host_if_drv *hif_drv, u8 *pu8MacAddress) |
c5c77ba1 | 3400 | { |
31390eec | 3401 | s32 result = 0; |
143eb95a | 3402 | struct host_if_msg msg; |
c5c77ba1 | 3403 | |
143eb95a | 3404 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3405 | |
a9f812a6 | 3406 | msg.id = HOST_IF_MSG_GET_MAC_ADDRESS; |
6ceba0af | 3407 | msg.body.get_mac_info.mac_addr = pu8MacAddress; |
a4ab1ade | 3408 | msg.drv = hif_drv; |
ae4dfa57 | 3409 | |
31390eec LK |
3410 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3411 | if (result) { | |
c5c77ba1 | 3412 | PRINT_ER("Failed to send get mac address\n"); |
e6e12661 | 3413 | return -EFAULT; |
c5c77ba1 JK |
3414 | } |
3415 | ||
2d25af87 | 3416 | down(&hif_sema_wait_response); |
31390eec | 3417 | return result; |
c5c77ba1 JK |
3418 | } |
3419 | ||
a4ab1ade | 3420 | s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress) |
c5c77ba1 | 3421 | { |
31390eec | 3422 | s32 result = 0; |
143eb95a | 3423 | struct host_if_msg msg; |
c5c77ba1 JK |
3424 | |
3425 | PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]); | |
3426 | ||
143eb95a | 3427 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3428 | msg.id = HOST_IF_MSG_SET_MAC_ADDRESS; |
ae5e4522 | 3429 | memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN); |
a4ab1ade | 3430 | msg.drv = hif_drv; |
c5c77ba1 | 3431 | |
31390eec LK |
3432 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3433 | if (result) | |
c5c77ba1 | 3434 | PRINT_ER("Failed to send message queue: Set mac address\n"); |
c5c77ba1 | 3435 | |
31390eec | 3436 | return result; |
c5c77ba1 JK |
3437 | } |
3438 | ||
a4ab1ade TC |
3439 | s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv, |
3440 | u8 *pu8PassPhrase, u8 u8Psklength) | |
c5c77ba1 | 3441 | { |
45102f83 | 3442 | struct wid wid; |
c5c77ba1 | 3443 | |
45102f83 LK |
3444 | wid.id = (u16)WID_11I_PSK; |
3445 | wid.type = WID_STR; | |
3446 | wid.size = u8Psklength; | |
3447 | wid.val = pu8PassPhrase; | |
c5c77ba1 | 3448 | |
b68d820b | 3449 | return 0; |
c5c77ba1 JK |
3450 | } |
3451 | ||
a4ab1ade | 3452 | s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource) |
c5c77ba1 | 3453 | { |
45102f83 | 3454 | struct wid wid; |
c5c77ba1 | 3455 | |
45102f83 LK |
3456 | wid.id = (u16)WID_START_SCAN_REQ; |
3457 | wid.type = WID_CHAR; | |
3458 | wid.val = (s8 *)&scanSource; | |
3459 | wid.size = sizeof(char); | |
c5c77ba1 | 3460 | |
b68d820b | 3461 | return 0; |
c5c77ba1 JK |
3462 | } |
3463 | ||
a4ab1ade | 3464 | s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource) |
c5c77ba1 | 3465 | { |
45102f83 | 3466 | struct wid wid; |
c5c77ba1 | 3467 | |
45102f83 LK |
3468 | wid.id = (u16)WID_START_SCAN_REQ; |
3469 | wid.type = WID_CHAR; | |
3470 | wid.val = (s8 *)pu8ScanSource; | |
3471 | wid.size = sizeof(char); | |
c5c77ba1 | 3472 | |
b68d820b | 3473 | return 0; |
c5c77ba1 JK |
3474 | } |
3475 | ||
a4ab1ade TC |
3476 | s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid, |
3477 | const u8 *pu8ssid, size_t ssidLen, | |
3478 | const u8 *pu8IEs, size_t IEsLen, | |
3479 | wilc_connect_result pfConnectResult, void *pvUserArg, | |
3480 | u8 u8security, enum AUTHTYPE tenuAuth_type, | |
3481 | u8 u8channel, void *pJoinParams) | |
c5c77ba1 | 3482 | { |
31390eec | 3483 | s32 result = 0; |
143eb95a | 3484 | struct host_if_msg msg; |
c5c77ba1 | 3485 | |
91109e11 | 3486 | if (!hif_drv || !pfConnectResult) { |
24db713f | 3487 | PRINT_ER("Driver is null\n"); |
77178807 | 3488 | return -EFAULT; |
24db713f | 3489 | } |
c5c77ba1 | 3490 | |
91109e11 | 3491 | if (!pJoinParams) { |
c5c77ba1 | 3492 | PRINT_ER("Unable to Join - JoinParams is NULL\n"); |
24db713f | 3493 | return -EFAULT; |
c5c77ba1 | 3494 | } |
24db713f | 3495 | |
143eb95a | 3496 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3497 | |
a9f812a6 | 3498 | msg.id = HOST_IF_MSG_CONNECT; |
c5c77ba1 | 3499 | |
a64fd677 | 3500 | msg.body.con_info.security = u8security; |
61b4fd02 | 3501 | msg.body.con_info.auth_type = tenuAuth_type; |
0d1527e6 | 3502 | msg.body.con_info.ch = u8channel; |
6abcc11d | 3503 | msg.body.con_info.result = pfConnectResult; |
8f38db89 | 3504 | msg.body.con_info.arg = pvUserArg; |
f2bed2ca | 3505 | msg.body.con_info.params = pJoinParams; |
a4ab1ade | 3506 | msg.drv = hif_drv ; |
c5c77ba1 | 3507 | |
91109e11 | 3508 | if (pu8bssid) { |
9254db07 LK |
3509 | msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL); |
3510 | memcpy(msg.body.con_info.bssid, pu8bssid, 6); | |
c5c77ba1 JK |
3511 | } |
3512 | ||
91109e11 | 3513 | if (pu8ssid) { |
8b3c9fa6 | 3514 | msg.body.con_info.ssid_len = ssidLen; |
f7bbd9cf LK |
3515 | msg.body.con_info.ssid = kmalloc(ssidLen, GFP_KERNEL); |
3516 | memcpy(msg.body.con_info.ssid, pu8ssid, ssidLen); | |
c5c77ba1 JK |
3517 | } |
3518 | ||
91109e11 | 3519 | if (pu8IEs) { |
b59d5c5b | 3520 | msg.body.con_info.ies_len = IEsLen; |
2ea158c4 LK |
3521 | msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL); |
3522 | memcpy(msg.body.con_info.ies, pu8IEs, IEsLen); | |
c5c77ba1 | 3523 | } |
b60005a8 LK |
3524 | if (hif_drv->hif_state < HOST_IF_CONNECTING) |
3525 | hif_drv->hif_state = HOST_IF_CONNECTING; | |
78174ada | 3526 | else |
b60005a8 LK |
3527 | PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' : %d\n", |
3528 | hif_drv->hif_state); | |
c5c77ba1 | 3529 | |
31390eec LK |
3530 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3531 | if (result) { | |
c5c77ba1 | 3532 | PRINT_ER("Failed to send message queue: Set join request\n"); |
24db713f | 3533 | return -EFAULT; |
c5c77ba1 JK |
3534 | } |
3535 | ||
81a59506 LK |
3536 | hif_drv->connect_timer.data = (unsigned long)hif_drv; |
3537 | mod_timer(&hif_drv->connect_timer, | |
9eb06643 | 3538 | jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT)); |
c5c77ba1 | 3539 | |
31390eec | 3540 | return result; |
c5c77ba1 JK |
3541 | } |
3542 | ||
a4ab1ade | 3543 | s32 host_int_flush_join_req(struct host_if_drv *hif_drv) |
c5c77ba1 | 3544 | { |
31390eec | 3545 | s32 result = 0; |
143eb95a | 3546 | struct host_if_msg msg; |
c5c77ba1 | 3547 | |
77178807 LK |
3548 | if (!join_req) |
3549 | return -EFAULT; | |
c5c77ba1 | 3550 | |
a4ab1ade | 3551 | if (!hif_drv) { |
24db713f | 3552 | PRINT_ER("Driver is null\n"); |
77178807 | 3553 | return -EFAULT; |
24db713f | 3554 | } |
c5c77ba1 | 3555 | |
a9f812a6 | 3556 | msg.id = HOST_IF_MSG_FLUSH_CONNECT; |
a4ab1ade | 3557 | msg.drv = hif_drv; |
c5c77ba1 | 3558 | |
31390eec LK |
3559 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3560 | if (result) { | |
c5c77ba1 | 3561 | PRINT_ER("Failed to send message queue: Flush join request\n"); |
24db713f | 3562 | return -EFAULT; |
c5c77ba1 JK |
3563 | } |
3564 | ||
31390eec | 3565 | return result; |
c5c77ba1 JK |
3566 | } |
3567 | ||
a4ab1ade | 3568 | s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode) |
c5c77ba1 | 3569 | { |
31390eec | 3570 | s32 result = 0; |
143eb95a | 3571 | struct host_if_msg msg; |
c5c77ba1 | 3572 | |
a4ab1ade | 3573 | if (!hif_drv) { |
24db713f LK |
3574 | PRINT_ER("Driver is null\n"); |
3575 | return -EFAULT; | |
c5c77ba1 JK |
3576 | } |
3577 | ||
143eb95a | 3578 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3579 | |
a9f812a6 | 3580 | msg.id = HOST_IF_MSG_DISCONNECT; |
a4ab1ade | 3581 | msg.drv = hif_drv; |
c5c77ba1 | 3582 | |
31390eec LK |
3583 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3584 | if (result) | |
c5c77ba1 | 3585 | PRINT_ER("Failed to send message queue: disconnect\n"); |
ae4dfa57 | 3586 | |
e55e4967 | 3587 | down(&hif_drv->sem_test_disconn_block); |
c5c77ba1 | 3588 | |
31390eec | 3589 | return result; |
c5c77ba1 JK |
3590 | } |
3591 | ||
a4ab1ade | 3592 | s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id) |
c5c77ba1 | 3593 | { |
45102f83 | 3594 | struct wid wid; |
c5c77ba1 | 3595 | |
45102f83 LK |
3596 | wid.id = (u16)WID_DISCONNECT; |
3597 | wid.type = WID_CHAR; | |
3598 | wid.val = (s8 *)&assoc_id; | |
3599 | wid.size = sizeof(char); | |
c5c77ba1 | 3600 | |
b68d820b | 3601 | return 0; |
c5c77ba1 JK |
3602 | } |
3603 | ||
8c8360b3 LK |
3604 | s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv, |
3605 | u8 *pu8AssocReqInfo, | |
3606 | u32 u32AssocReqInfoLen) | |
c5c77ba1 | 3607 | { |
45102f83 | 3608 | struct wid wid; |
c5c77ba1 | 3609 | |
45102f83 LK |
3610 | wid.id = (u16)WID_ASSOC_REQ_INFO; |
3611 | wid.type = WID_STR; | |
3612 | wid.val = pu8AssocReqInfo; | |
3613 | wid.size = u32AssocReqInfoLen; | |
c5c77ba1 | 3614 | |
b68d820b | 3615 | return 0; |
c5c77ba1 JK |
3616 | } |
3617 | ||
8c8360b3 LK |
3618 | s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv, |
3619 | u8 *pu8AssocRespInfo, | |
3620 | u32 u32MaxAssocRespInfoLen, | |
3621 | u32 *pu32RcvdAssocRespInfoLen) | |
c5c77ba1 | 3622 | { |
31390eec | 3623 | s32 result = 0; |
45102f83 | 3624 | struct wid wid; |
c5c77ba1 | 3625 | |
a4ab1ade | 3626 | if (!hif_drv) { |
24db713f LK |
3627 | PRINT_ER("Driver is null\n"); |
3628 | return -EFAULT; | |
c5c77ba1 JK |
3629 | } |
3630 | ||
45102f83 LK |
3631 | wid.id = (u16)WID_ASSOC_RES_INFO; |
3632 | wid.type = WID_STR; | |
3633 | wid.val = pu8AssocRespInfo; | |
3634 | wid.size = u32MaxAssocRespInfoLen; | |
c5c77ba1 | 3635 | |
45102f83 | 3636 | result = send_config_pkt(GET_CFG, &wid, 1, |
8c8360b3 | 3637 | get_id_from_handler(hif_drv)); |
31390eec | 3638 | if (result) { |
c5c77ba1 | 3639 | *pu32RcvdAssocRespInfoLen = 0; |
24db713f LK |
3640 | PRINT_ER("Failed to send association response config packet\n"); |
3641 | return -EINVAL; | |
c5c77ba1 | 3642 | } else { |
45102f83 | 3643 | *pu32RcvdAssocRespInfoLen = wid.size; |
c5c77ba1 JK |
3644 | } |
3645 | ||
31390eec | 3646 | return result; |
c5c77ba1 JK |
3647 | } |
3648 | ||
8c8360b3 LK |
3649 | s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv, |
3650 | u8 *pu8RxPowerLevel, | |
3651 | u32 u32RxPowerLevelLen) | |
c5c77ba1 | 3652 | { |
45102f83 | 3653 | struct wid wid; |
c5c77ba1 | 3654 | |
45102f83 LK |
3655 | wid.id = (u16)WID_RX_POWER_LEVEL; |
3656 | wid.type = WID_STR; | |
3657 | wid.val = pu8RxPowerLevel; | |
3658 | wid.size = u32RxPowerLevelLen; | |
c5c77ba1 | 3659 | |
b68d820b | 3660 | return 0; |
c5c77ba1 JK |
3661 | } |
3662 | ||
a4ab1ade | 3663 | int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel) |
c5c77ba1 | 3664 | { |
792fb25b | 3665 | int result; |
143eb95a | 3666 | struct host_if_msg msg; |
c5c77ba1 | 3667 | |
a4ab1ade | 3668 | if (!hif_drv) { |
24db713f LK |
3669 | PRINT_ER("driver is null\n"); |
3670 | return -EFAULT; | |
3671 | } | |
c5c77ba1 | 3672 | |
143eb95a | 3673 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3674 | msg.id = HOST_IF_MSG_SET_CHANNEL; |
730ee059 | 3675 | msg.body.channel_info.set_ch = channel; |
a4ab1ade | 3676 | msg.drv = hif_drv; |
c5c77ba1 | 3677 | |
cb067dcf | 3678 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
1ef58e42 | 3679 | if (result) { |
24db713f | 3680 | PRINT_ER("wilc mq send fail\n"); |
792fb25b | 3681 | return -EINVAL; |
c5c77ba1 JK |
3682 | } |
3683 | ||
792fb25b | 3684 | return 0; |
c5c77ba1 JK |
3685 | } |
3686 | ||
244efb1f | 3687 | int host_int_wait_msg_queue_idle(void) |
c5c77ba1 | 3688 | { |
6d6c9bbb | 3689 | int result = 0; |
143eb95a | 3690 | struct host_if_msg msg; |
c09389ac | 3691 | |
143eb95a | 3692 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3693 | msg.id = HOST_IF_MSG_Q_IDLE; |
cb067dcf | 3694 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
6d6c9bbb | 3695 | if (result) { |
24db713f | 3696 | PRINT_ER("wilc mq send fail\n"); |
6d6c9bbb | 3697 | result = -EINVAL; |
c5c77ba1 JK |
3698 | } |
3699 | ||
2d25af87 | 3700 | down(&hif_sema_wait_response); |
c5c77ba1 | 3701 | |
6d6c9bbb | 3702 | return result; |
c5c77ba1 JK |
3703 | } |
3704 | ||
a4ab1ade | 3705 | int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv) |
c5c77ba1 | 3706 | { |
a094101c | 3707 | int result = 0; |
143eb95a | 3708 | struct host_if_msg msg; |
c09389ac | 3709 | |
143eb95a | 3710 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3711 | msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER; |
a7f3b12f | 3712 | msg.body.drv.handler = get_id_from_handler(hif_drv); |
a4ab1ade | 3713 | msg.drv = hif_drv; |
c5c77ba1 | 3714 | |
cb067dcf | 3715 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
a094101c | 3716 | if (result) { |
24db713f | 3717 | PRINT_ER("wilc mq send fail\n"); |
a094101c | 3718 | result = -EINVAL; |
c5c77ba1 JK |
3719 | } |
3720 | ||
a094101c | 3721 | return result; |
c5c77ba1 JK |
3722 | } |
3723 | ||
a4ab1ade | 3724 | int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode) |
c5c77ba1 | 3725 | { |
a0c1ee0c | 3726 | int result = 0; |
143eb95a | 3727 | struct host_if_msg msg; |
c09389ac | 3728 | |
143eb95a | 3729 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3730 | msg.id = HOST_IF_MSG_SET_OPERATION_MODE; |
c96debf1 | 3731 | msg.body.mode.mode = mode; |
a4ab1ade | 3732 | msg.drv = hif_drv; |
c5c77ba1 | 3733 | |
cb067dcf | 3734 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
a0c1ee0c | 3735 | if (result) { |
24db713f | 3736 | PRINT_ER("wilc mq send fail\n"); |
a0c1ee0c | 3737 | result = -EINVAL; |
c5c77ba1 JK |
3738 | } |
3739 | ||
a0c1ee0c | 3740 | return result; |
c5c77ba1 JK |
3741 | } |
3742 | ||
a4ab1ade | 3743 | s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo) |
c5c77ba1 | 3744 | { |
31390eec | 3745 | s32 result = 0; |
143eb95a | 3746 | struct host_if_msg msg; |
c5c77ba1 | 3747 | |
a4ab1ade | 3748 | if (!hif_drv) { |
24db713f LK |
3749 | PRINT_ER("driver is null\n"); |
3750 | return -EFAULT; | |
c5c77ba1 JK |
3751 | } |
3752 | ||
143eb95a | 3753 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3754 | |
a9f812a6 | 3755 | msg.id = HOST_IF_MSG_GET_CHNL; |
a4ab1ade | 3756 | msg.drv = hif_drv; |
c5c77ba1 | 3757 | |
31390eec LK |
3758 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3759 | if (result) | |
24db713f | 3760 | PRINT_ER("wilc mq send fail\n"); |
4ea90008 | 3761 | down(&hif_drv->sem_get_chnl); |
c5c77ba1 | 3762 | |
95ebb0ff | 3763 | *pu8ChNo = ch_no; |
c5c77ba1 | 3764 | |
31390eec | 3765 | return result; |
c5c77ba1 JK |
3766 | } |
3767 | ||
a4ab1ade TC |
3768 | s32 host_int_get_inactive_time(struct host_if_drv *hif_drv, |
3769 | const u8 *mac, u32 *pu32InactiveTime) | |
c5c77ba1 | 3770 | { |
31390eec | 3771 | s32 result = 0; |
143eb95a | 3772 | struct host_if_msg msg; |
c5c77ba1 | 3773 | |
a4ab1ade | 3774 | if (!hif_drv) { |
24db713f LK |
3775 | PRINT_ER("driver is null\n"); |
3776 | return -EFAULT; | |
c5c77ba1 JK |
3777 | } |
3778 | ||
143eb95a | 3779 | memset(&msg, 0, sizeof(struct host_if_msg)); |
8c8360b3 | 3780 | memcpy(msg.body.mac_info.mac, mac, ETH_ALEN); |
c5c77ba1 | 3781 | |
a9f812a6 | 3782 | msg.id = HOST_IF_MSG_GET_INACTIVETIME; |
a4ab1ade | 3783 | msg.drv = hif_drv; |
c5c77ba1 | 3784 | |
31390eec LK |
3785 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3786 | if (result) | |
c5c77ba1 JK |
3787 | PRINT_ER("Failed to send get host channel param's message queue "); |
3788 | ||
569a3c67 | 3789 | down(&hif_drv->sem_inactive_time); |
c5c77ba1 | 3790 | |
ad26906f | 3791 | *pu32InactiveTime = inactive_time; |
c5c77ba1 | 3792 | |
31390eec | 3793 | return result; |
c5c77ba1 | 3794 | } |
108b3439 | 3795 | |
a4ab1ade | 3796 | s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr) |
c5c77ba1 | 3797 | { |
31390eec | 3798 | s32 result = 0; |
45102f83 | 3799 | struct wid wid; |
c5c77ba1 | 3800 | |
a4ab1ade | 3801 | if (!hif_drv) { |
24db713f LK |
3802 | PRINT_ER("driver is null\n"); |
3803 | return -EFAULT; | |
c5c77ba1 JK |
3804 | } |
3805 | ||
45102f83 LK |
3806 | wid.id = (u16)WID_MEMORY_ADDRESS; |
3807 | wid.type = WID_INT; | |
3808 | wid.val = (s8 *)pu32TestMemAddr; | |
3809 | wid.size = sizeof(u32); | |
c5c77ba1 | 3810 | |
45102f83 | 3811 | result = send_config_pkt(GET_CFG, &wid, 1, |
8c8360b3 | 3812 | get_id_from_handler(hif_drv)); |
ae4dfa57 | 3813 | |
31390eec | 3814 | if (result) { |
24db713f LK |
3815 | PRINT_ER("Failed to get wid value\n"); |
3816 | return -EINVAL; | |
c5c77ba1 JK |
3817 | } else { |
3818 | PRINT_D(HOSTINF_DBG, "Successfully got wid value\n"); | |
c5c77ba1 JK |
3819 | } |
3820 | ||
31390eec | 3821 | return result; |
c5c77ba1 JK |
3822 | } |
3823 | ||
a4ab1ade | 3824 | s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi) |
c5c77ba1 | 3825 | { |
31390eec | 3826 | s32 result = 0; |
143eb95a | 3827 | struct host_if_msg msg; |
c5c77ba1 | 3828 | |
c09389ac | 3829 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3830 | msg.id = HOST_IF_MSG_GET_RSSI; |
a4ab1ade | 3831 | msg.drv = hif_drv; |
c5c77ba1 | 3832 | |
31390eec LK |
3833 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3834 | if (result) { | |
c5c77ba1 | 3835 | PRINT_ER("Failed to send get host channel param's message queue "); |
e6e12661 | 3836 | return -EFAULT; |
c5c77ba1 JK |
3837 | } |
3838 | ||
7e111f9e | 3839 | down(&hif_drv->sem_get_rssi); |
c5c77ba1 | 3840 | |
91109e11 | 3841 | if (!ps8Rssi) { |
c5c77ba1 | 3842 | PRINT_ER("RSS pointer value is null"); |
e6e12661 | 3843 | return -EFAULT; |
c5c77ba1 JK |
3844 | } |
3845 | ||
144b7b23 | 3846 | *ps8Rssi = rssi; |
c5c77ba1 | 3847 | |
31390eec | 3848 | return result; |
c5c77ba1 JK |
3849 | } |
3850 | ||
a4ab1ade | 3851 | s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd) |
c5c77ba1 | 3852 | { |
143eb95a | 3853 | struct host_if_msg msg; |
31390eec | 3854 | s32 result = 0; |
c5c77ba1 | 3855 | |
c09389ac | 3856 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3857 | msg.id = HOST_IF_MSG_GET_LINKSPEED; |
a4ab1ade | 3858 | msg.drv = hif_drv; |
c5c77ba1 | 3859 | |
31390eec LK |
3860 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3861 | if (result) { | |
c5c77ba1 | 3862 | PRINT_ER("Failed to send GET_LINKSPEED to message queue "); |
e6e12661 | 3863 | return -EFAULT; |
c5c77ba1 JK |
3864 | } |
3865 | ||
bc34da66 | 3866 | down(&hif_drv->sem_get_link_speed); |
c5c77ba1 | 3867 | |
91109e11 | 3868 | if (!ps8lnkspd) { |
c5c77ba1 | 3869 | PRINT_ER("LINKSPEED pointer value is null"); |
e6e12661 | 3870 | return -EFAULT; |
c5c77ba1 JK |
3871 | } |
3872 | ||
75327a02 | 3873 | *ps8lnkspd = link_speed; |
c5c77ba1 | 3874 | |
31390eec | 3875 | return result; |
c5c77ba1 JK |
3876 | } |
3877 | ||
a4ab1ade | 3878 | s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics) |
c5c77ba1 | 3879 | { |
31390eec | 3880 | s32 result = 0; |
143eb95a | 3881 | struct host_if_msg msg; |
c5c77ba1 | 3882 | |
c09389ac | 3883 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3884 | msg.id = HOST_IF_MSG_GET_STATISTICS; |
e60831e9 | 3885 | msg.body.data = (char *)pstrStatistics; |
a4ab1ade | 3886 | msg.drv = hif_drv; |
ae4dfa57 | 3887 | |
31390eec LK |
3888 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3889 | if (result) { | |
c5c77ba1 | 3890 | PRINT_ER("Failed to send get host channel param's message queue "); |
e6e12661 | 3891 | return -EFAULT; |
c5c77ba1 JK |
3892 | } |
3893 | ||
2d25af87 | 3894 | down(&hif_sema_wait_response); |
31390eec | 3895 | return result; |
c5c77ba1 JK |
3896 | } |
3897 | ||
a4ab1ade TC |
3898 | s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource, |
3899 | u8 u8ScanType, u8 *pu8ChnlFreqList, | |
3900 | u8 u8ChnlListLen, const u8 *pu8IEs, | |
3901 | size_t IEsLen, wilc_scan_result ScanResult, | |
3902 | void *pvUserArg, struct hidden_network *pstrHiddenNetwork) | |
c5c77ba1 | 3903 | { |
31390eec | 3904 | s32 result = 0; |
143eb95a | 3905 | struct host_if_msg msg; |
c5c77ba1 | 3906 | |
91109e11 | 3907 | if (!hif_drv || !ScanResult) { |
a4ab1ade | 3908 | PRINT_ER("hif_drv or ScanResult = NULL\n"); |
24db713f LK |
3909 | return -EFAULT; |
3910 | } | |
c5c77ba1 | 3911 | |
143eb95a | 3912 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 3913 | |
a9f812a6 | 3914 | msg.id = HOST_IF_MSG_SCAN; |
c5c77ba1 | 3915 | |
91109e11 | 3916 | if (pstrHiddenNetwork) { |
629b9ca0 LK |
3917 | msg.body.scan_info.hidden_network.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo; |
3918 | msg.body.scan_info.hidden_network.u8ssidnum = pstrHiddenNetwork->u8ssidnum; | |
c5c77ba1 JK |
3919 | |
3920 | } else | |
3921 | PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n"); | |
3922 | ||
a4ab1ade | 3923 | msg.drv = hif_drv; |
42568898 | 3924 | msg.body.scan_info.src = u8ScanSource; |
1e276c88 | 3925 | msg.body.scan_info.type = u8ScanType; |
c17c6da6 | 3926 | msg.body.scan_info.result = ScanResult; |
5f2b50c8 | 3927 | msg.body.scan_info.arg = pvUserArg; |
4528bdb5 | 3928 | |
f97bd9ca | 3929 | msg.body.scan_info.ch_list_len = u8ChnlListLen; |
82eeb0ad LK |
3930 | msg.body.scan_info.ch_freq_list = kmalloc(u8ChnlListLen, GFP_KERNEL); |
3931 | memcpy(msg.body.scan_info.ch_freq_list, pu8ChnlFreqList, u8ChnlListLen); | |
c5c77ba1 | 3932 | |
7b1f76cd | 3933 | msg.body.scan_info.ies_len = IEsLen; |
d6f19aa5 LK |
3934 | msg.body.scan_info.ies = kmalloc(IEsLen, GFP_KERNEL); |
3935 | memcpy(msg.body.scan_info.ies, pu8IEs, IEsLen); | |
c5c77ba1 | 3936 | |
31390eec LK |
3937 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
3938 | if (result) { | |
24db713f LK |
3939 | PRINT_ER("Error in sending message queue\n"); |
3940 | return -EINVAL; | |
c5c77ba1 JK |
3941 | } |
3942 | ||
c5c77ba1 | 3943 | PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n"); |
13b313e4 LK |
3944 | hif_drv->scan_timer.data = (unsigned long)hif_drv; |
3945 | mod_timer(&hif_drv->scan_timer, | |
9eb06643 | 3946 | jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT)); |
c5c77ba1 | 3947 | |
31390eec | 3948 | return result; |
c5c77ba1 | 3949 | } |
ae4dfa57 | 3950 | |
a4ab1ade TC |
3951 | s32 hif_set_cfg(struct host_if_drv *hif_drv, |
3952 | struct cfg_param_val *pstrCfgParamVal) | |
c5c77ba1 | 3953 | { |
31390eec | 3954 | s32 result = 0; |
143eb95a | 3955 | struct host_if_msg msg; |
c5c77ba1 | 3956 | |
a4ab1ade TC |
3957 | if (!hif_drv) { |
3958 | PRINT_ER("hif_drv NULL\n"); | |
24db713f LK |
3959 | return -EFAULT; |
3960 | } | |
ae4dfa57 | 3961 | |
143eb95a | 3962 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 3963 | msg.id = HOST_IF_MSG_CFG_PARAMS; |
221371e5 | 3964 | msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal; |
a4ab1ade | 3965 | msg.drv = hif_drv; |
c5c77ba1 | 3966 | |
31390eec | 3967 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
c5c77ba1 | 3968 | |
31390eec | 3969 | return result; |
c5c77ba1 JK |
3970 | } |
3971 | ||
a4ab1ade | 3972 | s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value) |
c5c77ba1 | 3973 | { |
31390eec | 3974 | s32 result = 0; |
c5c77ba1 | 3975 | |
33110ad7 | 3976 | down(&hif_drv->sem_cfg_values); |
c5c77ba1 | 3977 | |
a4ab1ade TC |
3978 | if (!hif_drv) { |
3979 | PRINT_ER("hif_drv NULL\n"); | |
24db713f | 3980 | return -EFAULT; |
c5c77ba1 JK |
3981 | } |
3982 | PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n"); | |
3983 | switch (u16WID) { | |
c5c77ba1 | 3984 | case WID_BSS_TYPE: |
ace303f0 | 3985 | *pu16WID_Value = (u16)hif_drv->cfg_values.bss_type; |
c5c77ba1 JK |
3986 | break; |
3987 | ||
3988 | case WID_AUTH_TYPE: | |
ace303f0 | 3989 | *pu16WID_Value = (u16)hif_drv->cfg_values.auth_type; |
c5c77ba1 JK |
3990 | break; |
3991 | ||
3992 | case WID_AUTH_TIMEOUT: | |
ace303f0 | 3993 | *pu16WID_Value = hif_drv->cfg_values.auth_timeout; |
c5c77ba1 JK |
3994 | break; |
3995 | ||
3996 | case WID_POWER_MANAGEMENT: | |
ace303f0 | 3997 | *pu16WID_Value = (u16)hif_drv->cfg_values.power_mgmt_mode; |
c5c77ba1 JK |
3998 | break; |
3999 | ||
4000 | case WID_SHORT_RETRY_LIMIT: | |
ace303f0 | 4001 | *pu16WID_Value = hif_drv->cfg_values.short_retry_limit; |
c5c77ba1 JK |
4002 | break; |
4003 | ||
4004 | case WID_LONG_RETRY_LIMIT: | |
ace303f0 | 4005 | *pu16WID_Value = hif_drv->cfg_values.long_retry_limit; |
c5c77ba1 JK |
4006 | break; |
4007 | ||
4008 | case WID_FRAG_THRESHOLD: | |
ace303f0 | 4009 | *pu16WID_Value = hif_drv->cfg_values.frag_threshold; |
c5c77ba1 JK |
4010 | break; |
4011 | ||
4012 | case WID_RTS_THRESHOLD: | |
ace303f0 | 4013 | *pu16WID_Value = hif_drv->cfg_values.rts_threshold; |
c5c77ba1 JK |
4014 | break; |
4015 | ||
4016 | case WID_PREAMBLE: | |
ace303f0 | 4017 | *pu16WID_Value = (u16)hif_drv->cfg_values.preamble_type; |
c5c77ba1 JK |
4018 | break; |
4019 | ||
4020 | case WID_SHORT_SLOT_ALLOWED: | |
ace303f0 | 4021 | *pu16WID_Value = (u16)hif_drv->cfg_values.short_slot_allowed; |
c5c77ba1 JK |
4022 | break; |
4023 | ||
4024 | case WID_11N_TXOP_PROT_DISABLE: | |
ace303f0 | 4025 | *pu16WID_Value = (u16)hif_drv->cfg_values.txop_prot_disabled; |
c5c77ba1 JK |
4026 | break; |
4027 | ||
4028 | case WID_BEACON_INTERVAL: | |
ace303f0 | 4029 | *pu16WID_Value = hif_drv->cfg_values.beacon_interval; |
c5c77ba1 JK |
4030 | break; |
4031 | ||
4032 | case WID_DTIM_PERIOD: | |
ace303f0 | 4033 | *pu16WID_Value = (u16)hif_drv->cfg_values.dtim_period; |
c5c77ba1 JK |
4034 | break; |
4035 | ||
4036 | case WID_SITE_SURVEY: | |
ace303f0 | 4037 | *pu16WID_Value = (u16)hif_drv->cfg_values.site_survey_enabled; |
c5c77ba1 JK |
4038 | break; |
4039 | ||
4040 | case WID_SITE_SURVEY_SCAN_TIME: | |
ace303f0 | 4041 | *pu16WID_Value = hif_drv->cfg_values.site_survey_scan_time; |
c5c77ba1 JK |
4042 | break; |
4043 | ||
4044 | case WID_ACTIVE_SCAN_TIME: | |
ace303f0 | 4045 | *pu16WID_Value = hif_drv->cfg_values.active_scan_time; |
c5c77ba1 JK |
4046 | break; |
4047 | ||
4048 | case WID_PASSIVE_SCAN_TIME: | |
ace303f0 | 4049 | *pu16WID_Value = hif_drv->cfg_values.passive_scan_time; |
c5c77ba1 JK |
4050 | break; |
4051 | ||
4052 | case WID_CURRENT_TX_RATE: | |
ace303f0 | 4053 | *pu16WID_Value = hif_drv->cfg_values.curr_tx_rate; |
c5c77ba1 JK |
4054 | break; |
4055 | ||
4056 | default: | |
4057 | break; | |
4058 | } | |
4059 | ||
33110ad7 | 4060 | up(&hif_drv->sem_cfg_values); |
c5c77ba1 | 4061 | |
31390eec | 4062 | return result; |
c5c77ba1 JK |
4063 | } |
4064 | ||
93dee8ee | 4065 | static void GetPeriodicRSSI(unsigned long arg) |
c5c77ba1 | 4066 | { |
a4ab1ade | 4067 | struct host_if_drv *hif_drv = (struct host_if_drv *)arg; |
78c87591 | 4068 | |
a4ab1ade | 4069 | if (!hif_drv) { |
c5c77ba1 JK |
4070 | PRINT_ER("Driver handler is NULL\n"); |
4071 | return; | |
4072 | } | |
4073 | ||
b60005a8 | 4074 | if (hif_drv->hif_state == HOST_IF_CONNECTED) { |
31390eec | 4075 | s32 result = 0; |
143eb95a | 4076 | struct host_if_msg msg; |
c5c77ba1 | 4077 | |
143eb95a | 4078 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4079 | |
a9f812a6 | 4080 | msg.id = HOST_IF_MSG_GET_RSSI; |
a4ab1ade | 4081 | msg.drv = hif_drv; |
c5c77ba1 | 4082 | |
31390eec LK |
4083 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4084 | if (result) { | |
c5c77ba1 JK |
4085 | PRINT_ER("Failed to send get host channel param's message queue "); |
4086 | return; | |
4087 | } | |
4088 | } | |
262f55e1 LK |
4089 | periodic_rssi.data = (unsigned long)hif_drv; |
4090 | mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000)); | |
c5c77ba1 JK |
4091 | } |
4092 | ||
d5382219 | 4093 | s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) |
c5c77ba1 | 4094 | { |
5b09bd32 | 4095 | s32 result = 0; |
a4ab1ade | 4096 | struct host_if_drv *hif_drv; |
d42ab083 | 4097 | int err; |
d5382219 GL |
4098 | perInterface_wlan_t *nic; |
4099 | struct wilc *wilc; | |
4100 | ||
4101 | nic = netdev_priv(dev); | |
4102 | wilc = nic->wilc; | |
c5c77ba1 | 4103 | |
c5c77ba1 JK |
4104 | PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1); |
4105 | ||
ca8540e4 | 4106 | scan_while_connected = false; |
c5c77ba1 | 4107 | |
2d25af87 | 4108 | sema_init(&hif_sema_wait_response, 0); |
c5c77ba1 | 4109 | |
a4ab1ade TC |
4110 | hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL); |
4111 | if (!hif_drv) { | |
5b09bd32 | 4112 | result = -ENOMEM; |
17db84eb | 4113 | goto _fail_; |
c5c77ba1 | 4114 | } |
a4ab1ade TC |
4115 | *hif_drv_handler = hif_drv; |
4116 | err = add_handler_in_list(hif_drv); | |
d42ab083 | 4117 | if (err) { |
5b09bd32 | 4118 | result = -EFAULT; |
d42ab083 JK |
4119 | goto _fail_timer_2; |
4120 | } | |
c5c77ba1 | 4121 | |
72ed4dc7 | 4122 | g_obtainingIP = false; |
c5c77ba1 | 4123 | |
a4ab1ade | 4124 | PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv); |
c5c77ba1 | 4125 | if (clients_count == 0) { |
834e0cb0 | 4126 | sema_init(&hif_sema_thread, 0); |
27ff2168 | 4127 | sema_init(&hif_sema_driver, 0); |
440e8993 | 4128 | sema_init(&hif_sema_deinit, 1); |
83383ea3 AB |
4129 | } |
4130 | ||
9ea47133 | 4131 | sema_init(&hif_drv->sem_test_key_block, 0); |
e55e4967 | 4132 | sema_init(&hif_drv->sem_test_disconn_block, 0); |
7e111f9e | 4133 | sema_init(&hif_drv->sem_get_rssi, 0); |
bc34da66 | 4134 | sema_init(&hif_drv->sem_get_link_speed, 0); |
4ea90008 | 4135 | sema_init(&hif_drv->sem_get_chnl, 0); |
569a3c67 | 4136 | sema_init(&hif_drv->sem_inactive_time, 0); |
c5c77ba1 | 4137 | |
c5c77ba1 JK |
4138 | PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count); |
4139 | ||
4140 | if (clients_count == 0) { | |
cb067dcf | 4141 | result = wilc_mq_create(&hif_msg_q); |
c5c77ba1 | 4142 | |
5b09bd32 | 4143 | if (result < 0) { |
c5c77ba1 JK |
4144 | PRINT_ER("Failed to creat MQ\n"); |
4145 | goto _fail_; | |
4146 | } | |
c2115d8e | 4147 | |
d5382219 GL |
4148 | hif_thread_handler = kthread_run(hostIFthread, wilc, |
4149 | "WILC_kthread"); | |
c2115d8e LK |
4150 | |
4151 | if (IS_ERR(hif_thread_handler)) { | |
c5c77ba1 | 4152 | PRINT_ER("Failed to creat Thread\n"); |
5b09bd32 | 4153 | result = -EFAULT; |
c5c77ba1 JK |
4154 | goto _fail_mq_; |
4155 | } | |
262f55e1 | 4156 | setup_timer(&periodic_rssi, GetPeriodicRSSI, |
a4ab1ade | 4157 | (unsigned long)hif_drv); |
262f55e1 | 4158 | mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000)); |
c5c77ba1 JK |
4159 | } |
4160 | ||
13b313e4 | 4161 | setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0); |
81a59506 | 4162 | setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0); |
cc2d7e9e | 4163 | setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0); |
c5c77ba1 | 4164 | |
33110ad7 LK |
4165 | sema_init(&hif_drv->sem_cfg_values, 1); |
4166 | down(&hif_drv->sem_cfg_values); | |
c5c77ba1 | 4167 | |
b60005a8 | 4168 | hif_drv->hif_state = HOST_IF_IDLE; |
ace303f0 LK |
4169 | hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF; |
4170 | hif_drv->cfg_values.scan_source = DEFAULT_SCAN; | |
4171 | hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME; | |
4172 | hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME; | |
4173 | hif_drv->cfg_values.curr_tx_rate = AUTORATE; | |
c5c77ba1 | 4174 | |
1229b1ab | 4175 | hif_drv->p2p_timeout = 0; |
c5c77ba1 | 4176 | |
c5c77ba1 | 4177 | PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n", |
ace303f0 LK |
4178 | hif_drv->cfg_values.site_survey_enabled, |
4179 | hif_drv->cfg_values.scan_source, | |
4180 | hif_drv->cfg_values.active_scan_time, | |
4181 | hif_drv->cfg_values.passive_scan_time, | |
4182 | hif_drv->cfg_values.curr_tx_rate); | |
c5c77ba1 | 4183 | |
33110ad7 | 4184 | up(&hif_drv->sem_cfg_values); |
c5c77ba1 | 4185 | |
ae4dfa57 | 4186 | clients_count++; |
c5c77ba1 | 4187 | |
5b09bd32 | 4188 | return result; |
c5c77ba1 | 4189 | |
c5c77ba1 | 4190 | _fail_timer_2: |
33110ad7 | 4191 | up(&hif_drv->sem_cfg_values); |
81a59506 | 4192 | del_timer_sync(&hif_drv->connect_timer); |
13b313e4 | 4193 | del_timer_sync(&hif_drv->scan_timer); |
c2115d8e | 4194 | kthread_stop(hif_thread_handler); |
c5c77ba1 | 4195 | _fail_mq_: |
cb067dcf | 4196 | wilc_mq_destroy(&hif_msg_q); |
c5c77ba1 | 4197 | _fail_: |
5b09bd32 | 4198 | return result; |
c5c77ba1 | 4199 | } |
c5c77ba1 | 4200 | |
a4ab1ade | 4201 | s32 host_int_deinit(struct host_if_drv *hif_drv) |
c5c77ba1 | 4202 | { |
31390eec | 4203 | s32 result = 0; |
143eb95a | 4204 | struct host_if_msg msg; |
d42ab083 | 4205 | int ret; |
c5c77ba1 | 4206 | |
a4ab1ade TC |
4207 | if (!hif_drv) { |
4208 | PRINT_ER("hif_drv = NULL\n"); | |
c5c77ba1 JK |
4209 | return 0; |
4210 | } | |
4211 | ||
440e8993 | 4212 | down(&hif_sema_deinit); |
c5c77ba1 | 4213 | |
a4ab1ade | 4214 | terminated_handle = hif_drv; |
c5c77ba1 JK |
4215 | PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count); |
4216 | ||
13b313e4 | 4217 | if (del_timer_sync(&hif_drv->scan_timer)) |
03b2d5e7 | 4218 | PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n"); |
c5c77ba1 | 4219 | |
81a59506 | 4220 | if (del_timer_sync(&hif_drv->connect_timer)) |
03b2d5e7 | 4221 | PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n"); |
c5c77ba1 | 4222 | |
262f55e1 | 4223 | if (del_timer_sync(&periodic_rssi)) |
03b2d5e7 | 4224 | PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n"); |
c5c77ba1 | 4225 | |
cc2d7e9e | 4226 | del_timer_sync(&hif_drv->remain_on_ch_timer); |
c5c77ba1 | 4227 | |
218dc407 | 4228 | host_int_set_wfi_drv_handler(NULL); |
27ff2168 | 4229 | down(&hif_sema_driver); |
c5c77ba1 | 4230 | |
bc801855 LK |
4231 | if (hif_drv->usr_scan_req.scan_result) { |
4232 | hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, | |
66eaea30 | 4233 | hif_drv->usr_scan_req.arg, NULL); |
bc801855 | 4234 | hif_drv->usr_scan_req.scan_result = NULL; |
c5c77ba1 | 4235 | } |
c5c77ba1 | 4236 | |
b60005a8 | 4237 | hif_drv->hif_state = HOST_IF_IDLE; |
c5c77ba1 | 4238 | |
ca8540e4 | 4239 | scan_while_connected = false; |
c5c77ba1 | 4240 | |
143eb95a | 4241 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
4242 | |
4243 | if (clients_count == 1) { | |
262f55e1 | 4244 | if (del_timer_sync(&periodic_rssi)) |
03b2d5e7 | 4245 | PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n"); |
262f55e1 | 4246 | |
a9f812a6 | 4247 | msg.id = HOST_IF_MSG_EXIT; |
a4ab1ade | 4248 | msg.drv = hif_drv; |
c5c77ba1 | 4249 | |
31390eec LK |
4250 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4251 | if (result != 0) | |
4252 | PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result); | |
c5c77ba1 | 4253 | |
834e0cb0 | 4254 | down(&hif_sema_thread); |
c5c77ba1 | 4255 | |
cb067dcf | 4256 | wilc_mq_destroy(&hif_msg_q); |
c5c77ba1 JK |
4257 | } |
4258 | ||
33110ad7 | 4259 | down(&hif_drv->sem_cfg_values); |
c5c77ba1 | 4260 | |
a4ab1ade | 4261 | ret = remove_handler_in_list(hif_drv); |
d42ab083 | 4262 | if (ret) |
31390eec | 4263 | result = -ENOENT; |
d42ab083 | 4264 | |
a4ab1ade | 4265 | kfree(hif_drv); |
c5c77ba1 | 4266 | |
ae4dfa57 | 4267 | clients_count--; |
b1413b60 | 4268 | terminated_handle = NULL; |
440e8993 | 4269 | up(&hif_sema_deinit); |
31390eec | 4270 | return result; |
c5c77ba1 JK |
4271 | } |
4272 | ||
4e4467fd | 4273 | void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length) |
c5c77ba1 | 4274 | { |
31390eec | 4275 | s32 result = 0; |
143eb95a | 4276 | struct host_if_msg msg; |
d42ab083 | 4277 | int id; |
a4ab1ade | 4278 | struct host_if_drv *hif_drv = NULL; |
c5c77ba1 | 4279 | |
d42ab083 | 4280 | id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); |
a4ab1ade | 4281 | hif_drv = get_handler_from_id(id); |
c5c77ba1 | 4282 | |
a4ab1ade TC |
4283 | if (!hif_drv || hif_drv == terminated_handle) { |
4284 | PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv); | |
c5c77ba1 JK |
4285 | return; |
4286 | } | |
4287 | ||
143eb95a | 4288 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4289 | |
a9f812a6 | 4290 | msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO; |
a4ab1ade | 4291 | msg.drv = hif_drv; |
c5c77ba1 | 4292 | |
3bffac68 | 4293 | msg.body.net_info.len = u32Length; |
b021b80b LK |
4294 | msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL); |
4295 | memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length); | |
c5c77ba1 | 4296 | |
31390eec LK |
4297 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4298 | if (result) | |
4299 | PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result); | |
c5c77ba1 JK |
4300 | } |
4301 | ||
4e4467fd | 4302 | void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length) |
c5c77ba1 | 4303 | { |
31390eec | 4304 | s32 result = 0; |
143eb95a | 4305 | struct host_if_msg msg; |
d42ab083 | 4306 | int id; |
a4ab1ade | 4307 | struct host_if_drv *hif_drv = NULL; |
c5c77ba1 | 4308 | |
440e8993 | 4309 | down(&hif_sema_deinit); |
c5c77ba1 | 4310 | |
d42ab083 | 4311 | id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); |
a4ab1ade | 4312 | hif_drv = get_handler_from_id(id); |
03b2d5e7 | 4313 | PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n"); |
c5c77ba1 | 4314 | |
a4ab1ade | 4315 | if (!hif_drv || hif_drv == terminated_handle) { |
c5c77ba1 | 4316 | PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n"); |
440e8993 | 4317 | up(&hif_sema_deinit); |
c5c77ba1 JK |
4318 | return; |
4319 | } | |
4320 | ||
33bfb198 | 4321 | if (!hif_drv->usr_conn_req.conn_result) { |
c5c77ba1 | 4322 | PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n"); |
440e8993 | 4323 | up(&hif_sema_deinit); |
c5c77ba1 JK |
4324 | return; |
4325 | } | |
4326 | ||
143eb95a | 4327 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4328 | |
a9f812a6 | 4329 | msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO; |
a4ab1ade | 4330 | msg.drv = hif_drv; |
c5c77ba1 | 4331 | |
f94f4889 | 4332 | msg.body.async_info.len = u32Length; |
33722ac7 LK |
4333 | msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL); |
4334 | memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length); | |
c5c77ba1 | 4335 | |
31390eec LK |
4336 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4337 | if (result) | |
4338 | PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result); | |
c5c77ba1 | 4339 | |
440e8993 | 4340 | up(&hif_sema_deinit); |
c5c77ba1 JK |
4341 | } |
4342 | ||
4e4467fd | 4343 | void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length) |
c5c77ba1 | 4344 | { |
31390eec | 4345 | s32 result = 0; |
143eb95a | 4346 | struct host_if_msg msg; |
d42ab083 | 4347 | int id; |
a4ab1ade | 4348 | struct host_if_drv *hif_drv = NULL; |
78c87591 | 4349 | |
d42ab083 | 4350 | id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24)); |
a4ab1ade | 4351 | hif_drv = get_handler_from_id(id); |
c5c77ba1 | 4352 | |
a4ab1ade | 4353 | PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv); |
c5c77ba1 | 4354 | |
a4ab1ade | 4355 | if (!hif_drv || hif_drv == terminated_handle) |
c5c77ba1 | 4356 | return; |
c5c77ba1 | 4357 | |
bc801855 | 4358 | if (hif_drv->usr_scan_req.scan_result) { |
143eb95a | 4359 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4360 | |
a9f812a6 | 4361 | msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE; |
a4ab1ade | 4362 | msg.drv = hif_drv; |
c5c77ba1 | 4363 | |
31390eec LK |
4364 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4365 | if (result) | |
4366 | PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result); | |
c5c77ba1 JK |
4367 | } |
4368 | ||
c5c77ba1 | 4369 | return; |
c5c77ba1 JK |
4370 | } |
4371 | ||
a4ab1ade TC |
4372 | s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID, |
4373 | u32 u32duration, u16 chan, | |
4374 | wilc_remain_on_chan_expired RemainOnChanExpired, | |
4375 | wilc_remain_on_chan_ready RemainOnChanReady, | |
4376 | void *pvUserArg) | |
c5c77ba1 | 4377 | { |
31390eec | 4378 | s32 result = 0; |
143eb95a | 4379 | struct host_if_msg msg; |
c5c77ba1 | 4380 | |
a4ab1ade | 4381 | if (!hif_drv) { |
24db713f LK |
4382 | PRINT_ER("driver is null\n"); |
4383 | return -EFAULT; | |
4384 | } | |
c5c77ba1 | 4385 | |
143eb95a | 4386 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4387 | |
a9f812a6 | 4388 | msg.id = HOST_IF_MSG_REMAIN_ON_CHAN; |
839ab709 | 4389 | msg.body.remain_on_ch.ch = chan; |
bfb62abc | 4390 | msg.body.remain_on_ch.expired = RemainOnChanExpired; |
5e5f7916 | 4391 | msg.body.remain_on_ch.ready = RemainOnChanReady; |
c5cc4b12 | 4392 | msg.body.remain_on_ch.arg = pvUserArg; |
070d365c | 4393 | msg.body.remain_on_ch.u32duration = u32duration; |
9d764e38 | 4394 | msg.body.remain_on_ch.id = u32SessionID; |
a4ab1ade | 4395 | msg.drv = hif_drv; |
143eb95a | 4396 | |
31390eec LK |
4397 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4398 | if (result) | |
24db713f | 4399 | PRINT_ER("wilc mq send fail\n"); |
c5c77ba1 | 4400 | |
31390eec | 4401 | return result; |
c5c77ba1 JK |
4402 | } |
4403 | ||
a4ab1ade | 4404 | s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID) |
c5c77ba1 | 4405 | { |
31390eec | 4406 | s32 result = 0; |
143eb95a | 4407 | struct host_if_msg msg; |
c5c77ba1 | 4408 | |
a4ab1ade | 4409 | if (!hif_drv) { |
24db713f LK |
4410 | PRINT_ER("driver is null\n"); |
4411 | return -EFAULT; | |
4412 | } | |
c5c77ba1 | 4413 | |
cc2d7e9e | 4414 | del_timer(&hif_drv->remain_on_ch_timer); |
c5c77ba1 | 4415 | |
143eb95a | 4416 | memset(&msg, 0, sizeof(struct host_if_msg)); |
a9f812a6 | 4417 | msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED; |
a4ab1ade | 4418 | msg.drv = hif_drv; |
9d764e38 | 4419 | msg.body.remain_on_ch.id = u32SessionID; |
c5c77ba1 | 4420 | |
31390eec LK |
4421 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4422 | if (result) | |
24db713f | 4423 | PRINT_ER("wilc mq send fail\n"); |
c5c77ba1 | 4424 | |
31390eec | 4425 | return result; |
c5c77ba1 JK |
4426 | } |
4427 | ||
a4ab1ade | 4428 | s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg) |
c5c77ba1 | 4429 | { |
31390eec | 4430 | s32 result = 0; |
143eb95a | 4431 | struct host_if_msg msg; |
c5c77ba1 | 4432 | |
a4ab1ade | 4433 | if (!hif_drv) { |
24db713f LK |
4434 | PRINT_ER("driver is null\n"); |
4435 | return -EFAULT; | |
4436 | } | |
c5c77ba1 | 4437 | |
143eb95a | 4438 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4439 | |
a9f812a6 | 4440 | msg.id = HOST_IF_MSG_REGISTER_FRAME; |
c5c77ba1 JK |
4441 | switch (u16FrameType) { |
4442 | case ACTION: | |
4443 | PRINT_D(HOSTINF_DBG, "ACTION\n"); | |
bcb410bb | 4444 | msg.body.reg_frame.reg_id = ACTION_FRM_IDX; |
c5c77ba1 JK |
4445 | break; |
4446 | ||
4447 | case PROBE_REQ: | |
4448 | PRINT_D(HOSTINF_DBG, "PROBE REQ\n"); | |
bcb410bb | 4449 | msg.body.reg_frame.reg_id = PROBE_REQ_IDX; |
c5c77ba1 JK |
4450 | break; |
4451 | ||
4452 | default: | |
4453 | PRINT_D(HOSTINF_DBG, "Not valid frame type\n"); | |
4454 | break; | |
4455 | } | |
d5f654ca | 4456 | msg.body.reg_frame.frame_type = u16FrameType; |
6abf8681 | 4457 | msg.body.reg_frame.reg = bReg; |
a4ab1ade | 4458 | msg.drv = hif_drv; |
c5c77ba1 | 4459 | |
31390eec LK |
4460 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4461 | if (result) | |
24db713f | 4462 | PRINT_ER("wilc mq send fail\n"); |
c5c77ba1 | 4463 | |
31390eec | 4464 | return result; |
c5c77ba1 | 4465 | } |
c5c77ba1 | 4466 | |
a4ab1ade TC |
4467 | s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval, |
4468 | u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head, | |
4469 | u32 u32TailLen, u8 *pu8Tail) | |
c5c77ba1 | 4470 | { |
31390eec | 4471 | s32 result = 0; |
143eb95a | 4472 | struct host_if_msg msg; |
a98491e5 | 4473 | struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info; |
c5c77ba1 | 4474 | |
a4ab1ade | 4475 | if (!hif_drv) { |
24db713f LK |
4476 | PRINT_ER("driver is null\n"); |
4477 | return -EFAULT; | |
4478 | } | |
c5c77ba1 | 4479 | |
143eb95a | 4480 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
4481 | |
4482 | PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n"); | |
4483 | ||
a9f812a6 | 4484 | msg.id = HOST_IF_MSG_ADD_BEACON; |
a4ab1ade | 4485 | msg.drv = hif_drv; |
12262dda | 4486 | pstrSetBeaconParam->interval = u32Interval; |
e76ab770 | 4487 | pstrSetBeaconParam->dtim_period = u32DTIMPeriod; |
51c66185 | 4488 | pstrSetBeaconParam->head_len = u32HeadLen; |
543f5b13 | 4489 | pstrSetBeaconParam->head = kmemdup(pu8Head, u32HeadLen, GFP_KERNEL); |
91109e11 | 4490 | if (!pstrSetBeaconParam->head) { |
31390eec | 4491 | result = -ENOMEM; |
24db713f LK |
4492 | goto ERRORHANDLER; |
4493 | } | |
030c57e2 | 4494 | pstrSetBeaconParam->tail_len = u32TailLen; |
c5c77ba1 | 4495 | |
c5c77ba1 | 4496 | if (u32TailLen > 0) { |
543f5b13 SB |
4497 | pstrSetBeaconParam->tail = kmemdup(pu8Tail, u32TailLen, |
4498 | GFP_KERNEL); | |
91109e11 | 4499 | if (!pstrSetBeaconParam->tail) { |
31390eec | 4500 | result = -ENOMEM; |
24db713f LK |
4501 | goto ERRORHANDLER; |
4502 | } | |
c5c77ba1 | 4503 | } else { |
7dbcb6d3 | 4504 | pstrSetBeaconParam->tail = NULL; |
c5c77ba1 JK |
4505 | } |
4506 | ||
31390eec LK |
4507 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4508 | if (result) | |
24db713f | 4509 | PRINT_ER("wilc mq send fail\n"); |
c5c77ba1 | 4510 | |
24db713f | 4511 | ERRORHANDLER: |
31390eec | 4512 | if (result) { |
95f840fb | 4513 | kfree(pstrSetBeaconParam->head); |
c5c77ba1 | 4514 | |
95f840fb | 4515 | kfree(pstrSetBeaconParam->tail); |
c5c77ba1 JK |
4516 | } |
4517 | ||
31390eec | 4518 | return result; |
c5c77ba1 JK |
4519 | } |
4520 | ||
0a5298cb | 4521 | int host_int_del_beacon(struct host_if_drv *hif_drv) |
c5c77ba1 | 4522 | { |
0a5298cb | 4523 | int result = 0; |
143eb95a | 4524 | struct host_if_msg msg; |
c5c77ba1 | 4525 | |
a4ab1ade | 4526 | if (!hif_drv) { |
24db713f LK |
4527 | PRINT_ER("driver is null\n"); |
4528 | return -EFAULT; | |
4529 | } | |
c5c77ba1 | 4530 | |
a9f812a6 | 4531 | msg.id = HOST_IF_MSG_DEL_BEACON; |
a4ab1ade | 4532 | msg.drv = hif_drv; |
c5c77ba1 JK |
4533 | PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n"); |
4534 | ||
31390eec LK |
4535 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4536 | if (result) | |
7dc1d0cc | 4537 | PRINT_ER("wilc_mq_send fail\n"); |
c5c77ba1 | 4538 | |
31390eec | 4539 | return result; |
c5c77ba1 JK |
4540 | } |
4541 | ||
18cfbd33 | 4542 | int host_int_add_station(struct host_if_drv *hif_drv, |
e3378547 | 4543 | struct add_sta_param *sta_param) |
c5c77ba1 | 4544 | { |
18cfbd33 | 4545 | int result = 0; |
143eb95a | 4546 | struct host_if_msg msg; |
ca8f47f8 | 4547 | struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info; |
c5c77ba1 | 4548 | |
a4ab1ade | 4549 | if (!hif_drv) { |
24db713f LK |
4550 | PRINT_ER("driver is null\n"); |
4551 | return -EFAULT; | |
4552 | } | |
c5c77ba1 | 4553 | |
143eb95a | 4554 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
4555 | |
4556 | PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n"); | |
4557 | ||
a9f812a6 | 4558 | msg.id = HOST_IF_MSG_ADD_STATION; |
a4ab1ade | 4559 | msg.drv = hif_drv; |
c5c77ba1 | 4560 | |
e3378547 | 4561 | memcpy(pstrAddStationMsg, sta_param, sizeof(struct add_sta_param)); |
e734223c LK |
4562 | if (pstrAddStationMsg->rates_len > 0) { |
4563 | u8 *rates = kmalloc(pstrAddStationMsg->rates_len, GFP_KERNEL); | |
c09389ac | 4564 | |
7ae43363 LK |
4565 | if (!rates) |
4566 | return -ENOMEM; | |
c5c77ba1 | 4567 | |
e3378547 | 4568 | memcpy(rates, sta_param->rates, |
e734223c | 4569 | pstrAddStationMsg->rates_len); |
a622e016 | 4570 | pstrAddStationMsg->rates = rates; |
c5c77ba1 JK |
4571 | } |
4572 | ||
31390eec LK |
4573 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4574 | if (result) | |
24db713f | 4575 | PRINT_ER("wilc_mq_send fail\n"); |
31390eec | 4576 | return result; |
c5c77ba1 JK |
4577 | } |
4578 | ||
c9c4eb41 | 4579 | int host_int_del_station(struct host_if_drv *hif_drv, const u8 *mac_addr) |
c5c77ba1 | 4580 | { |
79a0c0a8 | 4581 | int result = 0; |
143eb95a | 4582 | struct host_if_msg msg; |
c87fbede | 4583 | struct del_sta *del_sta_info = &msg.body.del_sta_info; |
c5c77ba1 | 4584 | |
a4ab1ade | 4585 | if (!hif_drv) { |
24db713f LK |
4586 | PRINT_ER("driver is null\n"); |
4587 | return -EFAULT; | |
4588 | } | |
c5c77ba1 | 4589 | |
143eb95a | 4590 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
4591 | |
4592 | PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n"); | |
4593 | ||
a9f812a6 | 4594 | msg.id = HOST_IF_MSG_DEL_STATION; |
a4ab1ade | 4595 | msg.drv = hif_drv; |
c5c77ba1 | 4596 | |
c9c4eb41 | 4597 | if (!mac_addr) |
c87fbede | 4598 | eth_broadcast_addr(del_sta_info->mac_addr); |
c5c77ba1 | 4599 | else |
c87fbede | 4600 | memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN); |
c5c77ba1 | 4601 | |
31390eec LK |
4602 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4603 | if (result) | |
24db713f | 4604 | PRINT_ER("wilc_mq_send fail\n"); |
31390eec | 4605 | return result; |
c5c77ba1 | 4606 | } |
ae4dfa57 | 4607 | |
a4ab1ade | 4608 | s32 host_int_del_allstation(struct host_if_drv *hif_drv, |
441dc609 | 4609 | u8 pu8MacAddr[][ETH_ALEN]) |
c5c77ba1 | 4610 | { |
31390eec | 4611 | s32 result = 0; |
143eb95a | 4612 | struct host_if_msg msg; |
b0c1e80e | 4613 | struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info; |
63d03e47 | 4614 | u8 au8Zero_Buff[ETH_ALEN] = {0}; |
4e4467fd | 4615 | u32 i; |
63d03e47 | 4616 | u8 u8AssocNumb = 0; |
c5c77ba1 | 4617 | |
a4ab1ade | 4618 | if (!hif_drv) { |
24db713f LK |
4619 | PRINT_ER("driver is null\n"); |
4620 | return -EFAULT; | |
4621 | } | |
c5c77ba1 | 4622 | |
143eb95a | 4623 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 JK |
4624 | |
4625 | PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n"); | |
4626 | ||
a9f812a6 | 4627 | msg.id = HOST_IF_MSG_DEL_ALL_STA; |
a4ab1ade | 4628 | msg.drv = hif_drv; |
c5c77ba1 | 4629 | |
c5c77ba1 JK |
4630 | for (i = 0; i < MAX_NUM_STA; i++) { |
4631 | if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) { | |
e51b9216 LK |
4632 | memcpy(pstrDelAllStationMsg->del_all_sta[i], pu8MacAddr[i], ETH_ALEN); |
4633 | PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", | |
4634 | pstrDelAllStationMsg->del_all_sta[i][0], | |
4635 | pstrDelAllStationMsg->del_all_sta[i][1], | |
4636 | pstrDelAllStationMsg->del_all_sta[i][2], | |
4637 | pstrDelAllStationMsg->del_all_sta[i][3], | |
4638 | pstrDelAllStationMsg->del_all_sta[i][4], | |
4639 | pstrDelAllStationMsg->del_all_sta[i][5]); | |
c5c77ba1 JK |
4640 | u8AssocNumb++; |
4641 | } | |
4642 | } | |
4643 | if (!u8AssocNumb) { | |
4644 | PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n"); | |
31390eec | 4645 | return result; |
c5c77ba1 JK |
4646 | } |
4647 | ||
8ba1803f | 4648 | pstrDelAllStationMsg->assoc_sta = u8AssocNumb; |
31390eec | 4649 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
c5c77ba1 | 4650 | |
31390eec | 4651 | if (result) |
24db713f | 4652 | PRINT_ER("wilc_mq_send fail\n"); |
c5c77ba1 | 4653 | |
2d25af87 | 4654 | down(&hif_sema_wait_response); |
c5c77ba1 | 4655 | |
31390eec | 4656 | return result; |
c5c77ba1 JK |
4657 | } |
4658 | ||
a4ab1ade | 4659 | s32 host_int_edit_station(struct host_if_drv *hif_drv, |
6a89ba9c | 4660 | struct add_sta_param *pstrStaParams) |
c5c77ba1 | 4661 | { |
31390eec | 4662 | s32 result = 0; |
143eb95a | 4663 | struct host_if_msg msg; |
ca8f47f8 | 4664 | struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info; |
c5c77ba1 | 4665 | |
a4ab1ade | 4666 | if (!hif_drv) { |
24db713f LK |
4667 | PRINT_ER("driver is null\n"); |
4668 | return -EFAULT; | |
4669 | } | |
c5c77ba1 JK |
4670 | |
4671 | PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n"); | |
4672 | ||
143eb95a | 4673 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4674 | |
a9f812a6 | 4675 | msg.id = HOST_IF_MSG_EDIT_STATION; |
a4ab1ade | 4676 | msg.drv = hif_drv; |
c5c77ba1 | 4677 | |
6a89ba9c | 4678 | memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param)); |
e734223c LK |
4679 | if (pstrAddStationMsg->rates_len > 0) { |
4680 | u8 *rates = kmalloc(pstrAddStationMsg->rates_len, GFP_KERNEL); | |
c09389ac | 4681 | |
7ae43363 LK |
4682 | if (!rates) |
4683 | return -ENOMEM; | |
4684 | ||
a622e016 | 4685 | memcpy(rates, pstrStaParams->rates, |
e734223c | 4686 | pstrAddStationMsg->rates_len); |
a622e016 | 4687 | pstrAddStationMsg->rates = rates; |
c5c77ba1 JK |
4688 | } |
4689 | ||
31390eec LK |
4690 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4691 | if (result) | |
24db713f LK |
4692 | PRINT_ER("wilc_mq_send fail\n"); |
4693 | ||
31390eec | 4694 | return result; |
c5c77ba1 | 4695 | } |
108b3439 | 4696 | |
a4ab1ade TC |
4697 | s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv, |
4698 | bool bIsEnabled, | |
4699 | u32 u32Timeout) | |
c5c77ba1 | 4700 | { |
31390eec | 4701 | s32 result = 0; |
143eb95a | 4702 | struct host_if_msg msg; |
49e1f81b | 4703 | struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info; |
c5c77ba1 | 4704 | |
03b2d5e7 | 4705 | PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled); |
c5c77ba1 | 4706 | |
a4ab1ade | 4707 | if (!hif_drv) { |
24db713f LK |
4708 | PRINT_ER("driver is null\n"); |
4709 | return -EFAULT; | |
4710 | } | |
c5c77ba1 JK |
4711 | |
4712 | PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n"); | |
4713 | ||
143eb95a | 4714 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4715 | |
a9f812a6 | 4716 | msg.id = HOST_IF_MSG_POWER_MGMT; |
a4ab1ade | 4717 | msg.drv = hif_drv; |
c5c77ba1 | 4718 | |
33c70c1b | 4719 | pstrPowerMgmtParam->enabled = bIsEnabled; |
937918ff | 4720 | pstrPowerMgmtParam->timeout = u32Timeout; |
c5c77ba1 | 4721 | |
31390eec LK |
4722 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4723 | if (result) | |
24db713f | 4724 | PRINT_ER("wilc_mq_send fail\n"); |
31390eec | 4725 | return result; |
c5c77ba1 JK |
4726 | } |
4727 | ||
a4ab1ade TC |
4728 | s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv, |
4729 | bool bIsEnabled, | |
4730 | u32 u32count) | |
c5c77ba1 | 4731 | { |
31390eec | 4732 | s32 result = 0; |
143eb95a | 4733 | struct host_if_msg msg; |
a079cf4d | 4734 | struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info; |
c5c77ba1 | 4735 | |
a4ab1ade | 4736 | if (!hif_drv) { |
24db713f LK |
4737 | PRINT_ER("driver is null\n"); |
4738 | return -EFAULT; | |
4739 | } | |
c5c77ba1 JK |
4740 | |
4741 | PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n"); | |
4742 | ||
143eb95a | 4743 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4744 | |
a9f812a6 | 4745 | msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER; |
a4ab1ade | 4746 | msg.drv = hif_drv; |
c5c77ba1 | 4747 | |
bae636eb | 4748 | pstrMulticastFilterParam->enabled = bIsEnabled; |
adab2f71 | 4749 | pstrMulticastFilterParam->cnt = u32count; |
c5c77ba1 | 4750 | |
31390eec LK |
4751 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4752 | if (result) | |
24db713f | 4753 | PRINT_ER("wilc_mq_send fail\n"); |
31390eec | 4754 | return result; |
c5c77ba1 JK |
4755 | } |
4756 | ||
c5c77ba1 JK |
4757 | static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo) |
4758 | { | |
e0a12217 | 4759 | struct join_bss_param *pNewJoinBssParam = NULL; |
63d03e47 | 4760 | u8 *pu8IEs; |
d85f5326 CL |
4761 | u16 u16IEsLen; |
4762 | u16 index = 0; | |
63d03e47 GKH |
4763 | u8 suppRatesNo = 0; |
4764 | u8 extSuppRatesNo; | |
d85f5326 | 4765 | u16 jumpOffset; |
63d03e47 GKH |
4766 | u8 pcipherCount; |
4767 | u8 authCount; | |
4768 | u8 pcipherTotalCount = 0; | |
4769 | u8 authTotalCount = 0; | |
4770 | u8 i, j; | |
c5c77ba1 JK |
4771 | |
4772 | pu8IEs = ptstrNetworkInfo->pu8IEs; | |
4773 | u16IEsLen = ptstrNetworkInfo->u16IEsLen; | |
4774 | ||
b156f1ed | 4775 | pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL); |
91109e11 | 4776 | if (pNewJoinBssParam) { |
c5c77ba1 JK |
4777 | pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod; |
4778 | pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod; | |
4779 | pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo; | |
d00d2ba3 | 4780 | memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6); |
d00d2ba3 | 4781 | memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1); |
619d27b8 | 4782 | pNewJoinBssParam->ssid_len = ptstrNetworkInfo->u8SsidLen; |
2cc46837 CL |
4783 | memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3); |
4784 | memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3); | |
c5c77ba1 | 4785 | |
c5c77ba1 | 4786 | while (index < u16IEsLen) { |
c5c77ba1 | 4787 | if (pu8IEs[index] == SUPP_RATES_IE) { |
c5c77ba1 JK |
4788 | suppRatesNo = pu8IEs[index + 1]; |
4789 | pNewJoinBssParam->supp_rates[0] = suppRatesNo; | |
ae4dfa57 | 4790 | index += 2; |
c5c77ba1 | 4791 | |
d1666e2a | 4792 | for (i = 0; i < suppRatesNo; i++) |
c5c77ba1 | 4793 | pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i]; |
d1666e2a | 4794 | |
c5c77ba1 JK |
4795 | index += suppRatesNo; |
4796 | continue; | |
ae4dfa57 | 4797 | } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) { |
c5c77ba1 JK |
4798 | extSuppRatesNo = pu8IEs[index + 1]; |
4799 | if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo)) | |
4800 | pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED; | |
4801 | else | |
4802 | pNewJoinBssParam->supp_rates[0] += extSuppRatesNo; | |
4803 | index += 2; | |
d1666e2a | 4804 | for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++) |
c5c77ba1 | 4805 | pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i]; |
d1666e2a | 4806 | |
c5c77ba1 JK |
4807 | index += extSuppRatesNo; |
4808 | continue; | |
ae4dfa57 | 4809 | } else if (pu8IEs[index] == HT_CAPABILITY_IE) { |
0be1eb74 | 4810 | pNewJoinBssParam->ht_capable = true; |
ae4dfa57 | 4811 | index += pu8IEs[index + 1] + 2; |
c5c77ba1 | 4812 | continue; |
ae4dfa57 | 4813 | } else if ((pu8IEs[index] == WMM_IE) && |
c5c77ba1 | 4814 | (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) && |
ae4dfa57 LK |
4815 | (pu8IEs[index + 4] == 0xF2) && |
4816 | (pu8IEs[index + 5] == 0x02) && | |
4817 | ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) && | |
c5c77ba1 | 4818 | (pu8IEs[index + 7] == 0x01)) { |
0be1eb74 | 4819 | pNewJoinBssParam->wmm_cap = true; |
c5c77ba1 | 4820 | |
ffda203c | 4821 | if (pu8IEs[index + 8] & BIT(7)) |
0be1eb74 | 4822 | pNewJoinBssParam->uapsd_cap = true; |
c5c77ba1 JK |
4823 | index += pu8IEs[index + 1] + 2; |
4824 | continue; | |
ae4dfa57 | 4825 | } else if ((pu8IEs[index] == P2P_IE) && |
c5c77ba1 | 4826 | (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) && |
ae4dfa57 LK |
4827 | (pu8IEs[index + 4] == 0x9a) && |
4828 | (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) { | |
d85f5326 | 4829 | u16 u16P2P_count; |
78c87591 | 4830 | |
c5c77ba1 | 4831 | pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf; |
7a8d51d7 | 4832 | pNewJoinBssParam->noa_enabled = 1; |
cc179008 | 4833 | pNewJoinBssParam->idx = pu8IEs[index + 9]; |
c5c77ba1 | 4834 | |
ffda203c | 4835 | if (pu8IEs[index + 10] & BIT(7)) { |
d72b33ca | 4836 | pNewJoinBssParam->opp_enabled = 1; |
99b66945 | 4837 | pNewJoinBssParam->ct_window = pu8IEs[index + 10]; |
d72b33ca LK |
4838 | } else { |
4839 | pNewJoinBssParam->opp_enabled = 0; | |
4840 | } | |
ae4dfa57 | 4841 | |
03b2d5e7 | 4842 | PRINT_D(GENERIC_DBG, "P2P Dump\n"); |
c5c77ba1 | 4843 | for (i = 0; i < pu8IEs[index + 7]; i++) |
03b2d5e7 | 4844 | PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]); |
c5c77ba1 | 4845 | |
c21047ed | 4846 | pNewJoinBssParam->cnt = pu8IEs[index + 11]; |
c5c77ba1 JK |
4847 | u16P2P_count = index + 12; |
4848 | ||
109e6cab | 4849 | memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4); |
c5c77ba1 JK |
4850 | u16P2P_count += 4; |
4851 | ||
1d8b76b3 | 4852 | memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4); |
c5c77ba1 JK |
4853 | u16P2P_count += 4; |
4854 | ||
4be55e22 | 4855 | memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4); |
c5c77ba1 JK |
4856 | |
4857 | index += pu8IEs[index + 1] + 2; | |
4858 | continue; | |
4859 | ||
ae4dfa57 | 4860 | } else if ((pu8IEs[index] == RSN_IE) || |
c5c77ba1 JK |
4861 | ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) && |
4862 | (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) && | |
4863 | (pu8IEs[index + 5] == 0x01))) { | |
d85f5326 | 4864 | u16 rsnIndex = index; |
ae4dfa57 | 4865 | |
c5c77ba1 JK |
4866 | if (pu8IEs[rsnIndex] == RSN_IE) { |
4867 | pNewJoinBssParam->mode_802_11i = 2; | |
ae4dfa57 | 4868 | } else { |
c5c77ba1 JK |
4869 | if (pNewJoinBssParam->mode_802_11i == 0) |
4870 | pNewJoinBssParam->mode_802_11i = 1; | |
c5c77ba1 JK |
4871 | rsnIndex += 4; |
4872 | } | |
ae4dfa57 LK |
4873 | |
4874 | rsnIndex += 7; | |
c5c77ba1 JK |
4875 | pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex]; |
4876 | rsnIndex++; | |
ae4dfa57 | 4877 | jumpOffset = pu8IEs[rsnIndex] * 4; |
c5c77ba1 | 4878 | pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex]; |
ae4dfa57 | 4879 | rsnIndex += 2; |
c5c77ba1 | 4880 | |
d1666e2a | 4881 | for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++) |
c5c77ba1 | 4882 | pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1]; |
d1666e2a | 4883 | |
c5c77ba1 JK |
4884 | pcipherTotalCount += pcipherCount; |
4885 | rsnIndex += jumpOffset; | |
4886 | ||
4887 | jumpOffset = pu8IEs[rsnIndex] * 4; | |
4888 | ||
c5c77ba1 | 4889 | authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex]; |
ae4dfa57 | 4890 | rsnIndex += 2; |
c5c77ba1 | 4891 | |
d1666e2a | 4892 | for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++) |
c5c77ba1 | 4893 | pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1]; |
d1666e2a | 4894 | |
c5c77ba1 JK |
4895 | authTotalCount += authCount; |
4896 | rsnIndex += jumpOffset; | |
ae4dfa57 | 4897 | |
c5c77ba1 JK |
4898 | if (pu8IEs[index] == RSN_IE) { |
4899 | pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex]; | |
4900 | pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1]; | |
4901 | rsnIndex += 2; | |
4902 | } | |
f717c0eb | 4903 | pNewJoinBssParam->rsn_found = true; |
ae4dfa57 | 4904 | index += pu8IEs[index + 1] + 2; |
c5c77ba1 JK |
4905 | continue; |
4906 | } else | |
ae4dfa57 | 4907 | index += pu8IEs[index + 1] + 2; |
c5c77ba1 | 4908 | } |
c5c77ba1 JK |
4909 | } |
4910 | ||
4911 | return (void *)pNewJoinBssParam; | |
c5c77ba1 JK |
4912 | } |
4913 | ||
4914 | void host_int_freeJoinParams(void *pJoinParams) | |
4915 | { | |
91109e11 | 4916 | if ((struct bss_param *)pJoinParams) |
e0a12217 | 4917 | kfree((struct bss_param *)pJoinParams); |
c5c77ba1 JK |
4918 | else |
4919 | PRINT_ER("Unable to FREE null pointer\n"); | |
4920 | } | |
c5c77ba1 | 4921 | |
a4ab1ade | 4922 | s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID) |
c5c77ba1 | 4923 | { |
31390eec | 4924 | s32 result = 0; |
143eb95a | 4925 | struct host_if_msg msg; |
c833b474 | 4926 | struct ba_session_info *pBASessionInfo = &msg.body.session_info; |
c5c77ba1 | 4927 | |
a4ab1ade | 4928 | if (!hif_drv) { |
24db713f LK |
4929 | PRINT_ER("driver is null\n"); |
4930 | return -EFAULT; | |
4931 | } | |
c5c77ba1 | 4932 | |
143eb95a | 4933 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4934 | |
a9f812a6 | 4935 | msg.id = HOST_IF_MSG_DEL_BA_SESSION; |
c5c77ba1 | 4936 | |
3fc4999e | 4937 | memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); |
16c9b391 | 4938 | pBASessionInfo->tid = TID; |
a4ab1ade | 4939 | msg.drv = hif_drv; |
c5c77ba1 | 4940 | |
31390eec LK |
4941 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4942 | if (result) | |
24db713f | 4943 | PRINT_ER("wilc_mq_send fail\n"); |
c5c77ba1 | 4944 | |
2d25af87 | 4945 | down(&hif_sema_wait_response); |
c5c77ba1 | 4946 | |
31390eec | 4947 | return result; |
c5c77ba1 JK |
4948 | } |
4949 | ||
a4ab1ade TC |
4950 | s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv, |
4951 | char *pBSSID, | |
4952 | char TID) | |
c5c77ba1 | 4953 | { |
31390eec | 4954 | s32 result = 0; |
143eb95a | 4955 | struct host_if_msg msg; |
c833b474 | 4956 | struct ba_session_info *pBASessionInfo = &msg.body.session_info; |
c5c77ba1 | 4957 | |
a4ab1ade | 4958 | if (!hif_drv) { |
24db713f LK |
4959 | PRINT_ER("driver is null\n"); |
4960 | return -EFAULT; | |
4961 | } | |
c5c77ba1 | 4962 | |
143eb95a | 4963 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4964 | |
a9f812a6 | 4965 | msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS; |
c5c77ba1 | 4966 | |
3fc4999e | 4967 | memcpy(pBASessionInfo->bssid, pBSSID, ETH_ALEN); |
16c9b391 | 4968 | pBASessionInfo->tid = TID; |
a4ab1ade | 4969 | msg.drv = hif_drv; |
c5c77ba1 | 4970 | |
31390eec LK |
4971 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
4972 | if (result) | |
24db713f | 4973 | PRINT_ER("wilc_mq_send fail\n"); |
c5c77ba1 | 4974 | |
2d25af87 | 4975 | down(&hif_sema_wait_response); |
c5c77ba1 | 4976 | |
31390eec | 4977 | return result; |
c5c77ba1 JK |
4978 | } |
4979 | ||
a4ab1ade | 4980 | s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) |
c5c77ba1 | 4981 | { |
31390eec | 4982 | s32 result = 0; |
143eb95a | 4983 | struct host_if_msg msg; |
c5c77ba1 | 4984 | |
c5c77ba1 JK |
4985 | return 0; |
4986 | ||
a4ab1ade | 4987 | if (!hif_drv) { |
24db713f LK |
4988 | PRINT_ER("driver is null\n"); |
4989 | return -EFAULT; | |
4990 | } | |
c5c77ba1 | 4991 | |
143eb95a | 4992 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 4993 | |
a9f812a6 | 4994 | msg.id = HOST_IF_MSG_SET_IPADDRESS; |
c5c77ba1 | 4995 | |
78675be5 | 4996 | msg.body.ip_info.ip_addr = u16ipadd; |
a4ab1ade | 4997 | msg.drv = hif_drv; |
fb2d65ed | 4998 | msg.body.ip_info.idx = idx; |
c5c77ba1 | 4999 | |
31390eec LK |
5000 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
5001 | if (result) | |
24db713f | 5002 | PRINT_ER("wilc_mq_send fail\n"); |
c5c77ba1 | 5003 | |
31390eec | 5004 | return result; |
c5c77ba1 JK |
5005 | } |
5006 | ||
a4ab1ade | 5007 | s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx) |
c5c77ba1 | 5008 | { |
31390eec | 5009 | s32 result = 0; |
143eb95a | 5010 | struct host_if_msg msg; |
c5c77ba1 | 5011 | |
a4ab1ade | 5012 | if (!hif_drv) { |
24db713f LK |
5013 | PRINT_ER("driver is null\n"); |
5014 | return -EFAULT; | |
5015 | } | |
c5c77ba1 | 5016 | |
143eb95a | 5017 | memset(&msg, 0, sizeof(struct host_if_msg)); |
c5c77ba1 | 5018 | |
a9f812a6 | 5019 | msg.id = HOST_IF_MSG_GET_IPADDRESS; |
c5c77ba1 | 5020 | |
78675be5 | 5021 | msg.body.ip_info.ip_addr = u16ipadd; |
a4ab1ade | 5022 | msg.drv = hif_drv; |
fb2d65ed | 5023 | msg.body.ip_info.idx = idx; |
c5c77ba1 | 5024 | |
31390eec LK |
5025 | result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg)); |
5026 | if (result) | |
24db713f | 5027 | PRINT_ER("wilc_mq_send fail\n"); |
c5c77ba1 | 5028 | |
31390eec | 5029 | return result; |
c5c77ba1 | 5030 | } |