Blame view

drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 62.2 KB
c5c77ba18   Johnny Kim   staging: wilc1000...
1
  #include "wilc_wfi_cfgoperations.h"
491880eb4   Arnd Bergmann   staging/wilc1000:...
2
  #include "host_interface.h"
7ae433631   Leo Kim   staging: wilc1000...
3
  #include <linux/errno.h>
c5c77ba18   Johnny Kim   staging: wilc1000...
4

15162fbc7   Arnd Bergmann   staging/wilc1000:...
5
6
7
8
9
10
11
12
  #define NO_ENCRYPT		0
  #define ENCRYPT_ENABLED		BIT(0)
  #define WEP			BIT(1)
  #define WEP_EXTENDED		BIT(2)
  #define WPA			BIT(3)
  #define WPA2			BIT(4)
  #define AES			BIT(5)
  #define TKIP			BIT(6)
15162fbc7   Arnd Bergmann   staging/wilc1000:...
13
14
15
16
  #define FRAME_TYPE_ID			0
  #define ACTION_CAT_ID			24
  #define ACTION_SUBTYPE_ID		25
  #define P2P_PUB_ACTION_SUBTYPE		30
15162fbc7   Arnd Bergmann   staging/wilc1000:...
17
18
19
20
21
22
  #define ACTION_FRAME			0xd0
  #define GO_INTENT_ATTR_ID		0x04
  #define CHANLIST_ATTR_ID		0x0b
  #define OPERCHAN_ATTR_ID		0x11
  #define PUB_ACTION_ATTR_ID		0x04
  #define P2PELEM_ATTR_ID			0xdd
15162fbc7   Arnd Bergmann   staging/wilc1000:...
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  #define GO_NEG_REQ			0x00
  #define GO_NEG_RSP			0x01
  #define GO_NEG_CONF			0x02
  #define P2P_INV_REQ			0x03
  #define P2P_INV_RSP			0x04
  #define PUBLIC_ACT_VENDORSPEC		0x09
  #define GAS_INTIAL_REQ			0x0a
  #define GAS_INTIAL_RSP			0x0b
  
  #define INVALID_CHANNEL			0
  
  #define nl80211_SCAN_RESULT_EXPIRE	(3 * HZ)
  #define SCAN_RESULT_EXPIRE		(40 * HZ)
  
  static const u32 cipher_suites[] = {
  	WLAN_CIPHER_SUITE_WEP40,
  	WLAN_CIPHER_SUITE_WEP104,
  	WLAN_CIPHER_SUITE_TKIP,
  	WLAN_CIPHER_SUITE_CCMP,
  	WLAN_CIPHER_SUITE_AES_CMAC,
  };
  
  static const struct ieee80211_txrx_stypes
  	wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
  	[NL80211_IFTYPE_STATION] = {
  		.tx = 0xffff,
  		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  			BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  	},
  	[NL80211_IFTYPE_AP] = {
  		.tx = 0xffff,
  		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  			BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  			BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  			BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  			BIT(IEEE80211_STYPE_AUTH >> 4) |
  			BIT(IEEE80211_STYPE_DEAUTH >> 4) |
  			BIT(IEEE80211_STYPE_ACTION >> 4)
  	},
  	[NL80211_IFTYPE_P2P_CLIENT] = {
  		.tx = 0xffff,
  		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  			BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  			BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  			BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  			BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  			BIT(IEEE80211_STYPE_AUTH >> 4) |
  			BIT(IEEE80211_STYPE_DEAUTH >> 4)
  	}
  };
73584a40d   Glen Lee   staging: wilc1000...
73
74
75
  static const struct wiphy_wowlan_support wowlan_support = {
  	.flags = WIPHY_WOWLAN_ANY
  };
15162fbc7   Arnd Bergmann   staging/wilc1000:...
76
77
78
79
80
  #define WILC_WFI_DWELL_PASSIVE 100
  #define WILC_WFI_DWELL_ACTIVE  40
  
  #define TCP_ACK_FILTER_LINK_SPEED_THRESH	54
  #define DEFAULT_LINK_SPEED			72
c5c77ba18   Johnny Kim   staging: wilc1000...
81
82
83
84
  #define IS_MANAGMEMENT				0x100
  #define IS_MANAGMEMENT_CALLBACK			0x080
  #define IS_MGMT_STATUS_SUCCES			0x040
  #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
85
86
  extern int wilc_mac_open(struct net_device *ndev);
  extern int wilc_mac_close(struct net_device *ndev);
c5c77ba18   Johnny Kim   staging: wilc1000...
87

6b5180a08   Leo Kim   staging: wilc1000...
88
  static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
771fbae49   Leo Kim   staging: wilc1000...
89
  static u32 last_scanned_cnt;
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
90
  struct timer_list wilc_during_ip_timer;
1608c4034   Arnd Bergmann   staging/wilc1000:...
91
  static struct timer_list hAgingTimer;
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
92
  static u8 op_ifcs;
c5c77ba18   Johnny Kim   staging: wilc1000...
93

0e1af73dd   Arnd Bergmann   staging/wilc1000:...
94
  u8 wilc_initialized = 1;
c5c77ba18   Johnny Kim   staging: wilc1000...
95
96
  
  #define CHAN2G(_channel, _freq, _flags) {	 \
57fbcce37   Johannes Berg   cfg80211: remove ...
97
  		.band             = NL80211_BAND_2GHZ, \
c5c77ba18   Johnny Kim   staging: wilc1000...
98
99
100
101
102
103
  		.center_freq      = (_freq),		 \
  		.hw_value         = (_channel),		 \
  		.flags            = (_flags),		 \
  		.max_antenna_gain = 0,			 \
  		.max_power        = 30,			 \
  }
2736f476a   Leo Kim   staging: wilc1000...
104
  static struct ieee80211_channel ieee80211_2ghz_channels[] = {
c5c77ba18   Johnny Kim   staging: wilc1000...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  	CHAN2G(1,  2412, 0),
  	CHAN2G(2,  2417, 0),
  	CHAN2G(3,  2422, 0),
  	CHAN2G(4,  2427, 0),
  	CHAN2G(5,  2432, 0),
  	CHAN2G(6,  2437, 0),
  	CHAN2G(7,  2442, 0),
  	CHAN2G(8,  2447, 0),
  	CHAN2G(9,  2452, 0),
  	CHAN2G(10, 2457, 0),
  	CHAN2G(11, 2462, 0),
  	CHAN2G(12, 2467, 0),
  	CHAN2G(13, 2472, 0),
  	CHAN2G(14, 2484, 0),
  };
  
  #define RATETAB_ENT(_rate, _hw_value, _flags) {	\
  		.bitrate  = (_rate),			\
  		.hw_value = (_hw_value),		\
  		.flags    = (_flags),			\
  }
8d48b5bab   Leo Kim   staging: wilc1000...
126
  static struct ieee80211_rate ieee80211_bitrates[] = {
c5c77ba18   Johnny Kim   staging: wilc1000...
127
128
129
130
131
132
133
134
135
136
137
138
139
  	RATETAB_ENT(10,  0,  0),
  	RATETAB_ENT(20,  1,  0),
  	RATETAB_ENT(55,  2,  0),
  	RATETAB_ENT(110, 3,  0),
  	RATETAB_ENT(60,  9,  0),
  	RATETAB_ENT(90,  6,  0),
  	RATETAB_ENT(120, 7,  0),
  	RATETAB_ENT(180, 8,  0),
  	RATETAB_ENT(240, 9,  0),
  	RATETAB_ENT(360, 10, 0),
  	RATETAB_ENT(480, 11, 0),
  	RATETAB_ENT(540, 12, 0),
  };
c5c77ba18   Johnny Kim   staging: wilc1000...
140
141
142
143
  struct p2p_mgmt_data {
  	int size;
  	u8 *buff;
  };
0bd8274fb   Leo Kim   staging: wilc1000...
144
  static u8 wlan_channel = INVALID_CHANNEL;
1608c4034   Arnd Bergmann   staging/wilc1000:...
145
  static u8 curr_channel;
881eb5d81   Leo Kim   staging: wilc1000...
146
  static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
583d972cf   Leo Kim   staging: wilc1000...
147
  static u8 p2p_local_random = 0x01;
d38f5ba48   Eva Rachel Retuya   staging: wilc1000...
148
  static u8 p2p_recv_random;
8668594a9   Leo Kim   staging: wilc1000...
149
  static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
a25d51860   Leo Kim   staging: wilc1000...
150
  static bool wilc_ie;
c5c77ba18   Johnny Kim   staging: wilc1000...
151
152
  
  static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
2736f476a   Leo Kim   staging: wilc1000...
153
154
  	.channels = ieee80211_2ghz_channels,
  	.n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
8d48b5bab   Leo Kim   staging: wilc1000...
155
156
  	.bitrates = ieee80211_bitrates,
  	.n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
c5c77ba18   Johnny Kim   staging: wilc1000...
157
  };
c5c77ba18   Johnny Kim   staging: wilc1000...
158
159
  struct add_key_params {
  	u8 key_idx;
c5c77ba18   Johnny Kim   staging: wilc1000...
160
  	bool pairwise;
c5c77ba18   Johnny Kim   staging: wilc1000...
161
162
  	u8 *mac_addr;
  };
1608c4034   Arnd Bergmann   staging/wilc1000:...
163
164
165
166
167
168
169
170
  static struct add_key_params g_add_gtk_key_params;
  static struct wilc_wfi_key g_key_gtk_params;
  static struct add_key_params g_add_ptk_key_params;
  static struct wilc_wfi_key g_key_ptk_params;
  static struct wilc_wfi_wep_key g_key_wep_params;
  static bool g_ptk_keys_saved;
  static bool g_gtk_keys_saved;
  static bool g_wep_keys_saved;
c5c77ba18   Johnny Kim   staging: wilc1000...
171
172
  
  #define AGING_TIME	(9 * 1000)
7e872df9c   Leo Kim   staging: wilc1000...
173
  #define during_ip_time	15000
c5c77ba18   Johnny Kim   staging: wilc1000...
174

d14991afe   Leo Kim   staging: wilc1000...
175
  static void clear_shadow_scan(void)
c5c77ba18   Johnny Kim   staging: wilc1000...
176
  {
c5c77ba18   Johnny Kim   staging: wilc1000...
177
  	int i;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
178

c5c77ba18   Johnny Kim   staging: wilc1000...
179
  	if (op_ifcs == 0) {
4183e9794   Greg Kroah-Hartman   staging: wilc1000...
180
  		del_timer_sync(&hAgingTimer);
c5c77ba18   Johnny Kim   staging: wilc1000...
181

771fbae49   Leo Kim   staging: wilc1000...
182
  		for (i = 0; i < last_scanned_cnt; i++) {
390b6db00   Leo Kim   staging: wilc1000...
183
184
185
  			if (last_scanned_shadow[last_scanned_cnt].ies) {
  				kfree(last_scanned_shadow[i].ies);
  				last_scanned_shadow[last_scanned_cnt].ies = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
186
  			}
cb64de7c3   Leo Kim   staging: wilc1000...
187
188
  			kfree(last_scanned_shadow[i].join_params);
  			last_scanned_shadow[i].join_params = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
189
  		}
771fbae49   Leo Kim   staging: wilc1000...
190
  		last_scanned_cnt = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
191
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
192
  }
6b5180a08   Leo Kim   staging: wilc1000...
193
  static u32 get_rssi_avg(struct network_info *network_info)
c5c77ba18   Johnny Kim   staging: wilc1000...
194
  {
51e825f70   Chaehyun Lim   staging: wilc1000...
195
  	u8 i;
c5c77ba18   Johnny Kim   staging: wilc1000...
196
  	int rssi_v = 0;
f2050a189   Leo Kim   staging: wilc1000...
197
198
  	u8 num_rssi = (network_info->str_rssi.u8Full) ?
  		       NUM_RSSI : (network_info->str_rssi.u8Index);
c5c77ba18   Johnny Kim   staging: wilc1000...
199
200
  
  	for (i = 0; i < num_rssi; i++)
f2050a189   Leo Kim   staging: wilc1000...
201
  		rssi_v += network_info->str_rssi.as8RSSI[i];
c5c77ba18   Johnny Kim   staging: wilc1000...
202
203
204
205
  
  	rssi_v /= num_rssi;
  	return rssi_v;
  }
48ee7bad3   Leo Kim   staging: wilc1000...
206
  static void refresh_scan(void *user_void, u8 all, bool direct_scan)
c5c77ba18   Johnny Kim   staging: wilc1000...
207
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
208
  	struct wilc_priv *priv;
c5c77ba18   Johnny Kim   staging: wilc1000...
209
210
211
212
  	struct wiphy *wiphy;
  	struct cfg80211_bss *bss = NULL;
  	int i;
  	int rssi = 0;
4375cad94   Alison Schofield   staging: wilc1000...
213
  	priv = user_void;
c5c77ba18   Johnny Kim   staging: wilc1000...
214
  	wiphy = priv->dev->ieee80211_ptr->wiphy;
771fbae49   Leo Kim   staging: wilc1000...
215
  	for (i = 0; i < last_scanned_cnt; i++) {
6b5180a08   Leo Kim   staging: wilc1000...
216
  		struct network_info *network_info;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
217

ce3b1b5a8   Leo Kim   staging: wilc1000...
218
  		network_info = &last_scanned_shadow[i];
c5c77ba18   Johnny Kim   staging: wilc1000...
219

a35d6e2de   Leo Kim   staging: wilc1000...
220
  		if (!network_info->found || all) {
c6f5e3a67   Leo Kim   staging: wilc1000...
221
  			s32 freq;
c5c77ba18   Johnny Kim   staging: wilc1000...
222
  			struct ieee80211_channel *channel;
ce3b1b5a8   Leo Kim   staging: wilc1000...
223
  			if (network_info) {
57fbcce37   Johannes Berg   cfg80211: remove ...
224
  				freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ);
c6f5e3a67   Leo Kim   staging: wilc1000...
225
  				channel = ieee80211_get_channel(wiphy, freq);
c5c77ba18   Johnny Kim   staging: wilc1000...
226

ce3b1b5a8   Leo Kim   staging: wilc1000...
227
  				rssi = get_rssi_avg(network_info);
2a3ff58a8   Leo Kim   staging: wilc1000...
228
  				if (memcmp("DIRECT-", network_info->ssid, 7) ||
48ee7bad3   Leo Kim   staging: wilc1000...
229
  				    direct_scan) {
fa5e2d159   Leo Kim   staging: wilc1000...
230
231
232
  					bss = cfg80211_inform_bss(wiphy,
  								  channel,
  								  CFG80211_BSS_FTYPE_UNKNOWN,
38d3bb787   Leo Kim   staging: wilc1000...
233
  								  network_info->bssid,
17d2f2b36   Leo Kim   staging: wilc1000...
234
  								  network_info->tsf_hi,
fa5e2d159   Leo Kim   staging: wilc1000...
235
  								  network_info->cap_info,
4b313e915   Leo Kim   staging: wilc1000...
236
  								  network_info->beacon_period,
390b6db00   Leo Kim   staging: wilc1000...
237
238
  								  (const u8 *)network_info->ies,
  								  (size_t)network_info->ies_len,
fa5e2d159   Leo Kim   staging: wilc1000...
239
240
  								  (s32)rssi * 100,
  								  GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
241
  					cfg80211_put_bss(wiphy, bss);
c5c77ba18   Johnny Kim   staging: wilc1000...
242
243
  				}
  			}
c5c77ba18   Johnny Kim   staging: wilc1000...
244
245
  		}
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
246
  }
12b0138b2   Leo Kim   staging: wilc1000...
247
  static void reset_shadow_found(void)
c5c77ba18   Johnny Kim   staging: wilc1000...
248
  {
c5c77ba18   Johnny Kim   staging: wilc1000...
249
  	int i;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
250

771fbae49   Leo Kim   staging: wilc1000...
251
  	for (i = 0; i < last_scanned_cnt; i++)
a35d6e2de   Leo Kim   staging: wilc1000...
252
  		last_scanned_shadow[i].found = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
253
  }
5e51d8ba0   Leo Kim   staging: wilc1000...
254
  static void update_scan_time(void)
c5c77ba18   Johnny Kim   staging: wilc1000...
255
  {
c5c77ba18   Johnny Kim   staging: wilc1000...
256
  	int i;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
257

771fbae49   Leo Kim   staging: wilc1000...
258
  	for (i = 0; i < last_scanned_cnt; i++)
264d70f4d   Leo Kim   staging: wilc1000...
259
  		last_scanned_shadow[i].time_scan = jiffies;
c5c77ba18   Johnny Kim   staging: wilc1000...
260
  }
93dee8eea   Greg Kroah-Hartman   staging: wilc1000...
261
  static void remove_network_from_shadow(unsigned long arg)
c5c77ba18   Johnny Kim   staging: wilc1000...
262
  {
c5c77ba18   Johnny Kim   staging: wilc1000...
263
264
  	unsigned long now = jiffies;
  	int i, j;
c5c77ba18   Johnny Kim   staging: wilc1000...
265

771fbae49   Leo Kim   staging: wilc1000...
266
  	for (i = 0; i < last_scanned_cnt; i++) {
264d70f4d   Leo Kim   staging: wilc1000...
267
268
  		if (time_after(now, last_scanned_shadow[i].time_scan +
  			       (unsigned long)(SCAN_RESULT_EXPIRE))) {
390b6db00   Leo Kim   staging: wilc1000...
269
270
  			kfree(last_scanned_shadow[i].ies);
  			last_scanned_shadow[i].ies = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
271

cb64de7c3   Leo Kim   staging: wilc1000...
272
  			kfree(last_scanned_shadow[i].join_params);
c5c77ba18   Johnny Kim   staging: wilc1000...
273

771fbae49   Leo Kim   staging: wilc1000...
274
  			for (j = i; (j < last_scanned_cnt - 1); j++)
f1ab117db   Leo Kim   staging: wilc1000...
275
  				last_scanned_shadow[j] = last_scanned_shadow[j + 1];
771fbae49   Leo Kim   staging: wilc1000...
276
277
  
  			last_scanned_cnt--;
c5c77ba18   Johnny Kim   staging: wilc1000...
278
279
  		}
  	}
771fbae49   Leo Kim   staging: wilc1000...
280
  	if (last_scanned_cnt != 0) {
9eb066438   Greg Kroah-Hartman   staging: wilc1000...
281
282
  		hAgingTimer.data = arg;
  		mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
9eb066438   Greg Kroah-Hartman   staging: wilc1000...
283
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
284
  }
93dee8eea   Greg Kroah-Hartman   staging: wilc1000...
285
  static void clear_duringIP(unsigned long arg)
c5c77ba18   Johnny Kim   staging: wilc1000...
286
  {
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
287
  	wilc_optaining_ip = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
288
  }
c5c77ba18   Johnny Kim   staging: wilc1000...
289

6b5180a08   Leo Kim   staging: wilc1000...
290
  static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
157814f07   Leo Kim   staging: wilc1000...
291
  				void *user_void)
c5c77ba18   Johnny Kim   staging: wilc1000...
292
  {
a74cc6b8d   Chaehyun Lim   staging: wilc1000...
293
  	int state = -1;
c5c77ba18   Johnny Kim   staging: wilc1000...
294
  	int i;
771fbae49   Leo Kim   staging: wilc1000...
295
  	if (last_scanned_cnt == 0) {
157814f07   Leo Kim   staging: wilc1000...
296
  		hAgingTimer.data = (unsigned long)user_void;
9eb066438   Greg Kroah-Hartman   staging: wilc1000...
297
  		mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
c5c77ba18   Johnny Kim   staging: wilc1000...
298
299
  		state = -1;
  	} else {
771fbae49   Leo Kim   staging: wilc1000...
300
  		for (i = 0; i < last_scanned_cnt; i++) {
38d3bb787   Leo Kim   staging: wilc1000...
301
302
  			if (memcmp(last_scanned_shadow[i].bssid,
  				   pstrNetworkInfo->bssid, 6) == 0) {
c5c77ba18   Johnny Kim   staging: wilc1000...
303
304
305
306
307
308
309
  				state = i;
  				break;
  			}
  		}
  	}
  	return state;
  }
6b5180a08   Leo Kim   staging: wilc1000...
310
  static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
5c4cf0dda   Leo Kim   staging: wilc1000...
311
  				  void *user_void, void *pJoinParams)
