PageRenderTime 119ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/staging/wilc1000/host_interface.c

https://bitbucket.org/orzel/linux-kernel-stable
C | 4116 lines | 3331 code | 776 blank | 9 comment | 521 complexity | 2daf8027466b3004369df4a4936927b9 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. #include <linux/slab.h>
  2. #include <linux/time.h>
  3. #include <linux/kthread.h>
  4. #include <linux/delay.h>
  5. #include <linux/completion.h>
  6. #include "host_interface.h"
  7. #include "coreconfigurator.h"
  8. #include "wilc_wlan.h"
  9. #include "wilc_wlan_if.h"
  10. #include "wilc_msgqueue.h"
  11. #include <linux/etherdevice.h>
  12. #include "wilc_wfi_netdevice.h"
  13. #define HOST_IF_MSG_SCAN 0
  14. #define HOST_IF_MSG_CONNECT 1
  15. #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
  16. #define HOST_IF_MSG_KEY 3
  17. #define HOST_IF_MSG_RCVD_NTWRK_INFO 4
  18. #define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
  19. #define HOST_IF_MSG_CFG_PARAMS 6
  20. #define HOST_IF_MSG_SET_CHANNEL 7
  21. #define HOST_IF_MSG_DISCONNECT 8
  22. #define HOST_IF_MSG_GET_RSSI 9
  23. #define HOST_IF_MSG_ADD_BEACON 11
  24. #define HOST_IF_MSG_DEL_BEACON 12
  25. #define HOST_IF_MSG_ADD_STATION 13
  26. #define HOST_IF_MSG_DEL_STATION 14
  27. #define HOST_IF_MSG_EDIT_STATION 15
  28. #define HOST_IF_MSG_SCAN_TIMER_FIRED 16
  29. #define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
  30. #define HOST_IF_MSG_POWER_MGMT 18
  31. #define HOST_IF_MSG_GET_INACTIVETIME 19
  32. #define HOST_IF_MSG_REMAIN_ON_CHAN 20
  33. #define HOST_IF_MSG_REGISTER_FRAME 21
  34. #define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
  35. #define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
  36. #define HOST_IF_MSG_GET_MAC_ADDRESS 26
  37. #define HOST_IF_MSG_SET_OPERATION_MODE 27
  38. #define HOST_IF_MSG_SET_IPADDRESS 28
  39. #define HOST_IF_MSG_GET_IPADDRESS 29
  40. #define HOST_IF_MSG_GET_STATISTICS 31
  41. #define HOST_IF_MSG_SET_MULTICAST_FILTER 32
  42. #define HOST_IF_MSG_DEL_BA_SESSION 34
  43. #define HOST_IF_MSG_DEL_ALL_STA 36
  44. #define HOST_IF_MSG_SET_TX_POWER 38
  45. #define HOST_IF_MSG_GET_TX_POWER 39
  46. #define HOST_IF_MSG_EXIT 100
  47. #define HOST_IF_SCAN_TIMEOUT 4000
  48. #define HOST_IF_CONNECT_TIMEOUT 9500
  49. #define BA_SESSION_DEFAULT_BUFFER_SIZE 16
  50. #define BA_SESSION_DEFAULT_TIMEOUT 1000
  51. #define BLOCK_ACK_REQ_SIZE 0x14
  52. #define FALSE_FRMWR_CHANNEL 100
  53. #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
  54. #define DEFAULT_LINK_SPEED 72
  55. struct host_if_wpa_attr {
  56. u8 *key;
  57. const u8 *mac_addr;
  58. u8 *seq;
  59. u8 seq_len;
  60. u8 index;
  61. u8 key_len;
  62. u8 mode;
  63. };
  64. struct host_if_wep_attr {
  65. u8 *key;
  66. u8 key_len;
  67. u8 index;
  68. u8 mode;
  69. enum AUTHTYPE auth_type;
  70. };
  71. union host_if_key_attr {
  72. struct host_if_wep_attr wep;
  73. struct host_if_wpa_attr wpa;
  74. struct host_if_pmkid_attr pmkid;
  75. };
  76. struct key_attr {
  77. enum KEY_TYPE type;
  78. u8 action;
  79. union host_if_key_attr attr;
  80. };
  81. struct scan_attr {
  82. u8 src;
  83. u8 type;
  84. u8 *ch_freq_list;
  85. u8 ch_list_len;
  86. u8 *ies;
  87. size_t ies_len;
  88. wilc_scan_result result;
  89. void *arg;
  90. struct hidden_network hidden_network;
  91. };
  92. struct connect_attr {
  93. u8 *bssid;
  94. u8 *ssid;
  95. size_t ssid_len;
  96. u8 *ies;
  97. size_t ies_len;
  98. u8 security;
  99. wilc_connect_result result;
  100. void *arg;
  101. enum AUTHTYPE auth_type;
  102. u8 ch;
  103. void *params;
  104. };
  105. struct rcvd_async_info {
  106. u8 *buffer;
  107. u32 len;
  108. };
  109. struct channel_attr {
  110. u8 set_ch;
  111. };
  112. struct beacon_attr {
  113. u32 interval;
  114. u32 dtim_period;
  115. u32 head_len;
  116. u8 *head;
  117. u32 tail_len;
  118. u8 *tail;
  119. };
  120. struct set_multicast {
  121. bool enabled;
  122. u32 cnt;
  123. };
  124. struct del_all_sta {
  125. u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
  126. u8 assoc_sta;
  127. };
  128. struct del_sta {
  129. u8 mac_addr[ETH_ALEN];
  130. };
  131. struct power_mgmt_param {
  132. bool enabled;
  133. u32 timeout;
  134. };
  135. struct set_ip_addr {
  136. u8 *ip_addr;
  137. u8 idx;
  138. };
  139. struct sta_inactive_t {
  140. u8 mac[6];
  141. };
  142. struct tx_power {
  143. u8 tx_pwr;
  144. };
  145. union message_body {
  146. struct scan_attr scan_info;
  147. struct connect_attr con_info;
  148. struct rcvd_net_info net_info;
  149. struct rcvd_async_info async_info;
  150. struct key_attr key_info;
  151. struct cfg_param_attr cfg_info;
  152. struct channel_attr channel_info;
  153. struct beacon_attr beacon_info;
  154. struct add_sta_param add_sta_info;
  155. struct del_sta del_sta_info;
  156. struct add_sta_param edit_sta_info;
  157. struct power_mgmt_param pwr_mgmt_info;
  158. struct sta_inactive_t mac_info;
  159. struct set_ip_addr ip_info;
  160. struct drv_handler drv;
  161. struct set_multicast multicast_info;
  162. struct op_mode mode;
  163. struct set_mac_addr set_mac_info;
  164. struct get_mac_addr get_mac_info;
  165. struct ba_session_info session_info;
  166. struct remain_ch remain_on_ch;
  167. struct reg_frame reg_frame;
  168. char *data;
  169. struct del_all_sta del_all_sta_info;
  170. struct tx_power tx_power;
  171. };
  172. struct host_if_msg {
  173. u16 id;
  174. union message_body body;
  175. struct wilc_vif *vif;
  176. };
  177. struct join_bss_param {
  178. BSSTYPE_T bss_type;
  179. u8 dtim_period;
  180. u16 beacon_period;
  181. u16 cap_info;
  182. u8 bssid[6];
  183. char ssid[MAX_SSID_LEN];
  184. u8 ssid_len;
  185. u8 supp_rates[MAX_RATES_SUPPORTED + 1];
  186. u8 ht_capable;
  187. u8 wmm_cap;
  188. u8 uapsd_cap;
  189. bool rsn_found;
  190. u8 rsn_grp_policy;
  191. u8 mode_802_11i;
  192. u8 rsn_pcip_policy[3];
  193. u8 rsn_auth_policy[3];
  194. u8 rsn_cap[2];
  195. u32 tsf;
  196. u8 noa_enabled;
  197. u8 opp_enabled;
  198. u8 ct_window;
  199. u8 cnt;
  200. u8 idx;
  201. u8 duration[4];
  202. u8 interval[4];
  203. u8 start_time[4];
  204. };
  205. static struct host_if_drv *terminated_handle;
  206. bool wilc_optaining_ip;
  207. static u8 P2P_LISTEN_STATE;
  208. static struct task_struct *hif_thread_handler;
  209. static struct message_queue hif_msg_q;
  210. static struct completion hif_thread_comp;
  211. static struct completion hif_driver_comp;
  212. static struct completion hif_wait_response;
  213. static struct mutex hif_deinit_lock;
  214. static struct timer_list periodic_rssi;
  215. u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
  216. static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
  217. static bool scan_while_connected;
  218. static s8 rssi;
  219. static u8 set_ip[2][4];
  220. static u8 get_ip[2][4];
  221. static u32 inactive_time;
  222. static u8 del_beacon;
  223. static u32 clients_count;
  224. static u8 *join_req;
  225. static u8 *info_element;
  226. static u8 mode_11i;
  227. static u8 auth_type;
  228. static u32 join_req_size;
  229. static u32 info_element_size;
  230. static struct wilc_vif *join_req_vif;
  231. #define REAL_JOIN_REQ 0
  232. #define FLUSHED_JOIN_REQ 1
  233. #define FLUSHED_BYTE_POS 79
  234. static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
  235. static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
  236. static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
  237. /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
  238. * special purpose in wilc device, so we add 1 to the index to starts from 1.
  239. * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
  240. */
  241. int wilc_get_vif_idx(struct wilc_vif *vif)
  242. {
  243. return vif->idx + 1;
  244. }
  245. /* We need to minus 1 from idx which is from wilc device to get real index
  246. * of wilc->vif[], because we add 1 when pass to wilc device in the function
  247. * wilc_get_vif_idx.
  248. * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
  249. */
  250. static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
  251. {
  252. int index = idx - 1;
  253. if (index < 0 || index >= NUM_CONCURRENT_IFC)
  254. return NULL;
  255. return wilc->vif[index];
  256. }
  257. static void handle_set_channel(struct wilc_vif *vif,
  258. struct channel_attr *hif_set_ch)
  259. {
  260. int ret = 0;
  261. struct wid wid;
  262. wid.id = (u16)WID_CURRENT_CHANNEL;
  263. wid.type = WID_CHAR;
  264. wid.val = (char *)&hif_set_ch->set_ch;
  265. wid.size = sizeof(char);
  266. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  267. wilc_get_vif_idx(vif));
  268. if (ret)
  269. netdev_err(vif->ndev, "Failed to set channel\n");
  270. }
  271. static void handle_set_wfi_drv_handler(struct wilc_vif *vif,
  272. struct drv_handler *hif_drv_handler)
  273. {
  274. int ret = 0;
  275. struct wid wid;
  276. wid.id = (u16)WID_SET_DRV_HANDLER;
  277. wid.type = WID_STR;
  278. wid.val = (s8 *)hif_drv_handler;
  279. wid.size = sizeof(*hif_drv_handler);
  280. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  281. hif_drv_handler->handler);
  282. if (!hif_drv_handler->handler)
  283. complete(&hif_driver_comp);
  284. if (ret)
  285. netdev_err(vif->ndev, "Failed to set driver handler\n");
  286. }
  287. static void handle_set_operation_mode(struct wilc_vif *vif,
  288. struct op_mode *hif_op_mode)
  289. {
  290. int ret = 0;
  291. struct wid wid;
  292. wid.id = (u16)WID_SET_OPERATION_MODE;
  293. wid.type = WID_INT;
  294. wid.val = (s8 *)&hif_op_mode->mode;
  295. wid.size = sizeof(u32);
  296. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  297. wilc_get_vif_idx(vif));
  298. if ((hif_op_mode->mode) == IDLE_MODE)
  299. complete(&hif_driver_comp);
  300. if (ret)
  301. netdev_err(vif->ndev, "Failed to set driver handler\n");
  302. }
  303. static void handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
  304. {
  305. int ret = 0;
  306. struct wid wid;
  307. char firmware_ip_addr[4] = {0};
  308. if (ip_addr[0] < 192)
  309. ip_addr[0] = 0;
  310. memcpy(set_ip[idx], ip_addr, IP_ALEN);
  311. wid.id = (u16)WID_IP_ADDRESS;
  312. wid.type = WID_STR;
  313. wid.val = (u8 *)ip_addr;
  314. wid.size = IP_ALEN;
  315. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  316. wilc_get_vif_idx(vif));
  317. host_int_get_ipaddress(vif, firmware_ip_addr, idx);
  318. if (ret)
  319. netdev_err(vif->ndev, "Failed to set IP address\n");
  320. }
  321. static void handle_get_ip_address(struct wilc_vif *vif, u8 idx)
  322. {
  323. int ret = 0;
  324. struct wid wid;
  325. wid.id = (u16)WID_IP_ADDRESS;
  326. wid.type = WID_STR;
  327. wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
  328. wid.size = IP_ALEN;
  329. ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  330. wilc_get_vif_idx(vif));
  331. memcpy(get_ip[idx], wid.val, IP_ALEN);
  332. kfree(wid.val);
  333. if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
  334. wilc_setup_ipaddress(vif, set_ip[idx], idx);
  335. if (ret)
  336. netdev_err(vif->ndev, "Failed to get IP address\n");
  337. }
  338. static void handle_get_mac_address(struct wilc_vif *vif,
  339. struct get_mac_addr *get_mac_addr)
  340. {
  341. int ret = 0;
  342. struct wid wid;
  343. wid.id = (u16)WID_MAC_ADDR;
  344. wid.type = WID_STR;
  345. wid.val = get_mac_addr->mac_addr;
  346. wid.size = ETH_ALEN;
  347. ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  348. wilc_get_vif_idx(vif));
  349. if (ret)
  350. netdev_err(vif->ndev, "Failed to get mac address\n");
  351. complete(&hif_wait_response);
  352. }
  353. static s32 handle_cfg_param(struct wilc_vif *vif,
  354. struct cfg_param_attr *cfg_param_attr)
  355. {
  356. s32 result = 0;
  357. struct wid wid_list[32];
  358. struct host_if_drv *hif_drv = vif->hif_drv;
  359. int i = 0;
  360. mutex_lock(&hif_drv->cfg_values_lock);
  361. if (cfg_param_attr->flag & BSS_TYPE) {
  362. if (cfg_param_attr->bss_type < 6) {
  363. wid_list[i].id = WID_BSS_TYPE;
  364. wid_list[i].val = (s8 *)&cfg_param_attr->bss_type;
  365. wid_list[i].type = WID_CHAR;
  366. wid_list[i].size = sizeof(char);
  367. hif_drv->cfg_values.bss_type = (u8)cfg_param_attr->bss_type;
  368. } else {
  369. netdev_err(vif->ndev, "check value 6 over\n");
  370. result = -EINVAL;
  371. goto unlock;
  372. }
  373. i++;
  374. }
  375. if (cfg_param_attr->flag & AUTH_TYPE) {
  376. if (cfg_param_attr->auth_type == 1 ||
  377. cfg_param_attr->auth_type == 2 ||
  378. cfg_param_attr->auth_type == 5) {
  379. wid_list[i].id = WID_AUTH_TYPE;
  380. wid_list[i].val = (s8 *)&cfg_param_attr->auth_type;
  381. wid_list[i].type = WID_CHAR;
  382. wid_list[i].size = sizeof(char);
  383. hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->auth_type;
  384. } else {
  385. netdev_err(vif->ndev, "Impossible value\n");
  386. result = -EINVAL;
  387. goto unlock;
  388. }
  389. i++;
  390. }
  391. if (cfg_param_attr->flag & AUTHEN_TIMEOUT) {
  392. if (cfg_param_attr->auth_timeout > 0 &&
  393. cfg_param_attr->auth_timeout < 65536) {
  394. wid_list[i].id = WID_AUTH_TIMEOUT;
  395. wid_list[i].val = (s8 *)&cfg_param_attr->auth_timeout;
  396. wid_list[i].type = WID_SHORT;
  397. wid_list[i].size = sizeof(u16);
  398. hif_drv->cfg_values.auth_timeout = cfg_param_attr->auth_timeout;
  399. } else {
  400. netdev_err(vif->ndev, "Range(1 ~ 65535) over\n");
  401. result = -EINVAL;
  402. goto unlock;
  403. }
  404. i++;
  405. }
  406. if (cfg_param_attr->flag & POWER_MANAGEMENT) {
  407. if (cfg_param_attr->power_mgmt_mode < 5) {
  408. wid_list[i].id = WID_POWER_MANAGEMENT;
  409. wid_list[i].val = (s8 *)&cfg_param_attr->power_mgmt_mode;
  410. wid_list[i].type = WID_CHAR;
  411. wid_list[i].size = sizeof(char);
  412. hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->power_mgmt_mode;
  413. } else {
  414. netdev_err(vif->ndev, "Invalid power mode\n");
  415. result = -EINVAL;
  416. goto unlock;
  417. }
  418. i++;
  419. }
  420. if (cfg_param_attr->flag & RETRY_SHORT) {
  421. if (cfg_param_attr->short_retry_limit > 0 &&
  422. cfg_param_attr->short_retry_limit < 256) {
  423. wid_list[i].id = WID_SHORT_RETRY_LIMIT;
  424. wid_list[i].val = (s8 *)&cfg_param_attr->short_retry_limit;
  425. wid_list[i].type = WID_SHORT;
  426. wid_list[i].size = sizeof(u16);
  427. hif_drv->cfg_values.short_retry_limit = cfg_param_attr->short_retry_limit;
  428. } else {
  429. netdev_err(vif->ndev, "Range(1~256) over\n");
  430. result = -EINVAL;
  431. goto unlock;
  432. }
  433. i++;
  434. }
  435. if (cfg_param_attr->flag & RETRY_LONG) {
  436. if (cfg_param_attr->long_retry_limit > 0 &&
  437. cfg_param_attr->long_retry_limit < 256) {
  438. wid_list[i].id = WID_LONG_RETRY_LIMIT;
  439. wid_list[i].val = (s8 *)&cfg_param_attr->long_retry_limit;
  440. wid_list[i].type = WID_SHORT;
  441. wid_list[i].size = sizeof(u16);
  442. hif_drv->cfg_values.long_retry_limit = cfg_param_attr->long_retry_limit;
  443. } else {
  444. netdev_err(vif->ndev, "Range(1~256) over\n");
  445. result = -EINVAL;
  446. goto unlock;
  447. }
  448. i++;
  449. }
  450. if (cfg_param_attr->flag & FRAG_THRESHOLD) {
  451. if (cfg_param_attr->frag_threshold > 255 &&
  452. cfg_param_attr->frag_threshold < 7937) {
  453. wid_list[i].id = WID_FRAG_THRESHOLD;
  454. wid_list[i].val = (s8 *)&cfg_param_attr->frag_threshold;
  455. wid_list[i].type = WID_SHORT;
  456. wid_list[i].size = sizeof(u16);
  457. hif_drv->cfg_values.frag_threshold = cfg_param_attr->frag_threshold;
  458. } else {
  459. netdev_err(vif->ndev, "Threshold Range fail\n");
  460. result = -EINVAL;
  461. goto unlock;
  462. }
  463. i++;
  464. }
  465. if (cfg_param_attr->flag & RTS_THRESHOLD) {
  466. if (cfg_param_attr->rts_threshold > 255 &&
  467. cfg_param_attr->rts_threshold < 65536) {
  468. wid_list[i].id = WID_RTS_THRESHOLD;
  469. wid_list[i].val = (s8 *)&cfg_param_attr->rts_threshold;
  470. wid_list[i].type = WID_SHORT;
  471. wid_list[i].size = sizeof(u16);
  472. hif_drv->cfg_values.rts_threshold = cfg_param_attr->rts_threshold;
  473. } else {
  474. netdev_err(vif->ndev, "Threshold Range fail\n");
  475. result = -EINVAL;
  476. goto unlock;
  477. }
  478. i++;
  479. }
  480. if (cfg_param_attr->flag & PREAMBLE) {
  481. if (cfg_param_attr->preamble_type < 3) {
  482. wid_list[i].id = WID_PREAMBLE;
  483. wid_list[i].val = (s8 *)&cfg_param_attr->preamble_type;
  484. wid_list[i].type = WID_CHAR;
  485. wid_list[i].size = sizeof(char);
  486. hif_drv->cfg_values.preamble_type = cfg_param_attr->preamble_type;
  487. } else {
  488. netdev_err(vif->ndev, "Preamle Range(0~2) over\n");
  489. result = -EINVAL;
  490. goto unlock;
  491. }
  492. i++;
  493. }
  494. if (cfg_param_attr->flag & SHORT_SLOT_ALLOWED) {
  495. if (cfg_param_attr->short_slot_allowed < 2) {
  496. wid_list[i].id = WID_SHORT_SLOT_ALLOWED;
  497. wid_list[i].val = (s8 *)&cfg_param_attr->short_slot_allowed;
  498. wid_list[i].type = WID_CHAR;
  499. wid_list[i].size = sizeof(char);
  500. hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->short_slot_allowed;
  501. } else {
  502. netdev_err(vif->ndev, "Short slot(2) over\n");
  503. result = -EINVAL;
  504. goto unlock;
  505. }
  506. i++;
  507. }
  508. if (cfg_param_attr->flag & TXOP_PROT_DISABLE) {
  509. if (cfg_param_attr->txop_prot_disabled < 2) {
  510. wid_list[i].id = WID_11N_TXOP_PROT_DISABLE;
  511. wid_list[i].val = (s8 *)&cfg_param_attr->txop_prot_disabled;
  512. wid_list[i].type = WID_CHAR;
  513. wid_list[i].size = sizeof(char);
  514. hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->txop_prot_disabled;
  515. } else {
  516. netdev_err(vif->ndev, "TXOP prot disable\n");
  517. result = -EINVAL;
  518. goto unlock;
  519. }
  520. i++;
  521. }
  522. if (cfg_param_attr->flag & BEACON_INTERVAL) {
  523. if (cfg_param_attr->beacon_interval > 0 &&
  524. cfg_param_attr->beacon_interval < 65536) {
  525. wid_list[i].id = WID_BEACON_INTERVAL;
  526. wid_list[i].val = (s8 *)&cfg_param_attr->beacon_interval;
  527. wid_list[i].type = WID_SHORT;
  528. wid_list[i].size = sizeof(u16);
  529. hif_drv->cfg_values.beacon_interval = cfg_param_attr->beacon_interval;
  530. } else {
  531. netdev_err(vif->ndev, "Beacon interval(1~65535)fail\n");
  532. result = -EINVAL;
  533. goto unlock;
  534. }
  535. i++;
  536. }
  537. if (cfg_param_attr->flag & DTIM_PERIOD) {
  538. if (cfg_param_attr->dtim_period > 0 &&
  539. cfg_param_attr->dtim_period < 256) {
  540. wid_list[i].id = WID_DTIM_PERIOD;
  541. wid_list[i].val = (s8 *)&cfg_param_attr->dtim_period;
  542. wid_list[i].type = WID_CHAR;
  543. wid_list[i].size = sizeof(char);
  544. hif_drv->cfg_values.dtim_period = cfg_param_attr->dtim_period;
  545. } else {
  546. netdev_err(vif->ndev, "DTIM range(1~255) fail\n");
  547. result = -EINVAL;
  548. goto unlock;
  549. }
  550. i++;
  551. }
  552. if (cfg_param_attr->flag & SITE_SURVEY) {
  553. if (cfg_param_attr->site_survey_enabled < 3) {
  554. wid_list[i].id = WID_SITE_SURVEY;
  555. wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_enabled;
  556. wid_list[i].type = WID_CHAR;
  557. wid_list[i].size = sizeof(char);
  558. hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->site_survey_enabled;
  559. } else {
  560. netdev_err(vif->ndev, "Site survey disable\n");
  561. result = -EINVAL;
  562. goto unlock;
  563. }
  564. i++;
  565. }
  566. if (cfg_param_attr->flag & SITE_SURVEY_SCAN_TIME) {
  567. if (cfg_param_attr->site_survey_scan_time > 0 &&
  568. cfg_param_attr->site_survey_scan_time < 65536) {
  569. wid_list[i].id = WID_SITE_SURVEY_SCAN_TIME;
  570. wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_scan_time;
  571. wid_list[i].type = WID_SHORT;
  572. wid_list[i].size = sizeof(u16);
  573. hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->site_survey_scan_time;
  574. } else {
  575. netdev_err(vif->ndev, "Site scan time(1~65535) over\n");
  576. result = -EINVAL;
  577. goto unlock;
  578. }
  579. i++;
  580. }
  581. if (cfg_param_attr->flag & ACTIVE_SCANTIME) {
  582. if (cfg_param_attr->active_scan_time > 0 &&
  583. cfg_param_attr->active_scan_time < 65536) {
  584. wid_list[i].id = WID_ACTIVE_SCAN_TIME;
  585. wid_list[i].val = (s8 *)&cfg_param_attr->active_scan_time;
  586. wid_list[i].type = WID_SHORT;
  587. wid_list[i].size = sizeof(u16);
  588. hif_drv->cfg_values.active_scan_time = cfg_param_attr->active_scan_time;
  589. } else {
  590. netdev_err(vif->ndev, "Active time(1~65535) over\n");
  591. result = -EINVAL;
  592. goto unlock;
  593. }
  594. i++;
  595. }
  596. if (cfg_param_attr->flag & PASSIVE_SCANTIME) {
  597. if (cfg_param_attr->passive_scan_time > 0 &&
  598. cfg_param_attr->passive_scan_time < 65536) {
  599. wid_list[i].id = WID_PASSIVE_SCAN_TIME;
  600. wid_list[i].val = (s8 *)&cfg_param_attr->passive_scan_time;
  601. wid_list[i].type = WID_SHORT;
  602. wid_list[i].size = sizeof(u16);
  603. hif_drv->cfg_values.passive_scan_time = cfg_param_attr->passive_scan_time;
  604. } else {
  605. netdev_err(vif->ndev, "Passive time(1~65535) over\n");
  606. result = -EINVAL;
  607. goto unlock;
  608. }
  609. i++;
  610. }
  611. if (cfg_param_attr->flag & CURRENT_TX_RATE) {
  612. enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->curr_tx_rate;
  613. if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 ||
  614. curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 ||
  615. curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 ||
  616. curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 ||
  617. curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 ||
  618. curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 ||
  619. curr_tx_rate == MBPS_54) {
  620. wid_list[i].id = WID_CURRENT_TX_RATE;
  621. wid_list[i].val = (s8 *)&curr_tx_rate;
  622. wid_list[i].type = WID_SHORT;
  623. wid_list[i].size = sizeof(u16);
  624. hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate;
  625. } else {
  626. netdev_err(vif->ndev, "out of TX rate\n");
  627. result = -EINVAL;
  628. goto unlock;
  629. }
  630. i++;
  631. }
  632. result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
  633. i, wilc_get_vif_idx(vif));
  634. if (result)
  635. netdev_err(vif->ndev, "Error in setting CFG params\n");
  636. unlock:
  637. mutex_unlock(&hif_drv->cfg_values_lock);
  638. return result;
  639. }
  640. static s32 handle_scan(struct wilc_vif *vif, struct scan_attr *scan_info)
  641. {
  642. s32 result = 0;
  643. struct wid wid_list[5];
  644. u32 index = 0;
  645. u32 i;
  646. u8 *buffer;
  647. u8 valuesize = 0;
  648. u8 *pu8HdnNtwrksWidVal = NULL;
  649. struct host_if_drv *hif_drv = vif->hif_drv;
  650. hif_drv->usr_scan_req.scan_result = scan_info->result;
  651. hif_drv->usr_scan_req.arg = scan_info->arg;
  652. if ((hif_drv->hif_state >= HOST_IF_SCANNING) &&
  653. (hif_drv->hif_state < HOST_IF_CONNECTED)) {
  654. netdev_err(vif->ndev, "Already scan\n");
  655. result = -EBUSY;
  656. goto ERRORHANDLER;
  657. }
  658. if (wilc_optaining_ip || wilc_connecting) {
  659. netdev_err(vif->ndev, "Don't do obss scan\n");
  660. result = -EBUSY;
  661. goto ERRORHANDLER;
  662. }
  663. hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
  664. wid_list[index].id = (u16)WID_SSID_PROBE_REQ;
  665. wid_list[index].type = WID_STR;
  666. for (i = 0; i < scan_info->hidden_network.n_ssids; i++)
  667. valuesize += ((scan_info->hidden_network.net_info[i].ssid_len) + 1);
  668. pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
  669. wid_list[index].val = pu8HdnNtwrksWidVal;
  670. if (wid_list[index].val) {
  671. buffer = wid_list[index].val;
  672. *buffer++ = scan_info->hidden_network.n_ssids;
  673. for (i = 0; i < scan_info->hidden_network.n_ssids; i++) {
  674. *buffer++ = scan_info->hidden_network.net_info[i].ssid_len;
  675. memcpy(buffer, scan_info->hidden_network.net_info[i].ssid, scan_info->hidden_network.net_info[i].ssid_len);
  676. buffer += scan_info->hidden_network.net_info[i].ssid_len;
  677. }
  678. wid_list[index].size = (s32)(valuesize + 1);
  679. index++;
  680. }
  681. wid_list[index].id = WID_INFO_ELEMENT_PROBE;
  682. wid_list[index].type = WID_BIN_DATA;
  683. wid_list[index].val = scan_info->ies;
  684. wid_list[index].size = scan_info->ies_len;
  685. index++;
  686. wid_list[index].id = WID_SCAN_TYPE;
  687. wid_list[index].type = WID_CHAR;
  688. wid_list[index].size = sizeof(char);
  689. wid_list[index].val = (s8 *)&scan_info->type;
  690. index++;
  691. wid_list[index].id = WID_SCAN_CHANNEL_LIST;
  692. wid_list[index].type = WID_BIN_DATA;
  693. if (scan_info->ch_freq_list &&
  694. scan_info->ch_list_len > 0) {
  695. int i;
  696. for (i = 0; i < scan_info->ch_list_len; i++) {
  697. if (scan_info->ch_freq_list[i] > 0)
  698. scan_info->ch_freq_list[i] = scan_info->ch_freq_list[i] - 1;
  699. }
  700. }
  701. wid_list[index].val = scan_info->ch_freq_list;
  702. wid_list[index].size = scan_info->ch_list_len;
  703. index++;
  704. wid_list[index].id = WID_START_SCAN_REQ;
  705. wid_list[index].type = WID_CHAR;
  706. wid_list[index].size = sizeof(char);
  707. wid_list[index].val = (s8 *)&scan_info->src;
  708. index++;
  709. if (hif_drv->hif_state == HOST_IF_CONNECTED)
  710. scan_while_connected = true;
  711. else if (hif_drv->hif_state == HOST_IF_IDLE)
  712. scan_while_connected = false;
  713. result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
  714. index,
  715. wilc_get_vif_idx(vif));
  716. if (result)
  717. netdev_err(vif->ndev, "Failed to send scan parameters\n");
  718. ERRORHANDLER:
  719. if (result) {
  720. del_timer(&hif_drv->scan_timer);
  721. Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
  722. }
  723. kfree(scan_info->ch_freq_list);
  724. scan_info->ch_freq_list = NULL;
  725. kfree(scan_info->ies);
  726. scan_info->ies = NULL;
  727. kfree(scan_info->hidden_network.net_info);
  728. scan_info->hidden_network.net_info = NULL;
  729. kfree(pu8HdnNtwrksWidVal);
  730. return result;
  731. }
  732. static s32 Handle_ScanDone(struct wilc_vif *vif,
  733. enum scan_event enuEvent)
  734. {
  735. s32 result = 0;
  736. u8 u8abort_running_scan;
  737. struct wid wid;
  738. struct host_if_drv *hif_drv = vif->hif_drv;
  739. if (enuEvent == SCAN_EVENT_ABORTED) {
  740. u8abort_running_scan = 1;
  741. wid.id = (u16)WID_ABORT_RUNNING_SCAN;
  742. wid.type = WID_CHAR;
  743. wid.val = (s8 *)&u8abort_running_scan;
  744. wid.size = sizeof(char);
  745. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  746. wilc_get_vif_idx(vif));
  747. if (result) {
  748. netdev_err(vif->ndev, "Failed to set abort running\n");
  749. result = -EFAULT;
  750. }
  751. }
  752. if (!hif_drv) {
  753. netdev_err(vif->ndev, "Driver handler is NULL\n");
  754. return result;
  755. }
  756. if (hif_drv->usr_scan_req.scan_result) {
  757. hif_drv->usr_scan_req.scan_result(enuEvent, NULL,
  758. hif_drv->usr_scan_req.arg, NULL);
  759. hif_drv->usr_scan_req.scan_result = NULL;
  760. }
  761. return result;
  762. }
  763. u8 wilc_connected_ssid[6] = {0};
  764. static s32 Handle_Connect(struct wilc_vif *vif,
  765. struct connect_attr *pstrHostIFconnectAttr)
  766. {
  767. s32 result = 0;
  768. struct wid strWIDList[8];
  769. u32 u32WidsCount = 0, dummyval = 0;
  770. u8 *pu8CurrByte = NULL;
  771. struct join_bss_param *ptstrJoinBssParam;
  772. struct host_if_drv *hif_drv = vif->hif_drv;
  773. if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
  774. result = 0;
  775. netdev_err(vif->ndev, "Discard connect request\n");
  776. return result;
  777. }
  778. ptstrJoinBssParam = pstrHostIFconnectAttr->params;
  779. if (!ptstrJoinBssParam) {
  780. netdev_err(vif->ndev, "Required BSSID not found\n");
  781. result = -ENOENT;
  782. goto ERRORHANDLER;
  783. }
  784. if (pstrHostIFconnectAttr->bssid) {
  785. hif_drv->usr_conn_req.bssid = kmalloc(6, GFP_KERNEL);
  786. memcpy(hif_drv->usr_conn_req.bssid, pstrHostIFconnectAttr->bssid, 6);
  787. }
  788. hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len;
  789. if (pstrHostIFconnectAttr->ssid) {
  790. hif_drv->usr_conn_req.ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
  791. memcpy(hif_drv->usr_conn_req.ssid,
  792. pstrHostIFconnectAttr->ssid,
  793. pstrHostIFconnectAttr->ssid_len);
  794. hif_drv->usr_conn_req.ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
  795. }
  796. hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len;
  797. if (pstrHostIFconnectAttr->ies) {
  798. hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
  799. memcpy(hif_drv->usr_conn_req.ies,
  800. pstrHostIFconnectAttr->ies,
  801. pstrHostIFconnectAttr->ies_len);
  802. }
  803. hif_drv->usr_conn_req.security = pstrHostIFconnectAttr->security;
  804. hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type;
  805. hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result;
  806. hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg;
  807. strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
  808. strWIDList[u32WidsCount].type = WID_INT;
  809. strWIDList[u32WidsCount].size = sizeof(u32);
  810. strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
  811. u32WidsCount++;
  812. strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
  813. strWIDList[u32WidsCount].type = WID_INT;
  814. strWIDList[u32WidsCount].size = sizeof(u32);
  815. strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
  816. u32WidsCount++;
  817. strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
  818. strWIDList[u32WidsCount].type = WID_INT;
  819. strWIDList[u32WidsCount].size = sizeof(u32);
  820. strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
  821. u32WidsCount++;
  822. {
  823. strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
  824. strWIDList[u32WidsCount].type = WID_BIN_DATA;
  825. strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies;
  826. strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len;
  827. u32WidsCount++;
  828. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
  829. info_element_size = hif_drv->usr_conn_req.ies_len;
  830. info_element = kmalloc(info_element_size, GFP_KERNEL);
  831. memcpy(info_element, hif_drv->usr_conn_req.ies,
  832. info_element_size);
  833. }
  834. }
  835. strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
  836. strWIDList[u32WidsCount].type = WID_CHAR;
  837. strWIDList[u32WidsCount].size = sizeof(char);
  838. strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.security;
  839. u32WidsCount++;
  840. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
  841. mode_11i = hif_drv->usr_conn_req.security;
  842. strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
  843. strWIDList[u32WidsCount].type = WID_CHAR;
  844. strWIDList[u32WidsCount].size = sizeof(char);
  845. strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
  846. u32WidsCount++;
  847. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
  848. auth_type = (u8)hif_drv->usr_conn_req.auth_type;
  849. strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
  850. strWIDList[u32WidsCount].type = WID_STR;
  851. strWIDList[u32WidsCount].size = 112;
  852. strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
  853. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
  854. join_req_size = strWIDList[u32WidsCount].size;
  855. join_req = kmalloc(join_req_size, GFP_KERNEL);
  856. }
  857. if (!strWIDList[u32WidsCount].val) {
  858. result = -EFAULT;
  859. goto ERRORHANDLER;
  860. }
  861. pu8CurrByte = strWIDList[u32WidsCount].val;
  862. if (pstrHostIFconnectAttr->ssid) {
  863. memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
  864. pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
  865. }
  866. pu8CurrByte += MAX_SSID_LEN;
  867. *(pu8CurrByte++) = INFRASTRUCTURE;
  868. if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
  869. *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
  870. } else {
  871. netdev_err(vif->ndev, "Channel out of range\n");
  872. *(pu8CurrByte++) = 0xFF;
  873. }
  874. *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF;
  875. *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
  876. if (pstrHostIFconnectAttr->bssid)
  877. memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
  878. pu8CurrByte += 6;
  879. if (pstrHostIFconnectAttr->bssid)
  880. memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
  881. pu8CurrByte += 6;
  882. *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF;
  883. *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
  884. *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period;
  885. memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
  886. pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
  887. *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap;
  888. *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap;
  889. *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable;
  890. hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable;
  891. *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found;
  892. *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy;
  893. *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i;
  894. memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
  895. pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
  896. memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
  897. pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
  898. memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
  899. pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
  900. *(pu8CurrByte++) = REAL_JOIN_REQ;
  901. *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
  902. if (ptstrJoinBssParam->noa_enabled) {
  903. *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
  904. *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
  905. *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
  906. *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
  907. *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
  908. *(pu8CurrByte++) = ptstrJoinBssParam->idx;
  909. if (ptstrJoinBssParam->opp_enabled)
  910. *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
  911. *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
  912. memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
  913. pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
  914. memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
  915. pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
  916. memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
  917. pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
  918. }
  919. pu8CurrByte = strWIDList[u32WidsCount].val;
  920. u32WidsCount++;
  921. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
  922. memcpy(join_req, pu8CurrByte, join_req_size);
  923. join_req_vif = vif;
  924. }
  925. if (pstrHostIFconnectAttr->bssid)
  926. memcpy(wilc_connected_ssid,
  927. pstrHostIFconnectAttr->bssid, ETH_ALEN);
  928. result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
  929. u32WidsCount,
  930. wilc_get_vif_idx(vif));
  931. if (result) {
  932. netdev_err(vif->ndev, "failed to send config packet\n");
  933. result = -EFAULT;
  934. goto ERRORHANDLER;
  935. } else {
  936. hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
  937. }
  938. ERRORHANDLER:
  939. if (result) {
  940. struct connect_info strConnectInfo;
  941. del_timer(&hif_drv->connect_timer);
  942. memset(&strConnectInfo, 0, sizeof(struct connect_info));
  943. if (pstrHostIFconnectAttr->result) {
  944. if (pstrHostIFconnectAttr->bssid)
  945. memcpy(strConnectInfo.bssid, pstrHostIFconnectAttr->bssid, 6);
  946. if (pstrHostIFconnectAttr->ies) {
  947. strConnectInfo.req_ies_len = pstrHostIFconnectAttr->ies_len;
  948. strConnectInfo.req_ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
  949. memcpy(strConnectInfo.req_ies,
  950. pstrHostIFconnectAttr->ies,
  951. pstrHostIFconnectAttr->ies_len);
  952. }
  953. pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
  954. &strConnectInfo,
  955. MAC_DISCONNECTED,
  956. NULL,
  957. pstrHostIFconnectAttr->arg);
  958. hif_drv->hif_state = HOST_IF_IDLE;
  959. kfree(strConnectInfo.req_ies);
  960. strConnectInfo.req_ies = NULL;
  961. } else {
  962. netdev_err(vif->ndev, "Connect callback is NULL\n");
  963. }
  964. }
  965. kfree(pstrHostIFconnectAttr->bssid);
  966. pstrHostIFconnectAttr->bssid = NULL;
  967. kfree(pstrHostIFconnectAttr->ssid);
  968. pstrHostIFconnectAttr->ssid = NULL;
  969. kfree(pstrHostIFconnectAttr->ies);
  970. pstrHostIFconnectAttr->ies = NULL;
  971. kfree(pu8CurrByte);
  972. return result;
  973. }
  974. static s32 Handle_ConnectTimeout(struct wilc_vif *vif)
  975. {
  976. s32 result = 0;
  977. struct connect_info strConnectInfo;
  978. struct wid wid;
  979. u16 u16DummyReasonCode = 0;
  980. struct host_if_drv *hif_drv = vif->hif_drv;
  981. if (!hif_drv) {
  982. netdev_err(vif->ndev, "Driver handler is NULL\n");
  983. return result;
  984. }
  985. hif_drv->hif_state = HOST_IF_IDLE;
  986. scan_while_connected = false;
  987. memset(&strConnectInfo, 0, sizeof(struct connect_info));
  988. if (hif_drv->usr_conn_req.conn_result) {
  989. if (hif_drv->usr_conn_req.bssid) {
  990. memcpy(strConnectInfo.bssid,
  991. hif_drv->usr_conn_req.bssid, 6);
  992. }
  993. if (hif_drv->usr_conn_req.ies) {
  994. strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
  995. strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
  996. memcpy(strConnectInfo.req_ies,
  997. hif_drv->usr_conn_req.ies,
  998. hif_drv->usr_conn_req.ies_len);
  999. }
  1000. hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
  1001. &strConnectInfo,
  1002. MAC_DISCONNECTED,
  1003. NULL,
  1004. hif_drv->usr_conn_req.arg);
  1005. kfree(strConnectInfo.req_ies);
  1006. strConnectInfo.req_ies = NULL;
  1007. } else {
  1008. netdev_err(vif->ndev, "Connect callback is NULL\n");
  1009. }
  1010. wid.id = (u16)WID_DISCONNECT;
  1011. wid.type = WID_CHAR;
  1012. wid.val = (s8 *)&u16DummyReasonCode;
  1013. wid.size = sizeof(char);
  1014. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1015. wilc_get_vif_idx(vif));
  1016. if (result)
  1017. netdev_err(vif->ndev, "Failed to send dissconect\n");
  1018. hif_drv->usr_conn_req.ssid_len = 0;
  1019. kfree(hif_drv->usr_conn_req.ssid);
  1020. hif_drv->usr_conn_req.ssid = NULL;
  1021. kfree(hif_drv->usr_conn_req.bssid);
  1022. hif_drv->usr_conn_req.bssid = NULL;
  1023. hif_drv->usr_conn_req.ies_len = 0;
  1024. kfree(hif_drv->usr_conn_req.ies);
  1025. hif_drv->usr_conn_req.ies = NULL;
  1026. eth_zero_addr(wilc_connected_ssid);
  1027. if (join_req && join_req_vif == vif) {
  1028. kfree(join_req);
  1029. join_req = NULL;
  1030. }
  1031. if (info_element && join_req_vif == vif) {
  1032. kfree(info_element);
  1033. info_element = NULL;
  1034. }
  1035. return result;
  1036. }
  1037. static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif,
  1038. struct rcvd_net_info *pstrRcvdNetworkInfo)
  1039. {
  1040. u32 i;
  1041. bool bNewNtwrkFound;
  1042. s32 result = 0;
  1043. struct network_info *pstrNetworkInfo = NULL;
  1044. void *pJoinParams = NULL;
  1045. struct host_if_drv *hif_drv = vif->hif_drv;
  1046. bNewNtwrkFound = true;
  1047. if (hif_drv->usr_scan_req.scan_result) {
  1048. wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
  1049. if ((!pstrNetworkInfo) ||
  1050. (!hif_drv->usr_scan_req.scan_result)) {
  1051. netdev_err(vif->ndev, "driver is null\n");
  1052. result = -EINVAL;
  1053. goto done;
  1054. }
  1055. for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) {
  1056. if ((hif_drv->usr_scan_req.net_info[i].bssid) &&
  1057. (pstrNetworkInfo->bssid)) {
  1058. if (memcmp(hif_drv->usr_scan_req.net_info[i].bssid,
  1059. pstrNetworkInfo->bssid, 6) == 0) {
  1060. if (pstrNetworkInfo->rssi <= hif_drv->usr_scan_req.net_info[i].rssi) {
  1061. goto done;
  1062. } else {
  1063. hif_drv->usr_scan_req.net_info[i].rssi = pstrNetworkInfo->rssi;
  1064. bNewNtwrkFound = false;
  1065. break;
  1066. }
  1067. }
  1068. }
  1069. }
  1070. if (bNewNtwrkFound) {
  1071. if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
  1072. hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].rssi = pstrNetworkInfo->rssi;
  1073. if (hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid &&
  1074. pstrNetworkInfo->bssid) {
  1075. memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid,
  1076. pstrNetworkInfo->bssid, 6);
  1077. hif_drv->usr_scan_req.rcvd_ch_cnt++;
  1078. pstrNetworkInfo->new_network = true;
  1079. pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
  1080. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
  1081. hif_drv->usr_scan_req.arg,
  1082. pJoinParams);
  1083. }
  1084. }
  1085. } else {
  1086. pstrNetworkInfo->new_network = false;
  1087. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
  1088. hif_drv->usr_scan_req.arg, NULL);
  1089. }
  1090. }
  1091. done:
  1092. kfree(pstrRcvdNetworkInfo->buffer);
  1093. pstrRcvdNetworkInfo->buffer = NULL;
  1094. if (pstrNetworkInfo) {
  1095. kfree(pstrNetworkInfo->ies);
  1096. kfree(pstrNetworkInfo);
  1097. }
  1098. return result;
  1099. }
  1100. static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
  1101. u8 *pu8AssocRespInfo,
  1102. u32 u32MaxAssocRespInfoLen,
  1103. u32 *pu32RcvdAssocRespInfoLen);
  1104. static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif,
  1105. struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
  1106. {
  1107. s32 result = 0;
  1108. u8 u8MsgType = 0;
  1109. u8 u8MsgID = 0;
  1110. u16 u16MsgLen = 0;
  1111. u16 u16WidID = (u16)WID_NIL;
  1112. u8 u8WidLen = 0;
  1113. u8 u8MacStatus;
  1114. u8 u8MacStatusReasonCode;
  1115. u8 u8MacStatusAdditionalInfo;
  1116. struct connect_info strConnectInfo;
  1117. struct disconnect_info strDisconnectNotifInfo;
  1118. s32 s32Err = 0;
  1119. struct host_if_drv *hif_drv = vif->hif_drv;
  1120. if (!hif_drv) {
  1121. netdev_err(vif->ndev, "Driver handler is NULL\n");
  1122. return -ENODEV;
  1123. }
  1124. if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
  1125. (hif_drv->hif_state == HOST_IF_CONNECTED) ||
  1126. hif_drv->usr_scan_req.scan_result) {
  1127. if (!pstrRcvdGnrlAsyncInfo->buffer ||
  1128. !hif_drv->usr_conn_req.conn_result) {
  1129. netdev_err(vif->ndev, "driver is null\n");
  1130. return -EINVAL;
  1131. }
  1132. u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
  1133. if ('I' != u8MsgType) {
  1134. netdev_err(vif->ndev, "Received Message incorrect.\n");
  1135. return -EFAULT;
  1136. }
  1137. u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
  1138. u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
  1139. u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
  1140. u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
  1141. u8MacStatus = pstrRcvdGnrlAsyncInfo->buffer[7];
  1142. u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
  1143. u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
  1144. if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
  1145. u32 u32RcvdAssocRespInfoLen = 0;
  1146. struct connect_resp_info *pstrConnectRespInfo = NULL;
  1147. memset(&strConnectInfo, 0, sizeof(struct connect_info));
  1148. if (u8MacStatus == MAC_CONNECTED) {
  1149. memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
  1150. host_int_get_assoc_res_info(vif,
  1151. rcv_assoc_resp,
  1152. MAX_ASSOC_RESP_FRAME_SIZE,
  1153. &u32RcvdAssocRespInfoLen);
  1154. if (u32RcvdAssocRespInfoLen != 0) {
  1155. s32Err = wilc_parse_assoc_resp_info(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
  1156. &pstrConnectRespInfo);
  1157. if (s32Err) {
  1158. netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", s32Err);
  1159. } else {
  1160. strConnectInfo.status = pstrConnectRespInfo->status;
  1161. if (strConnectInfo.status == SUCCESSFUL_STATUSCODE) {
  1162. if (pstrConnectRespInfo->ies) {
  1163. strConnectInfo.resp_ies_len = pstrConnectRespInfo->ies_len;
  1164. strConnectInfo.resp_ies = kmalloc(pstrConnectRespInfo->ies_len, GFP_KERNEL);
  1165. memcpy(strConnectInfo.resp_ies, pstrConnectRespInfo->ies,
  1166. pstrConnectRespInfo->ies_len);
  1167. }
  1168. }
  1169. if (pstrConnectRespInfo) {
  1170. kfree(pstrConnectRespInfo->ies);
  1171. kfree(pstrConnectRespInfo);
  1172. }
  1173. }
  1174. }
  1175. }
  1176. if ((u8MacStatus == MAC_CONNECTED) &&
  1177. (strConnectInfo.status != SUCCESSFUL_STATUSCODE)) {
  1178. netdev_err(vif->ndev, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
  1179. eth_zero_addr(wilc_connected_ssid);
  1180. } else if (u8MacStatus == MAC_DISCONNECTED) {
  1181. netdev_err(vif->ndev, "Received MAC status is MAC_DISCONNECTED\n");
  1182. eth_zero_addr(wilc_connected_ssid);
  1183. }
  1184. if (hif_drv->usr_conn_req.bssid) {
  1185. memcpy(strConnectInfo.bssid, hif_drv->usr_conn_req.bssid, 6);
  1186. if ((u8MacStatus == MAC_CONNECTED) &&
  1187. (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) {
  1188. memcpy(hif_drv->assoc_bssid,
  1189. hif_drv->usr_conn_req.bssid, ETH_ALEN);
  1190. }
  1191. }
  1192. if (hif_drv->usr_conn_req.ies) {
  1193. strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
  1194. strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
  1195. memcpy(strConnectInfo.req_ies,
  1196. hif_drv->usr_conn_req.ies,
  1197. hif_drv->usr_conn_req.ies_len);
  1198. }
  1199. del_timer(&hif_drv->connect_timer);
  1200. hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
  1201. &strConnectInfo,
  1202. u8MacStatus,
  1203. NULL,
  1204. hif_drv->usr_conn_req.arg);
  1205. if ((u8MacStatus == MAC_CONNECTED) &&
  1206. (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) {
  1207. wilc_set_power_mgmt(vif, 0, 0);
  1208. hif_drv->hif_state = HOST_IF_CONNECTED;
  1209. wilc_optaining_ip = true;
  1210. mod_timer(&wilc_during_ip_timer,
  1211. jiffies + msecs_to_jiffies(10000));
  1212. } else {
  1213. hif_drv->hif_state = HOST_IF_IDLE;
  1214. scan_while_connected = false;
  1215. }
  1216. kfree(strConnectInfo.resp_ies);
  1217. strConnectInfo.resp_ies = NULL;
  1218. kfree(strConnectInfo.req_ies);
  1219. strConnectInfo.req_ies = NULL;
  1220. hif_drv->usr_conn_req.ssid_len = 0;
  1221. kfree(hif_drv->usr_conn_req.ssid);
  1222. hif_drv->usr_conn_req.ssid = NULL;
  1223. kfree(hif_drv->usr_conn_req.bssid);
  1224. hif_drv->usr_conn_req.bssid = NULL;
  1225. hif_drv->usr_conn_req.ies_len = 0;
  1226. kfree(hif_drv->usr_conn_req.ies);
  1227. hif_drv->usr_conn_req.ies = NULL;
  1228. } else if ((u8MacStatus == MAC_DISCONNECTED) &&
  1229. (hif_drv->hif_state == HOST_IF_CONNECTED)) {
  1230. memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
  1231. if (hif_drv->usr_scan_req.scan_result) {
  1232. del_timer(&hif_drv->scan_timer);
  1233. Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
  1234. }
  1235. strDisconnectNotifInfo.reason = 0;
  1236. strDisconnectNotifInfo.ie = NULL;
  1237. strDisconnectNotifInfo.ie_len = 0;
  1238. if (hif_drv->usr_conn_req.conn_result) {
  1239. wilc_optaining_ip = false;
  1240. wilc_set_power_mgmt(vif, 0, 0);
  1241. hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
  1242. NULL,
  1243. 0,
  1244. &strDisconnectNotifInfo,
  1245. hif_drv->usr_conn_req.arg);
  1246. } else {
  1247. netdev_err(vif->ndev, "Connect result NULL\n");
  1248. }
  1249. eth_zero_addr(hif_drv->assoc_bssid);
  1250. hif_drv->usr_conn_req.ssid_len = 0;
  1251. kfree(hif_drv->usr_conn_req.ssid);
  1252. hif_drv->usr_conn_req.ssid = NULL;
  1253. kfree(hif_drv->usr_conn_req.bssid);
  1254. hif_drv->usr_conn_req.bssid = NULL;
  1255. hif_drv->usr_conn_req.ies_len = 0;
  1256. kfree(hif_drv->usr_conn_req.ies);
  1257. hif_drv->usr_conn_req.ies = NULL;
  1258. if (join_req && join_req_vif == vif) {
  1259. kfree(join_req);
  1260. join_req = NULL;
  1261. }
  1262. if (info_element && join_req_vif == vif) {
  1263. kfree(info_element);
  1264. info_element = NULL;
  1265. }
  1266. hif_drv->hif_state = HOST_IF_IDLE;
  1267. scan_while_connected = false;
  1268. } else if ((u8MacStatus == MAC_DISCONNECTED) &&
  1269. (hif_drv->usr_scan_req.scan_result)) {
  1270. del_timer(&hif_drv->scan_timer);
  1271. if (hif_drv->usr_scan_req.scan_result)
  1272. Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
  1273. }
  1274. }
  1275. kfree(pstrRcvdGnrlAsyncInfo->buffer);
  1276. pstrRcvdGnrlAsyncInfo->buffer = NULL;
  1277. return result;
  1278. }
  1279. static int Handle_Key(struct wilc_vif *vif,
  1280. struct key_attr *pstrHostIFkeyAttr)
  1281. {
  1282. s32 result = 0;
  1283. struct wid wid;
  1284. struct wid strWIDList[5];
  1285. u8 i;
  1286. u8 *pu8keybuf;
  1287. s8 s8idxarray[1];
  1288. s8 ret = 0;
  1289. struct host_if_drv *hif_drv = vif->hif_drv;
  1290. switch (pstrHostIFkeyAttr->type) {
  1291. case WEP:
  1292. if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
  1293. strWIDList[0].id = (u16)WID_11I_MODE;
  1294. strWIDList[0].type = WID_CHAR;
  1295. strWIDList[0].size = sizeof(char);
  1296. strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
  1297. strWIDList[1].id = WID_AUTH_TYPE;
  1298. strWIDList[1].type = WID_CHAR;
  1299. strWIDList[1].size = sizeof(char);
  1300. strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
  1301. pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2,
  1302. GFP_KERNEL);
  1303. if (!pu8keybuf)
  1304. return -ENOMEM;
  1305. pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
  1306. pu8keybuf[1] = pstrHostIFkeyAttr->attr.wep.key_len;
  1307. memcpy(&pu8keybuf[2], pstrHostIFkeyAttr->attr.wep.key,
  1308. pstrHostIFkeyAttr->attr.wep.key_len);
  1309. kfree(pstrHostIFkeyAttr->attr.wep.key);
  1310. strWIDList[2].id = (u16)WID_WEP_KEY_VALUE;
  1311. strWIDList[2].type = WID_STR;
  1312. strWIDList[2].size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
  1313. strWIDList[2].val = (s8 *)pu8keybuf;
  1314. result = wilc_send_config_pkt(vif, SET_CFG,
  1315. strWIDList, 3,
  1316. wilc_get_vif_idx(vif));
  1317. kfree(pu8keybuf);
  1318. } else if (pstrHostIFkeyAttr->action & ADDKEY) {
  1319. pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
  1320. if (!pu8keybuf)
  1321. return -ENOMEM;
  1322. pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
  1323. memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
  1324. memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
  1325. pstrHostIFkeyAttr->attr.wep.key_len);
  1326. kfree(pstrHostIFkeyAttr->attr.wep.key);
  1327. wid.id = (u16)WID_ADD_WEP_KEY;
  1328. wid.type = WID_STR;
  1329. wid.val = (s8 *)pu8keybuf;
  1330. wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
  1331. result = wilc_send_config_pkt(vif, SET_CFG,
  1332. &wid, 1,
  1333. wilc_get_vif_idx(vif));
  1334. kfree(pu8keybuf);
  1335. } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
  1336. wid.id = (u16)WID_REMOVE_WEP_KEY;
  1337. wid.type = WID_STR;
  1338. s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
  1339. wid.val = s8idxarray;
  1340. wid.size = 1;
  1341. result = wilc_send_config_pkt(vif, SET_CFG,
  1342. &wid, 1,
  1343. wilc_get_vif_idx(vif));
  1344. } else if (pstrHostIFkeyAttr->action & DEFAULTKEY) {
  1345. wid.id = (u16)WID_KEY_ID;
  1346. wid.type = WID_CHAR;
  1347. wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
  1348. wid.size = sizeof(char);
  1349. result = wilc_send_config_pkt(vif, SET_CFG,
  1350. &wid, 1,
  1351. wilc_get_vif_idx(vif));
  1352. }
  1353. complete(&hif_drv->comp_test_key_block);
  1354. break;
  1355. case WPA_RX_GTK:
  1356. if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
  1357. pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
  1358. if (!pu8keybuf) {
  1359. ret = -ENOMEM;
  1360. goto _WPARxGtk_end_case_;
  1361. }
  1362. if (pstrHostIFkeyAttr->attr.wpa.seq)
  1363. memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
  1364. memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
  1365. memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
  1366. memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
  1367. pstrHostIFkeyAttr->attr.wpa.key_len);
  1368. strWIDList[0].id = (u16)WID_11I_MODE;
  1369. strWIDList[0].type = WID_CHAR;
  1370. strWIDList[0].size = sizeof(char);
  1371. strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
  1372. strWIDList[1].id = (u16)WID_ADD_RX_GTK;
  1373. strWIDList[1].type = WID_STR;
  1374. strWIDList[1].val = (s8 *)pu8keybuf;
  1375. strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
  1376. result = wilc_send_config_pkt(vif, SET_CFG,
  1377. strWIDList, 2,
  1378. wilc_get_vif_idx(vif));
  1379. kfree(pu8keybuf);
  1380. complete(&hif_drv->comp_test_key_block);
  1381. } else if (pstrHostIFkeyAttr->action & ADDKEY) {
  1382. pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
  1383. if (!pu8keybuf) {
  1384. ret = -ENOMEM;
  1385. goto _WPARxGtk_end_case_;
  1386. }
  1387. if (hif_drv->hif_state == HOST_IF_CONNECTED)
  1388. memcpy(pu8keybuf, hif_drv->assoc_bssid, ETH_ALEN);
  1389. else
  1390. netdev_err(vif->ndev, "Couldn't handle\n");
  1391. memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
  1392. memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
  1393. memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
  1394. memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
  1395. pstrHostIFkeyAttr->attr.wpa.key_len);
  1396. wid.id = (u16)WID_ADD_RX_GTK;
  1397. wid.type = WID_STR;
  1398. wid.val = (s8 *)pu8keybuf;
  1399. wid.size = RX_MIC_KEY_MSG_LEN;
  1400. result = wilc_send_config_pkt(vif, SET_CFG,
  1401. &wid, 1,
  1402. wilc_get_vif_idx(vif));
  1403. kfree(pu8keybuf);
  1404. complete(&hif_drv->comp_test_key_block);
  1405. }
  1406. _WPARxGtk_end_case_:
  1407. kfree(pstrHostIFkeyAttr->attr.wpa.key);
  1408. kfree(pstrHostIFkeyAttr->attr.wpa.seq);
  1409. if (ret)
  1410. return ret;
  1411. break;
  1412. case WPA_PTK:
  1413. if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
  1414. pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
  1415. if (!pu8keybuf) {
  1416. ret = -ENOMEM;
  1417. goto _WPAPtk_end_case_;
  1418. }
  1419. memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
  1420. memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
  1421. memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
  1422. memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
  1423. pstrHostIFkeyAttr->attr.wpa.key_len);
  1424. strWIDList[0].id = (u16)WID_11I_MODE;
  1425. strWIDList[0].type = WID_CHAR;
  1426. strWIDList[0].size = sizeof(char);
  1427. strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
  1428. strWIDList[1].id = (u16)WID_ADD_PTK;
  1429. strWIDList[1].type = WID_STR;
  1430. strWIDList[1].val = (s8 *)pu8keybuf;
  1431. strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
  1432. result = wilc_send_config_pkt(vif, SET_CFG,
  1433. strWIDList, 2,
  1434. wilc_get_vif_idx(vif));
  1435. kfree(pu8keybuf);
  1436. complete(&hif_drv->comp_test_key_block);
  1437. } else if (pstrHostIFkeyAttr->action & ADDKEY) {
  1438. pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
  1439. if (!pu8keybuf) {
  1440. netdev_err(vif->ndev, "No buffer send PTK\n");
  1441. ret = -ENOMEM;
  1442. goto _WPAPtk_end_case_;
  1443. }
  1444. memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
  1445. memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
  1446. memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
  1447. pstrHostIFkeyAttr->attr.wpa.key_len);
  1448. wid.id = (u16)WID_ADD_PTK;
  1449. wid.type = WID_STR;
  1450. wid.val = (s8 *)pu8keybuf;
  1451. wid.size = PTK_KEY_MSG_LEN;
  1452. result = wilc_send_config_pkt(vif, SET_CFG,
  1453. &wid, 1,
  1454. wilc_get_vif_idx(vif));
  1455. kfree(pu8keybuf);
  1456. complete(&hif_drv->comp_test_key_block);
  1457. }
  1458. _WPAPtk_end_case_:
  1459. kfree(pstrHostIFkeyAttr->attr.wpa.key);
  1460. if (ret)
  1461. return ret;
  1462. break;
  1463. case PMKSA:
  1464. pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
  1465. if (!pu8keybuf) {
  1466. netdev_err(vif->ndev, "No buffer to send PMKSA Key\n");
  1467. return -ENOMEM;
  1468. }
  1469. pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
  1470. for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
  1471. memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
  1472. memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
  1473. }
  1474. wid.id = (u16)WID_PMKID_INFO;
  1475. wid.type = WID_STR;
  1476. wid.val = (s8 *)pu8keybuf;
  1477. wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
  1478. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1479. wilc_get_vif_idx(vif));
  1480. kfree(pu8keybuf);
  1481. break;
  1482. }
  1483. if (result)
  1484. netdev_err(vif->ndev, "Failed to send key config packet\n");
  1485. return result;
  1486. }
  1487. static void Handle_Disconnect(struct wilc_vif *vif)
  1488. {
  1489. struct wid wid;
  1490. struct host_if_drv *hif_drv = vif->hif_drv;
  1491. s32 result = 0;
  1492. u16 u16DummyReasonCode = 0;
  1493. wid.id = (u16)WID_DISCONNECT;
  1494. wid.type = WID_CHAR;
  1495. wid.val = (s8 *)&u16DummyReasonCode;
  1496. wid.size = sizeof(char);
  1497. wilc_optaining_ip = false;
  1498. wilc_set_power_mgmt(vif, 0, 0);
  1499. eth_zero_addr(wilc_connected_ssid);
  1500. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1501. wilc_get_vif_idx(vif));
  1502. if (result) {
  1503. netdev_err(vif->ndev, "Failed to send dissconect\n");
  1504. } else {
  1505. struct disconnect_info strDisconnectNotifInfo;
  1506. memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
  1507. strDisconnectNotifInfo.reason = 0;
  1508. strDisconnectNotifInfo.ie = NULL;
  1509. strDisconnectNotifInfo.ie_len = 0;
  1510. if (hif_drv->usr_scan_req.scan_result) {
  1511. del_timer(&hif_drv->scan_timer);
  1512. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED,
  1513. NULL,
  1514. hif_drv->usr_scan_req.arg,
  1515. NULL);
  1516. hif_drv->usr_scan_req.scan_result = NULL;
  1517. }
  1518. if (hif_drv->usr_conn_req.conn_result) {
  1519. if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
  1520. del_timer(&hif_drv->connect_timer);
  1521. hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
  1522. NULL,
  1523. 0,
  1524. &strDisconnectNotifInfo,
  1525. hif_drv->usr_conn_req.arg);
  1526. } else {
  1527. netdev_err(vif->ndev, "conn_result = NULL\n");
  1528. }
  1529. scan_while_connected = false;
  1530. hif_drv->hif_state = HOST_IF_IDLE;
  1531. eth_zero_addr(hif_drv->assoc_bssid);
  1532. hif_drv->usr_conn_req.ssid_len = 0;
  1533. kfree(hif_drv->usr_conn_req.ssid);
  1534. hif_drv->usr_conn_req.ssid = NULL;
  1535. kfree(hif_drv->usr_conn_req.bssid);
  1536. hif_drv->usr_conn_req.bssid = NULL;
  1537. hif_drv->usr_conn_req.ies_len = 0;
  1538. kfree(hif_drv->usr_conn_req.ies);
  1539. hif_drv->usr_conn_req.ies = NULL;
  1540. if (join_req && join_req_vif == vif) {
  1541. kfree(join_req);
  1542. join_req = NULL;
  1543. }
  1544. if (info_element && join_req_vif == vif) {
  1545. kfree(info_element);
  1546. info_element = NULL;
  1547. }
  1548. }
  1549. complete(&hif_drv->comp_test_disconn_block);
  1550. }
  1551. void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
  1552. {
  1553. if (!vif->hif_drv)
  1554. return;
  1555. if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
  1556. (vif->hif_drv->hif_state == HOST_IF_CONNECTING))
  1557. wilc_disconnect(vif, 1);
  1558. }
  1559. static void Handle_GetRssi(struct wilc_vif *vif)
  1560. {
  1561. s32 result = 0;
  1562. struct wid wid;
  1563. wid.id = (u16)WID_RSSI;
  1564. wid.type = WID_CHAR;
  1565. wid.val = &rssi;
  1566. wid.size = sizeof(char);
  1567. result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  1568. wilc_get_vif_idx(vif));
  1569. if (result) {
  1570. netdev_err(vif->ndev, "Failed to get RSSI value\n");
  1571. result = -EFAULT;
  1572. }
  1573. complete(&vif->hif_drv->comp_get_rssi);
  1574. }
  1575. static s32 Handle_GetStatistics(struct wilc_vif *vif,
  1576. struct rf_info *pstrStatistics)
  1577. {
  1578. struct wid strWIDList[5];
  1579. u32 u32WidsCount = 0, result = 0;
  1580. strWIDList[u32WidsCount].id = WID_LINKSPEED;
  1581. strWIDList[u32WidsCount].type = WID_CHAR;
  1582. strWIDList[u32WidsCount].size = sizeof(char);
  1583. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->link_speed;
  1584. u32WidsCount++;
  1585. strWIDList[u32WidsCount].id = WID_RSSI;
  1586. strWIDList[u32WidsCount].type = WID_CHAR;
  1587. strWIDList[u32WidsCount].size = sizeof(char);
  1588. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rssi;
  1589. u32WidsCount++;
  1590. strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
  1591. strWIDList[u32WidsCount].type = WID_INT;
  1592. strWIDList[u32WidsCount].size = sizeof(u32);
  1593. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_cnt;
  1594. u32WidsCount++;
  1595. strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
  1596. strWIDList[u32WidsCount].type = WID_INT;
  1597. strWIDList[u32WidsCount].size = sizeof(u32);
  1598. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rx_cnt;
  1599. u32WidsCount++;
  1600. strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
  1601. strWIDList[u32WidsCount].type = WID_INT;
  1602. strWIDList[u32WidsCount].size = sizeof(u32);
  1603. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt;
  1604. u32WidsCount++;
  1605. result = wilc_send_config_pkt(vif, GET_CFG, strWIDList,
  1606. u32WidsCount,
  1607. wilc_get_vif_idx(vif));
  1608. if (result)
  1609. netdev_err(vif->ndev, "Failed to send scan parameters\n");
  1610. if (pstrStatistics->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
  1611. pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
  1612. wilc_enable_tcp_ack_filter(true);
  1613. else if (pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
  1614. wilc_enable_tcp_ack_filter(false);
  1615. if (pstrStatistics != &vif->wilc->dummy_statistics)
  1616. complete(&hif_wait_response);
  1617. return 0;
  1618. }
  1619. static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
  1620. struct sta_inactive_t *strHostIfStaInactiveT)
  1621. {
  1622. s32 result = 0;
  1623. u8 *stamac;
  1624. struct wid wid;
  1625. struct host_if_drv *hif_drv = vif->hif_drv;
  1626. wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
  1627. wid.type = WID_STR;
  1628. wid.size = ETH_ALEN;
  1629. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1630. stamac = wid.val;
  1631. memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
  1632. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1633. wilc_get_vif_idx(vif));
  1634. if (result) {
  1635. netdev_err(vif->ndev, "Failed to SET incative time\n");
  1636. return -EFAULT;
  1637. }
  1638. wid.id = (u16)WID_GET_INACTIVE_TIME;
  1639. wid.type = WID_INT;
  1640. wid.val = (s8 *)&inactive_time;
  1641. wid.size = sizeof(u32);
  1642. result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  1643. wilc_get_vif_idx(vif));
  1644. if (result) {
  1645. netdev_err(vif->ndev, "Failed to get incative time\n");
  1646. return -EFAULT;
  1647. }
  1648. complete(&hif_drv->comp_inactive_time);
  1649. return result;
  1650. }
  1651. static void Handle_AddBeacon(struct wilc_vif *vif,
  1652. struct beacon_attr *pstrSetBeaconParam)
  1653. {
  1654. s32 result = 0;
  1655. struct wid wid;
  1656. u8 *pu8CurrByte;
  1657. wid.id = (u16)WID_ADD_BEACON;
  1658. wid.type = WID_BIN;
  1659. wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
  1660. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1661. if (!wid.val)
  1662. goto ERRORHANDLER;
  1663. pu8CurrByte = wid.val;
  1664. *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
  1665. *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
  1666. *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
  1667. *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
  1668. *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
  1669. *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
  1670. *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
  1671. *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
  1672. *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
  1673. *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
  1674. *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
  1675. *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
  1676. memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
  1677. pu8CurrByte += pstrSetBeaconParam->head_len;
  1678. *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
  1679. *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
  1680. *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
  1681. *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
  1682. if (pstrSetBeaconParam->tail)
  1683. memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
  1684. pu8CurrByte += pstrSetBeaconParam->tail_len;
  1685. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1686. wilc_get_vif_idx(vif));
  1687. if (result)
  1688. netdev_err(vif->ndev, "Failed to send add beacon\n");
  1689. ERRORHANDLER:
  1690. kfree(wid.val);
  1691. kfree(pstrSetBeaconParam->head);
  1692. kfree(pstrSetBeaconParam->tail);
  1693. }
  1694. static void Handle_DelBeacon(struct wilc_vif *vif)
  1695. {
  1696. s32 result = 0;
  1697. struct wid wid;
  1698. u8 *pu8CurrByte;
  1699. wid.id = (u16)WID_DEL_BEACON;
  1700. wid.type = WID_CHAR;
  1701. wid.size = sizeof(char);
  1702. wid.val = &del_beacon;
  1703. if (!wid.val)
  1704. return;
  1705. pu8CurrByte = wid.val;
  1706. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1707. wilc_get_vif_idx(vif));
  1708. if (result)
  1709. netdev_err(vif->ndev, "Failed to send delete beacon\n");
  1710. }
  1711. static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
  1712. struct add_sta_param *pstrStationParam)
  1713. {
  1714. u8 *pu8CurrByte;
  1715. pu8CurrByte = pu8Buffer;
  1716. memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN);
  1717. pu8CurrByte += ETH_ALEN;
  1718. *pu8CurrByte++ = pstrStationParam->aid & 0xFF;
  1719. *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF;
  1720. *pu8CurrByte++ = pstrStationParam->rates_len;
  1721. if (pstrStationParam->rates_len > 0)
  1722. memcpy(pu8CurrByte, pstrStationParam->rates,
  1723. pstrStationParam->rates_len);
  1724. pu8CurrByte += pstrStationParam->rates_len;
  1725. *pu8CurrByte++ = pstrStationParam->ht_supported;
  1726. *pu8CurrByte++ = pstrStationParam->ht_capa_info & 0xFF;
  1727. *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF;
  1728. *pu8CurrByte++ = pstrStationParam->ht_ampdu_params;
  1729. memcpy(pu8CurrByte, pstrStationParam->ht_supp_mcs_set,
  1730. WILC_SUPP_MCS_SET_SIZE);
  1731. pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
  1732. *pu8CurrByte++ = pstrStationParam->ht_ext_params & 0xFF;
  1733. *pu8CurrByte++ = (pstrStationParam->ht_ext_params >> 8) & 0xFF;
  1734. *pu8CurrByte++ = pstrStationParam->ht_tx_bf_cap & 0xFF;
  1735. *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 8) & 0xFF;
  1736. *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 16) & 0xFF;
  1737. *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 24) & 0xFF;
  1738. *pu8CurrByte++ = pstrStationParam->ht_ante_sel;
  1739. *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF;
  1740. *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF;
  1741. *pu8CurrByte++ = pstrStationParam->flags_set & 0xFF;
  1742. *pu8CurrByte++ = (pstrStationParam->flags_set >> 8) & 0xFF;
  1743. return pu8CurrByte - pu8Buffer;
  1744. }
  1745. static void Handle_AddStation(struct wilc_vif *vif,
  1746. struct add_sta_param *pstrStationParam)
  1747. {
  1748. s32 result = 0;
  1749. struct wid wid;
  1750. u8 *pu8CurrByte;
  1751. wid.id = (u16)WID_ADD_STA;
  1752. wid.type = WID_BIN;
  1753. wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
  1754. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1755. if (!wid.val)
  1756. goto ERRORHANDLER;
  1757. pu8CurrByte = wid.val;
  1758. pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
  1759. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1760. wilc_get_vif_idx(vif));
  1761. if (result != 0)
  1762. netdev_err(vif->ndev, "Failed to send add station\n");
  1763. ERRORHANDLER:
  1764. kfree(pstrStationParam->rates);
  1765. kfree(wid.val);
  1766. }
  1767. static void Handle_DelAllSta(struct wilc_vif *vif,
  1768. struct del_all_sta *pstrDelAllStaParam)
  1769. {
  1770. s32 result = 0;
  1771. struct wid wid;
  1772. u8 *pu8CurrByte;
  1773. u8 i;
  1774. u8 au8Zero_Buff[6] = {0};
  1775. wid.id = (u16)WID_DEL_ALL_STA;
  1776. wid.type = WID_STR;
  1777. wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
  1778. wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
  1779. if (!wid.val)
  1780. goto ERRORHANDLER;
  1781. pu8CurrByte = wid.val;
  1782. *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
  1783. for (i = 0; i < MAX_NUM_STA; i++) {
  1784. if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
  1785. memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
  1786. else
  1787. continue;
  1788. pu8CurrByte += ETH_ALEN;
  1789. }
  1790. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1791. wilc_get_vif_idx(vif));
  1792. if (result)
  1793. netdev_err(vif->ndev, "Failed to send add station\n");
  1794. ERRORHANDLER:
  1795. kfree(wid.val);
  1796. complete(&hif_wait_response);
  1797. }
  1798. static void Handle_DelStation(struct wilc_vif *vif,
  1799. struct del_sta *pstrDelStaParam)
  1800. {
  1801. s32 result = 0;
  1802. struct wid wid;
  1803. u8 *pu8CurrByte;
  1804. wid.id = (u16)WID_REMOVE_STA;
  1805. wid.type = WID_BIN;
  1806. wid.size = ETH_ALEN;
  1807. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1808. if (!wid.val)
  1809. goto ERRORHANDLER;
  1810. pu8CurrByte = wid.val;
  1811. memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
  1812. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1813. wilc_get_vif_idx(vif));
  1814. if (result)
  1815. netdev_err(vif->ndev, "Failed to send add station\n");
  1816. ERRORHANDLER:
  1817. kfree(wid.val);
  1818. }
  1819. static void Handle_EditStation(struct wilc_vif *vif,
  1820. struct add_sta_param *pstrStationParam)
  1821. {
  1822. s32 result = 0;
  1823. struct wid wid;
  1824. u8 *pu8CurrByte;
  1825. wid.id = (u16)WID_EDIT_STA;
  1826. wid.type = WID_BIN;
  1827. wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
  1828. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1829. if (!wid.val)
  1830. goto ERRORHANDLER;
  1831. pu8CurrByte = wid.val;
  1832. pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
  1833. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1834. wilc_get_vif_idx(vif));
  1835. if (result)
  1836. netdev_err(vif->ndev, "Failed to send edit station\n");
  1837. ERRORHANDLER:
  1838. kfree(pstrStationParam->rates);
  1839. kfree(wid.val);
  1840. }
  1841. static int Handle_RemainOnChan(struct wilc_vif *vif,
  1842. struct remain_ch *pstrHostIfRemainOnChan)
  1843. {
  1844. s32 result = 0;
  1845. u8 u8remain_on_chan_flag;
  1846. struct wid wid;
  1847. struct host_if_drv *hif_drv = vif->hif_drv;
  1848. if (!hif_drv->remain_on_ch_pending) {
  1849. hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg;
  1850. hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired;
  1851. hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready;
  1852. hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch;
  1853. hif_drv->remain_on_ch.id = pstrHostIfRemainOnChan->id;
  1854. } else {
  1855. pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch;
  1856. }
  1857. if (hif_drv->usr_scan_req.scan_result) {
  1858. hif_drv->remain_on_ch_pending = 1;
  1859. result = -EBUSY;
  1860. goto ERRORHANDLER;
  1861. }
  1862. if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
  1863. result = -EBUSY;
  1864. goto ERRORHANDLER;
  1865. }
  1866. if (wilc_optaining_ip || wilc_connecting) {
  1867. result = -EBUSY;
  1868. goto ERRORHANDLER;
  1869. }
  1870. u8remain_on_chan_flag = true;
  1871. wid.id = (u16)WID_REMAIN_ON_CHAN;
  1872. wid.type = WID_STR;
  1873. wid.size = 2;
  1874. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1875. if (!wid.val) {
  1876. result = -ENOMEM;
  1877. goto ERRORHANDLER;
  1878. }
  1879. wid.val[0] = u8remain_on_chan_flag;
  1880. wid.val[1] = (s8)pstrHostIfRemainOnChan->ch;
  1881. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1882. wilc_get_vif_idx(vif));
  1883. if (result != 0)
  1884. netdev_err(vif->ndev, "Failed to set remain on channel\n");
  1885. ERRORHANDLER:
  1886. {
  1887. P2P_LISTEN_STATE = 1;
  1888. hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
  1889. mod_timer(&hif_drv->remain_on_ch_timer,
  1890. jiffies +
  1891. msecs_to_jiffies(pstrHostIfRemainOnChan->duration));
  1892. if (hif_drv->remain_on_ch.ready)
  1893. hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
  1894. if (hif_drv->remain_on_ch_pending)
  1895. hif_drv->remain_on_ch_pending = 0;
  1896. }
  1897. return result;
  1898. }
  1899. static int Handle_RegisterFrame(struct wilc_vif *vif,
  1900. struct reg_frame *pstrHostIfRegisterFrame)
  1901. {
  1902. s32 result = 0;
  1903. struct wid wid;
  1904. u8 *pu8CurrByte;
  1905. wid.id = (u16)WID_REGISTER_FRAME;
  1906. wid.type = WID_STR;
  1907. wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
  1908. if (!wid.val)
  1909. return -ENOMEM;
  1910. pu8CurrByte = wid.val;
  1911. *pu8CurrByte++ = pstrHostIfRegisterFrame->reg;
  1912. *pu8CurrByte++ = pstrHostIfRegisterFrame->reg_id;
  1913. memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16));
  1914. wid.size = sizeof(u16) + 2;
  1915. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1916. wilc_get_vif_idx(vif));
  1917. if (result) {
  1918. netdev_err(vif->ndev, "Failed to frame register\n");
  1919. result = -EINVAL;
  1920. }
  1921. return result;
  1922. }
  1923. static u32 Handle_ListenStateExpired(struct wilc_vif *vif,
  1924. struct remain_ch *pstrHostIfRemainOnChan)
  1925. {
  1926. u8 u8remain_on_chan_flag;
  1927. struct wid wid;
  1928. s32 result = 0;
  1929. struct host_if_drv *hif_drv = vif->hif_drv;
  1930. if (P2P_LISTEN_STATE) {
  1931. u8remain_on_chan_flag = false;
  1932. wid.id = (u16)WID_REMAIN_ON_CHAN;
  1933. wid.type = WID_STR;
  1934. wid.size = 2;
  1935. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1936. if (!wid.val) {
  1937. netdev_err(vif->ndev, "Failed to allocate memory\n");
  1938. return -ENOMEM;
  1939. }
  1940. wid.val[0] = u8remain_on_chan_flag;
  1941. wid.val[1] = FALSE_FRMWR_CHANNEL;
  1942. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1943. wilc_get_vif_idx(vif));
  1944. if (result != 0) {
  1945. netdev_err(vif->ndev, "Failed to set remain channel\n");
  1946. goto _done_;
  1947. }
  1948. if (hif_drv->remain_on_ch.expired) {
  1949. hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
  1950. pstrHostIfRemainOnChan->id);
  1951. }
  1952. P2P_LISTEN_STATE = 0;
  1953. } else {
  1954. netdev_dbg(vif->ndev, "Not in listen state\n");
  1955. result = -EFAULT;
  1956. }
  1957. _done_:
  1958. return result;
  1959. }
  1960. static void ListenTimerCB(unsigned long arg)
  1961. {
  1962. s32 result = 0;
  1963. struct host_if_msg msg;
  1964. struct wilc_vif *vif = (struct wilc_vif *)arg;
  1965. del_timer(&vif->hif_drv->remain_on_ch_timer);
  1966. memset(&msg, 0, sizeof(struct host_if_msg));
  1967. msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
  1968. msg.vif = vif;
  1969. msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
  1970. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  1971. if (result)
  1972. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  1973. }
  1974. static void Handle_PowerManagement(struct wilc_vif *vif,
  1975. struct power_mgmt_param *strPowerMgmtParam)
  1976. {
  1977. s32 result = 0;
  1978. struct wid wid;
  1979. s8 s8PowerMode;
  1980. wid.id = (u16)WID_POWER_MANAGEMENT;
  1981. if (strPowerMgmtParam->enabled)
  1982. s8PowerMode = MIN_FAST_PS;
  1983. else
  1984. s8PowerMode = NO_POWERSAVE;
  1985. wid.val = &s8PowerMode;
  1986. wid.size = sizeof(char);
  1987. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1988. wilc_get_vif_idx(vif));
  1989. if (result)
  1990. netdev_err(vif->ndev, "Failed to send power management\n");
  1991. }
  1992. static void Handle_SetMulticastFilter(struct wilc_vif *vif,
  1993. struct set_multicast *strHostIfSetMulti)
  1994. {
  1995. s32 result = 0;
  1996. struct wid wid;
  1997. u8 *pu8CurrByte;
  1998. wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
  1999. wid.type = WID_BIN;
  2000. wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
  2001. wid.val = kmalloc(wid.size, GFP_KERNEL);
  2002. if (!wid.val)
  2003. goto ERRORHANDLER;
  2004. pu8CurrByte = wid.val;
  2005. *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
  2006. *pu8CurrByte++ = 0;
  2007. *pu8CurrByte++ = 0;
  2008. *pu8CurrByte++ = 0;
  2009. *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
  2010. *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
  2011. *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
  2012. *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
  2013. if ((strHostIfSetMulti->cnt) > 0)
  2014. memcpy(pu8CurrByte, wilc_multicast_mac_addr_list,
  2015. ((strHostIfSetMulti->cnt) * ETH_ALEN));
  2016. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  2017. wilc_get_vif_idx(vif));
  2018. if (result)
  2019. netdev_err(vif->ndev, "Failed to send setup multicast\n");
  2020. ERRORHANDLER:
  2021. kfree(wid.val);
  2022. }
  2023. static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
  2024. {
  2025. int ret;
  2026. struct wid wid;
  2027. wid.id = (u16)WID_TX_POWER;
  2028. wid.type = WID_CHAR;
  2029. wid.val = &tx_pwr;
  2030. wid.size = sizeof(char);
  2031. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  2032. wilc_get_vif_idx(vif));
  2033. if (ret)
  2034. netdev_err(vif->ndev, "Failed to set TX PWR\n");
  2035. }
  2036. static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
  2037. {
  2038. int ret = 0;
  2039. struct wid wid;
  2040. wid.id = (u16)WID_TX_POWER;
  2041. wid.type = WID_CHAR;
  2042. wid.val = (s8 *)tx_pwr;
  2043. wid.size = sizeof(char);
  2044. ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  2045. wilc_get_vif_idx(vif));
  2046. if (ret)
  2047. netdev_err(vif->ndev, "Failed to get TX PWR\n");
  2048. complete(&hif_wait_response);
  2049. }
  2050. static int hostIFthread(void *pvArg)
  2051. {
  2052. u32 u32Ret;
  2053. struct host_if_msg msg;
  2054. struct wilc *wilc = pvArg;
  2055. struct wilc_vif *vif;
  2056. memset(&msg, 0, sizeof(struct host_if_msg));
  2057. while (1) {
  2058. wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
  2059. vif = msg.vif;
  2060. if (msg.id == HOST_IF_MSG_EXIT)
  2061. break;
  2062. if ((!wilc_initialized)) {
  2063. usleep_range(200 * 1000, 200 * 1000);
  2064. wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2065. continue;
  2066. }
  2067. if (msg.id == HOST_IF_MSG_CONNECT &&
  2068. vif->hif_drv->usr_scan_req.scan_result) {
  2069. wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2070. usleep_range(2 * 1000, 2 * 1000);
  2071. continue;
  2072. }
  2073. switch (msg.id) {
  2074. case HOST_IF_MSG_SCAN:
  2075. handle_scan(msg.vif, &msg.body.scan_info);
  2076. break;
  2077. case HOST_IF_MSG_CONNECT:
  2078. Handle_Connect(msg.vif, &msg.body.con_info);
  2079. break;
  2080. case HOST_IF_MSG_RCVD_NTWRK_INFO:
  2081. Handle_RcvdNtwrkInfo(msg.vif, &msg.body.net_info);
  2082. break;
  2083. case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
  2084. Handle_RcvdGnrlAsyncInfo(vif,
  2085. &msg.body.async_info);
  2086. break;
  2087. case HOST_IF_MSG_KEY:
  2088. Handle_Key(msg.vif, &msg.body.key_info);
  2089. break;
  2090. case HOST_IF_MSG_CFG_PARAMS:
  2091. handle_cfg_param(msg.vif, &msg.body.cfg_info);
  2092. break;
  2093. case HOST_IF_MSG_SET_CHANNEL:
  2094. handle_set_channel(msg.vif, &msg.body.channel_info);
  2095. break;
  2096. case HOST_IF_MSG_DISCONNECT:
  2097. Handle_Disconnect(msg.vif);
  2098. break;
  2099. case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
  2100. del_timer(&vif->hif_drv->scan_timer);
  2101. if (!wilc_wlan_get_num_conn_ifcs(wilc))
  2102. wilc_chip_sleep_manually(wilc);
  2103. Handle_ScanDone(msg.vif, SCAN_EVENT_DONE);
  2104. if (vif->hif_drv->remain_on_ch_pending)
  2105. Handle_RemainOnChan(msg.vif,
  2106. &msg.body.remain_on_ch);
  2107. break;
  2108. case HOST_IF_MSG_GET_RSSI:
  2109. Handle_GetRssi(msg.vif);
  2110. break;
  2111. case HOST_IF_MSG_GET_STATISTICS:
  2112. Handle_GetStatistics(msg.vif,
  2113. (struct rf_info *)msg.body.data);
  2114. break;
  2115. case HOST_IF_MSG_ADD_BEACON:
  2116. Handle_AddBeacon(msg.vif, &msg.body.beacon_info);
  2117. break;
  2118. case HOST_IF_MSG_DEL_BEACON:
  2119. Handle_DelBeacon(msg.vif);
  2120. break;
  2121. case HOST_IF_MSG_ADD_STATION:
  2122. Handle_AddStation(msg.vif, &msg.body.add_sta_info);
  2123. break;
  2124. case HOST_IF_MSG_DEL_STATION:
  2125. Handle_DelStation(msg.vif, &msg.body.del_sta_info);
  2126. break;
  2127. case HOST_IF_MSG_EDIT_STATION:
  2128. Handle_EditStation(msg.vif, &msg.body.edit_sta_info);
  2129. break;
  2130. case HOST_IF_MSG_GET_INACTIVETIME:
  2131. Handle_Get_InActiveTime(msg.vif, &msg.body.mac_info);
  2132. break;
  2133. case HOST_IF_MSG_SCAN_TIMER_FIRED:
  2134. Handle_ScanDone(msg.vif, SCAN_EVENT_ABORTED);
  2135. break;
  2136. case HOST_IF_MSG_CONNECT_TIMER_FIRED:
  2137. Handle_ConnectTimeout(msg.vif);
  2138. break;
  2139. case HOST_IF_MSG_POWER_MGMT:
  2140. Handle_PowerManagement(msg.vif,
  2141. &msg.body.pwr_mgmt_info);
  2142. break;
  2143. case HOST_IF_MSG_SET_WFIDRV_HANDLER:
  2144. handle_set_wfi_drv_handler(msg.vif, &msg.body.drv);
  2145. break;
  2146. case HOST_IF_MSG_SET_OPERATION_MODE:
  2147. handle_set_operation_mode(msg.vif, &msg.body.mode);
  2148. break;
  2149. case HOST_IF_MSG_SET_IPADDRESS:
  2150. handle_set_ip_address(vif,
  2151. msg.body.ip_info.ip_addr,
  2152. msg.body.ip_info.idx);
  2153. break;
  2154. case HOST_IF_MSG_GET_IPADDRESS:
  2155. handle_get_ip_address(vif, msg.body.ip_info.idx);
  2156. break;
  2157. case HOST_IF_MSG_GET_MAC_ADDRESS:
  2158. handle_get_mac_address(msg.vif,
  2159. &msg.body.get_mac_info);
  2160. break;
  2161. case HOST_IF_MSG_REMAIN_ON_CHAN:
  2162. Handle_RemainOnChan(msg.vif, &msg.body.remain_on_ch);
  2163. break;
  2164. case HOST_IF_MSG_REGISTER_FRAME:
  2165. Handle_RegisterFrame(msg.vif, &msg.body.reg_frame);
  2166. break;
  2167. case HOST_IF_MSG_LISTEN_TIMER_FIRED:
  2168. Handle_ListenStateExpired(msg.vif, &msg.body.remain_on_ch);
  2169. break;
  2170. case HOST_IF_MSG_SET_MULTICAST_FILTER:
  2171. Handle_SetMulticastFilter(msg.vif, &msg.body.multicast_info);
  2172. break;
  2173. case HOST_IF_MSG_DEL_ALL_STA:
  2174. Handle_DelAllSta(msg.vif, &msg.body.del_all_sta_info);
  2175. break;
  2176. case HOST_IF_MSG_SET_TX_POWER:
  2177. handle_set_tx_pwr(msg.vif, msg.body.tx_power.tx_pwr);
  2178. break;
  2179. case HOST_IF_MSG_GET_TX_POWER:
  2180. handle_get_tx_pwr(msg.vif, &msg.body.tx_power.tx_pwr);
  2181. break;
  2182. default:
  2183. netdev_err(vif->ndev, "[Host Interface] undefined\n");
  2184. break;
  2185. }
  2186. }
  2187. complete(&hif_thread_comp);
  2188. return 0;
  2189. }
  2190. static void TimerCB_Scan(unsigned long arg)
  2191. {
  2192. struct wilc_vif *vif = (struct wilc_vif *)arg;
  2193. struct host_if_msg msg;
  2194. memset(&msg, 0, sizeof(struct host_if_msg));
  2195. msg.vif = vif;
  2196. msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
  2197. wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2198. }
  2199. static void TimerCB_Connect(unsigned long arg)
  2200. {
  2201. struct wilc_vif *vif = (struct wilc_vif *)arg;
  2202. struct host_if_msg msg;
  2203. memset(&msg, 0, sizeof(struct host_if_msg));
  2204. msg.vif = vif;
  2205. msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
  2206. wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2207. }
  2208. s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
  2209. {
  2210. struct wid wid;
  2211. wid.id = (u16)WID_REMOVE_KEY;
  2212. wid.type = WID_STR;
  2213. wid.val = (s8 *)pu8StaAddress;
  2214. wid.size = 6;
  2215. return 0;
  2216. }
  2217. int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
  2218. {
  2219. int result = 0;
  2220. struct host_if_msg msg;
  2221. struct host_if_drv *hif_drv = vif->hif_drv;
  2222. if (!hif_drv) {
  2223. result = -EFAULT;
  2224. netdev_err(vif->ndev, "Failed to send setup multicast\n");
  2225. return result;
  2226. }
  2227. memset(&msg, 0, sizeof(struct host_if_msg));
  2228. msg.id = HOST_IF_MSG_KEY;
  2229. msg.body.key_info.type = WEP;
  2230. msg.body.key_info.action = REMOVEKEY;
  2231. msg.vif = vif;
  2232. msg.body.key_info.attr.wep.index = index;
  2233. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2234. if (result)
  2235. netdev_err(vif->ndev, "Request to remove WEP key\n");
  2236. else
  2237. wait_for_completion(&hif_drv->comp_test_key_block);
  2238. return result;
  2239. }
  2240. int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
  2241. {
  2242. int result = 0;
  2243. struct host_if_msg msg;
  2244. struct host_if_drv *hif_drv = vif->hif_drv;
  2245. if (!hif_drv) {
  2246. result = -EFAULT;
  2247. netdev_err(vif->ndev, "driver is null\n");
  2248. return result;
  2249. }
  2250. memset(&msg, 0, sizeof(struct host_if_msg));
  2251. msg.id = HOST_IF_MSG_KEY;
  2252. msg.body.key_info.type = WEP;
  2253. msg.body.key_info.action = DEFAULTKEY;
  2254. msg.vif = vif;
  2255. msg.body.key_info.attr.wep.index = index;
  2256. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2257. if (result)
  2258. netdev_err(vif->ndev, "Default key index\n");
  2259. else
  2260. wait_for_completion(&hif_drv->comp_test_key_block);
  2261. return result;
  2262. }
  2263. int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
  2264. u8 index)
  2265. {
  2266. int result = 0;
  2267. struct host_if_msg msg;
  2268. struct host_if_drv *hif_drv = vif->hif_drv;
  2269. if (!hif_drv) {
  2270. netdev_err(vif->ndev, "driver is null\n");
  2271. return -EFAULT;
  2272. }
  2273. memset(&msg, 0, sizeof(struct host_if_msg));
  2274. msg.id = HOST_IF_MSG_KEY;
  2275. msg.body.key_info.type = WEP;
  2276. msg.body.key_info.action = ADDKEY;
  2277. msg.vif = vif;
  2278. msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
  2279. if (!msg.body.key_info.attr.wep.key)
  2280. return -ENOMEM;
  2281. msg.body.key_info.attr.wep.key_len = len;
  2282. msg.body.key_info.attr.wep.index = index;
  2283. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2284. if (result)
  2285. netdev_err(vif->ndev, "STA - WEP Key\n");
  2286. wait_for_completion(&hif_drv->comp_test_key_block);
  2287. return result;
  2288. }
  2289. int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
  2290. u8 index, u8 mode, enum AUTHTYPE auth_type)
  2291. {
  2292. int result = 0;
  2293. struct host_if_msg msg;
  2294. struct host_if_drv *hif_drv = vif->hif_drv;
  2295. if (!hif_drv) {
  2296. netdev_err(vif->ndev, "driver is null\n");
  2297. return -EFAULT;
  2298. }
  2299. memset(&msg, 0, sizeof(struct host_if_msg));
  2300. msg.id = HOST_IF_MSG_KEY;
  2301. msg.body.key_info.type = WEP;
  2302. msg.body.key_info.action = ADDKEY_AP;
  2303. msg.vif = vif;
  2304. msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
  2305. if (!msg.body.key_info.attr.wep.key)
  2306. return -ENOMEM;
  2307. msg.body.key_info.attr.wep.key_len = len;
  2308. msg.body.key_info.attr.wep.index = index;
  2309. msg.body.key_info.attr.wep.mode = mode;
  2310. msg.body.key_info.attr.wep.auth_type = auth_type;
  2311. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2312. if (result)
  2313. netdev_err(vif->ndev, "AP - WEP Key\n");
  2314. else
  2315. wait_for_completion(&hif_drv->comp_test_key_block);
  2316. return result;
  2317. }
  2318. int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
  2319. const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
  2320. u8 mode, u8 cipher_mode, u8 index)
  2321. {
  2322. int result = 0;
  2323. struct host_if_msg msg;
  2324. struct host_if_drv *hif_drv = vif->hif_drv;
  2325. u8 key_len = ptk_key_len;
  2326. if (!hif_drv) {
  2327. netdev_err(vif->ndev, "driver is null\n");
  2328. return -EFAULT;
  2329. }
  2330. if (rx_mic)
  2331. key_len += RX_MIC_KEY_LEN;
  2332. if (tx_mic)
  2333. key_len += TX_MIC_KEY_LEN;
  2334. memset(&msg, 0, sizeof(struct host_if_msg));
  2335. msg.id = HOST_IF_MSG_KEY;
  2336. msg.body.key_info.type = WPA_PTK;
  2337. if (mode == AP_MODE) {
  2338. msg.body.key_info.action = ADDKEY_AP;
  2339. msg.body.key_info.attr.wpa.index = index;
  2340. }
  2341. if (mode == STATION_MODE)
  2342. msg.body.key_info.action = ADDKEY;
  2343. msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
  2344. if (!msg.body.key_info.attr.wpa.key)
  2345. return -ENOMEM;
  2346. if (rx_mic)
  2347. memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN);
  2348. if (tx_mic)
  2349. memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN);
  2350. msg.body.key_info.attr.wpa.key_len = key_len;
  2351. msg.body.key_info.attr.wpa.mac_addr = mac_addr;
  2352. msg.body.key_info.attr.wpa.mode = cipher_mode;
  2353. msg.vif = vif;
  2354. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2355. if (result)
  2356. netdev_err(vif->ndev, "PTK Key\n");
  2357. else
  2358. wait_for_completion(&hif_drv->comp_test_key_block);
  2359. return result;
  2360. }
  2361. int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
  2362. u8 index, u32 key_rsc_len, const u8 *key_rsc,
  2363. const u8 *rx_mic, const u8 *tx_mic, u8 mode,
  2364. u8 cipher_mode)
  2365. {
  2366. int result = 0;
  2367. struct host_if_msg msg;
  2368. struct host_if_drv *hif_drv = vif->hif_drv;
  2369. u8 key_len = gtk_key_len;
  2370. if (!hif_drv) {
  2371. netdev_err(vif->ndev, "driver is null\n");
  2372. return -EFAULT;
  2373. }
  2374. memset(&msg, 0, sizeof(struct host_if_msg));
  2375. if (rx_mic)
  2376. key_len += RX_MIC_KEY_LEN;
  2377. if (tx_mic)
  2378. key_len += TX_MIC_KEY_LEN;
  2379. if (key_rsc) {
  2380. msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
  2381. key_rsc_len,
  2382. GFP_KERNEL);
  2383. if (!msg.body.key_info.attr.wpa.seq)
  2384. return -ENOMEM;
  2385. }
  2386. msg.id = HOST_IF_MSG_KEY;
  2387. msg.body.key_info.type = WPA_RX_GTK;
  2388. msg.vif = vif;
  2389. if (mode == AP_MODE) {
  2390. msg.body.key_info.action = ADDKEY_AP;
  2391. msg.body.key_info.attr.wpa.mode = cipher_mode;
  2392. }
  2393. if (mode == STATION_MODE)
  2394. msg.body.key_info.action = ADDKEY;
  2395. msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
  2396. key_len,
  2397. GFP_KERNEL);
  2398. if (!msg.body.key_info.attr.wpa.key)
  2399. return -ENOMEM;
  2400. if (rx_mic)
  2401. memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
  2402. RX_MIC_KEY_LEN);
  2403. if (tx_mic)
  2404. memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
  2405. TX_MIC_KEY_LEN);
  2406. msg.body.key_info.attr.wpa.index = index;
  2407. msg.body.key_info.attr.wpa.key_len = key_len;
  2408. msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
  2409. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2410. if (result)
  2411. netdev_err(vif->ndev, "RX GTK\n");
  2412. else
  2413. wait_for_completion(&hif_drv->comp_test_key_block);
  2414. return result;
  2415. }
  2416. int wilc_set_pmkid_info(struct wilc_vif *vif,
  2417. struct host_if_pmkid_attr *pmkid)
  2418. {
  2419. int result = 0;
  2420. struct host_if_msg msg;
  2421. int i;
  2422. memset(&msg, 0, sizeof(struct host_if_msg));
  2423. msg.id = HOST_IF_MSG_KEY;
  2424. msg.body.key_info.type = PMKSA;
  2425. msg.body.key_info.action = ADDKEY;
  2426. msg.vif = vif;
  2427. for (i = 0; i < pmkid->numpmkid; i++) {
  2428. memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
  2429. &pmkid->pmkidlist[i].bssid, ETH_ALEN);
  2430. memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
  2431. &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
  2432. }
  2433. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2434. if (result)
  2435. netdev_err(vif->ndev, "PMKID Info\n");
  2436. return result;
  2437. }
  2438. int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
  2439. {
  2440. int result = 0;
  2441. struct host_if_msg msg;
  2442. memset(&msg, 0, sizeof(struct host_if_msg));
  2443. msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
  2444. msg.body.get_mac_info.mac_addr = mac_addr;
  2445. msg.vif = vif;
  2446. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2447. if (result) {
  2448. netdev_err(vif->ndev, "Failed to send get mac address\n");
  2449. return -EFAULT;
  2450. }
  2451. wait_for_completion(&hif_wait_response);
  2452. return result;
  2453. }
  2454. int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
  2455. size_t ssid_len, const u8 *ies, size_t ies_len,
  2456. wilc_connect_result connect_result, void *user_arg,
  2457. u8 security, enum AUTHTYPE auth_type,
  2458. u8 channel, void *join_params)
  2459. {
  2460. int result = 0;
  2461. struct host_if_msg msg;
  2462. struct host_if_drv *hif_drv = vif->hif_drv;
  2463. if (!hif_drv || !connect_result) {
  2464. netdev_err(vif->ndev, "Driver is null\n");
  2465. return -EFAULT;
  2466. }
  2467. if (!join_params) {
  2468. netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
  2469. return -EFAULT;
  2470. }
  2471. memset(&msg, 0, sizeof(struct host_if_msg));
  2472. msg.id = HOST_IF_MSG_CONNECT;
  2473. msg.body.con_info.security = security;
  2474. msg.body.con_info.auth_type = auth_type;
  2475. msg.body.con_info.ch = channel;
  2476. msg.body.con_info.result = connect_result;
  2477. msg.body.con_info.arg = user_arg;
  2478. msg.body.con_info.params = join_params;
  2479. msg.vif = vif;
  2480. if (bssid) {
  2481. msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
  2482. if (!msg.body.con_info.bssid)
  2483. return -ENOMEM;
  2484. }
  2485. if (ssid) {
  2486. msg.body.con_info.ssid_len = ssid_len;
  2487. msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
  2488. if (!msg.body.con_info.ssid)
  2489. return -ENOMEM;
  2490. }
  2491. if (ies) {
  2492. msg.body.con_info.ies_len = ies_len;
  2493. msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
  2494. if (!msg.body.con_info.ies)
  2495. return -ENOMEM;
  2496. }
  2497. if (hif_drv->hif_state < HOST_IF_CONNECTING)
  2498. hif_drv->hif_state = HOST_IF_CONNECTING;
  2499. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2500. if (result) {
  2501. netdev_err(vif->ndev, "send message: Set join request\n");
  2502. return -EFAULT;
  2503. }
  2504. hif_drv->connect_timer.data = (unsigned long)vif;
  2505. mod_timer(&hif_drv->connect_timer,
  2506. jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
  2507. return result;
  2508. }
  2509. int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
  2510. {
  2511. int result = 0;
  2512. struct host_if_msg msg;
  2513. struct host_if_drv *hif_drv = vif->hif_drv;
  2514. if (!hif_drv) {
  2515. netdev_err(vif->ndev, "Driver is null\n");
  2516. return -EFAULT;
  2517. }
  2518. memset(&msg, 0, sizeof(struct host_if_msg));
  2519. msg.id = HOST_IF_MSG_DISCONNECT;
  2520. msg.vif = vif;
  2521. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2522. if (result)
  2523. netdev_err(vif->ndev, "Failed to send message: disconnect\n");
  2524. else
  2525. wait_for_completion(&hif_drv->comp_test_disconn_block);
  2526. return result;
  2527. }
  2528. static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
  2529. u8 *pu8AssocRespInfo,
  2530. u32 u32MaxAssocRespInfoLen,
  2531. u32 *pu32RcvdAssocRespInfoLen)
  2532. {
  2533. s32 result = 0;
  2534. struct wid wid;
  2535. wid.id = (u16)WID_ASSOC_RES_INFO;
  2536. wid.type = WID_STR;
  2537. wid.val = pu8AssocRespInfo;
  2538. wid.size = u32MaxAssocRespInfoLen;
  2539. result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  2540. wilc_get_vif_idx(vif));
  2541. if (result) {
  2542. *pu32RcvdAssocRespInfoLen = 0;
  2543. netdev_err(vif->ndev, "Failed to send association response\n");
  2544. return -EINVAL;
  2545. }
  2546. *pu32RcvdAssocRespInfoLen = wid.size;
  2547. return result;
  2548. }
  2549. int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
  2550. {
  2551. int result;
  2552. struct host_if_msg msg;
  2553. memset(&msg, 0, sizeof(struct host_if_msg));
  2554. msg.id = HOST_IF_MSG_SET_CHANNEL;
  2555. msg.body.channel_info.set_ch = channel;
  2556. msg.vif = vif;
  2557. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2558. if (result) {
  2559. netdev_err(vif->ndev, "wilc mq send fail\n");
  2560. return -EINVAL;
  2561. }
  2562. return 0;
  2563. }
  2564. int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
  2565. {
  2566. int result = 0;
  2567. struct host_if_msg msg;
  2568. memset(&msg, 0, sizeof(struct host_if_msg));
  2569. msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
  2570. msg.body.drv.handler = index;
  2571. msg.body.drv.mac_idx = mac_idx;
  2572. msg.vif = vif;
  2573. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2574. if (result) {
  2575. netdev_err(vif->ndev, "wilc mq send fail\n");
  2576. result = -EINVAL;
  2577. }
  2578. return result;
  2579. }
  2580. int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
  2581. {
  2582. int result = 0;
  2583. struct host_if_msg msg;
  2584. memset(&msg, 0, sizeof(struct host_if_msg));
  2585. msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
  2586. msg.body.mode.mode = mode;
  2587. msg.vif = vif;
  2588. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2589. if (result) {
  2590. netdev_err(vif->ndev, "wilc mq send fail\n");
  2591. result = -EINVAL;
  2592. }
  2593. return result;
  2594. }
  2595. s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
  2596. u32 *pu32InactiveTime)
  2597. {
  2598. s32 result = 0;
  2599. struct host_if_msg msg;
  2600. struct host_if_drv *hif_drv = vif->hif_drv;
  2601. if (!hif_drv) {
  2602. netdev_err(vif->ndev, "driver is null\n");
  2603. return -EFAULT;
  2604. }
  2605. memset(&msg, 0, sizeof(struct host_if_msg));
  2606. memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
  2607. msg.id = HOST_IF_MSG_GET_INACTIVETIME;
  2608. msg.vif = vif;
  2609. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2610. if (result)
  2611. netdev_err(vif->ndev, "Failed to send get host ch param\n");
  2612. else
  2613. wait_for_completion(&hif_drv->comp_inactive_time);
  2614. *pu32InactiveTime = inactive_time;
  2615. return result;
  2616. }
  2617. int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
  2618. {
  2619. int result = 0;
  2620. struct host_if_msg msg;
  2621. struct host_if_drv *hif_drv = vif->hif_drv;
  2622. memset(&msg, 0, sizeof(struct host_if_msg));
  2623. msg.id = HOST_IF_MSG_GET_RSSI;
  2624. msg.vif = vif;
  2625. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2626. if (result) {
  2627. netdev_err(vif->ndev, "Failed to send get host ch param\n");
  2628. return -EFAULT;
  2629. }
  2630. wait_for_completion(&hif_drv->comp_get_rssi);
  2631. if (!rssi_level) {
  2632. netdev_err(vif->ndev, "RSS pointer value is null\n");
  2633. return -EFAULT;
  2634. }
  2635. *rssi_level = rssi;
  2636. return result;
  2637. }
  2638. int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
  2639. {
  2640. int result = 0;
  2641. struct host_if_msg msg;
  2642. memset(&msg, 0, sizeof(struct host_if_msg));
  2643. msg.id = HOST_IF_MSG_GET_STATISTICS;
  2644. msg.body.data = (char *)stats;
  2645. msg.vif = vif;
  2646. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2647. if (result) {
  2648. netdev_err(vif->ndev, "Failed to send get host channel\n");
  2649. return -EFAULT;
  2650. }
  2651. if (stats != &vif->wilc->dummy_statistics)
  2652. wait_for_completion(&hif_wait_response);
  2653. return result;
  2654. }
  2655. int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
  2656. u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
  2657. size_t ies_len, wilc_scan_result scan_result, void *user_arg,
  2658. struct hidden_network *hidden_network)
  2659. {
  2660. int result = 0;
  2661. struct host_if_msg msg;
  2662. struct scan_attr *scan_info = &msg.body.scan_info;
  2663. struct host_if_drv *hif_drv = vif->hif_drv;
  2664. if (!hif_drv || !scan_result) {
  2665. netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
  2666. return -EFAULT;
  2667. }
  2668. memset(&msg, 0, sizeof(struct host_if_msg));
  2669. msg.id = HOST_IF_MSG_SCAN;
  2670. if (hidden_network) {
  2671. scan_info->hidden_network.net_info = hidden_network->net_info;
  2672. scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
  2673. }
  2674. msg.vif = vif;
  2675. scan_info->src = scan_source;
  2676. scan_info->type = scan_type;
  2677. scan_info->result = scan_result;
  2678. scan_info->arg = user_arg;
  2679. scan_info->ch_list_len = ch_list_len;
  2680. scan_info->ch_freq_list = kmemdup(ch_freq_list,
  2681. ch_list_len,
  2682. GFP_KERNEL);
  2683. if (!scan_info->ch_freq_list)
  2684. return -ENOMEM;
  2685. scan_info->ies_len = ies_len;
  2686. scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
  2687. if (!scan_info->ies)
  2688. return -ENOMEM;
  2689. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2690. if (result) {
  2691. netdev_err(vif->ndev, "Error in sending message queue\n");
  2692. return -EINVAL;
  2693. }
  2694. hif_drv->scan_timer.data = (unsigned long)vif;
  2695. mod_timer(&hif_drv->scan_timer,
  2696. jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
  2697. return result;
  2698. }
  2699. int wilc_hif_set_cfg(struct wilc_vif *vif,
  2700. struct cfg_param_attr *cfg_param)
  2701. {
  2702. int result = 0;
  2703. struct host_if_msg msg;
  2704. struct host_if_drv *hif_drv = vif->hif_drv;
  2705. if (!hif_drv) {
  2706. netdev_err(vif->ndev, "hif_drv NULL\n");
  2707. return -EFAULT;
  2708. }
  2709. memset(&msg, 0, sizeof(struct host_if_msg));
  2710. msg.id = HOST_IF_MSG_CFG_PARAMS;
  2711. msg.body.cfg_info = *cfg_param;
  2712. msg.vif = vif;
  2713. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2714. return result;
  2715. }
  2716. static void GetPeriodicRSSI(unsigned long arg)
  2717. {
  2718. struct wilc_vif *vif = (struct wilc_vif *)arg;
  2719. if (!vif->hif_drv) {
  2720. netdev_err(vif->ndev, "Driver handler is NULL\n");
  2721. return;
  2722. }
  2723. if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
  2724. wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
  2725. periodic_rssi.data = (unsigned long)vif;
  2726. mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
  2727. }
  2728. int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
  2729. {
  2730. int result = 0;
  2731. struct host_if_drv *hif_drv;
  2732. struct wilc_vif *vif;
  2733. struct wilc *wilc;
  2734. int i;
  2735. vif = netdev_priv(dev);
  2736. wilc = vif->wilc;
  2737. scan_while_connected = false;
  2738. init_completion(&hif_wait_response);
  2739. hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
  2740. if (!hif_drv) {
  2741. result = -ENOMEM;
  2742. goto _fail_;
  2743. }
  2744. *hif_drv_handler = hif_drv;
  2745. for (i = 0; i < wilc->vif_num; i++)
  2746. if (dev == wilc->vif[i]->ndev) {
  2747. wilc->vif[i]->hif_drv = hif_drv;
  2748. break;
  2749. }
  2750. wilc_optaining_ip = false;
  2751. if (clients_count == 0) {
  2752. init_completion(&hif_thread_comp);
  2753. init_completion(&hif_driver_comp);
  2754. mutex_init(&hif_deinit_lock);
  2755. }
  2756. init_completion(&hif_drv->comp_test_key_block);
  2757. init_completion(&hif_drv->comp_test_disconn_block);
  2758. init_completion(&hif_drv->comp_get_rssi);
  2759. init_completion(&hif_drv->comp_inactive_time);
  2760. if (clients_count == 0) {
  2761. result = wilc_mq_create(&hif_msg_q);
  2762. if (result < 0) {
  2763. netdev_err(vif->ndev, "Failed to creat MQ\n");
  2764. goto _fail_;
  2765. }
  2766. hif_thread_handler = kthread_run(hostIFthread, wilc,
  2767. "WILC_kthread");
  2768. if (IS_ERR(hif_thread_handler)) {
  2769. netdev_err(vif->ndev, "Failed to creat Thread\n");
  2770. result = -EFAULT;
  2771. goto _fail_mq_;
  2772. }
  2773. setup_timer(&periodic_rssi, GetPeriodicRSSI,
  2774. (unsigned long)vif);
  2775. mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
  2776. }
  2777. setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0);
  2778. setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0);
  2779. setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0);
  2780. mutex_init(&hif_drv->cfg_values_lock);
  2781. mutex_lock(&hif_drv->cfg_values_lock);
  2782. hif_drv->hif_state = HOST_IF_IDLE;
  2783. hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
  2784. hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
  2785. hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
  2786. hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
  2787. hif_drv->cfg_values.curr_tx_rate = AUTORATE;
  2788. hif_drv->p2p_timeout = 0;
  2789. mutex_unlock(&hif_drv->cfg_values_lock);
  2790. clients_count++;
  2791. return result;
  2792. _fail_mq_:
  2793. wilc_mq_destroy(&hif_msg_q);
  2794. _fail_:
  2795. return result;
  2796. }
  2797. int wilc_deinit(struct wilc_vif *vif)
  2798. {
  2799. int result = 0;
  2800. struct host_if_msg msg;
  2801. struct host_if_drv *hif_drv = vif->hif_drv;
  2802. if (!hif_drv) {
  2803. netdev_err(vif->ndev, "hif_drv = NULL\n");
  2804. return -EFAULT;
  2805. }
  2806. mutex_lock(&hif_deinit_lock);
  2807. terminated_handle = hif_drv;
  2808. del_timer_sync(&hif_drv->scan_timer);
  2809. del_timer_sync(&hif_drv->connect_timer);
  2810. del_timer_sync(&periodic_rssi);
  2811. del_timer_sync(&hif_drv->remain_on_ch_timer);
  2812. wilc_set_wfi_drv_handler(vif, 0, 0);
  2813. wait_for_completion(&hif_driver_comp);
  2814. if (hif_drv->usr_scan_req.scan_result) {
  2815. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
  2816. hif_drv->usr_scan_req.arg, NULL);
  2817. hif_drv->usr_scan_req.scan_result = NULL;
  2818. }
  2819. hif_drv->hif_state = HOST_IF_IDLE;
  2820. scan_while_connected = false;
  2821. memset(&msg, 0, sizeof(struct host_if_msg));
  2822. if (clients_count == 1) {
  2823. msg.id = HOST_IF_MSG_EXIT;
  2824. msg.vif = vif;
  2825. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2826. if (result != 0)
  2827. netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
  2828. else
  2829. wait_for_completion(&hif_thread_comp);
  2830. wilc_mq_destroy(&hif_msg_q);
  2831. }
  2832. kfree(hif_drv);
  2833. clients_count--;
  2834. terminated_handle = NULL;
  2835. mutex_unlock(&hif_deinit_lock);
  2836. return result;
  2837. }
  2838. void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer,
  2839. u32 u32Length)
  2840. {
  2841. s32 result = 0;
  2842. struct host_if_msg msg;
  2843. int id;
  2844. struct host_if_drv *hif_drv = NULL;
  2845. struct wilc_vif *vif;
  2846. id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
  2847. vif = wilc_get_vif_from_idx(wilc, id);
  2848. if (!vif)
  2849. return;
  2850. hif_drv = vif->hif_drv;
  2851. if (!hif_drv || hif_drv == terminated_handle) {
  2852. netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
  2853. return;
  2854. }
  2855. memset(&msg, 0, sizeof(struct host_if_msg));
  2856. msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
  2857. msg.vif = vif;
  2858. msg.body.net_info.len = u32Length;
  2859. msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
  2860. memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
  2861. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2862. if (result)
  2863. netdev_err(vif->ndev, "message parameters (%d)\n", result);
  2864. }
  2865. void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer,
  2866. u32 u32Length)
  2867. {
  2868. s32 result = 0;
  2869. struct host_if_msg msg;
  2870. int id;
  2871. struct host_if_drv *hif_drv = NULL;
  2872. struct wilc_vif *vif;
  2873. mutex_lock(&hif_deinit_lock);
  2874. id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
  2875. vif = wilc_get_vif_from_idx(wilc, id);
  2876. if (!vif) {
  2877. mutex_unlock(&hif_deinit_lock);
  2878. return;
  2879. }
  2880. hif_drv = vif->hif_drv;
  2881. if (!hif_drv || hif_drv == terminated_handle) {
  2882. mutex_unlock(&hif_deinit_lock);
  2883. return;
  2884. }
  2885. if (!hif_drv->usr_conn_req.conn_result) {
  2886. netdev_err(vif->ndev, "there is no current Connect Request\n");
  2887. mutex_unlock(&hif_deinit_lock);
  2888. return;
  2889. }
  2890. memset(&msg, 0, sizeof(struct host_if_msg));
  2891. msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
  2892. msg.vif = vif;
  2893. msg.body.async_info.len = u32Length;
  2894. msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
  2895. memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
  2896. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2897. if (result)
  2898. netdev_err(vif->ndev, "synchronous info (%d)\n", result);
  2899. mutex_unlock(&hif_deinit_lock);
  2900. }
  2901. void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer,
  2902. u32 u32Length)
  2903. {
  2904. s32 result = 0;
  2905. struct host_if_msg msg;
  2906. int id;
  2907. struct host_if_drv *hif_drv = NULL;
  2908. struct wilc_vif *vif;
  2909. id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
  2910. vif = wilc_get_vif_from_idx(wilc, id);
  2911. if (!vif)
  2912. return;
  2913. hif_drv = vif->hif_drv;
  2914. if (!hif_drv || hif_drv == terminated_handle)
  2915. return;
  2916. if (hif_drv->usr_scan_req.scan_result) {
  2917. memset(&msg, 0, sizeof(struct host_if_msg));
  2918. msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
  2919. msg.vif = vif;
  2920. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2921. if (result)
  2922. netdev_err(vif->ndev, "complete param (%d)\n", result);
  2923. }
  2924. }
  2925. int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
  2926. u32 duration, u16 chan,
  2927. wilc_remain_on_chan_expired expired,
  2928. wilc_remain_on_chan_ready ready,
  2929. void *user_arg)
  2930. {
  2931. int result = 0;
  2932. struct host_if_msg msg;
  2933. memset(&msg, 0, sizeof(struct host_if_msg));
  2934. msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
  2935. msg.body.remain_on_ch.ch = chan;
  2936. msg.body.remain_on_ch.expired = expired;
  2937. msg.body.remain_on_ch.ready = ready;
  2938. msg.body.remain_on_ch.arg = user_arg;
  2939. msg.body.remain_on_ch.duration = duration;
  2940. msg.body.remain_on_ch.id = session_id;
  2941. msg.vif = vif;
  2942. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2943. if (result)
  2944. netdev_err(vif->ndev, "wilc mq send fail\n");
  2945. return result;
  2946. }
  2947. int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
  2948. {
  2949. int result = 0;
  2950. struct host_if_msg msg;
  2951. struct host_if_drv *hif_drv = vif->hif_drv;
  2952. if (!hif_drv) {
  2953. netdev_err(vif->ndev, "driver is null\n");
  2954. return -EFAULT;
  2955. }
  2956. del_timer(&hif_drv->remain_on_ch_timer);
  2957. memset(&msg, 0, sizeof(struct host_if_msg));
  2958. msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
  2959. msg.vif = vif;
  2960. msg.body.remain_on_ch.id = session_id;
  2961. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2962. if (result)
  2963. netdev_err(vif->ndev, "wilc mq send fail\n");
  2964. return result;
  2965. }
  2966. int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
  2967. {
  2968. int result = 0;
  2969. struct host_if_msg msg;
  2970. memset(&msg, 0, sizeof(struct host_if_msg));
  2971. msg.id = HOST_IF_MSG_REGISTER_FRAME;
  2972. switch (frame_type) {
  2973. case ACTION:
  2974. msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
  2975. break;
  2976. case PROBE_REQ:
  2977. msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
  2978. break;
  2979. default:
  2980. break;
  2981. }
  2982. msg.body.reg_frame.frame_type = frame_type;
  2983. msg.body.reg_frame.reg = reg;
  2984. msg.vif = vif;
  2985. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  2986. if (result)
  2987. netdev_err(vif->ndev, "wilc mq send fail\n");
  2988. return result;
  2989. }
  2990. int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
  2991. u32 head_len, u8 *head, u32 tail_len, u8 *tail)
  2992. {
  2993. int result = 0;
  2994. struct host_if_msg msg;
  2995. struct beacon_attr *beacon_info = &msg.body.beacon_info;
  2996. memset(&msg, 0, sizeof(struct host_if_msg));
  2997. msg.id = HOST_IF_MSG_ADD_BEACON;
  2998. msg.vif = vif;
  2999. beacon_info->interval = interval;
  3000. beacon_info->dtim_period = dtim_period;
  3001. beacon_info->head_len = head_len;
  3002. beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
  3003. if (!beacon_info->head) {
  3004. result = -ENOMEM;
  3005. goto ERRORHANDLER;
  3006. }
  3007. beacon_info->tail_len = tail_len;
  3008. if (tail_len > 0) {
  3009. beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
  3010. if (!beacon_info->tail) {
  3011. result = -ENOMEM;
  3012. goto ERRORHANDLER;
  3013. }
  3014. } else {
  3015. beacon_info->tail = NULL;
  3016. }
  3017. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3018. if (result)
  3019. netdev_err(vif->ndev, "wilc mq send fail\n");
  3020. ERRORHANDLER:
  3021. if (result) {
  3022. kfree(beacon_info->head);
  3023. kfree(beacon_info->tail);
  3024. }
  3025. return result;
  3026. }
  3027. int wilc_del_beacon(struct wilc_vif *vif)
  3028. {
  3029. int result = 0;
  3030. struct host_if_msg msg;
  3031. msg.id = HOST_IF_MSG_DEL_BEACON;
  3032. msg.vif = vif;
  3033. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3034. if (result)
  3035. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3036. return result;
  3037. }
  3038. int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
  3039. {
  3040. int result = 0;
  3041. struct host_if_msg msg;
  3042. struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
  3043. memset(&msg, 0, sizeof(struct host_if_msg));
  3044. msg.id = HOST_IF_MSG_ADD_STATION;
  3045. msg.vif = vif;
  3046. memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
  3047. if (add_sta_info->rates_len > 0) {
  3048. add_sta_info->rates = kmemdup(sta_param->rates,
  3049. add_sta_info->rates_len,
  3050. GFP_KERNEL);
  3051. if (!add_sta_info->rates)
  3052. return -ENOMEM;
  3053. }
  3054. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3055. if (result)
  3056. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3057. return result;
  3058. }
  3059. int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
  3060. {
  3061. int result = 0;
  3062. struct host_if_msg msg;
  3063. struct del_sta *del_sta_info = &msg.body.del_sta_info;
  3064. memset(&msg, 0, sizeof(struct host_if_msg));
  3065. msg.id = HOST_IF_MSG_DEL_STATION;
  3066. msg.vif = vif;
  3067. if (!mac_addr)
  3068. eth_broadcast_addr(del_sta_info->mac_addr);
  3069. else
  3070. memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
  3071. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3072. if (result)
  3073. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3074. return result;
  3075. }
  3076. int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
  3077. {
  3078. int result = 0;
  3079. struct host_if_msg msg;
  3080. struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
  3081. u8 zero_addr[ETH_ALEN] = {0};
  3082. int i;
  3083. u8 assoc_sta = 0;
  3084. memset(&msg, 0, sizeof(struct host_if_msg));
  3085. msg.id = HOST_IF_MSG_DEL_ALL_STA;
  3086. msg.vif = vif;
  3087. for (i = 0; i < MAX_NUM_STA; i++) {
  3088. if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
  3089. memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i], ETH_ALEN);
  3090. assoc_sta++;
  3091. }
  3092. }
  3093. if (!assoc_sta)
  3094. return result;
  3095. del_all_sta_info->assoc_sta = assoc_sta;
  3096. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3097. if (result)
  3098. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3099. else
  3100. wait_for_completion(&hif_wait_response);
  3101. return result;
  3102. }
  3103. int wilc_edit_station(struct wilc_vif *vif,
  3104. struct add_sta_param *sta_param)
  3105. {
  3106. int result = 0;
  3107. struct host_if_msg msg;
  3108. struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
  3109. memset(&msg, 0, sizeof(struct host_if_msg));
  3110. msg.id = HOST_IF_MSG_EDIT_STATION;
  3111. msg.vif = vif;
  3112. memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
  3113. if (add_sta_info->rates_len > 0) {
  3114. add_sta_info->rates = kmemdup(sta_param->rates,
  3115. add_sta_info->rates_len,
  3116. GFP_KERNEL);
  3117. if (!add_sta_info->rates)
  3118. return -ENOMEM;
  3119. }
  3120. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3121. if (result)
  3122. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3123. return result;
  3124. }
  3125. int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
  3126. {
  3127. int result = 0;
  3128. struct host_if_msg msg;
  3129. struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
  3130. if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
  3131. return 0;
  3132. memset(&msg, 0, sizeof(struct host_if_msg));
  3133. msg.id = HOST_IF_MSG_POWER_MGMT;
  3134. msg.vif = vif;
  3135. pwr_mgmt_info->enabled = enabled;
  3136. pwr_mgmt_info->timeout = timeout;
  3137. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3138. if (result)
  3139. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3140. return result;
  3141. }
  3142. int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
  3143. u32 count)
  3144. {
  3145. int result = 0;
  3146. struct host_if_msg msg;
  3147. struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
  3148. memset(&msg, 0, sizeof(struct host_if_msg));
  3149. msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
  3150. msg.vif = vif;
  3151. multicast_filter_param->enabled = enabled;
  3152. multicast_filter_param->cnt = count;
  3153. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3154. if (result)
  3155. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3156. return result;
  3157. }
  3158. static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
  3159. {
  3160. struct join_bss_param *pNewJoinBssParam = NULL;
  3161. u8 *pu8IEs;
  3162. u16 u16IEsLen;
  3163. u16 index = 0;
  3164. u8 suppRatesNo = 0;
  3165. u8 extSuppRatesNo;
  3166. u16 jumpOffset;
  3167. u8 pcipherCount;
  3168. u8 authCount;
  3169. u8 pcipherTotalCount = 0;
  3170. u8 authTotalCount = 0;
  3171. u8 i, j;
  3172. pu8IEs = ptstrNetworkInfo->ies;
  3173. u16IEsLen = ptstrNetworkInfo->ies_len;
  3174. pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
  3175. if (pNewJoinBssParam) {
  3176. pNewJoinBssParam->dtim_period = ptstrNetworkInfo->dtim_period;
  3177. pNewJoinBssParam->beacon_period = ptstrNetworkInfo->beacon_period;
  3178. pNewJoinBssParam->cap_info = ptstrNetworkInfo->cap_info;
  3179. memcpy(pNewJoinBssParam->bssid, ptstrNetworkInfo->bssid, 6);
  3180. memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->ssid,
  3181. ptstrNetworkInfo->ssid_len + 1);
  3182. pNewJoinBssParam->ssid_len = ptstrNetworkInfo->ssid_len;
  3183. memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
  3184. memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
  3185. while (index < u16IEsLen) {
  3186. if (pu8IEs[index] == SUPP_RATES_IE) {
  3187. suppRatesNo = pu8IEs[index + 1];
  3188. pNewJoinBssParam->supp_rates[0] = suppRatesNo;
  3189. index += 2;
  3190. for (i = 0; i < suppRatesNo; i++)
  3191. pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
  3192. index += suppRatesNo;
  3193. continue;
  3194. } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
  3195. extSuppRatesNo = pu8IEs[index + 1];
  3196. if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
  3197. pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
  3198. else
  3199. pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
  3200. index += 2;
  3201. for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
  3202. pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
  3203. index += extSuppRatesNo;
  3204. continue;
  3205. } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
  3206. pNewJoinBssParam->ht_capable = true;
  3207. index += pu8IEs[index + 1] + 2;
  3208. continue;
  3209. } else if ((pu8IEs[index] == WMM_IE) &&
  3210. (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
  3211. (pu8IEs[index + 4] == 0xF2) &&
  3212. (pu8IEs[index + 5] == 0x02) &&
  3213. ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
  3214. (pu8IEs[index + 7] == 0x01)) {
  3215. pNewJoinBssParam->wmm_cap = true;
  3216. if (pu8IEs[index + 8] & BIT(7))
  3217. pNewJoinBssParam->uapsd_cap = true;
  3218. index += pu8IEs[index + 1] + 2;
  3219. continue;
  3220. } else if ((pu8IEs[index] == P2P_IE) &&
  3221. (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
  3222. (pu8IEs[index + 4] == 0x9a) &&
  3223. (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
  3224. u16 u16P2P_count;
  3225. pNewJoinBssParam->tsf = ptstrNetworkInfo->tsf_lo;
  3226. pNewJoinBssParam->noa_enabled = 1;
  3227. pNewJoinBssParam->idx = pu8IEs[index + 9];
  3228. if (pu8IEs[index + 10] & BIT(7)) {
  3229. pNewJoinBssParam->opp_enabled = 1;
  3230. pNewJoinBssParam->ct_window = pu8IEs[index + 10];
  3231. } else {
  3232. pNewJoinBssParam->opp_enabled = 0;
  3233. }
  3234. pNewJoinBssParam->cnt = pu8IEs[index + 11];
  3235. u16P2P_count = index + 12;
  3236. memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
  3237. u16P2P_count += 4;
  3238. memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
  3239. u16P2P_count += 4;
  3240. memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
  3241. index += pu8IEs[index + 1] + 2;
  3242. continue;
  3243. } else if ((pu8IEs[index] == RSN_IE) ||
  3244. ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
  3245. (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
  3246. (pu8IEs[index + 5] == 0x01))) {
  3247. u16 rsnIndex = index;
  3248. if (pu8IEs[rsnIndex] == RSN_IE) {
  3249. pNewJoinBssParam->mode_802_11i = 2;
  3250. } else {
  3251. if (pNewJoinBssParam->mode_802_11i == 0)
  3252. pNewJoinBssParam->mode_802_11i = 1;
  3253. rsnIndex += 4;
  3254. }
  3255. rsnIndex += 7;
  3256. pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
  3257. rsnIndex++;
  3258. jumpOffset = pu8IEs[rsnIndex] * 4;
  3259. pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
  3260. rsnIndex += 2;
  3261. for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
  3262. pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
  3263. pcipherTotalCount += pcipherCount;
  3264. rsnIndex += jumpOffset;
  3265. jumpOffset = pu8IEs[rsnIndex] * 4;
  3266. authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
  3267. rsnIndex += 2;
  3268. for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
  3269. pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
  3270. authTotalCount += authCount;
  3271. rsnIndex += jumpOffset;
  3272. if (pu8IEs[index] == RSN_IE) {
  3273. pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
  3274. pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
  3275. rsnIndex += 2;
  3276. }
  3277. pNewJoinBssParam->rsn_found = true;
  3278. index += pu8IEs[index + 1] + 2;
  3279. continue;
  3280. } else
  3281. index += pu8IEs[index + 1] + 2;
  3282. }
  3283. }
  3284. return (void *)pNewJoinBssParam;
  3285. }
  3286. int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
  3287. {
  3288. int result = 0;
  3289. struct host_if_msg msg;
  3290. memset(&msg, 0, sizeof(struct host_if_msg));
  3291. msg.id = HOST_IF_MSG_SET_IPADDRESS;
  3292. msg.body.ip_info.ip_addr = ip_addr;
  3293. msg.vif = vif;
  3294. msg.body.ip_info.idx = idx;
  3295. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3296. if (result)
  3297. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3298. return result;
  3299. }
  3300. static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
  3301. {
  3302. int result = 0;
  3303. struct host_if_msg msg;
  3304. memset(&msg, 0, sizeof(struct host_if_msg));
  3305. msg.id = HOST_IF_MSG_GET_IPADDRESS;
  3306. msg.body.ip_info.ip_addr = ip_addr;
  3307. msg.vif = vif;
  3308. msg.body.ip_info.idx = idx;
  3309. result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3310. if (result)
  3311. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3312. return result;
  3313. }
  3314. int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
  3315. {
  3316. int ret = 0;
  3317. struct host_if_msg msg;
  3318. memset(&msg, 0, sizeof(struct host_if_msg));
  3319. msg.id = HOST_IF_MSG_SET_TX_POWER;
  3320. msg.body.tx_power.tx_pwr = tx_power;
  3321. msg.vif = vif;
  3322. ret = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3323. if (ret)
  3324. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3325. return ret;
  3326. }
  3327. int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
  3328. {
  3329. int ret = 0;
  3330. struct host_if_msg msg;
  3331. memset(&msg, 0, sizeof(struct host_if_msg));
  3332. msg.id = HOST_IF_MSG_GET_TX_POWER;
  3333. msg.vif = vif;
  3334. ret = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
  3335. if (ret)
  3336. netdev_err(vif->ndev, "Failed to get TX PWR\n");
  3337. wait_for_completion(&hif_wait_response);
  3338. *tx_power = msg.body.tx_power.tx_pwr;
  3339. return ret;
  3340. }