staging: wilc1000: remove typedef from pstrNetworkInfo
[linux-2.6/btrfs-unstable.git] / drivers / staging / wilc1000 / wilc_wfi_cfgoperations.c
blobb6a50c6b94c7feaa908a58988a382e25a3136208
1 #include "wilc_wfi_cfgoperations.h"
2 #include "host_interface.h"
3 #include <linux/errno.h>
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)
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
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
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
35 #define INVALID_CHANNEL 0
37 #define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
38 #define SCAN_RESULT_EXPIRE (40 * HZ)
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,
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)
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)
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)
77 static const struct wiphy_wowlan_support wowlan_support = {
78 .flags = WIPHY_WOWLAN_ANY
81 #define WILC_WFI_DWELL_PASSIVE 100
82 #define WILC_WFI_DWELL_ACTIVE 40
84 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
85 #define DEFAULT_LINK_SPEED 72
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)
93 extern int wilc_mac_open(struct net_device *ndev);
94 extern int wilc_mac_close(struct net_device *ndev);
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;
102 u8 wilc_initialized = 1;
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, \
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),
130 #define RATETAB_ENT(_rate, _hw_value, _flags) { \
131 .bitrate = (_rate), \
132 .hw_value = (_hw_value), \
133 .flags = (_flags), \
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),
151 struct p2p_mgmt_data {
152 int size;
153 u8 *buff;
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;
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),
172 struct add_key_params {
173 u8 key_idx;
174 bool pairwise;
175 u8 *mac_addr;
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;
186 #define AGING_TIME (9 * 1000)
187 #define during_ip_time 15000
189 static void clear_shadow_scan(void)
191 int i;
193 if (op_ifcs == 0) {
194 del_timer_sync(&hAgingTimer);
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;
202 kfree(last_scanned_shadow[i].pJoinParams);
203 last_scanned_shadow[i].pJoinParams = NULL;
205 last_scanned_cnt = 0;
209 static u32 get_rssi_avg(struct network_info *network_info)
211 u8 i;
212 int rssi_v = 0;
213 u8 num_rssi = (network_info->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index);
215 for (i = 0; i < num_rssi; i++)
216 rssi_v += network_info->strRssi.as8RSSI[i];
218 rssi_v /= num_rssi;
219 return rssi_v;
222 static void refresh_scan(void *user_void, u8 all, bool direct_scan)
224 struct wilc_priv *priv;
225 struct wiphy *wiphy;
226 struct cfg80211_bss *bss = NULL;
227 int i;
228 int rssi = 0;
230 priv = (struct wilc_priv *)user_void;
231 wiphy = priv->dev->ieee80211_ptr->wiphy;
233 for (i = 0; i < last_scanned_cnt; i++) {
234 struct network_info *network_info;
236 network_info = &last_scanned_shadow[i];
238 if (!network_info->u8Found || all) {
239 s32 freq;
240 struct ieee80211_channel *channel;
242 if (network_info) {
243 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
244 channel = ieee80211_get_channel(wiphy, freq);
246 rssi = get_rssi_avg(network_info);
247 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
248 direct_scan) {
249 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
250 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
251 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
252 cfg80211_put_bss(wiphy, bss);
259 static void reset_shadow_found(void)
261 int i;
263 for (i = 0; i < last_scanned_cnt; i++)
264 last_scanned_shadow[i].u8Found = 0;
267 static void update_scan_time(void)
269 int i;
271 for (i = 0; i < last_scanned_cnt; i++)
272 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
275 static void remove_network_from_shadow(unsigned long arg)
277 unsigned long now = jiffies;
278 int i, j;
281 for (i = 0; i < last_scanned_cnt; i++) {
282 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
283 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
285 kfree(last_scanned_shadow[i].pu8IEs);
286 last_scanned_shadow[i].pu8IEs = NULL;
288 kfree(last_scanned_shadow[i].pJoinParams);
290 for (j = i; (j < last_scanned_cnt - 1); j++)
291 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
293 last_scanned_cnt--;
297 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
298 last_scanned_cnt);
299 if (last_scanned_cnt != 0) {
300 hAgingTimer.data = arg;
301 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
302 } else {
303 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
307 static void clear_duringIP(unsigned long arg)
309 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
310 wilc_optaining_ip = false;
313 static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
314 void *user_void)
316 int state = -1;
317 int i;
319 if (last_scanned_cnt == 0) {
320 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
321 hAgingTimer.data = (unsigned long)user_void;
322 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
323 state = -1;
324 } else {
325 for (i = 0; i < last_scanned_cnt; i++) {
326 if (memcmp(last_scanned_shadow[i].au8bssid,
327 pstrNetworkInfo->au8bssid, 6) == 0) {
328 state = i;
329 break;
333 return state;
336 static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
337 void *user_void, void *pJoinParams)
339 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
340 u32 ap_index = 0;
341 u8 rssi_index = 0;
343 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
344 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
345 return;
347 if (ap_found == -1) {
348 ap_index = last_scanned_cnt;
349 last_scanned_cnt++;
350 } else {
351 ap_index = ap_found;
353 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
354 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
355 if (rssi_index == NUM_RSSI) {
356 rssi_index = 0;
357 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
359 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
360 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
361 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
362 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
363 memcpy(last_scanned_shadow[ap_index].au8ssid,
364 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
365 memcpy(last_scanned_shadow[ap_index].au8bssid,
366 pstrNetworkInfo->au8bssid, ETH_ALEN);
367 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
368 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
369 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
370 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
371 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
372 if (ap_found != -1)
373 kfree(last_scanned_shadow[ap_index].pu8IEs);
374 last_scanned_shadow[ap_index].pu8IEs =
375 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);
376 memcpy(last_scanned_shadow[ap_index].pu8IEs,
377 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
378 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
379 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
380 last_scanned_shadow[ap_index].u8Found = 1;
381 if (ap_found != -1)
382 kfree(last_scanned_shadow[ap_index].pJoinParams);
383 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
386 static void CfgScanResult(enum scan_event scan_event,
387 struct network_info *network_info,
388 void *user_void,
389 void *join_params)
391 struct wilc_priv *priv;
392 struct wiphy *wiphy;
393 s32 s32Freq;
394 struct ieee80211_channel *channel;
395 struct cfg80211_bss *bss = NULL;
397 priv = (struct wilc_priv *)user_void;
398 if (priv->bCfgScanning) {
399 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
400 wiphy = priv->dev->ieee80211_ptr->wiphy;
402 if (!wiphy)
403 return;
405 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
406 (((s32)network_info->s8rssi * 100) < 0 ||
407 ((s32)network_info->s8rssi * 100) > 100))
408 return;
410 if (network_info) {
411 s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
412 channel = ieee80211_get_channel(wiphy, s32Freq);
414 if (!channel)
415 return;
417 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
418 "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
419 network_info->u16CapInfo, network_info->u16BeaconPeriod);
421 if (network_info->bNewNetwork) {
422 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
423 PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
424 priv->u32RcvdChCount++;
426 add_network_to_shadow(network_info, priv, join_params);
428 if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
429 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
430 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
431 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
432 cfg80211_put_bss(wiphy, bss);
435 } else {
436 u32 i;
438 for (i = 0; i < priv->u32RcvdChCount; i++) {
439 if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
440 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
442 last_scanned_shadow[i].s8rssi = network_info->s8rssi;
443 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
444 break;
449 } else if (scan_event == SCAN_EVENT_DONE) {
450 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
451 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
452 refresh_scan(priv, 1, false);
454 if (priv->u32RcvdChCount > 0)
455 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
456 else
457 PRINT_D(CFG80211_DBG, "No networks found\n");
459 down(&(priv->hSemScanReq));
461 if (priv->pstrScanReq) {
462 cfg80211_scan_done(priv->pstrScanReq, false);
463 priv->u32RcvdChCount = 0;
464 priv->bCfgScanning = false;
465 priv->pstrScanReq = NULL;
467 up(&(priv->hSemScanReq));
468 } else if (scan_event == SCAN_EVENT_ABORTED) {
469 down(&(priv->hSemScanReq));
471 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
472 if (priv->pstrScanReq) {
473 update_scan_time();
474 refresh_scan(priv, 1, false);
476 cfg80211_scan_done(priv->pstrScanReq, false);
477 priv->bCfgScanning = false;
478 priv->pstrScanReq = NULL;
480 up(&(priv->hSemScanReq));
485 int wilc_connecting;
487 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
488 tstrConnectInfo *pstrConnectInfo,
489 u8 u8MacStatus,
490 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
491 void *pUserVoid)
493 struct wilc_priv *priv;
494 struct net_device *dev;
495 struct host_if_drv *pstrWFIDrv;
496 u8 NullBssid[ETH_ALEN] = {0};
497 struct wilc *wl;
498 struct wilc_vif *vif;
500 wilc_connecting = 0;
502 priv = (struct wilc_priv *)pUserVoid;
503 dev = priv->dev;
504 vif = netdev_priv(dev);
505 wl = vif->wilc;
506 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
508 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
509 u16 u16ConnectStatus;
511 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
513 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
515 if ((u8MacStatus == MAC_DISCONNECTED) &&
516 (pstrConnectInfo->u16ConnectStatus == 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);
522 if (!pstrWFIDrv->p2p_connect)
523 wlan_channel = INVALID_CHANNEL;
525 netdev_err(dev, "Unspecified failure\n");
528 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
529 bool bNeedScanRefresh = false;
530 u32 i;
532 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
533 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
534 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
537 for (i = 0; i < last_scanned_cnt; i++) {
538 if (memcmp(last_scanned_shadow[i].au8bssid,
539 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
540 unsigned long now = jiffies;
542 if (time_after(now,
543 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
544 bNeedScanRefresh = true;
547 break;
551 if (bNeedScanRefresh)
552 refresh_scan(priv, 1, true);
556 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
558 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
560 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
561 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
562 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
563 u16ConnectStatus, GFP_KERNEL);
564 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
565 wilc_optaining_ip = false;
566 p2p_local_random = 0x01;
567 p2p_recv_random = 0x00;
568 wilc_ie = false;
569 eth_zero_addr(priv->au8AssociatedBss);
570 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
571 eth_zero_addr(wilc_connected_ssid);
573 if (!pstrWFIDrv->p2p_connect)
574 wlan_channel = INVALID_CHANNEL;
575 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
576 pstrDisconnectNotifInfo->u16reason = 3;
577 } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
578 pstrDisconnectNotifInfo->u16reason = 1;
580 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
581 pstrDisconnectNotifInfo->ie_len, false,
582 GFP_KERNEL);
586 static int set_channel(struct wiphy *wiphy,
587 struct cfg80211_chan_def *chandef)
589 u32 channelnum = 0;
590 struct wilc_priv *priv;
591 int result = 0;
592 struct wilc_vif *vif;
594 priv = wiphy_priv(wiphy);
595 vif = netdev_priv(priv->dev);
597 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
598 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
600 curr_channel = channelnum;
601 result = wilc_set_mac_chnl_num(vif, channelnum);
603 if (result != 0)
604 netdev_err(priv->dev, "Error in setting channel\n");
606 return result;
609 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
611 struct wilc_priv *priv;
612 u32 i;
613 s32 s32Error = 0;
614 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
615 struct hidden_network strHiddenNetwork;
616 struct wilc_vif *vif;
618 priv = wiphy_priv(wiphy);
619 vif = netdev_priv(priv->dev);
621 priv->pstrScanReq = request;
623 priv->u32RcvdChCount = 0;
625 reset_shadow_found();
627 priv->bCfgScanning = true;
628 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
629 for (i = 0; i < request->n_channels; i++) {
630 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
631 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
634 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
635 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
637 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
639 if (request->n_ssids >= 1) {
640 strHiddenNetwork.net_info = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
641 strHiddenNetwork.n_ssids = request->n_ssids;
644 for (i = 0; i < request->n_ssids; i++) {
645 if (request->ssids[i].ssid &&
646 request->ssids[i].ssid_len != 0) {
647 strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
648 memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
649 strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
650 } else {
651 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
652 strHiddenNetwork.n_ssids -= 1;
655 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
656 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
657 au8ScanChanList,
658 request->n_channels,
659 (const u8 *)request->ie,
660 request->ie_len, CfgScanResult,
661 (void *)priv, &strHiddenNetwork);
662 } else {
663 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
664 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
665 au8ScanChanList,
666 request->n_channels,
667 (const u8 *)request->ie,
668 request->ie_len, CfgScanResult,
669 (void *)priv, NULL);
671 } else {
672 netdev_err(priv->dev, "Requested scanned channels over\n");
675 if (s32Error != 0) {
676 s32Error = -EBUSY;
677 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
680 return s32Error;
683 static int connect(struct wiphy *wiphy, struct net_device *dev,
684 struct cfg80211_connect_params *sme)
686 s32 s32Error = 0;
687 u32 i;
688 u8 u8security = NO_ENCRYPT;
689 enum AUTHTYPE tenuAuth_type = ANY;
690 char *pcgroup_encrypt_val = NULL;
691 char *pccipher_group = NULL;
692 char *pcwpa_version = NULL;
694 struct wilc_priv *priv;
695 struct host_if_drv *pstrWFIDrv;
696 struct network_info *pstrNetworkInfo = NULL;
697 struct wilc_vif *vif;
699 wilc_connecting = 1;
700 priv = wiphy_priv(wiphy);
701 vif = netdev_priv(priv->dev);
702 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
704 PRINT_D(CFG80211_DBG,
705 "Connecting to SSID [%s] on netdev [%p] host if [%p]\n",
706 sme->ssid, dev, priv->hif_drv);
707 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
708 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
709 pstrWFIDrv->p2p_connect = 1;
710 } else {
711 pstrWFIDrv->p2p_connect = 0;
713 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
715 for (i = 0; i < last_scanned_cnt; i++) {
716 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
717 memcmp(last_scanned_shadow[i].au8ssid,
718 sme->ssid,
719 sme->ssid_len) == 0) {
720 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
721 if (!sme->bssid) {
722 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
723 break;
724 } else {
725 if (memcmp(last_scanned_shadow[i].au8bssid,
726 sme->bssid,
727 ETH_ALEN) == 0) {
728 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
729 break;
735 if (i < last_scanned_cnt) {
736 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
738 pstrNetworkInfo = &last_scanned_shadow[i];
740 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
741 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
742 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
743 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
744 } else {
745 s32Error = -ENOENT;
746 if (last_scanned_cnt == 0)
747 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
748 else
749 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
750 wilc_connecting = 0;
751 return s32Error;
754 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
755 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
757 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
758 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
760 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
762 if (sme->crypto.cipher_group != NO_ENCRYPT) {
763 pcwpa_version = "Default";
764 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
765 u8security = ENCRYPT_ENABLED | WEP;
766 pcgroup_encrypt_val = "WEP40";
767 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
768 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
770 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
771 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
773 g_key_wep_params.key_len = sme->key_len;
774 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
775 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
776 g_key_wep_params.key_idx = sme->key_idx;
777 g_wep_keys_saved = true;
779 wilc_set_wep_default_keyid(vif, sme->key_idx);
780 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
781 sme->key_idx);
782 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
783 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
784 pcgroup_encrypt_val = "WEP104";
785 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
787 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
788 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
790 g_key_wep_params.key_len = sme->key_len;
791 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
792 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
793 g_key_wep_params.key_idx = sme->key_idx;
794 g_wep_keys_saved = true;
796 wilc_set_wep_default_keyid(vif, sme->key_idx);
797 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
798 sme->key_idx);
799 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
800 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
801 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
802 pcgroup_encrypt_val = "WPA2_TKIP";
803 pccipher_group = "TKIP";
804 } else {
805 u8security = ENCRYPT_ENABLED | WPA2 | AES;
806 pcgroup_encrypt_val = "WPA2_AES";
807 pccipher_group = "AES";
809 pcwpa_version = "WPA_VERSION_2";
810 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
811 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
812 u8security = ENCRYPT_ENABLED | WPA | TKIP;
813 pcgroup_encrypt_val = "WPA_TKIP";
814 pccipher_group = "TKIP";
815 } else {
816 u8security = ENCRYPT_ENABLED | WPA | AES;
817 pcgroup_encrypt_val = "WPA_AES";
818 pccipher_group = "AES";
820 pcwpa_version = "WPA_VERSION_1";
822 } else {
823 s32Error = -ENOTSUPP;
824 netdev_err(dev, "Not supported cipher\n");
825 wilc_connecting = 0;
826 return s32Error;
830 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
831 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
832 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
833 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
834 u8security = u8security | TKIP;
835 } else {
836 u8security = u8security | AES;
841 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
843 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
844 switch (sme->auth_type) {
845 case NL80211_AUTHTYPE_OPEN_SYSTEM:
846 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
847 tenuAuth_type = OPEN_SYSTEM;
848 break;
850 case NL80211_AUTHTYPE_SHARED_KEY:
851 tenuAuth_type = SHARED_KEY;
852 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
853 break;
855 default:
856 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
859 if (sme->crypto.n_akm_suites) {
860 switch (sme->crypto.akm_suites[0]) {
861 case WLAN_AKM_SUITE_8021X:
862 tenuAuth_type = IEEE8021;
863 break;
865 default:
866 break;
871 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
873 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
874 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
876 curr_channel = pstrNetworkInfo->u8channel;
878 if (!pstrWFIDrv->p2p_connect)
879 wlan_channel = pstrNetworkInfo->u8channel;
881 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid, STATION_MODE);
883 s32Error = wilc_set_join_req(vif, pstrNetworkInfo->au8bssid, sme->ssid,
884 sme->ssid_len, sme->ie, sme->ie_len,
885 CfgConnectResult, (void *)priv,
886 u8security, tenuAuth_type,
887 pstrNetworkInfo->u8channel,
888 pstrNetworkInfo->pJoinParams);
889 if (s32Error != 0) {
890 netdev_err(dev, "wilc_set_join_req(): Error\n");
891 s32Error = -ENOENT;
892 wilc_connecting = 0;
893 return s32Error;
896 return s32Error;
899 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
901 s32 s32Error = 0;
902 struct wilc_priv *priv;
903 struct host_if_drv *pstrWFIDrv;
904 struct wilc_vif *vif;
905 u8 NullBssid[ETH_ALEN] = {0};
907 wilc_connecting = 0;
908 priv = wiphy_priv(wiphy);
909 vif = netdev_priv(priv->dev);
911 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
912 if (!pstrWFIDrv->p2p_connect)
913 wlan_channel = INVALID_CHANNEL;
914 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
916 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
918 p2p_local_random = 0x01;
919 p2p_recv_random = 0x00;
920 wilc_ie = false;
921 pstrWFIDrv->p2p_timeout = 0;
923 s32Error = wilc_disconnect(vif, reason_code);
924 if (s32Error != 0) {
925 netdev_err(priv->dev, "Error in disconnecting\n");
926 s32Error = -EINVAL;
929 return s32Error;
932 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
933 bool pairwise,
934 const u8 *mac_addr, struct key_params *params)
937 s32 s32Error = 0, KeyLen = params->key_len;
938 u32 i;
939 struct wilc_priv *priv;
940 const u8 *pu8RxMic = NULL;
941 const u8 *pu8TxMic = NULL;
942 u8 u8mode = NO_ENCRYPT;
943 u8 u8gmode = NO_ENCRYPT;
944 u8 u8pmode = NO_ENCRYPT;
945 enum AUTHTYPE tenuAuth_type = ANY;
946 struct wilc *wl;
947 struct wilc_vif *vif;
949 priv = wiphy_priv(wiphy);
950 vif = netdev_priv(netdev);
951 wl = vif->wilc;
953 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
955 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
957 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
958 params->key[1],
959 params->key[2]);
962 switch (params->cipher) {
963 case WLAN_CIPHER_SUITE_WEP40:
964 case WLAN_CIPHER_SUITE_WEP104:
965 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
966 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
967 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
969 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
970 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
972 for (i = 0; i < params->key_len; i++)
973 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
975 tenuAuth_type = OPEN_SYSTEM;
977 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
978 u8mode = ENCRYPT_ENABLED | WEP;
979 else
980 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
982 wilc_add_wep_key_bss_ap(vif, params->key,
983 params->key_len, key_index,
984 u8mode, tenuAuth_type);
985 break;
987 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
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);
991 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
992 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
993 if (INFO) {
994 for (i = 0; i < params->key_len; i++)
995 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
997 wilc_add_wep_key_bss_sta(vif, params->key,
998 params->key_len, key_index);
1001 break;
1003 case WLAN_CIPHER_SUITE_TKIP:
1004 case WLAN_CIPHER_SUITE_CCMP:
1005 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1006 if (!priv->wilc_gtk[key_index]) {
1007 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
1008 priv->wilc_gtk[key_index]->key = NULL;
1009 priv->wilc_gtk[key_index]->seq = NULL;
1011 if (!priv->wilc_ptk[key_index]) {
1012 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
1013 priv->wilc_ptk[key_index]->key = NULL;
1014 priv->wilc_ptk[key_index]->seq = NULL;
1019 if (!pairwise) {
1020 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1021 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1022 else
1023 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1025 priv->wilc_groupkey = u8gmode;
1027 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1028 pu8TxMic = params->key + 24;
1029 pu8RxMic = params->key + 16;
1030 KeyLen = params->key_len - 16;
1032 kfree(priv->wilc_gtk[key_index]->key);
1034 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
1035 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
1036 kfree(priv->wilc_gtk[key_index]->seq);
1038 if ((params->seq_len) > 0) {
1039 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
1040 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
1043 priv->wilc_gtk[key_index]->cipher = params->cipher;
1044 priv->wilc_gtk[key_index]->key_len = params->key_len;
1045 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1047 if (INFO) {
1048 for (i = 0; i < params->key_len; i++)
1049 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1050 for (i = 0; i < params->seq_len; i++)
1051 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1055 wilc_add_rx_gtk(vif, params->key, KeyLen,
1056 key_index, params->seq_len,
1057 params->seq, pu8RxMic,
1058 pu8TxMic, AP_MODE, u8gmode);
1060 } else {
1061 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]);
1063 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1064 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1065 else
1066 u8pmode = priv->wilc_groupkey | AES;
1069 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1070 pu8TxMic = params->key + 24;
1071 pu8RxMic = params->key + 16;
1072 KeyLen = params->key_len - 16;
1075 kfree(priv->wilc_ptk[key_index]->key);
1077 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
1079 kfree(priv->wilc_ptk[key_index]->seq);
1081 if ((params->seq_len) > 0)
1082 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
1084 if (INFO) {
1085 for (i = 0; i < params->key_len; i++)
1086 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1088 for (i = 0; i < params->seq_len; i++)
1089 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1092 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
1094 if ((params->seq_len) > 0)
1095 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
1097 priv->wilc_ptk[key_index]->cipher = params->cipher;
1098 priv->wilc_ptk[key_index]->key_len = params->key_len;
1099 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1101 wilc_add_ptk(vif, params->key, KeyLen,
1102 mac_addr, pu8RxMic, pu8TxMic,
1103 AP_MODE, u8pmode, key_index);
1105 break;
1109 u8mode = 0;
1110 if (!pairwise) {
1111 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1112 pu8RxMic = params->key + 24;
1113 pu8TxMic = params->key + 16;
1114 KeyLen = params->key_len - 16;
1117 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
1118 g_add_gtk_key_params.key_idx = key_index;
1119 g_add_gtk_key_params.pairwise = pairwise;
1120 if (!mac_addr) {
1121 g_add_gtk_key_params.mac_addr = NULL;
1122 } else {
1123 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1124 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1126 g_key_gtk_params.key_len = params->key_len;
1127 g_key_gtk_params.seq_len = params->seq_len;
1128 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1129 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1130 if (params->seq_len > 0) {
1131 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1132 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1134 g_key_gtk_params.cipher = params->cipher;
1136 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1137 g_key_gtk_params.key[1],
1138 g_key_gtk_params.key[2]);
1139 g_gtk_keys_saved = true;
1142 wilc_add_rx_gtk(vif, params->key, KeyLen,
1143 key_index, params->seq_len,
1144 params->seq, pu8RxMic,
1145 pu8TxMic, STATION_MODE,
1146 u8mode);
1147 } else {
1148 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1149 pu8RxMic = params->key + 24;
1150 pu8TxMic = params->key + 16;
1151 KeyLen = params->key_len - 16;
1154 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1155 g_add_ptk_key_params.key_idx = key_index;
1156 g_add_ptk_key_params.pairwise = pairwise;
1157 if (!mac_addr) {
1158 g_add_ptk_key_params.mac_addr = NULL;
1159 } else {
1160 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1161 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1163 g_key_ptk_params.key_len = params->key_len;
1164 g_key_ptk_params.seq_len = params->seq_len;
1165 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1166 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1167 if (params->seq_len > 0) {
1168 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1169 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1171 g_key_ptk_params.cipher = params->cipher;
1173 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1174 g_key_ptk_params.key[1],
1175 g_key_ptk_params.key[2]);
1176 g_ptk_keys_saved = true;
1179 wilc_add_ptk(vif, params->key, KeyLen,
1180 mac_addr, pu8RxMic, pu8TxMic,
1181 STATION_MODE, u8mode, key_index);
1182 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1183 if (INFO) {
1184 for (i = 0; i < params->key_len; i++)
1185 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1189 break;
1191 default:
1192 netdev_err(netdev, "Not supported cipher\n");
1193 s32Error = -ENOTSUPP;
1196 return s32Error;
1199 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1200 u8 key_index,
1201 bool pairwise,
1202 const u8 *mac_addr)
1204 struct wilc_priv *priv;
1205 struct wilc *wl;
1206 struct wilc_vif *vif;
1208 priv = wiphy_priv(wiphy);
1209 vif = netdev_priv(netdev);
1210 wl = vif->wilc;
1212 if (netdev == wl->vif[0]->ndev) {
1213 g_ptk_keys_saved = false;
1214 g_gtk_keys_saved = false;
1215 g_wep_keys_saved = false;
1217 kfree(g_key_wep_params.key);
1218 g_key_wep_params.key = NULL;
1220 if ((priv->wilc_gtk[key_index]) != NULL) {
1221 kfree(priv->wilc_gtk[key_index]->key);
1222 priv->wilc_gtk[key_index]->key = NULL;
1223 kfree(priv->wilc_gtk[key_index]->seq);
1224 priv->wilc_gtk[key_index]->seq = NULL;
1226 kfree(priv->wilc_gtk[key_index]);
1227 priv->wilc_gtk[key_index] = NULL;
1230 if ((priv->wilc_ptk[key_index]) != NULL) {
1231 kfree(priv->wilc_ptk[key_index]->key);
1232 priv->wilc_ptk[key_index]->key = NULL;
1233 kfree(priv->wilc_ptk[key_index]->seq);
1234 priv->wilc_ptk[key_index]->seq = NULL;
1235 kfree(priv->wilc_ptk[key_index]);
1236 priv->wilc_ptk[key_index] = NULL;
1239 kfree(g_key_ptk_params.key);
1240 g_key_ptk_params.key = NULL;
1241 kfree(g_key_ptk_params.seq);
1242 g_key_ptk_params.seq = NULL;
1244 kfree(g_key_gtk_params.key);
1245 g_key_gtk_params.key = NULL;
1246 kfree(g_key_gtk_params.seq);
1247 g_key_gtk_params.seq = NULL;
1251 if (key_index >= 0 && key_index <= 3) {
1252 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
1253 priv->WILC_WFI_wep_key_len[key_index] = 0;
1255 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
1256 wilc_remove_wep_key(vif, key_index);
1257 } else {
1258 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
1259 wilc_remove_key(priv->hif_drv, mac_addr);
1262 return 0;
1265 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1266 bool pairwise,
1267 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1269 struct wilc_priv *priv;
1270 struct key_params key_params;
1271 u32 i;
1273 priv = wiphy_priv(wiphy);
1276 if (!pairwise) {
1277 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1279 key_params.key = priv->wilc_gtk[key_index]->key;
1280 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1281 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1282 key_params.seq = priv->wilc_gtk[key_index]->seq;
1283 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1284 if (INFO) {
1285 for (i = 0; i < key_params.key_len; i++)
1286 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1288 } else {
1289 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1291 key_params.key = priv->wilc_ptk[key_index]->key;
1292 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1293 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1294 key_params.seq = priv->wilc_ptk[key_index]->seq;
1295 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1298 callback(cookie, &key_params);
1300 return 0;
1303 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1304 bool unicast, bool multicast)
1306 struct wilc_priv *priv;
1307 struct wilc_vif *vif;
1309 priv = wiphy_priv(wiphy);
1310 vif = netdev_priv(priv->dev);
1312 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
1314 wilc_set_wep_default_keyid(vif, key_index);
1316 return 0;
1319 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1320 const u8 *mac, struct station_info *sinfo)
1322 struct wilc_priv *priv;
1323 struct wilc_vif *vif;
1324 u32 i = 0;
1325 u32 associatedsta = 0;
1326 u32 inactive_time = 0;
1327 priv = wiphy_priv(wiphy);
1328 vif = netdev_priv(dev);
1330 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1331 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1333 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1335 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1336 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1337 associatedsta = i;
1338 break;
1342 if (associatedsta == -1) {
1343 netdev_err(dev, "sta required is not associated\n");
1344 return -ENOENT;
1347 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1349 wilc_get_inactive_time(vif, mac, &inactive_time);
1350 sinfo->inactive_time = 1000 * inactive_time;
1351 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1354 if (vif->iftype == STATION_MODE) {
1355 struct rf_info strStatistics;
1357 wilc_get_statistics(vif, &strStatistics);
1359 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1360 BIT(NL80211_STA_INFO_RX_PACKETS) |
1361 BIT(NL80211_STA_INFO_TX_PACKETS) |
1362 BIT(NL80211_STA_INFO_TX_FAILED) |
1363 BIT(NL80211_STA_INFO_TX_BITRATE);
1365 sinfo->signal = strStatistics.rssi;
1366 sinfo->rx_packets = strStatistics.rx_cnt;
1367 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1368 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1369 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1371 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1372 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1373 wilc_enable_tcp_ack_filter(true);
1374 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1375 wilc_enable_tcp_ack_filter(false);
1377 return 0;
1380 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1381 struct bss_parameters *params)
1383 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1384 return 0;
1387 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1389 s32 s32Error = 0;
1390 struct cfg_param_val pstrCfgParamVal;
1391 struct wilc_priv *priv;
1392 struct wilc_vif *vif;
1394 priv = wiphy_priv(wiphy);
1395 vif = netdev_priv(priv->dev);
1397 pstrCfgParamVal.flag = 0;
1398 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
1400 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1401 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1402 priv->dev->ieee80211_ptr->wiphy->retry_short);
1403 pstrCfgParamVal.flag |= RETRY_SHORT;
1404 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1406 if (changed & WIPHY_PARAM_RETRY_LONG) {
1407 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
1408 pstrCfgParamVal.flag |= RETRY_LONG;
1409 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1411 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1412 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
1413 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1414 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1417 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1418 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1420 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1421 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1424 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
1425 s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1426 if (s32Error)
1427 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1429 return s32Error;
1432 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1433 struct cfg80211_pmksa *pmksa)
1435 u32 i;
1436 s32 s32Error = 0;
1437 u8 flag = 0;
1438 struct wilc_vif *vif;
1439 struct wilc_priv *priv = wiphy_priv(wiphy);
1441 vif = netdev_priv(priv->dev);
1442 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1445 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1446 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1447 ETH_ALEN)) {
1448 flag = PMKID_FOUND;
1449 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1450 break;
1453 if (i < WILC_MAX_NUM_PMKIDS) {
1454 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
1455 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1456 ETH_ALEN);
1457 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1458 PMKID_LEN);
1459 if (!(flag == PMKID_FOUND))
1460 priv->pmkid_list.numpmkid++;
1461 } else {
1462 netdev_err(netdev, "Invalid PMKID index\n");
1463 s32Error = -EINVAL;
1466 if (!s32Error) {
1467 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
1468 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1470 return s32Error;
1473 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1474 struct cfg80211_pmksa *pmksa)
1476 u32 i;
1477 s32 s32Error = 0;
1479 struct wilc_priv *priv = wiphy_priv(wiphy);
1481 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1483 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1484 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1485 ETH_ALEN)) {
1486 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
1487 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1488 break;
1492 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1493 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1494 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1495 priv->pmkid_list.pmkidlist[i + 1].bssid,
1496 ETH_ALEN);
1497 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1498 priv->pmkid_list.pmkidlist[i].pmkid,
1499 PMKID_LEN);
1501 priv->pmkid_list.numpmkid--;
1502 } else {
1503 s32Error = -EINVAL;
1506 return s32Error;
1509 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1511 struct wilc_priv *priv = wiphy_priv(wiphy);
1513 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1515 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1517 return 0;
1520 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1522 u32 index = 0;
1523 u32 i = 0, j = 0;
1525 u8 op_channel_attr_index = 0;
1526 u8 channel_list_attr_index = 0;
1528 while (index < len) {
1529 if (buf[index] == GO_INTENT_ATTR_ID) {
1530 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
1533 if (buf[index] == CHANLIST_ATTR_ID)
1534 channel_list_attr_index = index;
1535 else if (buf[index] == OPERCHAN_ATTR_ID)
1536 op_channel_attr_index = index;
1537 index += buf[index + 1] + 3;
1539 if (wlan_channel != INVALID_CHANNEL) {
1540 if (channel_list_attr_index) {
1541 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1542 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1543 if (buf[i] == 0x51) {
1544 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1545 buf[j] = wlan_channel;
1547 break;
1552 if (op_channel_attr_index) {
1553 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1554 buf[op_channel_attr_index + 6] = 0x51;
1555 buf[op_channel_attr_index + 7] = wlan_channel;
1560 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1562 u32 index = 0;
1563 u32 i = 0, j = 0;
1565 u8 op_channel_attr_index = 0;
1566 u8 channel_list_attr_index = 0;
1568 while (index < len) {
1569 if (buf[index] == GO_INTENT_ATTR_ID) {
1570 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
1572 break;
1575 if (buf[index] == CHANLIST_ATTR_ID)
1576 channel_list_attr_index = index;
1577 else if (buf[index] == OPERCHAN_ATTR_ID)
1578 op_channel_attr_index = index;
1579 index += buf[index + 1] + 3;
1581 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1582 if (channel_list_attr_index) {
1583 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1584 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1585 if (buf[i] == 0x51) {
1586 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1587 buf[j] = wlan_channel;
1589 break;
1594 if (op_channel_attr_index) {
1595 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1596 buf[op_channel_attr_index + 6] = 0x51;
1597 buf[op_channel_attr_index + 7] = wlan_channel;
1602 void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
1604 struct wilc_priv *priv;
1605 u32 header, pkt_offset;
1606 struct host_if_drv *pstrWFIDrv;
1607 u32 i = 0;
1608 s32 s32Freq;
1610 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1611 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1613 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1615 pkt_offset = GET_PKT_OFFSET(header);
1617 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1618 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1619 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
1620 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1621 return;
1622 } else {
1623 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1624 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],
1625 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
1626 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1627 } else {
1628 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],
1629 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
1630 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1632 return;
1634 } else {
1635 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1637 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
1639 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1640 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1642 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1643 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1644 return;
1646 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1647 switch (buff[ACTION_SUBTYPE_ID]) {
1648 case GAS_INTIAL_REQ:
1649 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1650 break;
1652 case GAS_INTIAL_RSP:
1653 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1654 break;
1656 case PUBLIC_ACT_VENDORSPEC:
1657 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1658 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1659 if (!wilc_ie) {
1660 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1661 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1662 p2p_recv_random = buff[i + 6];
1663 wilc_ie = true;
1664 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
1665 break;
1670 if (p2p_local_random > p2p_recv_random) {
1671 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1672 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1673 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1674 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1675 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1676 break;
1680 } else {
1681 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1686 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
1687 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
1688 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1689 return;
1691 break;
1693 default:
1694 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1695 break;
1700 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1704 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1706 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1709 kfree(pv_data->buff);
1710 kfree(pv_data);
1713 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1715 struct wilc_priv *priv;
1717 priv = (struct wilc_priv *)pUserVoid;
1719 priv->bInP2PlistenState = true;
1721 cfg80211_ready_on_channel(priv->wdev,
1722 priv->strRemainOnChanParams.u64ListenCookie,
1723 priv->strRemainOnChanParams.pstrListenChan,
1724 priv->strRemainOnChanParams.u32ListenDuration,
1725 GFP_KERNEL);
1728 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1730 struct wilc_priv *priv;
1732 priv = (struct wilc_priv *)pUserVoid;
1734 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1735 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
1737 priv->bInP2PlistenState = false;
1739 cfg80211_remain_on_channel_expired(priv->wdev,
1740 priv->strRemainOnChanParams.u64ListenCookie,
1741 priv->strRemainOnChanParams.pstrListenChan,
1742 GFP_KERNEL);
1743 } else {
1744 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
1745 , priv->strRemainOnChanParams.u32ListenSessionID);
1749 static int remain_on_channel(struct wiphy *wiphy,
1750 struct wireless_dev *wdev,
1751 struct ieee80211_channel *chan,
1752 unsigned int duration, u64 *cookie)
1754 s32 s32Error = 0;
1755 struct wilc_priv *priv;
1756 struct wilc_vif *vif;
1758 priv = wiphy_priv(wiphy);
1759 vif = netdev_priv(priv->dev);
1761 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
1764 if (wdev->iftype == NL80211_IFTYPE_AP) {
1765 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
1766 return s32Error;
1769 curr_channel = chan->hw_value;
1771 priv->strRemainOnChanParams.pstrListenChan = chan;
1772 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1773 priv->strRemainOnChanParams.u32ListenDuration = duration;
1774 priv->strRemainOnChanParams.u32ListenSessionID++;
1776 s32Error = wilc_remain_on_channel(vif,
1777 priv->strRemainOnChanParams.u32ListenSessionID,
1778 duration, chan->hw_value,
1779 WILC_WFI_RemainOnChannelExpired,
1780 WILC_WFI_RemainOnChannelReady, (void *)priv);
1782 return s32Error;
1785 static int cancel_remain_on_channel(struct wiphy *wiphy,
1786 struct wireless_dev *wdev,
1787 u64 cookie)
1789 s32 s32Error = 0;
1790 struct wilc_priv *priv;
1791 struct wilc_vif *vif;
1793 priv = wiphy_priv(wiphy);
1794 vif = netdev_priv(priv->dev);
1796 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1798 s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
1799 return s32Error;
1802 static int mgmt_tx(struct wiphy *wiphy,
1803 struct wireless_dev *wdev,
1804 struct cfg80211_mgmt_tx_params *params,
1805 u64 *cookie)
1807 struct ieee80211_channel *chan = params->chan;
1808 unsigned int wait = params->wait;
1809 const u8 *buf = params->buf;
1810 size_t len = params->len;
1811 const struct ieee80211_mgmt *mgmt;
1812 struct p2p_mgmt_data *mgmt_tx;
1813 struct wilc_priv *priv;
1814 struct host_if_drv *pstrWFIDrv;
1815 u32 i;
1816 struct wilc_vif *vif;
1817 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1819 vif = netdev_priv(wdev->netdev);
1820 priv = wiphy_priv(wiphy);
1821 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1823 *cookie = (unsigned long)buf;
1824 priv->u64tx_cookie = *cookie;
1825 mgmt = (const struct ieee80211_mgmt *) buf;
1827 if (ieee80211_is_mgmt(mgmt->frame_control)) {
1828 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1829 if (!mgmt_tx)
1830 return -EFAULT;
1832 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1833 if (!mgmt_tx->buff)
1834 kfree(mgmt_tx);
1835 return -EFAULT;
1837 memcpy(mgmt_tx->buff, buf, len);
1838 mgmt_tx->size = len;
1841 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1842 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
1843 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
1844 wilc_set_mac_chnl_num(vif, chan->hw_value);
1845 curr_channel = chan->hw_value;
1846 } else if (ieee80211_is_action(mgmt->frame_control)) {
1847 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
1850 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1851 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1852 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1853 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
1854 wilc_set_mac_chnl_num(vif,
1855 chan->hw_value);
1856 curr_channel = chan->hw_value;
1858 switch (buf[ACTION_SUBTYPE_ID]) {
1859 case GAS_INTIAL_REQ:
1861 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
1862 break;
1865 case GAS_INTIAL_RSP:
1867 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
1868 break;
1871 case PUBLIC_ACT_VENDORSPEC:
1873 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1874 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1875 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1876 get_random_bytes(&p2p_local_random, 1);
1877 p2p_local_random++;
1881 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1882 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1883 if (p2p_local_random > p2p_recv_random) {
1884 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1886 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1887 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1888 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1889 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1890 else
1891 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1892 break;
1896 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1897 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1898 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1899 mgmt_tx->size = buf_len;
1901 } else {
1902 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1906 } else {
1907 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
1910 break;
1913 default:
1915 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1916 break;
1921 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
1922 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1924 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
1925 jiffies, pstrWFIDrv->p2p_timeout);
1928 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1929 mgmt_tx->buff, mgmt_tx->size,
1930 WILC_WFI_mgmt_tx_complete);
1931 } else {
1932 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
1934 return 0;
1937 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1938 struct wireless_dev *wdev,
1939 u64 cookie)
1941 struct wilc_priv *priv;
1942 struct host_if_drv *pstrWFIDrv;
1944 priv = wiphy_priv(wiphy);
1945 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1948 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
1949 pstrWFIDrv->p2p_timeout = jiffies;
1951 if (!priv->bInP2PlistenState) {
1952 cfg80211_remain_on_channel_expired(priv->wdev,
1953 priv->strRemainOnChanParams.u64ListenCookie,
1954 priv->strRemainOnChanParams.pstrListenChan,
1955 GFP_KERNEL);
1958 return 0;
1961 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1962 u16 frame_type, bool reg)
1964 struct wilc_priv *priv;
1965 struct wilc_vif *vif;
1966 struct wilc *wl;
1968 priv = wiphy_priv(wiphy);
1969 vif = netdev_priv(priv->wdev->netdev);
1970 wl = vif->wilc;
1972 if (!frame_type)
1973 return;
1975 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
1976 switch (frame_type) {
1977 case PROBE_REQ:
1979 vif->g_struct_frame_reg[0].frame_type = frame_type;
1980 vif->g_struct_frame_reg[0].reg = reg;
1982 break;
1984 case ACTION:
1986 vif->g_struct_frame_reg[1].frame_type = frame_type;
1987 vif->g_struct_frame_reg[1].reg = reg;
1989 break;
1991 default:
1993 break;
1997 if (!wl->initialized) {
1998 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
1999 return;
2001 wilc_frame_register(vif, frame_type, reg);
2004 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2005 s32 rssi_thold, u32 rssi_hyst)
2007 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2008 return 0;
2011 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2012 int idx, u8 *mac, struct station_info *sinfo)
2014 struct wilc_priv *priv;
2015 struct wilc_vif *vif;
2017 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2019 if (idx != 0)
2020 return -ENOENT;
2022 priv = wiphy_priv(wiphy);
2023 vif = netdev_priv(priv->dev);
2025 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2027 wilc_get_rssi(vif, &sinfo->signal);
2029 return 0;
2032 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2033 bool enabled, int timeout)
2035 struct wilc_priv *priv;
2036 struct wilc_vif *vif;
2038 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2040 if (!wiphy)
2041 return -ENOENT;
2043 priv = wiphy_priv(wiphy);
2044 vif = netdev_priv(priv->dev);
2045 if (!priv->hif_drv)
2046 return -EIO;
2048 if (wilc_enable_ps)
2049 wilc_set_power_mgmt(vif, enabled, timeout);
2052 return 0;
2055 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2056 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
2058 struct wilc_priv *priv;
2059 struct wilc_vif *vif;
2060 struct wilc *wl;
2062 vif = netdev_priv(dev);
2063 priv = wiphy_priv(wiphy);
2064 wl = vif->wilc;
2066 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2067 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2068 p2p_local_random = 0x01;
2069 p2p_recv_random = 0x00;
2070 wilc_ie = false;
2071 wilc_optaining_ip = false;
2072 del_timer(&wilc_during_ip_timer);
2073 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
2075 switch (type) {
2076 case NL80211_IFTYPE_STATION:
2077 wilc_connecting = 0;
2078 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
2080 dev->ieee80211_ptr->iftype = type;
2081 priv->wdev->iftype = type;
2082 vif->monitor_flag = 0;
2083 vif->iftype = STATION_MODE;
2084 wilc_set_operation_mode(vif, STATION_MODE);
2086 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
2088 wilc_enable_ps = true;
2089 wilc_set_power_mgmt(vif, 1, 0);
2090 break;
2092 case NL80211_IFTYPE_P2P_CLIENT:
2093 wilc_connecting = 0;
2094 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
2096 dev->ieee80211_ptr->iftype = type;
2097 priv->wdev->iftype = type;
2098 vif->monitor_flag = 0;
2099 vif->iftype = CLIENT_MODE;
2100 wilc_set_operation_mode(vif, STATION_MODE);
2102 wilc_enable_ps = false;
2103 wilc_set_power_mgmt(vif, 0, 0);
2104 break;
2106 case NL80211_IFTYPE_AP:
2107 wilc_enable_ps = false;
2108 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
2109 dev->ieee80211_ptr->iftype = type;
2110 priv->wdev->iftype = type;
2111 vif->iftype = AP_MODE;
2113 if (wl->initialized) {
2114 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
2116 wilc_set_operation_mode(vif, AP_MODE);
2117 wilc_set_power_mgmt(vif, 0, 0);
2119 break;
2121 case NL80211_IFTYPE_P2P_GO:
2122 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2124 wilc_optaining_ip = true;
2125 mod_timer(&wilc_during_ip_timer,
2126 jiffies + msecs_to_jiffies(during_ip_time));
2127 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
2129 wilc_set_operation_mode(vif, AP_MODE);
2130 dev->ieee80211_ptr->iftype = type;
2131 priv->wdev->iftype = type;
2132 vif->iftype = GO_MODE;
2134 wilc_enable_ps = false;
2135 wilc_set_power_mgmt(vif, 0, 0);
2136 break;
2138 default:
2139 netdev_err(dev, "Unknown interface type= %d\n", type);
2140 return -EINVAL;
2143 return 0;
2146 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2147 struct cfg80211_ap_settings *settings)
2149 struct cfg80211_beacon_data *beacon = &(settings->beacon);
2150 struct wilc_priv *priv;
2151 s32 s32Error = 0;
2152 struct wilc *wl;
2153 struct wilc_vif *vif;
2155 priv = wiphy_priv(wiphy);
2156 vif = netdev_priv(dev);
2157 wl = vif ->wilc;
2158 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2160 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
2161 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2163 s32Error = set_channel(wiphy, &settings->chandef);
2165 if (s32Error != 0)
2166 netdev_err(dev, "Error in setting channel\n");
2168 wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
2169 wilc_set_power_mgmt(vif, 0, 0);
2171 s32Error = wilc_add_beacon(vif, settings->beacon_interval,
2172 settings->dtim_period, beacon->head_len,
2173 (u8 *)beacon->head, beacon->tail_len,
2174 (u8 *)beacon->tail);
2176 return s32Error;
2179 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2180 struct cfg80211_beacon_data *beacon)
2182 struct wilc_priv *priv;
2183 struct wilc_vif *vif;
2184 s32 s32Error = 0;
2186 priv = wiphy_priv(wiphy);
2187 vif = netdev_priv(priv->dev);
2188 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2191 s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
2192 (u8 *)beacon->head, beacon->tail_len,
2193 (u8 *)beacon->tail);
2195 return s32Error;
2198 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
2200 s32 s32Error = 0;
2201 struct wilc_priv *priv;
2202 struct wilc_vif *vif;
2203 u8 NullBssid[ETH_ALEN] = {0};
2205 if (!wiphy)
2206 return -EFAULT;
2208 priv = wiphy_priv(wiphy);
2209 vif = netdev_priv(priv->dev);
2211 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2213 wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
2215 s32Error = wilc_del_beacon(vif);
2217 if (s32Error)
2218 netdev_err(dev, "Host delete beacon fail\n");
2220 return s32Error;
2223 static int add_station(struct wiphy *wiphy, struct net_device *dev,
2224 const u8 *mac, struct station_parameters *params)
2226 s32 s32Error = 0;
2227 struct wilc_priv *priv;
2228 struct add_sta_param strStaParams = { {0} };
2229 struct wilc_vif *vif;
2231 if (!wiphy)
2232 return -EFAULT;
2234 priv = wiphy_priv(wiphy);
2235 vif = netdev_priv(dev);
2237 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2238 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2239 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
2240 strStaParams.aid = params->aid;
2241 strStaParams.rates_len = params->supported_rates_len;
2242 strStaParams.rates = params->supported_rates;
2244 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2246 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],
2247 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
2248 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
2249 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2250 strStaParams.rates_len);
2252 if (!params->ht_capa) {
2253 strStaParams.ht_supported = false;
2254 } else {
2255 strStaParams.ht_supported = true;
2256 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2257 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2258 memcpy(strStaParams.ht_supp_mcs_set,
2259 &params->ht_capa->mcs,
2260 WILC_SUPP_MCS_SET_SIZE);
2261 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2262 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2263 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2266 strStaParams.flags_mask = params->sta_flags_mask;
2267 strStaParams.flags_set = params->sta_flags_set;
2269 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2270 strStaParams.ht_supported);
2271 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2272 strStaParams.ht_capa_info);
2273 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2274 strStaParams.ht_ampdu_params);
2275 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2276 strStaParams.ht_ext_params);
2277 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2278 strStaParams.ht_tx_bf_cap);
2279 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2280 strStaParams.ht_ante_sel);
2281 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2282 strStaParams.flags_mask);
2283 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2284 strStaParams.flags_set);
2286 s32Error = wilc_add_station(vif, &strStaParams);
2287 if (s32Error)
2288 netdev_err(dev, "Host add station fail\n");
2291 return s32Error;
2294 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2295 struct station_del_parameters *params)
2297 const u8 *mac = params->mac;
2298 s32 s32Error = 0;
2299 struct wilc_priv *priv;
2300 struct wilc_vif *vif;
2302 if (!wiphy)
2303 return -EFAULT;
2305 priv = wiphy_priv(wiphy);
2306 vif = netdev_priv(dev);
2308 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2309 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2312 if (!mac) {
2313 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
2314 s32Error = wilc_del_allstation(vif,
2315 priv->assoc_stainfo.au8Sta_AssociatedBss);
2316 } else {
2317 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]);
2320 s32Error = wilc_del_station(vif, mac);
2322 if (s32Error)
2323 netdev_err(dev, "Host delete station fail\n");
2325 return s32Error;
2328 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2329 const u8 *mac, struct station_parameters *params)
2331 s32 s32Error = 0;
2332 struct wilc_priv *priv;
2333 struct add_sta_param strStaParams = { {0} };
2334 struct wilc_vif *vif;
2337 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2339 if (!wiphy)
2340 return -EFAULT;
2342 priv = wiphy_priv(wiphy);
2343 vif = netdev_priv(dev);
2345 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2346 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2347 strStaParams.aid = params->aid;
2348 strStaParams.rates_len = params->supported_rates_len;
2349 strStaParams.rates = params->supported_rates;
2351 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2352 strStaParams.bssid[0], strStaParams.bssid[1],
2353 strStaParams.bssid[2], strStaParams.bssid[3],
2354 strStaParams.bssid[4], strStaParams.bssid[5]);
2355 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
2356 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2357 strStaParams.rates_len);
2359 if (!params->ht_capa) {
2360 strStaParams.ht_supported = false;
2361 } else {
2362 strStaParams.ht_supported = true;
2363 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2364 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2365 memcpy(strStaParams.ht_supp_mcs_set,
2366 &params->ht_capa->mcs,
2367 WILC_SUPP_MCS_SET_SIZE);
2368 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2369 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2370 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2373 strStaParams.flags_mask = params->sta_flags_mask;
2374 strStaParams.flags_set = params->sta_flags_set;
2376 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2377 strStaParams.ht_supported);
2378 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2379 strStaParams.ht_capa_info);
2380 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2381 strStaParams.ht_ampdu_params);
2382 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2383 strStaParams.ht_ext_params);
2384 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2385 strStaParams.ht_tx_bf_cap);
2386 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2387 strStaParams.ht_ante_sel);
2388 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2389 strStaParams.flags_mask);
2390 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2391 strStaParams.flags_set);
2393 s32Error = wilc_edit_station(vif, &strStaParams);
2394 if (s32Error)
2395 netdev_err(dev, "Host edit station fail\n");
2397 return s32Error;
2400 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2401 const char *name,
2402 unsigned char name_assign_type,
2403 enum nl80211_iftype type,
2404 u32 *flags,
2405 struct vif_params *params)
2407 struct wilc_vif *vif;
2408 struct wilc_priv *priv;
2409 struct net_device *new_ifc = NULL;
2411 priv = wiphy_priv(wiphy);
2415 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2417 vif = netdev_priv(priv->wdev->netdev);
2420 if (type == NL80211_IFTYPE_MONITOR) {
2421 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
2422 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->ndev);
2423 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2424 if (new_ifc) {
2425 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
2426 vif = netdev_priv(priv->wdev->netdev);
2427 vif->monitor_flag = 1;
2430 return priv->wdev;
2433 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2435 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
2436 return 0;
2439 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2441 struct wilc_priv *priv = wiphy_priv(wiphy);
2442 struct wilc_vif *vif = netdev_priv(priv->dev);
2444 if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2445 vif->wilc->suspend_event = true;
2446 else
2447 vif->wilc->suspend_event = false;
2449 return 0;
2452 static int wilc_resume(struct wiphy *wiphy)
2454 struct wilc_priv *priv = wiphy_priv(wiphy);
2455 struct wilc_vif *vif = netdev_priv(priv->dev);
2457 netdev_info(vif->ndev, "cfg resume\n");
2458 return 0;
2461 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2463 struct wilc_priv *priv = wiphy_priv(wiphy);
2464 struct wilc_vif *vif = netdev_priv(priv->dev);
2466 netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2469 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2470 enum nl80211_tx_power_setting type, int mbm)
2472 int ret;
2473 s32 tx_power = MBM_TO_DBM(mbm);
2474 struct wilc_priv *priv = wiphy_priv(wiphy);
2475 struct wilc_vif *vif = netdev_priv(priv->dev);
2477 if (tx_power < 0)
2478 tx_power = 0;
2479 else if (tx_power > 18)
2480 tx_power = 18;
2481 ret = wilc_set_tx_power(vif, tx_power);
2482 if (ret)
2483 netdev_err(vif->ndev, "Failed to set tx power\n");
2485 return ret;
2488 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2489 int *dbm)
2491 int ret;
2492 struct wilc_priv *priv = wiphy_priv(wiphy);
2493 struct wilc_vif *vif = netdev_priv(priv->dev);
2495 ret = wilc_get_tx_power(vif, (u8 *)dbm);
2496 if (ret)
2497 netdev_err(vif->ndev, "Failed to get tx power\n");
2499 return ret;
2502 static struct cfg80211_ops wilc_cfg80211_ops = {
2503 .set_monitor_channel = set_channel,
2504 .scan = scan,
2505 .connect = connect,
2506 .disconnect = disconnect,
2507 .add_key = add_key,
2508 .del_key = del_key,
2509 .get_key = get_key,
2510 .set_default_key = set_default_key,
2511 .add_virtual_intf = add_virtual_intf,
2512 .del_virtual_intf = del_virtual_intf,
2513 .change_virtual_intf = change_virtual_intf,
2515 .start_ap = start_ap,
2516 .change_beacon = change_beacon,
2517 .stop_ap = stop_ap,
2518 .add_station = add_station,
2519 .del_station = del_station,
2520 .change_station = change_station,
2521 .get_station = get_station,
2522 .dump_station = dump_station,
2523 .change_bss = change_bss,
2524 .set_wiphy_params = set_wiphy_params,
2526 .set_pmksa = set_pmksa,
2527 .del_pmksa = del_pmksa,
2528 .flush_pmksa = flush_pmksa,
2529 .remain_on_channel = remain_on_channel,
2530 .cancel_remain_on_channel = cancel_remain_on_channel,
2531 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2532 .mgmt_tx = mgmt_tx,
2533 .mgmt_frame_register = wilc_mgmt_frame_register,
2534 .set_power_mgmt = set_power_mgmt,
2535 .set_cqm_rssi_config = set_cqm_rssi_config,
2537 .suspend = wilc_suspend,
2538 .resume = wilc_resume,
2539 .set_wakeup = wilc_set_wakeup,
2540 .set_tx_power = set_tx_power,
2541 .get_tx_power = get_tx_power,
2545 int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2547 struct wilc_priv *priv;
2549 priv = wiphy_priv(wiphy);
2550 switch (changed) {
2551 case WILC_WFI_RX_PKT:
2553 priv->netstats.rx_packets++;
2554 priv->netstats.rx_bytes += pktlen;
2555 priv->netstats.rx_time = get_jiffies_64();
2557 break;
2559 case WILC_WFI_TX_PKT:
2561 priv->netstats.tx_packets++;
2562 priv->netstats.tx_bytes += pktlen;
2563 priv->netstats.tx_time = get_jiffies_64();
2566 break;
2568 default:
2569 break;
2571 return 0;
2574 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2576 struct wireless_dev *wdev;
2579 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
2581 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2582 if (!wdev)
2583 goto _fail_;
2585 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2586 if (!wdev->wiphy)
2587 goto _fail_mem_;
2589 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2590 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2591 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2592 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2593 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2595 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2597 return wdev;
2599 _fail_mem_:
2600 kfree(wdev);
2601 _fail_:
2602 return NULL;
2605 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2607 struct wilc_priv *priv;
2608 struct wireless_dev *wdev;
2609 s32 s32Error = 0;
2611 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2613 wdev = WILC_WFI_CfgAlloc();
2614 if (!wdev) {
2615 netdev_err(net, "wiphy new allocate failed\n");
2616 return NULL;
2619 priv = wdev_priv(wdev);
2620 sema_init(&(priv->SemHandleUpdateStats), 1);
2621 priv->wdev = wdev;
2622 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2623 #ifdef CONFIG_PM
2624 wdev->wiphy->wowlan = &wowlan_support;
2625 #endif
2626 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2627 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
2629 wdev->wiphy->max_scan_ie_len = 1000;
2630 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2631 wdev->wiphy->cipher_suites = cipher_suites;
2632 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2633 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2635 wdev->wiphy->max_remain_on_channel_duration = 500;
2636 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2637 BIT(NL80211_IFTYPE_P2P_CLIENT);
2638 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2639 wdev->iftype = NL80211_IFTYPE_STATION;
2643 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2644 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2645 wdev->wiphy->interface_modes, wdev->iftype);
2647 set_wiphy_dev(wdev->wiphy, dev);
2649 s32Error = wiphy_register(wdev->wiphy);
2650 if (s32Error)
2651 netdev_err(net, "Cannot register wiphy device\n");
2652 else
2653 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2655 priv->dev = net;
2656 return wdev;
2659 int wilc_init_host_int(struct net_device *net)
2661 int s32Error = 0;
2663 struct wilc_priv *priv;
2665 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2666 priv = wdev_priv(net->ieee80211_ptr);
2667 if (op_ifcs == 0) {
2668 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2669 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2671 op_ifcs++;
2673 priv->gbAutoRateAdjusted = false;
2675 priv->bInP2PlistenState = false;
2677 sema_init(&(priv->hSemScanReq), 1);
2678 s32Error = wilc_init(net, &priv->hif_drv);
2679 if (s32Error)
2680 netdev_err(net, "Error while initializing hostinterface\n");
2682 return s32Error;
2685 int wilc_deinit_host_int(struct net_device *net)
2687 int s32Error = 0;
2688 struct wilc_vif *vif;
2689 struct wilc_priv *priv;
2691 priv = wdev_priv(net->ieee80211_ptr);
2692 vif = netdev_priv(priv->dev);
2694 priv->gbAutoRateAdjusted = false;
2696 priv->bInP2PlistenState = false;
2698 op_ifcs--;
2700 s32Error = wilc_deinit(vif);
2702 clear_shadow_scan();
2703 if (op_ifcs == 0)
2704 del_timer_sync(&wilc_during_ip_timer);
2706 if (s32Error)
2707 netdev_err(net, "Error while deintializing host interface\n");
2709 return s32Error;
2712 void wilc_free_wiphy(struct net_device *net)
2714 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2716 if (!net) {
2717 PRINT_D(INIT_DBG, "net_device is NULL\n");
2718 return;
2721 if (!net->ieee80211_ptr) {
2722 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2723 return;
2726 if (!net->ieee80211_ptr->wiphy) {
2727 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2728 return;
2731 wiphy_unregister(net->ieee80211_ptr->wiphy);
2733 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2734 wiphy_free(net->ieee80211_ptr->wiphy);
2735 kfree(net->ieee80211_ptr);