linux/drivers/staging/wilc1000/host_interface.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/slab.h>
   3#include <linux/time.h>
   4#include <linux/kthread.h>
   5#include <linux/delay.h>
   6#include <linux/completion.h>
   7#include <linux/list.h>
   8#include <linux/workqueue.h>
   9#include "host_interface.h"
  10#include <linux/spinlock.h>
  11#include <linux/errno.h>
  12#include "coreconfigurator.h"
  13#include "wilc_wlan.h"
  14#include "wilc_wlan_if.h"
  15#include <linux/etherdevice.h>
  16#include "wilc_wfi_netdevice.h"
  17
  18#define HOST_IF_MSG_SCAN                        0
  19#define HOST_IF_MSG_CONNECT                     1
  20#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO        2
  21#define HOST_IF_MSG_KEY                         3
  22#define HOST_IF_MSG_RCVD_NTWRK_INFO             4
  23#define HOST_IF_MSG_RCVD_SCAN_COMPLETE          5
  24#define HOST_IF_MSG_CFG_PARAMS                  6
  25#define HOST_IF_MSG_SET_CHANNEL                 7
  26#define HOST_IF_MSG_DISCONNECT                  8
  27#define HOST_IF_MSG_GET_RSSI                    9
  28#define HOST_IF_MSG_ADD_BEACON                  11
  29#define HOST_IF_MSG_DEL_BEACON                  12
  30#define HOST_IF_MSG_ADD_STATION                 13
  31#define HOST_IF_MSG_DEL_STATION                 14
  32#define HOST_IF_MSG_EDIT_STATION                15
  33#define HOST_IF_MSG_SCAN_TIMER_FIRED            16
  34#define HOST_IF_MSG_CONNECT_TIMER_FIRED         17
  35#define HOST_IF_MSG_POWER_MGMT                  18
  36#define HOST_IF_MSG_GET_INACTIVETIME            19
  37#define HOST_IF_MSG_REMAIN_ON_CHAN              20
  38#define HOST_IF_MSG_REGISTER_FRAME              21
  39#define HOST_IF_MSG_LISTEN_TIMER_FIRED          22
  40#define HOST_IF_MSG_SET_WFIDRV_HANDLER          24
  41#define HOST_IF_MSG_GET_MAC_ADDRESS             26
  42#define HOST_IF_MSG_SET_OPERATION_MODE          27
  43#define HOST_IF_MSG_SET_IPADDRESS               28
  44#define HOST_IF_MSG_GET_IPADDRESS               29
  45#define HOST_IF_MSG_GET_STATISTICS              31
  46#define HOST_IF_MSG_SET_MULTICAST_FILTER        32
  47#define HOST_IF_MSG_DEL_BA_SESSION              34
  48#define HOST_IF_MSG_DEL_ALL_STA                 36
  49#define HOST_IF_MSG_SET_TX_POWER                38
  50#define HOST_IF_MSG_GET_TX_POWER                39
  51#define HOST_IF_MSG_EXIT                        100
  52
  53#define HOST_IF_SCAN_TIMEOUT                    4000
  54#define HOST_IF_CONNECT_TIMEOUT                 9500
  55
  56#define BA_SESSION_DEFAULT_BUFFER_SIZE          16
  57#define BA_SESSION_DEFAULT_TIMEOUT              1000
  58#define BLOCK_ACK_REQ_SIZE                      0x14
  59#define FALSE_FRMWR_CHANNEL                     100
  60
  61#define TCP_ACK_FILTER_LINK_SPEED_THRESH        54
  62#define DEFAULT_LINK_SPEED                      72
  63
  64struct host_if_wpa_attr {
  65        u8 *key;
  66        const u8 *mac_addr;
  67        u8 *seq;
  68        u8 seq_len;
  69        u8 index;
  70        u8 key_len;
  71        u8 mode;
  72};
  73
  74struct host_if_wep_attr {
  75        u8 *key;
  76        u8 key_len;
  77        u8 index;
  78        u8 mode;
  79        enum AUTHTYPE auth_type;
  80};
  81
  82union host_if_key_attr {
  83        struct host_if_wep_attr wep;
  84        struct host_if_wpa_attr wpa;
  85        struct host_if_pmkid_attr pmkid;
  86};
  87
  88struct key_attr {
  89        enum KEY_TYPE type;
  90        u8 action;
  91        union host_if_key_attr attr;
  92};
  93
  94struct scan_attr {
  95        u8 src;
  96        u8 type;
  97        u8 *ch_freq_list;
  98        u8 ch_list_len;
  99        u8 *ies;
 100        size_t ies_len;
 101        wilc_scan_result result;
 102        void *arg;
 103        struct hidden_network hidden_network;
 104};
 105
 106struct connect_attr {
 107        u8 *bssid;
 108        u8 *ssid;
 109        size_t ssid_len;
 110        u8 *ies;
 111        size_t ies_len;
 112        u8 security;
 113        wilc_connect_result result;
 114        void *arg;
 115        enum AUTHTYPE auth_type;
 116        u8 ch;
 117        void *params;
 118};
 119
 120struct rcvd_async_info {
 121        u8 *buffer;
 122        u32 len;
 123};
 124
 125struct channel_attr {
 126        u8 set_ch;
 127};
 128
 129struct beacon_attr {
 130        u32 interval;
 131        u32 dtim_period;
 132        u32 head_len;
 133        u8 *head;
 134        u32 tail_len;
 135        u8 *tail;
 136};
 137
 138struct set_multicast {
 139        bool enabled;
 140        u32 cnt;
 141};
 142
 143struct del_all_sta {
 144        u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
 145        u8 assoc_sta;
 146};
 147
 148struct del_sta {
 149        u8 mac_addr[ETH_ALEN];
 150};
 151
 152struct power_mgmt_param {
 153        bool enabled;
 154        u32 timeout;
 155};
 156
 157struct set_ip_addr {
 158        u8 *ip_addr;
 159        u8 idx;
 160};
 161
 162struct sta_inactive_t {
 163        u8 mac[6];
 164};
 165
 166struct tx_power {
 167        u8 tx_pwr;
 168};
 169
 170union message_body {
 171        struct scan_attr scan_info;
 172        struct connect_attr con_info;
 173        struct rcvd_net_info net_info;
 174        struct rcvd_async_info async_info;
 175        struct key_attr key_info;
 176        struct cfg_param_attr cfg_info;
 177        struct channel_attr channel_info;
 178        struct beacon_attr beacon_info;
 179        struct add_sta_param add_sta_info;
 180        struct del_sta del_sta_info;
 181        struct add_sta_param edit_sta_info;
 182        struct power_mgmt_param pwr_mgmt_info;
 183        struct sta_inactive_t mac_info;
 184        struct set_ip_addr ip_info;
 185        struct drv_handler drv;
 186        struct set_multicast multicast_info;
 187        struct op_mode mode;
 188        struct get_mac_addr get_mac_info;
 189        struct ba_session_info session_info;
 190        struct remain_ch remain_on_ch;
 191        struct reg_frame reg_frame;
 192        char *data;
 193        struct del_all_sta del_all_sta_info;
 194        struct tx_power tx_power;
 195};
 196
 197struct host_if_msg {
 198        u16 id;
 199        union message_body body;
 200        struct wilc_vif *vif;
 201        struct work_struct work;
 202};
 203
 204struct join_bss_param {
 205        BSSTYPE_T bss_type;
 206        u8 dtim_period;
 207        u16 beacon_period;
 208        u16 cap_info;
 209        u8 bssid[6];
 210        char ssid[MAX_SSID_LEN];
 211        u8 ssid_len;
 212        u8 supp_rates[MAX_RATES_SUPPORTED + 1];
 213        u8 ht_capable;
 214        u8 wmm_cap;
 215        u8 uapsd_cap;
 216        bool rsn_found;
 217        u8 rsn_grp_policy;
 218        u8 mode_802_11i;
 219        u8 rsn_pcip_policy[3];
 220        u8 rsn_auth_policy[3];
 221        u8 rsn_cap[2];
 222        u32 tsf;
 223        u8 noa_enabled;
 224        u8 opp_enabled;
 225        u8 ct_window;
 226        u8 cnt;
 227        u8 idx;
 228        u8 duration[4];
 229        u8 interval[4];
 230        u8 start_time[4];
 231};
 232
 233static struct host_if_drv *terminated_handle;
 234bool wilc_optaining_ip;
 235static u8 P2P_LISTEN_STATE;
 236static struct workqueue_struct *hif_workqueue;
 237static struct completion hif_thread_comp;
 238static struct completion hif_driver_comp;
 239static struct completion hif_wait_response;
 240static struct mutex hif_deinit_lock;
 241static struct timer_list periodic_rssi;
 242
 243u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
 244
 245static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
 246
 247static bool scan_while_connected;
 248
 249static s8 rssi;
 250static u8 set_ip[2][4];
 251static u8 get_ip[2][4];
 252static u32 inactive_time;
 253static u8 del_beacon;
 254static u32 clients_count;
 255
 256static u8 *join_req;
 257static u8 *info_element;
 258static u8 mode_11i;
 259static u8 auth_type;
 260static u32 join_req_size;
 261static u32 info_element_size;
 262static struct wilc_vif *join_req_vif;
 263#define REAL_JOIN_REQ 0
 264#define FLUSHED_JOIN_REQ 1
 265#define FLUSHED_BYTE_POS 79
 266
 267static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
 268static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
 269static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
 270static void host_if_work(struct work_struct *work);
 271
 272/*!
 273 *  @author             syounan
 274 *  @date               1 Sep 2010
 275 *  @note               copied from FLO glue implementatuion
 276 *  @version            1.0
 277 */
 278static int wilc_enqueue_cmd(struct host_if_msg *msg)
 279{
 280        struct host_if_msg *new_msg;
 281
 282        new_msg = kmemdup(msg, sizeof(*new_msg), GFP_ATOMIC);
 283        if (!new_msg)
 284                return -ENOMEM;
 285
 286        INIT_WORK(&new_msg->work, host_if_work);
 287        queue_work(hif_workqueue, &new_msg->work);
 288        return 0;
 289}
 290
 291/* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
 292 * special purpose in wilc device, so we add 1 to the index to starts from 1.
 293 * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
 294 */
 295int wilc_get_vif_idx(struct wilc_vif *vif)
 296{
 297        return vif->idx + 1;
 298}
 299
 300/* We need to minus 1 from idx which is from wilc device to get real index
 301 * of wilc->vif[], because we add 1 when pass to wilc device in the function
 302 * wilc_get_vif_idx.
 303 * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
 304 */
 305static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
 306{
 307        int index = idx - 1;
 308
 309        if (index < 0 || index >= NUM_CONCURRENT_IFC)
 310                return NULL;
 311
 312        return wilc->vif[index];
 313}
 314
 315static void handle_set_channel(struct wilc_vif *vif,
 316                               struct channel_attr *hif_set_ch)
 317{
 318        int ret = 0;
 319        struct wid wid;
 320
 321        wid.id = (u16)WID_CURRENT_CHANNEL;
 322        wid.type = WID_CHAR;
 323        wid.val = (char *)&hif_set_ch->set_ch;
 324        wid.size = sizeof(char);
 325
 326        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 327                                   wilc_get_vif_idx(vif));
 328
 329        if (ret)
 330                netdev_err(vif->ndev, "Failed to set channel\n");
 331}
 332
 333static int handle_set_wfi_drv_handler(struct wilc_vif *vif,
 334                                      struct drv_handler *hif_drv_handler)
 335{
 336        int ret = 0;
 337        struct wid wid;
 338        u8 *currbyte, *buffer;
 339        struct host_if_drv *hif_drv = NULL;
 340
 341        if (!vif->hif_drv)
 342                return -EINVAL;
 343
 344        if (!hif_drv_handler)
 345                return -EINVAL;
 346
 347        hif_drv = vif->hif_drv;
 348
 349        buffer = kzalloc(DRV_HANDLER_SIZE, GFP_KERNEL);
 350        if (!buffer)
 351                return -ENOMEM;
 352
 353        currbyte = buffer;
 354        *currbyte = hif_drv->driver_handler_id & DRV_HANDLER_MASK;
 355        currbyte++;
 356        *currbyte = (u32)0 & DRV_HANDLER_MASK;
 357        currbyte++;
 358        *currbyte = (u32)0 & DRV_HANDLER_MASK;
 359        currbyte++;
 360        *currbyte = (u32)0 & DRV_HANDLER_MASK;
 361        currbyte++;
 362        *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 363
 364        wid.id = (u16)WID_SET_DRV_HANDLER;
 365        wid.type = WID_STR;
 366        wid.val = (s8 *)buffer;
 367        wid.size = DRV_HANDLER_SIZE;
 368
 369        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 370                                   hif_drv->driver_handler_id);
 371        if (ret) {
 372                netdev_err(vif->ndev, "Failed to set driver handler\n");
 373                complete(&hif_driver_comp);
 374                kfree(buffer);
 375                return ret;
 376        }
 377        complete(&hif_driver_comp);
 378        kfree(buffer);
 379        return 0;
 380}
 381
 382static void handle_set_operation_mode(struct wilc_vif *vif,
 383                                      struct op_mode *hif_op_mode)
 384{
 385        int ret = 0;
 386        struct wid wid;
 387
 388        wid.id = (u16)WID_SET_OPERATION_MODE;
 389        wid.type = WID_INT;
 390        wid.val = (s8 *)&hif_op_mode->mode;
 391        wid.size = sizeof(u32);
 392
 393        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 394                                   wilc_get_vif_idx(vif));
 395
 396        if ((hif_op_mode->mode) == IDLE_MODE)
 397                complete(&hif_driver_comp);
 398
 399        if (ret)
 400                netdev_err(vif->ndev, "Failed to set driver handler\n");
 401}
 402
 403static void handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
 404{
 405        int ret = 0;
 406        struct wid wid;
 407        char firmware_ip_addr[4] = {0};
 408
 409        if (ip_addr[0] < 192)
 410                ip_addr[0] = 0;
 411
 412        memcpy(set_ip[idx], ip_addr, IP_ALEN);
 413
 414        wid.id = (u16)WID_IP_ADDRESS;
 415        wid.type = WID_STR;
 416        wid.val = ip_addr;
 417        wid.size = IP_ALEN;
 418
 419        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 420                                   wilc_get_vif_idx(vif));
 421
 422        host_int_get_ipaddress(vif, firmware_ip_addr, idx);
 423
 424        if (ret)
 425                netdev_err(vif->ndev, "Failed to set IP address\n");
 426}
 427
 428static void handle_get_ip_address(struct wilc_vif *vif, u8 idx)
 429{
 430        int ret = 0;
 431        struct wid wid;
 432
 433        wid.id = (u16)WID_IP_ADDRESS;
 434        wid.type = WID_STR;
 435        wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
 436        wid.size = IP_ALEN;
 437
 438        ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
 439                                   wilc_get_vif_idx(vif));
 440
 441        memcpy(get_ip[idx], wid.val, IP_ALEN);
 442
 443        kfree(wid.val);
 444
 445        if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
 446                wilc_setup_ipaddress(vif, set_ip[idx], idx);
 447
 448        if (ret)
 449                netdev_err(vif->ndev, "Failed to get IP address\n");
 450}
 451
 452static void handle_get_mac_address(struct wilc_vif *vif,
 453                                   struct get_mac_addr *get_mac_addr)
 454{
 455        int ret = 0;
 456        struct wid wid;
 457
 458        wid.id = (u16)WID_MAC_ADDR;
 459        wid.type = WID_STR;
 460        wid.val = get_mac_addr->mac_addr;
 461        wid.size = ETH_ALEN;
 462
 463        ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
 464                                   wilc_get_vif_idx(vif));
 465
 466        if (ret)
 467                netdev_err(vif->ndev, "Failed to get mac address\n");
 468        complete(&hif_wait_response);
 469}
 470
 471static void handle_cfg_param(struct wilc_vif *vif,
 472                             struct cfg_param_attr *cfg_param_attr)
 473{
 474        int ret = 0;
 475        struct wid wid_list[32];
 476        struct host_if_drv *hif_drv = vif->hif_drv;
 477        int i = 0;
 478
 479        mutex_lock(&hif_drv->cfg_values_lock);
 480
 481        if (cfg_param_attr->flag & BSS_TYPE) {
 482                u8 bss_type = cfg_param_attr->bss_type;
 483
 484                if (bss_type < 6) {
 485                        wid_list[i].id = WID_BSS_TYPE;
 486                        wid_list[i].val = (s8 *)&bss_type;
 487                        wid_list[i].type = WID_CHAR;
 488                        wid_list[i].size = sizeof(char);
 489                        hif_drv->cfg_values.bss_type = bss_type;
 490                } else {
 491                        netdev_err(vif->ndev, "check value 6 over\n");
 492                        goto unlock;
 493                }
 494                i++;
 495        }
 496        if (cfg_param_attr->flag & AUTH_TYPE) {
 497                if (cfg_param_attr->auth_type == 1 ||
 498                    cfg_param_attr->auth_type == 2 ||
 499                    cfg_param_attr->auth_type == 5) {
 500                        wid_list[i].id = WID_AUTH_TYPE;
 501                        wid_list[i].val = (s8 *)&cfg_param_attr->auth_type;
 502                        wid_list[i].type = WID_CHAR;
 503                        wid_list[i].size = sizeof(char);
 504                        hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->auth_type;
 505                } else {
 506                        netdev_err(vif->ndev, "Impossible value\n");
 507                        goto unlock;
 508                }
 509                i++;
 510        }
 511        if (cfg_param_attr->flag & AUTHEN_TIMEOUT) {
 512                if (cfg_param_attr->auth_timeout > 0 &&
 513                    cfg_param_attr->auth_timeout < 65536) {
 514                        wid_list[i].id = WID_AUTH_TIMEOUT;
 515                        wid_list[i].val = (s8 *)&cfg_param_attr->auth_timeout;
 516                        wid_list[i].type = WID_SHORT;
 517                        wid_list[i].size = sizeof(u16);
 518                        hif_drv->cfg_values.auth_timeout = cfg_param_attr->auth_timeout;
 519                } else {
 520                        netdev_err(vif->ndev, "Range(1 ~ 65535) over\n");
 521                        goto unlock;
 522                }
 523                i++;
 524        }
 525        if (cfg_param_attr->flag & POWER_MANAGEMENT) {
 526                if (cfg_param_attr->power_mgmt_mode < 5) {
 527                        wid_list[i].id = WID_POWER_MANAGEMENT;
 528                        wid_list[i].val = (s8 *)&cfg_param_attr->power_mgmt_mode;
 529                        wid_list[i].type = WID_CHAR;
 530                        wid_list[i].size = sizeof(char);
 531                        hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->power_mgmt_mode;
 532                } else {
 533                        netdev_err(vif->ndev, "Invalid power mode\n");
 534                        goto unlock;
 535                }
 536                i++;
 537        }
 538        if (cfg_param_attr->flag & RETRY_SHORT) {
 539                if (cfg_param_attr->short_retry_limit > 0 &&
 540                    cfg_param_attr->short_retry_limit < 256) {
 541                        wid_list[i].id = WID_SHORT_RETRY_LIMIT;
 542                        wid_list[i].val = (s8 *)&cfg_param_attr->short_retry_limit;
 543                        wid_list[i].type = WID_SHORT;
 544                        wid_list[i].size = sizeof(u16);
 545                        hif_drv->cfg_values.short_retry_limit = cfg_param_attr->short_retry_limit;
 546                } else {
 547                        netdev_err(vif->ndev, "Range(1~256) over\n");
 548                        goto unlock;
 549                }
 550                i++;
 551        }
 552        if (cfg_param_attr->flag & RETRY_LONG) {
 553                if (cfg_param_attr->long_retry_limit > 0 &&
 554                    cfg_param_attr->long_retry_limit < 256) {
 555                        wid_list[i].id = WID_LONG_RETRY_LIMIT;
 556                        wid_list[i].val = (s8 *)&cfg_param_attr->long_retry_limit;
 557                        wid_list[i].type = WID_SHORT;
 558                        wid_list[i].size = sizeof(u16);
 559                        hif_drv->cfg_values.long_retry_limit = cfg_param_attr->long_retry_limit;
 560                } else {
 561                        netdev_err(vif->ndev, "Range(1~256) over\n");
 562                        goto unlock;
 563                }
 564                i++;
 565        }
 566        if (cfg_param_attr->flag & FRAG_THRESHOLD) {
 567                if (cfg_param_attr->frag_threshold > 255 &&
 568                    cfg_param_attr->frag_threshold < 7937) {
 569                        wid_list[i].id = WID_FRAG_THRESHOLD;
 570                        wid_list[i].val = (s8 *)&cfg_param_attr->frag_threshold;
 571                        wid_list[i].type = WID_SHORT;
 572                        wid_list[i].size = sizeof(u16);
 573                        hif_drv->cfg_values.frag_threshold = cfg_param_attr->frag_threshold;
 574                } else {
 575                        netdev_err(vif->ndev, "Threshold Range fail\n");
 576                        goto unlock;
 577                }
 578                i++;
 579        }
 580        if (cfg_param_attr->flag & RTS_THRESHOLD) {
 581                if (cfg_param_attr->rts_threshold > 255 &&
 582                    cfg_param_attr->rts_threshold < 65536) {
 583                        wid_list[i].id = WID_RTS_THRESHOLD;
 584                        wid_list[i].val = (s8 *)&cfg_param_attr->rts_threshold;
 585                        wid_list[i].type = WID_SHORT;
 586                        wid_list[i].size = sizeof(u16);
 587                        hif_drv->cfg_values.rts_threshold = cfg_param_attr->rts_threshold;
 588                } else {
 589                        netdev_err(vif->ndev, "Threshold Range fail\n");
 590                        goto unlock;
 591                }
 592                i++;
 593        }
 594        if (cfg_param_attr->flag & PREAMBLE) {
 595                if (cfg_param_attr->preamble_type < 3) {
 596                        wid_list[i].id = WID_PREAMBLE;
 597                        wid_list[i].val = (s8 *)&cfg_param_attr->preamble_type;
 598                        wid_list[i].type = WID_CHAR;
 599                        wid_list[i].size = sizeof(char);
 600                        hif_drv->cfg_values.preamble_type = cfg_param_attr->preamble_type;
 601                } else {
 602                        netdev_err(vif->ndev, "Preamle Range(0~2) over\n");
 603                        goto unlock;
 604                }
 605                i++;
 606        }
 607        if (cfg_param_attr->flag & SHORT_SLOT_ALLOWED) {
 608                if (cfg_param_attr->short_slot_allowed < 2) {
 609                        wid_list[i].id = WID_SHORT_SLOT_ALLOWED;
 610                        wid_list[i].val = (s8 *)&cfg_param_attr->short_slot_allowed;
 611                        wid_list[i].type = WID_CHAR;
 612                        wid_list[i].size = sizeof(char);
 613                        hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->short_slot_allowed;
 614                } else {
 615                        netdev_err(vif->ndev, "Short slot(2) over\n");
 616                        goto unlock;
 617                }
 618                i++;
 619        }
 620        if (cfg_param_attr->flag & TXOP_PROT_DISABLE) {
 621                if (cfg_param_attr->txop_prot_disabled < 2) {
 622                        wid_list[i].id = WID_11N_TXOP_PROT_DISABLE;
 623                        wid_list[i].val = (s8 *)&cfg_param_attr->txop_prot_disabled;
 624                        wid_list[i].type = WID_CHAR;
 625                        wid_list[i].size = sizeof(char);
 626                        hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->txop_prot_disabled;
 627                } else {
 628                        netdev_err(vif->ndev, "TXOP prot disable\n");
 629                        goto unlock;
 630                }
 631                i++;
 632        }
 633        if (cfg_param_attr->flag & BEACON_INTERVAL) {
 634                if (cfg_param_attr->beacon_interval > 0 &&
 635                    cfg_param_attr->beacon_interval < 65536) {
 636                        wid_list[i].id = WID_BEACON_INTERVAL;
 637                        wid_list[i].val = (s8 *)&cfg_param_attr->beacon_interval;
 638                        wid_list[i].type = WID_SHORT;
 639                        wid_list[i].size = sizeof(u16);
 640                        hif_drv->cfg_values.beacon_interval = cfg_param_attr->beacon_interval;
 641                } else {
 642                        netdev_err(vif->ndev, "Beacon interval(1~65535)fail\n");
 643                        goto unlock;
 644                }
 645                i++;
 646        }
 647        if (cfg_param_attr->flag & DTIM_PERIOD) {
 648                if (cfg_param_attr->dtim_period > 0 &&
 649                    cfg_param_attr->dtim_period < 256) {
 650                        wid_list[i].id = WID_DTIM_PERIOD;
 651                        wid_list[i].val = (s8 *)&cfg_param_attr->dtim_period;
 652                        wid_list[i].type = WID_CHAR;
 653                        wid_list[i].size = sizeof(char);
 654                        hif_drv->cfg_values.dtim_period = cfg_param_attr->dtim_period;
 655                } else {
 656                        netdev_err(vif->ndev, "DTIM range(1~255) fail\n");
 657                        goto unlock;
 658                }
 659                i++;
 660        }
 661        if (cfg_param_attr->flag & SITE_SURVEY) {
 662                if (cfg_param_attr->site_survey_enabled < 3) {
 663                        wid_list[i].id = WID_SITE_SURVEY;
 664                        wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_enabled;
 665                        wid_list[i].type = WID_CHAR;
 666                        wid_list[i].size = sizeof(char);
 667                        hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->site_survey_enabled;
 668                } else {
 669                        netdev_err(vif->ndev, "Site survey disable\n");
 670                        goto unlock;
 671                }
 672                i++;
 673        }
 674        if (cfg_param_attr->flag & SITE_SURVEY_SCAN_TIME) {
 675                if (cfg_param_attr->site_survey_scan_time > 0 &&
 676                    cfg_param_attr->site_survey_scan_time < 65536) {
 677                        wid_list[i].id = WID_SITE_SURVEY_SCAN_TIME;
 678                        wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_scan_time;
 679                        wid_list[i].type = WID_SHORT;
 680                        wid_list[i].size = sizeof(u16);
 681                        hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->site_survey_scan_time;
 682                } else {
 683                        netdev_err(vif->ndev, "Site scan time(1~65535) over\n");
 684                        goto unlock;
 685                }
 686                i++;
 687        }
 688        if (cfg_param_attr->flag & ACTIVE_SCANTIME) {
 689                if (cfg_param_attr->active_scan_time > 0 &&
 690                    cfg_param_attr->active_scan_time < 65536) {
 691                        wid_list[i].id = WID_ACTIVE_SCAN_TIME;
 692                        wid_list[i].val = (s8 *)&cfg_param_attr->active_scan_time;
 693                        wid_list[i].type = WID_SHORT;
 694                        wid_list[i].size = sizeof(u16);
 695                        hif_drv->cfg_values.active_scan_time = cfg_param_attr->active_scan_time;
 696                } else {
 697                        netdev_err(vif->ndev, "Active time(1~65535) over\n");
 698                        goto unlock;
 699                }
 700                i++;
 701        }
 702        if (cfg_param_attr->flag & PASSIVE_SCANTIME) {
 703                if (cfg_param_attr->passive_scan_time > 0 &&
 704                    cfg_param_attr->passive_scan_time < 65536) {
 705                        wid_list[i].id = WID_PASSIVE_SCAN_TIME;
 706                        wid_list[i].val = (s8 *)&cfg_param_attr->passive_scan_time;
 707                        wid_list[i].type = WID_SHORT;
 708                        wid_list[i].size = sizeof(u16);
 709                        hif_drv->cfg_values.passive_scan_time = cfg_param_attr->passive_scan_time;
 710                } else {
 711                        netdev_err(vif->ndev, "Passive time(1~65535) over\n");
 712                        goto unlock;
 713                }
 714                i++;
 715        }
 716        if (cfg_param_attr->flag & CURRENT_TX_RATE) {
 717                enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->curr_tx_rate;
 718
 719                if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 ||
 720                    curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 ||
 721                    curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 ||
 722                    curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 ||
 723                    curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 ||
 724                    curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 ||
 725                    curr_tx_rate == MBPS_54) {
 726                        wid_list[i].id = WID_CURRENT_TX_RATE;
 727                        wid_list[i].val = (s8 *)&curr_tx_rate;
 728                        wid_list[i].type = WID_SHORT;
 729                        wid_list[i].size = sizeof(u16);
 730                        hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate;
 731                } else {
 732                        netdev_err(vif->ndev, "out of TX rate\n");
 733                        goto unlock;
 734                }
 735                i++;
 736        }
 737
 738        ret = wilc_send_config_pkt(vif, SET_CFG, wid_list,
 739                                   i, wilc_get_vif_idx(vif));
 740
 741        if (ret)
 742                netdev_err(vif->ndev, "Error in setting CFG params\n");
 743
 744unlock:
 745        mutex_unlock(&hif_drv->cfg_values_lock);
 746}
 747
 748static s32 handle_scan(struct wilc_vif *vif, struct scan_attr *scan_info)
 749{
 750        s32 result = 0;
 751        struct wid wid_list[5];
 752        u32 index = 0;
 753        u32 i;
 754        u8 *buffer;
 755        u8 valuesize = 0;
 756        u8 *pu8HdnNtwrksWidVal = NULL;
 757        struct host_if_drv *hif_drv = vif->hif_drv;
 758
 759        hif_drv->usr_scan_req.scan_result = scan_info->result;
 760        hif_drv->usr_scan_req.arg = scan_info->arg;
 761
 762        if ((hif_drv->hif_state >= HOST_IF_SCANNING) &&
 763            (hif_drv->hif_state < HOST_IF_CONNECTED)) {
 764                netdev_err(vif->ndev, "Already scan\n");
 765                result = -EBUSY;
 766                goto ERRORHANDLER;
 767        }
 768
 769        if (wilc_optaining_ip || wilc_connecting) {
 770                netdev_err(vif->ndev, "Don't do obss scan\n");
 771                result = -EBUSY;
 772                goto ERRORHANDLER;
 773        }
 774
 775        hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
 776
 777        wid_list[index].id = (u16)WID_SSID_PROBE_REQ;
 778        wid_list[index].type = WID_STR;
 779
 780        for (i = 0; i < scan_info->hidden_network.n_ssids; i++)
 781                valuesize += ((scan_info->hidden_network.net_info[i].ssid_len) + 1);
 782        pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
 783        wid_list[index].val = pu8HdnNtwrksWidVal;
 784        if (wid_list[index].val) {
 785                buffer = wid_list[index].val;
 786
 787                *buffer++ = scan_info->hidden_network.n_ssids;
 788
 789                for (i = 0; i < scan_info->hidden_network.n_ssids; i++) {
 790                        *buffer++ = scan_info->hidden_network.net_info[i].ssid_len;
 791                        memcpy(buffer, scan_info->hidden_network.net_info[i].ssid, scan_info->hidden_network.net_info[i].ssid_len);
 792                        buffer += scan_info->hidden_network.net_info[i].ssid_len;
 793                }
 794
 795                wid_list[index].size = (s32)(valuesize + 1);
 796                index++;
 797        }
 798
 799        wid_list[index].id = WID_INFO_ELEMENT_PROBE;
 800        wid_list[index].type = WID_BIN_DATA;
 801        wid_list[index].val = scan_info->ies;
 802        wid_list[index].size = scan_info->ies_len;
 803        index++;
 804
 805        wid_list[index].id = WID_SCAN_TYPE;
 806        wid_list[index].type = WID_CHAR;
 807        wid_list[index].size = sizeof(char);
 808        wid_list[index].val = (s8 *)&scan_info->type;
 809        index++;
 810
 811        wid_list[index].id = WID_SCAN_CHANNEL_LIST;
 812        wid_list[index].type = WID_BIN_DATA;
 813
 814        if (scan_info->ch_freq_list &&
 815            scan_info->ch_list_len > 0) {
 816                int i;
 817
 818                for (i = 0; i < scan_info->ch_list_len; i++)    {
 819                        if (scan_info->ch_freq_list[i] > 0)
 820                                scan_info->ch_freq_list[i] = scan_info->ch_freq_list[i] - 1;
 821                }
 822        }
 823
 824        wid_list[index].val = scan_info->ch_freq_list;
 825        wid_list[index].size = scan_info->ch_list_len;
 826        index++;
 827
 828        wid_list[index].id = WID_START_SCAN_REQ;
 829        wid_list[index].type = WID_CHAR;
 830        wid_list[index].size = sizeof(char);
 831        wid_list[index].val = (s8 *)&scan_info->src;
 832        index++;
 833
 834        if (hif_drv->hif_state == HOST_IF_CONNECTED)
 835                scan_while_connected = true;
 836        else if (hif_drv->hif_state == HOST_IF_IDLE)
 837                scan_while_connected = false;
 838
 839        result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
 840                                      index,
 841                                      wilc_get_vif_idx(vif));
 842
 843        if (result)
 844                netdev_err(vif->ndev, "Failed to send scan parameters\n");
 845
 846ERRORHANDLER:
 847        if (result) {
 848                del_timer(&hif_drv->scan_timer);
 849                Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
 850        }
 851
 852        kfree(scan_info->ch_freq_list);
 853        scan_info->ch_freq_list = NULL;
 854
 855        kfree(scan_info->ies);
 856        scan_info->ies = NULL;
 857        kfree(scan_info->hidden_network.net_info);
 858        scan_info->hidden_network.net_info = NULL;
 859
 860        kfree(pu8HdnNtwrksWidVal);
 861
 862        return result;
 863}
 864
 865static s32 Handle_ScanDone(struct wilc_vif *vif,
 866                           enum scan_event enuEvent)
 867{
 868        s32 result = 0;
 869        u8 u8abort_running_scan;
 870        struct wid wid;
 871        struct host_if_drv *hif_drv = vif->hif_drv;
 872
 873        if (enuEvent == SCAN_EVENT_ABORTED) {
 874                u8abort_running_scan = 1;
 875                wid.id = (u16)WID_ABORT_RUNNING_SCAN;
 876                wid.type = WID_CHAR;
 877                wid.val = (s8 *)&u8abort_running_scan;
 878                wid.size = sizeof(char);
 879
 880                result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 881                                              wilc_get_vif_idx(vif));
 882
 883                if (result) {
 884                        netdev_err(vif->ndev, "Failed to set abort running\n");
 885                        result = -EFAULT;
 886                }
 887        }
 888
 889        if (!hif_drv) {
 890                netdev_err(vif->ndev, "Driver handler is NULL\n");
 891                return result;
 892        }
 893
 894        if (hif_drv->usr_scan_req.scan_result) {
 895                hif_drv->usr_scan_req.scan_result(enuEvent, NULL,
 896                                                  hif_drv->usr_scan_req.arg, NULL);
 897                hif_drv->usr_scan_req.scan_result = NULL;
 898        }
 899
 900        return result;
 901}
 902
 903u8 wilc_connected_ssid[6] = {0};
 904static s32 Handle_Connect(struct wilc_vif *vif,
 905                          struct connect_attr *pstrHostIFconnectAttr)
 906{
 907        s32 result = 0;
 908        struct wid strWIDList[8];
 909        u32 u32WidsCount = 0, dummyval = 0;
 910        u8 *pu8CurrByte = NULL;
 911        struct join_bss_param *ptstrJoinBssParam;
 912        struct host_if_drv *hif_drv = vif->hif_drv;
 913
 914        if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
 915                result = 0;
 916                netdev_err(vif->ndev, "Discard connect request\n");
 917                return result;
 918        }
 919
 920        ptstrJoinBssParam = pstrHostIFconnectAttr->params;
 921        if (!ptstrJoinBssParam) {
 922                netdev_err(vif->ndev, "Required BSSID not found\n");
 923                result = -ENOENT;
 924                goto ERRORHANDLER;
 925        }
 926
 927        if (pstrHostIFconnectAttr->bssid) {
 928                hif_drv->usr_conn_req.bssid = kmalloc(6, GFP_KERNEL);
 929                memcpy(hif_drv->usr_conn_req.bssid, pstrHostIFconnectAttr->bssid, 6);
 930        }
 931
 932        hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len;
 933        if (pstrHostIFconnectAttr->ssid) {
 934                hif_drv->usr_conn_req.ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
 935                memcpy(hif_drv->usr_conn_req.ssid,
 936                       pstrHostIFconnectAttr->ssid,
 937                       pstrHostIFconnectAttr->ssid_len);
 938                hif_drv->usr_conn_req.ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
 939        }
 940
 941        hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len;
 942        if (pstrHostIFconnectAttr->ies) {
 943                hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
 944                memcpy(hif_drv->usr_conn_req.ies,
 945                       pstrHostIFconnectAttr->ies,
 946                       pstrHostIFconnectAttr->ies_len);
 947        }
 948
 949        hif_drv->usr_conn_req.security = pstrHostIFconnectAttr->security;
 950        hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type;
 951        hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result;
 952        hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg;
 953
 954        strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
 955        strWIDList[u32WidsCount].type = WID_INT;
 956        strWIDList[u32WidsCount].size = sizeof(u32);
 957        strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
 958        u32WidsCount++;
 959
 960        strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
 961        strWIDList[u32WidsCount].type = WID_INT;
 962        strWIDList[u32WidsCount].size = sizeof(u32);
 963        strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
 964        u32WidsCount++;
 965
 966        strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
 967        strWIDList[u32WidsCount].type = WID_INT;
 968        strWIDList[u32WidsCount].size = sizeof(u32);
 969        strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
 970        u32WidsCount++;
 971
 972        {
 973                strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
 974                strWIDList[u32WidsCount].type = WID_BIN_DATA;
 975                strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies;
 976                strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len;
 977                u32WidsCount++;
 978
 979                if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
 980                        info_element_size = hif_drv->usr_conn_req.ies_len;
 981                        info_element = kmalloc(info_element_size, GFP_KERNEL);
 982                        memcpy(info_element, hif_drv->usr_conn_req.ies,
 983                               info_element_size);
 984                }
 985        }
 986        strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
 987        strWIDList[u32WidsCount].type = WID_CHAR;
 988        strWIDList[u32WidsCount].size = sizeof(char);
 989        strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.security;
 990        u32WidsCount++;
 991
 992        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
 993                mode_11i = hif_drv->usr_conn_req.security;
 994
 995        strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
 996        strWIDList[u32WidsCount].type = WID_CHAR;
 997        strWIDList[u32WidsCount].size = sizeof(char);
 998        strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
 999        u32WidsCount++;
