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