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_if.h"
   8#include "wilc_msgqueue.h"
   9#include <linux/etherdevice.h>
  10#include "wilc_wfi_netdevice.h"
  11
  12extern u8 connecting;
  13
  14extern struct timer_list hDuringIpTimer;
  15
  16extern u8 g_wilc_initialized;
  17
  18#define HOST_IF_MSG_SCAN                        0
  19#define HOST_IF_MSG_CONNECT                     1
  20#define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO        2
  21#define HOST_IF_MSG_KEY                         3
  22#define HOST_IF_MSG_RCVD_NTWRK_INFO             4
  23#define HOST_IF_MSG_RCVD_SCAN_COMPLETE          5
  24#define HOST_IF_MSG_CFG_PARAMS                  6
  25#define HOST_IF_MSG_SET_CHANNEL                 7
  26#define HOST_IF_MSG_DISCONNECT                  8
  27#define HOST_IF_MSG_GET_RSSI                    9
  28#define HOST_IF_MSG_GET_CHNL                    10
  29#define HOST_IF_MSG_ADD_BEACON                  11
  30#define HOST_IF_MSG_DEL_BEACON                  12
  31#define HOST_IF_MSG_ADD_STATION                 13
  32#define HOST_IF_MSG_DEL_STATION                 14
  33#define HOST_IF_MSG_EDIT_STATION                15
  34#define HOST_IF_MSG_SCAN_TIMER_FIRED            16
  35#define HOST_IF_MSG_CONNECT_TIMER_FIRED         17
  36#define HOST_IF_MSG_POWER_MGMT                  18
  37#define HOST_IF_MSG_GET_INACTIVETIME            19
  38#define HOST_IF_MSG_REMAIN_ON_CHAN              20
  39#define HOST_IF_MSG_REGISTER_FRAME              21
  40#define HOST_IF_MSG_LISTEN_TIMER_FIRED          22
  41#define HOST_IF_MSG_GET_LINKSPEED               23
  42#define HOST_IF_MSG_SET_WFIDRV_HANDLER          24
  43#define HOST_IF_MSG_SET_MAC_ADDRESS             25
  44#define HOST_IF_MSG_GET_MAC_ADDRESS             26
  45#define HOST_IF_MSG_SET_OPERATION_MODE          27
  46#define HOST_IF_MSG_SET_IPADDRESS               28
  47#define HOST_IF_MSG_GET_IPADDRESS               29
  48#define HOST_IF_MSG_FLUSH_CONNECT               30
  49#define HOST_IF_MSG_GET_STATISTICS              31
  50#define HOST_IF_MSG_SET_MULTICAST_FILTER        32
  51#define HOST_IF_MSG_ADD_BA_SESSION              33
  52#define HOST_IF_MSG_DEL_BA_SESSION              34
  53#define HOST_IF_MSG_Q_IDLE                      35
  54#define HOST_IF_MSG_DEL_ALL_STA                 36
  55#define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS      34
  56#define HOST_IF_MSG_EXIT                        100
  57
  58#define HOST_IF_SCAN_TIMEOUT                    4000
  59#define HOST_IF_CONNECT_TIMEOUT                 9500
  60
  61#define BA_SESSION_DEFAULT_BUFFER_SIZE          16
  62#define BA_SESSION_DEFAULT_TIMEOUT              1000
  63#define BLOCK_ACK_REQ_SIZE                      0x14
  64#define FALSE_FRMWR_CHANNEL                     100
  65
  66struct cfg_param_attr {
  67        struct cfg_param_val cfg_attr_info;
  68};
  69
  70struct host_if_wpa_attr {
  71        u8 *key;
  72        const u8 *mac_addr;
  73        u8 *seq;
  74        u8 seq_len;
  75        u8 index;
  76        u8 key_len;
  77        u8 mode;
  78};
  79
  80struct host_if_wep_attr {
  81        u8 *key;
  82        u8 key_len;
  83        u8 index;
  84        u8 mode;
  85        enum AUTHTYPE auth_type;
  86};
  87
  88union host_if_key_attr {
  89        struct host_if_wep_attr wep;
  90        struct host_if_wpa_attr wpa;
  91        struct host_if_pmkid_attr pmkid;
  92};
  93
  94struct key_attr {
  95        enum KEY_TYPE type;
  96        u8 action;
  97        union host_if_key_attr attr;
  98};
  99
 100struct scan_attr {
 101        u8 src;
 102        u8 type;
 103        u8 *ch_freq_list;
 104        u8 ch_list_len;
 105        u8 *ies;
 106        size_t ies_len;
 107        wilc_scan_result result;
 108        void *arg;
 109        struct hidden_network hidden_network;
 110};
 111
 112struct connect_attr {
 113        u8 *bssid;
 114        u8 *ssid;
 115        size_t ssid_len;
 116        u8 *ies;
 117        size_t ies_len;
 118        u8 security;
 119        wilc_connect_result result;
 120        void *arg;
 121        enum AUTHTYPE auth_type;
 122        u8 ch;
 123        void *params;
 124};
 125
 126struct rcvd_async_info {
 127        u8 *buffer;
 128        u32 len;
 129};
 130
 131struct channel_attr {
 132        u8 set_ch;
 133};
 134
 135struct beacon_attr {
 136        u32 interval;
 137        u32 dtim_period;
 138        u32 head_len;
 139        u8 *head;
 140        u32 tail_len;
 141        u8 *tail;
 142};
 143
 144struct set_multicast {
 145        bool enabled;
 146        u32 cnt;
 147};
 148
 149struct del_all_sta {
 150        u8 del_all_sta[MAX_NUM_STA][ETH_ALEN];
 151        u8 assoc_sta;
 152};
 153
 154struct del_sta {
 155        u8 mac_addr[ETH_ALEN];
 156};
 157
 158struct power_mgmt_param {
 159        bool enabled;
 160        u32 timeout;
 161};
 162
 163struct set_ip_addr {
 164        u8 *ip_addr;
 165        u8 idx;
 166};
 167
 168struct sta_inactive_t {
 169        u8 mac[6];
 170};
 171
 172union message_body {
 173        struct scan_attr scan_info;
 174        struct connect_attr con_info;
 175        struct rcvd_net_info net_info;
 176        struct rcvd_async_info async_info;
 177        struct key_attr key_info;
 178        struct cfg_param_attr cfg_info;
 179        struct channel_attr channel_info;
 180        struct beacon_attr beacon_info;
 181        struct add_sta_param add_sta_info;
 182        struct del_sta del_sta_info;
 183        struct add_sta_param edit_sta_info;
 184        struct power_mgmt_param pwr_mgmt_info;
 185        struct sta_inactive_t mac_info;
 186        struct set_ip_addr ip_info;
 187        struct drv_handler drv;
 188        struct set_multicast multicast_info;
 189        struct op_mode mode;
 190        struct set_mac_addr set_mac_info;
 191        struct get_mac_addr get_mac_info;
 192        struct ba_session_info session_info;
 193        struct remain_ch remain_on_ch;
 194        struct reg_frame reg_frame;
 195        char *data;
 196        struct del_all_sta del_all_sta_info;
 197};
 198
 199struct host_if_msg {
 200        u16 id;
 201        union message_body body;
 202        struct host_if_drv *drv;
 203};
 204
 205struct join_bss_param {
 206        BSSTYPE_T bss_type;
 207        u8 dtim_period;
 208        u16 beacon_period;
 209        u16 cap_info;
 210        u8 au8bssid[6];
 211        char ssid[MAX_SSID_LEN];
 212        u8 ssid_len;
 213        u8 supp_rates[MAX_RATES_SUPPORTED + 1];
 214        u8 ht_capable;
 215        u8 wmm_cap;
 216        u8 uapsd_cap;
 217        bool rsn_found;
 218        u8 rsn_grp_policy;
 219        u8 mode_802_11i;
 220        u8 rsn_pcip_policy[3];
 221        u8 rsn_auth_policy[3];
 222        u8 rsn_cap[2];
 223        u32 tsf;
 224        u8 noa_enabled;
 225        u8 opp_enabled;
 226        u8 ct_window;
 227        u8 cnt;
 228        u8 idx;
 229        u8 duration[4];
 230        u8 interval[4];
 231        u8 start_time[4];
 232};
 233
 234static struct host_if_drv *wfidrv_list[NUM_CONCURRENT_IFC + 1];
 235struct host_if_drv *terminated_handle;
 236bool g_obtainingIP;
 237u8 P2P_LISTEN_STATE;
 238static struct task_struct *hif_thread_handler;
 239static WILC_MsgQueueHandle hif_msg_q;
 240static struct semaphore hif_sema_thread;
 241static struct semaphore hif_sema_driver;
 242static struct semaphore hif_sema_wait_response;
 243static struct semaphore hif_sema_deinit;
 244static struct timer_list periodic_rssi;
 245
 246u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
 247
 248static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE];
 249
 250static bool scan_while_connected;
 251
 252static s8 rssi;
 253static s8 link_speed;
 254static u8 ch_no;
 255static u8 set_ip[2][4];
 256static u8 get_ip[2][4];
 257static u32 inactive_time;
 258static u8 del_beacon;
 259static u32 clients_count;
 260
 261static u8 *join_req;
 262u8 *info_element;
 263static u8 mode_11i;
 264u8 auth_type;
 265u32 join_req_size;
 266static u32 info_element_size;
 267static struct host_if_drv *join_req_drv;
 268#define REAL_JOIN_REQ 0
 269#define FLUSHED_JOIN_REQ 1
 270#define FLUSHED_BYTE_POS 79
 271
 272static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo);
 273
 274extern void chip_sleep_manually(u32 u32SleepTime);
 275extern int linux_wlan_get_num_conn_ifcs(void);
 276
 277static int add_handler_in_list(struct host_if_drv *handler)
 278{
 279        int i;
 280
 281        for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
 282                if (!wfidrv_list[i]) {
 283                        wfidrv_list[i] = handler;
 284                        return 0;
 285                }
 286        }
 287
 288        return -ENOBUFS;
 289}
 290
 291static int remove_handler_in_list(struct host_if_drv *handler)
 292{
 293        int i;
 294
 295        for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
 296                if (wfidrv_list[i] == handler) {
 297                        wfidrv_list[i] = NULL;
 298                        return 0;
 299                }
 300        }
 301
 302        return -EINVAL;
 303}
 304
 305static int get_id_from_handler(struct host_if_drv *handler)
 306{
 307        int i;
 308
 309        if (!handler)
 310                return 0;
 311
 312        for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
 313                if (wfidrv_list[i] == handler)
 314                        return i;
 315        }
 316
 317        return 0;
 318}
 319
 320static struct host_if_drv *get_handler_from_id(int id)
 321{
 322        if (id <= 0 || id >= ARRAY_SIZE(wfidrv_list))
 323                return NULL;
 324        return wfidrv_list[id];
 325}
 326
 327static s32 Handle_SetChannel(struct host_if_drv *hif_drv,
 328                             struct channel_attr *pstrHostIFSetChan)
 329{
 330        s32 result = 0;
 331        struct wid wid;
 332
 333        wid.id = (u16)WID_CURRENT_CHANNEL;
 334        wid.type = WID_CHAR;
 335        wid.val = (char *)&pstrHostIFSetChan->set_ch;
 336        wid.size = sizeof(char);
 337
 338        PRINT_D(HOSTINF_DBG, "Setting channel\n");
 339
 340        result = send_config_pkt(SET_CFG, &wid, 1,
 341                                 get_id_from_handler(hif_drv));
 342
 343        if (result) {
 344                PRINT_ER("Failed to set channel\n");
 345                return -EINVAL;
 346        }
 347
 348        return result;
 349}
 350
 351static s32 Handle_SetWfiDrvHandler(struct host_if_drv *hif_drv,
 352                                   struct drv_handler *pstrHostIfSetDrvHandler)
 353{
 354        s32 result = 0;
 355        struct wid wid;
 356
 357        wid.id = (u16)WID_SET_DRV_HANDLER;
 358        wid.type = WID_INT;
 359        wid.val = (s8 *)&pstrHostIfSetDrvHandler->handler;
 360        wid.size = sizeof(u32);
 361
 362        result = send_config_pkt(SET_CFG, &wid, 1,
 363                                 pstrHostIfSetDrvHandler->handler);
 364
 365        if (!hif_drv)
 366                up(&hif_sema_driver);
 367
 368        if (result) {
 369                PRINT_ER("Failed to set driver handler\n");
 370                return -EINVAL;
 371        }
 372
 373        return result;
 374}
 375
 376static s32 Handle_SetOperationMode(struct host_if_drv *hif_drv,
 377                                   struct op_mode *pstrHostIfSetOperationMode)
 378{
 379        s32 result = 0;
 380        struct wid wid;
 381
 382        wid.id = (u16)WID_SET_OPERATION_MODE;
 383        wid.type = WID_INT;
 384        wid.val = (s8 *)&pstrHostIfSetOperationMode->mode;
 385        wid.size = sizeof(u32);
 386
 387        result = send_config_pkt(SET_CFG, &wid, 1,
 388                                 get_id_from_handler(hif_drv));
 389
 390        if ((pstrHostIfSetOperationMode->mode) == IDLE_MODE)
 391                up(&hif_sema_driver);
 392
 393        if (result) {
 394                PRINT_ER("Failed to set driver handler\n");
 395                return -EINVAL;
 396        }
 397
 398        return result;
 399}
 400
 401s32 Handle_set_IPAddress(struct host_if_drv *hif_drv, u8 *pu8IPAddr, u8 idx)
 402{
 403        s32 result = 0;
 404        struct wid wid;
 405        char firmwareIPAddress[4] = {0};
 406
 407        if (pu8IPAddr[0] < 192)
 408                pu8IPAddr[0] = 0;
 409
 410        PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set  IP = %pI4\n", idx, pu8IPAddr);
 411
 412        memcpy(set_ip[idx], pu8IPAddr, IP_ALEN);
 413
 414        wid.id = (u16)WID_IP_ADDRESS;
 415        wid.type = WID_STR;
 416        wid.val = (u8 *)pu8IPAddr;
 417        wid.size = IP_ALEN;
 418
 419        result = send_config_pkt(SET_CFG, &wid, 1,
 420                                 get_id_from_handler(hif_drv));
 421
 422        host_int_get_ipaddress(hif_drv, firmwareIPAddress, idx);
 423
 424        if (result) {
 425                PRINT_ER("Failed to set IP address\n");
 426                return -EINVAL;
 427        }
 428
 429        PRINT_INFO(HOSTINF_DBG, "IP address set\n");
 430
 431        return result;
 432}
 433
 434s32 Handle_get_IPAddress(struct host_if_drv *hif_drv, u8 *pu8IPAddr, u8 idx)
 435{
 436        s32 result = 0;
 437        struct wid wid;
 438
 439        wid.id = (u16)WID_IP_ADDRESS;
 440        wid.type = WID_STR;
 441        wid.val = kmalloc(IP_ALEN, GFP_KERNEL);
 442        wid.size = IP_ALEN;
 443
 444        result = send_config_pkt(GET_CFG, &wid, 1,
 445                                 get_id_from_handler(hif_drv));
 446
 447        PRINT_INFO(HOSTINF_DBG, "%pI4\n", wid.val);
 448
 449        memcpy(get_ip[idx], wid.val, IP_ALEN);
 450
 451        kfree(wid.val);
 452
 453        if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0)
 454                host_int_setup_ipaddress(hif_drv, set_ip[idx], idx);
 455
 456        if (result != 0) {
 457                PRINT_ER("Failed to get IP address\n");
 458                return -EINVAL;
 459        }
 460
 461        PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d\n", idx);
 462        PRINT_INFO(HOSTINF_DBG, "%pI4\n", get_ip[idx]);
 463        PRINT_INFO(HOSTINF_DBG, "\n");
 464
 465        return result;
 466}
 467
 468static s32 Handle_SetMacAddress(struct host_if_drv *hif_drv,
 469                                struct set_mac_addr *pstrHostIfSetMacAddress)
 470{
 471        s32 result = 0;
 472        struct wid wid;
 473        u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL);
 474
 475        if (!mac_buf) {
 476                PRINT_ER("No buffer to send mac address\n");
 477                return -EFAULT;
 478        }
 479        memcpy(mac_buf, pstrHostIfSetMacAddress->mac_addr, ETH_ALEN);
 480
 481        wid.id = (u16)WID_MAC_ADDR;
 482        wid.type = WID_STR;
 483        wid.val = mac_buf;
 484        wid.size = ETH_ALEN;
 485        PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", wid.val);
 486
 487        result = send_config_pkt(SET_CFG, &wid, 1,
 488                                 get_id_from_handler(hif_drv));
 489        if (result) {
 490                PRINT_ER("Failed to set mac address\n");
 491                result = -EFAULT;
 492        }
 493
 494        kfree(mac_buf);
 495        return result;
 496}
 497
 498static s32 Handle_GetMacAddress(struct host_if_drv *hif_drv,
 499                                struct get_mac_addr *pstrHostIfGetMacAddress)
 500{
 501        s32 result = 0;
 502        struct wid wid;
 503
 504        wid.id = (u16)WID_MAC_ADDR;
 505        wid.type = WID_STR;
 506        wid.val = pstrHostIfGetMacAddress->mac_addr;
 507        wid.size = ETH_ALEN;
 508
 509        result = send_config_pkt(GET_CFG, &wid, 1,
 510                                 get_id_from_handler(hif_drv));
 511
 512        if (result) {
 513                PRINT_ER("Failed to get mac address\n");
 514                result = -EFAULT;
 515        }
 516        up(&hif_sema_wait_response);
 517
 518        return result;
 519}
 520
 521static s32 Handle_CfgParam(struct host_if_drv *hif_drv,
 522                           struct cfg_param_attr *strHostIFCfgParamAttr)
 523{
 524        s32 result = 0;
 525        struct wid strWIDList[32];
 526        u8 u8WidCnt = 0;
 527
 528        down(&hif_drv->gtOsCfgValuesSem);
 529
 530        PRINT_D(HOSTINF_DBG, "Setting CFG params\n");
 531
 532        if (strHostIFCfgParamAttr->cfg_attr_info.flag & BSS_TYPE) {
 533                if (strHostIFCfgParamAttr->cfg_attr_info.bss_type < 6) {
 534                        strWIDList[u8WidCnt].id = WID_BSS_TYPE;
 535                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.bss_type;
 536                        strWIDList[u8WidCnt].type = WID_CHAR;
 537                        strWIDList[u8WidCnt].size = sizeof(char);
 538                        hif_drv->strCfgValues.bss_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.bss_type;
 539                } else {
 540                        PRINT_ER("check value 6 over\n");
 541                        result = -EINVAL;
 542                        goto ERRORHANDLER;
 543                }
 544                u8WidCnt++;
 545        }
 546        if (strHostIFCfgParamAttr->cfg_attr_info.flag & AUTH_TYPE) {
 547                if ((strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 1 || (strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 2 || (strHostIFCfgParamAttr->cfg_attr_info.auth_type) == 5) {
 548                        strWIDList[u8WidCnt].id = WID_AUTH_TYPE;
 549                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_type;
 550                        strWIDList[u8WidCnt].type = WID_CHAR;
 551                        strWIDList[u8WidCnt].size = sizeof(char);
 552                        hif_drv->strCfgValues.auth_type = (u8)strHostIFCfgParamAttr->cfg_attr_info.auth_type;
 553                } else {
 554                        PRINT_ER("Impossible value \n");
 555                        result = -EINVAL;
 556                        goto ERRORHANDLER;
 557                }
 558                u8WidCnt++;
 559        }
 560        if (strHostIFCfgParamAttr->cfg_attr_info.flag & AUTHEN_TIMEOUT) {
 561                if (strHostIFCfgParamAttr->cfg_attr_info.auth_timeout > 0 && strHostIFCfgParamAttr->cfg_attr_info.auth_timeout < 65536) {
 562                        strWIDList[u8WidCnt].id = WID_AUTH_TIMEOUT;
 563                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.auth_timeout;
 564                        strWIDList[u8WidCnt].type = WID_SHORT;
 565                        strWIDList[u8WidCnt].size = sizeof(u16);
 566                        hif_drv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->cfg_attr_info.auth_timeout;
 567                } else {
 568                        PRINT_ER("Range(1 ~ 65535) over\n");
 569                        result = -EINVAL;
 570                        goto ERRORHANDLER;
 571                }
 572                u8WidCnt++;
 573        }
 574        if (strHostIFCfgParamAttr->cfg_attr_info.flag & POWER_MANAGEMENT) {
 575                if (strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode < 5) {
 576                        strWIDList[u8WidCnt].id = WID_POWER_MANAGEMENT;
 577                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode;
 578                        strWIDList[u8WidCnt].type = WID_CHAR;
 579                        strWIDList[u8WidCnt].size = sizeof(char);
 580                        hif_drv->strCfgValues.power_mgmt_mode = (u8)strHostIFCfgParamAttr->cfg_attr_info.power_mgmt_mode;
 581                } else {
 582                        PRINT_ER("Invalide power mode\n");
 583                        result = -EINVAL;
 584                        goto ERRORHANDLER;
 585                }
 586                u8WidCnt++;
 587        }
 588        if (strHostIFCfgParamAttr->cfg_attr_info.flag & RETRY_SHORT) {
 589                if ((strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit > 0) && (strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit < 256))     {
 590                        strWIDList[u8WidCnt].id = WID_SHORT_RETRY_LIMIT;
 591                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit;
 592                        strWIDList[u8WidCnt].type = WID_SHORT;
 593                        strWIDList[u8WidCnt].size = sizeof(u16);
 594                        hif_drv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.short_retry_limit;
 595                } else {
 596                        PRINT_ER("Range(1~256) over\n");
 597                        result = -EINVAL;
 598                        goto ERRORHANDLER;
 599                }
 600                u8WidCnt++;
 601        }
 602        if (strHostIFCfgParamAttr->cfg_attr_info.flag & RETRY_LONG) {
 603                if ((strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit > 0) && (strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit < 256)) {
 604                        strWIDList[u8WidCnt].id = WID_LONG_RETRY_LIMIT;
 605                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit;
 606
 607                        strWIDList[u8WidCnt].type = WID_SHORT;
 608                        strWIDList[u8WidCnt].size = sizeof(u16);
 609                        hif_drv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->cfg_attr_info.long_retry_limit;
 610                } else {
 611                        PRINT_ER("Range(1~256) over\n");
 612                        result = -EINVAL;
 613                        goto ERRORHANDLER;
 614                }
 615                u8WidCnt++;
 616        }
 617        if (strHostIFCfgParamAttr->cfg_attr_info.flag & FRAG_THRESHOLD) {
 618                if (strHostIFCfgParamAttr->cfg_attr_info.frag_threshold > 255 && strHostIFCfgParamAttr->cfg_attr_info.frag_threshold < 7937) {
 619                        strWIDList[u8WidCnt].id = WID_FRAG_THRESHOLD;
 620                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.frag_threshold;
 621                        strWIDList[u8WidCnt].type = WID_SHORT;
 622                        strWIDList[u8WidCnt].size = sizeof(u16);
 623                        hif_drv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->cfg_attr_info.frag_threshold;
 624                } else {
 625                        PRINT_ER("Threshold Range fail\n");
 626                        result = -EINVAL;
 627                        goto ERRORHANDLER;
 628                }
 629                u8WidCnt++;
 630        }
 631        if (strHostIFCfgParamAttr->cfg_attr_info.flag & RTS_THRESHOLD) {
 632                if (strHostIFCfgParamAttr->cfg_attr_info.rts_threshold > 255 && strHostIFCfgParamAttr->cfg_attr_info.rts_threshold < 65536)     {
 633                        strWIDList[u8WidCnt].id = WID_RTS_THRESHOLD;
 634                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.rts_threshold;
 635                        strWIDList[u8WidCnt].type = WID_SHORT;
 636                        strWIDList[u8WidCnt].size = sizeof(u16);
 637                        hif_drv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->cfg_attr_info.rts_threshold;
 638                } else {
 639                        PRINT_ER("Threshold Range fail\n");
 640                        result = -EINVAL;
 641                        goto ERRORHANDLER;
 642                }
 643                u8WidCnt++;
 644        }
 645        if (strHostIFCfgParamAttr->cfg_attr_info.flag & PREAMBLE) {
 646                if (strHostIFCfgParamAttr->cfg_attr_info.preamble_type < 3) {
 647                        strWIDList[u8WidCnt].id = WID_PREAMBLE;
 648                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.preamble_type;
 649                        strWIDList[u8WidCnt].type = WID_CHAR;
 650                        strWIDList[u8WidCnt].size = sizeof(char);
 651                        hif_drv->strCfgValues.preamble_type = strHostIFCfgParamAttr->cfg_attr_info.preamble_type;
 652                } else {
 653                        PRINT_ER("Preamle Range(0~2) over\n");
 654                        result = -EINVAL;
 655                        goto ERRORHANDLER;
 656                }
 657                u8WidCnt++;
 658        }
 659        if (strHostIFCfgParamAttr->cfg_attr_info.flag & SHORT_SLOT_ALLOWED) {
 660                if (strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed < 2) {
 661                        strWIDList[u8WidCnt].id = WID_SHORT_SLOT_ALLOWED;
 662                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed;
 663                        strWIDList[u8WidCnt].type = WID_CHAR;
 664                        strWIDList[u8WidCnt].size = sizeof(char);
 665                        hif_drv->strCfgValues.short_slot_allowed = (u8)strHostIFCfgParamAttr->cfg_attr_info.short_slot_allowed;
 666                } else {
 667                        PRINT_ER("Short slot(2) over\n");
 668                        result = -EINVAL;
 669                        goto ERRORHANDLER;
 670                }
 671                u8WidCnt++;
 672        }
 673        if (strHostIFCfgParamAttr->cfg_attr_info.flag & TXOP_PROT_DISABLE) {
 674                if (strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled < 2) {
 675                        strWIDList[u8WidCnt].id = WID_11N_TXOP_PROT_DISABLE;
 676                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled;
 677                        strWIDList[u8WidCnt].type = WID_CHAR;
 678                        strWIDList[u8WidCnt].size = sizeof(char);
 679                        hif_drv->strCfgValues.txop_prot_disabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.txop_prot_disabled;
 680                } else {
 681                        PRINT_ER("TXOP prot disable\n");
 682                        result = -EINVAL;
 683                        goto ERRORHANDLER;
 684                }
 685                u8WidCnt++;
 686        }
 687        if (strHostIFCfgParamAttr->cfg_attr_info.flag & BEACON_INTERVAL) {
 688                if (strHostIFCfgParamAttr->cfg_attr_info.beacon_interval > 0 && strHostIFCfgParamAttr->cfg_attr_info.beacon_interval < 65536) {
 689                        strWIDList[u8WidCnt].id = WID_BEACON_INTERVAL;
 690                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.beacon_interval;
 691                        strWIDList[u8WidCnt].type = WID_SHORT;
 692                        strWIDList[u8WidCnt].size = sizeof(u16);
 693                        hif_drv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->cfg_attr_info.beacon_interval;
 694                } else {
 695                        PRINT_ER("Beacon interval(1~65535) fail\n");
 696                        result = -EINVAL;
 697                        goto ERRORHANDLER;
 698                }
 699                u8WidCnt++;
 700        }
 701        if (strHostIFCfgParamAttr->cfg_attr_info.flag & DTIM_PERIOD) {
 702                if (strHostIFCfgParamAttr->cfg_attr_info.dtim_period > 0 && strHostIFCfgParamAttr->cfg_attr_info.dtim_period < 256) {
 703                        strWIDList[u8WidCnt].id = WID_DTIM_PERIOD;
 704                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.dtim_period;
 705                        strWIDList[u8WidCnt].type = WID_CHAR;
 706                        strWIDList[u8WidCnt].size = sizeof(char);
 707                        hif_drv->strCfgValues.dtim_period = strHostIFCfgParamAttr->cfg_attr_info.dtim_period;
 708                } else {
 709                        PRINT_ER("DTIM range(1~255) fail\n");
 710                        result = -EINVAL;
 711                        goto ERRORHANDLER;
 712                }
 713                u8WidCnt++;
 714        }
 715        if (strHostIFCfgParamAttr->cfg_attr_info.flag & SITE_SURVEY) {
 716                if (strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled < 3) {
 717                        strWIDList[u8WidCnt].id = WID_SITE_SURVEY;
 718                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled;
 719                        strWIDList[u8WidCnt].type = WID_CHAR;
 720                        strWIDList[u8WidCnt].size = sizeof(char);
 721                        hif_drv->strCfgValues.site_survey_enabled = (u8)strHostIFCfgParamAttr->cfg_attr_info.site_survey_enabled;
 722                } else {
 723                        PRINT_ER("Site survey disable\n");
 724                        result = -EINVAL;
 725                        goto ERRORHANDLER;
 726                }
 727                u8WidCnt++;
 728        }
 729        if (strHostIFCfgParamAttr->cfg_attr_info.flag & SITE_SURVEY_SCAN_TIME) {
 730                if (strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time < 65536) {
 731                        strWIDList[u8WidCnt].id = WID_SITE_SURVEY_SCAN_TIME;
 732                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time;
 733                        strWIDList[u8WidCnt].type = WID_SHORT;
 734                        strWIDList[u8WidCnt].size = sizeof(u16);
 735                        hif_drv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->cfg_attr_info.site_survey_scan_time;
 736                } else {
 737                        PRINT_ER("Site survey scan time(1~65535) over\n");
 738                        result = -EINVAL;
 739                        goto ERRORHANDLER;
 740                }
 741                u8WidCnt++;
 742        }
 743        if (strHostIFCfgParamAttr->cfg_attr_info.flag & ACTIVE_SCANTIME) {
 744                if (strHostIFCfgParamAttr->cfg_attr_info.active_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.active_scan_time < 65536) {
 745                        strWIDList[u8WidCnt].id = WID_ACTIVE_SCAN_TIME;
 746                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.active_scan_time;
 747                        strWIDList[u8WidCnt].type = WID_SHORT;
 748                        strWIDList[u8WidCnt].size = sizeof(u16);
 749                        hif_drv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->cfg_attr_info.active_scan_time;
 750                } else {
 751                        PRINT_ER("Active scan time(1~65535) over\n");
 752                        result = -EINVAL;
 753                        goto ERRORHANDLER;
 754                }
 755                u8WidCnt++;
 756        }
 757        if (strHostIFCfgParamAttr->cfg_attr_info.flag & PASSIVE_SCANTIME) {
 758                if (strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time > 0 && strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time < 65536) {
 759                        strWIDList[u8WidCnt].id = WID_PASSIVE_SCAN_TIME;
 760                        strWIDList[u8WidCnt].val = (s8 *)&strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time;
 761                        strWIDList[u8WidCnt].type = WID_SHORT;
 762                        strWIDList[u8WidCnt].size = sizeof(u16);
 763                        hif_drv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->cfg_attr_info.passive_scan_time;
 764                } else {
 765                        PRINT_ER("Passive scan time(1~65535) over\n");
 766                        result = -EINVAL;
 767                        goto ERRORHANDLER;
 768                }
 769                u8WidCnt++;
 770        }
 771        if (strHostIFCfgParamAttr->cfg_attr_info.flag & CURRENT_TX_RATE) {
 772                enum CURRENT_TXRATE curr_tx_rate = strHostIFCfgParamAttr->cfg_attr_info.curr_tx_rate;
 773
 774                if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1
 775                    || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5
 776                    || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6
 777                    || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12
 778                    || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24
 779                    || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) {
 780                        strWIDList[u8WidCnt].id = WID_CURRENT_TX_RATE;
 781                        strWIDList[u8WidCnt].val = (s8 *)&curr_tx_rate;
 782                        strWIDList[u8WidCnt].type = WID_SHORT;
 783                        strWIDList[u8WidCnt].size = sizeof(u16);
 784                        hif_drv->strCfgValues.curr_tx_rate = (u8)curr_tx_rate;
 785                } else {
 786                        PRINT_ER("out of TX rate\n");
 787                        result = -EINVAL;
 788                        goto ERRORHANDLER;
 789                }
 790                u8WidCnt++;
 791        }
 792
 793        result = send_config_pkt(SET_CFG, strWIDList, u8WidCnt,
 794                                 get_id_from_handler(hif_drv));
 795
 796        if (result)
 797                PRINT_ER("Error in setting CFG params\n");
 798
 799ERRORHANDLER:
 800        up(&hif_drv->gtOsCfgValuesSem);
 801        return result;
 802}
 803
 804static s32 Handle_wait_msg_q_empty(void)
 805{
 806        g_wilc_initialized = 0;
 807        up(&hif_sema_wait_response);
 808        return 0;
 809}
 810
 811static s32 Handle_Scan(struct host_if_drv *hif_drv,
 812                       struct scan_attr *pstrHostIFscanAttr)
 813{
 814        s32 result = 0;
 815        struct wid strWIDList[5];
 816        u32 u32WidsCount = 0;
 817        u32 i;
 818        u8 *pu8Buffer;
 819        u8 valuesize = 0;
 820        u8 *pu8HdnNtwrksWidVal = NULL;
 821
 822        PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
 823        PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", hif_drv->enuHostIFstate);
 824
 825        hif_drv->usr_scan_req.pfUserScanResult = pstrHostIFscanAttr->result;
 826        hif_drv->usr_scan_req.u32UserScanPvoid = pstrHostIFscanAttr->arg;
 827
 828        if ((hif_drv->enuHostIFstate >= HOST_IF_SCANNING) && (hif_drv->enuHostIFstate < HOST_IF_CONNECTED)) {
 829                PRINT_D(GENERIC_DBG, "Don't scan we are already in [%d] state\n", hif_drv->enuHostIFstate);
 830                PRINT_ER("Already scan\n");
 831                result = -EBUSY;
 832                goto ERRORHANDLER;
 833        }
 834
 835        if (g_obtainingIP || connecting) {
 836                PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
 837                PRINT_ER("Don't do obss scan\n");
 838                result = -EBUSY;
 839                goto ERRORHANDLER;
 840        }
 841
 842        PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
 843
 844        hif_drv->usr_scan_req.u32RcvdChCount = 0;
 845
 846        strWIDList[u32WidsCount].id = (u16)WID_SSID_PROBE_REQ;
 847        strWIDList[u32WidsCount].type = WID_STR;
 848
 849        for (i = 0; i < pstrHostIFscanAttr->hidden_network.u8ssidnum; i++)
 850                valuesize += ((pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen) + 1);
 851        pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
 852        strWIDList[u32WidsCount].val = pu8HdnNtwrksWidVal;
 853        if (strWIDList[u32WidsCount].val) {
 854                pu8Buffer = strWIDList[u32WidsCount].val;
 855
 856                *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.u8ssidnum;
 857
 858                PRINT_D(HOSTINF_DBG, "In Handle_ProbeRequest number of ssid %d\n", pstrHostIFscanAttr->hidden_network.u8ssidnum);
 859
 860                for (i = 0; i < pstrHostIFscanAttr->hidden_network.u8ssidnum; i++) {
 861                        *pu8Buffer++ = pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen;
 862                        memcpy(pu8Buffer, pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen);
 863                        pu8Buffer += pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo[i].u8ssidlen;
 864                }
 865
 866                strWIDList[u32WidsCount].size = (s32)(valuesize + 1);
 867                u32WidsCount++;
 868        }
 869
 870        {
 871                strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_PROBE;
 872                strWIDList[u32WidsCount].type = WID_BIN_DATA;
 873                strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ies;
 874                strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ies_len;
 875                u32WidsCount++;
 876        }
 877
 878        strWIDList[u32WidsCount].id = WID_SCAN_TYPE;
 879        strWIDList[u32WidsCount].type = WID_CHAR;
 880        strWIDList[u32WidsCount].size = sizeof(char);
 881        strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->type;
 882        u32WidsCount++;
 883
 884        strWIDList[u32WidsCount].id = WID_SCAN_CHANNEL_LIST;
 885        strWIDList[u32WidsCount].type = WID_BIN_DATA;
 886
 887        if (pstrHostIFscanAttr->ch_freq_list &&
 888            pstrHostIFscanAttr->ch_list_len > 0) {
 889                int i;
 890
 891                for (i = 0; i < pstrHostIFscanAttr->ch_list_len; i++)   {
 892                        if (pstrHostIFscanAttr->ch_freq_list[i] > 0)
 893                                pstrHostIFscanAttr->ch_freq_list[i] = pstrHostIFscanAttr->ch_freq_list[i] - 1;
 894                }
 895        }
 896
 897        strWIDList[u32WidsCount].val = pstrHostIFscanAttr->ch_freq_list;
 898        strWIDList[u32WidsCount].size = pstrHostIFscanAttr->ch_list_len;
 899        u32WidsCount++;
 900
 901        strWIDList[u32WidsCount].id = WID_START_SCAN_REQ;
 902        strWIDList[u32WidsCount].type = WID_CHAR;
 903        strWIDList[u32WidsCount].size = sizeof(char);
 904        strWIDList[u32WidsCount].val = (s8 *)&pstrHostIFscanAttr->src;
 905        u32WidsCount++;
 906
 907        if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)
 908                scan_while_connected = true;
 909        else if (hif_drv->enuHostIFstate == HOST_IF_IDLE)
 910                scan_while_connected = false;
 911
 912        result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
 913                                 get_id_from_handler(hif_drv));
 914
 915        if (result)
 916                PRINT_ER("Failed to send scan paramters config packet\n");
 917        else
 918                PRINT_D(HOSTINF_DBG, "Successfully sent SCAN params config packet\n");
 919
 920ERRORHANDLER:
 921        if (result) {
 922                del_timer(&hif_drv->hScanTimer);
 923                Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
 924        }
 925
 926        kfree(pstrHostIFscanAttr->ch_freq_list);
 927        pstrHostIFscanAttr->ch_freq_list = NULL;
 928
 929        kfree(pstrHostIFscanAttr->ies);
 930        pstrHostIFscanAttr->ies = NULL;
 931        kfree(pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo);
 932        pstrHostIFscanAttr->hidden_network.pstrHiddenNetworkInfo = NULL;
 933
 934        kfree(pu8HdnNtwrksWidVal);
 935
 936        return result;
 937}
 938
 939static s32 Handle_ScanDone(struct host_if_drv *hif_drv,
 940                           enum scan_event enuEvent)
 941{
 942        s32 result = 0;
 943        u8 u8abort_running_scan;
 944        struct wid wid;
 945
 946        PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n");
 947
 948        if (enuEvent == SCAN_EVENT_ABORTED) {
 949                PRINT_D(GENERIC_DBG, "Abort running scan\n");
 950                u8abort_running_scan = 1;
 951                wid.id = (u16)WID_ABORT_RUNNING_SCAN;
 952                wid.type = WID_CHAR;
 953                wid.val = (s8 *)&u8abort_running_scan;
 954                wid.size = sizeof(char);
 955
 956                result = send_config_pkt(SET_CFG, &wid, 1,
 957                                         get_id_from_handler(hif_drv));
 958
 959                if (result) {
 960                        PRINT_ER("Failed to set abort running scan\n");
 961                        result = -EFAULT;
 962                }
 963        }
 964
 965        if (!hif_drv) {
 966                PRINT_ER("Driver handler is NULL\n");
 967                return result;
 968        }
 969
 970        if (hif_drv->usr_scan_req.pfUserScanResult) {
 971                hif_drv->usr_scan_req.pfUserScanResult(enuEvent, NULL,
 972                                                       hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
 973                hif_drv->usr_scan_req.pfUserScanResult = NULL;
 974        }
 975
 976        return result;
 977}
 978
 979u8 u8ConnectedSSID[6] = {0};
 980static s32 Handle_Connect(struct host_if_drv *hif_drv,
 981                          struct connect_attr *pstrHostIFconnectAttr)
 982{
 983        s32 result = 0;
 984        struct wid strWIDList[8];
 985        u32 u32WidsCount = 0, dummyval = 0;
 986        u8 *pu8CurrByte = NULL;
 987        struct join_bss_param *ptstrJoinBssParam;
 988
 989        PRINT_D(GENERIC_DBG, "Handling connect request\n");
 990
 991        if (memcmp(pstrHostIFconnectAttr->bssid, u8ConnectedSSID, ETH_ALEN) == 0) {
 992                result = 0;
 993                PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n");
 994                return result;
 995        }
 996
 997        PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n");
 998
 999        ptstrJoinBssParam = (struct join_bss_param *)pstrHostIFconnectAttr->params;
1000        if (!ptstrJoinBssParam) {
1001                PRINT_ER("Required BSSID not found\n");
1002                result = -ENOENT;
1003                goto ERRORHANDLER;
1004        }
1005
1006        if (pstrHostIFconnectAttr->bssid) {
1007                hif_drv->usr_conn_req.pu8bssid = kmalloc(6, GFP_KERNEL);
1008                memcpy(hif_drv->usr_conn_req.pu8bssid, pstrHostIFconnectAttr->bssid, 6);
1009        }
1010
1011        hif_drv->usr_conn_req.ssidLen = pstrHostIFconnectAttr->ssid_len;
1012        if (pstrHostIFconnectAttr->ssid) {
1013                hif_drv->usr_conn_req.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssid_len + 1, GFP_KERNEL);
1014                memcpy(hif_drv->usr_conn_req.pu8ssid,
1015                       pstrHostIFconnectAttr->ssid,
1016                       pstrHostIFconnectAttr->ssid_len);
1017                hif_drv->usr_conn_req.pu8ssid[pstrHostIFconnectAttr->ssid_len] = '\0';
1018        }
1019
1020        hif_drv->usr_conn_req.ConnReqIEsLen = pstrHostIFconnectAttr->ies_len;
1021        if (pstrHostIFconnectAttr->ies) {
1022                hif_drv->usr_conn_req.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1023                memcpy(hif_drv->usr_conn_req.pu8ConnReqIEs,
1024                       pstrHostIFconnectAttr->ies,
1025                       pstrHostIFconnectAttr->ies_len);
1026        }
1027
1028        hif_drv->usr_conn_req.u8security = pstrHostIFconnectAttr->security;
1029        hif_drv->usr_conn_req.tenuAuth_type = pstrHostIFconnectAttr->auth_type;
1030        hif_drv->usr_conn_req.pfUserConnectResult = pstrHostIFconnectAttr->result;
1031        hif_drv->usr_conn_req.u32UserConnectPvoid = pstrHostIFconnectAttr->arg;
1032
1033        strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
1034        strWIDList[u32WidsCount].type = WID_INT;
1035        strWIDList[u32WidsCount].size = sizeof(u32);
1036        strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
1037        u32WidsCount++;
1038
1039        strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
1040        strWIDList[u32WidsCount].type = WID_INT;
1041        strWIDList[u32WidsCount].size = sizeof(u32);
1042        strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
1043        u32WidsCount++;
1044
1045        strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
1046        strWIDList[u32WidsCount].type = WID_INT;
1047        strWIDList[u32WidsCount].size = sizeof(u32);
1048        strWIDList[u32WidsCount].val = (s8 *)(&(dummyval));
1049        u32WidsCount++;
1050
1051        {
1052                strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
1053                strWIDList[u32WidsCount].type = WID_BIN_DATA;
1054                strWIDList[u32WidsCount].val = hif_drv->usr_conn_req.pu8ConnReqIEs;
1055                strWIDList[u32WidsCount].size = hif_drv->usr_conn_req.ConnReqIEsLen;
1056                u32WidsCount++;
1057
1058                if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1059                        info_element_size = hif_drv->usr_conn_req.ConnReqIEsLen;
1060                        info_element = kmalloc(info_element_size, GFP_KERNEL);
1061                        memcpy(info_element, hif_drv->usr_conn_req.pu8ConnReqIEs,
1062                               info_element_size);
1063                }
1064        }
1065        strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
1066        strWIDList[u32WidsCount].type = WID_CHAR;
1067        strWIDList[u32WidsCount].size = sizeof(char);
1068        strWIDList[u32WidsCount].val = (s8 *)&hif_drv->usr_conn_req.u8security;
1069        u32WidsCount++;
1070
1071        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1072                mode_11i = hif_drv->usr_conn_req.u8security;
1073
1074        PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", hif_drv->usr_conn_req.u8security);
1075
1076        strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
1077        strWIDList[u32WidsCount].type = WID_CHAR;
1078        strWIDList[u32WidsCount].size = sizeof(char);
1079        strWIDList[u32WidsCount].val = (s8 *)(&hif_drv->usr_conn_req.tenuAuth_type);
1080        u32WidsCount++;
1081
1082        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7))
1083                auth_type = (u8)hif_drv->usr_conn_req.tenuAuth_type;
1084
1085        PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", hif_drv->usr_conn_req.tenuAuth_type);
1086        PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n",
1087                hif_drv->usr_conn_req.pu8ssid, pstrHostIFconnectAttr->ch);
1088
1089        strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
1090        strWIDList[u32WidsCount].type = WID_STR;
1091        strWIDList[u32WidsCount].size = 112;
1092        strWIDList[u32WidsCount].val = kmalloc(strWIDList[u32WidsCount].size, GFP_KERNEL);
1093
1094        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1095                join_req_size = strWIDList[u32WidsCount].size;
1096                join_req = kmalloc(join_req_size, GFP_KERNEL);
1097        }
1098        if (!strWIDList[u32WidsCount].val) {
1099                result = -EFAULT;
1100                goto ERRORHANDLER;
1101        }
1102
1103        pu8CurrByte = strWIDList[u32WidsCount].val;
1104
1105        if (pstrHostIFconnectAttr->ssid) {
1106                memcpy(pu8CurrByte, pstrHostIFconnectAttr->ssid, pstrHostIFconnectAttr->ssid_len);
1107                pu8CurrByte[pstrHostIFconnectAttr->ssid_len] = '\0';
1108        }
1109        pu8CurrByte += MAX_SSID_LEN;
1110        *(pu8CurrByte++) = INFRASTRUCTURE;
1111
1112        if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) {
1113                *(pu8CurrByte++) = pstrHostIFconnectAttr->ch;
1114        } else {
1115                PRINT_ER("Channel out of range\n");
1116                *(pu8CurrByte++) = 0xFF;
1117        }
1118        *(pu8CurrByte++)  = (ptstrJoinBssParam->cap_info) & 0xFF;
1119        *(pu8CurrByte++)  = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
1120        PRINT_D(HOSTINF_DBG, "* Cap Info %0x*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8)));
1121
1122        if (pstrHostIFconnectAttr->bssid)
1123                memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1124        pu8CurrByte += 6;
1125
1126        if (pstrHostIFconnectAttr->bssid)
1127                memcpy(pu8CurrByte, pstrHostIFconnectAttr->bssid, 6);
1128        pu8CurrByte += 6;
1129
1130        *(pu8CurrByte++)  = (ptstrJoinBssParam->beacon_period) & 0xFF;
1131        *(pu8CurrByte++)  = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
1132        PRINT_D(HOSTINF_DBG, "* Beacon Period %d*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8)));
1133        *(pu8CurrByte++)  =  ptstrJoinBssParam->dtim_period;
1134        PRINT_D(HOSTINF_DBG, "* DTIM Period %d*\n", (*(pu8CurrByte - 1)));
1135
1136        memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
1137        pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1138
1139        *(pu8CurrByte++)  =  ptstrJoinBssParam->wmm_cap;
1140        PRINT_D(HOSTINF_DBG, "* wmm cap%d*\n", (*(pu8CurrByte - 1)));
1141        *(pu8CurrByte++)  = ptstrJoinBssParam->uapsd_cap;
1142
1143        *(pu8CurrByte++)  = ptstrJoinBssParam->ht_capable;
1144        hif_drv->usr_conn_req.IsHTCapable = ptstrJoinBssParam->ht_capable;
1145
1146        *(pu8CurrByte++)  =  ptstrJoinBssParam->rsn_found;
1147        PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1));
1148        *(pu8CurrByte++)  =  ptstrJoinBssParam->rsn_grp_policy;
1149        PRINT_D(HOSTINF_DBG, "* rsn group policy %0x*\n", (*(pu8CurrByte - 1)));
1150        *(pu8CurrByte++) =  ptstrJoinBssParam->mode_802_11i;
1151        PRINT_D(HOSTINF_DBG, "* mode_802_11i %d*\n", (*(pu8CurrByte - 1)));
1152
1153        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
1154        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1155
1156        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
1157        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1158
1159        memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
1160        pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1161
1162        *(pu8CurrByte++) = REAL_JOIN_REQ;
1163        *(pu8CurrByte++) = ptstrJoinBssParam->noa_enabled;
1164
1165        if (ptstrJoinBssParam->noa_enabled) {
1166                PRINT_D(HOSTINF_DBG, "NOA present\n");
1167
1168                *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1169                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1170                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1171                *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1172
1173                *(pu8CurrByte++) = ptstrJoinBssParam->opp_enabled;
1174                *(pu8CurrByte++) = ptstrJoinBssParam->idx;
1175
1176                if (ptstrJoinBssParam->opp_enabled)
1177                        *(pu8CurrByte++) = ptstrJoinBssParam->ct_window;
1178
1179                *(pu8CurrByte++) = ptstrJoinBssParam->cnt;
1180
1181                memcpy(pu8CurrByte, ptstrJoinBssParam->duration, sizeof(ptstrJoinBssParam->duration));
1182                pu8CurrByte += sizeof(ptstrJoinBssParam->duration);
1183
1184                memcpy(pu8CurrByte, ptstrJoinBssParam->interval, sizeof(ptstrJoinBssParam->interval));
1185                pu8CurrByte += sizeof(ptstrJoinBssParam->interval);
1186
1187                memcpy(pu8CurrByte, ptstrJoinBssParam->start_time, sizeof(ptstrJoinBssParam->start_time));
1188                pu8CurrByte += sizeof(ptstrJoinBssParam->start_time);
1189        } else
1190                PRINT_D(HOSTINF_DBG, "NOA not present\n");
1191
1192        pu8CurrByte = strWIDList[u32WidsCount].val;
1193        u32WidsCount++;
1194
1195        if (memcmp("DIRECT-", pstrHostIFconnectAttr->ssid, 7)) {
1196                memcpy(join_req, pu8CurrByte, join_req_size);
1197                join_req_drv = hif_drv;
1198        }
1199
1200        PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n");
1201
1202        if (pstrHostIFconnectAttr->bssid) {
1203                memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->bssid, ETH_ALEN);
1204
1205                PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->bssid);
1206                PRINT_D(GENERIC_DBG, "save bssid = %pM\n", u8ConnectedSSID);
1207        }
1208
1209        result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
1210                                 get_id_from_handler(hif_drv));
1211        if (result) {
1212                PRINT_ER("failed to send config packet\n");
1213                result = -EFAULT;
1214                goto ERRORHANDLER;
1215        } else {
1216                PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n");
1217                hif_drv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP;
1218        }
1219
1220ERRORHANDLER:
1221        if (result) {
1222                tstrConnectInfo strConnectInfo;
1223
1224                del_timer(&hif_drv->hConnectTimer);
1225
1226                PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n");
1227
1228                memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
1229
1230                if (pstrHostIFconnectAttr->result) {
1231                        if (pstrHostIFconnectAttr->bssid)
1232                                memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->bssid, 6);
1233
1234                        if (pstrHostIFconnectAttr->ies) {
1235                                strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->ies_len;
1236                                strConnectInfo.pu8ReqIEs = kmalloc(pstrHostIFconnectAttr->ies_len, GFP_KERNEL);
1237                                memcpy(strConnectInfo.pu8ReqIEs,
1238                                       pstrHostIFconnectAttr->ies,
1239                                       pstrHostIFconnectAttr->ies_len);
1240                        }
1241
1242                        pstrHostIFconnectAttr->result(CONN_DISCONN_EVENT_CONN_RESP,
1243                                                               &strConnectInfo,
1244                                                               MAC_DISCONNECTED,
1245                                                               NULL,
1246                                                               pstrHostIFconnectAttr->arg);
1247                        hif_drv->enuHostIFstate = HOST_IF_IDLE;
1248                        kfree(strConnectInfo.pu8ReqIEs);
1249                        strConnectInfo.pu8ReqIEs = NULL;
1250
1251                } else {
1252                        PRINT_ER("Connect callback function pointer is NULL\n");
1253                }
1254        }
1255
1256        PRINT_D(HOSTINF_DBG, "Deallocating connection parameters\n");
1257        kfree(pstrHostIFconnectAttr->bssid);
1258        pstrHostIFconnectAttr->bssid = NULL;
1259
1260        kfree(pstrHostIFconnectAttr->ssid);
1261        pstrHostIFconnectAttr->ssid = NULL;
1262
1263        kfree(pstrHostIFconnectAttr->ies);
1264        pstrHostIFconnectAttr->ies = NULL;
1265
1266        kfree(pu8CurrByte);
1267        return result;
1268}
1269
1270static s32 Handle_FlushConnect(struct host_if_drv *hif_drv)
1271{
1272        s32 result = 0;
1273        struct wid strWIDList[5];
1274        u32 u32WidsCount = 0;
1275        u8 *pu8CurrByte = NULL;
1276
1277        strWIDList[u32WidsCount].id = WID_INFO_ELEMENT_ASSOCIATE;
1278        strWIDList[u32WidsCount].type = WID_BIN_DATA;
1279        strWIDList[u32WidsCount].val = info_element;
1280        strWIDList[u32WidsCount].size = info_element_size;
1281        u32WidsCount++;
1282
1283        strWIDList[u32WidsCount].id = (u16)WID_11I_MODE;
1284        strWIDList[u32WidsCount].type = WID_CHAR;
1285        strWIDList[u32WidsCount].size = sizeof(char);
1286        strWIDList[u32WidsCount].val = (s8 *)(&(mode_11i));
1287        u32WidsCount++;
1288
1289        strWIDList[u32WidsCount].id = (u16)WID_AUTH_TYPE;
1290        strWIDList[u32WidsCount].type = WID_CHAR;
1291        strWIDList[u32WidsCount].size = sizeof(char);
1292        strWIDList[u32WidsCount].val = (s8 *)(&auth_type);
1293        u32WidsCount++;
1294
1295        strWIDList[u32WidsCount].id = (u16)WID_JOIN_REQ_EXTENDED;
1296        strWIDList[u32WidsCount].type = WID_STR;
1297        strWIDList[u32WidsCount].size = join_req_size;
1298        strWIDList[u32WidsCount].val = (s8 *)join_req;
1299        pu8CurrByte = strWIDList[u32WidsCount].val;
1300
1301        pu8CurrByte += FLUSHED_BYTE_POS;
1302        *(pu8CurrByte) = FLUSHED_JOIN_REQ;
1303
1304        u32WidsCount++;
1305
1306        result = send_config_pkt(SET_CFG, strWIDList, u32WidsCount,
1307                                 get_id_from_handler(join_req_drv));
1308        if (result) {
1309                PRINT_ER("failed to send config packet\n");
1310                result = -EINVAL;
1311        }
1312
1313        return result;
1314}
1315
1316static s32 Handle_ConnectTimeout(struct host_if_drv *hif_drv)
1317{
1318        s32 result = 0;
1319        tstrConnectInfo strConnectInfo;
1320        struct wid wid;
1321        u16 u16DummyReasonCode = 0;
1322
1323        if (!hif_drv) {
1324                PRINT_ER("Driver handler is NULL\n");
1325                return result;
1326        }
1327
1328        hif_drv->enuHostIFstate = HOST_IF_IDLE;
1329
1330        scan_while_connected = false;
1331
1332        memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
1333
1334        if (hif_drv->usr_conn_req.pfUserConnectResult) {
1335                if (hif_drv->usr_conn_req.pu8bssid) {
1336                        memcpy(strConnectInfo.au8bssid,
1337                               hif_drv->usr_conn_req.pu8bssid, 6);
1338                }
1339
1340                if (hif_drv->usr_conn_req.pu8ConnReqIEs) {
1341                        strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen;
1342                        strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL);
1343                        memcpy(strConnectInfo.pu8ReqIEs,
1344                               hif_drv->usr_conn_req.pu8ConnReqIEs,
1345                               hif_drv->usr_conn_req.ConnReqIEsLen);
1346                }
1347
1348                hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
1349                                                          &strConnectInfo,
1350                                                          MAC_DISCONNECTED,
1351                                                          NULL,
1352                                                          hif_drv->usr_conn_req.u32UserConnectPvoid);
1353
1354                kfree(strConnectInfo.pu8ReqIEs);
1355                strConnectInfo.pu8ReqIEs = NULL;
1356        } else {
1357                PRINT_ER("Connect callback function pointer is NULL\n");
1358        }
1359
1360        wid.id = (u16)WID_DISCONNECT;
1361        wid.type = WID_CHAR;
1362        wid.val = (s8 *)&u16DummyReasonCode;
1363        wid.size = sizeof(char);
1364
1365        PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
1366
1367        result = send_config_pkt(SET_CFG, &wid, 1,
1368                                 get_id_from_handler(hif_drv));
1369        if (result)
1370                PRINT_ER("Failed to send dissconect config packet\n");
1371
1372        hif_drv->usr_conn_req.ssidLen = 0;
1373        kfree(hif_drv->usr_conn_req.pu8ssid);
1374        kfree(hif_drv->usr_conn_req.pu8bssid);
1375        hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1376        kfree(hif_drv->usr_conn_req.pu8ConnReqIEs);
1377
1378        eth_zero_addr(u8ConnectedSSID);
1379
1380        if (join_req && join_req_drv == hif_drv) {
1381                kfree(join_req);
1382                join_req = NULL;
1383        }
1384
1385        if (info_element && join_req_drv == hif_drv) {
1386                kfree(info_element);
1387                info_element = NULL;
1388        }
1389
1390        return result;
1391}
1392
1393static s32 Handle_RcvdNtwrkInfo(struct host_if_drv *hif_drv,
1394                                struct rcvd_net_info *pstrRcvdNetworkInfo)
1395{
1396        u32 i;
1397        bool bNewNtwrkFound;
1398        s32 result = 0;
1399        tstrNetworkInfo *pstrNetworkInfo = NULL;
1400        void *pJoinParams = NULL;
1401
1402        bNewNtwrkFound = true;
1403        PRINT_INFO(HOSTINF_DBG, "Handling received network info\n");
1404
1405        if (hif_drv->usr_scan_req.pfUserScanResult) {
1406                PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n");
1407                parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo);
1408                if ((!pstrNetworkInfo) ||
1409                    (!hif_drv->usr_scan_req.pfUserScanResult)) {
1410                        PRINT_ER("driver is null\n");
1411                        result = -EINVAL;
1412                        goto done;
1413                }
1414
1415                for (i = 0; i < hif_drv->usr_scan_req.u32RcvdChCount; i++) {
1416                        if ((hif_drv->usr_scan_req.astrFoundNetworkInfo[i].au8bssid) &&
1417                            (pstrNetworkInfo->au8bssid)) {
1418                                if (memcmp(hif_drv->usr_scan_req.astrFoundNetworkInfo[i].au8bssid,
1419                                           pstrNetworkInfo->au8bssid, 6) == 0) {
1420                                        if (pstrNetworkInfo->s8rssi <= hif_drv->usr_scan_req.astrFoundNetworkInfo[i].s8rssi) {
1421                                                PRINT_D(HOSTINF_DBG, "Network previously discovered\n");
1422                                                goto done;
1423                                        } else {
1424                                                hif_drv->usr_scan_req.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi;
1425                                                bNewNtwrkFound = false;
1426                                                break;
1427                                        }
1428                                }
1429                        }
1430                }
1431
1432                if (bNewNtwrkFound) {
1433                        PRINT_D(HOSTINF_DBG, "New network found\n");
1434
1435                        if (hif_drv->usr_scan_req.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
1436                                hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi;
1437
1438                                if (hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid &&
1439                                    pstrNetworkInfo->au8bssid) {
1440                                        memcpy(hif_drv->usr_scan_req.astrFoundNetworkInfo[hif_drv->usr_scan_req.u32RcvdChCount].au8bssid,
1441                                               pstrNetworkInfo->au8bssid, 6);
1442
1443                                        hif_drv->usr_scan_req.u32RcvdChCount++;
1444
1445                                        pstrNetworkInfo->bNewNetwork = true;
1446                                        pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
1447
1448                                        hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1449                                                                               hif_drv->usr_scan_req.u32UserScanPvoid,
1450                                                                               pJoinParams);
1451                                }
1452                        } else {
1453                                PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit\n");
1454                        }
1455                } else {
1456                        pstrNetworkInfo->bNewNetwork = false;
1457                        hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
1458                                                               hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
1459                }
1460        }
1461
1462done:
1463        kfree(pstrRcvdNetworkInfo->buffer);
1464        pstrRcvdNetworkInfo->buffer = NULL;
1465
1466        if (pstrNetworkInfo) {
1467                DeallocateNetworkInfo(pstrNetworkInfo);
1468                pstrNetworkInfo = NULL;
1469        }
1470
1471        return result;
1472}
1473
1474static s32 Handle_RcvdGnrlAsyncInfo(struct host_if_drv *hif_drv,
1475                                    struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
1476{
1477        s32 result = 0;
1478        u8 u8MsgType = 0;
1479        u8 u8MsgID = 0;
1480        u16 u16MsgLen = 0;
1481        u16 u16WidID = (u16)WID_NIL;
1482        u8 u8WidLen  = 0;
1483        u8 u8MacStatus;
1484        u8 u8MacStatusReasonCode;
1485        u8 u8MacStatusAdditionalInfo;
1486        tstrConnectInfo strConnectInfo;
1487        tstrDisconnectNotifInfo strDisconnectNotifInfo;
1488        s32 s32Err = 0;
1489
1490        if (!hif_drv) {
1491                PRINT_ER("Driver handler is NULL\n");
1492                return -ENODEV;
1493        }
1494        PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", hif_drv->enuHostIFstate,
1495                pstrRcvdGnrlAsyncInfo->buffer[7]);
1496
1497        if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) ||
1498            (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) ||
1499            hif_drv->usr_scan_req.pfUserScanResult) {
1500                if (!pstrRcvdGnrlAsyncInfo->buffer ||
1501                    !hif_drv->usr_conn_req.pfUserConnectResult) {
1502                        PRINT_ER("driver is null\n");
1503                        return -EINVAL;
1504                }
1505
1506                u8MsgType = pstrRcvdGnrlAsyncInfo->buffer[0];
1507
1508                if ('I' != u8MsgType) {
1509                        PRINT_ER("Received Message format incorrect.\n");
1510                        return -EFAULT;
1511                }
1512
1513                u8MsgID = pstrRcvdGnrlAsyncInfo->buffer[1];
1514                u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[2], pstrRcvdGnrlAsyncInfo->buffer[3]);
1515                u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->buffer[4], pstrRcvdGnrlAsyncInfo->buffer[5]);
1516                u8WidLen = pstrRcvdGnrlAsyncInfo->buffer[6];
1517                u8MacStatus  = pstrRcvdGnrlAsyncInfo->buffer[7];
1518                u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->buffer[8];
1519                u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->buffer[9];
1520                PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
1521                if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
1522                        u32 u32RcvdAssocRespInfoLen;
1523                        tstrConnectRespInfo *pstrConnectRespInfo = NULL;
1524
1525                        PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
1526
1527                        memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
1528
1529                        if (u8MacStatus == MAC_CONNECTED) {
1530                                memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
1531
1532                                host_int_get_assoc_res_info(hif_drv,
1533                                                            rcv_assoc_resp,
1534                                                            MAX_ASSOC_RESP_FRAME_SIZE,
1535                                                            &u32RcvdAssocRespInfoLen);
1536
1537                                PRINT_INFO(HOSTINF_DBG, "Received association response with length = %d\n", u32RcvdAssocRespInfoLen);
1538
1539                                if (u32RcvdAssocRespInfoLen != 0) {
1540                                        PRINT_D(HOSTINF_DBG, "Parsing association response\n");
1541                                        s32Err = ParseAssocRespInfo(rcv_assoc_resp, u32RcvdAssocRespInfoLen,
1542                                                                    &pstrConnectRespInfo);
1543                                        if (s32Err) {
1544                                                PRINT_ER("ParseAssocRespInfo() returned error %d\n", s32Err);
1545                                        } else {
1546                                                strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus;
1547
1548                                                if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) {
1549                                                        PRINT_INFO(HOSTINF_DBG, "Association response received : Successful connection status\n");
1550                                                        if (pstrConnectRespInfo->pu8RespIEs) {
1551                                                                strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen;
1552                                                                strConnectInfo.pu8RespIEs = kmalloc(pstrConnectRespInfo->u16RespIEsLen, GFP_KERNEL);
1553                                                                memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs,
1554                                                                            pstrConnectRespInfo->u16RespIEsLen);
1555                                                        }
1556                                                }
1557
1558                                                if (pstrConnectRespInfo) {
1559                                                        DeallocateAssocRespInfo(pstrConnectRespInfo);
1560                                                        pstrConnectRespInfo = NULL;
1561                                                }
1562                                        }
1563                                }
1564                        }
1565
1566                        if ((u8MacStatus == MAC_CONNECTED) &&
1567                            (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) {
1568                                PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
1569                                eth_zero_addr(u8ConnectedSSID);
1570
1571                        } else if (u8MacStatus == MAC_DISCONNECTED)    {
1572                                PRINT_ER("Received MAC status is MAC_DISCONNECTED\n");
1573                                eth_zero_addr(u8ConnectedSSID);
1574                        }
1575
1576                        if (hif_drv->usr_conn_req.pu8bssid) {
1577                                PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n");
1578                                memcpy(strConnectInfo.au8bssid, hif_drv->usr_conn_req.pu8bssid, 6);
1579
1580                                if ((u8MacStatus == MAC_CONNECTED) &&
1581                                    (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
1582                                        memcpy(hif_drv->au8AssociatedBSSID,
1583                                               hif_drv->usr_conn_req.pu8bssid, ETH_ALEN);
1584                                }
1585                        }
1586
1587                        if (hif_drv->usr_conn_req.pu8ConnReqIEs) {
1588                                strConnectInfo.ReqIEsLen = hif_drv->usr_conn_req.ConnReqIEsLen;
1589                                strConnectInfo.pu8ReqIEs = kmalloc(hif_drv->usr_conn_req.ConnReqIEsLen, GFP_KERNEL);
1590                                memcpy(strConnectInfo.pu8ReqIEs,
1591                                       hif_drv->usr_conn_req.pu8ConnReqIEs,
1592                                       hif_drv->usr_conn_req.ConnReqIEsLen);
1593                        }
1594
1595                        del_timer(&hif_drv->hConnectTimer);
1596                        hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
1597                                                                  &strConnectInfo,
1598                                                                  u8MacStatus,
1599                                                                  NULL,
1600                                                                  hif_drv->usr_conn_req.u32UserConnectPvoid);
1601
1602                        if ((u8MacStatus == MAC_CONNECTED) &&
1603                            (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
1604                                host_int_set_power_mgmt(hif_drv, 0, 0);
1605
1606                                PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n");
1607                                hif_drv->enuHostIFstate = HOST_IF_CONNECTED;
1608
1609                                PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n");
1610                                g_obtainingIP = true;
1611                                mod_timer(&hDuringIpTimer,
1612                                          jiffies + msecs_to_jiffies(10000));
1613                        } else {
1614                                PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus);
1615                                hif_drv->enuHostIFstate = HOST_IF_IDLE;
1616                                scan_while_connected = false;
1617                        }
1618
1619                        kfree(strConnectInfo.pu8RespIEs);
1620                        strConnectInfo.pu8RespIEs = NULL;
1621
1622                        kfree(strConnectInfo.pu8ReqIEs);
1623                        strConnectInfo.pu8ReqIEs = NULL;
1624                        hif_drv->usr_conn_req.ssidLen = 0;
1625                        kfree(hif_drv->usr_conn_req.pu8ssid);
1626                        kfree(hif_drv->usr_conn_req.pu8bssid);
1627                        hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1628                        kfree(hif_drv->usr_conn_req.pu8ConnReqIEs);
1629                } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1630                           (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)) {
1631                        PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n");
1632
1633                        memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
1634
1635                        if (hif_drv->usr_scan_req.pfUserScanResult) {
1636                                PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n");
1637                                del_timer(&hif_drv->hScanTimer);
1638                                Handle_ScanDone((void *)hif_drv, SCAN_EVENT_ABORTED);
1639                        }
1640
1641                        strDisconnectNotifInfo.u16reason = 0;
1642                        strDisconnectNotifInfo.ie = NULL;
1643                        strDisconnectNotifInfo.ie_len = 0;
1644
1645                        if (hif_drv->usr_conn_req.pfUserConnectResult) {
1646                                g_obtainingIP = false;
1647                                host_int_set_power_mgmt(hif_drv, 0, 0);
1648
1649                                hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF,
1650                                                                          NULL,
1651                                                                          0,
1652                                                                          &strDisconnectNotifInfo,
1653                                                                          hif_drv->usr_conn_req.u32UserConnectPvoid);
1654                        } else {
1655                                PRINT_ER("Connect result callback function is NULL\n");
1656                        }
1657
1658                        eth_zero_addr(hif_drv->au8AssociatedBSSID);
1659
1660                        hif_drv->usr_conn_req.ssidLen = 0;
1661                        kfree(hif_drv->usr_conn_req.pu8ssid);
1662                        kfree(hif_drv->usr_conn_req.pu8bssid);
1663                        hif_drv->usr_conn_req.ConnReqIEsLen = 0;
1664                        kfree(hif_drv->usr_conn_req.pu8ConnReqIEs);
1665
1666                        if (join_req && join_req_drv == hif_drv) {
1667                                kfree(join_req);
1668                                join_req = NULL;
1669                        }
1670
1671                        if (info_element && join_req_drv == hif_drv) {
1672                                kfree(info_element);
1673                                info_element = NULL;
1674                        }
1675
1676                        hif_drv->enuHostIFstate = HOST_IF_IDLE;
1677                        scan_while_connected = false;
1678
1679                } else if ((u8MacStatus == MAC_DISCONNECTED) &&
1680                           (hif_drv->usr_scan_req.pfUserScanResult)) {
1681                        PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n");
1682                        PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n");
1683
1684                        del_timer(&hif_drv->hScanTimer);
1685                        if (hif_drv->usr_scan_req.pfUserScanResult)
1686                                Handle_ScanDone(hif_drv, SCAN_EVENT_ABORTED);
1687                }
1688        }
1689
1690        kfree(pstrRcvdGnrlAsyncInfo->buffer);
1691        pstrRcvdGnrlAsyncInfo->buffer = NULL;
1692
1693        return result;
1694}
1695
1696static int Handle_Key(struct host_if_drv *hif_drv,
1697                      struct key_attr *pstrHostIFkeyAttr)
1698{
1699        s32 result = 0;
1700        struct wid wid;
1701        struct wid strWIDList[5];
1702        u8 i;
1703        u8 *pu8keybuf;
1704        s8 s8idxarray[1];
1705        s8 ret = 0;
1706
1707        switch (pstrHostIFkeyAttr->type) {
1708        case WEP:
1709
1710                if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1711                        PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
1712                        PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", pstrHostIFkeyAttr->attr.wep.index);
1713                        strWIDList[0].id = (u16)WID_11I_MODE;
1714                        strWIDList[0].type = WID_CHAR;
1715                        strWIDList[0].size = sizeof(char);
1716                        strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.mode;
1717
1718                        strWIDList[1].id = WID_AUTH_TYPE;
1719                        strWIDList[1].type = WID_CHAR;
1720                        strWIDList[1].size = sizeof(char);
1721                        strWIDList[1].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.auth_type;
1722
1723                        strWIDList[2].id = (u16)WID_KEY_ID;
1724                        strWIDList[2].type = WID_CHAR;
1725
1726                        strWIDList[2].val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1727                        strWIDList[2].size = sizeof(char);
1728
1729                        pu8keybuf = kmemdup(pstrHostIFkeyAttr->attr.wep.key,
1730                                            pstrHostIFkeyAttr->attr.wep.key_len,
1731                                            GFP_KERNEL);
1732
1733                        if (pu8keybuf == NULL) {
1734                                PRINT_ER("No buffer to send Key\n");
1735                                return -ENOMEM;
1736                        }
1737
1738                        kfree(pstrHostIFkeyAttr->attr.wep.key);
1739
1740                        strWIDList[3].id = (u16)WID_WEP_KEY_VALUE;
1741                        strWIDList[3].type = WID_STR;
1742                        strWIDList[3].size = pstrHostIFkeyAttr->attr.wep.key_len;
1743                        strWIDList[3].val = (s8 *)pu8keybuf;
1744
1745                        result = send_config_pkt(SET_CFG, strWIDList, 4,
1746                                                 get_id_from_handler(hif_drv));
1747                        kfree(pu8keybuf);
1748                }
1749
1750                if (pstrHostIFkeyAttr->action & ADDKEY) {
1751                        PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
1752                        pu8keybuf = kmalloc(pstrHostIFkeyAttr->attr.wep.key_len + 2, GFP_KERNEL);
1753                        if (!pu8keybuf) {
1754                                PRINT_ER("No buffer to send Key\n");
1755                                return -ENOMEM;
1756                        }
1757                        pu8keybuf[0] = pstrHostIFkeyAttr->attr.wep.index;
1758                        memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->attr.wep.key_len, 1);
1759                        memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->attr.wep.key,
1760                               pstrHostIFkeyAttr->attr.wep.key_len);
1761                        kfree(pstrHostIFkeyAttr->attr.wep.key);
1762
1763                        wid.id = (u16)WID_ADD_WEP_KEY;
1764                        wid.type = WID_STR;
1765                        wid.val = (s8 *)pu8keybuf;
1766                        wid.size = pstrHostIFkeyAttr->attr.wep.key_len + 2;
1767
1768                        result = send_config_pkt(SET_CFG, &wid, 1,
1769                                                 get_id_from_handler(hif_drv));
1770                        kfree(pu8keybuf);
1771                } else if (pstrHostIFkeyAttr->action & REMOVEKEY) {
1772                        PRINT_D(HOSTINF_DBG, "Removing key\n");
1773                        wid.id = (u16)WID_REMOVE_WEP_KEY;
1774                        wid.type = WID_STR;
1775
1776                        s8idxarray[0] = (s8)pstrHostIFkeyAttr->attr.wep.index;
1777                        wid.val = s8idxarray;
1778                        wid.size = 1;
1779
1780                        result = send_config_pkt(SET_CFG, &wid, 1,
1781                                                 get_id_from_handler(hif_drv));
1782                } else {
1783                        wid.id = (u16)WID_KEY_ID;
1784                        wid.type = WID_CHAR;
1785                        wid.val = (s8 *)&pstrHostIFkeyAttr->attr.wep.index;
1786                        wid.size = sizeof(char);
1787
1788                        PRINT_D(HOSTINF_DBG, "Setting default key index\n");
1789
1790                        result = send_config_pkt(SET_CFG, &wid, 1,
1791                                                 get_id_from_handler(hif_drv));
1792                }
1793                up(&hif_drv->hSemTestKeyBlock);
1794                break;
1795
1796        case WPARxGtk:
1797                if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1798                        pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1799                        if (!pu8keybuf) {
1800                                PRINT_ER("No buffer to send RxGTK Key\n");
1801                                ret = -ENOMEM;
1802                                goto _WPARxGtk_end_case_;
1803                        }
1804
1805                        if (pstrHostIFkeyAttr->attr.wpa.seq)
1806                                memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1807
1808                        memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1809                        memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1810                        memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1811                               pstrHostIFkeyAttr->attr.wpa.key_len);
1812
1813                        strWIDList[0].id = (u16)WID_11I_MODE;
1814                        strWIDList[0].type = WID_CHAR;
1815                        strWIDList[0].size = sizeof(char);
1816                        strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1817
1818                        strWIDList[1].id = (u16)WID_ADD_RX_GTK;
1819                        strWIDList[1].type = WID_STR;
1820                        strWIDList[1].val = (s8 *)pu8keybuf;
1821                        strWIDList[1].size = RX_MIC_KEY_MSG_LEN;
1822
1823                        result = send_config_pkt(SET_CFG, strWIDList, 2,
1824                                                 get_id_from_handler(hif_drv));
1825
1826                        kfree(pu8keybuf);
1827                        up(&hif_drv->hSemTestKeyBlock);
1828                }
1829
1830                if (pstrHostIFkeyAttr->action & ADDKEY) {
1831                        PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n");
1832
1833                        pu8keybuf = kzalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
1834                        if (pu8keybuf == NULL) {
1835                                PRINT_ER("No buffer to send RxGTK Key\n");
1836                                ret = -ENOMEM;
1837                                goto _WPARxGtk_end_case_;
1838                        }
1839
1840                        if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED)
1841                                memcpy(pu8keybuf, hif_drv->au8AssociatedBSSID, ETH_ALEN);
1842                        else
1843                                PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED\n");
1844
1845                        memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->attr.wpa.seq, 8);
1846                        memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1847                        memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1848                        memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->attr.wpa.key,
1849                               pstrHostIFkeyAttr->attr.wpa.key_len);
1850
1851                        wid.id = (u16)WID_ADD_RX_GTK;
1852                        wid.type = WID_STR;
1853                        wid.val = (s8 *)pu8keybuf;
1854                        wid.size = RX_MIC_KEY_MSG_LEN;
1855
1856                        result = send_config_pkt(SET_CFG, &wid, 1,
1857                                                 get_id_from_handler(hif_drv));
1858
1859                        kfree(pu8keybuf);
1860                        up(&hif_drv->hSemTestKeyBlock);
1861                }
1862_WPARxGtk_end_case_:
1863                kfree(pstrHostIFkeyAttr->attr.wpa.key);
1864                kfree(pstrHostIFkeyAttr->attr.wpa.seq);
1865                if (ret)
1866                        return ret;
1867
1868                break;
1869
1870        case WPAPtk:
1871                if (pstrHostIFkeyAttr->action & ADDKEY_AP) {
1872                        pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
1873                        if (!pu8keybuf) {
1874                                PRINT_ER("No buffer to send PTK Key\n");
1875                                ret = -ENOMEM;
1876                                goto _WPAPtk_end_case_;
1877                        }
1878
1879                        memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1880                        memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.index, 1);
1881                        memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1882                        memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->attr.wpa.key,
1883                               pstrHostIFkeyAttr->attr.wpa.key_len);
1884
1885                        strWIDList[0].id = (u16)WID_11I_MODE;
1886                        strWIDList[0].type = WID_CHAR;
1887                        strWIDList[0].size = sizeof(char);
1888                        strWIDList[0].val = (s8 *)&pstrHostIFkeyAttr->attr.wpa.mode;
1889
1890                        strWIDList[1].id = (u16)WID_ADD_PTK;
1891                        strWIDList[1].type = WID_STR;
1892                        strWIDList[1].val = (s8 *)pu8keybuf;
1893                        strWIDList[1].size = PTK_KEY_MSG_LEN + 1;
1894
1895                        result = send_config_pkt(SET_CFG, strWIDList, 2,
1896                                                 get_id_from_handler(hif_drv));
1897                        kfree(pu8keybuf);
1898                        up(&hif_drv->hSemTestKeyBlock);
1899                }
1900                if (pstrHostIFkeyAttr->action & ADDKEY) {
1901                        pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
1902                        if (!pu8keybuf) {
1903                                PRINT_ER("No buffer to send PTK Key\n");
1904                                ret = -ENOMEM;
1905                                goto _WPAPtk_end_case_;
1906                        }
1907
1908                        memcpy(pu8keybuf, pstrHostIFkeyAttr->attr.wpa.mac_addr, 6);
1909                        memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->attr.wpa.key_len, 1);
1910                        memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->attr.wpa.key,
1911                               pstrHostIFkeyAttr->attr.wpa.key_len);
1912
1913                        wid.id = (u16)WID_ADD_PTK;
1914                        wid.type = WID_STR;
1915                        wid.val = (s8 *)pu8keybuf;
1916                        wid.size = PTK_KEY_MSG_LEN;
1917
1918                        result = send_config_pkt(SET_CFG, &wid, 1,
1919                                                 get_id_from_handler(hif_drv));
1920                        kfree(pu8keybuf);
1921                        up(&hif_drv->hSemTestKeyBlock);
1922                }
1923
1924_WPAPtk_end_case_:
1925                kfree(pstrHostIFkeyAttr->attr.wpa.key);
1926                if (ret)
1927                        return ret;
1928
1929                break;
1930
1931        case PMKSA:
1932
1933                PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n");
1934
1935                pu8keybuf = kmalloc((pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
1936                if (!pu8keybuf) {
1937                        PRINT_ER("No buffer to send PMKSA Key\n");
1938                        return -ENOMEM;
1939                }
1940
1941                pu8keybuf[0] = pstrHostIFkeyAttr->attr.pmkid.numpmkid;
1942
1943                for (i = 0; i < pstrHostIFkeyAttr->attr.pmkid.numpmkid; i++) {
1944                        memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
1945                        memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->attr.pmkid.pmkidlist[i].pmkid, PMKID_LEN);
1946                }
1947
1948                wid.id = (u16)WID_PMKID_INFO;
1949                wid.type = WID_STR;
1950                wid.val = (s8 *)pu8keybuf;
1951                wid.size = (pstrHostIFkeyAttr->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
1952
1953                result = send_config_pkt(SET_CFG, &wid, 1,
1954                                         get_id_from_handler(hif_drv));
1955
1956                kfree(pu8keybuf);
1957                break;
1958        }
1959
1960        if (result)
1961                PRINT_ER("Failed to send key config packet\n");
1962
1963        return result;
1964}
1965
1966static void Handle_Disconnect(struct host_if_drv *hif_drv)
1967{
1968        struct wid wid;
1969
1970        s32 result = 0;
1971        u16 u16DummyReasonCode = 0;
1972
1973        wid.id = (u16)WID_DISCONNECT;
1974        wid.type = WID_CHAR;
1975        wid.val = (s8 *)&u16DummyReasonCode;
1976        wid.size = sizeof(char);
1977
1978        PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
1979
1980        g_obtainingIP = false;
1981        host_int_set_power_mgmt(hif_drv, 0, 0);
1982
1983        eth_zero_addr(u8ConnectedSSID);
1984
1985        result = send_config_pkt(SET_CFG, &wid, 1,
1986                                 get_id_from_handler(hif_drv));
1987
1988        if (result) {
1989                PRINT_ER("Failed to send dissconect config packet\n");
1990        } else {
1991                tstrDisconnectNotifInfo strDisconnectNotifInfo;
1992
1993                memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
1994
1995                strDisconnectNotifInfo.u16reason = 0;
1996                strDisconnectNotifInfo.ie = NULL;
1997                strDisconnectNotifInfo.ie_len = 0;
1998
1999                if (hif_drv->usr_scan_req.pfUserScanResult) {
2000                        del_timer(&hif_drv->hScanTimer);
2001                        hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
2002                                                               hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
2003
2004                        hif_drv->usr_scan_req.pfUserScanResult = NULL;
2005                }
2006
2007                if (hif_drv->usr_conn_req.pfUserConnectResult) {
2008                        if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
2009                                PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n");
2010                                del_timer(&hif_drv->hConnectTimer);
2011                        }
2012
2013                        hif_drv->usr_conn_req.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
2014                                                                  0, &strDisconnectNotifInfo, hif_drv->usr_conn_req.u32UserConnectPvoid);
2015                } else {
2016                        PRINT_ER("usr_conn_req.pfUserConnectResult = NULL\n");
2017                }
2018
2019                scan_while_connected = false;
2020
2021                hif_drv->enuHostIFstate = HOST_IF_IDLE;
2022
2023                eth_zero_addr(hif_drv->au8AssociatedBSSID);
2024
2025                hif_drv->usr_conn_req.ssidLen = 0;
2026                kfree(hif_drv->usr_conn_req.pu8ssid);
2027                kfree(hif_drv->usr_conn_req.pu8bssid);
2028                hif_drv->usr_conn_req.ConnReqIEsLen = 0;
2029                kfree(hif_drv->usr_conn_req.pu8ConnReqIEs);
2030
2031                if (join_req && join_req_drv == hif_drv) {
2032                        kfree(join_req);
2033                        join_req = NULL;
2034                }
2035
2036                if (info_element && join_req_drv == hif_drv) {
2037                        kfree(info_element);
2038                        info_element = NULL;
2039                }
2040        }
2041
2042        up(&hif_drv->hSemTestDisconnectBlock);
2043}
2044
2045void resolve_disconnect_aberration(struct host_if_drv *hif_drv)
2046{
2047        if (!hif_drv)
2048                return;
2049        if ((hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (hif_drv->enuHostIFstate == HOST_IF_CONNECTING)) {
2050                PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n");
2051                host_int_disconnect(hif_drv, 1);
2052        }
2053}
2054
2055static s32 Handle_GetChnl(struct host_if_drv *hif_drv)
2056{
2057        s32 result = 0;
2058        struct wid wid;
2059
2060        wid.id = (u16)WID_CURRENT_CHANNEL;
2061        wid.type = WID_CHAR;
2062        wid.val = (s8 *)&ch_no;
2063        wid.size = sizeof(char);
2064
2065        PRINT_D(HOSTINF_DBG, "Getting channel value\n");
2066
2067        result = send_config_pkt(GET_CFG, &wid, 1,
2068                                 get_id_from_handler(hif_drv));
2069
2070        if (result) {
2071                PRINT_ER("Failed to get channel number\n");
2072                result = -EFAULT;
2073        }
2074
2075        up(&hif_drv->hSemGetCHNL);
2076
2077        return result;
2078}
2079
2080static void Handle_GetRssi(struct host_if_drv *hif_drv)
2081{
2082        s32 result = 0;
2083        struct wid wid;
2084
2085        wid.id = (u16)WID_RSSI;
2086        wid.type = WID_CHAR;
2087        wid.val = &rssi;
2088        wid.size = sizeof(char);
2089
2090        PRINT_D(HOSTINF_DBG, "Getting RSSI value\n");
2091
2092        result = send_config_pkt(GET_CFG, &wid, 1,
2093                                 get_id_from_handler(hif_drv));
2094        if (result) {
2095                PRINT_ER("Failed to get RSSI value\n");
2096                result = -EFAULT;
2097        }
2098
2099        up(&hif_drv->hSemGetRSSI);
2100}
2101
2102static void Handle_GetLinkspeed(struct host_if_drv *hif_drv)
2103{
2104        s32 result = 0;
2105        struct wid wid;
2106
2107        link_speed = 0;
2108
2109        wid.id = (u16)WID_LINKSPEED;
2110        wid.type = WID_CHAR;
2111        wid.val = &link_speed;
2112        wid.size = sizeof(char);
2113
2114        PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n");
2115
2116        result = send_config_pkt(GET_CFG, &wid, 1,
2117                                 get_id_from_handler(hif_drv));
2118        if (result) {
2119                PRINT_ER("Failed to get LINKSPEED value\n");
2120                result = -EFAULT;
2121        }
2122
2123        up(&hif_drv->hSemGetLINKSPEED);
2124}
2125
2126s32 Handle_GetStatistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
2127{
2128        struct wid strWIDList[5];
2129        u32 u32WidsCount = 0, result = 0;
2130
2131        strWIDList[u32WidsCount].id = WID_LINKSPEED;
2132        strWIDList[u32WidsCount].type = WID_CHAR;
2133        strWIDList[u32WidsCount].size = sizeof(char);
2134        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u8LinkSpeed;
2135        u32WidsCount++;
2136
2137        strWIDList[u32WidsCount].id = WID_RSSI;
2138        strWIDList[u32WidsCount].type = WID_CHAR;
2139        strWIDList[u32WidsCount].size = sizeof(char);
2140        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->s8RSSI;
2141        u32WidsCount++;
2142
2143        strWIDList[u32WidsCount].id = WID_SUCCESS_FRAME_COUNT;
2144        strWIDList[u32WidsCount].type = WID_INT;
2145        strWIDList[u32WidsCount].size = sizeof(u32);
2146        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxCount;
2147        u32WidsCount++;
2148
2149        strWIDList[u32WidsCount].id = WID_RECEIVED_FRAGMENT_COUNT;
2150        strWIDList[u32WidsCount].type = WID_INT;
2151        strWIDList[u32WidsCount].size = sizeof(u32);
2152        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32RxCount;
2153        u32WidsCount++;
2154
2155        strWIDList[u32WidsCount].id = WID_FAILED_COUNT;
2156        strWIDList[u32WidsCount].type = WID_INT;
2157        strWIDList[u32WidsCount].size = sizeof(u32);
2158        strWIDList[u32WidsCount].val = (s8 *)&pstrStatistics->u32TxFailureCount;
2159        u32WidsCount++;
2160
2161        result = send_config_pkt(GET_CFG, strWIDList, u32WidsCount,
2162                                 get_id_from_handler(hif_drv));
2163
2164        if (result)
2165                PRINT_ER("Failed to send scan paramters config packet\n");
2166
2167        up(&hif_sema_wait_response);
2168        return 0;
2169}
2170
2171static s32 Handle_Get_InActiveTime(struct host_if_drv *hif_drv,
2172                                   struct sta_inactive_t *strHostIfStaInactiveT)
2173{
2174        s32 result = 0;
2175        u8 *stamac;
2176        struct wid wid;
2177
2178        wid.id = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
2179        wid.type = WID_STR;
2180        wid.size = ETH_ALEN;
2181        wid.val = kmalloc(wid.size, GFP_KERNEL);
2182
2183        stamac = wid.val;
2184        memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
2185
2186        PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
2187
2188        result = send_config_pkt(SET_CFG, &wid, 1,
2189                                 get_id_from_handler(hif_drv));
2190
2191        if (result) {
2192                PRINT_ER("Failed to SET incative time\n");
2193                return -EFAULT;
2194        }
2195
2196        wid.id = (u16)WID_GET_INACTIVE_TIME;
2197        wid.type = WID_INT;
2198        wid.val = (s8 *)&inactive_time;
2199        wid.size = sizeof(u32);
2200
2201        result = send_config_pkt(GET_CFG, &wid, 1,
2202                                 get_id_from_handler(hif_drv));
2203
2204        if (result) {
2205                PRINT_ER("Failed to get incative time\n");
2206                return -EFAULT;
2207        }
2208
2209        PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", inactive_time);
2210
2211        up(&hif_drv->hSemInactiveTime);
2212
2213        return result;
2214}
2215
2216static void Handle_AddBeacon(struct host_if_drv *hif_drv,
2217                             struct beacon_attr *pstrSetBeaconParam)
2218{
2219        s32 result = 0;
2220        struct wid wid;
2221        u8 *pu8CurrByte;
2222
2223        PRINT_D(HOSTINF_DBG, "Adding BEACON\n");
2224
2225        wid.id = (u16)WID_ADD_BEACON;
2226        wid.type = WID_BIN;
2227        wid.size = pstrSetBeaconParam->head_len + pstrSetBeaconParam->tail_len + 16;
2228        wid.val = kmalloc(wid.size, GFP_KERNEL);
2229        if (!wid.val)
2230                goto ERRORHANDLER;
2231
2232        pu8CurrByte = wid.val;
2233        *pu8CurrByte++ = (pstrSetBeaconParam->interval & 0xFF);
2234        *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 8) & 0xFF);
2235        *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 16) & 0xFF);
2236        *pu8CurrByte++ = ((pstrSetBeaconParam->interval >> 24) & 0xFF);
2237
2238        *pu8CurrByte++ = (pstrSetBeaconParam->dtim_period & 0xFF);
2239        *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 8) & 0xFF);
2240        *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 16) & 0xFF);
2241        *pu8CurrByte++ = ((pstrSetBeaconParam->dtim_period >> 24) & 0xFF);
2242
2243        *pu8CurrByte++ = (pstrSetBeaconParam->head_len & 0xFF);
2244        *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 8) & 0xFF);
2245        *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 16) & 0xFF);
2246        *pu8CurrByte++ = ((pstrSetBeaconParam->head_len >> 24) & 0xFF);
2247
2248        memcpy(pu8CurrByte, pstrSetBeaconParam->head, pstrSetBeaconParam->head_len);
2249        pu8CurrByte += pstrSetBeaconParam->head_len;
2250
2251        *pu8CurrByte++ = (pstrSetBeaconParam->tail_len & 0xFF);
2252        *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 8) & 0xFF);
2253        *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 16) & 0xFF);
2254        *pu8CurrByte++ = ((pstrSetBeaconParam->tail_len >> 24) & 0xFF);
2255
2256        if (pstrSetBeaconParam->tail > 0)
2257                memcpy(pu8CurrByte, pstrSetBeaconParam->tail, pstrSetBeaconParam->tail_len);
2258        pu8CurrByte += pstrSetBeaconParam->tail_len;
2259
2260        result = send_config_pkt(SET_CFG, &wid, 1,
2261                                 get_id_from_handler(hif_drv));
2262        if (result)
2263                PRINT_ER("Failed to send add beacon config packet\n");
2264
2265ERRORHANDLER:
2266        kfree(wid.val);
2267        kfree(pstrSetBeaconParam->head);
2268        kfree(pstrSetBeaconParam->tail);
2269}
2270
2271static void Handle_DelBeacon(struct host_if_drv *hif_drv)
2272{
2273        s32 result = 0;
2274        struct wid wid;
2275        u8 *pu8CurrByte;
2276
2277        wid.id = (u16)WID_DEL_BEACON;
2278        wid.type = WID_CHAR;
2279        wid.size = sizeof(char);
2280        wid.val = &del_beacon;
2281
2282        if (!wid.val)
2283                return;
2284
2285        pu8CurrByte = wid.val;
2286
2287        PRINT_D(HOSTINF_DBG, "Deleting BEACON\n");
2288
2289        result = send_config_pkt(SET_CFG, &wid, 1,
2290                                 get_id_from_handler(hif_drv));
2291        if (result)
2292                PRINT_ER("Failed to send delete beacon config packet\n");
2293}
2294
2295static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
2296                                    struct add_sta_param *pstrStationParam)
2297{
2298        u8 *pu8CurrByte;
2299
2300        pu8CurrByte = pu8Buffer;
2301
2302        PRINT_D(HOSTINF_DBG, "Packing STA params\n");
2303        memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN);
2304        pu8CurrByte +=  ETH_ALEN;
2305
2306        *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF;
2307        *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF;
2308
2309        *pu8CurrByte++ = pstrStationParam->u8NumRates;
2310        if (pstrStationParam->u8NumRates > 0)
2311                memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates);
2312        pu8CurrByte += pstrStationParam->u8NumRates;
2313
2314        *pu8CurrByte++ = pstrStationParam->bIsHTSupported;
2315        *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF;
2316        *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF;
2317
2318        *pu8CurrByte++ = pstrStationParam->u8AmpduParams;
2319        memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE);
2320        pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
2321
2322        *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF;
2323        *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF;
2324
2325        *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF;
2326        *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF;
2327        *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF;
2328        *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF;
2329
2330        *pu8CurrByte++ = pstrStationParam->u8ASELCap;
2331
2332        *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF;
2333        *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF;
2334
2335        *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF;
2336        *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF;
2337
2338        return pu8CurrByte - pu8Buffer;
2339}
2340
2341static void Handle_AddStation(struct host_if_drv *hif_drv,
2342                              struct add_sta_param *pstrStationParam)
2343{
2344        s32 result = 0;
2345        struct wid wid;
2346        u8 *pu8CurrByte;
2347
2348        PRINT_D(HOSTINF_DBG, "Handling add station\n");
2349        wid.id = (u16)WID_ADD_STA;
2350        wid.type = WID_BIN;
2351        wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
2352
2353        wid.val = kmalloc(wid.size, GFP_KERNEL);
2354        if (!wid.val)
2355                goto ERRORHANDLER;
2356
2357        pu8CurrByte = wid.val;
2358        pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2359
2360        result = send_config_pkt(SET_CFG, &wid, 1,
2361                                 get_id_from_handler(hif_drv));
2362        if (result != 0)
2363                PRINT_ER("Failed to send add station config packet\n");
2364
2365ERRORHANDLER:
2366        kfree(pstrStationParam->pu8Rates);
2367        kfree(wid.val);
2368}
2369
2370static void Handle_DelAllSta(struct host_if_drv *hif_drv,
2371                             struct del_all_sta *pstrDelAllStaParam)
2372{
2373        s32 result = 0;
2374        struct wid wid;
2375        u8 *pu8CurrByte;
2376        u8 i;
2377        u8 au8Zero_Buff[6] = {0};
2378
2379        wid.id = (u16)WID_DEL_ALL_STA;
2380        wid.type = WID_STR;
2381        wid.size = (pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1;
2382
2383        PRINT_D(HOSTINF_DBG, "Handling delete station\n");
2384
2385        wid.val = kmalloc((pstrDelAllStaParam->assoc_sta * ETH_ALEN) + 1, GFP_KERNEL);
2386        if (!wid.val)
2387                goto ERRORHANDLER;
2388
2389        pu8CurrByte = wid.val;
2390
2391        *(pu8CurrByte++) = pstrDelAllStaParam->assoc_sta;
2392
2393        for (i = 0; i < MAX_NUM_STA; i++) {
2394                if (memcmp(pstrDelAllStaParam->del_all_sta[i], au8Zero_Buff, ETH_ALEN))
2395                        memcpy(pu8CurrByte, pstrDelAllStaParam->del_all_sta[i], ETH_ALEN);
2396                else
2397                        continue;
2398
2399                pu8CurrByte += ETH_ALEN;
2400        }
2401
2402        result = send_config_pkt(SET_CFG, &wid, 1,
2403                                 get_id_from_handler(hif_drv));
2404        if (result)
2405                PRINT_ER("Failed to send add station config packet\n");
2406
2407ERRORHANDLER:
2408        kfree(wid.val);
2409
2410        up(&hif_sema_wait_response);
2411}
2412
2413static void Handle_DelStation(struct host_if_drv *hif_drv,
2414                              struct del_sta *pstrDelStaParam)
2415{
2416        s32 result = 0;
2417        struct wid wid;
2418        u8 *pu8CurrByte;
2419
2420        wid.id = (u16)WID_REMOVE_STA;
2421        wid.type = WID_BIN;
2422        wid.size = ETH_ALEN;
2423
2424        PRINT_D(HOSTINF_DBG, "Handling delete station\n");
2425
2426        wid.val = kmalloc(wid.size, GFP_KERNEL);
2427        if (!wid.val)
2428                goto ERRORHANDLER;
2429
2430        pu8CurrByte = wid.val;
2431
2432        memcpy(pu8CurrByte, pstrDelStaParam->mac_addr, ETH_ALEN);
2433
2434        result = send_config_pkt(SET_CFG, &wid, 1,
2435                                 get_id_from_handler(hif_drv));
2436        if (result)
2437                PRINT_ER("Failed to send add station config packet\n");
2438
2439ERRORHANDLER:
2440        kfree(wid.val);
2441}
2442
2443static void Handle_EditStation(struct host_if_drv *hif_drv,
2444                               struct add_sta_param *pstrStationParam)
2445{
2446        s32 result = 0;
2447        struct wid wid;
2448        u8 *pu8CurrByte;
2449
2450        wid.id = (u16)WID_EDIT_STA;
2451        wid.type = WID_BIN;
2452        wid.size = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
2453
2454        PRINT_D(HOSTINF_DBG, "Handling edit station\n");
2455        wid.val = kmalloc(wid.size, GFP_KERNEL);
2456        if (!wid.val)
2457                goto ERRORHANDLER;
2458
2459        pu8CurrByte = wid.val;
2460        pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
2461
2462        result = send_config_pkt(SET_CFG, &wid, 1,
2463                                 get_id_from_handler(hif_drv));
2464        if (result)
2465                PRINT_ER("Failed to send edit station config packet\n");
2466
2467ERRORHANDLER:
2468        kfree(pstrStationParam->pu8Rates);
2469        kfree(wid.val);
2470}
2471
2472static int Handle_RemainOnChan(struct host_if_drv *hif_drv,
2473                               struct remain_ch *pstrHostIfRemainOnChan)
2474{
2475        s32 result = 0;
2476        u8 u8remain_on_chan_flag;
2477        struct wid wid;
2478
2479        if (!hif_drv->remain_on_ch_pending) {
2480                hif_drv->remain_on_ch.pVoid = pstrHostIfRemainOnChan->pVoid;
2481                hif_drv->remain_on_ch.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired;
2482                hif_drv->remain_on_ch.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady;
2483                hif_drv->remain_on_ch.u16Channel = pstrHostIfRemainOnChan->u16Channel;
2484                hif_drv->remain_on_ch.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID;
2485        } else {
2486                pstrHostIfRemainOnChan->u16Channel = hif_drv->remain_on_ch.u16Channel;
2487        }
2488
2489        if (hif_drv->usr_scan_req.pfUserScanResult) {
2490                PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n");
2491                hif_drv->remain_on_ch_pending = 1;
2492                result = -EBUSY;
2493                goto ERRORHANDLER;
2494        }
2495        if (hif_drv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
2496                PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n");
2497                result = -EBUSY;
2498                goto ERRORHANDLER;
2499        }
2500
2501        if (g_obtainingIP || connecting) {
2502                PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
2503                result = -EBUSY;
2504                goto ERRORHANDLER;
2505        }
2506
2507        PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel);
2508
2509        u8remain_on_chan_flag = true;
2510        wid.id = (u16)WID_REMAIN_ON_CHAN;
2511        wid.type = WID_STR;
2512        wid.size = 2;
2513        wid.val = kmalloc(wid.size, GFP_KERNEL);
2514        if (!wid.val) {
2515                result = -ENOMEM;
2516                goto ERRORHANDLER;
2517        }
2518
2519        wid.val[0] = u8remain_on_chan_flag;
2520        wid.val[1] = (s8)pstrHostIfRemainOnChan->u16Channel;
2521
2522        result = send_config_pkt(SET_CFG, &wid, 1,
2523                                 get_id_from_handler(hif_drv));
2524        if (result != 0)
2525                PRINT_ER("Failed to set remain on channel\n");
2526
2527ERRORHANDLER:
2528        {
2529                P2P_LISTEN_STATE = 1;
2530                hif_drv->hRemainOnChannel.data = (unsigned long)hif_drv;
2531                mod_timer(&hif_drv->hRemainOnChannel,
2532                          jiffies +
2533                          msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration));
2534
2535                if (hif_drv->remain_on_ch.pRemainOnChanReady)
2536                        hif_drv->remain_on_ch.pRemainOnChanReady(hif_drv->remain_on_ch.pVoid);
2537
2538                if (hif_drv->remain_on_ch_pending)
2539                        hif_drv->remain_on_ch_pending = 0;
2540        }
2541
2542        return result;
2543}
2544
2545static int Handle_RegisterFrame(struct host_if_drv *hif_drv,
2546                                struct reg_frame *pstrHostIfRegisterFrame)
2547{
2548        s32 result = 0;
2549        struct wid wid;
2550        u8 *pu8CurrByte;
2551
2552        PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType);
2553
2554        wid.id = (u16)WID_REGISTER_FRAME;
2555        wid.type = WID_STR;
2556        wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
2557        if (!wid.val)
2558                return -ENOMEM;
2559
2560        pu8CurrByte = wid.val;
2561
2562        *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg;
2563        *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid;
2564        memcpy(pu8CurrByte, &pstrHostIfRegisterFrame->u16FrameType,
2565               sizeof(u16));
2566
2567        wid.size = sizeof(u16) + 2;
2568
2569        result = send_config_pkt(SET_CFG, &wid, 1,
2570                                 get_id_from_handler(hif_drv));
2571        if (result) {
2572                PRINT_ER("Failed to frame register config packet\n");
2573                result = -EINVAL;
2574        }
2575
2576        return result;
2577}
2578
2579static u32 Handle_ListenStateExpired(struct host_if_drv *hif_drv,
2580                                     struct remain_ch *pstrHostIfRemainOnChan)
2581{
2582        u8 u8remain_on_chan_flag;
2583        struct wid wid;
2584        s32 result = 0;
2585
2586        PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n");
2587
2588        if (P2P_LISTEN_STATE) {
2589                u8remain_on_chan_flag = false;
2590                wid.id = (u16)WID_REMAIN_ON_CHAN;
2591                wid.type = WID_STR;
2592                wid.size = 2;
2593                wid.val = kmalloc(wid.size, GFP_KERNEL);
2594
2595                if (!wid.val)
2596                        PRINT_ER("Failed to allocate memory\n");
2597
2598                wid.val[0] = u8remain_on_chan_flag;
2599                wid.val[1] = FALSE_FRMWR_CHANNEL;
2600
2601                result = send_config_pkt(SET_CFG, &wid, 1,
2602                                         get_id_from_handler(hif_drv));
2603                if (result != 0) {
2604                        PRINT_ER("Failed to set remain on channel\n");
2605                        goto _done_;
2606                }
2607
2608                if (hif_drv->remain_on_ch.pRemainOnChanExpired) {
2609                        hif_drv->remain_on_ch.pRemainOnChanExpired(hif_drv->remain_on_ch.pVoid,
2610                                                                   pstrHostIfRemainOnChan->u32ListenSessionID);
2611                }
2612                P2P_LISTEN_STATE = 0;
2613        } else {
2614                PRINT_D(GENERIC_DBG, "Not in listen state\n");
2615                result = -EFAULT;
2616        }
2617
2618_done_:
2619        return result;
2620}
2621
2622static void ListenTimerCB(unsigned long arg)
2623{
2624        s32 result = 0;
2625        struct host_if_msg msg;
2626        struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
2627
2628        del_timer(&hif_drv->hRemainOnChannel);
2629
2630        memset(&msg, 0, sizeof(struct host_if_msg));
2631        msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
2632        msg.drv = hif_drv;
2633        msg.body.remain_on_ch.u32ListenSessionID = hif_drv->remain_on_ch.u32ListenSessionID;
2634
2635        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2636        if (result)
2637                PRINT_ER("wilc_mq_send fail\n");
2638}
2639
2640static void Handle_PowerManagement(struct host_if_drv *hif_drv,
2641                                   struct power_mgmt_param *strPowerMgmtParam)
2642{
2643        s32 result = 0;
2644        struct wid wid;
2645        s8 s8PowerMode;
2646
2647        wid.id = (u16)WID_POWER_MANAGEMENT;
2648
2649        if (strPowerMgmtParam->enabled)
2650                s8PowerMode = MIN_FAST_PS;
2651        else
2652                s8PowerMode = NO_POWERSAVE;
2653        PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode);
2654        wid.val = &s8PowerMode;
2655        wid.size = sizeof(char);
2656
2657        PRINT_D(HOSTINF_DBG, "Handling Power Management\n");
2658
2659        result = send_config_pkt(SET_CFG, &wid, 1,
2660                                 get_id_from_handler(hif_drv));
2661        if (result)
2662                PRINT_ER("Failed to send power management config packet\n");
2663}
2664
2665static void Handle_SetMulticastFilter(struct host_if_drv *hif_drv,
2666                                      struct set_multicast *strHostIfSetMulti)
2667{
2668        s32 result = 0;
2669        struct wid wid;
2670        u8 *pu8CurrByte;
2671
2672        PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n");
2673
2674        wid.id = (u16)WID_SETUP_MULTICAST_FILTER;
2675        wid.type = WID_BIN;
2676        wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN);
2677        wid.val = kmalloc(wid.size, GFP_KERNEL);
2678        if (!wid.val)
2679                goto ERRORHANDLER;
2680
2681        pu8CurrByte = wid.val;
2682        *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
2683        *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
2684        *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
2685        *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
2686
2687        *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
2688        *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
2689        *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 16) & 0xFF);
2690        *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 24) & 0xFF);
2691
2692        if ((strHostIfSetMulti->cnt) > 0)
2693                memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->cnt) * ETH_ALEN));
2694
2695        result = send_config_pkt(SET_CFG, &wid, 1,
2696                                 get_id_from_handler(hif_drv));
2697        if (result)
2698                PRINT_ER("Failed to send setup multicast config packet\n");
2699
2700ERRORHANDLER:
2701        kfree(wid.val);
2702}
2703
2704static s32 Handle_AddBASession(struct host_if_drv *hif_drv,
2705                               struct ba_session_info *strHostIfBASessionInfo)
2706{
2707        s32 result = 0;
2708        struct wid wid;
2709        int AddbaTimeout = 100;
2710        char *ptr = NULL;
2711
2712        PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n",
2713                strHostIfBASessionInfo->au8Bssid[0],
2714                strHostIfBASessionInfo->au8Bssid[1],
2715                strHostIfBASessionInfo->au8Bssid[2],
2716                strHostIfBASessionInfo->u16BufferSize,
2717                strHostIfBASessionInfo->u16SessionTimeout,
2718                strHostIfBASessionInfo->u8Ted);
2719
2720        wid.id = (u16)WID_11E_P_ACTION_REQ;
2721        wid.type = WID_STR;
2722        wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2723        wid.size = BLOCK_ACK_REQ_SIZE;
2724        ptr = wid.val;
2725        *ptr++ = 0x14;
2726        *ptr++ = 0x3;
2727        *ptr++ = 0x0;
2728        memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
2729        ptr += ETH_ALEN;
2730        *ptr++ = strHostIfBASessionInfo->u8Ted;
2731        *ptr++ = 1;
2732        *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2733        *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF);
2734        *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF);
2735        *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
2736        *ptr++ = (AddbaTimeout & 0xFF);
2737        *ptr++ = ((AddbaTimeout >> 16) & 0xFF);
2738        *ptr++ = 8;
2739        *ptr++ = 0;
2740
2741        result = send_config_pkt(SET_CFG, &wid, 1,
2742                                 get_id_from_handler(hif_drv));
2743        if (result)
2744                PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
2745
2746        wid.id = (u16)WID_11E_P_ACTION_REQ;
2747        wid.type = WID_STR;
2748        wid.size = 15;
2749        ptr = wid.val;
2750        *ptr++ = 15;
2751        *ptr++ = 7;
2752        *ptr++ = 0x2;
2753        memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
2754        ptr += ETH_ALEN;
2755        *ptr++ = strHostIfBASessionInfo->u8Ted;
2756        *ptr++ = 8;
2757        *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
2758        *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
2759        *ptr++ = 3;
2760        result = send_config_pkt(SET_CFG, &wid, 1,
2761                                 get_id_from_handler(hif_drv));
2762
2763        kfree(wid.val);
2764
2765        return result;
2766}
2767
2768static s32 Handle_DelAllRxBASessions(struct host_if_drv *hif_drv,
2769                                     struct ba_session_info *strHostIfBASessionInfo)
2770{
2771        s32 result = 0;
2772        struct wid wid;
2773        char *ptr = NULL;
2774
2775        PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n",
2776                strHostIfBASessionInfo->au8Bssid[0],
2777                strHostIfBASessionInfo->au8Bssid[1],
2778                strHostIfBASessionInfo->au8Bssid[2],
2779                strHostIfBASessionInfo->u8Ted);
2780
2781        wid.id = (u16)WID_DEL_ALL_RX_BA;
2782        wid.type = WID_STR;
2783        wid.val = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
2784        wid.size = BLOCK_ACK_REQ_SIZE;
2785        ptr = wid.val;
2786        *ptr++ = 0x14;
2787        *ptr++ = 0x3;
2788        *ptr++ = 0x2;
2789        memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
2790        ptr += ETH_ALEN;
2791        *ptr++ = strHostIfBASessionInfo->u8Ted;
2792        *ptr++ = 0;
2793        *ptr++ = 32;
2794
2795        result = send_config_pkt(SET_CFG, &wid, 1,
2796                                 get_id_from_handler(hif_drv));
2797        if (result)
2798                PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
2799
2800        kfree(wid.val);
2801
2802        up(&hif_sema_wait_response);
2803
2804        return result;
2805}
2806
2807static int hostIFthread(void *pvArg)
2808{
2809        u32 u32Ret;
2810        struct host_if_msg msg;
2811        struct host_if_drv *hif_drv;
2812
2813        memset(&msg, 0, sizeof(struct host_if_msg));
2814
2815        while (1) {
2816                wilc_mq_recv(&hif_msg_q, &msg, sizeof(struct host_if_msg), &u32Ret);
2817                hif_drv = (struct host_if_drv *)msg.drv;
2818                if (msg.id == HOST_IF_MSG_EXIT) {
2819                        PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n");
2820                        break;
2821                }
2822
2823                if ((!g_wilc_initialized)) {
2824                        PRINT_D(GENERIC_DBG, "--WAIT--");
2825                        usleep_range(200 * 1000, 200 * 1000);
2826                        wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2827                        continue;
2828                }
2829
2830                if (msg.id == HOST_IF_MSG_CONNECT &&
2831                    hif_drv->usr_scan_req.pfUserScanResult) {
2832                        PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n");
2833                        wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
2834                        usleep_range(2 * 1000, 2 * 1000);
2835                        continue;
2836                }
2837
2838                switch (msg.id) {
2839                case HOST_IF_MSG_Q_IDLE:
2840                        Handle_wait_msg_q_empty();
2841                        break;
2842
2843                case HOST_IF_MSG_SCAN:
2844                        Handle_Scan(msg.drv, &msg.body.scan_info);
2845                        break;
2846
2847                case HOST_IF_MSG_CONNECT:
2848                        Handle_Connect(msg.drv, &msg.body.con_info);
2849                        break;
2850
2851                case HOST_IF_MSG_FLUSH_CONNECT:
2852                        Handle_FlushConnect(msg.drv);
2853                        break;
2854
2855                case HOST_IF_MSG_RCVD_NTWRK_INFO:
2856                        Handle_RcvdNtwrkInfo(msg.drv, &msg.body.net_info);
2857                        break;
2858
2859                case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
2860                        Handle_RcvdGnrlAsyncInfo(msg.drv, &msg.body.async_info);
2861                        break;
2862
2863                case HOST_IF_MSG_KEY:
2864                        Handle_Key(msg.drv, &msg.body.key_info);
2865                        break;
2866
2867                case HOST_IF_MSG_CFG_PARAMS:
2868
2869                        Handle_CfgParam(msg.drv, &msg.body.cfg_info);
2870                        break;
2871
2872                case HOST_IF_MSG_SET_CHANNEL:
2873                        Handle_SetChannel(msg.drv, &msg.body.channel_info);
2874                        break;
2875
2876                case HOST_IF_MSG_DISCONNECT:
2877                        Handle_Disconnect(msg.drv);
2878                        break;
2879
2880                case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
2881                        del_timer(&hif_drv->hScanTimer);
2882                        PRINT_D(HOSTINF_DBG, "scan completed successfully\n");
2883
2884                        if (!linux_wlan_get_num_conn_ifcs())
2885                                chip_sleep_manually(INFINITE_SLEEP_TIME);
2886
2887                        Handle_ScanDone(msg.drv, SCAN_EVENT_DONE);
2888
2889                        if (hif_drv->remain_on_ch_pending)
2890                                Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
2891
2892                        break;
2893
2894                case HOST_IF_MSG_GET_RSSI:
2895                        Handle_GetRssi(msg.drv);
2896                        break;
2897
2898                case HOST_IF_MSG_GET_LINKSPEED:
2899                        Handle_GetLinkspeed(msg.drv);
2900                        break;
2901
2902                case HOST_IF_MSG_GET_STATISTICS:
2903                        Handle_GetStatistics(msg.drv, (struct rf_info *)msg.body.data);
2904                        break;
2905
2906                case HOST_IF_MSG_GET_CHNL:
2907                        Handle_GetChnl(msg.drv);
2908                        break;
2909
2910                case HOST_IF_MSG_ADD_BEACON:
2911                        Handle_AddBeacon(msg.drv, &msg.body.beacon_info);
2912                        break;
2913
2914                case HOST_IF_MSG_DEL_BEACON:
2915                        Handle_DelBeacon(msg.drv);
2916                        break;
2917
2918                case HOST_IF_MSG_ADD_STATION:
2919                        Handle_AddStation(msg.drv, &msg.body.add_sta_info);
2920                        break;
2921
2922                case HOST_IF_MSG_DEL_STATION:
2923                        Handle_DelStation(msg.drv, &msg.body.del_sta_info);
2924                        break;
2925
2926                case HOST_IF_MSG_EDIT_STATION:
2927                        Handle_EditStation(msg.drv, &msg.body.edit_sta_info);
2928                        break;
2929
2930                case HOST_IF_MSG_GET_INACTIVETIME:
2931                        Handle_Get_InActiveTime(msg.drv, &msg.body.mac_info);
2932                        break;
2933
2934                case HOST_IF_MSG_SCAN_TIMER_FIRED:
2935                        PRINT_D(HOSTINF_DBG, "Scan Timeout\n");
2936
2937                        Handle_ScanDone(msg.drv, SCAN_EVENT_ABORTED);
2938                        break;
2939
2940                case HOST_IF_MSG_CONNECT_TIMER_FIRED:
2941                        PRINT_D(HOSTINF_DBG, "Connect Timeout\n");
2942                        Handle_ConnectTimeout(msg.drv);
2943                        break;
2944
2945                case HOST_IF_MSG_POWER_MGMT:
2946                        Handle_PowerManagement(msg.drv, &msg.body.pwr_mgmt_info);
2947                        break;
2948
2949                case HOST_IF_MSG_SET_WFIDRV_HANDLER:
2950                        Handle_SetWfiDrvHandler(msg.drv,
2951                                                &msg.body.drv);
2952                        break;
2953
2954                case HOST_IF_MSG_SET_OPERATION_MODE:
2955                        Handle_SetOperationMode(msg.drv, &msg.body.mode);
2956                        break;
2957
2958                case HOST_IF_MSG_SET_IPADDRESS:
2959                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
2960                        Handle_set_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
2961                        break;
2962
2963                case HOST_IF_MSG_GET_IPADDRESS:
2964                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
2965                        Handle_get_IPAddress(msg.drv, msg.body.ip_info.ip_addr, msg.body.ip_info.idx);
2966                        break;
2967
2968                case HOST_IF_MSG_SET_MAC_ADDRESS:
2969                        Handle_SetMacAddress(msg.drv, &msg.body.set_mac_info);
2970                        break;
2971
2972                case HOST_IF_MSG_GET_MAC_ADDRESS:
2973                        Handle_GetMacAddress(msg.drv, &msg.body.get_mac_info);
2974                        break;
2975
2976                case HOST_IF_MSG_REMAIN_ON_CHAN:
2977                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n");
2978                        Handle_RemainOnChan(msg.drv, &msg.body.remain_on_ch);
2979                        break;
2980
2981                case HOST_IF_MSG_REGISTER_FRAME:
2982                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n");
2983                        Handle_RegisterFrame(msg.drv, &msg.body.reg_frame);
2984                        break;
2985
2986                case HOST_IF_MSG_LISTEN_TIMER_FIRED:
2987                        Handle_ListenStateExpired(msg.drv, &msg.body.remain_on_ch);
2988                        break;
2989
2990                case HOST_IF_MSG_SET_MULTICAST_FILTER:
2991                        PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n");
2992                        Handle_SetMulticastFilter(msg.drv, &msg.body.multicast_info);
2993                        break;
2994
2995                case HOST_IF_MSG_ADD_BA_SESSION:
2996                        Handle_AddBASession(msg.drv, &msg.body.session_info);
2997                        break;
2998
2999                case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS:
3000                        Handle_DelAllRxBASessions(msg.drv, &msg.body.session_info);
3001                        break;
3002
3003                case HOST_IF_MSG_DEL_ALL_STA:
3004                        Handle_DelAllSta(msg.drv, &msg.body.del_all_sta_info);
3005                        break;
3006
3007                default:
3008                        PRINT_ER("[Host Interface] undefined Received Msg ID\n");
3009                        break;
3010                }
3011        }
3012
3013        PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n");
3014        up(&hif_sema_thread);
3015        return 0;
3016}
3017
3018static void TimerCB_Scan(unsigned long arg)
3019{
3020        void *pvArg = (void *)arg;
3021        struct host_if_msg msg;
3022
3023        memset(&msg, 0, sizeof(struct host_if_msg));
3024        msg.drv = pvArg;
3025        msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
3026
3027        wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3028}
3029
3030static void TimerCB_Connect(unsigned long arg)
3031{
3032        void *pvArg = (void *)arg;
3033        struct host_if_msg msg;
3034
3035        memset(&msg, 0, sizeof(struct host_if_msg));
3036        msg.drv = pvArg;
3037        msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
3038
3039        wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3040}
3041
3042s32 host_int_remove_key(struct host_if_drv *hif_drv, const u8 *pu8StaAddress)
3043{
3044        struct wid wid;
3045
3046        wid.id = (u16)WID_REMOVE_KEY;
3047        wid.type = WID_STR;
3048        wid.val = (s8 *)pu8StaAddress;
3049        wid.size = 6;
3050
3051        return 0;
3052}
3053
3054int host_int_remove_wep_key(struct host_if_drv *hif_drv, u8 index)
3055{
3056        int result = 0;
3057        struct host_if_msg msg;
3058
3059        if (!hif_drv) {
3060                result = -EFAULT;
3061                PRINT_ER("Failed to send setup multicast config packet\n");
3062                return result;
3063        }
3064
3065        memset(&msg, 0, sizeof(struct host_if_msg));
3066
3067        msg.id = HOST_IF_MSG_KEY;
3068        msg.body.key_info.type = WEP;
3069        msg.body.key_info.action = REMOVEKEY;
3070        msg.drv = hif_drv;
3071        msg.body.key_info.attr.wep.index = index;
3072
3073        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3074        if (result)
3075                PRINT_ER("Error in sending message queue : Request to remove WEP key\n");
3076        down(&hif_drv->hSemTestKeyBlock);
3077
3078        return result;
3079}
3080
3081int host_int_set_wep_default_key(struct host_if_drv *hif_drv, u8 index)
3082{
3083        int result = 0;
3084        struct host_if_msg msg;
3085
3086        if (!hif_drv) {
3087                result = -EFAULT;
3088                PRINT_ER("driver is null\n");
3089                return result;
3090        }
3091
3092        memset(&msg, 0, sizeof(struct host_if_msg));
3093
3094        msg.id = HOST_IF_MSG_KEY;
3095        msg.body.key_info.type = WEP;
3096        msg.body.key_info.action = DEFAULTKEY;
3097        msg.drv = hif_drv;
3098        msg.body.key_info.attr.wep.index = index;
3099
3100        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3101        if (result)
3102                PRINT_ER("Error in sending message queue : Default key index\n");
3103        down(&hif_drv->hSemTestKeyBlock);
3104
3105        return result;
3106}
3107
3108int host_int_add_wep_key_bss_sta(struct host_if_drv *hif_drv,
3109                                 const u8 *key,
3110                                 u8 len,
3111                                 u8 index)
3112{
3113        int result = 0;
3114        struct host_if_msg msg;
3115
3116        if (!hif_drv) {
3117                PRINT_ER("driver is null\n");
3118                return -EFAULT;
3119        }
3120
3121        memset(&msg, 0, sizeof(struct host_if_msg));
3122
3123        msg.id = HOST_IF_MSG_KEY;
3124        msg.body.key_info.type = WEP;
3125        msg.body.key_info.action = ADDKEY;
3126        msg.drv = hif_drv;
3127        msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
3128        if (!msg.body.key_info.attr.wep.key)
3129                return -ENOMEM;
3130
3131        msg.body.key_info.attr.wep.key_len = len;
3132        msg.body.key_info.attr.wep.index = index;
3133
3134        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3135        if (result)
3136                PRINT_ER("Error in sending message queue :WEP Key\n");
3137        down(&hif_drv->hSemTestKeyBlock);
3138
3139        return result;
3140}
3141
3142int host_int_add_wep_key_bss_ap(struct host_if_drv *hif_drv,
3143                                const u8 *key,
3144                                u8 len,
3145                                u8 index,
3146                                u8 mode,
3147                                enum AUTHTYPE auth_type)
3148{
3149        int result = 0;
3150        struct host_if_msg msg;
3151        int i;
3152
3153        if (!hif_drv) {
3154                PRINT_ER("driver is null\n");
3155                return -EFAULT;
3156        }
3157
3158        memset(&msg, 0, sizeof(struct host_if_msg));
3159
3160        if (INFO) {
3161                for (i = 0; i < len; i++)
3162                        PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", key[i]);
3163        }
3164        msg.id = HOST_IF_MSG_KEY;
3165        msg.body.key_info.type = WEP;
3166        msg.body.key_info.action = ADDKEY_AP;
3167        msg.drv = hif_drv;
3168        msg.body.key_info.attr.wep.key = kmemdup(key, len, GFP_KERNEL);
3169        if (!msg.body.key_info.attr.wep.key)
3170                return -ENOMEM;
3171
3172        msg.body.key_info.attr.wep.key_len = len;
3173        msg.body.key_info.attr.wep.index = index;
3174        msg.body.key_info.attr.wep.mode = mode;
3175        msg.body.key_info.attr.wep.auth_type = auth_type;
3176
3177        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3178
3179        if (result)
3180                PRINT_ER("Error in sending message queue :WEP Key\n");
3181        down(&hif_drv->hSemTestKeyBlock);
3182
3183        return result;
3184}
3185
3186s32 host_int_add_ptk(struct host_if_drv *hif_drv, const u8 *pu8Ptk,
3187                     u8 u8PtkKeylen, const u8 *mac_addr,
3188                     const u8 *pu8RxMic, const u8 *pu8TxMic,
3189                     u8 mode, u8 u8Ciphermode, u8 u8Idx)
3190{
3191        s32 result = 0;
3192        struct host_if_msg msg;
3193        u8 u8KeyLen = u8PtkKeylen;
3194        u32 i;
3195
3196        if (!hif_drv) {
3197                PRINT_ER("driver is null\n");
3198                return -EFAULT;
3199        }
3200
3201        if (pu8RxMic)
3202                u8KeyLen += RX_MIC_KEY_LEN;
3203
3204        if (pu8TxMic)
3205                u8KeyLen += TX_MIC_KEY_LEN;
3206
3207        memset(&msg, 0, sizeof(struct host_if_msg));
3208
3209        msg.id = HOST_IF_MSG_KEY;
3210        msg.body.key_info.type = WPAPtk;
3211        if (mode == AP_MODE) {
3212                msg.body.key_info.action = ADDKEY_AP;
3213                msg.body.key_info.attr.wpa.index = u8Idx;
3214        }
3215        if (mode == STATION_MODE)
3216                msg.body.key_info.action = ADDKEY;
3217
3218        msg.body.key_info.attr.wpa.key = kmalloc(u8PtkKeylen, GFP_KERNEL);
3219        memcpy(msg.body.key_info.attr.wpa.key, pu8Ptk, u8PtkKeylen);
3220
3221        if (pu8RxMic) {
3222                memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic, RX_MIC_KEY_LEN);
3223                if (INFO) {
3224                        for (i = 0; i < RX_MIC_KEY_LEN; i++)
3225                                PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
3226                }
3227        }
3228        if (pu8TxMic) {
3229                memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic, TX_MIC_KEY_LEN);
3230                if (INFO) {
3231                        for (i = 0; i < TX_MIC_KEY_LEN; i++)
3232                                PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
3233                }
3234        }
3235
3236        msg.body.key_info.attr.wpa.key_len = u8KeyLen;
3237        msg.body.key_info.attr.wpa.mac_addr = mac_addr;
3238        msg.body.key_info.attr.wpa.mode = u8Ciphermode;
3239        msg.drv = hif_drv;
3240
3241        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3242
3243        if (result)
3244                PRINT_ER("Error in sending message queue:  PTK Key\n");
3245
3246        down(&hif_drv->hSemTestKeyBlock);
3247
3248        return result;
3249}
3250
3251s32 host_int_add_rx_gtk(struct host_if_drv *hif_drv, const u8 *pu8RxGtk,
3252                        u8 u8GtkKeylen, u8 u8KeyIdx,
3253                        u32 u32KeyRSClen, const u8 *KeyRSC,
3254                        const u8 *pu8RxMic, const u8 *pu8TxMic,
3255                        u8 mode, u8 u8Ciphermode)
3256{
3257        s32 result = 0;
3258        struct host_if_msg msg;
3259        u8 u8KeyLen = u8GtkKeylen;
3260
3261        if (!hif_drv) {
3262                PRINT_ER("driver is null\n");
3263                return -EFAULT;
3264        }
3265        memset(&msg, 0, sizeof(struct host_if_msg));
3266
3267        if (pu8RxMic)
3268                u8KeyLen += RX_MIC_KEY_LEN;
3269
3270        if (pu8TxMic)
3271                u8KeyLen += TX_MIC_KEY_LEN;
3272
3273        if (KeyRSC) {
3274                msg.body.key_info.attr.wpa.seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
3275                memcpy(msg.body.key_info.attr.wpa.seq, KeyRSC, u32KeyRSClen);
3276        }
3277
3278        msg.id = HOST_IF_MSG_KEY;
3279        msg.body.key_info.type = WPARxGtk;
3280        msg.drv = hif_drv;
3281
3282        if (mode == AP_MODE) {
3283                msg.body.key_info.action = ADDKEY_AP;
3284                msg.body.key_info.attr.wpa.mode = u8Ciphermode;
3285        }
3286        if (mode == STATION_MODE)
3287                msg.body.key_info.action = ADDKEY;
3288
3289        msg.body.key_info.attr.wpa.key = kmalloc(u8KeyLen, GFP_KERNEL);
3290        memcpy(msg.body.key_info.attr.wpa.key, pu8RxGtk, u8GtkKeylen);
3291
3292        if (pu8RxMic)
3293                memcpy(msg.body.key_info.attr.wpa.key + 16, pu8RxMic,
3294                       RX_MIC_KEY_LEN);
3295
3296        if (pu8TxMic)
3297                memcpy(msg.body.key_info.attr.wpa.key + 24, pu8TxMic,
3298                       TX_MIC_KEY_LEN);
3299
3300        msg.body.key_info.attr.wpa.index = u8KeyIdx;
3301        msg.body.key_info.attr.wpa.key_len = u8KeyLen;
3302        msg.body.key_info.attr.wpa.seq_len = u32KeyRSClen;
3303
3304        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3305        if (result)
3306                PRINT_ER("Error in sending message queue:  RX GTK\n");
3307
3308        down(&hif_drv->hSemTestKeyBlock);
3309
3310        return result;
3311}
3312
3313s32 host_int_set_pmkid_info(struct host_if_drv *hif_drv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
3314{
3315        s32 result = 0;
3316        struct host_if_msg msg;
3317        u32 i;
3318
3319        if (!hif_drv) {
3320                PRINT_ER("driver is null\n");
3321                return -EFAULT;
3322        }
3323
3324        memset(&msg, 0, sizeof(struct host_if_msg));
3325
3326        msg.id = HOST_IF_MSG_KEY;
3327        msg.body.key_info.type = PMKSA;
3328        msg.body.key_info.action = ADDKEY;
3329        msg.drv = hif_drv;
3330
3331        for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
3332                memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].bssid,
3333                       &pu8PmkidInfoArray->pmkidlist[i].bssid, ETH_ALEN);
3334                memcpy(msg.body.key_info.attr.pmkid.pmkidlist[i].pmkid,
3335                       &pu8PmkidInfoArray->pmkidlist[i].pmkid, PMKID_LEN);
3336        }
3337
3338        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3339        if (result)
3340                PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
3341
3342        return result;
3343}
3344
3345s32 host_int_get_pmkid_info(struct host_if_drv *hif_drv,
3346                            u8 *pu8PmkidInfoArray,
3347                            u32 u32PmkidInfoLen)
3348{
3349        struct wid wid;
3350
3351        wid.id = (u16)WID_PMKID_INFO;
3352        wid.type = WID_STR;
3353        wid.size = u32PmkidInfoLen;
3354        wid.val = pu8PmkidInfoArray;
3355
3356        return 0;
3357}
3358
3359s32 host_int_set_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3360                                         u8 *pu8PassPhrase,
3361                                         u8 u8Psklength)
3362{
3363        struct wid wid;
3364
3365        if ((u8Psklength > 7) && (u8Psklength < 65)) {
3366                wid.id = (u16)WID_11I_PSK;
3367                wid.type = WID_STR;
3368                wid.val = pu8PassPhrase;
3369                wid.size = u8Psklength;
3370        }
3371
3372        return 0;
3373}
3374
3375s32 host_int_get_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
3376{
3377        s32 result = 0;
3378        struct host_if_msg msg;
3379
3380        memset(&msg, 0, sizeof(struct host_if_msg));
3381
3382        msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
3383        msg.body.get_mac_info.mac_addr = pu8MacAddress;
3384        msg.drv = hif_drv;
3385
3386        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3387        if (result) {
3388                PRINT_ER("Failed to send get mac address\n");
3389                return -EFAULT;
3390        }
3391
3392        down(&hif_sema_wait_response);
3393        return result;
3394}
3395
3396s32 host_int_set_MacAddress(struct host_if_drv *hif_drv, u8 *pu8MacAddress)
3397{
3398        s32 result = 0;
3399        struct host_if_msg msg;
3400
3401        PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
3402
3403        memset(&msg, 0, sizeof(struct host_if_msg));
3404        msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
3405        memcpy(msg.body.set_mac_info.mac_addr, pu8MacAddress, ETH_ALEN);
3406        msg.drv = hif_drv;
3407
3408        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3409        if (result)
3410                PRINT_ER("Failed to send message queue: Set mac address\n");
3411
3412        return result;
3413}
3414
3415s32 host_int_get_RSNAConfigPSKPassPhrase(struct host_if_drv *hif_drv,
3416                                         u8 *pu8PassPhrase, u8 u8Psklength)
3417{
3418        struct wid wid;
3419
3420        wid.id = (u16)WID_11I_PSK;
3421        wid.type = WID_STR;
3422        wid.size = u8Psklength;
3423        wid.val = pu8PassPhrase;
3424
3425        return 0;
3426}
3427
3428s32 host_int_set_start_scan_req(struct host_if_drv *hif_drv, u8 scanSource)
3429{
3430        struct wid wid;
3431
3432        wid.id = (u16)WID_START_SCAN_REQ;
3433        wid.type = WID_CHAR;
3434        wid.val = (s8 *)&scanSource;
3435        wid.size = sizeof(char);
3436
3437        return 0;
3438}
3439
3440s32 host_int_get_start_scan_req(struct host_if_drv *hif_drv, u8 *pu8ScanSource)
3441{
3442        struct wid wid;
3443
3444        wid.id = (u16)WID_START_SCAN_REQ;
3445        wid.type = WID_CHAR;
3446        wid.val = (s8 *)pu8ScanSource;
3447        wid.size = sizeof(char);
3448
3449        return 0;
3450}
3451
3452s32 host_int_set_join_req(struct host_if_drv *hif_drv, u8 *pu8bssid,
3453                          const u8 *pu8ssid, size_t ssidLen,
3454                          const u8 *pu8IEs, size_t IEsLen,
3455                          wilc_connect_result pfConnectResult, void *pvUserArg,
3456                          u8 u8security, enum AUTHTYPE tenuAuth_type,
3457                          u8 u8channel, void *pJoinParams)
3458{
3459        s32 result = 0;
3460        struct host_if_msg msg;
3461
3462        if (!hif_drv || !pfConnectResult) {
3463                PRINT_ER("Driver is null\n");
3464                return -EFAULT;
3465        }
3466
3467        if (!pJoinParams) {
3468                PRINT_ER("Unable to Join - JoinParams is NULL\n");
3469                return -EFAULT;
3470        }
3471
3472        memset(&msg, 0, sizeof(struct host_if_msg));
3473
3474        msg.id = HOST_IF_MSG_CONNECT;
3475
3476        msg.body.con_info.security = u8security;
3477        msg.body.con_info.auth_type = tenuAuth_type;
3478        msg.body.con_info.ch = u8channel;
3479        msg.body.con_info.result = pfConnectResult;
3480        msg.body.con_info.arg = pvUserArg;
3481        msg.body.con_info.params = pJoinParams;
3482        msg.drv = hif_drv ;
3483
3484        if (pu8bssid) {
3485                msg.body.con_info.bssid = kmalloc(6, GFP_KERNEL);
3486                memcpy(msg.body.con_info.bssid, pu8bssid, 6);
3487        }
3488
3489        if (pu8ssid) {
3490                msg.body.con_info.ssid_len = ssidLen;
3491                msg.body.con_info.ssid = kmalloc(ssidLen, GFP_KERNEL);
3492                memcpy(msg.body.con_info.ssid, pu8ssid, ssidLen);
3493        }
3494
3495        if (pu8IEs) {
3496                msg.body.con_info.ies_len = IEsLen;
3497                msg.body.con_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3498                memcpy(msg.body.con_info.ies, pu8IEs, IEsLen);
3499        }
3500        if (hif_drv->enuHostIFstate < HOST_IF_CONNECTING)
3501                hif_drv->enuHostIFstate = HOST_IF_CONNECTING;
3502        else
3503                PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", hif_drv->enuHostIFstate);
3504
3505        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3506        if (result) {
3507                PRINT_ER("Failed to send message queue: Set join request\n");
3508                return -EFAULT;
3509        }
3510
3511        hif_drv->hConnectTimer.data = (unsigned long)hif_drv;
3512        mod_timer(&hif_drv->hConnectTimer,
3513                  jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
3514
3515        return result;
3516}
3517
3518s32 host_int_flush_join_req(struct host_if_drv *hif_drv)
3519{
3520        s32 result = 0;
3521        struct host_if_msg msg;
3522
3523        if (!join_req)
3524                return -EFAULT;
3525
3526        if (!hif_drv) {
3527                PRINT_ER("Driver is null\n");
3528                return -EFAULT;
3529        }
3530
3531        msg.id = HOST_IF_MSG_FLUSH_CONNECT;
3532        msg.drv = hif_drv;
3533
3534        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3535        if (result) {
3536                PRINT_ER("Failed to send message queue: Flush join request\n");
3537                return -EFAULT;
3538        }
3539
3540        return result;
3541}
3542
3543s32 host_int_disconnect(struct host_if_drv *hif_drv, u16 u16ReasonCode)
3544{
3545        s32 result = 0;
3546        struct host_if_msg msg;
3547
3548        if (!hif_drv) {
3549                PRINT_ER("Driver is null\n");
3550                return -EFAULT;
3551        }
3552
3553        memset(&msg, 0, sizeof(struct host_if_msg));
3554
3555        msg.id = HOST_IF_MSG_DISCONNECT;
3556        msg.drv = hif_drv;
3557
3558        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3559        if (result)
3560                PRINT_ER("Failed to send message queue: disconnect\n");
3561
3562        down(&hif_drv->hSemTestDisconnectBlock);
3563
3564        return result;
3565}
3566
3567s32 host_int_disconnect_station(struct host_if_drv *hif_drv, u8 assoc_id)
3568{
3569        struct wid wid;
3570
3571        wid.id = (u16)WID_DISCONNECT;
3572        wid.type = WID_CHAR;
3573        wid.val = (s8 *)&assoc_id;
3574        wid.size = sizeof(char);
3575
3576        return 0;
3577}
3578
3579s32 host_int_get_assoc_req_info(struct host_if_drv *hif_drv,
3580                                u8 *pu8AssocReqInfo,
3581                                u32 u32AssocReqInfoLen)
3582{
3583        struct wid wid;
3584
3585        wid.id = (u16)WID_ASSOC_REQ_INFO;
3586        wid.type = WID_STR;
3587        wid.val = pu8AssocReqInfo;
3588        wid.size = u32AssocReqInfoLen;
3589
3590        return 0;
3591}
3592
3593s32 host_int_get_assoc_res_info(struct host_if_drv *hif_drv,
3594                                u8 *pu8AssocRespInfo,
3595                                u32 u32MaxAssocRespInfoLen,
3596                                u32 *pu32RcvdAssocRespInfoLen)
3597{
3598        s32 result = 0;
3599        struct wid wid;
3600
3601        if (!hif_drv) {
3602                PRINT_ER("Driver is null\n");
3603                return -EFAULT;
3604        }
3605
3606        wid.id = (u16)WID_ASSOC_RES_INFO;
3607        wid.type = WID_STR;
3608        wid.val = pu8AssocRespInfo;
3609        wid.size = u32MaxAssocRespInfoLen;
3610
3611        result = send_config_pkt(GET_CFG, &wid, 1,
3612                                 get_id_from_handler(hif_drv));
3613        if (result) {
3614                *pu32RcvdAssocRespInfoLen = 0;
3615                PRINT_ER("Failed to send association response config packet\n");
3616                return -EINVAL;
3617        } else {
3618                *pu32RcvdAssocRespInfoLen = wid.size;
3619        }
3620
3621        return result;
3622}
3623
3624s32 host_int_get_rx_power_level(struct host_if_drv *hif_drv,
3625                                u8 *pu8RxPowerLevel,
3626                                u32 u32RxPowerLevelLen)
3627{
3628        struct wid wid;
3629
3630        wid.id = (u16)WID_RX_POWER_LEVEL;
3631        wid.type = WID_STR;
3632        wid.val = pu8RxPowerLevel;
3633        wid.size = u32RxPowerLevelLen;
3634
3635        return 0;
3636}
3637
3638int host_int_set_mac_chnl_num(struct host_if_drv *hif_drv, u8 channel)
3639{
3640        int result;
3641        struct host_if_msg msg;
3642
3643        if (!hif_drv) {
3644                PRINT_ER("driver is null\n");
3645                return -EFAULT;
3646        }
3647
3648        memset(&msg, 0, sizeof(struct host_if_msg));
3649        msg.id = HOST_IF_MSG_SET_CHANNEL;
3650        msg.body.channel_info.set_ch = channel;
3651        msg.drv = hif_drv;
3652
3653        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3654        if (result) {
3655                PRINT_ER("wilc mq send fail\n");
3656                return -EINVAL;
3657        }
3658
3659        return 0;
3660}
3661
3662int host_int_wait_msg_queue_idle(void)
3663{
3664        int result = 0;
3665        struct host_if_msg msg;
3666
3667        memset(&msg, 0, sizeof(struct host_if_msg));
3668        msg.id = HOST_IF_MSG_Q_IDLE;
3669        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3670        if (result) {
3671                PRINT_ER("wilc mq send fail\n");
3672                result = -EINVAL;
3673        }
3674
3675        down(&hif_sema_wait_response);
3676
3677        return result;
3678}
3679
3680int host_int_set_wfi_drv_handler(struct host_if_drv *hif_drv)
3681{
3682        int result = 0;
3683        struct host_if_msg msg;
3684
3685        memset(&msg, 0, sizeof(struct host_if_msg));
3686        msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
3687        msg.body.drv.handler = get_id_from_handler(hif_drv);
3688        msg.drv = hif_drv;
3689
3690        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3691        if (result) {
3692                PRINT_ER("wilc mq send fail\n");
3693                result = -EINVAL;
3694        }
3695
3696        return result;
3697}
3698
3699int host_int_set_operation_mode(struct host_if_drv *hif_drv, u32 mode)
3700{
3701        int result = 0;
3702        struct host_if_msg msg;
3703
3704        memset(&msg, 0, sizeof(struct host_if_msg));
3705        msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
3706        msg.body.mode.mode = mode;
3707        msg.drv = hif_drv;
3708
3709        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3710        if (result) {
3711                PRINT_ER("wilc mq send fail\n");
3712                result = -EINVAL;
3713        }
3714
3715        return result;
3716}
3717
3718s32 host_int_get_host_chnl_num(struct host_if_drv *hif_drv, u8 *pu8ChNo)
3719{
3720        s32 result = 0;
3721        struct host_if_msg msg;
3722
3723        if (!hif_drv) {
3724                PRINT_ER("driver is null\n");
3725                return -EFAULT;
3726        }
3727
3728        memset(&msg, 0, sizeof(struct host_if_msg));
3729
3730        msg.id = HOST_IF_MSG_GET_CHNL;
3731        msg.drv = hif_drv;
3732
3733        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3734        if (result)
3735                PRINT_ER("wilc mq send fail\n");
3736        down(&hif_drv->hSemGetCHNL);
3737
3738        *pu8ChNo = ch_no;
3739
3740        return result;
3741}
3742
3743s32 host_int_get_inactive_time(struct host_if_drv *hif_drv,
3744                               const u8 *mac, u32 *pu32InactiveTime)
3745{
3746        s32 result = 0;
3747        struct host_if_msg msg;
3748
3749        if (!hif_drv) {
3750                PRINT_ER("driver is null\n");
3751                return -EFAULT;
3752        }
3753
3754        memset(&msg, 0, sizeof(struct host_if_msg));
3755        memcpy(msg.body.mac_info.mac, mac, ETH_ALEN);
3756
3757        msg.id = HOST_IF_MSG_GET_INACTIVETIME;
3758        msg.drv = hif_drv;
3759
3760        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3761        if (result)
3762                PRINT_ER("Failed to send get host channel param's message queue ");
3763
3764        down(&hif_drv->hSemInactiveTime);
3765
3766        *pu32InactiveTime = inactive_time;
3767
3768        return result;
3769}
3770
3771s32 host_int_test_get_int_wid(struct host_if_drv *hif_drv, u32 *pu32TestMemAddr)
3772{
3773        s32 result = 0;
3774        struct wid wid;
3775
3776        if (!hif_drv) {
3777                PRINT_ER("driver is null\n");
3778                return -EFAULT;
3779        }
3780
3781        wid.id = (u16)WID_MEMORY_ADDRESS;
3782        wid.type = WID_INT;
3783        wid.val = (s8 *)pu32TestMemAddr;
3784        wid.size = sizeof(u32);
3785
3786        result = send_config_pkt(GET_CFG, &wid, 1,
3787                                 get_id_from_handler(hif_drv));
3788
3789        if (result) {
3790                PRINT_ER("Failed to get wid value\n");
3791                return -EINVAL;
3792        } else {
3793                PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
3794        }
3795
3796        return result;
3797}
3798
3799s32 host_int_get_rssi(struct host_if_drv *hif_drv, s8 *ps8Rssi)
3800{
3801        s32 result = 0;
3802        struct host_if_msg msg;
3803
3804        memset(&msg, 0, sizeof(struct host_if_msg));
3805        msg.id = HOST_IF_MSG_GET_RSSI;
3806        msg.drv = hif_drv;
3807
3808        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3809        if (result) {
3810                PRINT_ER("Failed to send get host channel param's message queue ");
3811                return -EFAULT;
3812        }
3813
3814        down(&hif_drv->hSemGetRSSI);
3815
3816        if (!ps8Rssi) {
3817                PRINT_ER("RSS pointer value is null");
3818                return -EFAULT;
3819        }
3820
3821        *ps8Rssi = rssi;
3822
3823        return result;
3824}
3825
3826s32 host_int_get_link_speed(struct host_if_drv *hif_drv, s8 *ps8lnkspd)
3827{
3828        struct host_if_msg msg;
3829        s32 result = 0;
3830
3831        memset(&msg, 0, sizeof(struct host_if_msg));
3832        msg.id = HOST_IF_MSG_GET_LINKSPEED;
3833        msg.drv = hif_drv;
3834
3835        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3836        if (result) {
3837                PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
3838                return -EFAULT;
3839        }
3840
3841        down(&hif_drv->hSemGetLINKSPEED);
3842
3843        if (!ps8lnkspd) {
3844                PRINT_ER("LINKSPEED pointer value is null");
3845                return -EFAULT;
3846        }
3847
3848        *ps8lnkspd = link_speed;
3849
3850        return result;
3851}
3852
3853s32 host_int_get_statistics(struct host_if_drv *hif_drv, struct rf_info *pstrStatistics)
3854{
3855        s32 result = 0;
3856        struct host_if_msg msg;
3857
3858        memset(&msg, 0, sizeof(struct host_if_msg));
3859        msg.id = HOST_IF_MSG_GET_STATISTICS;
3860        msg.body.data = (char *)pstrStatistics;
3861        msg.drv = hif_drv;
3862
3863        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3864        if (result) {
3865                PRINT_ER("Failed to send get host channel param's message queue ");
3866                return -EFAULT;
3867        }
3868
3869        down(&hif_sema_wait_response);
3870        return result;
3871}
3872
3873s32 host_int_scan(struct host_if_drv *hif_drv, u8 u8ScanSource,
3874                  u8 u8ScanType, u8 *pu8ChnlFreqList,
3875                  u8 u8ChnlListLen, const u8 *pu8IEs,
3876                  size_t IEsLen, wilc_scan_result ScanResult,
3877                  void *pvUserArg, struct hidden_network *pstrHiddenNetwork)
3878{
3879        s32 result = 0;
3880        struct host_if_msg msg;
3881
3882        if (!hif_drv || !ScanResult) {
3883                PRINT_ER("hif_drv or ScanResult = NULL\n");
3884                return -EFAULT;
3885        }
3886
3887        memset(&msg, 0, sizeof(struct host_if_msg));
3888
3889        msg.id = HOST_IF_MSG_SCAN;
3890
3891        if (pstrHiddenNetwork) {
3892                msg.body.scan_info.hidden_network.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
3893                msg.body.scan_info.hidden_network.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
3894
3895        } else
3896                PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
3897
3898        msg.drv = hif_drv;
3899        msg.body.scan_info.src = u8ScanSource;
3900        msg.body.scan_info.type = u8ScanType;
3901        msg.body.scan_info.result = ScanResult;
3902        msg.body.scan_info.arg = pvUserArg;
3903
3904        msg.body.scan_info.ch_list_len = u8ChnlListLen;
3905        msg.body.scan_info.ch_freq_list = kmalloc(u8ChnlListLen, GFP_KERNEL);
3906        memcpy(msg.body.scan_info.ch_freq_list, pu8ChnlFreqList, u8ChnlListLen);
3907
3908        msg.body.scan_info.ies_len = IEsLen;
3909        msg.body.scan_info.ies = kmalloc(IEsLen, GFP_KERNEL);
3910        memcpy(msg.body.scan_info.ies, pu8IEs, IEsLen);
3911
3912        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3913        if (result) {
3914                PRINT_ER("Error in sending message queue\n");
3915                return -EINVAL;
3916        }
3917
3918        PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
3919        hif_drv->hScanTimer.data = (unsigned long)hif_drv;
3920        mod_timer(&hif_drv->hScanTimer,
3921                  jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
3922
3923        return result;
3924}
3925
3926s32 hif_set_cfg(struct host_if_drv *hif_drv,
3927                struct cfg_param_val *pstrCfgParamVal)
3928{
3929        s32 result = 0;
3930        struct host_if_msg msg;
3931
3932        if (!hif_drv) {
3933                PRINT_ER("hif_drv NULL\n");
3934                return -EFAULT;
3935        }
3936
3937        memset(&msg, 0, sizeof(struct host_if_msg));
3938        msg.id = HOST_IF_MSG_CFG_PARAMS;
3939        msg.body.cfg_info.cfg_attr_info = *pstrCfgParamVal;
3940        msg.drv = hif_drv;
3941
3942        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
3943
3944        return result;
3945}
3946
3947s32 hif_get_cfg(struct host_if_drv *hif_drv, u16 u16WID, u16 *pu16WID_Value)
3948{
3949        s32 result = 0;
3950
3951        down(&hif_drv->gtOsCfgValuesSem);
3952
3953        if (!hif_drv) {
3954                PRINT_ER("hif_drv NULL\n");
3955                return -EFAULT;
3956        }
3957        PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
3958        switch (u16WID) {
3959        case WID_BSS_TYPE:
3960                *pu16WID_Value = (u16)hif_drv->strCfgValues.bss_type;
3961                break;
3962
3963        case WID_AUTH_TYPE:
3964                *pu16WID_Value = (u16)hif_drv->strCfgValues.auth_type;
3965                break;
3966
3967        case WID_AUTH_TIMEOUT:
3968                *pu16WID_Value = hif_drv->strCfgValues.auth_timeout;
3969                break;
3970
3971        case WID_POWER_MANAGEMENT:
3972                *pu16WID_Value = (u16)hif_drv->strCfgValues.power_mgmt_mode;
3973                break;
3974
3975        case WID_SHORT_RETRY_LIMIT:
3976                *pu16WID_Value =       hif_drv->strCfgValues.short_retry_limit;
3977                break;
3978
3979        case WID_LONG_RETRY_LIMIT:
3980                *pu16WID_Value = hif_drv->strCfgValues.long_retry_limit;
3981                break;
3982
3983        case WID_FRAG_THRESHOLD:
3984                *pu16WID_Value = hif_drv->strCfgValues.frag_threshold;
3985                break;
3986
3987        case WID_RTS_THRESHOLD:
3988                *pu16WID_Value = hif_drv->strCfgValues.rts_threshold;
3989                break;
3990
3991        case WID_PREAMBLE:
3992                *pu16WID_Value = (u16)hif_drv->strCfgValues.preamble_type;
3993                break;
3994
3995        case WID_SHORT_SLOT_ALLOWED:
3996                *pu16WID_Value = (u16) hif_drv->strCfgValues.short_slot_allowed;
3997                break;
3998
3999        case WID_11N_TXOP_PROT_DISABLE:
4000                *pu16WID_Value = (u16)hif_drv->strCfgValues.txop_prot_disabled;
4001                break;
4002
4003        case WID_BEACON_INTERVAL:
4004                *pu16WID_Value = hif_drv->strCfgValues.beacon_interval;
4005                break;
4006
4007        case WID_DTIM_PERIOD:
4008                *pu16WID_Value = (u16)hif_drv->strCfgValues.dtim_period;
4009                break;
4010
4011        case WID_SITE_SURVEY:
4012                *pu16WID_Value = (u16)hif_drv->strCfgValues.site_survey_enabled;
4013                break;
4014
4015        case WID_SITE_SURVEY_SCAN_TIME:
4016                *pu16WID_Value = hif_drv->strCfgValues.site_survey_scan_time;
4017                break;
4018
4019        case WID_ACTIVE_SCAN_TIME:
4020                *pu16WID_Value = hif_drv->strCfgValues.active_scan_time;
4021                break;
4022
4023        case WID_PASSIVE_SCAN_TIME:
4024                *pu16WID_Value = hif_drv->strCfgValues.passive_scan_time;
4025                break;
4026
4027        case WID_CURRENT_TX_RATE:
4028                *pu16WID_Value = hif_drv->strCfgValues.curr_tx_rate;
4029                break;
4030
4031        default:
4032                break;
4033        }
4034
4035        up(&hif_drv->gtOsCfgValuesSem);
4036
4037        return result;
4038}
4039
4040static void GetPeriodicRSSI(unsigned long arg)
4041{
4042        struct host_if_drv *hif_drv = (struct host_if_drv *)arg;
4043
4044        if (!hif_drv)   {
4045                PRINT_ER("Driver handler is NULL\n");
4046                return;
4047        }
4048
4049        if (hif_drv->enuHostIFstate == HOST_IF_CONNECTED) {
4050                s32 result = 0;
4051                struct host_if_msg msg;
4052
4053                memset(&msg, 0, sizeof(struct host_if_msg));
4054
4055                msg.id = HOST_IF_MSG_GET_RSSI;
4056                msg.drv = hif_drv;
4057
4058                result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4059                if (result) {
4060                        PRINT_ER("Failed to send get host channel param's message queue ");
4061                        return;
4062                }
4063        }
4064        periodic_rssi.data = (unsigned long)hif_drv;
4065        mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
4066}
4067
4068s32 host_int_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
4069{
4070        s32 result = 0;
4071        struct host_if_drv *hif_drv;
4072        int err;
4073        perInterface_wlan_t *nic;
4074        struct wilc *wilc;
4075
4076        nic = netdev_priv(dev);
4077        wilc = nic->wilc;
4078
4079        PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
4080
4081        scan_while_connected = false;
4082
4083        sema_init(&hif_sema_wait_response, 0);
4084
4085        hif_drv  = kzalloc(sizeof(struct host_if_drv), GFP_KERNEL);
4086        if (!hif_drv) {
4087                result = -ENOMEM;
4088                goto _fail_;
4089        }
4090        *hif_drv_handler = hif_drv;
4091        err = add_handler_in_list(hif_drv);
4092        if (err) {
4093                result = -EFAULT;
4094                goto _fail_timer_2;
4095        }
4096
4097        g_obtainingIP = false;
4098
4099        PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", hif_drv);
4100        if (clients_count == 0) {
4101                sema_init(&hif_sema_thread, 0);
4102                sema_init(&hif_sema_driver, 0);
4103                sema_init(&hif_sema_deinit, 1);
4104        }
4105
4106        sema_init(&hif_drv->hSemTestKeyBlock, 0);
4107        sema_init(&hif_drv->hSemTestDisconnectBlock, 0);
4108        sema_init(&hif_drv->hSemGetRSSI, 0);
4109        sema_init(&hif_drv->hSemGetLINKSPEED, 0);
4110        sema_init(&hif_drv->hSemGetCHNL, 0);
4111        sema_init(&hif_drv->hSemInactiveTime, 0);
4112
4113        PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
4114
4115        if (clients_count == 0) {
4116                result = wilc_mq_create(&hif_msg_q);
4117
4118                if (result < 0) {
4119                        PRINT_ER("Failed to creat MQ\n");
4120                        goto _fail_;
4121                }
4122
4123                hif_thread_handler = kthread_run(hostIFthread, wilc,
4124                                                 "WILC_kthread");
4125
4126                if (IS_ERR(hif_thread_handler)) {
4127                        PRINT_ER("Failed to creat Thread\n");
4128                        result = -EFAULT;
4129                        goto _fail_mq_;
4130                }
4131                setup_timer(&periodic_rssi, GetPeriodicRSSI,
4132                            (unsigned long)hif_drv);
4133                mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000));
4134        }
4135
4136        setup_timer(&hif_drv->hScanTimer, TimerCB_Scan, 0);
4137
4138        setup_timer(&hif_drv->hConnectTimer, TimerCB_Connect, 0);
4139
4140        setup_timer(&hif_drv->hRemainOnChannel, ListenTimerCB, 0);
4141
4142        sema_init(&hif_drv->gtOsCfgValuesSem, 1);
4143        down(&hif_drv->gtOsCfgValuesSem);
4144
4145        hif_drv->enuHostIFstate = HOST_IF_IDLE;
4146        hif_drv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
4147        hif_drv->strCfgValues.scan_source = DEFAULT_SCAN;
4148        hif_drv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
4149        hif_drv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME;
4150        hif_drv->strCfgValues.curr_tx_rate = AUTORATE;
4151
4152        hif_drv->u64P2p_MgmtTimeout = 0;
4153
4154        PRINT_INFO(HOSTINF_DBG, "Initialization values, Site survey value: %d\n Scan source: %d\n Active scan time: %d\n Passive scan time: %d\nCurrent tx Rate = %d\n",
4155
4156                   hif_drv->strCfgValues.site_survey_enabled, hif_drv->strCfgValues.scan_source,
4157                   hif_drv->strCfgValues.active_scan_time, hif_drv->strCfgValues.passive_scan_time,
4158                   hif_drv->strCfgValues.curr_tx_rate);
4159
4160        up(&hif_drv->gtOsCfgValuesSem);
4161
4162        clients_count++;
4163
4164        return result;
4165
4166_fail_timer_2:
4167        up(&hif_drv->gtOsCfgValuesSem);
4168        del_timer_sync(&hif_drv->hConnectTimer);
4169        del_timer_sync(&hif_drv->hScanTimer);
4170        kthread_stop(hif_thread_handler);
4171_fail_mq_:
4172        wilc_mq_destroy(&hif_msg_q);
4173_fail_:
4174        return result;
4175}
4176
4177s32 host_int_deinit(struct host_if_drv *hif_drv)
4178{
4179        s32 result = 0;
4180        struct host_if_msg msg;
4181        int ret;
4182
4183        if (!hif_drv)   {
4184                PRINT_ER("hif_drv = NULL\n");
4185                return 0;
4186        }
4187
4188        down(&hif_sema_deinit);
4189
4190        terminated_handle = hif_drv;
4191        PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count);
4192
4193        if (del_timer_sync(&hif_drv->hScanTimer))
4194                PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n");
4195
4196        if (del_timer_sync(&hif_drv->hConnectTimer))
4197                PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4198
4199        if (del_timer_sync(&periodic_rssi))
4200                PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4201
4202        del_timer_sync(&hif_drv->hRemainOnChannel);
4203
4204        host_int_set_wfi_drv_handler(NULL);
4205        down(&hif_sema_driver);
4206
4207        if (hif_drv->usr_scan_req.pfUserScanResult) {
4208                hif_drv->usr_scan_req.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
4209                                                       hif_drv->usr_scan_req.u32UserScanPvoid, NULL);
4210
4211                hif_drv->usr_scan_req.pfUserScanResult = NULL;
4212        }
4213
4214        hif_drv->enuHostIFstate = HOST_IF_IDLE;
4215
4216        scan_while_connected = false;
4217
4218        memset(&msg, 0, sizeof(struct host_if_msg));
4219
4220        if (clients_count == 1) {
4221                if (del_timer_sync(&periodic_rssi))
4222                        PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
4223
4224                msg.id = HOST_IF_MSG_EXIT;
4225                msg.drv = hif_drv;
4226
4227                result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4228                if (result != 0)
4229                        PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", result);
4230
4231                down(&hif_sema_thread);
4232
4233                wilc_mq_destroy(&hif_msg_q);
4234        }
4235
4236        down(&hif_drv->gtOsCfgValuesSem);
4237
4238        ret = remove_handler_in_list(hif_drv);
4239        if (ret)
4240                result = -ENOENT;
4241
4242        kfree(hif_drv);
4243
4244        clients_count--;
4245        terminated_handle = NULL;
4246        up(&hif_sema_deinit);
4247        return result;
4248}
4249
4250void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
4251{
4252        s32 result = 0;
4253        struct host_if_msg msg;
4254        int id;
4255        struct host_if_drv *hif_drv = NULL;
4256
4257        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4258        hif_drv = get_handler_from_id(id);
4259
4260        if (!hif_drv || hif_drv == terminated_handle)   {
4261                PRINT_ER("NetworkInfo received but driver not init[%p]\n", hif_drv);
4262                return;
4263        }
4264
4265        memset(&msg, 0, sizeof(struct host_if_msg));
4266
4267        msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
4268        msg.drv = hif_drv;
4269
4270        msg.body.net_info.len = u32Length;
4271        msg.body.net_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4272        memcpy(msg.body.net_info.buffer, pu8Buffer, u32Length);
4273
4274        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4275        if (result)
4276                PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", result);
4277}
4278
4279void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
4280{
4281        s32 result = 0;
4282        struct host_if_msg msg;
4283        int id;
4284        struct host_if_drv *hif_drv = NULL;
4285
4286        down(&hif_sema_deinit);
4287
4288        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4289        hif_drv = get_handler_from_id(id);
4290        PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
4291
4292        if (!hif_drv || hif_drv == terminated_handle) {
4293                PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n");
4294                up(&hif_sema_deinit);
4295                return;
4296        }
4297
4298        if (!hif_drv->usr_conn_req.pfUserConnectResult) {
4299                PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
4300                up(&hif_sema_deinit);
4301                return;
4302        }
4303
4304        memset(&msg, 0, sizeof(struct host_if_msg));
4305
4306        msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
4307        msg.drv = hif_drv;
4308
4309        msg.body.async_info.len = u32Length;
4310        msg.body.async_info.buffer = kmalloc(u32Length, GFP_KERNEL);
4311        memcpy(msg.body.async_info.buffer, pu8Buffer, u32Length);
4312
4313        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4314        if (result)
4315                PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", result);
4316
4317        up(&hif_sema_deinit);
4318}
4319
4320void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
4321{
4322        s32 result = 0;
4323        struct host_if_msg msg;
4324        int id;
4325        struct host_if_drv *hif_drv = NULL;
4326
4327        id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
4328        hif_drv = get_handler_from_id(id);
4329
4330        PRINT_D(GENERIC_DBG, "Scan notification received %p\n", hif_drv);
4331
4332        if (!hif_drv || hif_drv == terminated_handle)
4333                return;
4334
4335        if (hif_drv->usr_scan_req.pfUserScanResult) {
4336                memset(&msg, 0, sizeof(struct host_if_msg));
4337
4338                msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
4339                msg.drv = hif_drv;
4340
4341                result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4342                if (result)
4343                        PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", result);
4344        }
4345
4346        return;
4347}
4348
4349s32 host_int_remain_on_channel(struct host_if_drv *hif_drv, u32 u32SessionID,
4350                               u32 u32duration, u16 chan,
4351                               wilc_remain_on_chan_expired RemainOnChanExpired,
4352                               wilc_remain_on_chan_ready RemainOnChanReady,
4353                               void *pvUserArg)
4354{
4355        s32 result = 0;
4356        struct host_if_msg msg;
4357
4358        if (!hif_drv) {
4359                PRINT_ER("driver is null\n");
4360                return -EFAULT;
4361        }
4362
4363        memset(&msg, 0, sizeof(struct host_if_msg));
4364
4365        msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
4366        msg.body.remain_on_ch.u16Channel = chan;
4367        msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired;
4368        msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady;
4369        msg.body.remain_on_ch.pVoid = pvUserArg;
4370        msg.body.remain_on_ch.u32duration = u32duration;
4371        msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
4372        msg.drv = hif_drv;
4373
4374        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4375        if (result)
4376                PRINT_ER("wilc mq send fail\n");
4377
4378        return result;
4379}
4380
4381s32 host_int_ListenStateExpired(struct host_if_drv *hif_drv, u32 u32SessionID)
4382{
4383        s32 result = 0;
4384        struct host_if_msg msg;
4385
4386        if (!hif_drv) {
4387                PRINT_ER("driver is null\n");
4388                return -EFAULT;
4389        }
4390
4391        del_timer(&hif_drv->hRemainOnChannel);
4392
4393        memset(&msg, 0, sizeof(struct host_if_msg));
4394        msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
4395        msg.drv = hif_drv;
4396        msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
4397
4398        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4399        if (result)
4400                PRINT_ER("wilc mq send fail\n");
4401
4402        return result;
4403}
4404
4405s32 host_int_frame_register(struct host_if_drv *hif_drv, u16 u16FrameType, bool bReg)
4406{
4407        s32 result = 0;
4408        struct host_if_msg msg;
4409
4410        if (!hif_drv) {
4411                PRINT_ER("driver is null\n");
4412                return -EFAULT;
4413        }
4414
4415        memset(&msg, 0, sizeof(struct host_if_msg));
4416
4417        msg.id = HOST_IF_MSG_REGISTER_FRAME;
4418        switch (u16FrameType) {
4419        case ACTION:
4420                PRINT_D(HOSTINF_DBG, "ACTION\n");
4421                msg.body.reg_frame.u8Regid = ACTION_FRM_IDX;
4422                break;
4423
4424        case PROBE_REQ:
4425                PRINT_D(HOSTINF_DBG, "PROBE REQ\n");
4426                msg.body.reg_frame.u8Regid = PROBE_REQ_IDX;
4427                break;
4428
4429        default:
4430                PRINT_D(HOSTINF_DBG, "Not valid frame type\n");
4431                break;
4432        }
4433        msg.body.reg_frame.u16FrameType = u16FrameType;
4434        msg.body.reg_frame.bReg = bReg;
4435        msg.drv = hif_drv;
4436
4437        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4438        if (result)
4439                PRINT_ER("wilc mq send fail\n");
4440
4441        return result;
4442}
4443
4444s32 host_int_add_beacon(struct host_if_drv *hif_drv, u32 u32Interval,
4445                        u32 u32DTIMPeriod, u32 u32HeadLen, u8 *pu8Head,
4446                        u32 u32TailLen, u8 *pu8Tail)
4447{
4448        s32 result = 0;
4449        struct host_if_msg msg;
4450        struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
4451
4452        if (!hif_drv) {
4453                PRINT_ER("driver is null\n");
4454                return -EFAULT;
4455        }
4456
4457        memset(&msg, 0, sizeof(struct host_if_msg));
4458
4459        PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
4460
4461        msg.id = HOST_IF_MSG_ADD_BEACON;
4462        msg.drv = hif_drv;
4463        pstrSetBeaconParam->interval = u32Interval;
4464        pstrSetBeaconParam->dtim_period = u32DTIMPeriod;
4465        pstrSetBeaconParam->head_len = u32HeadLen;
4466        pstrSetBeaconParam->head = kmemdup(pu8Head, u32HeadLen, GFP_KERNEL);
4467        if (!pstrSetBeaconParam->head) {
4468                result = -ENOMEM;
4469                goto ERRORHANDLER;
4470        }
4471        pstrSetBeaconParam->tail_len = u32TailLen;
4472
4473        if (u32TailLen > 0) {
4474                pstrSetBeaconParam->tail = kmemdup(pu8Tail, u32TailLen,
4475                                                   GFP_KERNEL);
4476                if (!pstrSetBeaconParam->tail) {
4477                        result = -ENOMEM;
4478                        goto ERRORHANDLER;
4479                }
4480        } else {
4481                pstrSetBeaconParam->tail = NULL;
4482        }
4483
4484        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4485        if (result)
4486                PRINT_ER("wilc mq send fail\n");
4487
4488ERRORHANDLER:
4489        if (result) {
4490                kfree(pstrSetBeaconParam->head);
4491
4492                kfree(pstrSetBeaconParam->tail);
4493        }
4494
4495        return result;
4496}
4497
4498s32 host_int_del_beacon(struct host_if_drv *hif_drv)
4499{
4500        s32 result = 0;
4501        struct host_if_msg msg;
4502
4503        if (!hif_drv) {
4504                PRINT_ER("driver is null\n");
4505                return -EFAULT;
4506        }
4507
4508        msg.id = HOST_IF_MSG_DEL_BEACON;
4509        msg.drv = hif_drv;
4510        PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
4511
4512        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4513        if (result)
4514                PRINT_ER("wilc_mq_send fail\n");
4515
4516        return result;
4517}
4518
4519s32 host_int_add_station(struct host_if_drv *hif_drv,
4520                         struct add_sta_param *pstrStaParams)
4521{
4522        s32 result = 0;
4523        struct host_if_msg msg;
4524        struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
4525
4526        if (!hif_drv) {
4527                PRINT_ER("driver is null\n");
4528                return -EFAULT;
4529        }
4530
4531        memset(&msg, 0, sizeof(struct host_if_msg));
4532
4533        PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
4534
4535        msg.id = HOST_IF_MSG_ADD_STATION;
4536        msg.drv = hif_drv;
4537
4538        memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
4539        if (pstrAddStationMsg->u8NumRates > 0) {
4540                u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
4541
4542                if (!rates)
4543                        return -ENOMEM;
4544
4545                memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
4546                pstrAddStationMsg->pu8Rates = rates;
4547        }
4548
4549        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4550        if (result)
4551                PRINT_ER("wilc_mq_send fail\n");
4552        return result;
4553}
4554
4555s32 host_int_del_station(struct host_if_drv *hif_drv, const u8 *pu8MacAddr)
4556{
4557        s32 result = 0;
4558        struct host_if_msg msg;
4559        struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info;
4560
4561        if (!hif_drv) {
4562                PRINT_ER("driver is null\n");
4563                return -EFAULT;
4564        }
4565
4566        memset(&msg, 0, sizeof(struct host_if_msg));
4567
4568        PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
4569
4570        msg.id = HOST_IF_MSG_DEL_STATION;
4571        msg.drv = hif_drv;
4572
4573        if (!pu8MacAddr)
4574                eth_broadcast_addr(pstrDelStationMsg->mac_addr);
4575        else
4576                memcpy(pstrDelStationMsg->mac_addr, pu8MacAddr, ETH_ALEN);
4577
4578        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4579        if (result)
4580                PRINT_ER("wilc_mq_send fail\n");
4581        return result;
4582}
4583
4584s32 host_int_del_allstation(struct host_if_drv *hif_drv,
4585                            u8 pu8MacAddr[][ETH_ALEN])
4586{
4587        s32 result = 0;
4588        struct host_if_msg msg;
4589        struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
4590        u8 au8Zero_Buff[ETH_ALEN] = {0};
4591        u32 i;
4592        u8 u8AssocNumb = 0;
4593
4594        if (!hif_drv) {
4595                PRINT_ER("driver is null\n");
4596                return -EFAULT;
4597        }
4598
4599        memset(&msg, 0, sizeof(struct host_if_msg));
4600
4601        PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
4602
4603        msg.id = HOST_IF_MSG_DEL_ALL_STA;
4604        msg.drv = hif_drv;
4605
4606        for (i = 0; i < MAX_NUM_STA; i++) {
4607                if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
4608                        memcpy(pstrDelAllStationMsg->del_all_sta[i], pu8MacAddr[i], ETH_ALEN);
4609                        PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n",
4610                                pstrDelAllStationMsg->del_all_sta[i][0],
4611                                pstrDelAllStationMsg->del_all_sta[i][1],
4612                                pstrDelAllStationMsg->del_all_sta[i][2],
4613                                pstrDelAllStationMsg->del_all_sta[i][3],
4614                                pstrDelAllStationMsg->del_all_sta[i][4],
4615                                pstrDelAllStationMsg->del_all_sta[i][5]);
4616                        u8AssocNumb++;
4617                }
4618        }
4619        if (!u8AssocNumb) {
4620                PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
4621                return result;
4622        }
4623
4624        pstrDelAllStationMsg->assoc_sta = u8AssocNumb;
4625        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4626
4627        if (result)
4628                PRINT_ER("wilc_mq_send fail\n");
4629
4630        down(&hif_sema_wait_response);
4631
4632        return result;
4633}
4634
4635s32 host_int_edit_station(struct host_if_drv *hif_drv,
4636                          struct add_sta_param *pstrStaParams)
4637{
4638        s32 result = 0;
4639        struct host_if_msg msg;
4640        struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
4641
4642        if (!hif_drv) {
4643                PRINT_ER("driver is null\n");
4644                return -EFAULT;
4645        }
4646
4647        PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n");
4648
4649        memset(&msg, 0, sizeof(struct host_if_msg));
4650
4651        msg.id = HOST_IF_MSG_EDIT_STATION;
4652        msg.drv = hif_drv;
4653
4654        memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
4655        if (pstrAddStationMsg->u8NumRates > 0) {
4656                u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
4657
4658                if (!rates)
4659                        return -ENOMEM;
4660
4661                memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
4662                pstrAddStationMsg->pu8Rates = rates;
4663        }
4664
4665        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4666        if (result)
4667                PRINT_ER("wilc_mq_send fail\n");
4668
4669        return result;
4670}
4671
4672s32 host_int_set_power_mgmt(struct host_if_drv *hif_drv,
4673                            bool bIsEnabled,
4674                            u32 u32Timeout)
4675{
4676        s32 result = 0;
4677        struct host_if_msg msg;
4678        struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
4679
4680        PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
4681
4682        if (!hif_drv) {
4683                PRINT_ER("driver is null\n");
4684                return -EFAULT;
4685        }
4686
4687        PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n");
4688
4689        memset(&msg, 0, sizeof(struct host_if_msg));
4690
4691        msg.id = HOST_IF_MSG_POWER_MGMT;
4692        msg.drv = hif_drv;
4693
4694        pstrPowerMgmtParam->enabled = bIsEnabled;
4695        pstrPowerMgmtParam->timeout = u32Timeout;
4696
4697        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4698        if (result)
4699                PRINT_ER("wilc_mq_send fail\n");
4700        return result;
4701}
4702
4703s32 host_int_setup_multicast_filter(struct host_if_drv *hif_drv,
4704                                    bool bIsEnabled,
4705                                    u32 u32count)
4706{
4707        s32 result = 0;
4708        struct host_if_msg msg;
4709        struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
4710
4711        if (!hif_drv) {
4712                PRINT_ER("driver is null\n");
4713                return -EFAULT;
4714        }
4715
4716        PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n");
4717
4718        memset(&msg, 0, sizeof(struct host_if_msg));
4719
4720        msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
4721        msg.drv = hif_drv;
4722
4723        pstrMulticastFilterParam->enabled = bIsEnabled;
4724        pstrMulticastFilterParam->cnt = u32count;
4725
4726        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4727        if (result)
4728                PRINT_ER("wilc_mq_send fail\n");
4729        return result;
4730}
4731
4732static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
4733{
4734        struct join_bss_param *pNewJoinBssParam = NULL;
4735        u8 *pu8IEs;
4736        u16 u16IEsLen;
4737        u16 index = 0;
4738        u8 suppRatesNo = 0;
4739        u8 extSuppRatesNo;
4740        u16 jumpOffset;
4741        u8 pcipherCount;
4742        u8 authCount;
4743        u8 pcipherTotalCount = 0;
4744        u8 authTotalCount = 0;
4745        u8 i, j;
4746
4747        pu8IEs = ptstrNetworkInfo->pu8IEs;
4748        u16IEsLen = ptstrNetworkInfo->u16IEsLen;
4749
4750        pNewJoinBssParam = kzalloc(sizeof(struct join_bss_param), GFP_KERNEL);
4751        if (pNewJoinBssParam) {
4752                pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
4753                pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
4754                pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo;
4755                memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6);
4756                memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1);
4757                pNewJoinBssParam->ssid_len = ptstrNetworkInfo->u8SsidLen;
4758                memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
4759                memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
4760
4761                while (index < u16IEsLen) {
4762                        if (pu8IEs[index] == SUPP_RATES_IE) {
4763                                suppRatesNo = pu8IEs[index + 1];
4764                                pNewJoinBssParam->supp_rates[0] = suppRatesNo;
4765                                index += 2;
4766
4767                                for (i = 0; i < suppRatesNo; i++)
4768                                        pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
4769
4770                                index += suppRatesNo;
4771                                continue;
4772                        } else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
4773                                extSuppRatesNo = pu8IEs[index + 1];
4774                                if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
4775                                        pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
4776                                else
4777                                        pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
4778                                index += 2;
4779                                for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++)
4780                                        pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
4781
4782                                index += extSuppRatesNo;
4783                                continue;
4784                        } else if (pu8IEs[index] == HT_CAPABILITY_IE) {
4785                                pNewJoinBssParam->ht_capable = true;
4786                                index += pu8IEs[index + 1] + 2;
4787                                continue;
4788                        } else if ((pu8IEs[index] == WMM_IE) &&
4789                                   (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
4790                                   (pu8IEs[index + 4] == 0xF2) &&
4791                                   (pu8IEs[index + 5] == 0x02) &&
4792                                   ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) &&
4793                                   (pu8IEs[index + 7] == 0x01)) {
4794                                pNewJoinBssParam->wmm_cap = true;
4795
4796                                if (pu8IEs[index + 8] & BIT(7))
4797                                        pNewJoinBssParam->uapsd_cap = true;
4798                                index += pu8IEs[index + 1] + 2;
4799                                continue;
4800                        } else if ((pu8IEs[index] == P2P_IE) &&
4801                                 (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
4802                                 (pu8IEs[index + 4] == 0x9a) &&
4803                                 (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) {
4804                                u16 u16P2P_count;
4805
4806                                pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
4807                                pNewJoinBssParam->noa_enabled = 1;
4808                                pNewJoinBssParam->idx = pu8IEs[index + 9];
4809
4810                                if (pu8IEs[index + 10] & BIT(7)) {
4811                                        pNewJoinBssParam->opp_enabled = 1;
4812                                        pNewJoinBssParam->ct_window = pu8IEs[index + 10];
4813                                } else {
4814                                        pNewJoinBssParam->opp_enabled = 0;
4815                                }
4816
4817                                PRINT_D(GENERIC_DBG, "P2P Dump\n");
4818                                for (i = 0; i < pu8IEs[index + 7]; i++)
4819                                        PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]);
4820
4821                                pNewJoinBssParam->cnt = pu8IEs[index + 11];
4822                                u16P2P_count = index + 12;
4823
4824                                memcpy(pNewJoinBssParam->duration, pu8IEs + u16P2P_count, 4);
4825                                u16P2P_count += 4;
4826
4827                                memcpy(pNewJoinBssParam->interval, pu8IEs + u16P2P_count, 4);
4828                                u16P2P_count += 4;
4829
4830                                memcpy(pNewJoinBssParam->start_time, pu8IEs + u16P2P_count, 4);
4831
4832                                index += pu8IEs[index + 1] + 2;
4833                                continue;
4834
4835                        } else if ((pu8IEs[index] == RSN_IE) ||
4836                                 ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
4837                                  (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
4838                                  (pu8IEs[index + 5] == 0x01))) {
4839                                u16 rsnIndex = index;
4840
4841                                if (pu8IEs[rsnIndex] == RSN_IE) {
4842                                        pNewJoinBssParam->mode_802_11i = 2;
4843                                } else {
4844                                        if (pNewJoinBssParam->mode_802_11i == 0)
4845                                                pNewJoinBssParam->mode_802_11i = 1;
4846                                        rsnIndex += 4;
4847                                }
4848
4849                                rsnIndex += 7;
4850                                pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
4851                                rsnIndex++;
4852                                jumpOffset = pu8IEs[rsnIndex] * 4;
4853                                pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4854                                rsnIndex += 2;
4855
4856                                for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++)
4857                                        pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4858
4859                                pcipherTotalCount += pcipherCount;
4860                                rsnIndex += jumpOffset;
4861
4862                                jumpOffset = pu8IEs[rsnIndex] * 4;
4863
4864                                authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
4865                                rsnIndex += 2;
4866
4867                                for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++)
4868                                        pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
4869
4870                                authTotalCount += authCount;
4871                                rsnIndex += jumpOffset;
4872
4873                                if (pu8IEs[index] == RSN_IE) {
4874                                        pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
4875                                        pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
4876                                        rsnIndex += 2;
4877                                }
4878                                pNewJoinBssParam->rsn_found = true;
4879                                index += pu8IEs[index + 1] + 2;
4880                                continue;
4881                        } else
4882                                index += pu8IEs[index + 1] + 2;
4883                }
4884        }
4885
4886        return (void *)pNewJoinBssParam;
4887}
4888
4889void host_int_freeJoinParams(void *pJoinParams)
4890{
4891        if ((struct bss_param *)pJoinParams)
4892                kfree((struct bss_param *)pJoinParams);
4893        else
4894                PRINT_ER("Unable to FREE null pointer\n");
4895}
4896
4897s32 host_int_delBASession(struct host_if_drv *hif_drv, char *pBSSID, char TID)
4898{
4899        s32 result = 0;
4900        struct host_if_msg msg;
4901        struct ba_session_info *pBASessionInfo = &msg.body.session_info;
4902
4903        if (!hif_drv) {
4904                PRINT_ER("driver is null\n");
4905                return -EFAULT;
4906        }
4907
4908        memset(&msg, 0, sizeof(struct host_if_msg));
4909
4910        msg.id = HOST_IF_MSG_DEL_BA_SESSION;
4911
4912        memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4913        pBASessionInfo->u8Ted = TID;
4914        msg.drv = hif_drv;
4915
4916        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4917        if (result)
4918                PRINT_ER("wilc_mq_send fail\n");
4919
4920        down(&hif_sema_wait_response);
4921
4922        return result;
4923}
4924
4925s32 host_int_del_All_Rx_BASession(struct host_if_drv *hif_drv,
4926                                  char *pBSSID,
4927                                  char TID)
4928{
4929        s32 result = 0;
4930        struct host_if_msg msg;
4931        struct ba_session_info *pBASessionInfo = &msg.body.session_info;
4932
4933        if (!hif_drv) {
4934                PRINT_ER("driver is null\n");
4935                return -EFAULT;
4936        }
4937
4938        memset(&msg, 0, sizeof(struct host_if_msg));
4939
4940        msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS;
4941
4942        memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
4943        pBASessionInfo->u8Ted = TID;
4944        msg.drv = hif_drv;
4945
4946        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4947        if (result)
4948                PRINT_ER("wilc_mq_send fail\n");
4949
4950        down(&hif_sema_wait_response);
4951
4952        return result;
4953}
4954
4955s32 host_int_setup_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
4956{
4957        s32 result = 0;
4958        struct host_if_msg msg;
4959
4960        return 0;
4961
4962        if (!hif_drv) {
4963                PRINT_ER("driver is null\n");
4964                return -EFAULT;
4965        }
4966
4967        memset(&msg, 0, sizeof(struct host_if_msg));
4968
4969        msg.id = HOST_IF_MSG_SET_IPADDRESS;
4970
4971        msg.body.ip_info.ip_addr = u16ipadd;
4972        msg.drv = hif_drv;
4973        msg.body.ip_info.idx = idx;
4974
4975        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
4976        if (result)
4977                PRINT_ER("wilc_mq_send fail\n");
4978
4979        return result;
4980}
4981
4982s32 host_int_get_ipaddress(struct host_if_drv *hif_drv, u8 *u16ipadd, u8 idx)
4983{
4984        s32 result = 0;
4985        struct host_if_msg msg;
4986
4987        if (!hif_drv) {
4988                PRINT_ER("driver is null\n");
4989                return -EFAULT;
4990        }
4991
4992        memset(&msg, 0, sizeof(struct host_if_msg));
4993
4994        msg.id = HOST_IF_MSG_GET_IPADDRESS;
4995
4996        msg.body.ip_info.ip_addr = u16ipadd;
4997        msg.drv = hif_drv;
4998        msg.body.ip_info.idx = idx;
4999
5000        result = wilc_mq_send(&hif_msg_q, &msg, sizeof(struct host_if_msg));
5001        if (result)
5002                PRINT_ER("wilc_mq_send fail\n");
5003
5004        return result;
5005}
5006