c5c77ba18   Johnny Kim   staging: wilc1000...
312
  {
5c4cf0dda   Leo Kim   staging: wilc1000...
313
  	int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
fbc2fe16a   Chaehyun Lim   staging: wilc1000...
314
  	u32 ap_index = 0;
51e825f70   Chaehyun Lim   staging: wilc1000...
315
  	u8 rssi_index = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
316

64d3546a3   Chris Park   staging: wilc1000...
317
  	if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
c5c77ba18   Johnny Kim   staging: wilc1000...
318
  		return;
64d3546a3   Chris Park   staging: wilc1000...
319

c5c77ba18   Johnny Kim   staging: wilc1000...
320
  	if (ap_found == -1) {
771fbae49   Leo Kim   staging: wilc1000...
321
322
  		ap_index = last_scanned_cnt;
  		last_scanned_cnt++;
c5c77ba18   Johnny Kim   staging: wilc1000...
323
324
325
  	} else {
  		ap_index = ap_found;
  	}
f2050a189   Leo Kim   staging: wilc1000...
326
327
  	rssi_index = last_scanned_shadow[ap_index].str_rssi.u8Index;
  	last_scanned_shadow[ap_index].str_rssi.as8RSSI[rssi_index++] = pstrNetworkInfo->rssi;
c5c77ba18   Johnny Kim   staging: wilc1000...
328
329
  	if (rssi_index == NUM_RSSI) {
  		rssi_index = 0;
f2050a189   Leo Kim   staging: wilc1000...
330
  		last_scanned_shadow[ap_index].str_rssi.u8Full = 1;
c5c77ba18   Johnny Kim   staging: wilc1000...
331
  	}
f2050a189   Leo Kim   staging: wilc1000...
332
  	last_scanned_shadow[ap_index].str_rssi.u8Index = rssi_index;
5c23a2914   Leo Kim   staging: wilc1000...
333
  	last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
fa5e2d159   Leo Kim   staging: wilc1000...
334
  	last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
a36e89e9b   Leo Kim   staging: wilc1000...
335
  	last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
2a3ff58a8   Leo Kim   staging: wilc1000...
336
  	memcpy(last_scanned_shadow[ap_index].ssid,
a36e89e9b   Leo Kim   staging: wilc1000...
337
  	       pstrNetworkInfo->ssid, pstrNetworkInfo->ssid_len);
38d3bb787   Leo Kim   staging: wilc1000...
338
339
  	memcpy(last_scanned_shadow[ap_index].bssid,
  	       pstrNetworkInfo->bssid, ETH_ALEN);
4b313e915   Leo Kim   staging: wilc1000...
340
  	last_scanned_shadow[ap_index].beacon_period = pstrNetworkInfo->beacon_period;
df340fdf0   Leo Kim   staging: wilc1000...
341
  	last_scanned_shadow[ap_index].dtim_period = pstrNetworkInfo->dtim_period;
405a8c786   Leo Kim   staging: wilc1000...
342
  	last_scanned_shadow[ap_index].ch = pstrNetworkInfo->ch;
390b6db00   Leo Kim   staging: wilc1000...
343
  	last_scanned_shadow[ap_index].ies_len = pstrNetworkInfo->ies_len;
17d2f2b36   Leo Kim   staging: wilc1000...
344
  	last_scanned_shadow[ap_index].tsf_hi = pstrNetworkInfo->tsf_hi;
c5c77ba18   Johnny Kim   staging: wilc1000...
345
  	if (ap_found != -1)
390b6db00   Leo Kim   staging: wilc1000...
346
347
348
349
350
  		kfree(last_scanned_shadow[ap_index].ies);
  	last_scanned_shadow[ap_index].ies = kmalloc(pstrNetworkInfo->ies_len,
  						    GFP_KERNEL);
  	memcpy(last_scanned_shadow[ap_index].ies,
  	       pstrNetworkInfo->ies, pstrNetworkInfo->ies_len);
264d70f4d   Leo Kim   staging: wilc1000...
351
352
  	last_scanned_shadow[ap_index].time_scan = jiffies;
  	last_scanned_shadow[ap_index].time_scan_cached = jiffies;
a35d6e2de   Leo Kim   staging: wilc1000...
353
  	last_scanned_shadow[ap_index].found = 1;
c5c77ba18   Johnny Kim   staging: wilc1000...
354
  	if (ap_found != -1)
cb64de7c3   Leo Kim   staging: wilc1000...
355
356
  		kfree(last_scanned_shadow[ap_index].join_params);
  	last_scanned_shadow[ap_index].join_params = pJoinParams;
c5c77ba18   Johnny Kim   staging: wilc1000...
357
  }
1a4c8ce78   Leo Kim   staging: wilc1000...
358
  static void CfgScanResult(enum scan_event scan_event,
6b5180a08   Leo Kim   staging: wilc1000...
359
  			  struct network_info *network_info,
30cd10c46   Leo Kim   staging: wilc1000...
360
  			  void *user_void,
bdd3460f7   Leo Kim   staging: wilc1000...
361
  			  void *join_params)
c5c77ba18   Johnny Kim   staging: wilc1000...
362
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
363
  	struct wilc_priv *priv;
c5c77ba18   Johnny Kim   staging: wilc1000...
364
  	struct wiphy *wiphy;
fb4ec9caa   Chaehyun Lim   staging: wilc1000...
365
  	s32 s32Freq;
c5c77ba18   Johnny Kim   staging: wilc1000...
366
  	struct ieee80211_channel *channel;
c5c77ba18   Johnny Kim   staging: wilc1000...
367
  	struct cfg80211_bss *bss = NULL;
4375cad94   Alison Schofield   staging: wilc1000...
368
  	priv = user_void;
7e4e87d32   Luis de Bethencourt   staging: wilc1000...
369
  	if (priv->bCfgScanning) {
1a4c8ce78   Leo Kim   staging: wilc1000...
370
  		if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
c5c77ba18   Johnny Kim   staging: wilc1000...
371
  			wiphy = priv->dev->ieee80211_ptr->wiphy;
7ae433631   Leo Kim   staging: wilc1000...
372
373
374
  
  			if (!wiphy)
  				return;
0551a72e6   Leo Kim   staging: wilc1000...
375
  			if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
5c23a2914   Leo Kim   staging: wilc1000...
376
377
  			    (((s32)network_info->rssi * 100) < 0 ||
  			    ((s32)network_info->rssi * 100) > 100))
24db713fe   Leo Kim   staging: wilc1000...
378
  				return;
c5c77ba18   Johnny Kim   staging: wilc1000...
379

0551a72e6   Leo Kim   staging: wilc1000...
380
  			if (network_info) {
57fbcce37   Johannes Berg   cfg80211: remove ...
381
  				s32Freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ);
c5c77ba18   Johnny Kim   staging: wilc1000...
382
  				channel = ieee80211_get_channel(wiphy, s32Freq);
7ae433631   Leo Kim   staging: wilc1000...
383
384
  				if (!channel)
  					return;
c5c77ba18   Johnny Kim   staging: wilc1000...
385

d40207637   Leo Kim   staging: wilc1000...
386
  				if (network_info->new_network) {
a89f7c551   Leo Kim   staging: wilc1000...
387
  					if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
c5c77ba18   Johnny Kim   staging: wilc1000...
388
  						priv->u32RcvdChCount++;
bdd3460f7   Leo Kim   staging: wilc1000...
389
  						add_network_to_shadow(network_info, priv, join_params);
c5c77ba18   Johnny Kim   staging: wilc1000...
390

2a3ff58a8   Leo Kim   staging: wilc1000...
391
  						if (!(memcmp("DIRECT-", network_info->ssid, 7))) {
fa5e2d159   Leo Kim   staging: wilc1000...
392
393
394
  							bss = cfg80211_inform_bss(wiphy,
  										  channel,
  										  CFG80211_BSS_FTYPE_UNKNOWN,
38d3bb787   Leo Kim   staging: wilc1000...
395
  										  network_info->bssid,
17d2f2b36   Leo Kim   staging: wilc1000...
396
  										  network_info->tsf_hi,
fa5e2d159   Leo Kim   staging: wilc1000...
397
  										  network_info->cap_info,
4b313e915   Leo Kim   staging: wilc1000...
398
  										  network_info->beacon_period,
390b6db00   Leo Kim   staging: wilc1000...
399
400
  										  (const u8 *)network_info->ies,
  										  (size_t)network_info->ies_len,
fa5e2d159   Leo Kim   staging: wilc1000...
401
402
  										  (s32)network_info->rssi * 100,
  										  GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
403
  							cfg80211_put_bss(wiphy, bss);
c5c77ba18   Johnny Kim   staging: wilc1000...
404
  						}
c5c77ba18   Johnny Kim   staging: wilc1000...
405
406
  					}
  				} else {
4e4467fdd   Chaehyun Lim   staging: wilc1000...
407
  					u32 i;
a89f7c551   Leo Kim   staging: wilc1000...
408

c5c77ba18   Johnny Kim   staging: wilc1000...
409
  					for (i = 0; i < priv->u32RcvdChCount; i++) {
38d3bb787   Leo Kim   staging: wilc1000...
410
  						if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) {
5c23a2914   Leo Kim   staging: wilc1000...
411
  							last_scanned_shadow[i].rssi = network_info->rssi;
264d70f4d   Leo Kim   staging: wilc1000...
412
  							last_scanned_shadow[i].time_scan = jiffies;
c5c77ba18   Johnny Kim   staging: wilc1000...
413
414
415
416
417
  							break;
  						}
  					}
  				}
  			}
1a4c8ce78   Leo Kim   staging: wilc1000...
418
  		} else if (scan_event == SCAN_EVENT_DONE) {
72ed4dc73   Dean Lee   staging: wilc1000...
419
  			refresh_scan(priv, 1, false);
c5c77ba18   Johnny Kim   staging: wilc1000...
420

086620978   Chaehyun Lim   staging: wilc1000...
421
  			mutex_lock(&priv->scan_req_lock);
c5c77ba18   Johnny Kim   staging: wilc1000...
422

369a1d3bd   Leo Kim   staging: wilc1000...
423
  			if (priv->pstrScanReq) {
1d76250bd   Avraham Stern   nl80211: support ...
424
425
426
427
428
  				struct cfg80211_scan_info info = {
  					.aborted = false,
  				};
  
  				cfg80211_scan_done(priv->pstrScanReq, &info);
c5c77ba18   Johnny Kim   staging: wilc1000...
429
  				priv->u32RcvdChCount = 0;
72ed4dc73   Dean Lee   staging: wilc1000...
430
  				priv->bCfgScanning = false;
b1413b608   Greg Kroah-Hartman   staging: wilc100:...
431
  				priv->pstrScanReq = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
432
  			}
086620978   Chaehyun Lim   staging: wilc1000...
433
  			mutex_unlock(&priv->scan_req_lock);
1a4c8ce78   Leo Kim   staging: wilc1000...
434
  		} else if (scan_event == SCAN_EVENT_ABORTED) {
086620978   Chaehyun Lim   staging: wilc1000...
435
  			mutex_lock(&priv->scan_req_lock);
c5c77ba18   Johnny Kim   staging: wilc1000...
436

369a1d3bd   Leo Kim   staging: wilc1000...
437
  			if (priv->pstrScanReq) {
1d76250bd   Avraham Stern   nl80211: support ...
438
439
440
  				struct cfg80211_scan_info info = {
  					.aborted = false,
  				};
5e51d8ba0   Leo Kim   staging: wilc1000...
441
  				update_scan_time();
72ed4dc73   Dean Lee   staging: wilc1000...
442
  				refresh_scan(priv, 1, false);
c5c77ba18   Johnny Kim   staging: wilc1000...
443

1d76250bd   Avraham Stern   nl80211: support ...
444
  				cfg80211_scan_done(priv->pstrScanReq, &info);
72ed4dc73   Dean Lee   staging: wilc1000...
445
  				priv->bCfgScanning = false;
b1413b608   Greg Kroah-Hartman   staging: wilc100:...
446
  				priv->pstrScanReq = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
447
  			}
086620978   Chaehyun Lim   staging: wilc1000...
448
  			mutex_unlock(&priv->scan_req_lock);
c5c77ba18   Johnny Kim   staging: wilc1000...
449
450
  		}
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
451
  }
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
452
  int wilc_connecting;
c5c77ba18   Johnny Kim   staging: wilc1000...
453

ed3f0379a   Leo Kim   staging: wilc1000...
454
  static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
3b0437e18   Chaehyun Lim   staging: wilc1000...
455
  			     struct connect_info *pstrConnectInfo,
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
456
  			     u8 u8MacStatus,
bb76df5a4   Chaehyun Lim   staging: wilc1000...
457
  			     struct disconnect_info *pstrDisconnectNotifInfo,
c5c77ba18   Johnny Kim   staging: wilc1000...
458
459
  			     void *pUserVoid)
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
460
  	struct wilc_priv *priv;
c5c77ba18   Johnny Kim   staging: wilc1000...
461
  	struct net_device *dev;
441dc609d   Leo Kim   staging: wilc1000...
462
  	struct host_if_drv *pstrWFIDrv;
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
463
  	u8 NullBssid[ETH_ALEN] = {0};
c1ec2c12a   Glen Lee   staging: wilc1000...
464
  	struct wilc *wl;
a4cac4810   Glen Lee   staging: wilc1000...
465
  	struct wilc_vif *vif;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
466

0e1af73dd   Arnd Bergmann   staging/wilc1000:...
467
  	wilc_connecting = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
468

4375cad94   Alison Schofield   staging: wilc1000...
469
  	priv = pUserVoid;
c5c77ba18   Johnny Kim   staging: wilc1000...
470
  	dev = priv->dev;
a4cac4810   Glen Lee   staging: wilc1000...
471
472
  	vif = netdev_priv(dev);
  	wl = vif->wilc;
48b28df99   Leo Kim   staging: wilc1000...
473
  	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
c5c77ba18   Johnny Kim   staging: wilc1000...
474
475
  
  	if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
baba7c743   Amitoj Kaur Chawla   staging: wilc1000...
476
  		u16 u16ConnectStatus;
c5c77ba18   Johnny Kim   staging: wilc1000...
477

134b4cf2d   Chaehyun Lim   staging: wilc1000...
478
  		u16ConnectStatus = pstrConnectInfo->status;
c5c77ba18   Johnny Kim   staging: wilc1000...
479

