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 <linux/list.h>
   7#include <linux/workqueue.h>
   8#include "host_interface.h"
   9#include <linux/spinlock.h>
  10#include <linux/errno.h>
  11#include "coreconfigurator.h"
  12#include "wilc_wlan.h"
  13#include "wilc_wlan_if.h"
  14#include <linux/etherdevice.h>
  15#include "wilc_wfi_netdevice.h"
  16
  17#define HOST_IF_MSG_SCAN                        0
  18#define HOST_IF_MSG_CONNECT                     1
  19#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO        2
  20#define HOST_IF_MSG_KEY                         3
  21#define HOST_IF_MSG_RCVD_NTWRK_INFO             4
  22#define HOST_IF_MSG_RCVD_SCAN_COMPLETE          5
  23#define HOST_IF_MSG_CFG_PARAMS                  6
  24#define HOST_IF_MSG_SET_CHANNEL                 7
  25#define HOST_IF_MSG_DISCONNECT                  8
  26#define HOST_IF_MSG_GET_RSSI                    9
  27#define HOST_IF_MSG_ADD_BEACON                  11
  28#define HOST_IF_MSG_DEL_BEACON                  12
  29#define HOST_IF_MSG_ADD_STATION                 13
  30#define HOST_IF_MSG_DEL_STATION                 14
  31#define HOST_IF_MSG_EDIT_STATION                15
  32#define HOST_IF_MSG_SCAN_TIMER_FIRED            16
  33#define HOST_IF_MSG_CONNECT_TIMER_FIRED         17
  34#define HOST_IF_MSG_POWER_MGMT                  18
  35#define HOST_IF_MSG_GET_INACTIVETIME            19
  36#define HOST_IF_MSG_REMAIN_ON_CHAN              20
  37#define HOST_IF_MSG_REGISTER_FRAME              21
  38#define HOST_IF_MSG_LISTEN_TIMER_FIRED          22
  39#define HOST_IF_MSG_SET_WFIDRV_HANDLER          24
  40#define HOST_IF_MSG_GET_MAC_ADDRESS             26
  41#define HOST_IF_MSG_SET_OPERATION_MODE          27
  42#define HOST_IF_MSG_SET_IPADDRESS               28
  43#define HOST_IF_MSG_GET_IPADDRESS               29
  44#define HOST_IF_MSG_GET_STATISTICS              31
  45#define HOST_IF_MSG_SET_MULTICAST_FILTER        32
  46#define HOST_IF_MSG_DEL_BA_SESSION              34
  47#define HOST_IF_MSG_DEL_ALL_STA                 36
  48#define HOST_IF_MSG_SET_TX_POWER                38
  49#define HOST_IF_MSG_GET_TX_POWER                39
  50#define HOST_IF_MSG_EXIT                        100
  51
  52#define HOST_IF_SCAN_TIMEOUT                    4000
  53#define HOST_IF_CONNECT_TIMEOUT                 9500
  54
  55#define BA_SESSION_DEFAULT_BUFFER_SIZE          16
  56#define BA_SESSION_DEFAULT_TIMEOUT              1000
  57#define BLOCK_ACK_REQ_SIZE                      0x14
  58#define FALSE_FRMWR_CHANNEL                     100
  59
  60#define TCP_ACK_FILTER_LINK_SPEED_THRESH        54
  61#define DEFAULT_LINK_SPEED                      72
  62
  63struct host_if_wpa_attr {
  64        u8 *key;
  65        const u8 *mac_addr;
  66        u8 *seq;
  67        u8 seq_len;
  68        u8 index;
  69        u8 key_len;
  70        u8 mode;
  71};
  72
  73struct host_if_wep_attr {
  74        u8 *key;
  75        u8 key_len;
  76        u8 index;
  77        u8 mode;
  78        enum AUTHTYPE auth_type;
  79};
  80
  81union host_if_key_attr {
  82        struct host_if_wep_attr wep;
  83        struct host_if_wpa_attr wpa;
  84        struct host_if_pmkid_attr pmkid;
  85};
  86
  87struct key_attr {
  88        enum KEY_TYPE type;
  89        u8 action;
  90        union host_if_key_attr attr;
  91};
  92
  93struct scan_attr {
  94        u8 src;
  95        u8 type;
  96        u8 *ch_freq_list;
  97        u8 ch_list_len;
  98        u8 *ies;
  99        size_t ies_len;
 100        wilc_scan_result result;
 101        void *arg;
 102        struct hidden_network hidden_network;
 103};
 104
 105struct connect_attr {
 106        u8 *bssid;
 107        u8 *ssid;
 108        size_t ssid_len;
 109        u8 *ies;
 110        size_t ies_len;
 111        u8 security;
 112        wilc_connect_result result;
 113        void *arg;
 114        enum AUTHTYPE auth_type;
 115        u8 ch;
 116        void *params;
 117};
 118
 119struct rcvd_async_info {
 120        u8 *buffer;
 121        u32 len;
 122};
 123
 124struct channel_attr {
 125        u8 set_ch;
 126};
 127
 128struct beacon_attr {
 129        u32 interval;
 130        u32 dtim_period;
 131        u32 head_len;
 132        u8 *head;
 133        u32 tail_len;
 134        u8 *tail;
 135};
 136
 137struct set_multicast {
 138        bool enabled;
 139        u32 cnt;
 140};
 141
 142struct del_all_sta {
 143        u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
 144        u8 assoc_sta;
 145};
 146
 147struct del_sta {
 148        u8 mac_addr[ETH_ALEN];
 149};
 150
 151struct power_mgmt_param {
 152        bool enabled;
 153        u32 timeout;
 154};
 155
 156struct set_ip_addr {
 157        u8 *ip_addr;
 158        u8 idx;
 159};
 160
 161struct sta_inactive_t {
 162        u8 mac[6];
 163};
 164
 165struct tx_power {
 166        u8 tx_pwr;
 167};
 168
 169union message_body {
 170        struct scan_attr scan_info;
 171        struct connect_attr con_info;
 172        struct rcvd_net_info net_info;
 173        struct rcvd_async_info async_info;
 174        struct key_attr key_info;
 175        struct cfg_param_attr cfg_info;
 176        struct channel_attr channel_info;
 177        struct beacon_attr beacon_info;
 178        struct add_sta_param add_sta_info;
 179        struct del_sta del_sta_info;
 180        struct add_sta_param edit_sta_info;
 181        struct power_mgmt_param pwr_mgmt_info;
 182        struct sta_inactive_t mac_info;
 183        struct set_ip_addr ip_info;
 184        struct drv_handler drv;
 185        struct set_multicast multicast_info;
 186        struct op_mode mode;
 187        struct get_mac_addr get_mac_info;
 188        struct ba_session_info session_info;
 189        struct remain_ch remain_on_ch;
 190        struct reg_frame reg_frame;
 191        char *data;
 192        struct del_all_sta del_all_sta_info;
 193        struct tx_power tx_power;
 194};
 195
 196struct host_if_msg {
 197        u16 id;
 198        union message_body body;
 199        struct wilc_vif *vif;
 200        struct work_struct work;
 201};
 202
 203struct join_bss_param {
 204        BSSTYPE_T bss_type;
 205        u8 dtim_period;
 206        u16 beacon_period;
 207        u16 cap_info;
 208        u8 bssid[6];
 209        char ssid[MAX_SSID_LEN];
 210        u8 ssid_len;
 211        u8 supp_rates[MAX_RATES_SUPPORTED + 1];
 212        u8 ht_capable;
 213        u8 wmm_cap;
 214        u8 uapsd_cap;
 215        bool rsn_found;
 216        u8 rsn_grp_policy;
 217        u8 mode_802_11i;
 218        u8 rsn_pcip_policy[3];
 219        u8 rsn_auth_policy[3];
 220        u8 rsn_cap[2];
 221        u32 tsf;
 222        u8 noa_enabled;
 223        u8 opp_enabled;
 224        u8 ct_window;
 225        u8 cnt;
 226        u8 idx;
 227        u8 duration[4];
 228        u8 interval[4];
 229        u8 start_time[4];
 230};
 231
 232static struct host_if_drv *terminated_handle;
 233bool wilc_optaining_ip;
 234static u8 P2P_LISTEN_STATE;
 235static struct workqueue_struct *hif_workqueue;
 236static struct completion hif_thread_comp;
 237static struct completion hif_driver_comp;
 238static struct completion hif_wait_response;
 239static struct mutex hif_deinit_lock;
 240static struct timer_list periodic_rssi;
 241
 242u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
 243
 244static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
 245
 246static bool scan_while_connected;
 247
 248static s8 rssi;
 249static u8 set_ip[2][4];
 250static u8 get_ip[2][4];
 251static u32 inactive_time;
 252static u8 del_beacon;
 253static u32 clients_count;
 254
 255static u8 *join_req;
 256static u8 *info_element;
 257static u8 mode_11i;
 258static u8 auth_type;
 259static u32 join_req_size;
 260static u32 info_element_size;
 261static struct wilc_vif *join_req_vif;
 262#define REAL_JOIN_REQ 0
 263#define FLUSHED_JOIN_REQ 1
 264#define FLUSHED_BYTE_POS 79
 265
 266static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo);
 267static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx);
 268static s32 Handle_ScanDone(struct wilc_vif *vif, enum scan_event enuEvent);
 269static void host_if_work(struct work_struct *work);
 270
 271/*!
 272 *  @author             syounan
 273 *  @date               1 Sep 2010
 274 *  @note               copied from FLO glue implementatuion
 275 *  @version            1.0
 276 */
 277static int wilc_enqueue_cmd(struct host_if_msg *msg)
 278{
 279        struct host_if_msg *new_msg;
 280
 281        new_msg = kmemdup(msg, sizeof(*new_msg), GFP_ATOMIC);
 282        if (!new_msg)
 283                return -ENOMEM;
 284
 285        INIT_WORK(&new_msg->work, host_if_work);
 286        queue_work(hif_workqueue, &new_msg->work);
 287        return 0;
 288}
 289
 290
 291/* The u8IfIdx starts from 0 to NUM_CONCURRENT_IFC -1, but 0 index used as
 292 * special purpose in wilc device, so we add 1 to the index to starts from 1.
 293 * As a result, the returned index will be 1 to NUM_CONCURRENT_IFC.
 294 */
 295int wilc_get_vif_idx(struct wilc_vif *vif)
 296{
 297        return vif->idx + 1;
 298}
 299
 300/* We need to minus 1 from idx which is from wilc device to get real index
 301 * of wilc->vif[], because we add 1 when pass to wilc device in the function
 302 * wilc_get_vif_idx.
 303 * As a result, the index should be between 0 and NUM_CONCURRENT_IFC -1.
 304 */
 305static struct wilc_vif *wilc_get_vif_from_idx(struct wilc *wilc, int idx)
 306{
 307        int index = idx - 1;
 308
 309        if (index < 0 || index >= NUM_CONCURRENT_IFC)
 310                return NULL;
 311
 312        return wilc->vif[index];
 313}
 314
 315static void handle_set_channel(struct wilc_vif *vif,
 316                               struct channel_attr *hif_set_ch)
 317{
 318        int ret = 0;
 319        struct wid wid;
 320
 321        wid.id = (u16)WID_CURRENT_CHANNEL;
 322        wid.type = WID_CHAR;
 323        wid.val = (char *)&hif_set_ch->set_ch;
 324        wid.size = sizeof(char);
 325
 326        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 327                                   wilc_get_vif_idx(vif));
 328
 329        if (ret)
 330                netdev_err(vif->ndev, "Failed to set channel\n");
 331}
 332
 333static void handle_set_wfi_drv_handler(struct wilc_vif *vif,
 334                                       struct drv_handler *hif_drv_handler)
 335{
 336        int ret = 0;
 337        struct wid wid;
 338
 339        wid.id = (u16)WID_SET_DRV_HANDLER;
 340        wid.type = WID_STR;
 341        wid.val = (s8 *)hif_drv_handler;
 342        wid.size = sizeof(*hif_drv_handler);
 343
 344        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 345                                   hif_drv_handler->handler);
 346
 347        if (!hif_drv_handler->handler)
 348                complete(&hif_driver_comp);
 349
 350        if (ret)
 351                netdev_err(vif->ndev, "Failed to set driver handler\n");
 352}
 353
 354static void handle_set_operation_mode(struct wilc_vif *vif,
 355                                      struct op_mode *hif_op_mode)
 356{
 357        int ret = 0;
 358        struct wid wid;
 359
 360        wid.id = (u16)WID_SET_OPERATION_MODE;
 361        wid.type = WID_INT;
 362        wid.val = (s8 *)&hif_op_mode->mode;
 363        wid.size = sizeof(u32);
 364
 365        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 366                                   wilc_get_vif_idx(vif));
 367
 368        if ((hif_op_mode->mode) == IDLE_MODE)
 369                complete(&hif_driver_comp);
 370
 371        if (ret)
 372                netdev_err(vif->ndev, "Failed to set driver handler\n");
 373}
 374
 375static void handle_set_ip_address(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
 376{
 377        int ret = 0;
 378        struct wid wid;
 379        char firmware_ip_addr[4] = {0};
 380
 381        if (ip_addr[0] < 192)
 382                ip_addr[0] = 0;
 383
 384        memcpy(set_ip[idx], ip_addr, IP_ALEN);
 385
 386        wid.id = (u16)WID_IP_ADDRESS;
 387        wid.type = WID_STR;
 388        wid.val = (u8 *)ip_addr;
 389        wid.size = IP_ALEN;
 390
 391        ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 392                                   wilc_get_vif_idx(vif));
 393
 394        host_int_get_ipaddress(vif, firmware_ip_addr, idx);
 395
 396        if (ret)
 397                netdev_err(vif->ndev, "Failed to set IP address\n");
 398}
 399
 400static void handle_get_ip_address(struct wilc_vif *vif, u8 idx)
 401{
 402        int ret = 0;
 403        struct wid wid;
 404
 405        wid.id = (u16)WID_IP_ADDRESS;
 406        wid.type = WID_STR;
 407        wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
 408        wid.size = IP_ALEN;
 409
 410        ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
 411                                   wilc_get_vif_idx(vif));
 412
 413        memcpy(get_ip[idx], wid.val, IP_ALEN);
 414
 415        kfree(wid.val);
 416
 417        if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
 418                wilc_setup_ipaddress(vif, set_ip[idx], idx);
 419
 420        if (ret)
 421                netdev_err(vif->ndev, "Failed to get IP address\n");
 422}
 423
 424static void handle_get_mac_address(struct wilc_vif *vif,
 425                                   struct get_mac_addr *get_mac_addr)
 426{
 427        int ret = 0;
 428        struct wid wid;
 429
 430        wid.id = (u16)WID_MAC_ADDR;
 431        wid.type = WID_STR;
 432        wid.val = get_mac_addr->mac_addr;
 433        wid.size = ETH_ALEN;
 434
 435        ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
 436                                   wilc_get_vif_idx(vif));
 437
 438        if (ret)
 439                netdev_err(vif->ndev, "Failed to get mac address\n");
 440        complete(&hif_wait_response);
 441}
 442
 443static void handle_cfg_param(struct wilc_vif *vif,
 444                             struct cfg_param_attr *cfg_param_attr)
 445{
 446        int ret = 0;
 447        struct wid wid_list[32];
 448        struct host_if_drv *hif_drv = vif->hif_drv;
 449        int i = 0;
 450
 451        mutex_lock(&hif_drv->cfg_values_lock);
 452
 453        if (cfg_param_attr->flag & BSS_TYPE) {
 454                u8 bss_type = cfg_param_attr->bss_type;
 455
 456                if (bss_type < 6) {
 457                        wid_list[i].id = WID_BSS_TYPE;
 458                        wid_list[i].val = (s8 *)&bss_type;
 459                        wid_list[i].type = WID_CHAR;
 460                        wid_list[i].size = sizeof(char);
 461                        hif_drv->cfg_values.bss_type = bss_type;
 462                } else {
 463                        netdev_err(vif->ndev, "check value 6 over\n");
 464                        goto unlock;
 465                }
 466                i++;
 467        }
 468        if (cfg_param_attr->flag & AUTH_TYPE) {
 469                if (cfg_param_attr->auth_type == 1 ||
 470                    cfg_param_attr->auth_type == 2 ||
 471                    cfg_param_attr->auth_type == 5) {
 472                        wid_list[i].id = WID_AUTH_TYPE;
 473                        wid_list[i].val = (s8 *)&cfg_param_attr->auth_type;
 474                        wid_list[i].type = WID_CHAR;
 475                        wid_list[i].size = sizeof(char);
 476                        hif_drv->cfg_values.auth_type = (u8)cfg_param_attr->auth_type;
 477                } else {
 478                        netdev_err(vif->ndev, "Impossible value\n");
 479                        goto unlock;
 480                }
 481                i++;
 482        }
 483        if (cfg_param_attr->flag & AUTHEN_TIMEOUT) {
 484                if (cfg_param_attr->auth_timeout > 0 &&
 485                    cfg_param_attr->auth_timeout < 65536) {
 486                        wid_list[i].id = WID_AUTH_TIMEOUT;
 487                        wid_list[i].val = (s8 *)&cfg_param_attr->auth_timeout;
 488                        wid_list[i].type = WID_SHORT;
 489                        wid_list[i].size = sizeof(u16);
 490                        hif_drv->cfg_values.auth_timeout = cfg_param_attr->auth_timeout;
 491                } else {
 492                        netdev_err(vif->ndev, "Range(1 ~ 65535) over\n");
 493                        goto unlock;
 494                }
 495                i++;
 496        }
 497        if (cfg_param_attr->flag & POWER_MANAGEMENT) {
 498                if (cfg_param_attr->power_mgmt_mode < 5) {
 499                        wid_list[i].id = WID_POWER_MANAGEMENT;
 500                        wid_list[i].val = (s8 *)&cfg_param_attr->power_mgmt_mode;
 501                        wid_list[i].type = WID_CHAR;
 502                        wid_list[i].size = sizeof(char);
 503                        hif_drv->cfg_values.power_mgmt_mode = (u8)cfg_param_attr->power_mgmt_mode;
 504                } else {
 505                        netdev_err(vif->ndev, "Invalid power mode\n");
 506                        goto unlock;
 507                }
 508                i++;
 509        }
 510        if (cfg_param_attr->flag & RETRY_SHORT) {
 511                if (cfg_param_attr->short_retry_limit > 0 &&
 512                    cfg_param_attr->short_retry_limit < 256) {
 513                        wid_list[i].id = WID_SHORT_RETRY_LIMIT;
 514                        wid_list[i].val = (s8 *)&cfg_param_attr->short_retry_limit;
 515                        wid_list[i].type = WID_SHORT;
 516                        wid_list[i].size = sizeof(u16);
 517                        hif_drv->cfg_values.short_retry_limit = cfg_param_attr->short_retry_limit;
 518                } else {
 519                        netdev_err(vif->ndev, "Range(1~256) over\n");
 520                        goto unlock;
 521                }
 522                i++;
 523        }
 524        if (cfg_param_attr->flag & RETRY_LONG) {
 525                if (cfg_param_attr->long_retry_limit > 0 &&
 526                    cfg_param_attr->long_retry_limit < 256) {
 527                        wid_list[i].id = WID_LONG_RETRY_LIMIT;
 528                        wid_list[i].val = (s8 *)&cfg_param_attr->long_retry_limit;
 529                        wid_list[i].type = WID_SHORT;
 530                        wid_list[i].size = sizeof(u16);
 531                        hif_drv->cfg_values.long_retry_limit = cfg_param_attr->long_retry_limit;
 532                } else {
 533                        netdev_err(vif->ndev, "Range(1~256) over\n");
 534                        goto unlock;
 535                }
 536                i++;
 537        }
 538        if (cfg_param_attr->flag & FRAG_THRESHOLD) {
 539                if (cfg_param_attr->frag_threshold > 255 &&
 540                    cfg_param_attr->frag_threshold < 7937) {
 541                        wid_list[i].id = WID_FRAG_THRESHOLD;
 542                        wid_list[i].val = (s8 *)&cfg_param_attr->frag_threshold;
 543                        wid_list[i].type = WID_SHORT;
 544                        wid_list[i].size = sizeof(u16);
 545                        hif_drv->cfg_values.frag_threshold = cfg_param_attr->frag_threshold;
 546                } else {
 547                        netdev_err(vif->ndev, "Threshold Range fail\n");
 548                        goto unlock;
 549                }
 550                i++;
 551        }
 552        if (cfg_param_attr->flag & RTS_THRESHOLD) {
 553                if (cfg_param_attr->rts_threshold > 255 &&
 554                    cfg_param_attr->rts_threshold < 65536) {
 555                        wid_list[i].id = WID_RTS_THRESHOLD;
 556                        wid_list[i].val = (s8 *)&cfg_param_attr->rts_threshold;
 557                        wid_list[i].type = WID_SHORT;
 558                        wid_list[i].size = sizeof(u16);
 559                        hif_drv->cfg_values.rts_threshold = cfg_param_attr->rts_threshold;
 560                } else {
 561                        netdev_err(vif->ndev, "Threshold Range fail\n");
 562                        goto unlock;
 563                }
 564                i++;
 565        }
 566        if (cfg_param_attr->flag & PREAMBLE) {
 567                if (cfg_param_attr->preamble_type < 3) {
 568                        wid_list[i].id = WID_PREAMBLE;
 569                        wid_list[i].val = (s8 *)&cfg_param_attr->preamble_type;
 570                        wid_list[i].type = WID_CHAR;
 571                        wid_list[i].size = sizeof(char);
 572                        hif_drv->cfg_values.preamble_type = cfg_param_attr->preamble_type;
 573                } else {
 574                        netdev_err(vif->ndev, "Preamle Range(0~2) over\n");
 575                        goto unlock;
 576                }
 577                i++;
 578        }
 579        if (cfg_param_attr->flag & SHORT_SLOT_ALLOWED) {
 580                if (cfg_param_attr->short_slot_allowed < 2) {
 581                        wid_list[i].id = WID_SHORT_SLOT_ALLOWED;
 582                        wid_list[i].val = (s8 *)&cfg_param_attr->short_slot_allowed;
 583                        wid_list[i].type = WID_CHAR;
 584                        wid_list[i].size = sizeof(char);
 585                        hif_drv->cfg_values.short_slot_allowed = (u8)cfg_param_attr->short_slot_allowed;
 586                } else {
 587                        netdev_err(vif->ndev, "Short slot(2) over\n");
 588                        goto unlock;
 589                }
 590                i++;
 591        }
 592        if (cfg_param_attr->flag & TXOP_PROT_DISABLE) {
 593                if (cfg_param_attr->txop_prot_disabled < 2) {
 594                        wid_list[i].id = WID_11N_TXOP_PROT_DISABLE;
 595                        wid_list[i].val = (s8 *)&cfg_param_attr->txop_prot_disabled;
 596                        wid_list[i].type = WID_CHAR;
 597                        wid_list[i].size = sizeof(char);
 598                        hif_drv->cfg_values.txop_prot_disabled = (u8)cfg_param_attr->txop_prot_disabled;
 599                } else {
 600                        netdev_err(vif->ndev, "TXOP prot disable\n");
 601                        goto unlock;
 602                }
 603                i++;
 604        }
 605        if (cfg_param_attr->flag & BEACON_INTERVAL) {
 606                if (cfg_param_attr->beacon_interval > 0 &&
 607                    cfg_param_attr->beacon_interval < 65536) {
 608                        wid_list[i].id = WID_BEACON_INTERVAL;
 609                        wid_list[i].val = (s8 *)&cfg_param_attr->beacon_interval;
 610                        wid_list[i].type = WID_SHORT;
 611                        wid_list[i].size = sizeof(u16);
 612                        hif_drv->cfg_values.beacon_interval = cfg_param_attr->beacon_interval;
 613                } else {
 614                        netdev_err(vif->ndev, "Beacon interval(1~65535)fail\n");
 615                        goto unlock;
 616                }
 617                i++;
 618        }
 619        if (cfg_param_attr->flag & DTIM_PERIOD) {
 620                if (cfg_param_attr->dtim_period > 0 &&
 621                    cfg_param_attr->dtim_period < 256) {
 622                        wid_list[i].id = WID_DTIM_PERIOD;
 623                        wid_list[i].val = (s8 *)&cfg_param_attr->dtim_period;
 624                        wid_list[i].type = WID_CHAR;
 625                        wid_list[i].size = sizeof(char);
 626                        hif_drv->cfg_values.dtim_period = cfg_param_attr->dtim_period;
 627                } else {
 628                        netdev_err(vif->ndev, "DTIM range(1~255) fail\n");
 629                        goto unlock;
 630                }
 631                i++;
 632        }
 633        if (cfg_param_attr->flag & SITE_SURVEY) {
 634                if (cfg_param_attr->site_survey_enabled < 3) {
 635                        wid_list[i].id = WID_SITE_SURVEY;
 636                        wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_enabled;
 637                        wid_list[i].type = WID_CHAR;
 638                        wid_list[i].size = sizeof(char);
 639                        hif_drv->cfg_values.site_survey_enabled = (u8)cfg_param_attr->site_survey_enabled;
 640                } else {
 641                        netdev_err(vif->ndev, "Site survey disable\n");
 642                        goto unlock;
 643                }
 644                i++;
 645        }
 646        if (cfg_param_attr->flag & SITE_SURVEY_SCAN_TIME) {
 647                if (cfg_param_attr->site_survey_scan_time > 0 &&
 648                    cfg_param_attr->site_survey_scan_time < 65536) {
 649                        wid_list[i].id = WID_SITE_SURVEY_SCAN_TIME;
 650                        wid_list[i].val = (s8 *)&cfg_param_attr->site_survey_scan_time;
 651                        wid_list[i].type = WID_SHORT;
 652                        wid_list[i].size = sizeof(u16);
 653                        hif_drv->cfg_values.site_survey_scan_time = cfg_param_attr->site_survey_scan_time;
 654                } else {
 655                        netdev_err(vif->ndev, "Site scan time(1~65535) over\n");
 656                        goto unlock;
 657                }
 658                i++;
 659        }
 660        if (cfg_param_attr->flag & ACTIVE_SCANTIME) {
 661                if (cfg_param_attr->active_scan_time > 0 &&
 662                    cfg_param_attr->active_scan_time < 65536) {
 663                        wid_list[i].id = WID_ACTIVE_SCAN_TIME;
 664                        wid_list[i].val = (s8 *)&cfg_param_attr->active_scan_time;
 665                        wid_list[i].type = WID_SHORT;
 666                        wid_list[i].size = sizeof(u16);
 667                        hif_drv->cfg_values.active_scan_time = cfg_param_attr->active_scan_time;
 668                } else {
 669                        netdev_err(vif->ndev, "Active time(1~65535) over\n");
 670                        goto unlock;
 671                }
 672                i++;
 673        }
 674        if (cfg_param_attr->flag & PASSIVE_SCANTIME) {
 675                if (cfg_param_attr->passive_scan_time > 0 &&
 676                    cfg_param_attr->passive_scan_time < 65536) {
 677                        wid_list[i].id = WID_PASSIVE_SCAN_TIME;
 678                        wid_list[i].val = (s8 *)&cfg_param_attr->passive_scan_time;
 679                        wid_list[i].type = WID_SHORT;
 680                        wid_list[i].size = sizeof(u16);
 681                        hif_drv->cfg_values.passive_scan_time = cfg_param_attr->passive_scan_time;
 682                } else {
 683                        netdev_err(vif->ndev, "Passive time(1~65535) over\n");
 684                        goto unlock;
 685                }
 686                i++;
 687        }
 688        if (cfg_param_attr->flag & CURRENT_TX_RATE) {
 689                enum CURRENT_TXRATE curr_tx_rate = cfg_param_attr->curr_tx_rate;
 690
 691                if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1 ||
 692                    curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5 ||
 693                    curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6 ||
 694                    curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12 ||
 695                    curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24 ||
 696                    curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 ||
 697                    curr_tx_rate == MBPS_54) {
 698                        wid_list[i].id = WID_CURRENT_TX_RATE;
 699                        wid_list[i].val = (s8 *)&curr_tx_rate;
 700                        wid_list[i].type = WID_SHORT;
 701                        wid_list[i].size = sizeof(u16);
 702                        hif_drv->cfg_values.curr_tx_rate = (u8)curr_tx_rate;
 703                } else {
 704                        netdev_err(vif->ndev, "out of TX rate\n");
 705                        goto unlock;
 706                }
 707                i++;
 708        }
 709
 710        ret = wilc_send_config_pkt(vif, SET_CFG, wid_list,
 711                                   i, wilc_get_vif_idx(vif));
 712
 713        if (ret)
 714                netdev_err(vif->ndev, "Error in setting CFG params\n");
 715
 716unlock:
 717        mutex_unlock(&hif_drv->cfg_values_lock);
 718}
 719
 720static s32 handle_scan(struct wilc_vif *vif, struct scan_attr *scan_info)
 721{
 722        s32 result = 0;
 723        struct wid wid_list[5];
 724        u32 index = 0;
 725        u32 i;
 726        u8 *buffer;
 727        u8 valuesize = 0;
 728        u8 *pu8HdnNtwrksWidVal = NULL;
 729        struct host_if_drv *hif_drv = vif->hif_drv;
 730
 731        hif_drv->usr_scan_req.scan_result = scan_info->result;
 732        hif_drv->usr_scan_req.arg = scan_info->arg;
 733
 734        if ((hif_drv->hif_state >= HOST_IF_SCANNING) &&
 735            (hif_drv->hif_state < HOST_IF_CONNECTED)) {
 736                netdev_err(vif->ndev, "Already scan\n");
 737                result = -EBUSY;
 738                goto ERRORHANDLER;
 739        }
 740
 741        if (wilc_optaining_ip || wilc_connecting) {
 742                netdev_err(vif->ndev, "Don't do obss scan\n");
 743                result = -EBUSY;
 744                goto ERRORHANDLER;
 745        }
 746
 747        hif_drv->usr_scan_req.rcvd_ch_cnt = 0;
 748
 749        wid_list[index].id = (u16)WID_SSID_PROBE_REQ;
 750        wid_list[index].type = WID_STR;
 751
 752        for (i = 0; i < scan_info->hidden_network.n_ssids; i++)
 753                valuesize += ((scan_info->hidden_network.net_info[i].ssid_len) + 1);
 754        pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
 755        wid_list[index].val = pu8HdnNtwrksWidVal;
 756        if (wid_list[index].val) {
 757                buffer = wid_list[index].val;
 758
 759                *buffer++ = scan_info->hidden_network.n_ssids;
 760
 761                for (i = 0; i < scan_info->hidden_network.n_ssids; i++) {
 762                        *buffer++ = scan_info->hidden_network.net_info[i].ssid_len;
 763                        memcpy(buffer, scan_info->hidden_network.net_info[i].ssid, scan_info->hidden_network.net_info[i].ssid_len);
 764                        buffer += scan_info->hidden_network.net_info[i].ssid_len;
 765                }
 766
 767                wid_list[index].size = (s32)(valuesize + 1);
 768                index++;
 769        }
 770
 771        wid_list[index].id = WID_INFO_ELEMENT_PROBE;
 772        wid_list[index].type = WID_BIN_DATA;
 773        wid_list[index].val = scan_info->ies;
 774        wid_list[index].size = scan_info->ies_len;
 775        index++;
 776
 777        wid_list[index].id = WID_SCAN_TYPE;
 778        wid_list[index].type = WID_CHAR;
 779        wid_list[index].size = sizeof(char);
 780        wid_list[index].val = (s8 *)&scan_info->type;
 781        index++;
 782
 783        wid_list[index].id = WID_SCAN_CHANNEL_LIST;
 784        wid_list[index].type = WID_BIN_DATA;
 785
 786        if (scan_info->ch_freq_list &&
 787            scan_info->ch_list_len > 0) {
 788                int i;
 789
 790                for (i = 0; i < scan_info->ch_list_len; i++)    {
 791                        if (scan_info->ch_freq_list[i] > 0)
 792                                scan_info->ch_freq_list[i] = scan_info->ch_freq_list[i] - 1;
 793                }
 794        }
 795
 796        wid_list[index].val = scan_info->ch_freq_list;
 797        wid_list[index].size = scan_info->ch_list_len;
 798        index++;
 799
 800        wid_list[index].id = WID_START_SCAN_REQ;
 801        wid_list[index].type = WID_CHAR;
 802        wid_list[index].size = sizeof(char);
 803        wid_list[index].val = (s8 *)&scan_info->src;
 804        index++;
 805
 806        if (hif_drv->hif_state == HOST_IF_CONNECTED)
 807                scan_while_connected = true;
 808        else if (hif_drv->hif_state == HOST_IF_IDLE)
 809                scan_while_connected = false;
 810
 811        result = wilc_send_config_pkt(vif, SET_CFG, wid_list,
 812                                      index,
 813                                      wilc_get_vif_idx(vif));
 814
 815        if (result)
 816                netdev_err(vif->ndev, "Failed to send scan parameters\n");
 817
 818ERRORHANDLER:
 819        if (result) {
 820                del_timer(&hif_drv->scan_timer);
 821                Handle_ScanDone(vif, SCAN_EVENT_ABORTED);
 822        }
 823
 824        kfree(scan_info->ch_freq_list);
 825        scan_info->ch_freq_list = NULL;
 826
 827        kfree(scan_info->ies);
 828        scan_info->ies = NULL;
 829        kfree(scan_info->hidden_network.net_info);
 830        scan_info->hidden_network.net_info = NULL;
 831
 832        kfree(pu8HdnNtwrksWidVal);
 833
 834        return result;
 835}
 836
 837static s32 Handle_ScanDone(struct wilc_vif *vif,
 838                           enum scan_event enuEvent)
 839{
 840        s32 result = 0;
 841        u8 u8abort_running_scan;
 842        struct wid wid;
 843        struct host_if_drv *hif_drv = vif->hif_drv;
 844
 845        if (enuEvent == SCAN_EVENT_ABORTED) {
 846                u8abort_running_scan = 1;
 847                wid.id = (u16)WID_ABORT_RUNNING_SCAN;
 848                wid.type = WID_CHAR;
 849                wid.val = (s8 *)&u8abort_running_scan;
 850                wid.size = sizeof(char);
 851
 852                result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
 853                                              wilc_get_vif_idx(vif));
 854
 855                if (result) {
 856                        netdev_err(vif->ndev, "Failed to set abort running\n");
 857                        result = -EFAULT;
 858                }
 859        }
 860
 861        if (!hif_drv) {
 862                netdev_err(vif->ndev, "Driver handler is NULL\n");
 863                return result;
 864        }
 865
 866        if (hif_drv->usr_scan_req.scan_result) {
 867                hif_drv->usr_scan_req.scan_result(enuEvent, NULL,
 868                                                  hif_drv->usr_scan_req.arg, NULL);
 869                hif_drv->usr_scan_req.scan_result = NULL;
 870        }
 871
 872        return result;
 873}
 874
 875u8 wilc_connected_ssid[6] = {0};
 876static s32 Handle_Connect(struct wilc_vif *vif,
 877                          struct connect_attr *pstrHostIFconnectAttr)
 878{
 879        s32 result = 0;
 880        struct wid strWIDList[8];
 881        u32 u32WidsCount = 0, dummyval = 0;
 882        u8 *pu8CurrByte = NULL;
 883        struct join_bss_param *ptstrJoinBssParam;
 884        struct host_if_drv *hif_drv = vif->hif_drv;
 885
 886        if (memcmp(pstrHostIFconnectAttr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) {
 887                result = 0;
 888                netdev_err(vif->ndev, "Discard connect request\n");
 889                return result;
 890        }
 891
 892        ptstrJoinBssParam = pstrHostIFconnectAttr->params;
 893        if (!ptstrJoinBssParam) {
 894                netdev_err(vif->ndev, "Required BSSID not found\n");
 895                result = -ENOENT;
 896                goto ERRORHANDLER;
 897        }
 898
 899        if (pstrHostIFconnectAttr->bssid) {
 900                hif_drv->usr_conn_req.bssid = kmalloc(6, GFP_KERNEL);
 901                memcpy(hif_drv->usr_conn_req.bssid, pstrHostIFconnectAttr->bssid, 6);
 902        }
 903
 904        hif_drv->usr_conn_req.ssid_len = pstrHostIFconnectAttr->ssid_len;
 905        if (pstrHostIFconnectAttr->ssid) {
 906                hif_drv->usr_conn_req.ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
 907                memcpy(hif_drv->usr_conn_req.ssid,
 908                       pstrHostIFconnectAttr->ssid,
 909                       pstrHostIFconnectAttr->ssid_len);
 910                hif_drv->usr_conn_req.ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
 911        }
 912
 913        hif_drv->usr_conn_req.ies_len = pstrHostIFconnectAttr->ies_len;
 914        if (pstrHostIFconnectAttr->ies) {
 915                hif_drv->usr_conn_req.ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
 916                memcpy(hif_drv->usr_conn_req.ies,
 917                       pstrHostIFconnectAttr->ies,
 918                       pstrHostIFconnectAttr->ies_len);
 919        }
 920
 921        hif_drv->usr_conn_req.security = pstrHostIFconnectAttr->security;
 922        hif_drv->usr_conn_req.auth_type = pstrHostIFconnectAttr->auth_type;
 923        hif_drv->usr_conn_req.conn_result = pstrHostIFconnectAttr->result;
 924        hif_drv->usr_conn_req.arg = pstrHostIFconnectAttr->arg;
 925
 926        strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_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_RECEIVED_FRAGMENT_COUNT;
 933        strWIDList[u32WidsCount].type = WID_INT;
 934        strWIDList[u32WidsCount].size = sizeof(u32);
 935        strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
 936        u32WidsCount++;
 937
 938        strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
 939        strWIDList[u32WidsCount].type = WID_INT;
 940        strWIDList[u32WidsCount].size = sizeof(u32);
 941        strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
 942        u32WidsCount++;
 943
 944        {
 945                strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
 946                strWIDList[u32WidsCount].type = WID_BIN_DATA;
 947                strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.ies;
 948                strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ies_len;
 949                u32WidsCount++;
 950
 951                if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
 952                        info_element_size = hif_drv->usr_conn_req.ies_len;
 953                        info_element = kmalloc(info_element_size, GFP_KERNEL);
 954                        memcpy(info_element, hif_drv->usr_conn_req.ies,
 955                               info_element_size);
 956                }
 957        }
 958        strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
 959        strWIDList[u32WidsCount].type = WID_CHAR;
 960        strWIDList[u32WidsCount].size = sizeof(char);
 961        strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.security;
 962        u32WidsCount++;
 963
 964        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
 965                mode_11i = hif_drv->usr_conn_req.security;
 966
 967        strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
 968        strWIDList[u32WidsCount].type = WID_CHAR;
 969        strWIDList[u32WidsCount].size = sizeof(char);
 970        strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.auth_type;
 971        u32WidsCount++;
 972
 973        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
 974                auth_type = (u8)hif_drv->usr_conn_req.auth_type;
 975
 976        strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
 977        strWIDList[u32WidsCount].type = WID_STR;
 978        strWIDList[u32WidsCount].size = 112;
 979        strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
 980
 981        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
 982                join_req_size = strWIDList[u32WidsCount].size;
 983                join_req = kmalloc(join_req_size, GFP_KERNEL);
 984        }
 985        if (!strWIDList[u32WidsCount].val) {
 986                result = -EFAULT;
 987                goto ERRORHANDLER;
 988        }
 989
 990        pu8CurrByte = strWIDList[u32WidsCount].val;
 991
 992        if (pstrHostIFconnectAttr->ssid) {
 993                memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
 994                pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
 995        }
 996        pu8CurrByte += MAX_SSID_LEN;
 997        *(pu8CurrByte++) = INFRASTRUCTURE;
 998
 999        if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
