blob: 78f5613e9467cf5579a57f6d13137af9f5e1d5b9 [file] [log] [blame]
Chaehyun Lime215a872015-09-30 08:15:41 +09001#include <linux/slab.h>
2#include <linux/time.h>
3#include <linux/kthread.h>
4#include <linux/delay.h>
Alison Schofielde0c14962016-03-14 10:34:14 -07005#include <linux/completion.h>
Binoy Jayanc6bb38a2016-06-23 11:11:50 +05306#include <linux/list.h>
Binoy Jayan2518ac52016-06-23 11:11:51 +05307#include <linux/workqueue.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +09008#include "host_interface.h"
Binoy Jayanc6bb38a2016-06-23 11:11:50 +05309#include <linux/spinlock.h>
10#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +090011#include "coreconfigurator.h"
Arnd Bergmann491880e2015-11-16 15:04:55 +010012#include "wilc_wlan.h"
Chaehyun Lim53660122015-09-17 16:48:49 +090013#include "wilc_wlan_if.h"
Shraddha Barke281dd5a2015-10-05 17:00:33 +053014#include <linux/etherdevice.h>
Glen Leed53822192015-10-27 18:27:49 +090015#include "wilc_wfi_netdevice.h"
Johnny Kimc5c77ba2015-05-11 14:30:56 +090016
Chaehyun Lim9eac3a12015-06-18 22:08:51 +090017#define HOST_IF_MSG_SCAN 0
18#define HOST_IF_MSG_CONNECT 1
19#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO 2
20#define HOST_IF_MSG_KEY 3
21#define HOST_IF_MSG_RCVD_NTWRK_INFO 4
22#define HOST_IF_MSG_RCVD_SCAN_COMPLETE 5
23#define HOST_IF_MSG_CFG_PARAMS 6
24#define HOST_IF_MSG_SET_CHANNEL 7
25#define HOST_IF_MSG_DISCONNECT 8
26#define HOST_IF_MSG_GET_RSSI 9
Chaehyun Lim9eac3a12015-06-18 22:08:51 +090027#define HOST_IF_MSG_ADD_BEACON 11
28#define HOST_IF_MSG_DEL_BEACON 12
29#define HOST_IF_MSG_ADD_STATION 13
30#define HOST_IF_MSG_DEL_STATION 14
31#define HOST_IF_MSG_EDIT_STATION 15
32#define HOST_IF_MSG_SCAN_TIMER_FIRED 16
33#define HOST_IF_MSG_CONNECT_TIMER_FIRED 17
34#define HOST_IF_MSG_POWER_MGMT 18
35#define HOST_IF_MSG_GET_INACTIVETIME 19
36#define HOST_IF_MSG_REMAIN_ON_CHAN 20
37#define HOST_IF_MSG_REGISTER_FRAME 21
38#define HOST_IF_MSG_LISTEN_TIMER_FIRED 22
Chaehyun Lim9eac3a12015-06-18 22:08:51 +090039#define HOST_IF_MSG_SET_WFIDRV_HANDLER 24
Chaehyun Lim9eac3a12015-06-18 22:08:51 +090040#define HOST_IF_MSG_GET_MAC_ADDRESS 26
41#define HOST_IF_MSG_SET_OPERATION_MODE 27
42#define HOST_IF_MSG_SET_IPADDRESS 28
43#define HOST_IF_MSG_GET_IPADDRESS 29
Chaehyun Lim9eac3a12015-06-18 22:08:51 +090044#define HOST_IF_MSG_GET_STATISTICS 31
45#define HOST_IF_MSG_SET_MULTICAST_FILTER 32
Chaehyun Lim9eac3a12015-06-18 22:08:51 +090046#define HOST_IF_MSG_DEL_BA_SESSION 34
Chaehyun Lim9eac3a12015-06-18 22:08:51 +090047#define HOST_IF_MSG_DEL_ALL_STA 36
Glen Lee70418792016-02-04 18:15:27 +090048#define HOST_IF_MSG_SET_TX_POWER 38
49#define HOST_IF_MSG_GET_TX_POWER 39
Chaehyun Lim9eac3a12015-06-18 22:08:51 +090050#define HOST_IF_MSG_EXIT 100
Johnny Kimc5c77ba2015-05-11 14:30:56 +090051
Chaehyun Lime54d5b72015-06-18 22:08:50 +090052#define HOST_IF_SCAN_TIMEOUT 4000
53#define HOST_IF_CONNECT_TIMEOUT 9500
Johnny Kimc5c77ba2015-05-11 14:30:56 +090054
Chaehyun Lime54d5b72015-06-18 22:08:50 +090055#define BA_SESSION_DEFAULT_BUFFER_SIZE 16
56#define BA_SESSION_DEFAULT_TIMEOUT 1000
57#define BLOCK_ACK_REQ_SIZE 0x14
Leo Kim9f3295a2015-10-19 18:26:10 +090058#define FALSE_FRMWR_CHANNEL 100
Johnny Kimc5c77ba2015-05-11 14:30:56 +090059
Glen Lee4fd62292016-02-04 18:15:24 +090060#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
61#define DEFAULT_LINK_SPEED 72
62
Leo Kim4372d3d2015-10-05 15:25:43 +090063struct host_if_wpa_attr {
Leo Kim124968fc2015-10-13 19:49:30 +090064 u8 *key;
Leo Kim248080a2015-10-13 19:49:31 +090065 const u8 *mac_addr;
Leo Kim0e74c002015-10-13 19:49:32 +090066 u8 *seq;
Leo Kimdacc5942015-10-13 19:49:33 +090067 u8 seq_len;
Leo Kime2dfbac2015-10-13 19:49:34 +090068 u8 index;
Leo Kim6acf2912015-10-13 19:49:35 +090069 u8 key_len;
Leo Kim7b2ebb22015-10-13 19:49:36 +090070 u8 mode;
Leo Kim4372d3d2015-10-05 15:25:43 +090071};
Johnny Kimc5c77ba2015-05-11 14:30:56 +090072
Leo Kimc276c442015-10-05 15:25:42 +090073struct host_if_wep_attr {
Tony Choe5538d32015-10-12 16:56:11 +090074 u8 *key;
Tony Chod520e352015-10-12 16:56:12 +090075 u8 key_len;
Tony Cho259b3aa2015-10-12 16:56:13 +090076 u8 index;
Tony Chob5eaff12015-10-12 16:56:14 +090077 u8 mode;
Tony Cho7fa252e2015-10-12 16:56:15 +090078 enum AUTHTYPE auth_type;
Leo Kimc276c442015-10-05 15:25:42 +090079};
Johnny Kimc5c77ba2015-05-11 14:30:56 +090080
Leo Kim40cc2c92015-10-05 15:25:41 +090081union host_if_key_attr {
Tony Cho2ed7a2f2015-10-12 16:56:08 +090082 struct host_if_wep_attr wep;
Tony Choe3501a42015-10-12 16:56:09 +090083 struct host_if_wpa_attr wpa;
Tony Cho610e3862015-10-12 16:56:10 +090084 struct host_if_pmkid_attr pmkid;
Leo Kim40cc2c92015-10-05 15:25:41 +090085};
Johnny Kimc5c77ba2015-05-11 14:30:56 +090086
Tony Choc98387a2015-09-21 12:16:40 +090087struct key_attr {
Leo Kim8e9f4272015-10-13 19:49:27 +090088 enum KEY_TYPE type;
Leo Kim0d17e382015-10-13 19:49:28 +090089 u8 action;
Leo Kim73b2e382015-10-13 19:49:29 +090090 union host_if_key_attr attr;
Tony Choc98387a2015-09-21 12:16:40 +090091};
Johnny Kimc5c77ba2015-05-11 14:30:56 +090092
Tony Choc476feb2015-09-21 12:16:36 +090093struct scan_attr {
Leo Kim42568892015-10-13 19:49:37 +090094 u8 src;
Leo Kim1e276c82015-10-13 19:49:38 +090095 u8 type;
Leo Kim82eeb0a2015-10-13 19:49:40 +090096 u8 *ch_freq_list;
Leo Kimf97bd9c2015-10-13 19:49:41 +090097 u8 ch_list_len;
Leo Kimd6f19aa2015-10-13 19:49:42 +090098 u8 *ies;
Leo Kim7b1f76c2015-10-13 19:49:43 +090099 size_t ies_len;
Leo Kimc17c6da2015-10-13 19:49:44 +0900100 wilc_scan_result result;
Leo Kim5f2b50c2015-10-13 19:49:45 +0900101 void *arg;
Leo Kim629b9ca2015-10-13 19:49:46 +0900102 struct hidden_network hidden_network;
Tony Choc476feb2015-09-21 12:16:36 +0900103};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900104
Tony Cho120ae592015-09-21 12:16:37 +0900105struct connect_attr {
Leo Kim9254db02015-10-13 19:49:49 +0900106 u8 *bssid;
Leo Kimf7bbd9c2015-10-13 19:49:50 +0900107 u8 *ssid;
Leo Kim8b3c9fa2015-10-13 19:49:51 +0900108 size_t ssid_len;
Leo Kim2ea158c2015-10-13 19:49:52 +0900109 u8 *ies;
Leo Kimb59d5c52015-10-13 19:49:53 +0900110 size_t ies_len;
Leo Kima64fd672015-10-13 19:49:54 +0900111 u8 security;
Leo Kim6abcc112015-10-13 19:49:55 +0900112 wilc_connect_result result;
Leo Kim8f38db82015-10-13 19:49:56 +0900113 void *arg;
Leo Kim61b4fd02015-10-13 19:49:57 +0900114 enum AUTHTYPE auth_type;
Leo Kim0d1527e2015-10-13 19:49:58 +0900115 u8 ch;
Leo Kimf2bed2c2015-10-13 19:49:59 +0900116 void *params;
Tony Cho120ae592015-09-21 12:16:37 +0900117};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900118
Tony Chof23a9ea2015-09-21 12:16:39 +0900119struct rcvd_async_info {
Leo Kim33722ac72015-10-13 19:50:00 +0900120 u8 *buffer;
Leo Kimf94f4882015-10-13 19:50:01 +0900121 u32 len;
Tony Chof23a9ea2015-09-21 12:16:39 +0900122};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900123
Tony Cho94bdfe42015-09-30 18:44:27 +0900124struct channel_attr {
Leo Kim730ee052015-10-13 19:50:02 +0900125 u8 set_ch;
Tony Cho326b3232015-09-21 12:16:42 +0900126};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900127
Tony Cho7f33fec2015-09-30 18:44:30 +0900128struct beacon_attr {
Leo Kim12262dd2015-10-13 19:50:03 +0900129 u32 interval;
Leo Kime76ab772015-10-13 19:50:04 +0900130 u32 dtim_period;
Leo Kim51c66182015-10-13 19:50:05 +0900131 u32 head_len;
Leo Kim8ce528b2015-10-13 19:50:06 +0900132 u8 *head;
Leo Kim030c57e2015-10-13 19:50:07 +0900133 u32 tail_len;
Leo Kim7dbcb6d32015-10-13 19:50:08 +0900134 u8 *tail;
Tony Cho902362b2015-09-21 12:16:44 +0900135};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900136
Tony Cho641210a2015-09-21 12:16:52 +0900137struct set_multicast {
Leo Kimbae636eb2015-10-13 20:02:04 +0900138 bool enabled;
Leo Kimadab2f72015-10-13 20:02:05 +0900139 u32 cnt;
Tony Cho641210a2015-09-21 12:16:52 +0900140};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900141
Tony Chob4e644e2015-09-21 12:17:00 +0900142struct del_all_sta {
Leo Kime51b9212015-10-13 19:50:09 +0900143 u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
Leo Kim8ba18032015-10-13 19:50:10 +0900144 u8 assoc_sta;
Tony Chob4e644e2015-09-21 12:17:00 +0900145};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900146
Tony Chofb93a1e2015-09-21 12:16:57 +0900147struct del_sta {
Leo Kime4839d32015-10-13 20:02:06 +0900148 u8 mac_addr[ETH_ALEN];
Tony Chofb93a1e2015-09-21 12:16:57 +0900149};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900150
Tony Cho5a008f12015-09-21 12:16:48 +0900151struct power_mgmt_param {
Leo Kim33c70c12015-10-13 20:02:07 +0900152 bool enabled;
Leo Kim937918f2015-10-13 20:02:08 +0900153 u32 timeout;
Tony Cho5a008f12015-09-21 12:16:48 +0900154};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900155
Tony Cho15191ea2015-09-21 12:16:50 +0900156struct set_ip_addr {
Leo Kim78675be2015-10-13 20:02:09 +0900157 u8 *ip_addr;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900158 u8 idx;
Tony Cho15191ea2015-09-21 12:16:50 +0900159};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900160
Tony Cho3d1eac02015-09-21 12:16:49 +0900161struct sta_inactive_t {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900162 u8 mac[6];
Tony Cho3d1eac02015-09-21 12:16:49 +0900163};
Leo Kimae4dfa52015-10-13 19:49:26 +0900164
Glen Lee70418792016-02-04 18:15:27 +0900165struct tx_power {
166 u8 tx_pwr;
167};
168
Tony Chodfc76632015-09-21 12:16:34 +0900169union message_body {
Tony Cho4528bdb2015-09-30 18:44:20 +0900170 struct scan_attr scan_info;
Tony Cho3f501972015-09-30 18:44:21 +0900171 struct connect_attr con_info;
Tony Cho02d19462015-09-30 18:44:22 +0900172 struct rcvd_net_info net_info;
Tony Cho66add622015-09-30 18:44:23 +0900173 struct rcvd_async_info async_info;
Tony Cho18990bf2015-09-30 18:44:24 +0900174 struct key_attr key_info;
Tony Choa2340c32015-09-30 18:44:25 +0900175 struct cfg_param_attr cfg_info;
Tony Choffd6dbc2015-09-30 18:44:28 +0900176 struct channel_attr channel_info;
Tony Choa98491e2015-09-30 18:44:31 +0900177 struct beacon_attr beacon_info;
Tony Choca8f47f2015-09-30 18:44:32 +0900178 struct add_sta_param add_sta_info;
Tony Cho889c25b2015-09-30 18:44:33 +0900179 struct del_sta del_sta_info;
Tony Cho4a930962015-09-30 18:44:34 +0900180 struct add_sta_param edit_sta_info;
Tony Cho49e1f812015-09-30 18:44:36 +0900181 struct power_mgmt_param pwr_mgmt_info;
Tony Cho66bac7f2015-09-30 18:44:37 +0900182 struct sta_inactive_t mac_info;
Tony Chofb2d65e2015-09-30 18:44:39 +0900183 struct set_ip_addr ip_info;
Tony Cho5e4377e2015-09-30 18:44:38 +0900184 struct drv_handler drv;
Tony Choa079cf4d2015-09-30 18:55:05 +0900185 struct set_multicast multicast_info;
Tony Cho00c46302015-09-30 18:55:06 +0900186 struct op_mode mode;
Tony Choa5848692015-09-30 18:55:08 +0900187 struct get_mac_addr get_mac_info;
Tony Choc833b472015-09-30 18:55:09 +0900188 struct ba_session_info session_info;
Tony Cho070d3652015-09-30 18:55:10 +0900189 struct remain_ch remain_on_ch;
Tony Cho5c4008d2015-10-05 13:50:44 +0900190 struct reg_frame reg_frame;
Tony Choe60831e2015-10-05 13:50:45 +0900191 char *data;
Tony Chob0c1e802015-10-05 13:50:46 +0900192 struct del_all_sta del_all_sta_info;
Glen Lee70418792016-02-04 18:15:27 +0900193 struct tx_power tx_power;
Tony Chodfc76632015-09-21 12:16:34 +0900194};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900195
Tony Cho3a8c41b2015-09-18 18:11:04 +0900196struct host_if_msg {
Leo Kimae4dfa52015-10-13 19:49:26 +0900197 u16 id;
198 union message_body body;
Glen Leecf601062015-12-21 14:18:39 +0900199 struct wilc_vif *vif;
Binoy Jayan2518ac52016-06-23 11:11:51 +0530200 struct work_struct work;
Tony Cho3a8c41b2015-09-18 18:11:04 +0900201};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900202
Leo Kime0a12212015-10-12 16:55:49 +0900203struct join_bss_param {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900204 BSSTYPE_T bss_type;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900205 u8 dtim_period;
Chaehyun Limd85f5322015-06-11 14:35:54 +0900206 u16 beacon_period;
207 u16 cap_info;
Chaehyun Limf1764292016-02-12 23:04:37 +0900208 u8 bssid[6];
Dean Lee576917a2015-06-15 11:58:57 +0900209 char ssid[MAX_SSID_LEN];
Leo Kim619d27b2015-10-15 13:24:42 +0900210 u8 ssid_len;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900211 u8 supp_rates[MAX_RATES_SUPPORTED + 1];
212 u8 ht_capable;
213 u8 wmm_cap;
214 u8 uapsd_cap;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900215 bool rsn_found;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900216 u8 rsn_grp_policy;
217 u8 mode_802_11i;
218 u8 rsn_pcip_policy[3];
219 u8 rsn_auth_policy[3];
220 u8 rsn_cap[2];
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900221 u32 tsf;
Leo Kim7a8d51d2015-10-15 13:24:43 +0900222 u8 noa_enabled;
Leo Kimd72b33c2015-10-15 13:24:44 +0900223 u8 opp_enabled;
Leo Kim99b66942015-10-15 13:24:45 +0900224 u8 ct_window;
Leo Kimc21047e2015-10-15 13:24:46 +0900225 u8 cnt;
Leo Kimcc179002015-10-15 13:24:47 +0900226 u8 idx;
Leo Kim109e6ca2015-10-15 13:24:48 +0900227 u8 duration[4];
Leo Kim1d8b76b2015-10-15 13:24:49 +0900228 u8 interval[4];
Leo Kim4be55e22015-10-28 15:59:27 +0900229 u8 start_time[4];
Leo Kime0a12212015-10-12 16:55:49 +0900230};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900231
Hugo Camboulived27afda2016-01-04 22:02:23 +0000232static struct host_if_drv *terminated_handle;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100233bool wilc_optaining_ip;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100234static u8 P2P_LISTEN_STATE;
Binoy Jayan2518ac52016-06-23 11:11:51 +0530235static struct workqueue_struct *hif_workqueue;
Chaehyun Lim04dd9a42016-03-23 21:28:33 +0900236static struct completion hif_thread_comp;
Chaehyun Lim2bb02582016-03-23 21:28:34 +0900237static struct completion hif_driver_comp;
Chaehyun Lim613eaa32016-03-14 09:40:27 +0900238static struct completion hif_wait_response;
Chaehyun Lim896802a2016-03-22 08:39:24 +0900239static struct mutex hif_deinit_lock;
kbuild test robot24aadb82015-10-15 14:32:40 +0800240static struct timer_list periodic_rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900241
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100242u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900243
Leo Kima633c0b2015-10-15 13:24:59 +0900244static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900245
kbuild test robotf64321c2015-10-15 14:46:26 +0800246static bool scan_while_connected;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900247
Leo Kim144b7b22015-10-15 13:25:01 +0900248static s8 rssi;
Leo Kim078b1e92015-10-15 13:25:04 +0900249static u8 set_ip[2][4];
Leo Kim1e75d012015-10-15 13:25:05 +0900250static u8 get_ip[2][4];
Leo Kimad269062015-10-15 13:25:06 +0900251static u32 inactive_time;
Leo Kima74c7bf2015-10-15 13:25:07 +0900252static u8 del_beacon;
Leo Kim7178aed2015-10-19 18:26:09 +0900253static u32 clients_count;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900254
kbuild test robotef599192015-10-15 15:04:15 +0800255static u8 *join_req;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100256static u8 *info_element;
kbuild test robot23047d52015-10-15 15:18:34 +0800257static u8 mode_11i;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100258static u8 auth_type;
259static u32 join_req_size;
kbuild test robot5e0e7c22015-10-15 15:47:44 +0800260static u32 info_element_size;
Glen Lee7036c622015-12-21 14:18:45 +0900261static struct wilc_vif *join_req_vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900262#define REAL_JOIN_REQ 0
263#define FLUSHED_JOIN_REQ 1
Leo Kimae4dfa52015-10-13 19:49:26 +0900264#define FLUSHED_BYTE_POS 79
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900265
Leo Kim6b5180a2016-02-04 18:24:10 +0900266static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
Chaehyun Lim4ad878b2015-12-30 21:15:44 +0900267static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
Chaehyun Lim4aa33872016-04-04 20:04:44 +0900268static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
Binoy Jayan2518ac52016-06-23 11:11:51 +0530269static void host_if_work(struct work_struct *work);
Binoy Jayanc6bb38a2016-06-23 11:11:50 +0530270
271/*!
272 * @author syounan
273 * @date 1 Sep 2010
274 * @note copied from FLO glue implementatuion
275 * @version 1.0
276 */
Binoy Jayana5c84b22016-06-23 11:11:52 +0530277static int wilc_enqueue_cmd(struct host_if_msg *msg)
Binoy Jayanc6bb38a2016-06-23 11:11:50 +0530278{
Binoy Jayan2518ac52016-06-23 11:11:51 +0530279 struct host_if_msg *new_msg;
Binoy Jayanc6bb38a2016-06-23 11:11:50 +0530280
Binoy Jayana5c84b22016-06-23 11:11:52 +0530281 new_msg = kmemdup(msg, sizeof(*new_msg), GFP_ATOMIC);
Binoy Jayanc6bb38a2016-06-23 11:11:50 +0530282 if (!new_msg)
283 return -ENOMEM;
284
Binoy Jayan2518ac52016-06-23 11:11:51 +0530285 INIT_WORK(&new_msg->work, host_if_work);
286 queue_work(hif_workqueue, &new_msg->work);
Binoy Jayanc6bb38a2016-06-23 11:11:50 +0530287 return 0;
288}
289
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900290
Glen Leeeb9939b2015-12-21 14:18:43 +0900291/* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
292 * special purpose in wilc device, so we add 1 to the index to starts from 1.
293 * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
294 */
Glen Lee31f0f692015-12-21 14:18:44 +0900295int wilc_get_vif_idx(struct wilc_vif *vif)
Johnny Kimd42ab082015-08-20 16:32:52 +0900296{
Leo Kim67501402016-02-04 18:15:39 +0900297 return vif->idx + 1;
Glen Leeeb9939b2015-12-21 14:18:43 +0900298}
299
300/* We need to minus 1 from idx which is from wilc device to get real index
301 * of wilc->vif[], because we add 1 when pass to wilc device in the function
302 * wilc_get_vif_idx.
303 * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
304 */
305static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
306{
307 int index = idx - 1;
308
309 if (index < 0 || index >= NUM_CONCURRENT_IFC)
Johnny Kimd42ab082015-08-20 16:32:52 +0900310 return NULL;
Glen Leeeb9939b2015-12-21 14:18:43 +0900311
312 return wilc->vif[index];
Johnny Kimd42ab082015-08-20 16:32:52 +0900313}
314
Chaehyun Limc43f5f92016-02-12 23:04:44 +0900315static void handle_set_channel(struct wilc_vif *vif,
316 struct channel_attr *hif_set_ch)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900317{
Chaehyun Lim5349f6d2016-02-12 23:04:46 +0900318 int ret = 0;
Leo Kim45102f82015-10-28 15:59:28 +0900319 struct wid wid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900320
Leo Kim45102f82015-10-28 15:59:28 +0900321 wid.id = (u16)WID_CURRENT_CHANNEL;
322 wid.type = WID_CHAR;
Leo Kim9cf78782015-10-29 12:05:54 +0900323 wid.val = (char *)&hif_set_ch->set_ch;
Leo Kim45102f82015-10-28 15:59:28 +0900324 wid.size = sizeof(char);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900325
Chaehyun Lim5349f6d2016-02-12 23:04:46 +0900326 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
327 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +0900328
Chaehyun Lim5349f6d2016-02-12 23:04:46 +0900329 if (ret)
Chaehyun Limecdd5c72016-02-12 23:04:47 +0900330 netdev_err(vif->ndev, "Failed to set channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900331}
Leo Kimae4dfa52015-10-13 19:49:26 +0900332
Chaehyun Lim62a0d452016-04-07 08:10:38 +0900333static void handle_set_wfi_drv_handler(struct wilc_vif *vif,
334 struct drv_handler *hif_drv_handler)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335{
Chaehyun Limfdcc2852016-04-07 08:10:40 +0900336 int ret = 0;
Leo Kim45102f82015-10-28 15:59:28 +0900337 struct wid wid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900338
Leo Kim45102f82015-10-28 15:59:28 +0900339 wid.id = (u16)WID_SET_DRV_HANDLER;
Glen Leeb3306862016-02-04 18:15:18 +0900340 wid.type = WID_STR;
341 wid.val = (s8 *)hif_drv_handler;
342 wid.size = sizeof(*hif_drv_handler);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900343
Chaehyun Limfdcc2852016-04-07 08:10:40 +0900344 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
345 hif_drv_handler->handler);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900346
Glen Lee31f0f692015-12-21 14:18:44 +0900347 if (!hif_drv_handler->handler)
Chaehyun Lim2bb02582016-03-23 21:28:34 +0900348 complete(&hif_driver_comp);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900349
Chaehyun Limfdcc2852016-04-07 08:10:40 +0900350 if (ret)
Chris Parkb92f9302016-02-22 13:12:02 +0900351 netdev_err(vif->ndev, "Failed to set driver handler\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900352}
353
Chaehyun Limb093d4f2016-04-07 08:10:41 +0900354static void handle_set_operation_mode(struct wilc_vif *vif,
355 struct op_mode *hif_op_mode)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900356{
Chaehyun Lim14f3b082016-04-07 08:10:43 +0900357 int ret = 0;
Leo Kim45102f82015-10-28 15:59:28 +0900358 struct wid wid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900359
Leo Kim45102f82015-10-28 15:59:28 +0900360 wid.id = (u16)WID_SET_OPERATION_MODE;
361 wid.type = WID_INT;
Leo Kimacff1d72015-10-29 12:05:56 +0900362 wid.val = (s8 *)&hif_op_mode->mode;
Leo Kim45102f82015-10-28 15:59:28 +0900363 wid.size = sizeof(u32);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900364
Chaehyun Lim14f3b082016-04-07 08:10:43 +0900365 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
366 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900367
Leo Kimacff1d72015-10-29 12:05:56 +0900368 if ((hif_op_mode->mode) == IDLE_MODE)
Chaehyun Lim2bb02582016-03-23 21:28:34 +0900369 complete(&hif_driver_comp);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900370
Chaehyun Lim14f3b082016-04-07 08:10:43 +0900371 if (ret)
Chris Parkb92f9302016-02-22 13:12:02 +0900372 netdev_err(vif->ndev, "Failed to set driver handler\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900373}
374
Chaehyun Limfc6138b2016-04-19 09:35:29 +0900375static void handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900376{
Chaehyun Lim8958f582016-04-19 09:35:31 +0900377 int ret = 0;
Leo Kim45102f82015-10-28 15:59:28 +0900378 struct wid wid;
Leo Kimebc57d12015-11-05 14:36:03 +0900379 char firmware_ip_addr[4] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900380
Leo Kima6527c32015-11-05 14:36:02 +0900381 if (ip_addr[0] < 192)
382 ip_addr[0] = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900383
Leo Kima6527c32015-11-05 14:36:02 +0900384 memcpy(set_ip[idx], ip_addr, IP_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900385
Leo Kim45102f82015-10-28 15:59:28 +0900386 wid.id = (u16)WID_IP_ADDRESS;
387 wid.type = WID_STR;
Leo Kima6527c32015-11-05 14:36:02 +0900388 wid.val = (u8 *)ip_addr;
Leo Kim45102f82015-10-28 15:59:28 +0900389 wid.size = IP_ALEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900390
Chaehyun Lim8958f582016-04-19 09:35:31 +0900391 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
392 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900393
Chaehyun Limf8813d32015-12-30 21:15:42 +0900394 host_int_get_ipaddress(vif, firmware_ip_addr, idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900395
Chaehyun Lim8958f582016-04-19 09:35:31 +0900396 if (ret)
Chris Parkb92f9302016-02-22 13:12:02 +0900397 netdev_err(vif->ndev, "Failed to set IP address\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900398}
399
Chaehyun Lim8f9d9e02016-05-02 19:47:49 +0900400static void handle_get_ip_address(struct wilc_vif *vif, u8 idx)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900401{
Chaehyun Lim6f2f5d52016-05-02 19:47:51 +0900402 int ret = 0;
Leo Kim45102f82015-10-28 15:59:28 +0900403 struct wid wid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900404
Leo Kim45102f82015-10-28 15:59:28 +0900405 wid.id = (u16)WID_IP_ADDRESS;
406 wid.type = WID_STR;
407 wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
408 wid.size = IP_ALEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900409
Chaehyun Lim6f2f5d52016-05-02 19:47:51 +0900410 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
411 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900412
Leo Kim45102f82015-10-28 15:59:28 +0900413 memcpy(get_ip[idx], wid.val, IP_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900414
Leo Kim45102f82015-10-28 15:59:28 +0900415 kfree(wid.val);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900416
Leo Kim1e75d012015-10-15 13:25:05 +0900417 if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
Glen Leefbf53792015-12-21 14:18:40 +0900418 wilc_setup_ipaddress(vif, set_ip[idx], idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900419
Chaehyun Limabfaf5f2016-05-02 19:47:52 +0900420 if (ret)
Chris Parkb92f9302016-02-22 13:12:02 +0900421 netdev_err(vif->ndev, "Failed to get IP address\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900422}
423
Chaehyun Lim93dc5d52016-05-02 19:47:53 +0900424static void handle_get_mac_address(struct wilc_vif *vif,
425 struct get_mac_addr *get_mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426{
Chaehyun Limbeba2ab2016-05-02 19:47:55 +0900427 int ret = 0;
Leo Kim45102f82015-10-28 15:59:28 +0900428 struct wid wid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900429
Leo Kim45102f82015-10-28 15:59:28 +0900430 wid.id = (u16)WID_MAC_ADDR;
431 wid.type = WID_STR;
Leo Kim7f0ee9a2015-11-05 14:36:06 +0900432 wid.val = get_mac_addr->mac_addr;
Leo Kim45102f82015-10-28 15:59:28 +0900433 wid.size = ETH_ALEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900434
Chaehyun Limbeba2ab2016-05-02 19:47:55 +0900435 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
436 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +0900437
Chaehyun Limbeba2ab2016-05-02 19:47:55 +0900438 if (ret)
Chris Parkb92f9302016-02-22 13:12:02 +0900439 netdev_err(vif->ndev, "Failed to get mac address\n");
Chaehyun Lim613eaa32016-03-14 09:40:27 +0900440 complete(&hif_wait_response);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900441}
442
Chaehyun Limfbc976c2016-06-13 08:28:10 +0900443static void handle_cfg_param(struct wilc_vif *vif,
444 struct cfg_param_attr *cfg_param_attr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900445{
Chaehyun Lima1e7df42016-06-13 08:28:12 +0900446 int ret = 0;
Leo Kim13ca52a2015-11-06 11:20:11 +0900447 struct wid wid_list[32];
Glen Lee71130e82015-12-21 14:18:41 +0900448 struct host_if_drv *hif_drv = vif->hif_drv;
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900449 int i = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900450
Chaehyun Lim1f12f142016-03-08 10:04:32 +0900451 mutex_lock(&hif_drv->cfg_values_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900452
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900453 if (cfg_param_attr->flag & BSS_TYPE) {
Chaehyun Lim0cb7a5742016-06-13 08:28:14 +0900454 u8 bss_type = cfg_param_attr->bss_type;
455
456 if (bss_type < 6) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900457 wid_list[i].id = WID_BSS_TYPE;
Chaehyun Lim0cb7a5742016-06-13 08:28:14 +0900458 wid_list[i].val = (s8 *)&bss_type;
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900459 wid_list[i].type = WID_CHAR;
460 wid_list[i].size = sizeof(char);
Chaehyun Lim2938f202016-06-13 08:28:15 +0900461 hif_drv->cfg_values.bss_type = bss_type;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900462 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900463 netdev_err(vif->ndev, "check value 6 over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900464 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900465 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900466 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900467 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900468 if (cfg_param_attr->flag & AUTH_TYPE) {
469 if (cfg_param_attr->auth_type == 1 ||
470 cfg_param_attr->auth_type == 2 ||
471 cfg_param_attr->auth_type == 5) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900472 wid_list[i].id = WID_AUTH_TYPE;
473 wid_list[i].val = (s8 *)&cfg_param_attr->auth_type;
474 wid_list[i].type = WID_CHAR;
475 wid_list[i].size = sizeof(char);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900476 hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->auth_type;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900477 } else {
Chaehyun Limcdc6cd22016-02-23 15:38:03 +0900478 netdev_err(vif->ndev, "Impossible value\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900479 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900481 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900482 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900483 if (cfg_param_attr->flag & AUTHEN_TIMEOUT) {
484 if (cfg_param_attr->auth_timeout > 0 &&
485 cfg_param_attr->auth_timeout < 65536) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900486 wid_list[i].id = WID_AUTH_TIMEOUT;
487 wid_list[i].val = (s8 *)&cfg_param_attr->auth_timeout;
488 wid_list[i].type = WID_SHORT;
489 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900490 hif_drv->cfg_values.auth_timeout = cfg_param_attr->auth_timeout;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900491 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900492 netdev_err(vif->ndev, "Range(1 ~ 65535) over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900493 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900494 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900495 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900496 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900497 if (cfg_param_attr->flag & POWER_MANAGEMENT) {
498 if (cfg_param_attr->power_mgmt_mode < 5) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900499 wid_list[i].id = WID_POWER_MANAGEMENT;
500 wid_list[i].val = (s8 *)&cfg_param_attr->power_mgmt_mode;
501 wid_list[i].type = WID_CHAR;
502 wid_list[i].size = sizeof(char);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900503 hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->power_mgmt_mode;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900504 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900505 netdev_err(vif->ndev, "Invalid power mode\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900506 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900507 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900508 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900509 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900510 if (cfg_param_attr->flag & RETRY_SHORT) {
511 if (cfg_param_attr->short_retry_limit > 0 &&
512 cfg_param_attr->short_retry_limit < 256) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900513 wid_list[i].id = WID_SHORT_RETRY_LIMIT;
514 wid_list[i].val = (s8 *)&cfg_param_attr->short_retry_limit;
515 wid_list[i].type = WID_SHORT;
516 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900517 hif_drv->cfg_values.short_retry_limit = cfg_param_attr->short_retry_limit;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900518 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900519 netdev_err(vif->ndev, "Range(1~256) over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900520 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900521 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900522 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900523 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900524 if (cfg_param_attr->flag & RETRY_LONG) {
525 if (cfg_param_attr->long_retry_limit > 0 &&
526 cfg_param_attr->long_retry_limit < 256) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900527 wid_list[i].id = WID_LONG_RETRY_LIMIT;
528 wid_list[i].val = (s8 *)&cfg_param_attr->long_retry_limit;
529 wid_list[i].type = WID_SHORT;
530 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900531 hif_drv->cfg_values.long_retry_limit = cfg_param_attr->long_retry_limit;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900532 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900533 netdev_err(vif->ndev, "Range(1~256) over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900534 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900535 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900536 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900537 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900538 if (cfg_param_attr->flag & FRAG_THRESHOLD) {
539 if (cfg_param_attr->frag_threshold > 255 &&
540 cfg_param_attr->frag_threshold < 7937) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900541 wid_list[i].id = WID_FRAG_THRESHOLD;
542 wid_list[i].val = (s8 *)&cfg_param_attr->frag_threshold;
543 wid_list[i].type = WID_SHORT;
544 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900545 hif_drv->cfg_values.frag_threshold = cfg_param_attr->frag_threshold;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900546 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900547 netdev_err(vif->ndev, "Threshold Range fail\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900548 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900549 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900550 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900551 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900552 if (cfg_param_attr->flag & RTS_THRESHOLD) {
553 if (cfg_param_attr->rts_threshold > 255 &&
554 cfg_param_attr->rts_threshold < 65536) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900555 wid_list[i].id = WID_RTS_THRESHOLD;
556 wid_list[i].val = (s8 *)&cfg_param_attr->rts_threshold;
557 wid_list[i].type = WID_SHORT;
558 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900559 hif_drv->cfg_values.rts_threshold = cfg_param_attr->rts_threshold;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900560 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900561 netdev_err(vif->ndev, "Threshold Range fail\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900562 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900563 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900564 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900565 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900566 if (cfg_param_attr->flag & PREAMBLE) {
567 if (cfg_param_attr->preamble_type < 3) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900568 wid_list[i].id = WID_PREAMBLE;
569 wid_list[i].val = (s8 *)&cfg_param_attr->preamble_type;
570 wid_list[i].type = WID_CHAR;
571 wid_list[i].size = sizeof(char);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900572 hif_drv->cfg_values.preamble_type = cfg_param_attr->preamble_type;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900573 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900574 netdev_err(vif->ndev, "Preamle Range(0~2) over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900575 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900576 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900577 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900578 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900579 if (cfg_param_attr->flag & SHORT_SLOT_ALLOWED) {
580 if (cfg_param_attr->short_slot_allowed < 2) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900581 wid_list[i].id = WID_SHORT_SLOT_ALLOWED;
582 wid_list[i].val = (s8 *)&cfg_param_attr->short_slot_allowed;
583 wid_list[i].type = WID_CHAR;
584 wid_list[i].size = sizeof(char);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900585 hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->short_slot_allowed;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900586 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900587 netdev_err(vif->ndev, "Short slot(2) over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900588 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900589 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900590 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900591 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900592 if (cfg_param_attr->flag & TXOP_PROT_DISABLE) {
593 if (cfg_param_attr->txop_prot_disabled < 2) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900594 wid_list[i].id = WID_11N_TXOP_PROT_DISABLE;
595 wid_list[i].val = (s8 *)&cfg_param_attr->txop_prot_disabled;
596 wid_list[i].type = WID_CHAR;
597 wid_list[i].size = sizeof(char);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900598 hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->txop_prot_disabled;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900599 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900600 netdev_err(vif->ndev, "TXOP prot disable\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900601 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900602 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900603 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900604 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900605 if (cfg_param_attr->flag & BEACON_INTERVAL) {
606 if (cfg_param_attr->beacon_interval > 0 &&
607 cfg_param_attr->beacon_interval < 65536) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900608 wid_list[i].id = WID_BEACON_INTERVAL;
609 wid_list[i].val = (s8 *)&cfg_param_attr->beacon_interval;
610 wid_list[i].type = WID_SHORT;
611 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900612 hif_drv->cfg_values.beacon_interval = cfg_param_attr->beacon_interval;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900613 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900614 netdev_err(vif->ndev, "Beacon interval(1~65535)fail\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900615 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900616 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900617 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900618 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900619 if (cfg_param_attr->flag & DTIM_PERIOD) {
620 if (cfg_param_attr->dtim_period > 0 &&
621 cfg_param_attr->dtim_period < 256) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900622 wid_list[i].id = WID_DTIM_PERIOD;
623 wid_list[i].val = (s8 *)&cfg_param_attr->dtim_period;
624 wid_list[i].type = WID_CHAR;
625 wid_list[i].size = sizeof(char);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900626 hif_drv->cfg_values.dtim_period = cfg_param_attr->dtim_period;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900627 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900628 netdev_err(vif->ndev, "DTIM range(1~255) fail\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900629 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900630 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900631 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900632 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900633 if (cfg_param_attr->flag & SITE_SURVEY) {
634 if (cfg_param_attr->site_survey_enabled < 3) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900635 wid_list[i].id = WID_SITE_SURVEY;
636 wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_enabled;
637 wid_list[i].type = WID_CHAR;
638 wid_list[i].size = sizeof(char);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900639 hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->site_survey_enabled;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900640 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900641 netdev_err(vif->ndev, "Site survey disable\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900642 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900643 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900644 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900645 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900646 if (cfg_param_attr->flag & SITE_SURVEY_SCAN_TIME) {
647 if (cfg_param_attr->site_survey_scan_time > 0 &&
648 cfg_param_attr->site_survey_scan_time < 65536) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900649 wid_list[i].id = WID_SITE_SURVEY_SCAN_TIME;
650 wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_scan_time;
651 wid_list[i].type = WID_SHORT;
652 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900653 hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->site_survey_scan_time;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900654 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900655 netdev_err(vif->ndev, "Site scan time(1~65535) over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900656 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900657 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900658 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900659 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900660 if (cfg_param_attr->flag & ACTIVE_SCANTIME) {
661 if (cfg_param_attr->active_scan_time > 0 &&
662 cfg_param_attr->active_scan_time < 65536) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900663 wid_list[i].id = WID_ACTIVE_SCAN_TIME;
664 wid_list[i].val = (s8 *)&cfg_param_attr->active_scan_time;
665 wid_list[i].type = WID_SHORT;
666 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900667 hif_drv->cfg_values.active_scan_time = cfg_param_attr->active_scan_time;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900668 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900669 netdev_err(vif->ndev, "Active time(1~65535) over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900670 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900671 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900672 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900673 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900674 if (cfg_param_attr->flag & PASSIVE_SCANTIME) {
675 if (cfg_param_attr->passive_scan_time > 0 &&
676 cfg_param_attr->passive_scan_time < 65536) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900677 wid_list[i].id = WID_PASSIVE_SCAN_TIME;
678 wid_list[i].val = (s8 *)&cfg_param_attr->passive_scan_time;
679 wid_list[i].type = WID_SHORT;
680 wid_list[i].size = sizeof(u16);
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900681 hif_drv->cfg_values.passive_scan_time = cfg_param_attr->passive_scan_time;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900682 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900683 netdev_err(vif->ndev, "Passive time(1~65535) over\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900684 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900685 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900686 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900687 }
Chaehyun Lima5f0fb52016-02-23 15:37:58 +0900688 if (cfg_param_attr->flag & CURRENT_TX_RATE) {
689 enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->curr_tx_rate;
Leo Kimc09389a2015-10-28 15:59:24 +0900690
Chaehyun Limae9106a2016-02-23 15:38:01 +0900691 if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 ||
692 curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 ||
693 curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 ||
694 curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 ||
695 curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 ||
Chaehyun Lim940d43d2016-02-23 15:38:02 +0900696 curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 ||
697 curr_tx_rate == MBPS_54) {
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900698 wid_list[i].id = WID_CURRENT_TX_RATE;
699 wid_list[i].val = (s8 *)&curr_tx_rate;
700 wid_list[i].type = WID_SHORT;
701 wid_list[i].size = sizeof(u16);
Leo Kimace303f2015-10-29 11:58:26 +0900702 hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900703 } else {
Chris Parkb92f9302016-02-22 13:12:02 +0900704 netdev_err(vif->ndev, "out of TX rate\n");
Chaehyun Lim960efe02016-04-04 20:04:43 +0900705 goto unlock;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900706 }
Chaehyun Lim44a4db12016-02-23 15:38:00 +0900707 i++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900708 }
Leo Kim31390ee2015-10-19 18:26:08 +0900709
Chaehyun Lima1e7df42016-06-13 08:28:12 +0900710 ret = wilc_send_config_pkt(vif, SET_CFG, wid_list,
711 i, wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900712
Chaehyun Lima1e7df42016-06-13 08:28:12 +0900713 if (ret)
Chris Parkb92f9302016-02-22 13:12:02 +0900714 netdev_err(vif->ndev, "Error in setting CFG params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900715
Chaehyun Lim960efe02016-04-04 20:04:43 +0900716unlock:
Chaehyun Lim1f12f142016-03-08 10:04:32 +0900717 mutex_unlock(&hif_drv->cfg_values_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900718}
719
Chaehyun Lim34b107e2016-04-04 20:04:47 +0900720static s32 handle_scan(struct wilc_vif *vif, struct scan_attr *scan_info)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900721{
Leo Kim31390ee2015-10-19 18:26:08 +0900722 s32 result = 0;
Chaehyun Limbbff83d2016-04-04 20:04:48 +0900723 struct wid wid_list[5];
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900724 u32 index = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900725 u32 i;
Chaehyun Lim2f27ad12016-04-04 20:04:50 +0900726 u8 *buffer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900727 u8 valuesize = 0;
728 u8 *pu8HdnNtwrksWidVal = NULL;
Glen Lee71130e82015-12-21 14:18:41 +0900729 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900730
Chaehyun Lim34b107e2016-04-04 20:04:47 +0900731 hif_drv->usr_scan_req.scan_result = scan_info->result;
732 hif_drv->usr_scan_req.arg = scan_info->arg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900733
Leo Kimb60005a2015-10-29 11:58:24 +0900734 if ((hif_drv->hif_state >= HOST_IF_SCANNING) &&
735 (hif_drv->hif_state < HOST_IF_CONNECTED)) {
Chris Parkb92f9302016-02-22 13:12:02 +0900736 netdev_err(vif->ndev, "Already scan\n");
Leo Kim31390ee2015-10-19 18:26:08 +0900737 result = -EBUSY;
Leo Kim24db7132015-09-16 18:36:01 +0900738 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900739 }
740
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100741 if (wilc_optaining_ip || wilc_connecting) {
Chris Parkb92f9302016-02-22 13:12:02 +0900742 netdev_err(vif->ndev, "Don't do obss scan\n");
Leo Kim31390ee2015-10-19 18:26:08 +0900743 result = -EBUSY;
Leo Kim24db7132015-09-16 18:36:01 +0900744 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900745 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900746
Leo Kimf79756e2015-10-29 12:05:36 +0900747 hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900748
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900749 wid_list[index].id = (u16)WID_SSID_PROBE_REQ;
750 wid_list[index].type = WID_STR;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900751
Chaehyun Lim34b107e2016-04-04 20:04:47 +0900752 for (i = 0; i < scan_info->hidden_network.n_ssids; i++)
753 valuesize += ((scan_info->hidden_network.net_info[i].ssid_len) + 1);
Glen Leef3052582015-09-10 12:03:04 +0900754 pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900755 wid_list[index].val = pu8HdnNtwrksWidVal;
756 if (wid_list[index].val) {
Chaehyun Lim2f27ad12016-04-04 20:04:50 +0900757 buffer = wid_list[index].val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900758
Chaehyun Lim2f27ad12016-04-04 20:04:50 +0900759 *buffer++ = scan_info->hidden_network.n_ssids;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900760
Chaehyun Lim34b107e2016-04-04 20:04:47 +0900761 for (i = 0; i < scan_info->hidden_network.n_ssids; i++) {
Chaehyun Lim2f27ad12016-04-04 20:04:50 +0900762 *buffer++ = scan_info->hidden_network.net_info[i].ssid_len;
763 memcpy(buffer, scan_info->hidden_network.net_info[i].ssid, scan_info->hidden_network.net_info[i].ssid_len);
764 buffer += scan_info->hidden_network.net_info[i].ssid_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900765 }
766
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900767 wid_list[index].size = (s32)(valuesize + 1);
768 index++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900769 }
770
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900771 wid_list[index].id = WID_INFO_ELEMENT_PROBE;
772 wid_list[index].type = WID_BIN_DATA;
773 wid_list[index].val = scan_info->ies;
774 wid_list[index].size = scan_info->ies_len;
775 index++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900776
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900777 wid_list[index].id = WID_SCAN_TYPE;
778 wid_list[index].type = WID_CHAR;
779 wid_list[index].size = sizeof(char);
780 wid_list[index].val = (s8 *)&scan_info->type;
781 index++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900782
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900783 wid_list[index].id = WID_SCAN_CHANNEL_LIST;
784 wid_list[index].type = WID_BIN_DATA;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900785
Chaehyun Lim34b107e2016-04-04 20:04:47 +0900786 if (scan_info->ch_freq_list &&
787 scan_info->ch_list_len > 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900788 int i;
789
Chaehyun Lim34b107e2016-04-04 20:04:47 +0900790 for (i = 0; i < scan_info->ch_list_len; i++) {
791 if (scan_info->ch_freq_list[i] > 0)
792 scan_info->ch_freq_list[i] = scan_info->ch_freq_list[i] - 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900793 }
794 }
795
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900796 wid_list[index].val = scan_info->ch_freq_list;
797 wid_list[index].size = scan_info->ch_list_len;
798 index++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900799
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900800 wid_list[index].id = WID_START_SCAN_REQ;
801 wid_list[index].type = WID_CHAR;
802 wid_list[index].size = sizeof(char);
803 wid_list[index].val = (s8 *)&scan_info->src;
804 index++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900805
Leo Kimb60005a2015-10-29 11:58:24 +0900806 if (hif_drv->hif_state == HOST_IF_CONNECTED)
Leo Kimca8540e42015-10-15 13:25:00 +0900807 scan_while_connected = true;
Leo Kimb60005a2015-10-29 11:58:24 +0900808 else if (hif_drv->hif_state == HOST_IF_IDLE)
Leo Kimca8540e42015-10-15 13:25:00 +0900809 scan_while_connected = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900810
Chaehyun Limbbff83d2016-04-04 20:04:48 +0900811 result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
Chaehyun Lim87b16cb2016-04-04 20:04:49 +0900812 index,
Glen Leeeb9939b2015-12-21 14:18:43 +0900813 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900814
Leo Kim31390ee2015-10-19 18:26:08 +0900815 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +0900816 netdev_err(vif->ndev, "Failed to send scan parameters\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900817
Leo Kim24db7132015-09-16 18:36:01 +0900818ERRORHANDLER:
Leo Kim31390ee2015-10-19 18:26:08 +0900819 if (result) {
Leo Kim13b313e2015-10-29 11:58:34 +0900820 del_timer(&hif_drv->scan_timer);
Glen Lee71130e82015-12-21 14:18:41 +0900821 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900822 }
823
Chaehyun Lim34b107e2016-04-04 20:04:47 +0900824 kfree(scan_info->ch_freq_list);
825 scan_info->ch_freq_list = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900826
Chaehyun Lim34b107e2016-04-04 20:04:47 +0900827 kfree(scan_info->ies);
828 scan_info->ies = NULL;
829 kfree(scan_info->hidden_network.net_info);
830 scan_info->hidden_network.net_info = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900831
Shraddha Barke95f840f2015-10-14 07:29:19 +0530832 kfree(pu8HdnNtwrksWidVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900833
Leo Kim31390ee2015-10-19 18:26:08 +0900834 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835}
836
Glen Lee71130e82015-12-21 14:18:41 +0900837static s32 Handle_ScanDone(struct wilc_vif *vif,
Tony Choa4ab1ad2015-10-12 16:56:05 +0900838 enum scan_event enuEvent)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900839{
Leo Kim31390ee2015-10-19 18:26:08 +0900840 s32 result = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900841 u8 u8abort_running_scan;
Leo Kim45102f82015-10-28 15:59:28 +0900842 struct wid wid;
Glen Lee71130e82015-12-21 14:18:41 +0900843 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900844
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900845 if (enuEvent == SCAN_EVENT_ABORTED) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900846 u8abort_running_scan = 1;
Leo Kim45102f82015-10-28 15:59:28 +0900847 wid.id = (u16)WID_ABORT_RUNNING_SCAN;
848 wid.type = WID_CHAR;
849 wid.val = (s8 *)&u8abort_running_scan;
850 wid.size = sizeof(char);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900851
Glen Lee79df6a42016-02-04 18:15:31 +0900852 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +0900853 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +0900854
855 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +0900856 netdev_err(vif->ndev, "Failed to set abort running\n");
Leo Kim31390ee2015-10-19 18:26:08 +0900857 result = -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900858 }
859 }
860
Tony Choa4ab1ad2015-10-12 16:56:05 +0900861 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +0900862 netdev_err(vif->ndev, "Driver handler is NULL\n");
Leo Kim31390ee2015-10-19 18:26:08 +0900863 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900864 }
865
Leo Kimbc801852015-10-29 11:58:50 +0900866 if (hif_drv->usr_scan_req.scan_result) {
867 hif_drv->usr_scan_req.scan_result(enuEvent, NULL,
Leo Kim66eaea32015-10-29 11:58:51 +0900868 hif_drv->usr_scan_req.arg, NULL);
Leo Kimbc801852015-10-29 11:58:50 +0900869 hif_drv->usr_scan_req.scan_result = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900870 }
871
Leo Kim31390ee2015-10-19 18:26:08 +0900872 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900873}
874
Leo Kime554a302015-11-19 15:56:21 +0900875u8 wilc_connected_ssid[6] = {0};
Glen Lee71130e82015-12-21 14:18:41 +0900876static s32 Handle_Connect(struct wilc_vif *vif,
Tony Cho120ae592015-09-21 12:16:37 +0900877 struct connect_attr *pstrHostIFconnectAttr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900878{
Leo Kim31390ee2015-10-19 18:26:08 +0900879 s32 result = 0;
Leo Kime9e0c262015-10-12 16:55:41 +0900880 struct wid strWIDList[8];
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900881 u32 u32WidsCount = 0, dummyval = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900882 u8 *pu8CurrByte = NULL;
Leo Kime0a12212015-10-12 16:55:49 +0900883 struct join_bss_param *ptstrJoinBssParam;
Glen Lee71130e82015-12-21 14:18:41 +0900884 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900885
Leo Kime554a302015-11-19 15:56:21 +0900886 if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
Leo Kim31390ee2015-10-19 18:26:08 +0900887 result = 0;
Chris Parkb92f9302016-02-22 13:12:02 +0900888 netdev_err(vif->ndev, "Discard connect request\n");
Leo Kim31390ee2015-10-19 18:26:08 +0900889 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900890 }
891
Alison Schofield59b97b32016-02-12 22:51:04 -0800892 ptstrJoinBssParam = pstrHostIFconnectAttr->params;
Leo Kim91109e12015-10-19 18:26:13 +0900893 if (!ptstrJoinBssParam) {
Chris Parkb92f9302016-02-22 13:12:02 +0900894 netdev_err(vif->ndev, "Required BSSID not found\n");
Leo Kim31390ee2015-10-19 18:26:08 +0900895 result = -ENOENT;
Leo Kim24db7132015-09-16 18:36:01 +0900896 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900897 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900898
Leo Kim91109e12015-10-19 18:26:13 +0900899 if (pstrHostIFconnectAttr->bssid) {
Chaehyun Lim788f6fc2016-02-12 23:04:40 +0900900 hif_drv->usr_conn_req.bssid = kmalloc(6, GFP_KERNEL);
901 memcpy(hif_drv->usr_conn_req.bssid, pstrHostIFconnectAttr->bssid, 6);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900902 }
903
Leo Kim74ab5e42015-10-29 11:58:53 +0900904 hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len;
Leo Kim91109e12015-10-19 18:26:13 +0900905 if (pstrHostIFconnectAttr->ssid) {
Chaehyun Lim72216412016-02-12 23:04:41 +0900906 hif_drv->usr_conn_req.ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
907 memcpy(hif_drv->usr_conn_req.ssid,
Leo Kim8c8360b2015-10-19 18:26:12 +0900908 pstrHostIFconnectAttr->ssid,
909 pstrHostIFconnectAttr->ssid_len);
Chaehyun Lim72216412016-02-12 23:04:41 +0900910 hif_drv->usr_conn_req.ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900911 }
912
Leo Kim331ed082015-10-29 11:58:55 +0900913 hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len;
Leo Kim91109e12015-10-19 18:26:13 +0900914 if (pstrHostIFconnectAttr->ies) {
Leo Kima3b2f4b2015-10-29 11:58:54 +0900915 hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
916 memcpy(hif_drv->usr_conn_req.ies,
Leo Kim8c8360b2015-10-19 18:26:12 +0900917 pstrHostIFconnectAttr->ies,
918 pstrHostIFconnectAttr->ies_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900919 }
920
Chaehyun Lima0942c52016-02-12 23:04:42 +0900921 hif_drv->usr_conn_req.security = pstrHostIFconnectAttr->security;
Leo Kim7d069722015-10-29 12:05:37 +0900922 hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type;
Leo Kim33bfb192015-10-29 11:58:56 +0900923 hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result;
Leo Kim73abaa42015-10-29 12:05:27 +0900924 hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900925
Leo Kimdaaf16b2015-10-12 16:55:44 +0900926 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
Leo Kim416d8322015-10-12 16:55:43 +0900927 strWIDList[u32WidsCount].type = WID_INT;
Leo Kim2fd3e442015-10-12 16:55:45 +0900928 strWIDList[u32WidsCount].size = sizeof(u32);
Leo Kim900bb4a2015-10-12 16:55:46 +0900929 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930 u32WidsCount++;
931
Leo Kimdaaf16b2015-10-12 16:55:44 +0900932 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
Leo Kim416d8322015-10-12 16:55:43 +0900933 strWIDList[u32WidsCount].type = WID_INT;
Leo Kim2fd3e442015-10-12 16:55:45 +0900934 strWIDList[u32WidsCount].size = sizeof(u32);
Leo Kim900bb4a2015-10-12 16:55:46 +0900935 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900936 u32WidsCount++;
937
Leo Kimdaaf16b2015-10-12 16:55:44 +0900938 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
Leo Kim416d8322015-10-12 16:55:43 +0900939 strWIDList[u32WidsCount].type = WID_INT;
Leo Kim2fd3e442015-10-12 16:55:45 +0900940 strWIDList[u32WidsCount].size = sizeof(u32);
Leo Kim900bb4a2015-10-12 16:55:46 +0900941 strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900942 u32WidsCount++;
943
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900944 {
Leo Kimdaaf16b2015-10-12 16:55:44 +0900945 strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
Leo Kim416d8322015-10-12 16:55:43 +0900946 strWIDList[u32WidsCount].type = WID_BIN_DATA;
Leo Kima3b2f4b2015-10-29 11:58:54 +0900947 strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies;
Leo Kim331ed082015-10-29 11:58:55 +0900948 strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900949 u32WidsCount++;
950
Leo Kimf7bbd9c2015-10-13 19:49:50 +0900951 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
Leo Kim331ed082015-10-29 11:58:55 +0900952 info_element_size = hif_drv->usr_conn_req.ies_len;
Leo Kimdfef7b82015-10-15 13:25:14 +0900953 info_element = kmalloc(info_element_size, GFP_KERNEL);
Leo Kima3b2f4b2015-10-29 11:58:54 +0900954 memcpy(info_element, hif_drv->usr_conn_req.ies,
Leo Kimdfef7b82015-10-15 13:25:14 +0900955 info_element_size);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900956 }
957 }
Leo Kimdaaf16b2015-10-12 16:55:44 +0900958 strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
Leo Kim416d8322015-10-12 16:55:43 +0900959 strWIDList[u32WidsCount].type = WID_CHAR;
Leo Kim2fd3e442015-10-12 16:55:45 +0900960 strWIDList[u32WidsCount].size = sizeof(char);
Chaehyun Lima0942c52016-02-12 23:04:42 +0900961 strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.security;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900962 u32WidsCount++;
963
Leo Kimf7bbd9c2015-10-13 19:49:50 +0900964 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
Chaehyun Lima0942c52016-02-12 23:04:42 +0900965 mode_11i = hif_drv->usr_conn_req.security;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900966
Leo Kimdaaf16b2015-10-12 16:55:44 +0900967 strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
Leo Kim416d8322015-10-12 16:55:43 +0900968 strWIDList[u32WidsCount].type = WID_CHAR;
Leo Kim2fd3e442015-10-12 16:55:45 +0900969 strWIDList[u32WidsCount].size = sizeof(char);
Leo Kim7d069722015-10-29 12:05:37 +0900970 strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900971 u32WidsCount++;
972
Leo Kimf7bbd9c2015-10-13 19:49:50 +0900973 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
Leo Kim7d069722015-10-29 12:05:37 +0900974 auth_type = (u8)hif_drv->usr_conn_req.auth_type;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900975
Leo Kimdaaf16b2015-10-12 16:55:44 +0900976 strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
Leo Kim416d8322015-10-12 16:55:43 +0900977 strWIDList[u32WidsCount].type = WID_STR;
Leo Kimae4dfa52015-10-13 19:49:26 +0900978 strWIDList[u32WidsCount].size = 112;
Leo Kim900bb4a2015-10-12 16:55:46 +0900979 strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900980
Leo Kimf7bbd9c2015-10-13 19:49:50 +0900981 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
Leo Kim0626baa2015-10-15 13:25:13 +0900982 join_req_size = strWIDList[u32WidsCount].size;
983 join_req = kmalloc(join_req_size, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900984 }
Leo Kim91109e12015-10-19 18:26:13 +0900985 if (!strWIDList[u32WidsCount].val) {
Leo Kim31390ee2015-10-19 18:26:08 +0900986 result = -EFAULT;
Leo Kim24db7132015-09-16 18:36:01 +0900987 goto ERRORHANDLER;
988 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900989
Leo Kim900bb4a2015-10-12 16:55:46 +0900990 pu8CurrByte = strWIDList[u32WidsCount].val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900991
Leo Kim91109e12015-10-19 18:26:13 +0900992 if (pstrHostIFconnectAttr->ssid) {
Leo Kim8b3c9fa2015-10-13 19:49:51 +0900993 memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
994 pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900995 }
996 pu8CurrByte += MAX_SSID_LEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900997 *(pu8CurrByte++) = INFRASTRUCTURE;
Leo Kimae4dfa52015-10-13 19:49:26 +0900998
Leo Kim0d1527e2015-10-13 19:49:58 +0900999 if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
1000 *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001001 } else {
Chris Parkb92f9302016-02-22 13:12:02 +09001002 netdev_err(vif->ndev, "Channel out of range\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001003 *(pu8CurrByte++) = 0xFF;
1004 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001005 *(pu8CurrByte++) = (ptstrJoinBssParam->cap_info) & 0xFF;
1006 *(pu8CurrByte++) = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001007
Leo Kim91109e12015-10-19 18:26:13 +09001008 if (pstrHostIFconnectAttr->bssid)
Leo Kim9254db02015-10-13 19:49:49 +09001009 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001010 pu8CurrByte += 6;
1011
Tony Choc0f52fb2015-10-20 17:10:46 +09001012 if (pstrHostIFconnectAttr->bssid)
1013 memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1014 pu8CurrByte += 6;
1015
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001016 *(pu8CurrByte++) = (ptstrJoinBssParam->beacon_period) & 0xFF;
1017 *(pu8CurrByte++) = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001018 *(pu8CurrByte++) = ptstrJoinBssParam->dtim_period;
Leo Kimae4dfa52015-10-13 19:49:26 +09001019
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001020 memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001021 pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1022
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001023 *(pu8CurrByte++) = ptstrJoinBssParam->wmm_cap;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001024 *(pu8CurrByte++) = ptstrJoinBssParam->uapsd_cap;
1025
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001026 *(pu8CurrByte++) = ptstrJoinBssParam->ht_capable;
Leo Kimff069822015-10-29 12:05:26 +09001027 hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001028
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001029 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_found;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001030 *(pu8CurrByte++) = ptstrJoinBssParam->rsn_grp_policy;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001031 *(pu8CurrByte++) = ptstrJoinBssParam->mode_802_11i;
Leo Kimae4dfa52015-10-13 19:49:26 +09001032
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001033 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001034 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1035
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001036 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001037 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1038
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001039 memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001040 pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1041
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001042 *(pu8CurrByte++) = REAL_JOIN_REQ;
Leo Kim7a8d51d2015-10-15 13:24:43 +09001043 *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001044
Leo Kim7a8d51d2015-10-15 13:24:43 +09001045 if (ptstrJoinBssParam->noa_enabled) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001046 *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1047 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1048 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1049 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1050
Leo Kimd72b33c2015-10-15 13:24:44 +09001051 *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
Leo Kimcc179002015-10-15 13:24:47 +09001052 *(pu8CurrByte++) = ptstrJoinBssParam->idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001053
Leo Kimd72b33c2015-10-15 13:24:44 +09001054 if (ptstrJoinBssParam->opp_enabled)
Leo Kim99b66942015-10-15 13:24:45 +09001055 *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001056
Leo Kimc21047e2015-10-15 13:24:46 +09001057 *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001058
Leo Kim109e6ca2015-10-15 13:24:48 +09001059 memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
1060 pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001061
Leo Kim1d8b76b2015-10-15 13:24:49 +09001062 memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
1063 pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001064
Leo Kim4be55e22015-10-28 15:59:27 +09001065 memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
1066 pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
Chris Parkc4f97522016-02-04 18:24:04 +09001067 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001068
Leo Kim900bb4a2015-10-12 16:55:46 +09001069 pu8CurrByte = strWIDList[u32WidsCount].val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001070 u32WidsCount++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001071
Leo Kimf7bbd9c2015-10-13 19:49:50 +09001072 if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
Leo Kim0626baa2015-10-15 13:25:13 +09001073 memcpy(join_req, pu8CurrByte, join_req_size);
Glen Lee7036c622015-12-21 14:18:45 +09001074 join_req_vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001075 }
1076
Chris Parke3f16962016-02-04 18:24:30 +09001077 if (pstrHostIFconnectAttr->bssid)
Leo Kime554a302015-11-19 15:56:21 +09001078 memcpy(wilc_connected_ssid,
1079 pstrHostIFconnectAttr->bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001080
Glen Lee79df6a42016-02-04 18:15:31 +09001081 result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
Glen Leeec62e6d2015-11-18 15:11:33 +09001082 u32WidsCount,
Glen Leeeb9939b2015-12-21 14:18:43 +09001083 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09001084 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09001085 netdev_err(vif->ndev, "failed to send config packet\n");
Leo Kim31390ee2015-10-19 18:26:08 +09001086 result = -EFAULT;
Leo Kim24db7132015-09-16 18:36:01 +09001087 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001088 } else {
Leo Kimb60005a2015-10-29 11:58:24 +09001089 hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001090 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001091
Leo Kim24db7132015-09-16 18:36:01 +09001092ERRORHANDLER:
Leo Kim31390ee2015-10-19 18:26:08 +09001093 if (result) {
Chaehyun Lim3b0437e2016-02-25 09:15:42 +09001094 struct connect_info strConnectInfo;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001095
Leo Kim81a59502015-10-29 11:58:35 +09001096 del_timer(&hif_drv->connect_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001097
Chaehyun Lim3b0437e2016-02-25 09:15:42 +09001098 memset(&strConnectInfo, 0, sizeof(struct connect_info));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001099
Leo Kim91109e12015-10-19 18:26:13 +09001100 if (pstrHostIFconnectAttr->result) {
1101 if (pstrHostIFconnectAttr->bssid)
Chaehyun Limd4a24e02016-02-25 09:15:43 +09001102 memcpy(strConnectInfo.bssid, pstrHostIFconnectAttr->bssid, 6);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001103
Leo Kim91109e12015-10-19 18:26:13 +09001104 if (pstrHostIFconnectAttr->ies) {
Chaehyun Lim4607f9c2016-02-25 09:15:45 +09001105 strConnectInfo.req_ies_len = pstrHostIFconnectAttr->ies_len;
Chaehyun Lim4ff48572016-02-25 09:15:44 +09001106 strConnectInfo.req_ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1107 memcpy(strConnectInfo.req_ies,
Leo Kim8c8360b2015-10-19 18:26:12 +09001108 pstrHostIFconnectAttr->ies,
1109 pstrHostIFconnectAttr->ies_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001110 }
1111
Leo Kim6abcc112015-10-13 19:49:55 +09001112 pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001113 &strConnectInfo,
1114 MAC_DISCONNECTED,
1115 NULL,
Leo Kim8f38db82015-10-13 19:49:56 +09001116 pstrHostIFconnectAttr->arg);
Leo Kimb60005a2015-10-29 11:58:24 +09001117 hif_drv->hif_state = HOST_IF_IDLE;
Chaehyun Lim4ff48572016-02-25 09:15:44 +09001118 kfree(strConnectInfo.req_ies);
1119 strConnectInfo.req_ies = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001120
1121 } else {
Chris Parkb92f9302016-02-22 13:12:02 +09001122 netdev_err(vif->ndev, "Connect callback is NULL\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001123 }
1124 }
1125
Shraddha Barke95f840f2015-10-14 07:29:19 +05301126 kfree(pstrHostIFconnectAttr->bssid);
1127 pstrHostIFconnectAttr->bssid = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001128
Shraddha Barke95f840f2015-10-14 07:29:19 +05301129 kfree(pstrHostIFconnectAttr->ssid);
1130 pstrHostIFconnectAttr->ssid = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001131
Shraddha Barke95f840f2015-10-14 07:29:19 +05301132 kfree(pstrHostIFconnectAttr->ies);
1133 pstrHostIFconnectAttr->ies = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001134
Shraddha Barke95f840f2015-10-14 07:29:19 +05301135 kfree(pu8CurrByte);
Leo Kim31390ee2015-10-19 18:26:08 +09001136 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001137}
1138
Glen Lee71130e82015-12-21 14:18:41 +09001139static s32 Handle_ConnectTimeout(struct wilc_vif *vif)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001140{
Leo Kim31390ee2015-10-19 18:26:08 +09001141 s32 result = 0;
Chaehyun Lim3b0437e2016-02-25 09:15:42 +09001142 struct connect_info strConnectInfo;
Leo Kim45102f82015-10-28 15:59:28 +09001143 struct wid wid;
Chaehyun Limd85f5322015-06-11 14:35:54 +09001144 u16 u16DummyReasonCode = 0;
Glen Lee71130e82015-12-21 14:18:41 +09001145 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001146
Tony Choa4ab1ad2015-10-12 16:56:05 +09001147 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09001148 netdev_err(vif->ndev, "Driver handler is NULL\n");
Leo Kim31390ee2015-10-19 18:26:08 +09001149 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001150 }
1151
Leo Kimb60005a2015-10-29 11:58:24 +09001152 hif_drv->hif_state = HOST_IF_IDLE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001153
Leo Kimca8540e42015-10-15 13:25:00 +09001154 scan_while_connected = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001155
Chaehyun Lim3b0437e2016-02-25 09:15:42 +09001156 memset(&strConnectInfo, 0, sizeof(struct connect_info));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001157
Leo Kim33bfb192015-10-29 11:58:56 +09001158 if (hif_drv->usr_conn_req.conn_result) {
Chaehyun Lim788f6fc2016-02-12 23:04:40 +09001159 if (hif_drv->usr_conn_req.bssid) {
Chaehyun Limd4a24e02016-02-25 09:15:43 +09001160 memcpy(strConnectInfo.bssid,
Chaehyun Lim788f6fc2016-02-12 23:04:40 +09001161 hif_drv->usr_conn_req.bssid, 6);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001162 }
1163
Leo Kima3b2f4b2015-10-29 11:58:54 +09001164 if (hif_drv->usr_conn_req.ies) {
Chaehyun Lim4607f9c2016-02-25 09:15:45 +09001165 strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
Chaehyun Lim4ff48572016-02-25 09:15:44 +09001166 strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1167 memcpy(strConnectInfo.req_ies,
Leo Kima3b2f4b2015-10-29 11:58:54 +09001168 hif_drv->usr_conn_req.ies,
Leo Kim331ed082015-10-29 11:58:55 +09001169 hif_drv->usr_conn_req.ies_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001170 }
1171
Leo Kim33bfb192015-10-29 11:58:56 +09001172 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1173 &strConnectInfo,
1174 MAC_DISCONNECTED,
1175 NULL,
Leo Kim73abaa42015-10-29 12:05:27 +09001176 hif_drv->usr_conn_req.arg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001177
Chaehyun Lim4ff48572016-02-25 09:15:44 +09001178 kfree(strConnectInfo.req_ies);
1179 strConnectInfo.req_ies = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001180 } else {
Chris Parkb92f9302016-02-22 13:12:02 +09001181 netdev_err(vif->ndev, "Connect callback is NULL\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001182 }
1183
Leo Kim45102f82015-10-28 15:59:28 +09001184 wid.id = (u16)WID_DISCONNECT;
1185 wid.type = WID_CHAR;
1186 wid.val = (s8 *)&u16DummyReasonCode;
1187 wid.size = sizeof(char);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001188
Glen Lee79df6a42016-02-04 18:15:31 +09001189 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001190 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09001191 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09001192 netdev_err(vif->ndev, "Failed to send dissconect\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001193
Leo Kim74ab5e42015-10-29 11:58:53 +09001194 hif_drv->usr_conn_req.ssid_len = 0;
Chaehyun Lim72216412016-02-12 23:04:41 +09001195 kfree(hif_drv->usr_conn_req.ssid);
1196 hif_drv->usr_conn_req.ssid = NULL;
Chaehyun Lim788f6fc2016-02-12 23:04:40 +09001197 kfree(hif_drv->usr_conn_req.bssid);
1198 hif_drv->usr_conn_req.bssid = NULL;
Leo Kim331ed082015-10-29 11:58:55 +09001199 hif_drv->usr_conn_req.ies_len = 0;
Leo Kima3b2f4b2015-10-29 11:58:54 +09001200 kfree(hif_drv->usr_conn_req.ies);
Glen Leecc28e4b2015-12-18 18:26:02 +09001201 hif_drv->usr_conn_req.ies = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001202
Leo Kime554a302015-11-19 15:56:21 +09001203 eth_zero_addr(wilc_connected_ssid);
Leo Kimae4dfa52015-10-13 19:49:26 +09001204
Glen Lee7036c622015-12-21 14:18:45 +09001205 if (join_req && join_req_vif == vif) {
Leo Kim044a64102015-10-15 13:25:09 +09001206 kfree(join_req);
1207 join_req = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001208 }
Leo Kim48ce2462015-10-15 13:25:10 +09001209
Glen Lee7036c622015-12-21 14:18:45 +09001210 if (info_element && join_req_vif == vif) {
Leo Kim48ce2462015-10-15 13:25:10 +09001211 kfree(info_element);
1212 info_element = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001213 }
1214
Leo Kim31390ee2015-10-19 18:26:08 +09001215 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001216}
1217
Glen Lee71130e82015-12-21 14:18:41 +09001218static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif,
Tony Cho3bbd59f2015-09-21 12:16:38 +09001219 struct rcvd_net_info *pstrRcvdNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001220{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001221 u32 i;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001222 bool bNewNtwrkFound;
Leo Kim31390ee2015-10-19 18:26:08 +09001223 s32 result = 0;
Leo Kim6b5180a2016-02-04 18:24:10 +09001224 struct network_info *pstrNetworkInfo = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001225 void *pJoinParams = NULL;
Glen Lee71130e82015-12-21 14:18:41 +09001226 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001227
Dean Lee72ed4dc2015-06-12 14:11:44 +09001228 bNewNtwrkFound = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001229
Leo Kimbc801852015-10-29 11:58:50 +09001230 if (hif_drv->usr_scan_req.scan_result) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001231 wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
Leo Kim91109e12015-10-19 18:26:13 +09001232 if ((!pstrNetworkInfo) ||
Leo Kimbc801852015-10-29 11:58:50 +09001233 (!hif_drv->usr_scan_req.scan_result)) {
Chris Parkb92f9302016-02-22 13:12:02 +09001234 netdev_err(vif->ndev, "driver is null\n");
Leo Kim31390ee2015-10-19 18:26:08 +09001235 result = -EINVAL;
Leo Kim24db7132015-09-16 18:36:01 +09001236 goto done;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001237 }
1238
Leo Kimf79756e2015-10-29 12:05:36 +09001239 for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) {
Luis de Bethencourt4562d222016-06-23 18:57:09 +01001240 if (memcmp(hif_drv->usr_scan_req.net_info[i].bssid,
1241 pstrNetworkInfo->bssid, 6) == 0) {
1242 if (pstrNetworkInfo->rssi <= hif_drv->usr_scan_req.net_info[i].rssi) {
1243 goto done;
1244 } else {
1245 hif_drv->usr_scan_req.net_info[i].rssi = pstrNetworkInfo->rssi;
1246 bNewNtwrkFound = false;
1247 break;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001248 }
1249 }
1250 }
1251
Punit Vara047e6642015-10-25 04:01:25 +05301252 if (bNewNtwrkFound) {
Leo Kimf79756e2015-10-29 12:05:36 +09001253 if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
Chaehyun Lim5cfbbf12016-02-12 23:04:39 +09001254 hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].rssi = pstrNetworkInfo->rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001255
Luis de Bethencourt4562d222016-06-23 18:57:09 +01001256 memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid,
1257 pstrNetworkInfo->bssid, 6);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001258
Luis de Bethencourt4562d222016-06-23 18:57:09 +01001259 hif_drv->usr_scan_req.rcvd_ch_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001260
Luis de Bethencourt4562d222016-06-23 18:57:09 +01001261 pstrNetworkInfo->new_network = true;
1262 pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001263
Luis de Bethencourt4562d222016-06-23 18:57:09 +01001264 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1265 hif_drv->usr_scan_req.arg,
1266 pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001267 }
1268 } else {
Leo Kimd4020762016-02-04 18:24:20 +09001269 pstrNetworkInfo->new_network = false;
Leo Kimbc801852015-10-29 11:58:50 +09001270 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
Leo Kim66eaea32015-10-29 11:58:51 +09001271 hif_drv->usr_scan_req.arg, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001272 }
1273 }
1274
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001275done:
Shraddha Barke95f840f2015-10-14 07:29:19 +05301276 kfree(pstrRcvdNetworkInfo->buffer);
1277 pstrRcvdNetworkInfo->buffer = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278
Leo Kim91109e12015-10-19 18:26:13 +09001279 if (pstrNetworkInfo) {
Leo Kim390b6db2016-02-04 18:24:23 +09001280 kfree(pstrNetworkInfo->ies);
Leo Kimd9fb23d2016-02-04 18:24:06 +09001281 kfree(pstrNetworkInfo);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001282 }
1283
Leo Kim31390ee2015-10-19 18:26:08 +09001284 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001285}
1286
Glen Lee71130e82015-12-21 14:18:41 +09001287static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
Arnd Bergmann1608c402015-11-16 15:04:53 +01001288 u8 *pu8AssocRespInfo,
1289 u32 u32MaxAssocRespInfoLen,
1290 u32 *pu32RcvdAssocRespInfoLen);
1291
Glen Leecf601062015-12-21 14:18:39 +09001292static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif,
Tony Chof23a9ea2015-09-21 12:16:39 +09001293 struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001294{
Leo Kim31390ee2015-10-19 18:26:08 +09001295 s32 result = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001296 u8 u8MsgType = 0;
1297 u8 u8MsgID = 0;
Chaehyun Limd85f5322015-06-11 14:35:54 +09001298 u16 u16MsgLen = 0;
1299 u16 u16WidID = (u16)WID_NIL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001300 u8 u8WidLen = 0;
1301 u8 u8MacStatus;
1302 u8 u8MacStatusReasonCode;
1303 u8 u8MacStatusAdditionalInfo;
Chaehyun Lim3b0437e2016-02-25 09:15:42 +09001304 struct connect_info strConnectInfo;
Chaehyun Limbb76df52016-02-25 09:15:49 +09001305 struct disconnect_info strDisconnectNotifInfo;
Leo Kime6e12662015-09-16 18:36:03 +09001306 s32 s32Err = 0;
Glen Lee71130e82015-12-21 14:18:41 +09001307 struct host_if_drv *hif_drv = vif->hif_drv;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02001308
Tony Choa4ab1ad2015-10-12 16:56:05 +09001309 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09001310 netdev_err(vif->ndev, "Driver handler is NULL\n");
Leo Kim234837d2015-09-22 14:34:43 +09001311 return -ENODEV;
1312 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001313
Leo Kimb60005a2015-10-29 11:58:24 +09001314 if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
1315 (hif_drv->hif_state == HOST_IF_CONNECTED) ||
Leo Kimbc801852015-10-29 11:58:50 +09001316 hif_drv->usr_scan_req.scan_result) {
Leo Kim91109e12015-10-19 18:26:13 +09001317 if (!pstrRcvdGnrlAsyncInfo->buffer ||
Leo Kim33bfb192015-10-29 11:58:56 +09001318 !hif_drv->usr_conn_req.conn_result) {
Chris Parkb92f9302016-02-22 13:12:02 +09001319 netdev_err(vif->ndev, "driver is null\n");
Leo Kim24db7132015-09-16 18:36:01 +09001320 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001321 }
1322
Leo Kim33722ac72015-10-13 19:50:00 +09001323 u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001324
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001325 if ('I' != u8MsgType) {
Chris Parkb92f9302016-02-22 13:12:02 +09001326 netdev_err(vif->ndev, "Received Message incorrect.\n");
Leo Kim24db7132015-09-16 18:36:01 +09001327 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328 }
1329
Leo Kim33722ac72015-10-13 19:50:00 +09001330 u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
1331 u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
1332 u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
1333 u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
1334 u8MacStatus = pstrRcvdGnrlAsyncInfo->buffer[7];
1335 u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
1336 u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
Leo Kimb60005a2015-10-29 11:58:24 +09001337 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
Glen Lee71130e82015-12-21 14:18:41 +09001338 u32 u32RcvdAssocRespInfoLen = 0;
Leo Kim40d96e12016-02-04 18:24:08 +09001339 struct connect_resp_info *pstrConnectRespInfo = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001340
Chaehyun Lim3b0437e2016-02-25 09:15:42 +09001341 memset(&strConnectInfo, 0, sizeof(struct connect_info));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001342
1343 if (u8MacStatus == MAC_CONNECTED) {
Leo Kima633c0b2015-10-15 13:24:59 +09001344 memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001345
Glen Lee71130e82015-12-21 14:18:41 +09001346 host_int_get_assoc_res_info(vif,
Leo Kima633c0b2015-10-15 13:24:59 +09001347 rcv_assoc_resp,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001348 MAX_ASSOC_RESP_FRAME_SIZE,
1349 &u32RcvdAssocRespInfoLen);
1350
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001351 if (u32RcvdAssocRespInfoLen != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001352 s32Err = wilc_parse_assoc_resp_info(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001353 &pstrConnectRespInfo);
1354 if (s32Err) {
Chris Parkb92f9302016-02-22 13:12:02 +09001355 netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", s32Err);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001356 } else {
Chaehyun Lim134b4cf2016-02-25 09:15:48 +09001357 strConnectInfo.status = pstrConnectRespInfo->status;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001358
Chaehyun Lim134b4cf2016-02-25 09:15:48 +09001359 if (strConnectInfo.status == SUCCESSFUL_STATUSCODE) {
Leo Kimba7b6ff2016-02-04 18:24:09 +09001360 if (pstrConnectRespInfo->ies) {
Chaehyun Lim3e7477c2016-02-25 09:15:47 +09001361 strConnectInfo.resp_ies_len = pstrConnectRespInfo->ies_len;
Chaehyun Lim61e13262016-02-25 09:15:46 +09001362 strConnectInfo.resp_ies = kmalloc(pstrConnectRespInfo->ies_len, GFP_KERNEL);
1363 memcpy(strConnectInfo.resp_ies, pstrConnectRespInfo->ies,
Leo Kimba7b6ff2016-02-04 18:24:09 +09001364 pstrConnectRespInfo->ies_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001365 }
1366 }
1367
Leo Kim91109e12015-10-19 18:26:13 +09001368 if (pstrConnectRespInfo) {
Leo Kimba7b6ff2016-02-04 18:24:09 +09001369 kfree(pstrConnectRespInfo->ies);
Leo Kim5f79c2a2016-02-04 18:24:07 +09001370 kfree(pstrConnectRespInfo);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001371 }
1372 }
1373 }
1374 }
1375
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001376 if ((u8MacStatus == MAC_CONNECTED) &&
Chaehyun Lim134b4cf2016-02-25 09:15:48 +09001377 (strConnectInfo.status != SUCCESSFUL_STATUSCODE)) {
Chris Parkb92f9302016-02-22 13:12:02 +09001378 netdev_err(vif->ndev, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
Leo Kime554a302015-11-19 15:56:21 +09001379 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001380 } else if (u8MacStatus == MAC_DISCONNECTED) {
Chris Parkb92f9302016-02-22 13:12:02 +09001381 netdev_err(vif->ndev, "Received MAC status is MAC_DISCONNECTED\n");
Leo Kime554a302015-11-19 15:56:21 +09001382 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001383 }
1384
Chaehyun Lim788f6fc2016-02-12 23:04:40 +09001385 if (hif_drv->usr_conn_req.bssid) {
Chaehyun Limd4a24e02016-02-25 09:15:43 +09001386 memcpy(strConnectInfo.bssid, hif_drv->usr_conn_req.bssid, 6);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001387
1388 if ((u8MacStatus == MAC_CONNECTED) &&
Chaehyun Lim134b4cf2016-02-25 09:15:48 +09001389 (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) {
Leo Kim2a4eded2015-10-29 11:58:25 +09001390 memcpy(hif_drv->assoc_bssid,
Chaehyun Lim788f6fc2016-02-12 23:04:40 +09001391 hif_drv->usr_conn_req.bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001392 }
1393 }
1394
Leo Kima3b2f4b2015-10-29 11:58:54 +09001395 if (hif_drv->usr_conn_req.ies) {
Chaehyun Lim4607f9c2016-02-25 09:15:45 +09001396 strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
Chaehyun Lim4ff48572016-02-25 09:15:44 +09001397 strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1398 memcpy(strConnectInfo.req_ies,
Leo Kima3b2f4b2015-10-29 11:58:54 +09001399 hif_drv->usr_conn_req.ies,
Leo Kim331ed082015-10-29 11:58:55 +09001400 hif_drv->usr_conn_req.ies_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001401 }
1402
Leo Kim81a59502015-10-29 11:58:35 +09001403 del_timer(&hif_drv->connect_timer);
Leo Kim33bfb192015-10-29 11:58:56 +09001404 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1405 &strConnectInfo,
1406 u8MacStatus,
1407 NULL,
Leo Kim73abaa42015-10-29 12:05:27 +09001408 hif_drv->usr_conn_req.arg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001409
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001410 if ((u8MacStatus == MAC_CONNECTED) &&
Chaehyun Lim134b4cf2016-02-25 09:15:48 +09001411 (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) {
Glen Leefbf53792015-12-21 14:18:40 +09001412 wilc_set_power_mgmt(vif, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001413
Leo Kimb60005a2015-10-29 11:58:24 +09001414 hif_drv->hif_state = HOST_IF_CONNECTED;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001415
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001416 wilc_optaining_ip = true;
1417 mod_timer(&wilc_during_ip_timer,
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -07001418 jiffies + msecs_to_jiffies(10000));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001419 } else {
Leo Kimb60005a2015-10-29 11:58:24 +09001420 hif_drv->hif_state = HOST_IF_IDLE;
Leo Kimca8540e42015-10-15 13:25:00 +09001421 scan_while_connected = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001422 }
1423
Chaehyun Lim61e13262016-02-25 09:15:46 +09001424 kfree(strConnectInfo.resp_ies);
1425 strConnectInfo.resp_ies = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001426
Chaehyun Lim4ff48572016-02-25 09:15:44 +09001427 kfree(strConnectInfo.req_ies);
1428 strConnectInfo.req_ies = NULL;
Leo Kim74ab5e42015-10-29 11:58:53 +09001429 hif_drv->usr_conn_req.ssid_len = 0;
Chaehyun Lim72216412016-02-12 23:04:41 +09001430 kfree(hif_drv->usr_conn_req.ssid);
1431 hif_drv->usr_conn_req.ssid = NULL;
Chaehyun Lim788f6fc2016-02-12 23:04:40 +09001432 kfree(hif_drv->usr_conn_req.bssid);
1433 hif_drv->usr_conn_req.bssid = NULL;
Leo Kim331ed082015-10-29 11:58:55 +09001434 hif_drv->usr_conn_req.ies_len = 0;
Leo Kima3b2f4b2015-10-29 11:58:54 +09001435 kfree(hif_drv->usr_conn_req.ies);
Glen Leecc28e4b2015-12-18 18:26:02 +09001436 hif_drv->usr_conn_req.ies = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001437 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
Leo Kimb60005a2015-10-29 11:58:24 +09001438 (hif_drv->hif_state == HOST_IF_CONNECTED)) {
Chaehyun Limbb76df52016-02-25 09:15:49 +09001439 memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001440
Leo Kimbc801852015-10-29 11:58:50 +09001441 if (hif_drv->usr_scan_req.scan_result) {
Leo Kim13b313e2015-10-29 11:58:34 +09001442 del_timer(&hif_drv->scan_timer);
Glen Lee71130e82015-12-21 14:18:41 +09001443 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001444 }
1445
Chaehyun Lim90f209d2016-02-25 09:15:50 +09001446 strDisconnectNotifInfo.reason = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001447 strDisconnectNotifInfo.ie = NULL;
1448 strDisconnectNotifInfo.ie_len = 0;
1449
Leo Kim33bfb192015-10-29 11:58:56 +09001450 if (hif_drv->usr_conn_req.conn_result) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001451 wilc_optaining_ip = false;
Glen Leefbf53792015-12-21 14:18:40 +09001452 wilc_set_power_mgmt(vif, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001453
Leo Kim33bfb192015-10-29 11:58:56 +09001454 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1455 NULL,
1456 0,
1457 &strDisconnectNotifInfo,
Leo Kim73abaa42015-10-29 12:05:27 +09001458 hif_drv->usr_conn_req.arg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001459 } else {
Chris Parkb92f9302016-02-22 13:12:02 +09001460 netdev_err(vif->ndev, "Connect result NULL\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001461 }
1462
Leo Kim2a4eded2015-10-29 11:58:25 +09001463 eth_zero_addr(hif_drv->assoc_bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001464
Leo Kim74ab5e42015-10-29 11:58:53 +09001465 hif_drv->usr_conn_req.ssid_len = 0;
Chaehyun Lim72216412016-02-12 23:04:41 +09001466 kfree(hif_drv->usr_conn_req.ssid);
1467 hif_drv->usr_conn_req.ssid = NULL;
Chaehyun Lim788f6fc2016-02-12 23:04:40 +09001468 kfree(hif_drv->usr_conn_req.bssid);
1469 hif_drv->usr_conn_req.bssid = NULL;
Leo Kim331ed082015-10-29 11:58:55 +09001470 hif_drv->usr_conn_req.ies_len = 0;
Leo Kima3b2f4b2015-10-29 11:58:54 +09001471 kfree(hif_drv->usr_conn_req.ies);
Glen Leecc28e4b2015-12-18 18:26:02 +09001472 hif_drv->usr_conn_req.ies = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001473
Glen Lee7036c622015-12-21 14:18:45 +09001474 if (join_req && join_req_vif == vif) {
Leo Kim044a64102015-10-15 13:25:09 +09001475 kfree(join_req);
1476 join_req = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001477 }
Leo Kim48ce2462015-10-15 13:25:10 +09001478
Glen Lee7036c622015-12-21 14:18:45 +09001479 if (info_element && join_req_vif == vif) {
Leo Kim48ce2462015-10-15 13:25:10 +09001480 kfree(info_element);
1481 info_element = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001482 }
1483
Leo Kimb60005a2015-10-29 11:58:24 +09001484 hif_drv->hif_state = HOST_IF_IDLE;
Leo Kimca8540e42015-10-15 13:25:00 +09001485 scan_while_connected = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001486
1487 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
Leo Kimbc801852015-10-29 11:58:50 +09001488 (hif_drv->usr_scan_req.scan_result)) {
Leo Kim13b313e2015-10-29 11:58:34 +09001489 del_timer(&hif_drv->scan_timer);
Leo Kimbc801852015-10-29 11:58:50 +09001490 if (hif_drv->usr_scan_req.scan_result)
Glen Lee71130e82015-12-21 14:18:41 +09001491 Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001492 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001493 }
1494
Shraddha Barke95f840f2015-10-14 07:29:19 +05301495 kfree(pstrRcvdGnrlAsyncInfo->buffer);
1496 pstrRcvdGnrlAsyncInfo->buffer = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001497
Leo Kim31390ee2015-10-19 18:26:08 +09001498 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001499}
1500
Glen Lee71130e82015-12-21 14:18:41 +09001501static int Handle_Key(struct wilc_vif *vif,
Tony Choc98387a2015-09-21 12:16:40 +09001502 struct key_attr *pstrHostIFkeyAttr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001503{
Leo Kim31390ee2015-10-19 18:26:08 +09001504 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09001505 struct wid wid;
Leo Kime9e0c262015-10-12 16:55:41 +09001506 struct wid strWIDList[5];
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001507 u8 i;
1508 u8 *pu8keybuf;
Chaehyun Limca356ad2015-06-11 14:35:57 +09001509 s8 s8idxarray[1];
1510 s8 ret = 0;
Glen Lee71130e82015-12-21 14:18:41 +09001511 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001512
Leo Kim8e9f4272015-10-13 19:49:27 +09001513 switch (pstrHostIFkeyAttr->type) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001514 case WEP:
1515
Leo Kim0d17e382015-10-13 19:49:28 +09001516 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
Leo Kimdaaf16b2015-10-12 16:55:44 +09001517 strWIDList[0].id = (u16)WID_11I_MODE;
Leo Kim416d8322015-10-12 16:55:43 +09001518 strWIDList[0].type = WID_CHAR;
Leo Kim2fd3e442015-10-12 16:55:45 +09001519 strWIDList[0].size = sizeof(char);
Leo Kimbafaa692015-10-28 15:59:21 +09001520 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001521
Leo Kimdaaf16b2015-10-12 16:55:44 +09001522 strWIDList[1].id = WID_AUTH_TYPE;
Leo Kim416d8322015-10-12 16:55:43 +09001523 strWIDList[1].type = WID_CHAR;
Leo Kim2fd3e442015-10-12 16:55:45 +09001524 strWIDList[1].size = sizeof(char);
Leo Kimbafaa692015-10-28 15:59:21 +09001525 strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001526
Glen Leeec450482016-02-04 18:15:28 +09001527 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2,
Shraddha Barke543f5b12015-10-16 10:47:11 +05301528 GFP_KERNEL);
Chris Park77f3a712016-02-22 13:12:01 +09001529 if (!pu8keybuf)
Luis de Bethencourt90819872015-10-26 05:52:50 +00001530 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001531
Glen Leeec450482016-02-04 18:15:28 +09001532 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1533 pu8keybuf[1] = pstrHostIFkeyAttr->attr.wep.key_len;
1534
1535 memcpy(&pu8keybuf[2], pstrHostIFkeyAttr->attr.wep.key,
1536 pstrHostIFkeyAttr->attr.wep.key_len);
1537
Leo Kim73b2e382015-10-13 19:49:29 +09001538 kfree(pstrHostIFkeyAttr->attr.wep.key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001539
Glen Leeec450482016-02-04 18:15:28 +09001540 strWIDList[2].id = (u16)WID_WEP_KEY_VALUE;
1541 strWIDList[2].type = WID_STR;
1542 strWIDList[2].size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1543 strWIDList[2].val = (s8 *)pu8keybuf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001544
Glen Lee79df6a42016-02-04 18:15:31 +09001545 result = wilc_send_config_pkt(vif, SET_CFG,
Glen Leeec450482016-02-04 18:15:28 +09001546 strWIDList, 3,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001547 wilc_get_vif_idx(vif));
Chaehyun Lim49188af2015-08-11 10:32:41 +09001548 kfree(pu8keybuf);
Leo Kim9edaa5f2015-11-25 11:59:48 +09001549 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
Leo Kim73b2e382015-10-13 19:49:29 +09001550 pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
Chris Park77f3a712016-02-22 13:12:01 +09001551 if (!pu8keybuf)
Luis de Bethencourt90819872015-10-26 05:52:50 +00001552 return -ENOMEM;
Leo Kim73b2e382015-10-13 19:49:29 +09001553 pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1554 memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1555 memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
Leo Kim8c8360b2015-10-19 18:26:12 +09001556 pstrHostIFkeyAttr->attr.wep.key_len);
Leo Kim73b2e382015-10-13 19:49:29 +09001557 kfree(pstrHostIFkeyAttr->attr.wep.key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001558
Leo Kim45102f82015-10-28 15:59:28 +09001559 wid.id = (u16)WID_ADD_WEP_KEY;
1560 wid.type = WID_STR;
1561 wid.val = (s8 *)pu8keybuf;
1562 wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001563
Glen Lee79df6a42016-02-04 18:15:31 +09001564 result = wilc_send_config_pkt(vif, SET_CFG,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001565 &wid, 1,
1566 wilc_get_vif_idx(vif));
Chaehyun Lim49188af2015-08-11 10:32:41 +09001567 kfree(pu8keybuf);
Leo Kim0d17e382015-10-13 19:49:28 +09001568 } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
Leo Kim45102f82015-10-28 15:59:28 +09001569 wid.id = (u16)WID_REMOVE_WEP_KEY;
1570 wid.type = WID_STR;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001571
Leo Kim73b2e382015-10-13 19:49:29 +09001572 s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
Leo Kim45102f82015-10-28 15:59:28 +09001573 wid.val = s8idxarray;
1574 wid.size = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001575
Glen Lee79df6a42016-02-04 18:15:31 +09001576 result = wilc_send_config_pkt(vif, SET_CFG,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001577 &wid, 1,
1578 wilc_get_vif_idx(vif));
Glen Leeec450482016-02-04 18:15:28 +09001579 } else if (pstrHostIFkeyAttr->action & DEFAULTKEY) {
Leo Kim45102f82015-10-28 15:59:28 +09001580 wid.id = (u16)WID_KEY_ID;
1581 wid.type = WID_CHAR;
1582 wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1583 wid.size = sizeof(char);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001584
Glen Lee79df6a42016-02-04 18:15:31 +09001585 result = wilc_send_config_pkt(vif, SET_CFG,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001586 &wid, 1,
1587 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001588 }
Alison Schofield702962f2016-03-14 10:35:41 -07001589 complete(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590 break;
1591
Leo Kim5cd8f7a2015-10-29 12:05:34 +09001592 case WPA_RX_GTK:
Leo Kim0d17e382015-10-13 19:49:28 +09001593 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
Shraddha Barkeb156f1e2015-10-13 23:07:00 +05301594 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
Leo Kim91109e12015-10-19 18:26:13 +09001595 if (!pu8keybuf) {
Luis de Bethencourt90819872015-10-26 05:52:50 +00001596 ret = -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001597 goto _WPARxGtk_end_case_;
1598 }
1599
Leo Kim91109e12015-10-19 18:26:13 +09001600 if (pstrHostIFkeyAttr->attr.wpa.seq)
Leo Kim0e74c002015-10-13 19:49:32 +09001601 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001602
Leo Kime2dfbac2015-10-13 19:49:34 +09001603 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
Leo Kim6acf2912015-10-13 19:49:35 +09001604 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
Leo Kim124968fc2015-10-13 19:49:30 +09001605 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
Leo Kim8c8360b2015-10-19 18:26:12 +09001606 pstrHostIFkeyAttr->attr.wpa.key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001607
Leo Kimdaaf16b2015-10-12 16:55:44 +09001608 strWIDList[0].id = (u16)WID_11I_MODE;
Leo Kim416d8322015-10-12 16:55:43 +09001609 strWIDList[0].type = WID_CHAR;
Leo Kim2fd3e442015-10-12 16:55:45 +09001610 strWIDList[0].size = sizeof(char);
Leo Kimbafaa692015-10-28 15:59:21 +09001611 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001612
Leo Kimdaaf16b2015-10-12 16:55:44 +09001613 strWIDList[1].id = (u16)WID_ADD_RX_GTK;
Leo Kim416d8322015-10-12 16:55:43 +09001614 strWIDList[1].type = WID_STR;
Leo Kim900bb4a2015-10-12 16:55:46 +09001615 strWIDList[1].val = (s8 *)pu8keybuf;
Leo Kim2fd3e442015-10-12 16:55:45 +09001616 strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001617
Glen Lee79df6a42016-02-04 18:15:31 +09001618 result = wilc_send_config_pkt(vif, SET_CFG,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001619 strWIDList, 2,
1620 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001621
Chaehyun Lim49188af2015-08-11 10:32:41 +09001622 kfree(pu8keybuf);
Alison Schofield702962f2016-03-14 10:35:41 -07001623 complete(&hif_drv->comp_test_key_block);
Leo Kim9edaa5f2015-11-25 11:59:48 +09001624 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
Shraddha Barkeb156f1e2015-10-13 23:07:00 +05301625 pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
Roger H. Newellb59958e2016-03-19 12:50:52 -02301626 if (!pu8keybuf) {
Luis de Bethencourt90819872015-10-26 05:52:50 +00001627 ret = -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001628 goto _WPARxGtk_end_case_;
1629 }
1630
Leo Kimb60005a2015-10-29 11:58:24 +09001631 if (hif_drv->hif_state == HOST_IF_CONNECTED)
Leo Kim2a4eded2015-10-29 11:58:25 +09001632 memcpy(pu8keybuf, hif_drv->assoc_bssid, ETH_ALEN);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301633 else
Chris Parkb92f9302016-02-22 13:12:02 +09001634 netdev_err(vif->ndev, "Couldn't handle\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001635
Leo Kim0e74c002015-10-13 19:49:32 +09001636 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
Leo Kime2dfbac2015-10-13 19:49:34 +09001637 memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
Leo Kim6acf2912015-10-13 19:49:35 +09001638 memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
Leo Kim124968fc2015-10-13 19:49:30 +09001639 memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
Leo Kim8c8360b2015-10-19 18:26:12 +09001640 pstrHostIFkeyAttr->attr.wpa.key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001641
Leo Kim45102f82015-10-28 15:59:28 +09001642 wid.id = (u16)WID_ADD_RX_GTK;
1643 wid.type = WID_STR;
1644 wid.val = (s8 *)pu8keybuf;
1645 wid.size = RX_MIC_KEY_MSG_LEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001646
Glen Lee79df6a42016-02-04 18:15:31 +09001647 result = wilc_send_config_pkt(vif, SET_CFG,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001648 &wid, 1,
1649 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001650
Chaehyun Lim49188af2015-08-11 10:32:41 +09001651 kfree(pu8keybuf);
Alison Schofield702962f2016-03-14 10:35:41 -07001652 complete(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001653 }
1654_WPARxGtk_end_case_:
Leo Kim124968fc2015-10-13 19:49:30 +09001655 kfree(pstrHostIFkeyAttr->attr.wpa.key);
Leo Kim0e74c002015-10-13 19:49:32 +09001656 kfree(pstrHostIFkeyAttr->attr.wpa.seq);
Luis de Bethencourt90819872015-10-26 05:52:50 +00001657 if (ret)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001658 return ret;
1659
1660 break;
1661
Leo Kim2141fe32015-10-29 12:05:35 +09001662 case WPA_PTK:
Leo Kim0d17e382015-10-13 19:49:28 +09001663 if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
Glen Leef3052582015-09-10 12:03:04 +09001664 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
Leo Kim91109e12015-10-19 18:26:13 +09001665 if (!pu8keybuf) {
Luis de Bethencourt90819872015-10-26 05:52:50 +00001666 ret = -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001667 goto _WPAPtk_end_case_;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001668 }
1669
Leo Kim248080a2015-10-13 19:49:31 +09001670 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
Leo Kime2dfbac2015-10-13 19:49:34 +09001671 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
Leo Kim6acf2912015-10-13 19:49:35 +09001672 memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
Leo Kim124968fc2015-10-13 19:49:30 +09001673 memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
Leo Kim8c8360b2015-10-19 18:26:12 +09001674 pstrHostIFkeyAttr->attr.wpa.key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001675
Leo Kimdaaf16b2015-10-12 16:55:44 +09001676 strWIDList[0].id = (u16)WID_11I_MODE;
Leo Kim416d8322015-10-12 16:55:43 +09001677 strWIDList[0].type = WID_CHAR;
Leo Kim2fd3e442015-10-12 16:55:45 +09001678 strWIDList[0].size = sizeof(char);
Leo Kimbafaa692015-10-28 15:59:21 +09001679 strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001680
Leo Kimdaaf16b2015-10-12 16:55:44 +09001681 strWIDList[1].id = (u16)WID_ADD_PTK;
Leo Kim416d8322015-10-12 16:55:43 +09001682 strWIDList[1].type = WID_STR;
Leo Kim900bb4a2015-10-12 16:55:46 +09001683 strWIDList[1].val = (s8 *)pu8keybuf;
Leo Kim2fd3e442015-10-12 16:55:45 +09001684 strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001685
Glen Lee79df6a42016-02-04 18:15:31 +09001686 result = wilc_send_config_pkt(vif, SET_CFG,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001687 strWIDList, 2,
1688 wilc_get_vif_idx(vif));
Chaehyun Lim49188af2015-08-11 10:32:41 +09001689 kfree(pu8keybuf);
Alison Schofield702962f2016-03-14 10:35:41 -07001690 complete(&hif_drv->comp_test_key_block);
Leo Kim9edaa5f2015-11-25 11:59:48 +09001691 } else if (pstrHostIFkeyAttr->action & ADDKEY) {
Glen Leef3052582015-09-10 12:03:04 +09001692 pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
Leo Kim91109e12015-10-19 18:26:13 +09001693 if (!pu8keybuf) {
Chris Parkb92f9302016-02-22 13:12:02 +09001694 netdev_err(vif->ndev, "No buffer send PTK\n");
Luis de Bethencourt90819872015-10-26 05:52:50 +00001695 ret = -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001696 goto _WPAPtk_end_case_;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001697 }
1698
Leo Kim248080a2015-10-13 19:49:31 +09001699 memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
Leo Kim6acf2912015-10-13 19:49:35 +09001700 memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
Leo Kim124968fc2015-10-13 19:49:30 +09001701 memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
Leo Kim8c8360b2015-10-19 18:26:12 +09001702 pstrHostIFkeyAttr->attr.wpa.key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001703
Leo Kim45102f82015-10-28 15:59:28 +09001704 wid.id = (u16)WID_ADD_PTK;
1705 wid.type = WID_STR;
1706 wid.val = (s8 *)pu8keybuf;
1707 wid.size = PTK_KEY_MSG_LEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001708
Glen Lee79df6a42016-02-04 18:15:31 +09001709 result = wilc_send_config_pkt(vif, SET_CFG,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001710 &wid, 1,
1711 wilc_get_vif_idx(vif));
Chaehyun Lim49188af2015-08-11 10:32:41 +09001712 kfree(pu8keybuf);
Alison Schofield702962f2016-03-14 10:35:41 -07001713 complete(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001714 }
1715
1716_WPAPtk_end_case_:
Leo Kim124968fc2015-10-13 19:49:30 +09001717 kfree(pstrHostIFkeyAttr->attr.wpa.key);
Luis de Bethencourt90819872015-10-26 05:52:50 +00001718 if (ret)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001719 return ret;
1720
1721 break;
1722
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001723 case PMKSA:
Leo Kim73b2e382015-10-13 19:49:29 +09001724 pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
Leo Kim91109e12015-10-19 18:26:13 +09001725 if (!pu8keybuf) {
Chris Parkb92f9302016-02-22 13:12:02 +09001726 netdev_err(vif->ndev, "No buffer to send PMKSA Key\n");
Luis de Bethencourt90819872015-10-26 05:52:50 +00001727 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001728 }
1729
Leo Kim73b2e382015-10-13 19:49:29 +09001730 pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001731
Leo Kim73b2e382015-10-13 19:49:29 +09001732 for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1733 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1734 memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001735 }
1736
Leo Kim45102f82015-10-28 15:59:28 +09001737 wid.id = (u16)WID_PMKID_INFO;
1738 wid.type = WID_STR;
1739 wid.val = (s8 *)pu8keybuf;
1740 wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001741
Glen Lee79df6a42016-02-04 18:15:31 +09001742 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001743 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001744
Chaehyun Lim49188af2015-08-11 10:32:41 +09001745 kfree(pu8keybuf);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001746 break;
1747 }
1748
Leo Kim31390ee2015-10-19 18:26:08 +09001749 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09001750 netdev_err(vif->ndev, "Failed to send key config packet\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001751
Leo Kim31390ee2015-10-19 18:26:08 +09001752 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001753}
1754
Glen Lee71130e82015-12-21 14:18:41 +09001755static void Handle_Disconnect(struct wilc_vif *vif)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001756{
Leo Kim45102f82015-10-28 15:59:28 +09001757 struct wid wid;
Glen Lee71130e82015-12-21 14:18:41 +09001758 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001759
Leo Kim31390ee2015-10-19 18:26:08 +09001760 s32 result = 0;
Chaehyun Limd85f5322015-06-11 14:35:54 +09001761 u16 u16DummyReasonCode = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001762
Leo Kim45102f82015-10-28 15:59:28 +09001763 wid.id = (u16)WID_DISCONNECT;
1764 wid.type = WID_CHAR;
1765 wid.val = (s8 *)&u16DummyReasonCode;
1766 wid.size = sizeof(char);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001767
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001768 wilc_optaining_ip = false;
Glen Leefbf53792015-12-21 14:18:40 +09001769 wilc_set_power_mgmt(vif, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001770
Leo Kime554a302015-11-19 15:56:21 +09001771 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001772
Glen Lee79df6a42016-02-04 18:15:31 +09001773 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001774 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001775
Leo Kim31390ee2015-10-19 18:26:08 +09001776 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09001777 netdev_err(vif->ndev, "Failed to send dissconect\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001778 } else {
Chaehyun Limbb76df52016-02-25 09:15:49 +09001779 struct disconnect_info strDisconnectNotifInfo;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001780
Chaehyun Limbb76df52016-02-25 09:15:49 +09001781 memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001782
Chaehyun Lim90f209d2016-02-25 09:15:50 +09001783 strDisconnectNotifInfo.reason = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001784 strDisconnectNotifInfo.ie = NULL;
1785 strDisconnectNotifInfo.ie_len = 0;
1786
Leo Kimbc801852015-10-29 11:58:50 +09001787 if (hif_drv->usr_scan_req.scan_result) {
Leo Kim13b313e2015-10-29 11:58:34 +09001788 del_timer(&hif_drv->scan_timer);
Leo Kim33bfb192015-10-29 11:58:56 +09001789 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED,
1790 NULL,
1791 hif_drv->usr_scan_req.arg,
1792 NULL);
Leo Kimbc801852015-10-29 11:58:50 +09001793 hif_drv->usr_scan_req.scan_result = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001794 }
1795
Leo Kim33bfb192015-10-29 11:58:56 +09001796 if (hif_drv->usr_conn_req.conn_result) {
Chris Parkc4f97522016-02-04 18:24:04 +09001797 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
Leo Kim81a59502015-10-29 11:58:35 +09001798 del_timer(&hif_drv->connect_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001799
Leo Kim33bfb192015-10-29 11:58:56 +09001800 hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1801 NULL,
1802 0,
1803 &strDisconnectNotifInfo,
Leo Kim73abaa42015-10-29 12:05:27 +09001804 hif_drv->usr_conn_req.arg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001805 } else {
Chris Parkb92f9302016-02-22 13:12:02 +09001806 netdev_err(vif->ndev, "conn_result = NULL\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001807 }
1808
Leo Kimca8540e42015-10-15 13:25:00 +09001809 scan_while_connected = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001810
Leo Kimb60005a2015-10-29 11:58:24 +09001811 hif_drv->hif_state = HOST_IF_IDLE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001812
Leo Kim2a4eded2015-10-29 11:58:25 +09001813 eth_zero_addr(hif_drv->assoc_bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001814
Leo Kim74ab5e42015-10-29 11:58:53 +09001815 hif_drv->usr_conn_req.ssid_len = 0;
Chaehyun Lim72216412016-02-12 23:04:41 +09001816 kfree(hif_drv->usr_conn_req.ssid);
1817 hif_drv->usr_conn_req.ssid = NULL;
Chaehyun Lim788f6fc2016-02-12 23:04:40 +09001818 kfree(hif_drv->usr_conn_req.bssid);
1819 hif_drv->usr_conn_req.bssid = NULL;
Leo Kim331ed082015-10-29 11:58:55 +09001820 hif_drv->usr_conn_req.ies_len = 0;
Leo Kima3b2f4b2015-10-29 11:58:54 +09001821 kfree(hif_drv->usr_conn_req.ies);
Glen Leecc28e4b2015-12-18 18:26:02 +09001822 hif_drv->usr_conn_req.ies = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001823
Glen Lee7036c622015-12-21 14:18:45 +09001824 if (join_req && join_req_vif == vif) {
Leo Kim044a64102015-10-15 13:25:09 +09001825 kfree(join_req);
1826 join_req = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001827 }
Leo Kim48ce2462015-10-15 13:25:10 +09001828
Glen Lee7036c622015-12-21 14:18:45 +09001829 if (info_element && join_req_vif == vif) {
Leo Kim48ce2462015-10-15 13:25:10 +09001830 kfree(info_element);
1831 info_element = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001832 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001833 }
1834
Alison Schofield96adbd22016-03-14 10:35:05 -07001835 complete(&hif_drv->comp_test_disconn_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001836}
1837
Glen Leefbf53792015-12-21 14:18:40 +09001838void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001839{
Glen Leefbf53792015-12-21 14:18:40 +09001840 if (!vif->hif_drv)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001841 return;
Glen Leefbf53792015-12-21 14:18:40 +09001842 if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
Chris Parkc4f97522016-02-04 18:24:04 +09001843 (vif->hif_drv->hif_state == HOST_IF_CONNECTING))
Glen Leefbf53792015-12-21 14:18:40 +09001844 wilc_disconnect(vif, 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001845}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001846
Glen Lee71130e82015-12-21 14:18:41 +09001847static void Handle_GetRssi(struct wilc_vif *vif)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001848{
Leo Kim31390ee2015-10-19 18:26:08 +09001849 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09001850 struct wid wid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851
Leo Kim45102f82015-10-28 15:59:28 +09001852 wid.id = (u16)WID_RSSI;
1853 wid.type = WID_CHAR;
1854 wid.val = &rssi;
1855 wid.size = sizeof(char);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001856
Glen Lee79df6a42016-02-04 18:15:31 +09001857 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001858 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09001859 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09001860 netdev_err(vif->ndev, "Failed to get RSSI value\n");
Leo Kim31390ee2015-10-19 18:26:08 +09001861 result = -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001862 }
1863
Alison Schofield7c8a3dc2016-03-14 10:34:39 -07001864 complete(&vif->hif_drv->comp_get_rssi);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001865}
1866
Glen Lee71130e82015-12-21 14:18:41 +09001867static s32 Handle_GetStatistics(struct wilc_vif *vif,
1868 struct rf_info *pstrStatistics)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001869{
Leo Kime9e0c262015-10-12 16:55:41 +09001870 struct wid strWIDList[5];
Leo Kim31390ee2015-10-19 18:26:08 +09001871 u32 u32WidsCount = 0, result = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001872
Leo Kimdaaf16b2015-10-12 16:55:44 +09001873 strWIDList[u32WidsCount].id = WID_LINKSPEED;
Leo Kim416d8322015-10-12 16:55:43 +09001874 strWIDList[u32WidsCount].type = WID_CHAR;
Leo Kim2fd3e442015-10-12 16:55:45 +09001875 strWIDList[u32WidsCount].size = sizeof(char);
Leo Kim5babeec2015-10-29 12:05:29 +09001876 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->link_speed;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001877 u32WidsCount++;
1878
Leo Kimdaaf16b2015-10-12 16:55:44 +09001879 strWIDList[u32WidsCount].id = WID_RSSI;
Leo Kim416d8322015-10-12 16:55:43 +09001880 strWIDList[u32WidsCount].type = WID_CHAR;
Leo Kim2fd3e442015-10-12 16:55:45 +09001881 strWIDList[u32WidsCount].size = sizeof(char);
Leo Kim00c8dfc2015-10-29 12:05:30 +09001882 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001883 u32WidsCount++;
1884
Leo Kimdaaf16b2015-10-12 16:55:44 +09001885 strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
Leo Kim416d8322015-10-12 16:55:43 +09001886 strWIDList[u32WidsCount].type = WID_INT;
Leo Kim2fd3e442015-10-12 16:55:45 +09001887 strWIDList[u32WidsCount].size = sizeof(u32);
Leo Kim7e84ff42015-10-29 12:05:31 +09001888 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_cnt;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001889 u32WidsCount++;
1890
Leo Kimdaaf16b2015-10-12 16:55:44 +09001891 strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
Leo Kim416d8322015-10-12 16:55:43 +09001892 strWIDList[u32WidsCount].type = WID_INT;
Leo Kim2fd3e442015-10-12 16:55:45 +09001893 strWIDList[u32WidsCount].size = sizeof(u32);
Leo Kim9b992742015-10-29 12:05:32 +09001894 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rx_cnt;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001895 u32WidsCount++;
1896
Leo Kimdaaf16b2015-10-12 16:55:44 +09001897 strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
Leo Kim416d8322015-10-12 16:55:43 +09001898 strWIDList[u32WidsCount].type = WID_INT;
Leo Kim2fd3e442015-10-12 16:55:45 +09001899 strWIDList[u32WidsCount].size = sizeof(u32);
Leo Kim54160372015-10-29 12:05:33 +09001900 strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001901 u32WidsCount++;
1902
Glen Lee79df6a42016-02-04 18:15:31 +09001903 result = wilc_send_config_pkt(vif, GET_CFG, strWIDList,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001904 u32WidsCount,
1905 wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001906
Leo Kim31390ee2015-10-19 18:26:08 +09001907 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09001908 netdev_err(vif->ndev, "Failed to send scan parameters\n");
Leo Kim24db7132015-09-16 18:36:01 +09001909
Glen Lee4fd62292016-02-04 18:15:24 +09001910 if (pstrStatistics->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
1911 pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
1912 wilc_enable_tcp_ack_filter(true);
1913 else if (pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
1914 wilc_enable_tcp_ack_filter(false);
1915
1916 if (pstrStatistics != &vif->wilc->dummy_statistics)
Chaehyun Lim613eaa32016-03-14 09:40:27 +09001917 complete(&hif_wait_response);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001918 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001919}
1920
Glen Lee71130e82015-12-21 14:18:41 +09001921static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
Tony Cho3d1eac02015-09-21 12:16:49 +09001922 struct sta_inactive_t *strHostIfStaInactiveT)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001923{
Leo Kim31390ee2015-10-19 18:26:08 +09001924 s32 result = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001925 u8 *stamac;
Leo Kim45102f82015-10-28 15:59:28 +09001926 struct wid wid;
Glen Lee71130e82015-12-21 14:18:41 +09001927 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001928
Leo Kim45102f82015-10-28 15:59:28 +09001929 wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
1930 wid.type = WID_STR;
1931 wid.size = ETH_ALEN;
1932 wid.val = kmalloc(wid.size, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001933
Leo Kim45102f82015-10-28 15:59:28 +09001934 stamac = wid.val;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001935 memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001936
Glen Lee79df6a42016-02-04 18:15:31 +09001937 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001938 wilc_get_vif_idx(vif));
Leo Kimae4dfa52015-10-13 19:49:26 +09001939
Leo Kim31390ee2015-10-19 18:26:08 +09001940 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09001941 netdev_err(vif->ndev, "Failed to SET incative time\n");
Leo Kim24db7132015-09-16 18:36:01 +09001942 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001943 }
1944
Leo Kim45102f82015-10-28 15:59:28 +09001945 wid.id = (u16)WID_GET_INACTIVE_TIME;
1946 wid.type = WID_INT;
1947 wid.val = (s8 *)&inactive_time;
1948 wid.size = sizeof(u32);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001949
Glen Lee79df6a42016-02-04 18:15:31 +09001950 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09001951 wilc_get_vif_idx(vif));
Leo Kimae4dfa52015-10-13 19:49:26 +09001952
Leo Kim31390ee2015-10-19 18:26:08 +09001953 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09001954 netdev_err(vif->ndev, "Failed to get incative time\n");
Leo Kim24db7132015-09-16 18:36:01 +09001955 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001956 }
1957
Alison Schofielde0c14962016-03-14 10:34:14 -07001958 complete(&hif_drv->comp_inactive_time);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001959
Leo Kim31390ee2015-10-19 18:26:08 +09001960 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001961}
1962
Glen Lee71130e82015-12-21 14:18:41 +09001963static void Handle_AddBeacon(struct wilc_vif *vif,
Tony Cho7f33fec2015-09-30 18:44:30 +09001964 struct beacon_attr *pstrSetBeaconParam)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001965{
Leo Kim31390ee2015-10-19 18:26:08 +09001966 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09001967 struct wid wid;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001968 u8 *pu8CurrByte;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02001969
Leo Kim45102f82015-10-28 15:59:28 +09001970 wid.id = (u16)WID_ADD_BEACON;
1971 wid.type = WID_BIN;
1972 wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
1973 wid.val = kmalloc(wid.size, GFP_KERNEL);
1974 if (!wid.val)
Leo Kim24db7132015-09-16 18:36:01 +09001975 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001976
Leo Kim45102f82015-10-28 15:59:28 +09001977 pu8CurrByte = wid.val;
Leo Kim12262dd2015-10-13 19:50:03 +09001978 *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
1979 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
1980 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
1981 *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001982
Leo Kime76ab772015-10-13 19:50:04 +09001983 *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
1984 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
1985 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
1986 *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001987
Leo Kim51c66182015-10-13 19:50:05 +09001988 *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
1989 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
1990 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
1991 *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001992
Leo Kim8ce528b2015-10-13 19:50:06 +09001993 memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
Leo Kim51c66182015-10-13 19:50:05 +09001994 pu8CurrByte += pstrSetBeaconParam->head_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001995
Leo Kim030c57e2015-10-13 19:50:07 +09001996 *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
1997 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
1998 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
1999 *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002000
Mario J. Rugiero7cf8e592015-12-03 13:24:05 -03002001 if (pstrSetBeaconParam->tail)
Leo Kim7dbcb6d32015-10-13 19:50:08 +09002002 memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
Leo Kim030c57e2015-10-13 19:50:07 +09002003 pu8CurrByte += pstrSetBeaconParam->tail_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002004
Glen Lee79df6a42016-02-04 18:15:31 +09002005 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2006 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002007 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002008 netdev_err(vif->ndev, "Failed to send add beacon\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002009
Leo Kim24db7132015-09-16 18:36:01 +09002010ERRORHANDLER:
Leo Kim45102f82015-10-28 15:59:28 +09002011 kfree(wid.val);
Leo Kim8ce528b2015-10-13 19:50:06 +09002012 kfree(pstrSetBeaconParam->head);
Leo Kim7dbcb6d32015-10-13 19:50:08 +09002013 kfree(pstrSetBeaconParam->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002014}
2015
Glen Lee71130e82015-12-21 14:18:41 +09002016static void Handle_DelBeacon(struct wilc_vif *vif)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002017{
Leo Kim31390ee2015-10-19 18:26:08 +09002018 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09002019 struct wid wid;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002020 u8 *pu8CurrByte;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02002021
Leo Kim45102f82015-10-28 15:59:28 +09002022 wid.id = (u16)WID_DEL_BEACON;
2023 wid.type = WID_CHAR;
2024 wid.size = sizeof(char);
2025 wid.val = &del_beacon;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002026
Leo Kim45102f82015-10-28 15:59:28 +09002027 if (!wid.val)
Leo Kim24db7132015-09-16 18:36:01 +09002028 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002029
Leo Kim45102f82015-10-28 15:59:28 +09002030 pu8CurrByte = wid.val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002031
Glen Lee79df6a42016-02-04 18:15:31 +09002032 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002033 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002034 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002035 netdev_err(vif->ndev, "Failed to send delete beacon\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002036}
2037
Tony Cho6a89ba92015-09-21 12:16:46 +09002038static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2039 struct add_sta_param *pstrStationParam)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002040{
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002041 u8 *pu8CurrByte;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002042
2043 pu8CurrByte = pu8Buffer;
2044
Leo Kim2353c382015-10-29 12:05:41 +09002045 memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002046 pu8CurrByte += ETH_ALEN;
2047
Leo Kim4101eb82015-10-29 12:05:42 +09002048 *pu8CurrByte++ = pstrStationParam->aid & 0xFF;
2049 *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002050
Leo Kime7342232015-10-29 12:05:43 +09002051 *pu8CurrByte++ = pstrStationParam->rates_len;
2052 if (pstrStationParam->rates_len > 0)
Leo Kima622e012015-10-29 12:05:44 +09002053 memcpy(pu8CurrByte, pstrStationParam->rates,
Leo Kime7342232015-10-29 12:05:43 +09002054 pstrStationParam->rates_len);
2055 pu8CurrByte += pstrStationParam->rates_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002056
Leo Kim22520122015-10-29 12:05:45 +09002057 *pu8CurrByte++ = pstrStationParam->ht_supported;
Leo Kim0d073f62015-10-29 12:05:46 +09002058 *pu8CurrByte++ = pstrStationParam->ht_capa_info & 0xFF;
2059 *pu8CurrByte++ = (pstrStationParam->ht_capa_info >> 8) & 0xFF;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002060
Leo Kimfba1f2d2015-10-29 12:05:47 +09002061 *pu8CurrByte++ = pstrStationParam->ht_ampdu_params;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002062 memcpy(pu8CurrByte, pstrStationParam->ht_supp_mcs_set,
2063 WILC_SUPP_MCS_SET_SIZE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002064 pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
2065
Leo Kim223741d2015-10-29 12:05:49 +09002066 *pu8CurrByte++ = pstrStationParam->ht_ext_params & 0xFF;
2067 *pu8CurrByte++ = (pstrStationParam->ht_ext_params >> 8) & 0xFF;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002068
Leo Kim74fe73c2015-10-29 12:05:50 +09002069 *pu8CurrByte++ = pstrStationParam->ht_tx_bf_cap & 0xFF;
2070 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 8) & 0xFF;
2071 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 16) & 0xFF;
2072 *pu8CurrByte++ = (pstrStationParam->ht_tx_bf_cap >> 24) & 0xFF;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002073
Leo Kima486baf2015-10-29 12:05:51 +09002074 *pu8CurrByte++ = pstrStationParam->ht_ante_sel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002075
Leo Kimf676e172015-10-29 12:05:52 +09002076 *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF;
2077 *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002078
Leo Kim67ab64e2015-10-29 12:05:53 +09002079 *pu8CurrByte++ = pstrStationParam->flags_set & 0xFF;
2080 *pu8CurrByte++ = (pstrStationParam->flags_set >> 8) & 0xFF;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002081
2082 return pu8CurrByte - pu8Buffer;
2083}
2084
Glen Lee71130e82015-12-21 14:18:41 +09002085static void Handle_AddStation(struct wilc_vif *vif,
Tony Cho6a89ba92015-09-21 12:16:46 +09002086 struct add_sta_param *pstrStationParam)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002087{
Leo Kim31390ee2015-10-19 18:26:08 +09002088 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09002089 struct wid wid;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002090 u8 *pu8CurrByte;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02002091
Leo Kim45102f82015-10-28 15:59:28 +09002092 wid.id = (u16)WID_ADD_STA;
2093 wid.type = WID_BIN;
Leo Kime7342232015-10-29 12:05:43 +09002094 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002095
Leo Kim45102f82015-10-28 15:59:28 +09002096 wid.val = kmalloc(wid.size, GFP_KERNEL);
2097 if (!wid.val)
Leo Kim24db7132015-09-16 18:36:01 +09002098 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002099
Leo Kim45102f82015-10-28 15:59:28 +09002100 pu8CurrByte = wid.val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002101 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2102
Glen Lee79df6a42016-02-04 18:15:31 +09002103 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002104 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002105 if (result != 0)
Chris Parkb92f9302016-02-22 13:12:02 +09002106 netdev_err(vif->ndev, "Failed to send add station\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002107
Leo Kim24db7132015-09-16 18:36:01 +09002108ERRORHANDLER:
Leo Kima622e012015-10-29 12:05:44 +09002109 kfree(pstrStationParam->rates);
Leo Kim45102f82015-10-28 15:59:28 +09002110 kfree(wid.val);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002111}
2112
Glen Lee71130e82015-12-21 14:18:41 +09002113static void Handle_DelAllSta(struct wilc_vif *vif,
Tony Chob4e644e2015-09-21 12:17:00 +09002114 struct del_all_sta *pstrDelAllStaParam)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002115{
Leo Kim31390ee2015-10-19 18:26:08 +09002116 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09002117 struct wid wid;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002118 u8 *pu8CurrByte;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002119 u8 i;
Chaehyun Lim37034802015-06-11 14:34:32 +09002120 u8 au8Zero_Buff[6] = {0};
Luis de Bethencourt78c87592015-06-26 16:45:14 +02002121
Leo Kim45102f82015-10-28 15:59:28 +09002122 wid.id = (u16)WID_DEL_ALL_STA;
2123 wid.type = WID_STR;
2124 wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002125
Leo Kim45102f82015-10-28 15:59:28 +09002126 wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2127 if (!wid.val)
Leo Kim24db7132015-09-16 18:36:01 +09002128 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002129
Leo Kim45102f82015-10-28 15:59:28 +09002130 pu8CurrByte = wid.val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002131
Leo Kim8ba18032015-10-13 19:50:10 +09002132 *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002133
2134 for (i = 0; i < MAX_NUM_STA; i++) {
Leo Kime51b9212015-10-13 19:50:09 +09002135 if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2136 memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002137 else
2138 continue;
2139
2140 pu8CurrByte += ETH_ALEN;
2141 }
2142
Glen Lee79df6a42016-02-04 18:15:31 +09002143 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002144 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002145 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002146 netdev_err(vif->ndev, "Failed to send add station\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002147
Leo Kim24db7132015-09-16 18:36:01 +09002148ERRORHANDLER:
Leo Kim45102f82015-10-28 15:59:28 +09002149 kfree(wid.val);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002150
Chaehyun Lim613eaa32016-03-14 09:40:27 +09002151 complete(&hif_wait_response);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002152}
2153
Glen Lee71130e82015-12-21 14:18:41 +09002154static void Handle_DelStation(struct wilc_vif *vif,
Tony Chofb93a1e2015-09-21 12:16:57 +09002155 struct del_sta *pstrDelStaParam)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002156{
Leo Kim31390ee2015-10-19 18:26:08 +09002157 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09002158 struct wid wid;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002159 u8 *pu8CurrByte;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160
Leo Kim45102f82015-10-28 15:59:28 +09002161 wid.id = (u16)WID_REMOVE_STA;
2162 wid.type = WID_BIN;
2163 wid.size = ETH_ALEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002164
Leo Kim45102f82015-10-28 15:59:28 +09002165 wid.val = kmalloc(wid.size, GFP_KERNEL);
2166 if (!wid.val)
Leo Kim24db7132015-09-16 18:36:01 +09002167 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002168
Leo Kim45102f82015-10-28 15:59:28 +09002169 pu8CurrByte = wid.val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002170
Leo Kime4839d32015-10-13 20:02:06 +09002171 memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002172
Glen Lee79df6a42016-02-04 18:15:31 +09002173 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002174 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002175 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002176 netdev_err(vif->ndev, "Failed to send add station\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002177
Leo Kim24db7132015-09-16 18:36:01 +09002178ERRORHANDLER:
Leo Kim45102f82015-10-28 15:59:28 +09002179 kfree(wid.val);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002180}
2181
Glen Lee71130e82015-12-21 14:18:41 +09002182static void Handle_EditStation(struct wilc_vif *vif,
Tony Cho6a89ba92015-09-21 12:16:46 +09002183 struct add_sta_param *pstrStationParam)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002184{
Leo Kim31390ee2015-10-19 18:26:08 +09002185 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09002186 struct wid wid;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002187 u8 *pu8CurrByte;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002188
Leo Kim45102f82015-10-28 15:59:28 +09002189 wid.id = (u16)WID_EDIT_STA;
2190 wid.type = WID_BIN;
Leo Kime7342232015-10-29 12:05:43 +09002191 wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002192
Leo Kim45102f82015-10-28 15:59:28 +09002193 wid.val = kmalloc(wid.size, GFP_KERNEL);
2194 if (!wid.val)
Leo Kim24db7132015-09-16 18:36:01 +09002195 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002196
Leo Kim45102f82015-10-28 15:59:28 +09002197 pu8CurrByte = wid.val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002198 pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2199
Glen Lee79df6a42016-02-04 18:15:31 +09002200 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002201 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002202 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002203 netdev_err(vif->ndev, "Failed to send edit station\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002204
Leo Kim24db7132015-09-16 18:36:01 +09002205ERRORHANDLER:
Leo Kima622e012015-10-29 12:05:44 +09002206 kfree(pstrStationParam->rates);
Leo Kim45102f82015-10-28 15:59:28 +09002207 kfree(wid.val);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002208}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002209
Glen Lee71130e82015-12-21 14:18:41 +09002210static int Handle_RemainOnChan(struct wilc_vif *vif,
Tony Cho2f9c03f2015-09-21 12:16:58 +09002211 struct remain_ch *pstrHostIfRemainOnChan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002212{
Leo Kim31390ee2015-10-19 18:26:08 +09002213 s32 result = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002214 u8 u8remain_on_chan_flag;
Leo Kim45102f82015-10-28 15:59:28 +09002215 struct wid wid;
Glen Lee71130e82015-12-21 14:18:41 +09002216 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002217
Leo Kim5beef2c2015-10-28 15:59:36 +09002218 if (!hif_drv->remain_on_ch_pending) {
Leo Kimc5cc4b12015-10-29 11:58:44 +09002219 hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg;
Leo Kimbfb62ab2015-10-29 11:58:42 +09002220 hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired;
Leo Kim5e5f7912015-10-29 11:58:43 +09002221 hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready;
Leo Kim839ab702015-10-29 11:58:41 +09002222 hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch;
Leo Kim9d764e32015-10-29 12:05:38 +09002223 hif_drv->remain_on_ch.id = pstrHostIfRemainOnChan->id;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002224 } else {
Leo Kim839ab702015-10-29 11:58:41 +09002225 pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002226 }
2227
Leo Kimbc801852015-10-29 11:58:50 +09002228 if (hif_drv->usr_scan_req.scan_result) {
Leo Kim5beef2c2015-10-28 15:59:36 +09002229 hif_drv->remain_on_ch_pending = 1;
Leo Kim31390ee2015-10-19 18:26:08 +09002230 result = -EBUSY;
Leo Kim24db7132015-09-16 18:36:01 +09002231 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002232 }
Leo Kimb60005a2015-10-29 11:58:24 +09002233 if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
Leo Kim31390ee2015-10-19 18:26:08 +09002234 result = -EBUSY;
Leo Kim24db7132015-09-16 18:36:01 +09002235 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002236 }
2237
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002238 if (wilc_optaining_ip || wilc_connecting) {
Leo Kim31390ee2015-10-19 18:26:08 +09002239 result = -EBUSY;
Leo Kim24db7132015-09-16 18:36:01 +09002240 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002241 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002242
Dean Lee72ed4dc2015-06-12 14:11:44 +09002243 u8remain_on_chan_flag = true;
Leo Kim45102f82015-10-28 15:59:28 +09002244 wid.id = (u16)WID_REMAIN_ON_CHAN;
2245 wid.type = WID_STR;
2246 wid.size = 2;
2247 wid.val = kmalloc(wid.size, GFP_KERNEL);
2248 if (!wid.val) {
Leo Kim31390ee2015-10-19 18:26:08 +09002249 result = -ENOMEM;
Leo Kim24db7132015-09-16 18:36:01 +09002250 goto ERRORHANDLER;
2251 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002252
Leo Kim45102f82015-10-28 15:59:28 +09002253 wid.val[0] = u8remain_on_chan_flag;
Leo Kim839ab702015-10-29 11:58:41 +09002254 wid.val[1] = (s8)pstrHostIfRemainOnChan->ch;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002255
Glen Lee79df6a42016-02-04 18:15:31 +09002256 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002257 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002258 if (result != 0)
Chris Parkb92f9302016-02-22 13:12:02 +09002259 netdev_err(vif->ndev, "Failed to set remain on channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002260
Leo Kim24db7132015-09-16 18:36:01 +09002261ERRORHANDLER:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002262 {
2263 P2P_LISTEN_STATE = 1;
Glen Lee71130e82015-12-21 14:18:41 +09002264 hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
Leo Kimcc2d7e92015-10-29 11:58:36 +09002265 mod_timer(&hif_drv->remain_on_ch_timer,
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -07002266 jiffies +
Chaehyun Limfb6e0682016-01-03 17:35:33 +09002267 msecs_to_jiffies(pstrHostIfRemainOnChan->duration));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002268
Leo Kim5e5f7912015-10-29 11:58:43 +09002269 if (hif_drv->remain_on_ch.ready)
Leo Kimc5cc4b12015-10-29 11:58:44 +09002270 hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002271
Leo Kim5beef2c2015-10-28 15:59:36 +09002272 if (hif_drv->remain_on_ch_pending)
2273 hif_drv->remain_on_ch_pending = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002274 }
Leo Kim31390ee2015-10-19 18:26:08 +09002275
2276 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002277}
2278
Glen Lee71130e82015-12-21 14:18:41 +09002279static int Handle_RegisterFrame(struct wilc_vif *vif,
Tony Chobc37c5d2015-09-21 12:16:59 +09002280 struct reg_frame *pstrHostIfRegisterFrame)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002281{
Leo Kim31390ee2015-10-19 18:26:08 +09002282 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09002283 struct wid wid;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002284 u8 *pu8CurrByte;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002285
Leo Kim45102f82015-10-28 15:59:28 +09002286 wid.id = (u16)WID_REGISTER_FRAME;
2287 wid.type = WID_STR;
2288 wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2289 if (!wid.val)
Leo Kim24db7132015-09-16 18:36:01 +09002290 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002291
Leo Kim45102f82015-10-28 15:59:28 +09002292 pu8CurrByte = wid.val;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002293
Leo Kim6abf8682015-10-29 11:58:38 +09002294 *pu8CurrByte++ = pstrHostIfRegisterFrame->reg;
Leo Kimbcb410b2015-10-29 11:58:40 +09002295 *pu8CurrByte++ = pstrHostIfRegisterFrame->reg_id;
Leo Kimd5f654c2015-10-29 11:58:39 +09002296 memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002297
Leo Kim45102f82015-10-28 15:59:28 +09002298 wid.size = sizeof(u16) + 2;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002299
Glen Lee79df6a42016-02-04 18:15:31 +09002300 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002301 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002302 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09002303 netdev_err(vif->ndev, "Failed to frame register\n");
Leo Kim31390ee2015-10-19 18:26:08 +09002304 result = -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002305 }
2306
Leo Kim31390ee2015-10-19 18:26:08 +09002307 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002308}
2309
Glen Lee71130e82015-12-21 14:18:41 +09002310static u32 Handle_ListenStateExpired(struct wilc_vif *vif,
Tony Cho2f9c03f2015-09-21 12:16:58 +09002311 struct remain_ch *pstrHostIfRemainOnChan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002312{
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002313 u8 u8remain_on_chan_flag;
Leo Kim45102f82015-10-28 15:59:28 +09002314 struct wid wid;
Leo Kim31390ee2015-10-19 18:26:08 +09002315 s32 result = 0;
Glen Lee71130e82015-12-21 14:18:41 +09002316 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002317
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002318 if (P2P_LISTEN_STATE) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09002319 u8remain_on_chan_flag = false;
Leo Kim45102f82015-10-28 15:59:28 +09002320 wid.id = (u16)WID_REMAIN_ON_CHAN;
2321 wid.type = WID_STR;
2322 wid.size = 2;
2323 wid.val = kmalloc(wid.size, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002324
Leo Kim653bb462015-12-21 14:18:24 +09002325 if (!wid.val) {
Chris Parkb92f9302016-02-22 13:12:02 +09002326 netdev_err(vif->ndev, "Failed to allocate memory\n");
Leo Kim653bb462015-12-21 14:18:24 +09002327 return -ENOMEM;
2328 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002329
Leo Kim45102f82015-10-28 15:59:28 +09002330 wid.val[0] = u8remain_on_chan_flag;
2331 wid.val[1] = FALSE_FRMWR_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002332
Glen Lee79df6a42016-02-04 18:15:31 +09002333 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002334 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002335 if (result != 0) {
Chris Parkb92f9302016-02-22 13:12:02 +09002336 netdev_err(vif->ndev, "Failed to set remain channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002337 goto _done_;
2338 }
2339
Leo Kimbfb62ab2015-10-29 11:58:42 +09002340 if (hif_drv->remain_on_ch.expired) {
Leo Kimc5cc4b12015-10-29 11:58:44 +09002341 hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
Leo Kim9d764e32015-10-29 12:05:38 +09002342 pstrHostIfRemainOnChan->id);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002343 }
2344 P2P_LISTEN_STATE = 0;
2345 } else {
Chris Parke3f16962016-02-04 18:24:30 +09002346 netdev_dbg(vif->ndev, "Not in listen state\n");
Leo Kim31390ee2015-10-19 18:26:08 +09002347 result = -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002348 }
2349
2350_done_:
Leo Kim31390ee2015-10-19 18:26:08 +09002351 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002352}
2353
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07002354static void ListenTimerCB(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002355{
Leo Kim31390ee2015-10-19 18:26:08 +09002356 s32 result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002357 struct host_if_msg msg;
Glen Lee71130e82015-12-21 14:18:41 +09002358 struct wilc_vif *vif = (struct wilc_vif *)arg;
Leo Kimae4dfa52015-10-13 19:49:26 +09002359
Glen Lee71130e82015-12-21 14:18:41 +09002360 del_timer(&vif->hif_drv->remain_on_ch_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002361
Tony Cho143eb952015-09-21 12:16:32 +09002362 memset(&msg, 0, sizeof(struct host_if_msg));
Tony Choa9f812a2015-09-21 12:16:33 +09002363 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
Glen Lee71130e82015-12-21 14:18:41 +09002364 msg.vif = vif;
2365 msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002366
Binoy Jayana5c84b22016-06-23 11:11:52 +05302367 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09002368 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002369 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002370}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002371
Glen Lee71130e82015-12-21 14:18:41 +09002372static void Handle_PowerManagement(struct wilc_vif *vif,
Tony Cho5a008f12015-09-21 12:16:48 +09002373 struct power_mgmt_param *strPowerMgmtParam)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002374{
Leo Kim31390ee2015-10-19 18:26:08 +09002375 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09002376 struct wid wid;
Chaehyun Limca356ad2015-06-11 14:35:57 +09002377 s8 s8PowerMode;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02002378
Leo Kim45102f82015-10-28 15:59:28 +09002379 wid.id = (u16)WID_POWER_MANAGEMENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002380
Punit Vara047e6642015-10-25 04:01:25 +05302381 if (strPowerMgmtParam->enabled)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002382 s8PowerMode = MIN_FAST_PS;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05302383 else
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002384 s8PowerMode = NO_POWERSAVE;
Chris Parkc4f97522016-02-04 18:24:04 +09002385
Leo Kim45102f82015-10-28 15:59:28 +09002386 wid.val = &s8PowerMode;
2387 wid.size = sizeof(char);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002388
Glen Lee79df6a42016-02-04 18:15:31 +09002389 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002390 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002391 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002392 netdev_err(vif->ndev, "Failed to send power management\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393}
2394
Glen Lee71130e82015-12-21 14:18:41 +09002395static void Handle_SetMulticastFilter(struct wilc_vif *vif,
Tony Cho641210a2015-09-21 12:16:52 +09002396 struct set_multicast *strHostIfSetMulti)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002397{
Leo Kim31390ee2015-10-19 18:26:08 +09002398 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09002399 struct wid wid;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002400 u8 *pu8CurrByte;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002401
Leo Kim45102f82015-10-28 15:59:28 +09002402 wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2403 wid.type = WID_BIN;
2404 wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
2405 wid.val = kmalloc(wid.size, GFP_KERNEL);
2406 if (!wid.val)
Leo Kim24db7132015-09-16 18:36:01 +09002407 goto ERRORHANDLER;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002408
Leo Kim45102f82015-10-28 15:59:28 +09002409 pu8CurrByte = wid.val;
Leo Kimbae636eb2015-10-13 20:02:04 +09002410 *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
Leo Kimc8751ad2015-11-25 11:59:49 +09002411 *pu8CurrByte++ = 0;
2412 *pu8CurrByte++ = 0;
2413 *pu8CurrByte++ = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002414
Leo Kimadab2f72015-10-13 20:02:05 +09002415 *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2416 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2417 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2418 *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002419
Leo Kimadab2f72015-10-13 20:02:05 +09002420 if ((strHostIfSetMulti->cnt) > 0)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002421 memcpy(pu8CurrByte, wilc_multicast_mac_addr_list,
Leo Kimfb70e9f2015-11-05 14:36:09 +09002422 ((strHostIfSetMulti->cnt) * ETH_ALEN));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002423
Glen Lee79df6a42016-02-04 18:15:31 +09002424 result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09002425 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09002426 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002427 netdev_err(vif->ndev, "Failed to send setup multicast\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002428
Leo Kim24db7132015-09-16 18:36:01 +09002429ERRORHANDLER:
Leo Kim45102f82015-10-28 15:59:28 +09002430 kfree(wid.val);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002431}
2432
Glen Lee70418792016-02-04 18:15:27 +09002433static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
2434{
2435 int ret;
2436 struct wid wid;
2437
2438 wid.id = (u16)WID_TX_POWER;
2439 wid.type = WID_CHAR;
2440 wid.val = &tx_pwr;
2441 wid.size = sizeof(char);
2442
Glen Lee79df6a42016-02-04 18:15:31 +09002443 ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2444 wilc_get_vif_idx(vif));
Glen Lee70418792016-02-04 18:15:27 +09002445 if (ret)
2446 netdev_err(vif->ndev, "Failed to set TX PWR\n");
2447}
2448
2449static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
2450{
Chaehyun Lim12915c52016-04-07 08:10:37 +09002451 int ret = 0;
Glen Lee70418792016-02-04 18:15:27 +09002452 struct wid wid;
2453
2454 wid.id = (u16)WID_TX_POWER;
2455 wid.type = WID_CHAR;
2456 wid.val = (s8 *)tx_pwr;
2457 wid.size = sizeof(char);
2458
Glen Lee79df6a42016-02-04 18:15:31 +09002459 ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2460 wilc_get_vif_idx(vif));
Glen Lee70418792016-02-04 18:15:27 +09002461 if (ret)
2462 netdev_err(vif->ndev, "Failed to get TX PWR\n");
2463
Chaehyun Lim613eaa32016-03-14 09:40:27 +09002464 complete(&hif_wait_response);
Glen Lee70418792016-02-04 18:15:27 +09002465}
2466
Binoy Jayan2518ac52016-06-23 11:11:51 +05302467static void host_if_work(struct work_struct *work)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002468{
Binoy Jayan2518ac52016-06-23 11:11:51 +05302469 struct host_if_msg *msg;
2470 struct wilc *wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002471
Binoy Jayan2518ac52016-06-23 11:11:51 +05302472 msg = container_of(work, struct host_if_msg, work);
2473 wilc = msg->vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002474
Binoy Jayan2518ac52016-06-23 11:11:51 +05302475 if (msg->id == HOST_IF_MSG_CONNECT &&
2476 msg->vif->hif_drv->usr_scan_req.scan_result) {
Binoy Jayana5c84b22016-06-23 11:11:52 +05302477 wilc_enqueue_cmd(msg);
Binoy Jayan2518ac52016-06-23 11:11:51 +05302478 usleep_range(2 * 1000, 2 * 1000);
Binoy Jayana5c84b22016-06-23 11:11:52 +05302479 goto free_msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002480 }
Binoy Jayana5c84b22016-06-23 11:11:52 +05302481 switch (msg->id) {
2482 case HOST_IF_MSG_SCAN:
2483 handle_scan(msg->vif, &msg->body.scan_info);
2484 break;
2485
2486 case HOST_IF_MSG_CONNECT:
2487 Handle_Connect(msg->vif, &msg->body.con_info);
2488 break;
2489
2490 case HOST_IF_MSG_RCVD_NTWRK_INFO:
2491 Handle_RcvdNtwrkInfo(msg->vif, &msg->body.net_info);
2492 break;
2493
2494 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2495 Handle_RcvdGnrlAsyncInfo(msg->vif,
2496 &msg->body.async_info);
2497 break;
2498
2499 case HOST_IF_MSG_KEY:
2500 Handle_Key(msg->vif, &msg->body.key_info);
2501 break;
2502
2503 case HOST_IF_MSG_CFG_PARAMS:
2504 handle_cfg_param(msg->vif, &msg->body.cfg_info);
2505 break;
2506
2507 case HOST_IF_MSG_SET_CHANNEL:
2508 handle_set_channel(msg->vif, &msg->body.channel_info);
2509 break;
2510
2511 case HOST_IF_MSG_DISCONNECT:
2512 Handle_Disconnect(msg->vif);
2513 break;
2514
2515 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2516 del_timer(&msg->vif->hif_drv->scan_timer);
2517
2518 if (!wilc_wlan_get_num_conn_ifcs(wilc))
2519 wilc_chip_sleep_manually(wilc);
2520
2521 Handle_ScanDone(msg->vif, SCAN_EVENT_DONE);
2522
2523 if (msg->vif->hif_drv->remain_on_ch_pending)
2524 Handle_RemainOnChan(msg->vif,
2525 &msg->body.remain_on_ch);
2526
2527 break;
2528
2529 case HOST_IF_MSG_GET_RSSI:
2530 Handle_GetRssi(msg->vif);
2531 break;
2532
2533 case HOST_IF_MSG_GET_STATISTICS:
2534 Handle_GetStatistics(msg->vif,
2535 (struct rf_info *)msg->body.data);
2536 break;
2537
2538 case HOST_IF_MSG_ADD_BEACON:
2539 Handle_AddBeacon(msg->vif, &msg->body.beacon_info);
2540 break;
2541
2542 case HOST_IF_MSG_DEL_BEACON:
2543 Handle_DelBeacon(msg->vif);
2544 break;
2545
2546 case HOST_IF_MSG_ADD_STATION:
2547 Handle_AddStation(msg->vif, &msg->body.add_sta_info);
2548 break;
2549
2550 case HOST_IF_MSG_DEL_STATION:
2551 Handle_DelStation(msg->vif, &msg->body.del_sta_info);
2552 break;
2553
2554 case HOST_IF_MSG_EDIT_STATION:
2555 Handle_EditStation(msg->vif, &msg->body.edit_sta_info);
2556 break;
2557
2558 case HOST_IF_MSG_GET_INACTIVETIME:
2559 Handle_Get_InActiveTime(msg->vif, &msg->body.mac_info);
2560 break;
2561
2562 case HOST_IF_MSG_SCAN_TIMER_FIRED:
2563 Handle_ScanDone(msg->vif, SCAN_EVENT_ABORTED);
2564 break;
2565
2566 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2567 Handle_ConnectTimeout(msg->vif);
2568 break;
2569
2570 case HOST_IF_MSG_POWER_MGMT:
2571 Handle_PowerManagement(msg->vif,
2572 &msg->body.pwr_mgmt_info);
2573 break;
2574
2575 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2576 handle_set_wfi_drv_handler(msg->vif, &msg->body.drv);
2577 break;
2578
2579 case HOST_IF_MSG_SET_OPERATION_MODE:
2580 handle_set_operation_mode(msg->vif, &msg->body.mode);
2581 break;
2582
2583 case HOST_IF_MSG_SET_IPADDRESS:
2584 handle_set_ip_address(msg->vif,
2585 msg->body.ip_info.ip_addr,
2586 msg->body.ip_info.idx);
2587 break;
2588
2589 case HOST_IF_MSG_GET_IPADDRESS:
2590 handle_get_ip_address(msg->vif, msg->body.ip_info.idx);
2591 break;
2592
2593 case HOST_IF_MSG_GET_MAC_ADDRESS:
2594 handle_get_mac_address(msg->vif,
2595 &msg->body.get_mac_info);
2596 break;
2597
2598 case HOST_IF_MSG_REMAIN_ON_CHAN:
2599 Handle_RemainOnChan(msg->vif, &msg->body.remain_on_ch);
2600 break;
2601
2602 case HOST_IF_MSG_REGISTER_FRAME:
2603 Handle_RegisterFrame(msg->vif, &msg->body.reg_frame);
2604 break;
2605
2606 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2607 Handle_ListenStateExpired(msg->vif, &msg->body.remain_on_ch);
2608 break;
2609
2610 case HOST_IF_MSG_SET_MULTICAST_FILTER:
2611 Handle_SetMulticastFilter(msg->vif, &msg->body.multicast_info);
2612 break;
2613
2614 case HOST_IF_MSG_DEL_ALL_STA:
2615 Handle_DelAllSta(msg->vif, &msg->body.del_all_sta_info);
2616 break;
2617
2618 case HOST_IF_MSG_SET_TX_POWER:
2619 handle_set_tx_pwr(msg->vif, msg->body.tx_power.tx_pwr);
2620 break;
2621
2622 case HOST_IF_MSG_GET_TX_POWER:
2623 handle_get_tx_pwr(msg->vif, &msg->body.tx_power.tx_pwr);
2624 break;
2625 default:
2626 netdev_err(msg->vif->ndev, "[Host Interface] undefined\n");
2627 break;
2628 }
2629free_msg:
Binoy Jayan2518ac52016-06-23 11:11:51 +05302630 kfree(msg);
Chaehyun Lim04dd9a42016-03-23 21:28:33 +09002631 complete(&hif_thread_comp);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002632}
2633
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07002634static void TimerCB_Scan(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002635{
Glen Lee71130e82015-12-21 14:18:41 +09002636 struct wilc_vif *vif = (struct wilc_vif *)arg;
Tony Cho143eb952015-09-21 12:16:32 +09002637 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002638
Tony Cho143eb952015-09-21 12:16:32 +09002639 memset(&msg, 0, sizeof(struct host_if_msg));
Glen Lee71130e82015-12-21 14:18:41 +09002640 msg.vif = vif;
Tony Choa9f812a2015-09-21 12:16:33 +09002641 msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002642
Binoy Jayana5c84b22016-06-23 11:11:52 +05302643 wilc_enqueue_cmd(&msg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002644}
2645
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07002646static void TimerCB_Connect(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002647{
Glen Lee71130e82015-12-21 14:18:41 +09002648 struct wilc_vif *vif = (struct wilc_vif *)arg;
Tony Cho143eb952015-09-21 12:16:32 +09002649 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002650
Tony Cho143eb952015-09-21 12:16:32 +09002651 memset(&msg, 0, sizeof(struct host_if_msg));
Glen Lee71130e82015-12-21 14:18:41 +09002652 msg.vif = vif;
Tony Choa9f812a2015-09-21 12:16:33 +09002653 msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002654
Binoy Jayana5c84b22016-06-23 11:11:52 +05302655 wilc_enqueue_cmd(&msg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002656}
2657
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002658s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002659{
Leo Kim45102f82015-10-28 15:59:28 +09002660 struct wid wid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002661
Leo Kim45102f82015-10-28 15:59:28 +09002662 wid.id = (u16)WID_REMOVE_KEY;
2663 wid.type = WID_STR;
2664 wid.val = (s8 *)pu8StaAddress;
2665 wid.size = 6;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002666
Leo Kimb68d820b2015-10-12 16:55:37 +09002667 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002668}
2669
Glen Leefbf53792015-12-21 14:18:40 +09002670int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002671{
Chaehyun Lim9e5e8b42015-10-05 19:35:00 +09002672 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002673 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09002674 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002675
Tony Choa4ab1ad2015-10-12 16:56:05 +09002676 if (!hif_drv) {
Chaehyun Lim9e5e8b42015-10-05 19:35:00 +09002677 result = -EFAULT;
Chris Parkb92f9302016-02-22 13:12:02 +09002678 netdev_err(vif->ndev, "Failed to send setup multicast\n");
Chaehyun Lim9e5e8b42015-10-05 19:35:00 +09002679 return result;
Leo Kim24db7132015-09-16 18:36:01 +09002680 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002681
Tony Cho143eb952015-09-21 12:16:32 +09002682 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683
Tony Choa9f812a2015-09-21 12:16:33 +09002684 msg.id = HOST_IF_MSG_KEY;
Leo Kim8e9f4272015-10-13 19:49:27 +09002685 msg.body.key_info.type = WEP;
Leo Kim0d17e382015-10-13 19:49:28 +09002686 msg.body.key_info.action = REMOVEKEY;
Glen Leecf601062015-12-21 14:18:39 +09002687 msg.vif = vif;
Leo Kim73b2e382015-10-13 19:49:29 +09002688 msg.body.key_info.attr.wep.index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002689
Binoy Jayana5c84b22016-06-23 11:11:52 +05302690 result = wilc_enqueue_cmd(&msg);
Chaehyun Lim9e5e8b42015-10-05 19:35:00 +09002691 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002692 netdev_err(vif->ndev, "Request to remove WEP key\n");
Leo Kim27e1f132016-04-01 17:44:13 +09002693 else
2694 wait_for_completion(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002695
Chaehyun Lim9e5e8b42015-10-05 19:35:00 +09002696 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002697}
2698
Glen Leefbf53792015-12-21 14:18:40 +09002699int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002700{
Chaehyun Lim5b41c7c2015-10-26 09:44:42 +09002701 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002702 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09002703 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002704
Tony Choa4ab1ad2015-10-12 16:56:05 +09002705 if (!hif_drv) {
Leo Kim31390ee2015-10-19 18:26:08 +09002706 result = -EFAULT;
Chris Parkb92f9302016-02-22 13:12:02 +09002707 netdev_err(vif->ndev, "driver is null\n");
Leo Kim31390ee2015-10-19 18:26:08 +09002708 return result;
Leo Kim24db7132015-09-16 18:36:01 +09002709 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002710
Tony Cho143eb952015-09-21 12:16:32 +09002711 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002712
Tony Choa9f812a2015-09-21 12:16:33 +09002713 msg.id = HOST_IF_MSG_KEY;
Leo Kim8e9f4272015-10-13 19:49:27 +09002714 msg.body.key_info.type = WEP;
Leo Kim0d17e382015-10-13 19:49:28 +09002715 msg.body.key_info.action = DEFAULTKEY;
Glen Leecf601062015-12-21 14:18:39 +09002716 msg.vif = vif;
Chaehyun Lime91d0342015-10-26 09:44:44 +09002717 msg.body.key_info.attr.wep.index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002718
Binoy Jayana5c84b22016-06-23 11:11:52 +05302719 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09002720 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002721 netdev_err(vif->ndev, "Default key index\n");
Leo Kim27e1f132016-04-01 17:44:13 +09002722 else
2723 wait_for_completion(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002724
Leo Kim31390ee2015-10-19 18:26:08 +09002725 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002726}
2727
Glen Leefbf53792015-12-21 14:18:40 +09002728int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
2729 u8 index)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002730{
Chaehyun Lim66b8cb82015-10-27 20:40:32 +09002731 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002732 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09002733 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002734
Tony Choa4ab1ad2015-10-12 16:56:05 +09002735 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09002736 netdev_err(vif->ndev, "driver is null\n");
Leo Kim7717880782015-10-19 18:26:11 +09002737 return -EFAULT;
Leo Kim24db7132015-09-16 18:36:01 +09002738 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002739
Tony Cho143eb952015-09-21 12:16:32 +09002740 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002741
Tony Choa9f812a2015-09-21 12:16:33 +09002742 msg.id = HOST_IF_MSG_KEY;
Leo Kim8e9f4272015-10-13 19:49:27 +09002743 msg.body.key_info.type = WEP;
Leo Kim0d17e382015-10-13 19:49:28 +09002744 msg.body.key_info.action = ADDKEY;
Glen Leecf601062015-12-21 14:18:39 +09002745 msg.vif = vif;
Chaehyun Lim1cc0c322015-10-27 20:40:37 +09002746 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2747 if (!msg.body.key_info.attr.wep.key)
2748 return -ENOMEM;
2749
Chaehyun Limdbc53192015-10-27 20:40:35 +09002750 msg.body.key_info.attr.wep.key_len = len;
Chaehyun Lim0b2cc3e2015-10-27 20:40:36 +09002751 msg.body.key_info.attr.wep.index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002752
Binoy Jayana5c84b22016-06-23 11:11:52 +05302753 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09002754 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002755 netdev_err(vif->ndev, "STA - WEP Key\n");
Alison Schofield702962f2016-03-14 10:35:41 -07002756 wait_for_completion(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002757
Leo Kim31390ee2015-10-19 18:26:08 +09002758 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759}
2760
Glen Leefbf53792015-12-21 14:18:40 +09002761int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
2762 u8 index, u8 mode, enum AUTHTYPE auth_type)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002763{
Chaehyun Lim641c20a2015-10-28 08:19:19 +09002764 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002765 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09002766 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002767
Tony Choa4ab1ad2015-10-12 16:56:05 +09002768 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09002769 netdev_err(vif->ndev, "driver is null\n");
Leo Kim7717880782015-10-19 18:26:11 +09002770 return -EFAULT;
Leo Kim24db7132015-09-16 18:36:01 +09002771 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002772
Tony Cho143eb952015-09-21 12:16:32 +09002773 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002774
Tony Choa9f812a2015-09-21 12:16:33 +09002775 msg.id = HOST_IF_MSG_KEY;
Leo Kim8e9f4272015-10-13 19:49:27 +09002776 msg.body.key_info.type = WEP;
Leo Kim0d17e382015-10-13 19:49:28 +09002777 msg.body.key_info.action = ADDKEY_AP;
Glen Leecf601062015-12-21 14:18:39 +09002778 msg.vif = vif;
Chaehyun Lim58eabd62015-10-28 08:19:27 +09002779 msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2780 if (!msg.body.key_info.attr.wep.key)
2781 return -ENOMEM;
2782
Chaehyun Lima5389b02015-10-28 08:19:23 +09002783 msg.body.key_info.attr.wep.key_len = len;
Chaehyun Lima76dc952015-10-28 08:19:24 +09002784 msg.body.key_info.attr.wep.index = index;
Chaehyun Lim730a28d2015-10-28 08:19:25 +09002785 msg.body.key_info.attr.wep.mode = mode;
Chaehyun Limff3bce22015-10-28 08:19:26 +09002786 msg.body.key_info.attr.wep.auth_type = auth_type;
Leo Kimae4dfa52015-10-13 19:49:26 +09002787
Binoy Jayana5c84b22016-06-23 11:11:52 +05302788 result = wilc_enqueue_cmd(&msg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002789
Leo Kim31390ee2015-10-19 18:26:08 +09002790 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002791 netdev_err(vif->ndev, "AP - WEP Key\n");
Leo Kim27e1f132016-04-01 17:44:13 +09002792 else
2793 wait_for_completion(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002794
Leo Kim31390ee2015-10-19 18:26:08 +09002795 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002796}
Glen Lee108b3432015-09-16 18:53:20 +09002797
Glen Leefbf53792015-12-21 14:18:40 +09002798int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
2799 const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
2800 u8 mode, u8 cipher_mode, u8 index)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002801{
Chaehyun Lim706ab422015-11-08 16:48:54 +09002802 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002803 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09002804 struct host_if_drv *hif_drv = vif->hif_drv;
Chaehyun Lim53bbbb52015-11-08 16:49:03 +09002805 u8 key_len = ptk_key_len;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02002806
Tony Choa4ab1ad2015-10-12 16:56:05 +09002807 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09002808 netdev_err(vif->ndev, "driver is null\n");
Leo Kim7717880782015-10-19 18:26:11 +09002809 return -EFAULT;
Leo Kim24db7132015-09-16 18:36:01 +09002810 }
Leo Kim91109e12015-10-19 18:26:13 +09002811
Chaehyun Lim38f66292015-11-08 16:48:58 +09002812 if (rx_mic)
Chaehyun Lim53bbbb52015-11-08 16:49:03 +09002813 key_len += RX_MIC_KEY_LEN;
Leo Kim91109e12015-10-19 18:26:13 +09002814
Chaehyun Limd7c02422015-11-08 16:48:59 +09002815 if (tx_mic)
Chaehyun Lim53bbbb52015-11-08 16:49:03 +09002816 key_len += TX_MIC_KEY_LEN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002817
Tony Cho143eb952015-09-21 12:16:32 +09002818 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002819
Tony Choa9f812a2015-09-21 12:16:33 +09002820 msg.id = HOST_IF_MSG_KEY;
Leo Kim2141fe32015-10-29 12:05:35 +09002821 msg.body.key_info.type = WPA_PTK;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002822 if (mode == AP_MODE) {
Leo Kim0d17e382015-10-13 19:49:28 +09002823 msg.body.key_info.action = ADDKEY_AP;
Chaehyun Lim3e5c4ab2015-11-08 16:49:01 +09002824 msg.body.key_info.attr.wpa.index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002825 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002826 if (mode == STATION_MODE)
Leo Kim0d17e382015-10-13 19:49:28 +09002827 msg.body.key_info.action = ADDKEY;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002828
Chaehyun Lim8ab8c592015-11-08 16:49:04 +09002829 msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
2830 if (!msg.body.key_info.attr.wpa.key)
2831 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002832
Chris Park9ac0c052016-02-22 13:11:56 +09002833 if (rx_mic)
Chaehyun Lim38f66292015-11-08 16:48:58 +09002834 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN);
Chris Park9ac0c052016-02-22 13:11:56 +09002835
2836 if (tx_mic)
Chaehyun Limd7c02422015-11-08 16:48:59 +09002837 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002838
Chaehyun Lim53bbbb52015-11-08 16:49:03 +09002839 msg.body.key_info.attr.wpa.key_len = key_len;
Leo Kim248080a2015-10-13 19:49:31 +09002840 msg.body.key_info.attr.wpa.mac_addr = mac_addr;
Chaehyun Limf0c82572015-11-08 16:49:00 +09002841 msg.body.key_info.attr.wpa.mode = cipher_mode;
Glen Leecf601062015-12-21 14:18:39 +09002842 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002843
Binoy Jayana5c84b22016-06-23 11:11:52 +05302844 result = wilc_enqueue_cmd(&msg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002845
Leo Kim31390ee2015-10-19 18:26:08 +09002846 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002847 netdev_err(vif->ndev, "PTK Key\n");
Leo Kim27e1f132016-04-01 17:44:13 +09002848 else
2849 wait_for_completion(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002850
Leo Kim31390ee2015-10-19 18:26:08 +09002851 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002852}
2853
Glen Leefbf53792015-12-21 14:18:40 +09002854int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
2855 u8 index, u32 key_rsc_len, const u8 *key_rsc,
2856 const u8 *rx_mic, const u8 *tx_mic, u8 mode,
2857 u8 cipher_mode)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002858{
Chaehyun Lim15034572015-11-08 16:49:05 +09002859 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002860 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09002861 struct host_if_drv *hif_drv = vif->hif_drv;
Chaehyun Limd002fcc2015-11-08 16:49:15 +09002862 u8 key_len = gtk_key_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002863
Tony Choa4ab1ad2015-10-12 16:56:05 +09002864 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09002865 netdev_err(vif->ndev, "driver is null\n");
Leo Kim7717880782015-10-19 18:26:11 +09002866 return -EFAULT;
Leo Kim24db7132015-09-16 18:36:01 +09002867 }
Tony Cho143eb952015-09-21 12:16:32 +09002868 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002869
Chaehyun Lim6d36c272015-11-08 16:49:12 +09002870 if (rx_mic)
Chaehyun Limd002fcc2015-11-08 16:49:15 +09002871 key_len += RX_MIC_KEY_LEN;
Leo Kim91109e12015-10-19 18:26:13 +09002872
Chaehyun Lim2f797582015-11-08 16:49:13 +09002873 if (tx_mic)
Chaehyun Limd002fcc2015-11-08 16:49:15 +09002874 key_len += TX_MIC_KEY_LEN;
Leo Kim91109e12015-10-19 18:26:13 +09002875
Chaehyun Lim982859c2015-11-08 16:49:11 +09002876 if (key_rsc) {
Chaehyun Lim9bfda382015-11-08 16:49:16 +09002877 msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
2878 key_rsc_len,
2879 GFP_KERNEL);
2880 if (!msg.body.key_info.attr.wpa.seq)
2881 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002882 }
2883
Tony Choa9f812a2015-09-21 12:16:33 +09002884 msg.id = HOST_IF_MSG_KEY;
Leo Kim5cd8f7a2015-10-29 12:05:34 +09002885 msg.body.key_info.type = WPA_RX_GTK;
Glen Leecf601062015-12-21 14:18:39 +09002886 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002887
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002888 if (mode == AP_MODE) {
Leo Kim0d17e382015-10-13 19:49:28 +09002889 msg.body.key_info.action = ADDKEY_AP;
Chaehyun Lim57bfcbc2015-11-08 16:49:14 +09002890 msg.body.key_info.attr.wpa.mode = cipher_mode;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002891 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002892 if (mode == STATION_MODE)
Leo Kim0d17e382015-10-13 19:49:28 +09002893 msg.body.key_info.action = ADDKEY;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002894
Chaehyun Lim9bfda382015-11-08 16:49:16 +09002895 msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
2896 key_len,
2897 GFP_KERNEL);
2898 if (!msg.body.key_info.attr.wpa.key)
2899 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002900
Chaehyun Lim6d36c272015-11-08 16:49:12 +09002901 if (rx_mic)
2902 memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
Leo Kimd1666e22015-10-28 15:59:22 +09002903 RX_MIC_KEY_LEN);
Leo Kim91109e12015-10-19 18:26:13 +09002904
Chaehyun Lim2f797582015-11-08 16:49:13 +09002905 if (tx_mic)
2906 memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
Leo Kimd1666e22015-10-28 15:59:22 +09002907 TX_MIC_KEY_LEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002908
Chaehyun Lim9a5e57362015-11-08 16:49:09 +09002909 msg.body.key_info.attr.wpa.index = index;
Chaehyun Limd002fcc2015-11-08 16:49:15 +09002910 msg.body.key_info.attr.wpa.key_len = key_len;
Chaehyun Lim18bef992015-11-08 16:49:10 +09002911 msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912
Binoy Jayana5c84b22016-06-23 11:11:52 +05302913 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09002914 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002915 netdev_err(vif->ndev, "RX GTK\n");
Leo Kim27e1f132016-04-01 17:44:13 +09002916 else
2917 wait_for_completion(&hif_drv->comp_test_key_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002918
Leo Kim31390ee2015-10-19 18:26:08 +09002919 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002920}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002921
Chaehyun Lim1ab58702015-12-22 09:49:03 +09002922int wilc_set_pmkid_info(struct wilc_vif *vif,
Chaehyun Lim16c0cba2015-12-22 09:49:05 +09002923 struct host_if_pmkid_attr *pmkid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002924{
Chaehyun Lim1ab58702015-12-22 09:49:03 +09002925 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002926 struct host_if_msg msg;
Chaehyun Lim89dec132015-12-22 09:49:04 +09002927 int i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002928
Tony Cho143eb952015-09-21 12:16:32 +09002929 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002930
Tony Choa9f812a2015-09-21 12:16:33 +09002931 msg.id = HOST_IF_MSG_KEY;
Leo Kim8e9f4272015-10-13 19:49:27 +09002932 msg.body.key_info.type = PMKSA;
Leo Kim0d17e382015-10-13 19:49:28 +09002933 msg.body.key_info.action = ADDKEY;
Glen Leecf601062015-12-21 14:18:39 +09002934 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002935
Chaehyun Lim16c0cba2015-12-22 09:49:05 +09002936 for (i = 0; i < pmkid->numpmkid; i++) {
Leo Kim8c8360b2015-10-19 18:26:12 +09002937 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
Chaehyun Lim16c0cba2015-12-22 09:49:05 +09002938 &pmkid->pmkidlist[i].bssid, ETH_ALEN);
Leo Kim8c8360b2015-10-19 18:26:12 +09002939 memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
Chaehyun Lim16c0cba2015-12-22 09:49:05 +09002940 &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002941 }
2942
Binoy Jayana5c84b22016-06-23 11:11:52 +05302943 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09002944 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09002945 netdev_err(vif->ndev, "PMKID Info\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002946
Leo Kim31390ee2015-10-19 18:26:08 +09002947 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002948}
2949
Chaehyun Lim1eabfe32015-12-22 09:49:07 +09002950int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002951{
Chaehyun Limdcb15a02015-12-22 09:49:06 +09002952 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002953 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002954
Tony Cho143eb952015-09-21 12:16:32 +09002955 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002956
Tony Choa9f812a2015-09-21 12:16:33 +09002957 msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
Chaehyun Lim1eabfe32015-12-22 09:49:07 +09002958 msg.body.get_mac_info.mac_addr = mac_addr;
Glen Leecf601062015-12-21 14:18:39 +09002959 msg.vif = vif;
Leo Kimae4dfa52015-10-13 19:49:26 +09002960
Binoy Jayana5c84b22016-06-23 11:11:52 +05302961 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09002962 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09002963 netdev_err(vif->ndev, "Failed to send get mac address\n");
Leo Kime6e12662015-09-16 18:36:03 +09002964 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002965 }
2966
Chaehyun Lim613eaa32016-03-14 09:40:27 +09002967 wait_for_completion(&hif_wait_response);
Leo Kim31390ee2015-10-19 18:26:08 +09002968 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002969}
2970
Chaehyun Limf2cb5f32015-12-24 16:52:22 +09002971int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
Chaehyun Lim8c38d962015-12-24 16:52:25 +09002972 size_t ssid_len, const u8 *ies, size_t ies_len,
Chaehyun Lim2ef29832015-12-24 16:52:27 +09002973 wilc_connect_result connect_result, void *user_arg,
Chaehyun Lim12a3b8b2015-12-24 16:52:29 +09002974 u8 security, enum AUTHTYPE auth_type,
Chaehyun Limf382b372015-12-24 16:52:31 +09002975 u8 channel, void *join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002976{
Chaehyun Lim0a285b22015-12-24 16:52:20 +09002977 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09002978 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09002979 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002980
Chaehyun Lim81c23a72015-12-24 16:52:26 +09002981 if (!hif_drv || !connect_result) {
Chris Parkb92f9302016-02-22 13:12:02 +09002982 netdev_err(vif->ndev, "Driver is null\n");
Leo Kim7717880782015-10-19 18:26:11 +09002983 return -EFAULT;
Leo Kim24db7132015-09-16 18:36:01 +09002984 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002985
Chaehyun Limf382b372015-12-24 16:52:31 +09002986 if (!join_params) {
Chris Parkb92f9302016-02-22 13:12:02 +09002987 netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
Leo Kim24db7132015-09-16 18:36:01 +09002988 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002989 }
Leo Kim24db7132015-09-16 18:36:01 +09002990
Tony Cho143eb952015-09-21 12:16:32 +09002991 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002992
Tony Choa9f812a2015-09-21 12:16:33 +09002993 msg.id = HOST_IF_MSG_CONNECT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002994
Chaehyun Lime0c54a82015-12-24 16:52:28 +09002995 msg.body.con_info.security = security;
Chaehyun Lim12a3b8b2015-12-24 16:52:29 +09002996 msg.body.con_info.auth_type = auth_type;
Chaehyun Lim0ea1ece2015-12-24 16:52:30 +09002997 msg.body.con_info.ch = channel;
Chaehyun Lim81c23a72015-12-24 16:52:26 +09002998 msg.body.con_info.result = connect_result;
Chaehyun Lim2ef29832015-12-24 16:52:27 +09002999 msg.body.con_info.arg = user_arg;
Chaehyun Limf382b372015-12-24 16:52:31 +09003000 msg.body.con_info.params = join_params;
Glen Leecf601062015-12-21 14:18:39 +09003001 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003002
Chaehyun Lim16a537c2015-12-24 16:52:21 +09003003 if (bssid) {
Chaehyun Lim11623132015-12-24 16:52:32 +09003004 msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
3005 if (!msg.body.con_info.bssid)
3006 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003007 }
3008
Chaehyun Limf2cb5f32015-12-24 16:52:22 +09003009 if (ssid) {
Chaehyun Limdee39b12015-12-24 16:52:23 +09003010 msg.body.con_info.ssid_len = ssid_len;
Chaehyun Lim11623132015-12-24 16:52:32 +09003011 msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
3012 if (!msg.body.con_info.ssid)
3013 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003014 }
3015
Chaehyun Lim88c94212015-12-24 16:52:24 +09003016 if (ies) {
Chaehyun Lim8c38d962015-12-24 16:52:25 +09003017 msg.body.con_info.ies_len = ies_len;
Chaehyun Lim11623132015-12-24 16:52:32 +09003018 msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
3019 if (!msg.body.con_info.ies)
3020 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003021 }
Leo Kimb60005a2015-10-29 11:58:24 +09003022 if (hif_drv->hif_state < HOST_IF_CONNECTING)
3023 hif_drv->hif_state = HOST_IF_CONNECTING;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003024
Binoy Jayana5c84b22016-06-23 11:11:52 +05303025 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003026 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003027 netdev_err(vif->ndev, "send message: Set join request\n");
Leo Kim24db7132015-09-16 18:36:01 +09003028 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003029 }
3030
Glen Lee71130e82015-12-21 14:18:41 +09003031 hif_drv->connect_timer.data = (unsigned long)vif;
Leo Kim81a59502015-10-29 11:58:35 +09003032 mod_timer(&hif_drv->connect_timer,
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -07003033 jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003034
Leo Kim31390ee2015-10-19 18:26:08 +09003035 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003036}
3037
Chaehyun Lim9f723fd2015-12-24 16:52:34 +09003038int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003039{
Chaehyun Lim53502512015-12-24 16:52:33 +09003040 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003041 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09003042 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003043
Tony Choa4ab1ad2015-10-12 16:56:05 +09003044 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09003045 netdev_err(vif->ndev, "Driver is null\n");
Leo Kim24db7132015-09-16 18:36:01 +09003046 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003047 }
3048
Tony Cho143eb952015-09-21 12:16:32 +09003049 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003050
Tony Choa9f812a2015-09-21 12:16:33 +09003051 msg.id = HOST_IF_MSG_DISCONNECT;
Glen Leecf601062015-12-21 14:18:39 +09003052 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003053
Binoy Jayana5c84b22016-06-23 11:11:52 +05303054 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003055 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003056 netdev_err(vif->ndev, "Failed to send message: disconnect\n");
Leo Kim27e1f132016-04-01 17:44:13 +09003057 else
3058 wait_for_completion(&hif_drv->comp_test_disconn_block);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003059
Leo Kim31390ee2015-10-19 18:26:08 +09003060 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003061}
3062
Glen Lee71130e82015-12-21 14:18:41 +09003063static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
Arnd Bergmann1608c402015-11-16 15:04:53 +01003064 u8 *pu8AssocRespInfo,
3065 u32 u32MaxAssocRespInfoLen,
3066 u32 *pu32RcvdAssocRespInfoLen)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003067{
Leo Kim31390ee2015-10-19 18:26:08 +09003068 s32 result = 0;
Leo Kim45102f82015-10-28 15:59:28 +09003069 struct wid wid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003070
Leo Kim45102f82015-10-28 15:59:28 +09003071 wid.id = (u16)WID_ASSOC_RES_INFO;
3072 wid.type = WID_STR;
3073 wid.val = pu8AssocRespInfo;
3074 wid.size = u32MaxAssocRespInfoLen;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003075
Glen Lee79df6a42016-02-04 18:15:31 +09003076 result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
Chaehyun Lim4cf93d72016-01-26 18:50:00 +09003077 wilc_get_vif_idx(vif));
Leo Kim31390ee2015-10-19 18:26:08 +09003078 if (result) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003079 *pu32RcvdAssocRespInfoLen = 0;
Chris Parkb92f9302016-02-22 13:12:02 +09003080 netdev_err(vif->ndev, "Failed to send association response\n");
Leo Kim24db7132015-09-16 18:36:01 +09003081 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003082 }
Eva Rachel Retuyac22177d2016-02-16 16:24:44 +08003083
Janani Ravichandran24c6c292016-02-14 00:09:33 -05003084 *pu32RcvdAssocRespInfoLen = wid.size;
Leo Kim31390ee2015-10-19 18:26:08 +09003085 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003086}
3087
Glen Leefbf53792015-12-21 14:18:40 +09003088int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003089{
Chaehyun Lim792fb252015-10-05 11:07:22 +09003090 int result;
Tony Cho143eb952015-09-21 12:16:32 +09003091 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003092
Tony Cho143eb952015-09-21 12:16:32 +09003093 memset(&msg, 0, sizeof(struct host_if_msg));
Tony Choa9f812a2015-09-21 12:16:33 +09003094 msg.id = HOST_IF_MSG_SET_CHANNEL;
Leo Kim730ee052015-10-13 19:50:02 +09003095 msg.body.channel_info.set_ch = channel;
Glen Leecf601062015-12-21 14:18:39 +09003096 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003097
Binoy Jayana5c84b22016-06-23 11:11:52 +05303098 result = wilc_enqueue_cmd(&msg);
Chaehyun Lim1ef58e42015-10-02 21:44:49 +09003099 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003100 netdev_err(vif->ndev, "wilc mq send fail\n");
Chaehyun Lim792fb252015-10-05 11:07:22 +09003101 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003102 }
3103
Chaehyun Lim792fb252015-10-05 11:07:22 +09003104 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003105}
3106
Glen Leeb3306862016-02-04 18:15:18 +09003107int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003108{
Chaehyun Lima0941012015-10-05 19:34:47 +09003109 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003110 struct host_if_msg msg;
Leo Kimc09389a2015-10-28 15:59:24 +09003111
Tony Cho143eb952015-09-21 12:16:32 +09003112 memset(&msg, 0, sizeof(struct host_if_msg));
Tony Choa9f812a2015-09-21 12:16:33 +09003113 msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
Glen Lee31f0f692015-12-21 14:18:44 +09003114 msg.body.drv.handler = index;
Glen Leeb3306862016-02-04 18:15:18 +09003115 msg.body.drv.mac_idx = mac_idx;
Glen Leecf601062015-12-21 14:18:39 +09003116 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003117
Binoy Jayana5c84b22016-06-23 11:11:52 +05303118 result = wilc_enqueue_cmd(&msg);
Chaehyun Lima0941012015-10-05 19:34:47 +09003119 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003120 netdev_err(vif->ndev, "wilc mq send fail\n");
Chaehyun Lima0941012015-10-05 19:34:47 +09003121 result = -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003122 }
3123
Chaehyun Lima0941012015-10-05 19:34:47 +09003124 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003125}
3126
Glen Leefbf53792015-12-21 14:18:40 +09003127int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003128{
Chaehyun Lima0c1ee02015-10-05 19:34:50 +09003129 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003130 struct host_if_msg msg;
Leo Kimc09389a2015-10-28 15:59:24 +09003131
Tony Cho143eb952015-09-21 12:16:32 +09003132 memset(&msg, 0, sizeof(struct host_if_msg));
Tony Choa9f812a2015-09-21 12:16:33 +09003133 msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
Leo Kimc96debf2015-10-28 15:59:30 +09003134 msg.body.mode.mode = mode;
Glen Leecf601062015-12-21 14:18:39 +09003135 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003136
Binoy Jayana5c84b22016-06-23 11:11:52 +05303137 result = wilc_enqueue_cmd(&msg);
Chaehyun Lima0c1ee02015-10-05 19:34:50 +09003138 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003139 netdev_err(vif->ndev, "wilc mq send fail\n");
Chaehyun Lima0c1ee02015-10-05 19:34:50 +09003140 result = -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003141 }
3142
Chaehyun Lima0c1ee02015-10-05 19:34:50 +09003143 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003144}
3145
Glen Leefbf53792015-12-21 14:18:40 +09003146s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
3147 u32 *pu32InactiveTime)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003148{
Leo Kim31390ee2015-10-19 18:26:08 +09003149 s32 result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003150 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09003151 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003152
Tony Choa4ab1ad2015-10-12 16:56:05 +09003153 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09003154 netdev_err(vif->ndev, "driver is null\n");
Leo Kim24db7132015-09-16 18:36:01 +09003155 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003156 }
3157
Tony Cho143eb952015-09-21 12:16:32 +09003158 memset(&msg, 0, sizeof(struct host_if_msg));
Leo Kim8c8360b2015-10-19 18:26:12 +09003159 memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003160
Tony Choa9f812a2015-09-21 12:16:33 +09003161 msg.id = HOST_IF_MSG_GET_INACTIVETIME;
Glen Leecf601062015-12-21 14:18:39 +09003162 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003163
Binoy Jayana5c84b22016-06-23 11:11:52 +05303164 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003165 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003166 netdev_err(vif->ndev, "Failed to send get host ch param\n");
Leo Kim27e1f132016-04-01 17:44:13 +09003167 else
3168 wait_for_completion(&hif_drv->comp_inactive_time);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003169
Leo Kimad269062015-10-15 13:25:06 +09003170 *pu32InactiveTime = inactive_time;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003171
Leo Kim31390ee2015-10-19 18:26:08 +09003172 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003173}
Glen Lee108b3432015-09-16 18:53:20 +09003174
Chaehyun Lim652bb5e2015-12-24 16:52:37 +09003175int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003176{
Chaehyun Lime16aed62015-12-24 16:52:36 +09003177 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003178 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09003179 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003180
Leo Kimc09389a2015-10-28 15:59:24 +09003181 memset(&msg, 0, sizeof(struct host_if_msg));
Tony Choa9f812a2015-09-21 12:16:33 +09003182 msg.id = HOST_IF_MSG_GET_RSSI;
Glen Leecf601062015-12-21 14:18:39 +09003183 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003184
Binoy Jayana5c84b22016-06-23 11:11:52 +05303185 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003186 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003187 netdev_err(vif->ndev, "Failed to send get host ch param\n");
Leo Kime6e12662015-09-16 18:36:03 +09003188 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003189 }
3190
Alison Schofield7c8a3dc2016-03-14 10:34:39 -07003191 wait_for_completion(&hif_drv->comp_get_rssi);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003192
Chaehyun Lim652bb5e2015-12-24 16:52:37 +09003193 if (!rssi_level) {
Chris Parkb92f9302016-02-22 13:12:02 +09003194 netdev_err(vif->ndev, "RSS pointer value is null\n");
Leo Kime6e12662015-09-16 18:36:03 +09003195 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003196 }
3197
Chaehyun Lim652bb5e2015-12-24 16:52:37 +09003198 *rssi_level = rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003199
Leo Kim31390ee2015-10-19 18:26:08 +09003200 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003201}
3202
Chaehyun Limf70b25f2015-12-24 16:52:39 +09003203int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003204{
Chaehyun Limcd163d32015-12-24 16:52:38 +09003205 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003206 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003207
Leo Kimc09389a2015-10-28 15:59:24 +09003208 memset(&msg, 0, sizeof(struct host_if_msg));
Tony Choa9f812a2015-09-21 12:16:33 +09003209 msg.id = HOST_IF_MSG_GET_STATISTICS;
Chaehyun Limf70b25f2015-12-24 16:52:39 +09003210 msg.body.data = (char *)stats;
Glen Leecf601062015-12-21 14:18:39 +09003211 msg.vif = vif;
Leo Kimae4dfa52015-10-13 19:49:26 +09003212
Binoy Jayana5c84b22016-06-23 11:11:52 +05303213 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003214 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003215 netdev_err(vif->ndev, "Failed to send get host channel\n");
Leo Kime6e12662015-09-16 18:36:03 +09003216 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003217 }
3218
Glen Lee4fd62292016-02-04 18:15:24 +09003219 if (stats != &vif->wilc->dummy_statistics)
Chaehyun Lim613eaa32016-03-14 09:40:27 +09003220 wait_for_completion(&hif_wait_response);
Leo Kim31390ee2015-10-19 18:26:08 +09003221 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003222}
3223
Chaehyun Limc0734df2016-01-05 23:06:47 +09003224int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
Chaehyun Limce2d0232016-01-05 23:06:50 +09003225 u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
Chaehyun Lim2c97f2d2016-01-05 23:06:53 +09003226 size_t ies_len, wilc_scan_result scan_result, void *user_arg,
Chaehyun Limd3178182016-01-05 23:06:54 +09003227 struct hidden_network *hidden_network)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003228{
Chaehyun Lim03a5d8c2016-01-05 23:06:45 +09003229 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003230 struct host_if_msg msg;
Chaehyun Limb41dfdb2016-02-12 23:04:43 +09003231 struct scan_attr *scan_info = &msg.body.scan_info;
Glen Leefbf53792015-12-21 14:18:40 +09003232 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003233
Chaehyun Limc8fb0bf2016-01-05 23:06:52 +09003234 if (!hif_drv || !scan_result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003235 netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
Leo Kim24db7132015-09-16 18:36:01 +09003236 return -EFAULT;
3237 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003238
Tony Cho143eb952015-09-21 12:16:32 +09003239 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003240
Tony Choa9f812a2015-09-21 12:16:33 +09003241 msg.id = HOST_IF_MSG_SCAN;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003242
Chaehyun Limd3178182016-01-05 23:06:54 +09003243 if (hidden_network) {
Chaehyun Limb41dfdb2016-02-12 23:04:43 +09003244 scan_info->hidden_network.net_info = hidden_network->net_info;
3245 scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
Chris Parkc4f97522016-02-04 18:24:04 +09003246 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003247
Glen Leecf601062015-12-21 14:18:39 +09003248 msg.vif = vif;
Chaehyun Limb41dfdb2016-02-12 23:04:43 +09003249 scan_info->src = scan_source;
3250 scan_info->type = scan_type;
3251 scan_info->result = scan_result;
3252 scan_info->arg = user_arg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003253
Chaehyun Limb41dfdb2016-02-12 23:04:43 +09003254 scan_info->ch_list_len = ch_list_len;
3255 scan_info->ch_freq_list = kmemdup(ch_freq_list,
3256 ch_list_len,
3257 GFP_KERNEL);
3258 if (!scan_info->ch_freq_list)
Chaehyun Lim1a271d92016-01-05 23:06:55 +09003259 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003260
Chaehyun Limb41dfdb2016-02-12 23:04:43 +09003261 scan_info->ies_len = ies_len;
3262 scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
3263 if (!scan_info->ies)
Chaehyun Lim1a271d92016-01-05 23:06:55 +09003264 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003265
Binoy Jayana5c84b22016-06-23 11:11:52 +05303266 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003267 if (result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003268 netdev_err(vif->ndev, "Error in sending message queue\n");
Leo Kim24db7132015-09-16 18:36:01 +09003269 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003270 }
3271
Glen Lee71130e82015-12-21 14:18:41 +09003272 hif_drv->scan_timer.data = (unsigned long)vif;
Leo Kim13b313e2015-10-29 11:58:34 +09003273 mod_timer(&hif_drv->scan_timer,
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -07003274 jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003275
Leo Kim31390ee2015-10-19 18:26:08 +09003276 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003277}
Leo Kimae4dfa52015-10-13 19:49:26 +09003278
Chaehyun Lim4168da72016-02-05 10:35:11 +09003279int wilc_hif_set_cfg(struct wilc_vif *vif,
Chaehyun Lima5f0fb52016-02-23 15:37:58 +09003280 struct cfg_param_attr *cfg_param)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003281{
Tony Cho143eb952015-09-21 12:16:32 +09003282 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09003283 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003284
Tony Choa4ab1ad2015-10-12 16:56:05 +09003285 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09003286 netdev_err(vif->ndev, "hif_drv NULL\n");
Leo Kim24db7132015-09-16 18:36:01 +09003287 return -EFAULT;
3288 }
Leo Kimae4dfa52015-10-13 19:49:26 +09003289
Tony Cho143eb952015-09-21 12:16:32 +09003290 memset(&msg, 0, sizeof(struct host_if_msg));
Tony Choa9f812a2015-09-21 12:16:33 +09003291 msg.id = HOST_IF_MSG_CFG_PARAMS;
Chaehyun Lima5f0fb52016-02-23 15:37:58 +09003292 msg.body.cfg_info = *cfg_param;
Glen Leecf601062015-12-21 14:18:39 +09003293 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003294
Rehas Sachdevad37843d2016-09-20 13:18:40 +05303295 return wilc_enqueue_cmd(&msg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003296}
3297
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003298static void GetPeriodicRSSI(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003299{
Glen Lee71130e82015-12-21 14:18:41 +09003300 struct wilc_vif *vif = (struct wilc_vif *)arg;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02003301
Glen Lee71130e82015-12-21 14:18:41 +09003302 if (!vif->hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09003303 netdev_err(vif->ndev, "Driver handler is NULL\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003304 return;
3305 }
3306
Glen Lee4fd62292016-02-04 18:15:24 +09003307 if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
3308 wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003309
Glen Lee71130e82015-12-21 14:18:41 +09003310 periodic_rssi.data = (unsigned long)vif;
Leo Kim262f55e2015-10-15 13:24:58 +09003311 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003312}
3313
Chaehyun Lim1e995c12016-01-05 23:06:57 +09003314int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003315{
Chaehyun Lim1e995c12016-01-05 23:06:57 +09003316 int result = 0;
Tony Choa4ab1ad2015-10-12 16:56:05 +09003317 struct host_if_drv *hif_drv;
Glen Leea4cac482015-12-21 14:18:36 +09003318 struct wilc_vif *vif;
Glen Leed53822192015-10-27 18:27:49 +09003319 struct wilc *wilc;
Glen Lee03efae32015-12-21 14:18:49 +09003320 int i;
Glen Leed53822192015-10-27 18:27:49 +09003321
Glen Leea4cac482015-12-21 14:18:36 +09003322 vif = netdev_priv(dev);
3323 wilc = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003324
Leo Kimca8540e42015-10-15 13:25:00 +09003325 scan_while_connected = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003326
Chaehyun Lim613eaa32016-03-14 09:40:27 +09003327 init_completion(&hif_wait_response);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003328
sayli karnikfaa48ea2016-09-16 16:23:02 +05303329 hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
Tony Choa4ab1ad2015-10-12 16:56:05 +09003330 if (!hif_drv) {
Chaehyun Lim5b09bd32015-09-22 18:34:59 +09003331 result = -ENOMEM;
Vincent Stehlé17db84e2015-10-07 07:08:25 +02003332 goto _fail_;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003333 }
Tony Choa4ab1ad2015-10-12 16:56:05 +09003334 *hif_drv_handler = hif_drv;
Glen Lee03efae32015-12-21 14:18:49 +09003335 for (i = 0; i < wilc->vif_num; i++)
3336 if (dev == wilc->vif[i]->ndev) {
3337 wilc->vif[i]->hif_drv = hif_drv;
3338 break;
3339 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003340
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003341 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003342
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003343 if (clients_count == 0) {
Chaehyun Lim04dd9a42016-03-23 21:28:33 +09003344 init_completion(&hif_thread_comp);
Chaehyun Lim2bb02582016-03-23 21:28:34 +09003345 init_completion(&hif_driver_comp);
Chaehyun Lim896802a2016-03-22 08:39:24 +09003346 mutex_init(&hif_deinit_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003347 }
3348
Alison Schofield702962f2016-03-14 10:35:41 -07003349 init_completion(&hif_drv->comp_test_key_block);
Alison Schofield96adbd22016-03-14 10:35:05 -07003350 init_completion(&hif_drv->comp_test_disconn_block);
Alison Schofield7c8a3dc2016-03-14 10:34:39 -07003351 init_completion(&hif_drv->comp_get_rssi);
Alison Schofielde0c14962016-03-14 10:34:14 -07003352 init_completion(&hif_drv->comp_inactive_time);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003353
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003354 if (clients_count == 0) {
Chaehyun Lim5b09bd32015-09-22 18:34:59 +09003355 if (result < 0) {
Chris Parkb92f9302016-02-22 13:12:02 +09003356 netdev_err(vif->ndev, "Failed to creat MQ\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003357 goto _fail_;
3358 }
Binoy Jayan2518ac52016-06-23 11:11:51 +05303359 hif_workqueue = create_singlethread_workqueue("WILC_wq");
3360 if (!hif_workqueue) {
3361 netdev_err(vif->ndev, "Failed to create workqueue\n");
3362 result = -ENOMEM;
Dan Carpenter23436822016-07-16 13:07:55 +03003363 goto _fail_;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003364 }
Binoy Jayan2518ac52016-06-23 11:11:51 +05303365
Leo Kim262f55e2015-10-15 13:24:58 +09003366 setup_timer(&periodic_rssi, GetPeriodicRSSI,
Glen Lee71130e82015-12-21 14:18:41 +09003367 (unsigned long)vif);
Leo Kim262f55e2015-10-15 13:24:58 +09003368 mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003369 }
3370
Leo Kim13b313e2015-10-29 11:58:34 +09003371 setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0);
Leo Kim81a59502015-10-29 11:58:35 +09003372 setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0);
Leo Kimcc2d7e92015-10-29 11:58:36 +09003373 setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003374
Chaehyun Lim1f12f142016-03-08 10:04:32 +09003375 mutex_init(&hif_drv->cfg_values_lock);
3376 mutex_lock(&hif_drv->cfg_values_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003377
Leo Kimb60005a2015-10-29 11:58:24 +09003378 hif_drv->hif_state = HOST_IF_IDLE;
Leo Kimace303f2015-10-29 11:58:26 +09003379 hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
3380 hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
3381 hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
3382 hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
3383 hif_drv->cfg_values.curr_tx_rate = AUTORATE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003384
Leo Kim1229b1a2015-10-29 12:05:39 +09003385 hif_drv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003386
Chaehyun Lim1f12f142016-03-08 10:04:32 +09003387 mutex_unlock(&hif_drv->cfg_values_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003388
Leo Kimae4dfa52015-10-13 19:49:26 +09003389 clients_count++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003390
Binoy Jayan2518ac52016-06-23 11:11:51 +05303391 destroy_workqueue(hif_workqueue);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003392_fail_:
Chaehyun Lim5b09bd32015-09-22 18:34:59 +09003393 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003394}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003395
Chaehyun Lim127a27c2016-02-05 10:35:13 +09003396int wilc_deinit(struct wilc_vif *vif)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003397{
Chaehyun Lim127a27c2016-02-05 10:35:13 +09003398 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003399 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09003400 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003401
Tony Choa4ab1ad2015-10-12 16:56:05 +09003402 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09003403 netdev_err(vif->ndev, "hif_drv = NULL\n");
Chaehyun Lim8eb62f32016-02-05 10:35:14 +09003404 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003405 }
3406
Chaehyun Lim896802a2016-03-22 08:39:24 +09003407 mutex_lock(&hif_deinit_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003408
Tony Choa4ab1ad2015-10-12 16:56:05 +09003409 terminated_handle = hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003410
Chris Parkc4f97522016-02-04 18:24:04 +09003411 del_timer_sync(&hif_drv->scan_timer);
3412 del_timer_sync(&hif_drv->connect_timer);
3413 del_timer_sync(&periodic_rssi);
Leo Kimcc2d7e92015-10-29 11:58:36 +09003414 del_timer_sync(&hif_drv->remain_on_ch_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003415
Glen Leeb3306862016-02-04 18:15:18 +09003416 wilc_set_wfi_drv_handler(vif, 0, 0);
Chaehyun Lim2bb02582016-03-23 21:28:34 +09003417 wait_for_completion(&hif_driver_comp);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003418
Leo Kimbc801852015-10-29 11:58:50 +09003419 if (hif_drv->usr_scan_req.scan_result) {
3420 hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
Leo Kim66eaea32015-10-29 11:58:51 +09003421 hif_drv->usr_scan_req.arg, NULL);
Leo Kimbc801852015-10-29 11:58:50 +09003422 hif_drv->usr_scan_req.scan_result = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003423 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003424
Leo Kimb60005a2015-10-29 11:58:24 +09003425 hif_drv->hif_state = HOST_IF_IDLE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003426
Leo Kimca8540e42015-10-15 13:25:00 +09003427 scan_while_connected = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003428
Tony Cho143eb952015-09-21 12:16:32 +09003429 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003430
3431 if (clients_count == 1) {
Tony Choa9f812a2015-09-21 12:16:33 +09003432 msg.id = HOST_IF_MSG_EXIT;
Glen Leecf601062015-12-21 14:18:39 +09003433 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003434
Binoy Jayana5c84b22016-06-23 11:11:52 +05303435 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003436 if (result != 0)
Chris Parkb92f9302016-02-22 13:12:02 +09003437 netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
Leo Kim27e1f132016-04-01 17:44:13 +09003438 else
3439 wait_for_completion(&hif_thread_comp);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003440
Binoy Jayan2518ac52016-06-23 11:11:51 +05303441 destroy_workqueue(hif_workqueue);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003442 }
3443
Tony Choa4ab1ad2015-10-12 16:56:05 +09003444 kfree(hif_drv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003445
Leo Kimae4dfa52015-10-13 19:49:26 +09003446 clients_count--;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003447 terminated_handle = NULL;
Chaehyun Lim896802a2016-03-22 08:39:24 +09003448 mutex_unlock(&hif_deinit_lock);
Leo Kim31390ee2015-10-19 18:26:08 +09003449 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003450}
3451
Glen Leecd04d222015-12-21 14:18:42 +09003452void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer,
3453 u32 u32Length)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003454{
Leo Kim31390ee2015-10-19 18:26:08 +09003455 s32 result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003456 struct host_if_msg msg;
Johnny Kimd42ab082015-08-20 16:32:52 +09003457 int id;
Tony Choa4ab1ad2015-10-12 16:56:05 +09003458 struct host_if_drv *hif_drv = NULL;
Glen Leeeb9939b2015-12-21 14:18:43 +09003459 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003460
Johnny Kimd42ab082015-08-20 16:32:52 +09003461 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
Glen Leeeb9939b2015-12-21 14:18:43 +09003462 vif = wilc_get_vif_from_idx(wilc, id);
3463 if (!vif)
3464 return;
3465 hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003466
Tony Choa4ab1ad2015-10-12 16:56:05 +09003467 if (!hif_drv || hif_drv == terminated_handle) {
Chris Parkb92f9302016-02-22 13:12:02 +09003468 netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003469 return;
3470 }
3471
Tony Cho143eb952015-09-21 12:16:32 +09003472 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003473
Tony Choa9f812a2015-09-21 12:16:33 +09003474 msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
Glen Leeeb9939b2015-12-21 14:18:43 +09003475 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003476
Leo Kim3bffac62015-10-13 20:02:11 +09003477 msg.body.net_info.len = u32Length;
Leo Kimb021b802015-10-13 20:02:10 +09003478 msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
3479 memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003480
Binoy Jayana5c84b22016-06-23 11:11:52 +05303481 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003482 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003483 netdev_err(vif->ndev, "message parameters (%d)\n", result);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003484}
3485
Glen Leecd04d222015-12-21 14:18:42 +09003486void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer,
3487 u32 u32Length)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003488{
Leo Kim31390ee2015-10-19 18:26:08 +09003489 s32 result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003490 struct host_if_msg msg;
Johnny Kimd42ab082015-08-20 16:32:52 +09003491 int id;
Tony Choa4ab1ad2015-10-12 16:56:05 +09003492 struct host_if_drv *hif_drv = NULL;
Glen Leeeb9939b2015-12-21 14:18:43 +09003493 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003494
Chaehyun Lim896802a2016-03-22 08:39:24 +09003495 mutex_lock(&hif_deinit_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003496
Johnny Kimd42ab082015-08-20 16:32:52 +09003497 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
Glen Leeeb9939b2015-12-21 14:18:43 +09003498 vif = wilc_get_vif_from_idx(wilc, id);
3499 if (!vif) {
Chaehyun Lim896802a2016-03-22 08:39:24 +09003500 mutex_unlock(&hif_deinit_lock);
Glen Leeeb9939b2015-12-21 14:18:43 +09003501 return;
3502 }
3503
3504 hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003505
Tony Choa4ab1ad2015-10-12 16:56:05 +09003506 if (!hif_drv || hif_drv == terminated_handle) {
Chaehyun Lim896802a2016-03-22 08:39:24 +09003507 mutex_unlock(&hif_deinit_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003508 return;
3509 }
3510
Leo Kim33bfb192015-10-29 11:58:56 +09003511 if (!hif_drv->usr_conn_req.conn_result) {
Chris Parkb92f9302016-02-22 13:12:02 +09003512 netdev_err(vif->ndev, "there is no current Connect Request\n");
Chaehyun Lim896802a2016-03-22 08:39:24 +09003513 mutex_unlock(&hif_deinit_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003514 return;
3515 }
3516
Tony Cho143eb952015-09-21 12:16:32 +09003517 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003518
Tony Choa9f812a2015-09-21 12:16:33 +09003519 msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
Glen Leeeb9939b2015-12-21 14:18:43 +09003520 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003521
Leo Kimf94f4882015-10-13 19:50:01 +09003522 msg.body.async_info.len = u32Length;
Leo Kim33722ac72015-10-13 19:50:00 +09003523 msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
3524 memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003525
Binoy Jayana5c84b22016-06-23 11:11:52 +05303526 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003527 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003528 netdev_err(vif->ndev, "synchronous info (%d)\n", result);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003529
Chaehyun Lim896802a2016-03-22 08:39:24 +09003530 mutex_unlock(&hif_deinit_lock);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003531}
3532
Glen Leecd04d222015-12-21 14:18:42 +09003533void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer,
3534 u32 u32Length)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003535{
Leo Kim31390ee2015-10-19 18:26:08 +09003536 s32 result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003537 struct host_if_msg msg;
Johnny Kimd42ab082015-08-20 16:32:52 +09003538 int id;
Tony Choa4ab1ad2015-10-12 16:56:05 +09003539 struct host_if_drv *hif_drv = NULL;
Glen Leeeb9939b2015-12-21 14:18:43 +09003540 struct wilc_vif *vif;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02003541
Johnny Kimd42ab082015-08-20 16:32:52 +09003542 id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
Glen Leeeb9939b2015-12-21 14:18:43 +09003543 vif = wilc_get_vif_from_idx(wilc, id);
3544 if (!vif)
3545 return;
3546 hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003547
Tony Choa4ab1ad2015-10-12 16:56:05 +09003548 if (!hif_drv || hif_drv == terminated_handle)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003549 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003550
Leo Kimbc801852015-10-29 11:58:50 +09003551 if (hif_drv->usr_scan_req.scan_result) {
Tony Cho143eb952015-09-21 12:16:32 +09003552 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003553
Tony Choa9f812a2015-09-21 12:16:33 +09003554 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
Glen Leeeb9939b2015-12-21 14:18:43 +09003555 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003556
Binoy Jayana5c84b22016-06-23 11:11:52 +05303557 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003558 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003559 netdev_err(vif->ndev, "complete param (%d)\n", result);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003560 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003561}
3562
Chaehyun Lim6f7584b2016-01-03 17:35:35 +09003563int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
Chaehyun Limd44cd452016-01-03 17:35:36 +09003564 u32 duration, u16 chan,
Chaehyun Lim95bfdd52016-01-03 17:35:37 +09003565 wilc_remain_on_chan_expired expired,
Chaehyun Lim1aae9392016-01-03 17:35:38 +09003566 wilc_remain_on_chan_ready ready,
Chaehyun Lim482c4332016-01-03 17:35:39 +09003567 void *user_arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003568{
Chaehyun Lim6d6bc402016-01-03 17:35:34 +09003569 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003570 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003571
Tony Cho143eb952015-09-21 12:16:32 +09003572 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003573
Tony Choa9f812a2015-09-21 12:16:33 +09003574 msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
Leo Kim839ab702015-10-29 11:58:41 +09003575 msg.body.remain_on_ch.ch = chan;
Chaehyun Lim95bfdd52016-01-03 17:35:37 +09003576 msg.body.remain_on_ch.expired = expired;
Chaehyun Lim1aae9392016-01-03 17:35:38 +09003577 msg.body.remain_on_ch.ready = ready;
Chaehyun Lim482c4332016-01-03 17:35:39 +09003578 msg.body.remain_on_ch.arg = user_arg;
Chaehyun Limd44cd452016-01-03 17:35:36 +09003579 msg.body.remain_on_ch.duration = duration;
Chaehyun Lim6f7584b2016-01-03 17:35:35 +09003580 msg.body.remain_on_ch.id = session_id;
Glen Leecf601062015-12-21 14:18:39 +09003581 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003582
Binoy Jayana5c84b22016-06-23 11:11:52 +05303583 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003584 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003585 netdev_err(vif->ndev, "wilc mq send fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003586
Leo Kim31390ee2015-10-19 18:26:08 +09003587 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003588}
3589
Chaehyun Lim6b0f7cd2015-12-30 21:15:29 +09003590int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003591{
Chaehyun Lim5ca581e2015-12-30 21:15:28 +09003592 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003593 struct host_if_msg msg;
Glen Leefbf53792015-12-21 14:18:40 +09003594 struct host_if_drv *hif_drv = vif->hif_drv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003595
Tony Choa4ab1ad2015-10-12 16:56:05 +09003596 if (!hif_drv) {
Chris Parkb92f9302016-02-22 13:12:02 +09003597 netdev_err(vif->ndev, "driver is null\n");
Leo Kim24db7132015-09-16 18:36:01 +09003598 return -EFAULT;
3599 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003600
Leo Kimcc2d7e92015-10-29 11:58:36 +09003601 del_timer(&hif_drv->remain_on_ch_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003602
Tony Cho143eb952015-09-21 12:16:32 +09003603 memset(&msg, 0, sizeof(struct host_if_msg));
Tony Choa9f812a2015-09-21 12:16:33 +09003604 msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
Glen Leecf601062015-12-21 14:18:39 +09003605 msg.vif = vif;
Chaehyun Lim6b0f7cd2015-12-30 21:15:29 +09003606 msg.body.remain_on_ch.id = session_id;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003607
Binoy Jayana5c84b22016-06-23 11:11:52 +05303608 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003609 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003610 netdev_err(vif->ndev, "wilc mq send fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003611
Leo Kim31390ee2015-10-19 18:26:08 +09003612 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003613}
3614
Chaehyun Lim8859fc22015-12-30 21:15:27 +09003615int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003616{
Chaehyun Limde61db92015-12-30 21:15:25 +09003617 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003618 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003619
Tony Cho143eb952015-09-21 12:16:32 +09003620 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003621
Tony Choa9f812a2015-09-21 12:16:33 +09003622 msg.id = HOST_IF_MSG_REGISTER_FRAME;
Chaehyun Lim2a8432f2015-12-30 21:15:26 +09003623 switch (frame_type) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003624 case ACTION:
Leo Kimbcb410b2015-10-29 11:58:40 +09003625 msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003626 break;
3627
3628 case PROBE_REQ:
Leo Kimbcb410b2015-10-29 11:58:40 +09003629 msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003630 break;
3631
3632 default:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003633 break;
3634 }
Chaehyun Lim2a8432f2015-12-30 21:15:26 +09003635 msg.body.reg_frame.frame_type = frame_type;
Chaehyun Lim8859fc22015-12-30 21:15:27 +09003636 msg.body.reg_frame.reg = reg;
Glen Leecf601062015-12-21 14:18:39 +09003637 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003638
Binoy Jayana5c84b22016-06-23 11:11:52 +05303639 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003640 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003641 netdev_err(vif->ndev, "wilc mq send fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003642
Leo Kim31390ee2015-10-19 18:26:08 +09003643 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003644}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003645
Chaehyun Lim916935f2016-01-03 17:35:57 +09003646int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
Chaehyun Lim733d1032016-01-03 17:36:01 +09003647 u32 head_len, u8 *head, u32 tail_len, u8 *tail)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003648{
Chaehyun Lim4d84dbe2016-01-03 17:35:55 +09003649 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003650 struct host_if_msg msg;
Chaehyun Lim75bf22c2016-01-03 17:36:02 +09003651 struct beacon_attr *beacon_info = &msg.body.beacon_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003652
Tony Cho143eb952015-09-21 12:16:32 +09003653 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003654
Tony Choa9f812a2015-09-21 12:16:33 +09003655 msg.id = HOST_IF_MSG_ADD_BEACON;
Glen Leecf601062015-12-21 14:18:39 +09003656 msg.vif = vif;
Chaehyun Lim75bf22c2016-01-03 17:36:02 +09003657 beacon_info->interval = interval;
3658 beacon_info->dtim_period = dtim_period;
3659 beacon_info->head_len = head_len;
3660 beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
3661 if (!beacon_info->head) {
Leo Kim31390ee2015-10-19 18:26:08 +09003662 result = -ENOMEM;
Leo Kim24db7132015-09-16 18:36:01 +09003663 goto ERRORHANDLER;
3664 }
Chaehyun Lim75bf22c2016-01-03 17:36:02 +09003665 beacon_info->tail_len = tail_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003666
Chaehyun Lim2df35852016-01-03 17:36:00 +09003667 if (tail_len > 0) {
Chaehyun Lim75bf22c2016-01-03 17:36:02 +09003668 beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
3669 if (!beacon_info->tail) {
Leo Kim31390ee2015-10-19 18:26:08 +09003670 result = -ENOMEM;
Leo Kim24db7132015-09-16 18:36:01 +09003671 goto ERRORHANDLER;
3672 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003673 } else {
Chaehyun Lim75bf22c2016-01-03 17:36:02 +09003674 beacon_info->tail = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003675 }
3676
Binoy Jayana5c84b22016-06-23 11:11:52 +05303677 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003678 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003679 netdev_err(vif->ndev, "wilc mq send fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003680
Leo Kim24db7132015-09-16 18:36:01 +09003681ERRORHANDLER:
Leo Kim31390ee2015-10-19 18:26:08 +09003682 if (result) {
Chaehyun Lim75bf22c2016-01-03 17:36:02 +09003683 kfree(beacon_info->head);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003684
Chaehyun Lim75bf22c2016-01-03 17:36:02 +09003685 kfree(beacon_info->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003686 }
3687
Leo Kim31390ee2015-10-19 18:26:08 +09003688 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003689}
3690
Glen Leefbf53792015-12-21 14:18:40 +09003691int wilc_del_beacon(struct wilc_vif *vif)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003692{
Chaehyun Lim0a5298c2015-11-06 19:11:10 +09003693 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003694 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003695
Tony Choa9f812a2015-09-21 12:16:33 +09003696 msg.id = HOST_IF_MSG_DEL_BEACON;
Glen Leecf601062015-12-21 14:18:39 +09003697 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003698
Binoy Jayana5c84b22016-06-23 11:11:52 +05303699 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003700 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003701 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003702
Leo Kim31390ee2015-10-19 18:26:08 +09003703 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003704}
3705
Glen Leefbf53792015-12-21 14:18:40 +09003706int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003707{
Chaehyun Lim18cfbd32015-11-06 19:11:16 +09003708 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003709 struct host_if_msg msg;
Chaehyun Lim773e02e2015-11-06 19:11:19 +09003710 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003711
Tony Cho143eb952015-09-21 12:16:32 +09003712 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003713
Tony Choa9f812a2015-09-21 12:16:33 +09003714 msg.id = HOST_IF_MSG_ADD_STATION;
Glen Leecf601062015-12-21 14:18:39 +09003715 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003716
Chaehyun Lim773e02e2015-11-06 19:11:19 +09003717 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3718 if (add_sta_info->rates_len > 0) {
Chaehyun Lim90623052015-11-06 19:11:21 +09003719 add_sta_info->rates = kmemdup(sta_param->rates,
3720 add_sta_info->rates_len,
3721 GFP_KERNEL);
3722 if (!add_sta_info->rates)
Leo Kim7ae43362015-09-16 18:35:59 +09003723 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003724 }
3725
Binoy Jayana5c84b22016-06-23 11:11:52 +05303726 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003727 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003728 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Leo Kim31390ee2015-10-19 18:26:08 +09003729 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003730}
3731
Glen Leefbf53792015-12-21 14:18:40 +09003732int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003733{
Chaehyun Lim79a0c0a2015-11-06 19:11:12 +09003734 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003735 struct host_if_msg msg;
Chaehyun Limc87fbed2015-11-06 19:11:15 +09003736 struct del_sta *del_sta_info = &msg.body.del_sta_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003737
Tony Cho143eb952015-09-21 12:16:32 +09003738 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003739
Tony Choa9f812a2015-09-21 12:16:33 +09003740 msg.id = HOST_IF_MSG_DEL_STATION;
Glen Leecf601062015-12-21 14:18:39 +09003741 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003742
Chaehyun Limc9c4eb42015-11-06 19:11:14 +09003743 if (!mac_addr)
Chaehyun Limc87fbed2015-11-06 19:11:15 +09003744 eth_broadcast_addr(del_sta_info->mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003745 else
Chaehyun Limc87fbed2015-11-06 19:11:15 +09003746 memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003747
Binoy Jayana5c84b22016-06-23 11:11:52 +05303748 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003749 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003750 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Leo Kim31390ee2015-10-19 18:26:08 +09003751 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003752}
Leo Kimae4dfa52015-10-13 19:49:26 +09003753
Chaehyun Lim2092374d2016-01-03 17:35:50 +09003754int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003755{
Chaehyun Lim253eb922016-01-03 17:35:49 +09003756 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003757 struct host_if_msg msg;
Chaehyun Lim55d44a62016-01-03 17:35:51 +09003758 struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
Chaehyun Lim06e682b2016-01-03 17:35:52 +09003759 u8 zero_addr[ETH_ALEN] = {0};
Chaehyun Limcc971ee2016-01-03 17:35:53 +09003760 int i;
Chaehyun Lim9d6cec92016-01-03 17:35:54 +09003761 u8 assoc_sta = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003762
Tony Cho143eb952015-09-21 12:16:32 +09003763 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003764
Tony Choa9f812a2015-09-21 12:16:33 +09003765 msg.id = HOST_IF_MSG_DEL_ALL_STA;
Glen Leecf601062015-12-21 14:18:39 +09003766 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003767
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003768 for (i = 0; i < MAX_NUM_STA; i++) {
Chaehyun Lim06e682b2016-01-03 17:35:52 +09003769 if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
Chaehyun Lim55d44a62016-01-03 17:35:51 +09003770 memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i], ETH_ALEN);
Chaehyun Lim9d6cec92016-01-03 17:35:54 +09003771 assoc_sta++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003772 }
3773 }
Chris Park9ac0c052016-02-22 13:11:56 +09003774 if (!assoc_sta)
Leo Kim31390ee2015-10-19 18:26:08 +09003775 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003776
Chaehyun Lim9d6cec92016-01-03 17:35:54 +09003777 del_all_sta_info->assoc_sta = assoc_sta;
Binoy Jayana5c84b22016-06-23 11:11:52 +05303778 result = wilc_enqueue_cmd(&msg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003779
Leo Kim31390ee2015-10-19 18:26:08 +09003780 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003781 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Leo Kim27e1f132016-04-01 17:44:13 +09003782 else
3783 wait_for_completion(&hif_wait_response);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003784
Leo Kim31390ee2015-10-19 18:26:08 +09003785 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003786}
3787
Chaehyun Lim4208e662016-01-03 17:35:44 +09003788int wilc_edit_station(struct wilc_vif *vif,
Chaehyun Lim4c7abe12016-01-03 17:35:45 +09003789 struct add_sta_param *sta_param)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003790{
Chaehyun Lim4208e662016-01-03 17:35:44 +09003791 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003792 struct host_if_msg msg;
Chaehyun Lim785c0712016-01-03 17:35:46 +09003793 struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003794
Tony Cho143eb952015-09-21 12:16:32 +09003795 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003796
Tony Choa9f812a2015-09-21 12:16:33 +09003797 msg.id = HOST_IF_MSG_EDIT_STATION;
Glen Leecf601062015-12-21 14:18:39 +09003798 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003799
Chaehyun Lim785c0712016-01-03 17:35:46 +09003800 memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3801 if (add_sta_info->rates_len > 0) {
Chaehyun Lime38d8502016-01-03 17:35:48 +09003802 add_sta_info->rates = kmemdup(sta_param->rates,
3803 add_sta_info->rates_len,
3804 GFP_KERNEL);
3805 if (!add_sta_info->rates)
Leo Kim7ae43362015-09-16 18:35:59 +09003806 return -ENOMEM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003807 }
3808
Binoy Jayana5c84b22016-06-23 11:11:52 +05303809 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003810 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003811 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Leo Kim24db7132015-09-16 18:36:01 +09003812
Leo Kim31390ee2015-10-19 18:26:08 +09003813 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003814}
Glen Lee108b3432015-09-16 18:53:20 +09003815
Chaehyun Limecd27502015-12-30 21:15:32 +09003816int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003817{
Chaehyun Lim5d48f122015-12-30 21:15:30 +09003818 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003819 struct host_if_msg msg;
Chaehyun Lim568640e2015-12-30 21:15:33 +09003820 struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003821
Glen Leeff9d65a2016-02-04 18:15:20 +09003822 if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
3823 return 0;
3824
Tony Cho143eb952015-09-21 12:16:32 +09003825 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003826
Tony Choa9f812a2015-09-21 12:16:33 +09003827 msg.id = HOST_IF_MSG_POWER_MGMT;
Glen Leecf601062015-12-21 14:18:39 +09003828 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003829
Chaehyun Lim568640e2015-12-30 21:15:33 +09003830 pwr_mgmt_info->enabled = enabled;
3831 pwr_mgmt_info->timeout = timeout;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003832
Binoy Jayana5c84b22016-06-23 11:11:52 +05303833 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003834 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003835 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Leo Kim31390ee2015-10-19 18:26:08 +09003836 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003837}
3838
Chaehyun Limb80c0942015-12-30 21:15:35 +09003839int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
Chaehyun Lim2dff2d42015-12-30 21:15:36 +09003840 u32 count)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003841{
Chaehyun Lim14d95262015-12-30 21:15:34 +09003842 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09003843 struct host_if_msg msg;
Chaehyun Lim40ecd382015-12-30 21:15:37 +09003844 struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003845
Tony Cho143eb952015-09-21 12:16:32 +09003846 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003847
Tony Choa9f812a2015-09-21 12:16:33 +09003848 msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
Glen Leecf601062015-12-21 14:18:39 +09003849 msg.vif = vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003850
Chaehyun Lim40ecd382015-12-30 21:15:37 +09003851 multicast_filter_param->enabled = enabled;
3852 multicast_filter_param->cnt = count;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003853
Binoy Jayana5c84b22016-06-23 11:11:52 +05303854 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09003855 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09003856 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Leo Kim31390ee2015-10-19 18:26:08 +09003857 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003858}
3859
Leo Kim6b5180a2016-02-04 18:24:10 +09003860static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003861{
Leo Kime0a12212015-10-12 16:55:49 +09003862 struct join_bss_param *pNewJoinBssParam = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003863 u8 *pu8IEs;
Chaehyun Limd85f5322015-06-11 14:35:54 +09003864 u16 u16IEsLen;
3865 u16 index = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003866 u8 suppRatesNo = 0;
3867 u8 extSuppRatesNo;
Chaehyun Limd85f5322015-06-11 14:35:54 +09003868 u16 jumpOffset;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09003869 u8 pcipherCount;
3870 u8 authCount;
3871 u8 pcipherTotalCount = 0;
3872 u8 authTotalCount = 0;
3873 u8 i, j;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003874
Leo Kim390b6db2016-02-04 18:24:23 +09003875 pu8IEs = ptstrNetworkInfo->ies;
3876 u16IEsLen = ptstrNetworkInfo->ies_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003877
sayli karnikfaa48ea2016-09-16 16:23:02 +05303878 pNewJoinBssParam = kzalloc(sizeof(*pNewJoinBssParam), GFP_KERNEL);
Leo Kim91109e12015-10-19 18:26:13 +09003879 if (pNewJoinBssParam) {
Leo Kimdf340fd2016-02-04 18:24:17 +09003880 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->dtim_period;
Leo Kim4b313e92016-02-04 18:24:16 +09003881 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->beacon_period;
Leo Kimfa5e2d12016-02-04 18:24:12 +09003882 pNewJoinBssParam->cap_info = ptstrNetworkInfo->cap_info;
Chaehyun Limf1764292016-02-12 23:04:37 +09003883 memcpy(pNewJoinBssParam->bssid, ptstrNetworkInfo->bssid, 6);
Leo Kim2a3ff582016-02-04 18:24:13 +09003884 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->ssid,
Leo Kima36e89e2016-02-04 18:24:14 +09003885 ptstrNetworkInfo->ssid_len + 1);
3886 pNewJoinBssParam->ssid_len = ptstrNetworkInfo->ssid_len;
Chaehyun Lim2cc46832015-08-07 09:02:01 +09003887 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
3888 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003889
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003890 while (index < u16IEsLen) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003891 if (pu8IEs[index] == SUPP_RATES_IE) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003892 suppRatesNo = pu8IEs[index + 1];
3893 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
Leo Kimae4dfa52015-10-13 19:49:26 +09003894 index += 2;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003895
Leo Kimd1666e22015-10-28 15:59:22 +09003896 for (i = 0; i < suppRatesNo; i++)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003897 pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
Leo Kimd1666e22015-10-28 15:59:22 +09003898
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003899 index += suppRatesNo;
3900 continue;
Leo Kimae4dfa52015-10-13 19:49:26 +09003901 } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003902 extSuppRatesNo = pu8IEs[index + 1];
3903 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
3904 pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
3905 else
3906 pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
3907 index += 2;
Leo Kimd1666e22015-10-28 15:59:22 +09003908 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003909 pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
Leo Kimd1666e22015-10-28 15:59:22 +09003910
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003911 index += extSuppRatesNo;
3912 continue;
Leo Kimae4dfa52015-10-13 19:49:26 +09003913 } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
Chaehyun Lim0be1eb72015-06-13 15:41:18 +09003914 pNewJoinBssParam->ht_capable = true;
Leo Kimae4dfa52015-10-13 19:49:26 +09003915 index += pu8IEs[index + 1] + 2;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003916 continue;
Leo Kimae4dfa52015-10-13 19:49:26 +09003917 } else if ((pu8IEs[index] == WMM_IE) &&
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003918 (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
Leo Kimae4dfa52015-10-13 19:49:26 +09003919 (pu8IEs[index + 4] == 0xF2) &&
3920 (pu8IEs[index + 5] == 0x02) &&
3921 ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003922 (pu8IEs[index + 7] == 0x01)) {
Chaehyun Lim0be1eb72015-06-13 15:41:18 +09003923 pNewJoinBssParam->wmm_cap = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003924
Anish Bhattffda2032015-09-29 12:15:49 -07003925 if (pu8IEs[index + 8] & BIT(7))
Chaehyun Lim0be1eb72015-06-13 15:41:18 +09003926 pNewJoinBssParam->uapsd_cap = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003927 index += pu8IEs[index + 1] + 2;
3928 continue;
Leo Kimae4dfa52015-10-13 19:49:26 +09003929 } else if ((pu8IEs[index] == P2P_IE) &&
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003930 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
Leo Kimae4dfa52015-10-13 19:49:26 +09003931 (pu8IEs[index + 4] == 0x9a) &&
3932 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09003933 u16 u16P2P_count;
Luis de Bethencourt78c87592015-06-26 16:45:14 +02003934
Leo Kimafb70652016-02-04 18:24:22 +09003935 pNewJoinBssParam->tsf = ptstrNetworkInfo->tsf_lo;
Leo Kim7a8d51d2015-10-15 13:24:43 +09003936 pNewJoinBssParam->noa_enabled = 1;
Leo Kimcc179002015-10-15 13:24:47 +09003937 pNewJoinBssParam->idx = pu8IEs[index + 9];
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003938
Anish Bhattffda2032015-09-29 12:15:49 -07003939 if (pu8IEs[index + 10] & BIT(7)) {
Leo Kimd72b33c2015-10-15 13:24:44 +09003940 pNewJoinBssParam->opp_enabled = 1;
Leo Kim99b66942015-10-15 13:24:45 +09003941 pNewJoinBssParam->ct_window = pu8IEs[index + 10];
Leo Kimd72b33c2015-10-15 13:24:44 +09003942 } else {
3943 pNewJoinBssParam->opp_enabled = 0;
3944 }
Leo Kimae4dfa52015-10-13 19:49:26 +09003945
Leo Kimc21047e2015-10-15 13:24:46 +09003946 pNewJoinBssParam->cnt = pu8IEs[index + 11];
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003947 u16P2P_count = index + 12;
3948
Leo Kim109e6ca2015-10-15 13:24:48 +09003949 memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003950 u16P2P_count += 4;
3951
Leo Kim1d8b76b2015-10-15 13:24:49 +09003952 memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003953 u16P2P_count += 4;
3954
Leo Kim4be55e22015-10-28 15:59:27 +09003955 memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003956
3957 index += pu8IEs[index + 1] + 2;
3958 continue;
3959
Leo Kimae4dfa52015-10-13 19:49:26 +09003960 } else if ((pu8IEs[index] == RSN_IE) ||
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003961 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
3962 (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
3963 (pu8IEs[index + 5] == 0x01))) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09003964 u16 rsnIndex = index;
Leo Kimae4dfa52015-10-13 19:49:26 +09003965
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003966 if (pu8IEs[rsnIndex] == RSN_IE) {
3967 pNewJoinBssParam->mode_802_11i = 2;
Leo Kimae4dfa52015-10-13 19:49:26 +09003968 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003969 if (pNewJoinBssParam->mode_802_11i == 0)
3970 pNewJoinBssParam->mode_802_11i = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003971 rsnIndex += 4;
3972 }
Leo Kimae4dfa52015-10-13 19:49:26 +09003973
3974 rsnIndex += 7;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003975 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
3976 rsnIndex++;
Leo Kimae4dfa52015-10-13 19:49:26 +09003977 jumpOffset = pu8IEs[rsnIndex] * 4;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003978 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
Leo Kimae4dfa52015-10-13 19:49:26 +09003979 rsnIndex += 2;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003980
Leo Kimd1666e22015-10-28 15:59:22 +09003981 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003982 pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
Leo Kimd1666e22015-10-28 15:59:22 +09003983
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003984 pcipherTotalCount += pcipherCount;
3985 rsnIndex += jumpOffset;
3986
3987 jumpOffset = pu8IEs[rsnIndex] * 4;
3988
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003989 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
Leo Kimae4dfa52015-10-13 19:49:26 +09003990 rsnIndex += 2;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003991
Leo Kimd1666e22015-10-28 15:59:22 +09003992 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003993 pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
Leo Kimd1666e22015-10-28 15:59:22 +09003994
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003995 authTotalCount += authCount;
3996 rsnIndex += jumpOffset;
Leo Kimae4dfa52015-10-13 19:49:26 +09003997
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003998 if (pu8IEs[index] == RSN_IE) {
3999 pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4000 pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4001 rsnIndex += 2;
4002 }
Abdul Hussainf717c0eb2015-06-16 09:49:49 +00004003 pNewJoinBssParam->rsn_found = true;
Leo Kimae4dfa52015-10-13 19:49:26 +09004004 index += pu8IEs[index + 1] + 2;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004005 continue;
4006 } else
Leo Kimae4dfa52015-10-13 19:49:26 +09004007 index += pu8IEs[index + 1] + 2;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004008 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004009 }
4010
4011 return (void *)pNewJoinBssParam;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004012}
4013
Chaehyun Lim6964f082015-12-30 21:15:39 +09004014int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004015{
Chaehyun Lim3d2a0bf2015-12-30 21:15:38 +09004016 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09004017 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004018
Tony Cho143eb952015-09-21 12:16:32 +09004019 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004020
Tony Choa9f812a2015-09-21 12:16:33 +09004021 msg.id = HOST_IF_MSG_SET_IPADDRESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004022
Chaehyun Lim6964f082015-12-30 21:15:39 +09004023 msg.body.ip_info.ip_addr = ip_addr;
Glen Leecf601062015-12-21 14:18:39 +09004024 msg.vif = vif;
Tony Chofb2d65e2015-09-30 18:44:39 +09004025 msg.body.ip_info.idx = idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004026
Binoy Jayana5c84b22016-06-23 11:11:52 +05304027 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09004028 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09004029 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004030
Leo Kim31390ee2015-10-19 18:26:08 +09004031 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004032}
4033
Chaehyun Lim3b4276d2015-12-30 21:15:43 +09004034static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004035{
Chaehyun Limcb8f4e02015-12-30 21:15:41 +09004036 int result = 0;
Tony Cho143eb952015-09-21 12:16:32 +09004037 struct host_if_msg msg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004038
Tony Cho143eb952015-09-21 12:16:32 +09004039 memset(&msg, 0, sizeof(struct host_if_msg));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004040
Tony Choa9f812a2015-09-21 12:16:33 +09004041 msg.id = HOST_IF_MSG_GET_IPADDRESS;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004042
Chaehyun Lim3b4276d2015-12-30 21:15:43 +09004043 msg.body.ip_info.ip_addr = ip_addr;
Glen Leecf601062015-12-21 14:18:39 +09004044 msg.vif = vif;
Tony Chofb2d65e2015-09-30 18:44:39 +09004045 msg.body.ip_info.idx = idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004046
Binoy Jayana5c84b22016-06-23 11:11:52 +05304047 result = wilc_enqueue_cmd(&msg);
Leo Kim31390ee2015-10-19 18:26:08 +09004048 if (result)
Chris Parkb92f9302016-02-22 13:12:02 +09004049 netdev_err(vif->ndev, "wilc_mq_send fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004050
Leo Kim31390ee2015-10-19 18:26:08 +09004051 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004052}
Glen Lee70418792016-02-04 18:15:27 +09004053
4054int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
4055{
4056 int ret = 0;
4057 struct host_if_msg msg;
4058
4059 memset(&msg, 0, sizeof(struct host_if_msg));
4060
4061 msg.id = HOST_IF_MSG_SET_TX_POWER;
4062 msg.body.tx_power.tx_pwr = tx_power;
4063 msg.vif = vif;
4064
Binoy Jayana5c84b22016-06-23 11:11:52 +05304065 ret = wilc_enqueue_cmd(&msg);
Glen Lee70418792016-02-04 18:15:27 +09004066 if (ret)
4067 netdev_err(vif->ndev, "wilc_mq_send fail\n");
4068
4069 return ret;
4070}
4071
4072int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
4073{
4074 int ret = 0;
4075 struct host_if_msg msg;
4076
4077 memset(&msg, 0, sizeof(struct host_if_msg));
4078
4079 msg.id = HOST_IF_MSG_GET_TX_POWER;
4080 msg.vif = vif;
4081
Binoy Jayana5c84b22016-06-23 11:11:52 +05304082 ret = wilc_enqueue_cmd(&msg);
Glen Lee70418792016-02-04 18:15:27 +09004083 if (ret)
4084 netdev_err(vif->ndev, "Failed to get TX PWR\n");
4085
Chaehyun Lim613eaa32016-03-14 09:40:27 +09004086 wait_for_completion(&hif_wait_response);
Glen Lee70418792016-02-04 18:15:27 +09004087 *tx_power = msg.body.tx_power.tx_pwr;
4088
4089 return ret;
4090}