c5c77ba18   Johnny Kim   staging: wilc1000...
480
  		if ((u8MacStatus == MAC_DISCONNECTED) &&
134b4cf2d   Chaehyun Lim   staging: wilc1000...
481
  		    (pstrConnectInfo->status == SUCCESSFUL_STATUSCODE)) {
c5c77ba18   Johnny Kim   staging: wilc1000...
482
  			u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
ba615f1ef   Glen Lee   staging: wilc1000...
483
484
  			wilc_wlan_set_bssid(priv->dev, NullBssid,
  					    STATION_MODE);
e554a3055   Leo Kim   staging: wilc1000...
485
  			eth_zero_addr(wilc_connected_ssid);
c5c77ba18   Johnny Kim   staging: wilc1000...
486

ab16ec0b8   Leo Kim   staging: wilc1000...
487
  			if (!pstrWFIDrv->p2p_connect)
0bd8274fb   Leo Kim   staging: wilc1000...
488
  				wlan_channel = INVALID_CHANNEL;
c5c77ba18   Johnny Kim   staging: wilc1000...
489

06fb9336a   Leo Kim   staging: wilc1000...
490
491
  			netdev_err(dev, "Unspecified failure
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
492
493
494
  		}
  
  		if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
72ed4dc73   Dean Lee   staging: wilc1000...
495
  			bool bNeedScanRefresh = false;
4e4467fdd   Chaehyun Lim   staging: wilc1000...
496
  			u32 i;
c5c77ba18   Johnny Kim   staging: wilc1000...
497

d4a24e082   Chaehyun Lim   staging: wilc1000...
498
  			memcpy(priv->au8AssociatedBss, pstrConnectInfo->bssid, ETH_ALEN);
c5c77ba18   Johnny Kim   staging: wilc1000...
499

c5c77ba18   Johnny Kim   staging: wilc1000...
500

771fbae49   Leo Kim   staging: wilc1000...
501
  			for (i = 0; i < last_scanned_cnt; i++) {
38d3bb787   Leo Kim   staging: wilc1000...
502
  				if (memcmp(last_scanned_shadow[i].bssid,
d4a24e082   Chaehyun Lim   staging: wilc1000...
503
  					   pstrConnectInfo->bssid,
38d3bb787   Leo Kim   staging: wilc1000...
504
  					   ETH_ALEN) == 0) {
c5c77ba18   Johnny Kim   staging: wilc1000...
505
506
507
  					unsigned long now = jiffies;
  
  					if (time_after(now,
264d70f4d   Leo Kim   staging: wilc1000...
508
509
  						       last_scanned_shadow[i].time_scan_cached +
  						       (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
72ed4dc73   Dean Lee   staging: wilc1000...
510
  						bNeedScanRefresh = true;
c5c77ba18   Johnny Kim   staging: wilc1000...
511
512
513
514
  
  					break;
  				}
  			}
a89f7c551   Leo Kim   staging: wilc1000...
515
  			if (bNeedScanRefresh)
72ed4dc73   Dean Lee   staging: wilc1000...
516
  				refresh_scan(priv, 1, true);
c5c77ba18   Johnny Kim   staging: wilc1000...
517
  		}
d4a24e082   Chaehyun Lim   staging: wilc1000...
518
  		cfg80211_connect_result(dev, pstrConnectInfo->bssid,
4607f9ccb   Chaehyun Lim   staging: wilc1000...
519
  					pstrConnectInfo->req_ies, pstrConnectInfo->req_ies_len,
3e7477c24   Chaehyun Lim   staging: wilc1000...
520
  					pstrConnectInfo->resp_ies, pstrConnectInfo->resp_ies_len,
a89f7c551   Leo Kim   staging: wilc1000...
521
  					u16ConnectStatus, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
522
  	} else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF)    {
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
523
  		wilc_optaining_ip = false;
583d972cf   Leo Kim   staging: wilc1000...
524
  		p2p_local_random = 0x01;
b84a3ac42   Leo Kim   staging: wilc1000...
525
  		p2p_recv_random = 0x00;
a25d51860   Leo Kim   staging: wilc1000...
526
  		wilc_ie = false;
bcf026538   Shraddha Barke   Staging: wilc1000...
527
  		eth_zero_addr(priv->au8AssociatedBss);
ba615f1ef   Glen Lee   staging: wilc1000...
528
  		wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
e554a3055   Leo Kim   staging: wilc1000...
529
  		eth_zero_addr(wilc_connected_ssid);
c5c77ba18   Johnny Kim   staging: wilc1000...
530

ab16ec0b8   Leo Kim   staging: wilc1000...
531
  		if (!pstrWFIDrv->p2p_connect)
0bd8274fb   Leo Kim   staging: wilc1000...
532
  			wlan_channel = INVALID_CHANNEL;
d5e27e8b8   Roger H. Newell   staging: wilc1000...
533
  		if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
90f209daa   Chaehyun Lim   staging: wilc1000...
534
  			pstrDisconnectNotifInfo->reason = 3;
d5e27e8b8   Roger H. Newell   staging: wilc1000...
535
  		else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
90f209daa   Chaehyun Lim   staging: wilc1000...
536
  			pstrDisconnectNotifInfo->reason = 1;
d5e27e8b8   Roger H. Newell   staging: wilc1000...
537

90f209daa   Chaehyun Lim   staging: wilc1000...
538
  		cfg80211_disconnected(dev, pstrDisconnectNotifInfo->reason, pstrDisconnectNotifInfo->ie,
e26bb71da   Sudip Mukherjee   staging: wilc1000...
539
540
  				      pstrDisconnectNotifInfo->ie_len, false,
  				      GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
541
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
542
  }
80785a9a8   Chaehyun Lim   staging: wilc1000...
543
544
  static int set_channel(struct wiphy *wiphy,
  		       struct cfg80211_chan_def *chandef)
c5c77ba18   Johnny Kim   staging: wilc1000...
545
  {
4e4467fdd   Chaehyun Lim   staging: wilc1000...
546
  	u32 channelnum = 0;
2726887c5   Chaehyun Lim   staging: wilc1000...
547
  	struct wilc_priv *priv;
dd739ea51   Chaehyun Lim   staging: wilc1000...
548
  	int result = 0;
cf60106bf   Glen Lee   staging: wilc1000...
549
  	struct wilc_vif *vif;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
550

c5c77ba18   Johnny Kim   staging: wilc1000...
551
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
552
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
553

c5c77ba18   Johnny Kim   staging: wilc1000...
554
  	channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
c5c77ba18   Johnny Kim   staging: wilc1000...
555

866a2c247   Chaehyun Lim   staging: wilc1000...
556
  	curr_channel = channelnum;
fbf5379bf   Glen Lee   staging: wilc1000...
557
  	result = wilc_set_mac_chnl_num(vif, channelnum);
c5c77ba18   Johnny Kim   staging: wilc1000...
558

dd739ea51   Chaehyun Lim   staging: wilc1000...
559
  	if (result != 0)
06fb9336a   Leo Kim   staging: wilc1000...
560
561
  		netdev_err(priv->dev, "Error in setting channel
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
562

dd739ea51   Chaehyun Lim   staging: wilc1000...
563
  	return result;
c5c77ba18   Johnny Kim   staging: wilc1000...
564
  }
0e30d06d9   Chaehyun Lim   staging: wilc1000...
565
  static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
c5c77ba18   Johnny Kim   staging: wilc1000...
566
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
567
  	struct wilc_priv *priv;
4e4467fdd   Chaehyun Lim   staging: wilc1000...
568
  	u32 i;
e6e12661d   Leo Kim   staging: wilc1000...
569
  	s32 s32Error = 0;
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
570
  	u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
607db4479   Leo Kim   staging: wilc1000...
571
  	struct hidden_network strHiddenNetwork;
cf60106bf   Glen Lee   staging: wilc1000...
572
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
573
574
  
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
575
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
576

c5c77ba18   Johnny Kim   staging: wilc1000...
577
578
579
  	priv->pstrScanReq = request;
  
  	priv->u32RcvdChCount = 0;
12b0138b2   Leo Kim   staging: wilc1000...
580
  	reset_shadow_found();
c5c77ba18   Johnny Kim   staging: wilc1000...
581

72ed4dc73   Dean Lee   staging: wilc1000...
582
  	priv->bCfgScanning = true;
a89f7c551   Leo Kim   staging: wilc1000...
583
  	if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
64d3546a3   Chris Park   staging: wilc1000...
584
  		for (i = 0; i < request->n_channels; i++)
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
585
  			au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
c5c77ba18   Johnny Kim   staging: wilc1000...
586
587
  
  		if (request->n_ssids >= 1) {
8459af6ac   Janani Ravichandran   staging: wilc1000...
588
589
590
591
  			strHiddenNetwork.net_info =
  				kmalloc_array(request->n_ssids,
  					      sizeof(struct hidden_network),
  					      GFP_KERNEL);
396fa30e4   Leo Kim   staging: wilc1000...
592
593
  			if (!strHiddenNetwork.net_info)
  				return -ENOMEM;
40e05e86d   Chaehyun Lim   staging: wilc1000...
594
  			strHiddenNetwork.n_ssids = request->n_ssids;
c5c77ba18   Johnny Kim   staging: wilc1000...
595

c5c77ba18   Johnny Kim   staging: wilc1000...
596
  			for (i = 0; i < request->n_ssids; i++) {
4562d224e   Luis de Bethencourt   staging: wilc1000...
597
  				if (request->ssids[i].ssid_len != 0) {
245a18654   Chaehyun Lim   staging: wilc1000...
598
599
600
  					strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
  					memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
  					strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
c5c77ba18   Johnny Kim   staging: wilc1000...
601
  				} else {
40e05e86d   Chaehyun Lim   staging: wilc1000...
602
  					strHiddenNetwork.n_ssids -= 1;
c5c77ba18   Johnny Kim   staging: wilc1000...
603
604
  				}
  			}
fbf5379bf   Glen Lee   staging: wilc1000...
605
606
607
608
609
610
  			s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
  					     au8ScanChanList,
  					     request->n_channels,
  					     (const u8 *)request->ie,
  					     request->ie_len, CfgScanResult,
  					     (void *)priv, &strHiddenNetwork);
c5c77ba18   Johnny Kim   staging: wilc1000...
611
  		} else {
fbf5379bf   Glen Lee   staging: wilc1000...
612
613
614
615
616
617
  			s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
  					     au8ScanChanList,
  					     request->n_channels,
  					     (const u8 *)request->ie,
  					     request->ie_len, CfgScanResult,
  					     (void *)priv, NULL);
c5c77ba18   Johnny Kim   staging: wilc1000...
618
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
619
  	} else {
06fb9336a   Leo Kim   staging: wilc1000...
620
621
  		netdev_err(priv->dev, "Requested scanned channels over
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
622
  	}
64d3546a3   Chris Park   staging: wilc1000...
623
  	if (s32Error != 0)
c5c77ba18   Johnny Kim   staging: wilc1000...
624
  		s32Error = -EBUSY;
c5c77ba18   Johnny Kim   staging: wilc1000...
625
626
627
  
  	return s32Error;
  }
4ffbcdb6d   Chaehyun Lim   staging: wilc1000...
628
629
  static int connect(struct wiphy *wiphy, struct net_device *dev,
  		   struct cfg80211_connect_params *sme)
c5c77ba18   Johnny Kim   staging: wilc1000...
630
  {
e6e12661d   Leo Kim   staging: wilc1000...
631
  	s32 s32Error = 0;
4e4467fdd   Chaehyun Lim   staging: wilc1000...
632
  	u32 i;
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
633
  	u8 u8security = NO_ENCRYPT;
841dfc428   Leo Kim   staging: wilc1000...
634
  	enum AUTHTYPE tenuAuth_type = ANY;
c5c77ba18   Johnny Kim   staging: wilc1000...
635

2726887c5   Chaehyun Lim   staging: wilc1000...
636
  	struct wilc_priv *priv;
441dc609d   Leo Kim   staging: wilc1000...
637
  	struct host_if_drv *pstrWFIDrv;
6b5180a08   Leo Kim   staging: wilc1000...
638
  	struct network_info *pstrNetworkInfo = NULL;
cf60106bf   Glen Lee   staging: wilc1000...
639
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
640

0e1af73dd   Arnd Bergmann   staging/wilc1000:...
641
  	wilc_connecting = 1;
c5c77ba18   Johnny Kim   staging: wilc1000...
642
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
643
  	vif = netdev_priv(priv->dev);
48b28df99   Leo Kim   staging: wilc1000...
644
  	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
c5c77ba18   Johnny Kim   staging: wilc1000...
645

64d3546a3   Chris Park   staging: wilc1000...
646
  	if (!(strncmp(sme->ssid, "DIRECT-", 7)))
ab16ec0b8   Leo Kim   staging: wilc1000...
647
  		pstrWFIDrv->p2p_connect = 1;
64d3546a3   Chris Park   staging: wilc1000...
648
  	else
ab16ec0b8   Leo Kim   staging: wilc1000...
649
  		pstrWFIDrv->p2p_connect = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
650

771fbae49   Leo Kim   staging: wilc1000...
651
  	for (i = 0; i < last_scanned_cnt; i++) {
a36e89e9b   Leo Kim   staging: wilc1000...
652
  		if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
2a3ff58a8   Leo Kim   staging: wilc1000...
653
  		    memcmp(last_scanned_shadow[i].ssid,
f1ab117db   Leo Kim   staging: wilc1000...
654
655
  			   sme->ssid,
  			   sme->ssid_len) == 0) {
64d3546a3   Chris Park   staging: wilc1000...
656
  			if (!sme->bssid)
c5c77ba18   Johnny Kim   staging: wilc1000...
657
  				break;
64d3546a3   Chris Park   staging: wilc1000...
658
  			else
38d3bb787   Leo Kim   staging: wilc1000...
659
  				if (memcmp(last_scanned_shadow[i].bssid,
f1ab117db   Leo Kim   staging: wilc1000...
660
  					   sme->bssid,
64d3546a3   Chris Park   staging: wilc1000...
661
  					   ETH_ALEN) == 0)
c5c77ba18   Johnny Kim   staging: wilc1000...
662
  					break;
c5c77ba18   Johnny Kim   staging: wilc1000...
663
664
  		}
  	}
771fbae49   Leo Kim   staging: wilc1000...
665
  	if (i < last_scanned_cnt) {
f1ab117db   Leo Kim   staging: wilc1000...
666
  		pstrNetworkInfo = &last_scanned_shadow[i];
c5c77ba18   Johnny Kim   staging: wilc1000...
667
668
  	} else {
  		s32Error = -ENOENT;
430e640d6   Glen Lee   staging: wilc1000...
669
670
  		wilc_connecting = 0;
  		return s32Error;
c5c77ba18   Johnny Kim   staging: wilc1000...
671
  	}
2cc468378   Chaehyun Lim   staging: wilc1000...
672
673
  	memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
  	memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
c5c77ba18   Johnny Kim   staging: wilc1000...
674

c5c77ba18   Johnny Kim   staging: wilc1000...
675
  	if (sme->crypto.cipher_group != NO_ENCRYPT) {
c5c77ba18   Johnny Kim   staging: wilc1000...
676
  		if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
c5c77ba18   Johnny Kim   staging: wilc1000...
677
  			u8security = ENCRYPT_ENABLED | WEP;
c5c77ba18   Johnny Kim   staging: wilc1000...
678

c5c77ba18   Johnny Kim   staging: wilc1000...
679
  			priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
d00d2ba33   Chaehyun Lim   staging: wilc1000...
680
  			memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
c5c77ba18   Johnny Kim   staging: wilc1000...
681

c5c77ba18   Johnny Kim   staging: wilc1000...
682
  			g_key_wep_params.key_len = sme->key_len;
f3052587e   Glen Lee   staging: wilc1000...
683
  			g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
684
685
  			memcpy(g_key_wep_params.key, sme->key, sme->key_len);
  			g_key_wep_params.key_idx = sme->key_idx;
72ed4dc73   Dean Lee   staging: wilc1000...
686
  			g_wep_keys_saved = true;
c5c77ba18   Johnny Kim   staging: wilc1000...
687

fbf5379bf   Glen Lee   staging: wilc1000...
688
689
690
  			wilc_set_wep_default_keyid(vif, sme->key_idx);
  			wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
  						 sme->key_idx);
c5c77ba18   Johnny Kim   staging: wilc1000...
691
  		} else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)   {
c5c77ba18   Johnny Kim   staging: wilc1000...
692
  			u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
c5c77ba18   Johnny Kim   staging: wilc1000...
693

c5c77ba18   Johnny Kim   staging: wilc1000...
694
  			priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
d00d2ba33   Chaehyun Lim   staging: wilc1000...
695
  			memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
c5c77ba18   Johnny Kim   staging: wilc1000...
696

c5c77ba18   Johnny Kim   staging: wilc1000...
697
  			g_key_wep_params.key_len = sme->key_len;
f3052587e   Glen Lee   staging: wilc1000...
698
  			g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
699
700
  			memcpy(g_key_wep_params.key, sme->key, sme->key_len);
  			g_key_wep_params.key_idx = sme->key_idx;
72ed4dc73   Dean Lee   staging: wilc1000...
701
  			g_wep_keys_saved = true;
c5c77ba18   Johnny Kim   staging: wilc1000...
702

fbf5379bf   Glen Lee   staging: wilc1000...
703
704
705
  			wilc_set_wep_default_keyid(vif, sme->key_idx);
  			wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
  						 sme->key_idx);
c5c77ba18   Johnny Kim   staging: wilc1000...
706
  		} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)   {
d5e27e8b8   Roger H. Newell   staging: wilc1000...
707
  			if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
c5c77ba18   Johnny Kim   staging: wilc1000...
708
  				u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
d5e27e8b8   Roger H. Newell   staging: wilc1000...
709
  			else
c5c77ba18   Johnny Kim   staging: wilc1000...
710
  				u8security = ENCRYPT_ENABLED | WPA2 | AES;
c5c77ba18   Johnny Kim   staging: wilc1000...
711
  		} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)   {
d5e27e8b8   Roger H. Newell   staging: wilc1000...
712
  			if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
c5c77ba18   Johnny Kim   staging: wilc1000...
713
  				u8security = ENCRYPT_ENABLED | WPA | TKIP;
d5e27e8b8   Roger H. Newell   staging: wilc1000...
714
  			else
c5c77ba18   Johnny Kim   staging: wilc1000...
715
  				u8security = ENCRYPT_ENABLED | WPA | AES;
c5c77ba18   Johnny Kim   staging: wilc1000...
716
717
  		} else {
  			s32Error = -ENOTSUPP;
06fb9336a   Leo Kim   staging: wilc1000...
718
719
  			netdev_err(dev, "Not supported cipher
  ");
430e640d6   Glen Lee   staging: wilc1000...
720
721
  			wilc_connecting = 0;
  			return s32Error;
c5c77ba18   Johnny Kim   staging: wilc1000...
722
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
723
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
724
725
726
  	if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
  	    || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
  		for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
d5e27e8b8   Roger H. Newell   staging: wilc1000...
727
  			if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP)
c5c77ba18   Johnny Kim   staging: wilc1000...
728
  				u8security = u8security | TKIP;
d5e27e8b8   Roger H. Newell   staging: wilc1000...
729
  			else
c5c77ba18   Johnny Kim   staging: wilc1000...
730
  				u8security = u8security | AES;
c5c77ba18   Johnny Kim   staging: wilc1000...
731
732
  		}
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
733
734
  	switch (sme->auth_type)	{
  	case NL80211_AUTHTYPE_OPEN_SYSTEM:
c5c77ba18   Johnny Kim   staging: wilc1000...
735
736
737
738
739
  		tenuAuth_type = OPEN_SYSTEM;
  		break;
  
  	case NL80211_AUTHTYPE_SHARED_KEY:
  		tenuAuth_type = SHARED_KEY;
c5c77ba18   Johnny Kim   staging: wilc1000...
740
741
742
  		break;
  
  	default:
40bbaac72   Chris Park   staging: wilc1000...
743
  		break;
c5c77ba18   Johnny Kim   staging: wilc1000...
744
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
745
746
747
748
749
750
751
752
753
754
  	if (sme->crypto.n_akm_suites) {
  		switch (sme->crypto.akm_suites[0]) {
  		case WLAN_AKM_SUITE_8021X:
  			tenuAuth_type = IEEE8021;
  			break;
  
  		default:
  			break;
  		}
  	}
405a8c786   Leo Kim   staging: wilc1000...
755
  	curr_channel = pstrNetworkInfo->ch;
c5c77ba18   Johnny Kim   staging: wilc1000...
756

ab16ec0b8   Leo Kim   staging: wilc1000...
757
  	if (!pstrWFIDrv->p2p_connect)
405a8c786   Leo Kim   staging: wilc1000...
758
  		wlan_channel = pstrNetworkInfo->ch;
c5c77ba18   Johnny Kim   staging: wilc1000...
759

38d3bb787   Leo Kim   staging: wilc1000...
760
  	wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
c5c77ba18   Johnny Kim   staging: wilc1000...
761

38d3bb787   Leo Kim   staging: wilc1000...
762
  	s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
fbf5379bf   Glen Lee   staging: wilc1000...
763
764
765
  				     sme->ssid_len, sme->ie, sme->ie_len,
  				     CfgConnectResult, (void *)priv,
  				     u8security, tenuAuth_type,
405a8c786   Leo Kim   staging: wilc1000...
766
  				     pstrNetworkInfo->ch,
cb64de7c3   Leo Kim   staging: wilc1000...
767
  				     pstrNetworkInfo->join_params);