1000
1001        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1002                auth_type = (u8)hif_drv->usr_conn_req.auth_type;
1003
1004        strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
1005        strWIDList[u32WidsCount].type = WID_STR;
1006        strWIDList[u32WidsCount].size = 112;
1007        strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
1008
1009        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1010                join_req_size = strWIDList[u32WidsCount].size;
1011                join_req = kmalloc(join_req_size, GFP_KERNEL);
1012        }
1013        if (!strWIDList[u32WidsCount].val) {
1014                result = -EFAULT;
1015                goto ERRORHANDLER;
1016        }
1017
1018        pu8CurrByte = strWIDList[u32WidsCount].val;
1019
1020        if (pstrHostIFconnectAttr->ssid) {
1021                memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
1022                pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
1023        }
1024        pu8CurrByte += MAX_SSID_LEN;
1025        *(pu8CurrByte++) = INFRASTRUCTURE;
1026
1027        if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
1028                *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
1029        } else {
1030                netdev_err(vif->ndev, "Channel out of range\n");
1031                *(pu8CurrByte++) = 0xFF;
1032        }
1033        *(pu8CurrByte++)  = (ptstrJoinBssParam->cap_info) & 0xFF;
1034        *(pu8CurrByte++)  = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
1035
1036        if (pstrHostIFconnectAttr->bssid)
1037                memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1038        pu8CurrByte += 6;
1039
1040        if (pstrHostIFconnectAttr->bssid)
1041                memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1042        pu8CurrByte += 6;
1043
1044        *(pu8CurrByte++)  = (ptstrJoinBssParam->beacon_period) & 0xFF;
1045        *(pu8CurrByte++)  = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
1046        *(pu8CurrByte++)  =  ptstrJoinBssParam->dtim_period;
1047
1048        memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
1049        pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1050
1051        *(pu8CurrByte++)  =  ptstrJoinBssParam->wmm_cap;
1052        *(pu8CurrByte++)  = ptstrJoinBssParam->uapsd_cap;
1053
1054        *(pu8CurrByte++)  = ptstrJoinBssParam->ht_capable;
1055        hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable;
1056
1057        *(pu8CurrByte++)  =  ptstrJoinBssParam->rsn_found;
1058        *(pu8CurrByte++)  =  ptstrJoinBssParam->rsn_grp_policy;
1059        *(pu8CurrByte++) =  ptstrJoinBssParam->mode_802_11i;
1060
1061        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
1062        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1063
1064        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
1065        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1066
1067        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
1068        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1069
1070        *(pu8CurrByte++) = REAL_JOIN_REQ;
1071        *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
1072
1073        if (ptstrJoinBssParam->noa_enabled) {
1074                *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1075                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1076                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1077                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1078
1079                *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
1080                *(pu8CurrByte++) = ptstrJoinBssParam->idx;
1081
1082                if (ptstrJoinBssParam->opp_enabled)
1083                        *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
1084
1085                *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
1086
1087                memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
1088                pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
1089
1090                memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
1091                pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
1092
1093                memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
1094                pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
1095        }
1096
1097        pu8CurrByte = strWIDList[u32WidsCount].val;
1098        u32WidsCount++;
1099
1100        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1101                memcpy(join_req, pu8CurrByte, join_req_size);
1102                join_req_vif = vif;
1103        }
1104
1105        if (pstrHostIFconnectAttr->bssid)
1106                memcpy(wilc_connected_ssid,
1107                       pstrHostIFconnectAttr->bssid, ETH_ALEN);
1108
1109        result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
1110                                      u32WidsCount,
1111                                      wilc_get_vif_idx(vif));
1112        if (result) {
1113                netdev_err(vif->ndev, "failed to send config packet\n");
1114                result = -EFAULT;
1115                goto ERRORHANDLER;
1116        } else {
1117                hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
1118        }
1119
1120ERRORHANDLER:
1121        if (result) {
1122                struct connect_info strConnectInfo;
1123
1124                del_timer(&hif_drv->connect_timer);
1125
1126                memset(&strConnectInfo, 0, sizeof(struct connect_info));
1127
1128                if (pstrHostIFconnectAttr->result) {
1129                        if (pstrHostIFconnectAttr->bssid)
1130                                memcpy(strConnectInfo.bssid, pstrHostIFconnectAttr->bssid, 6);
1131
1132                        if (pstrHostIFconnectAttr->ies) {
1133                                strConnectInfo.req_ies_len = pstrHostIFconnectAttr->ies_len;
1134                                strConnectInfo.req_ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1135                                memcpy(strConnectInfo.req_ies,
1136                                       pstrHostIFconnectAttr->ies,
1137                                       pstrHostIFconnectAttr->ies_len);
1138                        }
1139
1140                        pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
1141                                                               &strConnectInfo,
1142                                                               MAC_DISCONNECTED,
1143                                                               NULL,
1144                                                               pstrHostIFconnectAttr->arg);
1145                        hif_drv->hif_state = HOST_IF_IDLE;
1146                        kfree(strConnectInfo.req_ies);
1147                        strConnectInfo.req_ies = NULL;
1148
1149                } else {
1150                        netdev_err(vif->ndev, "Connect callback is NULL\n");
1151                }
1152        }
1153
1154        kfree(pstrHostIFconnectAttr->bssid);
1155        pstrHostIFconnectAttr->bssid = NULL;
1156
1157        kfree(pstrHostIFconnectAttr->ssid);
1158        pstrHostIFconnectAttr->ssid = NULL;
1159
1160        kfree(pstrHostIFconnectAttr->ies);
1161        pstrHostIFconnectAttr->ies = NULL;
1162
1163        kfree(pu8CurrByte);
1164        return result;
1165}
1166
1167static s32 Handle_ConnectTimeout(struct wilc_vif *vif)
1168{
1169        s32 result = 0;
1170        struct connect_info strConnectInfo;
1171        struct wid wid;
1172        u16 u16DummyReasonCode = 0;
1173        struct host_if_drv *hif_drv = vif->hif_drv;
1174
1175        if (!hif_drv) {
1176                netdev_err(vif->ndev, "Driver handler is NULL\n");
1177                return result;
1178        }
1179
1180        hif_drv->hif_state = HOST_IF_IDLE;
1181
1182        scan_while_connected = false;
1183
1184        memset(&strConnectInfo, 0, sizeof(struct connect_info));
1185
1186        if (hif_drv->usr_conn_req.conn_result) {
1187                if (hif_drv->usr_conn_req.bssid) {
1188                        memcpy(strConnectInfo.bssid,
1189                               hif_drv->usr_conn_req.bssid, 6);
1190                }
1191
1192                if (hif_drv->usr_conn_req.ies) {
1193                        strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
1194                        strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1195                        memcpy(strConnectInfo.req_ies,
1196                               hif_drv->usr_conn_req.ies,
1197                               hif_drv->usr_conn_req.ies_len);
1198                }
1199
1200                hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1201                                                  &strConnectInfo,
1202                                                  MAC_DISCONNECTED,
1203                                                  NULL,
1204                                                  hif_drv->usr_conn_req.arg);
1205
1206                kfree(strConnectInfo.req_ies);
1207                strConnectInfo.req_ies = NULL;
1208        } else {
1209                netdev_err(vif->ndev, "Connect callback is NULL\n");
1210        }
1211
1212        wid.id = (u16)WID_DISCONNECT;
1213        wid.type = WID_CHAR;
1214        wid.val = (s8 *)&u16DummyReasonCode;
1215        wid.size = sizeof(char);
1216
1217        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1218                                      wilc_get_vif_idx(vif));
1219        if (result)
1220                netdev_err(vif->ndev, "Failed to send disconnect\n");
1221
1222        hif_drv->usr_conn_req.ssid_len = 0;
1223        kfree(hif_drv->usr_conn_req.ssid);
1224        hif_drv->usr_conn_req.ssid = NULL;
1225        kfree(hif_drv->usr_conn_req.bssid);
1226        hif_drv->usr_conn_req.bssid = NULL;
1227        hif_drv->usr_conn_req.ies_len = 0;
1228        kfree(hif_drv->usr_conn_req.ies);
1229        hif_drv->usr_conn_req.ies = NULL;
1230
1231        eth_zero_addr(wilc_connected_ssid);
1232
1233        if (join_req && join_req_vif == vif) {
1234                kfree(join_req);
1235                join_req = NULL;
1236        }
1237
1238        if (info_element && join_req_vif == vif) {
1239                kfree(info_element);
1240                info_element = NULL;
1241        }
1242
1243        return result;
1244}
1245
1246static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif,
1247                                struct rcvd_net_info *pstrRcvdNetworkInfo)
1248{
1249        u32 i;
1250        bool bNewNtwrkFound;
1251        s32 result = 0;
1252        struct network_info *pstrNetworkInfo = NULL;
1253        void *pJoinParams = NULL;
1254        struct host_if_drv *hif_drv = vif->hif_drv;
1255
1256        bNewNtwrkFound = true;
1257
1258        if (hif_drv->usr_scan_req.scan_result) {
1259                wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
1260                if ((!pstrNetworkInfo) ||
1261                    (!hif_drv->usr_scan_req.scan_result)) {
1262                        netdev_err(vif->ndev, "driver is null\n");
1263                        result = -EINVAL;
1264                        goto done;
1265                }
1266
1267                for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) {
1268                        if (memcmp(hif_drv->usr_scan_req.net_info[i].bssid,
1269                                   pstrNetworkInfo->bssid, 6) == 0) {
1270                                if (pstrNetworkInfo->rssi <= hif_drv->usr_scan_req.net_info[i].rssi) {
1271                                        goto done;
1272                                } else {
1273                                        hif_drv->usr_scan_req.net_info[i].rssi = pstrNetworkInfo->rssi;
1274                                        bNewNtwrkFound = false;
1275                                        break;
1276                                }
1277                        }
1278                }
1279
1280                if (bNewNtwrkFound) {
1281                        if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
1282                                hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].rssi = pstrNetworkInfo->rssi;
1283
1284                                memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid,
1285                                       pstrNetworkInfo->bssid, 6);
1286
1287                                hif_drv->usr_scan_req.rcvd_ch_cnt++;
1288
1289                                pstrNetworkInfo->new_network = true;
1290                                pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
1291
1292                                hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1293                                                                  hif_drv->usr_scan_req.arg,
1294                                                                  pJoinParams);
1295                        }
1296                } else {
1297                        pstrNetworkInfo->new_network = false;
1298                        hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1299                                                          hif_drv->usr_scan_req.arg, NULL);
1300                }
1301        }
1302
1303done:
1304        kfree(pstrRcvdNetworkInfo->buffer);
1305        pstrRcvdNetworkInfo->buffer = NULL;
1306
1307        if (pstrNetworkInfo) {
1308                kfree(pstrNetworkInfo->ies);
1309                kfree(pstrNetworkInfo);
1310        }
1311
1312        return result;
1313}
1314
1315static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
1316                                       u8 *pu8AssocRespInfo,
1317                                       u32 u32MaxAssocRespInfoLen,
1318                                       u32 *pu32RcvdAssocRespInfoLen);
1319
1320static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif,
1321                                    struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
1322{
1323        s32 result = 0;
1324        u8 u8MsgType = 0;
1325        u8 u8MsgID = 0;
1326        u16 u16MsgLen = 0;
1327        u16 u16WidID = (u16)WID_NIL;
1328        u8 u8WidLen  = 0;
1329        u8 u8MacStatus;
1330        u8 u8MacStatusReasonCode;
1331        u8 u8MacStatusAdditionalInfo;
1332        struct connect_info strConnectInfo;
1333        struct disconnect_info strDisconnectNotifInfo;
1334        s32 s32Err = 0;
1335        struct host_if_drv *hif_drv = vif->hif_drv;
1336
1337        if (!hif_drv) {
1338                netdev_err(vif->ndev, "Driver handler is NULL\n");
1339                return -ENODEV;
1340        }
1341
1342        if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
1343            (hif_drv->hif_state == HOST_IF_CONNECTED) ||
1344            hif_drv->usr_scan_req.scan_result) {
1345                if (!pstrRcvdGnrlAsyncInfo->buffer ||
1346                    !hif_drv->usr_conn_req.conn_result) {
1347                        netdev_err(vif->ndev, "driver is null\n");
1348                        return -EINVAL;
1349                }
1350
1351                u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
1352
1353                if ('I' != u8MsgType) {
1354                        netdev_err(vif->ndev, "Received Message incorrect.\n");
1355                        return -EFAULT;
1356                }
1357
1358                u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
1359                u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
1360                u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
1361                u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
1362                u8MacStatus  = pstrRcvdGnrlAsyncInfo->buffer[7];
1363                u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
1364                u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
1365                if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
1366                        u32 u32RcvdAssocRespInfoLen = 0;
1367                        struct connect_resp_info *pstrConnectRespInfo = NULL;
1368
1369                        memset(&strConnectInfo, 0, sizeof(struct connect_info));
1370
1371                        if (u8MacStatus == MAC_CONNECTED) {
1372                                memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
1373
1374                                host_int_get_assoc_res_info(vif,
1375                                                            rcv_assoc_resp,
1376                                                            MAX_ASSOC_RESP_FRAME_SIZE,
1377                                                            &u32RcvdAssocRespInfoLen);
1378
1379                                if (u32RcvdAssocRespInfoLen != 0) {
1380                                        s32Err = wilc_parse_assoc_resp_info(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
1381                                                                            &pstrConnectRespInfo);
1382                                        if (s32Err) {
1383                                                netdev_err(vif->ndev, "wilc_parse_assoc_resp_info() returned error %d\n", s32Err);
1384                                        } else {
1385                                                strConnectInfo.status = pstrConnectRespInfo->status;
1386
1387                                                if (strConnectInfo.status == SUCCESSFUL_STATUSCODE && pstrConnectRespInfo->ies) {
1388                                                        strConnectInfo.resp_ies_len = pstrConnectRespInfo->ies_len;
1389                                                        strConnectInfo.resp_ies = kmalloc(pstrConnectRespInfo->ies_len, GFP_KERNEL);
1390                                                        memcpy(strConnectInfo.resp_ies, pstrConnectRespInfo->ies,
1391                                                               pstrConnectRespInfo->ies_len);
1392                                                }
1393
1394                                                if (pstrConnectRespInfo) {
1395                                                        kfree(pstrConnectRespInfo->ies);
1396                                                        kfree(pstrConnectRespInfo);
1397                                                }
1398                                        }
1399                                }
1400                        }
1401
1402                        if ((u8MacStatus == MAC_CONNECTED) &&
1403                            (strConnectInfo.status != SUCCESSFUL_STATUSCODE))   {
1404                                netdev_err(vif->ndev, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
1405                                eth_zero_addr(wilc_connected_ssid);
1406                        } else if (u8MacStatus == MAC_DISCONNECTED)    {
1407                                netdev_err(vif->ndev, "Received MAC status is MAC_DISCONNECTED\n");
1408                                eth_zero_addr(wilc_connected_ssid);
1409                        }
1410
1411                        if (hif_drv->usr_conn_req.bssid) {
1412                                memcpy(strConnectInfo.bssid, hif_drv->usr_conn_req.bssid, 6);
1413
1414                                if ((u8MacStatus == MAC_CONNECTED) &&
1415                                    (strConnectInfo.status == SUCCESSFUL_STATUSCODE))   {
1416                                        memcpy(hif_drv->assoc_bssid,
1417                                               hif_drv->usr_conn_req.bssid, ETH_ALEN);
1418                                }
1419                        }
1420
1421                        if (hif_drv->usr_conn_req.ies) {
1422                                strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
1423                                strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1424                                memcpy(strConnectInfo.req_ies,
1425                                       hif_drv->usr_conn_req.ies,
1426                                       hif_drv->usr_conn_req.ies_len);
1427                        }
1428
1429                        del_timer(&hif_drv->connect_timer);
1430                        hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1431                                                          &strConnectInfo,
1432                                                          u8MacStatus,
1433                                                          NULL,
1434                                                          hif_drv->usr_conn_req.arg);
1435
1436                        if ((u8MacStatus == MAC_CONNECTED) &&
1437                            (strConnectInfo.status == SUCCESSFUL_STATUSCODE))   {
1438                                wilc_set_power_mgmt(vif, 0, 0);
1439
1440                                hif_drv->hif_state = HOST_IF_CONNECTED;
1441
1442                                wilc_optaining_ip = true;
1443                                mod_timer(&wilc_during_ip_timer,
1444                                          jiffies + msecs_to_jiffies(10000));
1445                        } else {
1446                                hif_drv->hif_state = HOST_IF_IDLE;
1447                                scan_while_connected = false;
1448                        }
1449
1450                        kfree(strConnectInfo.resp_ies);
1451                        strConnectInfo.resp_ies = NULL;
1452
1453                        kfree(strConnectInfo.req_ies);
1454                        strConnectInfo.req_ies = NULL;
1455                        hif_drv->usr_conn_req.ssid_len = 0;
1456                        kfree(hif_drv->usr_conn_req.ssid);
1457                        hif_drv->usr_conn_req.ssid = NULL;
1458                        kfree(hif_drv->usr_conn_req.bssid);
1459                        hif_drv->usr_conn_req.bssid = NULL;
1460                        hif_drv->usr_conn_req.ies_len = 0;
1461                        kfree(hif_drv->usr_conn_req.ies);
1462                        hif_drv->usr_conn_req.ies = NULL;
1463                } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1464                           (hif_drv->hif_state == HOST_IF_CONNECTED)) {
1465                        memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
1466
1467                        if (hif_drv->usr_scan_req.scan_result) {
1468                                del_timer(&hif_drv->scan_timer);
1469                                Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
1470                        }
1471
1472                        strDisconnectNotifInfo.reason = 0;
1473                        strDisconnectNotifInfo.ie = NULL;
1474                        strDisconnectNotifInfo.ie_len = 0;
1475
1476                        if (hif_drv->usr_conn_req.conn_result) {
1477                                wilc_optaining_ip = false;
1478                                wilc_set_power_mgmt(vif, 0, 0);
1479
1480                                hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1481                                                                  NULL,
1482                                                                  0,
1483                                                                  &strDisconnectNotifInfo,
1484                                                                  hif_drv->usr_conn_req.arg);
1485                        } else {
1486                                netdev_err(vif->ndev, "Connect result NULL\n");
1487                        }
1488
1489                        eth_zero_addr(hif_drv->assoc_bssid);
1490
1491                        hif_drv->usr_conn_req.ssid_len = 0;
1492                        kfree(hif_drv->usr_conn_req.ssid);
1493                        hif_drv->usr_conn_req.ssid = NULL;
1494                        kfree(hif_drv->usr_conn_req.bssid);
1495                        hif_drv->usr_conn_req.bssid = NULL;
1496                        hif_drv->usr_conn_req.ies_len = 0;
1497                        kfree(hif_drv->usr_conn_req.ies);
1498                        hif_drv->usr_conn_req.ies = NULL;
1499
1500                        if (join_req && join_req_vif == vif) {
1501                                kfree(join_req);
1502                                join_req = NULL;
1503                        }
1504
1505                        if (info_element && join_req_vif == vif) {
1506                                kfree(info_element);
1507                                info_element = NULL;
1508                        }
1509
1510                        hif_drv->hif_state = HOST_IF_IDLE;
1511                        scan_while_connected = false;
1512
1513                } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1514                           (hif_drv->usr_scan_req.scan_result)) {
1515                        del_timer(&hif_drv->scan_timer);
1516                        if (hif_drv->usr_scan_req.scan_result)
1517                                Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
1518                }
1519        }
1520
1521        kfree(pstrRcvdGnrlAsyncInfo->buffer);
1522        pstrRcvdGnrlAsyncInfo->buffer = NULL;
1523
1524        return result;
1525}
1526
1527static int Handle_Key(struct wilc_vif *vif,
1528                      struct key_attr *pstrHostIFkeyAttr)
1529{
1530        s32 result = 0;
1531        struct wid wid;
1532        struct wid strWIDList[5];
1533        u8 i;
1534        u8 *pu8keybuf;
1535        s8 s8idxarray[1];
1536        s8 ret = 0;
1537        struct host_if_drv *hif_drv = vif->hif_drv;
1538
1539        switch (pstrHostIFkeyAttr->type) {
1540        case WEP:
1541
1542                if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1543                        strWIDList[0].id = (u16)WID_11I_MODE;
1544                        strWIDList[0].type = WID_CHAR;
1545                        strWIDList[0].size = sizeof(char);
1546                        strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
1547
1548                        strWIDList[1].id = WID_AUTH_TYPE;
1549                        strWIDList[1].type = WID_CHAR;
1550                        strWIDList[1].size = sizeof(char);
1551                        strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
1552
1553                        pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2,
1554                                            GFP_KERNEL);
1555                        if (!pu8keybuf)
1556                                return -ENOMEM;
1557
1558                        pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1559                        pu8keybuf[1] = pstrHostIFkeyAttr->attr.wep.key_len;
1560
1561                        memcpy(&pu8keybuf[2], pstrHostIFkeyAttr->attr.wep.key,
1562                               pstrHostIFkeyAttr->attr.wep.key_len);
1563
1564                        kfree(pstrHostIFkeyAttr->attr.wep.key);
1565
1566                        strWIDList[2].id = (u16)WID_WEP_KEY_VALUE;
1567                        strWIDList[2].type = WID_STR;
1568                        strWIDList[2].size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1569                        strWIDList[2].val = (s8 *)pu8keybuf;
1570
1571                        result = wilc_send_config_pkt(vif, SET_CFG,
1572                                                      strWIDList, 3,
1573                                                      wilc_get_vif_idx(vif));
1574                        kfree(pu8keybuf);
1575                } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1576                        pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
1577                        if (!pu8keybuf)
1578                                return -ENOMEM;
1579                        pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1580                        memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1581                        memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
1582                               pstrHostIFkeyAttr->attr.wep.key_len);
1583                        kfree(pstrHostIFkeyAttr->attr.wep.key);
1584
1585                        wid.id = (u16)WID_ADD_WEP_KEY;
1586                        wid.type = WID_STR;
1587                        wid.val = (s8 *)pu8keybuf;
1588                        wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1589
1590                        result = wilc_send_config_pkt(vif, SET_CFG,
1591                                                      &wid, 1,
1592                                                      wilc_get_vif_idx(vif));
1593                        kfree(pu8keybuf);
1594                } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
1595                        wid.id = (u16)WID_REMOVE_WEP_KEY;
1596                        wid.type = WID_STR;
1597
1598                        s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
1599                        wid.val = s8idxarray;
1600                        wid.size = 1;
1601
1602                        result = wilc_send_config_pkt(vif, SET_CFG,
1603                                                      &wid, 1,
1604                                                      wilc_get_vif_idx(vif));
1605                } else if (pstrHostIFkeyAttr->action & DEFAULTKEY) {
1606                        wid.id = (u16)WID_KEY_ID;
1607                        wid.type = WID_CHAR;
1608                        wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1609                        wid.size = sizeof(char);
1610
1611                        result = wilc_send_config_pkt(vif, SET_CFG,
1612                                                      &wid, 1,
1613                                                      wilc_get_vif_idx(vif));
1614                }
1615                complete(&hif_drv->comp_test_key_block);
1616                break;
1617
1618        case WPA_RX_GTK:
1619                if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1620                        pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1621                        if (!pu8keybuf) {
1622                                ret = -ENOMEM;
1623                                goto _WPARxGtk_end_case_;
1624                        }
1625
1626                        if (pstrHostIFkeyAttr->attr.wpa.seq)
1627                                memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1628
1629                        memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1630                        memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1631                        memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1632                               pstrHostIFkeyAttr->attr.wpa.key_len);
1633
1634                        strWIDList[0].id = (u16)WID_11I_MODE;
1635                        strWIDList[0].type = WID_CHAR;
1636                        strWIDList[0].size = sizeof(char);
1637                        strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1638
1639                        strWIDList[1].id = (u16)WID_ADD_RX_GTK;
1640                        strWIDList[1].type = WID_STR;
1641                        strWIDList[1].val = (s8 *)pu8keybuf;
1642                        strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
1643
1644                        result = wilc_send_config_pkt(vif, SET_CFG,
1645                                                      strWIDList, 2,
1646                                                      wilc_get_vif_idx(vif));
1647
1648                        kfree(pu8keybuf);
1649                        complete(&hif_drv->comp_test_key_block);
1650                } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1651                        pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1652                        if (!pu8keybuf) {
1653                                ret = -ENOMEM;
1654                                goto _WPARxGtk_end_case_;
1655                        }
1656
1657                        if (hif_drv->hif_state == HOST_IF_CONNECTED)
1658                                memcpy(pu8keybuf, hif_drv->assoc_bssid, ETH_ALEN);
1659                        else
1660                                netdev_err(vif->ndev, "Couldn't handle\n");
1661
1662                        memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1663                        memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1664                        memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1665                        memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1666                               pstrHostIFkeyAttr->attr.wpa.key_len);
1667
1668                        wid.id = (u16)WID_ADD_RX_GTK;
1669                        wid.type = WID_STR;
1670                        wid.val = (s8 *)pu8keybuf;
1671                        wid.size = RX_MIC_KEY_MSG_LEN;
1672
1673                        result = wilc_send_config_pkt(vif, SET_CFG,
1674                                                      &wid, 1,
1675                                                      wilc_get_vif_idx(vif));
1676
1677                        kfree(pu8keybuf);
1678                        complete(&hif_drv->comp_test_key_block);
1679                }
1680_WPARxGtk_end_case_:
1681                kfree(pstrHostIFkeyAttr->attr.wpa.key);
1682                kfree(pstrHostIFkeyAttr->attr.wpa.seq);
1683                if (ret)
1684                        return ret;
1685
1686                break;
1687
1688        case WPA_PTK:
1689                if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1690                        pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
1691                        if (!pu8keybuf) {
1692                                ret = -ENOMEM;
1693                                goto _WPAPtk_end_case_;
1694                        }
1695
1696                        memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1697                        memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1698                        memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1699                        memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
1700                               pstrHostIFkeyAttr->attr.wpa.key_len);
1701
1702                        strWIDList[0].id = (u16)WID_11I_MODE;
1703                        strWIDList[0].type = WID_CHAR;
1704                        strWIDList[0].size = sizeof(char);
1705                        strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1706
1707                        strWIDList[1].id = (u16)WID_ADD_PTK;
1708                        strWIDList[1].type = WID_STR;
1709                        strWIDList[1].val = (s8 *)pu8keybuf;
1710                        strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
1711
1712                        result = wilc_send_config_pkt(vif, SET_CFG,
1713                                                      strWIDList, 2,
1714                                                      wilc_get_vif_idx(vif));
1715                        kfree(pu8keybuf);
1716                        complete(&hif_drv->comp_test_key_block);
1717                } else if (pstrHostIFkeyAttr->action & ADDKEY) {
1718                        pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
1719                        if (!pu8keybuf) {
1720                                netdev_err(vif->ndev, "No buffer send PTK\n");
1721                                ret = -ENOMEM;
1722                                goto _WPAPtk_end_case_;
1723                        }
1724
1725                        memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1726                        memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1727                        memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
1728                               pstrHostIFkeyAttr->attr.wpa.key_len);
1729
1730                        wid.id = (u16)WID_ADD_PTK;
1731                        wid.type = WID_STR;
1732                        wid.val = (s8 *)pu8keybuf;
1733                        wid.size = PTK_KEY_MSG_LEN;
1734
1735                        result = wilc_send_config_pkt(vif, SET_CFG,
1736                                                      &wid, 1,
1737                                                      wilc_get_vif_idx(vif));
1738                        kfree(pu8keybuf);
1739                        complete(&hif_drv->comp_test_key_block);
1740                }
1741
1742_WPAPtk_end_case_:
1743                kfree(pstrHostIFkeyAttr->attr.wpa.key);
1744                if (ret)
1745                        return ret;
1746
1747                break;
1748
1749        case PMKSA:
1750                pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
1751                if (!pu8keybuf)
1752                        return -ENOMEM;
1753
1754                pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
1755
1756                for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1757                        memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1758                        memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
1759                }
1760
1761                wid.id = (u16)WID_PMKID_INFO;
1762                wid.type = WID_STR;
1763                wid.val = (s8 *)pu8keybuf;
1764                wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
1765
1766                result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1767                                              wilc_get_vif_idx(vif));
1768
1769                kfree(pu8keybuf);
1770                break;
1771        }
1772
1773        if (result)
1774                netdev_err(vif->ndev, "Failed to send key config packet\n");
1775
1776        return result;
1777}
1778
1779static void Handle_Disconnect(struct wilc_vif *vif)
1780{
1781        struct wid wid;
1782        struct host_if_drv *hif_drv = vif->hif_drv;
1783
1784        s32 result = 0;
1785        u16 u16DummyReasonCode = 0;
1786
1787        wid.id = (u16)WID_DISCONNECT;
1788        wid.type = WID_CHAR;
1789        wid.val = (s8 *)&u16DummyReasonCode;
1790        wid.size = sizeof(char);
1791
1792        wilc_optaining_ip = false;
1793        wilc_set_power_mgmt(vif, 0, 0);
1794
1795        eth_zero_addr(wilc_connected_ssid);
1796
1797        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1798                                      wilc_get_vif_idx(vif));
1799
1800        if (result) {
1801                netdev_err(vif->ndev, "Failed to send dissconect\n");
1802        } else {
1803                struct disconnect_info strDisconnectNotifInfo;
1804
1805                memset(&strDisconnectNotifInfo, 0, sizeof(struct disconnect_info));
1806
1807                strDisconnectNotifInfo.reason = 0;
1808                strDisconnectNotifInfo.ie = NULL;
1809                strDisconnectNotifInfo.ie_len = 0;
1810
1811                if (hif_drv->usr_scan_req.scan_result) {
1812                        del_timer(&hif_drv->scan_timer);
1813                        hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED,
1814                                                          NULL,
1815                                                          hif_drv->usr_scan_req.arg,
1816                                                          NULL);
1817                        hif_drv->usr_scan_req.scan_result = NULL;
1818                }
1819
1820                if (hif_drv->usr_conn_req.conn_result) {
1821                        if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP)
1822                                del_timer(&hif_drv->connect_timer);
1823
1824                        hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1825                                                          NULL,
1826                                                          0,
1827                                                          &strDisconnectNotifInfo,
1828                                                          hif_drv->usr_conn_req.arg);
1829                } else {
1830                        netdev_err(vif->ndev, "conn_result = NULL\n");
1831                }
1832
1833                scan_while_connected = false;
1834
1835                hif_drv->hif_state = HOST_IF_IDLE;
1836
1837                eth_zero_addr(hif_drv->assoc_bssid);
1838
1839                hif_drv->usr_conn_req.ssid_len = 0;
1840                kfree(hif_drv->usr_conn_req.ssid);
1841                hif_drv->usr_conn_req.ssid = NULL;
1842                kfree(hif_drv->usr_conn_req.bssid);
1843                hif_drv->usr_conn_req.bssid = NULL;
1844                hif_drv->usr_conn_req.ies_len = 0;
1845                kfree(hif_drv->usr_conn_req.ies);
1846                hif_drv->usr_conn_req.ies = NULL;
1847
1848                if (join_req && join_req_vif == vif) {
1849                        kfree(join_req);
1850                        join_req = NULL;
1851                }
1852
1853                if (info_element && join_req_vif == vif) {
1854                        kfree(info_element);
1855                        info_element = NULL;
1856                }
1857        }
1858
1859        complete(&hif_drv->comp_test_disconn_block);
1860}
1861
1862void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
1863{
1864        if (!vif->hif_drv)
1865                return;
1866        if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) ||
1867            (vif->hif_drv->hif_state == HOST_IF_CONNECTING))
1868                wilc_disconnect(vif, 1);
1869}
1870
1871static void Handle_GetRssi(struct wilc_vif *vif)
1872{
1873        s32 result = 0;
1874        struct wid wid;
1875
1876        wid.id = (u16)WID_RSSI;
1877        wid.type = WID_CHAR;
1878        wid.val = &rssi;
1879        wid.size = sizeof(char);
1880
1881        result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1882                                      wilc_get_vif_idx(vif));
1883        if (result) {
1884                netdev_err(vif->ndev, "Failed to get RSSI value\n");
1885                result = -EFAULT;
1886        }
1887
1888        complete(&vif->hif_drv->comp_get_rssi);
1889}
1890
1891static s32 Handle_GetStatistics(struct wilc_vif *vif,
1892                                struct rf_info *pstrStatistics)
1893{
1894        struct wid strWIDList[5];
1895        u32 u32WidsCount = 0, result = 0;
1896
1897        strWIDList[u32WidsCount].id = WID_LINKSPEED;
1898        strWIDList[u32WidsCount].type = WID_CHAR;
1899        strWIDList[u32WidsCount].size = sizeof(char);
1900        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->link_speed;
1901        u32WidsCount++;
1902
1903        strWIDList[u32WidsCount].id = WID_RSSI;
1904        strWIDList[u32WidsCount].type = WID_CHAR;
1905        strWIDList[u32WidsCount].size = sizeof(char);
1906        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rssi;
1907        u32WidsCount++;
1908
1909        strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
1910        strWIDList[u32WidsCount].type = WID_INT;
1911        strWIDList[u32WidsCount].size = sizeof(u32);
1912        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_cnt;
1913        u32WidsCount++;
1914
1915        strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
1916        strWIDList[u32WidsCount].type = WID_INT;
1917        strWIDList[u32WidsCount].size = sizeof(u32);
1918        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->rx_cnt;
1919        u32WidsCount++;
1920
1921        strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
1922        strWIDList[u32WidsCount].type = WID_INT;
1923        strWIDList[u32WidsCount].size = sizeof(u32);
1924        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->tx_fail_cnt;
1925        u32WidsCount++;
1926
1927        result = wilc_send_config_pkt(vif, GET_CFG, strWIDList,
1928                                      u32WidsCount,
1929                                      wilc_get_vif_idx(vif));
1930
1931        if (result)
1932                netdev_err(vif->ndev, "Failed to send scan parameters\n");
1933
1934        if (pstrStatistics->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
1935            pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
1936                wilc_enable_tcp_ack_filter(true);
1937        else if (pstrStatistics->link_speed != DEFAULT_LINK_SPEED)
1938                wilc_enable_tcp_ack_filter(false);
1939
1940        if (pstrStatistics != &vif->wilc->dummy_statistics)
1941                complete(&hif_wait_response);
1942        return 0;
1943}
1944
1945static s32 Handle_Get_InActiveTime(struct wilc_vif *vif,
1946                                   struct sta_inactive_t *strHostIfStaInactiveT)
1947{
1948        s32 result = 0;
1949        u8 *stamac;
1950        struct wid wid;
1951        struct host_if_drv *hif_drv = vif->hif_drv;
1952
1953        wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
1954        wid.type = WID_STR;
1955        wid.size = ETH_ALEN;
1956        wid.val = kmalloc(wid.size, GFP_KERNEL);
1957        if (!wid.val)
1958                return -ENOMEM;
1959
1960        stamac = wid.val;
1961        ether_addr_copy(stamac, strHostIfStaInactiveT->mac);
1962
1963        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1964                                      wilc_get_vif_idx(vif));
1965
1966        if (result) {
1967                netdev_err(vif->ndev, "Failed to SET inactive time\n");
1968                return -EFAULT;
1969        }
1970
1971        wid.id = (u16)WID_GET_INACTIVE_TIME;
1972        wid.type = WID_INT;
1973        wid.val = (s8 *)&inactive_time;
1974        wid.size = sizeof(u32);
1975
1976        result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
1977                                      wilc_get_vif_idx(vif));
1978
1979        if (result) {
1980                netdev_err(vif->ndev, "Failed to get inactive time\n");
1981                return -EFAULT;
1982        }
1983
1984        complete(&hif_drv->comp_inactive_time);
1985
1986        return result;
1987}
1988
1989static void Handle_AddBeacon(struct wilc_vif *vif,
1990                             struct beacon_attr *pstrSetBeaconParam)
1991{
1992        s32 result = 0;
1993        struct wid wid;
1994        u8 *pu8CurrByte;
1995
1996        wid.id = (u16)WID_ADD_BEACON;
1997        wid.type = WID_BIN;
1998        wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
1999        wid.val = kmalloc(wid.size, GFP_KERNEL);
2000        if (!wid.val)
2001                goto ERRORHANDLER;
2002
2003        pu8CurrByte = wid.val;
2004        *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
2005        *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
2006        *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
2007        *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
2008
2009        *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
2010        *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
2011        *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
2012        *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
2013
2014        *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
2015        *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
2016        *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
2017        *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
2018
2019        memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
2020        pu8CurrByte += pstrSetBeaconParam->head_len;
2021
2022        *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
2023        *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
2024        *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
2025        *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
2026
2027        if (pstrSetBeaconParam->tail)
2028                memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
2029        pu8CurrByte += pstrSetBeaconParam->tail_len;
2030
2031        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2032                                      wilc_get_vif_idx(vif));
2033        if (result)
2034                netdev_err(vif->ndev, "Failed to send add beacon\n");
2035
2036ERRORHANDLER:
2037        kfree(wid.val);
2038        kfree(pstrSetBeaconParam->head);
2039        kfree(pstrSetBeaconParam->tail);
2040}
2041
2042static void Handle_DelBeacon(struct wilc_vif *vif)
2043{
2044        s32 result = 0;
2045        struct wid wid;
2046        u8 *pu8CurrByte;
2047
2048        wid.id = (u16)WID_DEL_BEACON;
2049        wid.type = WID_CHAR;
2050        wid.size = sizeof(char);
2051        wid.val = &del_beacon;
2052
2053        if (!wid.val)
2054                return;
2055
2056        pu8CurrByte = wid.val;
2057
2058        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2059                                      wilc_get_vif_idx(vif));
2060        if (result)
2061                netdev_err(vif->ndev, "Failed to send delete beacon\n");
2062}
2063
2064static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2065                                    struct add_sta_param *pstrStationParam)
2066{
2067        u8 *pu8CurrByte;
2068
2069        pu8CurrByte = pu8Buffer;
2070
2071        memcpy(pu8CurrByte, pstrStationParam->bssid, ETH_ALEN);
2072        pu8CurrByte +=  ETH_ALEN;
2073
2074        *pu8CurrByte++ = pstrStationParam->aid & 0xFF;
2075        *pu8CurrByte++ = (pstrStationParam->aid >> 8) & 0xFF;
2076
2077        *pu8CurrByte++ = pstrStationParam->rates_len;
2078        if (pstrStationParam->rates_len > 0)
2079                memcpy(pu8CurrByte, pstrStationParam->rates,
2080                       pstrStationParam->rates_len);
2081        pu8CurrByte += pstrStationParam->rates_len;
2082
2083        *pu8CurrByte++ = pstrStationParam->ht_supported;
2084        memcpy(pu8CurrByte, &pstrStationParam->ht_capa,
2085               sizeof(struct ieee80211_ht_cap));
2086        pu8CurrByte += sizeof(struct ieee80211_ht_cap);
2087
2088        *pu8CurrByte++ = pstrStationParam->flags_mask & 0xFF;
2089        *pu8CurrByte++ = (pstrStationParam->flags_mask >> 8) & 0xFF;
2090
2091        *pu8CurrByte++ = pstrStationParam->flags_set & 0xFF;
2092        *pu8CurrByte++ = (pstrStationParam->flags_set >> 8) & 0xFF;
2093
2094        return pu8CurrByte - pu8Buffer;
2095}
2096
2097static void Handle_AddStation(struct wilc_vif *vif,
2098                              struct add_sta_param *pstrStationParam)
2099{
2100        s32 result = 0;
2101        struct wid wid;
2102        u8 *pu8CurrByte;
2103
2104        wid.id = (u16)WID_ADD_STA;
2105        wid.type = WID_BIN;
2106        wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
2107
2108        wid.val = kmalloc(wid.size, GFP_KERNEL);
2109        if (!wid.val)
2110                goto ERRORHANDLER;
2111
2112        pu8CurrByte = wid.val;
2113        pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2114
2115        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2116                                      wilc_get_vif_idx(vif));
2117        if (result != 0)
2118                netdev_err(vif->ndev, "Failed to send add station\n");
2119
2120ERRORHANDLER:
2121        kfree(pstrStationParam->rates);
2122        kfree(wid.val);
2123}
2124
2125static void Handle_DelAllSta(struct wilc_vif *vif,
2126                             struct del_all_sta *pstrDelAllStaParam)
2127{
2128        s32 result = 0;
2129        struct wid wid;
2130        u8 *pu8CurrByte;
2131        u8 i;
2132        u8 au8Zero_Buff[6] = {0};
2133
2134        wid.id = (u16)WID_DEL_ALL_STA;
2135        wid.type = WID_STR;
2136        wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
2137
2138        wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2139        if (!wid.val)
2140                goto ERRORHANDLER;
2141
2142        pu8CurrByte = wid.val;
2143
2144        *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
2145
2146        for (i = 0; i < MAX_NUM_STA; i++) {
2147                if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2148                        memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
2149                else
2150                        continue;
2151
2152                pu8CurrByte += ETH_ALEN;
2153        }
2154
2155        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2156                                      wilc_get_vif_idx(vif));
2157        if (result)
2158                netdev_err(vif->ndev, "Failed to send add station\n");
2159
2160ERRORHANDLER:
2161        kfree(wid.val);
2162
2163        complete(&hif_wait_response);
2164}
2165
2166static void Handle_DelStation(struct wilc_vif *vif,
2167                              struct del_sta *pstrDelStaParam)
2168{
2169        s32 result = 0;
2170        struct wid wid;
2171        u8 *pu8CurrByte;
2172
2173        wid.id = (u16)WID_REMOVE_STA;
2174        wid.type = WID_BIN;
2175        wid.size = ETH_ALEN;
2176
2177        wid.val = kmalloc(wid.size, GFP_KERNEL);
2178        if (!wid.val)
2179                goto ERRORHANDLER;
2180
2181        pu8CurrByte = wid.val;
2182
2183        ether_addr_copy(pu8CurrByte, pstrDelStaParam->mac_addr);
2184
2185        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2186                                      wilc_get_vif_idx(vif));
2187        if (result)
2188                netdev_err(vif->ndev, "Failed to send add station\n");
2189
2190ERRORHANDLER:
2191        kfree(wid.val);
2192}
2193
2194static void Handle_EditStation(struct wilc_vif *vif,
2195                               struct add_sta_param *pstrStationParam)
2196{
2197        s32 result = 0;
2198        struct wid wid;
2199        u8 *pu8CurrByte;
2200
2201        wid.id = (u16)WID_EDIT_STA;
2202        wid.type = WID_BIN;
2203        wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->rates_len;
2204
2205        wid.val = kmalloc(wid.size, GFP_KERNEL);
2206        if (!wid.val)
2207                goto ERRORHANDLER;
2208
2209        pu8CurrByte = wid.val;
2210        pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2211
2212        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2213                                      wilc_get_vif_idx(vif));
2214        if (result)
2215                netdev_err(vif->ndev, "Failed to send edit station\n");
2216
2217ERRORHANDLER:
2218        kfree(pstrStationParam->rates);
2219        kfree(wid.val);
2220}
2221
2222static int Handle_RemainOnChan(struct wilc_vif *vif,
2223                               struct remain_ch *pstrHostIfRemainOnChan)
2224{
2225        s32 result = 0;
2226        u8 u8remain_on_chan_flag;
2227        struct wid wid;
2228        struct host_if_drv *hif_drv = vif->hif_drv;
2229
2230        if (!hif_drv->remain_on_ch_pending) {
2231                hif_drv->remain_on_ch.arg = pstrHostIfRemainOnChan->arg;
2232                hif_drv->remain_on_ch.expired = pstrHostIfRemainOnChan->expired;
2233                hif_drv->remain_on_ch.ready = pstrHostIfRemainOnChan->ready;
2234                hif_drv->remain_on_ch.ch = pstrHostIfRemainOnChan->ch;
2235                hif_drv->remain_on_ch.id = pstrHostIfRemainOnChan->id;
2236        } else {
2237                pstrHostIfRemainOnChan->ch = hif_drv->remain_on_ch.ch;
2238        }
2239
2240        if (hif_drv->usr_scan_req.scan_result) {
2241                hif_drv->remain_on_ch_pending = 1;
2242                result = -EBUSY;
2243                goto ERRORHANDLER;
2244        }
2245        if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) {
2246                result = -EBUSY;
2247                goto ERRORHANDLER;
2248        }
2249
2250        if (wilc_optaining_ip || wilc_connecting) {
2251                result = -EBUSY;
2252                goto ERRORHANDLER;
2253        }
2254
2255        u8remain_on_chan_flag = true;
2256        wid.id = (u16)WID_REMAIN_ON_CHAN;
2257        wid.type = WID_STR;
2258        wid.size = 2;
2259        wid.val = kmalloc(wid.size, GFP_KERNEL);
2260        if (!wid.val) {
2261                result = -ENOMEM;
2262                goto ERRORHANDLER;
2263        }
2264
2265        wid.val[0] = u8remain_on_chan_flag;
2266        wid.val[1] = (s8)pstrHostIfRemainOnChan->ch;
2267
2268        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2269                                      wilc_get_vif_idx(vif));
2270        if (result != 0)
2271                netdev_err(vif->ndev, "Failed to set remain on channel\n");
2272
2273ERRORHANDLER:
2274        {
2275                P2P_LISTEN_STATE = 1;
2276                hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
2277                mod_timer(&hif_drv->remain_on_ch_timer,
2278                          jiffies +
2279                          msecs_to_jiffies(pstrHostIfRemainOnChan->duration));
2280
2281                if (hif_drv->remain_on_ch.ready)
2282                        hif_drv->remain_on_ch.ready(hif_drv->remain_on_ch.arg);
2283
2284                if (hif_drv->remain_on_ch_pending)
2285                        hif_drv->remain_on_ch_pending = 0;
2286        }
2287
2288        return result;
2289}
2290
2291static int Handle_RegisterFrame(struct wilc_vif *vif,
2292                                struct reg_frame *pstrHostIfRegisterFrame)
2293{
2294        s32 result = 0;
2295        struct wid wid;
2296        u8 *pu8CurrByte;
2297
2298        wid.id = (u16)WID_REGISTER_FRAME;
2299        wid.type = WID_STR;
2300        wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2301        if (!wid.val)
2302                return -ENOMEM;
2303
2304        pu8CurrByte = wid.val;
2305
2306        *pu8CurrByte++ = pstrHostIfRegisterFrame->reg;
2307        *pu8CurrByte++ = pstrHostIfRegisterFrame->reg_id;
2308        memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->frame_type, sizeof(u16));
2309
2310        wid.size = sizeof(u16) + 2;
2311
2312        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2313                                      wilc_get_vif_idx(vif));
2314        if (result) {
2315                netdev_err(vif->ndev, "Failed to frame register\n");
2316                result = -EINVAL;
2317        }
2318
2319        return result;
2320}
2321
2322static u32 Handle_ListenStateExpired(struct wilc_vif *vif,
2323                                     struct remain_ch *pstrHostIfRemainOnChan)
2324{
2325        u8 u8remain_on_chan_flag;
2326        struct wid wid;
2327        s32 result = 0;
2328        struct host_if_drv *hif_drv = vif->hif_drv;
2329
2330        if (P2P_LISTEN_STATE) {
2331                u8remain_on_chan_flag = false;
2332                wid.id = (u16)WID_REMAIN_ON_CHAN;
2333                wid.type = WID_STR;
2334                wid.size = 2;
2335                wid.val = kmalloc(wid.size, GFP_KERNEL);
2336
2337                if (!wid.val)
2338                        return -ENOMEM;
2339
2340                wid.val[0] = u8remain_on_chan_flag;
2341                wid.val[1] = FALSE_FRMWR_CHANNEL;
2342
2343                result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2344                                              wilc_get_vif_idx(vif));
2345                if (result != 0) {
2346                        netdev_err(vif->ndev, "Failed to set remain channel\n");
2347                        goto _done_;
2348                }
2349
2350                if (hif_drv->remain_on_ch.expired) {
2351                        hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
2352                                                      pstrHostIfRemainOnChan->id);
2353                }
2354                P2P_LISTEN_STATE = 0;
2355        } else {
2356                netdev_dbg(vif->ndev, "Not in listen state\n");
2357                result = -EFAULT;
2358        }
2359
2360_done_:
2361        return result;
2362}
2363
2364static void ListenTimerCB(unsigned long arg)
2365{
2366        s32 result = 0;
2367        struct host_if_msg msg;
2368        struct wilc_vif *vif = (struct wilc_vif *)arg;
2369
2370        del_timer(&vif->hif_drv->remain_on_ch_timer);
2371
2372        memset(&msg, 0, sizeof(struct host_if_msg));
2373        msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
2374        msg.vif = vif;
2375        msg.body.remain_on_ch.id = vif->hif_drv->remain_on_ch.id;
2376
2377        result = wilc_enqueue_cmd(&msg);
2378        if (result)
2379                netdev_err(vif->ndev, "wilc_mq_send fail\n");
2380}
2381
2382static void Handle_PowerManagement(struct wilc_vif *vif,
2383                                   struct power_mgmt_param *strPowerMgmtParam)
2384{
2385        s32 result = 0;
2386        struct wid wid;
2387        s8 s8PowerMode;
2388
2389        wid.id = (u16)WID_POWER_MANAGEMENT;
2390
2391        if (strPowerMgmtParam->enabled)
2392                s8PowerMode = MIN_FAST_PS;
2393        else
2394                s8PowerMode = NO_POWERSAVE;
2395
2396        wid.val = &s8PowerMode;
2397        wid.size = sizeof(char);
2398
2399        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2400                                      wilc_get_vif_idx(vif));
2401        if (result)
2402                netdev_err(vif->ndev, "Failed to send power management\n");
2403}
2404
2405static void Handle_SetMulticastFilter(struct wilc_vif *vif,
2406                                      struct set_multicast *strHostIfSetMulti)
2407{
2408        s32 result = 0;
2409        struct wid wid;
2410        u8 *pu8CurrByte;
2411
2412        wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2413        wid.type = WID_BIN;
2414        wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
2415        wid.val = kmalloc(wid.size, GFP_KERNEL);
2416        if (!wid.val)
2417                goto ERRORHANDLER;
2418
2419        pu8CurrByte = wid.val;
2420        *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
2421        *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
2422        *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
2423        *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
2424
2425        *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2426        *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2427        *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2428        *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
2429
2430        if ((strHostIfSetMulti->cnt) > 0)
2431                memcpy(pu8CurrByte, wilc_multicast_mac_addr_list,
2432                       ((strHostIfSetMulti->cnt) * ETH_ALEN));
2433
2434        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2435                                      wilc_get_vif_idx(vif));
2436        if (result)
2437                netdev_err(vif->ndev, "Failed to send setup multicast\n");
2438
2439ERRORHANDLER:
2440        kfree(wid.val);
2441}
2442
2443static void handle_set_tx_pwr(struct wilc_vif *vif, u8 tx_pwr)
2444{
2445        int ret;
2446        struct wid wid;
2447
2448        wid.id = (u16)WID_TX_POWER;
2449        wid.type = WID_CHAR;
2450        wid.val = &tx_pwr;
2451        wid.size = sizeof(char);
2452
2453        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
2454                                   wilc_get_vif_idx(vif));
2455        if (ret)
2456                netdev_err(vif->ndev, "Failed to set TX PWR\n");
2457}
2458
2459static void handle_get_tx_pwr(struct wilc_vif *vif, u8 *tx_pwr)
2460{
2461        int ret = 0;
2462        struct wid wid;
2463
2464        wid.id = (u16)WID_TX_POWER;
2465        wid.type = WID_CHAR;
2466        wid.val = (s8 *)tx_pwr;
2467        wid.size = sizeof(char);
2468
2469        ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
2470                                   wilc_get_vif_idx(vif));
2471        if (ret)
2472                netdev_err(vif->ndev, "Failed to get TX PWR\n");
2473
2474        complete(&hif_wait_response);
2475}
2476
2477static void host_if_work(struct work_struct *work)
2478{
2479        struct host_if_msg *msg;
2480        struct wilc *wilc;
2481        int ret = 0;
2482
2483        msg = container_of(work, struct host_if_msg, work);
2484        wilc = msg->vif->wilc;
2485
2486        if (msg->id == HOST_IF_MSG_CONNECT &&
2487            msg->vif->hif_drv->usr_scan_req.scan_result) {
2488                wilc_enqueue_cmd(msg);
2489                usleep_range(2 * 1000, 2 * 1000);
2490                goto free_msg;
2491        }
2492        switch (msg->id) {
2493        case HOST_IF_MSG_SCAN:
2494                handle_scan(msg->vif, &msg->body.scan_info);
2495                break;
2496
2497        case HOST_IF_MSG_CONNECT:
2498                Handle_Connect(msg->vif, &msg->body.con_info);
2499                break;
2500
2501        case HOST_IF_MSG_RCVD_NTWRK_INFO:
2502                Handle_RcvdNtwrkInfo(msg->vif, &msg->body.net_info);
2503                break;
2504
2505        case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2506                Handle_RcvdGnrlAsyncInfo(msg->vif,
2507                                         &msg->body.async_info);
2508                break;
2509
2510        case HOST_IF_MSG_KEY:
2511                Handle_Key(msg->vif, &msg->body.key_info);
2512                break;
2513
2514        case HOST_IF_MSG_CFG_PARAMS:
2515                handle_cfg_param(msg->vif, &msg->body.cfg_info);
2516                break;
2517
2518        case HOST_IF_MSG_SET_CHANNEL:
2519                handle_set_channel(msg->vif, &msg->body.channel_info);
2520                break;
2521
2522        case HOST_IF_MSG_DISCONNECT:
2523                Handle_Disconnect(msg->vif);
2524                break;
2525
2526        case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2527                del_timer(&msg->vif->hif_drv->scan_timer);
2528
2529                if (!wilc_wlan_get_num_conn_ifcs(wilc))
2530                        wilc_chip_sleep_manually(wilc);
2531
2532                Handle_ScanDone(msg->vif, SCAN_EVENT_DONE);
2533
2534                if (msg->vif->hif_drv->remain_on_ch_pending)
2535                        Handle_RemainOnChan(msg->vif,
2536                                            &msg->body.remain_on_ch);
2537
2538                break;
2539
2540        case HOST_IF_MSG_GET_RSSI:
2541                Handle_GetRssi(msg->vif);
2542                break;
2543
2544        case HOST_IF_MSG_GET_STATISTICS:
2545                Handle_GetStatistics(msg->vif,
2546                                     (struct rf_info *)msg->body.data);
2547                break;
2548
2549        case HOST_IF_MSG_ADD_BEACON:
2550                Handle_AddBeacon(msg->vif, &msg->body.beacon_info);
2551                break;
2552
2553        case HOST_IF_MSG_DEL_BEACON:
2554                Handle_DelBeacon(msg->vif);
2555                break;
2556
2557        case HOST_IF_MSG_ADD_STATION:
2558                Handle_AddStation(msg->vif, &msg->body.add_sta_info);
2559                break;
2560
2561        case HOST_IF_MSG_DEL_STATION:
2562                Handle_DelStation(msg->vif, &msg->body.del_sta_info);
2563                break;
2564
2565        case HOST_IF_MSG_EDIT_STATION:
2566                Handle_EditStation(msg->vif, &msg->body.edit_sta_info);
2567                break;
2568
2569        case HOST_IF_MSG_GET_INACTIVETIME:
2570                Handle_Get_InActiveTime(msg->vif, &msg->body.mac_info);
2571                break;
2572
2573        case HOST_IF_MSG_SCAN_TIMER_FIRED:
2574                Handle_ScanDone(msg->vif, SCAN_EVENT_ABORTED);
2575                break;
2576
2577        case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2578                Handle_ConnectTimeout(msg->vif);
2579                break;
2580
2581        case HOST_IF_MSG_POWER_MGMT:
2582                Handle_PowerManagement(msg->vif,
2583                                       &msg->body.pwr_mgmt_info);
2584                break;
2585
2586        case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2587                ret = handle_set_wfi_drv_handler(msg->vif, &msg->body.drv);
2588                break;
2589
2590        case HOST_IF_MSG_SET_OPERATION_MODE:
2591                handle_set_operation_mode(msg->vif, &msg->body.mode);
2592                break;
2593
2594        case HOST_IF_MSG_SET_IPADDRESS:
2595                handle_set_ip_address(msg->vif,
2596                                      msg->body.ip_info.ip_addr,
2597                                      msg->body.ip_info.idx);
2598                break;
2599
2600        case HOST_IF_MSG_GET_IPADDRESS:
2601                handle_get_ip_address(msg->vif, msg->body.ip_info.idx);
2602                break;
2603
2604        case HOST_IF_MSG_GET_MAC_ADDRESS:
2605                handle_get_mac_address(msg->vif,
2606                                       &msg->body.get_mac_info);
2607                break;
2608
2609        case HOST_IF_MSG_REMAIN_ON_CHAN:
2610                Handle_RemainOnChan(msg->vif, &msg->body.remain_on_ch);
2611                break;
2612
2613        case HOST_IF_MSG_REGISTER_FRAME:
2614                Handle_RegisterFrame(msg->vif, &msg->body.reg_frame);
2615                break;
2616
2617        case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2618                Handle_ListenStateExpired(msg->vif, &msg->body.remain_on_ch);
2619                break;
2620
2621        case HOST_IF_MSG_SET_MULTICAST_FILTER:
2622                Handle_SetMulticastFilter(msg->vif, &msg->body.multicast_info);
2623                break;
2624
2625        case HOST_IF_MSG_DEL_ALL_STA:
2626                Handle_DelAllSta(msg->vif, &msg->body.del_all_sta_info);
2627                break;
2628
2629        case HOST_IF_MSG_SET_TX_POWER:
2630                handle_set_tx_pwr(msg->vif, msg->body.tx_power.tx_pwr);
2631                break;
2632
2633        case HOST_IF_MSG_GET_TX_POWER:
2634                handle_get_tx_pwr(msg->vif, &msg->body.tx_power.tx_pwr);
2635                break;
2636        default:
2637                netdev_err(msg->vif->ndev, "[Host Interface] undefined\n");
2638                break;
2639        }
2640free_msg:
2641        if (ret)
2642                netdev_err(msg->vif->ndev, "Host cmd %d failed\n", msg->id);
2643        kfree(msg);
2644        complete(&hif_thread_comp);
2645}
2646
2647static void TimerCB_Scan(unsigned long arg)
2648{
2649        struct wilc_vif *vif = (struct wilc_vif *)arg;
2650        struct host_if_msg msg;
2651
2652        memset(&msg, 0, sizeof(struct host_if_msg));
2653        msg.vif = vif;
2654        msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
2655
2656        wilc_enqueue_cmd(&msg);
2657}
2658
2659static void TimerCB_Connect(unsigned long arg)
2660{
2661        struct wilc_vif *vif = (struct wilc_vif *)arg;
2662        struct host_if_msg msg;
2663
2664        memset(&msg, 0, sizeof(struct host_if_msg));
2665        msg.vif = vif;
2666        msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
2667
2668        wilc_enqueue_cmd(&msg);
2669}
2670
2671s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
2672{
2673        struct wid wid;
2674
2675        wid.id = (u16)WID_REMOVE_KEY;
2676        wid.type = WID_STR;
2677        wid.val = (s8 *)pu8StaAddress;
2678        wid.size = 6;
2679
2680        return 0;
2681}
2682
2683int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
2684{
2685        int result = 0;
2686        struct host_if_msg msg;
2687        struct host_if_drv *hif_drv = vif->hif_drv;
2688
2689        if (!hif_drv) {
2690                result = -EFAULT;
2691                netdev_err(vif->ndev, "Failed to send setup multicast\n");
2692                return result;
2693        }
2694
2695        memset(&msg, 0, sizeof(struct host_if_msg));
2696
2697        msg.id = HOST_IF_MSG_KEY;
2698        msg.body.key_info.type = WEP;
2699        msg.body.key_info.action = REMOVEKEY;
2700        msg.vif = vif;
2701        msg.body.key_info.attr.wep.index = index;
2702
2703        result = wilc_enqueue_cmd(&msg);
2704        if (result)
2705                netdev_err(vif->ndev, "Request to remove WEP key\n");
2706        else
2707                wait_for_completion(&hif_drv->comp_test_key_block);
2708
2709        return result;
2710}
2711
2712int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
2713{
2714        int result = 0;
2715        struct host_if_msg msg;
2716        struct host_if_drv *hif_drv = vif->hif_drv;
2717
2718        if (!hif_drv) {
2719                result = -EFAULT;
2720                netdev_err(vif->ndev, "driver is null\n");
2721                return result;
2722        }
2723
2724        memset(&msg, 0, sizeof(struct host_if_msg));
2725
2726        msg.id = HOST_IF_MSG_KEY;
2727        msg.body.key_info.type = WEP;
2728        msg.body.key_info.action = DEFAULTKEY;
2729        msg.vif = vif;
2730        msg.body.key_info.attr.wep.index = index;
2731
2732        result = wilc_enqueue_cmd(&msg);
2733        if (result)
2734                netdev_err(vif->ndev, "Default key index\n");
2735        else
2736                wait_for_completion(&hif_drv->comp_test_key_block);
2737
2738        return result;
2739}
2740
2741int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
2742                             u8 index)
2743{
2744        int result = 0;
2745        struct host_if_msg msg;
2746        struct host_if_drv *hif_drv = vif->hif_drv;
2747
2748        if (!hif_drv) {
2749                netdev_err(vif->ndev, "driver is null\n");
2750                return -EFAULT;
2751        }
2752
2753        memset(&msg, 0, sizeof(struct host_if_msg));
2754
2755        msg.id = HOST_IF_MSG_KEY;
2756        msg.body.key_info.type = WEP;
2757        msg.body.key_info.action = ADDKEY;
2758        msg.vif = vif;
2759        msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2760        if (!msg.body.key_info.attr.wep.key)
2761                return -ENOMEM;
2762
2763        msg.body.key_info.attr.wep.key_len = len;
2764        msg.body.key_info.attr.wep.index = index;
2765
2766        result = wilc_enqueue_cmd(&msg);
2767        if (result)
2768                netdev_err(vif->ndev, "STA - WEP Key\n");
2769        wait_for_completion(&hif_drv->comp_test_key_block);
2770
2771        return result;
2772}
2773
2774int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
2775                            u8 index, u8 mode, enum AUTHTYPE auth_type)
2776{
2777        int result = 0;
2778        struct host_if_msg msg;
2779        struct host_if_drv *hif_drv = vif->hif_drv;
2780
2781        if (!hif_drv) {
2782                netdev_err(vif->ndev, "driver is null\n");
2783                return -EFAULT;
2784        }
2785
2786        memset(&msg, 0, sizeof(struct host_if_msg));
2787
2788        msg.id = HOST_IF_MSG_KEY;
2789        msg.body.key_info.type = WEP;
2790        msg.body.key_info.action = ADDKEY_AP;
2791        msg.vif = vif;
2792        msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2793        if (!msg.body.key_info.attr.wep.key)
2794                return -ENOMEM;
2795
2796        msg.body.key_info.attr.wep.key_len = len;
2797        msg.body.key_info.attr.wep.index = index;
2798        msg.body.key_info.attr.wep.mode = mode;
2799        msg.body.key_info.attr.wep.auth_type = auth_type;
2800
2801        result = wilc_enqueue_cmd(&msg);
2802
2803        if (result)
2804                netdev_err(vif->ndev, "AP - WEP Key\n");
2805        else
2806                wait_for_completion(&hif_drv->comp_test_key_block);
2807
2808        return result;
2809}
2810
2811int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
2812                 const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
2813                 u8 mode, u8 cipher_mode, u8 index)
2814{
2815        int result = 0;
2816        struct host_if_msg msg;
2817        struct host_if_drv *hif_drv = vif->hif_drv;
2818        u8 key_len = ptk_key_len;
2819
2820        if (!hif_drv) {
2821                netdev_err(vif->ndev, "driver is null\n");
2822                return -EFAULT;
2823        }
2824
2825        if (rx_mic)
2826                key_len += RX_MIC_KEY_LEN;
2827
2828        if (tx_mic)
2829                key_len += TX_MIC_KEY_LEN;
2830
2831        memset(&msg, 0, sizeof(struct host_if_msg));
2832
2833        msg.id = HOST_IF_MSG_KEY;
2834        msg.body.key_info.type = WPA_PTK;
2835        if (mode == AP_MODE) {
2836                msg.body.key_info.action = ADDKEY_AP;
2837                msg.body.key_info.attr.wpa.index = index;
2838        }
2839        if (mode == STATION_MODE)
2840                msg.body.key_info.action = ADDKEY;
2841
2842        msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
2843        if (!msg.body.key_info.attr.wpa.key)
2844                return -ENOMEM;
2845
2846        if (rx_mic)
2847                memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN);
2848
2849        if (tx_mic)
2850                memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN);
2851
2852        msg.body.key_info.attr.wpa.key_len = key_len;
2853        msg.body.key_info.attr.wpa.mac_addr = mac_addr;
2854        msg.body.key_info.attr.wpa.mode = cipher_mode;
2855        msg.vif = vif;
2856
2857        result = wilc_enqueue_cmd(&msg);
2858
2859        if (result)
2860                netdev_err(vif->ndev, "PTK Key\n");
2861        else
2862                wait_for_completion(&hif_drv->comp_test_key_block);
2863
2864        return result;
2865}
2866
2867int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
2868                    u8 index, u32 key_rsc_len, const u8 *key_rsc,
2869                    const u8 *rx_mic, const u8 *tx_mic, u8 mode,
2870                    u8 cipher_mode)
2871{
2872        int result = 0;
2873        struct host_if_msg msg;
2874        struct host_if_drv *hif_drv = vif->hif_drv;
2875        u8 key_len = gtk_key_len;
2876
2877        if (!hif_drv) {
2878                netdev_err(vif->ndev, "driver is null\n");
2879                return -EFAULT;
2880        }
2881        memset(&msg, 0, sizeof(struct host_if_msg));
2882
2883        if (rx_mic)
2884                key_len += RX_MIC_KEY_LEN;
2885
2886        if (tx_mic)
2887                key_len += TX_MIC_KEY_LEN;
2888
2889        if (key_rsc) {
2890                msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
2891                                                         key_rsc_len,
2892                                                         GFP_KERNEL);
2893                if (!msg.body.key_info.attr.wpa.seq)
2894                        return -ENOMEM;
2895        }
2896
2897        msg.id = HOST_IF_MSG_KEY;
2898        msg.body.key_info.type = WPA_RX_GTK;
2899        msg.vif = vif;
2900
2901        if (mode == AP_MODE) {
2902                msg.body.key_info.action = ADDKEY_AP;
2903                msg.body.key_info.attr.wpa.mode = cipher_mode;
2904        }
2905        if (mode == STATION_MODE)
2906                msg.body.key_info.action = ADDKEY;
2907
2908        msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
2909                                                 key_len,
2910                                                 GFP_KERNEL);
2911        if (!msg.body.key_info.attr.wpa.key)
2912                return -ENOMEM;
2913
2914        if (rx_mic)
2915                memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2916                       RX_MIC_KEY_LEN);
2917
2918        if (tx_mic)
2919                memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
2920                       TX_MIC_KEY_LEN);
2921
2922        msg.body.key_info.attr.wpa.index = index;
2923        msg.body.key_info.attr.wpa.key_len = key_len;
2924        msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
2925
2926        result = wilc_enqueue_cmd(&msg);
2927        if (result)
2928                netdev_err(vif->ndev, "RX GTK\n");
2929        else
2930                wait_for_completion(&hif_drv->comp_test_key_block);
2931
2932        return result;
2933}
2934
2935int wilc_set_pmkid_info(struct wilc_vif *vif,
2936                        struct host_if_pmkid_attr *pmkid)
2937{
2938        int result = 0;
2939        struct host_if_msg msg;
2940        int i;
2941
2942        memset(&msg, 0, sizeof(struct host_if_msg));
2943
2944        msg.id = HOST_IF_MSG_KEY;
2945        msg.body.key_info.type = PMKSA;
2946        msg.body.key_info.action = ADDKEY;
2947        msg.vif = vif;
2948
2949        for (i = 0; i < pmkid->numpmkid; i++) {
2950                memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
2951                       &pmkid->pmkidlist[i].bssid, ETH_ALEN);
2952                memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
2953                       &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
2954        }
2955
2956        result = wilc_enqueue_cmd(&msg);
2957        if (result)
2958                netdev_err(vif->ndev, "PMKID Info\n");
2959
2960        return result;
2961}
2962
2963int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
2964{
2965        int result = 0;
2966        struct host_if_msg msg;
2967
2968        memset(&msg, 0, sizeof(struct host_if_msg));
2969
2970        msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
2971        msg.body.get_mac_info.mac_addr = mac_addr;
2972        msg.vif = vif;
2973
2974        result = wilc_enqueue_cmd(&msg);
2975        if (result) {
2976                netdev_err(vif->ndev, "Failed to send get mac address\n");
2977                return -EFAULT;
2978        }
2979
2980        wait_for_completion(&hif_wait_response);
2981        return result;
2982}
2983
2984int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
2985                      size_t ssid_len, const u8 *ies, size_t ies_len,
2986                      wilc_connect_result connect_result, void *user_arg,
2987                      u8 security, enum AUTHTYPE auth_type,
2988                      u8 channel, void *join_params)
2989{
2990        int result = 0;
2991        struct host_if_msg msg;
2992        struct host_if_drv *hif_drv = vif->hif_drv;
2993
2994        if (!hif_drv || !connect_result) {
2995                netdev_err(vif->ndev, "Driver is null\n");
2996                return -EFAULT;
2997        }
2998
2999        if (!join_params) {
3000                netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
3001                return -EFAULT;
3002        }
3003
3004        memset(&msg, 0, sizeof(struct host_if_msg));
3005
3006        msg.id = HOST_IF_MSG_CONNECT;
3007
3008        msg.body.con_info.security = security;
3009        msg.body.con_info.auth_type = auth_type;
3010        msg.body.con_info.ch = channel;
3011        msg.body.con_info.result = connect_result;
3012        msg.body.con_info.arg = user_arg;
3013        msg.body.con_info.params = join_params;
3014        msg.vif = vif;
3015
3016        if (bssid) {
3017                msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
3018                if (!msg.body.con_info.bssid)
3019                        return -ENOMEM;
3020        }
3021
3022        if (ssid) {
3023                msg.body.con_info.ssid_len = ssid_len;
3024                msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
3025                if (!msg.body.con_info.ssid)
3026                        return -ENOMEM;
3027        }
3028
3029        if (ies) {
3030                msg.body.con_info.ies_len = ies_len;
3031                msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
3032                if (!msg.body.con_info.ies)
3033                        return -ENOMEM;
3034        }
3035        if (hif_drv->hif_state < HOST_IF_CONNECTING)
3036                hif_drv->hif_state = HOST_IF_CONNECTING;
3037
3038        result = wilc_enqueue_cmd(&msg);
3039        if (result) {
3040                netdev_err(vif->ndev, "send message: Set join request\n");
3041                return -EFAULT;
3042        }
3043
3044        hif_drv->connect_timer.data = (unsigned long)vif;
3045        mod_timer(&hif_drv->connect_timer,
3046                  jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3047
3048        return result;
3049}
3050
3051int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
3052{
3053        int result = 0;
3054        struct host_if_msg msg;
3055        struct host_if_drv *hif_drv = vif->hif_drv;
3056
3057        if (!hif_drv) {
3058                netdev_err(vif->ndev, "Driver is null\n");
3059                return -EFAULT;
3060        }
3061
3062        memset(&msg, 0, sizeof(struct host_if_msg));
3063
3064        msg.id = HOST_IF_MSG_DISCONNECT;
3065        msg.vif = vif;
3066
3067        result = wilc_enqueue_cmd(&msg);
3068        if (result)
3069                netdev_err(vif->ndev, "Failed to send message: disconnect\n");
3070        else
3071                wait_for_completion(&hif_drv->comp_test_disconn_block);
3072
3073        return result;
3074}
3075
3076static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
3077                                       u8 *pu8AssocRespInfo,
3078                                       u32 u32MaxAssocRespInfoLen,
3079                                       u32 *pu32RcvdAssocRespInfoLen)
3080{
3081        s32 result = 0;
3082        struct wid wid;
3083
3084        wid.id = (u16)WID_ASSOC_RES_INFO;
3085        wid.type = WID_STR;
3086        wid.val = pu8AssocRespInfo;
3087        wid.size = u32MaxAssocRespInfoLen;
3088
3089        result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
3090                                      wilc_get_vif_idx(vif));
3091        if (result) {
3092                *pu32RcvdAssocRespInfoLen = 0;
3093                netdev_err(vif->ndev, "Failed to send association response\n");
3094                return -EINVAL;
3095        }
3096
3097        *pu32RcvdAssocRespInfoLen = wid.size;
3098        return result;
3099}
3100
3101int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
3102{
3103        int result;
3104        struct host_if_msg msg;
3105
3106        memset(&msg, 0, sizeof(struct host_if_msg));
3107        msg.id = HOST_IF_MSG_SET_CHANNEL;
3108        msg.body.channel_info.set_ch = channel;
3109        msg.vif = vif;
3110
3111        result = wilc_enqueue_cmd(&msg);
3112        if (result) {
3113                netdev_err(vif->ndev, "wilc mq send fail\n");
3114                return -EINVAL;
3115        }
3116
3117        return 0;
3118}
3119
3120int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
3121                             u8 ifc_id)
3122{
3123        int result = 0;
3124        struct host_if_msg msg;
3125
3126        memset(&msg, 0, sizeof(struct host_if_msg));
3127        msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3128        msg.body.drv.handler = index;
3129        msg.body.drv.mode = mode;
3130        msg.body.drv.name = ifc_id;
3131        msg.vif = vif;
3132
3133        result = wilc_enqueue_cmd(&msg);
3134        if (result) {
3135                netdev_err(vif->ndev, "wilc mq send fail\n");
3136                result = -EINVAL;
3137        }
3138
3139        return result;
3140}
3141
3142int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
3143{
3144        int result = 0;
3145        struct host_if_msg msg;
3146
3147        memset(&msg, 0, sizeof(struct host_if_msg));
3148        msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3149        msg.body.mode.mode = mode;
3150        msg.vif = vif;
3151
3152        result = wilc_enqueue_cmd(&msg);
3153        if (result) {
3154                netdev_err(vif->ndev, "wilc mq send fail\n");
3155                result = -EINVAL;
3156        }
3157
3158        return result;
3159}
3160
3161s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
3162                           u32 *pu32InactiveTime)
3163{
3164        s32 result = 0;
3165        struct host_if_msg msg;
3166        struct host_if_drv *hif_drv = vif->hif_drv;
3167
3168        if (!hif_drv) {
3169                netdev_err(vif->ndev, "driver is null\n");
3170                return -EFAULT;
3171        }
3172
3173        memset(&msg, 0, sizeof(struct host_if_msg));
3174        memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3175
3176        msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3177        msg.vif = vif;
3178
3179        result = wilc_enqueue_cmd(&msg);
3180        if (result)
3181                netdev_err(vif->ndev, "Failed to send get host ch param\n");
3182        else
3183                wait_for_completion(&hif_drv->comp_inactive_time);
3184
3185        *pu32InactiveTime = inactive_time;
3186
3187        return result;
3188}
3189
3190int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
3191{
3192        int result = 0;
3193        struct host_if_msg msg;
3194        struct host_if_drv *hif_drv = vif->hif_drv;
3195
3196        memset(&msg, 0, sizeof(struct host_if_msg));
3197        msg.id = HOST_IF_MSG_GET_RSSI;
3198        msg.vif = vif;
3199
3200        result = wilc_enqueue_cmd(&msg);
3201        if (result) {
3202                netdev_err(vif->ndev, "Failed to send get host ch param\n");
3203                return -EFAULT;
3204        }
3205
3206        wait_for_completion(&hif_drv->comp_get_rssi);
3207
3208        if (!rssi_level) {
3209                netdev_err(vif->ndev, "RSS pointer value is null\n");
3210                return -EFAULT;
3211        }
3212
3213        *rssi_level = rssi;
3214
3215        return result;
3216}
3217
3218int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
3219{
3220        int result = 0;
3221        struct host_if_msg msg;
3222
3223        memset(&msg, 0, sizeof(struct host_if_msg));
3224        msg.id = HOST_IF_MSG_GET_STATISTICS;
3225        msg.body.data = (char *)stats;
3226        msg.vif = vif;
3227
3228        result = wilc_enqueue_cmd(&msg);
3229        if (result) {
3230                netdev_err(vif->ndev, "Failed to send get host channel\n");
3231                return -EFAULT;
3232        }
3233
3234        if (stats != &vif->wilc->dummy_statistics)
3235                wait_for_completion(&hif_wait_response);
3236        return result;
3237}
3238
3239int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
3240              u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
3241              size_t ies_len, wilc_scan_result scan_result, void *user_arg,
3242              struct hidden_network *hidden_network)
3243{
3244        int result = 0;
3245        struct host_if_msg msg;
3246        struct scan_attr *scan_info = &msg.body.scan_info;
3247        struct host_if_drv *hif_drv = vif->hif_drv;
3248
3249        if (!hif_drv || !scan_result) {
3250                netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
3251                return -EFAULT;
3252        }
3253
3254        memset(&msg, 0, sizeof(struct host_if_msg));
3255
3256        msg.id = HOST_IF_MSG_SCAN;
3257
3258        if (hidden_network) {
3259                scan_info->hidden_network.net_info = hidden_network->net_info;
3260                scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
3261        }
3262
3263        msg.vif = vif;
3264        scan_info->src = scan_source;
3265        scan_info->type = scan_type;
3266        scan_info->result = scan_result;
3267        scan_info->arg = user_arg;
3268
3269        scan_info->ch_list_len = ch_list_len;
3270        scan_info->ch_freq_list = kmemdup(ch_freq_list,
3271                                          ch_list_len,
3272                                          GFP_KERNEL);
3273        if (!scan_info->ch_freq_list)
3274                return -ENOMEM;
3275
3276        scan_info->ies_len = ies_len;
3277        scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
3278        if (!scan_info->ies)
3279                return -ENOMEM;
3280
3281        result = wilc_enqueue_cmd(&msg);
3282        if (result) {
3283                netdev_err(vif->ndev, "Error in sending message queue\n");
3284                return -EINVAL;
3285        }
3286
3287        hif_drv->scan_timer.data = (unsigned long)vif;
3288        mod_timer(&hif_drv->scan_timer,
3289                  jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3290
3291        return result;
3292}
3293
3294int wilc_hif_set_cfg(struct wilc_vif *vif,
3295                     struct cfg_param_attr *cfg_param)
3296{
3297        struct host_if_msg msg;
3298        struct host_if_drv *hif_drv = vif->hif_drv;
3299
3300        if (!hif_drv) {
3301                netdev_err(vif->ndev, "hif_drv NULL\n");
3302                return -EFAULT;
3303        }
3304
3305        memset(&msg, 0, sizeof(struct host_if_msg));
3306        msg.id = HOST_IF_MSG_CFG_PARAMS;
3307        msg.body.cfg_info = *cfg_param;
3308        msg.vif = vif;
3309
3310        return wilc_enqueue_cmd(&msg);
3311}
3312
3313static void GetPeriodicRSSI(unsigned long arg)
3314{
3315        struct wilc_vif *vif = (struct wilc_vif *)arg;
3316
3317        if (!vif->hif_drv) {
3318                netdev_err(vif->ndev, "Driver handler is NULL\n");
3319                return;
3320        }
3321
3322        if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
3323                wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
3324
3325        periodic_rssi.data = (unsigned long)vif;
3326        mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3327}
3328
3329int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
3330{
3331        int result = 0;
3332        struct host_if_drv *hif_drv;
3333        struct wilc_vif *vif;
3334        struct wilc *wilc;
3335        int i;
3336
3337        vif = netdev_priv(dev);
3338        wilc = vif->wilc;
3339
3340        scan_while_connected = false;
3341
3342        init_completion(&hif_wait_response);
3343
3344        hif_drv  = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
3345        if (!hif_drv) {
3346                result = -ENOMEM;
3347                goto _fail_;
3348        }
3349        *hif_drv_handler = hif_drv;
3350        for (i = 0; i < wilc->vif_num; i++)
3351                if (dev == wilc->vif[i]->ndev) {
3352                        wilc->vif[i]->hif_drv = hif_drv;
3353                        hif_drv->driver_handler_id = i + 1;
3354                        break;
3355                }
3356
3357        wilc_optaining_ip = false;
3358
3359        if (clients_count == 0) {
3360                init_completion(&hif_thread_comp);
3361                init_completion(&hif_driver_comp);
3362                mutex_init(&hif_deinit_lock);
3363        }
3364
3365        init_completion(&hif_drv->comp_test_key_block);
3366        init_completion(&hif_drv->comp_test_disconn_block);
3367        init_completion(&hif_drv->comp_get_rssi);
3368        init_completion(&hif_drv->comp_inactive_time);
3369
3370        if (clients_count == 0) {
3371                hif_workqueue = create_singlethread_workqueue("WILC_wq");
3372                if (!hif_workqueue) {
3373                        netdev_err(vif->ndev, "Failed to create workqueue\n");
3374                        result = -ENOMEM;
3375                        goto _fail_;
3376                }
3377
3378                setup_timer(&periodic_rssi, GetPeriodicRSSI,
3379                            (unsigned long)vif);
3380                mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3381        }
3382
3383        setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0);
3384        setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0);
3385        setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0);
3386
3387        mutex_init(&hif_drv->cfg_values_lock);
3388        mutex_lock(&hif_drv->cfg_values_lock);
3389
3390        hif_drv->hif_state = HOST_IF_IDLE;
3391        hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
3392        hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
3393        hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
3394        hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
3395        hif_drv->cfg_values.curr_tx_rate = AUTORATE;
3396
3397        hif_drv->p2p_timeout = 0;
3398
3399        mutex_unlock(&hif_drv->cfg_values_lock);
3400
3401        clients_count++;
3402
3403_fail_:
3404        return result;
3405}
3406
3407int wilc_deinit(struct wilc_vif *vif)
3408{
3409        int result = 0;
3410        struct host_if_msg msg;
3411        struct host_if_drv *hif_drv = vif->hif_drv;
3412
3413        if (!hif_drv)   {
3414                netdev_err(vif->ndev, "hif_drv = NULL\n");
3415                return -EFAULT;
3416        }
3417
3418        mutex_lock(&hif_deinit_lock);
3419
3420        terminated_handle = hif_drv;
3421
3422        del_timer_sync(&hif_drv->scan_timer);
3423        del_timer_sync(&hif_drv->connect_timer);
3424        del_timer_sync(&periodic_rssi);
3425        del_timer_sync(&hif_drv->remain_on_ch_timer);
3426
3427        wilc_set_wfi_drv_handler(vif, 0, 0, 0);
3428        wait_for_completion(&hif_driver_comp);
3429
3430        if (hif_drv->usr_scan_req.scan_result) {
3431                hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
3432                                                  hif_drv->usr_scan_req.arg, NULL);
3433                hif_drv->usr_scan_req.scan_result = NULL;
3434        }
3435
3436        hif_drv->hif_state = HOST_IF_IDLE;
3437
3438        scan_while_connected = false;
3439
3440        memset(&msg, 0, sizeof(struct host_if_msg));
3441
3442        if (clients_count == 1) {
3443                msg.id = HOST_IF_MSG_EXIT;
3444                msg.vif = vif;
3445
3446                result = wilc_enqueue_cmd(&msg);
3447                if (result != 0)
3448                        netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
3449                else
3450                        wait_for_completion(&hif_thread_comp);
3451
3452                destroy_workqueue(hif_workqueue);
3453        }
3454
3455        kfree(hif_drv);
3456
3457        clients_count--;
3458        terminated_handle = NULL;
3459        mutex_unlock(&hif_deinit_lock);
3460        return result;
3461}
3462
3463void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length)
3464{
3465        s32 result = 0;
3466        struct host_if_msg msg;
3467        int id;
3468        struct host_if_drv *hif_drv = NULL;
3469        struct wilc_vif *vif;
3470
3471        id = ((buffer[length - 4]) | (buffer[length - 3] << 8) | (buffer[length - 2] << 16) | (buffer[length - 1] << 24));
3472        vif = wilc_get_vif_from_idx(wilc, id);
3473        if (!vif)
3474                return;
3475        hif_drv = vif->hif_drv;
3476
3477        if (!hif_drv || hif_drv == terminated_handle)   {
3478                netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
3479                return;
3480        }
3481
3482        memset(&msg, 0, sizeof(struct host_if_msg));
3483
3484        msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
3485        msg.vif = vif;
3486
3487        msg.body.net_info.len = length;
3488        msg.body.net_info.buffer = kmalloc(length, GFP_KERNEL);
3489        memcpy(msg.body.net_info.buffer, buffer, length);
3490
3491        result = wilc_enqueue_cmd(&msg);
3492        if (result)
3493                netdev_err(vif->ndev, "message parameters (%d)\n", result);
3494}
3495
3496void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length)
3497{
3498        s32 result = 0;
3499        struct host_if_msg msg;
3500        int id;
3501        struct host_if_drv *hif_drv = NULL;
3502        struct wilc_vif *vif;
3503
3504        mutex_lock(&hif_deinit_lock);
3505
3506        id = ((buffer[length - 4]) | (buffer[length - 3] << 8) | (buffer[length - 2] << 16) | (buffer[length - 1] << 24));
3507        vif = wilc_get_vif_from_idx(wilc, id);
3508        if (!vif) {
3509                mutex_unlock(&hif_deinit_lock);
3510                return;
3511        }
3512
3513        hif_drv = vif->hif_drv;
3514
3515        if (!hif_drv || hif_drv == terminated_handle) {
3516                mutex_unlock(&hif_deinit_lock);
3517                return;
3518        }
3519
3520        if (!hif_drv->usr_conn_req.conn_result) {
3521                netdev_err(vif->ndev, "there is no current Connect Request\n");
3522                mutex_unlock(&hif_deinit_lock);
3523                return;
3524        }
3525
3526        memset(&msg, 0, sizeof(struct host_if_msg));
3527
3528        msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
3529        msg.vif = vif;
3530
3531        msg.body.async_info.len = length;
3532        msg.body.async_info.buffer = kmalloc(length, GFP_KERNEL);
3533        memcpy(msg.body.async_info.buffer, buffer, length);
3534
3535        result = wilc_enqueue_cmd(&msg);
3536        if (result)
3537                netdev_err(vif->ndev, "synchronous info (%d)\n", result);
3538
3539        mutex_unlock(&hif_deinit_lock);
3540}
3541
3542void wilc_scan_complete_received(struct wilc *wilc, u8 *buffer, u32 length)
3543{
3544        s32 result = 0;
3545        struct host_if_msg msg;
3546        int id;
3547        struct host_if_drv *hif_drv = NULL;
3548        struct wilc_vif *vif;
3549
3550        id = ((buffer[length - 4]) | (buffer[length - 3] << 8) | (buffer[length - 2] << 16) | (buffer[length - 1] << 24));
3551        vif = wilc_get_vif_from_idx(wilc, id);
3552        if (!vif)
3553                return;
3554        hif_drv = vif->hif_drv;
3555
3556        if (!hif_drv || hif_drv == terminated_handle)
3557                return;
3558
3559        if (hif_drv->usr_scan_req.scan_result) {
3560                memset(&msg, 0, sizeof(struct host_if_msg));
3561
3562                msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
3563                msg.vif = vif;
3564
3565                result = wilc_enqueue_cmd(&msg);
3566                if (result)
3567                        netdev_err(vif->ndev, "complete param (%d)\n", result);
3568        }
3569}
3570
3571int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
3572                           u32 duration, u16 chan,
3573                           wilc_remain_on_chan_expired expired,
3574                           wilc_remain_on_chan_ready ready,
3575                           void *user_arg)
3576{
3577        int result = 0;
3578        struct host_if_msg msg;
3579
3580        memset(&msg, 0, sizeof(struct host_if_msg));
3581
3582        msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
3583        msg.body.remain_on_ch.ch = chan;
3584        msg.body.remain_on_ch.expired = expired;
3585        msg.body.remain_on_ch.ready = ready;
3586        msg.body.remain_on_ch.arg = user_arg;
3587        msg.body.remain_on_ch.duration = duration;
3588        msg.body.remain_on_ch.id = session_id;
3589        msg.vif = vif;
3590
3591        result = wilc_enqueue_cmd(&msg);
3592        if (result)
3593                netdev_err(vif->ndev, "wilc mq send fail\n");
3594
3595        return result;
3596}
3597
3598int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
3599{
3600        int result = 0;
3601        struct host_if_msg msg;
3602        struct host_if_drv *hif_drv = vif->hif_drv;
3603
3604        if (!hif_drv) {
3605                netdev_err(vif->ndev, "driver is null\n");
3606                return -EFAULT;
3607        }
3608
3609        del_timer(&hif_drv->remain_on_ch_timer);
3610
3611        memset(&msg, 0, sizeof(struct host_if_msg));
3612        msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
3613        msg.vif = vif;
3614        msg.body.remain_on_ch.id = session_id;
3615
3616        result = wilc_enqueue_cmd(&msg);
3617        if (result)
3618                netdev_err(vif->ndev, "wilc mq send fail\n");
3619
3620        return result;
3621}
3622
3623int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
3624{
3625        int result = 0;
3626        struct host_if_msg msg;
3627
3628        memset(&msg, 0, sizeof(struct host_if_msg));
3629
3630        msg.id = HOST_IF_MSG_REGISTER_FRAME;
3631        switch (frame_type) {
3632        case ACTION:
3633                msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
3634                break;
3635
3636        case PROBE_REQ:
3637                msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
3638                break;
3639
3640        default:
3641                break;
3642        }
3643        msg.body.reg_frame.frame_type = frame_type;
3644        msg.body.reg_frame.reg = reg;
3645        msg.vif = vif;
3646
3647        result = wilc_enqueue_cmd(&msg);
3648        if (result)
3649                netdev_err(vif->ndev, "wilc mq send fail\n");
3650
3651        return result;
3652}
3653
3654int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
3655                    u32 head_len, u8 *head, u32 tail_len, u8 *tail)
3656{
3657        int result = 0;
3658        struct host_if_msg msg;
3659        struct beacon_attr *beacon_info = &msg.body.beacon_info;
3660
3661        memset(&msg, 0, sizeof(struct host_if_msg));
3662
3663        msg.id = HOST_IF_MSG_ADD_BEACON;
3664        msg.vif = vif;
3665        beacon_info->interval = interval;
3666        beacon_info->dtim_period = dtim_period;
3667        beacon_info->head_len = head_len;
3668        beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
3669        if (!beacon_info->head) {
3670                result = -ENOMEM;
3671                goto ERRORHANDLER;
3672        }
3673        beacon_info->tail_len = tail_len;
3674
3675        if (tail_len > 0) {
3676                beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
3677                if (!beacon_info->tail) {
3678                        result = -ENOMEM;
3679                        goto ERRORHANDLER;
3680                }
3681        } else {
3682                beacon_info->tail = NULL;
3683        }
3684
3685        result = wilc_enqueue_cmd(&msg);
3686        if (result)
3687                netdev_err(vif->ndev, "wilc mq send fail\n");
3688
3689ERRORHANDLER:
3690        if (result) {
3691                kfree(beacon_info->head);
3692
3693                kfree(beacon_info->tail);
3694        }
3695
3696        return result;
3697}
3698
3699int wilc_del_beacon(struct wilc_vif *vif)
3700{
3701        int result = 0;
3702        struct host_if_msg msg;
3703
3704        msg.id = HOST_IF_MSG_DEL_BEACON;
3705        msg.vif = vif;
3706
3707        result = wilc_enqueue_cmd(&msg);
3708        if (result)
3709                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3710
3711        return result;
3712}
3713
3714int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
3715{
3716        int result = 0;
3717        struct host_if_msg msg;
3718        struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3719
3720        memset(&msg, 0, sizeof(struct host_if_msg));
3721
3722        msg.id = HOST_IF_MSG_ADD_STATION;
3723        msg.vif = vif;
3724
3725        memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3726        if (add_sta_info->rates_len > 0) {
3727                add_sta_info->rates = kmemdup(sta_param->rates,
3728                                      add_sta_info->rates_len,
3729                                      GFP_KERNEL);
3730                if (!add_sta_info->rates)
3731                        return -ENOMEM;
3732        }
3733
3734        result = wilc_enqueue_cmd(&msg);
3735        if (result)
3736                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3737        return result;
3738}
3739
3740int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
3741{
3742        int result = 0;
3743        struct host_if_msg msg;
3744        struct del_sta *del_sta_info = &msg.body.del_sta_info;
3745
3746        memset(&msg, 0, sizeof(struct host_if_msg));
3747
3748        msg.id = HOST_IF_MSG_DEL_STATION;
3749        msg.vif = vif;
3750
3751        if (!mac_addr)
3752                eth_broadcast_addr(del_sta_info->mac_addr);
3753        else
3754                memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
3755
3756        result = wilc_enqueue_cmd(&msg);
3757        if (result)
3758                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3759        return result;
3760}
3761
3762int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
3763{
3764        int result = 0;
3765        struct host_if_msg msg;
3766        struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
3767        u8 zero_addr[ETH_ALEN] = {0};
3768        int i;
3769        u8 assoc_sta = 0;
3770
3771        memset(&msg, 0, sizeof(struct host_if_msg));
3772
3773        msg.id = HOST_IF_MSG_DEL_ALL_STA;
3774        msg.vif = vif;
3775
3776        for (i = 0; i < MAX_NUM_STA; i++) {
3777                if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
3778                        memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i], ETH_ALEN);
3779                        assoc_sta++;
3780                }
3781        }
3782        if (!assoc_sta)
3783                return result;
3784
3785        del_all_sta_info->assoc_sta = assoc_sta;
3786        result = wilc_enqueue_cmd(&msg);
3787
3788        if (result)
3789                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3790        else
3791                wait_for_completion(&hif_wait_response);
3792
3793        return result;
3794}
3795
3796int wilc_edit_station(struct wilc_vif *vif,
3797                      struct add_sta_param *sta_param)
3798{
3799        int result = 0;
3800        struct host_if_msg msg;
3801        struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3802
3803        memset(&msg, 0, sizeof(struct host_if_msg));
3804
3805        msg.id = HOST_IF_MSG_EDIT_STATION;
3806        msg.vif = vif;
3807
3808        memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3809        if (add_sta_info->rates_len > 0) {
3810                add_sta_info->rates = kmemdup(sta_param->rates,
3811                                              add_sta_info->rates_len,
3812                                              GFP_KERNEL);
3813                if (!add_sta_info->rates)
3814                        return -ENOMEM;
3815        }
3816
3817        result = wilc_enqueue_cmd(&msg);
3818        if (result)
3819                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3820
3821        return result;
3822}
3823
3824int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
3825{
3826        int result = 0;
3827        struct host_if_msg msg;
3828        struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
3829
3830        if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
3831                return 0;
3832
3833        memset(&msg, 0, sizeof(struct host_if_msg));
3834
3835        msg.id = HOST_IF_MSG_POWER_MGMT;
3836        msg.vif = vif;
3837
3838        pwr_mgmt_info->enabled = enabled;
3839        pwr_mgmt_info->timeout = timeout;
3840
3841        result = wilc_enqueue_cmd(&msg);
3842        if (result)
3843                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3844        return result;
3845}
3846
3847int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
3848                                u32 count)
3849{
3850        int result = 0;
3851        struct host_if_msg msg;
3852        struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
3853
3854        memset(&msg, 0, sizeof(struct host_if_msg));
3855
3856        msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
3857        msg.vif = vif;
3858
3859        multicast_filter_param->enabled = enabled;
3860        multicast_filter_param->cnt = count;
3861
3862        result = wilc_enqueue_cmd(&msg);
3863        if (result)
3864                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3865        return result;
3866}
3867
3868static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
3869{
3870        struct join_bss_param *pNewJoinBssParam = NULL;
3871        u8 *pu8IEs;
3872        u16 u16IEsLen;
3873        u16 index = 0;
3874        u8 suppRatesNo = 0;
3875        u8 extSuppRatesNo;
3876        u16 jumpOffset;
3877        u8 pcipherCount;
3878        u8 authCount;
3879        u8 pcipherTotalCount = 0;
3880        u8 authTotalCount = 0;
3881        u8 i, j;
3882
3883        pu8IEs = ptstrNetworkInfo->ies;
3884        u16IEsLen = ptstrNetworkInfo->ies_len;
3885
3886        pNewJoinBssParam = kzalloc(sizeof(*pNewJoinBssParam), GFP_KERNEL);
3887        if (pNewJoinBssParam) {
3888                pNewJoinBssParam->dtim_period = ptstrNetworkInfo->dtim_period;
3889                pNewJoinBssParam->beacon_period = ptstrNetworkInfo->beacon_period;
3890                pNewJoinBssParam->cap_info = ptstrNetworkInfo->cap_info;
3891                memcpy(pNewJoinBssParam->bssid, ptstrNetworkInfo->bssid, 6);
3892                memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->ssid,
3893                       ptstrNetworkInfo->ssid_len + 1);
3894                pNewJoinBssParam->ssid_len = ptstrNetworkInfo->ssid_len;
3895                memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
3896                memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
3897
3898                while (index < u16IEsLen) {
3899                        if (pu8IEs[index] == SUPP_RATES_IE) {
3900                                suppRatesNo = pu8IEs[index + 1];
3901                                pNewJoinBssParam->supp_rates[0] = suppRatesNo;
3902                                index += 2;
3903
3904                                for (i = 0; i < suppRatesNo; i++)
3905                                        pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
3906
3907                                index += suppRatesNo;
3908                        } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
3909                                extSuppRatesNo = pu8IEs[index + 1];
3910                                if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
3911                                        pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
3912                                else
3913                                        pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
3914                                index += 2;
3915                                for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
3916                                        pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
3917
3918                                index += extSuppRatesNo;
3919                        } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
3920                                pNewJoinBssParam->ht_capable = true;
3921                                index += pu8IEs[index + 1] + 2;
3922                        } else if ((pu8IEs[index] == WMM_IE) &&
3923                                   (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
3924                                   (pu8IEs[index + 4] == 0xF2) &&
3925                                   (pu8IEs[index + 5] == 0x02) &&
3926                                   ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
3927                                   (pu8IEs[index + 7] == 0x01)) {
3928                                pNewJoinBssParam->wmm_cap = true;
3929
3930                                if (pu8IEs[index + 8] & BIT(7))
3931                                        pNewJoinBssParam->uapsd_cap = true;
3932                                index += pu8IEs[index + 1] + 2;
3933                        } else if ((pu8IEs[index] == P2P_IE) &&
3934                                 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
3935                                 (pu8IEs[index + 4] == 0x9a) &&
3936                                 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
3937                                u16 u16P2P_count;
3938
3939                                pNewJoinBssParam->tsf = ptstrNetworkInfo->tsf_lo;
3940                                pNewJoinBssParam->noa_enabled = 1;
3941                                pNewJoinBssParam->idx = pu8IEs[index + 9];
3942
3943                                if (pu8IEs[index + 10] & BIT(7)) {
3944                                        pNewJoinBssParam->opp_enabled = 1;
3945                                        pNewJoinBssParam->ct_window = pu8IEs[index + 10];
3946                                } else {
3947                                        pNewJoinBssParam->opp_enabled = 0;
3948                                }
3949
3950                                pNewJoinBssParam->cnt = pu8IEs[index + 11];
3951                                u16P2P_count = index + 12;
3952
3953                                memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
3954                                u16P2P_count += 4;
3955
3956                                memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
3957                                u16P2P_count += 4;
3958
3959                                memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
3960
3961                                index += pu8IEs[index + 1] + 2;
3962                        } else if ((pu8IEs[index] == RSN_IE) ||
3963                                 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
3964                                  (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
3965                                  (pu8IEs[index + 5] == 0x01))) {
3966                                u16 rsnIndex = index;
3967
3968                                if (pu8IEs[rsnIndex] == RSN_IE) {
3969                                        pNewJoinBssParam->mode_802_11i = 2;
3970                                } else {
3971                                        if (pNewJoinBssParam->mode_802_11i == 0)
3972                                                pNewJoinBssParam->mode_802_11i = 1;
3973                                        rsnIndex += 4;
3974                                }
3975
3976                                rsnIndex += 7;
3977                                pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
3978                                rsnIndex++;
3979                                jumpOffset = pu8IEs[rsnIndex] * 4;
3980                                pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
3981                                rsnIndex += 2;
3982
3983                                for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
3984                                        pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
3985
3986                                pcipherTotalCount += pcipherCount;
3987                                rsnIndex += jumpOffset;
3988
3989                                jumpOffset = pu8IEs[rsnIndex] * 4;
3990
3991                                authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
3992                                rsnIndex += 2;
3993
3994                                for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
3995                                        pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
3996
3997                                authTotalCount += authCount;
3998                                rsnIndex += jumpOffset;
3999
4000                                if (pu8IEs[index] == RSN_IE) {
4001                                        pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4002                                        pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4003                                        rsnIndex += 2;
4004                                }
4005                                pNewJoinBssParam->rsn_found = true;
4006                                index += pu8IEs[index + 1] + 2;
4007                        } else {
4008                                index += pu8IEs[index + 1] + 2;
4009                        }
4010                }
4011        }
4012
4013        return (void *)pNewJoinBssParam;
4014}
4015
4016int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4017{
4018        int result = 0;
4019        struct host_if_msg msg;
4020
4021        memset(&msg, 0, sizeof(struct host_if_msg));
4022
4023        msg.id = HOST_IF_MSG_SET_IPADDRESS;
4024
4025        msg.body.ip_info.ip_addr = ip_addr;
4026        msg.vif = vif;
4027        msg.body.ip_info.idx = idx;
4028
4029        result = wilc_enqueue_cmd(&msg);
4030        if (result)
4031                netdev_err(vif->ndev, "wilc_mq_send fail\n");
4032
4033        return result;
4034}
4035
4036static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4037{
4038        int result = 0;
4039        struct host_if_msg msg;
4040
4041        memset(&msg, 0, sizeof(struct host_if_msg));
4042
4043        msg.id = HOST_IF_MSG_GET_IPADDRESS;
4044
4045        msg.body.ip_info.ip_addr = ip_addr;
4046        msg.vif = vif;
4047        msg.body.ip_info.idx = idx;
4048
4049        result = wilc_enqueue_cmd(&msg);
4050        if (result)
4051                netdev_err(vif->ndev, "wilc_mq_send fail\n");
4052
4053        return result;
4054}
4055
4056int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
4057{
4058        int ret = 0;
4059        struct host_if_msg msg;
4060
4061        memset(&msg, 0, sizeof(struct host_if_msg));
4062
4063        msg.id = HOST_IF_MSG_SET_TX_POWER;
4064        msg.body.tx_power.tx_pwr = tx_power;
4065        msg.vif = vif;
4066
4067        ret = wilc_enqueue_cmd(&msg);
4068        if (ret)
4069                netdev_err(vif->ndev, "wilc_mq_send fail\n");
4070
4071        return ret;
4072}
4073
4074int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
4075{
4076        int ret = 0;
4077        struct host_if_msg msg;
4078
4079        memset(&msg, 0, sizeof(struct host_if_msg));
4080
4081        msg.id = HOST_IF_MSG_GET_TX_POWER;
4082        msg.vif = vif;
4083
4084        ret = wilc_enqueue_cmd(&msg);
4085        if (ret)
4086                netdev_err(vif->ndev, "Failed to get TX PWR\n");
4087
4088        wait_for_completion(&hif_wait_response);
4089        *tx_power = msg.body.tx_power.tx_pwr;
4090
4091        return ret;
4092}
4093