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