Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
0004  * All rights reserved.
0005  */
0006 
0007 #include "cfg80211.h"
0008 
0009 #define GO_NEG_REQ          0x00
0010 #define GO_NEG_RSP          0x01
0011 #define GO_NEG_CONF         0x02
0012 #define P2P_INV_REQ         0x03
0013 #define P2P_INV_RSP         0x04
0014 
0015 #define WILC_INVALID_CHANNEL        0
0016 
0017 /* Operation at 2.4 GHz with channels 1-13 */
0018 #define WILC_WLAN_OPERATING_CLASS_2_4GHZ        0x51
0019 
0020 static const struct ieee80211_txrx_stypes
0021     wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
0022     [NL80211_IFTYPE_STATION] = {
0023         .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
0024             BIT(IEEE80211_STYPE_AUTH >> 4),
0025         .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
0026             BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
0027             BIT(IEEE80211_STYPE_AUTH >> 4)
0028     },
0029     [NL80211_IFTYPE_AP] = {
0030         .tx = 0xffff,
0031         .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
0032             BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
0033             BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
0034             BIT(IEEE80211_STYPE_DISASSOC >> 4) |
0035             BIT(IEEE80211_STYPE_AUTH >> 4) |
0036             BIT(IEEE80211_STYPE_DEAUTH >> 4) |
0037             BIT(IEEE80211_STYPE_ACTION >> 4)
0038     },
0039     [NL80211_IFTYPE_P2P_CLIENT] = {
0040         .tx = 0xffff,
0041         .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
0042             BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
0043             BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
0044             BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
0045             BIT(IEEE80211_STYPE_DISASSOC >> 4) |
0046             BIT(IEEE80211_STYPE_AUTH >> 4) |
0047             BIT(IEEE80211_STYPE_DEAUTH >> 4)
0048     }
0049 };
0050 
0051 #ifdef CONFIG_PM
0052 static const struct wiphy_wowlan_support wowlan_support = {
0053     .flags = WIPHY_WOWLAN_ANY
0054 };
0055 #endif
0056 
0057 struct wilc_p2p_mgmt_data {
0058     int size;
0059     u8 *buff;
0060 };
0061 
0062 struct wilc_p2p_pub_act_frame {
0063     u8 category;
0064     u8 action;
0065     u8 oui[3];
0066     u8 oui_type;
0067     u8 oui_subtype;
0068     u8 dialog_token;
0069     u8 elem[];
0070 } __packed;
0071 
0072 struct wilc_vendor_specific_ie {
0073     u8 tag_number;
0074     u8 tag_len;
0075     u8 oui[3];
0076     u8 oui_type;
0077     u8 attr[];
0078 } __packed;
0079 
0080 struct wilc_attr_entry {
0081     u8  attr_type;
0082     __le16 attr_len;
0083     u8 val[];
0084 } __packed;
0085 
0086 struct wilc_attr_oper_ch {
0087     u8 attr_type;
0088     __le16 attr_len;
0089     u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
0090     u8 op_class;
0091     u8 op_channel;
0092 } __packed;
0093 
0094 struct wilc_attr_ch_list {
0095     u8 attr_type;
0096     __le16 attr_len;
0097     u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
0098     u8 elem[];
0099 } __packed;
0100 
0101 struct wilc_ch_list_elem {
0102     u8 op_class;
0103     u8 no_of_channels;
0104     u8 ch_list[];
0105 } __packed;
0106 
0107 static void cfg_scan_result(enum scan_event scan_event,
0108                 struct wilc_rcvd_net_info *info, void *user_void)
0109 {
0110     struct wilc_priv *priv = user_void;
0111 
0112     if (!priv->cfg_scanning)
0113         return;
0114 
0115     if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
0116         s32 freq;
0117         struct ieee80211_channel *channel;
0118         struct cfg80211_bss *bss;
0119         struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
0120 
0121         if (!wiphy || !info)
0122             return;
0123 
0124         freq = ieee80211_channel_to_frequency((s32)info->ch,
0125                               NL80211_BAND_2GHZ);
0126         channel = ieee80211_get_channel(wiphy, freq);
0127         if (!channel)
0128             return;
0129 
0130         bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt,
0131                         info->frame_len,
0132                         (s32)info->rssi * 100,
0133                         GFP_KERNEL);
0134         cfg80211_put_bss(wiphy, bss);
0135     } else if (scan_event == SCAN_EVENT_DONE) {
0136         mutex_lock(&priv->scan_req_lock);
0137 
0138         if (priv->scan_req) {
0139             struct cfg80211_scan_info info = {
0140                 .aborted = false,
0141             };
0142 
0143             cfg80211_scan_done(priv->scan_req, &info);
0144             priv->cfg_scanning = false;
0145             priv->scan_req = NULL;
0146         }
0147         mutex_unlock(&priv->scan_req_lock);
0148     } else if (scan_event == SCAN_EVENT_ABORTED) {
0149         mutex_lock(&priv->scan_req_lock);
0150 
0151         if (priv->scan_req) {
0152             struct cfg80211_scan_info info = {
0153                 .aborted = false,
0154             };
0155 
0156             cfg80211_scan_done(priv->scan_req, &info);
0157             priv->cfg_scanning = false;
0158             priv->scan_req = NULL;
0159         }
0160         mutex_unlock(&priv->scan_req_lock);
0161     }
0162 }
0163 
0164 static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
0165                    void *priv_data)
0166 {
0167     struct wilc_priv *priv = priv_data;
0168     struct net_device *dev = priv->dev;
0169     struct wilc_vif *vif = netdev_priv(dev);
0170     struct wilc *wl = vif->wilc;
0171     struct host_if_drv *wfi_drv = priv->hif_drv;
0172     struct wilc_conn_info *conn_info = &wfi_drv->conn_info;
0173     struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
0174 
0175     vif->connecting = false;
0176 
0177     if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
0178         u16 connect_status = conn_info->status;
0179 
0180         if (mac_status == WILC_MAC_STATUS_DISCONNECTED &&
0181             connect_status == WLAN_STATUS_SUCCESS) {
0182             connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
0183             wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
0184 
0185             if (vif->iftype != WILC_CLIENT_MODE)
0186                 wl->sta_ch = WILC_INVALID_CHANNEL;
0187 
0188             netdev_err(dev, "Unspecified failure\n");
0189         }
0190 
0191         if (connect_status == WLAN_STATUS_SUCCESS)
0192             memcpy(priv->associated_bss, conn_info->bssid,
0193                    ETH_ALEN);
0194 
0195         cfg80211_ref_bss(wiphy, vif->bss);
0196         cfg80211_connect_bss(dev, conn_info->bssid, vif->bss,
0197                      conn_info->req_ies,
0198                      conn_info->req_ies_len,
0199                      conn_info->resp_ies,
0200                      conn_info->resp_ies_len,
0201                      connect_status, GFP_KERNEL,
0202                      NL80211_TIMEOUT_UNSPECIFIED);
0203 
0204         vif->bss = NULL;
0205     } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
0206         u16 reason = 0;
0207 
0208         eth_zero_addr(priv->associated_bss);
0209         wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
0210 
0211         if (vif->iftype != WILC_CLIENT_MODE) {
0212             wl->sta_ch = WILC_INVALID_CHANNEL;
0213         } else {
0214             if (wfi_drv->ifc_up)
0215                 reason = 3;
0216             else
0217                 reason = 1;
0218         }
0219 
0220         cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
0221     }
0222 }
0223 
0224 struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
0225 {
0226     struct wilc_vif *vif;
0227 
0228     vif = list_first_or_null_rcu(&wl->vif_list, typeof(*vif), list);
0229     if (!vif)
0230         return ERR_PTR(-EINVAL);
0231 
0232     return vif;
0233 }
0234 
0235 static int set_channel(struct wiphy *wiphy,
0236                struct cfg80211_chan_def *chandef)
0237 {
0238     struct wilc *wl = wiphy_priv(wiphy);
0239     struct wilc_vif *vif;
0240     u32 channelnum;
0241     int result;
0242     int srcu_idx;
0243 
0244     srcu_idx = srcu_read_lock(&wl->srcu);
0245     vif = wilc_get_wl_to_vif(wl);
0246     if (IS_ERR(vif)) {
0247         srcu_read_unlock(&wl->srcu, srcu_idx);
0248         return PTR_ERR(vif);
0249     }
0250 
0251     channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
0252 
0253     wl->op_ch = channelnum;
0254     result = wilc_set_mac_chnl_num(vif, channelnum);
0255     if (result)
0256         netdev_err(vif->ndev, "Error in setting channel\n");
0257 
0258     srcu_read_unlock(&wl->srcu, srcu_idx);
0259     return result;
0260 }
0261 
0262 static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
0263 {
0264     struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
0265     struct wilc_priv *priv = &vif->priv;
0266     u32 i;
0267     int ret = 0;
0268     u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
0269     u8 scan_type;
0270 
0271     if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
0272         netdev_err(vif->ndev, "Requested scanned channels over\n");
0273         return -EINVAL;
0274     }
0275 
0276     priv->scan_req = request;
0277     priv->cfg_scanning = true;
0278     for (i = 0; i < request->n_channels; i++) {
0279         u16 freq = request->channels[i]->center_freq;
0280 
0281         scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
0282     }
0283 
0284     if (request->n_ssids)
0285         scan_type = WILC_FW_ACTIVE_SCAN;
0286     else
0287         scan_type = WILC_FW_PASSIVE_SCAN;
0288 
0289     ret = wilc_scan(vif, WILC_FW_USER_SCAN, scan_type, scan_ch_list,
0290             request->n_channels, cfg_scan_result, (void *)priv,
0291             request);
0292 
0293     if (ret) {
0294         priv->scan_req = NULL;
0295         priv->cfg_scanning = false;
0296     }
0297 
0298     return ret;
0299 }
0300 
0301 static int connect(struct wiphy *wiphy, struct net_device *dev,
0302            struct cfg80211_connect_params *sme)
0303 {
0304     struct wilc_vif *vif = netdev_priv(dev);
0305     struct wilc_priv *priv = &vif->priv;
0306     struct host_if_drv *wfi_drv = priv->hif_drv;
0307     int ret;
0308     u32 i;
0309     u8 security = WILC_FW_SEC_NO;
0310     enum mfptype mfp_type = WILC_FW_MFP_NONE;
0311     enum authtype auth_type = WILC_FW_AUTH_ANY;
0312     u32 cipher_group;
0313     struct cfg80211_bss *bss;
0314     void *join_params;
0315     u8 ch;
0316 
0317     vif->connecting = true;
0318 
0319     cipher_group = sme->crypto.cipher_group;
0320     if (cipher_group != 0) {
0321         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
0322             if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
0323                 security = WILC_FW_SEC_WPA2_TKIP;
0324             else
0325                 security = WILC_FW_SEC_WPA2_AES;
0326         } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
0327             if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
0328                 security = WILC_FW_SEC_WPA_TKIP;
0329             else
0330                 security = WILC_FW_SEC_WPA_AES;
0331         } else {
0332             ret = -ENOTSUPP;
0333             netdev_err(dev, "%s: Unsupported cipher\n",
0334                    __func__);
0335             goto out_error;
0336         }
0337     }
0338 
0339     if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
0340         (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
0341         for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
0342             u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];
0343 
0344             if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
0345                 security |= WILC_FW_TKIP;
0346             else
0347                 security |= WILC_FW_AES;
0348         }
0349     }
0350 
0351     switch (sme->auth_type) {
0352     case NL80211_AUTHTYPE_OPEN_SYSTEM:
0353         auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
0354         break;
0355 
0356     case NL80211_AUTHTYPE_SAE:
0357         auth_type = WILC_FW_AUTH_SAE;
0358         if (sme->ssid_len) {
0359             memcpy(vif->auth.ssid.ssid, sme->ssid, sme->ssid_len);
0360             vif->auth.ssid.ssid_len = sme->ssid_len;
0361         }
0362         vif->auth.key_mgmt_suite = cpu_to_be32(sme->crypto.akm_suites[0]);
0363         ether_addr_copy(vif->auth.bssid, sme->bssid);
0364         break;
0365 
0366     default:
0367         break;
0368     }
0369 
0370     if (sme->crypto.n_akm_suites) {
0371         if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
0372             auth_type = WILC_FW_AUTH_IEEE8021;
0373         else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_PSK_SHA256)
0374             auth_type = WILC_FW_AUTH_OPEN_SYSTEM_SHA256;
0375         else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X_SHA256)
0376             auth_type = WILC_FW_AUTH_IEE8021X_SHA256;
0377     }
0378 
0379     if (wfi_drv->usr_scan_req.scan_result) {
0380         netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
0381         ret = -EBUSY;
0382         goto out_error;
0383     }
0384 
0385     bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid,
0386                    sme->ssid_len, IEEE80211_BSS_TYPE_ANY,
0387                    IEEE80211_PRIVACY(sme->privacy));
0388     if (!bss) {
0389         ret = -EINVAL;
0390         goto out_error;
0391     }
0392 
0393     if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) {
0394         ret = -EALREADY;
0395         goto out_put_bss;
0396     }
0397 
0398     join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
0399     if (!join_params) {
0400         netdev_err(dev, "%s: failed to construct join param\n",
0401                __func__);
0402         ret = -EINVAL;
0403         goto out_put_bss;
0404     }
0405 
0406     ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
0407     vif->wilc->op_ch = ch;
0408     if (vif->iftype != WILC_CLIENT_MODE)
0409         vif->wilc->sta_ch = ch;
0410 
0411     wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE);
0412 
0413     wfi_drv->conn_info.security = security;
0414     wfi_drv->conn_info.auth_type = auth_type;
0415     wfi_drv->conn_info.ch = ch;
0416     wfi_drv->conn_info.conn_result = cfg_connect_result;
0417     wfi_drv->conn_info.arg = priv;
0418     wfi_drv->conn_info.param = join_params;
0419 
0420     if (sme->mfp == NL80211_MFP_OPTIONAL)
0421         mfp_type = WILC_FW_MFP_OPTIONAL;
0422     else if (sme->mfp == NL80211_MFP_REQUIRED)
0423         mfp_type = WILC_FW_MFP_REQUIRED;
0424 
0425     wfi_drv->conn_info.mfp_type = mfp_type;
0426 
0427     ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
0428     if (ret) {
0429         netdev_err(dev, "wilc_set_join_req(): Error\n");
0430         ret = -ENOENT;
0431         if (vif->iftype != WILC_CLIENT_MODE)
0432             vif->wilc->sta_ch = WILC_INVALID_CHANNEL;
0433         wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE);
0434         wfi_drv->conn_info.conn_result = NULL;
0435         kfree(join_params);
0436         goto out_put_bss;
0437     }
0438     kfree(join_params);
0439     vif->bss = bss;
0440     cfg80211_put_bss(wiphy, bss);
0441     return 0;
0442 
0443 out_put_bss:
0444     cfg80211_put_bss(wiphy, bss);
0445 
0446 out_error:
0447     vif->connecting = false;
0448     return ret;
0449 }
0450 
0451 static int disconnect(struct wiphy *wiphy, struct net_device *dev,
0452               u16 reason_code)
0453 {
0454     struct wilc_vif *vif = netdev_priv(dev);
0455     struct wilc_priv *priv = &vif->priv;
0456     struct wilc *wilc = vif->wilc;
0457     int ret;
0458 
0459     vif->connecting = false;
0460 
0461     if (!wilc)
0462         return -EIO;
0463 
0464     if (wilc->close) {
0465         /* already disconnected done */
0466         cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
0467         return 0;
0468     }
0469 
0470     if (vif->iftype != WILC_CLIENT_MODE)
0471         wilc->sta_ch = WILC_INVALID_CHANNEL;
0472     wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
0473 
0474     priv->hif_drv->p2p_timeout = 0;
0475 
0476     ret = wilc_disconnect(vif);
0477     if (ret != 0) {
0478         netdev_err(priv->dev, "Error in disconnecting\n");
0479         ret = -EINVAL;
0480     }
0481 
0482     vif->bss = NULL;
0483 
0484     return ret;
0485 }
0486 
0487 static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
0488 {
0489     if (!priv->wilc_gtk[idx]) {
0490         priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
0491                           GFP_KERNEL);
0492         if (!priv->wilc_gtk[idx])
0493             return -ENOMEM;
0494     }
0495 
0496     if (!priv->wilc_ptk[idx]) {
0497         priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
0498                           GFP_KERNEL);
0499         if (!priv->wilc_ptk[idx])
0500             return -ENOMEM;
0501     }
0502 
0503     return 0;
0504 }
0505 
0506 static int wilc_wfi_cfg_allocate_wpa_igtk_entry(struct wilc_priv *priv, u8 idx)
0507 {
0508     idx -= 4;
0509     if (!priv->wilc_igtk[idx]) {
0510         priv->wilc_igtk[idx] = kzalloc(sizeof(*priv->wilc_igtk[idx]),
0511                            GFP_KERNEL);
0512         if (!priv->wilc_igtk[idx])
0513             return -ENOMEM;
0514     }
0515     return 0;
0516 }
0517 
0518 static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
0519                       struct key_params *params)
0520 {
0521     kfree(key_info->key);
0522 
0523     key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
0524     if (!key_info->key)
0525         return -ENOMEM;
0526 
0527     kfree(key_info->seq);
0528 
0529     if (params->seq_len > 0) {
0530         key_info->seq = kmemdup(params->seq, params->seq_len,
0531                     GFP_KERNEL);
0532         if (!key_info->seq)
0533             return -ENOMEM;
0534     }
0535 
0536     key_info->cipher = params->cipher;
0537     key_info->key_len = params->key_len;
0538     key_info->seq_len = params->seq_len;
0539 
0540     return 0;
0541 }
0542 
0543 static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
0544            bool pairwise, const u8 *mac_addr, struct key_params *params)
0545 
0546 {
0547     int ret = 0, keylen = params->key_len;
0548     const u8 *rx_mic = NULL;
0549     const u8 *tx_mic = NULL;
0550     u8 mode = WILC_FW_SEC_NO;
0551     u8 op_mode;
0552     struct wilc_vif *vif = netdev_priv(netdev);
0553     struct wilc_priv *priv = &vif->priv;
0554     struct wilc_wfi_key *key;
0555 
0556     switch (params->cipher) {
0557     case WLAN_CIPHER_SUITE_TKIP:
0558     case WLAN_CIPHER_SUITE_CCMP:
0559         if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
0560             priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
0561             struct wilc_wfi_key *key;
0562 
0563             ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
0564             if (ret)
0565                 return -ENOMEM;
0566 
0567             if (params->key_len > 16 &&
0568                 params->cipher == WLAN_CIPHER_SUITE_TKIP) {
0569                 tx_mic = params->key + 24;
0570                 rx_mic = params->key + 16;
0571                 keylen = params->key_len - 16;
0572             }
0573 
0574             if (!pairwise) {
0575                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
0576                     mode = WILC_FW_SEC_WPA_TKIP;
0577                 else
0578                     mode = WILC_FW_SEC_WPA2_AES;
0579 
0580                 priv->wilc_groupkey = mode;
0581 
0582                 key = priv->wilc_gtk[key_index];
0583             } else {
0584                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
0585                     mode = WILC_FW_SEC_WPA_TKIP;
0586                 else
0587                     mode = priv->wilc_groupkey | WILC_FW_AES;
0588 
0589                 key = priv->wilc_ptk[key_index];
0590             }
0591             ret = wilc_wfi_cfg_copy_wpa_info(key, params);
0592             if (ret)
0593                 return -ENOMEM;
0594 
0595             op_mode = WILC_AP_MODE;
0596         } else {
0597             if (params->key_len > 16 &&
0598                 params->cipher == WLAN_CIPHER_SUITE_TKIP) {
0599                 rx_mic = params->key + 24;
0600                 tx_mic = params->key + 16;
0601                 keylen = params->key_len - 16;
0602             }
0603 
0604             op_mode = WILC_STATION_MODE;
0605         }
0606 
0607         if (!pairwise)
0608             ret = wilc_add_rx_gtk(vif, params->key, keylen,
0609                           key_index, params->seq_len,
0610                           params->seq, rx_mic, tx_mic,
0611                           op_mode, mode);
0612         else
0613             ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
0614                        rx_mic, tx_mic, op_mode, mode,
0615                        key_index);
0616 
0617         break;
0618     case WLAN_CIPHER_SUITE_AES_CMAC:
0619         ret = wilc_wfi_cfg_allocate_wpa_igtk_entry(priv, key_index);
0620         if (ret)
0621             return -ENOMEM;
0622 
0623         key = priv->wilc_igtk[key_index - 4];
0624         ret = wilc_wfi_cfg_copy_wpa_info(key, params);
0625         if (ret)
0626             return -ENOMEM;
0627 
0628         if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
0629             priv->wdev.iftype == NL80211_IFTYPE_P2P_GO)
0630             op_mode = WILC_AP_MODE;
0631         else
0632             op_mode = WILC_STATION_MODE;
0633 
0634         ret = wilc_add_igtk(vif, params->key, keylen, params->seq,
0635                     params->seq_len, mac_addr, op_mode,
0636                     key_index);
0637         break;
0638 
0639     default:
0640         netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
0641         ret = -ENOTSUPP;
0642     }
0643 
0644     return ret;
0645 }
0646 
0647 static int del_key(struct wiphy *wiphy, struct net_device *netdev,
0648            u8 key_index,
0649            bool pairwise,
0650            const u8 *mac_addr)
0651 {
0652     struct wilc_vif *vif = netdev_priv(netdev);
0653     struct wilc_priv *priv = &vif->priv;
0654 
0655     if (!pairwise && (key_index == 4 || key_index == 5)) {
0656         key_index -= 4;
0657         if (priv->wilc_igtk[key_index]) {
0658             kfree(priv->wilc_igtk[key_index]->key);
0659             priv->wilc_igtk[key_index]->key = NULL;
0660             kfree(priv->wilc_igtk[key_index]->seq);
0661             priv->wilc_igtk[key_index]->seq = NULL;
0662             kfree(priv->wilc_igtk[key_index]);
0663             priv->wilc_igtk[key_index] = NULL;
0664         }
0665     } else {
0666         if (priv->wilc_gtk[key_index]) {
0667             kfree(priv->wilc_gtk[key_index]->key);
0668             priv->wilc_gtk[key_index]->key = NULL;
0669             kfree(priv->wilc_gtk[key_index]->seq);
0670             priv->wilc_gtk[key_index]->seq = NULL;
0671 
0672             kfree(priv->wilc_gtk[key_index]);
0673             priv->wilc_gtk[key_index] = NULL;
0674         }
0675         if (priv->wilc_ptk[key_index]) {
0676             kfree(priv->wilc_ptk[key_index]->key);
0677             priv->wilc_ptk[key_index]->key = NULL;
0678             kfree(priv->wilc_ptk[key_index]->seq);
0679             priv->wilc_ptk[key_index]->seq = NULL;
0680             kfree(priv->wilc_ptk[key_index]);
0681             priv->wilc_ptk[key_index] = NULL;
0682         }
0683     }
0684 
0685     return 0;
0686 }
0687 
0688 static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
0689            bool pairwise, const u8 *mac_addr, void *cookie,
0690            void (*callback)(void *cookie, struct key_params *))
0691 {
0692     struct wilc_vif *vif = netdev_priv(netdev);
0693     struct wilc_priv *priv = &vif->priv;
0694     struct  key_params key_params;
0695 
0696     if (!pairwise) {
0697         if (key_index == 4 || key_index == 5) {
0698             key_index -= 4;
0699             key_params.key = priv->wilc_igtk[key_index]->key;
0700             key_params.cipher = priv->wilc_igtk[key_index]->cipher;
0701             key_params.key_len = priv->wilc_igtk[key_index]->key_len;
0702             key_params.seq = priv->wilc_igtk[key_index]->seq;
0703             key_params.seq_len = priv->wilc_igtk[key_index]->seq_len;
0704         } else {
0705             key_params.key = priv->wilc_gtk[key_index]->key;
0706             key_params.cipher = priv->wilc_gtk[key_index]->cipher;
0707             key_params.key_len = priv->wilc_gtk[key_index]->key_len;
0708             key_params.seq = priv->wilc_gtk[key_index]->seq;
0709             key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
0710         }
0711     } else {
0712         key_params.key = priv->wilc_ptk[key_index]->key;
0713         key_params.cipher = priv->wilc_ptk[key_index]->cipher;
0714         key_params.key_len = priv->wilc_ptk[key_index]->key_len;
0715         key_params.seq = priv->wilc_ptk[key_index]->seq;
0716         key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
0717     }
0718 
0719     callback(cookie, &key_params);
0720 
0721     return 0;
0722 }
0723 
0724 /* wiphy_new_nm() will WARNON if not present */
0725 static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
0726                u8 key_index, bool unicast, bool multicast)
0727 {
0728     return 0;
0729 }
0730 
0731 static int set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev,
0732                 u8 key_index)
0733 {
0734     struct wilc_vif *vif = netdev_priv(netdev);
0735 
0736     return wilc_set_default_mgmt_key_index(vif, key_index);
0737 }
0738 
0739 static int get_station(struct wiphy *wiphy, struct net_device *dev,
0740                const u8 *mac, struct station_info *sinfo)
0741 {
0742     struct wilc_vif *vif = netdev_priv(dev);
0743     struct wilc_priv *priv = &vif->priv;
0744     struct wilc *wilc = vif->wilc;
0745     u32 i = 0;
0746     u32 associatedsta = ~0;
0747     u32 inactive_time = 0;
0748 
0749     if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
0750         for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
0751             if (!(memcmp(mac,
0752                      priv->assoc_stainfo.sta_associated_bss[i],
0753                      ETH_ALEN))) {
0754                 associatedsta = i;
0755                 break;
0756             }
0757         }
0758 
0759         if (associatedsta == ~0) {
0760             netdev_err(dev, "sta required is not associated\n");
0761             return -ENOENT;
0762         }
0763 
0764         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
0765 
0766         wilc_get_inactive_time(vif, mac, &inactive_time);
0767         sinfo->inactive_time = 1000 * inactive_time;
0768     } else if (vif->iftype == WILC_STATION_MODE) {
0769         struct rf_info stats;
0770 
0771         if (!wilc->initialized)
0772             return -EBUSY;
0773 
0774         wilc_get_statistics(vif, &stats);
0775 
0776         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
0777                  BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
0778                  BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
0779                  BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
0780                  BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
0781 
0782         sinfo->signal = stats.rssi;
0783         sinfo->rx_packets = stats.rx_cnt;
0784         sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
0785         sinfo->tx_failed = stats.tx_fail_cnt;
0786         sinfo->txrate.legacy = stats.link_speed * 10;
0787 
0788         if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
0789             stats.link_speed != DEFAULT_LINK_SPEED)
0790             wilc_enable_tcp_ack_filter(vif, true);
0791         else if (stats.link_speed != DEFAULT_LINK_SPEED)
0792             wilc_enable_tcp_ack_filter(vif, false);
0793     }
0794     return 0;
0795 }
0796 
0797 static int change_bss(struct wiphy *wiphy, struct net_device *dev,
0798               struct bss_parameters *params)
0799 {
0800     return 0;
0801 }
0802 
0803 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
0804 {
0805     int ret = -EINVAL;
0806     struct cfg_param_attr cfg_param_val;
0807     struct wilc *wl = wiphy_priv(wiphy);
0808     struct wilc_vif *vif;
0809     struct wilc_priv *priv;
0810     int srcu_idx;
0811 
0812     srcu_idx = srcu_read_lock(&wl->srcu);
0813     vif = wilc_get_wl_to_vif(wl);
0814     if (IS_ERR(vif))
0815         goto out;
0816 
0817     priv = &vif->priv;
0818     cfg_param_val.flag = 0;
0819 
0820     if (changed & WIPHY_PARAM_RETRY_SHORT) {
0821         netdev_dbg(vif->ndev,
0822                "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
0823                wiphy->retry_short);
0824         cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
0825         cfg_param_val.short_retry_limit = wiphy->retry_short;
0826     }
0827     if (changed & WIPHY_PARAM_RETRY_LONG) {
0828         netdev_dbg(vif->ndev,
0829                "Setting WIPHY_PARAM_RETRY_LONG %d\n",
0830                wiphy->retry_long);
0831         cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
0832         cfg_param_val.long_retry_limit = wiphy->retry_long;
0833     }
0834     if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
0835         if (wiphy->frag_threshold > 255 &&
0836             wiphy->frag_threshold < 7937) {
0837             netdev_dbg(vif->ndev,
0838                    "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
0839                    wiphy->frag_threshold);
0840             cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
0841             cfg_param_val.frag_threshold = wiphy->frag_threshold;
0842         } else {
0843             netdev_err(vif->ndev,
0844                    "Fragmentation threshold out of range\n");
0845             goto out;
0846         }
0847     }
0848 
0849     if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
0850         if (wiphy->rts_threshold > 255) {
0851             netdev_dbg(vif->ndev,
0852                    "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
0853                    wiphy->rts_threshold);
0854             cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
0855             cfg_param_val.rts_threshold = wiphy->rts_threshold;
0856         } else {
0857             netdev_err(vif->ndev, "RTS threshold out of range\n");
0858             goto out;
0859         }
0860     }
0861 
0862     ret = wilc_hif_set_cfg(vif, &cfg_param_val);
0863     if (ret)
0864         netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
0865 
0866 out:
0867     srcu_read_unlock(&wl->srcu, srcu_idx);
0868     return ret;
0869 }
0870 
0871 static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
0872              struct cfg80211_pmksa *pmksa)
0873 {
0874     struct wilc_vif *vif = netdev_priv(netdev);
0875     struct wilc_priv *priv = &vif->priv;
0876     u32 i;
0877     int ret = 0;
0878     u8 flag = 0;
0879 
0880     for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
0881         if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
0882                 ETH_ALEN)) {
0883             flag = PMKID_FOUND;
0884             break;
0885         }
0886     }
0887     if (i < WILC_MAX_NUM_PMKIDS) {
0888         memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
0889                ETH_ALEN);
0890         memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
0891                WLAN_PMKID_LEN);
0892         if (!(flag == PMKID_FOUND))
0893             priv->pmkid_list.numpmkid++;
0894     } else {
0895         netdev_err(netdev, "Invalid PMKID index\n");
0896         ret = -EINVAL;
0897     }
0898 
0899     if (!ret)
0900         ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
0901 
0902     return ret;
0903 }
0904 
0905 static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
0906              struct cfg80211_pmksa *pmksa)
0907 {
0908     u32 i;
0909     struct wilc_vif *vif = netdev_priv(netdev);
0910     struct wilc_priv *priv = &vif->priv;
0911 
0912     for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
0913         if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
0914                 ETH_ALEN)) {
0915             memset(&priv->pmkid_list.pmkidlist[i], 0,
0916                    sizeof(struct wilc_pmkid));
0917             break;
0918         }
0919     }
0920 
0921     if (i == priv->pmkid_list.numpmkid)
0922         return -EINVAL;
0923 
0924     for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
0925         memcpy(priv->pmkid_list.pmkidlist[i].bssid,
0926                priv->pmkid_list.pmkidlist[i + 1].bssid,
0927                ETH_ALEN);
0928         memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
0929                priv->pmkid_list.pmkidlist[i + 1].pmkid,
0930                WLAN_PMKID_LEN);
0931     }
0932     priv->pmkid_list.numpmkid--;
0933 
0934     return 0;
0935 }
0936 
0937 static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
0938 {
0939     struct wilc_vif *vif = netdev_priv(netdev);
0940 
0941     memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
0942 
0943     return 0;
0944 }
0945 
0946 static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
0947 {
0948     struct wilc_attr_entry *e;
0949     struct wilc_attr_ch_list *ch_list;
0950     struct wilc_attr_oper_ch *op_ch;
0951     u32 index = 0;
0952     u8 ch_list_idx = 0;
0953     u8 op_ch_idx = 0;
0954 
0955     if (sta_ch == WILC_INVALID_CHANNEL)
0956         return;
0957 
0958     while (index + sizeof(*e) <= len) {
0959         e = (struct wilc_attr_entry *)&buf[index];
0960         if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
0961             ch_list_idx = index;
0962         else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
0963             op_ch_idx = index;
0964         if (ch_list_idx && op_ch_idx)
0965             break;
0966         index += le16_to_cpu(e->attr_len) + sizeof(*e);
0967     }
0968 
0969     if (ch_list_idx) {
0970         u16 attr_size;
0971         struct wilc_ch_list_elem *e;
0972         int i;
0973 
0974         ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
0975         attr_size = le16_to_cpu(ch_list->attr_len);
0976         for (i = 0; i < attr_size;) {
0977             e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
0978             if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
0979                 memset(e->ch_list, sta_ch, e->no_of_channels);
0980                 break;
0981             }
0982             i += e->no_of_channels;
0983         }
0984     }
0985 
0986     if (op_ch_idx) {
0987         op_ch = (struct wilc_attr_oper_ch *)&buf[op_ch_idx];
0988         op_ch->op_class = WILC_WLAN_OPERATING_CLASS_2_4GHZ;
0989         op_ch->op_channel = sta_ch;
0990     }
0991 }
0992 
0993 bool wilc_wfi_mgmt_frame_rx(struct wilc_vif *vif, u8 *buff, u32 size)
0994 {
0995     struct wilc *wl = vif->wilc;
0996     struct wilc_priv *priv = &vif->priv;
0997     int freq, ret;
0998 
0999     freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
1000     ret = cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1001 
1002     return ret;
1003 }
1004 
1005 void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
1006 {
1007     struct wilc *wl = vif->wilc;
1008     struct wilc_priv *priv = &vif->priv;
1009     struct host_if_drv *wfi_drv = priv->hif_drv;
1010     struct ieee80211_mgmt *mgmt;
1011     struct wilc_vendor_specific_ie *p;
1012     struct wilc_p2p_pub_act_frame *d;
1013     int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
1014     const u8 *vendor_ie;
1015     u32 header, pkt_offset;
1016     s32 freq;
1017 
1018     header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
1019     pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
1020 
1021     if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1022         bool ack = false;
1023         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buff;
1024 
1025         if (ieee80211_is_probe_resp(hdr->frame_control) ||
1026             pkt_offset & IS_MGMT_STATUS_SUCCES)
1027             ack = true;
1028 
1029         cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
1030                     size, ack, GFP_KERNEL);
1031         return;
1032     }
1033 
1034     freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
1035 
1036     mgmt = (struct ieee80211_mgmt *)buff;
1037     if (!ieee80211_is_action(mgmt->frame_control))
1038         goto out_rx_mgmt;
1039 
1040     if (priv->cfg_scanning &&
1041         time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
1042         netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
1043         return;
1044     }
1045 
1046     if (!ieee80211_is_public_action((struct ieee80211_hdr *)buff, size))
1047         goto out_rx_mgmt;
1048 
1049     d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
1050     if (d->oui_subtype != GO_NEG_REQ && d->oui_subtype != GO_NEG_RSP &&
1051         d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
1052         goto out_rx_mgmt;
1053 
1054     vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1055                         buff + ie_offset, size - ie_offset);
1056     if (!vendor_ie)
1057         goto out_rx_mgmt;
1058 
1059     p = (struct wilc_vendor_specific_ie *)vendor_ie;
1060     wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
1061 
1062 out_rx_mgmt:
1063     cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1064 }
1065 
1066 static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
1067 {
1068     struct wilc_p2p_mgmt_data *pv_data = priv;
1069 
1070     kfree(pv_data->buff);
1071     kfree(pv_data);
1072 }
1073 
1074 static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
1075 {
1076     struct wilc_vif *vif = data;
1077     struct wilc_priv *priv = &vif->priv;
1078     struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
1079 
1080     if (cookie != params->listen_cookie)
1081         return;
1082 
1083     priv->p2p_listen_state = false;
1084 
1085     cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
1086                        params->listen_ch, GFP_KERNEL);
1087 }
1088 
1089 static int remain_on_channel(struct wiphy *wiphy,
1090                  struct wireless_dev *wdev,
1091                  struct ieee80211_channel *chan,
1092                  unsigned int duration, u64 *cookie)
1093 {
1094     int ret = 0;
1095     struct wilc_vif *vif = netdev_priv(wdev->netdev);
1096     struct wilc_priv *priv = &vif->priv;
1097     u64 id;
1098 
1099     if (wdev->iftype == NL80211_IFTYPE_AP) {
1100         netdev_dbg(vif->ndev, "Required while in AP mode\n");
1101         return ret;
1102     }
1103 
1104     id = ++priv->inc_roc_cookie;
1105     if (id == 0)
1106         id = ++priv->inc_roc_cookie;
1107 
1108     ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
1109                      wilc_wfi_remain_on_channel_expired,
1110                      (void *)vif);
1111     if (ret)
1112         return ret;
1113 
1114     vif->wilc->op_ch = chan->hw_value;
1115 
1116     priv->remain_on_ch_params.listen_ch = chan;
1117     priv->remain_on_ch_params.listen_cookie = id;
1118     *cookie = id;
1119     priv->p2p_listen_state = true;
1120     priv->remain_on_ch_params.listen_duration = duration;
1121 
1122     cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
1123     mod_timer(&vif->hif_drv->remain_on_ch_timer,
1124           jiffies + msecs_to_jiffies(duration + 1000));
1125 
1126     return ret;
1127 }
1128 
1129 static int cancel_remain_on_channel(struct wiphy *wiphy,
1130                     struct wireless_dev *wdev,
1131                     u64 cookie)
1132 {
1133     struct wilc_vif *vif = netdev_priv(wdev->netdev);
1134     struct wilc_priv *priv = &vif->priv;
1135 
1136     if (cookie != priv->remain_on_ch_params.listen_cookie)
1137         return -ENOENT;
1138 
1139     return wilc_listen_state_expired(vif, cookie);
1140 }
1141 
1142 static int mgmt_tx(struct wiphy *wiphy,
1143            struct wireless_dev *wdev,
1144            struct cfg80211_mgmt_tx_params *params,
1145            u64 *cookie)
1146 {
1147     struct ieee80211_channel *chan = params->chan;
1148     unsigned int wait = params->wait;
1149     const u8 *buf = params->buf;
1150     size_t len = params->len;
1151     const struct ieee80211_mgmt *mgmt;
1152     struct wilc_p2p_mgmt_data *mgmt_tx;
1153     struct wilc_vif *vif = netdev_priv(wdev->netdev);
1154     struct wilc_priv *priv = &vif->priv;
1155     struct host_if_drv *wfi_drv = priv->hif_drv;
1156     struct wilc_vendor_specific_ie *p;
1157     struct wilc_p2p_pub_act_frame *d;
1158     int ie_offset = offsetof(struct ieee80211_mgmt, u) + sizeof(*d);
1159     const u8 *vendor_ie;
1160     int ret = 0;
1161 
1162     *cookie = prandom_u32();
1163     priv->tx_cookie = *cookie;
1164     mgmt = (const struct ieee80211_mgmt *)buf;
1165 
1166     if (!ieee80211_is_mgmt(mgmt->frame_control))
1167         goto out;
1168 
1169     mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
1170     if (!mgmt_tx) {
1171         ret = -ENOMEM;
1172         goto out;
1173     }
1174 
1175     mgmt_tx->buff = kmemdup(buf, len, GFP_KERNEL);
1176     if (!mgmt_tx->buff) {
1177         ret = -ENOMEM;
1178         kfree(mgmt_tx);
1179         goto out;
1180     }
1181 
1182     mgmt_tx->size = len;
1183 
1184     if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1185         wilc_set_mac_chnl_num(vif, chan->hw_value);
1186         vif->wilc->op_ch = chan->hw_value;
1187         goto out_txq_add_pkt;
1188     }
1189 
1190     if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len)) {
1191         if (chan)
1192             wilc_set_mac_chnl_num(vif, chan->hw_value);
1193         else
1194             wilc_set_mac_chnl_num(vif, vif->wilc->op_ch);
1195 
1196         goto out_set_timeout;
1197     }
1198 
1199     d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
1200     if (d->oui_type != WLAN_OUI_TYPE_WFA_P2P ||
1201         d->oui_subtype != GO_NEG_CONF) {
1202         wilc_set_mac_chnl_num(vif, chan->hw_value);
1203         vif->wilc->op_ch = chan->hw_value;
1204     }
1205 
1206     if (d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
1207         goto out_set_timeout;
1208 
1209     vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1210                         mgmt_tx->buff + ie_offset,
1211                         len - ie_offset);
1212     if (!vendor_ie)
1213         goto out_set_timeout;
1214 
1215     p = (struct wilc_vendor_specific_ie *)vendor_ie;
1216     wilc_wfi_cfg_parse_ch_attr(p->attr, p->tag_len - 4, vif->wilc->sta_ch);
1217 
1218 out_set_timeout:
1219     wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1220 
1221 out_txq_add_pkt:
1222 
1223     wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1224                    mgmt_tx->buff, mgmt_tx->size,
1225                    wilc_wfi_mgmt_tx_complete);
1226 
1227 out:
1228 
1229     return ret;
1230 }
1231 
1232 static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1233                    struct wireless_dev *wdev,
1234                    u64 cookie)
1235 {
1236     struct wilc_vif *vif = netdev_priv(wdev->netdev);
1237     struct wilc_priv *priv = &vif->priv;
1238     struct host_if_drv *wfi_drv = priv->hif_drv;
1239 
1240     wfi_drv->p2p_timeout = jiffies;
1241 
1242     if (!priv->p2p_listen_state) {
1243         struct wilc_wfi_p2p_listen_params *params;
1244 
1245         params = &priv->remain_on_ch_params;
1246 
1247         cfg80211_remain_on_channel_expired(wdev,
1248                            params->listen_cookie,
1249                            params->listen_ch,
1250                            GFP_KERNEL);
1251     }
1252 
1253     return 0;
1254 }
1255 
1256 void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
1257                       struct wireless_dev *wdev,
1258                       struct mgmt_frame_regs *upd)
1259 {
1260     struct wilc *wl = wiphy_priv(wiphy);
1261     struct wilc_vif *vif = netdev_priv(wdev->netdev);
1262     u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
1263     u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4);
1264     u32 pauth_bit = BIT(IEEE80211_STYPE_AUTH >> 4);
1265 
1266     if (wl->initialized) {
1267         bool prev = vif->mgmt_reg_stypes & presp_bit;
1268         bool now = upd->interface_stypes & presp_bit;
1269 
1270         if (now != prev)
1271             wilc_frame_register(vif, IEEE80211_STYPE_PROBE_REQ, now);
1272 
1273         prev = vif->mgmt_reg_stypes & action_bit;
1274         now = upd->interface_stypes & action_bit;
1275 
1276         if (now != prev)
1277             wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now);
1278 
1279         prev = vif->mgmt_reg_stypes & pauth_bit;
1280         now = upd->interface_stypes & pauth_bit;
1281         if (now != prev)
1282             wilc_frame_register(vif, IEEE80211_STYPE_AUTH, now);
1283     }
1284 
1285     vif->mgmt_reg_stypes =
1286         upd->interface_stypes & (presp_bit | action_bit | pauth_bit);
1287 }
1288 
1289 static int external_auth(struct wiphy *wiphy, struct net_device *dev,
1290              struct cfg80211_external_auth_params *auth)
1291 {
1292     struct wilc_vif *vif = netdev_priv(dev);
1293 
1294     if (auth->status == WLAN_STATUS_SUCCESS)
1295         wilc_set_external_auth_param(vif, auth);
1296 
1297     return 0;
1298 }
1299 
1300 static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1301                    s32 rssi_thold, u32 rssi_hyst)
1302 {
1303     return 0;
1304 }
1305 
1306 static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1307             int idx, u8 *mac, struct station_info *sinfo)
1308 {
1309     struct wilc_vif *vif = netdev_priv(dev);
1310     int ret;
1311 
1312     if (idx != 0)
1313         return -ENOENT;
1314 
1315     ret = wilc_get_rssi(vif, &sinfo->signal);
1316     if (ret)
1317         return ret;
1318 
1319     sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1320     memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
1321     return 0;
1322 }
1323 
1324 static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1325               bool enabled, int timeout)
1326 {
1327     struct wilc_vif *vif = netdev_priv(dev);
1328     struct wilc_priv *priv = &vif->priv;
1329 
1330     if (!priv->hif_drv)
1331         return -EIO;
1332 
1333     wilc_set_power_mgmt(vif, enabled, timeout);
1334 
1335     return 0;
1336 }
1337 
1338 static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1339                    enum nl80211_iftype type,
1340                    struct vif_params *params)
1341 {
1342     struct wilc *wl = wiphy_priv(wiphy);
1343     struct wilc_vif *vif = netdev_priv(dev);
1344     struct wilc_priv *priv = &vif->priv;
1345 
1346     switch (type) {
1347     case NL80211_IFTYPE_STATION:
1348         vif->connecting = false;
1349         dev->ieee80211_ptr->iftype = type;
1350         priv->wdev.iftype = type;
1351         vif->monitor_flag = 0;
1352         if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
1353             wilc_wfi_deinit_mon_interface(wl, true);
1354         vif->iftype = WILC_STATION_MODE;
1355 
1356         if (wl->initialized)
1357             wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1358                         WILC_STATION_MODE, vif->idx);
1359 
1360         memset(priv->assoc_stainfo.sta_associated_bss, 0,
1361                WILC_MAX_NUM_STA * ETH_ALEN);
1362         break;
1363 
1364     case NL80211_IFTYPE_P2P_CLIENT:
1365         vif->connecting = false;
1366         dev->ieee80211_ptr->iftype = type;
1367         priv->wdev.iftype = type;
1368         vif->monitor_flag = 0;
1369         vif->iftype = WILC_CLIENT_MODE;
1370 
1371         if (wl->initialized)
1372             wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1373                         WILC_STATION_MODE, vif->idx);
1374         break;
1375 
1376     case NL80211_IFTYPE_AP:
1377         dev->ieee80211_ptr->iftype = type;
1378         priv->wdev.iftype = type;
1379         vif->iftype = WILC_AP_MODE;
1380 
1381         if (wl->initialized)
1382             wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1383                         WILC_AP_MODE, vif->idx);
1384         break;
1385 
1386     case NL80211_IFTYPE_P2P_GO:
1387         dev->ieee80211_ptr->iftype = type;
1388         priv->wdev.iftype = type;
1389         vif->iftype = WILC_GO_MODE;
1390 
1391         if (wl->initialized)
1392             wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1393                         WILC_AP_MODE, vif->idx);
1394         break;
1395 
1396     default:
1397         netdev_err(dev, "Unknown interface type= %d\n", type);
1398         return -EINVAL;
1399     }
1400 
1401     return 0;
1402 }
1403 
1404 static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1405             struct cfg80211_ap_settings *settings)
1406 {
1407     struct wilc_vif *vif = netdev_priv(dev);
1408     int ret;
1409 
1410     ret = set_channel(wiphy, &settings->chandef);
1411     if (ret != 0)
1412         netdev_err(dev, "Error in setting channel\n");
1413 
1414     wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
1415 
1416     return wilc_add_beacon(vif, settings->beacon_interval,
1417                    settings->dtim_period, &settings->beacon);
1418 }
1419 
1420 static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1421              struct cfg80211_beacon_data *beacon)
1422 {
1423     struct wilc_vif *vif = netdev_priv(dev);
1424 
1425     return wilc_add_beacon(vif, 0, 0, beacon);
1426 }
1427 
1428 static int stop_ap(struct wiphy *wiphy, struct net_device *dev,
1429            unsigned int link_id)
1430 {
1431     int ret;
1432     struct wilc_vif *vif = netdev_priv(dev);
1433 
1434     wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
1435 
1436     ret = wilc_del_beacon(vif);
1437 
1438     if (ret)
1439         netdev_err(dev, "Host delete beacon fail\n");
1440 
1441     return ret;
1442 }
1443 
1444 static int add_station(struct wiphy *wiphy, struct net_device *dev,
1445                const u8 *mac, struct station_parameters *params)
1446 {
1447     int ret = 0;
1448     struct wilc_vif *vif = netdev_priv(dev);
1449     struct wilc_priv *priv = &vif->priv;
1450 
1451     if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
1452         memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
1453                ETH_ALEN);
1454 
1455         ret = wilc_add_station(vif, mac, params);
1456         if (ret)
1457             netdev_err(dev, "Host add station fail\n");
1458     }
1459 
1460     return ret;
1461 }
1462 
1463 static int del_station(struct wiphy *wiphy, struct net_device *dev,
1464                struct station_del_parameters *params)
1465 {
1466     const u8 *mac = params->mac;
1467     int ret = 0;
1468     struct wilc_vif *vif = netdev_priv(dev);
1469     struct wilc_priv *priv = &vif->priv;
1470     struct sta_info *info;
1471 
1472     if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
1473         return ret;
1474 
1475     info = &priv->assoc_stainfo;
1476 
1477     if (!mac)
1478         ret = wilc_del_allstation(vif, info->sta_associated_bss);
1479 
1480     ret = wilc_del_station(vif, mac);
1481     if (ret)
1482         netdev_err(dev, "Host delete station fail\n");
1483     return ret;
1484 }
1485 
1486 static int change_station(struct wiphy *wiphy, struct net_device *dev,
1487               const u8 *mac, struct station_parameters *params)
1488 {
1489     int ret = 0;
1490     struct wilc_vif *vif = netdev_priv(dev);
1491 
1492     if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
1493         ret = wilc_edit_station(vif, mac, params);
1494         if (ret)
1495             netdev_err(dev, "Host edit station fail\n");
1496     }
1497     return ret;
1498 }
1499 
1500 static struct wilc_vif *wilc_get_vif_from_type(struct wilc *wl, int type)
1501 {
1502     struct wilc_vif *vif;
1503 
1504     list_for_each_entry_rcu(vif, &wl->vif_list, list) {
1505         if (vif->iftype == type)
1506             return vif;
1507     }
1508 
1509     return NULL;
1510 }
1511 
1512 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
1513                          const char *name,
1514                          unsigned char name_assign_type,
1515                          enum nl80211_iftype type,
1516                          struct vif_params *params)
1517 {
1518     struct wilc *wl = wiphy_priv(wiphy);
1519     struct wilc_vif *vif;
1520     struct wireless_dev *wdev;
1521     int iftype;
1522 
1523     if (type == NL80211_IFTYPE_MONITOR) {
1524         struct net_device *ndev;
1525         int srcu_idx;
1526 
1527         srcu_idx = srcu_read_lock(&wl->srcu);
1528         vif = wilc_get_vif_from_type(wl, WILC_AP_MODE);
1529         if (!vif) {
1530             vif = wilc_get_vif_from_type(wl, WILC_GO_MODE);
1531             if (!vif) {
1532                 srcu_read_unlock(&wl->srcu, srcu_idx);
1533                 goto validate_interface;
1534             }
1535         }
1536 
1537         if (vif->monitor_flag) {
1538             srcu_read_unlock(&wl->srcu, srcu_idx);
1539             goto validate_interface;
1540         }
1541 
1542         ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
1543         if (ndev) {
1544             vif->monitor_flag = 1;
1545         } else {
1546             srcu_read_unlock(&wl->srcu, srcu_idx);
1547             return ERR_PTR(-EINVAL);
1548         }
1549 
1550         wdev = &vif->priv.wdev;
1551         srcu_read_unlock(&wl->srcu, srcu_idx);
1552         return wdev;
1553     }
1554 
1555 validate_interface:
1556     mutex_lock(&wl->vif_mutex);
1557     if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
1558         pr_err("Reached maximum number of interface\n");
1559         mutex_unlock(&wl->vif_mutex);
1560         return ERR_PTR(-EINVAL);
1561     }
1562     mutex_unlock(&wl->vif_mutex);
1563 
1564     switch (type) {
1565     case NL80211_IFTYPE_STATION:
1566         iftype = WILC_STATION_MODE;
1567         break;
1568     case NL80211_IFTYPE_AP:
1569         iftype = WILC_AP_MODE;
1570         break;
1571     default:
1572         return ERR_PTR(-EOPNOTSUPP);
1573     }
1574 
1575     vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
1576     if (IS_ERR(vif))
1577         return ERR_CAST(vif);
1578 
1579     return &vif->priv.wdev;
1580 }
1581 
1582 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
1583 {
1584     struct wilc *wl = wiphy_priv(wiphy);
1585     struct wilc_vif *vif;
1586 
1587     if (wdev->iftype == NL80211_IFTYPE_AP ||
1588         wdev->iftype == NL80211_IFTYPE_P2P_GO)
1589         wilc_wfi_deinit_mon_interface(wl, true);
1590     vif = netdev_priv(wdev->netdev);
1591     cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
1592     cfg80211_unregister_netdevice(vif->ndev);
1593     vif->monitor_flag = 0;
1594 
1595     wilc_set_operation_mode(vif, 0, 0, 0);
1596     mutex_lock(&wl->vif_mutex);
1597     list_del_rcu(&vif->list);
1598     wl->vif_num--;
1599     mutex_unlock(&wl->vif_mutex);
1600     synchronize_srcu(&wl->srcu);
1601     return 0;
1602 }
1603 
1604 static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
1605 {
1606     struct wilc *wl = wiphy_priv(wiphy);
1607 
1608     if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
1609         wl->suspend_event = true;
1610     else
1611         wl->suspend_event = false;
1612 
1613     return 0;
1614 }
1615 
1616 static int wilc_resume(struct wiphy *wiphy)
1617 {
1618     return 0;
1619 }
1620 
1621 static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
1622 {
1623     struct wilc *wl = wiphy_priv(wiphy);
1624     struct wilc_vif *vif;
1625     int srcu_idx;
1626 
1627     srcu_idx = srcu_read_lock(&wl->srcu);
1628     vif = wilc_get_wl_to_vif(wl);
1629     if (IS_ERR(vif)) {
1630         srcu_read_unlock(&wl->srcu, srcu_idx);
1631         return;
1632     }
1633 
1634     netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
1635     wilc_set_wowlan_trigger(vif, enabled);
1636     srcu_read_unlock(&wl->srcu, srcu_idx);
1637 }
1638 
1639 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1640             enum nl80211_tx_power_setting type, int mbm)
1641 {
1642     int ret;
1643     int srcu_idx;
1644     s32 tx_power = MBM_TO_DBM(mbm);
1645     struct wilc *wl = wiphy_priv(wiphy);
1646     struct wilc_vif *vif;
1647 
1648     if (!wl->initialized)
1649         return -EIO;
1650 
1651     srcu_idx = srcu_read_lock(&wl->srcu);
1652     vif = wilc_get_wl_to_vif(wl);
1653     if (IS_ERR(vif)) {
1654         srcu_read_unlock(&wl->srcu, srcu_idx);
1655         return -EINVAL;
1656     }
1657 
1658     netdev_info(vif->ndev, "Setting tx power %d\n", tx_power);
1659     if (tx_power < 0)
1660         tx_power = 0;
1661     else if (tx_power > 18)
1662         tx_power = 18;
1663     ret = wilc_set_tx_power(vif, tx_power);
1664     if (ret)
1665         netdev_err(vif->ndev, "Failed to set tx power\n");
1666     srcu_read_unlock(&wl->srcu, srcu_idx);
1667 
1668     return ret;
1669 }
1670 
1671 static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1672             int *dbm)
1673 {
1674     int ret;
1675     struct wilc_vif *vif = netdev_priv(wdev->netdev);
1676     struct wilc *wl = vif->wilc;
1677 
1678     /* If firmware is not started, return. */
1679     if (!wl->initialized)
1680         return -EIO;
1681 
1682     ret = wilc_get_tx_power(vif, (u8 *)dbm);
1683     if (ret)
1684         netdev_err(vif->ndev, "Failed to get tx power\n");
1685 
1686     return ret;
1687 }
1688 
1689 static const struct cfg80211_ops wilc_cfg80211_ops = {
1690     .set_monitor_channel = set_channel,
1691     .scan = scan,
1692     .connect = connect,
1693     .disconnect = disconnect,
1694     .add_key = add_key,
1695     .del_key = del_key,
1696     .get_key = get_key,
1697     .set_default_key = set_default_key,
1698     .set_default_mgmt_key = set_default_mgmt_key,
1699     .add_virtual_intf = add_virtual_intf,
1700     .del_virtual_intf = del_virtual_intf,
1701     .change_virtual_intf = change_virtual_intf,
1702 
1703     .start_ap = start_ap,
1704     .change_beacon = change_beacon,
1705     .stop_ap = stop_ap,
1706     .add_station = add_station,
1707     .del_station = del_station,
1708     .change_station = change_station,
1709     .get_station = get_station,
1710     .dump_station = dump_station,
1711     .change_bss = change_bss,
1712     .set_wiphy_params = set_wiphy_params,
1713 
1714     .external_auth = external_auth,
1715     .set_pmksa = set_pmksa,
1716     .del_pmksa = del_pmksa,
1717     .flush_pmksa = flush_pmksa,
1718     .remain_on_channel = remain_on_channel,
1719     .cancel_remain_on_channel = cancel_remain_on_channel,
1720     .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
1721     .mgmt_tx = mgmt_tx,
1722     .update_mgmt_frame_registrations = wilc_update_mgmt_frame_registrations,
1723     .set_power_mgmt = set_power_mgmt,
1724     .set_cqm_rssi_config = set_cqm_rssi_config,
1725 
1726     .suspend = wilc_suspend,
1727     .resume = wilc_resume,
1728     .set_wakeup = wilc_set_wakeup,
1729     .set_tx_power = set_tx_power,
1730     .get_tx_power = get_tx_power,
1731 
1732 };
1733 
1734 static void wlan_init_locks(struct wilc *wl)
1735 {
1736     mutex_init(&wl->hif_cs);
1737     mutex_init(&wl->rxq_cs);
1738     mutex_init(&wl->cfg_cmd_lock);
1739     mutex_init(&wl->vif_mutex);
1740     mutex_init(&wl->deinit_lock);
1741 
1742     spin_lock_init(&wl->txq_spinlock);
1743     mutex_init(&wl->txq_add_to_head_cs);
1744 
1745     init_completion(&wl->txq_event);
1746     init_completion(&wl->cfg_event);
1747     init_completion(&wl->sync_event);
1748     init_completion(&wl->txq_thread_started);
1749     init_srcu_struct(&wl->srcu);
1750 }
1751 
1752 void wlan_deinit_locks(struct wilc *wilc)
1753 {
1754     mutex_destroy(&wilc->hif_cs);
1755     mutex_destroy(&wilc->rxq_cs);
1756     mutex_destroy(&wilc->cfg_cmd_lock);
1757     mutex_destroy(&wilc->txq_add_to_head_cs);
1758     mutex_destroy(&wilc->vif_mutex);
1759     mutex_destroy(&wilc->deinit_lock);
1760     cleanup_srcu_struct(&wilc->srcu);
1761 }
1762 
1763 int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
1764                const struct wilc_hif_func *ops)
1765 {
1766     struct wilc *wl;
1767     struct wilc_vif *vif;
1768     int ret, i;
1769 
1770     wl = wilc_create_wiphy(dev);
1771     if (!wl)
1772         return -EINVAL;
1773 
1774     wlan_init_locks(wl);
1775 
1776     ret = wilc_wlan_cfg_init(wl);
1777     if (ret)
1778         goto free_wl;
1779 
1780     *wilc = wl;
1781     wl->io_type = io_type;
1782     wl->hif_func = ops;
1783 
1784     for (i = 0; i < NQUEUES; i++)
1785         INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
1786 
1787     INIT_LIST_HEAD(&wl->rxq_head.list);
1788     INIT_LIST_HEAD(&wl->vif_list);
1789 
1790     vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
1791                    NL80211_IFTYPE_STATION, false);
1792     if (IS_ERR(vif)) {
1793         ret = PTR_ERR(vif);
1794         goto free_cfg;
1795     }
1796 
1797     return 0;
1798 
1799 free_cfg:
1800     wilc_wlan_cfg_deinit(wl);
1801 
1802 free_wl:
1803     wlan_deinit_locks(wl);
1804     wiphy_unregister(wl->wiphy);
1805     wiphy_free(wl->wiphy);
1806     return ret;
1807 }
1808 EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
1809 
1810 struct wilc *wilc_create_wiphy(struct device *dev)
1811 {
1812     struct wiphy *wiphy;
1813     struct wilc *wl;
1814     int ret;
1815 
1816     wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
1817     if (!wiphy)
1818         return NULL;
1819 
1820     wl = wiphy_priv(wiphy);
1821 
1822     memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
1823     memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
1824     wl->band.bitrates = wl->bitrates;
1825     wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
1826     wl->band.channels = wl->channels;
1827     wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
1828 
1829     wl->band.ht_cap.ht_supported = 1;
1830     wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
1831     wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
1832     wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
1833     wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1834 
1835     wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
1836 
1837     wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
1838 #ifdef CONFIG_PM
1839     wiphy->wowlan = &wowlan_support;
1840 #endif
1841     wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
1842     wiphy->max_scan_ie_len = 1000;
1843     wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1844     memcpy(wl->cipher_suites, wilc_cipher_suites,
1845            sizeof(wilc_cipher_suites));
1846     wiphy->cipher_suites = wl->cipher_suites;
1847     wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
1848     wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
1849 
1850     wiphy->max_remain_on_channel_duration = 500;
1851     wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1852                 BIT(NL80211_IFTYPE_AP) |
1853                 BIT(NL80211_IFTYPE_MONITOR) |
1854                 BIT(NL80211_IFTYPE_P2P_GO) |
1855                 BIT(NL80211_IFTYPE_P2P_CLIENT);
1856     wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
1857     wiphy->features |= NL80211_FEATURE_SAE;
1858     set_wiphy_dev(wiphy, dev);
1859     wl->wiphy = wiphy;
1860     ret = wiphy_register(wiphy);
1861     if (ret) {
1862         wiphy_free(wiphy);
1863         return NULL;
1864     }
1865     return wl;
1866 }
1867 
1868 int wilc_init_host_int(struct net_device *net)
1869 {
1870     int ret;
1871     struct wilc_vif *vif = netdev_priv(net);
1872     struct wilc_priv *priv = &vif->priv;
1873 
1874     priv->p2p_listen_state = false;
1875 
1876     mutex_init(&priv->scan_req_lock);
1877     ret = wilc_init(net, &priv->hif_drv);
1878     if (ret)
1879         netdev_err(net, "Error while initializing hostinterface\n");
1880 
1881     return ret;
1882 }
1883 
1884 void wilc_deinit_host_int(struct net_device *net)
1885 {
1886     int ret;
1887     struct wilc_vif *vif = netdev_priv(net);
1888     struct wilc_priv *priv = &vif->priv;
1889 
1890     priv->p2p_listen_state = false;
1891 
1892     flush_workqueue(vif->wilc->hif_workqueue);
1893     mutex_destroy(&priv->scan_req_lock);
1894     ret = wilc_deinit(vif);
1895 
1896     if (ret)
1897         netdev_err(net, "Error while deinitializing host interface\n");
1898 }
1899