linux/drivers/staging/wilc1000/cfg80211.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
   4 * All rights reserved.
   5 */
   6
   7#include "cfg80211.h"
   8
   9#define FRAME_TYPE_ID                   0
  10#define ACTION_CAT_ID                   24
  11#define ACTION_SUBTYPE_ID               25
  12#define P2P_PUB_ACTION_SUBTYPE          30
  13
  14#define ACTION_FRAME                    0xd0
  15#define GO_INTENT_ATTR_ID               0x04
  16#define CHANLIST_ATTR_ID                0x0b
  17#define OPERCHAN_ATTR_ID                0x11
  18#define PUB_ACTION_ATTR_ID              0x04
  19#define P2PELEM_ATTR_ID                 0xdd
  20
  21#define GO_NEG_REQ                      0x00
  22#define GO_NEG_RSP                      0x01
  23#define GO_NEG_CONF                     0x02
  24#define P2P_INV_REQ                     0x03
  25#define P2P_INV_RSP                     0x04
  26#define PUBLIC_ACT_VENDORSPEC           0x09
  27#define GAS_INITIAL_REQ                 0x0a
  28#define GAS_INITIAL_RSP                 0x0b
  29
  30#define WILC_INVALID_CHANNEL            0
  31
  32static const struct ieee80211_txrx_stypes
  33        wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
  34        [NL80211_IFTYPE_STATION] = {
  35                .tx = 0xffff,
  36                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  37                        BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  38        },
  39        [NL80211_IFTYPE_AP] = {
  40                .tx = 0xffff,
  41                .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  42                        BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  43                        BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  44                        BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  45                        BIT(IEEE80211_STYPE_AUTH >> 4) |
  46                        BIT(IEEE80211_STYPE_DEAUTH >> 4) |
  47                        BIT(IEEE80211_STYPE_ACTION >> 4)
  48        },
  49        [NL80211_IFTYPE_P2P_CLIENT] = {
  50                .tx = 0xffff,
  51                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  52                        BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  53                        BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  54                        BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  55                        BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  56                        BIT(IEEE80211_STYPE_AUTH >> 4) |
  57                        BIT(IEEE80211_STYPE_DEAUTH >> 4)
  58        }
  59};
  60
  61static const struct wiphy_wowlan_support wowlan_support = {
  62        .flags = WIPHY_WOWLAN_ANY
  63};
  64
  65struct wilc_p2p_mgmt_data {
  66        int size;
  67        u8 *buff;
  68};
  69
  70static const u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
  71static const u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
  72
  73static void cfg_scan_result(enum scan_event scan_event,
  74                            struct wilc_rcvd_net_info *info, void *user_void)
  75{
  76        struct wilc_priv *priv = user_void;
  77
  78        if (!priv->cfg_scanning)
  79                return;
  80
  81        if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
  82                s32 freq;
  83                struct ieee80211_channel *channel;
  84                struct cfg80211_bss *bss;
  85                struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
  86
  87                if (!wiphy || !info)
  88                        return;
  89
  90                freq = ieee80211_channel_to_frequency((s32)info->ch,
  91                                                      NL80211_BAND_2GHZ);
  92                channel = ieee80211_get_channel(wiphy, freq);
  93                if (!channel)
  94                        return;
  95
  96                bss = cfg80211_inform_bss_frame(wiphy, channel, info->mgmt,
  97                                                info->frame_len,
  98                                                (s32)info->rssi * 100,
  99                                                GFP_KERNEL);
 100                if (!bss)
 101                        cfg80211_put_bss(wiphy, bss);
 102        } else if (scan_event == SCAN_EVENT_DONE) {
 103                mutex_lock(&priv->scan_req_lock);
 104
 105                if (priv->scan_req) {
 106                        struct cfg80211_scan_info info = {
 107                                .aborted = false,
 108                        };
 109
 110                        cfg80211_scan_done(priv->scan_req, &info);
 111                        priv->cfg_scanning = false;
 112                        priv->scan_req = NULL;
 113                }
 114                mutex_unlock(&priv->scan_req_lock);
 115        } else if (scan_event == SCAN_EVENT_ABORTED) {
 116                mutex_lock(&priv->scan_req_lock);
 117
 118                if (priv->scan_req) {
 119                        struct cfg80211_scan_info info = {
 120                                .aborted = false,
 121                        };
 122
 123                        cfg80211_scan_done(priv->scan_req, &info);
 124                        priv->cfg_scanning = false;
 125                        priv->scan_req = NULL;
 126                }
 127                mutex_unlock(&priv->scan_req_lock);
 128        }
 129}
 130
 131static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
 132                               void *priv_data)
 133{
 134        struct wilc_priv *priv = priv_data;
 135        struct net_device *dev = priv->dev;
 136        struct wilc_vif *vif = netdev_priv(dev);
 137        struct wilc *wl = vif->wilc;
 138        struct host_if_drv *wfi_drv = priv->hif_drv;
 139        struct wilc_conn_info *conn_info = &wfi_drv->conn_info;
 140        struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 141
 142        vif->connecting = false;
 143
 144        if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) {
 145                u16 connect_status = conn_info->status;
 146
 147                if (mac_status == WILC_MAC_STATUS_DISCONNECTED &&
 148                    connect_status == WLAN_STATUS_SUCCESS) {
 149                        connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
 150                        wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
 151
 152                        if (vif->iftype != WILC_CLIENT_MODE)
 153                                wl->sta_ch = WILC_INVALID_CHANNEL;
 154
 155                        netdev_err(dev, "Unspecified failure\n");
 156                }
 157
 158                if (connect_status == WLAN_STATUS_SUCCESS)
 159                        memcpy(priv->associated_bss, conn_info->bssid,
 160                               ETH_ALEN);
 161
 162                cfg80211_ref_bss(wiphy, vif->bss);
 163                cfg80211_connect_bss(dev, conn_info->bssid, vif->bss,
 164                                     conn_info->req_ies,
 165                                     conn_info->req_ies_len,
 166                                     conn_info->resp_ies,
 167                                     conn_info->resp_ies_len,
 168                                     connect_status, GFP_KERNEL,
 169                                     NL80211_TIMEOUT_UNSPECIFIED);
 170
 171                vif->bss = NULL;
 172        } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
 173                u16 reason = 0;
 174
 175                priv->p2p.local_random = 0x01;
 176                priv->p2p.recv_random = 0x00;
 177                priv->p2p.is_wilc_ie = false;
 178                eth_zero_addr(priv->associated_bss);
 179                wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
 180
 181                if (vif->iftype != WILC_CLIENT_MODE) {
 182                        wl->sta_ch = WILC_INVALID_CHANNEL;
 183                } else {
 184                        if (wfi_drv->ifc_up)
 185                                reason = 3;
 186                        else
 187                                reason = 1;
 188                }
 189
 190                cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
 191        }
 192}
 193
 194struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
 195{
 196        struct wilc_vif *vif;
 197
 198        vif = list_first_or_null_rcu(&wl->vif_list, typeof(*vif), list);
 199        if (!vif)
 200                return ERR_PTR(-EINVAL);
 201
 202        return vif;
 203}
 204
 205static int set_channel(struct wiphy *wiphy,
 206                       struct cfg80211_chan_def *chandef)
 207{
 208        struct wilc *wl = wiphy_priv(wiphy);
 209        struct wilc_vif *vif;
 210        u32 channelnum;
 211        int result;
 212        int srcu_idx;
 213
 214        srcu_idx = srcu_read_lock(&wl->srcu);
 215        vif = wilc_get_wl_to_vif(wl);
 216        if (IS_ERR(vif)) {
 217                srcu_read_unlock(&wl->srcu, srcu_idx);
 218                return PTR_ERR(vif);
 219        }
 220
 221        channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
 222
 223        wl->op_ch = channelnum;
 224        result = wilc_set_mac_chnl_num(vif, channelnum);
 225        if (result)
 226                netdev_err(vif->ndev, "Error in setting channel\n");
 227
 228        srcu_read_unlock(&wl->srcu, srcu_idx);
 229        return result;
 230}
 231
 232static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 233{
 234        struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
 235        struct wilc_priv *priv = &vif->priv;
 236        u32 i;
 237        int ret = 0;
 238        u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
 239        u8 scan_type;
 240
 241        if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
 242                netdev_err(vif->ndev, "Requested scanned channels over\n");
 243                return -EINVAL;
 244        }
 245
 246        priv->scan_req = request;
 247        priv->cfg_scanning = true;
 248        for (i = 0; i < request->n_channels; i++) {
 249                u16 freq = request->channels[i]->center_freq;
 250
 251                scan_ch_list[i] = ieee80211_frequency_to_channel(freq);
 252        }
 253
 254        if (request->n_ssids)
 255                scan_type = WILC_FW_ACTIVE_SCAN;
 256        else
 257                scan_type = WILC_FW_PASSIVE_SCAN;
 258
 259        ret = wilc_scan(vif, WILC_FW_USER_SCAN, scan_type, scan_ch_list,
 260                        request->n_channels, cfg_scan_result, (void *)priv,
 261                        request);
 262
 263        if (ret) {
 264                priv->scan_req = NULL;
 265                priv->cfg_scanning = false;
 266        }
 267
 268        return ret;
 269}
 270
 271static int connect(struct wiphy *wiphy, struct net_device *dev,
 272                   struct cfg80211_connect_params *sme)
 273{
 274        struct wilc_vif *vif = netdev_priv(dev);
 275        struct wilc_priv *priv = &vif->priv;
 276        struct host_if_drv *wfi_drv = priv->hif_drv;
 277        int ret;
 278        u32 i;
 279        u8 security = WILC_FW_SEC_NO;
 280        enum authtype auth_type = WILC_FW_AUTH_ANY;
 281        u32 cipher_group;
 282        struct cfg80211_bss *bss;
 283        void *join_params;
 284        u8 ch;
 285
 286        vif->connecting = true;
 287
 288        memset(priv->wep_key, 0, sizeof(priv->wep_key));
 289        memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
 290
 291        cipher_group = sme->crypto.cipher_group;
 292        if (cipher_group != 0) {
 293                if (cipher_group == WLAN_CIPHER_SUITE_WEP40) {
 294                        security = WILC_FW_SEC_WEP;
 295
 296                        priv->wep_key_len[sme->key_idx] = sme->key_len;
 297                        memcpy(priv->wep_key[sme->key_idx], sme->key,
 298                               sme->key_len);
 299
 300                        wilc_set_wep_default_keyid(vif, sme->key_idx);
 301                        wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
 302                                                 sme->key_idx);
 303                } else if (cipher_group == WLAN_CIPHER_SUITE_WEP104) {
 304                        security = WILC_FW_SEC_WEP_EXTENDED;
 305
 306                        priv->wep_key_len[sme->key_idx] = sme->key_len;
 307                        memcpy(priv->wep_key[sme->key_idx], sme->key,
 308                               sme->key_len);
 309
 310                        wilc_set_wep_default_keyid(vif, sme->key_idx);
 311                        wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
 312                                                 sme->key_idx);
 313                } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
 314                        if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
 315                                security = WILC_FW_SEC_WPA2_TKIP;
 316                        else
 317                                security = WILC_FW_SEC_WPA2_AES;
 318                } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
 319                        if (cipher_group == WLAN_CIPHER_SUITE_TKIP)
 320                                security = WILC_FW_SEC_WPA_TKIP;
 321                        else
 322                                security = WILC_FW_SEC_WPA_AES;
 323                } else {
 324                        ret = -ENOTSUPP;
 325                        netdev_err(dev, "%s: Unsupported cipher\n",
 326                                   __func__);
 327                        goto out_error;
 328                }
 329        }
 330
 331        if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
 332            (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
 333                for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
 334                        u32 ciphers_pairwise = sme->crypto.ciphers_pairwise[i];
 335
 336                        if (ciphers_pairwise == WLAN_CIPHER_SUITE_TKIP)
 337                                security |= WILC_FW_TKIP;
 338                        else
 339                                security |= WILC_FW_AES;
 340                }
 341        }
 342
 343        switch (sme->auth_type) {
 344        case NL80211_AUTHTYPE_OPEN_SYSTEM:
 345                auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
 346                break;
 347
 348        case NL80211_AUTHTYPE_SHARED_KEY:
 349                auth_type = WILC_FW_AUTH_SHARED_KEY;
 350                break;
 351
 352        default:
 353                break;
 354        }
 355
 356        if (sme->crypto.n_akm_suites) {
 357                if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
 358                        auth_type = WILC_FW_AUTH_IEEE8021;
 359        }
 360
 361        if (wfi_drv->usr_scan_req.scan_result) {
 362                netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
 363                ret = -EBUSY;
 364                goto out_error;
 365        }
 366
 367        bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid,
 368                               sme->ssid_len, IEEE80211_BSS_TYPE_ANY,
 369                               IEEE80211_PRIVACY(sme->privacy));
 370        if (!bss) {
 371                ret = -EINVAL;
 372                goto out_error;
 373        }
 374
 375        if (ether_addr_equal_unaligned(vif->bssid, bss->bssid)) {
 376                ret = -EALREADY;
 377                goto out_put_bss;
 378        }
 379
 380        join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
 381        if (!join_params) {
 382                netdev_err(dev, "%s: failed to construct join param\n",
 383                           __func__);
 384                ret = -EINVAL;
 385                goto out_put_bss;
 386        }
 387
 388        ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
 389        vif->wilc->op_ch = ch;
 390        if (vif->iftype != WILC_CLIENT_MODE)
 391                vif->wilc->sta_ch = ch;
 392
 393        wilc_wlan_set_bssid(dev, bss->bssid, WILC_STATION_MODE);
 394
 395        wfi_drv->conn_info.security = security;
 396        wfi_drv->conn_info.auth_type = auth_type;
 397        wfi_drv->conn_info.ch = ch;
 398        wfi_drv->conn_info.conn_result = cfg_connect_result;
 399        wfi_drv->conn_info.arg = priv;
 400        wfi_drv->conn_info.param = join_params;
 401
 402        ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
 403        if (ret) {
 404                netdev_err(dev, "wilc_set_join_req(): Error\n");
 405                ret = -ENOENT;
 406                if (vif->iftype != WILC_CLIENT_MODE)
 407                        vif->wilc->sta_ch = WILC_INVALID_CHANNEL;
 408                wilc_wlan_set_bssid(dev, NULL, WILC_STATION_MODE);
 409                wfi_drv->conn_info.conn_result = NULL;
 410                kfree(join_params);
 411                goto out_put_bss;
 412        }
 413        kfree(join_params);
 414        vif->bss = bss;
 415        cfg80211_put_bss(wiphy, bss);
 416        return 0;
 417
 418out_put_bss:
 419        cfg80211_put_bss(wiphy, bss);
 420
 421out_error:
 422        vif->connecting = false;
 423        return ret;
 424}
 425
 426static int disconnect(struct wiphy *wiphy, struct net_device *dev,
 427                      u16 reason_code)
 428{
 429        struct wilc_vif *vif = netdev_priv(dev);
 430        struct wilc_priv *priv = &vif->priv;
 431        struct wilc *wilc = vif->wilc;
 432        int ret;
 433
 434        vif->connecting = false;
 435
 436        if (!wilc)
 437                return -EIO;
 438
 439        if (wilc->close) {
 440                /* already disconnected done */
 441                cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
 442                return 0;
 443        }
 444
 445        if (vif->iftype != WILC_CLIENT_MODE)
 446                wilc->sta_ch = WILC_INVALID_CHANNEL;
 447        wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
 448
 449        priv->p2p.local_random = 0x01;
 450        priv->p2p.recv_random = 0x00;
 451        priv->p2p.is_wilc_ie = false;
 452        priv->hif_drv->p2p_timeout = 0;
 453
 454        ret = wilc_disconnect(vif);
 455        if (ret != 0) {
 456                netdev_err(priv->dev, "Error in disconnecting\n");
 457                ret = -EINVAL;
 458        }
 459
 460        vif->bss = NULL;
 461
 462        return ret;
 463}
 464
 465static inline void wilc_wfi_cfg_copy_wep_info(struct wilc_priv *priv,
 466                                              u8 key_index,
 467                                              struct key_params *params)
 468{
 469        priv->wep_key_len[key_index] = params->key_len;
 470        memcpy(priv->wep_key[key_index], params->key, params->key_len);
 471}
 472
 473static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
 474{
 475        if (!priv->wilc_gtk[idx]) {
 476                priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]),
 477                                              GFP_KERNEL);
 478                if (!priv->wilc_gtk[idx])
 479                        return -ENOMEM;
 480        }
 481
 482        if (!priv->wilc_ptk[idx]) {
 483                priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]),
 484                                              GFP_KERNEL);
 485                if (!priv->wilc_ptk[idx])
 486                        return -ENOMEM;
 487        }
 488
 489        return 0;
 490}
 491
 492static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
 493                                      struct key_params *params)
 494{
 495        kfree(key_info->key);
 496
 497        key_info->key = kmemdup(params->key, params->key_len, GFP_KERNEL);
 498        if (!key_info->key)
 499                return -ENOMEM;
 500
 501        kfree(key_info->seq);
 502
 503        if (params->seq_len > 0) {
 504                key_info->seq = kmemdup(params->seq, params->seq_len,
 505                                        GFP_KERNEL);
 506                if (!key_info->seq)
 507                        return -ENOMEM;
 508        }
 509
 510        key_info->cipher = params->cipher;
 511        key_info->key_len = params->key_len;
 512        key_info->seq_len = params->seq_len;
 513
 514        return 0;
 515}
 516
 517static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 518                   bool pairwise, const u8 *mac_addr, struct key_params *params)
 519
 520{
 521        int ret = 0, keylen = params->key_len;
 522        const u8 *rx_mic = NULL;
 523        const u8 *tx_mic = NULL;
 524        u8 mode = WILC_FW_SEC_NO;
 525        u8 op_mode;
 526        struct wilc_vif *vif = netdev_priv(netdev);
 527        struct wilc_priv *priv = &vif->priv;
 528
 529        switch (params->cipher) {
 530        case WLAN_CIPHER_SUITE_WEP40:
 531        case WLAN_CIPHER_SUITE_WEP104:
 532                if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
 533                        wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
 534
 535                        if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
 536                                mode = WILC_FW_SEC_WEP;
 537                        else
 538                                mode = WILC_FW_SEC_WEP_EXTENDED;
 539
 540                        ret = wilc_add_wep_key_bss_ap(vif, params->key,
 541                                                      params->key_len,
 542                                                      key_index, mode,
 543                                                      WILC_FW_AUTH_OPEN_SYSTEM);
 544                        break;
 545                }
 546                if (memcmp(params->key, priv->wep_key[key_index],
 547                           params->key_len)) {
 548                        wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
 549
 550                        ret = wilc_add_wep_key_bss_sta(vif, params->key,
 551                                                       params->key_len,
 552                                                       key_index);
 553                }
 554
 555                break;
 556
 557        case WLAN_CIPHER_SUITE_TKIP:
 558        case WLAN_CIPHER_SUITE_CCMP:
 559                if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
 560                    priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
 561                        struct wilc_wfi_key *key;
 562
 563                        ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
 564                        if (ret)
 565                                return -ENOMEM;
 566
 567                        if (params->key_len > 16 &&
 568                            params->cipher == WLAN_CIPHER_SUITE_TKIP) {
 569                                tx_mic = params->key + 24;
 570                                rx_mic = params->key + 16;
 571                                keylen = params->key_len - 16;
 572                        }
 573
 574                        if (!pairwise) {
 575                                if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
 576                                        mode = WILC_FW_SEC_WPA_TKIP;
 577                                else
 578                                        mode = WILC_FW_SEC_WPA2_AES;
 579
 580                                priv->wilc_groupkey = mode;
 581
 582                                key = priv->wilc_gtk[key_index];
 583                        } else {
 584                                if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
 585                                        mode = WILC_FW_SEC_WPA_TKIP;
 586                                else
 587                                        mode = priv->wilc_groupkey | WILC_FW_AES;
 588
 589                                key = priv->wilc_ptk[key_index];
 590                        }
 591                        ret = wilc_wfi_cfg_copy_wpa_info(key, params);
 592                        if (ret)
 593                                return -ENOMEM;
 594
 595                        op_mode = WILC_AP_MODE;
 596                } else {
 597                        if (params->key_len > 16 &&
 598                            params->cipher == WLAN_CIPHER_SUITE_TKIP) {
 599                                rx_mic = params->key + 24;
 600                                tx_mic = params->key + 16;
 601                                keylen = params->key_len - 16;
 602                        }
 603
 604                        op_mode = WILC_STATION_MODE;
 605                }
 606
 607                if (!pairwise)
 608                        ret = wilc_add_rx_gtk(vif, params->key, keylen,
 609                                              key_index, params->seq_len,
 610                                              params->seq, rx_mic, tx_mic,
 611                                              op_mode, mode);
 612                else
 613                        ret = wilc_add_ptk(vif, params->key, keylen, mac_addr,
 614                                           rx_mic, tx_mic, op_mode, mode,
 615                                           key_index);
 616
 617                break;
 618
 619        default:
 620                netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
 621                ret = -ENOTSUPP;
 622        }
 623
 624        return ret;
 625}
 626
 627static int del_key(struct wiphy *wiphy, struct net_device *netdev,
 628                   u8 key_index,
 629                   bool pairwise,
 630                   const u8 *mac_addr)
 631{
 632        struct wilc_vif *vif = netdev_priv(netdev);
 633        struct wilc_priv *priv = &vif->priv;
 634
 635        if (priv->wilc_gtk[key_index]) {
 636                kfree(priv->wilc_gtk[key_index]->key);
 637                priv->wilc_gtk[key_index]->key = NULL;
 638                kfree(priv->wilc_gtk[key_index]->seq);
 639                priv->wilc_gtk[key_index]->seq = NULL;
 640
 641                kfree(priv->wilc_gtk[key_index]);
 642                priv->wilc_gtk[key_index] = NULL;
 643        }
 644
 645        if (priv->wilc_ptk[key_index]) {
 646                kfree(priv->wilc_ptk[key_index]->key);
 647                priv->wilc_ptk[key_index]->key = NULL;
 648                kfree(priv->wilc_ptk[key_index]->seq);
 649                priv->wilc_ptk[key_index]->seq = NULL;
 650                kfree(priv->wilc_ptk[key_index]);
 651                priv->wilc_ptk[key_index] = NULL;
 652        }
 653
 654        if (key_index <= 3 && priv->wep_key_len[key_index]) {
 655                memset(priv->wep_key[key_index], 0,
 656                       priv->wep_key_len[key_index]);
 657                priv->wep_key_len[key_index] = 0;
 658                wilc_remove_wep_key(vif, key_index);
 659        }
 660
 661        return 0;
 662}
 663
 664static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 665                   bool pairwise, const u8 *mac_addr, void *cookie,
 666                   void (*callback)(void *cookie, struct key_params *))
 667{
 668        struct wilc_vif *vif = netdev_priv(netdev);
 669        struct wilc_priv *priv = &vif->priv;
 670        struct  key_params key_params;
 671
 672        if (!pairwise) {
 673                key_params.key = priv->wilc_gtk[key_index]->key;
 674                key_params.cipher = priv->wilc_gtk[key_index]->cipher;
 675                key_params.key_len = priv->wilc_gtk[key_index]->key_len;
 676                key_params.seq = priv->wilc_gtk[key_index]->seq;
 677                key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
 678        } else {
 679                key_params.key = priv->wilc_ptk[key_index]->key;
 680                key_params.cipher = priv->wilc_ptk[key_index]->cipher;
 681                key_params.key_len = priv->wilc_ptk[key_index]->key_len;
 682                key_params.seq = priv->wilc_ptk[key_index]->seq;
 683                key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
 684        }
 685
 686        callback(cookie, &key_params);
 687
 688        return 0;
 689}
 690
 691static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
 692                           u8 key_index, bool unicast, bool multicast)
 693{
 694        struct wilc_vif *vif = netdev_priv(netdev);
 695
 696        wilc_set_wep_default_keyid(vif, key_index);
 697
 698        return 0;
 699}
 700
 701static int get_station(struct wiphy *wiphy, struct net_device *dev,
 702                       const u8 *mac, struct station_info *sinfo)
 703{
 704        struct wilc_vif *vif = netdev_priv(dev);
 705        struct wilc_priv *priv = &vif->priv;
 706        u32 i = 0;
 707        u32 associatedsta = ~0;
 708        u32 inactive_time = 0;
 709
 710        if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
 711                for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
 712                        if (!(memcmp(mac,
 713                                     priv->assoc_stainfo.sta_associated_bss[i],
 714                                     ETH_ALEN))) {
 715                                associatedsta = i;
 716                                break;
 717                        }
 718                }
 719
 720                if (associatedsta == ~0) {
 721                        netdev_err(dev, "sta required is not associated\n");
 722                        return -ENOENT;
 723                }
 724
 725                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
 726
 727                wilc_get_inactive_time(vif, mac, &inactive_time);
 728                sinfo->inactive_time = 1000 * inactive_time;
 729        } else if (vif->iftype == WILC_STATION_MODE) {
 730                struct rf_info stats;
 731
 732                wilc_get_statistics(vif, &stats);
 733
 734                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL) |
 735                                 BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
 736                                 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
 737                                 BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
 738                                 BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
 739
 740                sinfo->signal = stats.rssi;
 741                sinfo->rx_packets = stats.rx_cnt;
 742                sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt;
 743                sinfo->tx_failed = stats.tx_fail_cnt;
 744                sinfo->txrate.legacy = stats.link_speed * 10;
 745
 746                if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
 747                    stats.link_speed != DEFAULT_LINK_SPEED)
 748                        wilc_enable_tcp_ack_filter(vif, true);
 749                else if (stats.link_speed != DEFAULT_LINK_SPEED)
 750                        wilc_enable_tcp_ack_filter(vif, false);
 751        }
 752        return 0;
 753}
 754
 755static int change_bss(struct wiphy *wiphy, struct net_device *dev,
 756                      struct bss_parameters *params)
 757{
 758        return 0;
 759}
 760
 761static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
 762{
 763        int ret = -EINVAL;
 764        struct cfg_param_attr cfg_param_val;
 765        struct wilc *wl = wiphy_priv(wiphy);
 766        struct wilc_vif *vif;
 767        struct wilc_priv *priv;
 768        int srcu_idx;
 769
 770        srcu_idx = srcu_read_lock(&wl->srcu);
 771        vif = wilc_get_wl_to_vif(wl);
 772        if (IS_ERR(vif))
 773                goto out;
 774
 775        priv = &vif->priv;
 776        cfg_param_val.flag = 0;
 777
 778        if (changed & WIPHY_PARAM_RETRY_SHORT) {
 779                netdev_dbg(vif->ndev,
 780                           "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
 781                           wiphy->retry_short);
 782                cfg_param_val.flag  |= WILC_CFG_PARAM_RETRY_SHORT;
 783                cfg_param_val.short_retry_limit = wiphy->retry_short;
 784        }
 785        if (changed & WIPHY_PARAM_RETRY_LONG) {
 786                netdev_dbg(vif->ndev,
 787                           "Setting WIPHY_PARAM_RETRY_LONG %d\n",
 788                           wiphy->retry_long);
 789                cfg_param_val.flag |= WILC_CFG_PARAM_RETRY_LONG;
 790                cfg_param_val.long_retry_limit = wiphy->retry_long;
 791        }
 792        if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
 793                if (wiphy->frag_threshold > 255 &&
 794                    wiphy->frag_threshold < 7937) {
 795                        netdev_dbg(vif->ndev,
 796                                   "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n",
 797                                   wiphy->frag_threshold);
 798                        cfg_param_val.flag |= WILC_CFG_PARAM_FRAG_THRESHOLD;
 799                        cfg_param_val.frag_threshold = wiphy->frag_threshold;
 800                } else {
 801                        netdev_err(vif->ndev,
 802                                   "Fragmentation threshold out of range\n");
 803                        goto out;
 804                }
 805        }
 806
 807        if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
 808                if (wiphy->rts_threshold > 255) {
 809                        netdev_dbg(vif->ndev,
 810                                   "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n",
 811                                   wiphy->rts_threshold);
 812                        cfg_param_val.flag |= WILC_CFG_PARAM_RTS_THRESHOLD;
 813                        cfg_param_val.rts_threshold = wiphy->rts_threshold;
 814                } else {
 815                        netdev_err(vif->ndev, "RTS threshold out of range\n");
 816                        goto out;
 817                }
 818        }
 819
 820        ret = wilc_hif_set_cfg(vif, &cfg_param_val);
 821        if (ret)
 822                netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
 823
 824out:
 825        srcu_read_unlock(&wl->srcu, srcu_idx);
 826        return ret;
 827}
 828
 829static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
 830                     struct cfg80211_pmksa *pmksa)
 831{
 832        struct wilc_vif *vif = netdev_priv(netdev);
 833        struct wilc_priv *priv = &vif->priv;
 834        u32 i;
 835        int ret = 0;
 836        u8 flag = 0;
 837
 838        for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
 839                if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
 840                            ETH_ALEN)) {
 841                        flag = PMKID_FOUND;
 842                        break;
 843                }
 844        }
 845        if (i < WILC_MAX_NUM_PMKIDS) {
 846                memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
 847                       ETH_ALEN);
 848                memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
 849                       WLAN_PMKID_LEN);
 850                if (!(flag == PMKID_FOUND))
 851                        priv->pmkid_list.numpmkid++;
 852        } else {
 853                netdev_err(netdev, "Invalid PMKID index\n");
 854                ret = -EINVAL;
 855        }
 856
 857        if (!ret)
 858                ret = wilc_set_pmkid_info(vif, &priv->pmkid_list);
 859
 860        return ret;
 861}
 862
 863static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
 864                     struct cfg80211_pmksa *pmksa)
 865{
 866        u32 i;
 867        int ret = 0;
 868        struct wilc_vif *vif = netdev_priv(netdev);
 869        struct wilc_priv *priv = &vif->priv;
 870
 871        for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
 872                if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
 873                            ETH_ALEN)) {
 874                        memset(&priv->pmkid_list.pmkidlist[i], 0,
 875                               sizeof(struct wilc_pmkid));
 876                        break;
 877                }
 878        }
 879
 880        if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
 881                for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
 882                        memcpy(priv->pmkid_list.pmkidlist[i].bssid,
 883                               priv->pmkid_list.pmkidlist[i + 1].bssid,
 884                               ETH_ALEN);
 885                        memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
 886                               priv->pmkid_list.pmkidlist[i + 1].pmkid,
 887                               WLAN_PMKID_LEN);
 888                }
 889                priv->pmkid_list.numpmkid--;
 890        } else {
 891                ret = -EINVAL;
 892        }
 893
 894        return ret;
 895}
 896
 897static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
 898{
 899        struct wilc_vif *vif = netdev_priv(netdev);
 900
 901        memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
 902
 903        return 0;
 904}
 905
 906static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u8 ch_list_attr_idx,
 907                                              u8 op_ch_attr_idx, u8 sta_ch)
 908{
 909        int i = 0;
 910        int j = 0;
 911
 912        if (ch_list_attr_idx) {
 913                u8 limit = ch_list_attr_idx + 3 + buf[ch_list_attr_idx + 1];
 914
 915                for (i = ch_list_attr_idx + 3; i < limit; i++) {
 916                        if (buf[i] == 0x51) {
 917                                for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
 918                                        buf[j] = sta_ch;
 919                                break;
 920                        }
 921                }
 922        }
 923
 924        if (op_ch_attr_idx) {
 925                buf[op_ch_attr_idx + 6] = 0x51;
 926                buf[op_ch_attr_idx + 7] = sta_ch;
 927        }
 928}
 929
 930static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len, u8 sta_ch)
 931{
 932        u32 index = 0;
 933        u8 op_channel_attr_index = 0;
 934        u8 channel_list_attr_index = 0;
 935
 936        while (index < len) {
 937                if (buf[index] == GO_INTENT_ATTR_ID)
 938                        buf[index + 3] = (buf[index + 3]  & 0x01) | (0x00 << 1);
 939
 940                if (buf[index] ==  CHANLIST_ATTR_ID)
 941                        channel_list_attr_index = index;
 942                else if (buf[index] ==  OPERCHAN_ATTR_ID)
 943                        op_channel_attr_index = index;
 944                index += buf[index + 1] + 3;
 945        }
 946        if (sta_ch != WILC_INVALID_CHANNEL)
 947                wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index,
 948                                           op_channel_attr_index, sta_ch);
 949}
 950
 951static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch,
 952                                         u8 iftype, u8 sta_ch)
 953{
 954        u32 index = 0;
 955        u8 op_channel_attr_index = 0;
 956        u8 channel_list_attr_index = 0;
 957
 958        while (index < len) {
 959                if (buf[index] == GO_INTENT_ATTR_ID) {
 960                        buf[index + 3] = (buf[index + 3]  & 0x01) | (0x0f << 1);
 961
 962                        break;
 963                }
 964
 965                if (buf[index] ==  CHANLIST_ATTR_ID)
 966                        channel_list_attr_index = index;
 967                else if (buf[index] ==  OPERCHAN_ATTR_ID)
 968                        op_channel_attr_index = index;
 969                index += buf[index + 1] + 3;
 970        }
 971        if (sta_ch != WILC_INVALID_CHANNEL && oper_ch)
 972                wilc_wfi_cfg_parse_ch_attr(buf, channel_list_attr_index,
 973                                           op_channel_attr_index, sta_ch);
 974}
 975
 976static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff,
 977                                              u32 size)
 978{
 979        int i;
 980        u8 subtype;
 981        struct wilc_vif *vif = netdev_priv(priv->dev);
 982
 983        subtype = buff[P2P_PUB_ACTION_SUBTYPE];
 984        if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
 985            !priv->p2p.is_wilc_ie) {
 986                for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
 987                        if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
 988                                priv->p2p.recv_random = buff[i + 6];
 989                                priv->p2p.is_wilc_ie = true;
 990                                break;
 991                        }
 992                }
 993        }
 994
 995        if (priv->p2p.local_random <= priv->p2p.recv_random) {
 996                netdev_dbg(vif->ndev,
 997                           "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n",
 998                           priv->p2p.local_random, priv->p2p.recv_random);
 999                return;
1000        }
1001
1002        if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP ||
1003            subtype == P2P_INV_REQ || subtype == P2P_INV_RSP) {
1004                for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1005                        if (buff[i] == P2PELEM_ATTR_ID &&
1006                            !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1007                                wilc_wfi_cfg_parse_rx_action(&buff[i + 6],
1008                                                             size - (i + 6),
1009                                                             vif->wilc->sta_ch);
1010                                break;
1011                        }
1012                }
1013        }
1014}
1015
1016void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
1017{
1018        struct wilc *wl = vif->wilc;
1019        struct wilc_priv *priv = &vif->priv;
1020        struct host_if_drv *wfi_drv = priv->hif_drv;
1021        u32 header, pkt_offset;
1022        s32 freq;
1023        __le16 fc;
1024
1025        header = get_unaligned_le32(buff - HOST_HDR_OFFSET);
1026        pkt_offset = GET_PKT_OFFSET(header);
1027
1028        if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1029                bool ack = false;
1030
1031                if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP ||
1032                    pkt_offset & IS_MGMT_STATUS_SUCCES)
1033                        ack = true;
1034
1035                cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
1036                                        size, ack, GFP_KERNEL);
1037                return;
1038        }
1039
1040        freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
1041
1042        fc = ((struct ieee80211_hdr *)buff)->frame_control;
1043        if (!ieee80211_is_action(fc)) {
1044                cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1045                return;
1046        }
1047
1048        if (priv->cfg_scanning &&
1049            time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
1050                netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
1051                return;
1052        }
1053        if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1054                u8 subtype = buff[P2P_PUB_ACTION_SUBTYPE];
1055
1056                switch (buff[ACTION_SUBTYPE_ID]) {
1057                case GAS_INITIAL_REQ:
1058                case GAS_INITIAL_RSP:
1059                        break;
1060
1061                case PUBLIC_ACT_VENDORSPEC:
1062                        if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4))
1063                                wilc_wfi_cfg_parse_rx_vendor_spec(priv, buff,
1064                                                                  size);
1065
1066                        if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) &&
1067                            priv->p2p.is_wilc_ie)
1068                                size -= 7;
1069
1070                        break;
1071
1072                default:
1073                        netdev_dbg(vif->ndev,
1074                                   "%s: Not handled action frame type:%x\n",
1075                                   __func__, buff[ACTION_SUBTYPE_ID]);
1076                        break;
1077                }
1078        }
1079
1080        cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1081}
1082
1083static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
1084{
1085        struct wilc_p2p_mgmt_data *pv_data = priv;
1086
1087        kfree(pv_data->buff);
1088        kfree(pv_data);
1089}
1090
1091static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
1092{
1093        struct wilc_vif *vif = data;
1094        struct wilc_priv *priv = &vif->priv;
1095        struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
1096
1097        if (cookie != params->listen_cookie)
1098                return;
1099
1100        priv->p2p_listen_state = false;
1101
1102        cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
1103                                           params->listen_ch, GFP_KERNEL);
1104}
1105
1106static int remain_on_channel(struct wiphy *wiphy,
1107                             struct wireless_dev *wdev,
1108                             struct ieee80211_channel *chan,
1109                             unsigned int duration, u64 *cookie)
1110{
1111        int ret = 0;
1112        struct wilc_vif *vif = netdev_priv(wdev->netdev);
1113        struct wilc_priv *priv = &vif->priv;
1114        u64 id;
1115
1116        if (wdev->iftype == NL80211_IFTYPE_AP) {
1117                netdev_dbg(vif->ndev, "Required while in AP mode\n");
1118                return ret;
1119        }
1120
1121        id = ++priv->inc_roc_cookie;
1122        if (id == 0)
1123                id = ++priv->inc_roc_cookie;
1124
1125        ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
1126                                     wilc_wfi_remain_on_channel_expired,
1127                                     (void *)vif);
1128        if (ret)
1129                return ret;
1130
1131        vif->wilc->op_ch = chan->hw_value;
1132
1133        priv->remain_on_ch_params.listen_ch = chan;
1134        priv->remain_on_ch_params.listen_cookie = id;
1135        *cookie = id;
1136        priv->p2p_listen_state = true;
1137        priv->remain_on_ch_params.listen_duration = duration;
1138
1139        cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
1140        mod_timer(&vif->hif_drv->remain_on_ch_timer,
1141                  jiffies + msecs_to_jiffies(duration + 1000));
1142
1143        return ret;
1144}
1145
1146static int cancel_remain_on_channel(struct wiphy *wiphy,
1147                                    struct wireless_dev *wdev,
1148                                    u64 cookie)
1149{
1150        struct wilc_vif *vif = netdev_priv(wdev->netdev);
1151        struct wilc_priv *priv = &vif->priv;
1152
1153        if (cookie != priv->remain_on_ch_params.listen_cookie)
1154                return -ENOENT;
1155
1156        return wilc_listen_state_expired(vif, cookie);
1157}
1158
1159static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv,
1160                                        struct wilc_p2p_mgmt_data *mgmt_tx,
1161                                        struct cfg80211_mgmt_tx_params *params,
1162                                        u8 iftype, u32 buf_len)
1163{
1164        const u8 *buf = params->buf;
1165        size_t len = params->len;
1166        u32 i;
1167        u8 subtype = buf[P2P_PUB_ACTION_SUBTYPE];
1168        struct wilc_vif *vif = netdev_priv(priv->dev);
1169
1170        if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) {
1171                if (priv->p2p.local_random == 1 &&
1172                    priv->p2p.recv_random < priv->p2p.local_random) {
1173                        get_random_bytes(&priv->p2p.local_random, 1);
1174                        priv->p2p.local_random++;
1175                }
1176        }
1177
1178        if (priv->p2p.local_random <= priv->p2p.recv_random ||
1179            !(subtype == GO_NEG_REQ || subtype == GO_NEG_RSP ||
1180              subtype == P2P_INV_REQ || subtype == P2P_INV_RSP))
1181                return;
1182
1183        for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1184                if (buf[i] == P2PELEM_ATTR_ID &&
1185                    !memcmp(p2p_oui, &buf[i + 2], 4)) {
1186                        bool oper_ch = false;
1187                        u8 *tx_buff = &mgmt_tx->buff[i + 6];
1188
1189                        if (subtype == P2P_INV_REQ || subtype == P2P_INV_RSP)
1190                                oper_ch = true;
1191
1192                        wilc_wfi_cfg_parse_tx_action(tx_buff, len - (i + 6),
1193                                                     oper_ch, iftype,
1194                                                     vif->wilc->sta_ch);
1195
1196                        break;
1197                }
1198        }
1199
1200        if (subtype != P2P_INV_REQ && subtype != P2P_INV_RSP) {
1201                int vendor_spec_len = sizeof(p2p_vendor_spec);
1202
1203                memcpy(&mgmt_tx->buff[len], p2p_vendor_spec,
1204                       vendor_spec_len);
1205                mgmt_tx->buff[len + vendor_spec_len] = priv->p2p.local_random;
1206                mgmt_tx->size = buf_len;
1207        }
1208}
1209
1210static int mgmt_tx(struct wiphy *wiphy,
1211                   struct wireless_dev *wdev,
1212                   struct cfg80211_mgmt_tx_params *params,
1213                   u64 *cookie)
1214{
1215        struct ieee80211_channel *chan = params->chan;
1216        unsigned int wait = params->wait;
1217        const u8 *buf = params->buf;
1218        size_t len = params->len;
1219        const struct ieee80211_mgmt *mgmt;
1220        struct wilc_p2p_mgmt_data *mgmt_tx;
1221        struct wilc_vif *vif = netdev_priv(wdev->netdev);
1222        struct wilc_priv *priv = &vif->priv;
1223        struct host_if_drv *wfi_drv = priv->hif_drv;
1224        u32 buf_len = len + sizeof(p2p_vendor_spec) +
1225                        sizeof(priv->p2p.local_random);
1226        int ret = 0;
1227
1228        *cookie = prandom_u32();
1229        priv->tx_cookie = *cookie;
1230        mgmt = (const struct ieee80211_mgmt *)buf;
1231
1232        if (!ieee80211_is_mgmt(mgmt->frame_control))
1233                goto out;
1234
1235        mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL);
1236        if (!mgmt_tx) {
1237                ret = -ENOMEM;
1238                goto out;
1239        }
1240
1241        mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1242        if (!mgmt_tx->buff) {
1243                ret = -ENOMEM;
1244                kfree(mgmt_tx);
1245                goto out;
1246        }
1247
1248        memcpy(mgmt_tx->buff, buf, len);
1249        mgmt_tx->size = len;
1250
1251        if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1252                wilc_set_mac_chnl_num(vif, chan->hw_value);
1253                vif->wilc->op_ch = chan->hw_value;
1254                goto out_txq_add_pkt;
1255        }
1256
1257        if (!ieee80211_is_action(mgmt->frame_control))
1258                goto out_txq_add_pkt;
1259
1260        if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1261                if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1262                    buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1263                        wilc_set_mac_chnl_num(vif, chan->hw_value);
1264                        vif->wilc->op_ch = chan->hw_value;
1265                }
1266                switch (buf[ACTION_SUBTYPE_ID]) {
1267                case GAS_INITIAL_REQ:
1268                case GAS_INITIAL_RSP:
1269                        break;
1270
1271                case PUBLIC_ACT_VENDORSPEC:
1272                        if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4))
1273                                wilc_wfi_cfg_tx_vendor_spec(priv, mgmt_tx,
1274                                                            params, vif->iftype,
1275                                                            buf_len);
1276                        else
1277                                netdev_dbg(vif->ndev,
1278                                           "Not a P2P public action frame\n");
1279
1280                        break;
1281
1282                default:
1283                        netdev_dbg(vif->ndev,
1284                                   "%s: Not handled action frame type:%x\n",
1285                                   __func__, buf[ACTION_SUBTYPE_ID]);
1286                        break;
1287                }
1288        }
1289
1290        wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1291
1292out_txq_add_pkt:
1293
1294        wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1295                                   mgmt_tx->buff, mgmt_tx->size,
1296                                   wilc_wfi_mgmt_tx_complete);
1297
1298out:
1299
1300        return ret;
1301}
1302
1303static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1304                               struct wireless_dev *wdev,
1305                               u64 cookie)
1306{
1307        struct wilc_vif *vif = netdev_priv(wdev->netdev);
1308        struct wilc_priv *priv = &vif->priv;
1309        struct host_if_drv *wfi_drv = priv->hif_drv;
1310
1311        wfi_drv->p2p_timeout = jiffies;
1312
1313        if (!priv->p2p_listen_state) {
1314                struct wilc_wfi_p2p_listen_params *params;
1315
1316                params = &priv->remain_on_ch_params;
1317
1318                cfg80211_remain_on_channel_expired(wdev,
1319                                                   params->listen_cookie,
1320                                                   params->listen_ch,
1321                                                   GFP_KERNEL);
1322        }
1323
1324        return 0;
1325}
1326
1327void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1328                              u16 frame_type, bool reg)
1329{
1330        struct wilc *wl = wiphy_priv(wiphy);
1331        struct wilc_vif *vif = netdev_priv(wdev->netdev);
1332
1333        if (!frame_type)
1334                return;
1335
1336        switch (frame_type) {
1337        case IEEE80211_STYPE_PROBE_REQ:
1338                vif->frame_reg[0].type = frame_type;
1339                vif->frame_reg[0].reg = reg;
1340                break;
1341
1342        case IEEE80211_STYPE_ACTION:
1343                vif->frame_reg[1].type = frame_type;
1344                vif->frame_reg[1].reg = reg;
1345                break;
1346
1347        default:
1348                break;
1349        }
1350
1351        if (!wl->initialized)
1352                return;
1353        wilc_frame_register(vif, frame_type, reg);
1354}
1355
1356static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1357                               s32 rssi_thold, u32 rssi_hyst)
1358{
1359        return 0;
1360}
1361
1362static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1363                        int idx, u8 *mac, struct station_info *sinfo)
1364{
1365        struct wilc_vif *vif = netdev_priv(dev);
1366        int ret;
1367
1368        if (idx != 0)
1369                return -ENOENT;
1370
1371        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1372
1373        ret = wilc_get_rssi(vif, &sinfo->signal);
1374        if (ret)
1375                return ret;
1376
1377        memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
1378        return 0;
1379}
1380
1381static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1382                          bool enabled, int timeout)
1383{
1384        struct wilc_vif *vif = netdev_priv(dev);
1385        struct wilc_priv *priv = &vif->priv;
1386
1387        if (!priv->hif_drv)
1388                return -EIO;
1389
1390        wilc_set_power_mgmt(vif, enabled, timeout);
1391
1392        return 0;
1393}
1394
1395static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1396                               enum nl80211_iftype type,
1397                               struct vif_params *params)
1398{
1399        struct wilc *wl = wiphy_priv(wiphy);
1400        struct wilc_vif *vif = netdev_priv(dev);
1401        struct wilc_priv *priv = &vif->priv;
1402
1403        priv->p2p.local_random = 0x01;
1404        priv->p2p.recv_random = 0x00;
1405        priv->p2p.is_wilc_ie = false;
1406
1407        switch (type) {
1408        case NL80211_IFTYPE_STATION:
1409                vif->connecting = false;
1410                dev->ieee80211_ptr->iftype = type;
1411                priv->wdev.iftype = type;
1412                vif->monitor_flag = 0;
1413                if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
1414                        wilc_wfi_deinit_mon_interface(wl, true);
1415                vif->iftype = WILC_STATION_MODE;
1416
1417                if (wl->initialized)
1418                        wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1419                                                WILC_STATION_MODE, vif->idx);
1420
1421                memset(priv->assoc_stainfo.sta_associated_bss, 0,
1422                       WILC_MAX_NUM_STA * ETH_ALEN);
1423                break;
1424
1425        case NL80211_IFTYPE_P2P_CLIENT:
1426                vif->connecting = false;
1427                dev->ieee80211_ptr->iftype = type;
1428                priv->wdev.iftype = type;
1429                vif->monitor_flag = 0;
1430                vif->iftype = WILC_CLIENT_MODE;
1431
1432                if (wl->initialized)
1433                        wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1434                                                WILC_STATION_MODE, vif->idx);
1435                break;
1436
1437        case NL80211_IFTYPE_AP:
1438                dev->ieee80211_ptr->iftype = type;
1439                priv->wdev.iftype = type;
1440                vif->iftype = WILC_AP_MODE;
1441
1442                if (wl->initialized)
1443                        wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1444                                                WILC_AP_MODE, vif->idx);
1445                break;
1446
1447        case NL80211_IFTYPE_P2P_GO:
1448                dev->ieee80211_ptr->iftype = type;
1449                priv->wdev.iftype = type;
1450                vif->iftype = WILC_GO_MODE;
1451
1452                if (wl->initialized)
1453                        wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
1454                                                WILC_AP_MODE, vif->idx);
1455                break;
1456
1457        default:
1458                netdev_err(dev, "Unknown interface type= %d\n", type);
1459                return -EINVAL;
1460        }
1461
1462        return 0;
1463}
1464
1465static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1466                    struct cfg80211_ap_settings *settings)
1467{
1468        struct wilc_vif *vif = netdev_priv(dev);
1469        int ret;
1470
1471        ret = set_channel(wiphy, &settings->chandef);
1472        if (ret != 0)
1473                netdev_err(dev, "Error in setting channel\n");
1474
1475        wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
1476
1477        return wilc_add_beacon(vif, settings->beacon_interval,
1478                                   settings->dtim_period, &settings->beacon);
1479}
1480
1481static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1482                         struct cfg80211_beacon_data *beacon)
1483{
1484        struct wilc_vif *vif = netdev_priv(dev);
1485
1486        return wilc_add_beacon(vif, 0, 0, beacon);
1487}
1488
1489static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1490{
1491        int ret;
1492        struct wilc_vif *vif = netdev_priv(dev);
1493
1494        wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
1495
1496        ret = wilc_del_beacon(vif);
1497
1498        if (ret)
1499                netdev_err(dev, "Host delete beacon fail\n");
1500
1501        return ret;
1502}
1503
1504static int add_station(struct wiphy *wiphy, struct net_device *dev,
1505                       const u8 *mac, struct station_parameters *params)
1506{
1507        int ret = 0;
1508        struct wilc_vif *vif = netdev_priv(dev);
1509        struct wilc_priv *priv = &vif->priv;
1510
1511        if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
1512                memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
1513                       ETH_ALEN);
1514
1515                ret = wilc_add_station(vif, mac, params);
1516                if (ret)
1517                        netdev_err(dev, "Host add station fail\n");
1518        }
1519
1520        return ret;
1521}
1522
1523static int del_station(struct wiphy *wiphy, struct net_device *dev,
1524                       struct station_del_parameters *params)
1525{
1526        const u8 *mac = params->mac;
1527        int ret = 0;
1528        struct wilc_vif *vif = netdev_priv(dev);
1529        struct wilc_priv *priv = &vif->priv;
1530        struct sta_info *info;
1531
1532        if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
1533                return ret;
1534
1535        info = &priv->assoc_stainfo;
1536
1537        if (!mac)
1538                ret = wilc_del_allstation(vif, info->sta_associated_bss);
1539
1540        ret = wilc_del_station(vif, mac);
1541        if (ret)
1542                netdev_err(dev, "Host delete station fail\n");
1543        return ret;
1544}
1545
1546static int change_station(struct wiphy *wiphy, struct net_device *dev,
1547                          const u8 *mac, struct station_parameters *params)
1548{
1549        int ret = 0;
1550        struct wilc_vif *vif = netdev_priv(dev);
1551
1552        if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
1553                ret = wilc_edit_station(vif, mac, params);
1554                if (ret)
1555                        netdev_err(dev, "Host edit station fail\n");
1556        }
1557        return ret;
1558}
1559
1560static struct wilc_vif *wilc_get_vif_from_type(struct wilc *wl, int type)
1561{
1562        struct wilc_vif *vif;
1563
1564        list_for_each_entry_rcu(vif, &wl->vif_list, list) {
1565                if (vif->iftype == type)
1566                        return vif;
1567        }
1568
1569        return NULL;
1570}
1571
1572static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
1573                                             const char *name,
1574                                             unsigned char name_assign_type,
1575                                             enum nl80211_iftype type,
1576                                             struct vif_params *params)
1577{
1578        struct wilc *wl = wiphy_priv(wiphy);
1579        struct wilc_vif *vif;
1580        struct wireless_dev *wdev;
1581        int iftype;
1582
1583        if (type == NL80211_IFTYPE_MONITOR) {
1584                struct net_device *ndev;
1585                int srcu_idx;
1586
1587                srcu_idx = srcu_read_lock(&wl->srcu);
1588                vif = wilc_get_vif_from_type(wl, WILC_AP_MODE);
1589                if (!vif) {
1590                        vif = wilc_get_vif_from_type(wl, WILC_GO_MODE);
1591                        if (!vif) {
1592                                srcu_read_unlock(&wl->srcu, srcu_idx);
1593                                goto validate_interface;
1594                        }
1595                }
1596
1597                if (vif->monitor_flag) {
1598                        srcu_read_unlock(&wl->srcu, srcu_idx);
1599                        goto validate_interface;
1600                }
1601
1602                ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
1603                if (ndev) {
1604                        vif->monitor_flag = 1;
1605                } else {
1606                        srcu_read_unlock(&wl->srcu, srcu_idx);
1607                        return ERR_PTR(-EINVAL);
1608                }
1609
1610                wdev = &vif->priv.wdev;
1611                srcu_read_unlock(&wl->srcu, srcu_idx);
1612                return wdev;
1613        }
1614
1615validate_interface:
1616        mutex_lock(&wl->vif_mutex);
1617        if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
1618                pr_err("Reached maximum number of interface\n");
1619                mutex_unlock(&wl->vif_mutex);
1620                return ERR_PTR(-EINVAL);
1621        }
1622        mutex_unlock(&wl->vif_mutex);
1623
1624        switch (type) {
1625        case NL80211_IFTYPE_STATION:
1626                iftype = WILC_STATION_MODE;
1627                break;
1628        case NL80211_IFTYPE_AP:
1629                iftype = WILC_AP_MODE;
1630                break;
1631        default:
1632                return ERR_PTR(-EOPNOTSUPP);
1633        }
1634
1635        vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
1636        if (IS_ERR(vif))
1637                return ERR_CAST(vif);
1638
1639        return &vif->priv.wdev;
1640}
1641
1642static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
1643{
1644        struct wilc *wl = wiphy_priv(wiphy);
1645        struct wilc_vif *vif;
1646
1647        if (wdev->iftype == NL80211_IFTYPE_AP ||
1648            wdev->iftype == NL80211_IFTYPE_P2P_GO)
1649                wilc_wfi_deinit_mon_interface(wl, true);
1650        vif = netdev_priv(wdev->netdev);
1651        cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
1652        unregister_netdevice(vif->ndev);
1653        vif->monitor_flag = 0;
1654
1655        wilc_set_operation_mode(vif, 0, 0, 0);
1656        mutex_lock(&wl->vif_mutex);
1657        list_del_rcu(&vif->list);
1658        wl->vif_num--;
1659        mutex_unlock(&wl->vif_mutex);
1660        synchronize_srcu(&wl->srcu);
1661        return 0;
1662}
1663
1664static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
1665{
1666        struct wilc *wl = wiphy_priv(wiphy);
1667
1668        if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
1669                wl->suspend_event = true;
1670        else
1671                wl->suspend_event = false;
1672
1673        return 0;
1674}
1675
1676static int wilc_resume(struct wiphy *wiphy)
1677{
1678        return 0;
1679}
1680
1681static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
1682{
1683        struct wilc *wl = wiphy_priv(wiphy);
1684        struct wilc_vif *vif;
1685        int srcu_idx;
1686
1687        srcu_idx = srcu_read_lock(&wl->srcu);
1688        vif = wilc_get_wl_to_vif(wl);
1689        if (IS_ERR(vif)) {
1690                srcu_read_unlock(&wl->srcu, srcu_idx);
1691                return;
1692        }
1693
1694        netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
1695        srcu_read_unlock(&wl->srcu, srcu_idx);
1696}
1697
1698static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1699                        enum nl80211_tx_power_setting type, int mbm)
1700{
1701        int ret;
1702        int srcu_idx;
1703        s32 tx_power = MBM_TO_DBM(mbm);
1704        struct wilc *wl = wiphy_priv(wiphy);
1705        struct wilc_vif *vif;
1706
1707        if (!wl->initialized)
1708                return -EIO;
1709
1710        srcu_idx = srcu_read_lock(&wl->srcu);
1711        vif = wilc_get_wl_to_vif(wl);
1712        if (IS_ERR(vif)) {
1713                srcu_read_unlock(&wl->srcu, srcu_idx);
1714                return -EINVAL;
1715        }
1716
1717        netdev_info(vif->ndev, "Setting tx power %d\n", tx_power);
1718        if (tx_power < 0)
1719                tx_power = 0;
1720        else if (tx_power > 18)
1721                tx_power = 18;
1722        ret = wilc_set_tx_power(vif, tx_power);
1723        if (ret)
1724                netdev_err(vif->ndev, "Failed to set tx power\n");
1725        srcu_read_unlock(&wl->srcu, srcu_idx);
1726
1727        return ret;
1728}
1729
1730static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1731                        int *dbm)
1732{
1733        int ret;
1734        struct wilc_vif *vif = netdev_priv(wdev->netdev);
1735        struct wilc *wl = vif->wilc;
1736
1737        /* If firmware is not started, return. */
1738        if (!wl->initialized)
1739                return -EIO;
1740
1741        ret = wilc_get_tx_power(vif, (u8 *)dbm);
1742        if (ret)
1743                netdev_err(vif->ndev, "Failed to get tx power\n");
1744
1745        return ret;
1746}
1747
1748static const struct cfg80211_ops wilc_cfg80211_ops = {
1749        .set_monitor_channel = set_channel,
1750        .scan = scan,
1751        .connect = connect,
1752        .disconnect = disconnect,
1753        .add_key = add_key,
1754        .del_key = del_key,
1755        .get_key = get_key,
1756        .set_default_key = set_default_key,
1757        .add_virtual_intf = add_virtual_intf,
1758        .del_virtual_intf = del_virtual_intf,
1759        .change_virtual_intf = change_virtual_intf,
1760
1761        .start_ap = start_ap,
1762        .change_beacon = change_beacon,
1763        .stop_ap = stop_ap,
1764        .add_station = add_station,
1765        .del_station = del_station,
1766        .change_station = change_station,
1767        .get_station = get_station,
1768        .dump_station = dump_station,
1769        .change_bss = change_bss,
1770        .set_wiphy_params = set_wiphy_params,
1771
1772        .set_pmksa = set_pmksa,
1773        .del_pmksa = del_pmksa,
1774        .flush_pmksa = flush_pmksa,
1775        .remain_on_channel = remain_on_channel,
1776        .cancel_remain_on_channel = cancel_remain_on_channel,
1777        .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
1778        .mgmt_tx = mgmt_tx,
1779        .mgmt_frame_register = wilc_mgmt_frame_register,
1780        .set_power_mgmt = set_power_mgmt,
1781        .set_cqm_rssi_config = set_cqm_rssi_config,
1782
1783        .suspend = wilc_suspend,
1784        .resume = wilc_resume,
1785        .set_wakeup = wilc_set_wakeup,
1786        .set_tx_power = set_tx_power,
1787        .get_tx_power = get_tx_power,
1788
1789};
1790
1791static void wlan_init_locks(struct wilc *wl)
1792{
1793        mutex_init(&wl->hif_cs);
1794        mutex_init(&wl->rxq_cs);
1795        mutex_init(&wl->cfg_cmd_lock);
1796        mutex_init(&wl->vif_mutex);
1797
1798        spin_lock_init(&wl->txq_spinlock);
1799        mutex_init(&wl->txq_add_to_head_cs);
1800
1801        init_completion(&wl->txq_event);
1802        init_completion(&wl->cfg_event);
1803        init_completion(&wl->sync_event);
1804        init_completion(&wl->txq_thread_started);
1805        init_srcu_struct(&wl->srcu);
1806}
1807
1808void wlan_deinit_locks(struct wilc *wilc)
1809{
1810        mutex_destroy(&wilc->hif_cs);
1811        mutex_destroy(&wilc->rxq_cs);
1812        mutex_destroy(&wilc->cfg_cmd_lock);
1813        mutex_destroy(&wilc->txq_add_to_head_cs);
1814        mutex_destroy(&wilc->vif_mutex);
1815        cleanup_srcu_struct(&wilc->srcu);
1816}
1817
1818int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
1819                       const struct wilc_hif_func *ops)
1820{
1821        struct wilc *wl;
1822        struct wilc_vif *vif;
1823        int ret;
1824
1825        wl = wilc_create_wiphy(dev);
1826        if (!wl)
1827                return -EINVAL;
1828
1829        wlan_init_locks(wl);
1830
1831        ret = wilc_wlan_cfg_init(wl);
1832        if (ret)
1833                goto free_wl;
1834
1835        *wilc = wl;
1836        wl->io_type = io_type;
1837        wl->hif_func = ops;
1838        wl->chip_ps_state = WILC_CHIP_WAKEDUP;
1839        INIT_LIST_HEAD(&wl->txq_head.list);
1840        INIT_LIST_HEAD(&wl->rxq_head.list);
1841        INIT_LIST_HEAD(&wl->vif_list);
1842
1843        wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
1844        if (!wl->hif_workqueue) {
1845                ret = -ENOMEM;
1846                goto free_cfg;
1847        }
1848        vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
1849                                   NL80211_IFTYPE_STATION, false);
1850        if (IS_ERR(vif)) {
1851                ret = PTR_ERR(vif);
1852                goto free_hq;
1853        }
1854
1855        return 0;
1856
1857free_hq:
1858        destroy_workqueue(wl->hif_workqueue);
1859
1860free_cfg:
1861        wilc_wlan_cfg_deinit(wl);
1862
1863free_wl:
1864        wlan_deinit_locks(wl);
1865        wiphy_unregister(wl->wiphy);
1866        wiphy_free(wl->wiphy);
1867        return ret;
1868}
1869EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
1870
1871struct wilc *wilc_create_wiphy(struct device *dev)
1872{
1873        struct wiphy *wiphy;
1874        struct wilc *wl;
1875        int ret;
1876
1877        wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
1878        if (!wiphy)
1879                return NULL;
1880
1881        wl = wiphy_priv(wiphy);
1882
1883        memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
1884        memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
1885        wl->band.bitrates = wl->bitrates;
1886        wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
1887        wl->band.channels = wl->channels;
1888        wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
1889
1890        wl->band.ht_cap.ht_supported = 1;
1891        wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
1892        wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
1893        wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
1894        wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1895
1896        wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
1897
1898        wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
1899#ifdef CONFIG_PM
1900        wiphy->wowlan = &wowlan_support;
1901#endif
1902        wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
1903        wiphy->max_scan_ie_len = 1000;
1904        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1905        memcpy(wl->cipher_suites, wilc_cipher_suites,
1906               sizeof(wilc_cipher_suites));
1907        wiphy->cipher_suites = wl->cipher_suites;
1908        wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
1909        wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
1910
1911        wiphy->max_remain_on_channel_duration = 500;
1912        wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1913                                BIT(NL80211_IFTYPE_AP) |
1914                                BIT(NL80211_IFTYPE_MONITOR) |
1915                                BIT(NL80211_IFTYPE_P2P_GO) |
1916                                BIT(NL80211_IFTYPE_P2P_CLIENT);
1917        wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
1918
1919        set_wiphy_dev(wiphy, dev);
1920        wl->wiphy = wiphy;
1921        ret = wiphy_register(wiphy);
1922        if (ret) {
1923                wiphy_free(wiphy);
1924                return NULL;
1925        }
1926        return wl;
1927}
1928
1929int wilc_init_host_int(struct net_device *net)
1930{
1931        int ret;
1932        struct wilc_vif *vif = netdev_priv(net);
1933        struct wilc_priv *priv = &vif->priv;
1934
1935        priv->p2p_listen_state = false;
1936
1937        mutex_init(&priv->scan_req_lock);
1938        ret = wilc_init(net, &priv->hif_drv);
1939        if (ret)
1940                netdev_err(net, "Error while initializing hostinterface\n");
1941
1942        return ret;
1943}
1944
1945void wilc_deinit_host_int(struct net_device *net)
1946{
1947        int ret;
1948        struct wilc_vif *vif = netdev_priv(net);
1949        struct wilc_priv *priv = &vif->priv;
1950
1951        priv->p2p_listen_state = false;
1952
1953        flush_workqueue(vif->wilc->hif_workqueue);
1954        mutex_destroy(&priv->scan_req_lock);
1955        ret = wilc_deinit(vif);
1956
1957        if (ret)
1958                netdev_err(net, "Error while deinitializing host interface\n");
1959}
1960
1961