PageRenderTime 38ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/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
  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. case PMKSA:
  1459. pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
  1460. if (!pu8keybuf) {
  1461. netdev_err(vif->ndev, "No buffer to send PMKSA Key\n");
  1462. return -ENOMEM;
  1463. }
  1464. pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
  1465. for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
  1466. memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
  1467. memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
  1468. }
  1469. wid.id = (u16)WID_PMKID_INFO;
  1470. wid.type = WID_STR;
  1471. wid.val = (s8 *)pu8keybuf;
  1472. wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
  1473. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1474. wilc_get_vif_idx(vif));
  1475. kfree(pu8keybuf);
  1476. break;
  1477. }
  1478. if (result)
  1479. netdev_err(vif->ndev, "Failed to send key config packet\n");
  1480. return result;
  1481. }
  1482. static void Handle_Disconnect(struct wilc_vif *vif)
  1483. {
  1484. struct wid wid;
  1485. struct host_if_drv *hif_drv = vif->hif_drv;
  1486. s32 result = 0;
  1487. u16 u16DummyReasonCode = 0;
  1488. wid.id = (u16)WID_DISCONNECT;
  1489. wid.type = WID_CHAR;
  1490. wid.val = (s8 *)&u16DummyReasonCode;
  1491. wid.size = sizeof(char);
  1492. wilc_optaining_ip = false;
  1493. wilc_set_power_mgmt(vif, 0, 0);
  1494. eth_zero_addr(wilc_connected_ssid);
  1495. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1496. wilc_get_vif_idx(vif));
  1497. if (result) {
  1498. netdev_err(vif->ndev, "Failed to send dissconect\n");
  1499. } else {
  1500. struct disconnect_info strDisconnectNotifInfo;
  1501. memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
  1502. strDisconnectNotifInfo.reason = 0;
  1503. strDisconnectNotifInfo.ie = NULL;
  1504. strDisconnectNotifInfo.ie_len = 0;
  1505. if (hif_drv->usr_scan_req.scan_result) {
  1506. del_timer(&hif_drv->scan_timer);
  1507. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED,
  1508. NULL,
  1509. hif_drv->usr_scan_req.arg,
  1510. NULL);
  1511. hif_drv->usr_scan_req.scan_result = NULL;
  1512. }
  1513. if (hif_drv->usr_conn_req.conn_result) {
  1514. if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
  1515. del_timer(&hif_drv->connect_timer);
  1516. hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
  1517. NULL,
  1518. 0,
  1519. &strDisconnectNotifInfo,
  1520. hif_drv->usr_conn_req.arg);
  1521. } else {
  1522. netdev_err(vif->ndev, "conn_result = NULL\n");
  1523. }
  1524. scan_while_connected = false;
  1525. hif_drv->hif_state = HOST_IF_IDLE;
  1526. eth_zero_addr(hif_drv->assoc_bssid);
  1527. hif_drv->usr_conn_req.ssid_len = 0;
  1528. kfree(hif_drv->usr_conn_req.ssid);
  1529. hif_drv->usr_conn_req.ssid = NULL;
  1530. kfree(hif_drv->usr_conn_req.bssid);
  1531. hif_drv->usr_conn_req.bssid = NULL;
  1532. hif_drv->usr_conn_req.ies_len = 0;
  1533. kfree(hif_drv->usr_conn_req.ies);
  1534. hif_drv->usr_conn_req.ies = NULL;
  1535. if (join_req && join_req_vif == vif) {
  1536. kfree(join_req);
  1537. join_req = NULL;
  1538. }
  1539. if (info_element && join_req_vif == vif) {
  1540. kfree(info_element);
  1541. info_element = NULL;
  1542. }
  1543. }
  1544. complete(&hif_drv->comp_test_disconn_block);
  1545. }
  1546. void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
  1547. {
  1548. if (!vif->hif_drv)
  1549. return;
  1550. if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
  1551. (vif->hif_drv->hif_state == HOST_IF_CONNECTING))
  1552. wilc_disconnect(vif, 1);
  1553. }
  1554. static void Handle_GetRssi(struct wilc_vif *vif)
  1555. {
  1556. s32 result = 0;
  1557. struct wid wid;
  1558. wid.id = (u16)WID_RSSI;
  1559. wid.type = WID_CHAR;
  1560. wid.val = &rssi;
  1561. wid.size = sizeof(char);
  1562. result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  1563. wilc_get_vif_idx(vif));
  1564. if (result) {
  1565. netdev_err(vif->ndev, "Failed to get RSSI value\n");
  1566. result = -EFAULT;
  1567. }
  1568. complete(&vif->hif_drv->comp_get_rssi);
  1569. }
  1570. static s32 Handle_GetStatistics(struct wilc_vif *vif,
  1571. struct rf_info *pstrStatistics)
  1572. {
  1573. struct wid strWIDList[5];
  1574. u32 u32WidsCount = 0, result = 0;
  1575. strWIDList[u32WidsCount].id = WID_LINKSPEED;
  1576. strWIDList[u32WidsCount].type = WID_CHAR;
  1577. strWIDList[u32WidsCount].size = sizeof(char);
  1578. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->link_speed;
  1579. u32WidsCount++;
  1580. strWIDList[u32WidsCount].id = WID_RSSI;
  1581. strWIDList[u32WidsCount].type = WID_CHAR;
  1582. strWIDList[u32WidsCount].size = sizeof(char);
  1583. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rssi;
  1584. u32WidsCount++;
  1585. strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
  1586. strWIDList[u32WidsCount].type = WID_INT;
  1587. strWIDList[u32WidsCount].size = sizeof(u32);
  1588. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_cnt;
  1589. u32WidsCount++;
  1590. strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
  1591. strWIDList[u32WidsCount].type = WID_INT;
  1592. strWIDList[u32WidsCount].size = sizeof(u32);
  1593. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rx_cnt;
  1594. u32WidsCount++;
  1595. strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
  1596. strWIDList[u32WidsCount].type = WID_INT;
  1597. strWIDList[u32WidsCount].size = sizeof(u32);
  1598. strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt;
  1599. u32WidsCount++;
  1600. result = wilc_send_config_pkt(vif, GET_CFG, strWIDList,
  1601. u32WidsCount,
  1602. wilc_get_vif_idx(vif));
  1603. if (result)
  1604. netdev_err(vif->ndev, "Failed to send scan parameters\n");
  1605. if (pstrStatistics->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
  1606. pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
  1607. wilc_enable_tcp_ack_filter(true);
  1608. else if (pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
  1609. wilc_enable_tcp_ack_filter(false);
  1610. if (pstrStatistics != &vif->wilc->dummy_statistics)
  1611. complete(&hif_wait_response);
  1612. return 0;
  1613. }
  1614. static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
  1615. struct sta_inactive_t *strHostIfStaInactiveT)
  1616. {
  1617. s32 result = 0;
  1618. u8 *stamac;
  1619. struct wid wid;
  1620. struct host_if_drv *hif_drv = vif->hif_drv;
  1621. wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
  1622. wid.type = WID_STR;
  1623. wid.size = ETH_ALEN;
  1624. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1625. stamac = wid.val;
  1626. memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
  1627. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1628. wilc_get_vif_idx(vif));
  1629. if (result) {
  1630. netdev_err(vif->ndev, "Failed to SET incative time\n");
  1631. return -EFAULT;
  1632. }
  1633. wid.id = (u16)WID_GET_INACTIVE_TIME;
  1634. wid.type = WID_INT;
  1635. wid.val = (s8 *)&inactive_time;
  1636. wid.size = sizeof(u32);
  1637. result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  1638. wilc_get_vif_idx(vif));
  1639. if (result) {
  1640. netdev_err(vif->ndev, "Failed to get incative time\n");
  1641. return -EFAULT;
  1642. }
  1643. complete(&hif_drv->comp_inactive_time);
  1644. return result;
  1645. }
  1646. static void Handle_AddBeacon(struct wilc_vif *vif,
  1647. struct beacon_attr *pstrSetBeaconParam)
  1648. {
  1649. s32 result = 0;
  1650. struct wid wid;
  1651. u8 *pu8CurrByte;
  1652. wid.id = (u16)WID_ADD_BEACON;
  1653. wid.type = WID_BIN;
  1654. wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
  1655. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1656. if (!wid.val)
  1657. goto ERRORHANDLER;
  1658. pu8CurrByte = wid.val;
  1659. *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
  1660. *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
  1661. *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
  1662. *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
  1663. *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
  1664. *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
  1665. *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
  1666. *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
  1667. *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
  1668. *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
  1669. *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
  1670. *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
  1671. memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
  1672. pu8CurrByte += pstrSetBeaconParam->head_len;
  1673. *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
  1674. *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
  1675. *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
  1676. *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
  1677. if (pstrSetBeaconParam->tail)
  1678. memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
  1679. pu8CurrByte += pstrSetBeaconParam->tail_len;
  1680. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1681. wilc_get_vif_idx(vif));
  1682. if (result)
  1683. netdev_err(vif->ndev, "Failed to send add beacon\n");
  1684. ERRORHANDLER:
  1685. kfree(wid.val);
  1686. kfree(pstrSetBeaconParam->head);
  1687. kfree(pstrSetBeaconParam->tail);
  1688. }
  1689. static void Handle_DelBeacon(struct wilc_vif *vif)
  1690. {
  1691. s32 result = 0;
  1692. struct wid wid;
  1693. u8 *pu8CurrByte;
  1694. wid.id = (u16)WID_DEL_BEACON;
  1695. wid.type = WID_CHAR;
  1696. wid.size = sizeof(char);
  1697. wid.val = &del_beacon;
  1698. if (!wid.val)
  1699. return;
  1700. pu8CurrByte = wid.val;
  1701. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1702. wilc_get_vif_idx(vif));
  1703. if (result)
  1704. netdev_err(vif->ndev, "Failed to send delete beacon\n");
  1705. }
  1706. static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
  1707. struct add_sta_param *pstrStationParam)
  1708. {
  1709. u8 *pu8CurrByte;
  1710. pu8CurrByte = pu8Buffer;
  1711. memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN);
  1712. pu8CurrByte += ETH_ALEN;
  1713. *pu8CurrByte++ = pstrStationParam->aid & 0xFF;
  1714. *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF;
  1715. *pu8CurrByte++ = pstrStationParam->rates_len;
  1716. if (pstrStationParam->rates_len > 0)
  1717. memcpy(pu8CurrByte, pstrStationParam->rates,
  1718. pstrStationParam->rates_len);
  1719. pu8CurrByte += pstrStationParam->rates_len;
  1720. *pu8CurrByte++ = pstrStationParam->ht_supported;
  1721. *pu8CurrByte++ = pstrStationParam->ht_capa_info & 0xFF;
  1722. *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF;
  1723. *pu8CurrByte++ = pstrStationParam->ht_ampdu_params;
  1724. memcpy(pu8CurrByte, pstrStationParam->ht_supp_mcs_set,
  1725. WILC_SUPP_MCS_SET_SIZE);
  1726. pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
  1727. *pu8CurrByte++ = pstrStationParam->ht_ext_params & 0xFF;
  1728. *pu8CurrByte++ = (pstrStationParam->ht_ext_params >> 8) & 0xFF;
  1729. *pu8CurrByte++ = pstrStationParam->ht_tx_bf_cap & 0xFF;
  1730. *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 8) & 0xFF;
  1731. *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 16) & 0xFF;
  1732. *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 24) & 0xFF;
  1733. *pu8CurrByte++ = pstrStationParam->ht_ante_sel;
  1734. *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF;
  1735. *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF;
  1736. *pu8CurrByte++ = pstrStationParam->flags_set & 0xFF;
  1737. *pu8CurrByte++ = (pstrStationParam->flags_set >> 8) & 0xFF;
  1738. return pu8CurrByte - pu8Buffer;
  1739. }
  1740. static void Handle_AddStation(struct wilc_vif *vif,
  1741. struct add_sta_param *pstrStationParam)
  1742. {
  1743. s32 result = 0;
  1744. struct wid wid;
  1745. u8 *pu8CurrByte;
  1746. wid.id = (u16)WID_ADD_STA;
  1747. wid.type = WID_BIN;
  1748. wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
  1749. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1750. if (!wid.val)
  1751. goto ERRORHANDLER;
  1752. pu8CurrByte = wid.val;
  1753. pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
  1754. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1755. wilc_get_vif_idx(vif));
  1756. if (result != 0)
  1757. netdev_err(vif->ndev, "Failed to send add station\n");
  1758. ERRORHANDLER:
  1759. kfree(pstrStationParam->rates);
  1760. kfree(wid.val);
  1761. }
  1762. static void Handle_DelAllSta(struct wilc_vif *vif,
  1763. struct del_all_sta *pstrDelAllStaParam)
  1764. {
  1765. s32 result = 0;
  1766. struct wid wid;
  1767. u8 *pu8CurrByte;
  1768. u8 i;
  1769. u8 au8Zero_Buff[6] = {0};
  1770. wid.id = (u16)WID_DEL_ALL_STA;
  1771. wid.type = WID_STR;
  1772. wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
  1773. wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
  1774. if (!wid.val)
  1775. goto ERRORHANDLER;
  1776. pu8CurrByte = wid.val;
  1777. *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
  1778. for (i = 0; i < MAX_NUM_STA; i++) {
  1779. if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
  1780. memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
  1781. else
  1782. continue;
  1783. pu8CurrByte += ETH_ALEN;
  1784. }
  1785. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1786. wilc_get_vif_idx(vif));
  1787. if (result)
  1788. netdev_err(vif->ndev, "Failed to send add station\n");
  1789. ERRORHANDLER:
  1790. kfree(wid.val);
  1791. complete(&hif_wait_response);
  1792. }
  1793. static void Handle_DelStation(struct wilc_vif *vif,
  1794. struct del_sta *pstrDelStaParam)
  1795. {
  1796. s32 result = 0;
  1797. struct wid wid;
  1798. u8 *pu8CurrByte;
  1799. wid.id = (u16)WID_REMOVE_STA;
  1800. wid.type = WID_BIN;
  1801. wid.size = ETH_ALEN;
  1802. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1803. if (!wid.val)
  1804. goto ERRORHANDLER;
  1805. pu8CurrByte = wid.val;
  1806. memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
  1807. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1808. wilc_get_vif_idx(vif));
  1809. if (result)
  1810. netdev_err(vif->ndev, "Failed to send add station\n");
  1811. ERRORHANDLER:
  1812. kfree(wid.val);
  1813. }
  1814. static void Handle_EditStation(struct wilc_vif *vif,
  1815. struct add_sta_param *pstrStationParam)
  1816. {
  1817. s32 result = 0;
  1818. struct wid wid;
  1819. u8 *pu8CurrByte;
  1820. wid.id = (u16)WID_EDIT_STA;
  1821. wid.type = WID_BIN;
  1822. wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
  1823. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1824. if (!wid.val)
  1825. goto ERRORHANDLER;
  1826. pu8CurrByte = wid.val;
  1827. pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
  1828. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1829. wilc_get_vif_idx(vif));
  1830. if (result)
  1831. netdev_err(vif->ndev, "Failed to send edit station\n");
  1832. ERRORHANDLER:
  1833. kfree(pstrStationParam->rates);
  1834. kfree(wid.val);
  1835. }
  1836. static int Handle_RemainOnChan(struct wilc_vif *vif,
  1837. struct remain_ch *pstrHostIfRemainOnChan)
  1838. {
  1839. s32 result = 0;
  1840. u8 u8remain_on_chan_flag;
  1841. struct wid wid;
  1842. struct host_if_drv *hif_drv = vif->hif_drv;
  1843. if (!hif_drv->remain_on_ch_pending) {
  1844. hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg;
  1845. hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired;
  1846. hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready;
  1847. hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch;
  1848. hif_drv->remain_on_ch.id = pstrHostIfRemainOnChan->id;
  1849. } else {
  1850. pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch;
  1851. }
  1852. if (hif_drv->usr_scan_req.scan_result) {
  1853. hif_drv->remain_on_ch_pending = 1;
  1854. result = -EBUSY;
  1855. goto ERRORHANDLER;
  1856. }
  1857. if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
  1858. result = -EBUSY;
  1859. goto ERRORHANDLER;
  1860. }
  1861. if (wilc_optaining_ip || wilc_connecting) {
  1862. result = -EBUSY;
  1863. goto ERRORHANDLER;
  1864. }
  1865. u8remain_on_chan_flag = true;
  1866. wid.id = (u16)WID_REMAIN_ON_CHAN;
  1867. wid.type = WID_STR;
  1868. wid.size = 2;
  1869. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1870. if (!wid.val) {
  1871. result = -ENOMEM;
  1872. goto ERRORHANDLER;
  1873. }
  1874. wid.val[0] = u8remain_on_chan_flag;
  1875. wid.val[1] = (s8)pstrHostIfRemainOnChan->ch;
  1876. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1877. wilc_get_vif_idx(vif));
  1878. if (result != 0)
  1879. netdev_err(vif->ndev, "Failed to set remain on channel\n");
  1880. ERRORHANDLER:
  1881. {
  1882. P2P_LISTEN_STATE = 1;
  1883. hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
  1884. mod_timer(&hif_drv->remain_on_ch_timer,
  1885. jiffies +
  1886. msecs_to_jiffies(pstrHostIfRemainOnChan->duration));
  1887. if (hif_drv->remain_on_ch.ready)
  1888. hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
  1889. if (hif_drv->remain_on_ch_pending)
  1890. hif_drv->remain_on_ch_pending = 0;
  1891. }
  1892. return result;
  1893. }
  1894. static int Handle_RegisterFrame(struct wilc_vif *vif,
  1895. struct reg_frame *pstrHostIfRegisterFrame)
  1896. {
  1897. s32 result = 0;
  1898. struct wid wid;
  1899. u8 *pu8CurrByte;
  1900. wid.id = (u16)WID_REGISTER_FRAME;
  1901. wid.type = WID_STR;
  1902. wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
  1903. if (!wid.val)
  1904. return -ENOMEM;
  1905. pu8CurrByte = wid.val;
  1906. *pu8CurrByte++ = pstrHostIfRegisterFrame->reg;
  1907. *pu8CurrByte++ = pstrHostIfRegisterFrame->reg_id;
  1908. memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16));
  1909. wid.size = sizeof(u16) + 2;
  1910. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1911. wilc_get_vif_idx(vif));
  1912. if (result) {
  1913. netdev_err(vif->ndev, "Failed to frame register\n");
  1914. result = -EINVAL;
  1915. }
  1916. return result;
  1917. }
  1918. static u32 Handle_ListenStateExpired(struct wilc_vif *vif,
  1919. struct remain_ch *pstrHostIfRemainOnChan)
  1920. {
  1921. u8 u8remain_on_chan_flag;
  1922. struct wid wid;
  1923. s32 result = 0;
  1924. struct host_if_drv *hif_drv = vif->hif_drv;
  1925. if (P2P_LISTEN_STATE) {
  1926. u8remain_on_chan_flag = false;
  1927. wid.id = (u16)WID_REMAIN_ON_CHAN;
  1928. wid.type = WID_STR;
  1929. wid.size = 2;
  1930. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1931. if (!wid.val) {
  1932. netdev_err(vif->ndev, "Failed to allocate memory\n");
  1933. return -ENOMEM;
  1934. }
  1935. wid.val[0] = u8remain_on_chan_flag;
  1936. wid.val[1] = FALSE_FRMWR_CHANNEL;
  1937. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1938. wilc_get_vif_idx(vif));
  1939. if (result != 0) {
  1940. netdev_err(vif->ndev, "Failed to set remain channel\n");
  1941. goto _done_;
  1942. }
  1943. if (hif_drv->remain_on_ch.expired) {
  1944. hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
  1945. pstrHostIfRemainOnChan->id);
  1946. }
  1947. P2P_LISTEN_STATE = 0;
  1948. } else {
  1949. netdev_dbg(vif->ndev, "Not in listen state\n");
  1950. result = -EFAULT;
  1951. }
  1952. _done_:
  1953. return result;
  1954. }
  1955. static void ListenTimerCB(unsigned long arg)
  1956. {
  1957. s32 result = 0;
  1958. struct host_if_msg msg;
  1959. struct wilc_vif *vif = (struct wilc_vif *)arg;
  1960. del_timer(&vif->hif_drv->remain_on_ch_timer);
  1961. memset(&msg, 0, sizeof(struct host_if_msg));
  1962. msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
  1963. msg.vif = vif;
  1964. msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
  1965. result = wilc_enqueue_cmd(&msg);
  1966. if (result)
  1967. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  1968. }
  1969. static void Handle_PowerManagement(struct wilc_vif *vif,
  1970. struct power_mgmt_param *strPowerMgmtParam)
  1971. {
  1972. s32 result = 0;
  1973. struct wid wid;
  1974. s8 s8PowerMode;
  1975. wid.id = (u16)WID_POWER_MANAGEMENT;
  1976. if (strPowerMgmtParam->enabled)
  1977. s8PowerMode = MIN_FAST_PS;
  1978. else
  1979. s8PowerMode = NO_POWERSAVE;
  1980. wid.val = &s8PowerMode;
  1981. wid.size = sizeof(char);
  1982. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  1983. wilc_get_vif_idx(vif));
  1984. if (result)
  1985. netdev_err(vif->ndev, "Failed to send power management\n");
  1986. }
  1987. static void Handle_SetMulticastFilter(struct wilc_vif *vif,
  1988. struct set_multicast *strHostIfSetMulti)
  1989. {
  1990. s32 result = 0;
  1991. struct wid wid;
  1992. u8 *pu8CurrByte;
  1993. wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
  1994. wid.type = WID_BIN;
  1995. wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
  1996. wid.val = kmalloc(wid.size, GFP_KERNEL);
  1997. if (!wid.val)
  1998. goto ERRORHANDLER;
  1999. pu8CurrByte = wid.val;
  2000. *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
  2001. *pu8CurrByte++ = 0;
  2002. *pu8CurrByte++ = 0;
  2003. *pu8CurrByte++ = 0;
  2004. *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
  2005. *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
  2006. *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
  2007. *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
  2008. if ((strHostIfSetMulti->cnt) > 0)
  2009. memcpy(pu8CurrByte, wilc_multicast_mac_addr_list,
  2010. ((strHostIfSetMulti->cnt) * ETH_ALEN));
  2011. result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  2012. wilc_get_vif_idx(vif));
  2013. if (result)
  2014. netdev_err(vif->ndev, "Failed to send setup multicast\n");
  2015. ERRORHANDLER:
  2016. kfree(wid.val);
  2017. }
  2018. static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
  2019. {
  2020. int ret;
  2021. struct wid wid;
  2022. wid.id = (u16)WID_TX_POWER;
  2023. wid.type = WID_CHAR;
  2024. wid.val = &tx_pwr;
  2025. wid.size = sizeof(char);
  2026. ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
  2027. wilc_get_vif_idx(vif));
  2028. if (ret)
  2029. netdev_err(vif->ndev, "Failed to set TX PWR\n");
  2030. }
  2031. static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
  2032. {
  2033. int ret = 0;
  2034. struct wid wid;
  2035. wid.id = (u16)WID_TX_POWER;
  2036. wid.type = WID_CHAR;
  2037. wid.val = (s8 *)tx_pwr;
  2038. wid.size = sizeof(char);
  2039. ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  2040. wilc_get_vif_idx(vif));
  2041. if (ret)
  2042. netdev_err(vif->ndev, "Failed to get TX PWR\n");
  2043. complete(&hif_wait_response);
  2044. }
  2045. static void host_if_work(struct work_struct *work)
  2046. {
  2047. struct host_if_msg *msg;
  2048. struct wilc *wilc;
  2049. msg = container_of(work, struct host_if_msg, work);
  2050. wilc = msg->vif->wilc;
  2051. if (msg->id == HOST_IF_MSG_CONNECT &&
  2052. msg->vif->hif_drv->usr_scan_req.scan_result) {
  2053. wilc_enqueue_cmd(msg);
  2054. usleep_range(2 * 1000, 2 * 1000);
  2055. goto free_msg;
  2056. }
  2057. switch (msg->id) {
  2058. case HOST_IF_MSG_SCAN:
  2059. handle_scan(msg->vif, &msg->body.scan_info);
  2060. break;
  2061. case HOST_IF_MSG_CONNECT:
  2062. Handle_Connect(msg->vif, &msg->body.con_info);
  2063. break;
  2064. case HOST_IF_MSG_RCVD_NTWRK_INFO:
  2065. Handle_RcvdNtwrkInfo(msg->vif, &msg->body.net_info);
  2066. break;
  2067. case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
  2068. Handle_RcvdGnrlAsyncInfo(msg->vif,
  2069. &msg->body.async_info);
  2070. break;
  2071. case HOST_IF_MSG_KEY:
  2072. Handle_Key(msg->vif, &msg->body.key_info);
  2073. break;
  2074. case HOST_IF_MSG_CFG_PARAMS:
  2075. handle_cfg_param(msg->vif, &msg->body.cfg_info);
  2076. break;
  2077. case HOST_IF_MSG_SET_CHANNEL:
  2078. handle_set_channel(msg->vif, &msg->body.channel_info);
  2079. break;
  2080. case HOST_IF_MSG_DISCONNECT:
  2081. Handle_Disconnect(msg->vif);
  2082. break;
  2083. case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
  2084. del_timer(&msg->vif->hif_drv->scan_timer);
  2085. if (!wilc_wlan_get_num_conn_ifcs(wilc))
  2086. wilc_chip_sleep_manually(wilc);
  2087. Handle_ScanDone(msg->vif, SCAN_EVENT_DONE);
  2088. if (msg->vif->hif_drv->remain_on_ch_pending)
  2089. Handle_RemainOnChan(msg->vif,
  2090. &msg->body.remain_on_ch);
  2091. break;
  2092. case HOST_IF_MSG_GET_RSSI:
  2093. Handle_GetRssi(msg->vif);
  2094. break;
  2095. case HOST_IF_MSG_GET_STATISTICS:
  2096. Handle_GetStatistics(msg->vif,
  2097. (struct rf_info *)msg->body.data);
  2098. break;
  2099. case HOST_IF_MSG_ADD_BEACON:
  2100. Handle_AddBeacon(msg->vif, &msg->body.beacon_info);
  2101. break;
  2102. case HOST_IF_MSG_DEL_BEACON:
  2103. Handle_DelBeacon(msg->vif);
  2104. break;
  2105. case HOST_IF_MSG_ADD_STATION:
  2106. Handle_AddStation(msg->vif, &msg->body.add_sta_info);
  2107. break;
  2108. case HOST_IF_MSG_DEL_STATION:
  2109. Handle_DelStation(msg->vif, &msg->body.del_sta_info);
  2110. break;
  2111. case HOST_IF_MSG_EDIT_STATION:
  2112. Handle_EditStation(msg->vif, &msg->body.edit_sta_info);
  2113. break;
  2114. case HOST_IF_MSG_GET_INACTIVETIME:
  2115. Handle_Get_InActiveTime(msg->vif, &msg->body.mac_info);
  2116. break;
  2117. case HOST_IF_MSG_SCAN_TIMER_FIRED:
  2118. Handle_ScanDone(msg->vif, SCAN_EVENT_ABORTED);
  2119. break;
  2120. case HOST_IF_MSG_CONNECT_TIMER_FIRED:
  2121. Handle_ConnectTimeout(msg->vif);
  2122. break;
  2123. case HOST_IF_MSG_POWER_MGMT:
  2124. Handle_PowerManagement(msg->vif,
  2125. &msg->body.pwr_mgmt_info);
  2126. break;
  2127. case HOST_IF_MSG_SET_WFIDRV_HANDLER:
  2128. handle_set_wfi_drv_handler(msg->vif, &msg->body.drv);
  2129. break;
  2130. case HOST_IF_MSG_SET_OPERATION_MODE:
  2131. handle_set_operation_mode(msg->vif, &msg->body.mode);
  2132. break;
  2133. case HOST_IF_MSG_SET_IPADDRESS:
  2134. handle_set_ip_address(msg->vif,
  2135. msg->body.ip_info.ip_addr,
  2136. msg->body.ip_info.idx);
  2137. break;
  2138. case HOST_IF_MSG_GET_IPADDRESS:
  2139. handle_get_ip_address(msg->vif, msg->body.ip_info.idx);
  2140. break;
  2141. case HOST_IF_MSG_GET_MAC_ADDRESS:
  2142. handle_get_mac_address(msg->vif,
  2143. &msg->body.get_mac_info);
  2144. break;
  2145. case HOST_IF_MSG_REMAIN_ON_CHAN:
  2146. Handle_RemainOnChan(msg->vif, &msg->body.remain_on_ch);
  2147. break;
  2148. case HOST_IF_MSG_REGISTER_FRAME:
  2149. Handle_RegisterFrame(msg->vif, &msg->body.reg_frame);
  2150. break;
  2151. case HOST_IF_MSG_LISTEN_TIMER_FIRED:
  2152. Handle_ListenStateExpired(msg->vif, &msg->body.remain_on_ch);
  2153. break;
  2154. case HOST_IF_MSG_SET_MULTICAST_FILTER:
  2155. Handle_SetMulticastFilter(msg->vif, &msg->body.multicast_info);
  2156. break;
  2157. case HOST_IF_MSG_DEL_ALL_STA:
  2158. Handle_DelAllSta(msg->vif, &msg->body.del_all_sta_info);
  2159. break;
  2160. case HOST_IF_MSG_SET_TX_POWER:
  2161. handle_set_tx_pwr(msg->vif, msg->body.tx_power.tx_pwr);
  2162. break;
  2163. case HOST_IF_MSG_GET_TX_POWER:
  2164. handle_get_tx_pwr(msg->vif, &msg->body.tx_power.tx_pwr);
  2165. break;
  2166. default:
  2167. netdev_err(msg->vif->ndev, "[Host Interface] undefined\n");
  2168. break;
  2169. }
  2170. free_msg:
  2171. kfree(msg);
  2172. complete(&hif_thread_comp);
  2173. }
  2174. static void TimerCB_Scan(unsigned long arg)
  2175. {
  2176. struct wilc_vif *vif = (struct wilc_vif *)arg;
  2177. struct host_if_msg msg;
  2178. memset(&msg, 0, sizeof(struct host_if_msg));
  2179. msg.vif = vif;
  2180. msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
  2181. wilc_enqueue_cmd(&msg);
  2182. }
  2183. static void TimerCB_Connect(unsigned long arg)
  2184. {
  2185. struct wilc_vif *vif = (struct wilc_vif *)arg;
  2186. struct host_if_msg msg;
  2187. memset(&msg, 0, sizeof(struct host_if_msg));
  2188. msg.vif = vif;
  2189. msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
  2190. wilc_enqueue_cmd(&msg);
  2191. }
  2192. s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
  2193. {
  2194. struct wid wid;
  2195. wid.id = (u16)WID_REMOVE_KEY;
  2196. wid.type = WID_STR;
  2197. wid.val = (s8 *)pu8StaAddress;
  2198. wid.size = 6;
  2199. return 0;
  2200. }
  2201. int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
  2202. {
  2203. int result = 0;
  2204. struct host_if_msg msg;
  2205. struct host_if_drv *hif_drv = vif->hif_drv;
  2206. if (!hif_drv) {
  2207. result = -EFAULT;
  2208. netdev_err(vif->ndev, "Failed to send setup multicast\n");
  2209. return result;
  2210. }
  2211. memset(&msg, 0, sizeof(struct host_if_msg));
  2212. msg.id = HOST_IF_MSG_KEY;
  2213. msg.body.key_info.type = WEP;
  2214. msg.body.key_info.action = REMOVEKEY;
  2215. msg.vif = vif;
  2216. msg.body.key_info.attr.wep.index = index;
  2217. result = wilc_enqueue_cmd(&msg);
  2218. if (result)
  2219. netdev_err(vif->ndev, "Request to remove WEP key\n");
  2220. else
  2221. wait_for_completion(&hif_drv->comp_test_key_block);
  2222. return result;
  2223. }
  2224. int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
  2225. {
  2226. int result = 0;
  2227. struct host_if_msg msg;
  2228. struct host_if_drv *hif_drv = vif->hif_drv;
  2229. if (!hif_drv) {
  2230. result = -EFAULT;
  2231. netdev_err(vif->ndev, "driver is null\n");
  2232. return result;
  2233. }
  2234. memset(&msg, 0, sizeof(struct host_if_msg));
  2235. msg.id = HOST_IF_MSG_KEY;
  2236. msg.body.key_info.type = WEP;
  2237. msg.body.key_info.action = DEFAULTKEY;
  2238. msg.vif = vif;
  2239. msg.body.key_info.attr.wep.index = index;
  2240. result = wilc_enqueue_cmd(&msg);
  2241. if (result)
  2242. netdev_err(vif->ndev, "Default key index\n");
  2243. else
  2244. wait_for_completion(&hif_drv->comp_test_key_block);
  2245. return result;
  2246. }
  2247. int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
  2248. u8 index)
  2249. {
  2250. int result = 0;
  2251. struct host_if_msg msg;
  2252. struct host_if_drv *hif_drv = vif->hif_drv;
  2253. if (!hif_drv) {
  2254. netdev_err(vif->ndev, "driver is null\n");
  2255. return -EFAULT;
  2256. }
  2257. memset(&msg, 0, sizeof(struct host_if_msg));
  2258. msg.id = HOST_IF_MSG_KEY;
  2259. msg.body.key_info.type = WEP;
  2260. msg.body.key_info.action = ADDKEY;
  2261. msg.vif = vif;
  2262. msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
  2263. if (!msg.body.key_info.attr.wep.key)
  2264. return -ENOMEM;
  2265. msg.body.key_info.attr.wep.key_len = len;
  2266. msg.body.key_info.attr.wep.index = index;
  2267. result = wilc_enqueue_cmd(&msg);
  2268. if (result)
  2269. netdev_err(vif->ndev, "STA - WEP Key\n");
  2270. wait_for_completion(&hif_drv->comp_test_key_block);
  2271. return result;
  2272. }
  2273. int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
  2274. u8 index, u8 mode, enum AUTHTYPE auth_type)
  2275. {
  2276. int result = 0;
  2277. struct host_if_msg msg;
  2278. struct host_if_drv *hif_drv = vif->hif_drv;
  2279. if (!hif_drv) {
  2280. netdev_err(vif->ndev, "driver is null\n");
  2281. return -EFAULT;
  2282. }
  2283. memset(&msg, 0, sizeof(struct host_if_msg));
  2284. msg.id = HOST_IF_MSG_KEY;
  2285. msg.body.key_info.type = WEP;
  2286. msg.body.key_info.action = ADDKEY_AP;
  2287. msg.vif = vif;
  2288. msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
  2289. if (!msg.body.key_info.attr.wep.key)
  2290. return -ENOMEM;
  2291. msg.body.key_info.attr.wep.key_len = len;
  2292. msg.body.key_info.attr.wep.index = index;
  2293. msg.body.key_info.attr.wep.mode = mode;
  2294. msg.body.key_info.attr.wep.auth_type = auth_type;
  2295. result = wilc_enqueue_cmd(&msg);
  2296. if (result)
  2297. netdev_err(vif->ndev, "AP - WEP Key\n");
  2298. else
  2299. wait_for_completion(&hif_drv->comp_test_key_block);
  2300. return result;
  2301. }
  2302. int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
  2303. const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
  2304. u8 mode, u8 cipher_mode, u8 index)
  2305. {
  2306. int result = 0;
  2307. struct host_if_msg msg;
  2308. struct host_if_drv *hif_drv = vif->hif_drv;
  2309. u8 key_len = ptk_key_len;
  2310. if (!hif_drv) {
  2311. netdev_err(vif->ndev, "driver is null\n");
  2312. return -EFAULT;
  2313. }
  2314. if (rx_mic)
  2315. key_len += RX_MIC_KEY_LEN;
  2316. if (tx_mic)
  2317. key_len += TX_MIC_KEY_LEN;
  2318. memset(&msg, 0, sizeof(struct host_if_msg));
  2319. msg.id = HOST_IF_MSG_KEY;
  2320. msg.body.key_info.type = WPA_PTK;
  2321. if (mode == AP_MODE) {
  2322. msg.body.key_info.action = ADDKEY_AP;
  2323. msg.body.key_info.attr.wpa.index = index;
  2324. }
  2325. if (mode == STATION_MODE)
  2326. msg.body.key_info.action = ADDKEY;
  2327. msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
  2328. if (!msg.body.key_info.attr.wpa.key)
  2329. return -ENOMEM;
  2330. if (rx_mic)
  2331. memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN);
  2332. if (tx_mic)
  2333. memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN);
  2334. msg.body.key_info.attr.wpa.key_len = key_len;
  2335. msg.body.key_info.attr.wpa.mac_addr = mac_addr;
  2336. msg.body.key_info.attr.wpa.mode = cipher_mode;
  2337. msg.vif = vif;
  2338. result = wilc_enqueue_cmd(&msg);
  2339. if (result)
  2340. netdev_err(vif->ndev, "PTK Key\n");
  2341. else
  2342. wait_for_completion(&hif_drv->comp_test_key_block);
  2343. return result;
  2344. }
  2345. int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
  2346. u8 index, u32 key_rsc_len, const u8 *key_rsc,
  2347. const u8 *rx_mic, const u8 *tx_mic, u8 mode,
  2348. u8 cipher_mode)
  2349. {
  2350. int result = 0;
  2351. struct host_if_msg msg;
  2352. struct host_if_drv *hif_drv = vif->hif_drv;
  2353. u8 key_len = gtk_key_len;
  2354. if (!hif_drv) {
  2355. netdev_err(vif->ndev, "driver is null\n");
  2356. return -EFAULT;
  2357. }
  2358. memset(&msg, 0, sizeof(struct host_if_msg));
  2359. if (rx_mic)
  2360. key_len += RX_MIC_KEY_LEN;
  2361. if (tx_mic)
  2362. key_len += TX_MIC_KEY_LEN;
  2363. if (key_rsc) {
  2364. msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
  2365. key_rsc_len,
  2366. GFP_KERNEL);
  2367. if (!msg.body.key_info.attr.wpa.seq)
  2368. return -ENOMEM;
  2369. }
  2370. msg.id = HOST_IF_MSG_KEY;
  2371. msg.body.key_info.type = WPA_RX_GTK;
  2372. msg.vif = vif;
  2373. if (mode == AP_MODE) {
  2374. msg.body.key_info.action = ADDKEY_AP;
  2375. msg.body.key_info.attr.wpa.mode = cipher_mode;
  2376. }
  2377. if (mode == STATION_MODE)
  2378. msg.body.key_info.action = ADDKEY;
  2379. msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
  2380. key_len,
  2381. GFP_KERNEL);
  2382. if (!msg.body.key_info.attr.wpa.key)
  2383. return -ENOMEM;
  2384. if (rx_mic)
  2385. memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
  2386. RX_MIC_KEY_LEN);
  2387. if (tx_mic)
  2388. memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
  2389. TX_MIC_KEY_LEN);
  2390. msg.body.key_info.attr.wpa.index = index;
  2391. msg.body.key_info.attr.wpa.key_len = key_len;
  2392. msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
  2393. result = wilc_enqueue_cmd(&msg);
  2394. if (result)
  2395. netdev_err(vif->ndev, "RX GTK\n");
  2396. else
  2397. wait_for_completion(&hif_drv->comp_test_key_block);
  2398. return result;
  2399. }
  2400. int wilc_set_pmkid_info(struct wilc_vif *vif,
  2401. struct host_if_pmkid_attr *pmkid)
  2402. {
  2403. int result = 0;
  2404. struct host_if_msg msg;
  2405. int i;
  2406. memset(&msg, 0, sizeof(struct host_if_msg));
  2407. msg.id = HOST_IF_MSG_KEY;
  2408. msg.body.key_info.type = PMKSA;
  2409. msg.body.key_info.action = ADDKEY;
  2410. msg.vif = vif;
  2411. for (i = 0; i < pmkid->numpmkid; i++) {
  2412. memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
  2413. &pmkid->pmkidlist[i].bssid, ETH_ALEN);
  2414. memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
  2415. &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
  2416. }
  2417. result = wilc_enqueue_cmd(&msg);
  2418. if (result)
  2419. netdev_err(vif->ndev, "PMKID Info\n");
  2420. return result;
  2421. }
  2422. int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
  2423. {
  2424. int result = 0;
  2425. struct host_if_msg msg;
  2426. memset(&msg, 0, sizeof(struct host_if_msg));
  2427. msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
  2428. msg.body.get_mac_info.mac_addr = mac_addr;
  2429. msg.vif = vif;
  2430. result = wilc_enqueue_cmd(&msg);
  2431. if (result) {
  2432. netdev_err(vif->ndev, "Failed to send get mac address\n");
  2433. return -EFAULT;
  2434. }
  2435. wait_for_completion(&hif_wait_response);
  2436. return result;
  2437. }
  2438. int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
  2439. size_t ssid_len, const u8 *ies, size_t ies_len,
  2440. wilc_connect_result connect_result, void *user_arg,
  2441. u8 security, enum AUTHTYPE auth_type,
  2442. u8 channel, void *join_params)
  2443. {
  2444. int result = 0;
  2445. struct host_if_msg msg;
  2446. struct host_if_drv *hif_drv = vif->hif_drv;
  2447. if (!hif_drv || !connect_result) {
  2448. netdev_err(vif->ndev, "Driver is null\n");
  2449. return -EFAULT;
  2450. }
  2451. if (!join_params) {
  2452. netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
  2453. return -EFAULT;
  2454. }
  2455. memset(&msg, 0, sizeof(struct host_if_msg));
  2456. msg.id = HOST_IF_MSG_CONNECT;
  2457. msg.body.con_info.security = security;
  2458. msg.body.con_info.auth_type = auth_type;
  2459. msg.body.con_info.ch = channel;
  2460. msg.body.con_info.result = connect_result;
  2461. msg.body.con_info.arg = user_arg;
  2462. msg.body.con_info.params = join_params;
  2463. msg.vif = vif;
  2464. if (bssid) {
  2465. msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
  2466. if (!msg.body.con_info.bssid)
  2467. return -ENOMEM;
  2468. }
  2469. if (ssid) {
  2470. msg.body.con_info.ssid_len = ssid_len;
  2471. msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
  2472. if (!msg.body.con_info.ssid)
  2473. return -ENOMEM;
  2474. }
  2475. if (ies) {
  2476. msg.body.con_info.ies_len = ies_len;
  2477. msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
  2478. if (!msg.body.con_info.ies)
  2479. return -ENOMEM;
  2480. }
  2481. if (hif_drv->hif_state < HOST_IF_CONNECTING)
  2482. hif_drv->hif_state = HOST_IF_CONNECTING;
  2483. result = wilc_enqueue_cmd(&msg);
  2484. if (result) {
  2485. netdev_err(vif->ndev, "send message: Set join request\n");
  2486. return -EFAULT;
  2487. }
  2488. hif_drv->connect_timer.data = (unsigned long)vif;
  2489. mod_timer(&hif_drv->connect_timer,
  2490. jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
  2491. return result;
  2492. }
  2493. int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
  2494. {
  2495. int result = 0;
  2496. struct host_if_msg msg;
  2497. struct host_if_drv *hif_drv = vif->hif_drv;
  2498. if (!hif_drv) {
  2499. netdev_err(vif->ndev, "Driver is null\n");
  2500. return -EFAULT;
  2501. }
  2502. memset(&msg, 0, sizeof(struct host_if_msg));
  2503. msg.id = HOST_IF_MSG_DISCONNECT;
  2504. msg.vif = vif;
  2505. result = wilc_enqueue_cmd(&msg);
  2506. if (result)
  2507. netdev_err(vif->ndev, "Failed to send message: disconnect\n");
  2508. else
  2509. wait_for_completion(&hif_drv->comp_test_disconn_block);
  2510. return result;
  2511. }
  2512. static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
  2513. u8 *pu8AssocRespInfo,
  2514. u32 u32MaxAssocRespInfoLen,
  2515. u32 *pu32RcvdAssocRespInfoLen)
  2516. {
  2517. s32 result = 0;
  2518. struct wid wid;
  2519. wid.id = (u16)WID_ASSOC_RES_INFO;
  2520. wid.type = WID_STR;
  2521. wid.val = pu8AssocRespInfo;
  2522. wid.size = u32MaxAssocRespInfoLen;
  2523. result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
  2524. wilc_get_vif_idx(vif));
  2525. if (result) {
  2526. *pu32RcvdAssocRespInfoLen = 0;
  2527. netdev_err(vif->ndev, "Failed to send association response\n");
  2528. return -EINVAL;
  2529. }
  2530. *pu32RcvdAssocRespInfoLen = wid.size;
  2531. return result;
  2532. }
  2533. int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
  2534. {
  2535. int result;
  2536. struct host_if_msg msg;
  2537. memset(&msg, 0, sizeof(struct host_if_msg));
  2538. msg.id = HOST_IF_MSG_SET_CHANNEL;
  2539. msg.body.channel_info.set_ch = channel;
  2540. msg.vif = vif;
  2541. result = wilc_enqueue_cmd(&msg);
  2542. if (result) {
  2543. netdev_err(vif->ndev, "wilc mq send fail\n");
  2544. return -EINVAL;
  2545. }
  2546. return 0;
  2547. }
  2548. int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
  2549. {
  2550. int result = 0;
  2551. struct host_if_msg msg;
  2552. memset(&msg, 0, sizeof(struct host_if_msg));
  2553. msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
  2554. msg.body.drv.handler = index;
  2555. msg.body.drv.mac_idx = mac_idx;
  2556. msg.vif = vif;
  2557. result = wilc_enqueue_cmd(&msg);
  2558. if (result) {
  2559. netdev_err(vif->ndev, "wilc mq send fail\n");
  2560. result = -EINVAL;
  2561. }
  2562. return result;
  2563. }
  2564. int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
  2565. {
  2566. int result = 0;
  2567. struct host_if_msg msg;
  2568. memset(&msg, 0, sizeof(struct host_if_msg));
  2569. msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
  2570. msg.body.mode.mode = mode;
  2571. msg.vif = vif;
  2572. result = wilc_enqueue_cmd(&msg);
  2573. if (result) {
  2574. netdev_err(vif->ndev, "wilc mq send fail\n");
  2575. result = -EINVAL;
  2576. }
  2577. return result;
  2578. }
  2579. s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
  2580. u32 *pu32InactiveTime)
  2581. {
  2582. s32 result = 0;
  2583. struct host_if_msg msg;
  2584. struct host_if_drv *hif_drv = vif->hif_drv;
  2585. if (!hif_drv) {
  2586. netdev_err(vif->ndev, "driver is null\n");
  2587. return -EFAULT;
  2588. }
  2589. memset(&msg, 0, sizeof(struct host_if_msg));
  2590. memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
  2591. msg.id = HOST_IF_MSG_GET_INACTIVETIME;
  2592. msg.vif = vif;
  2593. result = wilc_enqueue_cmd(&msg);
  2594. if (result)
  2595. netdev_err(vif->ndev, "Failed to send get host ch param\n");
  2596. else
  2597. wait_for_completion(&hif_drv->comp_inactive_time);
  2598. *pu32InactiveTime = inactive_time;
  2599. return result;
  2600. }
  2601. int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
  2602. {
  2603. int result = 0;
  2604. struct host_if_msg msg;
  2605. struct host_if_drv *hif_drv = vif->hif_drv;
  2606. memset(&msg, 0, sizeof(struct host_if_msg));
  2607. msg.id = HOST_IF_MSG_GET_RSSI;
  2608. msg.vif = vif;
  2609. result = wilc_enqueue_cmd(&msg);
  2610. if (result) {
  2611. netdev_err(vif->ndev, "Failed to send get host ch param\n");
  2612. return -EFAULT;
  2613. }
  2614. wait_for_completion(&hif_drv->comp_get_rssi);
  2615. if (!rssi_level) {
  2616. netdev_err(vif->ndev, "RSS pointer value is null\n");
  2617. return -EFAULT;
  2618. }
  2619. *rssi_level = rssi;
  2620. return result;
  2621. }
  2622. int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
  2623. {
  2624. int result = 0;
  2625. struct host_if_msg msg;
  2626. memset(&msg, 0, sizeof(struct host_if_msg));
  2627. msg.id = HOST_IF_MSG_GET_STATISTICS;
  2628. msg.body.data = (char *)stats;
  2629. msg.vif = vif;
  2630. result = wilc_enqueue_cmd(&msg);
  2631. if (result) {
  2632. netdev_err(vif->ndev, "Failed to send get host channel\n");
  2633. return -EFAULT;
  2634. }
  2635. if (stats != &vif->wilc->dummy_statistics)
  2636. wait_for_completion(&hif_wait_response);
  2637. return result;
  2638. }
  2639. int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
  2640. u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
  2641. size_t ies_len, wilc_scan_result scan_result, void *user_arg,
  2642. struct hidden_network *hidden_network)
  2643. {
  2644. int result = 0;
  2645. struct host_if_msg msg;
  2646. struct scan_attr *scan_info = &msg.body.scan_info;
  2647. struct host_if_drv *hif_drv = vif->hif_drv;
  2648. if (!hif_drv || !scan_result) {
  2649. netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
  2650. return -EFAULT;
  2651. }
  2652. memset(&msg, 0, sizeof(struct host_if_msg));
  2653. msg.id = HOST_IF_MSG_SCAN;
  2654. if (hidden_network) {
  2655. scan_info->hidden_network.net_info = hidden_network->net_info;
  2656. scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
  2657. }
  2658. msg.vif = vif;
  2659. scan_info->src = scan_source;
  2660. scan_info->type = scan_type;
  2661. scan_info->result = scan_result;
  2662. scan_info->arg = user_arg;
  2663. scan_info->ch_list_len = ch_list_len;
  2664. scan_info->ch_freq_list = kmemdup(ch_freq_list,
  2665. ch_list_len,
  2666. GFP_KERNEL);
  2667. if (!scan_info->ch_freq_list)
  2668. return -ENOMEM;
  2669. scan_info->ies_len = ies_len;
  2670. scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
  2671. if (!scan_info->ies)
  2672. return -ENOMEM;
  2673. result = wilc_enqueue_cmd(&msg);
  2674. if (result) {
  2675. netdev_err(vif->ndev, "Error in sending message queue\n");
  2676. return -EINVAL;
  2677. }
  2678. hif_drv->scan_timer.data = (unsigned long)vif;
  2679. mod_timer(&hif_drv->scan_timer,
  2680. jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
  2681. return result;
  2682. }
  2683. int wilc_hif_set_cfg(struct wilc_vif *vif,
  2684. struct cfg_param_attr *cfg_param)
  2685. {
  2686. int result = 0;
  2687. struct host_if_msg msg;
  2688. struct host_if_drv *hif_drv = vif->hif_drv;
  2689. if (!hif_drv) {
  2690. netdev_err(vif->ndev, "hif_drv NULL\n");
  2691. return -EFAULT;
  2692. }
  2693. memset(&msg, 0, sizeof(struct host_if_msg));
  2694. msg.id = HOST_IF_MSG_CFG_PARAMS;
  2695. msg.body.cfg_info = *cfg_param;
  2696. msg.vif = vif;
  2697. result = wilc_enqueue_cmd(&msg);
  2698. return result;
  2699. }
  2700. static void GetPeriodicRSSI(unsigned long arg)
  2701. {
  2702. struct wilc_vif *vif = (struct wilc_vif *)arg;
  2703. if (!vif->hif_drv) {
  2704. netdev_err(vif->ndev, "Driver handler is NULL\n");
  2705. return;
  2706. }
  2707. if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
  2708. wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
  2709. periodic_rssi.data = (unsigned long)vif;
  2710. mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
  2711. }
  2712. int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
  2713. {
  2714. int result = 0;
  2715. struct host_if_drv *hif_drv;
  2716. struct wilc_vif *vif;
  2717. struct wilc *wilc;
  2718. int i;
  2719. vif = netdev_priv(dev);
  2720. wilc = vif->wilc;
  2721. scan_while_connected = false;
  2722. init_completion(&hif_wait_response);
  2723. hif_drv = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
  2724. if (!hif_drv) {
  2725. result = -ENOMEM;
  2726. goto _fail_;
  2727. }
  2728. *hif_drv_handler = hif_drv;
  2729. for (i = 0; i < wilc->vif_num; i++)
  2730. if (dev == wilc->vif[i]->ndev) {
  2731. wilc->vif[i]->hif_drv = hif_drv;
  2732. break;
  2733. }
  2734. wilc_optaining_ip = false;
  2735. if (clients_count == 0) {
  2736. init_completion(&hif_thread_comp);
  2737. init_completion(&hif_driver_comp);
  2738. mutex_init(&hif_deinit_lock);
  2739. }
  2740. init_completion(&hif_drv->comp_test_key_block);
  2741. init_completion(&hif_drv->comp_test_disconn_block);
  2742. init_completion(&hif_drv->comp_get_rssi);
  2743. init_completion(&hif_drv->comp_inactive_time);
  2744. if (clients_count == 0) {
  2745. if (result < 0) {
  2746. netdev_err(vif->ndev, "Failed to creat MQ\n");
  2747. goto _fail_;
  2748. }
  2749. hif_workqueue = create_singlethread_workqueue("WILC_wq");
  2750. if (!hif_workqueue) {
  2751. netdev_err(vif->ndev, "Failed to create workqueue\n");
  2752. result = -ENOMEM;
  2753. goto _fail_mq_;
  2754. }
  2755. setup_timer(&periodic_rssi, GetPeriodicRSSI,
  2756. (unsigned long)vif);
  2757. mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
  2758. }
  2759. setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0);
  2760. setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0);
  2761. setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0);
  2762. mutex_init(&hif_drv->cfg_values_lock);
  2763. mutex_lock(&hif_drv->cfg_values_lock);
  2764. hif_drv->hif_state = HOST_IF_IDLE;
  2765. hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
  2766. hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
  2767. hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
  2768. hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
  2769. hif_drv->cfg_values.curr_tx_rate = AUTORATE;
  2770. hif_drv->p2p_timeout = 0;
  2771. mutex_unlock(&hif_drv->cfg_values_lock);
  2772. clients_count++;
  2773. _fail_mq_:
  2774. destroy_workqueue(hif_workqueue);
  2775. _fail_:
  2776. return result;
  2777. }
  2778. int wilc_deinit(struct wilc_vif *vif)
  2779. {
  2780. int result = 0;
  2781. struct host_if_msg msg;
  2782. struct host_if_drv *hif_drv = vif->hif_drv;
  2783. if (!hif_drv) {
  2784. netdev_err(vif->ndev, "hif_drv = NULL\n");
  2785. return -EFAULT;
  2786. }
  2787. mutex_lock(&hif_deinit_lock);
  2788. terminated_handle = hif_drv;
  2789. del_timer_sync(&hif_drv->scan_timer);
  2790. del_timer_sync(&hif_drv->connect_timer);
  2791. del_timer_sync(&periodic_rssi);
  2792. del_timer_sync(&hif_drv->remain_on_ch_timer);
  2793. wilc_set_wfi_drv_handler(vif, 0, 0);
  2794. wait_for_completion(&hif_driver_comp);
  2795. if (hif_drv->usr_scan_req.scan_result) {
  2796. hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
  2797. hif_drv->usr_scan_req.arg, NULL);
  2798. hif_drv->usr_scan_req.scan_result = NULL;
  2799. }
  2800. hif_drv->hif_state = HOST_IF_IDLE;
  2801. scan_while_connected = false;
  2802. memset(&msg, 0, sizeof(struct host_if_msg));
  2803. if (clients_count == 1) {
  2804. msg.id = HOST_IF_MSG_EXIT;
  2805. msg.vif = vif;
  2806. result = wilc_enqueue_cmd(&msg);
  2807. if (result != 0)
  2808. netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
  2809. else
  2810. wait_for_completion(&hif_thread_comp);
  2811. destroy_workqueue(hif_workqueue);
  2812. }
  2813. kfree(hif_drv);
  2814. clients_count--;
  2815. terminated_handle = NULL;
  2816. mutex_unlock(&hif_deinit_lock);
  2817. return result;
  2818. }
  2819. void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer,
  2820. u32 u32Length)
  2821. {
  2822. s32 result = 0;
  2823. struct host_if_msg msg;
  2824. int id;
  2825. struct host_if_drv *hif_drv = NULL;
  2826. struct wilc_vif *vif;
  2827. id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
  2828. vif = wilc_get_vif_from_idx(wilc, id);
  2829. if (!vif)
  2830. return;
  2831. hif_drv = vif->hif_drv;
  2832. if (!hif_drv || hif_drv == terminated_handle) {
  2833. netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
  2834. return;
  2835. }
  2836. memset(&msg, 0, sizeof(struct host_if_msg));
  2837. msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
  2838. msg.vif = vif;
  2839. msg.body.net_info.len = u32Length;
  2840. msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
  2841. memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
  2842. result = wilc_enqueue_cmd(&msg);
  2843. if (result)
  2844. netdev_err(vif->ndev, "message parameters (%d)\n", result);
  2845. }
  2846. void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer,
  2847. u32 u32Length)
  2848. {
  2849. s32 result = 0;
  2850. struct host_if_msg msg;
  2851. int id;
  2852. struct host_if_drv *hif_drv = NULL;
  2853. struct wilc_vif *vif;
  2854. mutex_lock(&hif_deinit_lock);
  2855. id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
  2856. vif = wilc_get_vif_from_idx(wilc, id);
  2857. if (!vif) {
  2858. mutex_unlock(&hif_deinit_lock);
  2859. return;
  2860. }
  2861. hif_drv = vif->hif_drv;
  2862. if (!hif_drv || hif_drv == terminated_handle) {
  2863. mutex_unlock(&hif_deinit_lock);
  2864. return;
  2865. }
  2866. if (!hif_drv->usr_conn_req.conn_result) {
  2867. netdev_err(vif->ndev, "there is no current Connect Request\n");
  2868. mutex_unlock(&hif_deinit_lock);
  2869. return;
  2870. }
  2871. memset(&msg, 0, sizeof(struct host_if_msg));
  2872. msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
  2873. msg.vif = vif;
  2874. msg.body.async_info.len = u32Length;
  2875. msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
  2876. memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
  2877. result = wilc_enqueue_cmd(&msg);
  2878. if (result)
  2879. netdev_err(vif->ndev, "synchronous info (%d)\n", result);
  2880. mutex_unlock(&hif_deinit_lock);
  2881. }
  2882. void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer,
  2883. u32 u32Length)
  2884. {
  2885. s32 result = 0;
  2886. struct host_if_msg msg;
  2887. int id;
  2888. struct host_if_drv *hif_drv = NULL;
  2889. struct wilc_vif *vif;
  2890. id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
  2891. vif = wilc_get_vif_from_idx(wilc, id);
  2892. if (!vif)
  2893. return;
  2894. hif_drv = vif->hif_drv;
  2895. if (!hif_drv || hif_drv == terminated_handle)
  2896. return;
  2897. if (hif_drv->usr_scan_req.scan_result) {
  2898. memset(&msg, 0, sizeof(struct host_if_msg));
  2899. msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
  2900. msg.vif = vif;
  2901. result = wilc_enqueue_cmd(&msg);
  2902. if (result)
  2903. netdev_err(vif->ndev, "complete param (%d)\n", result);
  2904. }
  2905. }
  2906. int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
  2907. u32 duration, u16 chan,
  2908. wilc_remain_on_chan_expired expired,
  2909. wilc_remain_on_chan_ready ready,
  2910. void *user_arg)
  2911. {
  2912. int result = 0;
  2913. struct host_if_msg msg;
  2914. memset(&msg, 0, sizeof(struct host_if_msg));
  2915. msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
  2916. msg.body.remain_on_ch.ch = chan;
  2917. msg.body.remain_on_ch.expired = expired;
  2918. msg.body.remain_on_ch.ready = ready;
  2919. msg.body.remain_on_ch.arg = user_arg;
  2920. msg.body.remain_on_ch.duration = duration;
  2921. msg.body.remain_on_ch.id = session_id;
  2922. msg.vif = vif;
  2923. result = wilc_enqueue_cmd(&msg);
  2924. if (result)
  2925. netdev_err(vif->ndev, "wilc mq send fail\n");
  2926. return result;
  2927. }
  2928. int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
  2929. {
  2930. int result = 0;
  2931. struct host_if_msg msg;
  2932. struct host_if_drv *hif_drv = vif->hif_drv;
  2933. if (!hif_drv) {
  2934. netdev_err(vif->ndev, "driver is null\n");
  2935. return -EFAULT;
  2936. }
  2937. del_timer(&hif_drv->remain_on_ch_timer);
  2938. memset(&msg, 0, sizeof(struct host_if_msg));
  2939. msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
  2940. msg.vif = vif;
  2941. msg.body.remain_on_ch.id = session_id;
  2942. result = wilc_enqueue_cmd(&msg);
  2943. if (result)
  2944. netdev_err(vif->ndev, "wilc mq send fail\n");
  2945. return result;
  2946. }
  2947. int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
  2948. {
  2949. int result = 0;
  2950. struct host_if_msg msg;
  2951. memset(&msg, 0, sizeof(struct host_if_msg));
  2952. msg.id = HOST_IF_MSG_REGISTER_FRAME;
  2953. switch (frame_type) {
  2954. case ACTION:
  2955. msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
  2956. break;
  2957. case PROBE_REQ:
  2958. msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
  2959. break;
  2960. default:
  2961. break;
  2962. }
  2963. msg.body.reg_frame.frame_type = frame_type;
  2964. msg.body.reg_frame.reg = reg;
  2965. msg.vif = vif;
  2966. result = wilc_enqueue_cmd(&msg);
  2967. if (result)
  2968. netdev_err(vif->ndev, "wilc mq send fail\n");
  2969. return result;
  2970. }
  2971. int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
  2972. u32 head_len, u8 *head, u32 tail_len, u8 *tail)
  2973. {
  2974. int result = 0;
  2975. struct host_if_msg msg;
  2976. struct beacon_attr *beacon_info = &msg.body.beacon_info;
  2977. memset(&msg, 0, sizeof(struct host_if_msg));
  2978. msg.id = HOST_IF_MSG_ADD_BEACON;
  2979. msg.vif = vif;
  2980. beacon_info->interval = interval;
  2981. beacon_info->dtim_period = dtim_period;
  2982. beacon_info->head_len = head_len;
  2983. beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
  2984. if (!beacon_info->head) {
  2985. result = -ENOMEM;
  2986. goto ERRORHANDLER;
  2987. }
  2988. beacon_info->tail_len = tail_len;
  2989. if (tail_len > 0) {
  2990. beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
  2991. if (!beacon_info->tail) {
  2992. result = -ENOMEM;
  2993. goto ERRORHANDLER;
  2994. }
  2995. } else {
  2996. beacon_info->tail = NULL;
  2997. }
  2998. result = wilc_enqueue_cmd(&msg);
  2999. if (result)
  3000. netdev_err(vif->ndev, "wilc mq send fail\n");
  3001. ERRORHANDLER:
  3002. if (result) {
  3003. kfree(beacon_info->head);
  3004. kfree(beacon_info->tail);
  3005. }
  3006. return result;
  3007. }
  3008. int wilc_del_beacon(struct wilc_vif *vif)
  3009. {
  3010. int result = 0;
  3011. struct host_if_msg msg;
  3012. msg.id = HOST_IF_MSG_DEL_BEACON;
  3013. msg.vif = vif;
  3014. result = wilc_enqueue_cmd(&msg);
  3015. if (result)
  3016. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3017. return result;
  3018. }
  3019. int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
  3020. {
  3021. int result = 0;
  3022. struct host_if_msg msg;
  3023. struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
  3024. memset(&msg, 0, sizeof(struct host_if_msg));
  3025. msg.id = HOST_IF_MSG_ADD_STATION;
  3026. msg.vif = vif;
  3027. memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
  3028. if (add_sta_info->rates_len > 0) {
  3029. add_sta_info->rates = kmemdup(sta_param->rates,
  3030. add_sta_info->rates_len,
  3031. GFP_KERNEL);
  3032. if (!add_sta_info->rates)
  3033. return -ENOMEM;
  3034. }
  3035. result = wilc_enqueue_cmd(&msg);
  3036. if (result)
  3037. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3038. return result;
  3039. }
  3040. int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
  3041. {
  3042. int result = 0;
  3043. struct host_if_msg msg;
  3044. struct del_sta *del_sta_info = &msg.body.del_sta_info;
  3045. memset(&msg, 0, sizeof(struct host_if_msg));
  3046. msg.id = HOST_IF_MSG_DEL_STATION;
  3047. msg.vif = vif;
  3048. if (!mac_addr)
  3049. eth_broadcast_addr(del_sta_info->mac_addr);
  3050. else
  3051. memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
  3052. result = wilc_enqueue_cmd(&msg);
  3053. if (result)
  3054. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3055. return result;
  3056. }
  3057. int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
  3058. {
  3059. int result = 0;
  3060. struct host_if_msg msg;
  3061. struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
  3062. u8 zero_addr[ETH_ALEN] = {0};
  3063. int i;
  3064. u8 assoc_sta = 0;
  3065. memset(&msg, 0, sizeof(struct host_if_msg));
  3066. msg.id = HOST_IF_MSG_DEL_ALL_STA;
  3067. msg.vif = vif;
  3068. for (i = 0; i < MAX_NUM_STA; i++) {
  3069. if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
  3070. memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i], ETH_ALEN);
  3071. assoc_sta++;
  3072. }
  3073. }
  3074. if (!assoc_sta)
  3075. return result;
  3076. del_all_sta_info->assoc_sta = assoc_sta;
  3077. result = wilc_enqueue_cmd(&msg);
  3078. if (result)
  3079. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3080. else
  3081. wait_for_completion(&hif_wait_response);
  3082. return result;
  3083. }
  3084. int wilc_edit_station(struct wilc_vif *vif,
  3085. struct add_sta_param *sta_param)
  3086. {
  3087. int result = 0;
  3088. struct host_if_msg msg;
  3089. struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
  3090. memset(&msg, 0, sizeof(struct host_if_msg));
  3091. msg.id = HOST_IF_MSG_EDIT_STATION;
  3092. msg.vif = vif;
  3093. memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
  3094. if (add_sta_info->rates_len > 0) {
  3095. add_sta_info->rates = kmemdup(sta_param->rates,
  3096. add_sta_info->rates_len,
  3097. GFP_KERNEL);
  3098. if (!add_sta_info->rates)
  3099. return -ENOMEM;
  3100. }
  3101. result = wilc_enqueue_cmd(&msg);
  3102. if (result)
  3103. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3104. return result;
  3105. }
  3106. int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
  3107. {
  3108. int result = 0;
  3109. struct host_if_msg msg;
  3110. struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
  3111. if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
  3112. return 0;
  3113. memset(&msg, 0, sizeof(struct host_if_msg));
  3114. msg.id = HOST_IF_MSG_POWER_MGMT;
  3115. msg.vif = vif;
  3116. pwr_mgmt_info->enabled = enabled;
  3117. pwr_mgmt_info->timeout = timeout;
  3118. result = wilc_enqueue_cmd(&msg);
  3119. if (result)
  3120. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3121. return result;
  3122. }
  3123. int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
  3124. u32 count)
  3125. {
  3126. int result = 0;
  3127. struct host_if_msg msg;
  3128. struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
  3129. memset(&msg, 0, sizeof(struct host_if_msg));
  3130. msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
  3131. msg.vif = vif;
  3132. multicast_filter_param->enabled = enabled;
  3133. multicast_filter_param->cnt = count;
  3134. result = wilc_enqueue_cmd(&msg);
  3135. if (result)
  3136. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3137. return result;
  3138. }
  3139. static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
  3140. {
  3141. struct join_bss_param *pNewJoinBssParam = NULL;
  3142. u8 *pu8IEs;
  3143. u16 u16IEsLen;
  3144. u16 index = 0;
  3145. u8 suppRatesNo = 0;
  3146. u8 extSuppRatesNo;
  3147. u16 jumpOffset;
  3148. u8 pcipherCount;
  3149. u8 authCount;
  3150. u8 pcipherTotalCount = 0;
  3151. u8 authTotalCount = 0;
  3152. u8 i, j;
  3153. pu8IEs = ptstrNetworkInfo->ies;
  3154. u16IEsLen = ptstrNetworkInfo->ies_len;
  3155. pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
  3156. if (pNewJoinBssParam) {
  3157. pNewJoinBssParam->dtim_period = ptstrNetworkInfo->dtim_period;
  3158. pNewJoinBssParam->beacon_period = ptstrNetworkInfo->beacon_period;
  3159. pNewJoinBssParam->cap_info = ptstrNetworkInfo->cap_info;
  3160. memcpy(pNewJoinBssParam->bssid, ptstrNetworkInfo->bssid, 6);
  3161. memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->ssid,
  3162. ptstrNetworkInfo->ssid_len + 1);
  3163. pNewJoinBssParam->ssid_len = ptstrNetworkInfo->ssid_len;
  3164. memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
  3165. memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
  3166. while (index < u16IEsLen) {
  3167. if (pu8IEs[index] == SUPP_RATES_IE) {
  3168. suppRatesNo = pu8IEs[index + 1];
  3169. pNewJoinBssParam->supp_rates[0] = suppRatesNo;
  3170. index += 2;
  3171. for (i = 0; i < suppRatesNo; i++)
  3172. pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
  3173. index += suppRatesNo;
  3174. continue;
  3175. } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
  3176. extSuppRatesNo = pu8IEs[index + 1];
  3177. if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
  3178. pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
  3179. else
  3180. pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
  3181. index += 2;
  3182. for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
  3183. pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
  3184. index += extSuppRatesNo;
  3185. continue;
  3186. } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
  3187. pNewJoinBssParam->ht_capable = true;
  3188. index += pu8IEs[index + 1] + 2;
  3189. continue;
  3190. } else if ((pu8IEs[index] == WMM_IE) &&
  3191. (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
  3192. (pu8IEs[index + 4] == 0xF2) &&
  3193. (pu8IEs[index + 5] == 0x02) &&
  3194. ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
  3195. (pu8IEs[index + 7] == 0x01)) {
  3196. pNewJoinBssParam->wmm_cap = true;
  3197. if (pu8IEs[index + 8] & BIT(7))
  3198. pNewJoinBssParam->uapsd_cap = true;
  3199. index += pu8IEs[index + 1] + 2;
  3200. continue;
  3201. } else if ((pu8IEs[index] == P2P_IE) &&
  3202. (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
  3203. (pu8IEs[index + 4] == 0x9a) &&
  3204. (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
  3205. u16 u16P2P_count;
  3206. pNewJoinBssParam->tsf = ptstrNetworkInfo->tsf_lo;
  3207. pNewJoinBssParam->noa_enabled = 1;
  3208. pNewJoinBssParam->idx = pu8IEs[index + 9];
  3209. if (pu8IEs[index + 10] & BIT(7)) {
  3210. pNewJoinBssParam->opp_enabled = 1;
  3211. pNewJoinBssParam->ct_window = pu8IEs[index + 10];
  3212. } else {
  3213. pNewJoinBssParam->opp_enabled = 0;
  3214. }
  3215. pNewJoinBssParam->cnt = pu8IEs[index + 11];
  3216. u16P2P_count = index + 12;
  3217. memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
  3218. u16P2P_count += 4;
  3219. memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
  3220. u16P2P_count += 4;
  3221. memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
  3222. index += pu8IEs[index + 1] + 2;
  3223. continue;
  3224. } else if ((pu8IEs[index] == RSN_IE) ||
  3225. ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
  3226. (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
  3227. (pu8IEs[index + 5] == 0x01))) {
  3228. u16 rsnIndex = index;
  3229. if (pu8IEs[rsnIndex] == RSN_IE) {
  3230. pNewJoinBssParam->mode_802_11i = 2;
  3231. } else {
  3232. if (pNewJoinBssParam->mode_802_11i == 0)
  3233. pNewJoinBssParam->mode_802_11i = 1;
  3234. rsnIndex += 4;
  3235. }
  3236. rsnIndex += 7;
  3237. pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
  3238. rsnIndex++;
  3239. jumpOffset = pu8IEs[rsnIndex] * 4;
  3240. pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
  3241. rsnIndex += 2;
  3242. for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
  3243. pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
  3244. pcipherTotalCount += pcipherCount;
  3245. rsnIndex += jumpOffset;
  3246. jumpOffset = pu8IEs[rsnIndex] * 4;
  3247. authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
  3248. rsnIndex += 2;
  3249. for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
  3250. pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
  3251. authTotalCount += authCount;
  3252. rsnIndex += jumpOffset;
  3253. if (pu8IEs[index] == RSN_IE) {
  3254. pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
  3255. pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
  3256. rsnIndex += 2;
  3257. }
  3258. pNewJoinBssParam->rsn_found = true;
  3259. index += pu8IEs[index + 1] + 2;
  3260. continue;
  3261. } else
  3262. index += pu8IEs[index + 1] + 2;
  3263. }
  3264. }
  3265. return (void *)pNewJoinBssParam;
  3266. }
  3267. int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
  3268. {
  3269. int result = 0;
  3270. struct host_if_msg msg;
  3271. memset(&msg, 0, sizeof(struct host_if_msg));
  3272. msg.id = HOST_IF_MSG_SET_IPADDRESS;
  3273. msg.body.ip_info.ip_addr = ip_addr;
  3274. msg.vif = vif;
  3275. msg.body.ip_info.idx = idx;
  3276. result = wilc_enqueue_cmd(&msg);
  3277. if (result)
  3278. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3279. return result;
  3280. }
  3281. static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
  3282. {
  3283. int result = 0;
  3284. struct host_if_msg msg;
  3285. memset(&msg, 0, sizeof(struct host_if_msg));
  3286. msg.id = HOST_IF_MSG_GET_IPADDRESS;
  3287. msg.body.ip_info.ip_addr = ip_addr;
  3288. msg.vif = vif;
  3289. msg.body.ip_info.idx = idx;
  3290. result = wilc_enqueue_cmd(&msg);
  3291. if (result)
  3292. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3293. return result;
  3294. }
  3295. int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
  3296. {
  3297. int ret = 0;
  3298. struct host_if_msg msg;
  3299. memset(&msg, 0, sizeof(struct host_if_msg));
  3300. msg.id = HOST_IF_MSG_SET_TX_POWER;
  3301. msg.body.tx_power.tx_pwr = tx_power;
  3302. msg.vif = vif;
  3303. ret = wilc_enqueue_cmd(&msg);
  3304. if (ret)
  3305. netdev_err(vif->ndev, "wilc_mq_send fail\n");
  3306. return ret;
  3307. }
  3308. int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
  3309. {
  3310. int ret = 0;
  3311. struct host_if_msg msg;
  3312. memset(&msg, 0, sizeof(struct host_if_msg));
  3313. msg.id = HOST_IF_MSG_GET_TX_POWER;
  3314. msg.vif = vif;
  3315. ret = wilc_enqueue_cmd(&msg);
  3316. if (ret)
  3317. netdev_err(vif->ndev, "Failed to get TX PWR\n");
  3318. wait_for_completion(&hif_wait_response);
  3319. *tx_power = msg.body.tx_power.tx_pwr;
  3320. return ret;
  3321. }