e6e12661d   Leo Kim   staging: wilc1000...
768
  	if (s32Error != 0) {
06fb9336a   Leo Kim   staging: wilc1000...
769
770
  		netdev_err(dev, "wilc_set_join_req(): Error
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
771
  		s32Error = -ENOENT;
430e640d6   Glen Lee   staging: wilc1000...
772
773
  		wilc_connecting = 0;
  		return s32Error;
c5c77ba18   Johnny Kim   staging: wilc1000...
774
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
775
776
  	return s32Error;
  }
b027cde95   Chaehyun Lim   staging: wilc1000...
777
  static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
c5c77ba18   Johnny Kim   staging: wilc1000...
778
  {
e6e12661d   Leo Kim   staging: wilc1000...
779
  	s32 s32Error = 0;
2726887c5   Chaehyun Lim   staging: wilc1000...
780
  	struct wilc_priv *priv;
441dc609d   Leo Kim   staging: wilc1000...
781
  	struct host_if_drv *pstrWFIDrv;
cf60106bf   Glen Lee   staging: wilc1000...
782
  	struct wilc_vif *vif;
8006109ba   Leo Kim   staging: wilc1000...
783
  	struct wilc *wilc;
51e825f70   Chaehyun Lim   staging: wilc1000...
784
  	u8 NullBssid[ETH_ALEN] = {0};
8dfaafd63   Chaehyun Lim   staging: wilc1000...
785

0e1af73dd   Arnd Bergmann   staging/wilc1000:...
786
  	wilc_connecting = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
787
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
788
  	vif = netdev_priv(priv->dev);
8006109ba   Leo Kim   staging: wilc1000...
789
790
791
792
793
794
795
796
797
798
  	wilc = vif->wilc;
  
  	if (!wilc)
  		return -EIO;
  
  	if (wilc->close) {
  		/* already disconnected done */
  		cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
  		return 0;
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
799

48b28df99   Leo Kim   staging: wilc1000...
800
  	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
ab16ec0b8   Leo Kim   staging: wilc1000...
801
  	if (!pstrWFIDrv->p2p_connect)
0bd8274fb   Leo Kim   staging: wilc1000...
802
  		wlan_channel = INVALID_CHANNEL;
ba615f1ef   Glen Lee   staging: wilc1000...
803
  	wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
c5c77ba18   Johnny Kim   staging: wilc1000...
804

583d972cf   Leo Kim   staging: wilc1000...
805
  	p2p_local_random = 0x01;
b84a3ac42   Leo Kim   staging: wilc1000...
806
  	p2p_recv_random = 0x00;
a25d51860   Leo Kim   staging: wilc1000...
807
  	wilc_ie = false;
1229b1ab4   Leo Kim   staging: wilc1000...
808
  	pstrWFIDrv->p2p_timeout = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
809

fbf5379bf   Glen Lee   staging: wilc1000...
810
  	s32Error = wilc_disconnect(vif, reason_code);
e6e12661d   Leo Kim   staging: wilc1000...
811
  	if (s32Error != 0) {
06fb9336a   Leo Kim   staging: wilc1000...
812
813
  		netdev_err(priv->dev, "Error in disconnecting
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
814
815
816
817
818
  		s32Error = -EINVAL;
  	}
  
  	return s32Error;
  }
953d417a0   Chaehyun Lim   staging: wilc1000...
819
820
821
  static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
  		   bool pairwise,
  		   const u8 *mac_addr, struct key_params *params)
c5c77ba18   Johnny Kim   staging: wilc1000...
822
823
  
  {
e6e12661d   Leo Kim   staging: wilc1000...
824
  	s32 s32Error = 0, KeyLen = params->key_len;
2726887c5   Chaehyun Lim   staging: wilc1000...
825
  	struct wilc_priv *priv;
057d1e979   Arnd Bergmann   staging: wilc1000...
826
827
  	const u8 *pu8RxMic = NULL;
  	const u8 *pu8TxMic = NULL;
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
828
  	u8 u8mode = NO_ENCRYPT;
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
829
830
  	u8 u8gmode = NO_ENCRYPT;
  	u8 u8pmode = NO_ENCRYPT;
841dfc428   Leo Kim   staging: wilc1000...
831
  	enum AUTHTYPE tenuAuth_type = ANY;
764692008   Glen Lee   staging: wilc1000...
832
  	struct wilc *wl;
a4cac4810   Glen Lee   staging: wilc1000...
833
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
834
835
  
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
836
837
  	vif = netdev_priv(netdev);
  	wl = vif->wilc;
c5c77ba18   Johnny Kim   staging: wilc1000...
838

c5c77ba18   Johnny Kim   staging: wilc1000...
839
840
841
  	switch (params->cipher)	{
  	case WLAN_CIPHER_SUITE_WEP40:
  	case WLAN_CIPHER_SUITE_WEP104:
c5c77ba18   Johnny Kim   staging: wilc1000...
842
  		if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
c5c77ba18   Johnny Kim   staging: wilc1000...
843
  			priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
d00d2ba33   Chaehyun Lim   staging: wilc1000...
844
  			memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
c5c77ba18   Johnny Kim   staging: wilc1000...
845

c5c77ba18   Johnny Kim   staging: wilc1000...
846
847
848
849
850
851
  			tenuAuth_type = OPEN_SYSTEM;
  
  			if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
  				u8mode = ENCRYPT_ENABLED | WEP;
  			else
  				u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
fbf5379bf   Glen Lee   staging: wilc1000...
852
853
854
  			wilc_add_wep_key_bss_ap(vif, params->key,
  						params->key_len, key_index,
  						u8mode, tenuAuth_type);
c5c77ba18   Johnny Kim   staging: wilc1000...
855
856
  			break;
  		}
1a646e7e9   Chaehyun Lim   staging: wilc1000...
857
  		if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
c5c77ba18   Johnny Kim   staging: wilc1000...
858
  			priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
d00d2ba33   Chaehyun Lim   staging: wilc1000...
859
  			memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
c5c77ba18   Johnny Kim   staging: wilc1000...
860

fbf5379bf   Glen Lee   staging: wilc1000...
861
862
  			wilc_add_wep_key_bss_sta(vif, params->key,
  						 params->key_len, key_index);
c5c77ba18   Johnny Kim   staging: wilc1000...
863
864
865
866
867
868
  		}
  
  		break;
  
  	case WLAN_CIPHER_SUITE_TKIP:
  	case WLAN_CIPHER_SUITE_CCMP:
c5c77ba18   Johnny Kim   staging: wilc1000...
869
  		if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
369a1d3bd   Leo Kim   staging: wilc1000...
870
  			if (!priv->wilc_gtk[key_index]) {
f3052587e   Glen Lee   staging: wilc1000...
871
  				priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
b1413b608   Greg Kroah-Hartman   staging: wilc100:...
872
873
  				priv->wilc_gtk[key_index]->key = NULL;
  				priv->wilc_gtk[key_index]->seq = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
874
  			}
369a1d3bd   Leo Kim   staging: wilc1000...
875
  			if (!priv->wilc_ptk[key_index]) {
f3052587e   Glen Lee   staging: wilc1000...
876
  				priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
b1413b608   Greg Kroah-Hartman   staging: wilc100:...
877
878
  				priv->wilc_ptk[key_index]->key = NULL;
  				priv->wilc_ptk[key_index]->seq = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
879
  			}
1913221c0   Daniel Machon   staging: wilc1000...
880
  			if (!pairwise) {
c5c77ba18   Johnny Kim   staging: wilc1000...
881
882
883
884
885
886
887
888
  				if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
  					u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
  				else
  					u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
  
  				priv->wilc_groupkey = u8gmode;
  
  				if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba18   Johnny Kim   staging: wilc1000...
889
890
891
892
  					pu8TxMic = params->key + 24;
  					pu8RxMic = params->key + 16;
  					KeyLen = params->key_len - 16;
  				}
cccfc39e5   Shraddha Barke   Staging: wilc1000...
893
  				kfree(priv->wilc_gtk[key_index]->key);
c5c77ba18   Johnny Kim   staging: wilc1000...
894

f3052587e   Glen Lee   staging: wilc1000...
895
  				priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
d00d2ba33   Chaehyun Lim   staging: wilc1000...
896
  				memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
cccfc39e5   Shraddha Barke   Staging: wilc1000...
897
  				kfree(priv->wilc_gtk[key_index]->seq);
c5c77ba18   Johnny Kim   staging: wilc1000...
898
899
  
  				if ((params->seq_len) > 0) {
f3052587e   Glen Lee   staging: wilc1000...
900
  					priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
d00d2ba33   Chaehyun Lim   staging: wilc1000...
901
  					memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
c5c77ba18   Johnny Kim   staging: wilc1000...
902
903
904
905
906
  				}
  
  				priv->wilc_gtk[key_index]->cipher = params->cipher;
  				priv->wilc_gtk[key_index]->key_len = params->key_len;
  				priv->wilc_gtk[key_index]->seq_len = params->seq_len;
fbf5379bf   Glen Lee   staging: wilc1000...
907
908
909
910
  				wilc_add_rx_gtk(vif, params->key, KeyLen,
  						key_index, params->seq_len,
  						params->seq, pu8RxMic,
  						pu8TxMic, AP_MODE, u8gmode);
c5c77ba18   Johnny Kim   staging: wilc1000...
911
912
  
  			} else {
c5c77ba18   Johnny Kim   staging: wilc1000...
913
914
915
916
917
918
919
  				if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
  					u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
  				else
  					u8pmode = priv->wilc_groupkey | AES;
  
  
  				if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba18   Johnny Kim   staging: wilc1000...
920
921
922
923
  					pu8TxMic = params->key + 24;
  					pu8RxMic = params->key + 16;
  					KeyLen = params->key_len - 16;
  				}
cccfc39e5   Shraddha Barke   Staging: wilc1000...
924
  				kfree(priv->wilc_ptk[key_index]->key);
c5c77ba18   Johnny Kim   staging: wilc1000...
925

f3052587e   Glen Lee   staging: wilc1000...
926
  				priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
927

cccfc39e5   Shraddha Barke   Staging: wilc1000...
928
  				kfree(priv->wilc_ptk[key_index]->seq);
c5c77ba18   Johnny Kim   staging: wilc1000...
929
930
  
  				if ((params->seq_len) > 0)
f3052587e   Glen Lee   staging: wilc1000...
931
  					priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
932

d00d2ba33   Chaehyun Lim   staging: wilc1000...
933
  				memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
c5c77ba18   Johnny Kim   staging: wilc1000...
934
935
  
  				if ((params->seq_len) > 0)
d00d2ba33   Chaehyun Lim   staging: wilc1000...
936
  					memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
c5c77ba18   Johnny Kim   staging: wilc1000...
937
938
939
940
  
  				priv->wilc_ptk[key_index]->cipher = params->cipher;
  				priv->wilc_ptk[key_index]->key_len = params->key_len;
  				priv->wilc_ptk[key_index]->seq_len = params->seq_len;
fbf5379bf   Glen Lee   staging: wilc1000...
941
942
943
  				wilc_add_ptk(vif, params->key, KeyLen,
  					     mac_addr, pu8RxMic, pu8TxMic,
  					     AP_MODE, u8pmode, key_index);
c5c77ba18   Johnny Kim   staging: wilc1000...
944
945
946
  			}
  			break;
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
947
948
949
  
  		{
  			u8mode = 0;
1913221c0   Daniel Machon   staging: wilc1000...
950
  			if (!pairwise) {
c5c77ba18   Johnny Kim   staging: wilc1000...
951
  				if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba18   Johnny Kim   staging: wilc1000...
952
953
954
955
  					pu8RxMic = params->key + 24;
  					pu8TxMic = params->key + 16;
  					KeyLen = params->key_len - 16;
  				}
1f435d2ef   Glen Lee   staging: wilc1000...
956
  				if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
c5c77ba18   Johnny Kim   staging: wilc1000...
957
  					g_add_gtk_key_params.key_idx = key_index;
c5c77ba18   Johnny Kim   staging: wilc1000...
958
  					g_add_gtk_key_params.pairwise = pairwise;
c5c77ba18   Johnny Kim   staging: wilc1000...
959
960
961
  					if (!mac_addr) {
  						g_add_gtk_key_params.mac_addr = NULL;
  					} else {
f3052587e   Glen Lee   staging: wilc1000...
962
  						g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
963
964
965
966
  						memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
  					}
  					g_key_gtk_params.key_len = params->key_len;
  					g_key_gtk_params.seq_len = params->seq_len;
f3052587e   Glen Lee   staging: wilc1000...
967
  					g_key_gtk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
968
969
  					memcpy(g_key_gtk_params.key, params->key, params->key_len);
  					if (params->seq_len > 0) {
f3052587e   Glen Lee   staging: wilc1000...
970
  						g_key_gtk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
971
972
973
  						memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
  					}
  					g_key_gtk_params.cipher = params->cipher;
72ed4dc73   Dean Lee   staging: wilc1000...
974
  					g_gtk_keys_saved = true;
c5c77ba18   Johnny Kim   staging: wilc1000...
975
  				}
fbf5379bf   Glen Lee   staging: wilc1000...
976
977
978
979
980
  				wilc_add_rx_gtk(vif, params->key, KeyLen,
  						key_index, params->seq_len,
  						params->seq, pu8RxMic,
  						pu8TxMic, STATION_MODE,
  						u8mode);
c5c77ba18   Johnny Kim   staging: wilc1000...
981
982
  			} else {
  				if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
c5c77ba18   Johnny Kim   staging: wilc1000...
983
984
985
986
  					pu8RxMic = params->key + 24;
  					pu8TxMic = params->key + 16;
  					KeyLen = params->key_len - 16;
  				}
1f435d2ef   Glen Lee   staging: wilc1000...
987
  				if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
c5c77ba18   Johnny Kim   staging: wilc1000...
988
  					g_add_ptk_key_params.key_idx = key_index;
c5c77ba18   Johnny Kim   staging: wilc1000...
989
  					g_add_ptk_key_params.pairwise = pairwise;
c5c77ba18   Johnny Kim   staging: wilc1000...
990
991
992
  					if (!mac_addr) {
  						g_add_ptk_key_params.mac_addr = NULL;
  					} else {
f3052587e   Glen Lee   staging: wilc1000...
993
  						g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
994
995
996
997
  						memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
  					}
  					g_key_ptk_params.key_len = params->key_len;
  					g_key_ptk_params.seq_len = params->seq_len;
f3052587e   Glen Lee   staging: wilc1000...
998
  					g_key_ptk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
999
1000
  					memcpy(g_key_ptk_params.key, params->key, params->key_len);
  					if (params->seq_len > 0) {
f3052587e   Glen Lee   staging: wilc1000...
1001
  						g_key_ptk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
1002
1003
1004
  						memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
  					}
  					g_key_ptk_params.cipher = params->cipher;
72ed4dc73   Dean Lee   staging: wilc1000...
1005
  					g_ptk_keys_saved = true;
c5c77ba18   Johnny Kim   staging: wilc1000...
1006
  				}
fbf5379bf   Glen Lee   staging: wilc1000...
1007
1008
1009
  				wilc_add_ptk(vif, params->key, KeyLen,
  					     mac_addr, pu8RxMic, pu8TxMic,
  					     STATION_MODE, u8mode, key_index);
c5c77ba18   Johnny Kim   staging: wilc1000...
1010
1011
1012
1013
1014
  			}
  		}
  		break;
  
  	default:
06fb9336a   Leo Kim   staging: wilc1000...
1015
1016
  		netdev_err(netdev, "Not supported cipher
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1017
  		s32Error = -ENOTSUPP;
c5c77ba18   Johnny Kim   staging: wilc1000...
1018
1019
1020
1021
  	}
  
  	return s32Error;
  }
3044ba7e6   Chaehyun Lim   staging: wilc1000...
1022
1023
1024
1025
  static int del_key(struct wiphy *wiphy, struct net_device *netdev,
  		   u8 key_index,
  		   bool pairwise,
  		   const u8 *mac_addr)
c5c77ba18   Johnny Kim   staging: wilc1000...
1026
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1027
  	struct wilc_priv *priv;
692e2acef   Glen Lee   staging: wilc1000...
1028
  	struct wilc *wl;
a4cac4810   Glen Lee   staging: wilc1000...
1029
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
1030
1031
  
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
1032
1033
  	vif = netdev_priv(netdev);
  	wl = vif->wilc;
c5c77ba18   Johnny Kim   staging: wilc1000...
1034

1f435d2ef   Glen Lee   staging: wilc1000...
1035
  	if (netdev == wl->vif[0]->ndev) {
72ed4dc73   Dean Lee   staging: wilc1000...
1036
1037
1038
  		g_ptk_keys_saved = false;
  		g_gtk_keys_saved = false;
  		g_wep_keys_saved = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
1039

cccfc39e5   Shraddha Barke   Staging: wilc1000...
1040
1041
  		kfree(g_key_wep_params.key);
  		g_key_wep_params.key = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
1042

c5c77ba18   Johnny Kim   staging: wilc1000...
1043
  		if ((priv->wilc_gtk[key_index]) != NULL) {
cccfc39e5   Shraddha Barke   Staging: wilc1000...
1044
1045
1046
1047
  			kfree(priv->wilc_gtk[key_index]->key);
  			priv->wilc_gtk[key_index]->key = NULL;
  			kfree(priv->wilc_gtk[key_index]->seq);
  			priv->wilc_gtk[key_index]->seq = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
1048

49188af27   Chaehyun Lim   staging: wilc1000...
1049
  			kfree(priv->wilc_gtk[key_index]);
c5c77ba18   Johnny Kim   staging: wilc1000...
1050
  			priv->wilc_gtk[key_index] = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
1051
1052
1053
  		}
  
  		if ((priv->wilc_ptk[key_index]) != NULL) {
cccfc39e5   Shraddha Barke   Staging: wilc1000...
1054
1055
1056
1057
  			kfree(priv->wilc_ptk[key_index]->key);
  			priv->wilc_ptk[key_index]->key = NULL;
  			kfree(priv->wilc_ptk[key_index]->seq);
  			priv->wilc_ptk[key_index]->seq = NULL;
49188af27   Chaehyun Lim   staging: wilc1000...
1058
  			kfree(priv->wilc_ptk[key_index]);
c5c77ba18   Johnny Kim   staging: wilc1000...
1059
1060
  			priv->wilc_ptk[key_index] = NULL;
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
1061

cccfc39e5   Shraddha Barke   Staging: wilc1000...
1062
1063
1064
1065
1066
1067
1068
1069
1070
  		kfree(g_key_ptk_params.key);
  		g_key_ptk_params.key = NULL;
  		kfree(g_key_ptk_params.seq);
  		g_key_ptk_params.seq = NULL;
  
  		kfree(g_key_gtk_params.key);
  		g_key_gtk_params.key = NULL;
  		kfree(g_key_gtk_params.seq);
  		g_key_gtk_params.seq = NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
1071

c5c77ba18   Johnny Kim   staging: wilc1000...
1072
1073
1074
  	}
  
  	if (key_index >= 0 && key_index <= 3) {
b0f1836fa   Leo Kim   staging: wilc1000...
1075
1076
1077
1078
1079
1080
  		if (priv->WILC_WFI_wep_key_len[key_index]) {
  			memset(priv->WILC_WFI_wep_key[key_index], 0,
  			       priv->WILC_WFI_wep_key_len[key_index]);
  			priv->WILC_WFI_wep_key_len[key_index] = 0;
  			wilc_remove_wep_key(vif, key_index);
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
1081
  	} else {
48b28df99   Leo Kim   staging: wilc1000...
1082
  		wilc_remove_key(priv->hif_drv, mac_addr);
c5c77ba18   Johnny Kim   staging: wilc1000...
1083
  	}
aaed3290f   Leo Kim   staging: wilc1000...
1084
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1085
  }
f4893dfc3   Chaehyun Lim   staging: wilc1000...
1086
1087
1088
  static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
  		   bool pairwise,
  		   const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
c5c77ba18   Johnny Kim   staging: wilc1000...
1089
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1090
  	struct wilc_priv *priv;
c5c77ba18   Johnny Kim   staging: wilc1000...
1091
  	struct  key_params key_params;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1092

c5c77ba18   Johnny Kim   staging: wilc1000...
1093
  	priv = wiphy_priv(wiphy);
3604af50a   Alison Schofield   staging: wilc1000...
1094
  	if (!pairwise) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1095
1096
1097
1098
1099
  		key_params.key = priv->wilc_gtk[key_index]->key;
  		key_params.cipher = priv->wilc_gtk[key_index]->cipher;
  		key_params.key_len = priv->wilc_gtk[key_index]->key_len;
  		key_params.seq = priv->wilc_gtk[key_index]->seq;
  		key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
c5c77ba18   Johnny Kim   staging: wilc1000...
1100
  	} else {
c5c77ba18   Johnny Kim   staging: wilc1000...
1101
1102
1103
1104
1105
1106
1107
1108
  		key_params.key = priv->wilc_ptk[key_index]->key;
  		key_params.cipher = priv->wilc_ptk[key_index]->cipher;
  		key_params.key_len = priv->wilc_ptk[key_index]->key_len;
  		key_params.seq = priv->wilc_ptk[key_index]->seq;
  		key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
  	}
  
  	callback(cookie, &key_params);
a89f7c551   Leo Kim   staging: wilc1000...
1109
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1110
  }
0f5b8ca32   Chaehyun Lim   staging: wilc1000...
1111
1112
  static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
  			   bool unicast, bool multicast)
c5c77ba18   Johnny Kim   staging: wilc1000...
1113
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1114
  	struct wilc_priv *priv;
cf60106bf   Glen Lee   staging: wilc1000...
1115
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
1116
1117
  
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
1118
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1119

ec4504832   Glen Lee   staging: wilc1000...
1120
  	wilc_set_wep_default_keyid(vif, key_index);
c5c77ba18   Johnny Kim   staging: wilc1000...
1121

aaed3290f   Leo Kim   staging: wilc1000...
1122
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1123
  }
f06f562dd   Chaehyun Lim   staging: wilc1000...
1124
1125
  static int get_station(struct wiphy *wiphy, struct net_device *dev,
  		       const u8 *mac, struct station_info *sinfo)
c5c77ba18   Johnny Kim   staging: wilc1000...
1126
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1127
  	struct wilc_priv *priv;
