839af1f1326aed601530e20f0adf1c395cac4bab
[deliverable/linux.git] / drivers / staging / wilc1000 / wilc_wfi_cfgoperations.c
1 #include "wilc_wfi_cfgoperations.h"
2 #include "host_interface.h"
3 #include <linux/errno.h>
4
5 #define NO_ENCRYPT 0
6 #define ENCRYPT_ENABLED BIT(0)
7 #define WEP BIT(1)
8 #define WEP_EXTENDED BIT(2)
9 #define WPA BIT(3)
10 #define WPA2 BIT(4)
11 #define AES BIT(5)
12 #define TKIP BIT(6)
13
14 #define FRAME_TYPE_ID 0
15 #define ACTION_CAT_ID 24
16 #define ACTION_SUBTYPE_ID 25
17 #define P2P_PUB_ACTION_SUBTYPE 30
18
19 #define ACTION_FRAME 0xd0
20 #define GO_INTENT_ATTR_ID 0x04
21 #define CHANLIST_ATTR_ID 0x0b
22 #define OPERCHAN_ATTR_ID 0x11
23 #define PUB_ACTION_ATTR_ID 0x04
24 #define P2PELEM_ATTR_ID 0xdd
25
26 #define GO_NEG_REQ 0x00
27 #define GO_NEG_RSP 0x01
28 #define GO_NEG_CONF 0x02
29 #define P2P_INV_REQ 0x03
30 #define P2P_INV_RSP 0x04
31 #define PUBLIC_ACT_VENDORSPEC 0x09
32 #define GAS_INTIAL_REQ 0x0a
33 #define GAS_INTIAL_RSP 0x0b
34
35 #define INVALID_CHANNEL 0
36
37 #define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
38 #define SCAN_RESULT_EXPIRE (40 * HZ)
39
40 static const u32 cipher_suites[] = {
41 WLAN_CIPHER_SUITE_WEP40,
42 WLAN_CIPHER_SUITE_WEP104,
43 WLAN_CIPHER_SUITE_TKIP,
44 WLAN_CIPHER_SUITE_CCMP,
45 WLAN_CIPHER_SUITE_AES_CMAC,
46 };
47
48 static const struct ieee80211_txrx_stypes
49 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
50 [NL80211_IFTYPE_STATION] = {
51 .tx = 0xffff,
52 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
53 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
54 },
55 [NL80211_IFTYPE_AP] = {
56 .tx = 0xffff,
57 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
58 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
59 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
60 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
61 BIT(IEEE80211_STYPE_AUTH >> 4) |
62 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
63 BIT(IEEE80211_STYPE_ACTION >> 4)
64 },
65 [NL80211_IFTYPE_P2P_CLIENT] = {
66 .tx = 0xffff,
67 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
68 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
69 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
70 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
71 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
72 BIT(IEEE80211_STYPE_AUTH >> 4) |
73 BIT(IEEE80211_STYPE_DEAUTH >> 4)
74 }
75 };
76
77 static const struct wiphy_wowlan_support wowlan_support = {
78 .flags = WIPHY_WOWLAN_ANY
79 };
80
81 #define WILC_WFI_DWELL_PASSIVE 100
82 #define WILC_WFI_DWELL_ACTIVE 40
83
84 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
85 #define DEFAULT_LINK_SPEED 72
86
87
88 #define IS_MANAGMEMENT 0x100
89 #define IS_MANAGMEMENT_CALLBACK 0x080
90 #define IS_MGMT_STATUS_SUCCES 0x040
91 #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
92
93 extern int wilc_mac_open(struct net_device *ndev);
94 extern int wilc_mac_close(struct net_device *ndev);
95
96 static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
97 static u32 last_scanned_cnt;
98 struct timer_list wilc_during_ip_timer;
99 static struct timer_list hAgingTimer;
100 static u8 op_ifcs;
101
102 u8 wilc_initialized = 1;
103
104 #define CHAN2G(_channel, _freq, _flags) { \
105 .band = IEEE80211_BAND_2GHZ, \
106 .center_freq = (_freq), \
107 .hw_value = (_channel), \
108 .flags = (_flags), \
109 .max_antenna_gain = 0, \
110 .max_power = 30, \
111 }
112
113 static struct ieee80211_channel ieee80211_2ghz_channels[] = {
114 CHAN2G(1, 2412, 0),
115 CHAN2G(2, 2417, 0),
116 CHAN2G(3, 2422, 0),
117 CHAN2G(4, 2427, 0),
118 CHAN2G(5, 2432, 0),
119 CHAN2G(6, 2437, 0),
120 CHAN2G(7, 2442, 0),
121 CHAN2G(8, 2447, 0),
122 CHAN2G(9, 2452, 0),
123 CHAN2G(10, 2457, 0),
124 CHAN2G(11, 2462, 0),
125 CHAN2G(12, 2467, 0),
126 CHAN2G(13, 2472, 0),
127 CHAN2G(14, 2484, 0),
128 };
129
130 #define RATETAB_ENT(_rate, _hw_value, _flags) { \
131 .bitrate = (_rate), \
132 .hw_value = (_hw_value), \
133 .flags = (_flags), \
134 }
135
136 static struct ieee80211_rate ieee80211_bitrates[] = {
137 RATETAB_ENT(10, 0, 0),
138 RATETAB_ENT(20, 1, 0),
139 RATETAB_ENT(55, 2, 0),
140 RATETAB_ENT(110, 3, 0),
141 RATETAB_ENT(60, 9, 0),
142 RATETAB_ENT(90, 6, 0),
143 RATETAB_ENT(120, 7, 0),
144 RATETAB_ENT(180, 8, 0),
145 RATETAB_ENT(240, 9, 0),
146 RATETAB_ENT(360, 10, 0),
147 RATETAB_ENT(480, 11, 0),
148 RATETAB_ENT(540, 12, 0),
149 };
150
151 struct p2p_mgmt_data {
152 int size;
153 u8 *buff;
154 };
155
156 static u8 wlan_channel = INVALID_CHANNEL;
157 static u8 curr_channel;
158 static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
159 static u8 p2p_local_random = 0x01;
160 static u8 p2p_recv_random;
161 static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
162 static bool wilc_ie;
163
164 static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
165 .channels = ieee80211_2ghz_channels,
166 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
167 .bitrates = ieee80211_bitrates,
168 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
169 };
170
171
172 struct add_key_params {
173 u8 key_idx;
174 bool pairwise;
175 u8 *mac_addr;
176 };
177 static struct add_key_params g_add_gtk_key_params;
178 static struct wilc_wfi_key g_key_gtk_params;
179 static struct add_key_params g_add_ptk_key_params;
180 static struct wilc_wfi_key g_key_ptk_params;
181 static struct wilc_wfi_wep_key g_key_wep_params;
182 static bool g_ptk_keys_saved;
183 static bool g_gtk_keys_saved;
184 static bool g_wep_keys_saved;
185
186 #define AGING_TIME (9 * 1000)
187 #define during_ip_time 15000
188
189 static void clear_shadow_scan(void)
190 {
191 int i;
192
193 if (op_ifcs == 0) {
194 del_timer_sync(&hAgingTimer);
195
196 for (i = 0; i < last_scanned_cnt; i++) {
197 if (last_scanned_shadow[last_scanned_cnt].ies) {
198 kfree(last_scanned_shadow[i].ies);
199 last_scanned_shadow[last_scanned_cnt].ies = NULL;
200 }
201
202 kfree(last_scanned_shadow[i].join_params);
203 last_scanned_shadow[i].join_params = NULL;
204 }
205 last_scanned_cnt = 0;
206 }
207 }
208
209 static u32 get_rssi_avg(struct network_info *network_info)
210 {
211 u8 i;
212 int rssi_v = 0;
213 u8 num_rssi = (network_info->str_rssi.u8Full) ?
214 NUM_RSSI : (network_info->str_rssi.u8Index);
215
216 for (i = 0; i < num_rssi; i++)
217 rssi_v += network_info->str_rssi.as8RSSI[i];
218
219 rssi_v /= num_rssi;
220 return rssi_v;
221 }
222
223 static void refresh_scan(void *user_void, u8 all, bool direct_scan)
224 {
225 struct wilc_priv *priv;
226 struct wiphy *wiphy;
227 struct cfg80211_bss *bss = NULL;
228 int i;
229 int rssi = 0;
230
231 priv = user_void;
232 wiphy = priv->dev->ieee80211_ptr->wiphy;
233
234 for (i = 0; i < last_scanned_cnt; i++) {
235 struct network_info *network_info;
236
237 network_info = &last_scanned_shadow[i];
238
239 if (!network_info->found || all) {
240 s32 freq;
241 struct ieee80211_channel *channel;
242
243 if (network_info) {
244 freq = ieee80211_channel_to_frequency((s32)network_info->ch, IEEE80211_BAND_2GHZ);
245 channel = ieee80211_get_channel(wiphy, freq);
246
247 rssi = get_rssi_avg(network_info);
248 if (memcmp("DIRECT-", network_info->ssid, 7) ||
249 direct_scan) {
250 bss = cfg80211_inform_bss(wiphy,
251 channel,
252 CFG80211_BSS_FTYPE_UNKNOWN,
253 network_info->bssid,
254 network_info->tsf_hi,
255 network_info->cap_info,
256 network_info->beacon_period,
257 (const u8 *)network_info->ies,
258 (size_t)network_info->ies_len,
259 (s32)rssi * 100,
260 GFP_KERNEL);
261 cfg80211_put_bss(wiphy, bss);
262 }
263 }
264 }
265 }
266 }
267
268 static void reset_shadow_found(void)
269 {
270 int i;
271
272 for (i = 0; i < last_scanned_cnt; i++)
273 last_scanned_shadow[i].found = 0;
274 }
275
276 static void update_scan_time(void)
277 {
278 int i;
279
280 for (i = 0; i < last_scanned_cnt; i++)
281 last_scanned_shadow[i].time_scan = jiffies;
282 }
283
284 static void remove_network_from_shadow(unsigned long arg)
285 {
286 unsigned long now = jiffies;
287 int i, j;
288
289
290 for (i = 0; i < last_scanned_cnt; i++) {
291 if (time_after(now, last_scanned_shadow[i].time_scan +
292 (unsigned long)(SCAN_RESULT_EXPIRE))) {
293 PRINT_D(CFG80211_DBG, "Network expired ScanShadow:%s\n",
294 last_scanned_shadow[i].ssid);
295
296 kfree(last_scanned_shadow[i].ies);
297 last_scanned_shadow[i].ies = NULL;
298
299 kfree(last_scanned_shadow[i].join_params);
300
301 for (j = i; (j < last_scanned_cnt - 1); j++)
302 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
303
304 last_scanned_cnt--;
305 }
306 }
307
308 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
309 last_scanned_cnt);
310 if (last_scanned_cnt != 0) {
311 hAgingTimer.data = arg;
312 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
313 } else {
314 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
315 }
316 }
317
318 static void clear_duringIP(unsigned long arg)
319 {
320 wilc_optaining_ip = false;
321 }
322
323 static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
324 void *user_void)
325 {
326 int state = -1;
327 int i;
328
329 if (last_scanned_cnt == 0) {
330 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
331 hAgingTimer.data = (unsigned long)user_void;
332 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
333 state = -1;
334 } else {
335 for (i = 0; i < last_scanned_cnt; i++) {
336 if (memcmp(last_scanned_shadow[i].bssid,
337 pstrNetworkInfo->bssid, 6) == 0) {
338 state = i;
339 break;
340 }
341 }
342 }
343 return state;
344 }
345
346 static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
347 void *user_void, void *pJoinParams)
348 {
349 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
350 u32 ap_index = 0;
351 u8 rssi_index = 0;
352
353 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
354 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
355 return;
356 }
357 if (ap_found == -1) {
358 ap_index = last_scanned_cnt;
359 last_scanned_cnt++;
360 } else {
361 ap_index = ap_found;
362 }
363 rssi_index = last_scanned_shadow[ap_index].str_rssi.u8Index;
364 last_scanned_shadow[ap_index].str_rssi.as8RSSI[rssi_index++] = pstrNetworkInfo->rssi;
365 if (rssi_index == NUM_RSSI) {
366 rssi_index = 0;
367 last_scanned_shadow[ap_index].str_rssi.u8Full = 1;
368 }
369 last_scanned_shadow[ap_index].str_rssi.u8Index = rssi_index;
370 last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
371 last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
372 last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
373 memcpy(last_scanned_shadow[ap_index].ssid,
374 pstrNetworkInfo->ssid, pstrNetworkInfo->ssid_len);
375 memcpy(last_scanned_shadow[ap_index].bssid,
376 pstrNetworkInfo->bssid, ETH_ALEN);
377 last_scanned_shadow[ap_index].beacon_period = pstrNetworkInfo->beacon_period;
378 last_scanned_shadow[ap_index].dtim_period = pstrNetworkInfo->dtim_period;
379 last_scanned_shadow[ap_index].ch = pstrNetworkInfo->ch;
380 last_scanned_shadow[ap_index].ies_len = pstrNetworkInfo->ies_len;
381 last_scanned_shadow[ap_index].tsf_hi = pstrNetworkInfo->tsf_hi;
382 if (ap_found != -1)
383 kfree(last_scanned_shadow[ap_index].ies);
384 last_scanned_shadow[ap_index].ies = kmalloc(pstrNetworkInfo->ies_len,
385 GFP_KERNEL);
386 memcpy(last_scanned_shadow[ap_index].ies,
387 pstrNetworkInfo->ies, pstrNetworkInfo->ies_len);
388 last_scanned_shadow[ap_index].time_scan = jiffies;
389 last_scanned_shadow[ap_index].time_scan_cached = jiffies;
390 last_scanned_shadow[ap_index].found = 1;
391 if (ap_found != -1)
392 kfree(last_scanned_shadow[ap_index].join_params);
393 last_scanned_shadow[ap_index].join_params = pJoinParams;
394 }
395
396 static void CfgScanResult(enum scan_event scan_event,
397 struct network_info *network_info,
398 void *user_void,
399 void *join_params)
400 {
401 struct wilc_priv *priv;
402 struct wiphy *wiphy;
403 s32 s32Freq;
404 struct ieee80211_channel *channel;
405 struct cfg80211_bss *bss = NULL;
406
407 priv = user_void;
408 if (priv->bCfgScanning) {
409 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
410 wiphy = priv->dev->ieee80211_ptr->wiphy;
411
412 if (!wiphy)
413 return;
414
415 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
416 (((s32)network_info->rssi * 100) < 0 ||
417 ((s32)network_info->rssi * 100) > 100))
418 return;
419
420 if (network_info) {
421 s32Freq = ieee80211_channel_to_frequency((s32)network_info->ch, IEEE80211_BAND_2GHZ);
422 channel = ieee80211_get_channel(wiphy, s32Freq);
423
424 if (!channel)
425 return;
426
427 PRINT_INFO(CFG80211_DBG, "Network Info::"
428 "CHANNEL Frequency: %d,"
429 "RSSI: %d,"
430 "Capability Info: %d,"
431 "Beacon Period: %d\n",
432 channel->center_freq,
433 (s32)network_info->rssi * 100,
434 network_info->cap_info,
435 network_info->beacon_period);
436
437 if (network_info->new_network) {
438 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
439 PRINT_D(CFG80211_DBG,
440 "Network %s found\n",
441 network_info->ssid);
442 priv->u32RcvdChCount++;
443
444 add_network_to_shadow(network_info, priv, join_params);
445
446 if (!(memcmp("DIRECT-", network_info->ssid, 7))) {
447 bss = cfg80211_inform_bss(wiphy,
448 channel,
449 CFG80211_BSS_FTYPE_UNKNOWN,
450 network_info->bssid,
451 network_info->tsf_hi,
452 network_info->cap_info,
453 network_info->beacon_period,
454 (const u8 *)network_info->ies,
455 (size_t)network_info->ies_len,
456 (s32)network_info->rssi * 100,
457 GFP_KERNEL);
458 cfg80211_put_bss(wiphy, bss);
459 }
460 }
461 } else {
462 u32 i;
463
464 for (i = 0; i < priv->u32RcvdChCount; i++) {
465 if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) {
466 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].ssid);
467
468 last_scanned_shadow[i].rssi = network_info->rssi;
469 last_scanned_shadow[i].time_scan = jiffies;
470 break;
471 }
472 }
473 }
474 }
475 } else if (scan_event == SCAN_EVENT_DONE) {
476 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
477 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
478 refresh_scan(priv, 1, false);
479
480 if (priv->u32RcvdChCount > 0)
481 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
482 else
483 PRINT_D(CFG80211_DBG, "No networks found\n");
484
485 down(&(priv->hSemScanReq));
486
487 if (priv->pstrScanReq) {
488 cfg80211_scan_done(priv->pstrScanReq, false);
489 priv->u32RcvdChCount = 0;
490 priv->bCfgScanning = false;
491 priv->pstrScanReq = NULL;
492 }
493 up(&(priv->hSemScanReq));
494 } else if (scan_event == SCAN_EVENT_ABORTED) {
495 down(&(priv->hSemScanReq));
496
497 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
498 if (priv->pstrScanReq) {
499 update_scan_time();
500 refresh_scan(priv, 1, false);
501
502 cfg80211_scan_done(priv->pstrScanReq, false);
503 priv->bCfgScanning = false;
504 priv->pstrScanReq = NULL;
505 }
506 up(&(priv->hSemScanReq));
507 }
508 }
509 }
510
511 int wilc_connecting;
512
513 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
514 tstrConnectInfo *pstrConnectInfo,
515 u8 u8MacStatus,
516 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
517 void *pUserVoid)
518 {
519 struct wilc_priv *priv;
520 struct net_device *dev;
521 struct host_if_drv *pstrWFIDrv;
522 u8 NullBssid[ETH_ALEN] = {0};
523 struct wilc *wl;
524 struct wilc_vif *vif;
525
526 wilc_connecting = 0;
527
528 priv = pUserVoid;
529 dev = priv->dev;
530 vif = netdev_priv(dev);
531 wl = vif->wilc;
532 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
533
534 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
535 u16 u16ConnectStatus;
536
537 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
538
539 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
540
541 if ((u8MacStatus == MAC_DISCONNECTED) &&
542 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
543 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
544 wilc_wlan_set_bssid(priv->dev, NullBssid,
545 STATION_MODE);
546 eth_zero_addr(wilc_connected_ssid);
547
548 if (!pstrWFIDrv->p2p_connect)
549 wlan_channel = INVALID_CHANNEL;
550
551 netdev_err(dev, "Unspecified failure\n");
552 }
553
554 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
555 bool bNeedScanRefresh = false;
556 u32 i;
557
558 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
559 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
560 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
561
562
563 for (i = 0; i < last_scanned_cnt; i++) {
564 if (memcmp(last_scanned_shadow[i].bssid,
565 pstrConnectInfo->au8bssid,
566 ETH_ALEN) == 0) {
567 unsigned long now = jiffies;
568
569 if (time_after(now,
570 last_scanned_shadow[i].time_scan_cached +
571 (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
572 bNeedScanRefresh = true;
573
574 break;
575 }
576 }
577
578 if (bNeedScanRefresh)
579 refresh_scan(priv, 1, true);
580 }
581
582
583 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
584
585 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
586
587 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
588 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
589 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
590 u16ConnectStatus, GFP_KERNEL);
591 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
592 wilc_optaining_ip = false;
593 p2p_local_random = 0x01;
594 p2p_recv_random = 0x00;
595 wilc_ie = false;
596 eth_zero_addr(priv->au8AssociatedBss);
597 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
598 eth_zero_addr(wilc_connected_ssid);
599
600 if (!pstrWFIDrv->p2p_connect)
601 wlan_channel = INVALID_CHANNEL;
602 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
603 pstrDisconnectNotifInfo->u16reason = 3;
604 } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
605 pstrDisconnectNotifInfo->u16reason = 1;
606 }
607 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
608 pstrDisconnectNotifInfo->ie_len, false,
609 GFP_KERNEL);
610 }
611 }
612
613 static int set_channel(struct wiphy *wiphy,
614 struct cfg80211_chan_def *chandef)
615 {
616 u32 channelnum = 0;
617 struct wilc_priv *priv;
618 int result = 0;
619 struct wilc_vif *vif;
620
621 priv = wiphy_priv(wiphy);
622 vif = netdev_priv(priv->dev);
623
624 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
625 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
626
627 curr_channel = channelnum;
628 result = wilc_set_mac_chnl_num(vif, channelnum);
629
630 if (result != 0)
631 netdev_err(priv->dev, "Error in setting channel\n");
632
633 return result;
634 }
635
636 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
637 {
638 struct wilc_priv *priv;
639 u32 i;
640 s32 s32Error = 0;
641 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
642 struct hidden_network strHiddenNetwork;
643 struct wilc_vif *vif;
644
645 priv = wiphy_priv(wiphy);
646 vif = netdev_priv(priv->dev);
647
648 priv->pstrScanReq = request;
649
650 priv->u32RcvdChCount = 0;
651
652 reset_shadow_found();
653
654 priv->bCfgScanning = true;
655 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
656 for (i = 0; i < request->n_channels; i++) {
657 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
658 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
659 }
660
661 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
662 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
663
664 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
665
666 if (request->n_ssids >= 1) {
667 strHiddenNetwork.net_info =
668 kmalloc_array(request->n_ssids,
669 sizeof(struct hidden_network),
670 GFP_KERNEL);
671 strHiddenNetwork.n_ssids = request->n_ssids;
672
673
674 for (i = 0; i < request->n_ssids; i++) {
675 if (request->ssids[i].ssid &&
676 request->ssids[i].ssid_len != 0) {
677 strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
678 memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
679 strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
680 } else {
681 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
682 strHiddenNetwork.n_ssids -= 1;
683 }
684 }
685 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
686 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
687 au8ScanChanList,
688 request->n_channels,
689 (const u8 *)request->ie,
690 request->ie_len, CfgScanResult,
691 (void *)priv, &strHiddenNetwork);
692 } else {
693 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
694 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
695 au8ScanChanList,
696 request->n_channels,
697 (const u8 *)request->ie,
698 request->ie_len, CfgScanResult,
699 (void *)priv, NULL);
700 }
701 } else {
702 netdev_err(priv->dev, "Requested scanned channels over\n");
703 }
704
705 if (s32Error != 0) {
706 s32Error = -EBUSY;
707 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
708 }
709
710 return s32Error;
711 }
712
713 static int connect(struct wiphy *wiphy, struct net_device *dev,
714 struct cfg80211_connect_params *sme)
715 {
716 s32 s32Error = 0;
717 u32 i;
718 u8 u8security = NO_ENCRYPT;
719 enum AUTHTYPE tenuAuth_type = ANY;
720 char *pcgroup_encrypt_val = NULL;
721 char *pccipher_group = NULL;
722 char *pcwpa_version = NULL;
723
724 struct wilc_priv *priv;
725 struct host_if_drv *pstrWFIDrv;
726 struct network_info *pstrNetworkInfo = NULL;
727 struct wilc_vif *vif;
728
729 wilc_connecting = 1;
730 priv = wiphy_priv(wiphy);
731 vif = netdev_priv(priv->dev);
732 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
733
734 PRINT_D(CFG80211_DBG,
735 "Connecting to SSID [%s] on netdev [%p] host if [%p]\n",
736 sme->ssid, dev, priv->hif_drv);
737 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
738 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
739 pstrWFIDrv->p2p_connect = 1;
740 } else {
741 pstrWFIDrv->p2p_connect = 0;
742 }
743 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
744
745 for (i = 0; i < last_scanned_cnt; i++) {
746 if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
747 memcmp(last_scanned_shadow[i].ssid,
748 sme->ssid,
749 sme->ssid_len) == 0) {
750 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
751 if (!sme->bssid) {
752 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
753 break;
754 } else {
755 if (memcmp(last_scanned_shadow[i].bssid,
756 sme->bssid,
757 ETH_ALEN) == 0) {
758 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
759 break;
760 }
761 }
762 }
763 }
764
765 if (i < last_scanned_cnt) {
766 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
767
768 pstrNetworkInfo = &last_scanned_shadow[i];
769
770 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated:"
771 "%x%x%x%x%x%x\n",
772 pstrNetworkInfo->bssid[0], pstrNetworkInfo->bssid[1],
773 pstrNetworkInfo->bssid[2], pstrNetworkInfo->bssid[3],
774 pstrNetworkInfo->bssid[4], pstrNetworkInfo->bssid[5]);
775 } else {
776 s32Error = -ENOENT;
777 if (last_scanned_cnt == 0)
778 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
779 else
780 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
781 wilc_connecting = 0;
782 return s32Error;
783 }
784
785 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
786 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
787
788 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
789 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
790
791 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
792
793 if (sme->crypto.cipher_group != NO_ENCRYPT) {
794 pcwpa_version = "Default";
795 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
796 u8security = ENCRYPT_ENABLED | WEP;
797 pcgroup_encrypt_val = "WEP40";
798 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
799 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
800
801 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
802 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
803
804 g_key_wep_params.key_len = sme->key_len;
805 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
806 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
807 g_key_wep_params.key_idx = sme->key_idx;
808 g_wep_keys_saved = true;
809
810 wilc_set_wep_default_keyid(vif, sme->key_idx);
811 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
812 sme->key_idx);
813 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
814 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
815 pcgroup_encrypt_val = "WEP104";
816 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
817
818 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
819 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
820
821 g_key_wep_params.key_len = sme->key_len;
822 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
823 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
824 g_key_wep_params.key_idx = sme->key_idx;
825 g_wep_keys_saved = true;
826
827 wilc_set_wep_default_keyid(vif, sme->key_idx);
828 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
829 sme->key_idx);
830 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
831 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
832 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
833 pcgroup_encrypt_val = "WPA2_TKIP";
834 pccipher_group = "TKIP";
835 } else {
836 u8security = ENCRYPT_ENABLED | WPA2 | AES;
837 pcgroup_encrypt_val = "WPA2_AES";
838 pccipher_group = "AES";
839 }
840 pcwpa_version = "WPA_VERSION_2";
841 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
842 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
843 u8security = ENCRYPT_ENABLED | WPA | TKIP;
844 pcgroup_encrypt_val = "WPA_TKIP";
845 pccipher_group = "TKIP";
846 } else {
847 u8security = ENCRYPT_ENABLED | WPA | AES;
848 pcgroup_encrypt_val = "WPA_AES";
849 pccipher_group = "AES";
850 }
851 pcwpa_version = "WPA_VERSION_1";
852
853 } else {
854 s32Error = -ENOTSUPP;
855 netdev_err(dev, "Not supported cipher\n");
856 wilc_connecting = 0;
857 return s32Error;
858 }
859 }
860
861 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
862 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
863 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
864 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
865 u8security = u8security | TKIP;
866 } else {
867 u8security = u8security | AES;
868 }
869 }
870 }
871
872 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
873
874 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
875 switch (sme->auth_type) {
876 case NL80211_AUTHTYPE_OPEN_SYSTEM:
877 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
878 tenuAuth_type = OPEN_SYSTEM;
879 break;
880
881 case NL80211_AUTHTYPE_SHARED_KEY:
882 tenuAuth_type = SHARED_KEY;
883 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
884 break;
885
886 default:
887 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
888 }
889
890 if (sme->crypto.n_akm_suites) {
891 switch (sme->crypto.akm_suites[0]) {
892 case WLAN_AKM_SUITE_8021X:
893 tenuAuth_type = IEEE8021;
894 break;
895
896 default:
897 break;
898 }
899 }
900
901
902 PRINT_INFO(CFG80211_DBG, "Required Ch = %d\n", pstrNetworkInfo->ch);
903
904 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
905 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
906
907 curr_channel = pstrNetworkInfo->ch;
908
909 if (!pstrWFIDrv->p2p_connect)
910 wlan_channel = pstrNetworkInfo->ch;
911
912 wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
913
914 s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
915 sme->ssid_len, sme->ie, sme->ie_len,
916 CfgConnectResult, (void *)priv,
917 u8security, tenuAuth_type,
918 pstrNetworkInfo->ch,
919 pstrNetworkInfo->join_params);
920 if (s32Error != 0) {
921 netdev_err(dev, "wilc_set_join_req(): Error\n");
922 s32Error = -ENOENT;
923 wilc_connecting = 0;
924 return s32Error;
925 }
926
927 return s32Error;
928 }
929
930 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
931 {
932 s32 s32Error = 0;
933 struct wilc_priv *priv;
934 struct host_if_drv *pstrWFIDrv;
935 struct wilc_vif *vif;
936 u8 NullBssid[ETH_ALEN] = {0};
937
938 wilc_connecting = 0;
939 priv = wiphy_priv(wiphy);
940 vif = netdev_priv(priv->dev);
941
942 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
943 if (!pstrWFIDrv->p2p_connect)
944 wlan_channel = INVALID_CHANNEL;
945 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
946
947 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
948
949 p2p_local_random = 0x01;
950 p2p_recv_random = 0x00;
951 wilc_ie = false;
952 pstrWFIDrv->p2p_timeout = 0;
953
954 s32Error = wilc_disconnect(vif, reason_code);
955 if (s32Error != 0) {
956 netdev_err(priv->dev, "Error in disconnecting\n");
957 s32Error = -EINVAL;
958 }
959
960 return s32Error;
961 }
962
963 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
964 bool pairwise,
965 const u8 *mac_addr, struct key_params *params)
966
967 {
968 s32 s32Error = 0, KeyLen = params->key_len;
969 u32 i;
970 struct wilc_priv *priv;
971 const u8 *pu8RxMic = NULL;
972 const u8 *pu8TxMic = NULL;
973 u8 u8mode = NO_ENCRYPT;
974 u8 u8gmode = NO_ENCRYPT;
975 u8 u8pmode = NO_ENCRYPT;
976 enum AUTHTYPE tenuAuth_type = ANY;
977 struct wilc *wl;
978 struct wilc_vif *vif;
979
980 priv = wiphy_priv(wiphy);
981 vif = netdev_priv(netdev);
982 wl = vif->wilc;
983
984 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
985
986 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
987
988 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
989 params->key[1],
990 params->key[2]);
991
992
993 switch (params->cipher) {
994 case WLAN_CIPHER_SUITE_WEP40:
995 case WLAN_CIPHER_SUITE_WEP104:
996 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
997 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
998 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
999
1000 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1001 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1002
1003 for (i = 0; i < params->key_len; i++)
1004 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1005
1006 tenuAuth_type = OPEN_SYSTEM;
1007
1008 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1009 u8mode = ENCRYPT_ENABLED | WEP;
1010 else
1011 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1012
1013 wilc_add_wep_key_bss_ap(vif, params->key,
1014 params->key_len, key_index,
1015 u8mode, tenuAuth_type);
1016 break;
1017 }
1018 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
1019 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
1020 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
1021
1022 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1023 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1024 if (INFO) {
1025 for (i = 0; i < params->key_len; i++)
1026 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1027 }
1028 wilc_add_wep_key_bss_sta(vif, params->key,
1029 params->key_len, key_index);
1030 }
1031
1032 break;
1033
1034 case WLAN_CIPHER_SUITE_TKIP:
1035 case WLAN_CIPHER_SUITE_CCMP:
1036 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1037 if (!priv->wilc_gtk[key_index]) {
1038 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
1039 priv->wilc_gtk[key_index]->key = NULL;
1040 priv->wilc_gtk[key_index]->seq = NULL;
1041 }
1042 if (!priv->wilc_ptk[key_index]) {
1043 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
1044 priv->wilc_ptk[key_index]->key = NULL;
1045 priv->wilc_ptk[key_index]->seq = NULL;
1046 }
1047
1048
1049
1050 if (!pairwise) {
1051 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1052 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1053 else
1054 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1055
1056 priv->wilc_groupkey = u8gmode;
1057
1058 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1059 pu8TxMic = params->key + 24;
1060 pu8RxMic = params->key + 16;
1061 KeyLen = params->key_len - 16;
1062 }
1063 kfree(priv->wilc_gtk[key_index]->key);
1064
1065 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
1066 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
1067 kfree(priv->wilc_gtk[key_index]->seq);
1068
1069 if ((params->seq_len) > 0) {
1070 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
1071 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
1072 }
1073
1074 priv->wilc_gtk[key_index]->cipher = params->cipher;
1075 priv->wilc_gtk[key_index]->key_len = params->key_len;
1076 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1077
1078 if (INFO) {
1079 for (i = 0; i < params->key_len; i++)
1080 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1081 for (i = 0; i < params->seq_len; i++)
1082 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1083 }
1084
1085
1086 wilc_add_rx_gtk(vif, params->key, KeyLen,
1087 key_index, params->seq_len,
1088 params->seq, pu8RxMic,
1089 pu8TxMic, AP_MODE, u8gmode);
1090
1091 } else {
1092 PRINT_INFO(CFG80211_DBG, "STA Address: %x%x%x%x%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4]);
1093
1094 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1095 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1096 else
1097 u8pmode = priv->wilc_groupkey | AES;
1098
1099
1100 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1101 pu8TxMic = params->key + 24;
1102 pu8RxMic = params->key + 16;
1103 KeyLen = params->key_len - 16;
1104 }
1105
1106 kfree(priv->wilc_ptk[key_index]->key);
1107
1108 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
1109
1110 kfree(priv->wilc_ptk[key_index]->seq);
1111
1112 if ((params->seq_len) > 0)
1113 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
1114
1115 if (INFO) {
1116 for (i = 0; i < params->key_len; i++)
1117 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1118
1119 for (i = 0; i < params->seq_len; i++)
1120 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1121 }
1122
1123 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
1124
1125 if ((params->seq_len) > 0)
1126 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
1127
1128 priv->wilc_ptk[key_index]->cipher = params->cipher;
1129 priv->wilc_ptk[key_index]->key_len = params->key_len;
1130 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1131
1132 wilc_add_ptk(vif, params->key, KeyLen,
1133 mac_addr, pu8RxMic, pu8TxMic,
1134 AP_MODE, u8pmode, key_index);
1135 }
1136 break;
1137 }
1138
1139 {
1140 u8mode = 0;
1141 if (!pairwise) {
1142 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1143 pu8RxMic = params->key + 24;
1144 pu8TxMic = params->key + 16;
1145 KeyLen = params->key_len - 16;
1146 }
1147
1148 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
1149 g_add_gtk_key_params.key_idx = key_index;
1150 g_add_gtk_key_params.pairwise = pairwise;
1151 if (!mac_addr) {
1152 g_add_gtk_key_params.mac_addr = NULL;
1153 } else {
1154 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1155 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1156 }
1157 g_key_gtk_params.key_len = params->key_len;
1158 g_key_gtk_params.seq_len = params->seq_len;
1159 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1160 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1161 if (params->seq_len > 0) {
1162 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1163 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1164 }
1165 g_key_gtk_params.cipher = params->cipher;
1166
1167 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1168 g_key_gtk_params.key[1],
1169 g_key_gtk_params.key[2]);
1170 g_gtk_keys_saved = true;
1171 }
1172
1173 wilc_add_rx_gtk(vif, params->key, KeyLen,
1174 key_index, params->seq_len,
1175 params->seq, pu8RxMic,
1176 pu8TxMic, STATION_MODE,
1177 u8mode);
1178 } else {
1179 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1180 pu8RxMic = params->key + 24;
1181 pu8TxMic = params->key + 16;
1182 KeyLen = params->key_len - 16;
1183 }
1184
1185 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1186 g_add_ptk_key_params.key_idx = key_index;
1187 g_add_ptk_key_params.pairwise = pairwise;
1188 if (!mac_addr) {
1189 g_add_ptk_key_params.mac_addr = NULL;
1190 } else {
1191 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1192 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1193 }
1194 g_key_ptk_params.key_len = params->key_len;
1195 g_key_ptk_params.seq_len = params->seq_len;
1196 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1197 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1198 if (params->seq_len > 0) {
1199 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1200 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1201 }
1202 g_key_ptk_params.cipher = params->cipher;
1203
1204 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1205 g_key_ptk_params.key[1],
1206 g_key_ptk_params.key[2]);
1207 g_ptk_keys_saved = true;
1208 }
1209
1210 wilc_add_ptk(vif, params->key, KeyLen,
1211 mac_addr, pu8RxMic, pu8TxMic,
1212 STATION_MODE, u8mode, key_index);
1213 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1214 if (INFO) {
1215 for (i = 0; i < params->key_len; i++)
1216 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1217 }
1218 }
1219 }
1220 break;
1221
1222 default:
1223 netdev_err(netdev, "Not supported cipher\n");
1224 s32Error = -ENOTSUPP;
1225 }
1226
1227 return s32Error;
1228 }
1229
1230 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1231 u8 key_index,
1232 bool pairwise,
1233 const u8 *mac_addr)
1234 {
1235 struct wilc_priv *priv;
1236 struct wilc *wl;
1237 struct wilc_vif *vif;
1238
1239 priv = wiphy_priv(wiphy);
1240 vif = netdev_priv(netdev);
1241 wl = vif->wilc;
1242
1243 if (netdev == wl->vif[0]->ndev) {
1244 g_ptk_keys_saved = false;
1245 g_gtk_keys_saved = false;
1246 g_wep_keys_saved = false;
1247
1248 kfree(g_key_wep_params.key);
1249 g_key_wep_params.key = NULL;
1250
1251 if ((priv->wilc_gtk[key_index]) != NULL) {
1252 kfree(priv->wilc_gtk[key_index]->key);
1253 priv->wilc_gtk[key_index]->key = NULL;
1254 kfree(priv->wilc_gtk[key_index]->seq);
1255 priv->wilc_gtk[key_index]->seq = NULL;
1256
1257 kfree(priv->wilc_gtk[key_index]);
1258 priv->wilc_gtk[key_index] = NULL;
1259 }
1260
1261 if ((priv->wilc_ptk[key_index]) != NULL) {
1262 kfree(priv->wilc_ptk[key_index]->key);
1263 priv->wilc_ptk[key_index]->key = NULL;
1264 kfree(priv->wilc_ptk[key_index]->seq);
1265 priv->wilc_ptk[key_index]->seq = NULL;
1266 kfree(priv->wilc_ptk[key_index]);
1267 priv->wilc_ptk[key_index] = NULL;
1268 }
1269
1270 kfree(g_key_ptk_params.key);
1271 g_key_ptk_params.key = NULL;
1272 kfree(g_key_ptk_params.seq);
1273 g_key_ptk_params.seq = NULL;
1274
1275 kfree(g_key_gtk_params.key);
1276 g_key_gtk_params.key = NULL;
1277 kfree(g_key_gtk_params.seq);
1278 g_key_gtk_params.seq = NULL;
1279
1280 }
1281
1282 if (key_index >= 0 && key_index <= 3) {
1283 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
1284 priv->WILC_WFI_wep_key_len[key_index] = 0;
1285
1286 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
1287 wilc_remove_wep_key(vif, key_index);
1288 } else {
1289 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
1290 wilc_remove_key(priv->hif_drv, mac_addr);
1291 }
1292
1293 return 0;
1294 }
1295
1296 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1297 bool pairwise,
1298 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1299 {
1300 struct wilc_priv *priv;
1301 struct key_params key_params;
1302 u32 i;
1303
1304 priv = wiphy_priv(wiphy);
1305
1306
1307 if (!pairwise) {
1308 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1309
1310 key_params.key = priv->wilc_gtk[key_index]->key;
1311 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1312 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1313 key_params.seq = priv->wilc_gtk[key_index]->seq;
1314 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1315 if (INFO) {
1316 for (i = 0; i < key_params.key_len; i++)
1317 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1318 }
1319 } else {
1320 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1321
1322 key_params.key = priv->wilc_ptk[key_index]->key;
1323 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1324 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1325 key_params.seq = priv->wilc_ptk[key_index]->seq;
1326 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1327 }
1328
1329 callback(cookie, &key_params);
1330
1331 return 0;
1332 }
1333
1334 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1335 bool unicast, bool multicast)
1336 {
1337 struct wilc_priv *priv;
1338 struct wilc_vif *vif;
1339
1340 priv = wiphy_priv(wiphy);
1341 vif = netdev_priv(priv->dev);
1342
1343 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
1344
1345 wilc_set_wep_default_keyid(vif, key_index);
1346
1347 return 0;
1348 }
1349
1350 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1351 const u8 *mac, struct station_info *sinfo)
1352 {
1353 struct wilc_priv *priv;
1354 struct wilc_vif *vif;
1355 u32 i = 0;
1356 u32 associatedsta = 0;
1357 u32 inactive_time = 0;
1358 priv = wiphy_priv(wiphy);
1359 vif = netdev_priv(dev);
1360
1361 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1362 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1363
1364 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1365
1366 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1367 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1368 associatedsta = i;
1369 break;
1370 }
1371 }
1372
1373 if (associatedsta == -1) {
1374 netdev_err(dev, "sta required is not associated\n");
1375 return -ENOENT;
1376 }
1377
1378 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1379
1380 wilc_get_inactive_time(vif, mac, &inactive_time);
1381 sinfo->inactive_time = 1000 * inactive_time;
1382 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1383 }
1384
1385 if (vif->iftype == STATION_MODE) {
1386 struct rf_info strStatistics;
1387
1388 wilc_get_statistics(vif, &strStatistics);
1389
1390 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1391 BIT(NL80211_STA_INFO_RX_PACKETS) |
1392 BIT(NL80211_STA_INFO_TX_PACKETS) |
1393 BIT(NL80211_STA_INFO_TX_FAILED) |
1394 BIT(NL80211_STA_INFO_TX_BITRATE);
1395
1396 sinfo->signal = strStatistics.rssi;
1397 sinfo->rx_packets = strStatistics.rx_cnt;
1398 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1399 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1400 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1401
1402 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1403 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1404 wilc_enable_tcp_ack_filter(true);
1405 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1406 wilc_enable_tcp_ack_filter(false);
1407 }
1408 return 0;
1409 }
1410
1411 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1412 struct bss_parameters *params)
1413 {
1414 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1415 return 0;
1416 }
1417
1418 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1419 {
1420 s32 s32Error = 0;
1421 struct cfg_param_val pstrCfgParamVal;
1422 struct wilc_priv *priv;
1423 struct wilc_vif *vif;
1424
1425 priv = wiphy_priv(wiphy);
1426 vif = netdev_priv(priv->dev);
1427
1428 pstrCfgParamVal.flag = 0;
1429 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
1430
1431 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1432 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1433 priv->dev->ieee80211_ptr->wiphy->retry_short);
1434 pstrCfgParamVal.flag |= RETRY_SHORT;
1435 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1436 }
1437 if (changed & WIPHY_PARAM_RETRY_LONG) {
1438 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
1439 pstrCfgParamVal.flag |= RETRY_LONG;
1440 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1441 }
1442 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1443 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
1444 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1445 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1446 }
1447
1448 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1449 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1450
1451 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1452 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1453 }
1454
1455 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
1456 s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1457 if (s32Error)
1458 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1459
1460 return s32Error;
1461 }
1462
1463 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1464 struct cfg80211_pmksa *pmksa)
1465 {
1466 u32 i;
1467 s32 s32Error = 0;
1468 u8 flag = 0;
1469 struct wilc_vif *vif;
1470 struct wilc_priv *priv = wiphy_priv(wiphy);
1471
1472 vif = netdev_priv(priv->dev);
1473 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1474
1475
1476 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1477 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1478 ETH_ALEN)) {
1479 flag = PMKID_FOUND;
1480 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1481 break;
1482 }
1483 }
1484 if (i < WILC_MAX_NUM_PMKIDS) {
1485 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
1486 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1487 ETH_ALEN);
1488 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1489 PMKID_LEN);
1490 if (!(flag == PMKID_FOUND))
1491 priv->pmkid_list.numpmkid++;
1492 } else {
1493 netdev_err(netdev, "Invalid PMKID index\n");
1494 s32Error = -EINVAL;
1495 }
1496
1497 if (!s32Error) {
1498 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
1499 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1500 }
1501 return s32Error;
1502 }
1503
1504 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1505 struct cfg80211_pmksa *pmksa)
1506 {
1507 u32 i;
1508 s32 s32Error = 0;
1509
1510 struct wilc_priv *priv = wiphy_priv(wiphy);
1511
1512 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1513
1514 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1515 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1516 ETH_ALEN)) {
1517 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
1518 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1519 break;
1520 }
1521 }
1522
1523 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1524 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1525 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1526 priv->pmkid_list.pmkidlist[i + 1].bssid,
1527 ETH_ALEN);
1528 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1529 priv->pmkid_list.pmkidlist[i].pmkid,
1530 PMKID_LEN);
1531 }
1532 priv->pmkid_list.numpmkid--;
1533 } else {
1534 s32Error = -EINVAL;
1535 }
1536
1537 return s32Error;
1538 }
1539
1540 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1541 {
1542 struct wilc_priv *priv = wiphy_priv(wiphy);
1543
1544 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1545
1546 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1547
1548 return 0;
1549 }
1550
1551 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1552 {
1553 u32 index = 0;
1554 u32 i = 0, j = 0;
1555
1556 u8 op_channel_attr_index = 0;
1557 u8 channel_list_attr_index = 0;
1558
1559 while (index < len) {
1560 if (buf[index] == GO_INTENT_ATTR_ID) {
1561 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
1562 }
1563
1564 if (buf[index] == CHANLIST_ATTR_ID)
1565 channel_list_attr_index = index;
1566 else if (buf[index] == OPERCHAN_ATTR_ID)
1567 op_channel_attr_index = index;
1568 index += buf[index + 1] + 3;
1569 }
1570 if (wlan_channel != INVALID_CHANNEL) {
1571 if (channel_list_attr_index) {
1572 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1573 if (buf[i] == 0x51) {
1574 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1575 buf[j] = wlan_channel;
1576 }
1577 break;
1578 }
1579 }
1580 }
1581
1582 if (op_channel_attr_index) {
1583 buf[op_channel_attr_index + 6] = 0x51;
1584 buf[op_channel_attr_index + 7] = wlan_channel;
1585 }
1586 }
1587 }
1588
1589 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1590 {
1591 u32 index = 0;
1592 u32 i = 0, j = 0;
1593
1594 u8 op_channel_attr_index = 0;
1595 u8 channel_list_attr_index = 0;
1596
1597 while (index < len) {
1598 if (buf[index] == GO_INTENT_ATTR_ID) {
1599 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
1600
1601 break;
1602 }
1603
1604 if (buf[index] == CHANLIST_ATTR_ID)
1605 channel_list_attr_index = index;
1606 else if (buf[index] == OPERCHAN_ATTR_ID)
1607 op_channel_attr_index = index;
1608 index += buf[index + 1] + 3;
1609 }
1610 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1611 if (channel_list_attr_index) {
1612 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1613 if (buf[i] == 0x51) {
1614 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1615 buf[j] = wlan_channel;
1616 }
1617 break;
1618 }
1619 }
1620 }
1621
1622 if (op_channel_attr_index) {
1623 buf[op_channel_attr_index + 6] = 0x51;
1624 buf[op_channel_attr_index + 7] = wlan_channel;
1625 }
1626 }
1627 }
1628
1629 void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
1630 {
1631 struct wilc_priv *priv;
1632 u32 header, pkt_offset;
1633 struct host_if_drv *pstrWFIDrv;
1634 u32 i = 0;
1635 s32 s32Freq;
1636
1637 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1638 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1639
1640 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1641
1642 pkt_offset = GET_PKT_OFFSET(header);
1643
1644 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1645 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1646 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1647 return;
1648 } else {
1649 if (pkt_offset & IS_MGMT_STATUS_SUCCES)
1650 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1651 else
1652 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1653 return;
1654 }
1655 } else {
1656 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
1657
1658 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1659 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1660 netdev_dbg(dev, "Receiving action wrong ch\n");
1661 return;
1662 }
1663 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1664 switch (buff[ACTION_SUBTYPE_ID]) {
1665 case GAS_INTIAL_REQ:
1666 break;
1667
1668 case GAS_INTIAL_RSP:
1669 break;
1670
1671 case PUBLIC_ACT_VENDORSPEC:
1672 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1673 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1674 if (!wilc_ie) {
1675 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1676 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1677 p2p_recv_random = buff[i + 6];
1678 wilc_ie = true;
1679 break;
1680 }
1681 }
1682 }
1683 }
1684 if (p2p_local_random > p2p_recv_random) {
1685 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1686 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1687 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1688 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1689 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1690 break;
1691 }
1692 }
1693 }
1694 } else {
1695 netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1696 }
1697 }
1698
1699
1700 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
1701 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1702 return;
1703 }
1704 break;
1705
1706 default:
1707 netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1708 break;
1709 }
1710 }
1711 }
1712
1713 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1714 }
1715 }
1716
1717 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1718 {
1719 struct p2p_mgmt_data *pv_data = priv;
1720
1721
1722 kfree(pv_data->buff);
1723 kfree(pv_data);
1724 }
1725
1726 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1727 {
1728 struct wilc_priv *priv;
1729
1730 priv = pUserVoid;
1731
1732 priv->bInP2PlistenState = true;
1733
1734 cfg80211_ready_on_channel(priv->wdev,
1735 priv->strRemainOnChanParams.u64ListenCookie,
1736 priv->strRemainOnChanParams.pstrListenChan,
1737 priv->strRemainOnChanParams.u32ListenDuration,
1738 GFP_KERNEL);
1739 }
1740
1741 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1742 {
1743 struct wilc_priv *priv;
1744
1745 priv = pUserVoid;
1746
1747 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1748 priv->bInP2PlistenState = false;
1749
1750 cfg80211_remain_on_channel_expired(priv->wdev,
1751 priv->strRemainOnChanParams.u64ListenCookie,
1752 priv->strRemainOnChanParams.pstrListenChan,
1753 GFP_KERNEL);
1754 }
1755 }
1756
1757 static int remain_on_channel(struct wiphy *wiphy,
1758 struct wireless_dev *wdev,
1759 struct ieee80211_channel *chan,
1760 unsigned int duration, u64 *cookie)
1761 {
1762 s32 s32Error = 0;
1763 struct wilc_priv *priv;
1764 struct wilc_vif *vif;
1765
1766 priv = wiphy_priv(wiphy);
1767 vif = netdev_priv(priv->dev);
1768
1769 if (wdev->iftype == NL80211_IFTYPE_AP) {
1770 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1771 return s32Error;
1772 }
1773
1774 curr_channel = chan->hw_value;
1775
1776 priv->strRemainOnChanParams.pstrListenChan = chan;
1777 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1778 priv->strRemainOnChanParams.u32ListenDuration = duration;
1779 priv->strRemainOnChanParams.u32ListenSessionID++;
1780
1781 s32Error = wilc_remain_on_channel(vif,
1782 priv->strRemainOnChanParams.u32ListenSessionID,
1783 duration, chan->hw_value,
1784 WILC_WFI_RemainOnChannelExpired,
1785 WILC_WFI_RemainOnChannelReady, (void *)priv);
1786
1787 return s32Error;
1788 }
1789
1790 static int cancel_remain_on_channel(struct wiphy *wiphy,
1791 struct wireless_dev *wdev,
1792 u64 cookie)
1793 {
1794 s32 s32Error = 0;
1795 struct wilc_priv *priv;
1796 struct wilc_vif *vif;
1797
1798 priv = wiphy_priv(wiphy);
1799 vif = netdev_priv(priv->dev);
1800
1801 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1802
1803 s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
1804 return s32Error;
1805 }
1806
1807 static int mgmt_tx(struct wiphy *wiphy,
1808 struct wireless_dev *wdev,
1809 struct cfg80211_mgmt_tx_params *params,
1810 u64 *cookie)
1811 {
1812 struct ieee80211_channel *chan = params->chan;
1813 unsigned int wait = params->wait;
1814 const u8 *buf = params->buf;
1815 size_t len = params->len;
1816 const struct ieee80211_mgmt *mgmt;
1817 struct p2p_mgmt_data *mgmt_tx;
1818 struct wilc_priv *priv;
1819 struct host_if_drv *pstrWFIDrv;
1820 u32 i;
1821 struct wilc_vif *vif;
1822 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1823
1824 vif = netdev_priv(wdev->netdev);
1825 priv = wiphy_priv(wiphy);
1826 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1827
1828 *cookie = (unsigned long)buf;
1829 priv->u64tx_cookie = *cookie;
1830 mgmt = (const struct ieee80211_mgmt *) buf;
1831
1832 if (ieee80211_is_mgmt(mgmt->frame_control)) {
1833 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1834 if (!mgmt_tx)
1835 return -EFAULT;
1836
1837 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1838 if (!mgmt_tx->buff) {
1839 kfree(mgmt_tx);
1840 return -ENOMEM;
1841 }
1842
1843 memcpy(mgmt_tx->buff, buf, len);
1844 mgmt_tx->size = len;
1845
1846
1847 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1848 wilc_set_mac_chnl_num(vif, chan->hw_value);
1849 curr_channel = chan->hw_value;
1850 } else if (ieee80211_is_action(mgmt->frame_control)) {
1851 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1852 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1853 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1854 wilc_set_mac_chnl_num(vif,
1855 chan->hw_value);
1856 curr_channel = chan->hw_value;
1857 }
1858 switch (buf[ACTION_SUBTYPE_ID]) {
1859 case GAS_INTIAL_REQ:
1860 break;
1861
1862 case GAS_INTIAL_RSP:
1863 break;
1864
1865 case PUBLIC_ACT_VENDORSPEC:
1866 {
1867 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1868 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1869 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1870 get_random_bytes(&p2p_local_random, 1);
1871 p2p_local_random++;
1872 }
1873 }
1874
1875 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1876 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1877 if (p2p_local_random > p2p_recv_random) {
1878 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1879 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1880 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1881 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1882 else
1883 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1884 break;
1885 }
1886 }
1887
1888 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1889 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1890 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1891 mgmt_tx->size = buf_len;
1892 }
1893 }
1894 }
1895
1896 } else {
1897 netdev_dbg(vif->ndev, "Not a P2P public action frame\n");
1898 }
1899
1900 break;
1901 }
1902
1903 default:
1904 {
1905 netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1906 break;
1907 }
1908 }
1909 }
1910
1911 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1912 }
1913
1914 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1915 mgmt_tx->buff, mgmt_tx->size,
1916 WILC_WFI_mgmt_tx_complete);
1917 }
1918 return 0;
1919 }
1920
1921 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1922 struct wireless_dev *wdev,
1923 u64 cookie)
1924 {
1925 struct wilc_priv *priv;
1926 struct host_if_drv *pstrWFIDrv;
1927
1928 priv = wiphy_priv(wiphy);
1929 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1930 pstrWFIDrv->p2p_timeout = jiffies;
1931
1932 if (!priv->bInP2PlistenState) {
1933 cfg80211_remain_on_channel_expired(priv->wdev,
1934 priv->strRemainOnChanParams.u64ListenCookie,
1935 priv->strRemainOnChanParams.pstrListenChan,
1936 GFP_KERNEL);
1937 }
1938
1939 return 0;
1940 }
1941
1942 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1943 u16 frame_type, bool reg)
1944 {
1945 struct wilc_priv *priv;
1946 struct wilc_vif *vif;
1947 struct wilc *wl;
1948
1949 priv = wiphy_priv(wiphy);
1950 vif = netdev_priv(priv->wdev->netdev);
1951 wl = vif->wilc;
1952
1953 if (!frame_type)
1954 return;
1955
1956 switch (frame_type) {
1957 case PROBE_REQ:
1958 {
1959 vif->g_struct_frame_reg[0].frame_type = frame_type;
1960 vif->g_struct_frame_reg[0].reg = reg;
1961 }
1962 break;
1963
1964 case ACTION:
1965 {
1966 vif->g_struct_frame_reg[1].frame_type = frame_type;
1967 vif->g_struct_frame_reg[1].reg = reg;
1968 }
1969 break;
1970
1971 default:
1972 {
1973 break;
1974 }
1975 }
1976
1977 if (!wl->initialized)
1978 return;
1979 wilc_frame_register(vif, frame_type, reg);
1980 }
1981
1982 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1983 s32 rssi_thold, u32 rssi_hyst)
1984 {
1985 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
1986 return 0;
1987 }
1988
1989 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1990 int idx, u8 *mac, struct station_info *sinfo)
1991 {
1992 struct wilc_priv *priv;
1993 struct wilc_vif *vif;
1994
1995 PRINT_D(CFG80211_DBG, "Dumping station information\n");
1996
1997 if (idx != 0)
1998 return -ENOENT;
1999
2000 priv = wiphy_priv(wiphy);
2001 vif = netdev_priv(priv->dev);
2002
2003 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2004
2005 wilc_get_rssi(vif, &sinfo->signal);
2006
2007 return 0;
2008 }
2009
2010 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2011 bool enabled, int timeout)
2012 {
2013 struct wilc_priv *priv;
2014 struct wilc_vif *vif;
2015
2016 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2017
2018 if (!wiphy)
2019 return -ENOENT;
2020
2021 priv = wiphy_priv(wiphy);
2022 vif = netdev_priv(priv->dev);
2023 if (!priv->hif_drv)
2024 return -EIO;
2025
2026 if (wilc_enable_ps)
2027 wilc_set_power_mgmt(vif, enabled, timeout);
2028
2029
2030 return 0;
2031 }
2032
2033 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2034 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
2035 {
2036 struct wilc_priv *priv;
2037 struct wilc_vif *vif;
2038 struct wilc *wl;
2039
2040 vif = netdev_priv(dev);
2041 priv = wiphy_priv(wiphy);
2042 wl = vif->wilc;
2043
2044 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2045 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2046 p2p_local_random = 0x01;
2047 p2p_recv_random = 0x00;
2048 wilc_ie = false;
2049 wilc_optaining_ip = false;
2050 del_timer(&wilc_during_ip_timer);
2051
2052 switch (type) {
2053 case NL80211_IFTYPE_STATION:
2054 wilc_connecting = 0;
2055 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
2056
2057 dev->ieee80211_ptr->iftype = type;
2058 priv->wdev->iftype = type;
2059 vif->monitor_flag = 0;
2060 vif->iftype = STATION_MODE;
2061 wilc_set_operation_mode(vif, STATION_MODE);
2062
2063 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
2064
2065 wilc_enable_ps = true;
2066 wilc_set_power_mgmt(vif, 1, 0);
2067 break;
2068
2069 case NL80211_IFTYPE_P2P_CLIENT:
2070 wilc_connecting = 0;
2071 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
2072
2073 dev->ieee80211_ptr->iftype = type;
2074 priv->wdev->iftype = type;
2075 vif->monitor_flag = 0;
2076 vif->iftype = CLIENT_MODE;
2077 wilc_set_operation_mode(vif, STATION_MODE);
2078
2079 wilc_enable_ps = false;
2080 wilc_set_power_mgmt(vif, 0, 0);
2081 break;
2082
2083 case NL80211_IFTYPE_AP:
2084 wilc_enable_ps = false;
2085 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
2086 dev->ieee80211_ptr->iftype = type;
2087 priv->wdev->iftype = type;
2088 vif->iftype = AP_MODE;
2089
2090 if (wl->initialized) {
2091 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
2092 0);
2093 wilc_set_operation_mode(vif, AP_MODE);
2094 wilc_set_power_mgmt(vif, 0, 0);
2095 }
2096 break;
2097
2098 case NL80211_IFTYPE_P2P_GO:
2099 wilc_optaining_ip = true;
2100 mod_timer(&wilc_during_ip_timer,
2101 jiffies + msecs_to_jiffies(during_ip_time));
2102 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
2103
2104 wilc_set_operation_mode(vif, AP_MODE);
2105 dev->ieee80211_ptr->iftype = type;
2106 priv->wdev->iftype = type;
2107 vif->iftype = GO_MODE;
2108
2109 wilc_enable_ps = false;
2110 wilc_set_power_mgmt(vif, 0, 0);
2111 break;
2112
2113 default:
2114 netdev_err(dev, "Unknown interface type= %d\n", type);
2115 return -EINVAL;
2116 }
2117
2118 return 0;
2119 }
2120
2121 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2122 struct cfg80211_ap_settings *settings)
2123 {
2124 struct cfg80211_beacon_data *beacon = &(settings->beacon);
2125 struct wilc_priv *priv;
2126 s32 s32Error = 0;
2127 struct wilc *wl;
2128 struct wilc_vif *vif;
2129
2130 priv = wiphy_priv(wiphy);
2131 vif = netdev_priv(dev);
2132 wl = vif->wilc;
2133 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2134
2135 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
2136 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2137
2138 s32Error = set_channel(wiphy, &settings->chandef);
2139
2140 if (s32Error != 0)
2141 netdev_err(dev, "Error in setting channel\n");
2142
2143 wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
2144 wilc_set_power_mgmt(vif, 0, 0);
2145
2146 s32Error = wilc_add_beacon(vif, settings->beacon_interval,
2147 settings->dtim_period, beacon->head_len,
2148 (u8 *)beacon->head, beacon->tail_len,
2149 (u8 *)beacon->tail);
2150
2151 return s32Error;
2152 }
2153
2154 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2155 struct cfg80211_beacon_data *beacon)
2156 {
2157 struct wilc_priv *priv;
2158 struct wilc_vif *vif;
2159 s32 s32Error = 0;
2160
2161 priv = wiphy_priv(wiphy);
2162 vif = netdev_priv(priv->dev);
2163 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2164
2165
2166 s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
2167 (u8 *)beacon->head, beacon->tail_len,
2168 (u8 *)beacon->tail);
2169
2170 return s32Error;
2171 }
2172
2173 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
2174 {
2175 s32 s32Error = 0;
2176 struct wilc_priv *priv;
2177 struct wilc_vif *vif;
2178 u8 NullBssid[ETH_ALEN] = {0};
2179
2180 if (!wiphy)
2181 return -EFAULT;
2182
2183 priv = wiphy_priv(wiphy);
2184 vif = netdev_priv(priv->dev);
2185
2186 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2187
2188 wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
2189
2190 s32Error = wilc_del_beacon(vif);
2191
2192 if (s32Error)
2193 netdev_err(dev, "Host delete beacon fail\n");
2194
2195 return s32Error;
2196 }
2197
2198 static int add_station(struct wiphy *wiphy, struct net_device *dev,
2199 const u8 *mac, struct station_parameters *params)
2200 {
2201 s32 s32Error = 0;
2202 struct wilc_priv *priv;
2203 struct add_sta_param strStaParams = { {0} };
2204 struct wilc_vif *vif;
2205
2206 if (!wiphy)
2207 return -EFAULT;
2208
2209 priv = wiphy_priv(wiphy);
2210 vif = netdev_priv(dev);
2211
2212 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2213 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2214 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
2215 strStaParams.aid = params->aid;
2216 strStaParams.rates_len = params->supported_rates_len;
2217 strStaParams.rates = params->supported_rates;
2218
2219 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2220
2221 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
2222 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
2223 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
2224 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2225 strStaParams.rates_len);
2226
2227 if (!params->ht_capa) {
2228 strStaParams.ht_supported = false;
2229 } else {
2230 strStaParams.ht_supported = true;
2231 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2232 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2233 memcpy(strStaParams.ht_supp_mcs_set,
2234 &params->ht_capa->mcs,
2235 WILC_SUPP_MCS_SET_SIZE);
2236 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2237 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2238 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2239 }
2240
2241 strStaParams.flags_mask = params->sta_flags_mask;
2242 strStaParams.flags_set = params->sta_flags_set;
2243
2244 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2245 strStaParams.ht_supported);
2246 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2247 strStaParams.ht_capa_info);
2248 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2249 strStaParams.ht_ampdu_params);
2250 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2251 strStaParams.ht_ext_params);
2252 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2253 strStaParams.ht_tx_bf_cap);
2254 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2255 strStaParams.ht_ante_sel);
2256 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2257 strStaParams.flags_mask);
2258 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2259 strStaParams.flags_set);
2260
2261 s32Error = wilc_add_station(vif, &strStaParams);
2262 if (s32Error)
2263 netdev_err(dev, "Host add station fail\n");
2264 }
2265
2266 return s32Error;
2267 }
2268
2269 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2270 struct station_del_parameters *params)
2271 {
2272 const u8 *mac = params->mac;
2273 s32 s32Error = 0;
2274 struct wilc_priv *priv;
2275 struct wilc_vif *vif;
2276
2277 if (!wiphy)
2278 return -EFAULT;
2279
2280 priv = wiphy_priv(wiphy);
2281 vif = netdev_priv(dev);
2282
2283 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2284 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2285
2286
2287 if (!mac) {
2288 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
2289 s32Error = wilc_del_allstation(vif,
2290 priv->assoc_stainfo.au8Sta_AssociatedBss);
2291 } else {
2292 PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
2293 }
2294
2295 s32Error = wilc_del_station(vif, mac);
2296
2297 if (s32Error)
2298 netdev_err(dev, "Host delete station fail\n");
2299 }
2300 return s32Error;
2301 }
2302
2303 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2304 const u8 *mac, struct station_parameters *params)
2305 {
2306 s32 s32Error = 0;
2307 struct wilc_priv *priv;
2308 struct add_sta_param strStaParams = { {0} };
2309 struct wilc_vif *vif;
2310
2311
2312 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2313
2314 if (!wiphy)
2315 return -EFAULT;
2316
2317 priv = wiphy_priv(wiphy);
2318 vif = netdev_priv(dev);
2319
2320 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2321 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2322 strStaParams.aid = params->aid;
2323 strStaParams.rates_len = params->supported_rates_len;
2324 strStaParams.rates = params->supported_rates;
2325
2326 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2327 strStaParams.bssid[0], strStaParams.bssid[1],
2328 strStaParams.bssid[2], strStaParams.bssid[3],
2329 strStaParams.bssid[4], strStaParams.bssid[5]);
2330 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
2331 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2332 strStaParams.rates_len);
2333
2334 if (!params->ht_capa) {
2335 strStaParams.ht_supported = false;
2336 } else {
2337 strStaParams.ht_supported = true;
2338 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2339 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2340 memcpy(strStaParams.ht_supp_mcs_set,
2341 &params->ht_capa->mcs,
2342 WILC_SUPP_MCS_SET_SIZE);
2343 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2344 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2345 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2346 }
2347
2348 strStaParams.flags_mask = params->sta_flags_mask;
2349 strStaParams.flags_set = params->sta_flags_set;
2350
2351 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2352 strStaParams.ht_supported);
2353 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2354 strStaParams.ht_capa_info);
2355 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2356 strStaParams.ht_ampdu_params);
2357 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2358 strStaParams.ht_ext_params);
2359 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2360 strStaParams.ht_tx_bf_cap);
2361 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2362 strStaParams.ht_ante_sel);
2363 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2364 strStaParams.flags_mask);
2365 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2366 strStaParams.flags_set);
2367
2368 s32Error = wilc_edit_station(vif, &strStaParams);
2369 if (s32Error)
2370 netdev_err(dev, "Host edit station fail\n");
2371 }
2372 return s32Error;
2373 }
2374
2375 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2376 const char *name,
2377 unsigned char name_assign_type,
2378 enum nl80211_iftype type,
2379 u32 *flags,
2380 struct vif_params *params)
2381 {
2382 struct wilc_vif *vif;
2383 struct wilc_priv *priv;
2384 struct net_device *new_ifc = NULL;
2385
2386 priv = wiphy_priv(wiphy);
2387
2388
2389
2390 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2391
2392 vif = netdev_priv(priv->wdev->netdev);
2393
2394
2395 if (type == NL80211_IFTYPE_MONITOR) {
2396 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
2397 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->ndev);
2398 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2399 if (new_ifc) {
2400 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
2401 vif = netdev_priv(priv->wdev->netdev);
2402 vif->monitor_flag = 1;
2403 }
2404 }
2405 return priv->wdev;
2406 }
2407
2408 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2409 {
2410 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
2411 return 0;
2412 }
2413
2414 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2415 {
2416 struct wilc_priv *priv = wiphy_priv(wiphy);
2417 struct wilc_vif *vif = netdev_priv(priv->dev);
2418
2419 if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2420 vif->wilc->suspend_event = true;
2421 else
2422 vif->wilc->suspend_event = false;
2423
2424 return 0;
2425 }
2426
2427 static int wilc_resume(struct wiphy *wiphy)
2428 {
2429 struct wilc_priv *priv = wiphy_priv(wiphy);
2430 struct wilc_vif *vif = netdev_priv(priv->dev);
2431
2432 netdev_info(vif->ndev, "cfg resume\n");
2433 return 0;
2434 }
2435
2436 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2437 {
2438 struct wilc_priv *priv = wiphy_priv(wiphy);
2439 struct wilc_vif *vif = netdev_priv(priv->dev);
2440
2441 netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2442 }
2443
2444 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2445 enum nl80211_tx_power_setting type, int mbm)
2446 {
2447 int ret;
2448 s32 tx_power = MBM_TO_DBM(mbm);
2449 struct wilc_priv *priv = wiphy_priv(wiphy);
2450 struct wilc_vif *vif = netdev_priv(priv->dev);
2451
2452 if (tx_power < 0)
2453 tx_power = 0;
2454 else if (tx_power > 18)
2455 tx_power = 18;
2456 ret = wilc_set_tx_power(vif, tx_power);
2457 if (ret)
2458 netdev_err(vif->ndev, "Failed to set tx power\n");
2459
2460 return ret;
2461 }
2462
2463 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2464 int *dbm)
2465 {
2466 int ret;
2467 struct wilc_priv *priv = wiphy_priv(wiphy);
2468 struct wilc_vif *vif = netdev_priv(priv->dev);
2469
2470 ret = wilc_get_tx_power(vif, (u8 *)dbm);
2471 if (ret)
2472 netdev_err(vif->ndev, "Failed to get tx power\n");
2473
2474 return ret;
2475 }
2476
2477 static struct cfg80211_ops wilc_cfg80211_ops = {
2478 .set_monitor_channel = set_channel,
2479 .scan = scan,
2480 .connect = connect,
2481 .disconnect = disconnect,
2482 .add_key = add_key,
2483 .del_key = del_key,
2484 .get_key = get_key,
2485 .set_default_key = set_default_key,
2486 .add_virtual_intf = add_virtual_intf,
2487 .del_virtual_intf = del_virtual_intf,
2488 .change_virtual_intf = change_virtual_intf,
2489
2490 .start_ap = start_ap,
2491 .change_beacon = change_beacon,
2492 .stop_ap = stop_ap,
2493 .add_station = add_station,
2494 .del_station = del_station,
2495 .change_station = change_station,
2496 .get_station = get_station,
2497 .dump_station = dump_station,
2498 .change_bss = change_bss,
2499 .set_wiphy_params = set_wiphy_params,
2500
2501 .set_pmksa = set_pmksa,
2502 .del_pmksa = del_pmksa,
2503 .flush_pmksa = flush_pmksa,
2504 .remain_on_channel = remain_on_channel,
2505 .cancel_remain_on_channel = cancel_remain_on_channel,
2506 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2507 .mgmt_tx = mgmt_tx,
2508 .mgmt_frame_register = wilc_mgmt_frame_register,
2509 .set_power_mgmt = set_power_mgmt,
2510 .set_cqm_rssi_config = set_cqm_rssi_config,
2511
2512 .suspend = wilc_suspend,
2513 .resume = wilc_resume,
2514 .set_wakeup = wilc_set_wakeup,
2515 .set_tx_power = set_tx_power,
2516 .get_tx_power = get_tx_power,
2517
2518 };
2519
2520 int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2521 {
2522 struct wilc_priv *priv;
2523
2524 priv = wiphy_priv(wiphy);
2525 switch (changed) {
2526 case WILC_WFI_RX_PKT:
2527 {
2528 priv->netstats.rx_packets++;
2529 priv->netstats.rx_bytes += pktlen;
2530 priv->netstats.rx_time = get_jiffies_64();
2531 }
2532 break;
2533
2534 case WILC_WFI_TX_PKT:
2535 {
2536 priv->netstats.tx_packets++;
2537 priv->netstats.tx_bytes += pktlen;
2538 priv->netstats.tx_time = get_jiffies_64();
2539
2540 }
2541 break;
2542
2543 default:
2544 break;
2545 }
2546 return 0;
2547 }
2548
2549 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2550 {
2551 struct wireless_dev *wdev;
2552
2553
2554 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
2555
2556 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2557 if (!wdev)
2558 goto _fail_;
2559
2560 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2561 if (!wdev->wiphy)
2562 goto _fail_mem_;
2563
2564 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2565 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2566 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2567 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2568 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2569
2570 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2571
2572 return wdev;
2573
2574 _fail_mem_:
2575 kfree(wdev);
2576 _fail_:
2577 return NULL;
2578 }
2579
2580 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2581 {
2582 struct wilc_priv *priv;
2583 struct wireless_dev *wdev;
2584 s32 s32Error = 0;
2585
2586 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2587
2588 wdev = WILC_WFI_CfgAlloc();
2589 if (!wdev) {
2590 netdev_err(net, "wiphy new allocate failed\n");
2591 return NULL;
2592 }
2593
2594 priv = wdev_priv(wdev);
2595 sema_init(&(priv->SemHandleUpdateStats), 1);
2596 priv->wdev = wdev;
2597 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2598 #ifdef CONFIG_PM
2599 wdev->wiphy->wowlan = &wowlan_support;
2600 #endif
2601 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2602 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
2603
2604 wdev->wiphy->max_scan_ie_len = 1000;
2605 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2606 wdev->wiphy->cipher_suites = cipher_suites;
2607 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2608 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2609
2610 wdev->wiphy->max_remain_on_channel_duration = 500;
2611 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2612 BIT(NL80211_IFTYPE_P2P_CLIENT);
2613 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2614 wdev->iftype = NL80211_IFTYPE_STATION;
2615
2616
2617
2618 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2619 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2620 wdev->wiphy->interface_modes, wdev->iftype);
2621
2622 set_wiphy_dev(wdev->wiphy, dev);
2623
2624 s32Error = wiphy_register(wdev->wiphy);
2625 if (s32Error)
2626 netdev_err(net, "Cannot register wiphy device\n");
2627 else
2628 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2629
2630 priv->dev = net;
2631 return wdev;
2632 }
2633
2634 int wilc_init_host_int(struct net_device *net)
2635 {
2636 int s32Error = 0;
2637
2638 struct wilc_priv *priv;
2639
2640 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2641 priv = wdev_priv(net->ieee80211_ptr);
2642 if (op_ifcs == 0) {
2643 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2644 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2645 }
2646 op_ifcs++;
2647
2648 priv->gbAutoRateAdjusted = false;
2649
2650 priv->bInP2PlistenState = false;
2651
2652 sema_init(&(priv->hSemScanReq), 1);
2653 s32Error = wilc_init(net, &priv->hif_drv);
2654 if (s32Error)
2655 netdev_err(net, "Error while initializing hostinterface\n");
2656
2657 return s32Error;
2658 }
2659
2660 int wilc_deinit_host_int(struct net_device *net)
2661 {
2662 int s32Error = 0;
2663 struct wilc_vif *vif;
2664 struct wilc_priv *priv;
2665
2666 priv = wdev_priv(net->ieee80211_ptr);
2667 vif = netdev_priv(priv->dev);
2668
2669 priv->gbAutoRateAdjusted = false;
2670
2671 priv->bInP2PlistenState = false;
2672
2673 op_ifcs--;
2674
2675 s32Error = wilc_deinit(vif);
2676
2677 clear_shadow_scan();
2678 if (op_ifcs == 0)
2679 del_timer_sync(&wilc_during_ip_timer);
2680
2681 if (s32Error)
2682 netdev_err(net, "Error while deintializing host interface\n");
2683
2684 return s32Error;
2685 }
2686
2687 void wilc_free_wiphy(struct net_device *net)
2688 {
2689 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2690
2691 if (!net) {
2692 PRINT_D(INIT_DBG, "net_device is NULL\n");
2693 return;
2694 }
2695
2696 if (!net->ieee80211_ptr) {
2697 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2698 return;
2699 }
2700
2701 if (!net->ieee80211_ptr->wiphy) {
2702 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2703 return;
2704 }
2705
2706 wiphy_unregister(net->ieee80211_ptr->wiphy);
2707
2708 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2709 wiphy_free(net->ieee80211_ptr->wiphy);
2710 kfree(net->ieee80211_ptr);
2711 }
This page took 0.085417 seconds and 4 git commands to generate.