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 = NL80211_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
clear_shadow_scan(void)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
get_rssi_avg(struct network_info * network_info)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
refresh_scan(void * user_void,u8 all,bool direct_scan)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, NL80211_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
reset_shadow_found(void)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
update_scan_time(void)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
remove_network_from_shadow(unsigned long arg)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 kfree(last_scanned_shadow[i].ies);
294 last_scanned_shadow[i].ies = NULL;
295
296 kfree(last_scanned_shadow[i].join_params);
297
298 for (j = i; (j < last_scanned_cnt - 1); j++)
299 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
300
301 last_scanned_cnt--;
302 }
303 }
304
305 if (last_scanned_cnt != 0) {
306 hAgingTimer.data = arg;
307 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
308 }
309 }
310
clear_duringIP(unsigned long arg)311 static void clear_duringIP(unsigned long arg)
312 {
313 wilc_optaining_ip = false;
314 }
315
is_network_in_shadow(struct network_info * pstrNetworkInfo,void * user_void)316 static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
317 void *user_void)
318 {
319 int state = -1;
320 int i;
321
322 if (last_scanned_cnt == 0) {
323 hAgingTimer.data = (unsigned long)user_void;
324 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
325 state = -1;
326 } else {
327 for (i = 0; i < last_scanned_cnt; i++) {
328 if (memcmp(last_scanned_shadow[i].bssid,
329 pstrNetworkInfo->bssid, 6) == 0) {
330 state = i;
331 break;
332 }
333 }
334 }
335 return state;
336 }
337
add_network_to_shadow(struct network_info * pstrNetworkInfo,void * user_void,void * pJoinParams)338 static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
339 void *user_void, void *pJoinParams)
340 {
341 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
342 u32 ap_index = 0;
343 u8 rssi_index = 0;
344
345 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
346 return;
347
348 if (ap_found == -1) {
349 ap_index = last_scanned_cnt;
350 last_scanned_cnt++;
351 } else {
352 ap_index = ap_found;
353 }
354 rssi_index = last_scanned_shadow[ap_index].str_rssi.u8Index;
355 last_scanned_shadow[ap_index].str_rssi.as8RSSI[rssi_index++] = pstrNetworkInfo->rssi;
356 if (rssi_index == NUM_RSSI) {
357 rssi_index = 0;
358 last_scanned_shadow[ap_index].str_rssi.u8Full = 1;
359 }
360 last_scanned_shadow[ap_index].str_rssi.u8Index = rssi_index;
361 last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
362 last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
363 last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
364 memcpy(last_scanned_shadow[ap_index].ssid,
365 pstrNetworkInfo->ssid, pstrNetworkInfo->ssid_len);
366 memcpy(last_scanned_shadow[ap_index].bssid,
367 pstrNetworkInfo->bssid, ETH_ALEN);
368 last_scanned_shadow[ap_index].beacon_period = pstrNetworkInfo->beacon_period;
369 last_scanned_shadow[ap_index].dtim_period = pstrNetworkInfo->dtim_period;
370 last_scanned_shadow[ap_index].ch = pstrNetworkInfo->ch;
371 last_scanned_shadow[ap_index].ies_len = pstrNetworkInfo->ies_len;
372 last_scanned_shadow[ap_index].tsf_hi = pstrNetworkInfo->tsf_hi;
373 if (ap_found != -1)
374 kfree(last_scanned_shadow[ap_index].ies);
375 last_scanned_shadow[ap_index].ies = kmalloc(pstrNetworkInfo->ies_len,
376 GFP_KERNEL);
377 memcpy(last_scanned_shadow[ap_index].ies,
378 pstrNetworkInfo->ies, pstrNetworkInfo->ies_len);
379 last_scanned_shadow[ap_index].time_scan = jiffies;
380 last_scanned_shadow[ap_index].time_scan_cached = jiffies;
381 last_scanned_shadow[ap_index].found = 1;
382 if (ap_found != -1)
383 kfree(last_scanned_shadow[ap_index].join_params);
384 last_scanned_shadow[ap_index].join_params = pJoinParams;
385 }
386
CfgScanResult(enum scan_event scan_event,struct network_info * network_info,void * user_void,void * join_params)387 static void CfgScanResult(enum scan_event scan_event,
388 struct network_info *network_info,
389 void *user_void,
390 void *join_params)
391 {
392 struct wilc_priv *priv;
393 struct wiphy *wiphy;
394 s32 s32Freq;
395 struct ieee80211_channel *channel;
396 struct cfg80211_bss *bss = NULL;
397
398 priv = user_void;
399 if (priv->bCfgScanning) {
400 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
401 wiphy = priv->dev->ieee80211_ptr->wiphy;
402
403 if (!wiphy)
404 return;
405
406 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
407 (((s32)network_info->rssi * 100) < 0 ||
408 ((s32)network_info->rssi * 100) > 100))
409 return;
410
411 if (network_info) {
412 s32Freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ);
413 channel = ieee80211_get_channel(wiphy, s32Freq);
414
415 if (!channel)
416 return;
417
418 if (network_info->new_network) {
419 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
420 priv->u32RcvdChCount++;
421
422 add_network_to_shadow(network_info, priv, join_params);
423
424 if (!(memcmp("DIRECT-", network_info->ssid, 7))) {
425 bss = cfg80211_inform_bss(wiphy,
426 channel,
427 CFG80211_BSS_FTYPE_UNKNOWN,
428 network_info->bssid,
429 network_info->tsf_hi,
430 network_info->cap_info,
431 network_info->beacon_period,
432 (const u8 *)network_info->ies,
433 (size_t)network_info->ies_len,
434 (s32)network_info->rssi * 100,
435 GFP_KERNEL);
436 cfg80211_put_bss(wiphy, bss);
437 }
438 }
439 } else {
440 u32 i;
441
442 for (i = 0; i < priv->u32RcvdChCount; i++) {
443 if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) {
444 last_scanned_shadow[i].rssi = network_info->rssi;
445 last_scanned_shadow[i].time_scan = jiffies;
446 break;
447 }
448 }
449 }
450 }
451 } else if (scan_event == SCAN_EVENT_DONE) {
452 refresh_scan(priv, 1, false);
453
454 mutex_lock(&priv->scan_req_lock);
455
456 if (priv->pstrScanReq) {
457 struct cfg80211_scan_info info = {
458 .aborted = false,
459 };
460
461 cfg80211_scan_done(priv->pstrScanReq, &info);
462 priv->u32RcvdChCount = 0;
463 priv->bCfgScanning = false;
464 priv->pstrScanReq = NULL;
465 }
466 mutex_unlock(&priv->scan_req_lock);
467 } else if (scan_event == SCAN_EVENT_ABORTED) {
468 mutex_lock(&priv->scan_req_lock);
469
470 if (priv->pstrScanReq) {
471 struct cfg80211_scan_info info = {
472 .aborted = false,
473 };
474
475 update_scan_time();
476 refresh_scan(priv, 1, false);
477
478 cfg80211_scan_done(priv->pstrScanReq, &info);
479 priv->bCfgScanning = false;
480 priv->pstrScanReq = NULL;
481 }
482 mutex_unlock(&priv->scan_req_lock);
483 }
484 }
485 }
486
487 int wilc_connecting;
488
CfgConnectResult(enum conn_event enuConnDisconnEvent,struct connect_info * pstrConnectInfo,u8 u8MacStatus,struct disconnect_info * pstrDisconnectNotifInfo,void * pUserVoid)489 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
490 struct connect_info *pstrConnectInfo,
491 u8 u8MacStatus,
492 struct disconnect_info *pstrDisconnectNotifInfo,
493 void *pUserVoid)
494 {
495 struct wilc_priv *priv;
496 struct net_device *dev;
497 struct host_if_drv *pstrWFIDrv;
498 u8 NullBssid[ETH_ALEN] = {0};
499 struct wilc *wl;
500 struct wilc_vif *vif;
501
502 wilc_connecting = 0;
503
504 priv = pUserVoid;
505 dev = priv->dev;
506 vif = netdev_priv(dev);
507 wl = vif->wilc;
508 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
509
510 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
511 u16 u16ConnectStatus;
512
513 u16ConnectStatus = pstrConnectInfo->status;
514
515 if ((u8MacStatus == MAC_DISCONNECTED) &&
516 (pstrConnectInfo->status == SUCCESSFUL_STATUSCODE)) {
517 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
518 wilc_wlan_set_bssid(priv->dev, NullBssid,
519 STATION_MODE);
520 eth_zero_addr(wilc_connected_ssid);
521
522 if (!pstrWFIDrv->p2p_connect)
523 wlan_channel = INVALID_CHANNEL;
524
525 netdev_err(dev, "Unspecified failure\n");
526 }
527
528 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
529 bool bNeedScanRefresh = false;
530 u32 i;
531
532 memcpy(priv->au8AssociatedBss, pstrConnectInfo->bssid, ETH_ALEN);
533
534
535 for (i = 0; i < last_scanned_cnt; i++) {
536 if (memcmp(last_scanned_shadow[i].bssid,
537 pstrConnectInfo->bssid,
538 ETH_ALEN) == 0) {
539 unsigned long now = jiffies;
540
541 if (time_after(now,
542 last_scanned_shadow[i].time_scan_cached +
543 (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
544 bNeedScanRefresh = true;
545
546 break;
547 }
548 }
549
550 if (bNeedScanRefresh)
551 refresh_scan(priv, 1, true);
552 }
553
554 cfg80211_connect_result(dev, pstrConnectInfo->bssid,
555 pstrConnectInfo->req_ies, pstrConnectInfo->req_ies_len,
556 pstrConnectInfo->resp_ies, pstrConnectInfo->resp_ies_len,
557 u16ConnectStatus, GFP_KERNEL);
558 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
559 wilc_optaining_ip = false;
560 p2p_local_random = 0x01;
561 p2p_recv_random = 0x00;
562 wilc_ie = false;
563 eth_zero_addr(priv->au8AssociatedBss);
564 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
565 eth_zero_addr(wilc_connected_ssid);
566
567 if (!pstrWFIDrv->p2p_connect)
568 wlan_channel = INVALID_CHANNEL;
569 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
570 pstrDisconnectNotifInfo->reason = 3;
571 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
572 pstrDisconnectNotifInfo->reason = 1;
573
574 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->reason, pstrDisconnectNotifInfo->ie,
575 pstrDisconnectNotifInfo->ie_len, false,
576 GFP_KERNEL);
577 }
578 }
579
set_channel(struct wiphy * wiphy,struct cfg80211_chan_def * chandef)580 static int set_channel(struct wiphy *wiphy,
581 struct cfg80211_chan_def *chandef)
582 {
583 u32 channelnum = 0;
584 struct wilc_priv *priv;
585 int result = 0;
586 struct wilc_vif *vif;
587
588 priv = wiphy_priv(wiphy);
589 vif = netdev_priv(priv->dev);
590
591 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
592
593 curr_channel = channelnum;
594 result = wilc_set_mac_chnl_num(vif, channelnum);
595
596 if (result != 0)
597 netdev_err(priv->dev, "Error in setting channel\n");
598
599 return result;
600 }
601
scan(struct wiphy * wiphy,struct cfg80211_scan_request * request)602 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
603 {
604 struct wilc_priv *priv;
605 u32 i;
606 s32 s32Error = 0;
607 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
608 struct hidden_network strHiddenNetwork;
609 struct wilc_vif *vif;
610
611 priv = wiphy_priv(wiphy);
612 vif = netdev_priv(priv->dev);
613
614 priv->pstrScanReq = request;
615
616 priv->u32RcvdChCount = 0;
617
618 reset_shadow_found();
619
620 priv->bCfgScanning = true;
621 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
622 for (i = 0; i < request->n_channels; i++)
623 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
624
625 if (request->n_ssids >= 1) {
626 strHiddenNetwork.net_info =
627 kmalloc_array(request->n_ssids,
628 sizeof(struct hidden_network),
629 GFP_KERNEL);
630 if (!strHiddenNetwork.net_info)
631 return -ENOMEM;
632 strHiddenNetwork.n_ssids = request->n_ssids;
633
634
635 for (i = 0; i < request->n_ssids; i++) {
636 if (request->ssids[i].ssid_len != 0) {
637 strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
638 memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
639 strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
640 } else {
641 strHiddenNetwork.n_ssids -= 1;
642 }
643 }
644 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
645 au8ScanChanList,
646 request->n_channels,
647 (const u8 *)request->ie,
648 request->ie_len, CfgScanResult,
649 (void *)priv, &strHiddenNetwork);
650 } else {
651 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
652 au8ScanChanList,
653 request->n_channels,
654 (const u8 *)request->ie,
655 request->ie_len, CfgScanResult,
656 (void *)priv, NULL);
657 }
658 } else {
659 netdev_err(priv->dev, "Requested scanned channels over\n");
660 }
661
662 if (s32Error != 0)
663 s32Error = -EBUSY;
664
665 return s32Error;
666 }
667
connect(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_connect_params * sme)668 static int connect(struct wiphy *wiphy, struct net_device *dev,
669 struct cfg80211_connect_params *sme)
670 {
671 s32 s32Error = 0;
672 u32 i;
673 u8 u8security = NO_ENCRYPT;
674 enum AUTHTYPE tenuAuth_type = ANY;
675
676 struct wilc_priv *priv;
677 struct host_if_drv *pstrWFIDrv;
678 struct network_info *pstrNetworkInfo = NULL;
679 struct wilc_vif *vif;
680
681 wilc_connecting = 1;
682 priv = wiphy_priv(wiphy);
683 vif = netdev_priv(priv->dev);
684 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
685
686 if (!(strncmp(sme->ssid, "DIRECT-", 7)))
687 pstrWFIDrv->p2p_connect = 1;
688 else
689 pstrWFIDrv->p2p_connect = 0;
690
691 for (i = 0; i < last_scanned_cnt; i++) {
692 if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
693 memcmp(last_scanned_shadow[i].ssid,
694 sme->ssid,
695 sme->ssid_len) == 0) {
696 if (!sme->bssid)
697 break;
698 else
699 if (memcmp(last_scanned_shadow[i].bssid,
700 sme->bssid,
701 ETH_ALEN) == 0)
702 break;
703 }
704 }
705
706 if (i < last_scanned_cnt) {
707 pstrNetworkInfo = &last_scanned_shadow[i];
708 } else {
709 s32Error = -ENOENT;
710 wilc_connecting = 0;
711 return s32Error;
712 }
713
714 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
715 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
716
717 if (sme->crypto.cipher_group != NO_ENCRYPT) {
718 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
719 u8security = ENCRYPT_ENABLED | WEP;
720
721 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
722 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
723
724 g_key_wep_params.key_len = sme->key_len;
725 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
726 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
727 g_key_wep_params.key_idx = sme->key_idx;
728 g_wep_keys_saved = true;
729
730 wilc_set_wep_default_keyid(vif, sme->key_idx);
731 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
732 sme->key_idx);
733 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
734 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
735
736 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
737 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
738
739 g_key_wep_params.key_len = sme->key_len;
740 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
741 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
742 g_key_wep_params.key_idx = sme->key_idx;
743 g_wep_keys_saved = true;
744
745 wilc_set_wep_default_keyid(vif, sme->key_idx);
746 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
747 sme->key_idx);
748 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
749 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
750 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
751 else
752 u8security = ENCRYPT_ENABLED | WPA2 | AES;
753 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
754 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
755 u8security = ENCRYPT_ENABLED | WPA | TKIP;
756 else
757 u8security = ENCRYPT_ENABLED | WPA | AES;
758 } else {
759 s32Error = -ENOTSUPP;
760 netdev_err(dev, "Not supported cipher\n");
761 wilc_connecting = 0;
762 return s32Error;
763 }
764 }
765
766 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
767 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
768 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
769 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP)
770 u8security = u8security | TKIP;
771 else
772 u8security = u8security | AES;
773 }
774 }
775
776 switch (sme->auth_type) {
777 case NL80211_AUTHTYPE_OPEN_SYSTEM:
778 tenuAuth_type = OPEN_SYSTEM;
779 break;
780
781 case NL80211_AUTHTYPE_SHARED_KEY:
782 tenuAuth_type = SHARED_KEY;
783 break;
784
785 default:
786 break;
787 }
788
789 if (sme->crypto.n_akm_suites) {
790 switch (sme->crypto.akm_suites[0]) {
791 case WLAN_AKM_SUITE_8021X:
792 tenuAuth_type = IEEE8021;
793 break;
794
795 default:
796 break;
797 }
798 }
799
800 curr_channel = pstrNetworkInfo->ch;
801
802 if (!pstrWFIDrv->p2p_connect)
803 wlan_channel = pstrNetworkInfo->ch;
804
805 wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
806
807 s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
808 sme->ssid_len, sme->ie, sme->ie_len,
809 CfgConnectResult, (void *)priv,
810 u8security, tenuAuth_type,
811 pstrNetworkInfo->ch,
812 pstrNetworkInfo->join_params);
813 if (s32Error != 0) {
814 netdev_err(dev, "wilc_set_join_req(): Error\n");
815 s32Error = -ENOENT;
816 wilc_connecting = 0;
817 return s32Error;
818 }
819
820 return s32Error;
821 }
822
disconnect(struct wiphy * wiphy,struct net_device * dev,u16 reason_code)823 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
824 {
825 s32 s32Error = 0;
826 struct wilc_priv *priv;
827 struct host_if_drv *pstrWFIDrv;
828 struct wilc_vif *vif;
829 struct wilc *wilc;
830 u8 NullBssid[ETH_ALEN] = {0};
831
832 wilc_connecting = 0;
833 priv = wiphy_priv(wiphy);
834 vif = netdev_priv(priv->dev);
835 wilc = vif->wilc;
836
837 if (!wilc)
838 return -EIO;
839
840 if (wilc->close) {
841 /* already disconnected done */
842 cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
843 return 0;
844 }
845
846 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
847 if (!pstrWFIDrv->p2p_connect)
848 wlan_channel = INVALID_CHANNEL;
849 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
850
851 p2p_local_random = 0x01;
852 p2p_recv_random = 0x00;
853 wilc_ie = false;
854 pstrWFIDrv->p2p_timeout = 0;
855
856 s32Error = wilc_disconnect(vif, reason_code);
857 if (s32Error != 0) {
858 netdev_err(priv->dev, "Error in disconnecting\n");
859 s32Error = -EINVAL;
860 }
861
862 return s32Error;
863 }
864
add_key(struct wiphy * wiphy,struct net_device * netdev,u8 key_index,bool pairwise,const u8 * mac_addr,struct key_params * params)865 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
866 bool pairwise,
867 const u8 *mac_addr, struct key_params *params)
868
869 {
870 s32 s32Error = 0, KeyLen = params->key_len;
871 struct wilc_priv *priv;
872 const u8 *pu8RxMic = NULL;
873 const u8 *pu8TxMic = NULL;
874 u8 u8mode = NO_ENCRYPT;
875 u8 u8gmode = NO_ENCRYPT;
876 u8 u8pmode = NO_ENCRYPT;
877 enum AUTHTYPE tenuAuth_type = ANY;
878 struct wilc *wl;
879 struct wilc_vif *vif;
880
881 priv = wiphy_priv(wiphy);
882 vif = netdev_priv(netdev);
883 wl = vif->wilc;
884
885 switch (params->cipher) {
886 case WLAN_CIPHER_SUITE_WEP40:
887 case WLAN_CIPHER_SUITE_WEP104:
888 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
889 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
890 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
891
892 tenuAuth_type = OPEN_SYSTEM;
893
894 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
895 u8mode = ENCRYPT_ENABLED | WEP;
896 else
897 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
898
899 wilc_add_wep_key_bss_ap(vif, params->key,
900 params->key_len, key_index,
901 u8mode, tenuAuth_type);
902 break;
903 }
904 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
905 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
906 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
907
908 wilc_add_wep_key_bss_sta(vif, params->key,
909 params->key_len, key_index);
910 }
911
912 break;
913
914 case WLAN_CIPHER_SUITE_TKIP:
915 case WLAN_CIPHER_SUITE_CCMP:
916 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
917 if (!priv->wilc_gtk[key_index]) {
918 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
919 priv->wilc_gtk[key_index]->key = NULL;
920 priv->wilc_gtk[key_index]->seq = NULL;
921 }
922 if (!priv->wilc_ptk[key_index]) {
923 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
924 priv->wilc_ptk[key_index]->key = NULL;
925 priv->wilc_ptk[key_index]->seq = NULL;
926 }
927
928
929
930 if (!pairwise) {
931 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
932 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
933 else
934 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
935
936 priv->wilc_groupkey = u8gmode;
937
938 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
939 pu8TxMic = params->key + 24;
940 pu8RxMic = params->key + 16;
941 KeyLen = params->key_len - 16;
942 }
943 kfree(priv->wilc_gtk[key_index]->key);
944
945 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
946 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
947 kfree(priv->wilc_gtk[key_index]->seq);
948
949 if ((params->seq_len) > 0) {
950 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
951 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
952 }
953
954 priv->wilc_gtk[key_index]->cipher = params->cipher;
955 priv->wilc_gtk[key_index]->key_len = params->key_len;
956 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
957
958 wilc_add_rx_gtk(vif, params->key, KeyLen,
959 key_index, params->seq_len,
960 params->seq, pu8RxMic,
961 pu8TxMic, AP_MODE, u8gmode);
962
963 } else {
964 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
965 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
966 else
967 u8pmode = priv->wilc_groupkey | AES;
968
969
970 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
971 pu8TxMic = params->key + 24;
972 pu8RxMic = params->key + 16;
973 KeyLen = params->key_len - 16;
974 }
975
976 kfree(priv->wilc_ptk[key_index]->key);
977
978 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
979
980 kfree(priv->wilc_ptk[key_index]->seq);
981
982 if ((params->seq_len) > 0)
983 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
984
985 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
986
987 if ((params->seq_len) > 0)
988 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
989
990 priv->wilc_ptk[key_index]->cipher = params->cipher;
991 priv->wilc_ptk[key_index]->key_len = params->key_len;
992 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
993
994 wilc_add_ptk(vif, params->key, KeyLen,
995 mac_addr, pu8RxMic, pu8TxMic,
996 AP_MODE, u8pmode, key_index);
997 }
998 break;
999 }
1000
1001 {
1002 u8mode = 0;
1003 if (!pairwise) {
1004 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1005 pu8RxMic = params->key + 24;
1006 pu8TxMic = params->key + 16;
1007 KeyLen = params->key_len - 16;
1008 }
1009
1010 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
1011 g_add_gtk_key_params.key_idx = key_index;
1012 g_add_gtk_key_params.pairwise = pairwise;
1013 if (!mac_addr) {
1014 g_add_gtk_key_params.mac_addr = NULL;
1015 } else {
1016 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1017 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1018 }
1019 g_key_gtk_params.key_len = params->key_len;
1020 g_key_gtk_params.seq_len = params->seq_len;
1021 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1022 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1023 if (params->seq_len > 0) {
1024 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1025 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1026 }
1027 g_key_gtk_params.cipher = params->cipher;
1028 g_gtk_keys_saved = true;
1029 }
1030
1031 wilc_add_rx_gtk(vif, params->key, KeyLen,
1032 key_index, params->seq_len,
1033 params->seq, pu8RxMic,
1034 pu8TxMic, STATION_MODE,
1035 u8mode);
1036 } else {
1037 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1038 pu8RxMic = params->key + 24;
1039 pu8TxMic = params->key + 16;
1040 KeyLen = params->key_len - 16;
1041 }
1042
1043 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1044 g_add_ptk_key_params.key_idx = key_index;
1045 g_add_ptk_key_params.pairwise = pairwise;
1046 if (!mac_addr) {
1047 g_add_ptk_key_params.mac_addr = NULL;
1048 } else {
1049 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1050 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1051 }
1052 g_key_ptk_params.key_len = params->key_len;
1053 g_key_ptk_params.seq_len = params->seq_len;
1054 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1055 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1056 if (params->seq_len > 0) {
1057 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1058 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1059 }
1060 g_key_ptk_params.cipher = params->cipher;
1061 g_ptk_keys_saved = true;
1062 }
1063
1064 wilc_add_ptk(vif, params->key, KeyLen,
1065 mac_addr, pu8RxMic, pu8TxMic,
1066 STATION_MODE, u8mode, key_index);
1067 }
1068 }
1069 break;
1070
1071 default:
1072 netdev_err(netdev, "Not supported cipher\n");
1073 s32Error = -ENOTSUPP;
1074 }
1075
1076 return s32Error;
1077 }
1078
del_key(struct wiphy * wiphy,struct net_device * netdev,u8 key_index,bool pairwise,const u8 * mac_addr)1079 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1080 u8 key_index,
1081 bool pairwise,
1082 const u8 *mac_addr)
1083 {
1084 struct wilc_priv *priv;
1085 struct wilc *wl;
1086 struct wilc_vif *vif;
1087
1088 priv = wiphy_priv(wiphy);
1089 vif = netdev_priv(netdev);
1090 wl = vif->wilc;
1091
1092 if (netdev == wl->vif[0]->ndev) {
1093 g_ptk_keys_saved = false;
1094 g_gtk_keys_saved = false;
1095 g_wep_keys_saved = false;
1096
1097 kfree(g_key_wep_params.key);
1098 g_key_wep_params.key = NULL;
1099
1100 if ((priv->wilc_gtk[key_index]) != NULL) {
1101 kfree(priv->wilc_gtk[key_index]->key);
1102 priv->wilc_gtk[key_index]->key = NULL;
1103 kfree(priv->wilc_gtk[key_index]->seq);
1104 priv->wilc_gtk[key_index]->seq = NULL;
1105
1106 kfree(priv->wilc_gtk[key_index]);
1107 priv->wilc_gtk[key_index] = NULL;
1108 }
1109
1110 if ((priv->wilc_ptk[key_index]) != NULL) {
1111 kfree(priv->wilc_ptk[key_index]->key);
1112 priv->wilc_ptk[key_index]->key = NULL;
1113 kfree(priv->wilc_ptk[key_index]->seq);
1114 priv->wilc_ptk[key_index]->seq = NULL;
1115 kfree(priv->wilc_ptk[key_index]);
1116 priv->wilc_ptk[key_index] = NULL;
1117 }
1118
1119 kfree(g_key_ptk_params.key);
1120 g_key_ptk_params.key = NULL;
1121 kfree(g_key_ptk_params.seq);
1122 g_key_ptk_params.seq = NULL;
1123
1124 kfree(g_key_gtk_params.key);
1125 g_key_gtk_params.key = NULL;
1126 kfree(g_key_gtk_params.seq);
1127 g_key_gtk_params.seq = NULL;
1128
1129 }
1130
1131 if (key_index >= 0 && key_index <= 3) {
1132 if (priv->WILC_WFI_wep_key_len[key_index]) {
1133 memset(priv->WILC_WFI_wep_key[key_index], 0,
1134 priv->WILC_WFI_wep_key_len[key_index]);
1135 priv->WILC_WFI_wep_key_len[key_index] = 0;
1136 wilc_remove_wep_key(vif, key_index);
1137 }
1138 } else {
1139 wilc_remove_key(priv->hif_drv, mac_addr);
1140 }
1141
1142 return 0;
1143 }
1144
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 *))1145 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1146 bool pairwise,
1147 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1148 {
1149 struct wilc_priv *priv;
1150 struct key_params key_params;
1151
1152 priv = wiphy_priv(wiphy);
1153
1154
1155 if (!pairwise) {
1156 key_params.key = priv->wilc_gtk[key_index]->key;
1157 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1158 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1159 key_params.seq = priv->wilc_gtk[key_index]->seq;
1160 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1161 } else {
1162 key_params.key = priv->wilc_ptk[key_index]->key;
1163 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1164 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1165 key_params.seq = priv->wilc_ptk[key_index]->seq;
1166 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1167 }
1168
1169 callback(cookie, &key_params);
1170
1171 return 0;
1172 }
1173
set_default_key(struct wiphy * wiphy,struct net_device * netdev,u8 key_index,bool unicast,bool multicast)1174 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1175 bool unicast, bool multicast)
1176 {
1177 struct wilc_priv *priv;
1178 struct wilc_vif *vif;
1179
1180 priv = wiphy_priv(wiphy);
1181 vif = netdev_priv(priv->dev);
1182
1183 wilc_set_wep_default_keyid(vif, key_index);
1184
1185 return 0;
1186 }
1187
get_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_info * sinfo)1188 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1189 const u8 *mac, struct station_info *sinfo)
1190 {
1191 struct wilc_priv *priv;
1192 struct wilc_vif *vif;
1193 u32 i = 0;
1194 u32 associatedsta = ~0;
1195 u32 inactive_time = 0;
1196 priv = wiphy_priv(wiphy);
1197 vif = netdev_priv(dev);
1198
1199 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1200 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1201 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1202 associatedsta = i;
1203 break;
1204 }
1205 }
1206
1207 if (associatedsta == ~0) {
1208 netdev_err(dev, "sta required is not associated\n");
1209 return -ENOENT;
1210 }
1211
1212 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1213
1214 wilc_get_inactive_time(vif, mac, &inactive_time);
1215 sinfo->inactive_time = 1000 * inactive_time;
1216 }
1217
1218 if (vif->iftype == STATION_MODE) {
1219 struct rf_info strStatistics;
1220
1221 wilc_get_statistics(vif, &strStatistics);
1222
1223 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1224 BIT(NL80211_STA_INFO_RX_PACKETS) |
1225 BIT(NL80211_STA_INFO_TX_PACKETS) |
1226 BIT(NL80211_STA_INFO_TX_FAILED) |
1227 BIT(NL80211_STA_INFO_TX_BITRATE);
1228
1229 sinfo->signal = strStatistics.rssi;
1230 sinfo->rx_packets = strStatistics.rx_cnt;
1231 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1232 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1233 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1234
1235 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1236 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1237 wilc_enable_tcp_ack_filter(true);
1238 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1239 wilc_enable_tcp_ack_filter(false);
1240 }
1241 return 0;
1242 }
1243
change_bss(struct wiphy * wiphy,struct net_device * dev,struct bss_parameters * params)1244 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1245 struct bss_parameters *params)
1246 {
1247 return 0;
1248 }
1249
set_wiphy_params(struct wiphy * wiphy,u32 changed)1250 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1251 {
1252 s32 s32Error = 0;
1253 struct cfg_param_attr pstrCfgParamVal;
1254 struct wilc_priv *priv;
1255 struct wilc_vif *vif;
1256
1257 priv = wiphy_priv(wiphy);
1258 vif = netdev_priv(priv->dev);
1259
1260 pstrCfgParamVal.flag = 0;
1261
1262 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1263 pstrCfgParamVal.flag |= RETRY_SHORT;
1264 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1265 }
1266 if (changed & WIPHY_PARAM_RETRY_LONG) {
1267 pstrCfgParamVal.flag |= RETRY_LONG;
1268 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1269 }
1270 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1271 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1272 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1273 }
1274
1275 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1276 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1277 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1278 }
1279
1280 s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1281 if (s32Error)
1282 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1283
1284 return s32Error;
1285 }
1286
set_pmksa(struct wiphy * wiphy,struct net_device * netdev,struct cfg80211_pmksa * pmksa)1287 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1288 struct cfg80211_pmksa *pmksa)
1289 {
1290 u32 i;
1291 s32 s32Error = 0;
1292 u8 flag = 0;
1293 struct wilc_vif *vif;
1294 struct wilc_priv *priv = wiphy_priv(wiphy);
1295
1296 vif = netdev_priv(priv->dev);
1297
1298
1299 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1300 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1301 ETH_ALEN)) {
1302 flag = PMKID_FOUND;
1303 break;
1304 }
1305 }
1306 if (i < WILC_MAX_NUM_PMKIDS) {
1307 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1308 ETH_ALEN);
1309 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1310 PMKID_LEN);
1311 if (!(flag == PMKID_FOUND))
1312 priv->pmkid_list.numpmkid++;
1313 } else {
1314 netdev_err(netdev, "Invalid PMKID index\n");
1315 s32Error = -EINVAL;
1316 }
1317
1318 if (!s32Error)
1319 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1320
1321 return s32Error;
1322 }
1323
del_pmksa(struct wiphy * wiphy,struct net_device * netdev,struct cfg80211_pmksa * pmksa)1324 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1325 struct cfg80211_pmksa *pmksa)
1326 {
1327 u32 i;
1328 s32 s32Error = 0;
1329
1330 struct wilc_priv *priv = wiphy_priv(wiphy);
1331
1332 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1333 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1334 ETH_ALEN)) {
1335 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1336 break;
1337 }
1338 }
1339
1340 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1341 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1342 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1343 priv->pmkid_list.pmkidlist[i + 1].bssid,
1344 ETH_ALEN);
1345 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1346 priv->pmkid_list.pmkidlist[i].pmkid,
1347 PMKID_LEN);
1348 }
1349 priv->pmkid_list.numpmkid--;
1350 } else {
1351 s32Error = -EINVAL;
1352 }
1353
1354 return s32Error;
1355 }
1356
flush_pmksa(struct wiphy * wiphy,struct net_device * netdev)1357 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1358 {
1359 struct wilc_priv *priv = wiphy_priv(wiphy);
1360
1361 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1362
1363 return 0;
1364 }
1365
WILC_WFI_CfgParseRxAction(u8 * buf,u32 len)1366 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1367 {
1368 u32 index = 0;
1369 u32 i = 0, j = 0;
1370
1371 u8 op_channel_attr_index = 0;
1372 u8 channel_list_attr_index = 0;
1373
1374 while (index < len) {
1375 if (buf[index] == GO_INTENT_ATTR_ID)
1376 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
1377
1378 if (buf[index] == CHANLIST_ATTR_ID)
1379 channel_list_attr_index = index;
1380 else if (buf[index] == OPERCHAN_ATTR_ID)
1381 op_channel_attr_index = index;
1382 index += buf[index + 1] + 3;
1383 }
1384 if (wlan_channel != INVALID_CHANNEL) {
1385 if (channel_list_attr_index) {
1386 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1387 if (buf[i] == 0x51) {
1388 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1389 buf[j] = wlan_channel;
1390 break;
1391 }
1392 }
1393 }
1394
1395 if (op_channel_attr_index) {
1396 buf[op_channel_attr_index + 6] = 0x51;
1397 buf[op_channel_attr_index + 7] = wlan_channel;
1398 }
1399 }
1400 }
1401
WILC_WFI_CfgParseTxAction(u8 * buf,u32 len,bool bOperChan,u8 iftype)1402 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1403 {
1404 u32 index = 0;
1405 u32 i = 0, j = 0;
1406
1407 u8 op_channel_attr_index = 0;
1408 u8 channel_list_attr_index = 0;
1409
1410 while (index < len) {
1411 if (buf[index] == GO_INTENT_ATTR_ID) {
1412 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
1413
1414 break;
1415 }
1416
1417 if (buf[index] == CHANLIST_ATTR_ID)
1418 channel_list_attr_index = index;
1419 else if (buf[index] == OPERCHAN_ATTR_ID)
1420 op_channel_attr_index = index;
1421 index += buf[index + 1] + 3;
1422 }
1423 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1424 if (channel_list_attr_index) {
1425 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1426 if (buf[i] == 0x51) {
1427 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1428 buf[j] = wlan_channel;
1429 break;
1430 }
1431 }
1432 }
1433
1434 if (op_channel_attr_index) {
1435 buf[op_channel_attr_index + 6] = 0x51;
1436 buf[op_channel_attr_index + 7] = wlan_channel;
1437 }
1438 }
1439 }
1440
WILC_WFI_p2p_rx(struct net_device * dev,u8 * buff,u32 size)1441 void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
1442 {
1443 struct wilc_priv *priv;
1444 u32 header, pkt_offset;
1445 struct host_if_drv *pstrWFIDrv;
1446 u32 i = 0;
1447 s32 s32Freq;
1448
1449 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1450 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1451
1452 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1453
1454 pkt_offset = GET_PKT_OFFSET(header);
1455
1456 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1457 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1458 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1459 return;
1460 } else {
1461 if (pkt_offset & IS_MGMT_STATUS_SUCCES)
1462 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1463 else
1464 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1465 return;
1466 }
1467 } else {
1468 s32Freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ);
1469
1470 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1471 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1472 netdev_dbg(dev, "Receiving action wrong ch\n");
1473 return;
1474 }
1475 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1476 switch (buff[ACTION_SUBTYPE_ID]) {
1477 case GAS_INTIAL_REQ:
1478 break;
1479
1480 case GAS_INTIAL_RSP:
1481 break;
1482
1483 case PUBLIC_ACT_VENDORSPEC:
1484 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1485 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1486 if (!wilc_ie) {
1487 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1488 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1489 p2p_recv_random = buff[i + 6];
1490 wilc_ie = true;
1491 break;
1492 }
1493 }
1494 }
1495 }
1496 if (p2p_local_random > p2p_recv_random) {
1497 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1498 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1499 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1500 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1501 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1502 break;
1503 }
1504 }
1505 }
1506 } else {
1507 netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1508 }
1509 }
1510
1511
1512 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
1513 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1514 return;
1515 }
1516 break;
1517
1518 default:
1519 netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1520 break;
1521 }
1522 }
1523 }
1524
1525 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1526 }
1527 }
1528
WILC_WFI_mgmt_tx_complete(void * priv,int status)1529 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1530 {
1531 struct p2p_mgmt_data *pv_data = priv;
1532
1533
1534 kfree(pv_data->buff);
1535 kfree(pv_data);
1536 }
1537
WILC_WFI_RemainOnChannelReady(void * pUserVoid)1538 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1539 {
1540 struct wilc_priv *priv;
1541
1542 priv = pUserVoid;
1543
1544 priv->bInP2PlistenState = true;
1545
1546 cfg80211_ready_on_channel(priv->wdev,
1547 priv->strRemainOnChanParams.u64ListenCookie,
1548 priv->strRemainOnChanParams.pstrListenChan,
1549 priv->strRemainOnChanParams.u32ListenDuration,
1550 GFP_KERNEL);
1551 }
1552
WILC_WFI_RemainOnChannelExpired(void * pUserVoid,u32 u32SessionID)1553 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1554 {
1555 struct wilc_priv *priv;
1556
1557 priv = pUserVoid;
1558
1559 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1560 priv->bInP2PlistenState = false;
1561
1562 cfg80211_remain_on_channel_expired(priv->wdev,
1563 priv->strRemainOnChanParams.u64ListenCookie,
1564 priv->strRemainOnChanParams.pstrListenChan,
1565 GFP_KERNEL);
1566 }
1567 }
1568
remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,struct ieee80211_channel * chan,unsigned int duration,u64 * cookie)1569 static int remain_on_channel(struct wiphy *wiphy,
1570 struct wireless_dev *wdev,
1571 struct ieee80211_channel *chan,
1572 unsigned int duration, u64 *cookie)
1573 {
1574 s32 s32Error = 0;
1575 struct wilc_priv *priv;
1576 struct wilc_vif *vif;
1577
1578 priv = wiphy_priv(wiphy);
1579 vif = netdev_priv(priv->dev);
1580
1581 if (wdev->iftype == NL80211_IFTYPE_AP) {
1582 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1583 return s32Error;
1584 }
1585
1586 curr_channel = chan->hw_value;
1587
1588 priv->strRemainOnChanParams.pstrListenChan = chan;
1589 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1590 priv->strRemainOnChanParams.u32ListenDuration = duration;
1591 priv->strRemainOnChanParams.u32ListenSessionID++;
1592
1593 s32Error = wilc_remain_on_channel(vif,
1594 priv->strRemainOnChanParams.u32ListenSessionID,
1595 duration, chan->hw_value,
1596 WILC_WFI_RemainOnChannelExpired,
1597 WILC_WFI_RemainOnChannelReady, (void *)priv);
1598
1599 return s32Error;
1600 }
1601
cancel_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)1602 static int cancel_remain_on_channel(struct wiphy *wiphy,
1603 struct wireless_dev *wdev,
1604 u64 cookie)
1605 {
1606 s32 s32Error = 0;
1607 struct wilc_priv *priv;
1608 struct wilc_vif *vif;
1609
1610 priv = wiphy_priv(wiphy);
1611 vif = netdev_priv(priv->dev);
1612
1613 s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
1614 return s32Error;
1615 }
1616
mgmt_tx(struct wiphy * wiphy,struct wireless_dev * wdev,struct cfg80211_mgmt_tx_params * params,u64 * cookie)1617 static int mgmt_tx(struct wiphy *wiphy,
1618 struct wireless_dev *wdev,
1619 struct cfg80211_mgmt_tx_params *params,
1620 u64 *cookie)
1621 {
1622 struct ieee80211_channel *chan = params->chan;
1623 unsigned int wait = params->wait;
1624 const u8 *buf = params->buf;
1625 size_t len = params->len;
1626 const struct ieee80211_mgmt *mgmt;
1627 struct p2p_mgmt_data *mgmt_tx;
1628 struct wilc_priv *priv;
1629 struct host_if_drv *pstrWFIDrv;
1630 u32 i;
1631 struct wilc_vif *vif;
1632 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1633
1634 vif = netdev_priv(wdev->netdev);
1635 priv = wiphy_priv(wiphy);
1636 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1637
1638 *cookie = (unsigned long)buf;
1639 priv->u64tx_cookie = *cookie;
1640 mgmt = (const struct ieee80211_mgmt *) buf;
1641
1642 if (ieee80211_is_mgmt(mgmt->frame_control)) {
1643 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1644 if (!mgmt_tx)
1645 return -EFAULT;
1646
1647 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1648 if (!mgmt_tx->buff) {
1649 kfree(mgmt_tx);
1650 return -ENOMEM;
1651 }
1652
1653 memcpy(mgmt_tx->buff, buf, len);
1654 mgmt_tx->size = len;
1655
1656
1657 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1658 wilc_set_mac_chnl_num(vif, chan->hw_value);
1659 curr_channel = chan->hw_value;
1660 } else if (ieee80211_is_action(mgmt->frame_control)) {
1661 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1662 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1663 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1664 wilc_set_mac_chnl_num(vif,
1665 chan->hw_value);
1666 curr_channel = chan->hw_value;
1667 }
1668 switch (buf[ACTION_SUBTYPE_ID]) {
1669 case GAS_INTIAL_REQ:
1670 break;
1671
1672 case GAS_INTIAL_RSP:
1673 break;
1674
1675 case PUBLIC_ACT_VENDORSPEC:
1676 {
1677 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1678 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1679 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1680 get_random_bytes(&p2p_local_random, 1);
1681 p2p_local_random++;
1682 }
1683 }
1684
1685 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1686 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1687 if (p2p_local_random > p2p_recv_random) {
1688 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1689 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1690 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1691 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1692 else
1693 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1694 break;
1695 }
1696 }
1697
1698 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1699 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1700 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1701 mgmt_tx->size = buf_len;
1702 }
1703 }
1704 }
1705
1706 } else {
1707 netdev_dbg(vif->ndev, "Not a P2P public action frame\n");
1708 }
1709
1710 break;
1711 }
1712
1713 default:
1714 {
1715 netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1716 break;
1717 }
1718 }
1719 }
1720
1721 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1722 }
1723
1724 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1725 mgmt_tx->buff, mgmt_tx->size,
1726 WILC_WFI_mgmt_tx_complete);
1727 }
1728 return 0;
1729 }
1730
mgmt_tx_cancel_wait(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)1731 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1732 struct wireless_dev *wdev,
1733 u64 cookie)
1734 {
1735 struct wilc_priv *priv;
1736 struct host_if_drv *pstrWFIDrv;
1737
1738 priv = wiphy_priv(wiphy);
1739 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1740 pstrWFIDrv->p2p_timeout = jiffies;
1741
1742 if (!priv->bInP2PlistenState) {
1743 cfg80211_remain_on_channel_expired(priv->wdev,
1744 priv->strRemainOnChanParams.u64ListenCookie,
1745 priv->strRemainOnChanParams.pstrListenChan,
1746 GFP_KERNEL);
1747 }
1748
1749 return 0;
1750 }
1751
wilc_mgmt_frame_register(struct wiphy * wiphy,struct wireless_dev * wdev,u16 frame_type,bool reg)1752 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1753 u16 frame_type, bool reg)
1754 {
1755 struct wilc_priv *priv;
1756 struct wilc_vif *vif;
1757 struct wilc *wl;
1758
1759 priv = wiphy_priv(wiphy);
1760 vif = netdev_priv(priv->wdev->netdev);
1761 wl = vif->wilc;
1762
1763 if (!frame_type)
1764 return;
1765
1766 switch (frame_type) {
1767 case PROBE_REQ:
1768 {
1769 vif->frame_reg[0].type = frame_type;
1770 vif->frame_reg[0].reg = reg;
1771 }
1772 break;
1773
1774 case ACTION:
1775 {
1776 vif->frame_reg[1].type = frame_type;
1777 vif->frame_reg[1].reg = reg;
1778 }
1779 break;
1780
1781 default:
1782 {
1783 break;
1784 }
1785 }
1786
1787 if (!wl->initialized)
1788 return;
1789 wilc_frame_register(vif, frame_type, reg);
1790 }
1791
set_cqm_rssi_config(struct wiphy * wiphy,struct net_device * dev,s32 rssi_thold,u32 rssi_hyst)1792 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1793 s32 rssi_thold, u32 rssi_hyst)
1794 {
1795 return 0;
1796 }
1797
dump_station(struct wiphy * wiphy,struct net_device * dev,int idx,u8 * mac,struct station_info * sinfo)1798 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1799 int idx, u8 *mac, struct station_info *sinfo)
1800 {
1801 struct wilc_priv *priv;
1802 struct wilc_vif *vif;
1803
1804 if (idx != 0)
1805 return -ENOENT;
1806
1807 priv = wiphy_priv(wiphy);
1808 vif = netdev_priv(priv->dev);
1809
1810 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1811
1812 wilc_get_rssi(vif, &sinfo->signal);
1813
1814 memcpy(mac, priv->au8AssociatedBss, ETH_ALEN);
1815 return 0;
1816 }
1817
set_power_mgmt(struct wiphy * wiphy,struct net_device * dev,bool enabled,int timeout)1818 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1819 bool enabled, int timeout)
1820 {
1821 struct wilc_priv *priv;
1822 struct wilc_vif *vif;
1823
1824 if (!wiphy)
1825 return -ENOENT;
1826
1827 priv = wiphy_priv(wiphy);
1828 vif = netdev_priv(priv->dev);
1829 if (!priv->hif_drv)
1830 return -EIO;
1831
1832 if (wilc_enable_ps)
1833 wilc_set_power_mgmt(vif, enabled, timeout);
1834
1835
1836 return 0;
1837 }
1838
change_virtual_intf(struct wiphy * wiphy,struct net_device * dev,enum nl80211_iftype type,u32 * flags,struct vif_params * params)1839 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1840 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
1841 {
1842 struct wilc_priv *priv;
1843 struct wilc_vif *vif;
1844 struct wilc *wl;
1845
1846 vif = netdev_priv(dev);
1847 priv = wiphy_priv(wiphy);
1848 wl = vif->wilc;
1849 p2p_local_random = 0x01;
1850 p2p_recv_random = 0x00;
1851 wilc_ie = false;
1852 wilc_optaining_ip = false;
1853 del_timer(&wilc_during_ip_timer);
1854
1855 switch (type) {
1856 case NL80211_IFTYPE_STATION:
1857 wilc_connecting = 0;
1858 dev->ieee80211_ptr->iftype = type;
1859 priv->wdev->iftype = type;
1860 vif->monitor_flag = 0;
1861 vif->iftype = STATION_MODE;
1862 wilc_set_operation_mode(vif, STATION_MODE);
1863
1864 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
1865
1866 wilc_enable_ps = true;
1867 wilc_set_power_mgmt(vif, 1, 0);
1868 break;
1869
1870 case NL80211_IFTYPE_P2P_CLIENT:
1871 wilc_connecting = 0;
1872 dev->ieee80211_ptr->iftype = type;
1873 priv->wdev->iftype = type;
1874 vif->monitor_flag = 0;
1875 vif->iftype = CLIENT_MODE;
1876 wilc_set_operation_mode(vif, STATION_MODE);
1877
1878 wilc_enable_ps = false;
1879 wilc_set_power_mgmt(vif, 0, 0);
1880 break;
1881
1882 case NL80211_IFTYPE_AP:
1883 wilc_enable_ps = false;
1884 dev->ieee80211_ptr->iftype = type;
1885 priv->wdev->iftype = type;
1886 vif->iftype = AP_MODE;
1887
1888 if (wl->initialized) {
1889 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
1890 0);
1891 wilc_set_operation_mode(vif, AP_MODE);
1892 wilc_set_power_mgmt(vif, 0, 0);
1893 }
1894 break;
1895
1896 case NL80211_IFTYPE_P2P_GO:
1897 wilc_optaining_ip = true;
1898 mod_timer(&wilc_during_ip_timer,
1899 jiffies + msecs_to_jiffies(during_ip_time));
1900 wilc_set_operation_mode(vif, AP_MODE);
1901 dev->ieee80211_ptr->iftype = type;
1902 priv->wdev->iftype = type;
1903 vif->iftype = GO_MODE;
1904
1905 wilc_enable_ps = false;
1906 wilc_set_power_mgmt(vif, 0, 0);
1907 break;
1908
1909 default:
1910 netdev_err(dev, "Unknown interface type= %d\n", type);
1911 return -EINVAL;
1912 }
1913
1914 return 0;
1915 }
1916
start_ap(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_ap_settings * settings)1917 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1918 struct cfg80211_ap_settings *settings)
1919 {
1920 struct cfg80211_beacon_data *beacon = &(settings->beacon);
1921 struct wilc_priv *priv;
1922 s32 s32Error = 0;
1923 struct wilc *wl;
1924 struct wilc_vif *vif;
1925
1926 priv = wiphy_priv(wiphy);
1927 vif = netdev_priv(dev);
1928 wl = vif->wilc;
1929
1930 s32Error = set_channel(wiphy, &settings->chandef);
1931
1932 if (s32Error != 0)
1933 netdev_err(dev, "Error in setting channel\n");
1934
1935 wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
1936 wilc_set_power_mgmt(vif, 0, 0);
1937
1938 s32Error = wilc_add_beacon(vif, settings->beacon_interval,
1939 settings->dtim_period, beacon->head_len,
1940 (u8 *)beacon->head, beacon->tail_len,
1941 (u8 *)beacon->tail);
1942
1943 return s32Error;
1944 }
1945
change_beacon(struct wiphy * wiphy,struct net_device * dev,struct cfg80211_beacon_data * beacon)1946 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1947 struct cfg80211_beacon_data *beacon)
1948 {
1949 struct wilc_priv *priv;
1950 struct wilc_vif *vif;
1951 s32 s32Error = 0;
1952
1953 priv = wiphy_priv(wiphy);
1954 vif = netdev_priv(priv->dev);
1955
1956 s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
1957 (u8 *)beacon->head, beacon->tail_len,
1958 (u8 *)beacon->tail);
1959
1960 return s32Error;
1961 }
1962
stop_ap(struct wiphy * wiphy,struct net_device * dev)1963 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1964 {
1965 s32 s32Error = 0;
1966 struct wilc_priv *priv;
1967 struct wilc_vif *vif;
1968 u8 NullBssid[ETH_ALEN] = {0};
1969
1970 if (!wiphy)
1971 return -EFAULT;
1972
1973 priv = wiphy_priv(wiphy);
1974 vif = netdev_priv(priv->dev);
1975
1976 wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
1977
1978 s32Error = wilc_del_beacon(vif);
1979
1980 if (s32Error)
1981 netdev_err(dev, "Host delete beacon fail\n");
1982
1983 return s32Error;
1984 }
1985
add_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_parameters * params)1986 static int add_station(struct wiphy *wiphy, struct net_device *dev,
1987 const u8 *mac, struct station_parameters *params)
1988 {
1989 s32 s32Error = 0;
1990 struct wilc_priv *priv;
1991 struct add_sta_param strStaParams = { {0} };
1992 struct wilc_vif *vif;
1993
1994 if (!wiphy)
1995 return -EFAULT;
1996
1997 priv = wiphy_priv(wiphy);
1998 vif = netdev_priv(dev);
1999
2000 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2001 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2002 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
2003 strStaParams.aid = params->aid;
2004 strStaParams.rates_len = params->supported_rates_len;
2005 strStaParams.rates = params->supported_rates;
2006
2007 if (!params->ht_capa) {
2008 strStaParams.ht_supported = false;
2009 } else {
2010 strStaParams.ht_supported = true;
2011 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2012 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2013 memcpy(strStaParams.ht_supp_mcs_set,
2014 ¶ms->ht_capa->mcs,
2015 WILC_SUPP_MCS_SET_SIZE);
2016 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2017 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2018 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2019 }
2020
2021 strStaParams.flags_mask = params->sta_flags_mask;
2022 strStaParams.flags_set = params->sta_flags_set;
2023
2024 s32Error = wilc_add_station(vif, &strStaParams);
2025 if (s32Error)
2026 netdev_err(dev, "Host add station fail\n");
2027 }
2028
2029 return s32Error;
2030 }
2031
del_station(struct wiphy * wiphy,struct net_device * dev,struct station_del_parameters * params)2032 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2033 struct station_del_parameters *params)
2034 {
2035 const u8 *mac = params->mac;
2036 s32 s32Error = 0;
2037 struct wilc_priv *priv;
2038 struct wilc_vif *vif;
2039
2040 if (!wiphy)
2041 return -EFAULT;
2042
2043 priv = wiphy_priv(wiphy);
2044 vif = netdev_priv(dev);
2045
2046 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2047 if (!mac)
2048 s32Error = wilc_del_allstation(vif,
2049 priv->assoc_stainfo.au8Sta_AssociatedBss);
2050
2051 s32Error = wilc_del_station(vif, mac);
2052
2053 if (s32Error)
2054 netdev_err(dev, "Host delete station fail\n");
2055 }
2056 return s32Error;
2057 }
2058
change_station(struct wiphy * wiphy,struct net_device * dev,const u8 * mac,struct station_parameters * params)2059 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2060 const u8 *mac, struct station_parameters *params)
2061 {
2062 s32 s32Error = 0;
2063 struct wilc_priv *priv;
2064 struct add_sta_param strStaParams = { {0} };
2065 struct wilc_vif *vif;
2066
2067 if (!wiphy)
2068 return -EFAULT;
2069
2070 priv = wiphy_priv(wiphy);
2071 vif = netdev_priv(dev);
2072
2073 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2074 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2075 strStaParams.aid = params->aid;
2076 strStaParams.rates_len = params->supported_rates_len;
2077 strStaParams.rates = params->supported_rates;
2078
2079 if (!params->ht_capa) {
2080 strStaParams.ht_supported = false;
2081 } else {
2082 strStaParams.ht_supported = true;
2083 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2084 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2085 memcpy(strStaParams.ht_supp_mcs_set,
2086 ¶ms->ht_capa->mcs,
2087 WILC_SUPP_MCS_SET_SIZE);
2088 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2089 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2090 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2091 }
2092
2093 strStaParams.flags_mask = params->sta_flags_mask;
2094 strStaParams.flags_set = params->sta_flags_set;
2095
2096 s32Error = wilc_edit_station(vif, &strStaParams);
2097 if (s32Error)
2098 netdev_err(dev, "Host edit station fail\n");
2099 }
2100 return s32Error;
2101 }
2102
add_virtual_intf(struct wiphy * wiphy,const char * name,unsigned char name_assign_type,enum nl80211_iftype type,u32 * flags,struct vif_params * params)2103 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2104 const char *name,
2105 unsigned char name_assign_type,
2106 enum nl80211_iftype type,
2107 u32 *flags,
2108 struct vif_params *params)
2109 {
2110 struct wilc_vif *vif;
2111 struct wilc_priv *priv;
2112 struct net_device *new_ifc = NULL;
2113
2114 priv = wiphy_priv(wiphy);
2115 vif = netdev_priv(priv->wdev->netdev);
2116
2117
2118 if (type == NL80211_IFTYPE_MONITOR) {
2119 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2120 if (new_ifc) {
2121 vif = netdev_priv(priv->wdev->netdev);
2122 vif->monitor_flag = 1;
2123 }
2124 }
2125 return priv->wdev;
2126 }
2127
del_virtual_intf(struct wiphy * wiphy,struct wireless_dev * wdev)2128 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2129 {
2130 return 0;
2131 }
2132
wilc_suspend(struct wiphy * wiphy,struct cfg80211_wowlan * wow)2133 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2134 {
2135 struct wilc_priv *priv = wiphy_priv(wiphy);
2136 struct wilc_vif *vif = netdev_priv(priv->dev);
2137
2138 if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2139 vif->wilc->suspend_event = true;
2140 else
2141 vif->wilc->suspend_event = false;
2142
2143 return 0;
2144 }
2145
wilc_resume(struct wiphy * wiphy)2146 static int wilc_resume(struct wiphy *wiphy)
2147 {
2148 struct wilc_priv *priv = wiphy_priv(wiphy);
2149 struct wilc_vif *vif = netdev_priv(priv->dev);
2150
2151 netdev_info(vif->ndev, "cfg resume\n");
2152 return 0;
2153 }
2154
wilc_set_wakeup(struct wiphy * wiphy,bool enabled)2155 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2156 {
2157 struct wilc_priv *priv = wiphy_priv(wiphy);
2158 struct wilc_vif *vif = netdev_priv(priv->dev);
2159
2160 netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2161 }
2162
set_tx_power(struct wiphy * wiphy,struct wireless_dev * wdev,enum nl80211_tx_power_setting type,int mbm)2163 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2164 enum nl80211_tx_power_setting type, int mbm)
2165 {
2166 int ret;
2167 s32 tx_power = MBM_TO_DBM(mbm);
2168 struct wilc_priv *priv = wiphy_priv(wiphy);
2169 struct wilc_vif *vif = netdev_priv(priv->dev);
2170
2171 if (tx_power < 0)
2172 tx_power = 0;
2173 else if (tx_power > 18)
2174 tx_power = 18;
2175 ret = wilc_set_tx_power(vif, tx_power);
2176 if (ret)
2177 netdev_err(vif->ndev, "Failed to set tx power\n");
2178
2179 return ret;
2180 }
2181
get_tx_power(struct wiphy * wiphy,struct wireless_dev * wdev,int * dbm)2182 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2183 int *dbm)
2184 {
2185 int ret;
2186 struct wilc_priv *priv = wiphy_priv(wiphy);
2187 struct wilc_vif *vif = netdev_priv(priv->dev);
2188 struct wilc *wl;
2189
2190 wl = vif->wilc;
2191
2192 /* If firmware is not started, return. */
2193 if (!wl->initialized)
2194 return -EIO;
2195
2196 ret = wilc_get_tx_power(vif, (u8 *)dbm);
2197 if (ret)
2198 netdev_err(vif->ndev, "Failed to get tx power\n");
2199
2200 return ret;
2201 }
2202
2203 static const struct cfg80211_ops wilc_cfg80211_ops = {
2204 .set_monitor_channel = set_channel,
2205 .scan = scan,
2206 .connect = connect,
2207 .disconnect = disconnect,
2208 .add_key = add_key,
2209 .del_key = del_key,
2210 .get_key = get_key,
2211 .set_default_key = set_default_key,
2212 .add_virtual_intf = add_virtual_intf,
2213 .del_virtual_intf = del_virtual_intf,
2214 .change_virtual_intf = change_virtual_intf,
2215
2216 .start_ap = start_ap,
2217 .change_beacon = change_beacon,
2218 .stop_ap = stop_ap,
2219 .add_station = add_station,
2220 .del_station = del_station,
2221 .change_station = change_station,
2222 .get_station = get_station,
2223 .dump_station = dump_station,
2224 .change_bss = change_bss,
2225 .set_wiphy_params = set_wiphy_params,
2226
2227 .set_pmksa = set_pmksa,
2228 .del_pmksa = del_pmksa,
2229 .flush_pmksa = flush_pmksa,
2230 .remain_on_channel = remain_on_channel,
2231 .cancel_remain_on_channel = cancel_remain_on_channel,
2232 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2233 .mgmt_tx = mgmt_tx,
2234 .mgmt_frame_register = wilc_mgmt_frame_register,
2235 .set_power_mgmt = set_power_mgmt,
2236 .set_cqm_rssi_config = set_cqm_rssi_config,
2237
2238 .suspend = wilc_suspend,
2239 .resume = wilc_resume,
2240 .set_wakeup = wilc_set_wakeup,
2241 .set_tx_power = set_tx_power,
2242 .get_tx_power = get_tx_power,
2243
2244 };
2245
WILC_WFI_CfgAlloc(void)2246 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2247 {
2248 struct wireless_dev *wdev;
2249
2250 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2251 if (!wdev)
2252 goto _fail_;
2253
2254 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2255 if (!wdev->wiphy)
2256 goto _fail_mem_;
2257
2258 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2259 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2260 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2261 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2262 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2263
2264 wdev->wiphy->bands[NL80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2265
2266 return wdev;
2267
2268 _fail_mem_:
2269 kfree(wdev);
2270 _fail_:
2271 return NULL;
2272 }
2273
wilc_create_wiphy(struct net_device * net,struct device * dev)2274 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2275 {
2276 struct wilc_priv *priv;
2277 struct wireless_dev *wdev;
2278 s32 s32Error = 0;
2279
2280 wdev = WILC_WFI_CfgAlloc();
2281 if (!wdev) {
2282 netdev_err(net, "wiphy new allocate failed\n");
2283 return NULL;
2284 }
2285
2286 priv = wdev_priv(wdev);
2287 priv->wdev = wdev;
2288 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2289 #ifdef CONFIG_PM
2290 wdev->wiphy->wowlan = &wowlan_support;
2291 #endif
2292 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2293 wdev->wiphy->max_scan_ie_len = 1000;
2294 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2295 wdev->wiphy->cipher_suites = cipher_suites;
2296 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2297 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2298
2299 wdev->wiphy->max_remain_on_channel_duration = 500;
2300 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2301 BIT(NL80211_IFTYPE_P2P_CLIENT);
2302 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2303 wdev->iftype = NL80211_IFTYPE_STATION;
2304
2305 set_wiphy_dev(wdev->wiphy, dev);
2306
2307 s32Error = wiphy_register(wdev->wiphy);
2308 if (s32Error)
2309 netdev_err(net, "Cannot register wiphy device\n");
2310
2311 priv->dev = net;
2312 return wdev;
2313 }
2314
wilc_init_host_int(struct net_device * net)2315 int wilc_init_host_int(struct net_device *net)
2316 {
2317 int s32Error = 0;
2318
2319 struct wilc_priv *priv;
2320
2321 priv = wdev_priv(net->ieee80211_ptr);
2322 if (op_ifcs == 0) {
2323 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2324 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2325 }
2326 op_ifcs++;
2327
2328 priv->gbAutoRateAdjusted = false;
2329
2330 priv->bInP2PlistenState = false;
2331
2332 mutex_init(&priv->scan_req_lock);
2333 s32Error = wilc_init(net, &priv->hif_drv);
2334 if (s32Error)
2335 netdev_err(net, "Error while initializing hostinterface\n");
2336
2337 return s32Error;
2338 }
2339
wilc_deinit_host_int(struct net_device * net)2340 int wilc_deinit_host_int(struct net_device *net)
2341 {
2342 int s32Error = 0;
2343 struct wilc_vif *vif;
2344 struct wilc_priv *priv;
2345
2346 priv = wdev_priv(net->ieee80211_ptr);
2347 vif = netdev_priv(priv->dev);
2348
2349 priv->gbAutoRateAdjusted = false;
2350
2351 priv->bInP2PlistenState = false;
2352
2353 op_ifcs--;
2354
2355 s32Error = wilc_deinit(vif);
2356
2357 clear_shadow_scan();
2358 if (op_ifcs == 0)
2359 del_timer_sync(&wilc_during_ip_timer);
2360
2361 if (s32Error)
2362 netdev_err(net, "Error while deintializing host interface\n");
2363
2364 return s32Error;
2365 }
2366
wilc_free_wiphy(struct net_device * net)2367 void wilc_free_wiphy(struct net_device *net)
2368 {
2369 if (!net)
2370 return;
2371
2372 if (!net->ieee80211_ptr)
2373 return;
2374
2375 if (!net->ieee80211_ptr->wiphy)
2376 return;
2377
2378 wiphy_unregister(net->ieee80211_ptr->wiphy);
2379
2380 wiphy_free(net->ieee80211_ptr->wiphy);
2381 kfree(net->ieee80211_ptr);
2382 }
2383