1 // SPDX-License-Identifier: GPL-2.0
2 #include "wilc_wfi_cfgoperations.h"
3 #include "host_interface.h"
4 #include <linux/errno.h>
7 #define ENCRYPT_ENABLED BIT(0)
9 #define WEP_EXTENDED BIT(2)
15 #define FRAME_TYPE_ID 0
16 #define ACTION_CAT_ID 24
17 #define ACTION_SUBTYPE_ID 25
18 #define P2P_PUB_ACTION_SUBTYPE 30
20 #define ACTION_FRAME 0xd0
21 #define GO_INTENT_ATTR_ID 0x04
22 #define CHANLIST_ATTR_ID 0x0b
23 #define OPERCHAN_ATTR_ID 0x11
24 #define PUB_ACTION_ATTR_ID 0x04
25 #define P2PELEM_ATTR_ID 0xdd
27 #define GO_NEG_REQ 0x00
28 #define GO_NEG_RSP 0x01
29 #define GO_NEG_CONF 0x02
30 #define P2P_INV_REQ 0x03
31 #define P2P_INV_RSP 0x04
32 #define PUBLIC_ACT_VENDORSPEC 0x09
33 #define GAS_INITIAL_REQ 0x0a
34 #define GAS_INITIAL_RSP 0x0b
36 #define INVALID_CHANNEL 0
38 #define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
39 #define SCAN_RESULT_EXPIRE (40 * HZ)
41 static const u32 cipher_suites[] = {
42 WLAN_CIPHER_SUITE_WEP40,
43 WLAN_CIPHER_SUITE_WEP104,
44 WLAN_CIPHER_SUITE_TKIP,
45 WLAN_CIPHER_SUITE_CCMP,
46 WLAN_CIPHER_SUITE_AES_CMAC,
49 static const struct ieee80211_txrx_stypes
50 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
51 [NL80211_IFTYPE_STATION] = {
53 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
54 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
56 [NL80211_IFTYPE_AP] = {
58 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
59 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
60 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
61 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
62 BIT(IEEE80211_STYPE_AUTH >> 4) |
63 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
64 BIT(IEEE80211_STYPE_ACTION >> 4)
66 [NL80211_IFTYPE_P2P_CLIENT] = {
68 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
69 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
70 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
71 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
72 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
73 BIT(IEEE80211_STYPE_AUTH >> 4) |
74 BIT(IEEE80211_STYPE_DEAUTH >> 4)
78 static const struct wiphy_wowlan_support wowlan_support = {
79 .flags = WIPHY_WOWLAN_ANY
82 #define WILC_WFI_DWELL_PASSIVE 100
83 #define WILC_WFI_DWELL_ACTIVE 40
85 #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
86 #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 static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
94 static u32 last_scanned_cnt;
95 struct timer_list wilc_during_ip_timer;
96 static struct timer_list hAgingTimer;
99 #define CHAN2G(_channel, _freq, _flags) { \
100 .band = NL80211_BAND_2GHZ, \
101 .center_freq = (_freq), \
102 .hw_value = (_channel), \
104 .max_antenna_gain = 0, \
108 static struct ieee80211_channel ieee80211_2ghz_channels[] = {
125 #define RATETAB_ENT(_rate, _hw_value, _flags) { \
126 .bitrate = (_rate), \
127 .hw_value = (_hw_value), \
131 static struct ieee80211_rate ieee80211_bitrates[] = {
132 RATETAB_ENT(10, 0, 0),
133 RATETAB_ENT(20, 1, 0),
134 RATETAB_ENT(55, 2, 0),
135 RATETAB_ENT(110, 3, 0),
136 RATETAB_ENT(60, 9, 0),
137 RATETAB_ENT(90, 6, 0),
138 RATETAB_ENT(120, 7, 0),
139 RATETAB_ENT(180, 8, 0),
140 RATETAB_ENT(240, 9, 0),
141 RATETAB_ENT(360, 10, 0),
142 RATETAB_ENT(480, 11, 0),
143 RATETAB_ENT(540, 12, 0),
146 struct p2p_mgmt_data {
151 static u8 wlan_channel = INVALID_CHANNEL;
152 static u8 curr_channel;
153 static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
154 static u8 p2p_local_random = 0x01;
155 static u8 p2p_recv_random;
156 static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
159 static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
160 .channels = ieee80211_2ghz_channels,
161 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
162 .bitrates = ieee80211_bitrates,
163 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
166 struct add_key_params {
172 static struct add_key_params g_add_gtk_key_params;
173 static struct wilc_wfi_key g_key_gtk_params;
174 static struct add_key_params g_add_ptk_key_params;
175 static struct wilc_wfi_key g_key_ptk_params;
176 static struct wilc_wfi_wep_key g_key_wep_params;
177 static bool g_ptk_keys_saved;
178 static bool g_gtk_keys_saved;
179 static bool g_wep_keys_saved;
181 #define AGING_TIME (9 * 1000)
182 #define during_ip_time 15000
184 static void clear_shadow_scan(void)
189 del_timer_sync(&hAgingTimer);
191 for (i = 0; i < last_scanned_cnt; i++) {
192 if (last_scanned_shadow[last_scanned_cnt].ies) {
193 kfree(last_scanned_shadow[i].ies);
194 last_scanned_shadow[last_scanned_cnt].ies = NULL;
197 kfree(last_scanned_shadow[i].join_params);
198 last_scanned_shadow[i].join_params = NULL;
200 last_scanned_cnt = 0;
204 static u32 get_rssi_avg(struct network_info *network_info)
208 u8 num_rssi = (network_info->rssi_history.full) ?
209 NUM_RSSI : (network_info->rssi_history.index);
211 for (i = 0; i < num_rssi; i++)
212 rssi_v += network_info->rssi_history.samples[i];
218 static void refresh_scan(struct wilc_priv *priv, bool direct_scan)
220 struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
223 for (i = 0; i < last_scanned_cnt; i++) {
224 struct network_info *network_info;
226 struct ieee80211_channel *channel;
228 struct cfg80211_bss *bss;
230 network_info = &last_scanned_shadow[i];
232 if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan)
235 freq = ieee80211_channel_to_frequency((s32)network_info->ch,
237 channel = ieee80211_get_channel(wiphy, freq);
238 rssi = get_rssi_avg(network_info);
239 bss = cfg80211_inform_bss(wiphy,
241 CFG80211_BSS_FTYPE_UNKNOWN,
243 network_info->tsf_hi,
244 network_info->cap_info,
245 network_info->beacon_period,
246 (const u8 *)network_info->ies,
247 (size_t)network_info->ies_len,
250 cfg80211_put_bss(wiphy, bss);
254 static void reset_shadow_found(void)
258 for (i = 0; i < last_scanned_cnt; i++)
259 last_scanned_shadow[i].found = 0;
262 static void update_scan_time(void)
266 for (i = 0; i < last_scanned_cnt; i++)
267 last_scanned_shadow[i].time_scan = jiffies;
270 static void remove_network_from_shadow(unsigned long arg)
272 unsigned long now = jiffies;
275 for (i = 0; i < last_scanned_cnt; i++) {
276 if (time_after(now, last_scanned_shadow[i].time_scan +
277 (unsigned long)(SCAN_RESULT_EXPIRE))) {
278 kfree(last_scanned_shadow[i].ies);
279 last_scanned_shadow[i].ies = NULL;
281 kfree(last_scanned_shadow[i].join_params);
283 for (j = i; (j < last_scanned_cnt - 1); j++)
284 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
290 if (last_scanned_cnt != 0) {
291 hAgingTimer.data = arg;
292 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
296 static void clear_duringIP(unsigned long arg)
298 wilc_optaining_ip = false;
301 static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
307 if (last_scanned_cnt == 0) {
308 hAgingTimer.data = (unsigned long)user_void;
309 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
312 for (i = 0; i < last_scanned_cnt; i++) {
313 if (memcmp(last_scanned_shadow[i].bssid,
314 pstrNetworkInfo->bssid, 6) == 0) {
323 static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
324 void *user_void, void *pJoinParams)
326 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
330 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
333 if (ap_found == -1) {
334 ap_index = last_scanned_cnt;
339 rssi_index = last_scanned_shadow[ap_index].rssi_history.index;
340 last_scanned_shadow[ap_index].rssi_history.samples[rssi_index++] = pstrNetworkInfo->rssi;
341 if (rssi_index == NUM_RSSI) {
343 last_scanned_shadow[ap_index].rssi_history.full = true;
345 last_scanned_shadow[ap_index].rssi_history.index = rssi_index;
346 last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
347 last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
348 last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
349 memcpy(last_scanned_shadow[ap_index].ssid,
350 pstrNetworkInfo->ssid, pstrNetworkInfo->ssid_len);
351 memcpy(last_scanned_shadow[ap_index].bssid,
352 pstrNetworkInfo->bssid, ETH_ALEN);
353 last_scanned_shadow[ap_index].beacon_period = pstrNetworkInfo->beacon_period;
354 last_scanned_shadow[ap_index].dtim_period = pstrNetworkInfo->dtim_period;
355 last_scanned_shadow[ap_index].ch = pstrNetworkInfo->ch;
356 last_scanned_shadow[ap_index].ies_len = pstrNetworkInfo->ies_len;
357 last_scanned_shadow[ap_index].tsf_hi = pstrNetworkInfo->tsf_hi;
359 kfree(last_scanned_shadow[ap_index].ies);
360 last_scanned_shadow[ap_index].ies = kmalloc(pstrNetworkInfo->ies_len,
362 memcpy(last_scanned_shadow[ap_index].ies,
363 pstrNetworkInfo->ies, pstrNetworkInfo->ies_len);
364 last_scanned_shadow[ap_index].time_scan = jiffies;
365 last_scanned_shadow[ap_index].time_scan_cached = jiffies;
366 last_scanned_shadow[ap_index].found = 1;
368 kfree(last_scanned_shadow[ap_index].join_params);
369 last_scanned_shadow[ap_index].join_params = pJoinParams;
372 static void CfgScanResult(enum scan_event scan_event,
373 struct network_info *network_info,
377 struct wilc_priv *priv;
380 struct ieee80211_channel *channel;
381 struct cfg80211_bss *bss = NULL;
384 if (priv->bCfgScanning) {
385 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
386 wiphy = priv->dev->ieee80211_ptr->wiphy;
391 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
392 (((s32)network_info->rssi * 100) < 0 ||
393 ((s32)network_info->rssi * 100) > 100))
397 s32Freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ);
398 channel = ieee80211_get_channel(wiphy, s32Freq);
403 if (network_info->new_network) {
404 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
405 priv->u32RcvdChCount++;
407 add_network_to_shadow(network_info, priv, join_params);
409 if (!(memcmp("DIRECT-", network_info->ssid, 7))) {
410 bss = cfg80211_inform_bss(wiphy,
412 CFG80211_BSS_FTYPE_UNKNOWN,
414 network_info->tsf_hi,
415 network_info->cap_info,
416 network_info->beacon_period,
417 (const u8 *)network_info->ies,
418 (size_t)network_info->ies_len,
419 (s32)network_info->rssi * 100,
421 cfg80211_put_bss(wiphy, bss);
427 for (i = 0; i < priv->u32RcvdChCount; i++) {
428 if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) {
429 last_scanned_shadow[i].rssi = network_info->rssi;
430 last_scanned_shadow[i].time_scan = jiffies;
436 } else if (scan_event == SCAN_EVENT_DONE) {
437 refresh_scan(priv, false);
439 mutex_lock(&priv->scan_req_lock);
441 if (priv->pstrScanReq) {
442 struct cfg80211_scan_info info = {
446 cfg80211_scan_done(priv->pstrScanReq, &info);
447 priv->u32RcvdChCount = 0;
448 priv->bCfgScanning = false;
449 priv->pstrScanReq = NULL;
451 mutex_unlock(&priv->scan_req_lock);
452 } else if (scan_event == SCAN_EVENT_ABORTED) {
453 mutex_lock(&priv->scan_req_lock);
455 if (priv->pstrScanReq) {
456 struct cfg80211_scan_info info = {
461 refresh_scan(priv, false);
463 cfg80211_scan_done(priv->pstrScanReq, &info);
464 priv->bCfgScanning = false;
465 priv->pstrScanReq = NULL;
467 mutex_unlock(&priv->scan_req_lock);
474 static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
475 struct connect_info *pstrConnectInfo,
477 struct disconnect_info *pstrDisconnectNotifInfo,
480 struct wilc_priv *priv;
481 struct net_device *dev;
482 struct host_if_drv *pstrWFIDrv;
483 u8 NullBssid[ETH_ALEN] = {0};
485 struct wilc_vif *vif;
491 vif = netdev_priv(dev);
493 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
495 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
496 u16 u16ConnectStatus;
498 u16ConnectStatus = pstrConnectInfo->status;
500 if ((u8MacStatus == MAC_DISCONNECTED) &&
501 (pstrConnectInfo->status == SUCCESSFUL_STATUSCODE)) {
502 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
503 wilc_wlan_set_bssid(priv->dev, NullBssid,
505 eth_zero_addr(wilc_connected_ssid);
507 if (!pstrWFIDrv->p2p_connect)
508 wlan_channel = INVALID_CHANNEL;
510 netdev_err(dev, "Unspecified failure\n");
513 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
514 bool bNeedScanRefresh = false;
517 memcpy(priv->au8AssociatedBss, pstrConnectInfo->bssid, ETH_ALEN);
519 for (i = 0; i < last_scanned_cnt; i++) {
520 if (memcmp(last_scanned_shadow[i].bssid,
521 pstrConnectInfo->bssid,
523 unsigned long now = jiffies;
526 last_scanned_shadow[i].time_scan_cached +
527 (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
528 bNeedScanRefresh = true;
534 if (bNeedScanRefresh)
535 refresh_scan(priv, true);
538 cfg80211_connect_result(dev, pstrConnectInfo->bssid,
539 pstrConnectInfo->req_ies, pstrConnectInfo->req_ies_len,
540 pstrConnectInfo->resp_ies, pstrConnectInfo->resp_ies_len,
541 u16ConnectStatus, GFP_KERNEL);
542 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
543 wilc_optaining_ip = false;
544 p2p_local_random = 0x01;
545 p2p_recv_random = 0x00;
547 eth_zero_addr(priv->au8AssociatedBss);
548 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
549 eth_zero_addr(wilc_connected_ssid);
551 if (!pstrWFIDrv->p2p_connect)
552 wlan_channel = INVALID_CHANNEL;
553 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
554 pstrDisconnectNotifInfo->reason = 3;
555 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
556 pstrDisconnectNotifInfo->reason = 1;
558 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->reason, pstrDisconnectNotifInfo->ie,
559 pstrDisconnectNotifInfo->ie_len, false,
564 static int set_channel(struct wiphy *wiphy,
565 struct cfg80211_chan_def *chandef)
568 struct wilc_priv *priv;
570 struct wilc_vif *vif;
572 priv = wiphy_priv(wiphy);
573 vif = netdev_priv(priv->dev);
575 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
577 curr_channel = channelnum;
578 result = wilc_set_mac_chnl_num(vif, channelnum);
581 netdev_err(priv->dev, "Error in setting channel\n");
586 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
588 struct wilc_priv *priv;
591 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
592 struct hidden_network strHiddenNetwork;
593 struct wilc_vif *vif;
595 priv = wiphy_priv(wiphy);
596 vif = netdev_priv(priv->dev);
598 priv->pstrScanReq = request;
600 priv->u32RcvdChCount = 0;
602 reset_shadow_found();
604 priv->bCfgScanning = true;
605 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
606 for (i = 0; i < request->n_channels; i++)
607 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
609 if (request->n_ssids >= 1) {
610 strHiddenNetwork.net_info =
611 kmalloc_array(request->n_ssids,
612 sizeof(struct hidden_network),
614 if (!strHiddenNetwork.net_info)
616 strHiddenNetwork.n_ssids = request->n_ssids;
618 for (i = 0; i < request->n_ssids; i++) {
619 if (request->ssids[i].ssid_len != 0) {
620 strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
621 memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
622 strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
624 strHiddenNetwork.n_ssids -= 1;
627 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
630 (const u8 *)request->ie,
631 request->ie_len, CfgScanResult,
632 (void *)priv, &strHiddenNetwork);
634 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
637 (const u8 *)request->ie,
638 request->ie_len, CfgScanResult,
642 netdev_err(priv->dev, "Requested scanned channels over\n");
651 static int connect(struct wiphy *wiphy, struct net_device *dev,
652 struct cfg80211_connect_params *sme)
656 u32 sel_bssi_idx = UINT_MAX;
657 u8 u8security = NO_ENCRYPT;
658 enum AUTHTYPE tenuAuth_type = ANY;
660 struct wilc_priv *priv;
661 struct host_if_drv *pstrWFIDrv;
662 struct network_info *pstrNetworkInfo = NULL;
663 struct wilc_vif *vif;
666 priv = wiphy_priv(wiphy);
667 vif = netdev_priv(priv->dev);
668 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
670 if (!(strncmp(sme->ssid, "DIRECT-", 7)))
671 pstrWFIDrv->p2p_connect = 1;
673 pstrWFIDrv->p2p_connect = 0;
675 for (i = 0; i < last_scanned_cnt; i++) {
676 if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
677 memcmp(last_scanned_shadow[i].ssid,
679 sme->ssid_len) == 0) {
681 if (sel_bssi_idx == UINT_MAX ||
682 last_scanned_shadow[i].rssi >
683 last_scanned_shadow[sel_bssi_idx].rssi)
686 if (memcmp(last_scanned_shadow[i].bssid,
696 if (sel_bssi_idx < last_scanned_cnt) {
697 pstrNetworkInfo = &last_scanned_shadow[sel_bssi_idx];
704 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
705 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
707 if (sme->crypto.cipher_group != NO_ENCRYPT) {
708 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
709 u8security = ENCRYPT_ENABLED | WEP;
711 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
712 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
714 g_key_wep_params.key_len = sme->key_len;
715 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
716 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
717 g_key_wep_params.key_idx = sme->key_idx;
718 g_wep_keys_saved = true;
720 wilc_set_wep_default_keyid(vif, sme->key_idx);
721 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
723 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
724 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
726 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
727 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
729 g_key_wep_params.key_len = sme->key_len;
730 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
731 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
732 g_key_wep_params.key_idx = sme->key_idx;
733 g_wep_keys_saved = true;
735 wilc_set_wep_default_keyid(vif, sme->key_idx);
736 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
738 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
739 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
740 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
742 u8security = ENCRYPT_ENABLED | WPA2 | AES;
743 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
744 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
745 u8security = ENCRYPT_ENABLED | WPA | TKIP;
747 u8security = ENCRYPT_ENABLED | WPA | AES;
749 s32Error = -ENOTSUPP;
750 netdev_err(dev, "Not supported cipher\n");
756 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
757 (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
758 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
759 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP)
760 u8security = u8security | TKIP;
762 u8security = u8security | AES;
766 switch (sme->auth_type) {
767 case NL80211_AUTHTYPE_OPEN_SYSTEM:
768 tenuAuth_type = OPEN_SYSTEM;
771 case NL80211_AUTHTYPE_SHARED_KEY:
772 tenuAuth_type = SHARED_KEY;
779 if (sme->crypto.n_akm_suites) {
780 switch (sme->crypto.akm_suites[0]) {
781 case WLAN_AKM_SUITE_8021X:
782 tenuAuth_type = IEEE8021;
790 curr_channel = pstrNetworkInfo->ch;
792 if (!pstrWFIDrv->p2p_connect)
793 wlan_channel = pstrNetworkInfo->ch;
795 wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
797 s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
798 sme->ssid_len, sme->ie, sme->ie_len,
799 CfgConnectResult, (void *)priv,
800 u8security, tenuAuth_type,
802 pstrNetworkInfo->join_params);
804 netdev_err(dev, "wilc_set_join_req(): Error\n");
813 static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
816 struct wilc_priv *priv;
817 struct host_if_drv *pstrWFIDrv;
818 struct wilc_vif *vif;
820 u8 NullBssid[ETH_ALEN] = {0};
823 priv = wiphy_priv(wiphy);
824 vif = netdev_priv(priv->dev);
831 /* already disconnected done */
832 cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
836 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
837 if (!pstrWFIDrv->p2p_connect)
838 wlan_channel = INVALID_CHANNEL;
839 wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
841 p2p_local_random = 0x01;
842 p2p_recv_random = 0x00;
844 pstrWFIDrv->p2p_timeout = 0;
846 s32Error = wilc_disconnect(vif, reason_code);
848 netdev_err(priv->dev, "Error in disconnecting\n");
855 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
857 const u8 *mac_addr, struct key_params *params)
860 s32 s32Error = 0, KeyLen = params->key_len;
861 struct wilc_priv *priv;
862 const u8 *pu8RxMic = NULL;
863 const u8 *pu8TxMic = NULL;
864 u8 u8mode = NO_ENCRYPT;
865 u8 u8gmode = NO_ENCRYPT;
866 u8 u8pmode = NO_ENCRYPT;
867 enum AUTHTYPE tenuAuth_type = ANY;
869 struct wilc_vif *vif;
871 priv = wiphy_priv(wiphy);
872 vif = netdev_priv(netdev);
875 switch (params->cipher) {
876 case WLAN_CIPHER_SUITE_WEP40:
877 case WLAN_CIPHER_SUITE_WEP104:
878 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
879 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
880 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
882 tenuAuth_type = OPEN_SYSTEM;
884 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
885 u8mode = ENCRYPT_ENABLED | WEP;
887 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
889 wilc_add_wep_key_bss_ap(vif, params->key,
890 params->key_len, key_index,
891 u8mode, tenuAuth_type);
894 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
895 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
896 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
898 wilc_add_wep_key_bss_sta(vif, params->key,
899 params->key_len, key_index);
904 case WLAN_CIPHER_SUITE_TKIP:
905 case WLAN_CIPHER_SUITE_CCMP:
906 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
907 if (!priv->wilc_gtk[key_index]) {
908 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
909 priv->wilc_gtk[key_index]->key = NULL;
910 priv->wilc_gtk[key_index]->seq = NULL;
912 if (!priv->wilc_ptk[key_index]) {
913 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
914 priv->wilc_ptk[key_index]->key = NULL;
915 priv->wilc_ptk[key_index]->seq = NULL;
919 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
920 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
922 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
924 priv->wilc_groupkey = u8gmode;
926 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
927 pu8TxMic = params->key + 24;
928 pu8RxMic = params->key + 16;
929 KeyLen = params->key_len - 16;
931 kfree(priv->wilc_gtk[key_index]->key);
933 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
934 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
935 kfree(priv->wilc_gtk[key_index]->seq);
937 if ((params->seq_len) > 0) {
938 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
939 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
942 priv->wilc_gtk[key_index]->cipher = params->cipher;
943 priv->wilc_gtk[key_index]->key_len = params->key_len;
944 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
946 wilc_add_rx_gtk(vif, params->key, KeyLen,
947 key_index, params->seq_len,
948 params->seq, pu8RxMic,
949 pu8TxMic, AP_MODE, u8gmode);
952 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
953 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
955 u8pmode = priv->wilc_groupkey | AES;
957 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
958 pu8TxMic = params->key + 24;
959 pu8RxMic = params->key + 16;
960 KeyLen = params->key_len - 16;
963 kfree(priv->wilc_ptk[key_index]->key);
965 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
967 kfree(priv->wilc_ptk[key_index]->seq);
969 if ((params->seq_len) > 0)
970 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
972 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
974 if ((params->seq_len) > 0)
975 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
977 priv->wilc_ptk[key_index]->cipher = params->cipher;
978 priv->wilc_ptk[key_index]->key_len = params->key_len;
979 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
981 wilc_add_ptk(vif, params->key, KeyLen,
982 mac_addr, pu8RxMic, pu8TxMic,
983 AP_MODE, u8pmode, key_index);
991 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
992 pu8RxMic = params->key + 24;
993 pu8TxMic = params->key + 16;
994 KeyLen = params->key_len - 16;
997 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
998 g_add_gtk_key_params.key_idx = key_index;
999 g_add_gtk_key_params.pairwise = pairwise;
1001 g_add_gtk_key_params.mac_addr = NULL;
1003 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1004 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1006 g_key_gtk_params.key_len = params->key_len;
1007 g_key_gtk_params.seq_len = params->seq_len;
1008 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1009 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1010 if (params->seq_len > 0) {
1011 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1012 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1014 g_key_gtk_params.cipher = params->cipher;
1015 g_gtk_keys_saved = true;
1018 wilc_add_rx_gtk(vif, params->key, KeyLen,
1019 key_index, params->seq_len,
1020 params->seq, pu8RxMic,
1021 pu8TxMic, STATION_MODE,
1024 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1025 pu8RxMic = params->key + 24;
1026 pu8TxMic = params->key + 16;
1027 KeyLen = params->key_len - 16;
1030 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1031 g_add_ptk_key_params.key_idx = key_index;
1032 g_add_ptk_key_params.pairwise = pairwise;
1034 g_add_ptk_key_params.mac_addr = NULL;
1036 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1037 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1039 g_key_ptk_params.key_len = params->key_len;
1040 g_key_ptk_params.seq_len = params->seq_len;
1041 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
1042 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1043 if (params->seq_len > 0) {
1044 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
1045 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1047 g_key_ptk_params.cipher = params->cipher;
1048 g_ptk_keys_saved = true;
1051 wilc_add_ptk(vif, params->key, KeyLen,
1052 mac_addr, pu8RxMic, pu8TxMic,
1053 STATION_MODE, u8mode, key_index);
1059 netdev_err(netdev, "Not supported cipher\n");
1060 s32Error = -ENOTSUPP;
1066 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1071 struct wilc_priv *priv;
1073 struct wilc_vif *vif;
1075 priv = wiphy_priv(wiphy);
1076 vif = netdev_priv(netdev);
1079 if (netdev == wl->vif[0]->ndev) {
1080 g_ptk_keys_saved = false;
1081 g_gtk_keys_saved = false;
1082 g_wep_keys_saved = false;
1084 kfree(g_key_wep_params.key);
1085 g_key_wep_params.key = NULL;
1087 if ((priv->wilc_gtk[key_index]) != NULL) {
1088 kfree(priv->wilc_gtk[key_index]->key);
1089 priv->wilc_gtk[key_index]->key = NULL;
1090 kfree(priv->wilc_gtk[key_index]->seq);
1091 priv->wilc_gtk[key_index]->seq = NULL;
1093 kfree(priv->wilc_gtk[key_index]);
1094 priv->wilc_gtk[key_index] = NULL;
1097 if ((priv->wilc_ptk[key_index]) != NULL) {
1098 kfree(priv->wilc_ptk[key_index]->key);
1099 priv->wilc_ptk[key_index]->key = NULL;
1100 kfree(priv->wilc_ptk[key_index]->seq);
1101 priv->wilc_ptk[key_index]->seq = NULL;
1102 kfree(priv->wilc_ptk[key_index]);
1103 priv->wilc_ptk[key_index] = NULL;
1106 kfree(g_key_ptk_params.key);
1107 g_key_ptk_params.key = NULL;
1108 kfree(g_key_ptk_params.seq);
1109 g_key_ptk_params.seq = NULL;
1111 kfree(g_key_gtk_params.key);
1112 g_key_gtk_params.key = NULL;
1113 kfree(g_key_gtk_params.seq);
1114 g_key_gtk_params.seq = NULL;
1118 if (key_index >= 0 && key_index <= 3) {
1119 if (priv->WILC_WFI_wep_key_len[key_index]) {
1120 memset(priv->WILC_WFI_wep_key[key_index], 0,
1121 priv->WILC_WFI_wep_key_len[key_index]);
1122 priv->WILC_WFI_wep_key_len[key_index] = 0;
1123 wilc_remove_wep_key(vif, key_index);
1126 wilc_remove_key(priv->hif_drv, mac_addr);
1132 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1134 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1136 struct wilc_priv *priv;
1137 struct key_params key_params;
1139 priv = wiphy_priv(wiphy);
1142 key_params.key = priv->wilc_gtk[key_index]->key;
1143 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1144 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1145 key_params.seq = priv->wilc_gtk[key_index]->seq;
1146 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1148 key_params.key = priv->wilc_ptk[key_index]->key;
1149 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1150 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1151 key_params.seq = priv->wilc_ptk[key_index]->seq;
1152 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1155 callback(cookie, &key_params);
1160 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1161 bool unicast, bool multicast)
1163 struct wilc_priv *priv;
1164 struct wilc_vif *vif;
1166 priv = wiphy_priv(wiphy);
1167 vif = netdev_priv(priv->dev);
1169 wilc_set_wep_default_keyid(vif, key_index);
1174 static int get_station(struct wiphy *wiphy, struct net_device *dev,
1175 const u8 *mac, struct station_info *sinfo)
1177 struct wilc_priv *priv;
1178 struct wilc_vif *vif;
1180 u32 associatedsta = ~0;
1181 u32 inactive_time = 0;
1183 priv = wiphy_priv(wiphy);
1184 vif = netdev_priv(dev);
1186 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1187 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1188 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1194 if (associatedsta == ~0) {
1195 netdev_err(dev, "sta required is not associated\n");
1199 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1201 wilc_get_inactive_time(vif, mac, &inactive_time);
1202 sinfo->inactive_time = 1000 * inactive_time;
1205 if (vif->iftype == STATION_MODE) {
1206 struct rf_info strStatistics;
1208 wilc_get_statistics(vif, &strStatistics);
1210 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1211 BIT(NL80211_STA_INFO_RX_PACKETS) |
1212 BIT(NL80211_STA_INFO_TX_PACKETS) |
1213 BIT(NL80211_STA_INFO_TX_FAILED) |
1214 BIT(NL80211_STA_INFO_TX_BITRATE);
1216 sinfo->signal = strStatistics.rssi;
1217 sinfo->rx_packets = strStatistics.rx_cnt;
1218 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1219 sinfo->tx_failed = strStatistics.tx_fail_cnt;
1220 sinfo->txrate.legacy = strStatistics.link_speed * 10;
1222 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1223 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1224 wilc_enable_tcp_ack_filter(true);
1225 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1226 wilc_enable_tcp_ack_filter(false);
1231 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1232 struct bss_parameters *params)
1237 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1240 struct cfg_param_attr pstrCfgParamVal;
1241 struct wilc_priv *priv;
1242 struct wilc_vif *vif;
1244 priv = wiphy_priv(wiphy);
1245 vif = netdev_priv(priv->dev);
1247 pstrCfgParamVal.flag = 0;
1249 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1250 pstrCfgParamVal.flag |= RETRY_SHORT;
1251 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1253 if (changed & WIPHY_PARAM_RETRY_LONG) {
1254 pstrCfgParamVal.flag |= RETRY_LONG;
1255 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1257 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1258 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1259 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1262 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1263 pstrCfgParamVal.flag |= RTS_THRESHOLD;
1264 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1267 s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1269 netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1274 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1275 struct cfg80211_pmksa *pmksa)
1280 struct wilc_vif *vif;
1281 struct wilc_priv *priv = wiphy_priv(wiphy);
1283 vif = netdev_priv(priv->dev);
1285 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1286 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1292 if (i < WILC_MAX_NUM_PMKIDS) {
1293 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1295 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1297 if (!(flag == PMKID_FOUND))
1298 priv->pmkid_list.numpmkid++;
1300 netdev_err(netdev, "Invalid PMKID index\n");
1305 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1310 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1311 struct cfg80211_pmksa *pmksa)
1316 struct wilc_priv *priv = wiphy_priv(wiphy);
1318 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1319 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1321 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1326 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1327 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1328 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1329 priv->pmkid_list.pmkidlist[i + 1].bssid,
1331 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1332 priv->pmkid_list.pmkidlist[i + 1].pmkid,
1335 priv->pmkid_list.numpmkid--;
1343 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1345 struct wilc_priv *priv = wiphy_priv(wiphy);
1347 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1352 static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1357 u8 op_channel_attr_index = 0;
1358 u8 channel_list_attr_index = 0;
1360 while (index < len) {
1361 if (buf[index] == GO_INTENT_ATTR_ID)
1362 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
1364 if (buf[index] == CHANLIST_ATTR_ID)
1365 channel_list_attr_index = index;
1366 else if (buf[index] == OPERCHAN_ATTR_ID)
1367 op_channel_attr_index = index;
1368 index += buf[index + 1] + 3;
1370 if (wlan_channel != INVALID_CHANNEL) {
1371 if (channel_list_attr_index) {
1372 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1373 if (buf[i] == 0x51) {
1374 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1375 buf[j] = wlan_channel;
1381 if (op_channel_attr_index) {
1382 buf[op_channel_attr_index + 6] = 0x51;
1383 buf[op_channel_attr_index + 7] = wlan_channel;
1388 static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1393 u8 op_channel_attr_index = 0;
1394 u8 channel_list_attr_index = 0;
1396 while (index < len) {
1397 if (buf[index] == GO_INTENT_ATTR_ID) {
1398 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
1403 if (buf[index] == CHANLIST_ATTR_ID)
1404 channel_list_attr_index = index;
1405 else if (buf[index] == OPERCHAN_ATTR_ID)
1406 op_channel_attr_index = index;
1407 index += buf[index + 1] + 3;
1409 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1410 if (channel_list_attr_index) {
1411 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1412 if (buf[i] == 0x51) {
1413 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1414 buf[j] = wlan_channel;
1420 if (op_channel_attr_index) {
1421 buf[op_channel_attr_index + 6] = 0x51;
1422 buf[op_channel_attr_index + 7] = wlan_channel;
1427 void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
1429 struct wilc_priv *priv;
1430 u32 header, pkt_offset;
1431 struct host_if_drv *pstrWFIDrv;
1435 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1436 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1438 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1440 pkt_offset = GET_PKT_OFFSET(header);
1442 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1443 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1444 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1447 if (pkt_offset & IS_MGMT_STATUS_SUCCES)
1448 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1450 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1454 s32Freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ);
1456 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1457 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1458 netdev_dbg(dev, "Receiving action wrong ch\n");
1461 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1462 switch (buff[ACTION_SUBTYPE_ID]) {
1463 case GAS_INITIAL_REQ:
1466 case GAS_INITIAL_RSP:
1469 case PUBLIC_ACT_VENDORSPEC:
1470 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1471 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1473 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1474 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1475 p2p_recv_random = buff[i + 6];
1482 if (p2p_local_random > p2p_recv_random) {
1483 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP ||
1484 buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1485 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1486 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1487 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1493 netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1497 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie)) {
1498 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1504 netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1510 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1514 static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1516 struct p2p_mgmt_data *pv_data = priv;
1518 kfree(pv_data->buff);
1522 static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1524 struct wilc_priv *priv;
1528 priv->bInP2PlistenState = true;
1530 cfg80211_ready_on_channel(priv->wdev,
1531 priv->strRemainOnChanParams.u64ListenCookie,
1532 priv->strRemainOnChanParams.pstrListenChan,
1533 priv->strRemainOnChanParams.u32ListenDuration,
1537 static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1539 struct wilc_priv *priv;
1543 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1544 priv->bInP2PlistenState = false;
1546 cfg80211_remain_on_channel_expired(priv->wdev,
1547 priv->strRemainOnChanParams.u64ListenCookie,
1548 priv->strRemainOnChanParams.pstrListenChan,
1553 static int remain_on_channel(struct wiphy *wiphy,
1554 struct wireless_dev *wdev,
1555 struct ieee80211_channel *chan,
1556 unsigned int duration, u64 *cookie)
1559 struct wilc_priv *priv;
1560 struct wilc_vif *vif;
1562 priv = wiphy_priv(wiphy);
1563 vif = netdev_priv(priv->dev);
1565 if (wdev->iftype == NL80211_IFTYPE_AP) {
1566 netdev_dbg(vif->ndev, "Required while in AP mode\n");
1570 curr_channel = chan->hw_value;
1572 priv->strRemainOnChanParams.pstrListenChan = chan;
1573 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1574 priv->strRemainOnChanParams.u32ListenDuration = duration;
1575 priv->strRemainOnChanParams.u32ListenSessionID++;
1577 return wilc_remain_on_channel(vif,
1578 priv->strRemainOnChanParams.u32ListenSessionID,
1579 duration, chan->hw_value,
1580 WILC_WFI_RemainOnChannelExpired,
1581 WILC_WFI_RemainOnChannelReady, (void *)priv);
1584 static int cancel_remain_on_channel(struct wiphy *wiphy,
1585 struct wireless_dev *wdev,
1588 struct wilc_priv *priv;
1589 struct wilc_vif *vif;
1591 priv = wiphy_priv(wiphy);
1592 vif = netdev_priv(priv->dev);
1594 return wilc_listen_state_expired(vif,
1595 priv->strRemainOnChanParams.u32ListenSessionID);
1598 static int mgmt_tx(struct wiphy *wiphy,
1599 struct wireless_dev *wdev,
1600 struct cfg80211_mgmt_tx_params *params,
1603 struct ieee80211_channel *chan = params->chan;
1604 unsigned int wait = params->wait;
1605 const u8 *buf = params->buf;
1606 size_t len = params->len;
1607 const struct ieee80211_mgmt *mgmt;
1608 struct p2p_mgmt_data *mgmt_tx;
1609 struct wilc_priv *priv;
1610 struct host_if_drv *pstrWFIDrv;
1612 struct wilc_vif *vif;
1613 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1615 vif = netdev_priv(wdev->netdev);
1616 priv = wiphy_priv(wiphy);
1617 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1619 *cookie = (unsigned long)buf;
1620 priv->u64tx_cookie = *cookie;
1621 mgmt = (const struct ieee80211_mgmt *) buf;
1623 if (ieee80211_is_mgmt(mgmt->frame_control)) {
1624 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1628 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1629 if (!mgmt_tx->buff) {
1634 memcpy(mgmt_tx->buff, buf, len);
1635 mgmt_tx->size = len;
1637 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1638 wilc_set_mac_chnl_num(vif, chan->hw_value);
1639 curr_channel = chan->hw_value;
1640 } else if (ieee80211_is_action(mgmt->frame_control)) {
1641 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1642 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1643 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1644 wilc_set_mac_chnl_num(vif,
1646 curr_channel = chan->hw_value;
1648 switch (buf[ACTION_SUBTYPE_ID]) {
1649 case GAS_INITIAL_REQ:
1652 case GAS_INITIAL_RSP:
1655 case PUBLIC_ACT_VENDORSPEC:
1657 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1658 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1659 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1660 get_random_bytes(&p2p_local_random, 1);
1665 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP ||
1666 buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1667 if (p2p_local_random > p2p_recv_random) {
1668 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1669 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1670 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1671 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1673 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1678 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1679 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1680 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1681 mgmt_tx->size = buf_len;
1687 netdev_dbg(vif->ndev, "Not a P2P public action frame\n");
1695 netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1701 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1704 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1705 mgmt_tx->buff, mgmt_tx->size,
1706 WILC_WFI_mgmt_tx_complete);
1711 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1712 struct wireless_dev *wdev,
1715 struct wilc_priv *priv;
1716 struct host_if_drv *pstrWFIDrv;
1718 priv = wiphy_priv(wiphy);
1719 pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1720 pstrWFIDrv->p2p_timeout = jiffies;
1722 if (!priv->bInP2PlistenState) {
1723 cfg80211_remain_on_channel_expired(priv->wdev,
1724 priv->strRemainOnChanParams.u64ListenCookie,
1725 priv->strRemainOnChanParams.pstrListenChan,
1732 void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1733 u16 frame_type, bool reg)
1735 struct wilc_priv *priv;
1736 struct wilc_vif *vif;
1739 priv = wiphy_priv(wiphy);
1740 vif = netdev_priv(priv->wdev->netdev);
1746 switch (frame_type) {
1749 vif->frame_reg[0].type = frame_type;
1750 vif->frame_reg[0].reg = reg;
1756 vif->frame_reg[1].type = frame_type;
1757 vif->frame_reg[1].reg = reg;
1767 if (!wl->initialized)
1769 wilc_frame_register(vif, frame_type, reg);
1772 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1773 s32 rssi_thold, u32 rssi_hyst)
1778 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1779 int idx, u8 *mac, struct station_info *sinfo)
1781 struct wilc_priv *priv;
1782 struct wilc_vif *vif;
1787 priv = wiphy_priv(wiphy);
1788 vif = netdev_priv(priv->dev);
1790 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1792 wilc_get_rssi(vif, &sinfo->signal);
1794 memcpy(mac, priv->au8AssociatedBss, ETH_ALEN);
1798 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1799 bool enabled, int timeout)
1801 struct wilc_priv *priv;
1802 struct wilc_vif *vif;
1807 priv = wiphy_priv(wiphy);
1808 vif = netdev_priv(priv->dev);
1813 wilc_set_power_mgmt(vif, enabled, timeout);
1818 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1819 enum nl80211_iftype type, struct vif_params *params)
1821 struct wilc_priv *priv;
1822 struct wilc_vif *vif;
1825 vif = netdev_priv(dev);
1826 priv = wiphy_priv(wiphy);
1828 p2p_local_random = 0x01;
1829 p2p_recv_random = 0x00;
1831 wilc_optaining_ip = false;
1832 del_timer(&wilc_during_ip_timer);
1835 case NL80211_IFTYPE_STATION:
1836 wilc_connecting = 0;
1837 dev->ieee80211_ptr->iftype = type;
1838 priv->wdev->iftype = type;
1839 vif->monitor_flag = 0;
1840 vif->iftype = STATION_MODE;
1841 wilc_set_operation_mode(vif, STATION_MODE);
1843 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
1845 wilc_enable_ps = true;
1846 wilc_set_power_mgmt(vif, 1, 0);
1849 case NL80211_IFTYPE_P2P_CLIENT:
1850 wilc_connecting = 0;
1851 dev->ieee80211_ptr->iftype = type;
1852 priv->wdev->iftype = type;
1853 vif->monitor_flag = 0;
1854 vif->iftype = CLIENT_MODE;
1855 wilc_set_operation_mode(vif, STATION_MODE);
1857 wilc_enable_ps = false;
1858 wilc_set_power_mgmt(vif, 0, 0);
1861 case NL80211_IFTYPE_AP:
1862 wilc_enable_ps = false;
1863 dev->ieee80211_ptr->iftype = type;
1864 priv->wdev->iftype = type;
1865 vif->iftype = AP_MODE;
1867 if (wl->initialized) {
1868 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
1870 wilc_set_operation_mode(vif, AP_MODE);
1871 wilc_set_power_mgmt(vif, 0, 0);
1875 case NL80211_IFTYPE_P2P_GO:
1876 wilc_optaining_ip = true;
1877 mod_timer(&wilc_during_ip_timer,
1878 jiffies + msecs_to_jiffies(during_ip_time));
1879 wilc_set_operation_mode(vif, AP_MODE);
1880 dev->ieee80211_ptr->iftype = type;
1881 priv->wdev->iftype = type;
1882 vif->iftype = GO_MODE;
1884 wilc_enable_ps = false;
1885 wilc_set_power_mgmt(vif, 0, 0);
1889 netdev_err(dev, "Unknown interface type= %d\n", type);
1896 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1897 struct cfg80211_ap_settings *settings)
1899 struct cfg80211_beacon_data *beacon = &(settings->beacon);
1900 struct wilc_priv *priv;
1903 struct wilc_vif *vif;
1905 priv = wiphy_priv(wiphy);
1906 vif = netdev_priv(dev);
1909 s32Error = set_channel(wiphy, &settings->chandef);
1912 netdev_err(dev, "Error in setting channel\n");
1914 wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
1915 wilc_set_power_mgmt(vif, 0, 0);
1917 return wilc_add_beacon(vif, settings->beacon_interval,
1918 settings->dtim_period, beacon->head_len,
1919 (u8 *)beacon->head, beacon->tail_len,
1920 (u8 *)beacon->tail);
1923 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1924 struct cfg80211_beacon_data *beacon)
1926 struct wilc_priv *priv;
1927 struct wilc_vif *vif;
1929 priv = wiphy_priv(wiphy);
1930 vif = netdev_priv(priv->dev);
1932 return wilc_add_beacon(vif, 0, 0, beacon->head_len,
1933 (u8 *)beacon->head, beacon->tail_len,
1934 (u8 *)beacon->tail);
1937 static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1940 struct wilc_priv *priv;
1941 struct wilc_vif *vif;
1942 u8 NullBssid[ETH_ALEN] = {0};
1947 priv = wiphy_priv(wiphy);
1948 vif = netdev_priv(priv->dev);
1950 wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
1952 s32Error = wilc_del_beacon(vif);
1955 netdev_err(dev, "Host delete beacon fail\n");
1960 static int add_station(struct wiphy *wiphy, struct net_device *dev,
1961 const u8 *mac, struct station_parameters *params)
1964 struct wilc_priv *priv;
1965 struct add_sta_param strStaParams = { {0} };
1966 struct wilc_vif *vif;
1971 priv = wiphy_priv(wiphy);
1972 vif = netdev_priv(dev);
1974 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1975 memcpy(strStaParams.bssid, mac, ETH_ALEN);
1976 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
1977 strStaParams.aid = params->aid;
1978 strStaParams.rates_len = params->supported_rates_len;
1979 strStaParams.rates = params->supported_rates;
1981 if (!params->ht_capa) {
1982 strStaParams.ht_supported = false;
1984 strStaParams.ht_supported = true;
1985 strStaParams.ht_capa = *params->ht_capa;
1988 strStaParams.flags_mask = params->sta_flags_mask;
1989 strStaParams.flags_set = params->sta_flags_set;
1991 s32Error = wilc_add_station(vif, &strStaParams);
1993 netdev_err(dev, "Host add station fail\n");
1999 static int del_station(struct wiphy *wiphy, struct net_device *dev,
2000 struct station_del_parameters *params)
2002 const u8 *mac = params->mac;
2004 struct wilc_priv *priv;
2005 struct wilc_vif *vif;
2010 priv = wiphy_priv(wiphy);
2011 vif = netdev_priv(dev);
2013 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2015 s32Error = wilc_del_allstation(vif,
2016 priv->assoc_stainfo.au8Sta_AssociatedBss);
2018 s32Error = wilc_del_station(vif, mac);
2021 netdev_err(dev, "Host delete station fail\n");
2026 static int change_station(struct wiphy *wiphy, struct net_device *dev,
2027 const u8 *mac, struct station_parameters *params)
2030 struct wilc_priv *priv;
2031 struct add_sta_param strStaParams = { {0} };
2032 struct wilc_vif *vif;
2037 priv = wiphy_priv(wiphy);
2038 vif = netdev_priv(dev);
2040 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2041 memcpy(strStaParams.bssid, mac, ETH_ALEN);
2042 strStaParams.aid = params->aid;
2043 strStaParams.rates_len = params->supported_rates_len;
2044 strStaParams.rates = params->supported_rates;
2046 if (!params->ht_capa) {
2047 strStaParams.ht_supported = false;
2049 strStaParams.ht_supported = true;
2050 strStaParams.ht_capa = *params->ht_capa;
2053 strStaParams.flags_mask = params->sta_flags_mask;
2054 strStaParams.flags_set = params->sta_flags_set;
2056 s32Error = wilc_edit_station(vif, &strStaParams);
2058 netdev_err(dev, "Host edit station fail\n");
2063 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2065 unsigned char name_assign_type,
2066 enum nl80211_iftype type,
2067 struct vif_params *params)
2069 struct wilc_vif *vif;
2070 struct wilc_priv *priv;
2071 struct net_device *new_ifc = NULL;
2073 priv = wiphy_priv(wiphy);
2074 vif = netdev_priv(priv->wdev->netdev);
2076 if (type == NL80211_IFTYPE_MONITOR) {
2077 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2079 vif = netdev_priv(priv->wdev->netdev);
2080 vif->monitor_flag = 1;
2086 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2091 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2093 struct wilc_priv *priv = wiphy_priv(wiphy);
2094 struct wilc_vif *vif = netdev_priv(priv->dev);
2096 if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2097 vif->wilc->suspend_event = true;
2099 vif->wilc->suspend_event = false;
2104 static int wilc_resume(struct wiphy *wiphy)
2106 struct wilc_priv *priv = wiphy_priv(wiphy);
2107 struct wilc_vif *vif = netdev_priv(priv->dev);
2109 netdev_info(vif->ndev, "cfg resume\n");
2113 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2115 struct wilc_priv *priv = wiphy_priv(wiphy);
2116 struct wilc_vif *vif = netdev_priv(priv->dev);
2118 netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2121 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2122 enum nl80211_tx_power_setting type, int mbm)
2125 s32 tx_power = MBM_TO_DBM(mbm);
2126 struct wilc_priv *priv = wiphy_priv(wiphy);
2127 struct wilc_vif *vif = netdev_priv(priv->dev);
2131 else if (tx_power > 18)
2133 ret = wilc_set_tx_power(vif, tx_power);
2135 netdev_err(vif->ndev, "Failed to set tx power\n");
2140 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2144 struct wilc_priv *priv = wiphy_priv(wiphy);
2145 struct wilc_vif *vif = netdev_priv(priv->dev);
2150 /* If firmware is not started, return. */
2151 if (!wl->initialized)
2154 ret = wilc_get_tx_power(vif, (u8 *)dbm);
2156 netdev_err(vif->ndev, "Failed to get tx power\n");
2161 static const struct cfg80211_ops wilc_cfg80211_ops = {
2162 .set_monitor_channel = set_channel,
2165 .disconnect = disconnect,
2169 .set_default_key = set_default_key,
2170 .add_virtual_intf = add_virtual_intf,
2171 .del_virtual_intf = del_virtual_intf,
2172 .change_virtual_intf = change_virtual_intf,
2174 .start_ap = start_ap,
2175 .change_beacon = change_beacon,
2177 .add_station = add_station,
2178 .del_station = del_station,
2179 .change_station = change_station,
2180 .get_station = get_station,
2181 .dump_station = dump_station,
2182 .change_bss = change_bss,
2183 .set_wiphy_params = set_wiphy_params,
2185 .set_pmksa = set_pmksa,
2186 .del_pmksa = del_pmksa,
2187 .flush_pmksa = flush_pmksa,
2188 .remain_on_channel = remain_on_channel,
2189 .cancel_remain_on_channel = cancel_remain_on_channel,
2190 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2192 .mgmt_frame_register = wilc_mgmt_frame_register,
2193 .set_power_mgmt = set_power_mgmt,
2194 .set_cqm_rssi_config = set_cqm_rssi_config,
2196 .suspend = wilc_suspend,
2197 .resume = wilc_resume,
2198 .set_wakeup = wilc_set_wakeup,
2199 .set_tx_power = set_tx_power,
2200 .get_tx_power = get_tx_power,
2204 static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2206 struct wireless_dev *wdev;
2208 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2212 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2216 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2217 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2218 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2219 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2220 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2222 wdev->wiphy->bands[NL80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2232 struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2234 struct wilc_priv *priv;
2235 struct wireless_dev *wdev;
2238 wdev = WILC_WFI_CfgAlloc();
2240 netdev_err(net, "wiphy new allocate failed\n");
2244 priv = wdev_priv(wdev);
2246 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2248 wdev->wiphy->wowlan = &wowlan_support;
2250 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2251 wdev->wiphy->max_scan_ie_len = 1000;
2252 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2253 wdev->wiphy->cipher_suites = cipher_suites;
2254 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2255 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2257 wdev->wiphy->max_remain_on_channel_duration = 500;
2258 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2259 BIT(NL80211_IFTYPE_AP) |
2260 BIT(NL80211_IFTYPE_MONITOR) |
2261 BIT(NL80211_IFTYPE_P2P_GO) |
2262 BIT(NL80211_IFTYPE_P2P_CLIENT);
2263 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2264 wdev->iftype = NL80211_IFTYPE_STATION;
2266 set_wiphy_dev(wdev->wiphy, dev);
2268 s32Error = wiphy_register(wdev->wiphy);
2270 netdev_err(net, "Cannot register wiphy device\n");
2276 int wilc_init_host_int(struct net_device *net)
2280 struct wilc_priv *priv;
2282 priv = wdev_priv(net->ieee80211_ptr);
2284 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2285 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2289 priv->gbAutoRateAdjusted = false;
2291 priv->bInP2PlistenState = false;
2293 mutex_init(&priv->scan_req_lock);
2294 s32Error = wilc_init(net, &priv->hif_drv);
2296 netdev_err(net, "Error while initializing hostinterface\n");
2301 int wilc_deinit_host_int(struct net_device *net)
2304 struct wilc_vif *vif;
2305 struct wilc_priv *priv;
2307 priv = wdev_priv(net->ieee80211_ptr);
2308 vif = netdev_priv(priv->dev);
2310 priv->gbAutoRateAdjusted = false;
2312 priv->bInP2PlistenState = false;
2316 s32Error = wilc_deinit(vif);
2318 clear_shadow_scan();
2320 del_timer_sync(&wilc_during_ip_timer);
2323 netdev_err(net, "Error while deinitializing host interface\n");
2328 void wilc_free_wiphy(struct net_device *net)
2333 if (!net->ieee80211_ptr)
2336 if (!net->ieee80211_ptr->wiphy)
2339 wiphy_unregister(net->ieee80211_ptr->wiphy);
2341 wiphy_free(net->ieee80211_ptr->wiphy);
2342 kfree(net->ieee80211_ptr);