PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/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

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 "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));

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