PageRenderTime 64ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/wilc1000/host_interface.c

http://github.com/mirrors/linux-2.6
C | 4094 lines | 3306 code | 773 blank | 15 comment | 516 complexity | 36487000da69407ae6b0d036e5386c04 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  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 <linux/list.h>
  7. #include <linux/workqueue.h>
  8. #include "host_interface.h"
  9. #include <linux/spinlock.h>
  10. #include <linux/errno.h>
  11. #include "coreconfigurator.h"
  12. #include "wilc_wlan.h"
  13. #include "wilc_wlan_if.h"
  14. #include <linux/etherdevice.h>
  15. #include "wilc_wfi_netdevice.h"
  16. #define HOST_IF_MSG_SCAN 0
  17. #define HOST_IF_MSG_CONNECT 1
  18. #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
  19. #define HOST_IF_MSG_KEY 3
  20. #define HOST_IF_MSG_RCVD_NTWRK_INFO 4
  21. #define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
  22. #define HOST_IF_MSG_CFG_PARAMS 6
  23. #define HOST_IF_MSG_SET_CHANNEL 7
  24. #define HOST_IF_MSG_DISCONNECT 8
  25. #define HOST_IF_MSG_GET_RSSI 9
  26. #define HOST_IF_MSG_ADD_BEACON 11
  27. #define HOST_IF_MSG_DEL_BEACON 12
  28. #define HOST_IF_MSG_ADD_STATION 13
  29. #define HOST_IF_MSG_DEL_STATION 14
  30. #define HOST_IF_MSG_EDIT_STATION 15
  31. #define HOST_IF_MSG_SCAN_TIMER_FIRED 16
  32. #define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
  33. #define HOST_IF_MSG_POWER_MGMT 18
  34. #define HOST_IF_MSG_GET_INACTIVETIME 19
  35. #define HOST_IF_MSG_REMAIN_ON_CHAN 20
  36. #define HOST_IF_MSG_REGISTER_FRAME 21
  37. #define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
  38. #define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
  39. #define HOST_IF_MSG_GET_MAC_ADDRESS 26
  40. #define HOST_IF_MSG_SET_OPERATION_MODE 27
  41. #define HOST_IF_MSG_SET_IPADDRESS 28
  42. #define HOST_IF_MSG_GET_IPADDRESS 29
  43. #define HOST_IF_MSG_GET_STATISTICS 31
  44. #define HOST_IF_MSG_SET_MULTICAST_FILTER 32
  45. #define HOST_IF_MSG_DEL_BA_SESSION 34
  46. #define HOST_IF_MSG_DEL_ALL_STA 36
  47. #define HOST_IF_MSG_SET_TX_POWER 38
  48. #define HOST_IF_MSG_GET_TX_POWER 39
  49. #define HOST_IF_MSG_EXIT 100
  50. #define HOST_IF_SCAN_TIMEOUT 4000
  51. #define HOST_IF_CONNECT_TIMEOUT 9500
  52. #define BA_SESSION_DEFAULT_BUFFER_SIZE 16
  53. #define BA_SESSION_DEFAULT_TIMEOUT 1000
  54. #define BLOCK_ACK_REQ_SIZE 0x14
  55. #define FALSE_FRMWR_CHANNEL 100
  56. #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
  57. #define DEFAULT_LINK_SPEED 72
  58. struct host_if_wpa_attr {
  59. u8 *key;
  60. const u8 *mac_addr;
  61. u8 *seq;
  62. u8 seq_len;
  63. u8 index;
  64. u8 key_len;
  65. u8 mode;
  66. };
  67. struct host_if_wep_attr {
  68. u8 *key;
  69. u8 key_len;
  70. u8 index;
  71. u8 mode;
  72. enum AUTHTYPE auth_type;
  73. };
  74. union host_if_key_attr {
  75. struct host_if_wep_attr wep;
  76. struct host_if_wpa_attr wpa;
  77. struct host_if_pmkid_attr pmkid;
  78. };
  79. struct key_attr {
  80. enum KEY_TYPE type;
  81. u8 action;
  82. union host_if_key_attr attr;
  83. };
  84. struct scan_attr {
  85. u8 src;
  86. u8 type;
  87. u8 *ch_freq_list;
  88. u8 ch_list_len;
  89. u8 *ies;
  90. size_t ies_len;
  91. wilc_scan_result result;
  92. void *arg;
  93. struct hidden_network hidden_network;
  94. };
  95. struct connect_attr {
  96. u8 *bssid;
  97. u8 *ssid;
  98. size_t ssid_len;
  99. u8 *ies;
  100. size_t ies_len;
  101. u8 security;
  102. wilc_connect_result result;
  103. void *arg;
  104. enum AUTHTYPE auth_type;
  105. u8 ch;
  106. void *params;
  107. };
  108. struct rcvd_async_info {
  109. u8 *buffer;
  110. u32 len;
  111. };
  112. struct channel_attr {
  113. u8 set_ch;
  114. };
  115. struct beacon_attr {
  116. u32 interval;
  117. u32 dtim_period;
  118. u32 head_len;
  119. u8 *head;
  120. u32 tail_len;
  121. u8 *tail;
  122. };
  123. struct set_multicast {
  124. bool enabled;
  125. u32 cnt;
  126. };
  127. struct del_all_sta {
  128. u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
  129. u8 assoc_sta;
  130. };
  131. struct del_sta {
  132. u8 mac_addr[ETH_ALEN];
  133. };
  134. struct power_mgmt_param {
  135. bool enabled;
  136. u32 timeout;
  137. };
  138. struct set_ip_addr {
  139. u8 *ip_addr;
  140. u8 idx;
  141. };
  142. struct sta_inactive_t {
  143. u8 mac[6];
  144. };
  145. struct tx_power {
  146. u8 tx_pwr;
  147. };
  148. union message_body {
  149. struct scan_attr scan_info;
  150. struct connect_attr con_info;
  151. struct rcvd_net_info net_info;
  152. struct rcvd_async_info async_info;
  153. struct key_attr key_info;
  154. struct cfg_param_attr cfg_info;
  155. struct channel_attr channel_info;
  156. struct beacon_attr beacon_info;
  157. struct add_sta_param add_sta_info;
  158. struct del_sta del_sta_info;
  159. struct add_sta_param edit_sta_info;
  160. struct power_mgmt_param pwr_mgmt_info;
  161. struct sta_inactive_t mac_info;
  162. struct set_ip_addr ip_info;
  163. struct drv_handler drv;
  164. struct set_multicast multicast_info;
  165. struct op_mode mode;
  166. struct get_mac_addr get_mac_info;
  167. struct ba_session_info session_info;
  168. struct remain_ch remain_on_ch;
  169. struct reg_frame reg_frame;
  170. char *data;
  171. struct del_all_sta del_all_sta_info;
  172. struct tx_power tx_power;
  173. };
  174. struct host_if_msg {
  175. u16 id;
  176. union message_body body;
  177. struct wilc_vif *vif;
  178. struct work_struct work;
  179. };
  180. struct join_bss_param {
  181. BSSTYPE_T bss_type;
  182. u8 dtim_period;
  183. u16 beacon_period;
  184. u16 cap_info;
  185. u8 bssid[6];
  186. char ssid[MAX_SSID_LEN];
  187. u8 ssid_len;
  188. u8 supp_rates[MAX_RATES_SUPPORTED + 1];
  189. u8 ht_capable;
  190. u8 wmm_cap;
  191. u8 uapsd_cap;
  192. bool rsn_found;
  193. u8 rsn_grp_policy;
  194. u8 mode_802_11i;
  195. u8 rsn_pcip_policy[3];
  196. u8 rsn_auth_policy[3];
  197. u8 rsn_cap[2];
  198. u32 tsf;
  199. u8 noa_enabled;
  200. u8 opp_enabled;
  201. u8 ct_window;
  202. u8 cnt;
  203. u8 idx;
  204. u8 duration[4];
  205. u8 interval[4];
  206. u8 start_time[4];
  207. };
  208. static struct host_if_drv *terminated_handle;
  209. bool wilc_optaining_ip;
  210. static u8 P2P_LISTEN_STATE;
  211. static struct workqueue_struct *hif_workqueue;
  212. static struct completion hif_thread_comp;
  213. static struct completion hif_driver_comp;
  214. static struct completion hif_wait_response;
  215. static struct mutex hif_deinit_lock;
  216. static struct timer_list periodic_rssi;
  217. u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
  218. static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
  219. static bool scan_while_connected;
  220. static s8 rssi;
  221. static u8 set_ip[2][4];
  222. static u8 get_ip[2][4];
  223. static u32 inactive_time;
  224. static u8 del_beacon;
  225. static u32 clients_count;
  226. static u8 *join_req;
  227. static u8 *info_element;
  228. static u8 mode_11i;
  229. static u8 auth_type;
  230. static u32 join_req_size;
  231. static u32 info_element_size;
  232. static struct wilc_vif *join_req_vif;
  233. #define REAL_JOIN_REQ 0
  234. #define FLUSHED_JOIN_REQ 1
  235. #define FLUSHED_BYTE_POS 79
  236. static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
  237. static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
  238. static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
  239. static void host_if_work(struct work_struct *work);
  240. /*!
  241. * @author syounan
  242. * @date 1 Sep 2010
  243. * @note copied from FLO glue implementatuion
  244. * @version 1.0
  245. */
  246. static int wilc_enqueue_cmd(struct host_if_msg *msg)
  247. {
  248. struct host_if_msg *new_msg;
  249. new_msg = kmemdup(msg, sizeof(*new_msg), GFP_ATOMIC);
  250. if (!new_msg)
  251. return -ENOMEM;
  252. INIT_WORK(&new_msg->work, host_if_work);
  253. queue_work(hif_workqueue, &new_msg->work);
  254. return 0;
  255. }
  256. /* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
  257. * special purpose in wilc device, so we add 1 to the index to starts from 1.
  258. * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
  259. */
  260. int wilc_get_vif_idx(struct wilc_vif *vif)
  261. {
  262. return vif->idx + 1;
  263. }
  264. /* We need to minus 1 from idx which is from wilc device to get real index
  265. * of wilc->vif[], because we add 1 when pass to wilc device in the function
  266. * wilc_get_vif_idx.
  267. * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
  268. */
  269. static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
  270. {
  271. int index = idx - 1;
  272. if (index < 0 || index >= NUM_CONCURRENT_IFC)
  273. return NULL;
  274. return wilc->vif[index];
  275. }
  276. static void handle_set_channel(struct wilc_vif *vif,
  277. struct channel_attr *hif_set_ch)
  278. {
  279. int ret = 0;
  280. struct wid wid;
  281. wid.id = (u16)WID_CURRENT_CHANNEL;
  282. wid.type = WID_CHAR;
  283. wid.val = (char *)&hif_set_ch->set_ch;
  284. wid.size = sizeof(char);
  285. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  286. wilc_get_vif_idx(vif));
  287. if (ret)
  288. netdev_err(vif->ndev, "Failed to set channel\n");
  289. }
  290. static void handle_set_wfi_drv_handler(struct wilc_vif *vif,
  291. struct drv_handler *hif_drv_handler)
  292. {
  293. int ret = 0;
  294. struct wid wid;
  295. wid.id = (u16)WID_SET_DRV_HANDLER;
  296. wid.type = WID_STR;
  297. wid.val = (s8 *)hif_drv_handler;
  298. wid.size = sizeof(*hif_drv_handler);
  299. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  300. hif_drv_handler->handler);
  301. if (!hif_drv_handler->handler)
  302. complete(&hif_driver_comp);
  303. if (ret)
  304. netdev_err(vif->ndev, "Failed to set driver handler\n");
  305. }
  306. static void handle_set_operation_mode(struct wilc_vif *vif,
  307. struct op_mode *hif_op_mode)
  308. {
  309. int ret = 0;
  310. struct wid wid;
  311. wid.id = (u16)WID_SET_OPERATION_MODE;
  312. wid.type = WID_INT;
  313. wid.val = (s8 *)&hif_op_mode->mode;
  314. wid.size = sizeof(u32);
  315. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  316. wilc_get_vif_idx(vif));
  317. if ((hif_op_mode->mode) == IDLE_MODE)
  318. complete(&hif_driver_comp);
  319. if (ret)
  320. netdev_err(vif->ndev, "Failed to set driver handler\n");
  321. }
  322. static void handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
  323. {
  324. int ret = 0;
  325. struct wid wid;
  326. char firmware_ip_addr[4] = {0};
  327. if (ip_addr[0] < 192)
  328. ip_addr[0] = 0;
  329. memcpy(set_ip[idx], ip_addr, IP_ALEN);
  330. wid.id = (u16)WID_IP_ADDRESS;
  331. wid.type = WID_STR;
  332. wid.val = (u8 *)ip_addr;
  333. wid.size = IP_ALEN;
  334. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  335. wilc_get_vif_idx(vif));
  336. host_int_get_ipaddress(vif, firmware_ip_addr, idx);
  337. if (ret)
  338. netdev_err(vif->ndev, "Failed to set IP address\n");
  339. }
  340. static void handle_get_ip_address(struct wilc_vif *vif, u8 idx)
  341. {
  342. int ret = 0;
  343. struct wid wid;
  344. wid.id = (u16)WID_IP_ADDRESS;
  345. wid.type = WID_STR;
  346. wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
  347. wid.size = IP_ALEN;
  348. ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  349. wilc_get_vif_idx(vif));
  350. memcpy(get_ip[idx], wid.val, IP_ALEN);
  351. kfree(wid.val);
  352. if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
  353. wilc_setup_ipaddress(vif, set_ip[idx], idx);
  354. if (ret)
  355. netdev_err(vif->ndev, "Failed to get IP address\n");
  356. }
  357. static void handle_get_mac_address(struct wilc_vif *vif,
  358. struct get_mac_addr *get_mac_addr)
  359. {
  360. int ret = 0;
  361. struct wid wid;
  362. wid.id = (u16)WID_MAC_ADDR;
  363. wid.type = WID_STR;
  364. wid.val = get_mac_addr->mac_addr;
  365. wid.size = ETH_ALEN;
  366. ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  367. wilc_get_vif_idx(vif));
  368. if (ret)
  369. netdev_err(vif->ndev, "Failed to get mac address\n");
  370. complete(&hif_wait_response);
  371. }
  372. static void handle_cfg_param(struct wilc_vif *vif,
  373. struct cfg_param_attr *cfg_param_attr)
  374. {
  375. int ret = 0;
  376. struct wid wid_list[32];
  377. struct host_if_drv *hif_drv = vif->hif_drv;
  378. int i = 0;
  379. mutex_lock(&hif_drv->cfg_values_lock);
  380. if (cfg_param_attr->flag & BSS_TYPE) {
  381. u8 bss_type = cfg_param_attr->bss_type;
  382. if (bss_type < 6) {
  383. wid_list[i].id = WID_BSS_TYPE;
  384. wid_list[i].val = (s8 *)&bss_type;
  385. wid_list[i].type = WID_CHAR;
  386. wid_list[i].size = sizeof(char);
  387. hif_drv->cfg_values.bss_type = bss_type;
  388. } else {
  389. netdev_err(vif->ndev, "check value 6 over\n");
  390. goto unlock;
  391. }
  392. i++;
  393. }
  394. if (cfg_param_attr->flag & AUTH_TYPE) {
  395. if (cfg_param_attr->auth_type == 1 ||
  396. cfg_param_attr->auth_type == 2 ||
  397. cfg_param_attr->auth_type == 5) {
  398. wid_list[i].id = WID_AUTH_TYPE;
  399. wid_list[i].val = (s8 *)&cfg_param_attr->auth_type;
  400. wid_list[i].type = WID_CHAR;
  401. wid_list[i].size = sizeof(char);
  402. hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->auth_type;
  403. } else {
  404. netdev_err(vif->ndev, "Impossible value\n");
  405. goto unlock;
  406. }
  407. i++;
  408. }
  409. if (cfg_param_attr->flag & AUTHEN_TIMEOUT) {
  410. if (cfg_param_attr->auth_timeout > 0 &&
  411. cfg_param_attr->auth_timeout < 65536) {
  412. wid_list[i].id = WID_AUTH_TIMEOUT;
  413. wid_list[i].val = (s8 *)&cfg_param_attr->auth_timeout;
  414. wid_list[i].type = WID_SHORT;
  415. wid_list[i].size = sizeof(u16);
  416. hif_drv->cfg_values.auth_timeout = cfg_param_attr->auth_timeout;
  417. } else {
  418. netdev_err(vif->ndev, "Range(1 ~ 65535) over\n");
  419. goto unlock;
  420. }
  421. i++;
  422. }
  423. if (cfg_param_attr->flag & POWER_MANAGEMENT) {
  424. if (cfg_param_attr->power_mgmt_mode < 5) {
  425. wid_list[i].id = WID_POWER_MANAGEMENT;
  426. wid_list[i].val = (s8 *)&cfg_param_attr->power_mgmt_mode;
  427. wid_list[i].type = WID_CHAR;
  428. wid_list[i].size = sizeof(char);
  429. hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->power_mgmt_mode;
  430. } else {
  431. netdev_err(vif->ndev, "Invalid power mode\n");
  432. goto unlock;
  433. }
  434. i++;
  435. }
  436. if (cfg_param_attr->flag & RETRY_SHORT) {
  437. if (cfg_param_attr->short_retry_limit > 0 &&
  438. cfg_param_attr->short_retry_limit < 256) {
  439. wid_list[i].id = WID_SHORT_RETRY_LIMIT;
  440. wid_list[i].val = (s8 *)&cfg_param_attr->short_retry_limit;
  441. wid_list[i].type = WID_SHORT;
  442. wid_list[i].size = sizeof(u16);
  443. hif_drv->cfg_values.short_retry_limit = cfg_param_attr->short_retry_limit;
  444. } else {
  445. netdev_err(vif->ndev, "Range(1~256) over\n");
  446. goto unlock;
  447. }
  448. i++;
  449. }
  450. if (cfg_param_attr->flag & RETRY_LONG) {
  451. if (cfg_param_attr->long_retry_limit > 0 &&
  452. cfg_param_attr->long_retry_limit < 256) {
  453. wid_list[i].id = WID_LONG_RETRY_LIMIT;
  454. wid_list[i].val = (s8 *)&cfg_param_attr->long_retry_limit;
  455. wid_list[i].type = WID_SHORT;
  456. wid_list[i].size = sizeof(u16);
  457. hif_drv->cfg_values.long_retry_limit = cfg_param_attr->long_retry_limit;
  458. } else {
  459. netdev_err(vif->ndev, "Range(1~256) over\n");
  460. goto unlock;
  461. }
  462. i++;
  463. }
  464. if (cfg_param_attr->flag & FRAG_THRESHOLD) {
  465. if (cfg_param_attr->frag_threshold > 255 &&
  466. cfg_param_attr->frag_threshold < 7937) {
  467. wid_list[i].id = WID_FRAG_THRESHOLD;
  468. wid_list[i].val = (s8 *)&cfg_param_attr->frag_threshold;
  469. wid_list[i].type = WID_SHORT;
  470. wid_list[i].size = sizeof(u16);
  471. hif_drv->cfg_values.frag_threshold = cfg_param_attr->frag_threshold;
  472. } else {
  473. netdev_err(vif->ndev, "Threshold Range fail\n");
  474. goto unlock;
  475. }
  476. i++;
  477. }
  478. if (cfg_param_attr->flag & RTS_THRESHOLD) {
  479. if (cfg_param_attr->rts_threshold > 255 &&
  480. cfg_param_attr->rts_threshold < 65536) {
  481. wid_list[i].id = WID_RTS_THRESHOLD;
  482. wid_list[i].val = (s8 *)&cfg_param_attr->rts_threshold;
  483. wid_list[i].type = WID_SHORT;
  484. wid_list[i].size = sizeof(u16);
  485. hif_drv->cfg_values.rts_threshold = cfg_param_attr->rts_threshold;
  486. } else {
  487. netdev_err(vif->ndev, "Threshold Range fail\n");
  488. goto unlock;
  489. }
  490. i++;
  491. }
  492. if (cfg_param_attr->flag & PREAMBLE) {
  493. if (cfg_param_attr->preamble_type < 3) {
  494. wid_list[i].id = WID_PREAMBLE;
  495. wid_list[i].val = (s8 *)&cfg_param_attr->preamble_type;
  496. wid_list[i].type = WID_CHAR;
  497. wid_list[i].size = sizeof(char);
  498. hif_drv->cfg_values.preamble_type = cfg_param_attr->preamble_type;
  499. } else {
  500. netdev_err(vif->ndev, "Preamle Range(0~2) over\n");
  501. goto unlock;
  502. }
  503. i++;
  504. }
  505. if (cfg_param_attr->flag & SHORT_SLOT_ALLOWED) {
  506. if (cfg_param_attr->short_slot_allowed < 2) {
  507. wid_list[i].id = WID_SHORT_SLOT_ALLOWED;
  508. wid_list[i].val = (s8 *)&cfg_param_attr->short_slot_allowed;
  509. wid_list[i].type = WID_CHAR;
  510. wid_list[i].size = sizeof(char);
  511. hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->short_slot_allowed;
  512. } else {
  513. netdev_err(vif->ndev, "Short slot(2) over\n");
  514. goto unlock;
  515. }
  516. i++;
  517. }
  518. if (cfg_param_attr->flag & TXOP_PROT_DISABLE) {
  519. if (cfg_param_attr->txop_prot_disabled < 2) {
  520. wid_list[i].id = WID_11N_TXOP_PROT_DISABLE;
  521. wid_list[i].val = (s8 *)&cfg_param_attr->txop_prot_disabled;
  522. wid_list[i].type = WID_CHAR;
  523. wid_list[i].size = sizeof(char);
  524. hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->txop_prot_disabled;
  525. } else {
  526. netdev_err(vif->ndev, "TXOP prot disable\n");
  527. goto unlock;
  528. }
  529. i++;
  530. }
  531. if (cfg_param_attr->flag & BEACON_INTERVAL) {
  532. if (cfg_param_attr->beacon_interval > 0 &&
  533. cfg_param_attr->beacon_interval < 65536) {
  534. wid_list[i].id = WID_BEACON_INTERVAL;
  535. wid_list[i].val = (s8 *)&cfg_param_attr->beacon_interval;
  536. wid_list[i].type = WID_SHORT;
  537. wid_list[i].size = sizeof(u16);
  538. hif_drv->cfg_values.beacon_interval = cfg_param_attr->beacon_interval;
  539. } else {
  540. netdev_err(vif->ndev, "Beacon interval(1~65535)fail\n");
  541. goto unlock;
  542. }
  543. i++;
  544. }
  545. if (cfg_param_attr->flag & DTIM_PERIOD) {
  546. if (cfg_param_attr->dtim_period > 0 &&
  547. cfg_param_attr->dtim_period < 256) {
  548. wid_list[i].id = WID_DTIM_PERIOD;
  549. wid_list[i].val = (s8 *)&cfg_param_attr->dtim_period;
  550. wid_list[i].type = WID_CHAR;
  551. wid_list[i].size = sizeof(char);
  552. hif_drv->cfg_values.dtim_period = cfg_param_attr->dtim_period;
  553. } else {
  554. netdev_err(vif->ndev, "DTIM range(1~255) fail\n");
  555. goto unlock;
  556. }
  557. i++;
  558. }
  559. if (cfg_param_attr->flag & SITE_SURVEY) {
  560. if (cfg_param_attr->site_survey_enabled < 3) {
  561. wid_list[i].id = WID_SITE_SURVEY;
  562. wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_enabled;
  563. wid_list[i].type = WID_CHAR;
  564. wid_list[i].size = sizeof(char);
  565. hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->site_survey_enabled;
  566. } else {
  567. netdev_err(vif->ndev, "Site survey disable\n");
  568. goto unlock;
  569. }
  570. i++;
  571. }
  572. if (cfg_param_attr->flag & SITE_SURVEY_SCAN_TIME) {
  573. if (cfg_param_attr->site_survey_scan_time > 0 &&
  574. cfg_param_attr->site_survey_scan_time < 65536) {
  575. wid_list[i].id = WID_SITE_SURVEY_SCAN_TIME;
  576. wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_scan_time;
  577. wid_list[i].type = WID_SHORT;
  578. wid_list[i].size = sizeof(u16);
  579. hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->site_survey_scan_time;
  580. } else {
  581. netdev_err(vif->ndev, "Site scan time(1~65535) over\n");
  582. goto unlock;
  583. }
  584. i++;
  585. }
  586. if (cfg_param_attr->flag & ACTIVE_SCANTIME) {
  587. if (cfg_param_attr->active_scan_time > 0 &&
  588. cfg_param_attr->active_scan_time < 65536) {
  589. wid_list[i].id = WID_ACTIVE_SCAN_TIME;
  590. wid_list[i].val = (s8 *)&cfg_param_attr->active_scan_time;
  591. wid_list[i].type = WID_SHORT;
  592. wid_list[i].size = sizeof(u16);
  593. hif_drv->cfg_values.active_scan_time = cfg_param_attr->active_scan_time;
  594. } else {
  595. netdev_err(vif->ndev, "Active time(1~65535) over\n");
  596. goto unlock;
  597. }
  598. i++;
  599. }
  600. if (cfg_param_attr->flag & PASSIVE_SCANTIME) {
  601. if (cfg_param_attr->passive_scan_time > 0 &&
  602. cfg_param_attr->passive_scan_time < 65536) {
  603. wid_list[i].id = WID_PASSIVE_SCAN_TIME;
  604. wid_list[i].val = (s8 *)&cfg_param_attr->passive_scan_time;
  605. wid_list[i].type = WID_SHORT;
  606. wid_list[i].size = sizeof(u16);
  607. hif_drv->cfg_values.passive_scan_time = cfg_param_attr->passive_scan_time;
  608. } else {
  609. netdev_err(vif->ndev, "Passive time(1~65535) over\n");
  610. goto unlock;
  611. }
  612. i++;
  613. }
  614. if (cfg_param_attr->flag & CURRENT_TX_RATE) {
  615. enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->curr_tx_rate;
  616. if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 ||
  617. curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 ||
  618. curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 ||
  619. curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 ||
  620. curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 ||
  621. curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 ||
  622. curr_tx_rate == MBPS_54) {
  623. wid_list[i].id = WID_CURRENT_TX_RATE;
  624. wid_list[i].val = (s8 *)&curr_tx_rate;
  625. wid_list[i].type = WID_SHORT;
  626. wid_list[i].size = sizeof(u16);
  627. hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate;
  628. } else {
  629. netdev_err(vif->ndev, "out of TX rate\n");
  630. goto unlock;
  631. }
  632. i++;
  633. }
  634. ret = wilc_send_config_pkt(vif, SET_CFG, wid_list,
  635. i, wilc_get_vif_idx(vif));
  636. if (ret)
  637. netdev_err(vif->ndev, "Error in setting CFG params\n");
  638. unlock:
  639. mutex_unlock(&hif_drv->cfg_values_lock);
  640. }
  641. static s32 handle_scan(struct wilc_vif *vif, struct scan_attr *scan_info)
  642. {
  643. s32 result = 0;
  644. struct wid wid_list[5];
  645. u32 index = 0;
  646. u32 i;
  647. u8 *buffer;
  648. u8 valuesize = 0;
  649. u8 *pu8HdnNtwrksWidVal = NULL;
  650. struct host_if_drv *hif_drv = vif->hif_drv;
  651. hif_drv->usr_scan_req.scan_result = scan_info->result;
  652. hif_drv->usr_scan_req.arg = scan_info->arg;
  653. if ((hif_drv->hif_state >= HOST_IF_SCANNING) &&
  654. (hif_drv->hif_state < HOST_IF_CONNECTED)) {
  655. netdev_err(vif->ndev, "Already scan\n");
  656. result = -EBUSY;
  657. goto ERRORHANDLER;
  658. }
  659. if (wilc_optaining_ip || wilc_connecting) {
  660. netdev_err(vif->ndev, "Don't do obss scan\n");
  661. result = -EBUSY;
  662. goto ERRORHANDLER;
  663. }
  664. hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
  665. wid_list[index].id = (u16)WID_SSID_PROBE_REQ;
  666. wid_list[index].type = WID_STR;
  667. for (i = 0; i < scan_info->hidden_network.n_ssids; i++)
  668. valuesize += ((scan_info->hidden_network.net_info[i].ssid_len) + 1);
  669. pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
  670. wid_list[index].val = pu8HdnNtwrksWidVal;
  671. if (wid_list[index].val) {
  672. buffer = wid_list[index].val;
  673. *buffer++ = scan_info->hidden_network.n_ssids;
  674. for (i = 0; i < scan_info->hidden_network.n_ssids; i++) {
  675. *buffer++ = scan_info->hidden_network.net_info[i].ssid_len;
  676. memcpy(buffer, scan_info->hidden_network.net_info[i].ssid, scan_info->hidden_network.net_info[i].ssid_len);
  677. buffer += scan_info->hidden_network.net_info[i].ssid_len;
  678. }
  679. wid_list[index].size = (s32)(valuesize + 1);
  680. index++;
  681. }
  682. wid_list[index].id = WID_INFO_ELEMENT_PROBE;
  683. wid_list[index].type = WID_BIN_DATA;
  684. wid_list[index].val = scan_info->ies;
  685. wid_list[index].size = scan_info->ies_len;
  686. index++;
  687. wid_list[index].id = WID_SCAN_TYPE;
  688. wid_list[index].type = WID_CHAR;
  689. wid_list[index].size = sizeof(char);
  690. wid_list[index].val = (s8 *)&scan_info->type;
  691. index++;
  692. wid_list[index].id = WID_SCAN_CHANNEL_LIST;
  693. wid_list[index].type = WID_BIN_DATA;
  694. if (scan_info->ch_freq_list &&
  695. scan_info->ch_list_len > 0) {
  696. int i;
  697. for (i = 0; i < scan_info->ch_list_len; i++) {
  698. if (scan_info->ch_freq_list[i] > 0)
  699. scan_info->ch_freq_list[i] = scan_info->ch_freq_list[i] - 1;
  700. }
  701. }
  702. wid_list[index].val = scan_info->ch_freq_list;
  703. wid_list[index].size = scan_info->ch_list_len;
  704. index++;
  705. wid_list[index].id = WID_START_SCAN_REQ;
  706. wid_list[index].type = WID_CHAR;
  707. wid_list[index].size = sizeof(char);
  708. wid_list[index].val = (s8 *)&scan_info->src;
  709. index++;
  710. if (hif_drv->hif_state == HOST_IF_CONNECTED)
  711. scan_while_connected = true;
  712. else if (hif_drv->hif_state == HOST_IF_IDLE)
  713. scan_while_connected = false;
  714. result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
  715. index,
  716. wilc_get_vif_idx(vif));
  717. if (result)
  718. netdev_err(vif->ndev, "Failed to send scan parameters\n");
  719. ERRORHANDLER:
  720. if (result) {
  721. del_timer(&hif_drv->scan_timer);
  722. Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
  723. }
  724. kfree(scan_info->ch_freq_list);
  725. scan_info->ch_freq_list = NULL;
  726. kfree(scan_info->ies);
  727. scan_info->ies = NULL;
  728. kfree(scan_info->hidden_network.net_info);
  729. scan_info->hidden_network.net_info = NULL;
  730. kfree(pu8HdnNtwrksWidVal);
  731. return result;
  732. }
  733. static s32 Handle_ScanDone(struct wilc_vif *vif,
  734. enum scan_event enuEvent)
  735. {
  736. s32 result = 0;
  737. u8 u8abort_running_scan;
  738. struct wid wid;
  739. struct host_if_drv *hif_drv = vif->hif_drv;
  740. if (enuEvent == SCAN_EVENT_ABORTED) {
  741. u8abort_running_scan = 1;
  742. wid.id = (u16)WID_ABORT_RUNNING_SCAN;
  743. wid.type = WID_CHAR;
  744. wid.val = (s8 *)&u8abort_running_scan;
  745. wid.size = sizeof(char);
  746. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  747. wilc_get_vif_idx(vif));
  748. if (result) {
  749. netdev_err(vif->ndev, "Failed to set abort running\n");
  750. result = -EFAULT;
  751. }
  752. }
  753. if (!hif_drv) {
  754. netdev_err(vif->ndev, "Driver handler is NULL\n");
  755. return result;
  756. }
  757. if (hif_drv->usr_scan_req.scan_result) {
  758. hif_drv->usr_scan_req.scan_result(enuEvent, NULL,
  759. hif_drv->usr_scan_req.arg, NULL);
  760. hif_drv->usr_scan_req.scan_result = NULL;
  761. }
  762. return result;
  763. }
  764. u8 wilc_connected_ssid[6] = {0};
  765. static s32 Handle_Connect(struct wilc_vif *vif,
  766. struct connect_attr *pstrHostIFconnectAttr)
  767. {
  768. s32 result = 0;
  769. struct wid strWIDList[8];
  770. u32 u32WidsCount = 0, dummyval = 0;
  771. u8 *pu8CurrByte = NULL;
  772. struct join_bss_param *ptstrJoinBssParam;
  773. struct host_if_drv *hif_drv = vif->hif_drv;
  774. if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
  775. result = 0;
  776. netdev_err(vif->ndev, "Discard connect request\n");
  777. return result;
  778. }
  779. ptstrJoinBssParam = pstrHostIFconnectAttr->params;
  780. if (!ptstrJoinBssParam) {
  781. netdev_err(vif->ndev, "Required BSSID not found\n");
  782. result = -ENOENT;
  783. goto ERRORHANDLER;
  784. }
  785. if (pstrHostIFconnectAttr->bssid) {
  786. hif_drv->usr_conn_req.bssid = kmalloc(6, GFP_KERNEL);
  787. memcpy(hif_drv->usr_conn_req.bssid, pstrHostIFconnectAttr->bssid, 6);
  788. }
  789. hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len;
  790. if (pstrHostIFconnectAttr->ssid) {
  791. hif_drv->usr_conn_req.ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
  792. memcpy(hif_drv->usr_conn_req.ssid,
  793. pstrHostIFconnectAttr->ssid,
  794. pstrHostIFconnectAttr->ssid_len);
  795. hif_drv->usr_conn_req.ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
  796. }
  797. hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len;
  798. if (pstrHostIFconnectAttr->ies) {
  799. hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
  800. memcpy(hif_drv->usr_conn_req.ies,
  801. pstrHostIFconnectAttr->ies,
  802. pstrHostIFconnectAttr->ies_len);
  803. }
  804. hif_drv->usr_conn_req.security = pstrHostIFconnectAttr->security;
  805. hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type;
  806. hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result;
  807. hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg;
  808. strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
  809. strWIDList[u32WidsCount].type = WID_INT;
  810. strWIDList[u32WidsCount].size = sizeof(u32);
  811. strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
  812. u32WidsCount++;
  813. strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
  814. strWIDList[u32WidsCount].type = WID_INT;
  815. strWIDList[u32WidsCount].size = sizeof(u32);
  816. strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
  817. u32WidsCount++;
  818. strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
  819. strWIDList[u32WidsCount].type = WID_INT;
  820. strWIDList[u32WidsCount].size = sizeof(u32);
  821. strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
  822. u32WidsCount++;
  823. {
  824. strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
  825. strWIDList[u32WidsCount].type = WID_BIN_DATA;
  826. strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies;
  827. strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len;
  828. u32WidsCount++;
  829. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
  830. info_element_size = hif_drv->usr_conn_req.ies_len;
  831. info_element = kmalloc(info_element_size, GFP_KERNEL);
  832. memcpy(info_element, hif_drv->usr_conn_req.ies,
  833. info_element_size);
  834. }
  835. }
  836. strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
  837. strWIDList[u32WidsCount].type = WID_CHAR;
  838. strWIDList[u32WidsCount].size = sizeof(char);
  839. strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.security;
  840. u32WidsCount++;
  841. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
  842. mode_11i = hif_drv->usr_conn_req.security;
  843. strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
  844. strWIDList[u32WidsCount].type = WID_CHAR;
  845. strWIDList[u32WidsCount].size = sizeof(char);
  846. strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
  847. u32WidsCount++;
  848. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
  849. auth_type = (u8)hif_drv->usr_conn_req.auth_type;
  850. strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
  851. strWIDList[u32WidsCount].type = WID_STR;
  852. strWIDList[u32WidsCount].size = 112;
  853. strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
  854. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
  855. join_req_size = strWIDList[u32WidsCount].size;
  856. join_req = kmalloc(join_req_size, GFP_KERNEL);
  857. }
  858. if (!strWIDList[u32WidsCount].val) {
  859. result = -EFAULT;
  860. goto ERRORHANDLER;
  861. }
  862. pu8CurrByte = strWIDList[u32WidsCount].val;
  863. if (pstrHostIFconnectAttr->ssid) {
  864. memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
  865. pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
  866. }
  867. pu8CurrByte += MAX_SSID_LEN;
  868. *(pu8CurrByte++) = INFRASTRUCTURE;
  869. if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
  870. *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
  871. } else {
  872. netdev_err(vif->ndev, "Channel out of range\n");
  873. *(pu8CurrByte++) = 0xFF;
  874. }
  875. *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF;
  876. *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
  877. if (pstrHostIFconnectAttr->bssid)
  878. memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
  879. pu8CurrByte += 6;
  880. if (pstrHostIFconnectAttr->bssid)
  881. memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
  882. pu8CurrByte += 6;
  883. *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF;
  884. *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
  885. *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period;
  886. memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
  887. pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
  888. *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap;
  889. *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap;
  890. *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable;
  891. hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable;
  892. *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found;
  893. *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy;
  894. *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i;
  895. memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
  896. pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
  897. memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
  898. pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
  899. memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
  900. pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
  901. *(pu8CurrByte++) = REAL_JOIN_REQ;
  902. *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
  903. if (ptstrJoinBssParam->noa_enabled) {
  904. *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
  905. *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
  906. *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
  907. *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
  908. *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
  909. *(pu8CurrByte++) = ptstrJoinBssParam->idx;
  910. if (ptstrJoinBssParam->opp_enabled)
  911. *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
  912. *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
  913. memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
  914. pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
  915. memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
  916. pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
  917. memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
  918. pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
  919. }
  920. pu8CurrByte = strWIDList[u32WidsCount].val;
  921. u32WidsCount++;
  922. if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
  923. memcpy(join_req, pu8CurrByte, join_req_size);
  924. join_req_vif = vif;
  925. }
  926. if (pstrHostIFconnectAttr->bssid)
  927. memcpy(wilc_connected_ssid,
  928. pstrHostIFconnectAttr->bssid, ETH_ALEN);
  929. result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
  930. u32WidsCount,
  931. wilc_get_vif_idx(vif));
  932. if (result) {
  933. netdev_err(vif->ndev, "failed to send config packet\n");
  934. result = -EFAULT;
  935. goto ERRORHANDLER;
  936. } else {
  937. hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
  938. }
  939. ERRORHANDLER:
  940. if (result) {
  941. struct connect_info strConnectInfo;
  942. del_timer(&hif_drv->connect_timer);
  943. memset(&strConnectInfo, 0, sizeof(struct connect_info));
  944. if (pstrHostIFconnectAttr->result) {
  945. if (pstrHostIFconnectAttr->bssid)
  946. memcpy(strConnectInfo.bssid, pstrHostIFconnectAttr->bssid, 6);
  947. if (pstrHostIFconnectAttr->ies) {
  948. strConnectInfo.req_ies_len = pstrHostIFconnectAttr->ies_len;
  949. strConnectInfo.req_ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
  950. memcpy(strConnectInfo.req_ies,
  951. pstrHostIFconnectAttr->ies,
  952. pstrHostIFconnectAttr->ies_len);
  953. }
  954. pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
  955. &strConnectInfo,
  956. MAC_DISCONNECTED,
  957. NULL,
  958. pstrHostIFconnectAttr->arg);
  959. hif_drv->hif_state = HOST_IF_IDLE;
  960. kfree(strConnectInfo.req_ies);
  961. strConnectInfo.req_ies = NULL;
  962. } else {
  963. netdev_err(vif->ndev, "Connect callback is NULL\n");
  964. }
  965. }
  966. kfree(pstrHostIFconnectAttr->bssid);
  967. pstrHostIFconnectAttr->bssid = NULL;
  968. kfree(pstrHostIFconnectAttr->ssid);
  969. pstrHostIFconnectAttr->ssid = NULL;
  970. kfree(pstrHostIFconnectAttr->ies);
  971. pstrHostIFconnectAttr->ies = NULL;
  972. kfree(pu8CurrByte);
  973. return result;
  974. }
  975. static s32 Handle_ConnectTimeout(struct wilc_vif *vif)
  976. {
  977. s32 result = 0;
  978. struct connect_info strConnectInfo;
  979. struct wid wid;
  980. u16 u16DummyReasonCode = 0;
  981. struct host_if_drv *hif_drv = vif->hif_drv;
  982. if (!hif_drv) {
  983. netdev_err(vif->ndev, "Driver handler is NULL\n");
  984. return result;
  985. }
  986. hif_drv->hif_state = HOST_IF_IDLE;
  987. scan_while_connected = false;
  988. memset(&strConnectInfo, 0, sizeof(struct connect_info));
  989. if (hif_drv->usr_conn_req.conn_result) {
  990. if (hif_drv->usr_conn_req.bssid) {
  991. memcpy(strConnectInfo.bssid,
  992. hif_drv->usr_conn_req.bssid, 6);
  993. }
  994. if (hif_drv->usr_conn_req.ies) {
  995. strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
  996. strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
  997. memcpy(strConnectInfo.req_ies,
  998. hif_drv->usr_conn_req.ies,
  999. hif_drv->usr_conn_req.ies_len);
  1000. }
  1001. hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
  1002. &strConnectInfo,
  1003. MAC_DISCONNECTED,
  1004. NULL,
  1005. hif_drv->usr_conn_req.arg);
  1006. kfree(strConnectInfo.req_ies);
  1007. strConnectInfo.req_ies = NULL;
  1008. } else {
  1009. netdev_err(vif->ndev, "Connect callback is NULL\n");
  1010. }
  1011. wid.id = (u16)WID_DISCONNECT;
  1012. wid.type = WID_CHAR;
  1013. wid.val = (s8 *)&u16DummyReasonCode;
  1014. wid.size = sizeof(char);
  1015. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1016. wilc_get_vif_idx(vif));
  1017. if (result)
  1018. netdev_err(vif->ndev, "Failed to send dissconect\n");
  1019. hif_drv->usr_conn_req.ssid_len = 0;
  1020. kfree(hif_drv->usr_conn_req.ssid);
  1021. hif_drv->usr_conn_req.ssid = NULL;
  1022. kfree(hif_drv->usr_conn_req.bssid);
  1023. hif_drv->usr_conn_req.bssid = NULL;
  1024. hif_drv->usr_conn_req.ies_len = 0;
  1025. kfree(hif_drv->usr_conn_req.ies);
  1026. hif_drv->usr_conn_req.ies = NULL;
  1027. eth_zero_addr(wilc_connected_ssid);
  1028. if (join_req && join_req_vif == vif) {
  1029. kfree(join_req);
  1030. join_req = NULL;
  1031. }
  1032. if (info_element && join_req_vif == vif) {
  1033. kfree(info_element);
  1034. info_element = NULL;
  1035. }
  1036. return result;
  1037. }
  1038. static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif,
  1039. struct rcvd_net_info *pstrRcvdNetworkInfo)
  1040. {
  1041. u32 i;
  1042. bool bNewNtwrkFound;
  1043. s32 result = 0;
  1044. struct network_info *pstrNetworkInfo = NULL;
  1045. void *pJoinParams = NULL;
  1046. struct host_if_drv *hif_drv = vif->hif_drv;
  1047. bNewNtwrkFound = true;
  1048. if (hif_drv->usr_scan_req.scan_result) {
  1049. wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
  1050. if ((!pstrNetworkInfo) ||
  1051. (!hif_drv->usr_scan_req.scan_result)) {
  1052. netdev_err(vif->ndev, "driver is null\n");
  1053. result = -EINVAL;
  1054. goto done;
  1055. }
  1056. for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) {
  1057. if (memcmp(hif_drv->usr_scan_req.net_info[i].bssid,
  1058. pstrNetworkInfo->bssid, 6) == 0) {
  1059. if (pstrNetworkInfo->rssi <= hif_drv->usr_scan_req.net_info[i].rssi) {
  1060. goto done;
  1061. } else {
  1062. hif_drv->usr_scan_req.net_info[i].rssi = pstrNetworkInfo->rssi;
  1063. bNewNtwrkFound = false;
  1064. break;
  1065. }
  1066. }
  1067. }
  1068. if (bNewNtwrkFound) {
  1069. if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
  1070. hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].rssi = pstrNetworkInfo->rssi;
  1071. memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid,
  1072. pstrNetworkInfo->bssid, 6);
  1073. hif_drv->usr_scan_req.rcvd_ch_cnt++;
  1074. pstrNetworkInfo->new_network = true;
  1075. pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
  1076. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
  1077. hif_drv->usr_scan_req.arg,
  1078. pJoinParams);
  1079. }
  1080. } else {
  1081. pstrNetworkInfo->new_network = false;
  1082. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
  1083. hif_drv->usr_scan_req.arg, NULL);
  1084. }
  1085. }
  1086. done:
  1087. kfree(pstrRcvdNetworkInfo->buffer);
  1088. pstrRcvdNetworkInfo->buffer = NULL;
  1089. if (pstrNetworkInfo) {
  1090. kfree(pstrNetworkInfo->ies);
  1091. kfree(pstrNetworkInfo);
  1092. }
  1093. return result;
  1094. }
  1095. static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
  1096. u8 *pu8AssocRespInfo,
  1097. u32 u32MaxAssocRespInfoLen,
  1098. u32 *pu32RcvdAssocRespInfoLen);
  1099. static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif,
  1100. struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
  1101. {
  1102. s32 result = 0;
  1103. u8 u8MsgType = 0;
  1104. u8 u8MsgID = 0;
  1105. u16 u16MsgLen = 0;
  1106. u16 u16WidID = (u16)WID_NIL;
  1107. u8 u8WidLen = 0;
  1108. u8 u8MacStatus;
  1109. u8 u8MacStatusReasonCode;
  1110. u8 u8MacStatusAdditionalInfo;
  1111. struct connect_info strConnectInfo;
  1112. struct disconnect_info strDisconnectNotifInfo;
  1113. s32 s32Err = 0;
  1114. struct host_if_drv *hif_drv = vif->hif_drv;
  1115. if (!hif_drv) {
  1116. netdev_err(vif->ndev, "Driver handler is NULL\n");
  1117. return -ENODEV;
  1118. }
  1119. if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
  1120. (hif_drv->hif_state == HOST_IF_CONNECTED) ||
  1121. hif_drv->usr_scan_req.scan_result) {
  1122. if (!pstrRcvdGnrlAsyncInfo->buffer ||
  1123. !hif_drv->usr_conn_req.conn_result) {
  1124. netdev_err(vif->ndev, "driver is null\n");
  1125. return -EINVAL;
  1126. }
  1127. u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
  1128. if ('I' != u8MsgType) {
  1129. netdev_err(vif->ndev, "Received Message incorrect.\n");
  1130. return -EFAULT;
  1131. }
  1132. u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
  1133. u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
  1134. u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
  1135. u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
  1136. u8MacStatus = pstrRcvdGnrlAsyncInfo->buffer[7];
  1137. u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
  1138. u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
  1139. if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
  1140. u32 u32RcvdAssocRespInfoLen = 0;
  1141. struct connect_resp_info *pstrConnectRespInfo = NULL;
  1142. memset(&strConnectInfo, 0, sizeof(struct connect_info));
  1143. if (u8MacStatus == MAC_CONNECTED) {
  1144. memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
  1145. host_int_get_assoc_res_info(vif,
  1146. rcv_assoc_resp,
  1147. MAX_ASSOC_RESP_FRAME_SIZE,
  1148. &u32RcvdAssocRespInfoLen);
  1149. if (u32RcvdAssocRespInfoLen != 0) {
  1150. s32Err = wilc_parse_assoc_resp_info(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
  1151. &pstrConnectRespInfo);
  1152. if (s32Err) {
  1153. netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", s32Err);
  1154. } else {
  1155. strConnectInfo.status = pstrConnectRespInfo->status;
  1156. if (strConnectInfo.status == SUCCESSFUL_STATUSCODE) {
  1157. if (pstrConnectRespInfo->ies) {
  1158. strConnectInfo.resp_ies_len = pstrConnectRespInfo->ies_len;
  1159. strConnectInfo.resp_ies = kmalloc(pstrConnectRespInfo->ies_len, GFP_KERNEL);
  1160. memcpy(strConnectInfo.resp_ies, pstrConnectRespInfo->ies,
  1161. pstrConnectRespInfo->ies_len);
  1162. }
  1163. }
  1164. if (pstrConnectRespInfo) {
  1165. kfree(pstrConnectRespInfo->ies);
  1166. kfree(pstrConnectRespInfo);
  1167. }
  1168. }
  1169. }
  1170. }
  1171. if ((u8MacStatus == MAC_CONNECTED) &&
  1172. (strConnectInfo.status != SUCCESSFUL_STATUSCODE)) {
  1173. netdev_err(vif->ndev, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
  1174. eth_zero_addr(wilc_connected_ssid);
  1175. } else if (u8MacStatus == MAC_DISCONNECTED) {
  1176. netdev_err(vif->ndev, "Received MAC status is MAC_DISCONNECTED\n");
  1177. eth_zero_addr(wilc_connected_ssid);
  1178. }
  1179. if (hif_drv->usr_conn_req.bssid) {
  1180. memcpy(strConnectInfo.bssid, hif_drv->usr_conn_req.bssid, 6);
  1181. if ((u8MacStatus == MAC_CONNECTED) &&
  1182. (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) {
  1183. memcpy(hif_drv->assoc_bssid,
  1184. hif_drv->usr_conn_req.bssid, ETH_ALEN);
  1185. }
  1186. }
  1187. if (hif_drv->usr_conn_req.ies) {
  1188. strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
  1189. strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
  1190. memcpy(strConnectInfo.req_ies,
  1191. hif_drv->usr_conn_req.ies,
  1192. hif_drv->usr_conn_req.ies_len);
  1193. }
  1194. del_timer(&hif_drv->connect_timer);
  1195. hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
  1196. &strConnectInfo,
  1197. u8MacStatus,
  1198. NULL,
  1199. hif_drv->usr_conn_req.arg);
  1200. if ((u8MacStatus == MAC_CONNECTED) &&
  1201. (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) {
  1202. wilc_set_power_mgmt(vif, 0, 0);
  1203. hif_drv->hif_state = HOST_IF_CONNECTED;
  1204. wilc_optaining_ip = true;
  1205. mod_timer(&wilc_during_ip_timer,
  1206. jiffies + msecs_to_jiffies(10000));
  1207. } else {
  1208. hif_drv->hif_state = HOST_IF_IDLE;
  1209. scan_while_connected = false;
  1210. }
  1211. kfree(strConnectInfo.resp_ies);
  1212. strConnectInfo.resp_ies = NULL;
  1213. kfree(strConnectInfo.req_ies);
  1214. strConnectInfo.req_ies = NULL;
  1215. hif_drv->usr_conn_req.ssid_len = 0;
  1216. kfree(hif_drv->usr_conn_req.ssid);
  1217. hif_drv->usr_conn_req.ssid = NULL;
  1218. kfree(hif_drv->usr_conn_req.bssid);
  1219. hif_drv->usr_conn_req.bssid = NULL;
  1220. hif_drv->usr_conn_req.ies_len = 0;
  1221. kfree(hif_drv->usr_conn_req.ies);
  1222. hif_drv->usr_conn_req.ies = NULL;
  1223. } else if ((u8MacStatus == MAC_DISCONNECTED) &&
  1224. (hif_drv->hif_state == HOST_IF_CONNECTED)) {
  1225. memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
  1226. if (hif_drv->usr_scan_req.scan_result) {
  1227. del_timer(&hif_drv->scan_timer);
  1228. Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
  1229. }
  1230. strDisconnectNotifInfo.reason = 0;
  1231. strDisconnectNotifInfo.ie = NULL;
  1232. strDisconnectNotifInfo.ie_len = 0;
  1233. if (hif_drv->usr_conn_req.conn_result) {
  1234. wilc_optaining_ip = false;
  1235. wilc_set_power_mgmt(vif, 0, 0);
  1236. hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
  1237. NULL,
  1238. 0,
  1239. &strDisconnectNotifInfo,
  1240. hif_drv->usr_conn_req.arg);
  1241. } else {
  1242. netdev_err(vif->ndev, "Connect result NULL\n");
  1243. }
  1244. eth_zero_addr(hif_drv->assoc_bssid);
  1245. hif_drv->usr_conn_req.ssid_len = 0;
  1246. kfree(hif_drv->usr_conn_req.ssid);
  1247. hif_drv->usr_conn_req.ssid = NULL;
  1248. kfree(hif_drv->usr_conn_req.bssid);
  1249. hif_drv->usr_conn_req.bssid = NULL;
  1250. hif_drv->usr_conn_req.ies_len = 0;
  1251. kfree(hif_drv->usr_conn_req.ies);
  1252. hif_drv->usr_conn_req.ies = NULL;
  1253. if (join_req && join_req_vif == vif) {
  1254. kfree(join_req);
  1255. join_req = NULL;
  1256. }
  1257. if (info_element && join_req_vif == vif) {
  1258. kfree(info_element);
  1259. info_element = NULL;
  1260. }
  1261. hif_drv->hif_state = HOST_IF_IDLE;
  1262. scan_while_connected = false;
  1263. } else if ((u8MacStatus == MAC_DISCONNECTED) &&
  1264. (hif_drv->usr_scan_req.scan_result)) {
  1265. del_timer(&hif_drv->scan_timer);
  1266. if (hif_drv->usr_scan_req.scan_result)
  1267. Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
  1268. }
  1269. }
  1270. kfree(pstrRcvdGnrlAsyncInfo->buffer);
  1271. pstrRcvdGnrlAsyncInfo->buffer = NULL;
  1272. return result;
  1273. }
  1274. static int Handle_Key(struct wilc_vif *vif,
  1275. struct key_attr *pstrHostIFkeyAttr)
  1276. {
  1277. s32 result = 0;
  1278. struct wid wid;
  1279. struct wid strWIDList[5];
  1280. u8 i;
  1281. u8 *pu8keybuf;
  1282. s8 s8idxarray[1];
  1283. s8 ret = 0;
  1284. struct host_if_drv *hif_drv = vif->hif_drv;
  1285. switch (pstrHostIFkeyAttr->type) {
  1286. case WEP:
  1287. if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
  1288. strWIDList[0].id = (u16)WID_11I_MODE;
  1289. strWIDList[0].type = WID_CHAR;
  1290. strWIDList[0].size = sizeof(char);
  1291. strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
  1292. strWIDList[1].id = WID_AUTH_TYPE;
  1293. strWIDList[1].type = WID_CHAR;
  1294. strWIDList[1].size = sizeof(char);
  1295. strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
  1296. pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2,
  1297. GFP_KERNEL);
  1298. if (!pu8keybuf)
  1299. return -ENOMEM;
  1300. pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
  1301. pu8keybuf[1] = pstrHostIFkeyAttr->attr.wep.key_len;
  1302. memcpy(&pu8keybuf[2], pstrHostIFkeyAttr->attr.wep.key,
  1303. pstrHostIFkeyAttr->attr.wep.key_len);
  1304. kfree(pstrHostIFkeyAttr->attr.wep.key);
  1305. strWIDList[2].id = (u16)WID_WEP_KEY_VALUE;
  1306. strWIDList[2].type = WID_STR;
  1307. strWIDList[2].size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
  1308. strWIDList[2].val = (s8 *)pu8keybuf;
  1309. result = wilc_send_config_pkt(vif, SET_CFG,
  1310. strWIDList, 3,
  1311. wilc_get_vif_idx(vif));
  1312. kfree(pu8keybuf);
  1313. } else if (pstrHostIFkeyAttr->action & ADDKEY) {
  1314. pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
  1315. if (!pu8keybuf)
  1316. return -ENOMEM;
  1317. pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
  1318. memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
  1319. memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
  1320. pstrHostIFkeyAttr->attr.wep.key_len);
  1321. kfree(pstrHostIFkeyAttr->attr.wep.key);
  1322. wid.id = (u16)WID_ADD_WEP_KEY;
  1323. wid.type = WID_STR;
  1324. wid.val = (s8 *)pu8keybuf;
  1325. wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
  1326. result = wilc_send_config_pkt(vif, SET_CFG,
  1327. &wid, 1,
  1328. wilc_get_vif_idx(vif));
  1329. kfree(pu8keybuf);
  1330. } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
  1331. wid.id = (u16)WID_REMOVE_WEP_KEY;
  1332. wid.type = WID_STR;
  1333. s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
  1334. wid.val = s8idxarray;
  1335. wid.size = 1;
  1336. result = wilc_send_config_pkt(vif, SET_CFG,
  1337. &wid, 1,
  1338. wilc_get_vif_idx(vif));
  1339. } else if (pstrHostIFkeyAttr->action & DEFAULTKEY) {
  1340. wid.id = (u16)WID_KEY_ID;
  1341. wid.type = WID_CHAR;
  1342. wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
  1343. wid.size = sizeof(char);
  1344. result = wilc_send_config_pkt(vif, SET_CFG,
  1345. &wid, 1,
  1346. wilc_get_vif_idx(vif));
  1347. }
  1348. complete(&hif_drv->comp_test_key_block);
  1349. break;
  1350. case WPA_RX_GTK:
  1351. if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
  1352. pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
  1353. if (!pu8keybuf) {
  1354. ret = -ENOMEM;
  1355. goto _WPARxGtk_end_case_;
  1356. }
  1357. if (pstrHostIFkeyAttr->attr.wpa.seq)
  1358. memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
  1359. memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
  1360. memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
  1361. memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
  1362. pstrHostIFkeyAttr->attr.wpa.key_len);
  1363. strWIDList[0].id = (u16)WID_11I_MODE;
  1364. strWIDList[0].type = WID_CHAR;
  1365. strWIDList[0].size = sizeof(char);
  1366. strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
  1367. strWIDList[1].id = (u16)WID_ADD_RX_GTK;
  1368. strWIDList[1].type = WID_STR;
  1369. strWIDList[1].val = (s8 *)pu8keybuf;
  1370. strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
  1371. result = wilc_send_config_pkt(vif, SET_CFG,
  1372. strWIDList, 2,
  1373. wilc_get_vif_idx(vif));
  1374. kfree(pu8keybuf);
  1375. complete(&hif_drv->comp_test_key_block);
  1376. } else if (pstrHostIFkeyAttr->action & ADDKEY) {
  1377. pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
  1378. if (!pu8keybuf) {
  1379. ret = -ENOMEM;
  1380. goto _WPARxGtk_end_case_;
  1381. }
  1382. if (hif_drv->hif_state == HOST_IF_CONNECTED)
  1383. memcpy(pu8keybuf, hif_drv->assoc_bssid, ETH_ALEN);
  1384. else
  1385. netdev_err(vif->ndev, "Couldn't handle\n");
  1386. memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
  1387. memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
  1388. memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
  1389. memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
  1390. pstrHostIFkeyAttr->attr.wpa.key_len);
  1391. wid.id = (u16)WID_ADD_RX_GTK;
  1392. wid.type = WID_STR;
  1393. wid.val = (s8 *)pu8keybuf;
  1394. wid.size = RX_MIC_KEY_MSG_LEN;
  1395. result = wilc_send_config_pkt(vif, SET_CFG,
  1396. &wid, 1,
  1397. wilc_get_vif_idx(vif));
  1398. kfree(pu8keybuf);
  1399. complete(&hif_drv->comp_test_key_block);
  1400. }
  1401. _WPARxGtk_end_case_:
  1402. kfree(pstrHostIFkeyAttr->attr.wpa.key);
  1403. kfree(pstrHostIFkeyAttr->attr.wpa.seq);
  1404. if (ret)
  1405. return ret;
  1406. break;
  1407. case WPA_PTK:
  1408. if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
  1409. pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
  1410. if (!pu8keybuf) {
  1411. ret = -ENOMEM;
  1412. goto _WPAPtk_end_case_;
  1413. }
  1414. memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
  1415. memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
  1416. memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
  1417. memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
  1418. pstrHostIFkeyAttr->attr.wpa.key_len);
  1419. strWIDList[0].id = (u16)WID_11I_MODE;
  1420. strWIDList[0].type = WID_CHAR;
  1421. strWIDList[0].size = sizeof(char);
  1422. strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
  1423. strWIDList[1].id = (u16)WID_ADD_PTK;
  1424. strWIDList[1].type = WID_STR;
  1425. strWIDList[1].val = (s8 *)pu8keybuf;
  1426. strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
  1427. result = wilc_send_config_pkt(vif, SET_CFG,
  1428. strWIDList, 2,
  1429. wilc_get_vif_idx(vif));
  1430. kfree(pu8keybuf);
  1431. complete(&hif_drv->comp_test_key_block);
  1432. } else if (pstrHostIFkeyAttr->action & ADDKEY) {
  1433. pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
  1434. if (!pu8keybuf) {
  1435. netdev_err(vif->ndev, "No buffer send PTK\n");
  1436. ret = -ENOMEM;
  1437. goto _WPAPtk_end_case_;
  1438. }
  1439. memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
  1440. memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
  1441. memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
  1442. pstrHostIFkeyAttr->attr.wpa.key_len);
  1443. wid.id = (u16)WID_ADD_PTK;
  1444. wid.type = WID_STR;
  1445. wid.val = (s8 *)pu8keybuf;
  1446. wid.size = PTK_KEY_MSG_LEN;
  1447. result = wilc_send_config_pkt(vif, SET_CFG,
  1448. &wid, 1,
  1449. wilc_get_vif_idx(vif));
  1450. kfree(pu8keybuf);
  1451. complete(&hif_drv->comp_test_key_block);
  1452. }
  1453. _WPAPtk_end_case_:
  1454. kfree(pstrHostIFkeyAttr->attr.wpa.key);
  1455. if (ret)
  1456. return ret;
  1457. break;
  1458. c

Large files files are truncated, but you can click here to view the full file