1000                *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
1001        } else {
1002                netdev_err(vif->ndev, "Channel out of range\n");
1003                *(pu8CurrByte++) = 0xFF;
1004        }
1005        *(pu8CurrByte++)  = (ptstrJoinBssParam->cap_info) & 0xFF;
1006        *(pu8CurrByte++)  = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
1007
1008        if (pstrHostIFconnectAttr->bssid)
1009                memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1010        pu8CurrByte += 6;
1011
1012        if (pstrHostIFconnectAttr->bssid)
1013                memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1014        pu8CurrByte += 6;
1015
1016        *(pu8CurrByte++)  = (ptstrJoinBssParam->beacon_period) & 0xFF;
1017        *(pu8CurrByte++)  = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
1018        *(pu8CurrByte++)  =  ptstrJoinBssParam->dtim_period;
1019
1020        memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
1021        pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1022
1023        *(pu8CurrByte++)  =  ptstrJoinBssParam->wmm_cap;
1024        *(pu8CurrByte++)  = ptstrJoinBssParam->uapsd_cap;
1025
1026        *(pu8CurrByte++)  = ptstrJoinBssParam->ht_capable;
1027        hif_drv->usr_conn_req.ht_capable = ptstrJoinBssParam->ht_capable;
1028
1029        *(pu8CurrByte++)  =  ptstrJoinBssParam->rsn_found;
1030        *(pu8CurrByte++)  =  ptstrJoinBssParam->rsn_grp_policy;
1031        *(pu8CurrByte++) =  ptstrJoinBssParam->mode_802_11i;
1032
1033        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
1034        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1035
1036        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
1037        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1038
1039        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
1040        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1041
1042        *(pu8CurrByte++) = REAL_JOIN_REQ;
1043        *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
1044
1045        if (ptstrJoinBssParam->noa_enabled) {
1046                *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1047                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1048                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1049                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1050
1051                *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
1052                *(pu8CurrByte++) = ptstrJoinBssParam->idx;
1053
1054                if (ptstrJoinBssParam->opp_enabled)
1055                        *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
1056
1057                *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
1058
1059                memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
1060                pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
1061
1062                memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
1063                pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
1064
1065                memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
1066                pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
1067        }
1068
1069        pu8CurrByte = strWIDList[u32WidsCount].val;
1070        u32WidsCount++;
1071
1072        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1073                memcpy(join_req, pu8CurrByte, join_req_size);
1074                join_req_vif = vif;
1075        }
1076
1077        if (pstrHostIFconnectAttr->bssid)
1078                memcpy(wilc_connected_ssid,
1079                       pstrHostIFconnectAttr->bssid, ETH_ALEN);
1080
1081        result = wilc_send_config_pkt(vif, SET_CFG, strWIDList,
1082                                      u32WidsCount,
1083                                      wilc_get_vif_idx(vif));
1084        if (result) {
1085                netdev_err(vif->ndev, "failed to send config packet\n");
1086                result = -EFAULT;
1087                goto ERRORHANDLER;
1088        } else {
1089                hif_drv->hif_state = HOST_IF_WAITING_CONN_RESP;
1090        }
1091
1092ERRORHANDLER:
1093        if (result) {
1094                struct connect_info strConnectInfo;
1095
1096                del_timer(&hif_drv->connect_timer);
1097
1098                memset(&strConnectInfo, 0, sizeof(struct connect_info));
1099
1100                if (pstrHostIFconnectAttr->result) {
1101                        if (pstrHostIFconnectAttr->bssid)
1102                                memcpy(strConnectInfo.bssid, pstrHostIFconnectAttr->bssid, 6);
1103
1104                        if (pstrHostIFconnectAttr->ies) {
1105                                strConnectInfo.req_ies_len = pstrHostIFconnectAttr->ies_len;
1106                                strConnectInfo.req_ies = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1107                                memcpy(strConnectInfo.req_ies,
1108                                       pstrHostIFconnectAttr->ies,
1109                                       pstrHostIFconnectAttr->ies_len);
1110                        }
1111
1112                        pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
1113                                                               &strConnectInfo,
1114                                                               MAC_DISCONNECTED,
1115                                                               NULL,
1116                                                               pstrHostIFconnectAttr->arg);
1117                        hif_drv->hif_state = HOST_IF_IDLE;
1118                        kfree(strConnectInfo.req_ies);
1119                        strConnectInfo.req_ies = NULL;
1120
1121                } else {
1122                        netdev_err(vif->ndev, "Connect callback is NULL\n");
1123                }
1124        }
1125
1126        kfree(pstrHostIFconnectAttr->bssid);
1127        pstrHostIFconnectAttr->bssid = NULL;
1128
1129        kfree(pstrHostIFconnectAttr->ssid);
1130        pstrHostIFconnectAttr->ssid = NULL;
1131
1132        kfree(pstrHostIFconnectAttr->ies);
1133        pstrHostIFconnectAttr->ies = NULL;
1134
1135        kfree(pu8CurrByte);
1136        return result;
1137}
1138
1139static s32 Handle_ConnectTimeout(struct wilc_vif *vif)
1140{
1141        s32 result = 0;
1142        struct connect_info strConnectInfo;
1143        struct wid wid;
1144        u16 u16DummyReasonCode = 0;
1145        struct host_if_drv *hif_drv = vif->hif_drv;
1146
1147        if (!hif_drv) {
1148                netdev_err(vif->ndev, "Driver handler is NULL\n");
1149                return result;
1150        }
1151
1152        hif_drv->hif_state = HOST_IF_IDLE;
1153
1154        scan_while_connected = false;
1155
1156        memset(&strConnectInfo, 0, sizeof(struct connect_info));
1157
1158        if (hif_drv->usr_conn_req.conn_result) {
1159                if (hif_drv->usr_conn_req.bssid) {
1160                        memcpy(strConnectInfo.bssid,
1161                               hif_drv->usr_conn_req.bssid, 6);
1162                }
1163
1164                if (hif_drv->usr_conn_req.ies) {
1165                        strConnectInfo.req_ies_len = hif_drv->usr_conn_req.ies_len;
1166                        strConnectInfo.req_ies = kmalloc(hif_drv->usr_conn_req.ies_len, GFP_KERNEL);
1167                        memcpy(strConnectInfo.req_ies,
1168                               hif_drv->usr_conn_req.ies,
1169                               hif_drv->usr_conn_req.ies_len);
1170                }
1171
1172                hif_drv->usr_conn_req.conn_result(CONN_DISCONN_EVENT_CONN_RESP,
1173                                                  &strConnectInfo,
1174                                                  MAC_DISCONNECTED,
1175                                                  NULL,
1176                                                  hif_drv->usr_conn_req.arg);
1177
1178                kfree(strConnectInfo.req_ies);
1179                strConnectInfo.req_ies = NULL;
1180        } else {
1181                netdev_err(vif->ndev, "Connect callback is NULL\n");
1182        }
1183
1184        wid.id = (u16)WID_DISCONNECT;
1185        wid.type = WID_CHAR;
1186        wid.val = (s8 *)&u16DummyReasonCode;
1187        wid.size = sizeof(char);
1188
1189        result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
1190                                      wilc_get_vif_idx(vif));
1191        if (result)
1192                netdev_err(vif->ndev, "Failed to send dissconect\n");
1193
1194        hif_drv->usr_conn_req.ssid_len = 0;
1195        kfree(hif_drv->usr_conn_req.ssid);
1196        hif_drv->usr_conn_req.ssid = NULL;
1197        kfree(hif_drv->usr_conn_req.bssid);
1198        hif_drv->usr_conn_req.bssid = NULL;
1199        hif_drv->usr_conn_req.ies_len = 0;
1200        kfree(hif_drv->usr_conn_req.ies);
1201        hif_drv->usr_conn_req.ies = NULL;
1202
1203        eth_zero_addr(wilc_connected_ssid);
1204
1205        if (join_req && join_req_vif == vif) {
1206                kfree(join_req);
1207                join_req = NULL;
1208        }
1209
1210        if (info_element && join_req_vif == vif) {
1211                kfree(info_element);
1212                info_element = NULL;
1213        }
1214
1215        return result;
1216}
1217
1218static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif,
1219                                struct rcvd_net_info *pstrRcvdNetworkInfo)
1220{
1221        u32 i;
1222        bool bNewNtwrkFound;
1223        s32 result = 0;
1224        struct network_info *pstrNetworkInfo = NULL;
1225        void *pJoinParams = NULL;
1226        struct host_if_drv *hif_drv = vif->hif_drv;
1227
1228        bNewNtwrkFound = true;
1229
1230        if (hif_drv->usr_scan_req.scan_result) {
1231                wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
1232                if ((!pstrNetworkInfo) ||
1233                    (!hif_drv->usr_scan_req.scan_result)) {
1234                        netdev_err(vif->ndev, "driver is null\n");
1235                        result = -EINVAL;
1236                        goto done;
1237                }
1238
1239                for (i = 0; i < hif_drv->usr_scan_req.rcvd_ch_cnt; i++) {
1240                        if (memcmp(hif_drv->usr_scan_req.net_info[i].bssid,
1241                                   pstrNetworkInfo->bssid, 6) == 0) {
1242                                if (pstrNetworkInfo->rssi <= hif_drv->usr_scan_req.net_info[i].rssi) {
1243                                        goto done;
1244                                } else {
1245                                        hif_drv->usr_scan_req.net_info[i].rssi = pstrNetworkInfo->rssi;
1246                                        bNewNtwrkFound = false;
1247                                        break;
1248                                }
1249                        }
1250                }
1251
1252                if (bNewNtwrkFound) {
1253                        if (hif_drv->usr_scan_req.rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) {
1254                                hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].rssi = pstrNetworkInfo->rssi;
1255
1256                                memcpy(hif_drv->usr_scan_req.net_info[hif_drv->usr_scan_req.rcvd_ch_cnt].bssid,
1257                                       pstrNetworkInfo->bssid, 6);
1258
1259                                hif_drv->usr_scan_req.rcvd_ch_cnt++;
1260
1261                                pstrNetworkInfo->new_network = true;
1262                                pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
1263
1264                                hif_drv->usr_scan_req.scan_result(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1265                                                                  hif_drv->usr_scan_req.arg,
1266                                                                  pJoinParams);
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_enqueue_cmd(&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 void host_if_work(struct work_struct *work)
2468{
2469        struct host_if_msg *msg;
2470        struct wilc *wilc;
2471
2472        msg = container_of(work, struct host_if_msg, work);
2473        wilc = msg->vif->wilc;
2474
2475        if (msg->id == HOST_IF_MSG_CONNECT &&
2476            msg->vif->hif_drv->usr_scan_req.scan_result) {
2477                wilc_enqueue_cmd(msg);
2478                usleep_range(2 * 1000, 2 * 1000);
2479                goto free_msg;
2480        }
2481        switch (msg->id) {
2482        case HOST_IF_MSG_SCAN:
2483                handle_scan(msg->vif, &msg->body.scan_info);
2484                break;
2485
2486        case HOST_IF_MSG_CONNECT:
2487                Handle_Connect(msg->vif, &msg->body.con_info);
2488                break;
2489
2490        case HOST_IF_MSG_RCVD_NTWRK_INFO:
2491                Handle_RcvdNtwrkInfo(msg->vif, &msg->body.net_info);
2492                break;
2493
2494        case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2495                Handle_RcvdGnrlAsyncInfo(msg->vif,
2496                                         &msg->body.async_info);
2497                break;
2498
2499        case HOST_IF_MSG_KEY:
2500                Handle_Key(msg->vif, &msg->body.key_info);
2501                break;
2502
2503        case HOST_IF_MSG_CFG_PARAMS:
2504                handle_cfg_param(msg->vif, &msg->body.cfg_info);
2505                break;
2506
2507        case HOST_IF_MSG_SET_CHANNEL:
2508                handle_set_channel(msg->vif, &msg->body.channel_info);
2509                break;
2510
2511        case HOST_IF_MSG_DISCONNECT:
2512                Handle_Disconnect(msg->vif);
2513                break;
2514
2515        case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2516                del_timer(&msg->vif->hif_drv->scan_timer);
2517
2518                if (!wilc_wlan_get_num_conn_ifcs(wilc))
2519                        wilc_chip_sleep_manually(wilc);
2520
2521                Handle_ScanDone(msg->vif, SCAN_EVENT_DONE);
2522
2523                if (msg->vif->hif_drv->remain_on_ch_pending)
2524                        Handle_RemainOnChan(msg->vif,
2525                                            &msg->body.remain_on_ch);
2526
2527                break;
2528
2529        case HOST_IF_MSG_GET_RSSI:
2530                Handle_GetRssi(msg->vif);
2531                break;
2532
2533        case HOST_IF_MSG_GET_STATISTICS:
2534                Handle_GetStatistics(msg->vif,
2535                                     (struct rf_info *)msg->body.data);
2536                break;
2537
2538        case HOST_IF_MSG_ADD_BEACON:
2539                Handle_AddBeacon(msg->vif, &msg->body.beacon_info);
2540                break;
2541
2542        case HOST_IF_MSG_DEL_BEACON:
2543                Handle_DelBeacon(msg->vif);
2544                break;
2545
2546        case HOST_IF_MSG_ADD_STATION:
2547                Handle_AddStation(msg->vif, &msg->body.add_sta_info);
2548                break;
2549
2550        case HOST_IF_MSG_DEL_STATION:
2551                Handle_DelStation(msg->vif, &msg->body.del_sta_info);
2552                break;
2553
2554        case HOST_IF_MSG_EDIT_STATION:
2555                Handle_EditStation(msg->vif, &msg->body.edit_sta_info);
2556                break;
2557
2558        case HOST_IF_MSG_GET_INACTIVETIME:
2559                Handle_Get_InActiveTime(msg->vif, &msg->body.mac_info);
2560                break;
2561
2562        case HOST_IF_MSG_SCAN_TIMER_FIRED:
2563                Handle_ScanDone(msg->vif, SCAN_EVENT_ABORTED);
2564                break;
2565
2566        case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2567                Handle_ConnectTimeout(msg->vif);
2568                break;
2569
2570        case HOST_IF_MSG_POWER_MGMT:
2571                Handle_PowerManagement(msg->vif,
2572                                       &msg->body.pwr_mgmt_info);
2573                break;
2574
2575        case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2576                handle_set_wfi_drv_handler(msg->vif, &msg->body.drv);
2577                break;
2578
2579        case HOST_IF_MSG_SET_OPERATION_MODE:
2580                handle_set_operation_mode(msg->vif, &msg->body.mode);
2581                break;
2582
2583        case HOST_IF_MSG_SET_IPADDRESS:
2584                handle_set_ip_address(msg->vif,
2585                                      msg->body.ip_info.ip_addr,
2586                                      msg->body.ip_info.idx);
2587                break;
2588
2589        case HOST_IF_MSG_GET_IPADDRESS:
2590                handle_get_ip_address(msg->vif, msg->body.ip_info.idx);
2591                break;
2592
2593        case HOST_IF_MSG_GET_MAC_ADDRESS:
2594                handle_get_mac_address(msg->vif,
2595                                       &msg->body.get_mac_info);
2596                break;
2597
2598        case HOST_IF_MSG_REMAIN_ON_CHAN:
2599                Handle_RemainOnChan(msg->vif, &msg->body.remain_on_ch);
2600                break;
2601
2602        case HOST_IF_MSG_REGISTER_FRAME:
2603                Handle_RegisterFrame(msg->vif, &msg->body.reg_frame);
2604                break;
2605
2606        case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2607                Handle_ListenStateExpired(msg->vif, &msg->body.remain_on_ch);
2608                break;
2609
2610        case HOST_IF_MSG_SET_MULTICAST_FILTER:
2611                Handle_SetMulticastFilter(msg->vif, &msg->body.multicast_info);
2612                break;
2613
2614        case HOST_IF_MSG_DEL_ALL_STA:
2615                Handle_DelAllSta(msg->vif, &msg->body.del_all_sta_info);
2616                break;
2617
2618        case HOST_IF_MSG_SET_TX_POWER:
2619                handle_set_tx_pwr(msg->vif, msg->body.tx_power.tx_pwr);
2620                break;
2621
2622        case HOST_IF_MSG_GET_TX_POWER:
2623                handle_get_tx_pwr(msg->vif, &msg->body.tx_power.tx_pwr);
2624                break;
2625        default:
2626                netdev_err(msg->vif->ndev, "[Host Interface] undefined\n");
2627                break;
2628        }
2629free_msg:
2630        kfree(msg);
2631        complete(&hif_thread_comp);
2632}
2633
2634static void TimerCB_Scan(unsigned long arg)
2635{
2636        struct wilc_vif *vif = (struct wilc_vif *)arg;
2637        struct host_if_msg msg;
2638
2639        memset(&msg, 0, sizeof(struct host_if_msg));
2640        msg.vif = vif;
2641        msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
2642
2643        wilc_enqueue_cmd(&msg);
2644}
2645
2646static void TimerCB_Connect(unsigned long arg)
2647{
2648        struct wilc_vif *vif = (struct wilc_vif *)arg;
2649        struct host_if_msg msg;
2650
2651        memset(&msg, 0, sizeof(struct host_if_msg));
2652        msg.vif = vif;
2653        msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
2654
2655        wilc_enqueue_cmd(&msg);
2656}
2657
2658s32 wilc_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
2659{
2660        struct wid wid;
2661
2662        wid.id = (u16)WID_REMOVE_KEY;
2663        wid.type = WID_STR;
2664        wid.val = (s8 *)pu8StaAddress;
2665        wid.size = 6;
2666
2667        return 0;
2668}
2669
2670int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
2671{
2672        int result = 0;
2673        struct host_if_msg msg;
2674        struct host_if_drv *hif_drv = vif->hif_drv;
2675
2676        if (!hif_drv) {
2677                result = -EFAULT;
2678                netdev_err(vif->ndev, "Failed to send setup multicast\n");
2679                return result;
2680        }
2681
2682        memset(&msg, 0, sizeof(struct host_if_msg));
2683
2684        msg.id = HOST_IF_MSG_KEY;
2685        msg.body.key_info.type = WEP;
2686        msg.body.key_info.action = REMOVEKEY;
2687        msg.vif = vif;
2688        msg.body.key_info.attr.wep.index = index;
2689
2690        result = wilc_enqueue_cmd(&msg);
2691        if (result)
2692                netdev_err(vif->ndev, "Request to remove WEP key\n");
2693        else
2694                wait_for_completion(&hif_drv->comp_test_key_block);
2695
2696        return result;
2697}
2698
2699int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
2700{
2701        int result = 0;
2702        struct host_if_msg msg;
2703        struct host_if_drv *hif_drv = vif->hif_drv;
2704
2705        if (!hif_drv) {
2706                result = -EFAULT;
2707                netdev_err(vif->ndev, "driver is null\n");
2708                return result;
2709        }
2710
2711        memset(&msg, 0, sizeof(struct host_if_msg));
2712
2713        msg.id = HOST_IF_MSG_KEY;
2714        msg.body.key_info.type = WEP;
2715        msg.body.key_info.action = DEFAULTKEY;
2716        msg.vif = vif;
2717        msg.body.key_info.attr.wep.index = index;
2718
2719        result = wilc_enqueue_cmd(&msg);
2720        if (result)
2721                netdev_err(vif->ndev, "Default key index\n");
2722        else
2723                wait_for_completion(&hif_drv->comp_test_key_block);
2724
2725        return result;
2726}
2727
2728int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
2729                             u8 index)
2730{
2731        int result = 0;
2732        struct host_if_msg msg;
2733        struct host_if_drv *hif_drv = vif->hif_drv;
2734
2735        if (!hif_drv) {
2736                netdev_err(vif->ndev, "driver is null\n");
2737                return -EFAULT;
2738        }
2739
2740        memset(&msg, 0, sizeof(struct host_if_msg));
2741
2742        msg.id = HOST_IF_MSG_KEY;
2743        msg.body.key_info.type = WEP;
2744        msg.body.key_info.action = ADDKEY;
2745        msg.vif = vif;
2746        msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2747        if (!msg.body.key_info.attr.wep.key)
2748                return -ENOMEM;
2749
2750        msg.body.key_info.attr.wep.key_len = len;
2751        msg.body.key_info.attr.wep.index = index;
2752
2753        result = wilc_enqueue_cmd(&msg);
2754        if (result)
2755                netdev_err(vif->ndev, "STA - WEP Key\n");
2756        wait_for_completion(&hif_drv->comp_test_key_block);
2757
2758        return result;
2759}
2760
2761int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
2762                            u8 index, u8 mode, enum AUTHTYPE auth_type)
2763{
2764        int result = 0;
2765        struct host_if_msg msg;
2766        struct host_if_drv *hif_drv = vif->hif_drv;
2767
2768        if (!hif_drv) {
2769                netdev_err(vif->ndev, "driver is null\n");
2770                return -EFAULT;
2771        }
2772
2773        memset(&msg, 0, sizeof(struct host_if_msg));
2774
2775        msg.id = HOST_IF_MSG_KEY;
2776        msg.body.key_info.type = WEP;
2777        msg.body.key_info.action = ADDKEY_AP;
2778        msg.vif = vif;
2779        msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
2780        if (!msg.body.key_info.attr.wep.key)
2781                return -ENOMEM;
2782
2783        msg.body.key_info.attr.wep.key_len = len;
2784        msg.body.key_info.attr.wep.index = index;
2785        msg.body.key_info.attr.wep.mode = mode;
2786        msg.body.key_info.attr.wep.auth_type = auth_type;
2787
2788        result = wilc_enqueue_cmd(&msg);
2789
2790        if (result)
2791                netdev_err(vif->ndev, "AP - WEP Key\n");
2792        else
2793                wait_for_completion(&hif_drv->comp_test_key_block);
2794
2795        return result;
2796}
2797
2798int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
2799                 const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
2800                 u8 mode, u8 cipher_mode, u8 index)
2801{
2802        int result = 0;
2803        struct host_if_msg msg;
2804        struct host_if_drv *hif_drv = vif->hif_drv;
2805        u8 key_len = ptk_key_len;
2806
2807        if (!hif_drv) {
2808                netdev_err(vif->ndev, "driver is null\n");
2809                return -EFAULT;
2810        }
2811
2812        if (rx_mic)
2813                key_len += RX_MIC_KEY_LEN;
2814
2815        if (tx_mic)
2816                key_len += TX_MIC_KEY_LEN;
2817
2818        memset(&msg, 0, sizeof(struct host_if_msg));
2819
2820        msg.id = HOST_IF_MSG_KEY;
2821        msg.body.key_info.type = WPA_PTK;
2822        if (mode == AP_MODE) {
2823                msg.body.key_info.action = ADDKEY_AP;
2824                msg.body.key_info.attr.wpa.index = index;
2825        }
2826        if (mode == STATION_MODE)
2827                msg.body.key_info.action = ADDKEY;
2828
2829        msg.body.key_info.attr.wpa.key = kmemdup(ptk, ptk_key_len, GFP_KERNEL);
2830        if (!msg.body.key_info.attr.wpa.key)
2831                return -ENOMEM;
2832
2833        if (rx_mic)
2834                memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic, RX_MIC_KEY_LEN);
2835
2836        if (tx_mic)
2837                memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic, TX_MIC_KEY_LEN);
2838
2839        msg.body.key_info.attr.wpa.key_len = key_len;
2840        msg.body.key_info.attr.wpa.mac_addr = mac_addr;
2841        msg.body.key_info.attr.wpa.mode = cipher_mode;
2842        msg.vif = vif;
2843
2844        result = wilc_enqueue_cmd(&msg);
2845
2846        if (result)
2847                netdev_err(vif->ndev, "PTK Key\n");
2848        else
2849                wait_for_completion(&hif_drv->comp_test_key_block);
2850
2851        return result;
2852}
2853
2854int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
2855                    u8 index, u32 key_rsc_len, const u8 *key_rsc,
2856                    const u8 *rx_mic, const u8 *tx_mic, u8 mode,
2857                    u8 cipher_mode)
2858{
2859        int result = 0;
2860        struct host_if_msg msg;
2861        struct host_if_drv *hif_drv = vif->hif_drv;
2862        u8 key_len = gtk_key_len;
2863
2864        if (!hif_drv) {
2865                netdev_err(vif->ndev, "driver is null\n");
2866                return -EFAULT;
2867        }
2868        memset(&msg, 0, sizeof(struct host_if_msg));
2869
2870        if (rx_mic)
2871                key_len += RX_MIC_KEY_LEN;
2872
2873        if (tx_mic)
2874                key_len += TX_MIC_KEY_LEN;
2875
2876        if (key_rsc) {
2877                msg.body.key_info.attr.wpa.seq = kmemdup(key_rsc,
2878                                                         key_rsc_len,
2879                                                         GFP_KERNEL);
2880                if (!msg.body.key_info.attr.wpa.seq)
2881                        return -ENOMEM;
2882        }
2883
2884        msg.id = HOST_IF_MSG_KEY;
2885        msg.body.key_info.type = WPA_RX_GTK;
2886        msg.vif = vif;
2887
2888        if (mode == AP_MODE) {
2889                msg.body.key_info.action = ADDKEY_AP;
2890                msg.body.key_info.attr.wpa.mode = cipher_mode;
2891        }
2892        if (mode == STATION_MODE)
2893                msg.body.key_info.action = ADDKEY;
2894
2895        msg.body.key_info.attr.wpa.key = kmemdup(rx_gtk,
2896                                                 key_len,
2897                                                 GFP_KERNEL);
2898        if (!msg.body.key_info.attr.wpa.key)
2899                return -ENOMEM;
2900
2901        if (rx_mic)
2902                memcpy(msg.body.key_info.attr.wpa.key + 16, rx_mic,
2903                       RX_MIC_KEY_LEN);
2904
2905        if (tx_mic)
2906                memcpy(msg.body.key_info.attr.wpa.key + 24, tx_mic,
2907                       TX_MIC_KEY_LEN);
2908
2909        msg.body.key_info.attr.wpa.index = index;
2910        msg.body.key_info.attr.wpa.key_len = key_len;
2911        msg.body.key_info.attr.wpa.seq_len = key_rsc_len;
2912
2913        result = wilc_enqueue_cmd(&msg);
2914        if (result)
2915                netdev_err(vif->ndev, "RX GTK\n");
2916        else
2917                wait_for_completion(&hif_drv->comp_test_key_block);
2918
2919        return result;
2920}
2921
2922int wilc_set_pmkid_info(struct wilc_vif *vif,
2923                        struct host_if_pmkid_attr *pmkid)
2924{
2925        int result = 0;
2926        struct host_if_msg msg;
2927        int i;
2928
2929        memset(&msg, 0, sizeof(struct host_if_msg));
2930
2931        msg.id = HOST_IF_MSG_KEY;
2932        msg.body.key_info.type = PMKSA;
2933        msg.body.key_info.action = ADDKEY;
2934        msg.vif = vif;
2935
2936        for (i = 0; i < pmkid->numpmkid; i++) {
2937                memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
2938                       &pmkid->pmkidlist[i].bssid, ETH_ALEN);
2939                memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
2940                       &pmkid->pmkidlist[i].pmkid, PMKID_LEN);
2941        }
2942
2943        result = wilc_enqueue_cmd(&msg);
2944        if (result)
2945                netdev_err(vif->ndev, "PMKID Info\n");
2946
2947        return result;
2948}
2949
2950int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
2951{
2952        int result = 0;
2953        struct host_if_msg msg;
2954
2955        memset(&msg, 0, sizeof(struct host_if_msg));
2956
2957        msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
2958        msg.body.get_mac_info.mac_addr = mac_addr;
2959        msg.vif = vif;
2960
2961        result = wilc_enqueue_cmd(&msg);
2962        if (result) {
2963                netdev_err(vif->ndev, "Failed to send get mac address\n");
2964                return -EFAULT;
2965        }
2966
2967        wait_for_completion(&hif_wait_response);
2968        return result;
2969}
2970
2971int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, const u8 *ssid,
2972                      size_t ssid_len, const u8 *ies, size_t ies_len,
2973                      wilc_connect_result connect_result, void *user_arg,
2974                      u8 security, enum AUTHTYPE auth_type,
2975                      u8 channel, void *join_params)
2976{
2977        int result = 0;
2978        struct host_if_msg msg;
2979        struct host_if_drv *hif_drv = vif->hif_drv;
2980
2981        if (!hif_drv || !connect_result) {
2982                netdev_err(vif->ndev, "Driver is null\n");
2983                return -EFAULT;
2984        }
2985
2986        if (!join_params) {
2987                netdev_err(vif->ndev, "Unable to Join - JoinParams is NULL\n");
2988                return -EFAULT;
2989        }
2990
2991        memset(&msg, 0, sizeof(struct host_if_msg));
2992
2993        msg.id = HOST_IF_MSG_CONNECT;
2994
2995        msg.body.con_info.security = security;
2996        msg.body.con_info.auth_type = auth_type;
2997        msg.body.con_info.ch = channel;
2998        msg.body.con_info.result = connect_result;
2999        msg.body.con_info.arg = user_arg;
3000        msg.body.con_info.params = join_params;
3001        msg.vif = vif;
3002
3003        if (bssid) {
3004                msg.body.con_info.bssid = kmemdup(bssid, 6, GFP_KERNEL);
3005                if (!msg.body.con_info.bssid)
3006                        return -ENOMEM;
3007        }
3008
3009        if (ssid) {
3010                msg.body.con_info.ssid_len = ssid_len;
3011                msg.body.con_info.ssid = kmemdup(ssid, ssid_len, GFP_KERNEL);
3012                if (!msg.body.con_info.ssid)
3013                        return -ENOMEM;
3014        }
3015
3016        if (ies) {
3017                msg.body.con_info.ies_len = ies_len;
3018                msg.body.con_info.ies = kmemdup(ies, ies_len, GFP_KERNEL);
3019                if (!msg.body.con_info.ies)
3020                        return -ENOMEM;
3021        }
3022        if (hif_drv->hif_state < HOST_IF_CONNECTING)
3023                hif_drv->hif_state = HOST_IF_CONNECTING;
3024
3025        result = wilc_enqueue_cmd(&msg);
3026        if (result) {
3027                netdev_err(vif->ndev, "send message: Set join request\n");
3028                return -EFAULT;
3029        }
3030
3031        hif_drv->connect_timer.data = (unsigned long)vif;
3032        mod_timer(&hif_drv->connect_timer,
3033                  jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3034
3035        return result;
3036}
3037
3038int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
3039{
3040        int result = 0;
3041        struct host_if_msg msg;
3042        struct host_if_drv *hif_drv = vif->hif_drv;
3043
3044        if (!hif_drv) {
3045                netdev_err(vif->ndev, "Driver is null\n");
3046                return -EFAULT;
3047        }
3048
3049        memset(&msg, 0, sizeof(struct host_if_msg));
3050
3051        msg.id = HOST_IF_MSG_DISCONNECT;
3052        msg.vif = vif;
3053
3054        result = wilc_enqueue_cmd(&msg);
3055        if (result)
3056                netdev_err(vif->ndev, "Failed to send message: disconnect\n");
3057        else
3058                wait_for_completion(&hif_drv->comp_test_disconn_block);
3059
3060        return result;
3061}
3062
3063static s32 host_int_get_assoc_res_info(struct wilc_vif *vif,
3064                                       u8 *pu8AssocRespInfo,
3065                                       u32 u32MaxAssocRespInfoLen,
3066                                       u32 *pu32RcvdAssocRespInfoLen)
3067{
3068        s32 result = 0;
3069        struct wid wid;
3070
3071        wid.id = (u16)WID_ASSOC_RES_INFO;
3072        wid.type = WID_STR;
3073        wid.val = pu8AssocRespInfo;
3074        wid.size = u32MaxAssocRespInfoLen;
3075
3076        result = wilc_send_config_pkt(vif, GET_CFG, &wid, 1,
3077                                      wilc_get_vif_idx(vif));
3078        if (result) {
3079                *pu32RcvdAssocRespInfoLen = 0;
3080                netdev_err(vif->ndev, "Failed to send association response\n");
3081                return -EINVAL;
3082        }
3083
3084        *pu32RcvdAssocRespInfoLen = wid.size;
3085        return result;
3086}
3087
3088int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
3089{
3090        int result;
3091        struct host_if_msg msg;
3092
3093        memset(&msg, 0, sizeof(struct host_if_msg));
3094        msg.id = HOST_IF_MSG_SET_CHANNEL;
3095        msg.body.channel_info.set_ch = channel;
3096        msg.vif = vif;
3097
3098        result = wilc_enqueue_cmd(&msg);
3099        if (result) {
3100                netdev_err(vif->ndev, "wilc mq send fail\n");
3101                return -EINVAL;
3102        }
3103
3104        return 0;
3105}
3106
3107int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
3108{
3109        int result = 0;
3110        struct host_if_msg msg;
3111
3112        memset(&msg, 0, sizeof(struct host_if_msg));
3113        msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3114        msg.body.drv.handler = index;
3115        msg.body.drv.mac_idx = mac_idx;
3116        msg.vif = vif;
3117
3118        result = wilc_enqueue_cmd(&msg);
3119        if (result) {
3120                netdev_err(vif->ndev, "wilc mq send fail\n");
3121                result = -EINVAL;
3122        }
3123
3124        return result;
3125}
3126
3127int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
3128{
3129        int result = 0;
3130        struct host_if_msg msg;
3131
3132        memset(&msg, 0, sizeof(struct host_if_msg));
3133        msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3134        msg.body.mode.mode = mode;
3135        msg.vif = vif;
3136
3137        result = wilc_enqueue_cmd(&msg);
3138        if (result) {
3139                netdev_err(vif->ndev, "wilc mq send fail\n");
3140                result = -EINVAL;
3141        }
3142
3143        return result;
3144}
3145
3146s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
3147                           u32 *pu32InactiveTime)
3148{
3149        s32 result = 0;
3150        struct host_if_msg msg;
3151        struct host_if_drv *hif_drv = vif->hif_drv;
3152
3153        if (!hif_drv) {
3154                netdev_err(vif->ndev, "driver is null\n");
3155                return -EFAULT;
3156        }
3157
3158        memset(&msg, 0, sizeof(struct host_if_msg));
3159        memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3160
3161        msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3162        msg.vif = vif;
3163
3164        result = wilc_enqueue_cmd(&msg);
3165        if (result)
3166                netdev_err(vif->ndev, "Failed to send get host ch param\n");
3167        else
3168                wait_for_completion(&hif_drv->comp_inactive_time);
3169
3170        *pu32InactiveTime = inactive_time;
3171
3172        return result;
3173}
3174
3175int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
3176{
3177        int result = 0;
3178        struct host_if_msg msg;
3179        struct host_if_drv *hif_drv = vif->hif_drv;
3180
3181        memset(&msg, 0, sizeof(struct host_if_msg));
3182        msg.id = HOST_IF_MSG_GET_RSSI;
3183        msg.vif = vif;
3184
3185        result = wilc_enqueue_cmd(&msg);
3186        if (result) {
3187                netdev_err(vif->ndev, "Failed to send get host ch param\n");
3188                return -EFAULT;
3189        }
3190
3191        wait_for_completion(&hif_drv->comp_get_rssi);
3192
3193        if (!rssi_level) {
3194                netdev_err(vif->ndev, "RSS pointer value is null\n");
3195                return -EFAULT;
3196        }
3197
3198        *rssi_level = rssi;
3199
3200        return result;
3201}
3202
3203int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
3204{
3205        int result = 0;
3206        struct host_if_msg msg;
3207
3208        memset(&msg, 0, sizeof(struct host_if_msg));
3209        msg.id = HOST_IF_MSG_GET_STATISTICS;
3210        msg.body.data = (char *)stats;
3211        msg.vif = vif;
3212
3213        result = wilc_enqueue_cmd(&msg);
3214        if (result) {
3215                netdev_err(vif->ndev, "Failed to send get host channel\n");
3216                return -EFAULT;
3217        }
3218
3219        if (stats != &vif->wilc->dummy_statistics)
3220                wait_for_completion(&hif_wait_response);
3221        return result;
3222}
3223
3224int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
3225              u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
3226              size_t ies_len, wilc_scan_result scan_result, void *user_arg,
3227              struct hidden_network *hidden_network)
3228{
3229        int result = 0;
3230        struct host_if_msg msg;
3231        struct scan_attr *scan_info = &msg.body.scan_info;
3232        struct host_if_drv *hif_drv = vif->hif_drv;
3233
3234        if (!hif_drv || !scan_result) {
3235                netdev_err(vif->ndev, "hif_drv or scan_result = NULL\n");
3236                return -EFAULT;
3237        }
3238
3239        memset(&msg, 0, sizeof(struct host_if_msg));
3240
3241        msg.id = HOST_IF_MSG_SCAN;
3242
3243        if (hidden_network) {
3244                scan_info->hidden_network.net_info = hidden_network->net_info;
3245                scan_info->hidden_network.n_ssids = hidden_network->n_ssids;
3246        }
3247
3248        msg.vif = vif;
3249        scan_info->src = scan_source;
3250        scan_info->type = scan_type;
3251        scan_info->result = scan_result;
3252        scan_info->arg = user_arg;
3253
3254        scan_info->ch_list_len = ch_list_len;
3255        scan_info->ch_freq_list = kmemdup(ch_freq_list,
3256                                          ch_list_len,
3257                                          GFP_KERNEL);
3258        if (!scan_info->ch_freq_list)
3259                return -ENOMEM;
3260
3261        scan_info->ies_len = ies_len;
3262        scan_info->ies = kmemdup(ies, ies_len, GFP_KERNEL);
3263        if (!scan_info->ies)
3264                return -ENOMEM;
3265
3266        result = wilc_enqueue_cmd(&msg);
3267        if (result) {
3268                netdev_err(vif->ndev, "Error in sending message queue\n");
3269                return -EINVAL;
3270        }
3271
3272        hif_drv->scan_timer.data = (unsigned long)vif;
3273        mod_timer(&hif_drv->scan_timer,
3274                  jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3275
3276        return result;
3277}
3278
3279int wilc_hif_set_cfg(struct wilc_vif *vif,
3280                     struct cfg_param_attr *cfg_param)
3281{
3282        int result = 0;
3283        struct host_if_msg msg;
3284        struct host_if_drv *hif_drv = vif->hif_drv;
3285
3286        if (!hif_drv) {
3287                netdev_err(vif->ndev, "hif_drv NULL\n");
3288                return -EFAULT;
3289        }
3290
3291        memset(&msg, 0, sizeof(struct host_if_msg));
3292        msg.id = HOST_IF_MSG_CFG_PARAMS;
3293        msg.body.cfg_info = *cfg_param;
3294        msg.vif = vif;
3295
3296        result = wilc_enqueue_cmd(&msg);
3297
3298        return result;
3299}
3300
3301static void GetPeriodicRSSI(unsigned long arg)
3302{
3303        struct wilc_vif *vif = (struct wilc_vif *)arg;
3304
3305        if (!vif->hif_drv) {
3306                netdev_err(vif->ndev, "Driver handler is NULL\n");
3307                return;
3308        }
3309
3310        if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
3311                wilc_get_statistics(vif, &vif->wilc->dummy_statistics);
3312
3313        periodic_rssi.data = (unsigned long)vif;
3314        mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3315}
3316
3317int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
3318{
3319        int result = 0;
3320        struct host_if_drv *hif_drv;
3321        struct wilc_vif *vif;
3322        struct wilc *wilc;
3323        int i;
3324
3325        vif = netdev_priv(dev);
3326        wilc = vif->wilc;
3327
3328        scan_while_connected = false;
3329
3330        init_completion(&hif_wait_response);
3331
3332        hif_drv  = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
3333        if (!hif_drv) {
3334                result = -ENOMEM;
3335                goto _fail_;
3336        }
3337        *hif_drv_handler = hif_drv;
3338        for (i = 0; i < wilc->vif_num; i++)
3339                if (dev == wilc->vif[i]->ndev) {
3340                        wilc->vif[i]->hif_drv = hif_drv;
3341                        break;
3342                }
3343
3344        wilc_optaining_ip = false;
3345
3346        if (clients_count == 0) {
3347                init_completion(&hif_thread_comp);
3348                init_completion(&hif_driver_comp);
3349                mutex_init(&hif_deinit_lock);
3350        }
3351
3352        init_completion(&hif_drv->comp_test_key_block);
3353        init_completion(&hif_drv->comp_test_disconn_block);
3354        init_completion(&hif_drv->comp_get_rssi);
3355        init_completion(&hif_drv->comp_inactive_time);
3356
3357        if (clients_count == 0) {
3358                if (result < 0) {
3359                        netdev_err(vif->ndev, "Failed to creat MQ\n");
3360                        goto _fail_;
3361                }
3362                hif_workqueue = create_singlethread_workqueue("WILC_wq");
3363                if (!hif_workqueue) {
3364                        netdev_err(vif->ndev, "Failed to create workqueue\n");
3365                        result = -ENOMEM;
3366                        goto _fail_;
3367                }
3368
3369                setup_timer(&periodic_rssi, GetPeriodicRSSI,
3370                            (unsigned long)vif);
3371                mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
3372        }
3373
3374        setup_timer(&hif_drv->scan_timer, TimerCB_Scan, 0);
3375        setup_timer(&hif_drv->connect_timer, TimerCB_Connect, 0);
3376        setup_timer(&hif_drv->remain_on_ch_timer, ListenTimerCB, 0);
3377
3378        mutex_init(&hif_drv->cfg_values_lock);
3379        mutex_lock(&hif_drv->cfg_values_lock);
3380
3381        hif_drv->hif_state = HOST_IF_IDLE;
3382        hif_drv->cfg_values.site_survey_enabled = SITE_SURVEY_OFF;
3383        hif_drv->cfg_values.scan_source = DEFAULT_SCAN;
3384        hif_drv->cfg_values.active_scan_time = ACTIVE_SCAN_TIME;
3385        hif_drv->cfg_values.passive_scan_time = PASSIVE_SCAN_TIME;
3386        hif_drv->cfg_values.curr_tx_rate = AUTORATE;
3387
3388        hif_drv->p2p_timeout = 0;
3389
3390        mutex_unlock(&hif_drv->cfg_values_lock);
3391
3392        clients_count++;
3393
3394        destroy_workqueue(hif_workqueue);
3395_fail_:
3396        return result;
3397}
3398
3399int wilc_deinit(struct wilc_vif *vif)
3400{
3401        int result = 0;
3402        struct host_if_msg msg;
3403        struct host_if_drv *hif_drv = vif->hif_drv;
3404
3405        if (!hif_drv)   {
3406                netdev_err(vif->ndev, "hif_drv = NULL\n");
3407                return -EFAULT;
3408        }
3409
3410        mutex_lock(&hif_deinit_lock);
3411
3412        terminated_handle = hif_drv;
3413
3414        del_timer_sync(&hif_drv->scan_timer);
3415        del_timer_sync(&hif_drv->connect_timer);
3416        del_timer_sync(&periodic_rssi);
3417        del_timer_sync(&hif_drv->remain_on_ch_timer);
3418
3419        wilc_set_wfi_drv_handler(vif, 0, 0);
3420        wait_for_completion(&hif_driver_comp);
3421
3422        if (hif_drv->usr_scan_req.scan_result) {
3423                hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
3424                                                  hif_drv->usr_scan_req.arg, NULL);
3425                hif_drv->usr_scan_req.scan_result = NULL;
3426        }
3427
3428        hif_drv->hif_state = HOST_IF_IDLE;
3429
3430        scan_while_connected = false;
3431
3432        memset(&msg, 0, sizeof(struct host_if_msg));
3433
3434        if (clients_count == 1) {
3435                msg.id = HOST_IF_MSG_EXIT;
3436                msg.vif = vif;
3437
3438                result = wilc_enqueue_cmd(&msg);
3439                if (result != 0)
3440                        netdev_err(vif->ndev, "deinit : Error(%d)\n", result);
3441                else
3442                        wait_for_completion(&hif_thread_comp);
3443
3444                destroy_workqueue(hif_workqueue);
3445        }
3446
3447        kfree(hif_drv);
3448
3449        clients_count--;
3450        terminated_handle = NULL;
3451        mutex_unlock(&hif_deinit_lock);
3452        return result;
3453}
3454
3455void wilc_network_info_received(struct wilc *wilc, u8 *pu8Buffer,
3456                                u32 u32Length)
3457{
3458        s32 result = 0;
3459        struct host_if_msg msg;
3460        int id;
3461        struct host_if_drv *hif_drv = NULL;
3462        struct wilc_vif *vif;
3463
3464        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3465        vif = wilc_get_vif_from_idx(wilc, id);
3466        if (!vif)
3467                return;
3468        hif_drv = vif->hif_drv;
3469
3470        if (!hif_drv || hif_drv == terminated_handle)   {
3471                netdev_err(vif->ndev, "driver not init[%p]\n", hif_drv);
3472                return;
3473        }
3474
3475        memset(&msg, 0, sizeof(struct host_if_msg));
3476
3477        msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
3478        msg.vif = vif;
3479
3480        msg.body.net_info.len = u32Length;
3481        msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
3482        memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
3483
3484        result = wilc_enqueue_cmd(&msg);
3485        if (result)
3486                netdev_err(vif->ndev, "message parameters (%d)\n", result);
3487}
3488
3489void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *pu8Buffer,
3490                                   u32 u32Length)
3491{
3492        s32 result = 0;
3493        struct host_if_msg msg;
3494        int id;
3495        struct host_if_drv *hif_drv = NULL;
3496        struct wilc_vif *vif;
3497
3498        mutex_lock(&hif_deinit_lock);
3499
3500        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3501        vif = wilc_get_vif_from_idx(wilc, id);
3502        if (!vif) {
3503                mutex_unlock(&hif_deinit_lock);
3504                return;
3505        }
3506
3507        hif_drv = vif->hif_drv;
3508
3509        if (!hif_drv || hif_drv == terminated_handle) {
3510                mutex_unlock(&hif_deinit_lock);
3511                return;
3512        }
3513
3514        if (!hif_drv->usr_conn_req.conn_result) {
3515                netdev_err(vif->ndev, "there is no current Connect Request\n");
3516                mutex_unlock(&hif_deinit_lock);
3517                return;
3518        }
3519
3520        memset(&msg, 0, sizeof(struct host_if_msg));
3521
3522        msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
3523        msg.vif = vif;
3524
3525        msg.body.async_info.len = u32Length;
3526        msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
3527        memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
3528
3529        result = wilc_enqueue_cmd(&msg);
3530        if (result)
3531                netdev_err(vif->ndev, "synchronous info (%d)\n", result);
3532
3533        mutex_unlock(&hif_deinit_lock);
3534}
3535
3536void wilc_scan_complete_received(struct wilc *wilc, u8 *pu8Buffer,
3537                                 u32 u32Length)
3538{
3539        s32 result = 0;
3540        struct host_if_msg msg;
3541        int id;
3542        struct host_if_drv *hif_drv = NULL;
3543        struct wilc_vif *vif;
3544
3545        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
3546        vif = wilc_get_vif_from_idx(wilc, id);
3547        if (!vif)
3548                return;
3549        hif_drv = vif->hif_drv;
3550
3551        if (!hif_drv || hif_drv == terminated_handle)
3552                return;
3553
3554        if (hif_drv->usr_scan_req.scan_result) {
3555                memset(&msg, 0, sizeof(struct host_if_msg));
3556
3557                msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
3558                msg.vif = vif;
3559
3560                result = wilc_enqueue_cmd(&msg);
3561                if (result)
3562                        netdev_err(vif->ndev, "complete param (%d)\n", result);
3563        }
3564}
3565
3566int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id,
3567                           u32 duration, u16 chan,
3568                           wilc_remain_on_chan_expired expired,
3569                           wilc_remain_on_chan_ready ready,
3570                           void *user_arg)
3571{
3572        int result = 0;
3573        struct host_if_msg msg;
3574
3575        memset(&msg, 0, sizeof(struct host_if_msg));
3576
3577        msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
3578        msg.body.remain_on_ch.ch = chan;
3579        msg.body.remain_on_ch.expired = expired;
3580        msg.body.remain_on_ch.ready = ready;
3581        msg.body.remain_on_ch.arg = user_arg;
3582        msg.body.remain_on_ch.duration = duration;
3583        msg.body.remain_on_ch.id = session_id;
3584        msg.vif = vif;
3585
3586        result = wilc_enqueue_cmd(&msg);
3587        if (result)
3588                netdev_err(vif->ndev, "wilc mq send fail\n");
3589
3590        return result;
3591}
3592
3593int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id)
3594{
3595        int result = 0;
3596        struct host_if_msg msg;
3597        struct host_if_drv *hif_drv = vif->hif_drv;
3598
3599        if (!hif_drv) {
3600                netdev_err(vif->ndev, "driver is null\n");
3601                return -EFAULT;
3602        }
3603
3604        del_timer(&hif_drv->remain_on_ch_timer);
3605
3606        memset(&msg, 0, sizeof(struct host_if_msg));
3607        msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
3608        msg.vif = vif;
3609        msg.body.remain_on_ch.id = session_id;
3610
3611        result = wilc_enqueue_cmd(&msg);
3612        if (result)
3613                netdev_err(vif->ndev, "wilc mq send fail\n");
3614
3615        return result;
3616}
3617
3618int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
3619{
3620        int result = 0;
3621        struct host_if_msg msg;
3622
3623        memset(&msg, 0, sizeof(struct host_if_msg));
3624
3625        msg.id = HOST_IF_MSG_REGISTER_FRAME;
3626        switch (frame_type) {
3627        case ACTION:
3628                msg.body.reg_frame.reg_id = ACTION_FRM_IDX;
3629                break;
3630
3631        case PROBE_REQ:
3632                msg.body.reg_frame.reg_id = PROBE_REQ_IDX;
3633                break;
3634
3635        default:
3636                break;
3637        }
3638        msg.body.reg_frame.frame_type = frame_type;
3639        msg.body.reg_frame.reg = reg;
3640        msg.vif = vif;
3641
3642        result = wilc_enqueue_cmd(&msg);
3643        if (result)
3644                netdev_err(vif->ndev, "wilc mq send fail\n");
3645
3646        return result;
3647}
3648
3649int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
3650                    u32 head_len, u8 *head, u32 tail_len, u8 *tail)
3651{
3652        int result = 0;
3653        struct host_if_msg msg;
3654        struct beacon_attr *beacon_info = &msg.body.beacon_info;
3655
3656        memset(&msg, 0, sizeof(struct host_if_msg));
3657
3658        msg.id = HOST_IF_MSG_ADD_BEACON;
3659        msg.vif = vif;
3660        beacon_info->interval = interval;
3661        beacon_info->dtim_period = dtim_period;
3662        beacon_info->head_len = head_len;
3663        beacon_info->head = kmemdup(head, head_len, GFP_KERNEL);
3664        if (!beacon_info->head) {
3665                result = -ENOMEM;
3666                goto ERRORHANDLER;
3667        }
3668        beacon_info->tail_len = tail_len;
3669
3670        if (tail_len > 0) {
3671                beacon_info->tail = kmemdup(tail, tail_len, GFP_KERNEL);
3672                if (!beacon_info->tail) {
3673                        result = -ENOMEM;
3674                        goto ERRORHANDLER;
3675                }
3676        } else {
3677                beacon_info->tail = NULL;
3678        }
3679
3680        result = wilc_enqueue_cmd(&msg);
3681        if (result)
3682                netdev_err(vif->ndev, "wilc mq send fail\n");
3683
3684ERRORHANDLER:
3685        if (result) {
3686                kfree(beacon_info->head);
3687
3688                kfree(beacon_info->tail);
3689        }
3690
3691        return result;
3692}
3693
3694int wilc_del_beacon(struct wilc_vif *vif)
3695{
3696        int result = 0;
3697        struct host_if_msg msg;
3698
3699        msg.id = HOST_IF_MSG_DEL_BEACON;
3700        msg.vif = vif;
3701
3702        result = wilc_enqueue_cmd(&msg);
3703        if (result)
3704                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3705
3706        return result;
3707}
3708
3709int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param)
3710{
3711        int result = 0;
3712        struct host_if_msg msg;
3713        struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3714
3715        memset(&msg, 0, sizeof(struct host_if_msg));
3716
3717        msg.id = HOST_IF_MSG_ADD_STATION;
3718        msg.vif = vif;
3719
3720        memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3721        if (add_sta_info->rates_len > 0) {
3722                add_sta_info->rates = kmemdup(sta_param->rates,
3723                                      add_sta_info->rates_len,
3724                                      GFP_KERNEL);
3725                if (!add_sta_info->rates)
3726                        return -ENOMEM;
3727        }
3728
3729        result = wilc_enqueue_cmd(&msg);
3730        if (result)
3731                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3732        return result;
3733}
3734
3735int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
3736{
3737        int result = 0;
3738        struct host_if_msg msg;
3739        struct del_sta *del_sta_info = &msg.body.del_sta_info;
3740
3741        memset(&msg, 0, sizeof(struct host_if_msg));
3742
3743        msg.id = HOST_IF_MSG_DEL_STATION;
3744        msg.vif = vif;
3745
3746        if (!mac_addr)
3747                eth_broadcast_addr(del_sta_info->mac_addr);
3748        else
3749                memcpy(del_sta_info->mac_addr, mac_addr, ETH_ALEN);
3750
3751        result = wilc_enqueue_cmd(&msg);
3752        if (result)
3753                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3754        return result;
3755}
3756
3757int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
3758{
3759        int result = 0;
3760        struct host_if_msg msg;
3761        struct del_all_sta *del_all_sta_info = &msg.body.del_all_sta_info;
3762        u8 zero_addr[ETH_ALEN] = {0};
3763        int i;
3764        u8 assoc_sta = 0;
3765
3766        memset(&msg, 0, sizeof(struct host_if_msg));
3767
3768        msg.id = HOST_IF_MSG_DEL_ALL_STA;
3769        msg.vif = vif;
3770
3771        for (i = 0; i < MAX_NUM_STA; i++) {
3772                if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
3773                        memcpy(del_all_sta_info->del_all_sta[i], mac_addr[i], ETH_ALEN);
3774                        assoc_sta++;
3775                }
3776        }
3777        if (!assoc_sta)
3778                return result;
3779
3780        del_all_sta_info->assoc_sta = assoc_sta;
3781        result = wilc_enqueue_cmd(&msg);
3782
3783        if (result)
3784                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3785        else
3786                wait_for_completion(&hif_wait_response);
3787
3788        return result;
3789}
3790
3791int wilc_edit_station(struct wilc_vif *vif,
3792                      struct add_sta_param *sta_param)
3793{
3794        int result = 0;
3795        struct host_if_msg msg;
3796        struct add_sta_param *add_sta_info = &msg.body.add_sta_info;
3797
3798        memset(&msg, 0, sizeof(struct host_if_msg));
3799
3800        msg.id = HOST_IF_MSG_EDIT_STATION;
3801        msg.vif = vif;
3802
3803        memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param));
3804        if (add_sta_info->rates_len > 0) {
3805                add_sta_info->rates = kmemdup(sta_param->rates,
3806                                              add_sta_info->rates_len,
3807                                              GFP_KERNEL);
3808                if (!add_sta_info->rates)
3809                        return -ENOMEM;
3810        }
3811
3812        result = wilc_enqueue_cmd(&msg);
3813        if (result)
3814                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3815
3816        return result;
3817}
3818
3819int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
3820{
3821        int result = 0;
3822        struct host_if_msg msg;
3823        struct power_mgmt_param *pwr_mgmt_info = &msg.body.pwr_mgmt_info;
3824
3825        if (wilc_wlan_get_num_conn_ifcs(vif->wilc) == 2 && enabled)
3826                return 0;
3827
3828        memset(&msg, 0, sizeof(struct host_if_msg));
3829
3830        msg.id = HOST_IF_MSG_POWER_MGMT;
3831        msg.vif = vif;
3832
3833        pwr_mgmt_info->enabled = enabled;
3834        pwr_mgmt_info->timeout = timeout;
3835
3836        result = wilc_enqueue_cmd(&msg);
3837        if (result)
3838                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3839        return result;
3840}
3841
3842int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled,
3843                                u32 count)
3844{
3845        int result = 0;
3846        struct host_if_msg msg;
3847        struct set_multicast *multicast_filter_param = &msg.body.multicast_info;
3848
3849        memset(&msg, 0, sizeof(struct host_if_msg));
3850
3851        msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
3852        msg.vif = vif;
3853
3854        multicast_filter_param->enabled = enabled;
3855        multicast_filter_param->cnt = count;
3856
3857        result = wilc_enqueue_cmd(&msg);
3858        if (result)
3859                netdev_err(vif->ndev, "wilc_mq_send fail\n");
3860        return result;
3861}
3862
3863static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
3864{
3865        struct join_bss_param *pNewJoinBssParam = NULL;
3866        u8 *pu8IEs;
3867        u16 u16IEsLen;
3868        u16 index = 0;
3869        u8 suppRatesNo = 0;
3870        u8 extSuppRatesNo;
3871        u16 jumpOffset;
3872        u8 pcipherCount;
3873        u8 authCount;
3874        u8 pcipherTotalCount = 0;
3875        u8 authTotalCount = 0;
3876        u8 i, j;
3877
3878        pu8IEs = ptstrNetworkInfo->ies;
3879        u16IEsLen = ptstrNetworkInfo->ies_len;
3880
3881        pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
3882        if (pNewJoinBssParam) {
3883                pNewJoinBssParam->dtim_period = ptstrNetworkInfo->dtim_period;
3884                pNewJoinBssParam->beacon_period = ptstrNetworkInfo->beacon_period;
3885                pNewJoinBssParam->cap_info = ptstrNetworkInfo->cap_info;
3886                memcpy(pNewJoinBssParam->bssid, ptstrNetworkInfo->bssid, 6);
3887                memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->ssid,
3888                       ptstrNetworkInfo->ssid_len + 1);
3889                pNewJoinBssParam->ssid_len = ptstrNetworkInfo->ssid_len;
3890                memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
3891                memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
3892
3893                while (index < u16IEsLen) {
3894                        if (pu8IEs[index] == SUPP_RATES_IE) {
3895                                suppRatesNo = pu8IEs[index + 1];
3896                                pNewJoinBssParam->supp_rates[0] = suppRatesNo;
3897                                index += 2;
3898
3899                                for (i = 0; i < suppRatesNo; i++)
3900                                        pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
3901
3902                                index += suppRatesNo;
3903                                continue;
3904                        } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
3905                                extSuppRatesNo = pu8IEs[index + 1];
3906                                if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
3907                                        pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
3908                                else
3909                                        pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
3910                                index += 2;
3911                                for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
3912                                        pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
3913
3914                                index += extSuppRatesNo;
3915                                continue;
3916                        } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
3917                                pNewJoinBssParam->ht_capable = true;
3918                                index += pu8IEs[index + 1] + 2;
3919                                continue;
3920                        } else if ((pu8IEs[index] == WMM_IE) &&
3921                                   (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
3922                                   (pu8IEs[index + 4] == 0xF2) &&
3923                                   (pu8IEs[index + 5] == 0x02) &&
3924                                   ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
3925                                   (pu8IEs[index + 7] == 0x01)) {
3926                                pNewJoinBssParam->wmm_cap = true;
3927
3928                                if (pu8IEs[index + 8] & BIT(7))
3929                                        pNewJoinBssParam->uapsd_cap = true;
3930                                index += pu8IEs[index + 1] + 2;
3931                                continue;
3932                        } else if ((pu8IEs[index] == P2P_IE) &&
3933                                 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
3934                                 (pu8IEs[index + 4] == 0x9a) &&
3935                                 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
3936                                u16 u16P2P_count;
3937
3938                                pNewJoinBssParam->tsf = ptstrNetworkInfo->tsf_lo;
3939                                pNewJoinBssParam->noa_enabled = 1;
3940                                pNewJoinBssParam->idx = pu8IEs[index + 9];
3941
3942                                if (pu8IEs[index + 10] & BIT(7)) {
3943                                        pNewJoinBssParam->opp_enabled = 1;
3944                                        pNewJoinBssParam->ct_window = pu8IEs[index + 10];
3945                                } else {
3946                                        pNewJoinBssParam->opp_enabled = 0;
3947                                }
3948
3949                                pNewJoinBssParam->cnt = pu8IEs[index + 11];
3950                                u16P2P_count = index + 12;
3951
3952                                memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
3953                                u16P2P_count += 4;
3954
3955                                memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
3956                                u16P2P_count += 4;
3957
3958                                memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
3959
3960                                index += pu8IEs[index + 1] + 2;
3961                                continue;
3962
3963                        } else if ((pu8IEs[index] == RSN_IE) ||
3964                                 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
3965                                  (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
3966                                  (pu8IEs[index + 5] == 0x01))) {
3967                                u16 rsnIndex = index;
3968
3969                                if (pu8IEs[rsnIndex] == RSN_IE) {
3970                                        pNewJoinBssParam->mode_802_11i = 2;
3971                                } else {
3972                                        if (pNewJoinBssParam->mode_802_11i == 0)
3973                                                pNewJoinBssParam->mode_802_11i = 1;
3974                                        rsnIndex += 4;
3975                                }
3976
3977                                rsnIndex += 7;
3978                                pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
3979                                rsnIndex++;
3980                                jumpOffset = pu8IEs[rsnIndex] * 4;
3981                                pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
3982                                rsnIndex += 2;
3983
3984                                for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
3985                                        pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
3986
3987                                pcipherTotalCount += pcipherCount;
3988                                rsnIndex += jumpOffset;
3989
3990                                jumpOffset = pu8IEs[rsnIndex] * 4;
3991
3992                                authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
3993                                rsnIndex += 2;
3994
3995                                for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
3996                                        pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
3997
3998                                authTotalCount += authCount;
3999                                rsnIndex += jumpOffset;
4000
4001                                if (pu8IEs[index] == RSN_IE) {
4002                                        pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4003                                        pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4004                                        rsnIndex += 2;
4005                                }
4006                                pNewJoinBssParam->rsn_found = true;
4007                                index += pu8IEs[index + 1] + 2;
4008                                continue;
4009                        } else
4010                                index += pu8IEs[index + 1] + 2;
4011                }
4012        }
4013
4014        return (void *)pNewJoinBssParam;
4015}
4016
4017int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4018{
4019        int result = 0;
4020        struct host_if_msg msg;
4021
4022        memset(&msg, 0, sizeof(struct host_if_msg));
4023
4024        msg.id = HOST_IF_MSG_SET_IPADDRESS;
4025
4026        msg.body.ip_info.ip_addr = ip_addr;
4027        msg.vif = vif;
4028        msg.body.ip_info.idx = idx;
4029
4030        result = wilc_enqueue_cmd(&msg);
4031        if (result)
4032                netdev_err(vif->ndev, "wilc_mq_send fail\n");
4033
4034        return result;
4035}
4036
4037static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx)
4038{
4039        int result = 0;
4040        struct host_if_msg msg;
4041
4042        memset(&msg, 0, sizeof(struct host_if_msg));
4043
4044        msg.id = HOST_IF_MSG_GET_IPADDRESS;
4045
4046        msg.body.ip_info.ip_addr = ip_addr;
4047        msg.vif = vif;
4048        msg.body.ip_info.idx = idx;
4049
4050        result = wilc_enqueue_cmd(&msg);
4051        if (result)
4052                netdev_err(vif->ndev, "wilc_mq_send fail\n");
4053
4054        return result;
4055}
4056
4057int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
4058{
4059        int ret = 0;
4060        struct host_if_msg msg;
4061
4062        memset(&msg, 0, sizeof(struct host_if_msg));
4063
4064        msg.id = HOST_IF_MSG_SET_TX_POWER;
4065        msg.body.tx_power.tx_pwr = tx_power;
4066        msg.vif = vif;
4067
4068        ret = wilc_enqueue_cmd(&msg);
4069        if (ret)
4070                netdev_err(vif->ndev, "wilc_mq_send fail\n");
4071
4072        return ret;
4073}
4074
4075int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
4076{
4077        int ret = 0;
4078        struct host_if_msg msg;
4079
4080        memset(&msg, 0, sizeof(struct host_if_msg));
4081
4082        msg.id = HOST_IF_MSG_GET_TX_POWER;
4083        msg.vif = vif;
4084
4085        ret = wilc_enqueue_cmd(&msg);
4086        if (ret)
4087                netdev_err(vif->ndev, "Failed to get TX PWR\n");
4088
4089        wait_for_completion(&hif_wait_response);
4090        *tx_power = msg.body.tx_power.tx_pwr;
4091
4092        return ret;
4093}
4094