a4cac4810   Glen Lee   staging: wilc1000...
1128
  	struct wilc_vif *vif;
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1129
  	u32 i = 0;
6c08fda03   Colin Ian King   staging: wilc1000...
1130
  	u32 associatedsta = ~0;
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1131
  	u32 inactive_time = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1132
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
1133
  	vif = netdev_priv(dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1134

a4cac4810   Glen Lee   staging: wilc1000...
1135
  	if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1136
  		for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1137
1138
1139
1140
  			if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
  				associatedsta = i;
  				break;
  			}
c5c77ba18   Johnny Kim   staging: wilc1000...
1141
  		}
6c08fda03   Colin Ian King   staging: wilc1000...
1142
  		if (associatedsta == ~0) {
06fb9336a   Leo Kim   staging: wilc1000...
1143
1144
  			netdev_err(dev, "sta required is not associated
  ");
aaed3290f   Leo Kim   staging: wilc1000...
1145
  			return -ENOENT;
c5c77ba18   Johnny Kim   staging: wilc1000...
1146
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
1147
  		sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
c5c77ba18   Johnny Kim   staging: wilc1000...
1148

fbf5379bf   Glen Lee   staging: wilc1000...
1149
  		wilc_get_inactive_time(vif, mac, &inactive_time);
c5c77ba18   Johnny Kim   staging: wilc1000...
1150
  		sinfo->inactive_time = 1000 * inactive_time;
c5c77ba18   Johnny Kim   staging: wilc1000...
1151
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
1152

a4cac4810   Glen Lee   staging: wilc1000...
1153
  	if (vif->iftype == STATION_MODE) {
03e7b9c42   Leo Kim   staging: wilc1000...
1154
  		struct rf_info strStatistics;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1155

fbf5379bf   Glen Lee   staging: wilc1000...
1156
  		wilc_get_statistics(vif, &strStatistics);
c5c77ba18   Johnny Kim   staging: wilc1000...
1157

c5c77ba18   Johnny Kim   staging: wilc1000...
1158
  		sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
6212990a8   Chandra S Gorentla   drivers: staging:...
1159
  						BIT(NL80211_STA_INFO_RX_PACKETS) |
c5c77ba18   Johnny Kim   staging: wilc1000...
1160
1161
1162
  						BIT(NL80211_STA_INFO_TX_PACKETS) |
  						BIT(NL80211_STA_INFO_TX_FAILED) |
  						BIT(NL80211_STA_INFO_TX_BITRATE);
c5c77ba18   Johnny Kim   staging: wilc1000...
1163

00c8dfcf9   Leo Kim   staging: wilc1000...
1164
  		sinfo->signal = strStatistics.rssi;
9b99274a7   Leo Kim   staging: wilc1000...
1165
  		sinfo->rx_packets = strStatistics.rx_cnt;
541603767   Leo Kim   staging: wilc1000...
1166
1167
  		sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
  		sinfo->tx_failed = strStatistics.tx_fail_cnt;
5babeecb9   Leo Kim   staging: wilc1000...
1168
  		sinfo->txrate.legacy = strStatistics.link_speed * 10;
c5c77ba18   Johnny Kim   staging: wilc1000...
1169

5babeecb9   Leo Kim   staging: wilc1000...
1170
1171
  		if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
  		    (strStatistics.link_speed != DEFAULT_LINK_SPEED))
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
1172
  			wilc_enable_tcp_ack_filter(true);
5babeecb9   Leo Kim   staging: wilc1000...
1173
  		else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
1174
  			wilc_enable_tcp_ack_filter(false);
c5c77ba18   Johnny Kim   staging: wilc1000...
1175
  	}
aaed3290f   Leo Kim   staging: wilc1000...
1176
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1177
  }
a5f7db6aa   Chaehyun Lim   staging: wilc1000...
1178
1179
  static int change_bss(struct wiphy *wiphy, struct net_device *dev,
  		      struct bss_parameters *params)
c5c77ba18   Johnny Kim   staging: wilc1000...
1180
  {
c5c77ba18   Johnny Kim   staging: wilc1000...
1181
1182
  	return 0;
  }
a76b63ef5   Chaehyun Lim   staging: wilc1000...
1183
  static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
c5c77ba18   Johnny Kim   staging: wilc1000...
1184
  {
e6e12661d   Leo Kim   staging: wilc1000...
1185
  	s32 s32Error = 0;
a5f0fb5ca   Chaehyun Lim   staging: wilc1000...
1186
  	struct cfg_param_attr pstrCfgParamVal;
2726887c5   Chaehyun Lim   staging: wilc1000...
1187
  	struct wilc_priv *priv;
cf60106bf   Glen Lee   staging: wilc1000...
1188
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
1189
1190
  
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
1191
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1192

87c05b286   Tony Cho   staging: wilc1000...
1193
  	pstrCfgParamVal.flag = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1194
1195
  
  	if (changed & WIPHY_PARAM_RETRY_SHORT) {
87c05b286   Tony Cho   staging: wilc1000...
1196
  		pstrCfgParamVal.flag  |= RETRY_SHORT;
c5c77ba18   Johnny Kim   staging: wilc1000...
1197
1198
1199
  		pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
  	}
  	if (changed & WIPHY_PARAM_RETRY_LONG) {
87c05b286   Tony Cho   staging: wilc1000...
1200
  		pstrCfgParamVal.flag |= RETRY_LONG;
c5c77ba18   Johnny Kim   staging: wilc1000...
1201
  		pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
c5c77ba18   Johnny Kim   staging: wilc1000...
1202
1203
  	}
  	if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
87c05b286   Tony Cho   staging: wilc1000...
1204
  		pstrCfgParamVal.flag |= FRAG_THRESHOLD;
c5c77ba18   Johnny Kim   staging: wilc1000...
1205
  		pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
c5c77ba18   Johnny Kim   staging: wilc1000...
1206
1207
1208
  	}
  
  	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
87c05b286   Tony Cho   staging: wilc1000...
1209
  		pstrCfgParamVal.flag |= RTS_THRESHOLD;
c5c77ba18   Johnny Kim   staging: wilc1000...
1210
  		pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
c5c77ba18   Johnny Kim   staging: wilc1000...
1211
  	}
fbf5379bf   Glen Lee   staging: wilc1000...
1212
  	s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
c5c77ba18   Johnny Kim   staging: wilc1000...
1213
  	if (s32Error)
06fb9336a   Leo Kim   staging: wilc1000...
1214
1215
  		netdev_err(priv->dev, "Error in setting WIPHY PARAMS
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1216
1217
1218
  
  	return s32Error;
  }
e5af05614   Arnd Bergmann   staging: wilc1000...
1219

4d46657a2   Chaehyun Lim   staging: wilc1000...
1220
1221
  static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
  		     struct cfg80211_pmksa *pmksa)
c5c77ba18   Johnny Kim   staging: wilc1000...
1222
  {
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1223
  	u32 i;
e6e12661d   Leo Kim   staging: wilc1000...
1224
  	s32 s32Error = 0;
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
1225
  	u8 flag = 0;
cf60106bf   Glen Lee   staging: wilc1000...
1226
  	struct wilc_vif *vif;
2726887c5   Chaehyun Lim   staging: wilc1000...
1227
  	struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba18   Johnny Kim   staging: wilc1000...
1228

cf60106bf   Glen Lee   staging: wilc1000...
1229
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1230
1231
1232
  
  
  	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
1a646e7e9   Chaehyun Lim   staging: wilc1000...
1233
  		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba18   Johnny Kim   staging: wilc1000...
1234
  				 ETH_ALEN)) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1235
  			flag = PMKID_FOUND;
c5c77ba18   Johnny Kim   staging: wilc1000...
1236
1237
1238
1239
  			break;
  		}
  	}
  	if (i < WILC_MAX_NUM_PMKIDS) {
d00d2ba33   Chaehyun Lim   staging: wilc1000...
1240
  		memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
c5c77ba18   Johnny Kim   staging: wilc1000...
1241
  			    ETH_ALEN);
d00d2ba33   Chaehyun Lim   staging: wilc1000...
1242
  		memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
c5c77ba18   Johnny Kim   staging: wilc1000...
1243
1244
1245
1246
  			    PMKID_LEN);
  		if (!(flag == PMKID_FOUND))
  			priv->pmkid_list.numpmkid++;
  	} else {
06fb9336a   Leo Kim   staging: wilc1000...
1247
1248
  		netdev_err(netdev, "Invalid PMKID index
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1249
1250
  		s32Error = -EINVAL;
  	}
64d3546a3   Chris Park   staging: wilc1000...
1251
  	if (!s32Error)
fbf5379bf   Glen Lee   staging: wilc1000...
1252
  		s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
64d3546a3   Chris Park   staging: wilc1000...
1253

c5c77ba18   Johnny Kim   staging: wilc1000...
1254
1255
  	return s32Error;
  }
1ff86d960   Chaehyun Lim   staging: wilc1000...
1256
1257
  static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
  		     struct cfg80211_pmksa *pmksa)
c5c77ba18   Johnny Kim   staging: wilc1000...
1258
  {
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1259
  	u32 i;
e6e12661d   Leo Kim   staging: wilc1000...
1260
  	s32 s32Error = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1261

2726887c5   Chaehyun Lim   staging: wilc1000...
1262
  	struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba18   Johnny Kim   staging: wilc1000...
1263

c5c77ba18   Johnny Kim   staging: wilc1000...
1264
  	for (i = 0; i < priv->pmkid_list.numpmkid; i++)	{
1a646e7e9   Chaehyun Lim   staging: wilc1000...
1265
  		if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba18   Johnny Kim   staging: wilc1000...
1266
  				 ETH_ALEN)) {
cd1e6cb4c   Leo Kim   staging: wilc1000...
1267
  			memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
c5c77ba18   Johnny Kim   staging: wilc1000...
1268
1269
1270
1271
1272
1273
  			break;
  		}
  	}
  
  	if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
  		for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
d00d2ba33   Chaehyun Lim   staging: wilc1000...
1274
  			memcpy(priv->pmkid_list.pmkidlist[i].bssid,
c5c77ba18   Johnny Kim   staging: wilc1000...
1275
1276
  				    priv->pmkid_list.pmkidlist[i + 1].bssid,
  				    ETH_ALEN);
d00d2ba33   Chaehyun Lim   staging: wilc1000...
1277
  			memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
c5c77ba18   Johnny Kim   staging: wilc1000...
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
  				    priv->pmkid_list.pmkidlist[i].pmkid,
  				    PMKID_LEN);
  		}
  		priv->pmkid_list.numpmkid--;
  	} else {
  		s32Error = -EINVAL;
  	}
  
  	return s32Error;
  }
b33c39b1f   Chaehyun Lim   staging: wilc1000...
1288
  static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
c5c77ba18   Johnny Kim   staging: wilc1000...
1289
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1290
  	struct wilc_priv *priv = wiphy_priv(wiphy);
c5c77ba18   Johnny Kim   staging: wilc1000...
1291

a949f9095   Leo Kim   staging: wilc1000...
1292
  	memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
c5c77ba18   Johnny Kim   staging: wilc1000...
1293
1294
1295
  
  	return 0;
  }
c5c77ba18   Johnny Kim   staging: wilc1000...
1296

1608c4034   Arnd Bergmann   staging/wilc1000:...
1297
  static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
c5c77ba18   Johnny Kim   staging: wilc1000...
1298
  {
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1299
1300
  	u32 index = 0;
  	u32 i = 0, j = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1301

63d03e477   Greg Kroah-Hartman   staging: wilc1000...
1302
1303
  	u8 op_channel_attr_index = 0;
  	u8 channel_list_attr_index = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1304
1305
  
  	while (index < len) {
d5e27e8b8   Roger H. Newell   staging: wilc1000...
1306
  		if (buf[index] == GO_INTENT_ATTR_ID)
c5c77ba18   Johnny Kim   staging: wilc1000...
1307
  			buf[index + 3] = (buf[index + 3]  & 0x01) | (0x00 << 1);
c5c77ba18   Johnny Kim   staging: wilc1000...
1308

78174adaf   Chandra S Gorentla   staging: wilc1000...
1309
  		if (buf[index] ==  CHANLIST_ATTR_ID)
c5c77ba18   Johnny Kim   staging: wilc1000...
1310
  			channel_list_attr_index = index;
78174adaf   Chandra S Gorentla   staging: wilc1000...
1311
  		else if (buf[index] ==  OPERCHAN_ATTR_ID)
c5c77ba18   Johnny Kim   staging: wilc1000...
1312
  			op_channel_attr_index = index;
a89f7c551   Leo Kim   staging: wilc1000...
1313
  		index += buf[index + 1] + 3;
c5c77ba18   Johnny Kim   staging: wilc1000...
1314
  	}
0bd8274fb   Leo Kim   staging: wilc1000...
1315
  	if (wlan_channel != INVALID_CHANNEL) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1316
  		if (channel_list_attr_index) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1317
1318
  			for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
  				if (buf[i] == 0x51) {
d5e27e8b8   Roger H. Newell   staging: wilc1000...
1319
  					for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
0bd8274fb   Leo Kim   staging: wilc1000...
1320
  						buf[j] = wlan_channel;
c5c77ba18   Johnny Kim   staging: wilc1000...
1321
1322
1323
1324
  					break;
  				}
  			}
  		}
a89f7c551   Leo Kim   staging: wilc1000...
1325

c5c77ba18   Johnny Kim   staging: wilc1000...
1326
  		if (op_channel_attr_index) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1327
  			buf[op_channel_attr_index + 6] = 0x51;
0bd8274fb   Leo Kim   staging: wilc1000...
1328
  			buf[op_channel_attr_index + 7] = wlan_channel;
c5c77ba18   Johnny Kim   staging: wilc1000...
1329
1330
1331
  		}
  	}
  }
1608c4034   Arnd Bergmann   staging/wilc1000:...
1332
  static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
c5c77ba18   Johnny Kim   staging: wilc1000...
1333
  {
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1334
1335
  	u32 index = 0;
  	u32 i = 0, j = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1336

63d03e477   Greg Kroah-Hartman   staging: wilc1000...
1337
1338
  	u8 op_channel_attr_index = 0;
  	u8 channel_list_attr_index = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1339
1340
  
  	while (index < len) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1341
  		if (buf[index] == GO_INTENT_ATTR_ID) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1342
  			buf[index + 3] = (buf[index + 3]  & 0x01) | (0x0f << 1);
c5c77ba18   Johnny Kim   staging: wilc1000...
1343
1344
1345
  
  			break;
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
1346

78174adaf   Chandra S Gorentla   staging: wilc1000...
1347
  		if (buf[index] ==  CHANLIST_ATTR_ID)
c5c77ba18   Johnny Kim   staging: wilc1000...
1348
  			channel_list_attr_index = index;
78174adaf   Chandra S Gorentla   staging: wilc1000...
1349
  		else if (buf[index] ==  OPERCHAN_ATTR_ID)
c5c77ba18   Johnny Kim   staging: wilc1000...
1350
  			op_channel_attr_index = index;
a89f7c551   Leo Kim   staging: wilc1000...
1351
  		index += buf[index + 1] + 3;
c5c77ba18   Johnny Kim   staging: wilc1000...
1352
  	}
0bd8274fb   Leo Kim   staging: wilc1000...
1353
  	if (wlan_channel != INVALID_CHANNEL && bOperChan) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1354
  		if (channel_list_attr_index) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1355
1356
  			for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
  				if (buf[i] == 0x51) {
d5e27e8b8   Roger H. Newell   staging: wilc1000...
1357
  					for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
0bd8274fb   Leo Kim   staging: wilc1000...
1358
  						buf[j] = wlan_channel;
c5c77ba18   Johnny Kim   staging: wilc1000...
1359
1360
1361
1362
  					break;
  				}
  			}
  		}
a89f7c551   Leo Kim   staging: wilc1000...
1363

c5c77ba18   Johnny Kim   staging: wilc1000...
1364
  		if (op_channel_attr_index) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1365
  			buf[op_channel_attr_index + 6] = 0x51;
0bd8274fb   Leo Kim   staging: wilc1000...
1366
  			buf[op_channel_attr_index + 7] = wlan_channel;
c5c77ba18   Johnny Kim   staging: wilc1000...
1367
1368
1369
  		}
  	}
  }
63f803518   Anchal Jain   staging: wilc1000...
1370
  void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
c5c77ba18   Johnny Kim   staging: wilc1000...
1371
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1372
  	struct wilc_priv *priv;
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1373
  	u32 header, pkt_offset;
441dc609d   Leo Kim   staging: wilc1000...
1374
  	struct host_if_drv *pstrWFIDrv;
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1375
  	u32 i = 0;
fb4ec9caa   Chaehyun Lim   staging: wilc1000...
1376
  	s32 s32Freq;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1377

c5c77ba18   Johnny Kim   staging: wilc1000...
1378
  	priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
48b28df99   Leo Kim   staging: wilc1000...
1379
  	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
c5c77ba18   Johnny Kim   staging: wilc1000...
1380

d00d2ba33   Chaehyun Lim   staging: wilc1000...
1381
  	memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
c5c77ba18   Johnny Kim   staging: wilc1000...
1382

c5c77ba18   Johnny Kim   staging: wilc1000...
1383
1384
1385
1386
  	pkt_offset = GET_PKT_OFFSET(header);
  
  	if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
  		if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1387
  			cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
1388
1389
  			return;
  		} else {
e3f16965c   Chris Park   staging: wilc1000...
1390
  			if (pkt_offset & IS_MGMT_STATUS_SUCCES)
c5c77ba18   Johnny Kim   staging: wilc1000...
1391
  				cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
e3f16965c   Chris Park   staging: wilc1000...
1392
  			else
c5c77ba18   Johnny Kim   staging: wilc1000...
1393
  				cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
1394
1395
1396
  			return;
  		}
  	} else {
57fbcce37   Johannes Berg   cfg80211: remove ...
1397
  		s32Freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ);
c5c77ba18   Johnny Kim   staging: wilc1000...
1398
1399
  
  		if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1229b1ab4   Leo Kim   staging: wilc1000...
1400
  			if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
e3f16965c   Chris Park   staging: wilc1000...
1401
1402
  				netdev_dbg(dev, "Receiving action wrong ch
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1403
1404
1405
  				return;
  			}
  			if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1406
1407
  				switch (buff[ACTION_SUBTYPE_ID]) {
  				case GAS_INTIAL_REQ:
c5c77ba18   Johnny Kim   staging: wilc1000...
1408
1409
1410
  					break;
  
  				case GAS_INTIAL_RSP:
c5c77ba18   Johnny Kim   staging: wilc1000...
1411
1412
1413
  					break;
  
  				case PUBLIC_ACT_VENDORSPEC:
881eb5d81   Leo Kim   staging: wilc1000...
1414
  					if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1415
  						if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP))	{
a25d51860   Leo Kim   staging: wilc1000...
1416
  							if (!wilc_ie) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1417
  								for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++)	{
8668594a9   Leo Kim   staging: wilc1000...
1418
  									if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
b84a3ac42   Leo Kim   staging: wilc1000...
1419
  										p2p_recv_random = buff[i + 6];
a25d51860   Leo Kim   staging: wilc1000...
1420
  										wilc_ie = true;
c5c77ba18   Johnny Kim   staging: wilc1000...
1421
1422
1423
1424
1425
  										break;
  									}
  								}
  							}
  						}
b84a3ac42   Leo Kim   staging: wilc1000...
1426
  						if (p2p_local_random > p2p_recv_random)	{
c5c77ba18   Johnny Kim   staging: wilc1000...
1427
1428
1429
  							if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
  							      || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
  								for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
881eb5d81   Leo Kim   staging: wilc1000...
1430
  									if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1431
1432
1433
1434
1435
  										WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
  										break;
  									}
  								}
  							}
