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