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