583d972cf   Leo Kim   staging: wilc1000...
1436
  						} else {
e3f16965c   Chris Park   staging: wilc1000...
1437
1438
  							netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x
  ", p2p_local_random, p2p_recv_random);
583d972cf   Leo Kim   staging: wilc1000...
1439
  						}
c5c77ba18   Johnny Kim   staging: wilc1000...
1440
  					}
a25d51860   Leo Kim   staging: wilc1000...
1441
  					if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie))	{
c5c77ba18   Johnny Kim   staging: wilc1000...
1442
  						cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
c5c77ba18   Johnny Kim   staging: wilc1000...
1443
1444
1445
1446
1447
  						return;
  					}
  					break;
  
  				default:
e3f16965c   Chris Park   staging: wilc1000...
1448
1449
  					netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x
  ", buff[ACTION_SUBTYPE_ID]);
c5c77ba18   Johnny Kim   staging: wilc1000...
1450
1451
1452
1453
  					break;
  				}
  			}
  		}
783d07c1b   Glen Lee   staging: wilc1000...
1454
  		cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
c5c77ba18   Johnny Kim   staging: wilc1000...
1455
1456
  	}
  }
c5c77ba18   Johnny Kim   staging: wilc1000...
1457
1458
  static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
  {
4375cad94   Alison Schofield   staging: wilc1000...
1459
  	struct p2p_mgmt_data *pv_data = priv;
c5c77ba18   Johnny Kim   staging: wilc1000...
1460
1461
1462
1463
1464
  
  
  	kfree(pv_data->buff);
  	kfree(pv_data);
  }
c5c77ba18   Johnny Kim   staging: wilc1000...
1465
1466
  static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1467
  	struct wilc_priv *priv;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1468

4375cad94   Alison Schofield   staging: wilc1000...
1469
  	priv = pUserVoid;
c5c77ba18   Johnny Kim   staging: wilc1000...
1470

72ed4dc73   Dean Lee   staging: wilc1000...
1471
  	priv->bInP2PlistenState = true;
c5c77ba18   Johnny Kim   staging: wilc1000...
1472

c5c77ba18   Johnny Kim   staging: wilc1000...
1473
1474
1475
1476
1477
  	cfg80211_ready_on_channel(priv->wdev,
  				  priv->strRemainOnChanParams.u64ListenCookie,
  				  priv->strRemainOnChanParams.pstrListenChan,
  				  priv->strRemainOnChanParams.u32ListenDuration,
  				  GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
1478
  }
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1479
  static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
c5c77ba18   Johnny Kim   staging: wilc1000...
1480
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1481
  	struct wilc_priv *priv;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1482

4375cad94   Alison Schofield   staging: wilc1000...
1483
  	priv = pUserVoid;
c5c77ba18   Johnny Kim   staging: wilc1000...
1484

c5c77ba18   Johnny Kim   staging: wilc1000...
1485
  	if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
72ed4dc73   Dean Lee   staging: wilc1000...
1486
  		priv->bInP2PlistenState = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
1487

c5c77ba18   Johnny Kim   staging: wilc1000...
1488
1489
1490
1491
  		cfg80211_remain_on_channel_expired(priv->wdev,
  						   priv->strRemainOnChanParams.u64ListenCookie,
  						   priv->strRemainOnChanParams.pstrListenChan,
  						   GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
1492
1493
  	}
  }
6d19d695e   Chaehyun Lim   staging: wilc1000...
1494
1495
1496
1497
  static int remain_on_channel(struct wiphy *wiphy,
  			     struct wireless_dev *wdev,
  			     struct ieee80211_channel *chan,
  			     unsigned int duration, u64 *cookie)
c5c77ba18   Johnny Kim   staging: wilc1000...
1498
  {
e6e12661d   Leo Kim   staging: wilc1000...
1499
  	s32 s32Error = 0;
2726887c5   Chaehyun Lim   staging: wilc1000...
1500
  	struct wilc_priv *priv;
cf60106bf   Glen Lee   staging: wilc1000...
1501
  	struct wilc_vif *vif;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1502

c5c77ba18   Johnny Kim   staging: wilc1000...
1503
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
1504
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1505

c5c77ba18   Johnny Kim   staging: wilc1000...
1506
  	if (wdev->iftype == NL80211_IFTYPE_AP) {
e3f16965c   Chris Park   staging: wilc1000...
1507
1508
  		netdev_dbg(vif->ndev, "Required while in AP mode
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1509
1510
  		return s32Error;
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
1511

866a2c247   Chaehyun Lim   staging: wilc1000...
1512
  	curr_channel = chan->hw_value;
c5c77ba18   Johnny Kim   staging: wilc1000...
1513

c5c77ba18   Johnny Kim   staging: wilc1000...
1514
1515
  	priv->strRemainOnChanParams.pstrListenChan = chan;
  	priv->strRemainOnChanParams.u64ListenCookie = *cookie;
c5c77ba18   Johnny Kim   staging: wilc1000...
1516
1517
  	priv->strRemainOnChanParams.u32ListenDuration = duration;
  	priv->strRemainOnChanParams.u32ListenSessionID++;
fbf5379bf   Glen Lee   staging: wilc1000...
1518
1519
1520
1521
1522
  	s32Error = wilc_remain_on_channel(vif,
  				priv->strRemainOnChanParams.u32ListenSessionID,
  				duration, chan->hw_value,
  				WILC_WFI_RemainOnChannelExpired,
  				WILC_WFI_RemainOnChannelReady, (void *)priv);
c5c77ba18   Johnny Kim   staging: wilc1000...
1523
1524
1525
  
  	return s32Error;
  }
1dd5440b6   Chaehyun Lim   staging: wilc1000...
1526
1527
1528
  static int cancel_remain_on_channel(struct wiphy *wiphy,
  				    struct wireless_dev *wdev,
  				    u64 cookie)
c5c77ba18   Johnny Kim   staging: wilc1000...
1529
  {
e6e12661d   Leo Kim   staging: wilc1000...
1530
  	s32 s32Error = 0;
2726887c5   Chaehyun Lim   staging: wilc1000...
1531
  	struct wilc_priv *priv;
cf60106bf   Glen Lee   staging: wilc1000...
1532
  	struct wilc_vif *vif;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1533

c5c77ba18   Johnny Kim   staging: wilc1000...
1534
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
1535
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1536

fbf5379bf   Glen Lee   staging: wilc1000...
1537
  	s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
c5c77ba18   Johnny Kim   staging: wilc1000...
1538
1539
  	return s32Error;
  }
a89f7c551   Leo Kim   staging: wilc1000...
1540

c156032da   Chaehyun Lim   staging: wilc1000...
1541
1542
1543
1544
  static int mgmt_tx(struct wiphy *wiphy,
  		   struct wireless_dev *wdev,
  		   struct cfg80211_mgmt_tx_params *params,
  		   u64 *cookie)
c5c77ba18   Johnny Kim   staging: wilc1000...
1545
  {
c5c77ba18   Johnny Kim   staging: wilc1000...
1546
1547
1548
1549
  	struct ieee80211_channel *chan = params->chan;
  	unsigned int wait = params->wait;
  	const u8 *buf = params->buf;
  	size_t len = params->len;
c5c77ba18   Johnny Kim   staging: wilc1000...
1550
1551
  	const struct ieee80211_mgmt *mgmt;
  	struct p2p_mgmt_data *mgmt_tx;
2726887c5   Chaehyun Lim   staging: wilc1000...
1552
  	struct wilc_priv *priv;
441dc609d   Leo Kim   staging: wilc1000...
1553
  	struct host_if_drv *pstrWFIDrv;
4e4467fdd   Chaehyun Lim   staging: wilc1000...
1554
  	u32 i;
a4cac4810   Glen Lee   staging: wilc1000...
1555
  	struct wilc_vif *vif;
8668594a9   Leo Kim   staging: wilc1000...
1556
  	u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
c5c77ba18   Johnny Kim   staging: wilc1000...
1557

a4cac4810   Glen Lee   staging: wilc1000...
1558
  	vif = netdev_priv(wdev->netdev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1559
  	priv = wiphy_priv(wiphy);
48b28df99   Leo Kim   staging: wilc1000...
1560
  	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
c5c77ba18   Johnny Kim   staging: wilc1000...
1561
1562
1563
1564
1565
1566
  
  	*cookie = (unsigned long)buf;
  	priv->u64tx_cookie = *cookie;
  	mgmt = (const struct ieee80211_mgmt *) buf;
  
  	if (ieee80211_is_mgmt(mgmt->frame_control)) {
f3052587e   Glen Lee   staging: wilc1000...
1567
  		mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
06fb9336a   Leo Kim   staging: wilc1000...
1568
  		if (!mgmt_tx)
e6e12661d   Leo Kim   staging: wilc1000...
1569
  			return -EFAULT;
06fb9336a   Leo Kim   staging: wilc1000...
1570

f3052587e   Glen Lee   staging: wilc1000...
1571
  		mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
d99ee289b   Dan Carpenter   staging: wilc1000...
1572
  		if (!mgmt_tx->buff) {
f638dd391   Tony Cho   staging: wilc1000...
1573
  			kfree(mgmt_tx);
d99ee289b   Dan Carpenter   staging: wilc1000...
1574
1575
  			return -ENOMEM;
  		}
06fb9336a   Leo Kim   staging: wilc1000...
1576

d00d2ba33   Chaehyun Lim   staging: wilc1000...
1577
  		memcpy(mgmt_tx->buff, buf, len);
c5c77ba18   Johnny Kim   staging: wilc1000...
1578
1579
1580
1581
  		mgmt_tx->size = len;
  
  
  		if (ieee80211_is_probe_resp(mgmt->frame_control)) {
fbf5379bf   Glen Lee   staging: wilc1000...
1582
  			wilc_set_mac_chnl_num(vif, chan->hw_value);
866a2c247   Chaehyun Lim   staging: wilc1000...
1583
  			curr_channel = chan->hw_value;
c5c77ba18   Johnny Kim   staging: wilc1000...
1584
  		} else if (ieee80211_is_action(mgmt->frame_control))   {
c5c77ba18   Johnny Kim   staging: wilc1000...
1585
  			if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1586
1587
  				if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
  				    buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF)	{
fbf5379bf   Glen Lee   staging: wilc1000...
1588
1589
  					wilc_set_mac_chnl_num(vif,
  							      chan->hw_value);
866a2c247   Chaehyun Lim   staging: wilc1000...
1590
  					curr_channel = chan->hw_value;
c5c77ba18   Johnny Kim   staging: wilc1000...
1591
1592
1593
  				}
  				switch (buf[ACTION_SUBTYPE_ID])	{
  				case GAS_INTIAL_REQ:
c5c77ba18   Johnny Kim   staging: wilc1000...
1594
  					break;
c5c77ba18   Johnny Kim   staging: wilc1000...
1595
1596
  
  				case GAS_INTIAL_RSP:
c5c77ba18   Johnny Kim   staging: wilc1000...
1597
  					break;
c5c77ba18   Johnny Kim   staging: wilc1000...
1598
1599
1600
  
  				case PUBLIC_ACT_VENDORSPEC:
  				{
881eb5d81   Leo Kim   staging: wilc1000...
1601
  					if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1602
  						if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
b84a3ac42   Leo Kim   staging: wilc1000...
1603
  							if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
583d972cf   Leo Kim   staging: wilc1000...
1604
1605
  								get_random_bytes(&p2p_local_random, 1);
  								p2p_local_random++;
c5c77ba18   Johnny Kim   staging: wilc1000...
1606
1607
1608
1609
1610
  							}
  						}
  
  						if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
  						      || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
b84a3ac42   Leo Kim   staging: wilc1000...
1611
  							if (p2p_local_random > p2p_recv_random)	{
c5c77ba18   Johnny Kim   staging: wilc1000...
1612
  								for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
881eb5d81   Leo Kim   staging: wilc1000...
1613
  									if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1614
  										if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
a4cac4810   Glen Lee   staging: wilc1000...
1615
  											WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
c5c77ba18   Johnny Kim   staging: wilc1000...
1616
  										else
a4cac4810   Glen Lee   staging: wilc1000...
1617
  											WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
c5c77ba18   Johnny Kim   staging: wilc1000...
1618
1619
1620
1621
1622
  										break;
  									}
  								}
  
  								if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
8668594a9   Leo Kim   staging: wilc1000...
1623
1624
  									memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
  									mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
c5c77ba18   Johnny Kim   staging: wilc1000...
1625
1626
  									mgmt_tx->size = buf_len;
  								}
583d972cf   Leo Kim   staging: wilc1000...
1627
  							}
c5c77ba18   Johnny Kim   staging: wilc1000...
1628
1629
1630
  						}
  
  					} else {
e3f16965c   Chris Park   staging: wilc1000...
1631
1632
  						netdev_dbg(vif->ndev, "Not a P2P public action frame
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1633
1634
1635
1636
1637
1638
1639
  					}
  
  					break;
  				}
  
  				default:
  				{
e3f16965c   Chris Park   staging: wilc1000...
1640
1641
  					netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x
  ", buf[ACTION_SUBTYPE_ID]);
c5c77ba18   Johnny Kim   staging: wilc1000...
1642
1643
1644
  					break;
  				}
  				}
c5c77ba18   Johnny Kim   staging: wilc1000...
1645
  			}
1229b1ab4   Leo Kim   staging: wilc1000...
1646
  			pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
c5c77ba18   Johnny Kim   staging: wilc1000...
1647
  		}
829c477fd   Glen Lee   staging: wilc1000...
1648
1649
  		wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
  					   mgmt_tx->buff, mgmt_tx->size,
c9d4834d9   Glen Lee   staging: wilc1000...
1650
  					   WILC_WFI_mgmt_tx_complete);
c5c77ba18   Johnny Kim   staging: wilc1000...
1651
  	}
aaed3290f   Leo Kim   staging: wilc1000...
1652
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1653
  }
85c587a54   Chaehyun Lim   staging: wilc1000...
1654
1655
1656
  static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
  			       struct wireless_dev *wdev,
  			       u64 cookie)
c5c77ba18   Johnny Kim   staging: wilc1000...
1657
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1658
  	struct wilc_priv *priv;
441dc609d   Leo Kim   staging: wilc1000...
1659
  	struct host_if_drv *pstrWFIDrv;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1660

c5c77ba18   Johnny Kim   staging: wilc1000...
1661
  	priv = wiphy_priv(wiphy);
48b28df99   Leo Kim   staging: wilc1000...
1662
  	pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1229b1ab4   Leo Kim   staging: wilc1000...
1663
  	pstrWFIDrv->p2p_timeout = jiffies;
c5c77ba18   Johnny Kim   staging: wilc1000...
1664

7e4e87d32   Luis de Bethencourt   staging: wilc1000...
1665
  	if (!priv->bInP2PlistenState) {
c5c77ba18   Johnny Kim   staging: wilc1000...
1666
1667
1668
1669
  		cfg80211_remain_on_channel_expired(priv->wdev,
  						   priv->strRemainOnChanParams.u64ListenCookie,
  						   priv->strRemainOnChanParams.pstrListenChan,
  						   GFP_KERNEL);
c5c77ba18   Johnny Kim   staging: wilc1000...
1670
1671
1672
1673
  	}
  
  	return 0;
  }
8e0735c5e   Chaehyun Lim   staging: wilc1000...
1674
1675
  void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
  			      u16 frame_type, bool reg)
c5c77ba18   Johnny Kim   staging: wilc1000...
1676
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1677
  	struct wilc_priv *priv;
a4cac4810   Glen Lee   staging: wilc1000...
1678
  	struct wilc_vif *vif;
1b86935eb   Glen Lee   staging: wilc1000...
1679
  	struct wilc *wl;
c5c77ba18   Johnny Kim   staging: wilc1000...
1680
1681
  
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
1682
1683
  	vif = netdev_priv(priv->wdev->netdev);
  	wl = vif->wilc;
c5c77ba18   Johnny Kim   staging: wilc1000...
1684

c5c77ba18   Johnny Kim   staging: wilc1000...
1685
1686
  	if (!frame_type)
  		return;
c5c77ba18   Johnny Kim   staging: wilc1000...
1687
1688
1689
  	switch (frame_type) {
  	case PROBE_REQ:
  	{
340a84ff9   Leo Kim   staging: wilc1000...
1690
  		vif->frame_reg[0].type = frame_type;
89febb21c   Leo Kim   staging: wilc1000...
1691
  		vif->frame_reg[0].reg = reg;
c5c77ba18   Johnny Kim   staging: wilc1000...
1692
1693
1694
1695
1696
  	}
  	break;
  
  	case ACTION:
  	{
340a84ff9   Leo Kim   staging: wilc1000...
1697
  		vif->frame_reg[1].type = frame_type;
89febb21c   Leo Kim   staging: wilc1000...
1698
  		vif->frame_reg[1].reg = reg;
c5c77ba18   Johnny Kim   staging: wilc1000...
1699
1700
1701
1702
1703
1704
1705
  	}
  	break;
  
  	default:
  	{
  		break;
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
1706
  	}
a89f7c551   Leo Kim   staging: wilc1000...
1707

e3f16965c   Chris Park   staging: wilc1000...
1708
  	if (!wl->initialized)
c5c77ba18   Johnny Kim   staging: wilc1000...
1709
  		return;
fbf5379bf   Glen Lee   staging: wilc1000...
1710
  	wilc_frame_register(vif, frame_type, reg);
c5c77ba18   Johnny Kim   staging: wilc1000...
1711
  }
c5c77ba18   Johnny Kim   staging: wilc1000...
1712

a8047e26c   Chaehyun Lim   staging: wilc1000...
1713
1714
  static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
  			       s32 rssi_thold, u32 rssi_hyst)
c5c77ba18   Johnny Kim   staging: wilc1000...
1715
  {
c5c77ba18   Johnny Kim   staging: wilc1000...
1716
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1717
  }
a89f7c551   Leo Kim   staging: wilc1000...
1718

bdb6338f6   Chaehyun Lim   staging: wilc1000...
1719
1720
  static int dump_station(struct wiphy *wiphy, struct net_device *dev,
  			int idx, u8 *mac, struct station_info *sinfo)
c5c77ba18   Johnny Kim   staging: wilc1000...
1721
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1722
  	struct wilc_priv *priv;
cf60106bf   Glen Lee   staging: wilc1000...
1723
  	struct wilc_vif *vif;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1724

c5c77ba18   Johnny Kim   staging: wilc1000...
1725
1726
1727
1728
  	if (idx != 0)
  		return -ENOENT;
  
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
1729
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1730

c5c77ba18   Johnny Kim   staging: wilc1000...
1731
  	sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
c5c77ba18   Johnny Kim   staging: wilc1000...
1732

fbf5379bf   Glen Lee   staging: wilc1000...
1733
  	wilc_get_rssi(vif, &sinfo->signal);
c5c77ba18   Johnny Kim   staging: wilc1000...
1734

d13829686   Kangjie Lu   staging: wilc1000...
1735
  	memcpy(mac, priv->au8AssociatedBss, ETH_ALEN);
c5c77ba18   Johnny Kim   staging: wilc1000...
1736
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1737
  }
465306795   Chaehyun Lim   staging: wilc1000...
1738
1739
  static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
  			  bool enabled, int timeout)
c5c77ba18   Johnny Kim   staging: wilc1000...
1740
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1741
  	struct wilc_priv *priv;
cf60106bf   Glen Lee   staging: wilc1000...
1742
  	struct wilc_vif *vif;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1743

369a1d3bd   Leo Kim   staging: wilc1000...
1744
  	if (!wiphy)
