linux/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include "wilc_wfi_cfgoperations.h"
   3#include "host_interface.h"
   4#include <linux/errno.h>
   5
   6#define NO_ENCRYPT              0
   7#define ENCRYPT_ENABLED         BIT(0)
   8#define WEP                     BIT(1)
   9#define WEP_EXTENDED            BIT(2)
  10#define WPA                     BIT(3)
  11#define WPA2                    BIT(4)
  12#define AES                     BIT(5)
  13#define TKIP                    BIT(6)
  14
  15#define FRAME_TYPE_ID                   0
  16#define ACTION_CAT_ID                   24
  17#define ACTION_SUBTYPE_ID               25
  18#define P2P_PUB_ACTION_SUBTYPE          30
  19
  20#define ACTION_FRAME                    0xd0
  21#define GO_INTENT_ATTR_ID               0x04
  22#define CHANLIST_ATTR_ID                0x0b
  23#define OPERCHAN_ATTR_ID                0x11
  24#define PUB_ACTION_ATTR_ID              0x04
  25#define P2PELEM_ATTR_ID                 0xdd
  26
  27#define GO_NEG_REQ                      0x00
  28#define GO_NEG_RSP                      0x01
  29#define GO_NEG_CONF                     0x02
  30#define P2P_INV_REQ                     0x03
  31#define P2P_INV_RSP                     0x04
  32#define PUBLIC_ACT_VENDORSPEC           0x09
  33#define GAS_INITIAL_REQ                 0x0a
  34#define GAS_INITIAL_RSP                 0x0b
  35
  36#define INVALID_CHANNEL                 0
  37
  38#define nl80211_SCAN_RESULT_EXPIRE      (3 * HZ)
  39#define SCAN_RESULT_EXPIRE              (40 * HZ)
  40
  41static const u32 cipher_suites[] = {
  42        WLAN_CIPHER_SUITE_WEP40,
  43        WLAN_CIPHER_SUITE_WEP104,
  44        WLAN_CIPHER_SUITE_TKIP,
  45        WLAN_CIPHER_SUITE_CCMP,
  46        WLAN_CIPHER_SUITE_AES_CMAC,
  47};
  48
  49static const struct ieee80211_txrx_stypes
  50        wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
  51        [NL80211_IFTYPE_STATION] = {
  52                .tx = 0xffff,
  53                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  54                        BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
  55        },
  56        [NL80211_IFTYPE_AP] = {
  57                .tx = 0xffff,
  58                .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  59                        BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  60                        BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  61                        BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  62                        BIT(IEEE80211_STYPE_AUTH >> 4) |
  63                        BIT(IEEE80211_STYPE_DEAUTH >> 4) |
  64                        BIT(IEEE80211_STYPE_ACTION >> 4)
  65        },
  66        [NL80211_IFTYPE_P2P_CLIENT] = {
  67                .tx = 0xffff,
  68                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
  69                        BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
  70                        BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
  71                        BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
  72                        BIT(IEEE80211_STYPE_DISASSOC >> 4) |
  73                        BIT(IEEE80211_STYPE_AUTH >> 4) |
  74                        BIT(IEEE80211_STYPE_DEAUTH >> 4)
  75        }
  76};
  77
  78static const struct wiphy_wowlan_support wowlan_support = {
  79        .flags = WIPHY_WOWLAN_ANY
  80};
  81
  82#define WILC_WFI_DWELL_PASSIVE 100
  83#define WILC_WFI_DWELL_ACTIVE  40
  84
  85#define TCP_ACK_FILTER_LINK_SPEED_THRESH        54
  86#define DEFAULT_LINK_SPEED                      72
  87
  88#define IS_MANAGMEMENT                          0x100
  89#define IS_MANAGMEMENT_CALLBACK                 0x080
  90#define IS_MGMT_STATUS_SUCCES                   0x040
  91#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
  92
  93static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
  94static u32 last_scanned_cnt;
  95struct timer_list wilc_during_ip_timer;
  96static struct timer_list hAgingTimer;
  97static u8 op_ifcs;
  98
  99#define CHAN2G(_channel, _freq, _flags) {        \
 100                .band             = NL80211_BAND_2GHZ, \
 101                .center_freq      = (_freq),             \
 102                .hw_value         = (_channel),          \
 103                .flags            = (_flags),            \
 104                .max_antenna_gain = 0,                   \
 105                .max_power        = 30,                  \
 106}
 107
 108static struct ieee80211_channel ieee80211_2ghz_channels[] = {
 109        CHAN2G(1,  2412, 0),
 110        CHAN2G(2,  2417, 0),
 111        CHAN2G(3,  2422, 0),
 112        CHAN2G(4,  2427, 0),
 113        CHAN2G(5,  2432, 0),
 114        CHAN2G(6,  2437, 0),
 115        CHAN2G(7,  2442, 0),
 116        CHAN2G(8,  2447, 0),
 117        CHAN2G(9,  2452, 0),
 118        CHAN2G(10, 2457, 0),
 119        CHAN2G(11, 2462, 0),
 120        CHAN2G(12, 2467, 0),
 121        CHAN2G(13, 2472, 0),
 122        CHAN2G(14, 2484, 0),
 123};
 124
 125#define RATETAB_ENT(_rate, _hw_value, _flags) { \
 126                .bitrate  = (_rate),                    \
 127                .hw_value = (_hw_value),                \
 128                .flags    = (_flags),                   \
 129}
 130
 131static struct ieee80211_rate ieee80211_bitrates[] = {
 132        RATETAB_ENT(10,  0,  0),
 133        RATETAB_ENT(20,  1,  0),
 134        RATETAB_ENT(55,  2,  0),
 135        RATETAB_ENT(110, 3,  0),
 136        RATETAB_ENT(60,  9,  0),
 137        RATETAB_ENT(90,  6,  0),
 138        RATETAB_ENT(120, 7,  0),
 139        RATETAB_ENT(180, 8,  0),
 140        RATETAB_ENT(240, 9,  0),
 141        RATETAB_ENT(360, 10, 0),
 142        RATETAB_ENT(480, 11, 0),
 143        RATETAB_ENT(540, 12, 0),
 144};
 145
 146struct p2p_mgmt_data {
 147        int size;
 148        u8 *buff;
 149};
 150
 151static u8 wlan_channel = INVALID_CHANNEL;
 152static u8 curr_channel;
 153static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
 154static u8 p2p_local_random = 0x01;
 155static u8 p2p_recv_random;
 156static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
 157static bool wilc_ie;
 158
 159static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
 160        .channels = ieee80211_2ghz_channels,
 161        .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
 162        .bitrates = ieee80211_bitrates,
 163        .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
 164};
 165
 166struct add_key_params {
 167        u8 key_idx;
 168        bool pairwise;
 169        u8 *mac_addr;
 170};
 171
 172static struct add_key_params g_add_gtk_key_params;
 173static struct wilc_wfi_key g_key_gtk_params;
 174static struct add_key_params g_add_ptk_key_params;
 175static struct wilc_wfi_key g_key_ptk_params;
 176static struct wilc_wfi_wep_key g_key_wep_params;
 177static bool g_ptk_keys_saved;
 178static bool g_gtk_keys_saved;
 179static bool g_wep_keys_saved;
 180
 181#define AGING_TIME      (9 * 1000)
 182#define during_ip_time  15000
 183
 184static void clear_shadow_scan(void)
 185{
 186        int i;
 187
 188        if (op_ifcs == 0) {
 189                del_timer_sync(&hAgingTimer);
 190
 191                for (i = 0; i < last_scanned_cnt; i++) {
 192                        if (last_scanned_shadow[last_scanned_cnt].ies) {
 193                                kfree(last_scanned_shadow[i].ies);
 194                                last_scanned_shadow[last_scanned_cnt].ies = NULL;
 195                        }
 196
 197                        kfree(last_scanned_shadow[i].join_params);
 198                        last_scanned_shadow[i].join_params = NULL;
 199                }
 200                last_scanned_cnt = 0;
 201        }
 202}
 203
 204static u32 get_rssi_avg(struct network_info *network_info)
 205{
 206        u8 i;
 207        int rssi_v = 0;
 208        u8 num_rssi = (network_info->rssi_history.full) ?
 209                       NUM_RSSI : (network_info->rssi_history.index);
 210
 211        for (i = 0; i < num_rssi; i++)
 212                rssi_v += network_info->rssi_history.samples[i];
 213
 214        rssi_v /= num_rssi;
 215        return rssi_v;
 216}
 217
 218static void refresh_scan(struct wilc_priv *priv, bool direct_scan)
 219{
 220        struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy;
 221        int i;
 222
 223        for (i = 0; i < last_scanned_cnt; i++) {
 224                struct network_info *network_info;
 225                s32 freq;
 226                struct ieee80211_channel *channel;
 227                int rssi;
 228                struct cfg80211_bss *bss;
 229
 230                network_info = &last_scanned_shadow[i];
 231
 232                if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan)
 233                        continue;
 234
 235                freq = ieee80211_channel_to_frequency((s32)network_info->ch,
 236                                                      NL80211_BAND_2GHZ);
 237                channel = ieee80211_get_channel(wiphy, freq);
 238                rssi = get_rssi_avg(network_info);
 239                bss = cfg80211_inform_bss(wiphy,
 240                                          channel,
 241                                          CFG80211_BSS_FTYPE_UNKNOWN,
 242                                          network_info->bssid,
 243                                          network_info->tsf_hi,
 244                                          network_info->cap_info,
 245                                          network_info->beacon_period,
 246                                          (const u8 *)network_info->ies,
 247                                          (size_t)network_info->ies_len,
 248                                          (s32)rssi * 100,
 249                                          GFP_KERNEL);
 250                cfg80211_put_bss(wiphy, bss);
 251        }
 252}
 253
 254static void reset_shadow_found(void)
 255{
 256        int i;
 257
 258        for (i = 0; i < last_scanned_cnt; i++)
 259                last_scanned_shadow[i].found = 0;
 260}
 261
 262static void update_scan_time(void)
 263{
 264        int i;
 265
 266        for (i = 0; i < last_scanned_cnt; i++)
 267                last_scanned_shadow[i].time_scan = jiffies;
 268}
 269
 270static void remove_network_from_shadow(unsigned long arg)
 271{
 272        unsigned long now = jiffies;
 273        int i, j;
 274
 275        for (i = 0; i < last_scanned_cnt; i++) {
 276                if (time_after(now, last_scanned_shadow[i].time_scan +
 277                               (unsigned long)(SCAN_RESULT_EXPIRE))) {
 278                        kfree(last_scanned_shadow[i].ies);
 279                        last_scanned_shadow[i].ies = NULL;
 280
 281                        kfree(last_scanned_shadow[i].join_params);
 282
 283                        for (j = i; (j < last_scanned_cnt - 1); j++)
 284                                last_scanned_shadow[j] = last_scanned_shadow[j + 1];
 285
 286                        last_scanned_cnt--;
 287                }
 288        }
 289
 290        if (last_scanned_cnt != 0) {
 291                hAgingTimer.data = arg;
 292                mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
 293        }
 294}
 295
 296static void clear_duringIP(unsigned long arg)
 297{
 298        wilc_optaining_ip = false;
 299}
 300
 301static int is_network_in_shadow(struct network_info *pstrNetworkInfo,
 302                                void *user_void)
 303{
 304        int state = -1;
 305        int i;
 306
 307        if (last_scanned_cnt == 0) {
 308                hAgingTimer.data = (unsigned long)user_void;
 309                mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
 310                state = -1;
 311        } else {
 312                for (i = 0; i < last_scanned_cnt; i++) {
 313                        if (memcmp(last_scanned_shadow[i].bssid,
 314                                   pstrNetworkInfo->bssid, 6) == 0) {
 315                                state = i;
 316                                break;
 317                        }
 318                }
 319        }
 320        return state;
 321}
 322
 323static void add_network_to_shadow(struct network_info *pstrNetworkInfo,
 324                                  void *user_void, void *pJoinParams)
 325{
 326        int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
 327        u32 ap_index = 0;
 328        u8 rssi_index = 0;
 329
 330        if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW)
 331                return;
 332
 333        if (ap_found == -1) {
 334                ap_index = last_scanned_cnt;
 335                last_scanned_cnt++;
 336        } else {
 337                ap_index = ap_found;
 338        }
 339        rssi_index = last_scanned_shadow[ap_index].rssi_history.index;
 340        last_scanned_shadow[ap_index].rssi_history.samples[rssi_index++] = pstrNetworkInfo->rssi;
 341        if (rssi_index == NUM_RSSI) {
 342                rssi_index = 0;
 343                last_scanned_shadow[ap_index].rssi_history.full = true;
 344        }
 345        last_scanned_shadow[ap_index].rssi_history.index = rssi_index;
 346        last_scanned_shadow[ap_index].rssi = pstrNetworkInfo->rssi;
 347        last_scanned_shadow[ap_index].cap_info = pstrNetworkInfo->cap_info;
 348        last_scanned_shadow[ap_index].ssid_len = pstrNetworkInfo->ssid_len;
 349        memcpy(last_scanned_shadow[ap_index].ssid,
 350               pstrNetworkInfo->ssid, pstrNetworkInfo->ssid_len);
 351        memcpy(last_scanned_shadow[ap_index].bssid,
 352               pstrNetworkInfo->bssid, ETH_ALEN);
 353        last_scanned_shadow[ap_index].beacon_period = pstrNetworkInfo->beacon_period;
 354        last_scanned_shadow[ap_index].dtim_period = pstrNetworkInfo->dtim_period;
 355        last_scanned_shadow[ap_index].ch = pstrNetworkInfo->ch;
 356        last_scanned_shadow[ap_index].ies_len = pstrNetworkInfo->ies_len;
 357        last_scanned_shadow[ap_index].tsf_hi = pstrNetworkInfo->tsf_hi;
 358        if (ap_found != -1)
 359                kfree(last_scanned_shadow[ap_index].ies);
 360        last_scanned_shadow[ap_index].ies = kmalloc(pstrNetworkInfo->ies_len,
 361                                                    GFP_KERNEL);
 362        memcpy(last_scanned_shadow[ap_index].ies,
 363               pstrNetworkInfo->ies, pstrNetworkInfo->ies_len);
 364        last_scanned_shadow[ap_index].time_scan = jiffies;
 365        last_scanned_shadow[ap_index].time_scan_cached = jiffies;
 366        last_scanned_shadow[ap_index].found = 1;
 367        if (ap_found != -1)
 368                kfree(last_scanned_shadow[ap_index].join_params);
 369        last_scanned_shadow[ap_index].join_params = pJoinParams;
 370}
 371
 372static void CfgScanResult(enum scan_event scan_event,
 373                          struct network_info *network_info,
 374                          void *user_void,
 375                          void *join_params)
 376{
 377        struct wilc_priv *priv;
 378        struct wiphy *wiphy;
 379        s32 s32Freq;
 380        struct ieee80211_channel *channel;
 381        struct cfg80211_bss *bss = NULL;
 382
 383        priv = user_void;
 384        if (priv->bCfgScanning) {
 385                if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
 386                        wiphy = priv->dev->ieee80211_ptr->wiphy;
 387
 388                        if (!wiphy)
 389                                return;
 390
 391                        if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
 392                            (((s32)network_info->rssi * 100) < 0 ||
 393                            ((s32)network_info->rssi * 100) > 100))
 394                                return;
 395
 396                        if (network_info) {
 397                                s32Freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ);
 398                                channel = ieee80211_get_channel(wiphy, s32Freq);
 399
 400                                if (!channel)
 401                                        return;
 402
 403                                if (network_info->new_network) {
 404                                        if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
 405                                                priv->u32RcvdChCount++;
 406
 407                                                add_network_to_shadow(network_info, priv, join_params);
 408
 409                                                if (!(memcmp("DIRECT-", network_info->ssid, 7))) {
 410                                                        bss = cfg80211_inform_bss(wiphy,
 411                                                                                  channel,
 412                                                                                  CFG80211_BSS_FTYPE_UNKNOWN,
 413                                                                                  network_info->bssid,
 414                                                                                  network_info->tsf_hi,
 415                                                                                  network_info->cap_info,
 416                                                                                  network_info->beacon_period,
 417                                                                                  (const u8 *)network_info->ies,
 418                                                                                  (size_t)network_info->ies_len,
 419                                                                                  (s32)network_info->rssi * 100,
 420                                                                                  GFP_KERNEL);
 421                                                        cfg80211_put_bss(wiphy, bss);
 422                                                }
 423                                        }
 424                                } else {
 425                                        u32 i;
 426
 427                                        for (i = 0; i < priv->u32RcvdChCount; i++) {
 428                                                if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) {
 429                                                        last_scanned_shadow[i].rssi = network_info->rssi;
 430                                                        last_scanned_shadow[i].time_scan = jiffies;
 431                                                        break;
 432                                                }
 433                                        }
 434                                }
 435                        }
 436                } else if (scan_event == SCAN_EVENT_DONE) {
 437                        refresh_scan(priv, false);
 438
 439                        mutex_lock(&priv->scan_req_lock);
 440
 441                        if (priv->pstrScanReq) {
 442                                struct cfg80211_scan_info info = {
 443                                        .aborted = false,
 444                                };
 445
 446                                cfg80211_scan_done(priv->pstrScanReq, &info);
 447                                priv->u32RcvdChCount = 0;
 448                                priv->bCfgScanning = false;
 449                                priv->pstrScanReq = NULL;
 450                        }
 451                        mutex_unlock(&priv->scan_req_lock);
 452                } else if (scan_event == SCAN_EVENT_ABORTED) {
 453                        mutex_lock(&priv->scan_req_lock);
 454
 455                        if (priv->pstrScanReq) {
 456                                struct cfg80211_scan_info info = {
 457                                        .aborted = false,
 458                                };
 459
 460                                update_scan_time();
 461                                refresh_scan(priv, false);
 462
 463                                cfg80211_scan_done(priv->pstrScanReq, &info);
 464                                priv->bCfgScanning = false;
 465                                priv->pstrScanReq = NULL;
 466                        }
 467                        mutex_unlock(&priv->scan_req_lock);
 468                }
 469        }
 470}
 471
 472int wilc_connecting;
 473
 474static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
 475                             struct connect_info *pstrConnectInfo,
 476                             u8 u8MacStatus,
 477                             struct disconnect_info *pstrDisconnectNotifInfo,
 478                             void *pUserVoid)
 479{
 480        struct wilc_priv *priv;
 481        struct net_device *dev;
 482        struct host_if_drv *pstrWFIDrv;
 483        u8 NullBssid[ETH_ALEN] = {0};
 484        struct wilc *wl;
 485        struct wilc_vif *vif;
 486
 487        wilc_connecting = 0;
 488
 489        priv = pUserVoid;
 490        dev = priv->dev;
 491        vif = netdev_priv(dev);
 492        wl = vif->wilc;
 493        pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
 494
 495        if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
 496                u16 u16ConnectStatus;
 497
 498                u16ConnectStatus = pstrConnectInfo->status;
 499
 500                if ((u8MacStatus == MAC_DISCONNECTED) &&
 501                    (pstrConnectInfo->status == SUCCESSFUL_STATUSCODE)) {
 502                        u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
 503                        wilc_wlan_set_bssid(priv->dev, NullBssid,
 504                                            STATION_MODE);
 505                        eth_zero_addr(wilc_connected_ssid);
 506
 507                        if (!pstrWFIDrv->p2p_connect)
 508                                wlan_channel = INVALID_CHANNEL;
 509
 510                        netdev_err(dev, "Unspecified failure\n");
 511                }
 512
 513                if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
 514                        bool bNeedScanRefresh = false;
 515                        u32 i;
 516
 517                        memcpy(priv->au8AssociatedBss, pstrConnectInfo->bssid, ETH_ALEN);
 518
 519                        for (i = 0; i < last_scanned_cnt; i++) {
 520                                if (memcmp(last_scanned_shadow[i].bssid,
 521                                           pstrConnectInfo->bssid,
 522                                           ETH_ALEN) == 0) {
 523                                        unsigned long now = jiffies;
 524
 525                                        if (time_after(now,
 526                                                       last_scanned_shadow[i].time_scan_cached +
 527                                                       (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ))))
 528                                                bNeedScanRefresh = true;
 529
 530                                        break;
 531                                }
 532                        }
 533
 534                        if (bNeedScanRefresh)
 535                                refresh_scan(priv, true);
 536                }
 537
 538                cfg80211_connect_result(dev, pstrConnectInfo->bssid,
 539                                        pstrConnectInfo->req_ies, pstrConnectInfo->req_ies_len,
 540                                        pstrConnectInfo->resp_ies, pstrConnectInfo->resp_ies_len,
 541                                        u16ConnectStatus, GFP_KERNEL);
 542        } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF)    {
 543                wilc_optaining_ip = false;
 544                p2p_local_random = 0x01;
 545                p2p_recv_random = 0x00;
 546                wilc_ie = false;
 547                eth_zero_addr(priv->au8AssociatedBss);
 548                wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
 549                eth_zero_addr(wilc_connected_ssid);
 550
 551                if (!pstrWFIDrv->p2p_connect)
 552                        wlan_channel = INVALID_CHANNEL;
 553                if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
 554                        pstrDisconnectNotifInfo->reason = 3;
 555                else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev))
 556                        pstrDisconnectNotifInfo->reason = 1;
 557
 558                cfg80211_disconnected(dev, pstrDisconnectNotifInfo->reason, pstrDisconnectNotifInfo->ie,
 559                                      pstrDisconnectNotifInfo->ie_len, false,
 560                                      GFP_KERNEL);
 561        }
 562}
 563
 564static int set_channel(struct wiphy *wiphy,
 565                       struct cfg80211_chan_def *chandef)
 566{
 567        u32 channelnum = 0;
 568        struct wilc_priv *priv;
 569        int result = 0;
 570        struct wilc_vif *vif;
 571
 572        priv = wiphy_priv(wiphy);
 573        vif = netdev_priv(priv->dev);
 574
 575        channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
 576
 577        curr_channel = channelnum;
 578        result = wilc_set_mac_chnl_num(vif, channelnum);
 579
 580        if (result != 0)
 581                netdev_err(priv->dev, "Error in setting channel\n");
 582
 583        return result;
 584}
 585
 586static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 587{
 588        struct wilc_priv *priv;
 589        u32 i;
 590        s32 s32Error = 0;
 591        u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
 592        struct hidden_network strHiddenNetwork;
 593        struct wilc_vif *vif;
 594
 595        priv = wiphy_priv(wiphy);
 596        vif = netdev_priv(priv->dev);
 597
 598        priv->pstrScanReq = request;
 599
 600        priv->u32RcvdChCount = 0;
 601
 602        reset_shadow_found();
 603
 604        priv->bCfgScanning = true;
 605        if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
 606                for (i = 0; i < request->n_channels; i++)
 607                        au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
 608
 609                if (request->n_ssids >= 1) {
 610                        strHiddenNetwork.net_info =
 611                                kmalloc_array(request->n_ssids,
 612                                              sizeof(struct hidden_network),
 613                                              GFP_KERNEL);
 614                        if (!strHiddenNetwork.net_info)
 615                                return -ENOMEM;
 616                        strHiddenNetwork.n_ssids = request->n_ssids;
 617
 618                        for (i = 0; i < request->n_ssids; i++) {
 619                                if (request->ssids[i].ssid_len != 0) {
 620                                        strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
 621                                        memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
 622                                        strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
 623                                } else {
 624                                        strHiddenNetwork.n_ssids -= 1;
 625                                }
 626                        }
 627                        s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
 628                                             au8ScanChanList,
 629                                             request->n_channels,
 630                                             (const u8 *)request->ie,
 631                                             request->ie_len, CfgScanResult,
 632                                             (void *)priv, &strHiddenNetwork);
 633                } else {
 634                        s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
 635                                             au8ScanChanList,
 636                                             request->n_channels,
 637                                             (const u8 *)request->ie,
 638                                             request->ie_len, CfgScanResult,
 639                                             (void *)priv, NULL);
 640                }
 641        } else {
 642                netdev_err(priv->dev, "Requested scanned channels over\n");
 643        }
 644
 645        if (s32Error != 0)
 646                s32Error = -EBUSY;
 647
 648        return s32Error;
 649}
 650
 651static int connect(struct wiphy *wiphy, struct net_device *dev,
 652                   struct cfg80211_connect_params *sme)
 653{
 654        s32 s32Error = 0;
 655        u32 i;
 656        u32 sel_bssi_idx = UINT_MAX;
 657        u8 u8security = NO_ENCRYPT;
 658        enum AUTHTYPE tenuAuth_type = ANY;
 659
 660        struct wilc_priv *priv;
 661        struct host_if_drv *pstrWFIDrv;
 662        struct network_info *pstrNetworkInfo = NULL;
 663        struct wilc_vif *vif;
 664
 665        wilc_connecting = 1;
 666        priv = wiphy_priv(wiphy);
 667        vif = netdev_priv(priv->dev);
 668        pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
 669
 670        if (!(strncmp(sme->ssid, "DIRECT-", 7)))
 671                pstrWFIDrv->p2p_connect = 1;
 672        else
 673                pstrWFIDrv->p2p_connect = 0;
 674
 675        for (i = 0; i < last_scanned_cnt; i++) {
 676                if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) &&
 677                    memcmp(last_scanned_shadow[i].ssid,
 678                           sme->ssid,
 679                           sme->ssid_len) == 0) {
 680                        if (!sme->bssid) {
 681                                if (sel_bssi_idx == UINT_MAX ||
 682                                    last_scanned_shadow[i].rssi >
 683                                    last_scanned_shadow[sel_bssi_idx].rssi)
 684                                        sel_bssi_idx = i;
 685                        } else {
 686                                if (memcmp(last_scanned_shadow[i].bssid,
 687                                           sme->bssid,
 688                                           ETH_ALEN) == 0) {
 689                                        sel_bssi_idx = i;
 690                                        break;
 691                                }
 692                        }
 693                }
 694        }
 695
 696        if (sel_bssi_idx < last_scanned_cnt) {
 697                pstrNetworkInfo = &last_scanned_shadow[sel_bssi_idx];
 698        } else {
 699                s32Error = -ENOENT;
 700                wilc_connecting = 0;
 701                return s32Error;
 702        }
 703
 704        memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
 705        memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
 706
 707        if (sme->crypto.cipher_group != NO_ENCRYPT) {
 708                if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
 709                        u8security = ENCRYPT_ENABLED | WEP;
 710
 711                        priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
 712                        memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
 713
 714                        g_key_wep_params.key_len = sme->key_len;
 715                        g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
 716                        memcpy(g_key_wep_params.key, sme->key, sme->key_len);
 717                        g_key_wep_params.key_idx = sme->key_idx;
 718                        g_wep_keys_saved = true;
 719
 720                        wilc_set_wep_default_keyid(vif, sme->key_idx);
 721                        wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
 722                                                 sme->key_idx);
 723                } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104)   {
 724                        u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
 725
 726                        priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
 727                        memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
 728
 729                        g_key_wep_params.key_len = sme->key_len;
 730                        g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
 731                        memcpy(g_key_wep_params.key, sme->key, sme->key_len);
 732                        g_key_wep_params.key_idx = sme->key_idx;
 733                        g_wep_keys_saved = true;
 734
 735                        wilc_set_wep_default_keyid(vif, sme->key_idx);
 736                        wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
 737                                                 sme->key_idx);
 738                } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)   {
 739                        if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
 740                                u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
 741                        else
 742                                u8security = ENCRYPT_ENABLED | WPA2 | AES;
 743                } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)   {
 744                        if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP)
 745                                u8security = ENCRYPT_ENABLED | WPA | TKIP;
 746                        else
 747                                u8security = ENCRYPT_ENABLED | WPA | AES;
 748                } else {
 749                        s32Error = -ENOTSUPP;
 750                        netdev_err(dev, "Not supported cipher\n");
 751                        wilc_connecting = 0;
 752                        return s32Error;
 753                }
 754        }
 755
 756        if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) ||
 757            (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
 758                for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
 759                        if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP)
 760                                u8security = u8security | TKIP;
 761                        else
 762                                u8security = u8security | AES;
 763                }
 764        }
 765
 766        switch (sme->auth_type) {
 767        case NL80211_AUTHTYPE_OPEN_SYSTEM:
 768                tenuAuth_type = OPEN_SYSTEM;
 769                break;
 770
 771        case NL80211_AUTHTYPE_SHARED_KEY:
 772                tenuAuth_type = SHARED_KEY;
 773                break;
 774
 775        default:
 776                break;
 777        }
 778
 779        if (sme->crypto.n_akm_suites) {
 780                switch (sme->crypto.akm_suites[0]) {
 781                case WLAN_AKM_SUITE_8021X:
 782                        tenuAuth_type = IEEE8021;
 783                        break;
 784
 785                default:
 786                        break;
 787                }
 788        }
 789
 790        curr_channel = pstrNetworkInfo->ch;
 791
 792        if (!pstrWFIDrv->p2p_connect)
 793                wlan_channel = pstrNetworkInfo->ch;
 794
 795        wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE);
 796
 797        s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid,
 798                                     sme->ssid_len, sme->ie, sme->ie_len,
 799                                     CfgConnectResult, (void *)priv,
 800                                     u8security, tenuAuth_type,
 801                                     pstrNetworkInfo->ch,
 802                                     pstrNetworkInfo->join_params);
 803        if (s32Error != 0) {
 804                netdev_err(dev, "wilc_set_join_req(): Error\n");
 805                s32Error = -ENOENT;
 806                wilc_connecting = 0;
 807                return s32Error;
 808        }
 809
 810        return s32Error;
 811}
 812
 813static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
 814{
 815        s32 s32Error = 0;
 816        struct wilc_priv *priv;
 817        struct host_if_drv *pstrWFIDrv;
 818        struct wilc_vif *vif;
 819        struct wilc *wilc;
 820        u8 NullBssid[ETH_ALEN] = {0};
 821
 822        wilc_connecting = 0;
 823        priv = wiphy_priv(wiphy);
 824        vif = netdev_priv(priv->dev);
 825        wilc = vif->wilc;
 826
 827        if (!wilc)
 828                return -EIO;
 829
 830        if (wilc->close) {
 831                /* already disconnected done */
 832                cfg80211_disconnected(dev, 0, NULL, 0, true, GFP_KERNEL);
 833                return 0;
 834        }
 835
 836        pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
 837        if (!pstrWFIDrv->p2p_connect)
 838                wlan_channel = INVALID_CHANNEL;
 839        wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE);
 840
 841        p2p_local_random = 0x01;
 842        p2p_recv_random = 0x00;
 843        wilc_ie = false;
 844        pstrWFIDrv->p2p_timeout = 0;
 845
 846        s32Error = wilc_disconnect(vif, reason_code);
 847        if (s32Error != 0) {
 848                netdev_err(priv->dev, "Error in disconnecting\n");
 849                s32Error = -EINVAL;
 850        }
 851
 852        return s32Error;
 853}
 854
 855static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
 856                   bool pairwise,
 857                   const u8 *mac_addr, struct key_params *params)
 858
 859{
 860        s32 s32Error = 0, KeyLen = params->key_len;
 861        struct wilc_priv *priv;
 862        const u8 *pu8RxMic = NULL;
 863        const u8 *pu8TxMic = NULL;
 864        u8 u8mode = NO_ENCRYPT;
 865        u8 u8gmode = NO_ENCRYPT;
 866        u8 u8pmode = NO_ENCRYPT;
 867        enum AUTHTYPE tenuAuth_type = ANY;
 868        struct wilc *wl;
 869        struct wilc_vif *vif;
 870
 871        priv = wiphy_priv(wiphy);
 872        vif = netdev_priv(netdev);
 873        wl = vif->wilc;
 874
 875        switch (params->cipher) {
 876        case WLAN_CIPHER_SUITE_WEP40:
 877        case WLAN_CIPHER_SUITE_WEP104:
 878                if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
 879                        priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
 880                        memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
 881
 882                        tenuAuth_type = OPEN_SYSTEM;
 883
 884                        if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
 885                                u8mode = ENCRYPT_ENABLED | WEP;
 886                        else
 887                                u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
 888
 889                        wilc_add_wep_key_bss_ap(vif, params->key,
 890                                                params->key_len, key_index,
 891                                                u8mode, tenuAuth_type);
 892                        break;
 893                }
 894                if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
 895                        priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
 896                        memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
 897
 898                        wilc_add_wep_key_bss_sta(vif, params->key,
 899                                                 params->key_len, key_index);
 900                }
 901
 902                break;
 903
 904        case WLAN_CIPHER_SUITE_TKIP:
 905        case WLAN_CIPHER_SUITE_CCMP:
 906                if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
 907                        if (!priv->wilc_gtk[key_index]) {
 908                                priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
 909                                priv->wilc_gtk[key_index]->key = NULL;
 910                                priv->wilc_gtk[key_index]->seq = NULL;
 911                        }
 912                        if (!priv->wilc_ptk[key_index]) {
 913                                priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
 914                                priv->wilc_ptk[key_index]->key = NULL;
 915                                priv->wilc_ptk[key_index]->seq = NULL;
 916                        }
 917
 918                        if (!pairwise) {
 919                                if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
 920                                        u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
 921                                else
 922                                        u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
 923
 924                                priv->wilc_groupkey = u8gmode;
 925
 926                                if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
 927                                        pu8TxMic = params->key + 24;
 928                                        pu8RxMic = params->key + 16;
 929                                        KeyLen = params->key_len - 16;
 930                                }
 931                                kfree(priv->wilc_gtk[key_index]->key);
 932
 933                                priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
 934                                memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
 935                                kfree(priv->wilc_gtk[key_index]->seq);
 936
 937                                if ((params->seq_len) > 0) {
 938                                        priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
 939                                        memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
 940                                }
 941
 942                                priv->wilc_gtk[key_index]->cipher = params->cipher;
 943                                priv->wilc_gtk[key_index]->key_len = params->key_len;
 944                                priv->wilc_gtk[key_index]->seq_len = params->seq_len;
 945
 946                                wilc_add_rx_gtk(vif, params->key, KeyLen,
 947                                                key_index, params->seq_len,
 948                                                params->seq, pu8RxMic,
 949                                                pu8TxMic, AP_MODE, u8gmode);
 950
 951                        } else {
 952                                if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
 953                                        u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
 954                                else
 955                                        u8pmode = priv->wilc_groupkey | AES;
 956
 957                                if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
 958                                        pu8TxMic = params->key + 24;
 959                                        pu8RxMic = params->key + 16;
 960                                        KeyLen = params->key_len - 16;
 961                                }
 962
 963                                kfree(priv->wilc_ptk[key_index]->key);
 964
 965                                priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
 966
 967                                kfree(priv->wilc_ptk[key_index]->seq);
 968
 969                                if ((params->seq_len) > 0)
 970                                        priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
 971
 972                                memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
 973
 974                                if ((params->seq_len) > 0)
 975                                        memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
 976
 977                                priv->wilc_ptk[key_index]->cipher = params->cipher;
 978                                priv->wilc_ptk[key_index]->key_len = params->key_len;
 979                                priv->wilc_ptk[key_index]->seq_len = params->seq_len;
 980
 981                                wilc_add_ptk(vif, params->key, KeyLen,
 982                                             mac_addr, pu8RxMic, pu8TxMic,
 983                                             AP_MODE, u8pmode, key_index);
 984                        }
 985                        break;
 986                }
 987
 988                {
 989                        u8mode = 0;
 990                        if (!pairwise) {
 991                                if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
 992                                        pu8RxMic = params->key + 24;
 993                                        pu8TxMic = params->key + 16;
 994                                        KeyLen = params->key_len - 16;
 995                                }
 996
 997                                if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
 998                                        g_add_gtk_key_params.key_idx = key_index;
 999                                        g_add_gtk_key_params.pairwise = pairwise;
1000                                        if (!mac_addr) {
1001                                                g_add_gtk_key_params.mac_addr = NULL;
1002                                        } else {
1003                                                g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1004                                                memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1005                                        }
1006                                        g_key_gtk_params.key_len = params->key_len;
1007                                        g_key_gtk_params.seq_len = params->seq_len;
1008                                        g_key_gtk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
1009                                        memcpy(g_key_gtk_params.key, params->key, params->key_len);
1010                                        if (params->seq_len > 0) {
1011                                                g_key_gtk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
1012                                                memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1013                                        }
1014                                        g_key_gtk_params.cipher = params->cipher;
1015                                        g_gtk_keys_saved = true;
1016                                }
1017
1018                                wilc_add_rx_gtk(vif, params->key, KeyLen,
1019                                                key_index, params->seq_len,
1020                                                params->seq, pu8RxMic,
1021                                                pu8TxMic, STATION_MODE,
1022                                                u8mode);
1023                        } else {
1024                                if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1025                                        pu8RxMic = params->key + 24;
1026                                        pu8TxMic = params->key + 16;
1027                                        KeyLen = params->key_len - 16;
1028                                }
1029
1030                                if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
1031                                        g_add_ptk_key_params.key_idx = key_index;
1032                                        g_add_ptk_key_params.pairwise = pairwise;
1033                                        if (!mac_addr) {
1034                                                g_add_ptk_key_params.mac_addr = NULL;
1035                                        } else {
1036                                                g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
1037                                                memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1038                                        }
1039                                        g_key_ptk_params.key_len = params->key_len;
1040                                        g_key_ptk_params.seq_len = params->seq_len;
1041                                        g_key_ptk_params.key =  kmalloc(params->key_len, GFP_KERNEL);
1042                                        memcpy(g_key_ptk_params.key, params->key, params->key_len);
1043                                        if (params->seq_len > 0) {
1044                                                g_key_ptk_params.seq =  kmalloc(params->seq_len, GFP_KERNEL);
1045                                                memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1046                                        }
1047                                        g_key_ptk_params.cipher = params->cipher;
1048                                        g_ptk_keys_saved = true;
1049                                }
1050
1051                                wilc_add_ptk(vif, params->key, KeyLen,
1052                                             mac_addr, pu8RxMic, pu8TxMic,
1053                                             STATION_MODE, u8mode, key_index);
1054                        }
1055                }
1056                break;
1057
1058        default:
1059                netdev_err(netdev, "Not supported cipher\n");
1060                s32Error = -ENOTSUPP;
1061        }
1062
1063        return s32Error;
1064}
1065
1066static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1067                   u8 key_index,
1068                   bool pairwise,
1069                   const u8 *mac_addr)
1070{
1071        struct wilc_priv *priv;
1072        struct wilc *wl;
1073        struct wilc_vif *vif;
1074
1075        priv = wiphy_priv(wiphy);
1076        vif = netdev_priv(netdev);
1077        wl = vif->wilc;
1078
1079        if (netdev == wl->vif[0]->ndev) {
1080                g_ptk_keys_saved = false;
1081                g_gtk_keys_saved = false;
1082                g_wep_keys_saved = false;
1083
1084                kfree(g_key_wep_params.key);
1085                g_key_wep_params.key = NULL;
1086
1087                if ((priv->wilc_gtk[key_index]) != NULL) {
1088                        kfree(priv->wilc_gtk[key_index]->key);
1089                        priv->wilc_gtk[key_index]->key = NULL;
1090                        kfree(priv->wilc_gtk[key_index]->seq);
1091                        priv->wilc_gtk[key_index]->seq = NULL;
1092
1093                        kfree(priv->wilc_gtk[key_index]);
1094                        priv->wilc_gtk[key_index] = NULL;
1095                }
1096
1097                if ((priv->wilc_ptk[key_index]) != NULL) {
1098                        kfree(priv->wilc_ptk[key_index]->key);
1099                        priv->wilc_ptk[key_index]->key = NULL;
1100                        kfree(priv->wilc_ptk[key_index]->seq);
1101                        priv->wilc_ptk[key_index]->seq = NULL;
1102                        kfree(priv->wilc_ptk[key_index]);
1103                        priv->wilc_ptk[key_index] = NULL;
1104                }
1105
1106                kfree(g_key_ptk_params.key);
1107                g_key_ptk_params.key = NULL;
1108                kfree(g_key_ptk_params.seq);
1109                g_key_ptk_params.seq = NULL;
1110
1111                kfree(g_key_gtk_params.key);
1112                g_key_gtk_params.key = NULL;
1113                kfree(g_key_gtk_params.seq);
1114                g_key_gtk_params.seq = NULL;
1115
1116        }
1117
1118        if (key_index >= 0 && key_index <= 3) {
1119                if (priv->WILC_WFI_wep_key_len[key_index]) {
1120                        memset(priv->WILC_WFI_wep_key[key_index], 0,
1121                               priv->WILC_WFI_wep_key_len[key_index]);
1122                        priv->WILC_WFI_wep_key_len[key_index] = 0;
1123                        wilc_remove_wep_key(vif, key_index);
1124                }
1125        } else {
1126                wilc_remove_key(priv->hif_drv, mac_addr);
1127        }
1128
1129        return 0;
1130}
1131
1132static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1133                   bool pairwise,
1134                   const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
1135{
1136        struct wilc_priv *priv;
1137        struct  key_params key_params;
1138
1139        priv = wiphy_priv(wiphy);
1140
1141        if (!pairwise) {
1142                key_params.key = priv->wilc_gtk[key_index]->key;
1143                key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1144                key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1145                key_params.seq = priv->wilc_gtk[key_index]->seq;
1146                key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1147        } else {
1148                key_params.key = priv->wilc_ptk[key_index]->key;
1149                key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1150                key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1151                key_params.seq = priv->wilc_ptk[key_index]->seq;
1152                key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1153        }
1154
1155        callback(cookie, &key_params);
1156
1157        return 0;
1158}
1159
1160static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1161                           bool unicast, bool multicast)
1162{
1163        struct wilc_priv *priv;
1164        struct wilc_vif *vif;
1165
1166        priv = wiphy_priv(wiphy);
1167        vif = netdev_priv(priv->dev);
1168
1169        wilc_set_wep_default_keyid(vif, key_index);
1170
1171        return 0;
1172}
1173
1174static int get_station(struct wiphy *wiphy, struct net_device *dev,
1175                       const u8 *mac, struct station_info *sinfo)
1176{
1177        struct wilc_priv *priv;
1178        struct wilc_vif *vif;
1179        u32 i = 0;
1180        u32 associatedsta = ~0;
1181        u32 inactive_time = 0;
1182
1183        priv = wiphy_priv(wiphy);
1184        vif = netdev_priv(dev);
1185
1186        if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1187                for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1188                        if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1189                                associatedsta = i;
1190                                break;
1191                        }
1192                }
1193
1194                if (associatedsta == ~0) {
1195                        netdev_err(dev, "sta required is not associated\n");
1196                        return -ENOENT;
1197                }
1198
1199                sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
1200
1201                wilc_get_inactive_time(vif, mac, &inactive_time);
1202                sinfo->inactive_time = 1000 * inactive_time;
1203        }
1204
1205        if (vif->iftype == STATION_MODE) {
1206                struct rf_info strStatistics;
1207
1208                wilc_get_statistics(vif, &strStatistics);
1209
1210                sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
1211                                                BIT(NL80211_STA_INFO_RX_PACKETS) |
1212                                                BIT(NL80211_STA_INFO_TX_PACKETS) |
1213                                                BIT(NL80211_STA_INFO_TX_FAILED) |
1214                                                BIT(NL80211_STA_INFO_TX_BITRATE);
1215
1216                sinfo->signal = strStatistics.rssi;
1217                sinfo->rx_packets = strStatistics.rx_cnt;
1218                sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1219                sinfo->tx_failed = strStatistics.tx_fail_cnt;
1220                sinfo->txrate.legacy = strStatistics.link_speed * 10;
1221
1222                if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1223                    (strStatistics.link_speed != DEFAULT_LINK_SPEED))
1224                        wilc_enable_tcp_ack_filter(true);
1225                else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
1226                        wilc_enable_tcp_ack_filter(false);
1227        }
1228        return 0;
1229}
1230
1231static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1232                      struct bss_parameters *params)
1233{
1234        return 0;
1235}
1236
1237static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
1238{
1239        s32 s32Error = 0;
1240        struct cfg_param_attr pstrCfgParamVal;
1241        struct wilc_priv *priv;
1242        struct wilc_vif *vif;
1243
1244        priv = wiphy_priv(wiphy);
1245        vif = netdev_priv(priv->dev);
1246
1247        pstrCfgParamVal.flag = 0;
1248
1249        if (changed & WIPHY_PARAM_RETRY_SHORT) {
1250                pstrCfgParamVal.flag  |= RETRY_SHORT;
1251                pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1252        }
1253        if (changed & WIPHY_PARAM_RETRY_LONG) {
1254                pstrCfgParamVal.flag |= RETRY_LONG;
1255                pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1256        }
1257        if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1258                pstrCfgParamVal.flag |= FRAG_THRESHOLD;
1259                pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1260        }
1261
1262        if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1263                pstrCfgParamVal.flag |= RTS_THRESHOLD;
1264                pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1265        }
1266
1267        s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
1268        if (s32Error)
1269                netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
1270
1271        return s32Error;
1272}
1273
1274static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1275                     struct cfg80211_pmksa *pmksa)
1276{
1277        u32 i;
1278        s32 s32Error = 0;
1279        u8 flag = 0;
1280        struct wilc_vif *vif;
1281        struct wilc_priv *priv = wiphy_priv(wiphy);
1282
1283        vif = netdev_priv(priv->dev);
1284
1285        for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1286                if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1287                            ETH_ALEN)) {
1288                        flag = PMKID_FOUND;
1289                        break;
1290                }
1291        }
1292        if (i < WILC_MAX_NUM_PMKIDS) {
1293                memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
1294                       ETH_ALEN);
1295                memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
1296                       PMKID_LEN);
1297                if (!(flag == PMKID_FOUND))
1298                        priv->pmkid_list.numpmkid++;
1299        } else {
1300                netdev_err(netdev, "Invalid PMKID index\n");
1301                s32Error = -EINVAL;
1302        }
1303
1304        if (!s32Error)
1305                s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
1306
1307        return s32Error;
1308}
1309
1310static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1311                     struct cfg80211_pmksa *pmksa)
1312{
1313        u32 i;
1314        s32 s32Error = 0;
1315
1316        struct wilc_priv *priv = wiphy_priv(wiphy);
1317
1318        for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
1319                if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
1320                            ETH_ALEN)) {
1321                        memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
1322                        break;
1323                }
1324        }
1325
1326        if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1327                for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
1328                        memcpy(priv->pmkid_list.pmkidlist[i].bssid,
1329                               priv->pmkid_list.pmkidlist[i + 1].bssid,
1330                               ETH_ALEN);
1331                        memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
1332                               priv->pmkid_list.pmkidlist[i + 1].pmkid,
1333                               PMKID_LEN);
1334                }
1335                priv->pmkid_list.numpmkid--;
1336        } else {
1337                s32Error = -EINVAL;
1338        }
1339
1340        return s32Error;
1341}
1342
1343static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1344{
1345        struct wilc_priv *priv = wiphy_priv(wiphy);
1346
1347        memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
1348
1349        return 0;
1350}
1351
1352static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
1353{
1354        u32 index = 0;
1355        u32 i = 0, j = 0;
1356
1357        u8 op_channel_attr_index = 0;
1358        u8 channel_list_attr_index = 0;
1359
1360        while (index < len) {
1361                if (buf[index] == GO_INTENT_ATTR_ID)
1362                        buf[index + 3] = (buf[index + 3]  & 0x01) | (0x00 << 1);
1363
1364                if (buf[index] ==  CHANLIST_ATTR_ID)
1365                        channel_list_attr_index = index;
1366                else if (buf[index] ==  OPERCHAN_ATTR_ID)
1367                        op_channel_attr_index = index;
1368                index += buf[index + 1] + 3;
1369        }
1370        if (wlan_channel != INVALID_CHANNEL) {
1371                if (channel_list_attr_index) {
1372                        for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1373                                if (buf[i] == 0x51) {
1374                                        for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1375                                                buf[j] = wlan_channel;
1376                                        break;
1377                                }
1378                        }
1379                }
1380
1381                if (op_channel_attr_index) {
1382                        buf[op_channel_attr_index + 6] = 0x51;
1383                        buf[op_channel_attr_index + 7] = wlan_channel;
1384                }
1385        }
1386}
1387
1388static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
1389{
1390        u32 index = 0;
1391        u32 i = 0, j = 0;
1392
1393        u8 op_channel_attr_index = 0;
1394        u8 channel_list_attr_index = 0;
1395
1396        while (index < len) {
1397                if (buf[index] == GO_INTENT_ATTR_ID) {
1398                        buf[index + 3] = (buf[index + 3]  & 0x01) | (0x0f << 1);
1399
1400                        break;
1401                }
1402
1403                if (buf[index] ==  CHANLIST_ATTR_ID)
1404                        channel_list_attr_index = index;
1405                else if (buf[index] ==  OPERCHAN_ATTR_ID)
1406                        op_channel_attr_index = index;
1407                index += buf[index + 1] + 3;
1408        }
1409        if (wlan_channel != INVALID_CHANNEL && bOperChan) {
1410                if (channel_list_attr_index) {
1411                        for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1412                                if (buf[i] == 0x51) {
1413                                        for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++)
1414                                                buf[j] = wlan_channel;
1415                                        break;
1416                                }
1417                        }
1418                }
1419
1420                if (op_channel_attr_index) {
1421                        buf[op_channel_attr_index + 6] = 0x51;
1422                        buf[op_channel_attr_index + 7] = wlan_channel;
1423                }
1424        }
1425}
1426
1427void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
1428{
1429        struct wilc_priv *priv;
1430        u32 header, pkt_offset;
1431        struct host_if_drv *pstrWFIDrv;
1432        u32 i = 0;
1433        s32 s32Freq;
1434
1435        priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
1436        pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1437
1438        memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
1439
1440        pkt_offset = GET_PKT_OFFSET(header);
1441
1442        if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1443                if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1444                        cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1445                        return;
1446                } else {
1447                        if (pkt_offset & IS_MGMT_STATUS_SUCCES)
1448                                cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
1449                        else
1450                                cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
1451                        return;
1452                }
1453        } else {
1454                s32Freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ);
1455
1456                if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1457                        if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
1458                                netdev_dbg(dev, "Receiving action wrong ch\n");
1459                                return;
1460                        }
1461                        if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1462                                switch (buff[ACTION_SUBTYPE_ID]) {
1463                                case GAS_INITIAL_REQ:
1464                                        break;
1465
1466                                case GAS_INITIAL_RSP:
1467                                        break;
1468
1469                                case PUBLIC_ACT_VENDORSPEC:
1470                                        if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
1471                                                if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1472                                                        if (!wilc_ie) {
1473                                                                for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
1474                                                                        if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
1475                                                                                p2p_recv_random = buff[i + 6];
1476                                                                                wilc_ie = true;
1477                                                                                break;
1478                                                                        }
1479                                                                }
1480                                                        }
1481                                                }
1482                                                if (p2p_local_random > p2p_recv_random) {
1483                                                        if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP ||
1484                                                             buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1485                                                                for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
1486                                                                        if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
1487                                                                                WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1488                                                                                break;
1489                                                                        }
1490                                                                }
1491                                                        }
1492                                                } else {
1493                                                        netdev_dbg(dev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
1494                                                }
1495                                        }
1496
1497                                        if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (wilc_ie))    {
1498                                                cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
1499                                                return;
1500                                        }
1501                                        break;
1502
1503                                default:
1504                                        netdev_dbg(dev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1505                                        break;
1506                                }
1507                        }
1508                }
1509
1510                cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size, 0);
1511        }
1512}
1513
1514static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1515{
1516        struct p2p_mgmt_data *pv_data = priv;
1517
1518        kfree(pv_data->buff);
1519        kfree(pv_data);
1520}
1521
1522static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1523{
1524        struct wilc_priv *priv;
1525
1526        priv = pUserVoid;
1527
1528        priv->bInP2PlistenState = true;
1529
1530        cfg80211_ready_on_channel(priv->wdev,
1531                                  priv->strRemainOnChanParams.u64ListenCookie,
1532                                  priv->strRemainOnChanParams.pstrListenChan,
1533                                  priv->strRemainOnChanParams.u32ListenDuration,
1534                                  GFP_KERNEL);
1535}
1536
1537static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
1538{
1539        struct wilc_priv *priv;
1540
1541        priv = pUserVoid;
1542
1543        if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
1544                priv->bInP2PlistenState = false;
1545
1546                cfg80211_remain_on_channel_expired(priv->wdev,
1547                                                   priv->strRemainOnChanParams.u64ListenCookie,
1548                                                   priv->strRemainOnChanParams.pstrListenChan,
1549                                                   GFP_KERNEL);
1550        }
1551}
1552
1553static int remain_on_channel(struct wiphy *wiphy,
1554                             struct wireless_dev *wdev,
1555                             struct ieee80211_channel *chan,
1556                             unsigned int duration, u64 *cookie)
1557{
1558        s32 s32Error = 0;
1559        struct wilc_priv *priv;
1560        struct wilc_vif *vif;
1561
1562        priv = wiphy_priv(wiphy);
1563        vif = netdev_priv(priv->dev);
1564
1565        if (wdev->iftype == NL80211_IFTYPE_AP) {
1566                netdev_dbg(vif->ndev, "Required while in AP mode\n");
1567                return s32Error;
1568        }
1569
1570        curr_channel = chan->hw_value;
1571
1572        priv->strRemainOnChanParams.pstrListenChan = chan;
1573        priv->strRemainOnChanParams.u64ListenCookie = *cookie;
1574        priv->strRemainOnChanParams.u32ListenDuration = duration;
1575        priv->strRemainOnChanParams.u32ListenSessionID++;
1576
1577        return wilc_remain_on_channel(vif,
1578                                priv->strRemainOnChanParams.u32ListenSessionID,
1579                                duration, chan->hw_value,
1580                                WILC_WFI_RemainOnChannelExpired,
1581                                WILC_WFI_RemainOnChannelReady, (void *)priv);
1582}
1583
1584static int cancel_remain_on_channel(struct wiphy *wiphy,
1585                                    struct wireless_dev *wdev,
1586                                    u64 cookie)
1587{
1588        struct wilc_priv *priv;
1589        struct wilc_vif *vif;
1590
1591        priv = wiphy_priv(wiphy);
1592        vif = netdev_priv(priv->dev);
1593
1594        return wilc_listen_state_expired(vif,
1595                        priv->strRemainOnChanParams.u32ListenSessionID);
1596}
1597
1598static int mgmt_tx(struct wiphy *wiphy,
1599                   struct wireless_dev *wdev,
1600                   struct cfg80211_mgmt_tx_params *params,
1601                   u64 *cookie)
1602{
1603        struct ieee80211_channel *chan = params->chan;
1604        unsigned int wait = params->wait;
1605        const u8 *buf = params->buf;
1606        size_t len = params->len;
1607        const struct ieee80211_mgmt *mgmt;
1608        struct p2p_mgmt_data *mgmt_tx;
1609        struct wilc_priv *priv;
1610        struct host_if_drv *pstrWFIDrv;
1611        u32 i;
1612        struct wilc_vif *vif;
1613        u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
1614
1615        vif = netdev_priv(wdev->netdev);
1616        priv = wiphy_priv(wiphy);
1617        pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1618
1619        *cookie = (unsigned long)buf;
1620        priv->u64tx_cookie = *cookie;
1621        mgmt = (const struct ieee80211_mgmt *) buf;
1622
1623        if (ieee80211_is_mgmt(mgmt->frame_control)) {
1624                mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
1625                if (!mgmt_tx)
1626                        return -EFAULT;
1627
1628                mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
1629                if (!mgmt_tx->buff) {
1630                        kfree(mgmt_tx);
1631                        return -ENOMEM;
1632                }
1633
1634                memcpy(mgmt_tx->buff, buf, len);
1635                mgmt_tx->size = len;
1636
1637                if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1638                        wilc_set_mac_chnl_num(vif, chan->hw_value);
1639                        curr_channel = chan->hw_value;
1640                } else if (ieee80211_is_action(mgmt->frame_control))   {
1641                        if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1642                                if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1643                                    buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1644                                        wilc_set_mac_chnl_num(vif,
1645                                                              chan->hw_value);
1646                                        curr_channel = chan->hw_value;
1647                                }
1648                                switch (buf[ACTION_SUBTYPE_ID]) {
1649                                case GAS_INITIAL_REQ:
1650                                        break;
1651
1652                                case GAS_INITIAL_RSP:
1653                                        break;
1654
1655                                case PUBLIC_ACT_VENDORSPEC:
1656                                {
1657                                        if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
1658                                                if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
1659                                                        if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
1660                                                                get_random_bytes(&p2p_local_random, 1);
1661                                                                p2p_local_random++;
1662                                                        }
1663                                                }
1664
1665                                                if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP ||
1666                                                     buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1667                                                        if (p2p_local_random > p2p_recv_random) {
1668                                                                for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
1669                                                                        if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
1670                                                                                if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
1671                                                                                        WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
1672                                                                                else
1673                                                                                        WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
1674                                                                                break;
1675                                                                        }
1676                                                                }
1677
1678                                                                if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
1679                                                                        memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1680                                                                        mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
1681                                                                        mgmt_tx->size = buf_len;
1682                                                                }
1683                                                        }
1684                                                }
1685
1686                                        } else {
1687                                                netdev_dbg(vif->ndev, "Not a P2P public action frame\n");
1688                                        }
1689
1690                                        break;
1691                                }
1692
1693                                default:
1694                                {
1695                                        netdev_dbg(vif->ndev, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1696                                        break;
1697                                }
1698                                }
1699                        }
1700
1701                        pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
1702                }
1703
1704                wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1705                                           mgmt_tx->buff, mgmt_tx->size,
1706                                           WILC_WFI_mgmt_tx_complete);
1707        }
1708        return 0;
1709}
1710
1711static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1712                               struct wireless_dev *wdev,
1713                               u64 cookie)
1714{
1715        struct wilc_priv *priv;
1716        struct host_if_drv *pstrWFIDrv;
1717
1718        priv = wiphy_priv(wiphy);
1719        pstrWFIDrv = (struct host_if_drv *)priv->hif_drv;
1720        pstrWFIDrv->p2p_timeout = jiffies;
1721
1722        if (!priv->bInP2PlistenState) {
1723                cfg80211_remain_on_channel_expired(priv->wdev,
1724                                                   priv->strRemainOnChanParams.u64ListenCookie,
1725                                                   priv->strRemainOnChanParams.pstrListenChan,
1726                                                   GFP_KERNEL);
1727        }
1728
1729        return 0;
1730}
1731
1732void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1733                              u16 frame_type, bool reg)
1734{
1735        struct wilc_priv *priv;
1736        struct wilc_vif *vif;
1737        struct wilc *wl;
1738
1739        priv = wiphy_priv(wiphy);
1740        vif = netdev_priv(priv->wdev->netdev);
1741        wl = vif->wilc;
1742
1743        if (!frame_type)
1744                return;
1745
1746        switch (frame_type) {
1747        case PROBE_REQ:
1748        {
1749                vif->frame_reg[0].type = frame_type;
1750                vif->frame_reg[0].reg = reg;
1751        }
1752        break;
1753
1754        case ACTION:
1755        {
1756                vif->frame_reg[1].type = frame_type;
1757                vif->frame_reg[1].reg = reg;
1758        }
1759        break;
1760
1761        default:
1762        {
1763                break;
1764        }
1765        }
1766
1767        if (!wl->initialized)
1768                return;
1769        wilc_frame_register(vif, frame_type, reg);
1770}
1771
1772static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
1773                               s32 rssi_thold, u32 rssi_hyst)
1774{
1775        return 0;
1776}
1777
1778static int dump_station(struct wiphy *wiphy, struct net_device *dev,
1779                        int idx, u8 *mac, struct station_info *sinfo)
1780{
1781        struct wilc_priv *priv;
1782        struct wilc_vif *vif;
1783
1784        if (idx != 0)
1785                return -ENOENT;
1786
1787        priv = wiphy_priv(wiphy);
1788        vif = netdev_priv(priv->dev);
1789
1790        sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1791
1792        wilc_get_rssi(vif, &sinfo->signal);
1793
1794        memcpy(mac, priv->au8AssociatedBss, ETH_ALEN);
1795        return 0;
1796}
1797
1798static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1799                          bool enabled, int timeout)
1800{
1801        struct wilc_priv *priv;
1802        struct wilc_vif *vif;
1803
1804        if (!wiphy)
1805                return -ENOENT;
1806
1807        priv = wiphy_priv(wiphy);
1808        vif = netdev_priv(priv->dev);
1809        if (!priv->hif_drv)
1810                return -EIO;
1811
1812        if (wilc_enable_ps)
1813                wilc_set_power_mgmt(vif, enabled, timeout);
1814
1815        return 0;
1816}
1817
1818static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
1819                               enum nl80211_iftype type, struct vif_params *params)
1820{
1821        struct wilc_priv *priv;
1822        struct wilc_vif *vif;
1823        struct wilc *wl;
1824
1825        vif = netdev_priv(dev);
1826        priv = wiphy_priv(wiphy);
1827        wl = vif->wilc;
1828        p2p_local_random = 0x01;
1829        p2p_recv_random = 0x00;
1830        wilc_ie = false;
1831        wilc_optaining_ip = false;
1832        del_timer(&wilc_during_ip_timer);
1833
1834        switch (type) {
1835        case NL80211_IFTYPE_STATION:
1836                wilc_connecting = 0;
1837                dev->ieee80211_ptr->iftype = type;
1838                priv->wdev->iftype = type;
1839                vif->monitor_flag = 0;
1840                vif->iftype = STATION_MODE;
1841                wilc_set_operation_mode(vif, STATION_MODE);
1842
1843                memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
1844
1845                wilc_enable_ps = true;
1846                wilc_set_power_mgmt(vif, 1, 0);
1847                break;
1848
1849        case NL80211_IFTYPE_P2P_CLIENT:
1850                wilc_connecting = 0;
1851                dev->ieee80211_ptr->iftype = type;
1852                priv->wdev->iftype = type;
1853                vif->monitor_flag = 0;
1854                vif->iftype = CLIENT_MODE;
1855                wilc_set_operation_mode(vif, STATION_MODE);
1856
1857                wilc_enable_ps = false;
1858                wilc_set_power_mgmt(vif, 0, 0);
1859                break;
1860
1861        case NL80211_IFTYPE_AP:
1862                wilc_enable_ps = false;
1863                dev->ieee80211_ptr->iftype = type;
1864                priv->wdev->iftype = type;
1865                vif->iftype = AP_MODE;
1866
1867                if (wl->initialized) {
1868                        wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
1869                                                 0, vif->ifc_id);
1870                        wilc_set_operation_mode(vif, AP_MODE);
1871                        wilc_set_power_mgmt(vif, 0, 0);
1872                }
1873                break;
1874
1875        case NL80211_IFTYPE_P2P_GO:
1876                wilc_optaining_ip = true;
1877                mod_timer(&wilc_during_ip_timer,
1878                          jiffies + msecs_to_jiffies(during_ip_time));
1879                wilc_set_operation_mode(vif, AP_MODE);
1880                dev->ieee80211_ptr->iftype = type;
1881                priv->wdev->iftype = type;
1882                vif->iftype = GO_MODE;
1883
1884                wilc_enable_ps = false;
1885                wilc_set_power_mgmt(vif, 0, 0);
1886                break;
1887
1888        default:
1889                netdev_err(dev, "Unknown interface type= %d\n", type);
1890                return -EINVAL;
1891        }
1892
1893        return 0;
1894}
1895
1896static int start_ap(struct wiphy *wiphy, struct net_device *dev,
1897                    struct cfg80211_ap_settings *settings)
1898{
1899        struct cfg80211_beacon_data *beacon = &(settings->beacon);
1900        struct wilc_priv *priv;
1901        s32 s32Error = 0;
1902        struct wilc *wl;
1903        struct wilc_vif *vif;
1904
1905        priv = wiphy_priv(wiphy);
1906        vif = netdev_priv(dev);
1907        wl = vif->wilc;
1908
1909        s32Error = set_channel(wiphy, &settings->chandef);
1910
1911        if (s32Error != 0)
1912                netdev_err(dev, "Error in setting channel\n");
1913
1914        wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE);
1915        wilc_set_power_mgmt(vif, 0, 0);
1916
1917        return wilc_add_beacon(vif, settings->beacon_interval,
1918                                   settings->dtim_period, beacon->head_len,
1919                                   (u8 *)beacon->head, beacon->tail_len,
1920                                   (u8 *)beacon->tail);
1921}
1922
1923static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
1924                         struct cfg80211_beacon_data *beacon)
1925{
1926        struct wilc_priv *priv;
1927        struct wilc_vif *vif;
1928
1929        priv = wiphy_priv(wiphy);
1930        vif = netdev_priv(priv->dev);
1931
1932        return wilc_add_beacon(vif, 0, 0, beacon->head_len,
1933                                   (u8 *)beacon->head, beacon->tail_len,
1934                                   (u8 *)beacon->tail);
1935}
1936
1937static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
1938{
1939        s32 s32Error = 0;
1940        struct wilc_priv *priv;
1941        struct wilc_vif *vif;
1942        u8 NullBssid[ETH_ALEN] = {0};
1943
1944        if (!wiphy)
1945                return -EFAULT;
1946
1947        priv = wiphy_priv(wiphy);
1948        vif = netdev_priv(priv->dev);
1949
1950        wilc_wlan_set_bssid(dev, NullBssid, AP_MODE);
1951
1952        s32Error = wilc_del_beacon(vif);
1953
1954        if (s32Error)
1955                netdev_err(dev, "Host delete beacon fail\n");
1956
1957        return s32Error;
1958}
1959
1960static int add_station(struct wiphy *wiphy, struct net_device *dev,
1961                       const u8 *mac, struct station_parameters *params)
1962{
1963        s32 s32Error = 0;
1964        struct wilc_priv *priv;
1965        struct add_sta_param strStaParams = { {0} };
1966        struct wilc_vif *vif;
1967
1968        if (!wiphy)
1969                return -EFAULT;
1970
1971        priv = wiphy_priv(wiphy);
1972        vif = netdev_priv(dev);
1973
1974        if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
1975                memcpy(strStaParams.bssid, mac, ETH_ALEN);
1976                memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
1977                strStaParams.aid = params->aid;
1978                strStaParams.rates_len = params->supported_rates_len;
1979                strStaParams.rates = params->supported_rates;
1980
1981                if (!params->ht_capa) {
1982                        strStaParams.ht_supported = false;
1983                } else {
1984                        strStaParams.ht_supported = true;
1985                        strStaParams.ht_capa = *params->ht_capa;
1986                }
1987
1988                strStaParams.flags_mask = params->sta_flags_mask;
1989                strStaParams.flags_set = params->sta_flags_set;
1990
1991                s32Error = wilc_add_station(vif, &strStaParams);
1992                if (s32Error)
1993                        netdev_err(dev, "Host add station fail\n");
1994        }
1995
1996        return s32Error;
1997}
1998
1999static int del_station(struct wiphy *wiphy, struct net_device *dev,
2000                       struct station_del_parameters *params)
2001{
2002        const u8 *mac = params->mac;
2003        s32 s32Error = 0;
2004        struct wilc_priv *priv;
2005        struct wilc_vif *vif;
2006
2007        if (!wiphy)
2008                return -EFAULT;
2009
2010        priv = wiphy_priv(wiphy);
2011        vif = netdev_priv(dev);
2012
2013        if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2014                if (!mac)
2015                        s32Error = wilc_del_allstation(vif,
2016                                     priv->assoc_stainfo.au8Sta_AssociatedBss);
2017
2018                s32Error = wilc_del_station(vif, mac);
2019
2020                if (s32Error)
2021                        netdev_err(dev, "Host delete station fail\n");
2022        }
2023        return s32Error;
2024}
2025
2026static int change_station(struct wiphy *wiphy, struct net_device *dev,
2027                          const u8 *mac, struct station_parameters *params)
2028{
2029        s32 s32Error = 0;
2030        struct wilc_priv *priv;
2031        struct add_sta_param strStaParams = { {0} };
2032        struct wilc_vif *vif;
2033
2034        if (!wiphy)
2035                return -EFAULT;
2036
2037        priv = wiphy_priv(wiphy);
2038        vif = netdev_priv(dev);
2039
2040        if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
2041                memcpy(strStaParams.bssid, mac, ETH_ALEN);
2042                strStaParams.aid = params->aid;
2043                strStaParams.rates_len = params->supported_rates_len;
2044                strStaParams.rates = params->supported_rates;
2045
2046                if (!params->ht_capa) {
2047                        strStaParams.ht_supported = false;
2048                } else {
2049                        strStaParams.ht_supported = true;
2050                        strStaParams.ht_capa = *params->ht_capa;
2051                }
2052
2053                strStaParams.flags_mask = params->sta_flags_mask;
2054                strStaParams.flags_set = params->sta_flags_set;
2055
2056                s32Error = wilc_edit_station(vif, &strStaParams);
2057                if (s32Error)
2058                        netdev_err(dev, "Host edit station fail\n");
2059        }
2060        return s32Error;
2061}
2062
2063static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2064                                             const char *name,
2065                                             unsigned char name_assign_type,
2066                                             enum nl80211_iftype type,
2067                                             struct vif_params *params)
2068{
2069        struct wilc_vif *vif;
2070        struct wilc_priv *priv;
2071        struct net_device *new_ifc = NULL;
2072
2073        priv = wiphy_priv(wiphy);
2074        vif = netdev_priv(priv->wdev->netdev);
2075
2076        if (type == NL80211_IFTYPE_MONITOR) {
2077                new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
2078                if (new_ifc) {
2079                        vif = netdev_priv(priv->wdev->netdev);
2080                        vif->monitor_flag = 1;
2081                }
2082        }
2083        return priv->wdev;
2084}
2085
2086static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2087{
2088        return 0;
2089}
2090
2091static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2092{
2093        struct wilc_priv *priv = wiphy_priv(wiphy);
2094        struct wilc_vif *vif = netdev_priv(priv->dev);
2095
2096        if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
2097                vif->wilc->suspend_event = true;
2098        else
2099                vif->wilc->suspend_event = false;
2100
2101        return 0;
2102}
2103
2104static int wilc_resume(struct wiphy *wiphy)
2105{
2106        struct wilc_priv *priv = wiphy_priv(wiphy);
2107        struct wilc_vif *vif = netdev_priv(priv->dev);
2108
2109        netdev_info(vif->ndev, "cfg resume\n");
2110        return 0;
2111}
2112
2113static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
2114{
2115        struct wilc_priv *priv = wiphy_priv(wiphy);
2116        struct wilc_vif *vif = netdev_priv(priv->dev);
2117
2118        netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
2119}
2120
2121static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2122                        enum nl80211_tx_power_setting type, int mbm)
2123{
2124        int ret;
2125        s32 tx_power = MBM_TO_DBM(mbm);
2126        struct wilc_priv *priv = wiphy_priv(wiphy);
2127        struct wilc_vif *vif = netdev_priv(priv->dev);
2128
2129        if (tx_power < 0)
2130                tx_power = 0;
2131        else if (tx_power > 18)
2132                tx_power = 18;
2133        ret = wilc_set_tx_power(vif, tx_power);
2134        if (ret)
2135                netdev_err(vif->ndev, "Failed to set tx power\n");
2136
2137        return ret;
2138}
2139
2140static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2141                        int *dbm)
2142{
2143        int ret;
2144        struct wilc_priv *priv = wiphy_priv(wiphy);
2145        struct wilc_vif *vif = netdev_priv(priv->dev);
2146        struct wilc *wl;
2147
2148        wl = vif->wilc;
2149
2150        /* If firmware is not started, return. */
2151        if (!wl->initialized)
2152                return -EIO;
2153
2154        ret = wilc_get_tx_power(vif, (u8 *)dbm);
2155        if (ret)
2156                netdev_err(vif->ndev, "Failed to get tx power\n");
2157
2158        return ret;
2159}
2160
2161static const struct cfg80211_ops wilc_cfg80211_ops = {
2162        .set_monitor_channel = set_channel,
2163        .scan = scan,
2164        .connect = connect,
2165        .disconnect = disconnect,
2166        .add_key = add_key,
2167        .del_key = del_key,
2168        .get_key = get_key,
2169        .set_default_key = set_default_key,
2170        .add_virtual_intf = add_virtual_intf,
2171        .del_virtual_intf = del_virtual_intf,
2172        .change_virtual_intf = change_virtual_intf,
2173
2174        .start_ap = start_ap,
2175        .change_beacon = change_beacon,
2176        .stop_ap = stop_ap,
2177        .add_station = add_station,
2178        .del_station = del_station,
2179        .change_station = change_station,
2180        .get_station = get_station,
2181        .dump_station = dump_station,
2182        .change_bss = change_bss,
2183        .set_wiphy_params = set_wiphy_params,
2184
2185        .set_pmksa = set_pmksa,
2186        .del_pmksa = del_pmksa,
2187        .flush_pmksa = flush_pmksa,
2188        .remain_on_channel = remain_on_channel,
2189        .cancel_remain_on_channel = cancel_remain_on_channel,
2190        .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
2191        .mgmt_tx = mgmt_tx,
2192        .mgmt_frame_register = wilc_mgmt_frame_register,
2193        .set_power_mgmt = set_power_mgmt,
2194        .set_cqm_rssi_config = set_cqm_rssi_config,
2195
2196        .suspend = wilc_suspend,
2197        .resume = wilc_resume,
2198        .set_wakeup = wilc_set_wakeup,
2199        .set_tx_power = set_tx_power,
2200        .get_tx_power = get_tx_power,
2201
2202};
2203
2204static struct wireless_dev *WILC_WFI_CfgAlloc(void)
2205{
2206        struct wireless_dev *wdev;
2207
2208        wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2209        if (!wdev)
2210                goto _fail_;
2211
2212        wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
2213        if (!wdev->wiphy)
2214                goto _fail_mem_;
2215
2216        WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2217        WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2218        WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2219        WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2220        WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
2221
2222        wdev->wiphy->bands[NL80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2223
2224        return wdev;
2225
2226_fail_mem_:
2227        kfree(wdev);
2228_fail_:
2229        return NULL;
2230}
2231
2232struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
2233{
2234        struct wilc_priv *priv;
2235        struct wireless_dev *wdev;
2236        s32 s32Error = 0;
2237
2238        wdev = WILC_WFI_CfgAlloc();
2239        if (!wdev) {
2240                netdev_err(net, "wiphy new allocate failed\n");
2241                return NULL;
2242        }
2243
2244        priv = wdev_priv(wdev);
2245        priv->wdev = wdev;
2246        wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
2247#ifdef CONFIG_PM
2248        wdev->wiphy->wowlan = &wowlan_support;
2249#endif
2250        wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2251        wdev->wiphy->max_scan_ie_len = 1000;
2252        wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2253        wdev->wiphy->cipher_suites = cipher_suites;
2254        wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2255        wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
2256
2257        wdev->wiphy->max_remain_on_channel_duration = 500;
2258        wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2259                                        BIT(NL80211_IFTYPE_AP) |
2260                                        BIT(NL80211_IFTYPE_MONITOR) |
2261                                        BIT(NL80211_IFTYPE_P2P_GO) |
2262                                        BIT(NL80211_IFTYPE_P2P_CLIENT);
2263        wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2264        wdev->iftype = NL80211_IFTYPE_STATION;
2265
2266        set_wiphy_dev(wdev->wiphy, dev);
2267
2268        s32Error = wiphy_register(wdev->wiphy);
2269        if (s32Error)
2270                netdev_err(net, "Cannot register wiphy device\n");
2271
2272        priv->dev = net;
2273        return wdev;
2274}
2275
2276int wilc_init_host_int(struct net_device *net)
2277{
2278        int s32Error = 0;
2279
2280        struct wilc_priv *priv;
2281
2282        priv = wdev_priv(net->ieee80211_ptr);
2283        if (op_ifcs == 0) {
2284                setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
2285                setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
2286        }
2287        op_ifcs++;
2288
2289        priv->gbAutoRateAdjusted = false;
2290
2291        priv->bInP2PlistenState = false;
2292
2293        mutex_init(&priv->scan_req_lock);
2294        s32Error = wilc_init(net, &priv->hif_drv);
2295        if (s32Error)
2296                netdev_err(net, "Error while initializing hostinterface\n");
2297
2298        return s32Error;
2299}
2300
2301int wilc_deinit_host_int(struct net_device *net)
2302{
2303        int s32Error = 0;
2304        struct wilc_vif *vif;
2305        struct wilc_priv *priv;
2306
2307        priv = wdev_priv(net->ieee80211_ptr);
2308        vif = netdev_priv(priv->dev);
2309
2310        priv->gbAutoRateAdjusted = false;
2311
2312        priv->bInP2PlistenState = false;
2313
2314        op_ifcs--;
2315
2316        s32Error = wilc_deinit(vif);
2317
2318        clear_shadow_scan();
2319        if (op_ifcs == 0)
2320                del_timer_sync(&wilc_during_ip_timer);
2321
2322        if (s32Error)
2323                netdev_err(net, "Error while deinitializing host interface\n");
2324
2325        return s32Error;
2326}
2327
2328void wilc_free_wiphy(struct net_device *net)
2329{
2330        if (!net)
2331                return;
2332
2333        if (!net->ieee80211_ptr)
2334                return;
2335
2336        if (!net->ieee80211_ptr->wiphy)
2337                return;
2338
2339        wiphy_unregister(net->ieee80211_ptr->wiphy);
2340
2341        wiphy_free(net->ieee80211_ptr->wiphy);
2342        kfree(net->ieee80211_ptr);
2343}
2344