1 #include "wilc_wfi_cfgoperations.h"
2 #include "host_interface.h"
3 #include <linux/errno.h>
6 #define ENCRYPT_ENABLED BIT(0)
8 #define WEP_EXTENDED BIT(2)
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] = {
52 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
53 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
55 [NL80211_IFTYPE_AP] = {
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] = {
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;
102 u8 wilc_initialized = 1;
104 #define CHAN2G(_channel, _freq, _flags) { \
105 .band = IEEE80211_BAND_2GHZ, \
106 .center_freq = (_freq), \
107 .hw_value = (_channel), \
109 .max_antenna_gain = 0, \
113 static struct ieee80211_channel ieee80211_2ghz_channels[] = {
130 #define RATETAB_ENT(_rate, _hw_value, _flags) { \
131 .bitrate = (_rate), \
132 .hw_value = (_hw_value), \
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 {
156 static u8 wlan_channel = INVALID_CHANNEL;
157 static u8 curr_channel;
158 static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
159 static u8 p2p_local_random = 0x01;
160 static u8 p2p_recv_random;
161 static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
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 {
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)
194 del_timer_sync(&hAgingTimer);
196 for (i = 0; i < last_scanned_cnt; i++) {
197 if (last_scanned_shadow[last_scanned_cnt].ies) {
198 kfree(last_scanned_shadow[i].ies);
199 last_scanned_shadow[last_scanned_cnt].ies = NULL;
202 kfree(last_scanned_shadow[i].join_params);
203 last_scanned_shadow[i].join_params = NULL;
205 last_scanned_cnt = 0;
209 static u32 get_rssi_avg(struct network_info *network_info)
213 u8 num_rssi = (network_info->str_rssi.u8Full) ?
214 NUM_RSSI : (network_info->str_rssi.u8Index);
216 for (i = 0; i < num_rssi; i++)
217 rssi_v += network_info->str_rssi.as8RSSI[i];
223 static void refresh_scan(void *user_void, u8 all, bool direct_scan)
225 struct wilc_priv *priv;
227 struct cfg80211_bss *bss = NULL;
232 wiphy = priv->dev->ieee80211_ptr->wiphy;
234 for (i = 0; i < last_scanned_cnt; i++) {
235 struct network_info *network_info;
237 network_info = &last_scanned_shadow[i];
239 if (!network_info->found || all) {
241 struct ieee80211_channel *channel;
244 freq = ieee80211_channel_to_frequency((s32)network_info->ch, IEEE80211_BAND_2GHZ);
245 channel = ieee80211_get_channel(wiphy, freq);
247 rssi = get_rssi_avg(network_info);
248 if (memcmp("DIRECT-", network_info->ssid, 7) ||
250 bss = cfg80211_inform_bss(wiphy,
252 CFG80211_BSS_FTYPE_UNKNOWN,
254 network_info->tsf_hi,
255 network_info->cap_info,
256 network_info->beacon_period,
257 (const u8 *)network_info->ies,
258 (size_t)network_info->ies_len,
261 cfg80211_put_bss(wiphy, bss);
268 static void reset_shadow_found(void)
272 for (i = 0; i < last_scanned_cnt; i++)
273 last_scanned_shadow[i].found = 0;
276 static void update_scan_time(void)
280 for (i = 0; i < last_scanned_cnt; i++)
281 last_scanned_shadow[i].time_scan = jiffies;
284 static void remove_network_from_shadow(unsigned long arg)
286 unsigned long now = jiffies;
290 for (i = 0; i < last_scanned_cnt; i++) {
291 if (time_after(now, last_scanned_shadow[i].time_scan +
292 (unsigned long)(SCAN_RESULT_EXPIRE))) {
293 kfree(last_scanned_shadow[i].ies);
294 last_scanned_shadow[i].ies = NULL;
296 kfree(last_scanned_shadow[i].join_params);
298 for (j = i; (j < last_scanned_cnt - 1); j++)
299 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
305 if (last_scanned_cnt != 0) {
306 hAgingTimer.data = arg;
307 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
311 static void clear_duringIP(unsigned long arg)
313 wilc_optaining_ip = false;
316 static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
322 if (last_scanned_cnt == 0) {
323 hAgingTimer.data = (unsigned long)user_void;
324 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
327 for (i = 0; i < last_scanned_cnt; i++) {
328 if (memcmp(last_scanned_shadow[i].bssid,
329 pstrNetworkInfo->bssid, 6) == 0) {
338 static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
339 void *user_void, void *pJoinParams)
341 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
345 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
348 if (ap_found == -1) {
349 ap_index = last_scanned_cnt;
354 rssi_index = last_scanned_shadow[ap_index].str_rssi.u8Index;
355 last_scanned_shadow[ap_index].str_rssi.as8RSSI[rssi_index++] = pstrNetworkInfo->rssi;
356 if (rssi_index == NUM_RSSI) {
358 last_scanned_shadow[ap_index].str_rssi.u8Full = 1;
360 last_scanned_shadow[ap_index].str_rssi.u8Index = rssi_index;
361 last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
362 last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
363 last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
364 memcpy(last_scanned_shadow[ap_index].ssid,
365 pstrNetworkInfo->ssid, pstrNetworkInfo->ssid_len);
366 memcpy(last_scanned_shadow[ap_index].bssid,
367 pstrNetworkInfo->bssid, ETH_ALEN);
368 last_scanned_shadow[ap_index].beacon_period = pstrNetworkInfo->beacon_period;
369 last_scanned_shadow[ap_index].dtim_period = pstrNetworkInfo->dtim_period;
370 last_scanned_shadow[ap_index].ch = pstrNetworkInfo->ch;
371 last_scanned_shadow[ap_index].ies_len = pstrNetworkInfo->ies_len;
372 last_scanned_shadow[ap_index].tsf_hi = pstrNetworkInfo->tsf_hi;
374 kfree(last_scanned_shadow[ap_index].ies);
375 last_scanned_shadow[ap_index].ies = kmalloc(pstrNetworkInfo->ies_len,
377 memcpy(last_scanned_shadow[ap_index].ies,
378 pstrNetworkInfo->ies, pstrNetworkInfo->ies_len);
379 last_scanned_shadow[ap_index].time_scan = jiffies;
380 last_scanned_shadow[ap_index].time_scan_cached = jiffies;
381 last_scanned_shadow[ap_index].found = 1;
383 kfree(last_scanned_shadow[ap_index].join_params);
384 last_scanned_shadow[ap_index].join_params = pJoinParams;
387 static void CfgScanResult(enum scan_event scan_event,
388 struct network_info *network_info,
392 struct wilc_priv *priv;
395 struct ieee80211_channel *channel;
396 struct cfg80211_bss *bss = NULL;
399 if (priv->bCfgScanning) {
400 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
401 wiphy = priv->dev->ieee80211_ptr->wiphy;
406 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
407 (((s32)network_info->rssi * 100) < 0 ||
408 ((s32)network_info->rssi * 100) > 100))
412 s32Freq = ieee80211_channel_to_frequency((s32)network_info->ch, IEEE80211_BAND_2GHZ);
413 channel = ieee80211_get_channel(wiphy, s32Freq);
418 if (network_info->new_network) {
419 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
420 priv->u32RcvdChCount++;
422 add_network_to_shadow(network_info, priv, join_params);
424 if (!(memcmp("DIRECT-", network_info->ssid, 7))) {
425 bss = cfg80211_inform_bss(wiphy,
427 CFG80211_BSS_FTYPE_UNKNOWN,
429 network_info->tsf_hi,
430 network_info->cap_info,
431 network_info->beacon_period,
432 (const u8 *)network_info->ies,
433 (size_t)network_info->ies_len,
434 (s32)network_info->rssi * 100,
436 cfg80211_put_bss(wiphy, bss);
442 for (i = 0; i < priv->u32RcvdChCount; i++) {
443 if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) {
444 last_scanned_shadow[i].rssi = network_info->rssi;
445 last_scanned_shadow[i].time_scan = jiffies;
451 } else if (scan_event == SCAN_EVENT_DONE) {
452 refresh_scan(priv, 1, false);
454 down(&(priv->hSemScanReq));
456 if (priv->pstrScanReq) {
457 cfg80211_scan_done(priv->pstrScanReq, false);
458 priv->u32RcvdChCount = 0;
459 priv->bCfgScanning = false;
460 priv->pstrScanReq = NULL;
462 up(&(priv->hSemScanReq));
463 } else if (scan_event == SCAN_EVENT_ABORTED) {
464 down(&(priv->hSemScanReq));
466 if (priv->pstrScanReq) {
468 refresh_scan(priv, 1, false);
470 cfg80211_scan_done(priv->pstrScanReq, false);
471 priv->bCfgScanning = false;
472 priv->pstrScanReq = NULL;
474 up(&(priv->hSemScanReq));
481 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
482 tstrConnectInfo *pstrConnectInfo,
484 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
487 struct wilc_priv *priv;
488 struct net_device *dev;
489 struct host_if_drv *pstrWFIDrv;
490 u8 NullBssid[ETH_ALEN] = {0};
492 struct wilc_vif *vif;
498 vif = netdev_priv(dev);
500 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
502 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
503 u16 u16ConnectStatus;
505 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
507 if ((u8MacStatus == MAC_DISCONNECTED) &&
508 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
509 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
510 wilc_wlan_set_bssid(priv->dev, NullBssid,
512 eth_zero_addr(wilc_connected_ssid);
514 if (!pstrWFIDrv->p2p_connect)
515 wlan_channel = INVALID_CHANNEL;
517 netdev_err(dev, "Unspecified failure\n");
520 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
521 bool bNeedScanRefresh = false;
524 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
527 for (i = 0; i < last_scanned_cnt; i++) {
528 if (memcmp(last_scanned_shadow[i].bssid,
529 pstrConnectInfo->au8bssid,
531 unsigned long now = jiffies;
534 last_scanned_shadow[i].time_scan_cached +
535 (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
536 bNeedScanRefresh = true;
542 if (bNeedScanRefresh)
543 refresh_scan(priv, 1, true);
546 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
547 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
548 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
549 u16ConnectStatus, GFP_KERNEL);
550 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
551 wilc_optaining_ip = false;
552 p2p_local_random = 0x01;
553 p2p_recv_random = 0x00;
555 eth_zero_addr(priv->au8AssociatedBss);
556 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
557 eth_zero_addr(wilc_connected_ssid);
559 if (!pstrWFIDrv->p2p_connect)
560 wlan_channel = INVALID_CHANNEL;
561 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
562 pstrDisconnectNotifInfo->u16reason = 3;
563 } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
564 pstrDisconnectNotifInfo->u16reason = 1;
566 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
567 pstrDisconnectNotifInfo->ie_len, false,
572 static int set_channel(struct wiphy *wiphy,
573 struct cfg80211_chan_def *chandef)
576 struct wilc_priv *priv;
578 struct wilc_vif *vif;
580 priv = wiphy_priv(wiphy);
581 vif = netdev_priv(priv->dev);
583 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
585 curr_channel = channelnum;
586 result = wilc_set_mac_chnl_num(vif, channelnum);
589 netdev_err(priv->dev, "Error in setting channel\n");
594 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
596 struct wilc_priv *priv;
599 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
600 struct hidden_network strHiddenNetwork;
601 struct wilc_vif *vif;
603 priv = wiphy_priv(wiphy);
604 vif = netdev_priv(priv->dev);
606 priv->pstrScanReq = request;
608 priv->u32RcvdChCount = 0;
610 reset_shadow_found();
612 priv->bCfgScanning = true;
613 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
614 for (i = 0; i < request->n_channels; i++)
615 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
617 if (request->n_ssids >= 1) {
618 strHiddenNetwork.net_info =
619 kmalloc_array(request->n_ssids,
620 sizeof(struct hidden_network),
622 if (!strHiddenNetwork.net_info)
624 strHiddenNetwork.n_ssids = request->n_ssids;
627 for (i = 0; i < request->n_ssids; i++) {
628 if (request->ssids[i].ssid &&
629 request->ssids[i].ssid_len != 0) {
630 strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
631 memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
632 strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
634 strHiddenNetwork.n_ssids -= 1;
637 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
640 (const u8 *)request->ie,
641 request->ie_len, CfgScanResult,
642 (void *)priv, &strHiddenNetwork);
644 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
647 (const u8 *)request->ie,
648 request->ie_len, CfgScanResult,
652 netdev_err(priv->dev, "Requested scanned channels over\n");
661 static int connect(struct wiphy *wiphy, struct net_device *dev,
662 struct cfg80211_connect_params *sme)
666 u8 u8security = NO_ENCRYPT;
667 enum AUTHTYPE tenuAuth_type = ANY;
668 char *pcgroup_encrypt_val = NULL;
669 char *pccipher_group = NULL;
670 char *pcwpa_version = NULL;
672 struct wilc_priv *priv;
673 struct host_if_drv *pstrWFIDrv;
674 struct network_info *pstrNetworkInfo = NULL;
675 struct wilc_vif *vif;
678 priv = wiphy_priv(wiphy);
679 vif = netdev_priv(priv->dev);
680 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
682 if (!(strncmp(sme->ssid, "DIRECT-", 7)))
683 pstrWFIDrv->p2p_connect = 1;
685 pstrWFIDrv->p2p_connect = 0;
687 for (i = 0; i < last_scanned_cnt; i++) {
688 if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
689 memcmp(last_scanned_shadow[i].ssid,
691 sme->ssid_len) == 0) {
695 if (memcmp(last_scanned_shadow[i].bssid,
702 if (i < last_scanned_cnt) {
703 pstrNetworkInfo = &last_scanned_shadow[i];
710 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
711 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
713 if (sme->crypto.cipher_group != NO_ENCRYPT) {
714 pcwpa_version = "Default";
715 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
716 u8security = ENCRYPT_ENABLED | WEP;
717 pcgroup_encrypt_val = "WEP40";
718 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
720 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
721 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
723 g_key_wep_params.key_len = sme->key_len;
724 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
725 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
726 g_key_wep_params.key_idx = sme->key_idx;
727 g_wep_keys_saved = true;
729 wilc_set_wep_default_keyid(vif, sme->key_idx);
730 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
732 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
733 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
734 pcgroup_encrypt_val = "WEP104";
735 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
737 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
738 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
740 g_key_wep_params.key_len = sme->key_len;
741 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
742 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
743 g_key_wep_params.key_idx = sme->key_idx;
744 g_wep_keys_saved = true;
746 wilc_set_wep_default_keyid(vif, sme->key_idx);
747 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
749 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
750 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
751 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
752 pcgroup_encrypt_val = "WPA2_TKIP";
753 pccipher_group = "TKIP";
755 u8security = ENCRYPT_ENABLED | WPA2 | AES;
756 pcgroup_encrypt_val = "WPA2_AES";
757 pccipher_group = "AES";
759 pcwpa_version = "WPA_VERSION_2";
760 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
761 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
762 u8security = ENCRYPT_ENABLED | WPA | TKIP;
763 pcgroup_encrypt_val = "WPA_TKIP";
764 pccipher_group = "TKIP";
766 u8security = ENCRYPT_ENABLED | WPA | AES;
767 pcgroup_encrypt_val = "WPA_AES";
768 pccipher_group = "AES";
770 pcwpa_version = "WPA_VERSION_1";
773 s32Error = -ENOTSUPP;
774 netdev_err(dev, "Not supported cipher\n");
780 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
781 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
782 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
783 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
784 u8security = u8security | TKIP;
786 u8security = u8security | AES;
791 switch (sme->auth_type) {
792 case NL80211_AUTHTYPE_OPEN_SYSTEM:
793 tenuAuth_type = OPEN_SYSTEM;
796 case NL80211_AUTHTYPE_SHARED_KEY:
797 tenuAuth_type = SHARED_KEY;
804 if (sme->crypto.n_akm_suites) {
805 switch (sme->crypto.akm_suites[0]) {
806 case WLAN_AKM_SUITE_8021X:
807 tenuAuth_type = IEEE8021;
815 curr_channel = pstrNetworkInfo->ch;
817 if (!pstrWFIDrv->p2p_connect)
818 wlan_channel = pstrNetworkInfo->ch;
820 wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
822 s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
823 sme->ssid_len, sme->ie, sme->ie_len,
824 CfgConnectResult, (void *)priv,
825 u8security, tenuAuth_type,
827 pstrNetworkInfo->join_params);
829 netdev_err(dev, "wilc_set_join_req(): Error\n");
838 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
841 struct wilc_priv *priv;
842 struct host_if_drv *pstrWFIDrv;
843 struct wilc_vif *vif;
844 u8 NullBssid[ETH_ALEN] = {0};
847 priv = wiphy_priv(wiphy);
848 vif = netdev_priv(priv->dev);
850 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
851 if (!pstrWFIDrv->p2p_connect)
852 wlan_channel = INVALID_CHANNEL;
853 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
855 p2p_local_random = 0x01;
856 p2p_recv_random = 0x00;
858 pstrWFIDrv->p2p_timeout = 0;
860 s32Error = wilc_disconnect(vif, reason_code);
862 netdev_err(priv->dev, "Error in disconnecting\n");
869 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
871 const u8 *mac_addr, struct key_params *params)
874 s32 s32Error = 0, KeyLen = params->key_len;
875 struct wilc_priv *priv;
876 const u8 *pu8RxMic = NULL;
877 const u8 *pu8TxMic = NULL;
878 u8 u8mode = NO_ENCRYPT;
879 u8 u8gmode = NO_ENCRYPT;
880 u8 u8pmode = NO_ENCRYPT;
881 enum AUTHTYPE tenuAuth_type = ANY;
883 struct wilc_vif *vif;
885 priv = wiphy_priv(wiphy);
886 vif = netdev_priv(netdev);
889 switch (params->cipher) {
890 case WLAN_CIPHER_SUITE_WEP40:
891 case WLAN_CIPHER_SUITE_WEP104:
892 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
893 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
894 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
896 tenuAuth_type = OPEN_SYSTEM;
898 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
899 u8mode = ENCRYPT_ENABLED | WEP;
901 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
903 wilc_add_wep_key_bss_ap(vif, params->key,
904 params->key_len, key_index,
905 u8mode, tenuAuth_type);
908 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
909 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
910 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
912 wilc_add_wep_key_bss_sta(vif, params->key,
913 params->key_len, key_index);
918 case WLAN_CIPHER_SUITE_TKIP:
919 case WLAN_CIPHER_SUITE_CCMP:
920 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
921 if (!priv->wilc_gtk[key_index]) {
922 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
923 priv->wilc_gtk[key_index]->key = NULL;
924 priv->wilc_gtk[key_index]->seq = NULL;
926 if (!priv->wilc_ptk[key_index]) {
927 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
928 priv->wilc_ptk[key_index]->key = NULL;
929 priv->wilc_ptk[key_index]->seq = NULL;
935 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
936 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
938 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
940 priv->wilc_groupkey = u8gmode;
942 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
943 pu8TxMic = params->key + 24;
944 pu8RxMic = params->key + 16;
945 KeyLen = params->key_len - 16;
947 kfree(priv->wilc_gtk[key_index]->key);
949 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
950 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
951 kfree(priv->wilc_gtk[key_index]->seq);
953 if ((params->seq_len) > 0) {
954 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
955 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
958 priv->wilc_gtk[key_index]->cipher = params->cipher;
959 priv->wilc_gtk[key_index]->key_len = params->key_len;
960 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
962 wilc_add_rx_gtk(vif, params->key, KeyLen,
963 key_index, params->seq_len,
964 params->seq, pu8RxMic,
965 pu8TxMic, AP_MODE, u8gmode);
968 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
969 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
971 u8pmode = priv->wilc_groupkey | AES;
974 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
975 pu8TxMic = params->key + 24;
976 pu8RxMic = params->key + 16;
977 KeyLen = params->key_len - 16;
980 kfree(priv->wilc_ptk[key_index]->key);
982 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
984 kfree(priv->wilc_ptk[key_index]->seq);
986 if ((params->seq_len) > 0)
987 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
989 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
991 if ((params->seq_len) > 0)
992 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
994 priv->wilc_ptk[key_index]->cipher = params->cipher;
995 priv->wilc_ptk[key_index]->key_len = params->key_len;
996 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
998 wilc_add_ptk(vif, params->key, KeyLen,
999 mac_addr, pu8RxMic, pu8TxMic,
1000 AP_MODE, u8pmode, key_index);
1008 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1009 pu8RxMic = params->key + 24;
1010 pu8TxMic = params->key + 16;
1011 KeyLen = params->key_len - 16;
1014 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
1015 g_add_gtk_key_params.key_idx = key_index;
1016 g_add_gtk_key_params.pairwise = pairwise;
1018 g_add_gtk_key_params.mac_addr = NULL;
1020 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1021 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1023 g_key_gtk_params.key_len = params->key_len;
1024 g_key_gtk_params.seq_len = params->seq_len;
1025 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1026 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1027 if (params->seq_len > 0) {
1028 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1029 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1031 g_key_gtk_params.cipher = params->cipher;
1032 g_gtk_keys_saved = true;
1035 wilc_add_rx_gtk(vif, params->key, KeyLen,
1036 key_index, params->seq_len,
1037 params->seq, pu8RxMic,
1038 pu8TxMic, STATION_MODE,
1041 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1042 pu8RxMic = params->key + 24;
1043 pu8TxMic = params->key + 16;
1044 KeyLen = params->key_len - 16;
1047 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1048 g_add_ptk_key_params.key_idx = key_index;
1049 g_add_ptk_key_params.pairwise = pairwise;
1051 g_add_ptk_key_params.mac_addr = NULL;
1053 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1054 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1056 g_key_ptk_params.key_len = params->key_len;
1057 g_key_ptk_params.seq_len = params->seq_len;
1058 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1059 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1060 if (params->seq_len > 0) {
1061 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1062 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1064 g_key_ptk_params.cipher = params->cipher;
1065 g_ptk_keys_saved = true;
1068 wilc_add_ptk(vif, params->key, KeyLen,
1069 mac_addr, pu8RxMic, pu8TxMic,
1070 STATION_MODE, u8mode, key_index);
1076 netdev_err(netdev, "Not supported cipher\n");
1077 s32Error = -ENOTSUPP;
1083 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1088 struct wilc_priv *priv;
1090 struct wilc_vif *vif;
1092 priv = wiphy_priv(wiphy);
1093 vif = netdev_priv(netdev);
1096 if (netdev == wl->vif[0]->ndev) {
1097 g_ptk_keys_saved = false;
1098 g_gtk_keys_saved = false;
1099 g_wep_keys_saved = false;
1101 kfree(g_key_wep_params.key);
1102 g_key_wep_params.key = NULL;
1104 if ((priv->wilc_gtk[key_index]) != NULL) {
1105 kfree(priv->wilc_gtk[key_index]->key);
1106 priv->wilc_gtk[key_index]->key = NULL;
1107 kfree(priv->wilc_gtk[key_index]->seq);
1108 priv->wilc_gtk[key_index]->seq = NULL;
1110 kfree(priv->wilc_gtk[key_index]);
1111 priv->wilc_gtk[key_index] = NULL;
1114 if ((priv->wilc_ptk[key_index]) != NULL) {
1115 kfree(priv->wilc_ptk[key_index]->key);
1116 priv->wilc_ptk[key_index]->key = NULL;
1117 kfree(priv->wilc_ptk[key_index]->seq);
1118 priv->wilc_ptk[key_index]->seq = NULL;
1119 kfree(priv->wilc_ptk[key_index]);
1120 priv->wilc_ptk[key_index] = NULL;
1123 kfree(g_key_ptk_params.key);
1124 g_key_ptk_params.key = NULL;
1125 kfree(g_key_ptk_params.seq);
1126 g_key_ptk_params.seq = NULL;
1128 kfree(g_key_gtk_params.key);
1129 g_key_gtk_params.key = NULL;
1130 kfree(g_key_gtk_params.seq);
1131 g_key_gtk_params.seq = NULL;
1135 if (key_index >= 0 && key_index <= 3) {
1136 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
1137 priv->WILC_WFI_wep_key_len[key_index] = 0;
1138 wilc_remove_wep_key(vif, key_index);
1140 wilc_remove_key(priv->hif_drv, mac_addr);
1146 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1148 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1150 struct wilc_priv *priv;
1151 struct key_params key_params;
1153 priv = wiphy_priv(wiphy);
1157 key_params.key = priv->wilc_gtk[key_index]->key;
1158 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1159 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1160 key_params.seq = priv->wilc_gtk[key_index]->seq;
1161 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1163 key_params.key = priv->wilc_ptk[key_index]->key;
1164 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1165 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1166 key_params.seq = priv->wilc_ptk[key_index]->seq;
1167 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1170 callback(cookie, &key_params);
1175 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1176 bool unicast, bool multicast)
1178 struct wilc_priv *priv;
1179 struct wilc_vif *vif;
1181 priv = wiphy_priv(wiphy);
1182 vif = netdev_priv(priv->dev);
1184 wilc_set_wep_default_keyid(vif, key_index);
1189 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1190 const u8 *mac, struct station_info *sinfo)
1192 struct wilc_priv *priv;
1193 struct wilc_vif *vif;
1195 u32 associatedsta = 0;
1196 u32 inactive_time = 0;
1197 priv = wiphy_priv(wiphy);
1198 vif = netdev_priv(dev);
1200 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1201 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1202 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1208 if (associatedsta == -1) {
1209 netdev_err(dev, "sta required is not associated\n");
1213 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1215 wilc_get_inactive_time(vif, mac, &inactive_time);
1216 sinfo->inactive_time = 1000 * inactive_time;
1219 if (vif->iftype == STATION_MODE) {
1220 struct rf_info strStatistics;
1222 wilc_get_statistics(vif, &strStatistics);
1224 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1225 BIT(NL80211_STA_INFO_RX_PACKETS) |
1226 BIT(NL80211_STA_INFO_TX_PACKETS) |
1227 BIT(NL80211_STA_INFO_TX_FAILED) |
1228 BIT(NL80211_STA_INFO_TX_BITRATE);
1230 sinfo->signal = strStatistics.rssi;
1231 sinfo->rx_packets = strStatistics.rx_cnt;
1232 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1233 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1234 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1236 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1237 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1238 wilc_enable_tcp_ack_filter(true);
1239 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1240 wilc_enable_tcp_ack_filter(false);
1245 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1246 struct bss_parameters *params)
1251 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1254 struct cfg_param_val pstrCfgParamVal;
1255 struct wilc_priv *priv;
1256 struct wilc_vif *vif;
1258 priv = wiphy_priv(wiphy);
1259 vif = netdev_priv(priv->dev);
1261 pstrCfgParamVal.flag = 0;
1263 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1264 pstrCfgParamVal.flag |= RETRY_SHORT;
1265 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1267 if (changed & WIPHY_PARAM_RETRY_LONG) {
1268 pstrCfgParamVal.flag |= RETRY_LONG;
1269 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1271 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1272 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1273 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1276 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1277 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1278 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1281 s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1283 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1288 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1289 struct cfg80211_pmksa *pmksa)
1294 struct wilc_vif *vif;
1295 struct wilc_priv *priv = wiphy_priv(wiphy);
1297 vif = netdev_priv(priv->dev);
1300 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1301 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1307 if (i < WILC_MAX_NUM_PMKIDS) {
1308 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1310 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1312 if (!(flag == PMKID_FOUND))
1313 priv->pmkid_list.numpmkid++;
1315 netdev_err(netdev, "Invalid PMKID index\n");
1320 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1325 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1326 struct cfg80211_pmksa *pmksa)
1331 struct wilc_priv *priv = wiphy_priv(wiphy);
1333 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1334 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1336 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1341 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1342 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1343 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1344 priv->pmkid_list.pmkidlist[i + 1].bssid,
1346 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1347 priv->pmkid_list.pmkidlist[i].pmkid,
1350 priv->pmkid_list.numpmkid--;
1358 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1360 struct wilc_priv *priv = wiphy_priv(wiphy);
1362 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1367 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1372 u8 op_channel_attr_index = 0;
1373 u8 channel_list_attr_index = 0;
1375 while (index < len) {
1376 if (buf[index] == GO_INTENT_ATTR_ID) {
1377 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
1380 if (buf[index] == CHANLIST_ATTR_ID)
1381 channel_list_attr_index = index;
1382 else if (buf[index] == OPERCHAN_ATTR_ID)
1383 op_channel_attr_index = index;
1384 index += buf[index + 1] + 3;
1386 if (wlan_channel != INVALID_CHANNEL) {
1387 if (channel_list_attr_index) {
1388 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1389 if (buf[i] == 0x51) {
1390 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1391 buf[j] = wlan_channel;
1398 if (op_channel_attr_index) {
1399 buf[op_channel_attr_index + 6] = 0x51;
1400 buf[op_channel_attr_index + 7] = wlan_channel;
1405 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1410 u8 op_channel_attr_index = 0;
1411 u8 channel_list_attr_index = 0;
1413 while (index < len) {
1414 if (buf[index] == GO_INTENT_ATTR_ID) {
1415 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
1420 if (buf[index] == CHANLIST_ATTR_ID)
1421 channel_list_attr_index = index;
1422 else if (buf[index] == OPERCHAN_ATTR_ID)
1423 op_channel_attr_index = index;
1424 index += buf[index + 1] + 3;
1426 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1427 if (channel_list_attr_index) {
1428 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1429 if (buf[i] == 0x51) {
1430 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1431 buf[j] = wlan_channel;
1438 if (op_channel_attr_index) {
1439 buf[op_channel_attr_index + 6] = 0x51;
1440 buf[op_channel_attr_index + 7] = wlan_channel;
1445 void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
1447 struct wilc_priv *priv;
1448 u32 header, pkt_offset;
1449 struct host_if_drv *pstrWFIDrv;
1453 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1454 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1456 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1458 pkt_offset = GET_PKT_OFFSET(header);
1460 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1461 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1462 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1465 if (pkt_offset & IS_MGMT_STATUS_SUCCES)
1466 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1468 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1472 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
1474 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1475 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1476 netdev_dbg(dev, "Receiving action wrong ch\n");
1479 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1480 switch (buff[ACTION_SUBTYPE_ID]) {
1481 case GAS_INTIAL_REQ:
1484 case GAS_INTIAL_RSP:
1487 case PUBLIC_ACT_VENDORSPEC:
1488 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1489 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1491 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1492 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1493 p2p_recv_random = buff[i + 6];
1500 if (p2p_local_random > p2p_recv_random) {
1501 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1502 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1503 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1504 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1505 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1511 netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1516 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
1517 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1523 netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1529 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1533 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1535 struct p2p_mgmt_data *pv_data = priv;
1538 kfree(pv_data->buff);
1542 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1544 struct wilc_priv *priv;
1548 priv->bInP2PlistenState = true;
1550 cfg80211_ready_on_channel(priv->wdev,
1551 priv->strRemainOnChanParams.u64ListenCookie,
1552 priv->strRemainOnChanParams.pstrListenChan,
1553 priv->strRemainOnChanParams.u32ListenDuration,
1557 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1559 struct wilc_priv *priv;
1563 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1564 priv->bInP2PlistenState = false;
1566 cfg80211_remain_on_channel_expired(priv->wdev,
1567 priv->strRemainOnChanParams.u64ListenCookie,
1568 priv->strRemainOnChanParams.pstrListenChan,
1573 static int remain_on_channel(struct wiphy *wiphy,
1574 struct wireless_dev *wdev,
1575 struct ieee80211_channel *chan,
1576 unsigned int duration, u64 *cookie)
1579 struct wilc_priv *priv;
1580 struct wilc_vif *vif;
1582 priv = wiphy_priv(wiphy);
1583 vif = netdev_priv(priv->dev);
1585 if (wdev->iftype == NL80211_IFTYPE_AP) {
1586 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1590 curr_channel = chan->hw_value;
1592 priv->strRemainOnChanParams.pstrListenChan = chan;
1593 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1594 priv->strRemainOnChanParams.u32ListenDuration = duration;
1595 priv->strRemainOnChanParams.u32ListenSessionID++;
1597 s32Error = wilc_remain_on_channel(vif,
1598 priv->strRemainOnChanParams.u32ListenSessionID,
1599 duration, chan->hw_value,
1600 WILC_WFI_RemainOnChannelExpired,
1601 WILC_WFI_RemainOnChannelReady, (void *)priv);
1606 static int cancel_remain_on_channel(struct wiphy *wiphy,
1607 struct wireless_dev *wdev,
1611 struct wilc_priv *priv;
1612 struct wilc_vif *vif;
1614 priv = wiphy_priv(wiphy);
1615 vif = netdev_priv(priv->dev);
1617 s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
1621 static int mgmt_tx(struct wiphy *wiphy,
1622 struct wireless_dev *wdev,
1623 struct cfg80211_mgmt_tx_params *params,
1626 struct ieee80211_channel *chan = params->chan;
1627 unsigned int wait = params->wait;
1628 const u8 *buf = params->buf;
1629 size_t len = params->len;
1630 const struct ieee80211_mgmt *mgmt;
1631 struct p2p_mgmt_data *mgmt_tx;
1632 struct wilc_priv *priv;
1633 struct host_if_drv *pstrWFIDrv;
1635 struct wilc_vif *vif;
1636 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1638 vif = netdev_priv(wdev->netdev);
1639 priv = wiphy_priv(wiphy);
1640 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1642 *cookie = (unsigned long)buf;
1643 priv->u64tx_cookie = *cookie;
1644 mgmt = (const struct ieee80211_mgmt *) buf;
1646 if (ieee80211_is_mgmt(mgmt->frame_control)) {
1647 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1651 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1652 if (!mgmt_tx->buff) {
1657 memcpy(mgmt_tx->buff, buf, len);
1658 mgmt_tx->size = len;
1661 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1662 wilc_set_mac_chnl_num(vif, chan->hw_value);
1663 curr_channel = chan->hw_value;
1664 } else if (ieee80211_is_action(mgmt->frame_control)) {
1665 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1666 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1667 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1668 wilc_set_mac_chnl_num(vif,
1670 curr_channel = chan->hw_value;
1672 switch (buf[ACTION_SUBTYPE_ID]) {
1673 case GAS_INTIAL_REQ:
1676 case GAS_INTIAL_RSP:
1679 case PUBLIC_ACT_VENDORSPEC:
1681 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1682 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1683 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1684 get_random_bytes(&p2p_local_random, 1);
1689 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1690 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1691 if (p2p_local_random > p2p_recv_random) {
1692 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1693 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1694 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1695 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1697 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1702 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1703 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1704 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1705 mgmt_tx->size = buf_len;
1711 netdev_dbg(vif->ndev, "Not a P2P public action frame\n");
1719 netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1725 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1728 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1729 mgmt_tx->buff, mgmt_tx->size,
1730 WILC_WFI_mgmt_tx_complete);
1735 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1736 struct wireless_dev *wdev,
1739 struct wilc_priv *priv;
1740 struct host_if_drv *pstrWFIDrv;
1742 priv = wiphy_priv(wiphy);
1743 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1744 pstrWFIDrv->p2p_timeout = jiffies;
1746 if (!priv->bInP2PlistenState) {
1747 cfg80211_remain_on_channel_expired(priv->wdev,
1748 priv->strRemainOnChanParams.u64ListenCookie,
1749 priv->strRemainOnChanParams.pstrListenChan,
1756 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1757 u16 frame_type, bool reg)
1759 struct wilc_priv *priv;
1760 struct wilc_vif *vif;
1763 priv = wiphy_priv(wiphy);
1764 vif = netdev_priv(priv->wdev->netdev);
1770 switch (frame_type) {
1773 vif->g_struct_frame_reg[0].frame_type = frame_type;
1774 vif->g_struct_frame_reg[0].reg = reg;
1780 vif->g_struct_frame_reg[1].frame_type = frame_type;
1781 vif->g_struct_frame_reg[1].reg = reg;
1791 if (!wl->initialized)
1793 wilc_frame_register(vif, frame_type, reg);
1796 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1797 s32 rssi_thold, u32 rssi_hyst)
1802 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1803 int idx, u8 *mac, struct station_info *sinfo)
1805 struct wilc_priv *priv;
1806 struct wilc_vif *vif;
1811 priv = wiphy_priv(wiphy);
1812 vif = netdev_priv(priv->dev);
1814 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1816 wilc_get_rssi(vif, &sinfo->signal);
1821 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1822 bool enabled, int timeout)
1824 struct wilc_priv *priv;
1825 struct wilc_vif *vif;
1830 priv = wiphy_priv(wiphy);
1831 vif = netdev_priv(priv->dev);
1836 wilc_set_power_mgmt(vif, enabled, timeout);
1842 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1843 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
1845 struct wilc_priv *priv;
1846 struct wilc_vif *vif;
1849 vif = netdev_priv(dev);
1850 priv = wiphy_priv(wiphy);
1852 p2p_local_random = 0x01;
1853 p2p_recv_random = 0x00;
1855 wilc_optaining_ip = false;
1856 del_timer(&wilc_during_ip_timer);
1859 case NL80211_IFTYPE_STATION:
1860 wilc_connecting = 0;
1861 dev->ieee80211_ptr->iftype = type;
1862 priv->wdev->iftype = type;
1863 vif->monitor_flag = 0;
1864 vif->iftype = STATION_MODE;
1865 wilc_set_operation_mode(vif, STATION_MODE);
1867 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
1869 wilc_enable_ps = true;
1870 wilc_set_power_mgmt(vif, 1, 0);
1873 case NL80211_IFTYPE_P2P_CLIENT:
1874 wilc_connecting = 0;
1875 dev->ieee80211_ptr->iftype = type;
1876 priv->wdev->iftype = type;
1877 vif->monitor_flag = 0;
1878 vif->iftype = CLIENT_MODE;
1879 wilc_set_operation_mode(vif, STATION_MODE);
1881 wilc_enable_ps = false;
1882 wilc_set_power_mgmt(vif, 0, 0);
1885 case NL80211_IFTYPE_AP:
1886 wilc_enable_ps = false;
1887 dev->ieee80211_ptr->iftype = type;
1888 priv->wdev->iftype = type;
1889 vif->iftype = AP_MODE;
1891 if (wl->initialized) {
1892 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
1894 wilc_set_operation_mode(vif, AP_MODE);
1895 wilc_set_power_mgmt(vif, 0, 0);
1899 case NL80211_IFTYPE_P2P_GO:
1900 wilc_optaining_ip = true;
1901 mod_timer(&wilc_during_ip_timer,
1902 jiffies + msecs_to_jiffies(during_ip_time));
1903 wilc_set_operation_mode(vif, AP_MODE);
1904 dev->ieee80211_ptr->iftype = type;
1905 priv->wdev->iftype = type;
1906 vif->iftype = GO_MODE;
1908 wilc_enable_ps = false;
1909 wilc_set_power_mgmt(vif, 0, 0);
1913 netdev_err(dev, "Unknown interface type= %d\n", type);
1920 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1921 struct cfg80211_ap_settings *settings)
1923 struct cfg80211_beacon_data *beacon = &(settings->beacon);
1924 struct wilc_priv *priv;
1927 struct wilc_vif *vif;
1929 priv = wiphy_priv(wiphy);
1930 vif = netdev_priv(dev);
1933 s32Error = set_channel(wiphy, &settings->chandef);
1936 netdev_err(dev, "Error in setting channel\n");
1938 wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
1939 wilc_set_power_mgmt(vif, 0, 0);
1941 s32Error = wilc_add_beacon(vif, settings->beacon_interval,
1942 settings->dtim_period, beacon->head_len,
1943 (u8 *)beacon->head, beacon->tail_len,
1944 (u8 *)beacon->tail);
1949 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1950 struct cfg80211_beacon_data *beacon)
1952 struct wilc_priv *priv;
1953 struct wilc_vif *vif;
1956 priv = wiphy_priv(wiphy);
1957 vif = netdev_priv(priv->dev);
1959 s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
1960 (u8 *)beacon->head, beacon->tail_len,
1961 (u8 *)beacon->tail);
1966 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1969 struct wilc_priv *priv;
1970 struct wilc_vif *vif;
1971 u8 NullBssid[ETH_ALEN] = {0};
1976 priv = wiphy_priv(wiphy);
1977 vif = netdev_priv(priv->dev);
1979 wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
1981 s32Error = wilc_del_beacon(vif);
1984 netdev_err(dev, "Host delete beacon fail\n");
1989 static int add_station(struct wiphy *wiphy, struct net_device *dev,
1990 const u8 *mac, struct station_parameters *params)
1993 struct wilc_priv *priv;
1994 struct add_sta_param strStaParams = { {0} };
1995 struct wilc_vif *vif;
2000 priv = wiphy_priv(wiphy);
2001 vif = netdev_priv(dev);
2003 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2004 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2005 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
2006 strStaParams.aid = params->aid;
2007 strStaParams.rates_len = params->supported_rates_len;
2008 strStaParams.rates = params->supported_rates;
2010 if (!params->ht_capa) {
2011 strStaParams.ht_supported = false;
2013 strStaParams.ht_supported = true;
2014 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2015 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2016 memcpy(strStaParams.ht_supp_mcs_set,
2017 ¶ms->ht_capa->mcs,
2018 WILC_SUPP_MCS_SET_SIZE);
2019 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2020 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2021 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2024 strStaParams.flags_mask = params->sta_flags_mask;
2025 strStaParams.flags_set = params->sta_flags_set;
2027 s32Error = wilc_add_station(vif, &strStaParams);
2029 netdev_err(dev, "Host add station fail\n");
2035 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2036 struct station_del_parameters *params)
2038 const u8 *mac = params->mac;
2040 struct wilc_priv *priv;
2041 struct wilc_vif *vif;
2046 priv = wiphy_priv(wiphy);
2047 vif = netdev_priv(dev);
2049 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2051 s32Error = wilc_del_allstation(vif,
2052 priv->assoc_stainfo.au8Sta_AssociatedBss);
2054 s32Error = wilc_del_station(vif, mac);
2057 netdev_err(dev, "Host delete station fail\n");
2062 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2063 const u8 *mac, struct station_parameters *params)
2066 struct wilc_priv *priv;
2067 struct add_sta_param strStaParams = { {0} };
2068 struct wilc_vif *vif;
2073 priv = wiphy_priv(wiphy);
2074 vif = netdev_priv(dev);
2076 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2077 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2078 strStaParams.aid = params->aid;
2079 strStaParams.rates_len = params->supported_rates_len;
2080 strStaParams.rates = params->supported_rates;
2082 if (!params->ht_capa) {
2083 strStaParams.ht_supported = false;
2085 strStaParams.ht_supported = true;
2086 strStaParams.ht_capa_info = params->ht_capa->cap_info;
2087 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
2088 memcpy(strStaParams.ht_supp_mcs_set,
2089 ¶ms->ht_capa->mcs,
2090 WILC_SUPP_MCS_SET_SIZE);
2091 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
2092 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
2093 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
2096 strStaParams.flags_mask = params->sta_flags_mask;
2097 strStaParams.flags_set = params->sta_flags_set;
2099 s32Error = wilc_edit_station(vif, &strStaParams);
2101 netdev_err(dev, "Host edit station fail\n");
2106 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2108 unsigned char name_assign_type,
2109 enum nl80211_iftype type,
2111 struct vif_params *params)
2113 struct wilc_vif *vif;
2114 struct wilc_priv *priv;
2115 struct net_device *new_ifc = NULL;
2117 priv = wiphy_priv(wiphy);
2118 vif = netdev_priv(priv->wdev->netdev);
2121 if (type == NL80211_IFTYPE_MONITOR) {
2122 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2124 vif = netdev_priv(priv->wdev->netdev);
2125 vif->monitor_flag = 1;
2131 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2136 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2138 struct wilc_priv *priv = wiphy_priv(wiphy);
2139 struct wilc_vif *vif = netdev_priv(priv->dev);
2141 if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2142 vif->wilc->suspend_event = true;
2144 vif->wilc->suspend_event = false;
2149 static int wilc_resume(struct wiphy *wiphy)
2151 struct wilc_priv *priv = wiphy_priv(wiphy);
2152 struct wilc_vif *vif = netdev_priv(priv->dev);
2154 netdev_info(vif->ndev, "cfg resume\n");
2158 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2160 struct wilc_priv *priv = wiphy_priv(wiphy);
2161 struct wilc_vif *vif = netdev_priv(priv->dev);
2163 netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2166 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2167 enum nl80211_tx_power_setting type, int mbm)
2170 s32 tx_power = MBM_TO_DBM(mbm);
2171 struct wilc_priv *priv = wiphy_priv(wiphy);
2172 struct wilc_vif *vif = netdev_priv(priv->dev);
2176 else if (tx_power > 18)
2178 ret = wilc_set_tx_power(vif, tx_power);
2180 netdev_err(vif->ndev, "Failed to set tx power\n");
2185 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2189 struct wilc_priv *priv = wiphy_priv(wiphy);
2190 struct wilc_vif *vif = netdev_priv(priv->dev);
2192 ret = wilc_get_tx_power(vif, (u8 *)dbm);
2194 netdev_err(vif->ndev, "Failed to get tx power\n");
2199 static struct cfg80211_ops wilc_cfg80211_ops = {
2200 .set_monitor_channel = set_channel,
2203 .disconnect = disconnect,
2207 .set_default_key = set_default_key,
2208 .add_virtual_intf = add_virtual_intf,
2209 .del_virtual_intf = del_virtual_intf,
2210 .change_virtual_intf = change_virtual_intf,
2212 .start_ap = start_ap,
2213 .change_beacon = change_beacon,
2215 .add_station = add_station,
2216 .del_station = del_station,
2217 .change_station = change_station,
2218 .get_station = get_station,
2219 .dump_station = dump_station,
2220 .change_bss = change_bss,
2221 .set_wiphy_params = set_wiphy_params,
2223 .set_pmksa = set_pmksa,
2224 .del_pmksa = del_pmksa,
2225 .flush_pmksa = flush_pmksa,
2226 .remain_on_channel = remain_on_channel,
2227 .cancel_remain_on_channel = cancel_remain_on_channel,
2228 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2230 .mgmt_frame_register = wilc_mgmt_frame_register,
2231 .set_power_mgmt = set_power_mgmt,
2232 .set_cqm_rssi_config = set_cqm_rssi_config,
2234 .suspend = wilc_suspend,
2235 .resume = wilc_resume,
2236 .set_wakeup = wilc_set_wakeup,
2237 .set_tx_power = set_tx_power,
2238 .get_tx_power = get_tx_power,
2242 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2244 struct wireless_dev *wdev;
2246 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2250 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2254 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2255 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2256 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2257 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2258 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2260 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2270 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2272 struct wilc_priv *priv;
2273 struct wireless_dev *wdev;
2276 wdev = WILC_WFI_CfgAlloc();
2278 netdev_err(net, "wiphy new allocate failed\n");
2282 priv = wdev_priv(wdev);
2283 sema_init(&(priv->SemHandleUpdateStats), 1);
2285 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2287 wdev->wiphy->wowlan = &wowlan_support;
2289 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2290 wdev->wiphy->max_scan_ie_len = 1000;
2291 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2292 wdev->wiphy->cipher_suites = cipher_suites;
2293 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2294 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2296 wdev->wiphy->max_remain_on_channel_duration = 500;
2297 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2298 BIT(NL80211_IFTYPE_P2P_CLIENT);
2299 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2300 wdev->iftype = NL80211_IFTYPE_STATION;
2302 set_wiphy_dev(wdev->wiphy, dev);
2304 s32Error = wiphy_register(wdev->wiphy);
2306 netdev_err(net, "Cannot register wiphy device\n");
2312 int wilc_init_host_int(struct net_device *net)
2316 struct wilc_priv *priv;
2318 priv = wdev_priv(net->ieee80211_ptr);
2320 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2321 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2325 priv->gbAutoRateAdjusted = false;
2327 priv->bInP2PlistenState = false;
2329 sema_init(&(priv->hSemScanReq), 1);
2330 s32Error = wilc_init(net, &priv->hif_drv);
2332 netdev_err(net, "Error while initializing hostinterface\n");
2337 int wilc_deinit_host_int(struct net_device *net)
2340 struct wilc_vif *vif;
2341 struct wilc_priv *priv;
2343 priv = wdev_priv(net->ieee80211_ptr);
2344 vif = netdev_priv(priv->dev);
2346 priv->gbAutoRateAdjusted = false;
2348 priv->bInP2PlistenState = false;
2352 s32Error = wilc_deinit(vif);
2354 clear_shadow_scan();
2356 del_timer_sync(&wilc_during_ip_timer);
2359 netdev_err(net, "Error while deintializing host interface\n");
2364 void wilc_free_wiphy(struct net_device *net)
2369 if (!net->ieee80211_ptr)
2372 if (!net->ieee80211_ptr->wiphy)
2375 wiphy_unregister(net->ieee80211_ptr->wiphy);
2377 wiphy_free(net->ieee80211_ptr->wiphy);
2378 kfree(net->ieee80211_ptr);