c5c77ba18   Johnny Kim   staging: wilc1000...
1745
1746
1747
  		return -ENOENT;
  
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
1748
  	vif = netdev_priv(priv->dev);
06fb9336a   Leo Kim   staging: wilc1000...
1749
  	if (!priv->hif_drv)
c5c77ba18   Johnny Kim   staging: wilc1000...
1750
  		return -EIO;
c5c77ba18   Johnny Kim   staging: wilc1000...
1751

0e1af73dd   Arnd Bergmann   staging/wilc1000:...
1752
  	if (wilc_enable_ps)
fbf5379bf   Glen Lee   staging: wilc1000...
1753
  		wilc_set_power_mgmt(vif, enabled, timeout);
c5c77ba18   Johnny Kim   staging: wilc1000...
1754

e6e12661d   Leo Kim   staging: wilc1000...
1755
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1756
  }
108b3439b   Glen Lee   staging: wilc1000...
1757

3615e9a36   Chaehyun Lim   staging: wilc1000...
1758
1759
  static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
  			       enum nl80211_iftype type, u32 *flags, struct vif_params *params)
c5c77ba18   Johnny Kim   staging: wilc1000...
1760
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1761
  	struct wilc_priv *priv;
a4cac4810   Glen Lee   staging: wilc1000...
1762
  	struct wilc_vif *vif;
299382cf4   Glen Lee   staging: wilc1000...
1763
  	struct wilc *wl;
c5c77ba18   Johnny Kim   staging: wilc1000...
1764

a4cac4810   Glen Lee   staging: wilc1000...
1765
  	vif = netdev_priv(dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1766
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
1767
  	wl = vif->wilc;
583d972cf   Leo Kim   staging: wilc1000...
1768
  	p2p_local_random = 0x01;
b84a3ac42   Leo Kim   staging: wilc1000...
1769
  	p2p_recv_random = 0x00;
a25d51860   Leo Kim   staging: wilc1000...
1770
  	wilc_ie = false;
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
1771
1772
  	wilc_optaining_ip = false;
  	del_timer(&wilc_during_ip_timer);
a89f7c551   Leo Kim   staging: wilc1000...
1773

c5c77ba18   Johnny Kim   staging: wilc1000...
1774
1775
  	switch (type) {
  	case NL80211_IFTYPE_STATION:
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
1776
  		wilc_connecting = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1777
1778
  		dev->ieee80211_ptr->iftype = type;
  		priv->wdev->iftype = type;
a4cac4810   Glen Lee   staging: wilc1000...
1779
1780
  		vif->monitor_flag = 0;
  		vif->iftype = STATION_MODE;
86bff01b9   Glen Lee   staging: wilc1000...
1781
  		wilc_set_operation_mode(vif, STATION_MODE);
c5c77ba18   Johnny Kim   staging: wilc1000...
1782

c5c77ba18   Johnny Kim   staging: wilc1000...
1783
  		memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
c5c77ba18   Johnny Kim   staging: wilc1000...
1784

86bff01b9   Glen Lee   staging: wilc1000...
1785
1786
  		wilc_enable_ps = true;
  		wilc_set_power_mgmt(vif, 1, 0);
c5c77ba18   Johnny Kim   staging: wilc1000...
1787
1788
1789
  		break;
  
  	case NL80211_IFTYPE_P2P_CLIENT:
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
1790
  		wilc_connecting = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1791
1792
  		dev->ieee80211_ptr->iftype = type;
  		priv->wdev->iftype = type;
a4cac4810   Glen Lee   staging: wilc1000...
1793
  		vif->monitor_flag = 0;
a4cac4810   Glen Lee   staging: wilc1000...
1794
  		vif->iftype = CLIENT_MODE;
86bff01b9   Glen Lee   staging: wilc1000...
1795
  		wilc_set_operation_mode(vif, STATION_MODE);
ee6323092   Glen Lee   staging: wilc1000...
1796
1797
1798
  
  		wilc_enable_ps = false;
  		wilc_set_power_mgmt(vif, 0, 0);
c5c77ba18   Johnny Kim   staging: wilc1000...
1799
1800
1801
  		break;
  
  	case NL80211_IFTYPE_AP:
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
1802
  		wilc_enable_ps = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
1803
1804
  		dev->ieee80211_ptr->iftype = type;
  		priv->wdev->iftype = type;
a4cac4810   Glen Lee   staging: wilc1000...
1805
  		vif->iftype = AP_MODE;
86bff01b9   Glen Lee   staging: wilc1000...
1806
1807
  
  		if (wl->initialized) {
b33068659   Glen Lee   staging: wilc1000...
1808
1809
  			wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
  						 0);
86bff01b9   Glen Lee   staging: wilc1000...
1810
1811
  			wilc_set_operation_mode(vif, AP_MODE);
  			wilc_set_power_mgmt(vif, 0, 0);
c5c77ba18   Johnny Kim   staging: wilc1000...
1812
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
1813
1814
1815
  		break;
  
  	case NL80211_IFTYPE_P2P_GO:
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
1816
  		wilc_optaining_ip = true;
7e872df9c   Leo Kim   staging: wilc1000...
1817
1818
  		mod_timer(&wilc_during_ip_timer,
  			  jiffies + msecs_to_jiffies(during_ip_time));
86bff01b9   Glen Lee   staging: wilc1000...
1819
  		wilc_set_operation_mode(vif, AP_MODE);
c5c77ba18   Johnny Kim   staging: wilc1000...
1820
1821
  		dev->ieee80211_ptr->iftype = type;
  		priv->wdev->iftype = type;
a4cac4810   Glen Lee   staging: wilc1000...
1822
  		vif->iftype = GO_MODE;
ee6323092   Glen Lee   staging: wilc1000...
1823
1824
1825
  
  		wilc_enable_ps = false;
  		wilc_set_power_mgmt(vif, 0, 0);
c5c77ba18   Johnny Kim   staging: wilc1000...
1826
1827
1828
  		break;
  
  	default:
06fb9336a   Leo Kim   staging: wilc1000...
1829
1830
  		netdev_err(dev, "Unknown interface type= %d
  ", type);
aaed3290f   Leo Kim   staging: wilc1000...
1831
  		return -EINVAL;
c5c77ba18   Johnny Kim   staging: wilc1000...
1832
  	}
aaed3290f   Leo Kim   staging: wilc1000...
1833
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1834
  }
a13168d75   Chaehyun Lim   staging: wilc1000...
1835
1836
  static int start_ap(struct wiphy *wiphy, struct net_device *dev,
  		    struct cfg80211_ap_settings *settings)
c5c77ba18   Johnny Kim   staging: wilc1000...
1837
1838
  {
  	struct cfg80211_beacon_data *beacon = &(settings->beacon);
2726887c5   Chaehyun Lim   staging: wilc1000...
1839
  	struct wilc_priv *priv;
e6e12661d   Leo Kim   staging: wilc1000...
1840
  	s32 s32Error = 0;
684dc1861   Glen Lee   staging: wilc1000...
1841
  	struct wilc *wl;
a4cac4810   Glen Lee   staging: wilc1000...
1842
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
1843
1844
  
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
1845
  	vif = netdev_priv(dev);
79f7dfa54   Leo Kim   staging: wilc1000...
1846
  	wl = vif->wilc;
c5c77ba18   Johnny Kim   staging: wilc1000...
1847

80785a9a8   Chaehyun Lim   staging: wilc1000...
1848
  	s32Error = set_channel(wiphy, &settings->chandef);
c5c77ba18   Johnny Kim   staging: wilc1000...
1849

e6e12661d   Leo Kim   staging: wilc1000...
1850
  	if (s32Error != 0)
06fb9336a   Leo Kim   staging: wilc1000...
1851
1852
  		netdev_err(dev, "Error in setting channel
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1853

6750140df   Leo Kim   staging: wilc1000...
1854
  	wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
cba352a4c   Glen Lee   staging: wilc1000...
1855
  	wilc_set_power_mgmt(vif, 0, 0);
c5c77ba18   Johnny Kim   staging: wilc1000...
1856

fbf5379bf   Glen Lee   staging: wilc1000...
1857
1858
1859
1860
  	s32Error = wilc_add_beacon(vif, settings->beacon_interval,
  				   settings->dtim_period, beacon->head_len,
  				   (u8 *)beacon->head, beacon->tail_len,
  				   (u8 *)beacon->tail);
c5c77ba18   Johnny Kim   staging: wilc1000...
1861
1862
1863
  
  	return s32Error;
  }
2a4c84d7a   Chaehyun Lim   staging: wilc1000...
1864
1865
  static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
  			 struct cfg80211_beacon_data *beacon)
c5c77ba18   Johnny Kim   staging: wilc1000...
1866
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
1867
  	struct wilc_priv *priv;
cf60106bf   Glen Lee   staging: wilc1000...
1868
  	struct wilc_vif *vif;
e6e12661d   Leo Kim   staging: wilc1000...
1869
  	s32 s32Error = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
1870
1871
  
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
1872
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1873

fbf5379bf   Glen Lee   staging: wilc1000...
1874
1875
1876
  	s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
  				   (u8 *)beacon->head, beacon->tail_len,
  				   (u8 *)beacon->tail);
c5c77ba18   Johnny Kim   staging: wilc1000...
1877
1878
1879
  
  	return s32Error;
  }
c8cddd791   Chaehyun Lim   staging: wilc1000...
1880
  static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
