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