c5c77ba18   Johnny Kim   staging: wilc1000...
1881
  {
e6e12661d   Leo Kim   staging: wilc1000...
1882
  	s32 s32Error = 0;
2726887c5   Chaehyun Lim   staging: wilc1000...
1883
  	struct wilc_priv *priv;
cf60106bf   Glen Lee   staging: wilc1000...
1884
  	struct wilc_vif *vif;
63d03e477   Greg Kroah-Hartman   staging: wilc1000...
1885
  	u8 NullBssid[ETH_ALEN] = {0};
c5c77ba18   Johnny Kim   staging: wilc1000...
1886

7ae433631   Leo Kim   staging: wilc1000...
1887
1888
  	if (!wiphy)
  		return -EFAULT;
c5c77ba18   Johnny Kim   staging: wilc1000...
1889
1890
  
  	priv = wiphy_priv(wiphy);
cf60106bf   Glen Lee   staging: wilc1000...
1891
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1892

ba615f1ef   Glen Lee   staging: wilc1000...
1893
  	wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
c5c77ba18   Johnny Kim   staging: wilc1000...
1894

fbf5379bf   Glen Lee   staging: wilc1000...
1895
  	s32Error = wilc_del_beacon(vif);
c5c77ba18   Johnny Kim   staging: wilc1000...
1896

7dc1d0cc1   Leo Kim   staging: wilc1000...
1897
  	if (s32Error)
06fb9336a   Leo Kim   staging: wilc1000...
1898
1899
  		netdev_err(dev, "Host delete beacon fail
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1900

c5c77ba18   Johnny Kim   staging: wilc1000...
1901
1902
  	return s32Error;
  }
ed26955ca   Chaehyun Lim   staging: wilc1000...
1903
1904
  static int add_station(struct wiphy *wiphy, struct net_device *dev,
  		       const u8 *mac, struct station_parameters *params)
c5c77ba18   Johnny Kim   staging: wilc1000...
1905
  {
e6e12661d   Leo Kim   staging: wilc1000...
1906
  	s32 s32Error = 0;
2726887c5   Chaehyun Lim   staging: wilc1000...
1907
  	struct wilc_priv *priv;
6a89ba9ce   Tony Cho   staging: wilc1000...
1908
  	struct add_sta_param strStaParams = { {0} };
a4cac4810   Glen Lee   staging: wilc1000...
1909
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
1910

7ae433631   Leo Kim   staging: wilc1000...
1911
1912
  	if (!wiphy)
  		return -EFAULT;
c5c77ba18   Johnny Kim   staging: wilc1000...
1913
1914
  
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
1915
  	vif = netdev_priv(dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1916

a4cac4810   Glen Lee   staging: wilc1000...
1917
  	if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2353c388d   Leo Kim   staging: wilc1000...
1918
  		memcpy(strStaParams.bssid, mac, ETH_ALEN);
d00d2ba33   Chaehyun Lim   staging: wilc1000...
1919
  		memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
4101eb8a0   Leo Kim   staging: wilc1000...
1920
  		strStaParams.aid = params->aid;
e734223cd   Leo Kim   staging: wilc1000...
1921
  		strStaParams.rates_len = params->supported_rates_len;
a622e0164   Leo Kim   staging: wilc1000...
1922
  		strStaParams.rates = params->supported_rates;
c5c77ba18   Johnny Kim   staging: wilc1000...
1923

369a1d3bd   Leo Kim   staging: wilc1000...
1924
  		if (!params->ht_capa) {
225201208   Leo Kim   staging: wilc1000...
1925
  			strStaParams.ht_supported = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
1926
  		} else {
225201208   Leo Kim   staging: wilc1000...
1927
  			strStaParams.ht_supported = true;
0d073f69b   Leo Kim   staging: wilc1000...
1928
  			strStaParams.ht_capa_info = params->ht_capa->cap_info;
fba1f2d22   Leo Kim   staging: wilc1000...
1929
  			strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
5ebbf4f74   Leo Kim   staging: wilc1000...
1930
1931
1932
  			memcpy(strStaParams.ht_supp_mcs_set,
  			       &params->ht_capa->mcs,
  			       WILC_SUPP_MCS_SET_SIZE);
223741d71   Leo Kim   staging: wilc1000...
1933
  			strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
74fe73cf0   Leo Kim   staging: wilc1000...
1934
  			strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
a486baff7   Leo Kim   staging: wilc1000...
1935
  			strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
c5c77ba18   Johnny Kim   staging: wilc1000...
1936
  		}
f676e17a7   Leo Kim   staging: wilc1000...
1937
  		strStaParams.flags_mask = params->sta_flags_mask;
67ab64e44   Leo Kim   staging: wilc1000...
1938
  		strStaParams.flags_set = params->sta_flags_set;
c5c77ba18   Johnny Kim   staging: wilc1000...
1939

fbf5379bf   Glen Lee   staging: wilc1000...
1940
  		s32Error = wilc_add_station(vif, &strStaParams);
7dc1d0cc1   Leo Kim   staging: wilc1000...
1941
  		if (s32Error)
06fb9336a   Leo Kim   staging: wilc1000...
1942
1943
  			netdev_err(dev, "Host add station fail
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1944
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
1945
1946
  	return s32Error;
  }
a0a8be95c   Chaehyun Lim   staging: wilc1000...
1947
1948
  static int del_station(struct wiphy *wiphy, struct net_device *dev,
  		       struct station_del_parameters *params)
c5c77ba18   Johnny Kim   staging: wilc1000...
1949
  {
057d1e979   Arnd Bergmann   staging: wilc1000...
1950
  	const u8 *mac = params->mac;
e6e12661d   Leo Kim   staging: wilc1000...
1951
  	s32 s32Error = 0;
2726887c5   Chaehyun Lim   staging: wilc1000...
1952
  	struct wilc_priv *priv;
a4cac4810   Glen Lee   staging: wilc1000...
1953
  	struct wilc_vif *vif;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
1954

7ae433631   Leo Kim   staging: wilc1000...
1955
1956
  	if (!wiphy)
  		return -EFAULT;
c5c77ba18   Johnny Kim   staging: wilc1000...
1957
1958
  
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
1959
  	vif = netdev_priv(dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1960

a4cac4810   Glen Lee   staging: wilc1000...
1961
  	if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
a1b56a4c5   Chris Park   staging: wilc1000...
1962
  		if (!mac)
fbf5379bf   Glen Lee   staging: wilc1000...
1963
1964
  			s32Error = wilc_del_allstation(vif,
  				     priv->assoc_stainfo.au8Sta_AssociatedBss);
c5c77ba18   Johnny Kim   staging: wilc1000...
1965

fbf5379bf   Glen Lee   staging: wilc1000...
1966
  		s32Error = wilc_del_station(vif, mac);
c5c77ba18   Johnny Kim   staging: wilc1000...
1967

7dc1d0cc1   Leo Kim   staging: wilc1000...
1968
  		if (s32Error)
06fb9336a   Leo Kim   staging: wilc1000...
1969
1970
  			netdev_err(dev, "Host delete station fail
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
1971
1972
1973
  	}
  	return s32Error;
  }
14b420849   Chaehyun Lim   staging: wilc1000...
1974
1975
  static int change_station(struct wiphy *wiphy, struct net_device *dev,
  			  const u8 *mac, struct station_parameters *params)
c5c77ba18   Johnny Kim   staging: wilc1000...
1976
  {
e6e12661d   Leo Kim   staging: wilc1000...
1977
  	s32 s32Error = 0;
2726887c5   Chaehyun Lim   staging: wilc1000...
1978
  	struct wilc_priv *priv;
6a89ba9ce   Tony Cho   staging: wilc1000...
1979
  	struct add_sta_param strStaParams = { {0} };
a4cac4810   Glen Lee   staging: wilc1000...
1980
  	struct wilc_vif *vif;
c5c77ba18   Johnny Kim   staging: wilc1000...
1981

7ae433631   Leo Kim   staging: wilc1000...
1982
1983
  	if (!wiphy)
  		return -EFAULT;
c5c77ba18   Johnny Kim   staging: wilc1000...
1984
1985
  
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
1986
  	vif = netdev_priv(dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
1987

a4cac4810   Glen Lee   staging: wilc1000...
1988
  	if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2353c388d   Leo Kim   staging: wilc1000...
1989
  		memcpy(strStaParams.bssid, mac, ETH_ALEN);
4101eb8a0   Leo Kim   staging: wilc1000...
1990
  		strStaParams.aid = params->aid;
e734223cd   Leo Kim   staging: wilc1000...
1991
  		strStaParams.rates_len = params->supported_rates_len;
a622e0164   Leo Kim   staging: wilc1000...
1992
  		strStaParams.rates = params->supported_rates;
c5c77ba18   Johnny Kim   staging: wilc1000...
1993

369a1d3bd   Leo Kim   staging: wilc1000...
1994
  		if (!params->ht_capa) {
225201208   Leo Kim   staging: wilc1000...
1995
  			strStaParams.ht_supported = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
1996
  		} else {
225201208   Leo Kim   staging: wilc1000...
1997
  			strStaParams.ht_supported = true;
0d073f69b   Leo Kim   staging: wilc1000...
1998
  			strStaParams.ht_capa_info = params->ht_capa->cap_info;
fba1f2d22   Leo Kim   staging: wilc1000...
1999
  			strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
5ebbf4f74   Leo Kim   staging: wilc1000...
2000
2001
2002
  			memcpy(strStaParams.ht_supp_mcs_set,
  			       &params->ht_capa->mcs,
  			       WILC_SUPP_MCS_SET_SIZE);
223741d71   Leo Kim   staging: wilc1000...
2003
  			strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
74fe73cf0   Leo Kim   staging: wilc1000...
2004
  			strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
a486baff7   Leo Kim   staging: wilc1000...
2005
  			strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
c5c77ba18   Johnny Kim   staging: wilc1000...
2006
  		}
f676e17a7   Leo Kim   staging: wilc1000...
2007
  		strStaParams.flags_mask = params->sta_flags_mask;
67ab64e44   Leo Kim   staging: wilc1000...
2008
  		strStaParams.flags_set = params->sta_flags_set;
c5c77ba18   Johnny Kim   staging: wilc1000...
2009

fbf5379bf   Glen Lee   staging: wilc1000...
2010
  		s32Error = wilc_edit_station(vif, &strStaParams);
7dc1d0cc1   Leo Kim   staging: wilc1000...
2011
  		if (s32Error)
06fb9336a   Leo Kim   staging: wilc1000...
2012
2013
  			netdev_err(dev, "Host edit station fail
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
2014
2015
2016
  	}
  	return s32Error;
  }
37316e816   Chaehyun Lim   staging: wilc1000...
2017
2018
2019
2020
2021
2022
  static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
  					     const char *name,
  					     unsigned char name_assign_type,
  					     enum nl80211_iftype type,
  					     u32 *flags,
  					     struct vif_params *params)
c5c77ba18   Johnny Kim   staging: wilc1000...
2023
  {
a4cac4810   Glen Lee   staging: wilc1000...
2024
  	struct wilc_vif *vif;
2726887c5   Chaehyun Lim   staging: wilc1000...
2025
  	struct wilc_priv *priv;
c5c77ba18   Johnny Kim   staging: wilc1000...
2026
  	struct net_device *new_ifc = NULL;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
2027

c5c77ba18   Johnny Kim   staging: wilc1000...
2028
  	priv = wiphy_priv(wiphy);
a4cac4810   Glen Lee   staging: wilc1000...
2029
  	vif = netdev_priv(priv->wdev->netdev);
c5c77ba18   Johnny Kim   staging: wilc1000...
2030
2031
2032
  
  
  	if (type == NL80211_IFTYPE_MONITOR) {
1006b5c71   Glen Lee   staging: wilc1000...
2033
  		new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
369a1d3bd   Leo Kim   staging: wilc1000...
2034
  		if (new_ifc) {
a4cac4810   Glen Lee   staging: wilc1000...
2035
2036
  			vif = netdev_priv(priv->wdev->netdev);
  			vif->monitor_flag = 1;
06fb9336a   Leo Kim   staging: wilc1000...
2037
  		}
c5c77ba18   Johnny Kim   staging: wilc1000...
2038
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
2039
  	return priv->wdev;
c5c77ba18   Johnny Kim   staging: wilc1000...
2040
  }
956d72119   Chaehyun Lim   staging: wilc1000...
2041
  static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
c5c77ba18   Johnny Kim   staging: wilc1000...
2042
  {
e6e12661d   Leo Kim   staging: wilc1000...
2043
  	return 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
2044
  }
73584a40d   Glen Lee   staging: wilc1000...
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
  static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
  {
  	struct wilc_priv *priv = wiphy_priv(wiphy);
  	struct wilc_vif *vif = netdev_priv(priv->dev);
  
  	if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
  		vif->wilc->suspend_event = true;
  	else
  		vif->wilc->suspend_event = false;
  
  	return 0;
  }
  
  static int wilc_resume(struct wiphy *wiphy)
  {
  	struct wilc_priv *priv = wiphy_priv(wiphy);
  	struct wilc_vif *vif = netdev_priv(priv->dev);
  
  	netdev_info(vif->ndev, "cfg resume
  ");
  	return 0;
  }
  
  static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
  {
  	struct wilc_priv *priv = wiphy_priv(wiphy);
  	struct wilc_vif *vif = netdev_priv(priv->dev);
  
  	netdev_info(vif->ndev, "cfg set wake up = %d
  ", enabled);
  }
704187904   Glen Lee   staging: wilc1000...
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
  static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
  			enum nl80211_tx_power_setting type, int mbm)
  {
  	int ret;
  	s32 tx_power = MBM_TO_DBM(mbm);
  	struct wilc_priv *priv = wiphy_priv(wiphy);
  	struct wilc_vif *vif = netdev_priv(priv->dev);
  
  	if (tx_power < 0)
  		tx_power = 0;
  	else if (tx_power > 18)
  		tx_power = 18;
  	ret = wilc_set_tx_power(vif, tx_power);
  	if (ret)
  		netdev_err(vif->ndev, "Failed to set tx power
  ");
  
  	return ret;
  }
  
  static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
  			int *dbm)
  {
  	int ret;
  	struct wilc_priv *priv = wiphy_priv(wiphy);
  	struct wilc_vif *vif = netdev_priv(priv->dev);
8827bd88e   Leo Kim   staging: wilc1000...
2102
2103
2104
2105
2106
2107
2108
  	struct wilc *wl;
  
  	wl = vif->wilc;
  
  	/* If firmware is not started, return. */
  	if (!wl->initialized)
  		return -EIO;
704187904   Glen Lee   staging: wilc1000...
2109
2110
2111
2112
2113
2114
2115
2116
  
  	ret = wilc_get_tx_power(vif, (u8 *)dbm);
  	if (ret)
  		netdev_err(vif->ndev, "Failed to get tx power
  ");
  
  	return ret;
  }
1c40429df   Bhumika Goyal   Staging: wilc1000...
2117
  static const struct cfg80211_ops wilc_cfg80211_ops = {
80785a9a8   Chaehyun Lim   staging: wilc1000...
2118
  	.set_monitor_channel = set_channel,
0e30d06d9   Chaehyun Lim   staging: wilc1000...
2119
  	.scan = scan,
4ffbcdb6d   Chaehyun Lim   staging: wilc1000...
2120
  	.connect = connect,
b027cde95   Chaehyun Lim   staging: wilc1000...
2121
  	.disconnect = disconnect,
953d417a0   Chaehyun Lim   staging: wilc1000...
2122
  	.add_key = add_key,
3044ba7e6   Chaehyun Lim   staging: wilc1000...
2123
  	.del_key = del_key,
f4893dfc3   Chaehyun Lim   staging: wilc1000...
2124
  	.get_key = get_key,
0f5b8ca32   Chaehyun Lim   staging: wilc1000...
2125
  	.set_default_key = set_default_key,
69deb4c2a   Chaehyun Lim   staging: wilc1000...
2126
  	.add_virtual_intf = add_virtual_intf,
b4a733558   Chaehyun Lim   staging: wilc1000...
2127
  	.del_virtual_intf = del_virtual_intf,
3615e9a36   Chaehyun Lim   staging: wilc1000...
2128
  	.change_virtual_intf = change_virtual_intf,
c5c77ba18   Johnny Kim   staging: wilc1000...
2129

a13168d75   Chaehyun Lim   staging: wilc1000...
2130
  	.start_ap = start_ap,
2a4c84d7a   Chaehyun Lim   staging: wilc1000...
2131
  	.change_beacon = change_beacon,
c8cddd791   Chaehyun Lim   staging: wilc1000...
2132
  	.stop_ap = stop_ap,
ed26955ca   Chaehyun Lim   staging: wilc1000...
2133
  	.add_station = add_station,
a0a8be95c   Chaehyun Lim   staging: wilc1000...
2134
  	.del_station = del_station,
14b420849   Chaehyun Lim   staging: wilc1000...
2135
  	.change_station = change_station,
f06f562dd   Chaehyun Lim   staging: wilc1000...
2136
  	.get_station = get_station,
bdb6338f6   Chaehyun Lim   staging: wilc1000...
2137
  	.dump_station = dump_station,
a5f7db6aa   Chaehyun Lim   staging: wilc1000...
2138
  	.change_bss = change_bss,
a76b63ef5   Chaehyun Lim   staging: wilc1000...
2139
  	.set_wiphy_params = set_wiphy_params,
c5c77ba18   Johnny Kim   staging: wilc1000...
2140

4d46657a2   Chaehyun Lim   staging: wilc1000...
2141
  	.set_pmksa = set_pmksa,
1ff86d960   Chaehyun Lim   staging: wilc1000...
2142
  	.del_pmksa = del_pmksa,
b33c39b1f   Chaehyun Lim   staging: wilc1000...
2143
  	.flush_pmksa = flush_pmksa,
6d19d695e   Chaehyun Lim   staging: wilc1000...
2144
  	.remain_on_channel = remain_on_channel,
1dd5440b6   Chaehyun Lim   staging: wilc1000...
2145
  	.cancel_remain_on_channel = cancel_remain_on_channel,
4a2f9b38a   Chaehyun Lim   staging: wilc1000...
2146
  	.mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
12a26a33f   Chaehyun Lim   staging: wilc1000...
2147
  	.mgmt_tx = mgmt_tx,
8e0735c5e   Chaehyun Lim   staging: wilc1000...
2148
  	.mgmt_frame_register = wilc_mgmt_frame_register,
465306795   Chaehyun Lim   staging: wilc1000...
2149
  	.set_power_mgmt = set_power_mgmt,
a8047e26c   Chaehyun Lim   staging: wilc1000...
2150
  	.set_cqm_rssi_config = set_cqm_rssi_config,
c5c77ba18   Johnny Kim   staging: wilc1000...
2151

73584a40d   Glen Lee   staging: wilc1000...
2152
2153
2154
  	.suspend = wilc_suspend,
  	.resume = wilc_resume,
  	.set_wakeup = wilc_set_wakeup,
704187904   Glen Lee   staging: wilc1000...
2155
2156
  	.set_tx_power = set_tx_power,
  	.get_tx_power = get_tx_power,
73584a40d   Glen Lee   staging: wilc1000...
2157

c5c77ba18   Johnny Kim   staging: wilc1000...
2158
  };
1608c4034   Arnd Bergmann   staging/wilc1000:...
2159
  static struct wireless_dev *WILC_WFI_CfgAlloc(void)
c5c77ba18   Johnny Kim   staging: wilc1000...
2160
  {
c5c77ba18   Johnny Kim   staging: wilc1000...
2161
  	struct wireless_dev *wdev;
c5c77ba18   Johnny Kim   staging: wilc1000...
2162
  	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
06fb9336a   Leo Kim   staging: wilc1000...
2163
  	if (!wdev)
c5c77ba18   Johnny Kim   staging: wilc1000...
2164
  		goto _fail_;
c5c77ba18   Johnny Kim   staging: wilc1000...
2165

2726887c5   Chaehyun Lim   staging: wilc1000...
2166
  	wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
06fb9336a   Leo Kim   staging: wilc1000...
2167
  	if (!wdev->wiphy)
c5c77ba18   Johnny Kim   staging: wilc1000...
2168
  		goto _fail_mem_;
c5c77ba18   Johnny Kim   staging: wilc1000...
2169

c5c77ba18   Johnny Kim   staging: wilc1000...
2170
2171
2172
2173
2174
  	WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
  	WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
  	WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
  	WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
  	WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
c5c77ba18   Johnny Kim   staging: wilc1000...
2175

57fbcce37   Johannes Berg   cfg80211: remove ...
2176
  	wdev->wiphy->bands[NL80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
c5c77ba18   Johnny Kim   staging: wilc1000...
2177
2178
2179
2180
2181
2182
2183
  
  	return wdev;
  
  _fail_mem_:
  	kfree(wdev);
  _fail_:
  	return NULL;
c5c77ba18   Johnny Kim   staging: wilc1000...
2184
  }
a89f7c551   Leo Kim   staging: wilc1000...
2185

2e7d5377f   Arnd Bergmann   staging/wilc1000:...
2186
  struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
c5c77ba18   Johnny Kim   staging: wilc1000...
2187
  {
2726887c5   Chaehyun Lim   staging: wilc1000...
2188
  	struct wilc_priv *priv;
c5c77ba18   Johnny Kim   staging: wilc1000...
2189
  	struct wireless_dev *wdev;
e6e12661d   Leo Kim   staging: wilc1000...
2190
  	s32 s32Error = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
2191

c5c77ba18   Johnny Kim   staging: wilc1000...
2192
  	wdev = WILC_WFI_CfgAlloc();
369a1d3bd   Leo Kim   staging: wilc1000...
2193
  	if (!wdev) {
06fb9336a   Leo Kim   staging: wilc1000...
2194
2195
  		netdev_err(net, "wiphy new allocate failed
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
2196
2197
  		return NULL;
  	}
c5c77ba18   Johnny Kim   staging: wilc1000...
2198
  	priv = wdev_priv(wdev);
c5c77ba18   Johnny Kim   staging: wilc1000...
2199
  	priv->wdev = wdev;
c5c77ba18   Johnny Kim   staging: wilc1000...
2200
  	wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
abb4f8add   Sudip Mukherjee   staging: wilc1000...
2201
  #ifdef CONFIG_PM
73584a40d   Glen Lee   staging: wilc1000...
2202
  	wdev->wiphy->wowlan = &wowlan_support;
abb4f8add   Sudip Mukherjee   staging: wilc1000...
2203
  #endif
c5c77ba18   Johnny Kim   staging: wilc1000...
2204
  	wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
c5c77ba18   Johnny Kim   staging: wilc1000...
2205
  	wdev->wiphy->max_scan_ie_len = 1000;
c5c77ba18   Johnny Kim   staging: wilc1000...
2206
  	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
c5c77ba18   Johnny Kim   staging: wilc1000...
2207
2208
  	wdev->wiphy->cipher_suites = cipher_suites;
  	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
c5c77ba18   Johnny Kim   staging: wilc1000...
2209
  	wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
c5c77ba18   Johnny Kim   staging: wilc1000...
2210

c5c77ba18   Johnny Kim   staging: wilc1000...
2211
  	wdev->wiphy->max_remain_on_channel_duration = 500;
c5c77ba18   Johnny Kim   staging: wilc1000...
2212
2213
  	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
  		BIT(NL80211_IFTYPE_P2P_CLIENT);
c5c77ba18   Johnny Kim   staging: wilc1000...
2214
  	wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
c5c77ba18   Johnny Kim   staging: wilc1000...
2215
  	wdev->iftype = NL80211_IFTYPE_STATION;
2e7d5377f   Arnd Bergmann   staging/wilc1000:...
2216
  	set_wiphy_dev(wdev->wiphy, dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
2217

c5c77ba18   Johnny Kim   staging: wilc1000...
2218
  	s32Error = wiphy_register(wdev->wiphy);
06fb9336a   Leo Kim   staging: wilc1000...
2219
2220
2221
  	if (s32Error)
  		netdev_err(net, "Cannot register wiphy device
  ");
c5c77ba18   Johnny Kim   staging: wilc1000...
2222

c5c77ba18   Johnny Kim   staging: wilc1000...
2223
  	priv->dev = net;
c5c77ba18   Johnny Kim   staging: wilc1000...
2224
  	return wdev;
c5c77ba18   Johnny Kim   staging: wilc1000...
2225
  }
a89f7c551   Leo Kim   staging: wilc1000...
2226

dd4b6a832   Chaehyun Lim   staging: wilc1000...
2227
  int wilc_init_host_int(struct net_device *net)
c5c77ba18   Johnny Kim   staging: wilc1000...
2228
  {
1a8ccd858   Chaehyun Lim   staging: wilc1000...
2229
  	int s32Error = 0;
c5c77ba18   Johnny Kim   staging: wilc1000...
2230

2726887c5   Chaehyun Lim   staging: wilc1000...
2231
  	struct wilc_priv *priv;
c5c77ba18   Johnny Kim   staging: wilc1000...
2232

c5c77ba18   Johnny Kim   staging: wilc1000...
2233
2234
  	priv = wdev_priv(net->ieee80211_ptr);
  	if (op_ifcs == 0) {
93dee8eea   Greg Kroah-Hartman   staging: wilc1000...
2235
  		setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
2236
  		setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
c5c77ba18   Johnny Kim   staging: wilc1000...
2237
2238
  	}
  	op_ifcs++;
c5c77ba18   Johnny Kim   staging: wilc1000...
2239

72ed4dc73   Dean Lee   staging: wilc1000...
2240
  	priv->gbAutoRateAdjusted = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
2241

72ed4dc73   Dean Lee   staging: wilc1000...
2242
  	priv->bInP2PlistenState = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
2243

086620978   Chaehyun Lim   staging: wilc1000...
2244
  	mutex_init(&priv->scan_req_lock);
48b28df99   Leo Kim   staging: wilc1000...
2245
  	s32Error = wilc_init(net, &priv->hif_drv);
f1fe9c435   Chaehyun Lim   staging: wilc1000...
2246
  	if (s32Error)
06fb9336a   Leo Kim   staging: wilc1000...
2247
2248
  		netdev_err(net, "Error while initializing hostinterface
  ");
f1fe9c435   Chaehyun Lim   staging: wilc1000...
2249

c5c77ba18   Johnny Kim   staging: wilc1000...
2250
2251
  	return s32Error;
  }
a9a168234   Chaehyun Lim   staging: wilc1000...
2252
  int wilc_deinit_host_int(struct net_device *net)
c5c77ba18   Johnny Kim   staging: wilc1000...
2253
  {
1a8ccd858   Chaehyun Lim   staging: wilc1000...
2254
  	int s32Error = 0;
cf60106bf   Glen Lee   staging: wilc1000...
2255
  	struct wilc_vif *vif;
2726887c5   Chaehyun Lim   staging: wilc1000...
2256
  	struct wilc_priv *priv;
8dfaafd63   Chaehyun Lim   staging: wilc1000...
2257

c5c77ba18   Johnny Kim   staging: wilc1000...
2258
  	priv = wdev_priv(net->ieee80211_ptr);
cf60106bf   Glen Lee   staging: wilc1000...
2259
  	vif = netdev_priv(priv->dev);
c5c77ba18   Johnny Kim   staging: wilc1000...
2260

72ed4dc73   Dean Lee   staging: wilc1000...
2261
  	priv->gbAutoRateAdjusted = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
2262

72ed4dc73   Dean Lee   staging: wilc1000...
2263
  	priv->bInP2PlistenState = false;
c5c77ba18   Johnny Kim   staging: wilc1000...
2264
2265
  
  	op_ifcs--;
fbf5379bf   Glen Lee   staging: wilc1000...
2266
  	s32Error = wilc_deinit(vif);
c5c77ba18   Johnny Kim   staging: wilc1000...
2267

d14991afe   Leo Kim   staging: wilc1000...
2268
  	clear_shadow_scan();
368949a7c   Chris Park   staging: wilc1000...
2269
  	if (op_ifcs == 0)
0e1af73dd   Arnd Bergmann   staging/wilc1000:...
2270
  		del_timer_sync(&wilc_during_ip_timer);
c5c77ba18   Johnny Kim   staging: wilc1000...
2271

f1fe9c435   Chaehyun Lim   staging: wilc1000...
2272
  	if (s32Error)
06fb9336a   Leo Kim   staging: wilc1000...
2273
2274
  		netdev_err(net, "Error while deintializing host interface
  ");
f1fe9c435   Chaehyun Lim   staging: wilc1000...
2275

c5c77ba18   Johnny Kim   staging: wilc1000...
2276
2277
  	return s32Error;
  }
96da20a9a   Chaehyun Lim   staging: wilc1000...
2278
  void wilc_free_wiphy(struct net_device *net)
c5c77ba18   Johnny Kim   staging: wilc1000...
2279
  {
d9766d52d   Chris Park   staging: wilc1000...
2280
  	if (!net)
c5c77ba18   Johnny Kim   staging: wilc1000...
2281
  		return;
c5c77ba18   Johnny Kim   staging: wilc1000...
2282

d9766d52d   Chris Park   staging: wilc1000...
2283
  	if (!net->ieee80211_ptr)
c5c77ba18   Johnny Kim   staging: wilc1000...
2284
  		return;
c5c77ba18   Johnny Kim   staging: wilc1000...
2285

d9766d52d   Chris Park   staging: wilc1000...
2286
  	if (!net->ieee80211_ptr->wiphy)
c5c77ba18   Johnny Kim   staging: wilc1000...
2287
  		return;
c5c77ba18   Johnny Kim   staging: wilc1000...
2288
2289
  
  	wiphy_unregister(net->ieee80211_ptr->wiphy);
c5c77ba18   Johnny Kim   staging: wilc1000...
2290
2291
  	wiphy_free(net->ieee80211_ptr->wiphy);
  	kfree(net->ieee80211_ptr);
c5c77ba18   Johnny Kim   staging: wilc1000...
2292
  }