]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/wilc1000/host_interface.c
staging: wilc1000: rename s32Error in host_int_set_operation_mode
[karo-tx-linux.git] / drivers / staging / wilc1000 / host_interface.c
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
10 extern u8 connecting;
11
12 extern struct timer_list hDuringIpTimer;
13
14 extern u8 g_wilc_initialized;
15
16 /* Message types of the Host IF Message Queue*/
17 #define HOST_IF_MSG_SCAN                        0
18 #define HOST_IF_MSG_CONNECT                     1
19 #define HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO        2
20 #define HOST_IF_MSG_KEY                         3
21 #define HOST_IF_MSG_RCVD_NTWRK_INFO             4
22 #define HOST_IF_MSG_RCVD_SCAN_COMPLETE          5
23 #define HOST_IF_MSG_CFG_PARAMS                  6
24 #define HOST_IF_MSG_SET_CHANNEL                 7
25 #define HOST_IF_MSG_DISCONNECT                  8
26 #define HOST_IF_MSG_GET_RSSI                    9
27 #define HOST_IF_MSG_GET_CHNL                    10
28 #define HOST_IF_MSG_ADD_BEACON                  11
29 #define HOST_IF_MSG_DEL_BEACON                  12
30 #define HOST_IF_MSG_ADD_STATION                 13
31 #define HOST_IF_MSG_DEL_STATION                 14
32 #define HOST_IF_MSG_EDIT_STATION                15
33 #define HOST_IF_MSG_SCAN_TIMER_FIRED            16
34 #define HOST_IF_MSG_CONNECT_TIMER_FIRED         17
35 #define HOST_IF_MSG_POWER_MGMT                  18
36 #define HOST_IF_MSG_GET_INACTIVETIME            19
37 #define HOST_IF_MSG_REMAIN_ON_CHAN              20
38 #define HOST_IF_MSG_REGISTER_FRAME              21
39 #define HOST_IF_MSG_LISTEN_TIMER_FIRED          22
40 #define HOST_IF_MSG_GET_LINKSPEED               23
41 #define HOST_IF_MSG_SET_WFIDRV_HANDLER          24
42 #define HOST_IF_MSG_SET_MAC_ADDRESS             25
43 #define HOST_IF_MSG_GET_MAC_ADDRESS             26
44 #define HOST_IF_MSG_SET_OPERATION_MODE          27
45 #define HOST_IF_MSG_SET_IPADDRESS               28
46 #define HOST_IF_MSG_GET_IPADDRESS               29
47 #define HOST_IF_MSG_FLUSH_CONNECT               30
48 #define HOST_IF_MSG_GET_STATISTICS              31
49 #define HOST_IF_MSG_SET_MULTICAST_FILTER        32
50 #define HOST_IF_MSG_ADD_BA_SESSION              33
51 #define HOST_IF_MSG_DEL_BA_SESSION              34
52 #define HOST_IF_MSG_Q_IDLE                      35
53 #define HOST_IF_MSG_DEL_ALL_STA                 36
54 #define HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS      34
55 #define HOST_IF_MSG_EXIT                        100
56
57 #define HOST_IF_SCAN_TIMEOUT                    4000
58 #define HOST_IF_CONNECT_TIMEOUT                 9500
59
60 #define BA_SESSION_DEFAULT_BUFFER_SIZE          16
61 #define BA_SESSION_DEFAULT_TIMEOUT              1000
62 #define BLOCK_ACK_REQ_SIZE                      0x14
63
64 /*!
65  *  @struct             cfg_param_attr
66  *  @brief              Structure to hold Host IF CFG Params Attributes
67  *  @details
68  *  @todo
69  *  @sa
70  *  @author             Mai Daftedar
71  *  @date               02 April 2012
72  *  @version            1.0
73  */
74 struct cfg_param_attr {
75         struct cfg_param_val pstrCfgParamVal;
76 };
77
78 /*!
79  *  @struct             host_if_wpa_attr
80  *  @brief              Structure to hold Host IF Scan Attributes
81  *  @details
82  *  @todo
83  *  @sa
84  *  @author             Mai Daftedar
85  *  @date               25 March 2012
86  *  @version            1.0
87  */
88 struct host_if_wpa_attr {
89         u8 *pu8key;
90         const u8 *pu8macaddr;
91         u8 *pu8seq;
92         u8 u8seqlen;
93         u8 u8keyidx;
94         u8 u8Keylen;
95         u8 u8Ciphermode;
96 };
97
98
99 /*!
100  *  @struct             host_if_wep_attr
101  *  @brief              Structure to hold Host IF Scan Attributes
102  *  @details
103  *  @todo
104  *  @sa
105  *  @author             Mai Daftedar
106  *  @date               25 March 2012
107  *  @version            1.0
108  */
109 struct host_if_wep_attr {
110         u8 *pu8WepKey;
111         u8 u8WepKeylen;
112         u8 u8Wepidx;
113         u8 u8mode;
114         enum AUTHTYPE tenuAuth_type;
115 };
116
117 /*!
118  *  @struct             host_if_key_attr
119  *  @brief              Structure to hold Host IF Scan Attributes
120  *  @details
121  *  @todo
122  *  @sa
123  *  @author             Mai Daftedar
124  *  @date               25 March 2012
125  *  @version            1.0
126  */
127 union host_if_key_attr {
128         struct host_if_wep_attr strHostIFwepAttr;
129         struct host_if_wpa_attr strHostIFwpaAttr;
130         struct host_if_pmkid_attr strHostIFpmkidAttr;
131 };
132
133 /*!
134  *  @struct             key_attr
135  *  @brief              Structure to hold Host IF Scan Attributes
136  *  @details
137  *  @todo
138  *  @sa
139  *  @author             Mai Daftedar
140  *  @date               25 March 2012
141  *  @version            1.0
142  */
143 struct key_attr {
144         enum KEY_TYPE enuKeyType;
145         u8 u8KeyAction;
146         union host_if_key_attr uniHostIFkeyAttr;
147 };
148
149
150
151
152 /*!
153  *  @struct             scan_attr
154  *  @brief              Structure to hold Host IF Scan Attributes
155  *  @details
156  *  @todo
157  *  @sa
158  *  @author             Mostafa Abu Bakr
159  *  @date               25 March 2012
160  *  @version            1.0
161  */
162 struct scan_attr {
163         u8 u8ScanSource;
164         u8 u8ScanType;
165         u8 *pu8ChnlFreqList;
166         u8 u8ChnlListLen;
167         u8 *pu8IEs;
168         size_t IEsLen;
169         wilc_scan_result pfScanResult;
170         void *pvUserArg;
171         struct hidden_network strHiddenNetwork;
172 };
173
174 /*!
175  *  @struct             connect_attr
176  *  @brief              Structure to hold Host IF Connect Attributes
177  *  @details
178  *  @todo
179  *  @sa
180  *  @author             Mostafa Abu Bakr
181  *  @date               25 March 2012
182  *  @version            1.0
183  */
184 struct connect_attr {
185         u8 *pu8bssid;
186         u8 *pu8ssid;
187         size_t ssidLen;
188         u8 *pu8IEs;
189         size_t IEsLen;
190         u8 u8security;
191         wilc_connect_result pfConnectResult;
192         void *pvUserArg;
193         enum AUTHTYPE tenuAuth_type;
194         u8 u8channel;
195         void *pJoinParams;
196 };
197
198 /*!
199  *  @struct             rcvd_async_info
200  *  @brief              Structure to hold Received General Asynchronous info
201  *  @details
202  *  @todo
203  *  @sa
204  *  @author             Mostafa Abu Bakr
205  *  @date               25 March 2012
206  *  @version            1.0
207  */
208 struct rcvd_async_info {
209         u8 *pu8Buffer;
210         u32 u32Length;
211 };
212
213 /*!
214  *  @struct             channel_attr
215  *  @brief              Set Channel  message body
216  *  @details
217  *  @todo
218  *  @sa
219  *  @author             Mai Daftedar
220  *  @date               25 March 2012
221  *  @version            1.0
222  */
223 struct channel_attr {
224         u8 u8SetChan;
225 };
226
227 /*!
228  *  @struct             tstrScanComplete
229  *  @brief                      hold received Async. Scan Complete message body
230  *  @details
231  *  @todo
232  *  @sa
233  *  @author             zsalah
234  *  @date               25 March 2012
235  *  @version            1.0
236  */
237 /*typedef struct _tstrScanComplete
238  * {
239  *      u8* pu8Buffer;
240  *      u32 u32Length;
241  * } tstrScanComplete;*/
242
243 /*!
244  *  @struct             beacon_attr
245  *  @brief              Set Beacon  message body
246  *  @details
247  *  @todo
248  *  @sa
249  *  @author             Adham Abozaeid
250  *  @date               10 July 2012
251  *  @version            1.0
252  */
253 struct beacon_attr {
254         u32 u32Interval;                        /*!< Beacon Interval. Period between two successive beacons on air  */
255         u32 u32DTIMPeriod;              /*!< DTIM Period. Indicates how many Beacon frames
256                                                                                         *                              (including the current frame) appear before the next DTIM                */
257         u32 u32HeadLen;                         /*!< Length of the head buffer in bytes         */
258         u8 *pu8Head;                    /*!< Pointer to the beacon's head buffer. Beacon's head is the part
259                                                                                         *              from the beacon's start till the TIM element, NOT including the TIM              */
260         u32 u32TailLen;                         /*!< Length of the tail buffer in bytes */
261         u8 *pu8Tail;                    /*!< Pointer to the beacon's tail buffer. Beacon's tail starts just
262                                                                                         *                              after the TIM inormation element */
263 };
264
265 /*!
266  *  @struct             set_multicast
267  *  @brief              set Multicast filter Address
268  *  @details
269  *  @todo
270  *  @sa
271  *  @author             Abdelrahman Sobhy
272  *  @date               30 August 2013
273  *  @version            1.0 Description
274  */
275
276 struct set_multicast {
277         bool bIsEnabled;
278         u32 u32count;
279 };
280
281 /*!
282  *  @struct             del_all_sta
283  *  @brief              Deauth station message body
284  *  @details
285  *  @todo
286  *  @sa
287  *  @author             Mai Daftedar
288  *  @date               09 April 2014
289  *  @version            1.0 Description
290  */
291 struct del_all_sta {
292         u8 au8Sta_DelAllSta[MAX_NUM_STA][ETH_ALEN];
293         u8 u8Num_AssocSta;
294 };
295
296 /*!
297  *  @struct             del_sta
298  *  @brief              Delete station message body
299  *  @details
300  *  @todo
301  *  @sa
302  *  @author             Adham Abozaeid
303  *  @date               15 July 2012
304  *  @version            1.0 Description
305  */
306 struct del_sta {
307         u8 au8MacAddr[ETH_ALEN];
308 };
309
310 /*!
311  *  @struct     power_mgmt_param
312  *  @brief              Power management message body
313  *  @details
314  *  @todo
315  *  @sa
316  *  @author             Adham Abozaeid
317  *  @date               24 November 2012
318  *  @version            1.0
319  */
320 struct power_mgmt_param {
321
322         bool bIsEnabled;
323         u32 u32Timeout;
324 };
325
326 /*!
327  *  @struct             set_ip_addr
328  *  @brief              set IP Address message body
329  *  @details
330  *  @todo
331  *  @sa
332  *  @author             Abdelrahman Sobhy
333  *  @date               30 August 2013
334  *  @version            1.0 Description
335  */
336 struct set_ip_addr {
337         u8 *au8IPAddr;
338         u8 idx;
339 };
340
341 /*!
342  *  @struct     sta_inactive_t
343  *  @brief              Get station message body
344  *  @details
345  *  @todo
346  *  @sa
347  *  @author         Mai Daftedar
348  *  @date               16 April 2013
349  *  @version            1.0
350  */
351 struct sta_inactive_t {
352         u8 mac[6];
353 };
354 /**/
355 /*!
356  *  @union              message_body
357  *  @brief              Message body for the Host Interface message_q
358  *  @details
359  *  @todo
360  *  @sa
361  *  @author             Mostafa Abu Bakr
362  *  @date               25 March 2012
363  *  @version            1.0
364  */
365 union message_body {
366         struct scan_attr scan_info;
367         struct connect_attr con_info;
368         struct rcvd_net_info net_info;
369         struct rcvd_async_info async_info;
370         struct key_attr key_info;
371         struct cfg_param_attr cfg_info;
372         struct channel_attr channel_info;
373         struct beacon_attr beacon_info;
374         struct add_sta_param add_sta_info;
375         struct del_sta del_sta_info;
376         struct add_sta_param edit_sta_info;
377         struct power_mgmt_param pwr_mgmt_info;
378         struct sta_inactive_t mac_info;
379         struct set_ip_addr ip_info;
380         struct drv_handler drv;
381         struct set_multicast multicast_info;
382         struct op_mode mode;
383         struct set_mac_addr set_mac_info;
384         struct get_mac_addr get_mac_info;
385         struct ba_session_info session_info;
386         struct remain_ch remain_on_ch;
387         struct reg_frame reg_frame;
388         char *data;
389         struct del_all_sta del_all_sta_info;
390 };
391
392 /*!
393  *  @struct             struct host_if_msg
394  *  @brief              Host Interface message
395  *  @details
396  *  @todo
397  *  @sa
398  *  @author             Mostafa Abu Bakr
399  *  @date               25 March 2012
400  *  @version            1.0
401  */
402 struct host_if_msg {
403         u16 id;                                           /*!< Message ID */
404         union message_body body;             /*!< Message body */
405         tstrWILC_WFIDrv *drvHandler;
406 };
407
408 typedef struct _tstrWidJoinReqExt {
409         char SSID[MAX_SSID_LEN];
410         u8 u8channel;
411         u8 BSSID[6];
412 } tstrWidJoinReqExt;
413
414 /*Struct containg joinParam of each AP*/
415 typedef struct _tstrJoinBssParam {
416         BSSTYPE_T bss_type;
417         u8 dtim_period;
418         u16 beacon_period;
419         u16 cap_info;
420         u8 au8bssid[6];
421         char ssid[MAX_SSID_LEN];
422         u8 ssidLen;
423         u8 supp_rates[MAX_RATES_SUPPORTED + 1];
424         u8 ht_capable;
425         u8 wmm_cap;
426         u8 uapsd_cap;
427         bool rsn_found;
428         u8 rsn_grp_policy;
429         u8 mode_802_11i;
430         u8 rsn_pcip_policy[3];
431         u8 rsn_auth_policy[3];
432         u8 rsn_cap[2];
433         struct _tstrJoinParam *nextJoinBss;
434         u32 tsf;
435         u8 u8NoaEnbaled;
436         u8 u8OppEnable;
437         u8 u8CtWindow;
438         u8 u8Count;
439         u8 u8Index;
440         u8 au8Duration[4];
441         u8 au8Interval[4];
442         u8 au8StartTime[4];
443 } tstrJoinBssParam;
444 /*a linked list table containing needed join parameters entries for each AP found in most recent scan*/
445 typedef struct _tstrBssTable {
446         u8 u8noBssEntries;
447         tstrJoinBssParam *head;
448         tstrJoinBssParam *tail;
449 } tstrBssTable;
450
451 typedef enum {
452         SCAN_TIMER = 0,
453         CONNECT_TIMER   = 1,
454         SCAN_CONNECT_TIMER_FORCE_32BIT = 0xFFFFFFFF
455 } tenuScanConnTimer;
456
457 /*****************************************************************************/
458 /*                                                                                                                                                       */
459 /*                                                      Global Variabls                                                                  */
460 /*                                                                                                                                                       */
461 /*****************************************************************************/
462 /* Zero is not used, because a zero ID means termination */
463 static tstrWILC_WFIDrv *wfidrv_list[NUM_CONCURRENT_IFC + 1];
464 tstrWILC_WFIDrv *terminated_handle;
465 tstrWILC_WFIDrv *gWFiDrvHandle;
466 bool g_obtainingIP = false;
467 u8 P2P_LISTEN_STATE;
468 static struct task_struct *HostIFthreadHandler;
469 static WILC_MsgQueueHandle gMsgQHostIF;
470 static struct semaphore hSemHostIFthrdEnd;
471
472 struct semaphore hSemDeinitDrvHandle;
473 static struct semaphore hWaitResponse;
474 struct semaphore hSemHostIntDeinit;
475 struct timer_list g_hPeriodicRSSI;
476
477
478
479 u8 gau8MulticastMacAddrList[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
480
481 static u8 gapu8RcvdAssocResp[MAX_ASSOC_RESP_FRAME_SIZE];
482
483 bool gbScanWhileConnected = false;
484
485 static s8 gs8Rssi;
486 static s8 gs8lnkspd;
487 static u8 gu8Chnl;
488 static u8 gs8SetIP[2][4];
489 static u8 gs8GetIP[2][4];
490 static u32 gu32InactiveTime;
491 static u8 gu8DelBcn;
492 static u32 gu32WidConnRstHack;
493
494 u8 *gu8FlushedJoinReq;
495 u8 *gu8FlushedInfoElemAsoc;
496 u8 gu8Flushed11iMode;
497 u8 gu8FlushedAuthType;
498 u32 gu32FlushedJoinReqSize;
499 u32 gu32FlushedInfoElemAsocSize;
500 tstrWILC_WFIDrv *gu8FlushedJoinReqDrvHandler;
501 #define REAL_JOIN_REQ 0
502 #define FLUSHED_JOIN_REQ 1
503 #define FLUSHED_BYTE_POS 79     /* Position the byte indicating flushing in the flushed request */
504
505 static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo);
506
507 extern void chip_sleep_manually(u32 u32SleepTime);
508 extern int linux_wlan_get_num_conn_ifcs(void);
509
510 static int add_handler_in_list(tstrWILC_WFIDrv *handler)
511 {
512         int i;
513
514         for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
515                 if (!wfidrv_list[i]) {
516                         wfidrv_list[i] = handler;
517                         return 0;
518                 }
519         }
520
521         return -ENOBUFS;
522 }
523
524 static int remove_handler_in_list(tstrWILC_WFIDrv *handler)
525 {
526         int i;
527
528         for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
529                 if (wfidrv_list[i] == handler) {
530                         wfidrv_list[i] = NULL;
531                         return 0;
532                 }
533         }
534
535         return -EINVAL;
536 }
537
538 static int get_id_from_handler(tstrWILC_WFIDrv *handler)
539 {
540         int i;
541
542         if (!handler)
543                 return 0;
544
545         for (i = 1; i < ARRAY_SIZE(wfidrv_list); i++) {
546                 if (wfidrv_list[i] == handler)
547                         return i;
548         }
549
550         return 0;
551 }
552
553 static tstrWILC_WFIDrv *get_handler_from_id(int id)
554 {
555         if (id <= 0 || id >= ARRAY_SIZE(wfidrv_list))
556                 return NULL;
557         return wfidrv_list[id];
558 }
559
560 /**
561  *  @brief Handle_SetChannel
562  *  @details    Sending config packet to firmware to set channel
563  *  @param[in]   struct channel_attr *pstrHostIFSetChan
564  *  @return     Error code.
565  *  @author
566  *  @date
567  *  @version    1.0
568  */
569 static s32 Handle_SetChannel(tstrWILC_WFIDrv *drvHandler,
570                              struct channel_attr *pstrHostIFSetChan)
571 {
572
573         s32 s32Error = 0;
574         tstrWID strWID;
575         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
576
577         /*prepare configuration packet*/
578         strWID.u16WIDid = (u16)WID_CURRENT_CHANNEL;
579         strWID.enuWIDtype = WID_CHAR;
580         strWID.ps8WidVal = (char *)&(pstrHostIFSetChan->u8SetChan);
581         strWID.s32ValueSize = sizeof(char);
582
583         PRINT_D(HOSTINF_DBG, "Setting channel\n");
584         /*Sending Cfg*/
585         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
586                                    get_id_from_handler(pstrWFIDrv));
587         if (s32Error) {
588                 PRINT_ER("Failed to set channel\n");
589                 return -EINVAL;
590         }
591
592         return s32Error;
593 }
594 /**
595  *  @brief Handle_SetWfiDrvHandler
596  *  @details    Sending config packet to firmware to set driver handler
597  *  @param[in]   void * drvHandler,
598  *               struct drv_handler *pstrHostIfSetDrvHandler
599  *  @return     Error code.
600  *  @author
601  *  @date
602  *  @version    1.0
603  */
604 static s32 Handle_SetWfiDrvHandler(tstrWILC_WFIDrv *drvHandler,
605                                    struct drv_handler *pstrHostIfSetDrvHandler)
606 {
607
608         s32 s32Error = 0;
609         tstrWID strWID;
610         tstrWILC_WFIDrv *pstrWFIDrv = drvHandler;
611
612
613         /*prepare configuration packet*/
614         strWID.u16WIDid = (u16)WID_SET_DRV_HANDLER;
615         strWID.enuWIDtype = WID_INT;
616         strWID.ps8WidVal = (s8 *)&(pstrHostIfSetDrvHandler->u32Address);
617         strWID.s32ValueSize = sizeof(u32);
618
619         /*Sending Cfg*/
620
621         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
622                                    pstrHostIfSetDrvHandler->u32Address);
623
624         if (pstrWFIDrv == NULL)
625                 up(&hSemDeinitDrvHandle);
626
627
628         if (s32Error) {
629                 PRINT_ER("Failed to set driver handler\n");
630                 return -EINVAL;
631         }
632
633         return s32Error;
634 }
635
636 /**
637  *  @brief Handle_SetWfiAPDrvHandler
638  *  @details    Sending config packet to firmware to set driver handler
639  *  @param[in]   void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler
640  *  @return     Error code.
641  *  @author
642  *  @date
643  *  @version    1.0
644  */
645 static s32 Handle_SetOperationMode(tstrWILC_WFIDrv *drvHandler,
646                                    struct op_mode *pstrHostIfSetOperationMode)
647 {
648
649         s32 s32Error = 0;
650         tstrWID strWID;
651         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
652
653
654         /*prepare configuration packet*/
655         strWID.u16WIDid = (u16)WID_SET_OPERATION_MODE;
656         strWID.enuWIDtype = WID_INT;
657         strWID.ps8WidVal = (s8 *)&(pstrHostIfSetOperationMode->u32Mode);
658         strWID.s32ValueSize = sizeof(u32);
659
660         /*Sending Cfg*/
661         PRINT_INFO(HOSTINF_DBG, "pstrWFIDrv= %p\n", pstrWFIDrv);
662
663         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
664                                    get_id_from_handler(pstrWFIDrv));
665
666
667         if ((pstrHostIfSetOperationMode->u32Mode) == IDLE_MODE)
668                 up(&hSemDeinitDrvHandle);
669
670
671         if (s32Error) {
672                 PRINT_ER("Failed to set driver handler\n");
673                 return -EINVAL;
674         }
675
676         return s32Error;
677 }
678
679 /**
680  *  @brief host_int_set_IPAddress
681  *  @details       Setting IP address params in message queue
682  *  @param[in]    WILC_WFIDrvHandle hWFIDrv, u8* pu8IPAddr
683  *  @return         Error code.
684  *  @author
685  *  @date
686  *  @version    1.0
687  */
688 s32 Handle_set_IPAddress(tstrWILC_WFIDrv *drvHandler, u8 *pu8IPAddr, u8 idx)
689 {
690
691         s32 s32Error = 0;
692         tstrWID strWID;
693         char firmwareIPAddress[4] = {0};
694         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
695
696         if (pu8IPAddr[0] < 192)
697                 pu8IPAddr[0] = 0;
698
699         PRINT_INFO(HOSTINF_DBG, "Indx = %d, Handling set  IP = %pI4\n", idx, pu8IPAddr);
700
701         memcpy(gs8SetIP[idx], pu8IPAddr, IP_ALEN);
702
703         /*prepare configuration packet*/
704         strWID.u16WIDid = (u16)WID_IP_ADDRESS;
705         strWID.enuWIDtype = WID_STR;
706         strWID.ps8WidVal = (u8 *)pu8IPAddr;
707         strWID.s32ValueSize = IP_ALEN;
708
709         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
710                                    get_id_from_handler(pstrWFIDrv));
711
712
713         host_int_get_ipaddress(drvHandler, firmwareIPAddress, idx);
714
715         if (s32Error) {
716                 PRINT_ER("Failed to set IP address\n");
717                 return -EINVAL;
718         }
719
720         PRINT_INFO(HOSTINF_DBG, "IP address set\n");
721
722         return s32Error;
723 }
724
725
726 /**
727  *  @brief Handle_get_IPAddress
728  *  @details       Setting IP address params in message queue
729  *  @param[in]    WILC_WFIDrvHandle hWFIDrv, u8* pu8IPAddr
730  *  @return         Error code.
731  *  @author
732  *  @date
733  *  @version    1.0
734  */
735 s32 Handle_get_IPAddress(tstrWILC_WFIDrv *drvHandler, u8 *pu8IPAddr, u8 idx)
736 {
737
738         s32 s32Error = 0;
739         tstrWID strWID;
740         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
741
742         /*prepare configuration packet*/
743         strWID.u16WIDid = (u16)WID_IP_ADDRESS;
744         strWID.enuWIDtype = WID_STR;
745         strWID.ps8WidVal = kmalloc(IP_ALEN, GFP_KERNEL);
746         strWID.s32ValueSize = IP_ALEN;
747
748         s32Error = send_config_pkt(GET_CFG, &strWID, 1, true,
749                                    get_id_from_handler(pstrWFIDrv));
750
751         PRINT_INFO(HOSTINF_DBG, "%pI4\n", strWID.ps8WidVal);
752
753         memcpy(gs8GetIP[idx], strWID.ps8WidVal, IP_ALEN);
754
755         /*get the value by searching the local copy*/
756         kfree(strWID.ps8WidVal);
757
758         if (memcmp(gs8GetIP[idx], gs8SetIP[idx], IP_ALEN) != 0)
759                 host_int_setup_ipaddress(pstrWFIDrv, gs8SetIP[idx], idx);
760
761         if (s32Error != 0) {
762                 PRINT_ER("Failed to get IP address\n");
763                 return -EINVAL;
764         }
765
766         PRINT_INFO(HOSTINF_DBG, "IP address retrieved:: u8IfIdx = %d\n", idx);
767         PRINT_INFO(HOSTINF_DBG, "%pI4\n", gs8GetIP[idx]);
768         PRINT_INFO(HOSTINF_DBG, "\n");
769
770         return s32Error;
771 }
772
773
774 /**
775  *  @brief Handle_SetMacAddress
776  *  @details    Setting mac address
777  *  @param[in]   void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler
778  *  @return     Error code.
779  *  @author     Amr Abdel-Moghny
780  *  @date               November 2013
781  *  @version    7.0
782  */
783 static s32 Handle_SetMacAddress(tstrWILC_WFIDrv *drvHandler,
784                                 struct set_mac_addr *pstrHostIfSetMacAddress)
785 {
786
787         s32 s32Error = 0;
788         tstrWID strWID;
789         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
790         u8 *mac_buf = kmalloc(ETH_ALEN, GFP_KERNEL);
791
792         if (mac_buf == NULL) {
793                 PRINT_ER("No buffer to send mac address\n");
794                 return -EFAULT;
795         }
796         memcpy(mac_buf, pstrHostIfSetMacAddress->u8MacAddress, ETH_ALEN);
797
798         /*prepare configuration packet*/
799         strWID.u16WIDid = (u16)WID_MAC_ADDR;
800         strWID.enuWIDtype = WID_STR;
801         strWID.ps8WidVal = mac_buf;
802         strWID.s32ValueSize = ETH_ALEN;
803         PRINT_D(GENERIC_DBG, "mac addr = :%pM\n", strWID.ps8WidVal);
804         /*Sending Cfg*/
805         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
806                                    get_id_from_handler(pstrWFIDrv));
807         if (s32Error) {
808                 PRINT_ER("Failed to set mac address\n");
809                 s32Error = -EFAULT;
810         }
811
812         kfree(mac_buf);
813         return s32Error;
814 }
815
816
817 /**
818  *  @brief Handle_GetMacAddress
819  *  @details    Getting mac address
820  *  @param[in]   void * drvHandler,tstrHostIfSetDrvHandler* pstrHostIfSetDrvHandler
821  *  @return     Error code.
822  *  @author     Amr Abdel-Moghny
823  *  @date               JAN 2013
824  *  @version    8.0
825  */
826 static s32 Handle_GetMacAddress(tstrWILC_WFIDrv *drvHandler,
827                                 struct get_mac_addr *pstrHostIfGetMacAddress)
828 {
829
830         s32 s32Error = 0;
831         tstrWID strWID;
832
833         /*prepare configuration packet*/
834         strWID.u16WIDid = (u16)WID_MAC_ADDR;
835         strWID.enuWIDtype = WID_STR;
836         strWID.ps8WidVal = pstrHostIfGetMacAddress->u8MacAddress;
837         strWID.s32ValueSize = ETH_ALEN;
838
839         /*Sending Cfg*/
840         s32Error = send_config_pkt(GET_CFG, &strWID, 1, false,
841                                    get_id_from_handler(drvHandler));
842         if (s32Error) {
843                 PRINT_ER("Failed to get mac address\n");
844                 s32Error = -EFAULT;
845         }
846         up(&hWaitResponse);
847
848         return s32Error;
849 }
850
851
852 /**
853  *  @brief Handle_CfgParam
854  *  @details    Sending config packet to firmware to set CFG params
855  *  @param[in]   struct cfg_param_attr *strHostIFCfgParamAttr
856  *  @return     Error code.
857  *  @author
858  *  @date
859  *  @version    1.0
860  */
861 static s32 Handle_CfgParam(tstrWILC_WFIDrv *drvHandler,
862                            struct cfg_param_attr *strHostIFCfgParamAttr)
863 {
864         s32 s32Error = 0;
865         tstrWID strWIDList[32];
866         u8 u8WidCnt = 0;
867         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
868
869
870         down(&(pstrWFIDrv->gtOsCfgValuesSem));
871
872
873         PRINT_D(HOSTINF_DBG, "Setting CFG params\n");
874
875         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BSS_TYPE) {
876                 /*----------------------------------------------------------*/
877                 /*Input Value:  INFRASTRUCTURE = 1,                                                     */
878                 /*                              INDEPENDENT= 2,                                                         */
879                 /*                              ANY_BSS= 3                                                                      */
880                 /*----------------------------------------------------------*/
881                 /* validate input then copy>> need to check value 4 and 5 */
882                 if (strHostIFCfgParamAttr->pstrCfgParamVal.bss_type < 6) {
883                         strWIDList[u8WidCnt].u16WIDid = WID_BSS_TYPE;
884                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.bss_type;
885                         strWIDList[u8WidCnt].enuWIDtype = WID_CHAR;
886                         strWIDList[u8WidCnt].s32ValueSize = sizeof(char);
887                         pstrWFIDrv->strCfgValues.bss_type = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.bss_type;
888                 } else {
889                         PRINT_ER("check value 6 over\n");
890                         s32Error = -EINVAL;
891                         goto ERRORHANDLER;
892                 }
893                 u8WidCnt++;
894         }
895         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTH_TYPE) {
896                 /*------------------------------------------------------*/
897                 /*Input Values: OPEN_SYSTEM     = 0,                                    */
898                 /*                              SHARED_KEY      = 1,                                    */
899                 /*                              ANY             = 2                                             */
900                 /*------------------------------------------------------*/
901                 /*validate Possible values*/
902                 if ((strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 1 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 2 || (strHostIFCfgParamAttr->pstrCfgParamVal.auth_type) == 5) {
903                         strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TYPE;
904                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_type;
905                         strWIDList[u8WidCnt].enuWIDtype = WID_CHAR;
906                         strWIDList[u8WidCnt].s32ValueSize = sizeof(char);
907                         pstrWFIDrv->strCfgValues.auth_type = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.auth_type;
908                 } else {
909                         PRINT_ER("Impossible value \n");
910                         s32Error = -EINVAL;
911                         goto ERRORHANDLER;
912                 }
913                 u8WidCnt++;
914         }
915         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & AUTHEN_TIMEOUT) {
916                 /* range is 1 to 65535. */
917                 if (strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout < 65536) {
918                         strWIDList[u8WidCnt].u16WIDid = WID_AUTH_TIMEOUT;
919                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout;
920                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
921                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
922                         pstrWFIDrv->strCfgValues.auth_timeout = strHostIFCfgParamAttr->pstrCfgParamVal.auth_timeout;
923                 } else {
924                         PRINT_ER("Range(1 ~ 65535) over\n");
925                         s32Error = -EINVAL;
926                         goto ERRORHANDLER;
927                 }
928                 u8WidCnt++;
929         }
930         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & POWER_MANAGEMENT) {
931                 /*-----------------------------------------------------------*/
932                 /*Input Values: NO_POWERSAVE     = 0,                                           */
933                 /*                              MIN_FAST_PS      = 1,                                           */
934                 /*                              MAX_FAST_PS      = 2,                                           */
935                 /*                              MIN_PSPOLL_PS    = 3,                                           */
936                 /*                              MAX_PSPOLL_PS    = 4                                            */
937                 /*----------------------------------------------------------*/
938                 if (strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode < 5) {
939                         strWIDList[u8WidCnt].u16WIDid = WID_POWER_MANAGEMENT;
940                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode;
941                         strWIDList[u8WidCnt].enuWIDtype = WID_CHAR;
942                         strWIDList[u8WidCnt].s32ValueSize = sizeof(char);
943                         pstrWFIDrv->strCfgValues.power_mgmt_mode = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.power_mgmt_mode;
944                 } else {
945                         PRINT_ER("Invalide power mode\n");
946                         s32Error = -EINVAL;
947                         goto ERRORHANDLER;
948                 }
949                 u8WidCnt++;
950         }
951         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_SHORT) {
952                 /* range from 1 to 256 */
953                 if ((strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit > 0) && (strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit < 256)) {
954                         strWIDList[u8WidCnt].u16WIDid = WID_SHORT_RETRY_LIMIT;
955                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit;
956                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
957                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
958                         pstrWFIDrv->strCfgValues.short_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.short_retry_limit;
959                 } else {
960                         PRINT_ER("Range(1~256) over\n");
961                         s32Error = -EINVAL;
962                         goto ERRORHANDLER;
963                 }
964                 u8WidCnt++;
965         }
966         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RETRY_LONG) {
967                 /* range from 1 to 256 */
968                 if ((strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit > 0) && (strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit < 256)) {
969                         strWIDList[u8WidCnt].u16WIDid = WID_LONG_RETRY_LIMIT;
970                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit;
971
972                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
973                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
974                         pstrWFIDrv->strCfgValues.long_retry_limit = strHostIFCfgParamAttr->pstrCfgParamVal.long_retry_limit;
975                 } else {
976                         PRINT_ER("Range(1~256) over\n");
977                         s32Error = -EINVAL;
978                         goto ERRORHANDLER;
979                 }
980                 u8WidCnt++;
981         }
982         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & FRAG_THRESHOLD) {
983
984                 if (strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold > 255 && strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold < 7937) {
985                         strWIDList[u8WidCnt].u16WIDid = WID_FRAG_THRESHOLD;
986                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold;
987                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
988                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
989                         pstrWFIDrv->strCfgValues.frag_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.frag_threshold;
990                 } else {
991                         PRINT_ER("Threshold Range fail\n");
992                         s32Error = -EINVAL;
993                         goto ERRORHANDLER;
994                 }
995                 u8WidCnt++;
996         }
997         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & RTS_THRESHOLD) {
998                 /* range 256 to 65535 */
999                 if (strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold > 255 && strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold < 65536) {
1000                         strWIDList[u8WidCnt].u16WIDid = WID_RTS_THRESHOLD;
1001                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold;
1002                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
1003                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
1004                         pstrWFIDrv->strCfgValues.rts_threshold = strHostIFCfgParamAttr->pstrCfgParamVal.rts_threshold;
1005                 } else {
1006                         PRINT_ER("Threshold Range fail\n");
1007                         s32Error = -EINVAL;
1008                         goto ERRORHANDLER;
1009                 }
1010                 u8WidCnt++;
1011         }
1012         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PREAMBLE) {
1013                 /*-----------------------------------------------------*/
1014                 /*Input Values: Short= 0,                                                               */
1015                 /*                              Long= 1,                                */
1016                 /*                              Auto= 2                                                                 */
1017                 /*------------------------------------------------------*/
1018                 if (strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type < 3) {
1019                         strWIDList[u8WidCnt].u16WIDid = WID_PREAMBLE;
1020                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type;
1021                         strWIDList[u8WidCnt].enuWIDtype = WID_CHAR;
1022                         strWIDList[u8WidCnt].s32ValueSize = sizeof(char);
1023                         pstrWFIDrv->strCfgValues.preamble_type = strHostIFCfgParamAttr->pstrCfgParamVal.preamble_type;
1024                 } else {
1025                         PRINT_ER("Preamle Range(0~2) over\n");
1026                         s32Error = -EINVAL;
1027                         goto ERRORHANDLER;
1028                 }
1029                 u8WidCnt++;
1030         }
1031         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SHORT_SLOT_ALLOWED) {
1032                 if (strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed < 2) {
1033                         strWIDList[u8WidCnt].u16WIDid = WID_SHORT_SLOT_ALLOWED;
1034                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed;
1035                         strWIDList[u8WidCnt].enuWIDtype = WID_CHAR;
1036                         strWIDList[u8WidCnt].s32ValueSize = sizeof(char);
1037                         pstrWFIDrv->strCfgValues.short_slot_allowed = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.short_slot_allowed;
1038                 } else {
1039                         PRINT_ER("Short slot(2) over\n");
1040                         s32Error = -EINVAL;
1041                         goto ERRORHANDLER;
1042                 }
1043                 u8WidCnt++;
1044         }
1045         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & TXOP_PROT_DISABLE) {
1046                 /*Description:  used to Disable RTS-CTS protection for TXOP burst*/
1047                 /*transmission when the acknowledgement policy is No-Ack or Block-Ack   */
1048                 /* this information is useful for external supplicant                                   */
1049                 /*Input Values: 1 for enable and 0 for disable.                                                 */
1050                 if (strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled < 2) {
1051                         strWIDList[u8WidCnt].u16WIDid = WID_11N_TXOP_PROT_DISABLE;
1052                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled;
1053                         strWIDList[u8WidCnt].enuWIDtype = WID_CHAR;
1054                         strWIDList[u8WidCnt].s32ValueSize = sizeof(char);
1055                         pstrWFIDrv->strCfgValues.txop_prot_disabled = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.txop_prot_disabled;
1056                 } else {
1057                         PRINT_ER("TXOP prot disable\n");
1058                         s32Error = -EINVAL;
1059                         goto ERRORHANDLER;
1060                 }
1061                 u8WidCnt++;
1062         }
1063         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & BEACON_INTERVAL) {
1064                 /* range is 1 to 65535. */
1065                 if (strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval < 65536) {
1066                         strWIDList[u8WidCnt].u16WIDid = WID_BEACON_INTERVAL;
1067                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval;
1068                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
1069                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
1070                         pstrWFIDrv->strCfgValues.beacon_interval = strHostIFCfgParamAttr->pstrCfgParamVal.beacon_interval;
1071                 } else {
1072                         PRINT_ER("Beacon interval(1~65535) fail\n");
1073                         s32Error = -EINVAL;
1074                         goto ERRORHANDLER;
1075                 }
1076                 u8WidCnt++;
1077         }
1078         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & DTIM_PERIOD) {
1079                 /* range is 1 to 255. */
1080                 if (strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period < 256) {
1081                         strWIDList[u8WidCnt].u16WIDid = WID_DTIM_PERIOD;
1082                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period;
1083                         strWIDList[u8WidCnt].enuWIDtype = WID_CHAR;
1084                         strWIDList[u8WidCnt].s32ValueSize = sizeof(char);
1085                         pstrWFIDrv->strCfgValues.dtim_period = strHostIFCfgParamAttr->pstrCfgParamVal.dtim_period;
1086                 } else {
1087                         PRINT_ER("DTIM range(1~255) fail\n");
1088                         s32Error = -EINVAL;
1089                         goto ERRORHANDLER;
1090                 }
1091                 u8WidCnt++;
1092         }
1093         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY) {
1094                 /*----------------------------------------------------------------------*/
1095                 /*Input Values: SITE_SURVEY_1CH    = 0, i.e.: currently set channel             */
1096                 /*                              SITE_SURVEY_ALL_CH = 1,                                                                 */
1097                 /*                              SITE_SURVEY_OFF    = 2                                                                  */
1098                 /*----------------------------------------------------------------------*/
1099                 if (strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled < 3) {
1100                         strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY;
1101                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled;
1102                         strWIDList[u8WidCnt].enuWIDtype = WID_CHAR;
1103                         strWIDList[u8WidCnt].s32ValueSize = sizeof(char);
1104                         pstrWFIDrv->strCfgValues.site_survey_enabled = (u8)strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_enabled;
1105                 } else {
1106                         PRINT_ER("Site survey disable\n");
1107                         s32Error = -EINVAL;
1108                         goto ERRORHANDLER;
1109                 }
1110                 u8WidCnt++;
1111         }
1112         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & SITE_SURVEY_SCAN_TIME) {
1113                 /* range is 1 to 65535. */
1114                 if (strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time < 65536) {
1115                         strWIDList[u8WidCnt].u16WIDid = WID_SITE_SURVEY_SCAN_TIME;
1116                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time;
1117                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
1118                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
1119                         pstrWFIDrv->strCfgValues.site_survey_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.site_survey_scan_time;
1120                 } else {
1121                         PRINT_ER("Site survey scan time(1~65535) over\n");
1122                         s32Error = -EINVAL;
1123                         goto ERRORHANDLER;
1124                 }
1125                 u8WidCnt++;
1126         }
1127         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & ACTIVE_SCANTIME) {
1128                 /* range is 1 to 65535. */
1129                 if (strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time < 65536) {
1130                         strWIDList[u8WidCnt].u16WIDid = WID_ACTIVE_SCAN_TIME;
1131                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time;
1132                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
1133                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
1134                         pstrWFIDrv->strCfgValues.active_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.active_scan_time;
1135                 } else {
1136                         PRINT_ER("Active scan time(1~65535) over\n");
1137                         s32Error = -EINVAL;
1138                         goto ERRORHANDLER;
1139                 }
1140                 u8WidCnt++;
1141         }
1142         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & PASSIVE_SCANTIME) {
1143                 /* range is 1 to 65535. */
1144                 if (strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time > 0 && strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time < 65536) {
1145                         strWIDList[u8WidCnt].u16WIDid = WID_PASSIVE_SCAN_TIME;
1146                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time;
1147                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
1148                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
1149                         pstrWFIDrv->strCfgValues.passive_scan_time = strHostIFCfgParamAttr->pstrCfgParamVal.passive_scan_time;
1150                 } else {
1151                         PRINT_ER("Passive scan time(1~65535) over\n");
1152                         s32Error = -EINVAL;
1153                         goto ERRORHANDLER;
1154                 }
1155                 u8WidCnt++;
1156         }
1157         if (strHostIFCfgParamAttr->pstrCfgParamVal.u32SetCfgFlag & CURRENT_TX_RATE) {
1158                 enum CURRENT_TXRATE curr_tx_rate = strHostIFCfgParamAttr->pstrCfgParamVal.curr_tx_rate;
1159                 /*----------------------------------------------------------------------*/
1160                 /*Rates:                1   2   5.5   11   6  9  12  18  24  36  48   54  Auto  */
1161                 /*InputValues:  1   2     3    4   5  6   7   8   9  10  11   12  0             */
1162                 /*----------------------------------------------------------------------*/
1163                 /* validate rate */
1164                 if (curr_tx_rate == AUTORATE || curr_tx_rate == MBPS_1
1165                     || curr_tx_rate == MBPS_2 || curr_tx_rate == MBPS_5_5
1166                     || curr_tx_rate == MBPS_11 || curr_tx_rate == MBPS_6
1167                     || curr_tx_rate == MBPS_9 || curr_tx_rate == MBPS_12
1168                     || curr_tx_rate == MBPS_18 || curr_tx_rate == MBPS_24
1169                     || curr_tx_rate == MBPS_36 || curr_tx_rate == MBPS_48 || curr_tx_rate == MBPS_54) {
1170                         strWIDList[u8WidCnt].u16WIDid = WID_CURRENT_TX_RATE;
1171                         strWIDList[u8WidCnt].ps8WidVal = (s8 *)&curr_tx_rate;
1172                         strWIDList[u8WidCnt].enuWIDtype = WID_SHORT;
1173                         strWIDList[u8WidCnt].s32ValueSize = sizeof(u16);
1174                         pstrWFIDrv->strCfgValues.curr_tx_rate = (u8)curr_tx_rate;
1175                 } else {
1176                         PRINT_ER("out of TX rate\n");
1177                         s32Error = -EINVAL;
1178                         goto ERRORHANDLER;
1179                 }
1180                 u8WidCnt++;
1181         }
1182         s32Error = send_config_pkt(SET_CFG, strWIDList, u8WidCnt, false,
1183                                    get_id_from_handler(pstrWFIDrv));
1184
1185         if (s32Error)
1186                 PRINT_ER("Error in setting CFG params\n");
1187
1188 ERRORHANDLER:
1189         up(&(pstrWFIDrv->gtOsCfgValuesSem));
1190         return s32Error;
1191 }
1192
1193
1194 /**
1195  *  @brief Handle_wait_msg_q_empty
1196  *  @details       this should be the last msg and then the msg Q becomes idle
1197  *  @param[in]    tstrHostIFscanAttr* pstrHostIFscanAttr
1198  *  @return         Error code.
1199  *  @author
1200  *  @date
1201  *  @version    1.0
1202  */
1203 static s32 Handle_wait_msg_q_empty(void)
1204 {
1205         s32 s32Error = 0;
1206
1207         g_wilc_initialized = 0;
1208         up(&hWaitResponse);
1209         return s32Error;
1210 }
1211
1212 /**
1213  *  @brief Handle_Scan
1214  *  @details       Sending config packet to firmware to set the scan params
1215  *  @param[in]    struct scan_attr *pstrHostIFscanAttr
1216  *  @return         Error code.
1217  *  @author
1218  *  @date
1219  *  @version    1.0
1220  */
1221 static s32 Handle_Scan(tstrWILC_WFIDrv *drvHandler,
1222                        struct scan_attr *pstrHostIFscanAttr)
1223 {
1224         s32 s32Error = 0;
1225         tstrWID strWIDList[5];
1226         u32 u32WidsCount = 0;
1227         u32 i;
1228         u8 *pu8Buffer;
1229         u8 valuesize = 0;
1230         u8 *pu8HdnNtwrksWidVal = NULL;
1231         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler;
1232
1233         PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
1234         PRINT_D(HOSTINF_DBG, "Scanning: In [%d] state\n", pstrWFIDrv->enuHostIFstate);
1235
1236         pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = pstrHostIFscanAttr->pfScanResult;
1237         pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid = pstrHostIFscanAttr->pvUserArg;
1238
1239         if ((pstrWFIDrv->enuHostIFstate >= HOST_IF_SCANNING) && (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTED)) {
1240                 /* here we either in HOST_IF_SCANNING, HOST_IF_WAITING_CONN_REQ or HOST_IF_WAITING_CONN_RESP */
1241                 PRINT_D(GENERIC_DBG, "Don't scan we are already in [%d] state\n", pstrWFIDrv->enuHostIFstate);
1242                 PRINT_ER("Already scan\n");
1243                 s32Error = -EBUSY;
1244                 goto ERRORHANDLER;
1245         }
1246
1247         if (g_obtainingIP || connecting) {
1248                 PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
1249                 PRINT_ER("Don't do obss scan\n");
1250                 s32Error = -EBUSY;
1251                 goto ERRORHANDLER;
1252         }
1253
1254         PRINT_D(HOSTINF_DBG, "Setting SCAN params\n");
1255
1256
1257         pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount = 0;
1258
1259         strWIDList[u32WidsCount].u16WIDid = (u16)WID_SSID_PROBE_REQ;
1260         strWIDList[u32WidsCount].enuWIDtype = WID_STR;
1261
1262         for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++)
1263                 valuesize += ((pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen) + 1);
1264         pu8HdnNtwrksWidVal = kmalloc(valuesize + 1, GFP_KERNEL);
1265         strWIDList[u32WidsCount].ps8WidVal = pu8HdnNtwrksWidVal;
1266         if (strWIDList[u32WidsCount].ps8WidVal != NULL) {
1267                 pu8Buffer = strWIDList[u32WidsCount].ps8WidVal;
1268
1269                 *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum;
1270
1271                 PRINT_D(HOSTINF_DBG, "In Handle_ProbeRequest number of ssid %d\n", pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum);
1272
1273                 for (i = 0; i < pstrHostIFscanAttr->strHiddenNetwork.u8ssidnum; i++) {
1274                         *pu8Buffer++ = pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen;
1275                         memcpy(pu8Buffer, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen);
1276                         pu8Buffer += pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen;
1277                 }
1278
1279
1280
1281                 strWIDList[u32WidsCount].s32ValueSize =  (s32)(valuesize + 1);
1282                 u32WidsCount++;
1283         }
1284
1285         /*filling cfg param array*/
1286
1287         /* if((pstrHostIFscanAttr->pu8IEs != NULL) && (pstrHostIFscanAttr->IEsLen != 0)) */
1288         {
1289                 /* IEs to be inserted in Probe Request */
1290                 strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_PROBE;
1291                 strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
1292                 strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8IEs;
1293                 strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->IEsLen;
1294                 u32WidsCount++;
1295         }
1296
1297         /*Scan Type*/
1298         strWIDList[u32WidsCount].u16WIDid = WID_SCAN_TYPE;
1299         strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
1300         strWIDList[u32WidsCount].s32ValueSize = sizeof(char);
1301         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrHostIFscanAttr->u8ScanType));
1302         u32WidsCount++;
1303
1304         /*list of channels to be scanned*/
1305         strWIDList[u32WidsCount].u16WIDid = WID_SCAN_CHANNEL_LIST;
1306         strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
1307
1308         if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL && pstrHostIFscanAttr->u8ChnlListLen > 0) {
1309                 int i;
1310
1311                 for (i = 0; i < pstrHostIFscanAttr->u8ChnlListLen; i++) {
1312                         if (pstrHostIFscanAttr->pu8ChnlFreqList[i] > 0)
1313                                 pstrHostIFscanAttr->pu8ChnlFreqList[i] = pstrHostIFscanAttr->pu8ChnlFreqList[i] - 1;
1314                 }
1315         }
1316
1317         strWIDList[u32WidsCount].ps8WidVal = pstrHostIFscanAttr->pu8ChnlFreqList;
1318         strWIDList[u32WidsCount].s32ValueSize = pstrHostIFscanAttr->u8ChnlListLen;
1319         u32WidsCount++;
1320
1321         /*Scan Request*/
1322         strWIDList[u32WidsCount].u16WIDid = WID_START_SCAN_REQ;
1323         strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
1324         strWIDList[u32WidsCount].s32ValueSize = sizeof(char);
1325         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrHostIFscanAttr->u8ScanSource));
1326         u32WidsCount++;
1327
1328         /*keep the state as is , no need to change it*/
1329         /* gWFiDrvHandle->enuHostIFstate = HOST_IF_SCANNING; */
1330
1331         if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)
1332                 gbScanWhileConnected = true;
1333         else if (pstrWFIDrv->enuHostIFstate == HOST_IF_IDLE)
1334                 gbScanWhileConnected = false;
1335
1336         s32Error = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, false,
1337                                    get_id_from_handler(pstrWFIDrv));
1338
1339         if (s32Error)
1340                 PRINT_ER("Failed to send scan paramters config packet\n");
1341         else
1342                 PRINT_D(HOSTINF_DBG, "Successfully sent SCAN params config packet\n");
1343
1344 ERRORHANDLER:
1345         if (s32Error) {
1346                 del_timer(&pstrWFIDrv->hScanTimer);
1347                 /*if there is an ongoing scan request*/
1348                 Handle_ScanDone(drvHandler, SCAN_EVENT_ABORTED);
1349         }
1350
1351         /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */
1352         if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL) {
1353                 kfree(pstrHostIFscanAttr->pu8ChnlFreqList);
1354                 pstrHostIFscanAttr->pu8ChnlFreqList = NULL;
1355         }
1356
1357         /* Deallocate pstrHostIFscanAttr->pu8IEs which was previously allocated by the sending thread */
1358         if (pstrHostIFscanAttr->pu8IEs != NULL) {
1359                 kfree(pstrHostIFscanAttr->pu8IEs);
1360                 pstrHostIFscanAttr->pu8IEs = NULL;
1361         }
1362         if (pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo != NULL) {
1363                 kfree(pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo);
1364                 pstrHostIFscanAttr->strHiddenNetwork.pstrHiddenNetworkInfo = NULL;
1365         }
1366
1367         /* Deallocate pstrHostIFscanAttr->u8ChnlListLen which was prevoisuly allocated by the sending thread */
1368         if (pstrHostIFscanAttr->pu8ChnlFreqList != NULL) {
1369                 kfree(pstrHostIFscanAttr->pu8ChnlFreqList);
1370                 pstrHostIFscanAttr->pu8ChnlFreqList = NULL;
1371         }
1372
1373         if (pu8HdnNtwrksWidVal != NULL)
1374                 kfree(pu8HdnNtwrksWidVal);
1375
1376         return s32Error;
1377 }
1378
1379 /**
1380  *  @brief Handle_ScanDone
1381  *  @details       Call scan notification callback function
1382  *  @param[in]    NONE
1383  *  @return         Error code.
1384  *  @author
1385  *  @date
1386  *  @version    1.0
1387  */
1388 static s32 Handle_ScanDone(tstrWILC_WFIDrv *drvHandler, tenuScanEvent enuEvent)
1389 {
1390         s32 s32Error = 0;
1391
1392         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
1393
1394
1395         u8 u8abort_running_scan;
1396         tstrWID strWID;
1397
1398
1399         PRINT_D(HOSTINF_DBG, "in Handle_ScanDone()\n");
1400
1401         /*Ask FW to abort the running scan, if any*/
1402         if (enuEvent == SCAN_EVENT_ABORTED) {
1403                 PRINT_D(GENERIC_DBG, "Abort running scan\n");
1404                 u8abort_running_scan = 1;
1405                 strWID.u16WIDid = (u16)WID_ABORT_RUNNING_SCAN;
1406                 strWID.enuWIDtype       = WID_CHAR;
1407                 strWID.ps8WidVal = (s8 *)&u8abort_running_scan;
1408                 strWID.s32ValueSize = sizeof(char);
1409
1410                 /*Sending Cfg*/
1411                 s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
1412                                            get_id_from_handler(pstrWFIDrv));
1413                 if (s32Error) {
1414                         PRINT_ER("Failed to set abort running scan\n");
1415                         s32Error = -EFAULT;
1416                 }
1417         }
1418
1419         if (pstrWFIDrv == NULL) {
1420                 PRINT_ER("Driver handler is NULL\n");
1421                 return s32Error;
1422         }
1423
1424         /*if there is an ongoing scan request*/
1425         if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) {
1426                 pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(enuEvent, NULL,
1427                                                                 pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
1428                 /*delete current scan request*/
1429                 pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = NULL;
1430         }
1431
1432         return s32Error;
1433 }
1434
1435 /**
1436  *  @brief Handle_Connect
1437  *  @details       Sending config packet to firmware to starting connection
1438  *  @param[in]    struct connect_attr *pstrHostIFconnectAttr
1439  *  @return         Error code.
1440  *  @author
1441  *  @date
1442  *  @version    1.0
1443  */
1444 u8 u8ConnectedSSID[6] = {0};
1445 static s32 Handle_Connect(tstrWILC_WFIDrv *drvHandler,
1446                           struct connect_attr *pstrHostIFconnectAttr)
1447 {
1448         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler;
1449         s32 s32Error = 0;
1450         tstrWID strWIDList[8];
1451         u32 u32WidsCount = 0, dummyval = 0;
1452         /* char passphrase[] = "12345678"; */
1453         u8 *pu8CurrByte = NULL;
1454         tstrJoinBssParam *ptstrJoinBssParam;
1455
1456         PRINT_D(GENERIC_DBG, "Handling connect request\n");
1457
1458         /* if we try to connect to an already connected AP then discard the request */
1459
1460         if (memcmp(pstrHostIFconnectAttr->pu8bssid, u8ConnectedSSID, ETH_ALEN) == 0) {
1461
1462                 s32Error = 0;
1463                 PRINT_ER("Trying to connect to an already connected AP, Discard connect request\n");
1464                 return s32Error;
1465         }
1466
1467         PRINT_INFO(HOSTINF_DBG, "Saving connection parameters in global structure\n");
1468
1469         ptstrJoinBssParam = (tstrJoinBssParam *)pstrHostIFconnectAttr->pJoinParams;
1470         if (ptstrJoinBssParam == NULL) {
1471                 PRINT_ER("Required BSSID not found\n");
1472                 s32Error = -ENOENT;
1473                 goto ERRORHANDLER;
1474         }
1475
1476         if (pstrHostIFconnectAttr->pu8bssid != NULL) {
1477                 pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = kmalloc(6, GFP_KERNEL);
1478                 memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, pstrHostIFconnectAttr->pu8bssid, 6);
1479         }
1480
1481         pstrWFIDrv->strWILC_UsrConnReq.ssidLen = pstrHostIFconnectAttr->ssidLen;
1482         if (pstrHostIFconnectAttr->pu8ssid != NULL) {
1483                 pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = kmalloc(pstrHostIFconnectAttr->ssidLen + 1, GFP_KERNEL);
1484                 memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->pu8ssid,
1485                             pstrHostIFconnectAttr->ssidLen);
1486                 pstrWFIDrv->strWILC_UsrConnReq.pu8ssid[pstrHostIFconnectAttr->ssidLen] = '\0';
1487         }
1488
1489         pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = pstrHostIFconnectAttr->IEsLen;
1490         if (pstrHostIFconnectAttr->pu8IEs != NULL) {
1491                 pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = kmalloc(pstrHostIFconnectAttr->IEsLen, GFP_KERNEL);
1492                 memcpy(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs, pstrHostIFconnectAttr->pu8IEs,
1493                             pstrHostIFconnectAttr->IEsLen);
1494         }
1495
1496         pstrWFIDrv->strWILC_UsrConnReq.u8security = pstrHostIFconnectAttr->u8security;
1497         pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type = pstrHostIFconnectAttr->tenuAuth_type;
1498         pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult = pstrHostIFconnectAttr->pfConnectResult;
1499         pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid = pstrHostIFconnectAttr->pvUserArg;
1500
1501         strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT;
1502         strWIDList[u32WidsCount].enuWIDtype = WID_INT;
1503         strWIDList[u32WidsCount].s32ValueSize = sizeof(u32);
1504         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(dummyval));
1505         u32WidsCount++;
1506
1507         strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT;
1508         strWIDList[u32WidsCount].enuWIDtype = WID_INT;
1509         strWIDList[u32WidsCount].s32ValueSize = sizeof(u32);
1510         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(dummyval));
1511         u32WidsCount++;
1512
1513         strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT;
1514         strWIDList[u32WidsCount].enuWIDtype = WID_INT;
1515         strWIDList[u32WidsCount].s32ValueSize = sizeof(u32);
1516         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(dummyval));
1517         u32WidsCount++;
1518
1519         /* if((gWFiDrvHandle->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) && */
1520         /* (gWFiDrvHandle->strWILC_UsrConnReq.ConnReqIEsLen != 0)) */
1521         {
1522                 /* IEs to be inserted in Association Request */
1523                 strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE;
1524                 strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
1525                 strWIDList[u32WidsCount].ps8WidVal = pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs;
1526                 strWIDList[u32WidsCount].s32ValueSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen;
1527                 u32WidsCount++;
1528
1529                 if (memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) {
1530
1531                         gu32FlushedInfoElemAsocSize = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen;
1532                         gu8FlushedInfoElemAsoc =  kmalloc(gu32FlushedInfoElemAsocSize, GFP_KERNEL);
1533                         memcpy(gu8FlushedInfoElemAsoc, pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs,
1534                                gu32FlushedInfoElemAsocSize);
1535                 }
1536         }
1537         strWIDList[u32WidsCount].u16WIDid = (u16)WID_11I_MODE;
1538         strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
1539         strWIDList[u32WidsCount].s32ValueSize = sizeof(char);
1540         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrWFIDrv->strWILC_UsrConnReq.u8security));
1541         u32WidsCount++;
1542
1543         if (memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7))
1544                 gu8Flushed11iMode = pstrWFIDrv->strWILC_UsrConnReq.u8security;
1545
1546         PRINT_INFO(HOSTINF_DBG, "Encrypt Mode = %x\n", pstrWFIDrv->strWILC_UsrConnReq.u8security);
1547
1548
1549         strWIDList[u32WidsCount].u16WIDid = (u16)WID_AUTH_TYPE;
1550         strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
1551         strWIDList[u32WidsCount].s32ValueSize = sizeof(char);
1552         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type);
1553         u32WidsCount++;
1554
1555         if (memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7))
1556                 gu8FlushedAuthType = (u8)pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type;
1557
1558         PRINT_INFO(HOSTINF_DBG, "Authentication Type = %x\n", pstrWFIDrv->strWILC_UsrConnReq.tenuAuth_type);
1559         /*
1560          * strWIDList[u32WidsCount].u16WIDid = (u16)WID_11I_PSK;
1561          * strWIDList[u32WidsCount].enuWIDtype = WID_STR;
1562          * strWIDList[u32WidsCount].s32ValueSize = sizeof(passphrase);
1563          * strWIDList[u32WidsCount].ps8WidVal = (s8*)(passphrase);
1564          * u32WidsCount++;
1565          */
1566
1567         PRINT_D(HOSTINF_DBG, "Connecting to network of SSID %s on channel %d\n",
1568                 pstrWFIDrv->strWILC_UsrConnReq.pu8ssid, pstrHostIFconnectAttr->u8channel);
1569
1570         strWIDList[u32WidsCount].u16WIDid = (u16)WID_JOIN_REQ_EXTENDED;
1571         strWIDList[u32WidsCount].enuWIDtype = WID_STR;
1572
1573         /*Sending NoA attributes during connection*/
1574         strWIDList[u32WidsCount].s32ValueSize = 112; /* 79; */
1575         strWIDList[u32WidsCount].ps8WidVal = kmalloc(strWIDList[u32WidsCount].s32ValueSize, GFP_KERNEL);
1576
1577         if (memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) {
1578                 gu32FlushedJoinReqSize = strWIDList[u32WidsCount].s32ValueSize;
1579                 gu8FlushedJoinReq = kmalloc(gu32FlushedJoinReqSize, GFP_KERNEL);
1580         }
1581         if (strWIDList[u32WidsCount].ps8WidVal == NULL) {
1582                 s32Error = -EFAULT;
1583                 goto ERRORHANDLER;
1584         }
1585
1586         pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal;
1587
1588
1589         if (pstrHostIFconnectAttr->pu8ssid != NULL) {
1590                 memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8ssid, pstrHostIFconnectAttr->ssidLen);
1591                 pu8CurrByte[pstrHostIFconnectAttr->ssidLen] = '\0';
1592         }
1593         pu8CurrByte += MAX_SSID_LEN;
1594
1595         /* BSS type*/
1596         *(pu8CurrByte++) = INFRASTRUCTURE;
1597         /* Channel*/
1598         if ((pstrHostIFconnectAttr->u8channel >= 1) && (pstrHostIFconnectAttr->u8channel <= 14)) {
1599                 *(pu8CurrByte++) = pstrHostIFconnectAttr->u8channel;
1600         } else {
1601                 PRINT_ER("Channel out of range\n");
1602                 *(pu8CurrByte++) = 0xFF;
1603         }
1604         /* Cap Info*/
1605         *(pu8CurrByte++)  = (ptstrJoinBssParam->cap_info) & 0xFF;
1606         *(pu8CurrByte++)  = ((ptstrJoinBssParam->cap_info) >> 8) & 0xFF;
1607         PRINT_D(HOSTINF_DBG, "* Cap Info %0x*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8)));
1608
1609         /* sa*/
1610         if (pstrHostIFconnectAttr->pu8bssid != NULL)
1611                 memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6);
1612         pu8CurrByte += 6;
1613
1614         /* bssid*/
1615         if (pstrHostIFconnectAttr->pu8bssid != NULL)
1616                 memcpy(pu8CurrByte, pstrHostIFconnectAttr->pu8bssid, 6);
1617         pu8CurrByte += 6;
1618
1619         /* Beacon Period*/
1620         *(pu8CurrByte++)  = (ptstrJoinBssParam->beacon_period) & 0xFF;
1621         *(pu8CurrByte++)  = ((ptstrJoinBssParam->beacon_period) >> 8) & 0xFF;
1622         PRINT_D(HOSTINF_DBG, "* Beacon Period %d*\n", (*(pu8CurrByte - 2) | ((*(pu8CurrByte - 1)) << 8)));
1623         /* DTIM Period*/
1624         *(pu8CurrByte++)  =  ptstrJoinBssParam->dtim_period;
1625         PRINT_D(HOSTINF_DBG, "* DTIM Period %d*\n", (*(pu8CurrByte - 1)));
1626         /* Supported rates*/
1627         memcpy(pu8CurrByte, ptstrJoinBssParam->supp_rates, MAX_RATES_SUPPORTED + 1);
1628         pu8CurrByte += (MAX_RATES_SUPPORTED + 1);
1629
1630         /* wmm cap*/
1631         *(pu8CurrByte++)  =  ptstrJoinBssParam->wmm_cap;
1632         PRINT_D(HOSTINF_DBG, "* wmm cap%d*\n", (*(pu8CurrByte - 1)));
1633         /* uapsd cap*/
1634         *(pu8CurrByte++)  = ptstrJoinBssParam->uapsd_cap;
1635
1636         /* ht cap*/
1637         *(pu8CurrByte++)  = ptstrJoinBssParam->ht_capable;
1638         /* copy this information to the user request */
1639         pstrWFIDrv->strWILC_UsrConnReq.IsHTCapable = ptstrJoinBssParam->ht_capable;
1640
1641         /* rsn found*/
1642         *(pu8CurrByte++)  =  ptstrJoinBssParam->rsn_found;
1643         PRINT_D(HOSTINF_DBG, "* rsn found %d*\n", *(pu8CurrByte - 1));
1644         /* rsn group policy*/
1645         *(pu8CurrByte++)  =  ptstrJoinBssParam->rsn_grp_policy;
1646         PRINT_D(HOSTINF_DBG, "* rsn group policy %0x*\n", (*(pu8CurrByte - 1)));
1647         /* mode_802_11i*/
1648         *(pu8CurrByte++) =  ptstrJoinBssParam->mode_802_11i;
1649         PRINT_D(HOSTINF_DBG, "* mode_802_11i %d*\n", (*(pu8CurrByte - 1)));
1650         /* rsn pcip policy*/
1651         memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_pcip_policy, sizeof(ptstrJoinBssParam->rsn_pcip_policy));
1652         pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_pcip_policy);
1653
1654         /* rsn auth policy*/
1655         memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_auth_policy, sizeof(ptstrJoinBssParam->rsn_auth_policy));
1656         pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_auth_policy);
1657
1658         /* rsn auth policy*/
1659         memcpy(pu8CurrByte, ptstrJoinBssParam->rsn_cap, sizeof(ptstrJoinBssParam->rsn_cap));
1660         pu8CurrByte += sizeof(ptstrJoinBssParam->rsn_cap);
1661
1662         *(pu8CurrByte++) = REAL_JOIN_REQ;
1663
1664         *(pu8CurrByte++) = ptstrJoinBssParam->u8NoaEnbaled;
1665         if (ptstrJoinBssParam->u8NoaEnbaled) {
1666                 PRINT_D(HOSTINF_DBG, "NOA present\n");
1667
1668                 *(pu8CurrByte++) = (ptstrJoinBssParam->tsf) & 0xFF;
1669                 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 8) & 0xFF;
1670                 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 16) & 0xFF;
1671                 *(pu8CurrByte++) = ((ptstrJoinBssParam->tsf) >> 24) & 0xFF;
1672
1673                 *(pu8CurrByte++) = ptstrJoinBssParam->u8Index;
1674
1675                 *(pu8CurrByte++) = ptstrJoinBssParam->u8OppEnable;
1676
1677                 if (ptstrJoinBssParam->u8OppEnable)
1678                         *(pu8CurrByte++) = ptstrJoinBssParam->u8CtWindow;
1679
1680                 *(pu8CurrByte++) = ptstrJoinBssParam->u8Count;
1681
1682                 memcpy(pu8CurrByte, ptstrJoinBssParam->au8Duration, sizeof(ptstrJoinBssParam->au8Duration));
1683
1684                 pu8CurrByte += sizeof(ptstrJoinBssParam->au8Duration);
1685
1686                 memcpy(pu8CurrByte, ptstrJoinBssParam->au8Interval, sizeof(ptstrJoinBssParam->au8Interval));
1687
1688                 pu8CurrByte += sizeof(ptstrJoinBssParam->au8Interval);
1689
1690                 memcpy(pu8CurrByte, ptstrJoinBssParam->au8StartTime, sizeof(ptstrJoinBssParam->au8StartTime));
1691
1692                 pu8CurrByte += sizeof(ptstrJoinBssParam->au8StartTime);
1693
1694         } else
1695                 PRINT_D(HOSTINF_DBG, "NOA not present\n");
1696
1697         /* keep the buffer at the start of the allocated pointer to use it with the free*/
1698         pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal;
1699         u32WidsCount++;
1700
1701         /* A temporary workaround to avoid handling the misleading MAC_DISCONNECTED raised from the
1702          *   firmware at chip reset when processing the WIDs of the Connect Request.
1703          *   (This workaround should be removed in the future when the Chip reset of the Connect WIDs is disabled) */
1704         /* ////////////////////// */
1705         gu32WidConnRstHack = 0;
1706         /* ////////////////////// */
1707
1708         if (memcmp("DIRECT-", pstrHostIFconnectAttr->pu8ssid, 7)) {
1709                 memcpy(gu8FlushedJoinReq, pu8CurrByte, gu32FlushedJoinReqSize);
1710                 gu8FlushedJoinReqDrvHandler = pstrWFIDrv;
1711         }
1712
1713         PRINT_D(GENERIC_DBG, "send HOST_IF_WAITING_CONN_RESP\n");
1714
1715         if (pstrHostIFconnectAttr->pu8bssid != NULL) {
1716                 memcpy(u8ConnectedSSID, pstrHostIFconnectAttr->pu8bssid, ETH_ALEN);
1717
1718                 PRINT_D(GENERIC_DBG, "save Bssid = %pM\n", pstrHostIFconnectAttr->pu8bssid);
1719                 PRINT_D(GENERIC_DBG, "save bssid = %pM\n", u8ConnectedSSID);
1720         }
1721
1722         s32Error = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, false,
1723                                    get_id_from_handler(pstrWFIDrv));
1724         if (s32Error) {
1725                 PRINT_ER("failed to send config packet\n");
1726                 s32Error = -EFAULT;
1727                 goto ERRORHANDLER;
1728         } else {
1729                 PRINT_D(GENERIC_DBG, "set HOST_IF_WAITING_CONN_RESP\n");
1730                 pstrWFIDrv->enuHostIFstate = HOST_IF_WAITING_CONN_RESP;
1731         }
1732
1733 ERRORHANDLER:
1734         if (s32Error) {
1735                 tstrConnectInfo strConnectInfo;
1736
1737                 del_timer(&pstrWFIDrv->hConnectTimer);
1738
1739                 PRINT_D(HOSTINF_DBG, "could not start connecting to the required network\n");
1740
1741                 memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
1742
1743                 if (pstrHostIFconnectAttr->pfConnectResult != NULL) {
1744                         if (pstrHostIFconnectAttr->pu8bssid != NULL)
1745                                 memcpy(strConnectInfo.au8bssid, pstrHostIFconnectAttr->pu8bssid, 6);
1746
1747                         if (pstrHostIFconnectAttr->pu8IEs != NULL) {
1748                                 strConnectInfo.ReqIEsLen = pstrHostIFconnectAttr->IEsLen;
1749                                 strConnectInfo.pu8ReqIEs = kmalloc(pstrHostIFconnectAttr->IEsLen, GFP_KERNEL);
1750                                 memcpy(strConnectInfo.pu8ReqIEs,
1751                                             pstrHostIFconnectAttr->pu8IEs,
1752                                             pstrHostIFconnectAttr->IEsLen);
1753                         }
1754
1755                         pstrHostIFconnectAttr->pfConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
1756                                                                &strConnectInfo,
1757                                                                MAC_DISCONNECTED,
1758                                                                NULL,
1759                                                                pstrHostIFconnectAttr->pvUserArg);
1760                         /*Change state to idle*/
1761                         pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
1762                         /* Deallocation */
1763                         if (strConnectInfo.pu8ReqIEs != NULL) {
1764                                 kfree(strConnectInfo.pu8ReqIEs);
1765                                 strConnectInfo.pu8ReqIEs = NULL;
1766                         }
1767
1768                 } else {
1769                         PRINT_ER("Connect callback function pointer is NULL\n");
1770                 }
1771         }
1772
1773         PRINT_D(HOSTINF_DBG, "Deallocating connection parameters\n");
1774         /* Deallocate pstrHostIFconnectAttr->pu8bssid which was prevoisuly allocated by the sending thread */
1775         if (pstrHostIFconnectAttr->pu8bssid != NULL) {
1776                 kfree(pstrHostIFconnectAttr->pu8bssid);
1777                 pstrHostIFconnectAttr->pu8bssid = NULL;
1778         }
1779
1780         /* Deallocate pstrHostIFconnectAttr->pu8ssid which was prevoisuly allocated by the sending thread */
1781         if (pstrHostIFconnectAttr->pu8ssid != NULL) {
1782                 kfree(pstrHostIFconnectAttr->pu8ssid);
1783                 pstrHostIFconnectAttr->pu8ssid = NULL;
1784         }
1785
1786         /* Deallocate pstrHostIFconnectAttr->pu8IEs which was prevoisuly allocated by the sending thread */
1787         if (pstrHostIFconnectAttr->pu8IEs != NULL) {
1788                 kfree(pstrHostIFconnectAttr->pu8IEs);
1789                 pstrHostIFconnectAttr->pu8IEs = NULL;
1790         }
1791
1792         if (pu8CurrByte != NULL)
1793                 kfree(pu8CurrByte);
1794         return s32Error;
1795 }
1796
1797 /**
1798  *  @brief                      Handle_FlushConnect
1799  *  @details            Sending config packet to firmware to flush an old connection
1800  *                              after switching FW from station one to hybrid one
1801  *  @param[in]          void * drvHandler
1802  *  @return             Error code.
1803  *  @author             Amr Abdel-Moghny
1804  *  @date                       19 DEC 2013
1805  *  @version            8.0
1806  */
1807
1808 static s32 Handle_FlushConnect(tstrWILC_WFIDrv *drvHandler)
1809 {
1810         s32 s32Error = 0;
1811         tstrWID strWIDList[5];
1812         u32 u32WidsCount = 0;
1813         u8 *pu8CurrByte = NULL;
1814
1815
1816         /* IEs to be inserted in Association Request */
1817         strWIDList[u32WidsCount].u16WIDid = WID_INFO_ELEMENT_ASSOCIATE;
1818         strWIDList[u32WidsCount].enuWIDtype = WID_BIN_DATA;
1819         strWIDList[u32WidsCount].ps8WidVal = gu8FlushedInfoElemAsoc;
1820         strWIDList[u32WidsCount].s32ValueSize = gu32FlushedInfoElemAsocSize;
1821         u32WidsCount++;
1822
1823         strWIDList[u32WidsCount].u16WIDid = (u16)WID_11I_MODE;
1824         strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
1825         strWIDList[u32WidsCount].s32ValueSize = sizeof(char);
1826         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(gu8Flushed11iMode));
1827         u32WidsCount++;
1828
1829
1830
1831         strWIDList[u32WidsCount].u16WIDid = (u16)WID_AUTH_TYPE;
1832         strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
1833         strWIDList[u32WidsCount].s32ValueSize = sizeof(char);
1834         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&gu8FlushedAuthType);
1835         u32WidsCount++;
1836
1837         strWIDList[u32WidsCount].u16WIDid = (u16)WID_JOIN_REQ_EXTENDED;
1838         strWIDList[u32WidsCount].enuWIDtype = WID_STR;
1839         strWIDList[u32WidsCount].s32ValueSize = gu32FlushedJoinReqSize;
1840         strWIDList[u32WidsCount].ps8WidVal = (s8 *)gu8FlushedJoinReq;
1841         pu8CurrByte = strWIDList[u32WidsCount].ps8WidVal;
1842
1843         pu8CurrByte += FLUSHED_BYTE_POS;
1844         *(pu8CurrByte) = FLUSHED_JOIN_REQ;
1845
1846         u32WidsCount++;
1847
1848         s32Error = send_config_pkt(SET_CFG, strWIDList, u32WidsCount, false,
1849                                    get_id_from_handler(gu8FlushedJoinReqDrvHandler));
1850         if (s32Error) {
1851                 PRINT_ER("failed to send config packet\n");
1852                 s32Error = -EINVAL;
1853         }
1854
1855         return s32Error;
1856 }
1857
1858 /**
1859  *  @brief                 Handle_ConnectTimeout
1860  *  @details       Call connect notification callback function indicating connection failure
1861  *  @param[in]    NONE
1862  *  @return         Error code.
1863  *  @author
1864  *  @date
1865  *  @version    1.0
1866  */
1867 static s32 Handle_ConnectTimeout(tstrWILC_WFIDrv *drvHandler)
1868 {
1869         s32 s32Error = 0;
1870         tstrConnectInfo strConnectInfo;
1871         tstrWID strWID;
1872         u16 u16DummyReasonCode = 0;
1873         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler;
1874
1875         if (pstrWFIDrv == NULL) {
1876                 PRINT_ER("Driver handler is NULL\n");
1877                 return s32Error;
1878         }
1879
1880         pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
1881
1882         gbScanWhileConnected = false;
1883
1884
1885         memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
1886
1887
1888         /* First, we will notify the upper layer with the Connection failure {through the Connect Callback function},
1889          *   then we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying
1890          *   WID_DISCONNECT} */
1891         if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) {
1892                 if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) {
1893                         memcpy(strConnectInfo.au8bssid,
1894                                     pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, 6);
1895                 }
1896
1897                 if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
1898                         strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen;
1899                         strConnectInfo.pu8ReqIEs = kmalloc(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen, GFP_KERNEL);
1900                         memcpy(strConnectInfo.pu8ReqIEs,
1901                                     pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs,
1902                                     pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen);
1903                 }
1904
1905                 pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
1906                                                                    &strConnectInfo,
1907                                                                    MAC_DISCONNECTED,
1908                                                                    NULL,
1909                                                                    pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid);
1910
1911                 /* Deallocation of strConnectInfo.pu8ReqIEs */
1912                 if (strConnectInfo.pu8ReqIEs != NULL) {
1913                         kfree(strConnectInfo.pu8ReqIEs);
1914                         strConnectInfo.pu8ReqIEs = NULL;
1915                 }
1916         } else {
1917                 PRINT_ER("Connect callback function pointer is NULL\n");
1918         }
1919
1920         /* Here we will notify our firmware also with the Connection failure {through sending to it Cfg packet carrying
1921          *   WID_DISCONNECT} */
1922         strWID.u16WIDid = (u16)WID_DISCONNECT;
1923         strWID.enuWIDtype = WID_CHAR;
1924         strWID.ps8WidVal = (s8 *)&u16DummyReasonCode;
1925         strWID.s32ValueSize = sizeof(char);
1926
1927         PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
1928
1929         s32Error = send_config_pkt(SET_CFG, &strWID, 1, false,
1930                                    get_id_from_handler(pstrWFIDrv));
1931         if (s32Error)
1932                 PRINT_ER("Failed to send dissconect config packet\n");
1933
1934         /* Deallocation of the Saved Connect Request in the global Handle */
1935         pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0;
1936         if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) {
1937                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid);
1938                 pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL;
1939         }
1940
1941         if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) {
1942                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid);
1943                 pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL;
1944         }
1945
1946         pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
1947         if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
1948                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs);
1949                 pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL;
1950         }
1951
1952         memset(u8ConnectedSSID, 0, ETH_ALEN);
1953         /*Freeing flushed join request params on connect timeout*/
1954         if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
1955                 kfree(gu8FlushedJoinReq);
1956                 gu8FlushedJoinReq = NULL;
1957         }
1958         if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
1959                 kfree(gu8FlushedInfoElemAsoc);
1960                 gu8FlushedInfoElemAsoc = NULL;
1961         }
1962
1963         return s32Error;
1964 }
1965
1966 /**
1967  *  @brief Handle_RcvdNtwrkInfo
1968  *  @details       Handling received network information
1969  *  @param[in]    struct rcvd_net_info *pstrRcvdNetworkInfo
1970  *  @return         Error code.
1971  *  @author
1972  *  @date
1973  *  @version    1.0
1974  */
1975 static s32 Handle_RcvdNtwrkInfo(tstrWILC_WFIDrv *drvHandler,
1976                                 struct rcvd_net_info *pstrRcvdNetworkInfo)
1977 {
1978         u32 i;
1979         bool bNewNtwrkFound;
1980
1981
1982
1983         s32 s32Error = 0;
1984         tstrNetworkInfo *pstrNetworkInfo = NULL;
1985         void *pJoinParams = NULL;
1986
1987         tstrWILC_WFIDrv *pstrWFIDrv  = (tstrWILC_WFIDrv *)drvHandler;
1988
1989
1990
1991         bNewNtwrkFound = true;
1992         PRINT_INFO(HOSTINF_DBG, "Handling received network info\n");
1993
1994         /*if there is a an ongoing scan request*/
1995         if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) {
1996                 PRINT_D(HOSTINF_DBG, "State: Scanning, parsing network information received\n");
1997                 parse_network_info(pstrRcvdNetworkInfo->pu8Buffer, &pstrNetworkInfo);
1998                 if ((pstrNetworkInfo == NULL)
1999                     || (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult == NULL)) {
2000                         PRINT_ER("driver is null\n");
2001                         s32Error = -EINVAL;
2002                         goto done;
2003                 }
2004
2005                 /* check whether this network is discovered before */
2006                 for (i = 0; i < pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount; i++) {
2007
2008                         if ((pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid != NULL) &&
2009                             (pstrNetworkInfo->au8bssid != NULL)) {
2010                                 if (memcmp(pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].au8bssid,
2011                                                 pstrNetworkInfo->au8bssid, 6) == 0) {
2012                                         if (pstrNetworkInfo->s8rssi <= pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi) {
2013                                                 /*we have already found this network with better rssi, so keep the old cached one and don't
2014                                                  *  send anything to the upper layer */
2015                                                 PRINT_D(HOSTINF_DBG, "Network previously discovered\n");
2016                                                 goto done;
2017                                         } else {
2018                                                 /* here the same already found network is found again but with a better rssi, so just update
2019                                                  *   the rssi for this cached network and send this updated network to the upper layer but
2020                                                  *   don't add a new record for it */
2021                                                 pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[i].s8rssi = pstrNetworkInfo->s8rssi;
2022                                                 bNewNtwrkFound = false;
2023                                                 break;
2024                                         }
2025                                 }
2026                         }
2027                 }
2028
2029                 if (bNewNtwrkFound == true) {
2030                         /* here it is confirmed that it is a new discovered network,
2031                          * so add its record then call the User CallBack function */
2032
2033                         PRINT_D(HOSTINF_DBG, "New network found\n");
2034
2035                         if (pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
2036                                 pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].s8rssi = pstrNetworkInfo->s8rssi;
2037
2038                                 if ((pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid != NULL)
2039                                     && (pstrNetworkInfo->au8bssid != NULL)) {
2040                                         memcpy(pstrWFIDrv->strWILC_UsrScanReq.astrFoundNetworkInfo[pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount].au8bssid,
2041                                                     pstrNetworkInfo->au8bssid, 6);
2042
2043                                         pstrWFIDrv->strWILC_UsrScanReq.u32RcvdChCount++;
2044
2045                                         pstrNetworkInfo->bNewNetwork = true;
2046                                         /* add new BSS to JoinBssTable */
2047                                         pJoinParams = host_int_ParseJoinBssParam(pstrNetworkInfo);
2048
2049                                         pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
2050                                                                                         pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid,
2051                                                                                         pJoinParams);
2052
2053
2054                                 }
2055                         } else {
2056                                 PRINT_WRN(HOSTINF_DBG, "Discovered networks exceeded max. limit\n");
2057                         }
2058                 } else {
2059                         pstrNetworkInfo->bNewNetwork = false;
2060                         /* just call the User CallBack function to send the same discovered network with its updated RSSI */
2061                         pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_NETWORK_FOUND, pstrNetworkInfo,
2062                                                                         pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
2063                 }
2064         }
2065
2066 done:
2067         /* Deallocate pstrRcvdNetworkInfo->pu8Buffer which was prevoisuly allocated by the sending thread */
2068         if (pstrRcvdNetworkInfo->pu8Buffer != NULL) {
2069                 kfree(pstrRcvdNetworkInfo->pu8Buffer);
2070                 pstrRcvdNetworkInfo->pu8Buffer = NULL;
2071         }
2072
2073         /*free structure allocated*/
2074         if (pstrNetworkInfo != NULL) {
2075                 DeallocateNetworkInfo(pstrNetworkInfo);
2076                 pstrNetworkInfo = NULL;
2077         }
2078
2079         return s32Error;
2080 }
2081
2082 /**
2083  *  @brief Handle_RcvdGnrlAsyncInfo
2084  *  @details       Handling received asynchrous general network information
2085  *  @param[in]     struct rcvd_async_info *pstrRcvdGnrlAsyncInfo
2086  *  @return         Error code.
2087  *  @author
2088  *  @date
2089  *  @version    1.0
2090  */
2091 static s32 Handle_RcvdGnrlAsyncInfo(tstrWILC_WFIDrv *drvHandler,
2092                                     struct rcvd_async_info *pstrRcvdGnrlAsyncInfo)
2093 {
2094         /* TODO: mostafa: till now, this function just handles only the received mac status msg, */
2095         /*                               which carries only 1 WID which have WID ID = WID_STATUS */
2096         s32 s32Error = 0;
2097         u8 u8MsgType = 0;
2098         u8 u8MsgID = 0;
2099         u16 u16MsgLen = 0;
2100         u16 u16WidID = (u16)WID_NIL;
2101         u8 u8WidLen  = 0;
2102         u8 u8MacStatus;
2103         u8 u8MacStatusReasonCode;
2104         u8 u8MacStatusAdditionalInfo;
2105         tstrConnectInfo strConnectInfo;
2106         tstrDisconnectNotifInfo strDisconnectNotifInfo;
2107         s32 s32Err = 0;
2108         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler;
2109
2110         if (!pstrWFIDrv) {
2111                 PRINT_ER("Driver handler is NULL\n");
2112                 return -ENODEV;
2113         }
2114         PRINT_D(GENERIC_DBG, "Current State = %d,Received state = %d\n", pstrWFIDrv->enuHostIFstate,
2115                 pstrRcvdGnrlAsyncInfo->pu8Buffer[7]);
2116
2117         if ((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) ||
2118             (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) ||
2119             pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) {
2120                 if ((pstrRcvdGnrlAsyncInfo->pu8Buffer == NULL) ||
2121                     (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult == NULL)) {
2122                         PRINT_ER("driver is null\n");
2123                         return -EINVAL;
2124                 }
2125
2126                 u8MsgType = pstrRcvdGnrlAsyncInfo->pu8Buffer[0];
2127
2128                 /* Check whether the received message type is 'I' */
2129                 if ('I' != u8MsgType) {
2130                         PRINT_ER("Received Message format incorrect.\n");
2131                         return -EFAULT;
2132                 }
2133
2134                 /* Extract message ID */
2135                 u8MsgID = pstrRcvdGnrlAsyncInfo->pu8Buffer[1];
2136
2137                 /* Extract message Length */
2138                 u16MsgLen = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[2], pstrRcvdGnrlAsyncInfo->pu8Buffer[3]);
2139
2140                 /* Extract WID ID [expected to be = WID_STATUS] */
2141                 u16WidID = MAKE_WORD16(pstrRcvdGnrlAsyncInfo->pu8Buffer[4], pstrRcvdGnrlAsyncInfo->pu8Buffer[5]);
2142
2143                 /* Extract WID Length [expected to be = 1] */
2144                 u8WidLen = pstrRcvdGnrlAsyncInfo->pu8Buffer[6];
2145
2146                 /* get the WID value [expected to be one of two values: either MAC_CONNECTED = (1) or MAC_DISCONNECTED = (0)] */
2147                 u8MacStatus  = pstrRcvdGnrlAsyncInfo->pu8Buffer[7];
2148                 u8MacStatusReasonCode = pstrRcvdGnrlAsyncInfo->pu8Buffer[8];
2149                 u8MacStatusAdditionalInfo = pstrRcvdGnrlAsyncInfo->pu8Buffer[9];
2150                 PRINT_INFO(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Info = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
2151                 if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
2152                         /* our station had sent Association Request frame, so here it will get the Association Response frame then parse it */
2153                         u32 u32RcvdAssocRespInfoLen;
2154                         tstrConnectRespInfo *pstrConnectRespInfo = NULL;
2155
2156                         PRINT_D(HOSTINF_DBG, "Recieved MAC status = %d with Reason = %d , Code = %d\n", u8MacStatus, u8MacStatusReasonCode, u8MacStatusAdditionalInfo);
2157
2158                         memset(&strConnectInfo, 0, sizeof(tstrConnectInfo));
2159
2160                         if (u8MacStatus == MAC_CONNECTED) {
2161                                 memset(gapu8RcvdAssocResp, 0, MAX_ASSOC_RESP_FRAME_SIZE);
2162
2163                                 host_int_get_assoc_res_info(pstrWFIDrv,
2164                                                             gapu8RcvdAssocResp,
2165                                                             MAX_ASSOC_RESP_FRAME_SIZE,
2166                                                             &u32RcvdAssocRespInfoLen);
2167
2168                                 PRINT_INFO(HOSTINF_DBG, "Received association response with length = %d\n", u32RcvdAssocRespInfoLen);
2169
2170                                 if (u32RcvdAssocRespInfoLen != 0) {
2171
2172                                         PRINT_D(HOSTINF_DBG, "Parsing association response\n");
2173                                         s32Err = ParseAssocRespInfo(gapu8RcvdAssocResp, u32RcvdAssocRespInfoLen,
2174                                                                     &pstrConnectRespInfo);
2175                                         if (s32Err) {
2176                                                 PRINT_ER("ParseAssocRespInfo() returned error %d\n", s32Err);
2177                                         } else {
2178                                                 /* use the necessary parsed Info from the Received Association Response */
2179                                                 strConnectInfo.u16ConnectStatus = pstrConnectRespInfo->u16ConnectStatus;
2180
2181                                                 if (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE) {
2182                                                         PRINT_INFO(HOSTINF_DBG, "Association response received : Successful connection status\n");
2183                                                         if (pstrConnectRespInfo->pu8RespIEs != NULL) {
2184                                                                 strConnectInfo.u16RespIEsLen = pstrConnectRespInfo->u16RespIEsLen;
2185
2186
2187                                                                 strConnectInfo.pu8RespIEs = kmalloc(pstrConnectRespInfo->u16RespIEsLen, GFP_KERNEL);
2188                                                                 memcpy(strConnectInfo.pu8RespIEs, pstrConnectRespInfo->pu8RespIEs,
2189                                                                             pstrConnectRespInfo->u16RespIEsLen);
2190                                                         }
2191                                                 }
2192
2193                                                 /* deallocate the Assoc. Resp. parsed structure as it is not needed anymore */
2194                                                 if (pstrConnectRespInfo != NULL) {
2195                                                         DeallocateAssocRespInfo(pstrConnectRespInfo);
2196                                                         pstrConnectRespInfo = NULL;
2197                                                 }
2198                                         }
2199                                 }
2200                         }
2201
2202                         /* The station has just received mac status and it also received assoc. response which
2203                          *   it was waiting for.
2204                          *   So check first the matching between the received mac status and the received status code in Asoc Resp */
2205                         if ((u8MacStatus == MAC_CONNECTED) &&
2206                             (strConnectInfo.u16ConnectStatus != SUCCESSFUL_STATUSCODE)) {
2207                                 PRINT_ER("Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n");
2208                                 memset(u8ConnectedSSID, 0, ETH_ALEN);
2209
2210                         } else if (u8MacStatus == MAC_DISCONNECTED)    {
2211                                 PRINT_ER("Received MAC status is MAC_DISCONNECTED\n");
2212                                 memset(u8ConnectedSSID, 0, ETH_ALEN);
2213                         }
2214
2215                         /* TODO: mostafa: correct BSSID should be retrieved from actual BSSID received from AP */
2216                         /*               through a structure of type tstrConnectRespInfo */
2217                         if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) {
2218                                 PRINT_D(HOSTINF_DBG, "Retrieving actual BSSID from AP\n");
2219                                 memcpy(strConnectInfo.au8bssid, pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, 6);
2220
2221                                 if ((u8MacStatus == MAC_CONNECTED) &&
2222                                     (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
2223                                         memcpy(pstrWFIDrv->au8AssociatedBSSID,
2224                                                     pstrWFIDrv->strWILC_UsrConnReq.pu8bssid, ETH_ALEN);
2225                                 }
2226                         }
2227
2228
2229                         if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
2230                                 strConnectInfo.ReqIEsLen = pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen;
2231                                 strConnectInfo.pu8ReqIEs = kmalloc(pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen, GFP_KERNEL);
2232                                 memcpy(strConnectInfo.pu8ReqIEs,
2233                                             pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs,
2234                                             pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen);
2235                         }
2236
2237
2238                         del_timer(&pstrWFIDrv->hConnectTimer);
2239                         pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_CONN_RESP,
2240                                                                            &strConnectInfo,
2241                                                                            u8MacStatus,
2242                                                                            NULL,
2243                                                                            pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid);
2244
2245
2246                         /* if received mac status is MAC_CONNECTED and
2247                          *  received status code in Asoc Resp is SUCCESSFUL_STATUSCODE, change state to CONNECTED
2248                          *  else change state to IDLE */
2249                         if ((u8MacStatus == MAC_CONNECTED) &&
2250                             (strConnectInfo.u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
2251                                 host_int_set_power_mgmt(pstrWFIDrv, 0, 0);
2252
2253                                 PRINT_D(HOSTINF_DBG, "MAC status : CONNECTED and Connect Status : Successful\n");
2254                                 pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTED;
2255
2256                                 PRINT_D(GENERIC_DBG, "Obtaining an IP, Disable Scan\n");
2257                                 g_obtainingIP = true;
2258                                 mod_timer(&hDuringIpTimer,
2259                                           jiffies + msecs_to_jiffies(10000));
2260
2261                                 /* open a BA session if possible */
2262                                 /* if(pstrWFIDrv->strWILC_UsrConnReq.IsHTCapable) */
2263                                 /* BA_SESSION_DEFAULT_BUFFER_SIZE,BA_SESSION_DEFAULT_TIMEOUT); */
2264                         } else {
2265                                 PRINT_D(HOSTINF_DBG, "MAC status : %d and Connect Status : %d\n", u8MacStatus, strConnectInfo.u16ConnectStatus);
2266                                 pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
2267                                 gbScanWhileConnected = false;
2268                         }
2269
2270                         /* Deallocation */
2271                         if (strConnectInfo.pu8RespIEs != NULL) {
2272                                 kfree(strConnectInfo.pu8RespIEs);
2273                                 strConnectInfo.pu8RespIEs = NULL;
2274                         }
2275
2276                         if (strConnectInfo.pu8ReqIEs != NULL) {
2277                                 kfree(strConnectInfo.pu8ReqIEs);
2278                                 strConnectInfo.pu8ReqIEs = NULL;
2279                         }
2280
2281
2282                         pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0;
2283                         if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) {
2284                                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid);
2285                                 pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL;
2286                         }
2287
2288                         if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) {
2289                                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid);
2290                                 pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL;
2291                         }
2292
2293                         pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
2294                         if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
2295                                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs);
2296                                 pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL;
2297                         }
2298
2299                 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
2300                            (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)) {
2301                         /* Disassociation or Deauthentication frame has been received */
2302                         PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW\n");
2303
2304                         memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
2305
2306                         if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) {
2307                                 PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running OBSS Scan >>\n\n");
2308                                 del_timer(&pstrWFIDrv->hScanTimer);
2309                                 Handle_ScanDone((void *)pstrWFIDrv, SCAN_EVENT_ABORTED);
2310                         }
2311
2312                         strDisconnectNotifInfo.u16reason = 0;
2313                         strDisconnectNotifInfo.ie = NULL;
2314                         strDisconnectNotifInfo.ie_len = 0;
2315
2316                         if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) {
2317                                 g_obtainingIP = false;
2318                                 host_int_set_power_mgmt(pstrWFIDrv, 0, 0);
2319
2320                                 pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF,
2321                                                                                    NULL,
2322                                                                                    0,
2323                                                                                    &strDisconnectNotifInfo,
2324                                                                                    pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid);
2325
2326                         } else {
2327                                 PRINT_ER("Connect result callback function is NULL\n");
2328                         }
2329
2330                         memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN);
2331
2332
2333                         /* Deallocation */
2334
2335                         /* if Information Elements were retrieved from the Received deauth/disassoc frame, then they
2336                          *  should be deallocated here */
2337                         /*
2338                          * if(strDisconnectNotifInfo.ie != NULL)
2339                          * {
2340                          *      kfree(strDisconnectNotifInfo.ie);
2341                          *      strDisconnectNotifInfo.ie = NULL;
2342                          * }
2343                          */
2344
2345                         pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0;
2346                         if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) {
2347                                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid);
2348                                 pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL;
2349                         }
2350
2351                         if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) {
2352                                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid);
2353                                 pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL;
2354                         }
2355
2356                         pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
2357                         if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
2358                                 kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs);
2359                                 pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL;
2360                         }
2361
2362                         /*Freeing flushed join request params on receiving*/
2363                         /*MAC_DISCONNECTED while connected*/
2364                         if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
2365                                 kfree(gu8FlushedJoinReq);
2366                                 gu8FlushedJoinReq = NULL;
2367                         }
2368                         if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
2369                                 kfree(gu8FlushedInfoElemAsoc);
2370                                 gu8FlushedInfoElemAsoc = NULL;
2371                         }
2372
2373                         pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
2374                         gbScanWhileConnected = false;
2375
2376                 } else if ((u8MacStatus == MAC_DISCONNECTED) &&
2377                            (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL)) {
2378                         PRINT_D(HOSTINF_DBG, "Received MAC_DISCONNECTED from the FW while scanning\n");
2379                         PRINT_D(HOSTINF_DBG, "\n\n<< Abort the running Scan >>\n\n");
2380                         /*Abort the running scan*/
2381                         del_timer(&pstrWFIDrv->hScanTimer);
2382                         if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult)
2383                                 Handle_ScanDone(pstrWFIDrv, SCAN_EVENT_ABORTED);
2384
2385                 }
2386
2387         }
2388
2389         /* Deallocate pstrRcvdGnrlAsyncInfo->pu8Buffer which was prevoisuly allocated by the sending thread */
2390         if (pstrRcvdGnrlAsyncInfo->pu8Buffer != NULL) {
2391                 kfree(pstrRcvdGnrlAsyncInfo->pu8Buffer);
2392                 pstrRcvdGnrlAsyncInfo->pu8Buffer = NULL;
2393         }
2394
2395         return s32Error;
2396 }
2397
2398 /**
2399  *  @brief Handle_Key
2400  *  @details       Sending config packet to firmware to set key
2401  *  @param[in]    struct key_attr *pstrHostIFkeyAttr
2402  *  @return         Error code.
2403  *  @author
2404  *  @date
2405  *  @version    1.0
2406  */
2407 static int Handle_Key(tstrWILC_WFIDrv *drvHandler,
2408                       struct key_attr *pstrHostIFkeyAttr)
2409 {
2410         s32 s32Error = 0;
2411         tstrWID strWID;
2412         tstrWID strWIDList[5];
2413         u8 i;
2414         u8 *pu8keybuf;
2415         s8 s8idxarray[1];
2416         s8 ret = 0;
2417         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
2418
2419
2420         switch (pstrHostIFkeyAttr->enuKeyType) {
2421
2422
2423         case WEP:
2424
2425                 if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) {
2426
2427                         PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
2428                         PRINT_D(GENERIC_DBG, "ID Hostint is %d\n", (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx));
2429                         strWIDList[0].u16WIDid = (u16)WID_11I_MODE;
2430                         strWIDList[0].enuWIDtype = WID_CHAR;
2431                         strWIDList[0].s32ValueSize = sizeof(char);
2432                         strWIDList[0].ps8WidVal = (s8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8mode));
2433
2434                         strWIDList[1].u16WIDid     = WID_AUTH_TYPE;
2435                         strWIDList[1].enuWIDtype  = WID_CHAR;
2436                         strWIDList[1].s32ValueSize = sizeof(char);
2437                         strWIDList[1].ps8WidVal = (s8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type));
2438
2439                         strWIDList[2].u16WIDid  = (u16)WID_KEY_ID;
2440                         strWIDList[2].enuWIDtype        = WID_CHAR;
2441
2442                         strWIDList[2].ps8WidVal = (s8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx));
2443                         strWIDList[2].s32ValueSize = sizeof(char);
2444
2445
2446                         pu8keybuf = kmalloc(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen, GFP_KERNEL);
2447
2448
2449                         if (pu8keybuf == NULL) {
2450                                 PRINT_ER("No buffer to send Key\n");
2451                                 return -1;
2452                         }
2453
2454                         memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
2455                                     pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen);
2456
2457
2458                         kfree(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey);
2459
2460                         strWIDList[3].u16WIDid = (u16)WID_WEP_KEY_VALUE;
2461                         strWIDList[3].enuWIDtype = WID_STR;
2462                         strWIDList[3].s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen;
2463                         strWIDList[3].ps8WidVal = (s8 *)pu8keybuf;
2464
2465
2466                         s32Error = send_config_pkt(SET_CFG, strWIDList, 4, true,
2467                                                    get_id_from_handler(pstrWFIDrv));
2468                         kfree(pu8keybuf);
2469
2470
2471                 }
2472
2473                 if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) {
2474                         PRINT_D(HOSTINF_DBG, "Handling WEP key\n");
2475                         pu8keybuf = kmalloc(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2, GFP_KERNEL);
2476                         if (pu8keybuf == NULL) {
2477                                 PRINT_ER("No buffer to send Key\n");
2478                                 return -1;
2479                         }
2480                         pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx;
2481
2482                         memcpy(pu8keybuf + 1, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen, 1);
2483
2484                         memcpy(pu8keybuf + 2, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
2485                                     pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen);
2486
2487                         kfree(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey);
2488
2489                         strWID.u16WIDid = (u16)WID_ADD_WEP_KEY;
2490                         strWID.enuWIDtype       = WID_STR;
2491                         strWID.ps8WidVal        = (s8 *)pu8keybuf;
2492                         strWID.s32ValueSize = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen + 2;
2493
2494                         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
2495                                                    get_id_from_handler(pstrWFIDrv));
2496                         kfree(pu8keybuf);
2497                 } else if (pstrHostIFkeyAttr->u8KeyAction & REMOVEKEY)    {
2498
2499                         PRINT_D(HOSTINF_DBG, "Removing key\n");
2500                         strWID.u16WIDid = (u16)WID_REMOVE_WEP_KEY;
2501                         strWID.enuWIDtype       = WID_STR;
2502
2503                         s8idxarray[0] = (s8)pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx;
2504                         strWID.ps8WidVal = s8idxarray;
2505                         strWID.s32ValueSize = 1;
2506
2507                         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
2508                                                    get_id_from_handler(pstrWFIDrv));
2509                 } else {
2510                         strWID.u16WIDid = (u16)WID_KEY_ID;
2511                         strWID.enuWIDtype       = WID_CHAR;
2512                         strWID.ps8WidVal        = (s8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx));
2513                         strWID.s32ValueSize = sizeof(char);
2514
2515                         PRINT_D(HOSTINF_DBG, "Setting default key index\n");
2516
2517                         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
2518                                                    get_id_from_handler(pstrWFIDrv));
2519                 }
2520                 up(&(pstrWFIDrv->hSemTestKeyBlock));
2521                 break;
2522
2523         case WPARxGtk:
2524                 if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) {
2525                         pu8keybuf = kmalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
2526                         if (pu8keybuf == NULL) {
2527                                 PRINT_ER("No buffer to send RxGTK Key\n");
2528                                 ret = -1;
2529                                 goto _WPARxGtk_end_case_;
2530                         }
2531
2532                         memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN);
2533
2534
2535                         /*|----------------------------------------------------------------------------|
2536                          * |Sta Address | Key RSC | KeyID | Key Length | Temporal Key   | Rx Michael Key |
2537                          * |------------|---------|-------|------------|---------------|----------------|
2538                          |      6 bytes  | 8 byte  |1 byte |  1 byte    |   16 bytes    |         8 bytes        |*/
2539
2540
2541
2542                         if (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq != NULL)
2543                                 memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8);
2544
2545
2546                         memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1);
2547
2548                         memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1);
2549
2550                         memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
2551                                     pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen);
2552                         /* pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode =  0X51; */
2553                         strWIDList[0].u16WIDid = (u16)WID_11I_MODE;
2554                         strWIDList[0].enuWIDtype = WID_CHAR;
2555                         strWIDList[0].s32ValueSize = sizeof(char);
2556                         strWIDList[0].ps8WidVal = (s8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode));
2557
2558                         strWIDList[1].u16WIDid  = (u16)WID_ADD_RX_GTK;
2559                         strWIDList[1].enuWIDtype        = WID_STR;
2560                         strWIDList[1].ps8WidVal = (s8 *)pu8keybuf;
2561                         strWIDList[1].s32ValueSize = RX_MIC_KEY_MSG_LEN;
2562
2563                         s32Error = send_config_pkt(SET_CFG, strWIDList, 2, true,
2564                                                    get_id_from_handler(pstrWFIDrv));
2565
2566                         kfree(pu8keybuf);
2567
2568                         /* ////////////////////////// */
2569                         up(&(pstrWFIDrv->hSemTestKeyBlock));
2570                         /* ///////////////////////// */
2571                 }
2572
2573                 if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) {
2574                         PRINT_D(HOSTINF_DBG, "Handling group key(Rx) function\n");
2575
2576                         pu8keybuf = kmalloc(RX_MIC_KEY_MSG_LEN, GFP_KERNEL);
2577                         if (pu8keybuf == NULL) {
2578                                 PRINT_ER("No buffer to send RxGTK Key\n");
2579                                 ret = -1;
2580                                 goto _WPARxGtk_end_case_;
2581                         }
2582
2583                         memset(pu8keybuf, 0, RX_MIC_KEY_MSG_LEN);
2584
2585
2586                         /*|----------------------------------------------------------------------------|
2587                          * |Sta Address | Key RSC | KeyID | Key Length | Temporal Key   | Rx Michael Key |
2588                          * |------------|---------|-------|------------|---------------|----------------|
2589                          |      6 bytes  | 8 byte  |1 byte |  1 byte    |   16 bytes    |         8 bytes        |*/
2590
2591                         if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED)
2592                                 memcpy(pu8keybuf, pstrWFIDrv->au8AssociatedBSSID, ETH_ALEN);
2593                         else
2594                                 PRINT_ER("Couldn't handle WPARxGtk while enuHostIFstate is not HOST_IF_CONNECTED\n");
2595
2596                         memcpy(pu8keybuf + 6, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq, 8);
2597
2598                         memcpy(pu8keybuf + 14, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1);
2599
2600                         memcpy(pu8keybuf + 15, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1);
2601                         memcpy(pu8keybuf + 16, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
2602                                     pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen);
2603
2604                         strWID.u16WIDid = (u16)WID_ADD_RX_GTK;
2605                         strWID.enuWIDtype       = WID_STR;
2606                         strWID.ps8WidVal        = (s8 *)pu8keybuf;
2607                         strWID.s32ValueSize = RX_MIC_KEY_MSG_LEN;
2608
2609                         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
2610                                                    get_id_from_handler(pstrWFIDrv));
2611
2612                         kfree(pu8keybuf);
2613
2614                         /* ////////////////////////// */
2615                         up(&(pstrWFIDrv->hSemTestKeyBlock));
2616                         /* ///////////////////////// */
2617                 }
2618 _WPARxGtk_end_case_:
2619                 kfree(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key);
2620                 kfree(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq);
2621                 if (ret == -1)
2622                         return ret;
2623
2624                 break;
2625
2626         case WPAPtk:
2627                 if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY_AP) {
2628
2629
2630                         pu8keybuf = kmalloc(PTK_KEY_MSG_LEN + 1, GFP_KERNEL);
2631
2632
2633
2634                         if (pu8keybuf == NULL) {
2635                                 PRINT_ER("No buffer to send PTK Key\n");
2636                                 ret = -1;
2637                                 goto _WPAPtk_end_case_;
2638
2639                         }
2640
2641                         /*|-----------------------------------------------------------------------------|
2642                          * |Station address |   keyidx     |Key Length    |Temporal Key  | Rx Michael Key |Tx Michael Key |
2643                          * |----------------|------------  |--------------|----------------|---------------|
2644                          |      6 bytes    |    1 byte    |   1byte      |   16 bytes    |        8 bytes         |        8 bytes        |
2645                          |-----------------------------------------------------------------------------|*/
2646
2647                         memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6);  /*1 bytes Key Length */
2648
2649                         memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx, 1);
2650                         memcpy(pu8keybuf + 7, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1);
2651                         /*16 byte TK*/
2652                         memcpy(pu8keybuf + 8, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
2653                                     pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen);
2654
2655
2656                         strWIDList[0].u16WIDid = (u16)WID_11I_MODE;
2657                         strWIDList[0].enuWIDtype = WID_CHAR;
2658                         strWIDList[0].s32ValueSize = sizeof(char);
2659                         strWIDList[0].ps8WidVal = (s8 *)(&(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode));
2660
2661                         strWIDList[1].u16WIDid  = (u16)WID_ADD_PTK;
2662                         strWIDList[1].enuWIDtype        = WID_STR;
2663                         strWIDList[1].ps8WidVal = (s8 *)pu8keybuf;
2664                         strWIDList[1].s32ValueSize = PTK_KEY_MSG_LEN + 1;
2665
2666                         s32Error = send_config_pkt(SET_CFG, strWIDList, 2, true,
2667                                                    get_id_from_handler(pstrWFIDrv));
2668                         kfree(pu8keybuf);
2669
2670                         /* ////////////////////////// */
2671                         up(&(pstrWFIDrv->hSemTestKeyBlock));
2672                         /* ///////////////////////// */
2673                 }
2674                 if (pstrHostIFkeyAttr->u8KeyAction & ADDKEY) {
2675
2676
2677                         pu8keybuf = kmalloc(PTK_KEY_MSG_LEN, GFP_KERNEL);
2678
2679
2680
2681                         if (pu8keybuf == NULL) {
2682                                 PRINT_ER("No buffer to send PTK Key\n");
2683                                 ret = -1;
2684                                 goto _WPAPtk_end_case_;
2685
2686                         }
2687
2688                         /*|-----------------------------------------------------------------------------|
2689                          * |Station address | Key Length |      Temporal Key | Rx Michael Key |Tx Michael Key |
2690                          * |----------------|------------|--------------|----------------|---------------|
2691                          |      6 bytes          |      1byte     |   16 bytes   |        8 bytes         |        8 bytes        |
2692                          |-----------------------------------------------------------------------------|*/
2693
2694                         memcpy(pu8keybuf, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr, 6);  /*1 bytes Key Length */
2695
2696                         memcpy(pu8keybuf + 6, &pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen, 1);
2697                         /*16 byte TK*/
2698                         memcpy(pu8keybuf + 7, pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
2699                                     pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen);
2700
2701
2702                         strWID.u16WIDid = (u16)WID_ADD_PTK;
2703                         strWID.enuWIDtype       = WID_STR;
2704                         strWID.ps8WidVal        = (s8 *)pu8keybuf;
2705                         strWID.s32ValueSize = PTK_KEY_MSG_LEN;
2706
2707                         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
2708                                                    get_id_from_handler(pstrWFIDrv));
2709                         kfree(pu8keybuf);
2710
2711                         /* ////////////////////////// */
2712                         up(&(pstrWFIDrv->hSemTestKeyBlock));
2713                         /* ///////////////////////// */
2714                 }
2715
2716 _WPAPtk_end_case_:
2717                 kfree(pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFwpaAttr.pu8key);
2718                 if (ret == -1)
2719                         return ret;
2720
2721                 break;
2722
2723
2724         case PMKSA:
2725
2726                 PRINT_D(HOSTINF_DBG, "Handling PMKSA key\n");
2727
2728                 pu8keybuf = kmalloc((pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1, GFP_KERNEL);
2729                 if (pu8keybuf == NULL) {
2730                         PRINT_ER("No buffer to send PMKSA Key\n");
2731                         return -1;
2732                 }
2733
2734                 pu8keybuf[0] = pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid;
2735
2736                 for (i = 0; i < pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid; i++) {
2737
2738                         memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + 1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, ETH_ALEN);
2739                         memcpy(pu8keybuf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1), pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, PMKID_LEN);
2740                 }
2741
2742                 strWID.u16WIDid = (u16)WID_PMKID_INFO;
2743                 strWID.enuWIDtype = WID_STR;
2744                 strWID.ps8WidVal = (s8 *)pu8keybuf;
2745                 strWID.s32ValueSize = (pstrHostIFkeyAttr->uniHostIFkeyAttr.strHostIFpmkidAttr.numpmkid * PMKSA_KEY_LEN) + 1;
2746
2747                 s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
2748                                            get_id_from_handler(pstrWFIDrv));
2749
2750                 kfree(pu8keybuf);
2751                 break;
2752         }
2753
2754         if (s32Error)
2755                 PRINT_ER("Failed to send key config packet\n");
2756
2757
2758         return s32Error;
2759 }
2760
2761
2762 /**
2763  *  @brief Handle_Disconnect
2764  *  @details       Sending config packet to firmware to disconnect
2765  *  @param[in]    NONE
2766  *  @return         NONE
2767  *  @author
2768  *  @date
2769  *  @version    1.0
2770  */
2771 static void Handle_Disconnect(tstrWILC_WFIDrv *drvHandler)
2772 {
2773         tstrWID strWID;
2774
2775         s32 s32Error = 0;
2776         u16 u16DummyReasonCode = 0;
2777         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
2778
2779
2780         strWID.u16WIDid = (u16)WID_DISCONNECT;
2781         strWID.enuWIDtype = WID_CHAR;
2782         strWID.ps8WidVal = (s8 *)&u16DummyReasonCode;
2783         strWID.s32ValueSize = sizeof(char);
2784
2785
2786
2787         PRINT_D(HOSTINF_DBG, "Sending disconnect request\n");
2788
2789         g_obtainingIP = false;
2790         host_int_set_power_mgmt(pstrWFIDrv, 0, 0);
2791
2792         memset(u8ConnectedSSID, 0, ETH_ALEN);
2793
2794         s32Error = send_config_pkt(SET_CFG, &strWID, 1, false,
2795                                    get_id_from_handler(pstrWFIDrv));
2796
2797         if (s32Error) {
2798                 PRINT_ER("Failed to send dissconect config packet\n");
2799         } else {
2800                 tstrDisconnectNotifInfo strDisconnectNotifInfo;
2801
2802                 memset(&strDisconnectNotifInfo, 0, sizeof(tstrDisconnectNotifInfo));
2803
2804                 strDisconnectNotifInfo.u16reason = 0;
2805                 strDisconnectNotifInfo.ie = NULL;
2806                 strDisconnectNotifInfo.ie_len = 0;
2807
2808                 if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) {
2809                         del_timer(&pstrWFIDrv->hScanTimer);
2810                         pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
2811                                                                         pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
2812
2813                         pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = NULL;
2814                 }
2815
2816                 if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult != NULL) {
2817
2818                         /*Stop connect timer, if connection in progress*/
2819                         if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
2820                                 PRINT_D(HOSTINF_DBG, "Upper layer requested termination of connection\n");
2821                                 del_timer(&pstrWFIDrv->hConnectTimer);
2822                         }
2823
2824                         pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL,
2825                                                                            0, &strDisconnectNotifInfo, pstrWFIDrv->strWILC_UsrConnReq.u32UserConnectPvoid);
2826                 } else {
2827                         PRINT_ER("strWILC_UsrConnReq.pfUserConnectResult = NULL\n");
2828                 }
2829
2830                 gbScanWhileConnected = false;
2831
2832                 pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
2833
2834                 memset(pstrWFIDrv->au8AssociatedBSSID, 0, ETH_ALEN);
2835
2836
2837                 /* Deallocation */
2838                 pstrWFIDrv->strWILC_UsrConnReq.ssidLen = 0;
2839                 if (pstrWFIDrv->strWILC_UsrConnReq.pu8ssid != NULL) {
2840                         kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8ssid);
2841                         pstrWFIDrv->strWILC_UsrConnReq.pu8ssid = NULL;
2842                 }
2843
2844                 if (pstrWFIDrv->strWILC_UsrConnReq.pu8bssid != NULL) {
2845                         kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8bssid);
2846                         pstrWFIDrv->strWILC_UsrConnReq.pu8bssid = NULL;
2847                 }
2848
2849                 pstrWFIDrv->strWILC_UsrConnReq.ConnReqIEsLen = 0;
2850                 if (pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs != NULL) {
2851                         kfree(pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs);
2852                         pstrWFIDrv->strWILC_UsrConnReq.pu8ConnReqIEs = NULL;
2853                 }
2854
2855
2856                 if (gu8FlushedJoinReq != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
2857                         kfree(gu8FlushedJoinReq);
2858                         gu8FlushedJoinReq = NULL;
2859                 }
2860                 if (gu8FlushedInfoElemAsoc != NULL && gu8FlushedJoinReqDrvHandler == drvHandler) {
2861                         kfree(gu8FlushedInfoElemAsoc);
2862                         gu8FlushedInfoElemAsoc = NULL;
2863                 }
2864
2865         }
2866
2867         /* ////////////////////////// */
2868         up(&(pstrWFIDrv->hSemTestDisconnectBlock));
2869         /* ///////////////////////// */
2870
2871 }
2872
2873
2874 void resolve_disconnect_aberration(tstrWILC_WFIDrv *drvHandler)
2875 {
2876         tstrWILC_WFIDrv *pstrWFIDrv;
2877
2878         pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
2879         if (pstrWFIDrv  == NULL)
2880                 return;
2881         if ((pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) || (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTING)) {
2882                 PRINT_D(HOSTINF_DBG, "\n\n<< correcting Supplicant state machine >>\n\n");
2883                 host_int_disconnect(pstrWFIDrv, 1);
2884         }
2885 }
2886
2887 /**
2888  *  @brief Handle_GetChnl
2889  *  @details       Sending config packet to get channel
2890  *  @param[in]    NONE
2891  *  @return         NONE
2892  *
2893  *  @author
2894  *  @date
2895  *  @version    1.0
2896  */
2897 static s32 Handle_GetChnl(tstrWILC_WFIDrv *drvHandler)
2898 {
2899
2900         s32 s32Error = 0;
2901         tstrWID strWID;
2902         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
2903         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
2904
2905         strWID.u16WIDid = (u16)WID_CURRENT_CHANNEL;
2906         strWID.enuWIDtype = WID_CHAR;
2907         strWID.ps8WidVal = (s8 *)&gu8Chnl;
2908         strWID.s32ValueSize = sizeof(char);
2909
2910         PRINT_D(HOSTINF_DBG, "Getting channel value\n");
2911
2912         s32Error = send_config_pkt(GET_CFG, &strWID, 1, true,
2913                                    get_id_from_handler(pstrWFIDrv));
2914         /*get the value by searching the local copy*/
2915         if (s32Error) {
2916                 PRINT_ER("Failed to get channel number\n");
2917                 s32Error = -EFAULT;
2918         }
2919
2920         up(&(pstrWFIDrv->hSemGetCHNL));
2921
2922         return s32Error;
2923
2924
2925
2926 }
2927
2928
2929 /**
2930  *  @brief Handle_GetRssi
2931  *  @details       Sending config packet to get RSSI
2932  *  @param[in]    NONE
2933  *  @return         NONE
2934  *  @author
2935  *  @date
2936  *  @version    1.0
2937  */
2938 static void Handle_GetRssi(tstrWILC_WFIDrv *drvHandler)
2939 {
2940         s32 s32Error = 0;
2941         tstrWID strWID;
2942         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
2943
2944         strWID.u16WIDid = (u16)WID_RSSI;
2945         strWID.enuWIDtype = WID_CHAR;
2946         strWID.ps8WidVal = &gs8Rssi;
2947         strWID.s32ValueSize = sizeof(char);
2948
2949         /*Sending Cfg*/
2950         PRINT_D(HOSTINF_DBG, "Getting RSSI value\n");
2951
2952         s32Error = send_config_pkt(GET_CFG, &strWID, 1, true,
2953                                    get_id_from_handler(pstrWFIDrv));
2954         if (s32Error) {
2955                 PRINT_ER("Failed to get RSSI value\n");
2956                 s32Error = -EFAULT;
2957         }
2958
2959         up(&(pstrWFIDrv->hSemGetRSSI));
2960
2961
2962 }
2963
2964
2965 static void Handle_GetLinkspeed(tstrWILC_WFIDrv *drvHandler)
2966 {
2967         s32 s32Error = 0;
2968         tstrWID strWID;
2969         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
2970
2971         gs8lnkspd = 0;
2972
2973         strWID.u16WIDid = (u16)WID_LINKSPEED;
2974         strWID.enuWIDtype = WID_CHAR;
2975         strWID.ps8WidVal = &gs8lnkspd;
2976         strWID.s32ValueSize = sizeof(char);
2977         /*Sending Cfg*/
2978         PRINT_D(HOSTINF_DBG, "Getting LINKSPEED value\n");
2979
2980         s32Error = send_config_pkt(GET_CFG, &strWID, 1, true,
2981                                    get_id_from_handler(pstrWFIDrv));
2982         if (s32Error) {
2983                 PRINT_ER("Failed to get LINKSPEED value\n");
2984                 s32Error = -EFAULT;
2985         }
2986
2987         up(&(pstrWFIDrv->hSemGetLINKSPEED));
2988
2989
2990 }
2991
2992 s32 Handle_GetStatistics(tstrWILC_WFIDrv *drvHandler, tstrStatistics *pstrStatistics)
2993 {
2994         tstrWID strWIDList[5];
2995         u32 u32WidsCount = 0, s32Error = 0;
2996
2997         strWIDList[u32WidsCount].u16WIDid = WID_LINKSPEED;
2998         strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
2999         strWIDList[u32WidsCount].s32ValueSize = sizeof(char);
3000         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrStatistics->u8LinkSpeed));
3001         u32WidsCount++;
3002
3003         strWIDList[u32WidsCount].u16WIDid = WID_RSSI;
3004         strWIDList[u32WidsCount].enuWIDtype = WID_CHAR;
3005         strWIDList[u32WidsCount].s32ValueSize = sizeof(char);
3006         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrStatistics->s8RSSI));
3007         u32WidsCount++;
3008
3009         strWIDList[u32WidsCount].u16WIDid = WID_SUCCESS_FRAME_COUNT;
3010         strWIDList[u32WidsCount].enuWIDtype = WID_INT;
3011         strWIDList[u32WidsCount].s32ValueSize = sizeof(u32);
3012         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrStatistics->u32TxCount));
3013         u32WidsCount++;
3014
3015         strWIDList[u32WidsCount].u16WIDid = WID_RECEIVED_FRAGMENT_COUNT;
3016         strWIDList[u32WidsCount].enuWIDtype = WID_INT;
3017         strWIDList[u32WidsCount].s32ValueSize = sizeof(u32);
3018         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrStatistics->u32RxCount));
3019         u32WidsCount++;
3020
3021         strWIDList[u32WidsCount].u16WIDid = WID_FAILED_COUNT;
3022         strWIDList[u32WidsCount].enuWIDtype = WID_INT;
3023         strWIDList[u32WidsCount].s32ValueSize = sizeof(u32);
3024         strWIDList[u32WidsCount].ps8WidVal = (s8 *)(&(pstrStatistics->u32TxFailureCount));
3025         u32WidsCount++;
3026
3027         s32Error = send_config_pkt(GET_CFG, strWIDList, u32WidsCount, false,
3028                                    get_id_from_handler(drvHandler));
3029
3030         if (s32Error)
3031                 PRINT_ER("Failed to send scan paramters config packet\n");
3032
3033         up(&hWaitResponse);
3034         return 0;
3035
3036 }
3037
3038 /**
3039  *  @brief Handle_Get_InActiveTime
3040  *  @details       Sending config packet to set mac adddress for station and
3041  *                 get inactive time
3042  *  @param[in]    NONE
3043  *  @return         NONE
3044  *
3045  *  @author
3046  *  @date
3047  *  @version    1.0
3048  */
3049 static s32 Handle_Get_InActiveTime(tstrWILC_WFIDrv *drvHandler,
3050                                    struct sta_inactive_t *strHostIfStaInactiveT)
3051 {
3052
3053         s32 s32Error = 0;
3054         u8 *stamac;
3055         tstrWID strWID;
3056         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3057
3058
3059         strWID.u16WIDid = (u16)WID_SET_STA_MAC_INACTIVE_TIME;
3060         strWID.enuWIDtype = WID_STR;
3061         strWID.s32ValueSize = ETH_ALEN;
3062         strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
3063
3064
3065         stamac = strWID.ps8WidVal;
3066         memcpy(stamac, strHostIfStaInactiveT->mac, ETH_ALEN);
3067
3068
3069         PRINT_D(CFG80211_DBG, "SETING STA inactive time\n");
3070
3071
3072         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3073                                    get_id_from_handler(pstrWFIDrv));
3074         /*get the value by searching the local copy*/
3075         if (s32Error) {
3076                 PRINT_ER("Failed to SET incative time\n");
3077                 return -EFAULT;
3078         }
3079
3080
3081         strWID.u16WIDid = (u16)WID_GET_INACTIVE_TIME;
3082         strWID.enuWIDtype = WID_INT;
3083         strWID.ps8WidVal = (s8 *)&gu32InactiveTime;
3084         strWID.s32ValueSize = sizeof(u32);
3085
3086
3087         s32Error = send_config_pkt(GET_CFG, &strWID, 1, true,
3088                                    get_id_from_handler(pstrWFIDrv));
3089         /*get the value by searching the local copy*/
3090         if (s32Error) {
3091                 PRINT_ER("Failed to get incative time\n");
3092                 return -EFAULT;
3093         }
3094
3095
3096         PRINT_D(CFG80211_DBG, "Getting inactive time : %d\n", gu32InactiveTime);
3097
3098         up(&(pstrWFIDrv->hSemInactiveTime));
3099
3100         return s32Error;
3101
3102
3103
3104 }
3105
3106
3107 /**
3108  *  @brief Handle_AddBeacon
3109  *  @details       Sending config packet to add beacon
3110  *  @param[in]    struct beacon_attr *pstrSetBeaconParam
3111  *  @return         NONE
3112  *  @author
3113  *  @date
3114  *  @version    1.0
3115  */
3116 static void Handle_AddBeacon(tstrWILC_WFIDrv *drvHandler,
3117                              struct beacon_attr *pstrSetBeaconParam)
3118 {
3119         s32 s32Error = 0;
3120         tstrWID strWID;
3121         u8 *pu8CurrByte;
3122         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3123
3124         PRINT_D(HOSTINF_DBG, "Adding BEACON\n");
3125
3126         strWID.u16WIDid = (u16)WID_ADD_BEACON;
3127         strWID.enuWIDtype = WID_BIN;
3128         strWID.s32ValueSize = pstrSetBeaconParam->u32HeadLen + pstrSetBeaconParam->u32TailLen + 16;
3129         strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
3130         if (strWID.ps8WidVal == NULL)
3131                 goto ERRORHANDLER;
3132
3133         pu8CurrByte = strWID.ps8WidVal;
3134         *pu8CurrByte++ = (pstrSetBeaconParam->u32Interval & 0xFF);
3135         *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 8) & 0xFF);
3136         *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 16) & 0xFF);
3137         *pu8CurrByte++ = ((pstrSetBeaconParam->u32Interval >> 24) & 0xFF);
3138
3139         *pu8CurrByte++ = (pstrSetBeaconParam->u32DTIMPeriod & 0xFF);
3140         *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 8) & 0xFF);
3141         *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 16) & 0xFF);
3142         *pu8CurrByte++ = ((pstrSetBeaconParam->u32DTIMPeriod >> 24) & 0xFF);
3143
3144         *pu8CurrByte++ = (pstrSetBeaconParam->u32HeadLen & 0xFF);
3145         *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 8) & 0xFF);
3146         *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 16) & 0xFF);
3147         *pu8CurrByte++ = ((pstrSetBeaconParam->u32HeadLen >> 24) & 0xFF);
3148
3149         memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Head, pstrSetBeaconParam->u32HeadLen);
3150         pu8CurrByte += pstrSetBeaconParam->u32HeadLen;
3151
3152         *pu8CurrByte++ = (pstrSetBeaconParam->u32TailLen & 0xFF);
3153         *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 8) & 0xFF);
3154         *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 16) & 0xFF);
3155         *pu8CurrByte++ = ((pstrSetBeaconParam->u32TailLen >> 24) & 0xFF);
3156
3157         if (pstrSetBeaconParam->pu8Tail > 0)
3158                 memcpy(pu8CurrByte, pstrSetBeaconParam->pu8Tail, pstrSetBeaconParam->u32TailLen);
3159         pu8CurrByte += pstrSetBeaconParam->u32TailLen;
3160
3161
3162
3163         /*Sending Cfg*/
3164         s32Error = send_config_pkt(SET_CFG, &strWID, 1, false,
3165                                    get_id_from_handler(pstrWFIDrv));
3166         if (s32Error)
3167                 PRINT_ER("Failed to send add beacon config packet\n");
3168
3169 ERRORHANDLER:
3170         kfree(strWID.ps8WidVal);
3171         kfree(pstrSetBeaconParam->pu8Head);
3172         kfree(pstrSetBeaconParam->pu8Tail);
3173 }
3174
3175
3176 /**
3177  *  @brief Handle_AddBeacon
3178  *  @details       Sending config packet to delete beacon
3179  *  @param[in]  tstrWILC_WFIDrv *drvHandler
3180  *  @return         NONE
3181  *  @author
3182  *  @date
3183  *  @version    1.0
3184  */
3185 static void Handle_DelBeacon(tstrWILC_WFIDrv *drvHandler)
3186 {
3187         s32 s32Error = 0;
3188         tstrWID strWID;
3189         u8 *pu8CurrByte;
3190         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3191
3192         strWID.u16WIDid = (u16)WID_DEL_BEACON;
3193         strWID.enuWIDtype = WID_CHAR;
3194         strWID.s32ValueSize = sizeof(char);
3195         strWID.ps8WidVal = &gu8DelBcn;
3196
3197         if (strWID.ps8WidVal == NULL)
3198                 return;
3199
3200         pu8CurrByte = strWID.ps8WidVal;
3201
3202         PRINT_D(HOSTINF_DBG, "Deleting BEACON\n");
3203         /* TODO: build del beacon message*/
3204
3205         /*Sending Cfg*/
3206         s32Error = send_config_pkt(SET_CFG, &strWID, 1, false,
3207                                    get_id_from_handler(pstrWFIDrv));
3208         if (s32Error)
3209                 PRINT_ER("Failed to send delete beacon config packet\n");
3210 }
3211
3212
3213 /**
3214  *  @brief WILC_HostIf_PackStaParam
3215  *  @details       Handling packing of the station params in a buffer
3216  *  @param[in]   u8* pu8Buffer, struct add_sta_param *pstrStationParam
3217  *  @return         NONE
3218  *  @author
3219  *  @date
3220  *  @version    1.0
3221  */
3222 static u32 WILC_HostIf_PackStaParam(u8 *pu8Buffer,
3223                                     struct add_sta_param *pstrStationParam)
3224 {
3225         u8 *pu8CurrByte;
3226
3227         pu8CurrByte = pu8Buffer;
3228
3229         PRINT_D(HOSTINF_DBG, "Packing STA params\n");
3230         memcpy(pu8CurrByte, pstrStationParam->au8BSSID, ETH_ALEN);
3231         pu8CurrByte +=  ETH_ALEN;
3232
3233         *pu8CurrByte++ = pstrStationParam->u16AssocID & 0xFF;
3234         *pu8CurrByte++ = (pstrStationParam->u16AssocID >> 8) & 0xFF;
3235
3236         *pu8CurrByte++ = pstrStationParam->u8NumRates;
3237         if (pstrStationParam->u8NumRates > 0)
3238                 memcpy(pu8CurrByte, pstrStationParam->pu8Rates, pstrStationParam->u8NumRates);
3239         pu8CurrByte += pstrStationParam->u8NumRates;
3240
3241         *pu8CurrByte++ = pstrStationParam->bIsHTSupported;
3242         *pu8CurrByte++ = pstrStationParam->u16HTCapInfo & 0xFF;
3243         *pu8CurrByte++ = (pstrStationParam->u16HTCapInfo >> 8) & 0xFF;
3244
3245         *pu8CurrByte++ = pstrStationParam->u8AmpduParams;
3246         memcpy(pu8CurrByte, pstrStationParam->au8SuppMCsSet, WILC_SUPP_MCS_SET_SIZE);
3247         pu8CurrByte += WILC_SUPP_MCS_SET_SIZE;
3248
3249         *pu8CurrByte++ = pstrStationParam->u16HTExtParams & 0xFF;
3250         *pu8CurrByte++ = (pstrStationParam->u16HTExtParams >> 8) & 0xFF;
3251
3252         *pu8CurrByte++ = pstrStationParam->u32TxBeamformingCap & 0xFF;
3253         *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 8) & 0xFF;
3254         *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 16) & 0xFF;
3255         *pu8CurrByte++ = (pstrStationParam->u32TxBeamformingCap >> 24) & 0xFF;
3256
3257         *pu8CurrByte++ = pstrStationParam->u8ASELCap;
3258
3259         *pu8CurrByte++ = pstrStationParam->u16FlagsMask & 0xFF;
3260         *pu8CurrByte++ = (pstrStationParam->u16FlagsMask >> 8) & 0xFF;
3261
3262         *pu8CurrByte++ = pstrStationParam->u16FlagsSet & 0xFF;
3263         *pu8CurrByte++ = (pstrStationParam->u16FlagsSet >> 8) & 0xFF;
3264
3265         return pu8CurrByte - pu8Buffer;
3266 }
3267
3268 /**
3269  *  @brief Handle_AddStation
3270  *  @details       Sending config packet to add station
3271  *  @param[in]   struct add_sta_param *pstrStationParam
3272  *  @return         NONE
3273  *  @author
3274  *  @date
3275  *  @version    1.0
3276  */
3277 static void Handle_AddStation(tstrWILC_WFIDrv *drvHandler,
3278                               struct add_sta_param *pstrStationParam)
3279 {
3280         s32 s32Error = 0;
3281         tstrWID strWID;
3282         u8 *pu8CurrByte;
3283         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3284
3285         PRINT_D(HOSTINF_DBG, "Handling add station\n");
3286         strWID.u16WIDid = (u16)WID_ADD_STA;
3287         strWID.enuWIDtype = WID_BIN;
3288         strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
3289
3290         strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
3291         if (strWID.ps8WidVal == NULL)
3292                 goto ERRORHANDLER;
3293
3294         pu8CurrByte = strWID.ps8WidVal;
3295         pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
3296
3297         /*Sending Cfg*/
3298         s32Error = send_config_pkt(SET_CFG, &strWID, 1, false,
3299                                    get_id_from_handler(pstrWFIDrv));
3300         if (s32Error != 0)
3301                 PRINT_ER("Failed to send add station config packet\n");
3302
3303 ERRORHANDLER:
3304         kfree(pstrStationParam->pu8Rates);
3305         kfree(strWID.ps8WidVal);
3306 }
3307
3308 /**
3309  *  @brief Handle_DelAllSta
3310  *  @details        Sending config packet to delete station
3311  *  @param[in]   tstrHostIFDelSta* pstrDelStaParam
3312  *  @return         NONE
3313  *  @author
3314  *  @date
3315  *  @version    1.0
3316  */
3317 static void Handle_DelAllSta(tstrWILC_WFIDrv *drvHandler,
3318                              struct del_all_sta *pstrDelAllStaParam)
3319 {
3320         s32 s32Error = 0;
3321
3322         tstrWID strWID;
3323         u8 *pu8CurrByte;
3324         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3325         u8 i;
3326         u8 au8Zero_Buff[6] = {0};
3327
3328         strWID.u16WIDid = (u16)WID_DEL_ALL_STA;
3329         strWID.enuWIDtype = WID_STR;
3330         strWID.s32ValueSize = (pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1;
3331
3332         PRINT_D(HOSTINF_DBG, "Handling delete station\n");
3333
3334         strWID.ps8WidVal = kmalloc((pstrDelAllStaParam->u8Num_AssocSta * ETH_ALEN) + 1, GFP_KERNEL);
3335         if (strWID.ps8WidVal == NULL)
3336                 goto ERRORHANDLER;
3337
3338         pu8CurrByte = strWID.ps8WidVal;
3339
3340         *(pu8CurrByte++) = pstrDelAllStaParam->u8Num_AssocSta;
3341
3342         for (i = 0; i < MAX_NUM_STA; i++) {
3343                 if (memcmp(pstrDelAllStaParam->au8Sta_DelAllSta[i], au8Zero_Buff, ETH_ALEN))
3344                         memcpy(pu8CurrByte, pstrDelAllStaParam->au8Sta_DelAllSta[i], ETH_ALEN);
3345                 else
3346                         continue;
3347
3348                 pu8CurrByte += ETH_ALEN;
3349         }
3350
3351         /*Sending Cfg*/
3352         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3353                                    get_id_from_handler(pstrWFIDrv));
3354         if (s32Error)
3355                 PRINT_ER("Failed to send add station config packet\n");
3356
3357 ERRORHANDLER:
3358         kfree(strWID.ps8WidVal);
3359
3360         up(&hWaitResponse);
3361 }
3362
3363
3364 /**
3365  *  @brief Handle_DelStation
3366  *  @details        Sending config packet to delete station
3367  *  @param[in]   struct del_sta *pstrDelStaParam
3368  *  @return         NONE
3369  *  @author
3370  *  @date
3371  *  @version    1.0
3372  */
3373 static void Handle_DelStation(tstrWILC_WFIDrv *drvHandler,
3374                               struct del_sta *pstrDelStaParam)
3375 {
3376         s32 s32Error = 0;
3377         tstrWID strWID;
3378         u8 *pu8CurrByte;
3379         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3380
3381         strWID.u16WIDid = (u16)WID_REMOVE_STA;
3382         strWID.enuWIDtype = WID_BIN;
3383         strWID.s32ValueSize = ETH_ALEN;
3384
3385         PRINT_D(HOSTINF_DBG, "Handling delete station\n");
3386
3387         strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
3388         if (strWID.ps8WidVal == NULL)
3389                 goto ERRORHANDLER;
3390
3391         pu8CurrByte = strWID.ps8WidVal;
3392
3393         memcpy(pu8CurrByte, pstrDelStaParam->au8MacAddr, ETH_ALEN);
3394
3395         /*Sending Cfg*/
3396         s32Error = send_config_pkt(SET_CFG, &strWID, 1, false,
3397                                    get_id_from_handler(pstrWFIDrv));
3398         if (s32Error)
3399                 PRINT_ER("Failed to send add station config packet\n");
3400
3401 ERRORHANDLER:
3402         kfree(strWID.ps8WidVal);
3403 }
3404
3405
3406 /**
3407  *  @brief Handle_EditStation
3408  *  @details        Sending config packet to edit station
3409  *  @param[in]   struct add_sta_param *pstrStationParam
3410  *  @return         NONE
3411  *  @author
3412  *  @date
3413  *  @version    1.0
3414  */
3415 static void Handle_EditStation(tstrWILC_WFIDrv *drvHandler,
3416                                struct add_sta_param *pstrStationParam)
3417 {
3418         s32 s32Error = 0;
3419         tstrWID strWID;
3420         u8 *pu8CurrByte;
3421         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3422
3423         strWID.u16WIDid = (u16)WID_EDIT_STA;
3424         strWID.enuWIDtype = WID_BIN;
3425         strWID.s32ValueSize = WILC_ADD_STA_LENGTH + pstrStationParam->u8NumRates;
3426
3427         PRINT_D(HOSTINF_DBG, "Handling edit station\n");
3428         strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
3429         if (strWID.ps8WidVal == NULL)
3430                 goto ERRORHANDLER;
3431
3432         pu8CurrByte = strWID.ps8WidVal;
3433         pu8CurrByte += WILC_HostIf_PackStaParam(pu8CurrByte, pstrStationParam);
3434
3435         /*Sending Cfg*/
3436         s32Error = send_config_pkt(SET_CFG, &strWID, 1, false,
3437                                    get_id_from_handler(pstrWFIDrv));
3438         if (s32Error)
3439                 PRINT_ER("Failed to send edit station config packet\n");
3440
3441 ERRORHANDLER:
3442         kfree(pstrStationParam->pu8Rates);
3443         kfree(strWID.ps8WidVal);
3444 }
3445
3446 /**
3447  *  @brief Handle_RemainOnChan
3448  *  @details        Sending config packet to edit station
3449  *  @param[in]   tstrWILC_AddStaParam* pstrStationParam
3450  *  @return         NONE
3451  *  @author
3452  *  @date
3453  *  @version    1.0
3454  */
3455 static int Handle_RemainOnChan(tstrWILC_WFIDrv *drvHandler,
3456                                struct remain_ch *pstrHostIfRemainOnChan)
3457 {
3458         s32 s32Error = 0;
3459         u8 u8remain_on_chan_flag;
3460         tstrWID strWID;
3461         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler;
3462
3463         /*If it's a pendig remain-on-channel, don't overwrite gWFiDrvHandle values (since incoming msg is garbbage)*/
3464         if (!pstrWFIDrv->u8RemainOnChan_pendingreq) {
3465                 pstrWFIDrv->strHostIfRemainOnChan.pVoid = pstrHostIfRemainOnChan->pVoid;
3466                 pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired = pstrHostIfRemainOnChan->pRemainOnChanExpired;
3467                 pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady = pstrHostIfRemainOnChan->pRemainOnChanReady;
3468                 pstrWFIDrv->strHostIfRemainOnChan.u16Channel = pstrHostIfRemainOnChan->u16Channel;
3469                 pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID = pstrHostIfRemainOnChan->u32ListenSessionID;
3470         } else {
3471                 /*Set the channel to use it as a wid val*/
3472                 pstrHostIfRemainOnChan->u16Channel = pstrWFIDrv->strHostIfRemainOnChan.u16Channel;
3473         }
3474
3475         if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) {
3476                 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while scanning return\n");
3477                 pstrWFIDrv->u8RemainOnChan_pendingreq = 1;
3478                 s32Error = -EBUSY;
3479                 goto ERRORHANDLER;
3480         }
3481         if (pstrWFIDrv->enuHostIFstate == HOST_IF_WAITING_CONN_RESP) {
3482                 PRINT_INFO(GENERIC_DBG, "Required to remain on chan while connecting return\n");
3483                 s32Error = -EBUSY;
3484                 goto ERRORHANDLER;
3485         }
3486
3487         if (g_obtainingIP || connecting) {
3488                 PRINT_D(GENERIC_DBG, "[handle_scan]: Don't do obss scan until IP adresss is obtained\n");
3489                 s32Error = -EBUSY;
3490                 goto ERRORHANDLER;
3491         }
3492
3493         PRINT_D(HOSTINF_DBG, "Setting channel :%d\n", pstrHostIfRemainOnChan->u16Channel);
3494
3495         u8remain_on_chan_flag = true;
3496         strWID.u16WIDid = (u16)WID_REMAIN_ON_CHAN;
3497         strWID.enuWIDtype       = WID_STR;
3498         strWID.s32ValueSize = 2;
3499         strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
3500
3501         if (strWID.ps8WidVal == NULL) {
3502                 s32Error = -ENOMEM;
3503                 goto ERRORHANDLER;
3504         }
3505
3506         strWID.ps8WidVal[0] = u8remain_on_chan_flag;
3507         strWID.ps8WidVal[1] = (s8)pstrHostIfRemainOnChan->u16Channel;
3508
3509         /*Sending Cfg*/
3510         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3511                                    get_id_from_handler(pstrWFIDrv));
3512         if (s32Error != 0)
3513                 PRINT_ER("Failed to set remain on channel\n");
3514
3515 ERRORHANDLER:
3516         {
3517                 P2P_LISTEN_STATE = 1;
3518                 pstrWFIDrv->hRemainOnChannel.data = (unsigned long)pstrWFIDrv;
3519                 mod_timer(&pstrWFIDrv->hRemainOnChannel,
3520                           jiffies +
3521                           msecs_to_jiffies(pstrHostIfRemainOnChan->u32duration));
3522
3523                 /*Calling CFG ready_on_channel*/
3524                 if (pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady)
3525                         pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanReady(pstrWFIDrv->strHostIfRemainOnChan.pVoid);
3526
3527                 if (pstrWFIDrv->u8RemainOnChan_pendingreq)
3528                         pstrWFIDrv->u8RemainOnChan_pendingreq = 0;
3529         }
3530         return s32Error;
3531 }
3532
3533 /**
3534  *  @brief Handle_RegisterFrame
3535  *  @details
3536  *  @param[in]
3537  *  @return         NONE
3538  *  @author
3539  *  @date
3540  *  @version    1.0
3541  */
3542 static int Handle_RegisterFrame(tstrWILC_WFIDrv *drvHandler,
3543                                 struct reg_frame *pstrHostIfRegisterFrame)
3544 {
3545         s32 s32Error = 0;
3546         tstrWID strWID;
3547         u8 *pu8CurrByte;
3548         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3549
3550         PRINT_D(HOSTINF_DBG, "Handling frame register Flag : %d FrameType: %d\n", pstrHostIfRegisterFrame->bReg, pstrHostIfRegisterFrame->u16FrameType);
3551
3552         /*prepare configuration packet*/
3553         strWID.u16WIDid = (u16)WID_REGISTER_FRAME;
3554         strWID.enuWIDtype = WID_STR;
3555         strWID.ps8WidVal = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
3556         if (strWID.ps8WidVal == NULL)
3557                 return -ENOMEM;
3558
3559         pu8CurrByte = strWID.ps8WidVal;
3560
3561         *pu8CurrByte++ = pstrHostIfRegisterFrame->bReg;
3562         *pu8CurrByte++ = pstrHostIfRegisterFrame->u8Regid;
3563         memcpy(pu8CurrByte, &(pstrHostIfRegisterFrame->u16FrameType), sizeof(u16));
3564
3565
3566         strWID.s32ValueSize = sizeof(u16) + 2;
3567
3568
3569         /*Sending Cfg*/
3570         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3571                                    get_id_from_handler(pstrWFIDrv));
3572         if (s32Error) {
3573                 PRINT_ER("Failed to frame register config packet\n");
3574                 s32Error = -EINVAL;
3575         }
3576
3577         return s32Error;
3578
3579 }
3580
3581 /**
3582  *  @brief                      Handle_ListenStateExpired
3583  *  @details            Handle of listen state expiration
3584  *  @param[in]          NONE
3585  *  @return             Error code.
3586  *  @author
3587  *  @date
3588  *  @version            1.0
3589  */
3590 #define FALSE_FRMWR_CHANNEL 100
3591 static u32 Handle_ListenStateExpired(tstrWILC_WFIDrv *drvHandler,
3592                                      struct remain_ch *pstrHostIfRemainOnChan)
3593 {
3594         u8 u8remain_on_chan_flag;
3595         tstrWID strWID;
3596         s32 s32Error = 0;
3597         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *) drvHandler;
3598
3599         PRINT_D(HOSTINF_DBG, "CANCEL REMAIN ON CHAN\n");
3600
3601         /*Make sure we are already in listen state*/
3602         /*This is to handle duplicate expiry messages (listen timer fired and supplicant called cancel_remain_on_channel())*/
3603         if (P2P_LISTEN_STATE) {
3604                 u8remain_on_chan_flag = false;
3605                 strWID.u16WIDid = (u16)WID_REMAIN_ON_CHAN;
3606                 strWID.enuWIDtype       = WID_STR;
3607                 strWID.s32ValueSize = 2;
3608                 strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
3609
3610                 if (strWID.ps8WidVal == NULL)
3611                         PRINT_ER("Failed to allocate memory\n");
3612
3613                 strWID.ps8WidVal[0] = u8remain_on_chan_flag;
3614                 strWID.ps8WidVal[1] = FALSE_FRMWR_CHANNEL;
3615
3616                 /*Sending Cfg*/
3617                 s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3618                                            get_id_from_handler(pstrWFIDrv));
3619                 if (s32Error != 0) {
3620                         PRINT_ER("Failed to set remain on channel\n");
3621                         goto _done_;
3622                 }
3623
3624                 if (pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired) {
3625                         pstrWFIDrv->strHostIfRemainOnChan.pRemainOnChanExpired(pstrWFIDrv->strHostIfRemainOnChan.pVoid
3626                                                                                , pstrHostIfRemainOnChan->u32ListenSessionID);
3627                 }
3628                 P2P_LISTEN_STATE = 0;
3629         } else {
3630                 PRINT_D(GENERIC_DBG, "Not in listen state\n");
3631                 s32Error = -EFAULT;
3632         }
3633
3634 _done_:
3635         return s32Error;
3636 }
3637
3638
3639 /**
3640  *  @brief                      ListenTimerCB
3641  *  @details            Callback function of remain-on-channel timer
3642  *  @param[in]          NONE
3643  *  @return             Error code.
3644  *  @author
3645  *  @date
3646  *  @version            1.0
3647  */
3648 static void ListenTimerCB(unsigned long arg)
3649 {
3650         s32 s32Error = 0;
3651         struct host_if_msg msg;
3652         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)arg;
3653         /*Stopping remain-on-channel timer*/
3654         del_timer(&pstrWFIDrv->hRemainOnChannel);
3655
3656         /* prepare the Timer Callback message */
3657         memset(&msg, 0, sizeof(struct host_if_msg));
3658         msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
3659         msg.drvHandler = pstrWFIDrv;
3660         msg.body.remain_on_ch.u32ListenSessionID = pstrWFIDrv->strHostIfRemainOnChan.u32ListenSessionID;
3661
3662         /* send the message */
3663         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
3664         if (s32Error)
3665                 PRINT_ER("wilc_mq_send fail\n");
3666 }
3667
3668 /**
3669  *  @brief Handle_EditStation
3670  *  @details        Sending config packet to edit station
3671  *  @param[in]   tstrWILC_AddStaParam* pstrStationParam
3672  *  @return         NONE
3673  *  @author
3674  *  @date
3675  *  @version    1.0
3676  */
3677 static void Handle_PowerManagement(tstrWILC_WFIDrv *drvHandler,
3678                                    struct power_mgmt_param *strPowerMgmtParam)
3679 {
3680         s32 s32Error = 0;
3681         tstrWID strWID;
3682         s8 s8PowerMode;
3683         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3684
3685         strWID.u16WIDid = (u16)WID_POWER_MANAGEMENT;
3686
3687         if (strPowerMgmtParam->bIsEnabled == true)
3688                 s8PowerMode = MIN_FAST_PS;
3689         else
3690                 s8PowerMode = NO_POWERSAVE;
3691         PRINT_D(HOSTINF_DBG, "Handling power mgmt to %d\n", s8PowerMode);
3692         strWID.ps8WidVal = &s8PowerMode;
3693         strWID.s32ValueSize = sizeof(char);
3694
3695         PRINT_D(HOSTINF_DBG, "Handling Power Management\n");
3696
3697         /*Sending Cfg*/
3698         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3699                                    get_id_from_handler(pstrWFIDrv));
3700         if (s32Error)
3701                 PRINT_ER("Failed to send power management config packet\n");
3702 }
3703
3704 /**
3705  *  @brief Handle_SetMulticastFilter
3706  *  @details        Set Multicast filter in firmware
3707  *  @param[in]   struct set_multicast *strHostIfSetMulti
3708  *  @return         NONE
3709  *  @author             asobhy
3710  *  @date
3711  *  @version    1.0
3712  */
3713 static void Handle_SetMulticastFilter(tstrWILC_WFIDrv *drvHandler,
3714                                       struct set_multicast *strHostIfSetMulti)
3715 {
3716         s32 s32Error = 0;
3717         tstrWID strWID;
3718         u8 *pu8CurrByte;
3719
3720         PRINT_D(HOSTINF_DBG, "Setup Multicast Filter\n");
3721
3722         strWID.u16WIDid = (u16)WID_SETUP_MULTICAST_FILTER;
3723         strWID.enuWIDtype = WID_BIN;
3724         strWID.s32ValueSize = sizeof(struct set_multicast) + ((strHostIfSetMulti->u32count) * ETH_ALEN);
3725         strWID.ps8WidVal = kmalloc(strWID.s32ValueSize, GFP_KERNEL);
3726         if (strWID.ps8WidVal == NULL)
3727                 goto ERRORHANDLER;
3728
3729         pu8CurrByte = strWID.ps8WidVal;
3730         *pu8CurrByte++ = (strHostIfSetMulti->bIsEnabled & 0xFF);
3731         *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 8) & 0xFF);
3732         *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 16) & 0xFF);
3733         *pu8CurrByte++ = ((strHostIfSetMulti->bIsEnabled >> 24) & 0xFF);
3734
3735         *pu8CurrByte++ = (strHostIfSetMulti->u32count & 0xFF);
3736         *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 8) & 0xFF);
3737         *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 16) & 0xFF);
3738         *pu8CurrByte++ = ((strHostIfSetMulti->u32count >> 24) & 0xFF);
3739
3740         if ((strHostIfSetMulti->u32count) > 0)
3741                 memcpy(pu8CurrByte, gau8MulticastMacAddrList, ((strHostIfSetMulti->u32count) * ETH_ALEN));
3742
3743         /*Sending Cfg*/
3744         s32Error = send_config_pkt(SET_CFG, &strWID, 1, false,
3745                                    get_id_from_handler(drvHandler));
3746         if (s32Error)
3747                 PRINT_ER("Failed to send setup multicast config packet\n");
3748
3749 ERRORHANDLER:
3750         kfree(strWID.ps8WidVal);
3751
3752 }
3753
3754
3755 /**
3756  *  @brief                      Handle_AddBASession
3757  *  @details            Add block ack session
3758  *  @param[in]          tstrHostIFSetMulti* strHostIfSetMulti
3759  *  @return             NONE
3760  *  @author             Amr Abdel-Moghny
3761  *  @date                       Feb. 2014
3762  *  @version            9.0
3763  */
3764 static s32 Handle_AddBASession(tstrWILC_WFIDrv *drvHandler,
3765                                struct ba_session_info *strHostIfBASessionInfo)
3766 {
3767         s32 s32Error = 0;
3768         tstrWID strWID;
3769         int AddbaTimeout = 100;
3770         char *ptr = NULL;
3771         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3772
3773         PRINT_D(HOSTINF_DBG, "Opening Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\nBufferSize == %d\nSessionTimeOut = %d\n",
3774                 strHostIfBASessionInfo->au8Bssid[0],
3775                 strHostIfBASessionInfo->au8Bssid[1],
3776                 strHostIfBASessionInfo->au8Bssid[2],
3777                 strHostIfBASessionInfo->u16BufferSize,
3778                 strHostIfBASessionInfo->u16SessionTimeout,
3779                 strHostIfBASessionInfo->u8Ted);
3780
3781         strWID.u16WIDid = (u16)WID_11E_P_ACTION_REQ;
3782         strWID.enuWIDtype = WID_STR;
3783         strWID.ps8WidVal = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
3784         strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE;
3785         ptr = strWID.ps8WidVal;
3786         /* *ptr++ = 0x14; */
3787         *ptr++ = 0x14;
3788         *ptr++ = 0x3;
3789         *ptr++ = 0x0;
3790         memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
3791         ptr += ETH_ALEN;
3792         *ptr++ = strHostIfBASessionInfo->u8Ted;
3793         /* BA Policy*/
3794         *ptr++ = 1;
3795         /* Buffer size*/
3796         *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
3797         *ptr++ = ((strHostIfBASessionInfo->u16BufferSize >> 16) & 0xFF);
3798         /* BA timeout*/
3799         *ptr++ = (strHostIfBASessionInfo->u16SessionTimeout & 0xFF);
3800         *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
3801         /* ADDBA timeout*/
3802         *ptr++ = (AddbaTimeout & 0xFF);
3803         *ptr++ = ((AddbaTimeout >> 16) & 0xFF);
3804         /* Group Buffer Max Frames*/
3805         *ptr++ = 8;
3806         /* Group Buffer Timeout */
3807         *ptr++ = 0;
3808
3809         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3810                                    get_id_from_handler(pstrWFIDrv));
3811         if (s32Error)
3812                 PRINT_D(HOSTINF_DBG, "Couldn't open BA Session\n");
3813
3814
3815         strWID.u16WIDid = (u16)WID_11E_P_ACTION_REQ;
3816         strWID.enuWIDtype = WID_STR;
3817         strWID.s32ValueSize = 15;
3818         ptr = strWID.ps8WidVal;
3819         /* *ptr++ = 0x14; */
3820         *ptr++ = 15;
3821         *ptr++ = 7;
3822         *ptr++ = 0x2;
3823         memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
3824         ptr += ETH_ALEN;
3825         /* TID*/
3826         *ptr++ = strHostIfBASessionInfo->u8Ted;
3827         /* Max Num MSDU */
3828         *ptr++ = 8;
3829         /* BA timeout*/
3830         *ptr++ = (strHostIfBASessionInfo->u16BufferSize & 0xFF);
3831         *ptr++ = ((strHostIfBASessionInfo->u16SessionTimeout >> 16) & 0xFF);
3832         /*Ack-Policy */
3833         *ptr++ = 3;
3834         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3835                                    get_id_from_handler(pstrWFIDrv));
3836
3837         if (strWID.ps8WidVal != NULL)
3838                 kfree(strWID.ps8WidVal);
3839
3840         return s32Error;
3841
3842 }
3843
3844 /**
3845  *  @brief                      Handle_DelAllRxBASessions
3846  *  @details            Delete all Rx BA sessions
3847  *  @param[in]          tstrHostIFSetMulti* strHostIfSetMulti
3848  *  @return             NONE
3849  *  @author             Abdelrahman Sobhy
3850  *  @date                       Feb. 2013
3851  *  @version            9.0
3852  */
3853 static s32 Handle_DelAllRxBASessions(tstrWILC_WFIDrv *drvHandler,
3854                                      struct ba_session_info *strHostIfBASessionInfo)
3855 {
3856         s32 s32Error = 0;
3857         tstrWID strWID;
3858         char *ptr = NULL;
3859         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)drvHandler;
3860
3861         PRINT_D(GENERIC_DBG, "Delete Block Ack session with\nBSSID = %.2x:%.2x:%.2x\nTID=%d\n",
3862                 strHostIfBASessionInfo->au8Bssid[0],
3863                 strHostIfBASessionInfo->au8Bssid[1],
3864                 strHostIfBASessionInfo->au8Bssid[2],
3865                 strHostIfBASessionInfo->u8Ted);
3866
3867         strWID.u16WIDid = (u16)WID_DEL_ALL_RX_BA;
3868         strWID.enuWIDtype = WID_STR;
3869         strWID.ps8WidVal = kmalloc(BLOCK_ACK_REQ_SIZE, GFP_KERNEL);
3870         strWID.s32ValueSize = BLOCK_ACK_REQ_SIZE;
3871         ptr = strWID.ps8WidVal;
3872         *ptr++ = 0x14;
3873         *ptr++ = 0x3;
3874         *ptr++ = 0x2;
3875         memcpy(ptr, strHostIfBASessionInfo->au8Bssid, ETH_ALEN);
3876         ptr += ETH_ALEN;
3877         *ptr++ = strHostIfBASessionInfo->u8Ted;
3878         /* BA direction = recipent*/
3879         *ptr++ = 0;
3880         /* Delba Reason */
3881         *ptr++ = 32; /* Unspecific QOS reason */
3882
3883         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
3884                                    get_id_from_handler(pstrWFIDrv));
3885         if (s32Error)
3886                 PRINT_D(HOSTINF_DBG, "Couldn't delete BA Session\n");
3887
3888
3889         if (strWID.ps8WidVal != NULL)
3890                 kfree(strWID.ps8WidVal);
3891
3892         up(&hWaitResponse);
3893
3894         return s32Error;
3895
3896 }
3897
3898 /**
3899  *  @brief hostIFthread
3900  *  @details        Main thread to handle message queue requests
3901  *  @param[in]   void* pvArg
3902  *  @return         NONE
3903  *  @author
3904  *  @date
3905  *  @version    1.0
3906  */
3907 static int hostIFthread(void *pvArg)
3908 {
3909         u32 u32Ret;
3910         struct host_if_msg msg;
3911         tstrWILC_WFIDrv *pstrWFIDrv;
3912
3913         memset(&msg, 0, sizeof(struct host_if_msg));
3914
3915         while (1) {
3916                 wilc_mq_recv(&gMsgQHostIF, &msg, sizeof(struct host_if_msg), &u32Ret);
3917                 pstrWFIDrv = (tstrWILC_WFIDrv *)msg.drvHandler;
3918                 if (msg.id == HOST_IF_MSG_EXIT) {
3919                         PRINT_D(GENERIC_DBG, "THREAD: Exiting HostIfThread\n");
3920                         break;
3921                 }
3922
3923
3924                 /*Re-Queue HIF message*/
3925                 if ((!g_wilc_initialized)) {
3926                         PRINT_D(GENERIC_DBG, "--WAIT--");
3927                         usleep_range(200 * 1000, 200 * 1000);
3928                         wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
3929                         continue;
3930                 }
3931
3932                 if (msg.id == HOST_IF_MSG_CONNECT && pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult != NULL) {
3933                         PRINT_D(HOSTINF_DBG, "Requeue connect request till scan done received\n");
3934                         wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
3935                         usleep_range(2 * 1000, 2 * 1000);
3936                         continue;
3937                 }
3938
3939                 switch (msg.id) {
3940                 case HOST_IF_MSG_Q_IDLE:
3941                         Handle_wait_msg_q_empty();
3942                         break;
3943
3944                 case HOST_IF_MSG_SCAN:
3945                         Handle_Scan(msg.drvHandler, &msg.body.scan_info);
3946                         break;
3947
3948                 case HOST_IF_MSG_CONNECT:
3949                         Handle_Connect(msg.drvHandler, &msg.body.con_info);
3950                         break;
3951
3952                 case HOST_IF_MSG_FLUSH_CONNECT:
3953                         Handle_FlushConnect(msg.drvHandler);
3954                         break;
3955
3956                 case HOST_IF_MSG_RCVD_NTWRK_INFO:
3957                         Handle_RcvdNtwrkInfo(msg.drvHandler, &msg.body.net_info);
3958                         break;
3959
3960                 case HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO:
3961                         Handle_RcvdGnrlAsyncInfo(msg.drvHandler, &msg.body.async_info);
3962                         break;
3963
3964                 case HOST_IF_MSG_KEY:
3965                         Handle_Key(msg.drvHandler, &msg.body.key_info);
3966                         break;
3967
3968                 case HOST_IF_MSG_CFG_PARAMS:
3969
3970                         Handle_CfgParam(msg.drvHandler, &msg.body.cfg_info);
3971                         break;
3972
3973                 case HOST_IF_MSG_SET_CHANNEL:
3974                         Handle_SetChannel(msg.drvHandler, &msg.body.channel_info);
3975                         break;
3976
3977                 case HOST_IF_MSG_DISCONNECT:
3978                         Handle_Disconnect(msg.drvHandler);
3979                         break;
3980
3981                 case HOST_IF_MSG_RCVD_SCAN_COMPLETE:
3982                         del_timer(&pstrWFIDrv->hScanTimer);
3983                         PRINT_D(HOSTINF_DBG, "scan completed successfully\n");
3984
3985                         /*Allow chip sleep, only if both interfaces are not connected*/
3986                         if (!linux_wlan_get_num_conn_ifcs())
3987                                 chip_sleep_manually(INFINITE_SLEEP_TIME);
3988
3989                         Handle_ScanDone(msg.drvHandler, SCAN_EVENT_DONE);
3990
3991                         if (pstrWFIDrv->u8RemainOnChan_pendingreq)
3992                                 Handle_RemainOnChan(msg.drvHandler, &msg.body.remain_on_ch);
3993
3994                         break;
3995
3996                 case HOST_IF_MSG_GET_RSSI:
3997                         Handle_GetRssi(msg.drvHandler);
3998                         break;
3999
4000                 case HOST_IF_MSG_GET_LINKSPEED:
4001                         Handle_GetLinkspeed(msg.drvHandler);
4002                         break;
4003
4004                 case HOST_IF_MSG_GET_STATISTICS:
4005                         Handle_GetStatistics(msg.drvHandler, (tstrStatistics *)msg.body.data);
4006                         break;
4007
4008                 case HOST_IF_MSG_GET_CHNL:
4009                         Handle_GetChnl(msg.drvHandler);
4010                         break;
4011
4012                 case HOST_IF_MSG_ADD_BEACON:
4013                         Handle_AddBeacon(msg.drvHandler, &msg.body.beacon_info);
4014                         break;
4015
4016                 case HOST_IF_MSG_DEL_BEACON:
4017                         Handle_DelBeacon(msg.drvHandler);
4018                         break;
4019
4020                 case HOST_IF_MSG_ADD_STATION:
4021                         Handle_AddStation(msg.drvHandler, &msg.body.add_sta_info);
4022                         break;
4023
4024                 case HOST_IF_MSG_DEL_STATION:
4025                         Handle_DelStation(msg.drvHandler, &msg.body.del_sta_info);
4026                         break;
4027
4028                 case HOST_IF_MSG_EDIT_STATION:
4029                         Handle_EditStation(msg.drvHandler, &msg.body.edit_sta_info);
4030                         break;
4031
4032                 case HOST_IF_MSG_GET_INACTIVETIME:
4033                         Handle_Get_InActiveTime(msg.drvHandler, &msg.body.mac_info);
4034                         break;
4035
4036                 case HOST_IF_MSG_SCAN_TIMER_FIRED:
4037                         PRINT_D(HOSTINF_DBG, "Scan Timeout\n");
4038
4039                         Handle_ScanDone(msg.drvHandler, SCAN_EVENT_ABORTED);
4040                         break;
4041
4042                 case HOST_IF_MSG_CONNECT_TIMER_FIRED:
4043                         PRINT_D(HOSTINF_DBG, "Connect Timeout\n");
4044                         Handle_ConnectTimeout(msg.drvHandler);
4045                         break;
4046
4047                 case HOST_IF_MSG_POWER_MGMT:
4048                         Handle_PowerManagement(msg.drvHandler, &msg.body.pwr_mgmt_info);
4049                         break;
4050
4051                 case HOST_IF_MSG_SET_WFIDRV_HANDLER:
4052                         Handle_SetWfiDrvHandler(msg.drvHandler,
4053                                                 &msg.body.drv);
4054                         break;
4055
4056                 case HOST_IF_MSG_SET_OPERATION_MODE:
4057                         Handle_SetOperationMode(msg.drvHandler, &msg.body.mode);
4058                         break;
4059
4060                 case HOST_IF_MSG_SET_IPADDRESS:
4061                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
4062                         Handle_set_IPAddress(msg.drvHandler, msg.body.ip_info.au8IPAddr, msg.body.ip_info.idx);
4063                         break;
4064
4065                 case HOST_IF_MSG_GET_IPADDRESS:
4066                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_IPADDRESS\n");
4067                         Handle_get_IPAddress(msg.drvHandler, msg.body.ip_info.au8IPAddr, msg.body.ip_info.idx);
4068                         break;
4069
4070                 case HOST_IF_MSG_SET_MAC_ADDRESS:
4071                         Handle_SetMacAddress(msg.drvHandler, &msg.body.set_mac_info);
4072                         break;
4073
4074                 case HOST_IF_MSG_GET_MAC_ADDRESS:
4075                         Handle_GetMacAddress(msg.drvHandler, &msg.body.get_mac_info);
4076                         break;
4077
4078                 case HOST_IF_MSG_REMAIN_ON_CHAN:
4079                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REMAIN_ON_CHAN\n");
4080                         Handle_RemainOnChan(msg.drvHandler, &msg.body.remain_on_ch);
4081                         break;
4082
4083                 case HOST_IF_MSG_REGISTER_FRAME:
4084                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_REGISTER_FRAME\n");
4085                         Handle_RegisterFrame(msg.drvHandler, &msg.body.reg_frame);
4086                         break;
4087
4088                 case HOST_IF_MSG_LISTEN_TIMER_FIRED:
4089                         Handle_ListenStateExpired(msg.drvHandler, &msg.body.remain_on_ch);
4090                         break;
4091
4092                 case HOST_IF_MSG_SET_MULTICAST_FILTER:
4093                         PRINT_D(HOSTINF_DBG, "HOST_IF_MSG_SET_MULTICAST_FILTER\n");
4094                         Handle_SetMulticastFilter(msg.drvHandler, &msg.body.multicast_info);
4095                         break;
4096
4097                 case HOST_IF_MSG_ADD_BA_SESSION:
4098                         Handle_AddBASession(msg.drvHandler, &msg.body.session_info);
4099                         break;
4100
4101                 case HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS:
4102                         Handle_DelAllRxBASessions(msg.drvHandler, &msg.body.session_info);
4103                         break;
4104
4105                 case HOST_IF_MSG_DEL_ALL_STA:
4106                         Handle_DelAllSta(msg.drvHandler, &msg.body.del_all_sta_info);
4107                         break;
4108
4109                 default:
4110                         PRINT_ER("[Host Interface] undefined Received Msg ID\n");
4111                         break;
4112                 }
4113         }
4114
4115         PRINT_D(HOSTINF_DBG, "Releasing thread exit semaphore\n");
4116         up(&hSemHostIFthrdEnd);
4117         return 0;
4118 }
4119
4120 static void TimerCB_Scan(unsigned long arg)
4121 {
4122         void *pvArg = (void *)arg;
4123         struct host_if_msg msg;
4124
4125         /* prepare the Timer Callback message */
4126         memset(&msg, 0, sizeof(struct host_if_msg));
4127         msg.drvHandler = pvArg;
4128         msg.id = HOST_IF_MSG_SCAN_TIMER_FIRED;
4129
4130         /* send the message */
4131         wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4132 }
4133
4134 static void TimerCB_Connect(unsigned long arg)
4135 {
4136         void *pvArg = (void *)arg;
4137         struct host_if_msg msg;
4138
4139         /* prepare the Timer Callback message */
4140         memset(&msg, 0, sizeof(struct host_if_msg));
4141         msg.drvHandler = pvArg;
4142         msg.id = HOST_IF_MSG_CONNECT_TIMER_FIRED;
4143
4144         /* send the message */
4145         wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4146 }
4147
4148
4149 /**
4150  *  @brief              removes wpa/wpa2 keys
4151  *  @details    only in BSS STA mode if External Supplicant support is enabled.
4152  *                              removes all WPA/WPA2 station key entries from MAC hardware.
4153  *  @param[in,out] handle to the wifi driver
4154  *  @param[in]  6 bytes of Station Adress in the station entry table
4155  *  @return             Error code indicating success/failure
4156  *  @note
4157  *  @author             zsalah
4158  *  @date               8 March 2012
4159  *  @version            1.0
4160  */
4161 /* Check implementation in core adding 9 bytes to the input! */
4162 s32 host_int_remove_key(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8StaAddress)
4163 {
4164         s32 s32Error = 0;
4165         tstrWID strWID;
4166         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
4167
4168         strWID.u16WIDid = (u16)WID_REMOVE_KEY;
4169         strWID.enuWIDtype       = WID_STR;
4170         strWID.ps8WidVal        = (s8 *)pu8StaAddress;
4171         strWID.s32ValueSize = 6;
4172
4173         return s32Error;
4174
4175 }
4176
4177 /**
4178  *  @brief              removes WEP key
4179  *  @details    valid only in BSS STA mode if External Supplicant support is enabled.
4180  *                              remove a WEP key entry from MAC HW.
4181  *                              The BSS Station automatically finds the index of the entry using its
4182  *                              BSS ID and removes that entry from the MAC hardware.
4183  *  @param[in,out] handle to the wifi driver
4184  *  @param[in]  6 bytes of Station Adress in the station entry table
4185  *  @return             Error code indicating success/failure
4186  *  @note               NO need for the STA add since it is not used for processing
4187  *  @author             zsalah
4188  *  @date               8 March 2012
4189  *  @version            1.0
4190  */
4191 s32 host_int_remove_wep_key(tstrWILC_WFIDrv *hWFIDrv, u8 u8keyIdx)
4192 {
4193         s32 s32Error = 0;
4194         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
4195         struct host_if_msg msg;
4196
4197
4198         if (pstrWFIDrv == NULL) {
4199                 s32Error = -EFAULT;
4200                 PRINT_ER("Failed to send setup multicast config packet\n");
4201                 return s32Error;
4202         }
4203
4204         /* prepare the Remove Wep Key Message */
4205         memset(&msg, 0, sizeof(struct host_if_msg));
4206
4207
4208         msg.id = HOST_IF_MSG_KEY;
4209         msg.body.key_info.enuKeyType = WEP;
4210         msg.body.key_info.u8KeyAction = REMOVEKEY;
4211         msg.drvHandler = hWFIDrv;
4212
4213
4214
4215         msg.body.key_info.
4216         uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8keyIdx;
4217
4218         /* send the message */
4219         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4220         if (s32Error)
4221                 PRINT_ER("Error in sending message queue : Request to remove WEP key\n");
4222         down(&(pstrWFIDrv->hSemTestKeyBlock));
4223
4224         return s32Error;
4225 }
4226
4227 /**
4228  *  @brief              sets WEP default key
4229  *  @details    Sets the index of the WEP encryption key in use,
4230  *                              in the key table
4231  *  @param[in,out] handle to the wifi driver
4232  *  @param[in]  key index ( 0, 1, 2, 3)
4233  *  @return             Error code indicating success/failure
4234  *  @note
4235  *  @author             zsalah
4236  *  @date               8 March 2012
4237  *  @version            1.0
4238  */
4239 s32 host_int_set_WEPDefaultKeyID(tstrWILC_WFIDrv *hWFIDrv, u8 u8Index)
4240 {
4241         s32 s32Error = 0;
4242         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
4243         struct host_if_msg msg;
4244
4245
4246         if (pstrWFIDrv == NULL) {
4247                 s32Error = -EFAULT;
4248                 PRINT_ER("driver is null\n");
4249                 return s32Error;
4250         }
4251
4252         /* prepare the Key Message */
4253         memset(&msg, 0, sizeof(struct host_if_msg));
4254
4255
4256         msg.id = HOST_IF_MSG_KEY;
4257         msg.body.key_info.enuKeyType = WEP;
4258         msg.body.key_info.u8KeyAction = DEFAULTKEY;
4259         msg.drvHandler = hWFIDrv;
4260
4261
4262         msg.body.key_info.
4263         uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Index;
4264
4265         /* send the message */
4266         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4267         if (s32Error)
4268                 PRINT_ER("Error in sending message queue : Default key index\n");
4269         down(&(pstrWFIDrv->hSemTestKeyBlock));
4270
4271         return s32Error;
4272 }
4273
4274 /**
4275  *  @brief              sets WEP deafault key
4276  *  @details    valid only in BSS STA mode if External Supplicant support is enabled.
4277  *                              sets WEP key entry into MAC hardware when it receives the
4278  *                              corresponding request from NDIS.
4279  *  @param[in,out] handle to the wifi driver
4280  *  @param[in]  message containing WEP Key in the following format
4281  *|---------------------------------------|
4282  *|Key ID Value | Key Length |  Key             |
4283  *|-------------|------------|------------|
4284  |      1byte     |             1byte  | Key Length     |
4285  ||---------------------------------------|
4286  |
4287  *  @return             Error code indicating success/failure
4288  *  @note
4289  *  @author             zsalah
4290  *  @date               8 March 2012
4291  *  @version            1.0
4292  */
4293 s32 host_int_add_wep_key_bss_sta(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8WepKey, u8 u8WepKeylen, u8 u8Keyidx)
4294 {
4295
4296         s32 s32Error = 0;
4297         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
4298         struct host_if_msg msg;
4299
4300         if (pstrWFIDrv == NULL) {
4301                 s32Error = -EFAULT;
4302                 PRINT_ER("driver is null\n");
4303                 return s32Error;
4304         }
4305
4306         /* prepare the Key Message */
4307         memset(&msg, 0, sizeof(struct host_if_msg));
4308
4309
4310         msg.id = HOST_IF_MSG_KEY;
4311         msg.body.key_info.enuKeyType = WEP;
4312         msg.body.key_info.u8KeyAction = ADDKEY;
4313         msg.drvHandler = hWFIDrv;
4314
4315
4316         msg.body.key_info.
4317         uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = kmalloc(u8WepKeylen, GFP_KERNEL);
4318
4319         memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
4320                     pu8WepKey, u8WepKeylen);
4321
4322
4323         msg.body.key_info.
4324         uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen);
4325
4326         msg.body.key_info.
4327         uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx;
4328
4329         /* send the message */
4330         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4331         if (s32Error)
4332                 PRINT_ER("Error in sending message queue :WEP Key\n");
4333         down(&(pstrWFIDrv->hSemTestKeyBlock));
4334
4335         return s32Error;
4336
4337 }
4338
4339 /**
4340  *
4341  *  @brief              host_int_add_wep_key_bss_ap
4342  *  @details    valid only in BSS AP mode if External Supplicant support is enabled.
4343  *                              sets WEP key entry into MAC hardware when it receives the
4344  *
4345  *                              corresponding request from NDIS.
4346  *  @param[in,out] handle to the wifi driver
4347  *
4348  *
4349  *  @return             Error code indicating success/failure
4350  *  @note
4351  *  @author             mdaftedar
4352  *  @date               28 FEB 2013
4353  *  @version            1.0
4354  */
4355 s32 host_int_add_wep_key_bss_ap(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8WepKey, u8 u8WepKeylen, u8 u8Keyidx, u8 u8mode, enum AUTHTYPE tenuAuth_type)
4356 {
4357
4358         s32 s32Error = 0;
4359         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
4360         struct host_if_msg msg;
4361         u8 i;
4362
4363         if (pstrWFIDrv == NULL) {
4364                 s32Error = -EFAULT;
4365                 PRINT_ER("driver is null\n");
4366                 return s32Error;
4367         }
4368
4369         /* prepare the Key Message */
4370         memset(&msg, 0, sizeof(struct host_if_msg));
4371
4372         if (INFO) {
4373                 for (i = 0; i < u8WepKeylen; i++)
4374                         PRINT_INFO(HOSTAPD_DBG, "KEY is %x\n", pu8WepKey[i]);
4375         }
4376         msg.id = HOST_IF_MSG_KEY;
4377         msg.body.key_info.enuKeyType = WEP;
4378         msg.body.key_info.u8KeyAction = ADDKEY_AP;
4379         msg.drvHandler = hWFIDrv;
4380
4381
4382         msg.body.key_info.
4383         uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey = kmalloc(u8WepKeylen, GFP_KERNEL);
4384
4385
4386         memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwepAttr.pu8WepKey,
4387                     pu8WepKey, (u8WepKeylen));
4388
4389
4390         msg.body.key_info.
4391         uniHostIFkeyAttr.strHostIFwepAttr.u8WepKeylen = (u8WepKeylen);
4392
4393         msg.body.key_info.
4394         uniHostIFkeyAttr.strHostIFwepAttr.u8Wepidx = u8Keyidx;
4395
4396         msg.body.key_info.
4397         uniHostIFkeyAttr.strHostIFwepAttr.u8mode = u8mode;
4398
4399         msg.body.key_info.
4400         uniHostIFkeyAttr.strHostIFwepAttr.tenuAuth_type = tenuAuth_type;
4401         /* send the message */
4402         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4403
4404         if (s32Error)
4405                 PRINT_ER("Error in sending message queue :WEP Key\n");
4406         down(&(pstrWFIDrv->hSemTestKeyBlock));
4407
4408         return s32Error;
4409
4410 }
4411
4412 /**
4413  *  @brief              adds ptk Key
4414  *  @details
4415  *  @param[in,out] handle to the wifi driver
4416  *  @param[in]  message containing PTK Key in the following format
4417  *|-----------------------------------------------------------------------------|
4418  *|Station address | Key Length |       Temporal Key | Rx Michael Key |Tx Michael Key |
4419  *|----------------|------------|--------------|----------------|---------------|
4420  |      6 bytes          |      1byte     |   16 bytes   |        8 bytes         |        8 bytes        |
4421  ||-----------------------------------------------------------------------------|
4422  *  @return             Error code indicating success/failure
4423  *  @note
4424  *  @author             zsalah
4425  *  @date               8 March 2012
4426  *  @version            1.0
4427  */
4428 s32 host_int_add_ptk(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8Ptk, u8 u8PtkKeylen,
4429                              const u8 *mac_addr, const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode, u8 u8Idx)
4430 {
4431         s32 s32Error = 0;
4432         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
4433         struct host_if_msg msg;
4434         u8 u8KeyLen = u8PtkKeylen;
4435         u32 i;
4436
4437         if (pstrWFIDrv == NULL) {
4438                 s32Error = -EFAULT;
4439                 PRINT_ER("driver is null\n");
4440                 return s32Error;
4441         }
4442         if (pu8RxMic != NULL)
4443                 u8KeyLen += RX_MIC_KEY_LEN;
4444         if (pu8TxMic != NULL)
4445                 u8KeyLen += TX_MIC_KEY_LEN;
4446
4447         /* prepare the Key Message */
4448         memset(&msg, 0, sizeof(struct host_if_msg));
4449
4450
4451         msg.id = HOST_IF_MSG_KEY;
4452         msg.body.key_info.enuKeyType = WPAPtk;
4453         if (mode == AP_MODE) {
4454                 msg.body.key_info.u8KeyAction = ADDKEY_AP;
4455                 msg.body.key_info.
4456                 uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8Idx;
4457         }
4458         if (mode == STATION_MODE)
4459                 msg.body.key_info.u8KeyAction = ADDKEY;
4460
4461
4462         msg.body.key_info.
4463         uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = kmalloc(u8PtkKeylen, GFP_KERNEL);
4464
4465
4466         memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
4467                     pu8Ptk, u8PtkKeylen);
4468
4469         if (pu8RxMic != NULL) {
4470
4471                 memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 16,
4472                             pu8RxMic, RX_MIC_KEY_LEN);
4473                 if (INFO) {
4474                         for (i = 0; i < RX_MIC_KEY_LEN; i++)
4475                                 PRINT_INFO(CFG80211_DBG, "PairwiseRx[%d] = %x\n", i, pu8RxMic[i]);
4476                 }
4477         }
4478         if (pu8TxMic != NULL) {
4479
4480                 memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 24,
4481                             pu8TxMic, TX_MIC_KEY_LEN);
4482                 if (INFO) {
4483                         for (i = 0; i < TX_MIC_KEY_LEN; i++)
4484                                 PRINT_INFO(CFG80211_DBG, "PairwiseTx[%d] = %x\n", i, pu8TxMic[i]);
4485                 }
4486         }
4487
4488         msg.body.key_info.
4489         uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen;
4490
4491         msg.body.key_info.
4492         uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode;
4493         msg.body.key_info.
4494         uniHostIFkeyAttr.strHostIFwpaAttr.pu8macaddr = mac_addr;
4495         msg.drvHandler = hWFIDrv;
4496
4497         /* send the message */
4498         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4499
4500         if (s32Error)
4501                 PRINT_ER("Error in sending message queue:  PTK Key\n");
4502
4503         /* ////////////// */
4504         down(&(pstrWFIDrv->hSemTestKeyBlock));
4505         /* /////// */
4506
4507         return s32Error;
4508 }
4509
4510 /**
4511  *  @brief              adds Rx GTk Key
4512  *  @details
4513  *  @param[in,out] handle to the wifi driver
4514  *  @param[in]  pu8RxGtk : contains temporal key | Rx Mic | Tx Mic
4515  *                              u8GtkKeylen :The total key length
4516  *
4517  *  @return             Error code indicating success/failure
4518  *  @note
4519  *  @author             zsalah
4520  *  @date               8 March 2012
4521  *  @version            1.0
4522  */
4523 s32 host_int_add_rx_gtk(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8RxGtk, u8 u8GtkKeylen,
4524                                 u8 u8KeyIdx, u32 u32KeyRSClen, const u8 *KeyRSC,
4525                                 const u8 *pu8RxMic, const u8 *pu8TxMic, u8 mode, u8 u8Ciphermode)
4526 {
4527         s32 s32Error = 0;
4528         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
4529         struct host_if_msg msg;
4530         u8 u8KeyLen = u8GtkKeylen;
4531
4532         if (pstrWFIDrv == NULL) {
4533                 s32Error = -EFAULT;
4534                 PRINT_ER("driver is null\n");
4535                 return s32Error;
4536         }
4537         /* prepare the Key Message */
4538         memset(&msg, 0, sizeof(struct host_if_msg));
4539
4540
4541         if (pu8RxMic != NULL)
4542                 u8KeyLen += RX_MIC_KEY_LEN;
4543         if (pu8TxMic != NULL)
4544                 u8KeyLen += TX_MIC_KEY_LEN;
4545         if (KeyRSC != NULL) {
4546                 msg.body.key_info.
4547                 uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq = kmalloc(u32KeyRSClen, GFP_KERNEL);
4548
4549                 memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwpaAttr.pu8seq,
4550                             KeyRSC, u32KeyRSClen);
4551         }
4552
4553
4554         msg.id = HOST_IF_MSG_KEY;
4555         msg.body.key_info.enuKeyType = WPARxGtk;
4556         msg.drvHandler = hWFIDrv;
4557
4558         if (mode == AP_MODE) {
4559                 msg.body.key_info.u8KeyAction = ADDKEY_AP;
4560                 msg.body.key_info.uniHostIFkeyAttr.strHostIFwpaAttr.u8Ciphermode = u8Ciphermode;
4561         }
4562         if (mode == STATION_MODE)
4563                 msg.body.key_info.u8KeyAction = ADDKEY;
4564
4565
4566         msg.body.key_info.
4567         uniHostIFkeyAttr.strHostIFwpaAttr.pu8key = kmalloc(u8KeyLen, GFP_KERNEL);
4568
4569         memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key,
4570                     pu8RxGtk, u8GtkKeylen);
4571
4572         if (pu8RxMic != NULL) {
4573
4574                 memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 16,
4575                             pu8RxMic, RX_MIC_KEY_LEN);
4576
4577         }
4578         if (pu8TxMic != NULL) {
4579
4580                 memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFwpaAttr.pu8key + 24,
4581                             pu8TxMic, TX_MIC_KEY_LEN);
4582
4583         }
4584
4585         msg.body.key_info.
4586         uniHostIFkeyAttr.strHostIFwpaAttr.u8keyidx = u8KeyIdx;
4587         msg.body.key_info.
4588         uniHostIFkeyAttr.strHostIFwpaAttr.u8Keylen = u8KeyLen;
4589
4590         msg.body.key_info.
4591         uniHostIFkeyAttr.strHostIFwpaAttr.u8seqlen = u32KeyRSClen;
4592
4593
4594
4595         /* send the message */
4596         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4597         if (s32Error)
4598                 PRINT_ER("Error in sending message queue:  RX GTK\n");
4599         /* ////////////// */
4600         down(&(pstrWFIDrv->hSemTestKeyBlock));
4601         /* /////// */
4602
4603         return s32Error;
4604 }
4605
4606 /**
4607  *  @brief              host_int_set_pmkid_info
4608  *  @details    caches the pmkid valid only in BSS STA mode if External Supplicant
4609  *                              support is enabled. This Function sets the PMKID in firmware
4610  *                              when host drivr receives the corresponding request from NDIS.
4611  *                              The firmware then includes theset PMKID in the appropriate
4612  *                              management frames
4613  *  @param[in,out] handle to the wifi driver
4614  *  @param[in]  message containing PMKID Info in the following format
4615  *|-----------------------------------------------------------------|
4616  *|NumEntries | BSSID[1] | PMKID[1] |  ...      | BSSID[K] | PMKID[K] |
4617  *|-----------|------------|----------|-------|----------|----------|
4618  |         1    |               6        |   16         |  ...  |        6         |    16        |
4619  ||-----------------------------------------------------------------|
4620  *  @return             Error code indicating success/failure
4621  *  @note
4622  *  @author             zsalah
4623  *  @date               8 March 2012
4624  *  @version            1.0
4625  */
4626 s32 host_int_set_pmkid_info(tstrWILC_WFIDrv *hWFIDrv, struct host_if_pmkid_attr *pu8PmkidInfoArray)
4627 {
4628         s32 s32Error = 0;
4629         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
4630         struct host_if_msg msg;
4631         u32 i;
4632
4633
4634         if (pstrWFIDrv == NULL) {
4635                 s32Error = -EFAULT;
4636                 PRINT_ER("driver is null\n");
4637                 return s32Error;
4638         }
4639
4640         /* prepare the Key Message */
4641         memset(&msg, 0, sizeof(struct host_if_msg));
4642
4643         msg.id = HOST_IF_MSG_KEY;
4644         msg.body.key_info.enuKeyType = PMKSA;
4645         msg.body.key_info.u8KeyAction = ADDKEY;
4646         msg.drvHandler = hWFIDrv;
4647
4648         for (i = 0; i < pu8PmkidInfoArray->numpmkid; i++) {
4649
4650                 memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].bssid, &pu8PmkidInfoArray->pmkidlist[i].bssid,
4651                             ETH_ALEN);
4652
4653                 memcpy(msg.body.key_info.uniHostIFkeyAttr.strHostIFpmkidAttr.pmkidlist[i].pmkid, &pu8PmkidInfoArray->pmkidlist[i].pmkid,
4654                             PMKID_LEN);
4655         }
4656
4657         /* send the message */
4658         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4659         if (s32Error)
4660                 PRINT_ER(" Error in sending messagequeue: PMKID Info\n");
4661
4662         return s32Error;
4663 }
4664
4665 /**
4666  *  @brief              gets the cached the pmkid info
4667  *  @details    valid only in BSS STA mode if External Supplicant
4668  *                              support is enabled. This Function sets the PMKID in firmware
4669  *                              when host drivr receives the corresponding request from NDIS.
4670  *                              The firmware then includes theset PMKID in the appropriate
4671  *                              management frames
4672  *  @param[in,out] handle to the wifi driver,
4673  *                                message containing PMKID Info in the following format
4674  *|-----------------------------------------------------------------|
4675  *|NumEntries | BSSID[1] | PMKID[1] |  ...      | BSSID[K] | PMKID[K] |
4676  *|-----------|------------|----------|-------|----------|----------|
4677  |         1    |               6        |   16         |  ...  |        6         |    16        |
4678  ||-----------------------------------------------------------------|
4679  *  @param[in]
4680  *  @return             Error code indicating success/failure
4681  *  @note
4682  *  @author             zsalah
4683  *  @date               8 March 2012
4684  *  @version            1.0
4685  */
4686 s32 host_int_get_pmkid_info(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8PmkidInfoArray,
4687                                     u32 u32PmkidInfoLen)
4688 {
4689         s32 s32Error = 0;
4690         tstrWID strWID;
4691         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
4692
4693         strWID.u16WIDid = (u16)WID_PMKID_INFO;
4694         strWID.enuWIDtype       = WID_STR;
4695         strWID.s32ValueSize = u32PmkidInfoLen;
4696         strWID.ps8WidVal = pu8PmkidInfoArray;
4697
4698         return s32Error;
4699 }
4700
4701 /**
4702  *  @brief              sets the pass phrase
4703  *  @details    AP/STA mode. This function gives the pass phrase used to
4704  *                              generate the Pre-Shared Key when WPA/WPA2 is enabled
4705  *                              The length of the field can vary from 8 to 64 bytes,
4706  *                              the lower layer should get the
4707  *  @param[in,out] handle to the wifi driver,
4708  *  @param[in]   String containing PSK
4709  *  @return             Error code indicating success/failure
4710  *  @note
4711  *  @author             zsalah
4712  *  @date               8 March 2012
4713  *  @version            1.0
4714  */
4715 s32 host_int_set_RSNAConfigPSKPassPhrase(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8PassPhrase,
4716                                                  u8 u8Psklength)
4717 {
4718         s32 s32Error = 0;
4719         tstrWID strWID;
4720
4721         /*validating psk length*/
4722         if ((u8Psklength > 7) && (u8Psklength < 65)) {
4723                 strWID.u16WIDid = (u16)WID_11I_PSK;
4724                 strWID.enuWIDtype       = WID_STR;
4725                 strWID.ps8WidVal        = pu8PassPhrase;
4726                 strWID.s32ValueSize = u8Psklength;
4727         }
4728
4729         return s32Error;
4730 }
4731 /**
4732  *  @brief              host_int_get_MacAddress
4733  *  @details    gets mac address
4734  *  @param[in,out] handle to the wifi driver,
4735  *
4736  *  @return             Error code indicating success/failure
4737  *  @note
4738  *  @author             mdaftedar
4739  *  @date               19 April 2012
4740  *  @version            1.0
4741  */
4742 s32 host_int_get_MacAddress(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8MacAddress)
4743 {
4744         s32 s32Error = 0;
4745         struct host_if_msg msg;
4746
4747
4748         /* prepare the Message */
4749         memset(&msg, 0, sizeof(struct host_if_msg));
4750
4751         msg.id = HOST_IF_MSG_GET_MAC_ADDRESS;
4752         msg.body.get_mac_info.u8MacAddress = pu8MacAddress;
4753         msg.drvHandler = hWFIDrv;
4754         /* send the message */
4755         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4756         if (s32Error) {
4757                 PRINT_ER("Failed to send get mac address\n");
4758                 return -EFAULT;
4759         }
4760
4761         down(&hWaitResponse);
4762         return s32Error;
4763 }
4764
4765 /**
4766  *  @brief              host_int_set_MacAddress
4767  *  @details    sets mac address
4768  *  @param[in,out] handle to the wifi driver,
4769  *
4770  *  @return             Error code indicating success/failure
4771  *  @note
4772  *  @author             mabubakr
4773  *  @date               16 July 2012
4774  *  @version            1.0
4775  */
4776 s32 host_int_set_MacAddress(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8MacAddress)
4777 {
4778         s32 s32Error = 0;
4779         struct host_if_msg msg;
4780
4781         PRINT_D(GENERIC_DBG, "mac addr = %x:%x:%x\n", pu8MacAddress[0], pu8MacAddress[1], pu8MacAddress[2]);
4782
4783         /* prepare setting mac address message */
4784         memset(&msg, 0, sizeof(struct host_if_msg));
4785         msg.id = HOST_IF_MSG_SET_MAC_ADDRESS;
4786         memcpy(msg.body.set_mac_info.u8MacAddress, pu8MacAddress, ETH_ALEN);
4787         msg.drvHandler = hWFIDrv;
4788
4789         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4790         if (s32Error)
4791                 PRINT_ER("Failed to send message queue: Set mac address\n");
4792
4793         return s32Error;
4794
4795 }
4796
4797 /**
4798  *  @brief              host_int_get_RSNAConfigPSKPassPhrase
4799  *  @details    gets the pass phrase:AP/STA mode. This function gets the pass phrase used to
4800  *                              generate the Pre-Shared Key when WPA/WPA2 is enabled
4801  *                              The length of the field can vary from 8 to 64 bytes,
4802  *                              the lower layer should get the
4803  *  @param[in,out] handle to the wifi driver,
4804  *                                String containing PSK
4805  *  @return             Error code indicating success/failure
4806  *  @note
4807  *  @author             zsalah
4808  *  @date               8 March 2012
4809  *  @version            1.0
4810  */
4811 s32 host_int_get_RSNAConfigPSKPassPhrase(tstrWILC_WFIDrv *hWFIDrv,
4812                                                  u8 *pu8PassPhrase, u8 u8Psklength)
4813 {
4814         s32 s32Error = 0;
4815         tstrWID strWID;
4816         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
4817
4818         strWID.u16WIDid = (u16)WID_11I_PSK;
4819         strWID.enuWIDtype       = WID_STR;
4820         strWID.s32ValueSize = u8Psklength;
4821         strWID.ps8WidVal        = pu8PassPhrase;
4822
4823         return s32Error;
4824 }
4825
4826 /**
4827  *  @brief              sets a start scan request
4828  *  @details
4829  *  @param[in,out] handle to the wifi driver,
4830  *  @param[in]  Scan Source one of the following values
4831  *                              DEFAULT_SCAN        0
4832  *                              USER_SCAN           BIT0
4833  *                              OBSS_PERIODIC_SCAN  BIT1
4834  *                              OBSS_ONETIME_SCAN   BIT2
4835  *  @return             Error code indicating success/failure
4836  *  @note
4837  *  @author             zsalah
4838  *  @date               8 March 2012
4839  *  @version            1.0
4840  */
4841 s32 host_int_set_start_scan_req(tstrWILC_WFIDrv *hWFIDrv, u8 scanSource)
4842 {
4843         s32 s32Error = 0;
4844         tstrWID strWID;
4845         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
4846
4847         strWID.u16WIDid = (u16)WID_START_SCAN_REQ;
4848         strWID.enuWIDtype = WID_CHAR;
4849         strWID.ps8WidVal = (s8 *)&scanSource;
4850         strWID.s32ValueSize = sizeof(char);
4851
4852         return s32Error;
4853 }
4854
4855 /**
4856  *  @brief                      host_int_get_start_scan_req
4857  *  @details            gets a start scan request
4858  *  @param[in,out] handle to the wifi driver,
4859  *  @param[in]  Scan Source one of the following values
4860  *                              DEFAULT_SCAN        0
4861  *                              USER_SCAN           BIT0
4862  *                              OBSS_PERIODIC_SCAN  BIT1
4863  *                              OBSS_ONETIME_SCAN   BIT2
4864  *  @return             Error code indicating success/failure
4865  *  @note
4866  *  @author             zsalah
4867  *  @date               8 March 2012
4868  *  @version            1.0
4869  */
4870
4871 s32 host_int_get_start_scan_req(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8ScanSource)
4872 {
4873         s32 s32Error = 0;
4874         tstrWID strWID;
4875         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
4876
4877         strWID.u16WIDid = (u16)WID_START_SCAN_REQ;
4878         strWID.enuWIDtype = WID_CHAR;
4879         strWID.ps8WidVal = (s8 *)pu8ScanSource;
4880         strWID.s32ValueSize = sizeof(char);
4881
4882         return s32Error;
4883 }
4884
4885 /**
4886  *  @brief                      host_int_set_join_req
4887  *  @details            sets a join request
4888  *  @param[in,out] handle to the wifi driver,
4889  *  @param[in]  Index of the bss descriptor
4890  *  @return             Error code indicating success/failure
4891  *  @note
4892  *  @author             zsalah
4893  *  @date               8 March 2012
4894  *  @version            1.0
4895  */
4896 s32 host_int_set_join_req(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8bssid,
4897                                   const u8 *pu8ssid, size_t ssidLen,
4898                                   const u8 *pu8IEs, size_t IEsLen,
4899                                   wilc_connect_result pfConnectResult, void *pvUserArg,
4900                                   u8 u8security, enum AUTHTYPE tenuAuth_type,
4901                                   u8 u8channel,
4902                                   void *pJoinParams)
4903 {
4904         s32 s32Error = 0;
4905         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
4906         struct host_if_msg msg;
4907         tenuScanConnTimer enuScanConnTimer;
4908
4909         if (pstrWFIDrv == NULL || pfConnectResult == NULL) {
4910                 s32Error = -EFAULT;
4911                 PRINT_ER("Driver is null\n");
4912                 return s32Error;
4913         }
4914
4915         if (hWFIDrv == NULL) {
4916                 PRINT_ER("Driver is null\n");
4917                 return -EFAULT;
4918         }
4919
4920         if (pJoinParams == NULL) {
4921                 PRINT_ER("Unable to Join - JoinParams is NULL\n");
4922                 return -EFAULT;
4923         }
4924
4925         /* prepare the Connect Message */
4926         memset(&msg, 0, sizeof(struct host_if_msg));
4927
4928         msg.id = HOST_IF_MSG_CONNECT;
4929
4930         msg.body.con_info.u8security = u8security;
4931         msg.body.con_info.tenuAuth_type = tenuAuth_type;
4932         msg.body.con_info.u8channel = u8channel;
4933         msg.body.con_info.pfConnectResult = pfConnectResult;
4934         msg.body.con_info.pvUserArg = pvUserArg;
4935         msg.body.con_info.pJoinParams = pJoinParams;
4936         msg.drvHandler = hWFIDrv;
4937
4938         if (pu8bssid != NULL) {
4939                 msg.body.con_info.pu8bssid = kmalloc(6, GFP_KERNEL); /* will be deallocated by the receiving thread */
4940                 memcpy(msg.body.con_info.pu8bssid,
4941                             pu8bssid, 6);
4942         }
4943
4944         if (pu8ssid != NULL) {
4945                 msg.body.con_info.ssidLen = ssidLen;
4946                 msg.body.con_info.pu8ssid = kmalloc(ssidLen, GFP_KERNEL); /* will be deallocated by the receiving thread */
4947                 memcpy(msg.body.con_info.pu8ssid,
4948
4949                             pu8ssid, ssidLen);
4950         }
4951
4952         if (pu8IEs != NULL) {
4953                 msg.body.con_info.IEsLen = IEsLen;
4954                 msg.body.con_info.pu8IEs = kmalloc(IEsLen, GFP_KERNEL); /* will be deallocated by the receiving thread */
4955                 memcpy(msg.body.con_info.pu8IEs,
4956                             pu8IEs, IEsLen);
4957         }
4958         if (pstrWFIDrv->enuHostIFstate < HOST_IF_CONNECTING)
4959                 pstrWFIDrv->enuHostIFstate = HOST_IF_CONNECTING;
4960         else
4961                 PRINT_D(GENERIC_DBG, "Don't set state to 'connecting' as state is %d\n", pstrWFIDrv->enuHostIFstate);
4962
4963         /* send the message */
4964         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
4965         if (s32Error) {
4966                 PRINT_ER("Failed to send message queue: Set join request\n");
4967                 return -EFAULT;
4968         }
4969
4970         enuScanConnTimer = CONNECT_TIMER;
4971         pstrWFIDrv->hConnectTimer.data = (unsigned long)hWFIDrv;
4972         mod_timer(&pstrWFIDrv->hConnectTimer,
4973                   jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
4974
4975         return s32Error;
4976 }
4977
4978 /**
4979  *  @brief              Flush a join request parameters to FW, but actual connection
4980  *  @details    The function is called in situation where WILC is connected to AP and
4981  *                      required to switch to hybrid FW for P2P connection
4982  *  @param[in] handle to the wifi driver,
4983  *  @return     Error code indicating success/failure
4984  *  @note
4985  *  @author     Amr Abdel-Moghny
4986  *  @date               19 DEC 2013
4987  *  @version    8.0
4988  */
4989
4990 s32 host_int_flush_join_req(tstrWILC_WFIDrv *hWFIDrv)
4991 {
4992         s32 s32Error = 0;
4993         struct host_if_msg msg;
4994
4995         if (!gu8FlushedJoinReq) {
4996                 s32Error = -EFAULT;
4997                 return s32Error;
4998         }
4999
5000
5001         if (hWFIDrv  == NULL) {
5002                 s32Error = -EFAULT;
5003                 PRINT_ER("Driver is null\n");
5004                 return s32Error;
5005         }
5006
5007         msg.id = HOST_IF_MSG_FLUSH_CONNECT;
5008         msg.drvHandler = hWFIDrv;
5009
5010         /* send the message */
5011         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5012         if (s32Error) {
5013                 PRINT_ER("Failed to send message queue: Flush join request\n");
5014                 return -EFAULT;
5015         }
5016
5017         return s32Error;
5018 }
5019
5020 /**
5021  *  @brief                      host_int_disconnect
5022  *  @details            disconnects from the currently associated network
5023  *  @param[in,out] handle to the wifi driver,
5024  *  @param[in]  Reason Code of the Disconnection
5025  *  @return             Error code indicating success/failure
5026  *  @note
5027  *  @author             zsalah
5028  *  @date               8 March 2012
5029  *  @version            1.0
5030  */
5031 s32 host_int_disconnect(tstrWILC_WFIDrv *hWFIDrv, u16 u16ReasonCode)
5032 {
5033         s32 s32Error = 0;
5034         struct host_if_msg msg;
5035         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5036
5037         if (pstrWFIDrv == NULL) {
5038                 PRINT_ER("Driver is null\n");
5039                 return -EFAULT;
5040         }
5041
5042         /* prepare the Disconnect Message */
5043         memset(&msg, 0, sizeof(struct host_if_msg));
5044
5045         msg.id = HOST_IF_MSG_DISCONNECT;
5046         msg.drvHandler = hWFIDrv;
5047
5048         /* send the message */
5049         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5050         if (s32Error)
5051                 PRINT_ER("Failed to send message queue: disconnect\n");
5052         /* ////////////// */
5053         down(&(pstrWFIDrv->hSemTestDisconnectBlock));
5054         /* /////// */
5055
5056         return s32Error;
5057 }
5058
5059 /**
5060  *  @brief              host_int_disconnect_station
5061  *  @details     disconnects a sta
5062  *  @param[in,out] handle to the wifi driver,
5063  *  @param[in]  Association Id of the station to be disconnected
5064  *  @return             Error code indicating success/failure
5065  *  @note
5066  *  @author             zsalah
5067  *  @date               8 March 2012
5068  *  @version            1.0
5069  */
5070 s32 host_int_disconnect_station(tstrWILC_WFIDrv *hWFIDrv, u8 assoc_id)
5071 {
5072         s32 s32Error = 0;
5073         tstrWID strWID;
5074         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
5075
5076         strWID.u16WIDid = (u16)WID_DISCONNECT;
5077         strWID.enuWIDtype = WID_CHAR;
5078         strWID.ps8WidVal = (s8 *)&assoc_id;
5079         strWID.s32ValueSize = sizeof(char);
5080
5081         return s32Error;
5082 }
5083
5084 /**
5085  *  @brief                      host_int_get_assoc_req_info
5086  *  @details            gets a Association request info
5087  *  @param[in,out] handle to the wifi driver,
5088  *                              Message containg assoc. req info in the following format
5089  * ------------------------------------------------------------------------
5090  |                        Management Frame Format                    |
5091  ||-------------------------------------------------------------------|
5092  ||Frame Control|Duration|DA|SA|BSSID|Sequence Control|Frame Body|FCS |
5093  ||-------------|--------|--|--|-----|----------------|----------|----|
5094  | 2           |2       |6 |6 |6    |           2       |0 - 2312  | 4  |
5095  ||-------------------------------------------------------------------|
5096  |                                                                   |
5097  |             Association Request Frame - Frame Body                |
5098  ||-------------------------------------------------------------------|
5099  | Capability Information | Listen Interval | SSID | Supported Rates |
5100  ||------------------------|-----------------|------|-----------------|
5101  |                      2            |           2         | 2-34 |             3-10        |
5102  | ---------------------------------------------------------------------
5103  *  @return             Error code indicating success/failure
5104  *  @note
5105  *  @author             zsalah
5106  *  @date               8 March 2012
5107  *  @version            1.0
5108  */
5109
5110 s32 host_int_get_assoc_req_info(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8AssocReqInfo,
5111                                         u32 u32AssocReqInfoLen)
5112 {
5113         s32 s32Error = 0;
5114         tstrWID strWID;
5115         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
5116
5117         strWID.u16WIDid = (u16)WID_ASSOC_REQ_INFO;
5118         strWID.enuWIDtype = WID_STR;
5119         strWID.ps8WidVal = pu8AssocReqInfo;
5120         strWID.s32ValueSize = u32AssocReqInfoLen;
5121
5122
5123         return s32Error;
5124 }
5125
5126 /**
5127  *  @brief              gets a Association Response info
5128  *  @details
5129  *  @param[in,out] handle to the wifi driver,
5130  *                              Message containg assoc. resp info
5131  *  @return             Error code indicating success/failure
5132  *  @note
5133  *  @author             zsalah
5134  *  @date               8 March 2012
5135  *  @version            1.0
5136  */
5137 s32 host_int_get_assoc_res_info(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8AssocRespInfo,
5138                                         u32 u32MaxAssocRespInfoLen, u32 *pu32RcvdAssocRespInfoLen)
5139 {
5140         s32 s32Error = 0;
5141         tstrWID strWID;
5142         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5143
5144         if (pstrWFIDrv == NULL) {
5145                 PRINT_ER("Driver is null\n");
5146                 return -EFAULT;
5147         }
5148
5149         strWID.u16WIDid = (u16)WID_ASSOC_RES_INFO;
5150         strWID.enuWIDtype = WID_STR;
5151         strWID.ps8WidVal = pu8AssocRespInfo;
5152         strWID.s32ValueSize = u32MaxAssocRespInfoLen;
5153
5154
5155         /* Sending Configuration packet */
5156         s32Error = send_config_pkt(GET_CFG, &strWID, 1, true,
5157                                    get_id_from_handler(pstrWFIDrv));
5158         if (s32Error) {
5159                 *pu32RcvdAssocRespInfoLen = 0;
5160                 PRINT_ER("Failed to send association response config packet\n");
5161                 return -EINVAL;
5162         } else {
5163                 *pu32RcvdAssocRespInfoLen = strWID.s32ValueSize;
5164         }
5165
5166         return s32Error;
5167 }
5168
5169 /**
5170  *  @brief              gets a Association Response info
5171  *  @details    Valid only in STA mode. This function gives the RSSI
5172  *                              values observed in all the channels at the time of scanning.
5173  *                              The length of the field is 1 greater that the total number of
5174  *                              channels supported. Byte 0 contains the number of channels while
5175  *                              each of Byte N contains the observed RSSI value for the channel index N.
5176  *  @param[in,out] handle to the wifi driver,
5177  *                              array of scanned channels' RSSI
5178  *  @return             Error code indicating success/failure
5179  *  @note
5180  *  @author             zsalah
5181  *  @date               8 March 2012
5182  *  @version            1.0
5183  */
5184 s32 host_int_get_rx_power_level(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8RxPowerLevel,
5185                                         u32 u32RxPowerLevelLen)
5186 {
5187         s32 s32Error = 0;
5188         tstrWID strWID;
5189         /* tstrWILC_WFIDrv * pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv; */
5190
5191         strWID.u16WIDid = (u16)WID_RX_POWER_LEVEL;
5192         strWID.enuWIDtype = WID_STR;
5193         strWID.ps8WidVal = pu8RxPowerLevel;
5194         strWID.s32ValueSize = u32RxPowerLevelLen;
5195
5196
5197         return s32Error;
5198 }
5199
5200 /**
5201  *  @brief              sets a channel
5202  *  @details
5203  *  @param[in,out] handle to the wifi driver,
5204  *  @param[in]  Index of the channel to be set
5205  *|-------------------------------------------------------------------|
5206  |          CHANNEL1      CHANNEL2 ....                      CHANNEL14  |
5207  |  Input:         1             2                                                  14  |
5208  ||-------------------------------------------------------------------|
5209  *  @return             Error code indicating success/failure
5210  *  @note
5211  *  @author             zsalah
5212  *  @date               8 March 2012
5213  *  @version            1.0
5214  */
5215 int host_int_set_mac_chnl_num(tstrWILC_WFIDrv *wfi_drv, u8 channel)
5216 {
5217         int result;
5218         struct host_if_msg msg;
5219
5220         if (!wfi_drv) {
5221                 PRINT_ER("driver is null\n");
5222                 return -EFAULT;
5223         }
5224
5225         /* prepare the set channel message */
5226         memset(&msg, 0, sizeof(struct host_if_msg));
5227         msg.id = HOST_IF_MSG_SET_CHANNEL;
5228         msg.body.channel_info.u8SetChan = channel;
5229         msg.drvHandler = wfi_drv;
5230
5231         result = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5232         if (result) {
5233                 PRINT_ER("wilc mq send fail\n");
5234                 return -EINVAL;
5235         }
5236
5237         return 0;
5238 }
5239
5240 int host_int_wait_msg_queue_idle(void)
5241 {
5242         int result = 0;
5243
5244         struct host_if_msg msg;
5245
5246         /* prepare the set driver handler message */
5247
5248         memset(&msg, 0, sizeof(struct host_if_msg));
5249         msg.id = HOST_IF_MSG_Q_IDLE;
5250         result = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5251         if (result) {
5252                 PRINT_ER("wilc mq send fail\n");
5253                 result = -EINVAL;
5254         }
5255
5256         /* wait untill MSG Q is empty */
5257         down(&hWaitResponse);
5258
5259         return result;
5260 }
5261
5262 int host_int_set_wfi_drv_handler(tstrWILC_WFIDrv *address)
5263 {
5264         int result = 0;
5265
5266         struct host_if_msg msg;
5267
5268
5269         /* prepare the set driver handler message */
5270
5271         memset(&msg, 0, sizeof(struct host_if_msg));
5272         msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
5273         msg.body.drv.u32Address = get_id_from_handler(address);
5274         msg.drvHandler = address;
5275
5276         result = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5277         if (result) {
5278                 PRINT_ER("wilc mq send fail\n");
5279                 result = -EINVAL;
5280         }
5281
5282         return result;
5283 }
5284
5285 int host_int_set_operation_mode(tstrWILC_WFIDrv *hWFIDrv, u32 u32mode)
5286 {
5287         int result = 0;
5288
5289         struct host_if_msg msg;
5290
5291         /* prepare the set driver handler message */
5292
5293         memset(&msg, 0, sizeof(struct host_if_msg));
5294         msg.id = HOST_IF_MSG_SET_OPERATION_MODE;
5295         msg.body.mode.u32Mode = u32mode;
5296         msg.drvHandler = hWFIDrv;
5297
5298         result = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5299         if (result) {
5300                 PRINT_ER("wilc mq send fail\n");
5301                 result = -EINVAL;
5302         }
5303
5304         return result;
5305 }
5306
5307 /**
5308  *  @brief              gets the current channel index
5309  *  @details
5310  *  @param[in,out] handle to the wifi driver,
5311  *                              current channel index
5312  *|-----------------------------------------------------------------------|
5313  |          CHANNEL1      CHANNEL2 ....                     CHANNEL14   |
5314  |  Input:         1             2                                 14   |
5315  ||-----------------------------------------------------------------------|
5316  *  @return             Error code indicating success/failure
5317  *  @note
5318  *  @author             zsalah
5319  *  @date               8 March 2012
5320  *  @version            1.0
5321  */
5322 s32 host_int_get_host_chnl_num(tstrWILC_WFIDrv *hWFIDrv, u8 *pu8ChNo)
5323 {
5324         s32 s32Error = 0;
5325         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5326         struct host_if_msg msg;
5327
5328         if (pstrWFIDrv == NULL) {
5329                 PRINT_ER("driver is null\n");
5330                 return -EFAULT;
5331         }
5332
5333         /* prepare the Get Channel Message */
5334         memset(&msg, 0, sizeof(struct host_if_msg));
5335
5336         msg.id = HOST_IF_MSG_GET_CHNL;
5337         msg.drvHandler = hWFIDrv;
5338
5339         /* send the message */
5340         s32Error =      wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5341         if (s32Error)
5342                 PRINT_ER("wilc mq send fail\n");
5343         down(&(pstrWFIDrv->hSemGetCHNL));
5344         /* gu8Chnl = 11; */
5345
5346         *pu8ChNo = gu8Chnl;
5347
5348         return s32Error;
5349
5350
5351 }
5352
5353
5354 /**
5355  *  @brief                       host_int_test_set_int_wid
5356  *  @details             Test function for setting wids
5357  *  @param[in,out]   WILC_WFIDrvHandle hWFIDrv, u32 u32TestMemAddr
5358  *  @return              Error code indicating success/failure
5359  *  @note
5360  *  @author             zsalah
5361  *  @date               8 March 2012
5362  *  @version            1.0
5363  */
5364 s32 host_int_test_set_int_wid(tstrWILC_WFIDrv *hWFIDrv, u32 u32TestMemAddr)
5365 {
5366         s32 s32Error = 0;
5367         tstrWID strWID;
5368         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5369
5370
5371         if (pstrWFIDrv == NULL) {
5372                 PRINT_ER("driver is null\n");
5373                 return -EFAULT;
5374         }
5375
5376         /*prepare configuration packet*/
5377         strWID.u16WIDid = (u16)WID_MEMORY_ADDRESS;
5378         strWID.enuWIDtype = WID_INT;
5379         strWID.ps8WidVal = (char *)&u32TestMemAddr;
5380         strWID.s32ValueSize = sizeof(u32);
5381
5382         /*Sending Cfg*/
5383         s32Error = send_config_pkt(SET_CFG, &strWID, 1, true,
5384                                    get_id_from_handler(pstrWFIDrv));
5385         if (s32Error) {
5386                 PRINT_ER("Failed to set wid value\n");
5387                 return -EINVAL;
5388         } else {
5389                 PRINT_D(HOSTINF_DBG, "Successfully set wid value\n");
5390
5391         }
5392
5393         return s32Error;
5394 }
5395
5396 /**
5397  *  @brief              host_int_get_inactive_time
5398  *  @details
5399  *  @param[in,out] handle to the wifi driver,
5400  *                              current sta macaddress, inactive_time
5401  *  @return
5402  *  @note
5403  *  @author
5404  *  @date
5405  *  @version            1.0
5406  */
5407 s32 host_int_get_inactive_time(tstrWILC_WFIDrv *hWFIDrv, const u8 *mac, u32 *pu32InactiveTime)
5408 {
5409         s32 s32Error = 0;
5410         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5411         struct host_if_msg msg;
5412
5413         if (pstrWFIDrv == NULL) {
5414                 PRINT_ER("driver is null\n");
5415                 return -EFAULT;
5416         }
5417
5418         memset(&msg, 0, sizeof(struct host_if_msg));
5419
5420
5421         memcpy(msg.body.mac_info.mac,
5422                     mac, ETH_ALEN);
5423
5424         msg.id = HOST_IF_MSG_GET_INACTIVETIME;
5425         msg.drvHandler = hWFIDrv;
5426
5427         /* send the message */
5428         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5429         if (s32Error)
5430                 PRINT_ER("Failed to send get host channel param's message queue ");
5431
5432         down(&(pstrWFIDrv->hSemInactiveTime));
5433
5434         *pu32InactiveTime = gu32InactiveTime;
5435
5436         return s32Error;
5437 }
5438
5439 /**
5440  *  @brief              host_int_test_get_int_wid
5441  *  @details    Test function for getting wids
5442  *  @param[in,out] WILC_WFIDrvHandle hWFIDrv, u32* pu32TestMemAddr
5443  *  @return             Error code indicating success/failure
5444  *  @note
5445  *  @author             zsalah
5446  *  @date               8 March 2012
5447  *  @version            1.0
5448  */
5449 s32 host_int_test_get_int_wid(tstrWILC_WFIDrv *hWFIDrv, u32 *pu32TestMemAddr)
5450 {
5451
5452         s32 s32Error = 0;
5453         tstrWID strWID;
5454         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5455
5456
5457         if (pstrWFIDrv == NULL) {
5458                 PRINT_ER("driver is null\n");
5459                 return -EFAULT;
5460         }
5461
5462         strWID.u16WIDid = (u16)WID_MEMORY_ADDRESS;
5463         strWID.enuWIDtype = WID_INT;
5464         strWID.ps8WidVal = (s8 *)pu32TestMemAddr;
5465         strWID.s32ValueSize = sizeof(u32);
5466
5467         s32Error = send_config_pkt(GET_CFG, &strWID, 1, true,
5468                                    get_id_from_handler(pstrWFIDrv));
5469         /*get the value by searching the local copy*/
5470         if (s32Error) {
5471                 PRINT_ER("Failed to get wid value\n");
5472                 return -EINVAL;
5473         } else {
5474                 PRINT_D(HOSTINF_DBG, "Successfully got wid value\n");
5475
5476         }
5477
5478         return s32Error;
5479 }
5480
5481
5482 /**
5483  *  @brief              host_int_get_rssi
5484  *  @details    gets the currently maintained RSSI value for the station.
5485  *                              The received signal strength value in dB.
5486  *                              The range of valid values is -128 to 0.
5487  *  @param[in,out] handle to the wifi driver,
5488  *                              rssi value in dB
5489  *  @return             Error code indicating success/failure
5490  *  @note
5491  *  @author             zsalah
5492  *  @date               8 March 2012
5493  *  @version            1.0
5494  */
5495 s32 host_int_get_rssi(tstrWILC_WFIDrv *hWFIDrv, s8 *ps8Rssi)
5496 {
5497         s32 s32Error = 0;
5498         struct host_if_msg msg;
5499         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5500
5501
5502         /* prepare the Get RSSI Message */
5503         memset(&msg, 0, sizeof(struct host_if_msg));
5504
5505         msg.id = HOST_IF_MSG_GET_RSSI;
5506         msg.drvHandler = hWFIDrv;
5507
5508         /* send the message */
5509         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5510         if (s32Error) {
5511                 PRINT_ER("Failed to send get host channel param's message queue ");
5512                 return -EFAULT;
5513         }
5514
5515         down(&(pstrWFIDrv->hSemGetRSSI));
5516
5517
5518         if (ps8Rssi == NULL) {
5519                 PRINT_ER("RSS pointer value is null");
5520                 return -EFAULT;
5521         }
5522
5523
5524         *ps8Rssi = gs8Rssi;
5525
5526
5527         return s32Error;
5528 }
5529
5530 s32 host_int_get_link_speed(tstrWILC_WFIDrv *hWFIDrv, s8 *ps8lnkspd)
5531 {
5532         struct host_if_msg msg;
5533         s32 s32Error = 0;
5534
5535         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5536
5537
5538
5539         /* prepare the Get LINKSPEED Message */
5540         memset(&msg, 0, sizeof(struct host_if_msg));
5541
5542         msg.id = HOST_IF_MSG_GET_LINKSPEED;
5543         msg.drvHandler = hWFIDrv;
5544
5545         /* send the message */
5546         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5547         if (s32Error) {
5548                 PRINT_ER("Failed to send GET_LINKSPEED to message queue ");
5549                 return -EFAULT;
5550         }
5551
5552         down(&(pstrWFIDrv->hSemGetLINKSPEED));
5553
5554
5555         if (ps8lnkspd == NULL) {
5556                 PRINT_ER("LINKSPEED pointer value is null");
5557                 return -EFAULT;
5558         }
5559
5560
5561         *ps8lnkspd = gs8lnkspd;
5562
5563
5564         return s32Error;
5565 }
5566
5567 s32 host_int_get_statistics(tstrWILC_WFIDrv *hWFIDrv, tstrStatistics *pstrStatistics)
5568 {
5569         s32 s32Error = 0;
5570         struct host_if_msg msg;
5571
5572
5573         /* prepare the Get RSSI Message */
5574         memset(&msg, 0, sizeof(struct host_if_msg));
5575
5576         msg.id = HOST_IF_MSG_GET_STATISTICS;
5577         msg.body.data = (char *)pstrStatistics;
5578         msg.drvHandler = hWFIDrv;
5579         /* send the message */
5580         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5581         if (s32Error) {
5582                 PRINT_ER("Failed to send get host channel param's message queue ");
5583                 return -EFAULT;
5584         }
5585
5586         down(&hWaitResponse);
5587         return s32Error;
5588 }
5589
5590
5591 /**
5592  *  @brief              host_int_scan
5593  *  @details    scans a set of channels
5594  *  @param[in,out] handle to the wifi driver,
5595  *  @param[in]  Scan source
5596  *                              Scan Type       PASSIVE_SCAN = 0,
5597  *                                                      ACTIVE_SCAN  = 1
5598  *                              Channels Array
5599  *                              Channels Array length
5600  *                              Scan Callback function
5601  *  @return             Error code indicating success/failure
5602  *  @note
5603  *  @author             zsalah
5604  *  @date               8 March 2012
5605  *  @version            1.0
5606  */
5607 s32 host_int_scan(tstrWILC_WFIDrv *hWFIDrv, u8 u8ScanSource,
5608                           u8 u8ScanType, u8 *pu8ChnlFreqList,
5609                           u8 u8ChnlListLen, const u8 *pu8IEs,
5610                           size_t IEsLen, wilc_scan_result ScanResult,
5611                           void *pvUserArg,
5612                           struct hidden_network *pstrHiddenNetwork)
5613 {
5614         s32 s32Error = 0;
5615         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5616         struct host_if_msg msg;
5617         tenuScanConnTimer enuScanConnTimer;
5618
5619         if (pstrWFIDrv == NULL || ScanResult == NULL) {
5620                 PRINT_ER("pstrWFIDrv or ScanResult = NULL\n");
5621                 return -EFAULT;
5622         }
5623
5624         /* prepare the Scan Message */
5625         memset(&msg, 0, sizeof(struct host_if_msg));
5626
5627         msg.id = HOST_IF_MSG_SCAN;
5628
5629         if (pstrHiddenNetwork != NULL) {
5630                 msg.body.scan_info.strHiddenNetwork.pstrHiddenNetworkInfo = pstrHiddenNetwork->pstrHiddenNetworkInfo;
5631                 msg.body.scan_info.strHiddenNetwork.u8ssidnum = pstrHiddenNetwork->u8ssidnum;
5632
5633         } else
5634                 PRINT_D(HOSTINF_DBG, "pstrHiddenNetwork IS EQUAL TO NULL\n");
5635
5636         msg.drvHandler = hWFIDrv;
5637         msg.body.scan_info.u8ScanSource = u8ScanSource;
5638         msg.body.scan_info.u8ScanType = u8ScanType;
5639         msg.body.scan_info.pfScanResult = ScanResult;
5640         msg.body.scan_info.pvUserArg = pvUserArg;
5641
5642         msg.body.scan_info.u8ChnlListLen = u8ChnlListLen;
5643         msg.body.scan_info.pu8ChnlFreqList = kmalloc(u8ChnlListLen, GFP_KERNEL);        /* will be deallocated by the receiving thread */
5644         memcpy(msg.body.scan_info.pu8ChnlFreqList,
5645                     pu8ChnlFreqList, u8ChnlListLen);
5646
5647         msg.body.scan_info.IEsLen = IEsLen;
5648         msg.body.scan_info.pu8IEs = kmalloc(IEsLen, GFP_KERNEL);        /* will be deallocated by the receiving thread */
5649         memcpy(msg.body.scan_info.pu8IEs,
5650                     pu8IEs, IEsLen);
5651
5652         /* send the message */
5653         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5654         if (s32Error) {
5655                 PRINT_ER("Error in sending message queue\n");
5656                 return -EINVAL;
5657         }
5658
5659         enuScanConnTimer = SCAN_TIMER;
5660         PRINT_D(HOSTINF_DBG, ">> Starting the SCAN timer\n");
5661         pstrWFIDrv->hScanTimer.data = (unsigned long)hWFIDrv;
5662         mod_timer(&pstrWFIDrv->hScanTimer,
5663                   jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
5664
5665         return s32Error;
5666
5667 }
5668 /**
5669  *  @brief                      hif_set_cfg
5670  *  @details            sets configuration wids values
5671  *  @param[in,out] handle to the wifi driver,
5672  *  @param[in]  WID, WID value
5673  *  @return             Error code indicating success/failure
5674  *  @note
5675  *  @author             zsalah
5676  *  @date               8 March 2012
5677  *  @version            1.0
5678  */
5679 s32 hif_set_cfg(tstrWILC_WFIDrv *hWFIDrv, struct cfg_param_val *pstrCfgParamVal)
5680 {
5681
5682         s32 s32Error = 0;
5683         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5684
5685         struct host_if_msg msg;
5686
5687
5688         if (pstrWFIDrv == NULL) {
5689                 PRINT_ER("pstrWFIDrv NULL\n");
5690                 return -EFAULT;
5691         }
5692         /* prepare the WiphyParams Message */
5693         memset(&msg, 0, sizeof(struct host_if_msg));
5694         msg.id = HOST_IF_MSG_CFG_PARAMS;
5695         msg.body.cfg_info.pstrCfgParamVal = *pstrCfgParamVal;
5696         msg.drvHandler = hWFIDrv;
5697
5698         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5699
5700         return s32Error;
5701
5702 }
5703
5704
5705 /**
5706  *  @brief              hif_get_cfg
5707  *  @details    gets configuration wids values
5708  *  @param[in,out] handle to the wifi driver,
5709  *                              WID value
5710  *  @param[in]  WID,
5711  *  @return             Error code indicating success/failure
5712  *  @note
5713  *  @author             zsalah
5714  *
5715  *  @date               8 March 2012
5716  *  @version            1.0
5717  */
5718 s32 hif_get_cfg(tstrWILC_WFIDrv *hWFIDrv, u16 u16WID, u16 *pu16WID_Value)
5719 {
5720         s32 s32Error = 0;
5721         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
5722
5723         down(&(pstrWFIDrv->gtOsCfgValuesSem));
5724
5725         if (pstrWFIDrv == NULL) {
5726                 PRINT_ER("pstrWFIDrv NULL\n");
5727                 return -EFAULT;
5728         }
5729         PRINT_D(HOSTINF_DBG, "Getting configuration parameters\n");
5730         switch (u16WID) {
5731
5732         case WID_BSS_TYPE:
5733                 *pu16WID_Value = (u16)pstrWFIDrv->strCfgValues.bss_type;
5734                 break;
5735
5736         case WID_AUTH_TYPE:
5737                 *pu16WID_Value = (u16)pstrWFIDrv->strCfgValues.auth_type;
5738                 break;
5739
5740         case WID_AUTH_TIMEOUT:
5741                 *pu16WID_Value = pstrWFIDrv->strCfgValues.auth_timeout;
5742                 break;
5743
5744         case WID_POWER_MANAGEMENT:
5745                 *pu16WID_Value = (u16)pstrWFIDrv->strCfgValues.power_mgmt_mode;
5746                 break;
5747
5748         case WID_SHORT_RETRY_LIMIT:
5749                 *pu16WID_Value =       pstrWFIDrv->strCfgValues.short_retry_limit;
5750                 break;
5751
5752         case WID_LONG_RETRY_LIMIT:
5753                 *pu16WID_Value = pstrWFIDrv->strCfgValues.long_retry_limit;
5754                 break;
5755
5756         case WID_FRAG_THRESHOLD:
5757                 *pu16WID_Value = pstrWFIDrv->strCfgValues.frag_threshold;
5758                 break;
5759
5760         case WID_RTS_THRESHOLD:
5761                 *pu16WID_Value = pstrWFIDrv->strCfgValues.rts_threshold;
5762                 break;
5763
5764         case WID_PREAMBLE:
5765                 *pu16WID_Value = (u16)pstrWFIDrv->strCfgValues.preamble_type;
5766                 break;
5767
5768         case WID_SHORT_SLOT_ALLOWED:
5769                 *pu16WID_Value = (u16) pstrWFIDrv->strCfgValues.short_slot_allowed;
5770                 break;
5771
5772         case WID_11N_TXOP_PROT_DISABLE:
5773                 *pu16WID_Value = (u16)pstrWFIDrv->strCfgValues.txop_prot_disabled;
5774                 break;
5775
5776         case WID_BEACON_INTERVAL:
5777                 *pu16WID_Value = pstrWFIDrv->strCfgValues.beacon_interval;
5778                 break;
5779
5780         case WID_DTIM_PERIOD:
5781                 *pu16WID_Value = (u16)pstrWFIDrv->strCfgValues.dtim_period;
5782                 break;
5783
5784         case WID_SITE_SURVEY:
5785                 *pu16WID_Value = (u16)pstrWFIDrv->strCfgValues.site_survey_enabled;
5786                 break;
5787
5788         case WID_SITE_SURVEY_SCAN_TIME:
5789                 *pu16WID_Value = pstrWFIDrv->strCfgValues.site_survey_scan_time;
5790                 break;
5791
5792         case WID_ACTIVE_SCAN_TIME:
5793                 *pu16WID_Value = pstrWFIDrv->strCfgValues.active_scan_time;
5794                 break;
5795
5796         case WID_PASSIVE_SCAN_TIME:
5797                 *pu16WID_Value = pstrWFIDrv->strCfgValues.passive_scan_time;
5798                 break;
5799
5800         case WID_CURRENT_TX_RATE:
5801                 *pu16WID_Value = pstrWFIDrv->strCfgValues.curr_tx_rate;
5802                 break;
5803
5804         default:
5805                 break;
5806         }
5807
5808         up(&(pstrWFIDrv->gtOsCfgValuesSem));
5809
5810         return s32Error;
5811
5812 }
5813
5814 /*****************************************************************************/
5815 /*                                                      Notification Functions                                                   */
5816 /*****************************************************************************/
5817 /**
5818  *  @brief              notifies host with join and leave requests
5819  *  @details    This function prepares an Information frame having the
5820  *                              information about a joining/leaving station.
5821  *  @param[in,out] handle to the wifi driver,
5822  *  @param[in]  6 byte Sta Adress
5823  *                              Join or leave flag:
5824  *                              Join = 1,
5825  *                              Leave =0
5826  *  @return             Error code indicating success/failure
5827  *  @note
5828  *  @author             zsalah
5829  *  @date               8 March 2012
5830  *  @version            1.0
5831  */
5832 void host_int_send_join_leave_info_to_host
5833         (u16 assocId, u8 *stationAddr, bool joining)
5834 {
5835 }
5836 /**
5837  *  @brief              notifies host with stations found in scan
5838  *  @details    sends the beacon/probe response from scan
5839  *  @param[in,out] handle to the wifi driver,
5840  *  @param[in]  Sta Address,
5841  *                              Frame length,
5842  *                              Rssi of the Station found
5843  *  @return             Error code indicating success/failure
5844  *  @note
5845  *  @author             zsalah
5846  *  @date               8 March 2012
5847  *  @version            1.0
5848  */
5849
5850 static void GetPeriodicRSSI(unsigned long arg)
5851 {
5852         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)arg;
5853
5854         if (pstrWFIDrv == NULL) {
5855                 PRINT_ER("Driver handler is NULL\n");
5856                 return;
5857         }
5858
5859         if (pstrWFIDrv->enuHostIFstate == HOST_IF_CONNECTED) {
5860                 s32 s32Error = 0;
5861                 struct host_if_msg msg;
5862
5863                 /* prepare the Get RSSI Message */
5864                 memset(&msg, 0, sizeof(struct host_if_msg));
5865
5866                 msg.id = HOST_IF_MSG_GET_RSSI;
5867                 msg.drvHandler = pstrWFIDrv;
5868
5869                 /* send the message */
5870                 s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
5871                 if (s32Error) {
5872                         PRINT_ER("Failed to send get host channel param's message queue ");
5873                         return;
5874                 }
5875         }
5876         g_hPeriodicRSSI.data = (unsigned long)pstrWFIDrv;
5877         mod_timer(&g_hPeriodicRSSI, jiffies + msecs_to_jiffies(5000));
5878 }
5879
5880
5881 void host_int_send_network_info_to_host
5882         (u8 *macStartAddress, u16 u16RxFrameLen, s8 s8Rssi)
5883 {
5884 }
5885 /**
5886  *  @brief              host_int_init
5887  *  @details    host interface initialization function
5888  *  @param[in,out] handle to the wifi driver,
5889  *  @note
5890  *  @author             zsalah
5891  *  @date               8 March 2012
5892  *  @version            1.0
5893  */
5894 static u32 clients_count;
5895
5896 s32 host_int_init(tstrWILC_WFIDrv **phWFIDrv)
5897 {
5898         s32 result = 0;
5899         tstrWILC_WFIDrv *pstrWFIDrv;
5900         int err;
5901
5902         PRINT_D(HOSTINF_DBG, "Initializing host interface for client %d\n", clients_count + 1);
5903
5904         gbScanWhileConnected = false;
5905
5906         sema_init(&hWaitResponse, 0);
5907
5908         /*Allocate host interface private structure*/
5909         pstrWFIDrv  = kzalloc(sizeof(tstrWILC_WFIDrv), GFP_KERNEL);
5910         if (!pstrWFIDrv) {
5911                 result = -ENOMEM;
5912                 goto _fail_timer_2;
5913         }
5914         *phWFIDrv = pstrWFIDrv;
5915         err = add_handler_in_list(pstrWFIDrv);
5916         if (err) {
5917                 result = -EFAULT;
5918                 goto _fail_timer_2;
5919         }
5920
5921         g_obtainingIP = false;
5922
5923         PRINT_D(HOSTINF_DBG, "Global handle pointer value=%p\n", pstrWFIDrv);
5924         if (clients_count == 0) {
5925                 sema_init(&hSemHostIFthrdEnd, 0);
5926                 sema_init(&hSemDeinitDrvHandle, 0);
5927                 sema_init(&hSemHostIntDeinit, 1);
5928         }
5929
5930         sema_init(&pstrWFIDrv->hSemTestKeyBlock, 0);
5931         sema_init(&pstrWFIDrv->hSemTestDisconnectBlock, 0);
5932         sema_init(&pstrWFIDrv->hSemGetRSSI, 0);
5933         sema_init(&pstrWFIDrv->hSemGetLINKSPEED, 0);
5934         sema_init(&pstrWFIDrv->hSemGetCHNL, 0);
5935         sema_init(&pstrWFIDrv->hSemInactiveTime, 0);
5936
5937         PRINT_D(HOSTINF_DBG, "INIT: CLIENT COUNT %d\n", clients_count);
5938
5939         if (clients_count == 0) {
5940                 result = wilc_mq_create(&gMsgQHostIF);
5941
5942                 if (result < 0) {
5943                         PRINT_ER("Failed to creat MQ\n");
5944                         goto _fail_;
5945                 }
5946                 HostIFthreadHandler = kthread_run(hostIFthread, NULL, "WILC_kthread");
5947                 if (IS_ERR(HostIFthreadHandler)) {
5948                         PRINT_ER("Failed to creat Thread\n");
5949                         result = -EFAULT;
5950                         goto _fail_mq_;
5951                 }
5952                 setup_timer(&g_hPeriodicRSSI, GetPeriodicRSSI,
5953                             (unsigned long)pstrWFIDrv);
5954                 mod_timer(&g_hPeriodicRSSI, jiffies + msecs_to_jiffies(5000));
5955         }
5956
5957         setup_timer(&pstrWFIDrv->hScanTimer, TimerCB_Scan, 0);
5958
5959         setup_timer(&pstrWFIDrv->hConnectTimer, TimerCB_Connect, 0);
5960
5961         /*Remain on channel timer*/
5962         setup_timer(&pstrWFIDrv->hRemainOnChannel, ListenTimerCB, 0);
5963
5964         sema_init(&(pstrWFIDrv->gtOsCfgValuesSem), 1);
5965         down(&pstrWFIDrv->gtOsCfgValuesSem);
5966
5967         pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
5968
5969         /*Initialize CFG WIDS Defualt Values*/
5970
5971         pstrWFIDrv->strCfgValues.site_survey_enabled = SITE_SURVEY_OFF;
5972         pstrWFIDrv->strCfgValues.scan_source = DEFAULT_SCAN;
5973         pstrWFIDrv->strCfgValues.active_scan_time = ACTIVE_SCAN_TIME;
5974         pstrWFIDrv->strCfgValues.passive_scan_time = PASSIVE_SCAN_TIME;
5975         pstrWFIDrv->strCfgValues.curr_tx_rate = AUTORATE;
5976
5977         pstrWFIDrv->u64P2p_MgmtTimeout = 0;
5978
5979         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",
5980
5981                    pstrWFIDrv->strCfgValues.site_survey_enabled, pstrWFIDrv->strCfgValues.scan_source,
5982                    pstrWFIDrv->strCfgValues.active_scan_time, pstrWFIDrv->strCfgValues.passive_scan_time,
5983                    pstrWFIDrv->strCfgValues.curr_tx_rate);
5984
5985         up(&pstrWFIDrv->gtOsCfgValuesSem);
5986
5987         clients_count++; /* increase number of created entities */
5988
5989         return result;
5990
5991 _fail_timer_2:
5992         up(&pstrWFIDrv->gtOsCfgValuesSem);
5993         del_timer_sync(&pstrWFIDrv->hConnectTimer);
5994         del_timer_sync(&pstrWFIDrv->hScanTimer);
5995         kthread_stop(HostIFthreadHandler);
5996 _fail_mq_:
5997         wilc_mq_destroy(&gMsgQHostIF);
5998 _fail_:
5999         return result;
6000 }
6001 /**
6002  *  @brief              host_int_deinit
6003  *  @details    host interface initialization function
6004  *  @param[in,out] handle to the wifi driver,
6005  *  @note
6006  *  @author             zsalah
6007  *  @date               8 March 2012
6008  *  @version            1.0
6009  */
6010
6011 s32 host_int_deinit(tstrWILC_WFIDrv *hWFIDrv)
6012 {
6013         s32 s32Error = 0;
6014         struct host_if_msg msg;
6015         int ret;
6016
6017         /*obtain driver handle*/
6018         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6019
6020         if (pstrWFIDrv == NULL) {
6021                 PRINT_ER("pstrWFIDrv = NULL\n");
6022                 return 0;
6023         }
6024
6025         down(&hSemHostIntDeinit);
6026
6027         terminated_handle = pstrWFIDrv;
6028         PRINT_D(HOSTINF_DBG, "De-initializing host interface for client %d\n", clients_count);
6029
6030         /*Destroy all timers before acquiring hSemDeinitDrvHandle*/
6031         /*to guarantee handling all messages befor proceeding*/
6032         if (del_timer_sync(&pstrWFIDrv->hScanTimer)) {
6033                 PRINT_D(HOSTINF_DBG, ">> Scan timer is active\n");
6034                 /* msleep(HOST_IF_SCAN_TIMEOUT+1000); */
6035         }
6036
6037         if (del_timer_sync(&pstrWFIDrv->hConnectTimer)) {
6038                 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
6039                 /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */
6040         }
6041
6042
6043         if (del_timer_sync(&g_hPeriodicRSSI)) {
6044                 PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
6045                 /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */
6046         }
6047
6048         /*Destroy Remain-onchannel Timer*/
6049         del_timer_sync(&pstrWFIDrv->hRemainOnChannel);
6050
6051         host_int_set_wfi_drv_handler(NULL);
6052         down(&hSemDeinitDrvHandle);
6053
6054
6055         /*Calling the CFG80211 scan done function with the abort flag set to true*/
6056         if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) {
6057                 pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult(SCAN_EVENT_ABORTED, NULL,
6058                                                                 pstrWFIDrv->strWILC_UsrScanReq.u32UserScanPvoid, NULL);
6059
6060                 pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult = NULL;
6061         }
6062
6063         pstrWFIDrv->enuHostIFstate = HOST_IF_IDLE;
6064
6065         gbScanWhileConnected = false;
6066
6067         memset(&msg, 0, sizeof(struct host_if_msg));
6068
6069         if (clients_count == 1) {
6070                 if (del_timer_sync(&g_hPeriodicRSSI)) {
6071                         PRINT_D(HOSTINF_DBG, ">> Connect timer is active\n");
6072                         /* msleep(HOST_IF_CONNECT_TIMEOUT+1000); */
6073                 }
6074                 msg.id = HOST_IF_MSG_EXIT;
6075                 msg.drvHandler = hWFIDrv;
6076
6077
6078                 s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6079                 if (s32Error != 0)
6080                         PRINT_ER("Error in sending deinit's message queue message function: Error(%d)\n", s32Error);
6081
6082                 down(&hSemHostIFthrdEnd);
6083
6084                 wilc_mq_destroy(&gMsgQHostIF);
6085         }
6086
6087         down(&(pstrWFIDrv->gtOsCfgValuesSem));
6088
6089         /*Setting the gloabl driver handler with NULL*/
6090         /* gWFiDrvHandle = NULL; */
6091         ret = remove_handler_in_list(pstrWFIDrv);
6092         if (ret)
6093                 s32Error = -ENOENT;
6094
6095         if (pstrWFIDrv != NULL) {
6096                 kfree(pstrWFIDrv);
6097                 /* pstrWFIDrv=NULL; */
6098
6099         }
6100
6101         clients_count--; /* Decrease number of created entities */
6102         terminated_handle = NULL;
6103         up(&hSemHostIntDeinit);
6104         return s32Error;
6105 }
6106
6107
6108 /**
6109  *  @brief              NetworkInfoReceived
6110  *  @details    function to to be called when network info packet is received
6111  *  @param[in]  pu8Buffer the received packet
6112  *  @param[in]   u32Length  length of the received packet
6113  *  @return             none
6114  *  @note
6115  *  @author
6116  *  @date               1 Mar 2012
6117  *  @version            1.0
6118  */
6119 void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length)
6120 {
6121         s32 s32Error = 0;
6122         struct host_if_msg msg;
6123         int id;
6124         tstrWILC_WFIDrv *pstrWFIDrv = NULL;
6125
6126         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
6127         pstrWFIDrv = get_handler_from_id(id);
6128
6129
6130
6131
6132         if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle)      {
6133                 PRINT_ER("NetworkInfo received but driver not init[%p]\n", pstrWFIDrv);
6134                 return;
6135         }
6136
6137         /* prepare the Asynchronous Network Info message */
6138         memset(&msg, 0, sizeof(struct host_if_msg));
6139
6140         msg.id = HOST_IF_MSG_RCVD_NTWRK_INFO;
6141         msg.drvHandler = pstrWFIDrv;
6142
6143         msg.body.net_info.u32Length = u32Length;
6144         msg.body.net_info.pu8Buffer = kmalloc(u32Length, GFP_KERNEL); /* will be deallocated by the receiving thread */
6145         memcpy(msg.body.net_info.pu8Buffer,
6146                     pu8Buffer, u32Length);
6147
6148         /* send the message */
6149         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6150         if (s32Error)
6151                 PRINT_ER("Error in sending network info message queue message parameters: Error(%d)\n", s32Error);
6152 }
6153
6154 /**
6155  *  @brief              GnrlAsyncInfoReceived
6156  *  @details    function to be called when general Asynchronous info packet is received
6157  *  @param[in]  pu8Buffer the received packet
6158  *  @param[in]   u32Length  length of the received packet
6159  *  @return             none
6160  *  @note
6161  *  @author
6162  *  @date               15 Mar 2012
6163  *  @version            1.0
6164  */
6165 void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length)
6166 {
6167         s32 s32Error = 0;
6168         struct host_if_msg msg;
6169         int id;
6170         tstrWILC_WFIDrv *pstrWFIDrv = NULL;
6171
6172         down(&hSemHostIntDeinit);
6173
6174         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
6175         pstrWFIDrv = get_handler_from_id(id);
6176         PRINT_D(HOSTINF_DBG, "General asynchronous info packet received\n");
6177
6178
6179         if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle) {
6180                 PRINT_D(HOSTINF_DBG, "Wifi driver handler is equal to NULL\n");
6181                 up(&hSemHostIntDeinit);
6182                 return;
6183         }
6184
6185         if (pstrWFIDrv->strWILC_UsrConnReq.pfUserConnectResult == NULL) {
6186                 /* received mac status is not needed when there is no current Connect Request */
6187                 PRINT_ER("Received mac status is not needed when there is no current Connect Reques\n");
6188                 up(&hSemHostIntDeinit);
6189                 return;
6190         }
6191
6192         /* prepare the General Asynchronous Info message */
6193         memset(&msg, 0, sizeof(struct host_if_msg));
6194
6195
6196         msg.id = HOST_IF_MSG_RCVD_GNRL_ASYNC_INFO;
6197         msg.drvHandler = pstrWFIDrv;
6198
6199
6200         msg.body.async_info.u32Length = u32Length;
6201         msg.body.async_info.pu8Buffer = kmalloc(u32Length, GFP_KERNEL); /* will be deallocated by the receiving thread */
6202         memcpy(msg.body.async_info.pu8Buffer,
6203                     pu8Buffer, u32Length);
6204
6205         /* send the message */
6206         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6207         if (s32Error)
6208                 PRINT_ER("Error in sending message queue asynchronous message info: Error(%d)\n", s32Error);
6209
6210         up(&hSemHostIntDeinit);
6211 }
6212
6213 /**
6214  *  @brief host_int_ScanCompleteReceived
6215  *  @details        Setting scan complete received notifcation in message queue
6216  *  @param[in]     u8* pu8Buffer, u32 u32Length
6217  *  @return         Error code.
6218  *  @author
6219  *  @date
6220  *  @version    1.0
6221  */
6222 void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length)
6223 {
6224         s32 s32Error = 0;
6225         struct host_if_msg msg;
6226         int id;
6227         tstrWILC_WFIDrv *pstrWFIDrv = NULL;
6228
6229         id = ((pu8Buffer[u32Length - 4]) | (pu8Buffer[u32Length - 3] << 8) | (pu8Buffer[u32Length - 2] << 16) | (pu8Buffer[u32Length - 1] << 24));
6230         pstrWFIDrv = get_handler_from_id(id);
6231
6232
6233         PRINT_D(GENERIC_DBG, "Scan notification received %p\n", pstrWFIDrv);
6234
6235         if (pstrWFIDrv == NULL || pstrWFIDrv == terminated_handle)
6236                 return;
6237
6238         /*if there is an ongoing scan request*/
6239         if (pstrWFIDrv->strWILC_UsrScanReq.pfUserScanResult) {
6240                 /* prepare theScan Done message */
6241                 memset(&msg, 0, sizeof(struct host_if_msg));
6242
6243                 msg.id = HOST_IF_MSG_RCVD_SCAN_COMPLETE;
6244                 msg.drvHandler = pstrWFIDrv;
6245
6246
6247                 /* will be deallocated by the receiving thread */
6248                 /*no need to send message body*/
6249
6250                 /*msg.body.strScanComplete.u32Length = u32Length;
6251                  * msg.body.strScanComplete.pu8Buffer  = (u8*)WILC_MALLOC(u32Length);
6252                  * memcpy(msg.body.strScanComplete.pu8Buffer,
6253                  *                        pu8Buffer, u32Length); */
6254
6255                 /* send the message */
6256                 s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6257                 if (s32Error)
6258                         PRINT_ER("Error in sending message queue scan complete parameters: Error(%d)\n", s32Error);
6259         }
6260
6261
6262         return;
6263
6264 }
6265
6266 /**
6267  *  @brief              host_int_remain_on_channel
6268  *  @details
6269  *  @param[in]          Handle to wifi driver
6270  *                              Duration to remain on channel
6271  *                              Channel to remain on
6272  *                              Pointer to fn to be called on receive frames in listen state
6273  *                              Pointer to remain-on-channel expired fn
6274  *                              Priv
6275  *  @return             Error code.
6276  *  @author
6277  *  @date
6278  *  @version            1.0
6279  */
6280 s32 host_int_remain_on_channel(tstrWILC_WFIDrv *hWFIDrv, u32 u32SessionID, u32 u32duration, u16 chan, wilc_remain_on_chan_expired RemainOnChanExpired, wilc_remain_on_chan_ready RemainOnChanReady, void *pvUserArg)
6281 {
6282         s32 s32Error = 0;
6283         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6284         struct host_if_msg msg;
6285
6286         if (pstrWFIDrv == NULL) {
6287                 PRINT_ER("driver is null\n");
6288                 return -EFAULT;
6289         }
6290
6291         /* prepare the remainonchan Message */
6292         memset(&msg, 0, sizeof(struct host_if_msg));
6293
6294         /* prepare the WiphyParams Message */
6295         msg.id = HOST_IF_MSG_REMAIN_ON_CHAN;
6296         msg.body.remain_on_ch.u16Channel = chan;
6297         msg.body.remain_on_ch.pRemainOnChanExpired = RemainOnChanExpired;
6298         msg.body.remain_on_ch.pRemainOnChanReady = RemainOnChanReady;
6299         msg.body.remain_on_ch.pVoid = pvUserArg;
6300         msg.body.remain_on_ch.u32duration = u32duration;
6301         msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
6302         msg.drvHandler = hWFIDrv;
6303
6304         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6305         if (s32Error)
6306                 PRINT_ER("wilc mq send fail\n");
6307
6308         return s32Error;
6309 }
6310
6311 /**
6312  *  @brief              host_int_ListenStateExpired
6313  *  @details
6314  *  @param[in]          Handle to wifi driver
6315  *                              Duration to remain on channel
6316  *                              Channel to remain on
6317  *                              Pointer to fn to be called on receive frames in listen state
6318  *                              Pointer to remain-on-channel expired fn
6319  *                              Priv
6320  *  @return             Error code.
6321  *  @author
6322  *  @date
6323  *  @version            1.0
6324  */
6325 s32 host_int_ListenStateExpired(tstrWILC_WFIDrv *hWFIDrv, u32 u32SessionID)
6326 {
6327         s32 s32Error = 0;
6328         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6329         struct host_if_msg msg;
6330
6331         if (pstrWFIDrv == NULL) {
6332                 PRINT_ER("driver is null\n");
6333                 return -EFAULT;
6334         }
6335
6336         /*Stopping remain-on-channel timer*/
6337         del_timer(&pstrWFIDrv->hRemainOnChannel);
6338
6339         /* prepare the timer fire Message */
6340         memset(&msg, 0, sizeof(struct host_if_msg));
6341         msg.id = HOST_IF_MSG_LISTEN_TIMER_FIRED;
6342         msg.drvHandler = hWFIDrv;
6343         msg.body.remain_on_ch.u32ListenSessionID = u32SessionID;
6344
6345         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6346         if (s32Error)
6347                 PRINT_ER("wilc mq send fail\n");
6348
6349         return s32Error;
6350 }
6351
6352 /**
6353  *  @brief              host_int_frame_register
6354  *  @details
6355  *  @param[in]          Handle to wifi driver
6356  *  @return             Error code.
6357  *  @author
6358  *  @date
6359  *  @version            1.0*/
6360 s32 host_int_frame_register(tstrWILC_WFIDrv *hWFIDrv, u16 u16FrameType, bool bReg)
6361 {
6362         s32 s32Error = 0;
6363         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6364         struct host_if_msg msg;
6365
6366         if (pstrWFIDrv == NULL) {
6367                 PRINT_ER("driver is null\n");
6368                 return -EFAULT;
6369         }
6370
6371         memset(&msg, 0, sizeof(struct host_if_msg));
6372
6373         /* prepare the WiphyParams Message */
6374         msg.id = HOST_IF_MSG_REGISTER_FRAME;
6375         switch (u16FrameType) {
6376         case ACTION:
6377                 PRINT_D(HOSTINF_DBG, "ACTION\n");
6378                 msg.body.reg_frame.u8Regid = ACTION_FRM_IDX;
6379                 break;
6380
6381         case PROBE_REQ:
6382                 PRINT_D(HOSTINF_DBG, "PROBE REQ\n");
6383                 msg.body.reg_frame.u8Regid = PROBE_REQ_IDX;
6384                 break;
6385
6386         default:
6387                 PRINT_D(HOSTINF_DBG, "Not valid frame type\n");
6388                 break;
6389         }
6390         msg.body.reg_frame.u16FrameType = u16FrameType;
6391         msg.body.reg_frame.bReg = bReg;
6392         msg.drvHandler = hWFIDrv;
6393
6394         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6395         if (s32Error)
6396                 PRINT_ER("wilc mq send fail\n");
6397
6398         return s32Error;
6399
6400
6401 }
6402
6403 /**
6404  *  @brief host_int_add_beacon
6405  *  @details       Setting add beacon params in message queue
6406  *  @param[in]    WILC_WFIDrvHandle hWFIDrv, u32 u32Interval,
6407  *                         u32 u32DTIMPeriod,u32 u32HeadLen, u8* pu8Head,
6408  *                         u32 u32TailLen, u8* pu8Tail
6409  *  @return         Error code.
6410  *  @author
6411  *  @date
6412  *  @version    1.0
6413  */
6414 s32 host_int_add_beacon(tstrWILC_WFIDrv *hWFIDrv, u32 u32Interval,
6415                                 u32 u32DTIMPeriod,
6416                                 u32 u32HeadLen, u8 *pu8Head,
6417                                 u32 u32TailLen, u8 *pu8Tail)
6418 {
6419         s32 s32Error = 0;
6420         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6421         struct host_if_msg msg;
6422         struct beacon_attr *pstrSetBeaconParam = &msg.body.beacon_info;
6423
6424         if (pstrWFIDrv == NULL) {
6425                 PRINT_ER("driver is null\n");
6426                 return -EFAULT;
6427         }
6428
6429         memset(&msg, 0, sizeof(struct host_if_msg));
6430
6431         PRINT_D(HOSTINF_DBG, "Setting adding beacon message queue params\n");
6432
6433
6434         /* prepare the WiphyParams Message */
6435         msg.id = HOST_IF_MSG_ADD_BEACON;
6436         msg.drvHandler = hWFIDrv;
6437         pstrSetBeaconParam->u32Interval = u32Interval;
6438         pstrSetBeaconParam->u32DTIMPeriod = u32DTIMPeriod;
6439         pstrSetBeaconParam->u32HeadLen = u32HeadLen;
6440         pstrSetBeaconParam->pu8Head = kmalloc(u32HeadLen, GFP_KERNEL);
6441         if (pstrSetBeaconParam->pu8Head == NULL) {
6442                 s32Error = -ENOMEM;
6443                 goto ERRORHANDLER;
6444         }
6445         memcpy(pstrSetBeaconParam->pu8Head, pu8Head, u32HeadLen);
6446         pstrSetBeaconParam->u32TailLen = u32TailLen;
6447
6448         if (u32TailLen > 0) {
6449                 pstrSetBeaconParam->pu8Tail = kmalloc(u32TailLen, GFP_KERNEL);
6450                 if (pstrSetBeaconParam->pu8Tail == NULL) {
6451                         s32Error = -ENOMEM;
6452                         goto ERRORHANDLER;
6453                 }
6454                 memcpy(pstrSetBeaconParam->pu8Tail, pu8Tail, u32TailLen);
6455         } else {
6456                 pstrSetBeaconParam->pu8Tail = NULL;
6457         }
6458
6459         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6460         if (s32Error)
6461                 PRINT_ER("wilc mq send fail\n");
6462
6463 ERRORHANDLER:
6464         if (s32Error) {
6465                 if (pstrSetBeaconParam->pu8Head != NULL)
6466                         kfree(pstrSetBeaconParam->pu8Head);
6467
6468                 if (pstrSetBeaconParam->pu8Tail != NULL)
6469                         kfree(pstrSetBeaconParam->pu8Tail);
6470         }
6471
6472         return s32Error;
6473
6474 }
6475
6476
6477 /**
6478  *  @brief host_int_del_beacon
6479  *  @details       Setting add beacon params in message queue
6480  *  @param[in]    WILC_WFIDrvHandle hWFIDrv
6481  *  @return         Error code.
6482  *  @author
6483  *  @date
6484  *  @version    1.0
6485  */
6486 s32 host_int_del_beacon(tstrWILC_WFIDrv *hWFIDrv)
6487 {
6488         s32 s32Error = 0;
6489         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6490         struct host_if_msg msg;
6491
6492         if (pstrWFIDrv == NULL) {
6493                 PRINT_ER("driver is null\n");
6494                 return -EFAULT;
6495         }
6496
6497         /* prepare the WiphyParams Message */
6498         msg.id = HOST_IF_MSG_DEL_BEACON;
6499         msg.drvHandler = hWFIDrv;
6500         PRINT_D(HOSTINF_DBG, "Setting deleting beacon message queue params\n");
6501
6502         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6503         if (s32Error)
6504                 PRINT_ER("wilc_mq_send fail\n");
6505
6506         return s32Error;
6507 }
6508
6509
6510 /**
6511  *  @brief host_int_add_station
6512  *  @details       Setting add station params in message queue
6513  *  @param[in]    WILC_WFIDrvHandle hWFIDrv, struct add_sta_param *pstrStaParams
6514  *  @return         Error code.
6515  *  @author
6516  *  @date
6517  *  @version    1.0
6518  */
6519 s32 host_int_add_station(tstrWILC_WFIDrv *hWFIDrv,
6520                          struct add_sta_param *pstrStaParams)
6521 {
6522         s32 s32Error = 0;
6523         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6524         struct host_if_msg msg;
6525         struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
6526
6527
6528         if (pstrWFIDrv == NULL) {
6529                 PRINT_ER("driver is null\n");
6530                 return -EFAULT;
6531         }
6532
6533         memset(&msg, 0, sizeof(struct host_if_msg));
6534
6535         PRINT_D(HOSTINF_DBG, "Setting adding station message queue params\n");
6536
6537
6538         /* prepare the WiphyParams Message */
6539         msg.id = HOST_IF_MSG_ADD_STATION;
6540         msg.drvHandler = hWFIDrv;
6541
6542         memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
6543         if (pstrAddStationMsg->u8NumRates > 0) {
6544                 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
6545
6546                 if (!rates)
6547                         return -ENOMEM;
6548
6549                 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
6550                 pstrAddStationMsg->pu8Rates = rates;
6551         }
6552
6553
6554         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6555         if (s32Error)
6556                 PRINT_ER("wilc_mq_send fail\n");
6557         return s32Error;
6558 }
6559
6560 /**
6561  *  @brief host_int_del_station
6562  *  @details       Setting delete station params in message queue
6563  *  @param[in]    WILC_WFIDrvHandle hWFIDrv, u8* pu8MacAddr
6564  *  @return         Error code.
6565  *  @author
6566  *  @date
6567  *  @version    1.0
6568  */
6569 s32 host_int_del_station(tstrWILC_WFIDrv *hWFIDrv, const u8 *pu8MacAddr)
6570 {
6571         s32 s32Error = 0;
6572         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6573         struct host_if_msg msg;
6574         struct del_sta *pstrDelStationMsg = &msg.body.del_sta_info;
6575
6576         if (pstrWFIDrv == NULL) {
6577                 PRINT_ER("driver is null\n");
6578                 return -EFAULT;
6579         }
6580
6581         memset(&msg, 0, sizeof(struct host_if_msg));
6582
6583         PRINT_D(HOSTINF_DBG, "Setting deleting station message queue params\n");
6584
6585
6586
6587         /* prepare the WiphyParams Message */
6588         msg.id = HOST_IF_MSG_DEL_STATION;
6589         msg.drvHandler = hWFIDrv;
6590
6591         if (pu8MacAddr == NULL)
6592                 memset(pstrDelStationMsg->au8MacAddr, 255, ETH_ALEN);
6593         else
6594                 memcpy(pstrDelStationMsg->au8MacAddr, pu8MacAddr, ETH_ALEN);
6595
6596         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6597         if (s32Error)
6598                 PRINT_ER("wilc_mq_send fail\n");
6599         return s32Error;
6600 }
6601 /**
6602  *  @brief      host_int_del_allstation
6603  *  @details    Setting del station params in message queue
6604  *  @param[in]  WILC_WFIDrvHandle hWFIDrv, u8 pu8MacAddr[][ETH_ALEN]s
6605  *  @return        Error code.
6606  *  @author
6607  *  @date
6608  *  @version    1.0
6609  */
6610 s32 host_int_del_allstation(tstrWILC_WFIDrv *hWFIDrv, u8 pu8MacAddr[][ETH_ALEN])
6611 {
6612         s32 s32Error = 0;
6613         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6614         struct host_if_msg msg;
6615         struct del_all_sta *pstrDelAllStationMsg = &msg.body.del_all_sta_info;
6616         u8 au8Zero_Buff[ETH_ALEN] = {0};
6617         u32 i;
6618         u8 u8AssocNumb = 0;
6619
6620
6621         if (pstrWFIDrv == NULL) {
6622                 PRINT_ER("driver is null\n");
6623                 return -EFAULT;
6624         }
6625
6626         memset(&msg, 0, sizeof(struct host_if_msg));
6627
6628         PRINT_D(HOSTINF_DBG, "Setting deauthenticating station message queue params\n");
6629
6630         /* prepare the WiphyParams Message */
6631         msg.id = HOST_IF_MSG_DEL_ALL_STA;
6632         msg.drvHandler = hWFIDrv;
6633
6634         /* Handling situation of deauthenticing all associated stations*/
6635         for (i = 0; i < MAX_NUM_STA; i++) {
6636                 if (memcmp(pu8MacAddr[i], au8Zero_Buff, ETH_ALEN)) {
6637                         memcpy(pstrDelAllStationMsg->au8Sta_DelAllSta[i], pu8MacAddr[i], ETH_ALEN);
6638                         PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", pstrDelAllStationMsg->au8Sta_DelAllSta[i][0], pstrDelAllStationMsg->au8Sta_DelAllSta[i][1], pstrDelAllStationMsg->au8Sta_DelAllSta[i][2], pstrDelAllStationMsg->au8Sta_DelAllSta[i][3], pstrDelAllStationMsg->au8Sta_DelAllSta[i][4],
6639                                 pstrDelAllStationMsg->au8Sta_DelAllSta[i][5]);
6640                         u8AssocNumb++;
6641                 }
6642         }
6643         if (!u8AssocNumb) {
6644                 PRINT_D(CFG80211_DBG, "NO ASSOCIATED STAS\n");
6645                 return s32Error;
6646         }
6647
6648         pstrDelAllStationMsg->u8Num_AssocSta = u8AssocNumb;
6649         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6650
6651
6652         if (s32Error)
6653                 PRINT_ER("wilc_mq_send fail\n");
6654
6655         down(&hWaitResponse);
6656
6657         return s32Error;
6658
6659 }
6660
6661 /**
6662  *  @brief host_int_edit_station
6663  *  @details       Setting edit station params in message queue
6664  *  @param[in]    WILC_WFIDrvHandle hWFIDrv, struct add_sta_param *pstrStaParams
6665  *  @return         Error code.
6666  *  @author
6667  *  @date
6668  *  @version    1.0
6669  */
6670 s32 host_int_edit_station(tstrWILC_WFIDrv *hWFIDrv,
6671                           struct add_sta_param *pstrStaParams)
6672 {
6673         s32 s32Error = 0;
6674         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6675         struct host_if_msg msg;
6676         struct add_sta_param *pstrAddStationMsg = &msg.body.add_sta_info;
6677
6678         if (pstrWFIDrv == NULL) {
6679                 PRINT_ER("driver is null\n");
6680                 return -EFAULT;
6681         }
6682
6683         PRINT_D(HOSTINF_DBG, "Setting editing station message queue params\n");
6684
6685         memset(&msg, 0, sizeof(struct host_if_msg));
6686
6687
6688         /* prepare the WiphyParams Message */
6689         msg.id = HOST_IF_MSG_EDIT_STATION;
6690         msg.drvHandler = hWFIDrv;
6691
6692         memcpy(pstrAddStationMsg, pstrStaParams, sizeof(struct add_sta_param));
6693         if (pstrAddStationMsg->u8NumRates > 0) {
6694                 u8 *rates = kmalloc(pstrAddStationMsg->u8NumRates, GFP_KERNEL);
6695
6696                 if (!rates)
6697                         return -ENOMEM;
6698
6699                 memcpy(rates, pstrStaParams->pu8Rates, pstrAddStationMsg->u8NumRates);
6700                 pstrAddStationMsg->pu8Rates = rates;
6701         }
6702
6703         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6704         if (s32Error)
6705                 PRINT_ER("wilc_mq_send fail\n");
6706
6707         return s32Error;
6708 }
6709
6710 s32 host_int_set_power_mgmt(tstrWILC_WFIDrv *hWFIDrv, bool bIsEnabled, u32 u32Timeout)
6711 {
6712         s32 s32Error = 0;
6713         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6714         struct host_if_msg msg;
6715         struct power_mgmt_param *pstrPowerMgmtParam = &msg.body.pwr_mgmt_info;
6716
6717         PRINT_INFO(HOSTINF_DBG, "\n\n>> Setting PS to %d <<\n\n", bIsEnabled);
6718
6719         if (pstrWFIDrv == NULL) {
6720                 PRINT_ER("driver is null\n");
6721                 return -EFAULT;
6722         }
6723
6724         PRINT_D(HOSTINF_DBG, "Setting Power management message queue params\n");
6725
6726         memset(&msg, 0, sizeof(struct host_if_msg));
6727
6728
6729         /* prepare the WiphyParams Message */
6730         msg.id = HOST_IF_MSG_POWER_MGMT;
6731         msg.drvHandler = hWFIDrv;
6732
6733         pstrPowerMgmtParam->bIsEnabled = bIsEnabled;
6734         pstrPowerMgmtParam->u32Timeout = u32Timeout;
6735
6736
6737         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6738         if (s32Error)
6739                 PRINT_ER("wilc_mq_send fail\n");
6740         return s32Error;
6741 }
6742
6743 s32 host_int_setup_multicast_filter(tstrWILC_WFIDrv *hWFIDrv, bool bIsEnabled, u32 u32count)
6744 {
6745         s32 s32Error = 0;
6746
6747         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6748         struct host_if_msg msg;
6749         struct set_multicast *pstrMulticastFilterParam = &msg.body.multicast_info;
6750
6751
6752         if (pstrWFIDrv == NULL) {
6753                 PRINT_ER("driver is null\n");
6754                 return -EFAULT;
6755         }
6756
6757         PRINT_D(HOSTINF_DBG, "Setting Multicast Filter params\n");
6758
6759         memset(&msg, 0, sizeof(struct host_if_msg));
6760
6761
6762         /* prepare the WiphyParams Message */
6763         msg.id = HOST_IF_MSG_SET_MULTICAST_FILTER;
6764         msg.drvHandler = hWFIDrv;
6765
6766         pstrMulticastFilterParam->bIsEnabled = bIsEnabled;
6767         pstrMulticastFilterParam->u32count = u32count;
6768
6769         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
6770         if (s32Error)
6771                 PRINT_ER("wilc_mq_send fail\n");
6772         return s32Error;
6773 }
6774
6775 /**
6776  *  @brief              host_int_ParseJoinBssParam
6777  *  @details            Parse Needed Join Parameters and save it in a new JoinBssParam entry
6778  *  @param[in]          tstrNetworkInfo* ptstrNetworkInfo
6779  *  @return
6780  *  @author             zsalah
6781  *  @date
6782  *  @version            1.0**/
6783 static void *host_int_ParseJoinBssParam(tstrNetworkInfo *ptstrNetworkInfo)
6784 {
6785         tstrJoinBssParam *pNewJoinBssParam = NULL;
6786         u8 *pu8IEs;
6787         u16 u16IEsLen;
6788         u16 index = 0;
6789         u8 suppRatesNo = 0;
6790         u8 extSuppRatesNo;
6791         u16 jumpOffset;
6792         u8 pcipherCount;
6793         u8 authCount;
6794         u8 pcipherTotalCount = 0;
6795         u8 authTotalCount = 0;
6796         u8 i, j;
6797
6798         pu8IEs = ptstrNetworkInfo->pu8IEs;
6799         u16IEsLen = ptstrNetworkInfo->u16IEsLen;
6800
6801         pNewJoinBssParam = kmalloc(sizeof(tstrJoinBssParam), GFP_KERNEL);
6802         if (pNewJoinBssParam != NULL) {
6803                 memset(pNewJoinBssParam, 0, sizeof(tstrJoinBssParam));
6804                 pNewJoinBssParam->dtim_period = ptstrNetworkInfo->u8DtimPeriod;
6805                 pNewJoinBssParam->beacon_period = ptstrNetworkInfo->u16BeaconPeriod;
6806                 pNewJoinBssParam->cap_info = ptstrNetworkInfo->u16CapInfo;
6807                 memcpy(pNewJoinBssParam->au8bssid, ptstrNetworkInfo->au8bssid, 6);
6808                 /*for(i=0; i<6;i++)
6809                  *      PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->au8bssid[i]);*/
6810                 memcpy((u8 *)pNewJoinBssParam->ssid, ptstrNetworkInfo->au8ssid, ptstrNetworkInfo->u8SsidLen + 1);
6811                 pNewJoinBssParam->ssidLen = ptstrNetworkInfo->u8SsidLen;
6812                 memset(pNewJoinBssParam->rsn_pcip_policy, 0xFF, 3);
6813                 memset(pNewJoinBssParam->rsn_auth_policy, 0xFF, 3);
6814                 /*for(i=0; i<pNewJoinBssParam->ssidLen;i++)
6815                  *      PRINT_D(HOSTINF_DBG,"%c",pNewJoinBssParam->ssid[i]);*/
6816
6817                 /* parse supported rates: */
6818                 while (index < u16IEsLen) {
6819                         /* supportedRates IE */
6820                         if (pu8IEs[index] == SUPP_RATES_IE) {
6821                                 /* PRINT_D(HOSTINF_DBG, "Supported Rates\n"); */
6822                                 suppRatesNo = pu8IEs[index + 1];
6823                                 pNewJoinBssParam->supp_rates[0] = suppRatesNo;
6824                                 index += 2; /* skipping ID and length bytes; */
6825
6826                                 for (i = 0; i < suppRatesNo; i++) {
6827                                         pNewJoinBssParam->supp_rates[i + 1] = pu8IEs[index + i];
6828                                         /* PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[i+1]); */
6829                                 }
6830                                 index += suppRatesNo;
6831                                 continue;
6832                         }
6833                         /* Ext SupportedRates IE */
6834                         else if (pu8IEs[index] == EXT_SUPP_RATES_IE) {
6835                                 /* PRINT_D(HOSTINF_DBG, "Extended Supported Rates\n"); */
6836                                 /* checking if no of ext. supp and supp rates < max limit */
6837                                 extSuppRatesNo = pu8IEs[index + 1];
6838                                 if (extSuppRatesNo > (MAX_RATES_SUPPORTED - suppRatesNo))
6839                                         pNewJoinBssParam->supp_rates[0] = MAX_RATES_SUPPORTED;
6840                                 else
6841                                         pNewJoinBssParam->supp_rates[0] += extSuppRatesNo;
6842                                 index += 2;
6843                                 /* pNewJoinBssParam.supp_rates[0] contains now old number not the ext. no */
6844                                 for (i = 0; i < (pNewJoinBssParam->supp_rates[0] - suppRatesNo); i++) {
6845                                         pNewJoinBssParam->supp_rates[suppRatesNo + i + 1] = pu8IEs[index + i];
6846                                         /* PRINT_D(HOSTINF_DBG,"%0x ",pNewJoinBssParam->supp_rates[suppRatesNo+i+1]); */
6847                                 }
6848                                 index += extSuppRatesNo;
6849                                 continue;
6850                         }
6851                         /* HT Cap. IE */
6852                         else if (pu8IEs[index] == HT_CAPABILITY_IE) {
6853                                 /* if IE found set the flag */
6854                                 pNewJoinBssParam->ht_capable = true;
6855                                 index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */
6856                                 /* PRINT_D(HOSTINF_DBG,"HT_CAPABALE\n"); */
6857                                 continue;
6858                         } else if ((pu8IEs[index] == WMM_IE) && /* WMM Element ID */
6859                                    (pu8IEs[index + 2] == 0x00) && (pu8IEs[index + 3] == 0x50) &&
6860                                    (pu8IEs[index + 4] == 0xF2) && /* OUI */
6861                                    (pu8IEs[index + 5] == 0x02) && /* OUI Type     */
6862                                    ((pu8IEs[index + 6] == 0x00) || (pu8IEs[index + 6] == 0x01)) && /* OUI Sub Type */
6863                                    (pu8IEs[index + 7] == 0x01)) {
6864                                 /* Presence of WMM Info/Param element indicates WMM capability */
6865                                 pNewJoinBssParam->wmm_cap = true;
6866
6867                                 /* Check if Bit 7 is set indicating U-APSD capability */
6868                                 if (pu8IEs[index + 8] & BIT(7))
6869                                         pNewJoinBssParam->uapsd_cap = true;
6870                                 index += pu8IEs[index + 1] + 2;
6871                                 continue;
6872                         }
6873                         else if ((pu8IEs[index] == P2P_IE) && /* P2P Element ID */
6874                                  (pu8IEs[index + 2] == 0x50) && (pu8IEs[index + 3] == 0x6f) &&
6875                                  (pu8IEs[index + 4] == 0x9a) && /* OUI */
6876                                  (pu8IEs[index + 5] == 0x09) && (pu8IEs[index + 6] == 0x0c)) { /* OUI Type     */
6877                                 u16 u16P2P_count;
6878
6879                                 pNewJoinBssParam->tsf = ptstrNetworkInfo->u32Tsf;
6880                                 pNewJoinBssParam->u8NoaEnbaled = 1;
6881                                 pNewJoinBssParam->u8Index = pu8IEs[index + 9];
6882
6883                                 /* Check if Bit 7 is set indicating Opss capability */
6884                                 if (pu8IEs[index + 10] & BIT(7)) {
6885                                         pNewJoinBssParam->u8OppEnable = 1;
6886                                         pNewJoinBssParam->u8CtWindow = pu8IEs[index + 10];
6887                                 } else
6888                                         pNewJoinBssParam->u8OppEnable = 0;
6889                                 /* HOSTINF_DBG */
6890                                 PRINT_D(GENERIC_DBG, "P2P Dump\n");
6891                                 for (i = 0; i < pu8IEs[index + 7]; i++)
6892                                         PRINT_D(GENERIC_DBG, " %x\n", pu8IEs[index + 9 + i]);
6893
6894                                 pNewJoinBssParam->u8Count = pu8IEs[index + 11];
6895                                 u16P2P_count = index + 12;
6896
6897                                 memcpy(pNewJoinBssParam->au8Duration, pu8IEs + u16P2P_count, 4);
6898                                 u16P2P_count += 4;
6899
6900                                 memcpy(pNewJoinBssParam->au8Interval, pu8IEs + u16P2P_count, 4);
6901                                 u16P2P_count += 4;
6902
6903                                 memcpy(pNewJoinBssParam->au8StartTime, pu8IEs + u16P2P_count, 4);
6904
6905                                 index += pu8IEs[index + 1] + 2;
6906                                 continue;
6907
6908                         }
6909                         else if ((pu8IEs[index] == RSN_IE) ||
6910                                  ((pu8IEs[index] == WPA_IE) && (pu8IEs[index + 2] == 0x00) &&
6911                                   (pu8IEs[index + 3] == 0x50) && (pu8IEs[index + 4] == 0xF2) &&
6912                                   (pu8IEs[index + 5] == 0x01))) {
6913                                 u16 rsnIndex = index;
6914                                 /*PRINT_D(HOSTINF_DBG,"RSN IE Length:%d\n",pu8IEs[rsnIndex+1]);
6915                                  * for(i=0; i<pu8IEs[rsnIndex+1]; i++)
6916                                  * {
6917                                  *      PRINT_D(HOSTINF_DBG,"%0x ",pu8IEs[rsnIndex+2+i]);
6918                                  * }*/
6919                                 if (pu8IEs[rsnIndex] == RSN_IE) {
6920                                         pNewJoinBssParam->mode_802_11i = 2;
6921                                         /* PRINT_D(HOSTINF_DBG,"\nRSN_IE\n"); */
6922                                 } else { /* check if rsn was previously parsed */
6923                                         if (pNewJoinBssParam->mode_802_11i == 0)
6924                                                 pNewJoinBssParam->mode_802_11i = 1;
6925                                         /* PRINT_D(HOSTINF_DBG,"\nWPA_IE\n"); */
6926                                         rsnIndex += 4;
6927                                 }
6928                                 rsnIndex += 7; /* skipping id, length, version(2B) and first 3 bytes of gcipher */
6929                                 pNewJoinBssParam->rsn_grp_policy = pu8IEs[rsnIndex];
6930                                 rsnIndex++;
6931                                 /* PRINT_D(HOSTINF_DBG,"Group Policy: %0x\n",pNewJoinBssParam->rsn_grp_policy); */
6932                                 /* initialize policies with invalid values */
6933
6934                                 jumpOffset = pu8IEs[rsnIndex] * 4; /* total no.of bytes of pcipher field (count*4) */
6935
6936                                 /*parsing pairwise cipher*/
6937
6938                                 /* saving 3 pcipher max. */
6939                                 pcipherCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
6940                                 rsnIndex += 2; /* jump 2 bytes of pcipher count */
6941
6942                                 /* PRINT_D(HOSTINF_DBG,"\npcipher:%d\n",pcipherCount); */
6943                                 for (i = pcipherTotalCount, j = 0; i < pcipherCount + pcipherTotalCount && i < 3; i++, j++) {
6944                                         /* each count corresponds to 4 bytes, only last byte is saved */
6945                                         pNewJoinBssParam->rsn_pcip_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
6946                                         /* PRINT_D(HOSTINF_DBG,"PAIR policy = [%0x,%0x]\n",pNewJoinBssParam->rsn_pcip_policy[i],i); */
6947                                 }
6948                                 pcipherTotalCount += pcipherCount;
6949                                 rsnIndex += jumpOffset;
6950
6951                                 jumpOffset = pu8IEs[rsnIndex] * 4;
6952
6953                                 /*parsing AKM suite (auth_policy)*/
6954                                 /* saving 3 auth policies max. */
6955                                 authCount = (pu8IEs[rsnIndex] > 3) ? 3 : pu8IEs[rsnIndex];
6956                                 rsnIndex += 2; /* jump 2 bytes of pcipher count */
6957
6958                                 for (i = authTotalCount, j = 0; i < authTotalCount + authCount; i++, j++) {
6959                                         /* each count corresponds to 4 bytes, only last byte is saved */
6960                                         pNewJoinBssParam->rsn_auth_policy[i] = pu8IEs[rsnIndex + ((j + 1) * 4) - 1];
6961                                 }
6962                                 authTotalCount += authCount;
6963                                 rsnIndex += jumpOffset;
6964                                 /*pasring rsn cap. only if rsn IE*/
6965                                 if (pu8IEs[index] == RSN_IE) {
6966                                         pNewJoinBssParam->rsn_cap[0] = pu8IEs[rsnIndex];
6967                                         pNewJoinBssParam->rsn_cap[1] = pu8IEs[rsnIndex + 1];
6968                                         rsnIndex += 2;
6969                                 }
6970                                 pNewJoinBssParam->rsn_found = true;
6971                                 index += pu8IEs[index + 1] + 2; /* ID,Length bytes and IE body */
6972                                 continue;
6973                         } else
6974                                 index += pu8IEs[index + 1] + 2;  /* ID,Length bytes and IE body */
6975
6976                 }
6977
6978
6979         }
6980
6981         return (void *)pNewJoinBssParam;
6982
6983 }
6984
6985 void host_int_freeJoinParams(void *pJoinParams)
6986 {
6987         if ((tstrJoinBssParam *)pJoinParams != NULL)
6988                 kfree((tstrJoinBssParam *)pJoinParams);
6989         else
6990                 PRINT_ER("Unable to FREE null pointer\n");
6991 }
6992
6993 s32 host_int_delBASession(tstrWILC_WFIDrv *hWFIDrv, char *pBSSID, char TID)
6994 {
6995         s32 s32Error = 0;
6996         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
6997         struct host_if_msg msg;
6998         struct ba_session_info *pBASessionInfo = &msg.body.session_info;
6999
7000         if (pstrWFIDrv == NULL) {
7001                 PRINT_ER("driver is null\n");
7002                 return -EFAULT;
7003         }
7004
7005         memset(&msg, 0, sizeof(struct host_if_msg));
7006
7007         /* prepare the WiphyParams Message */
7008         msg.id = HOST_IF_MSG_DEL_BA_SESSION;
7009
7010         memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
7011         pBASessionInfo->u8Ted = TID;
7012         msg.drvHandler = hWFIDrv;
7013
7014         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
7015         if (s32Error)
7016                 PRINT_ER("wilc_mq_send fail\n");
7017
7018         down(&hWaitResponse);
7019
7020         return s32Error;
7021 }
7022
7023 s32 host_int_del_All_Rx_BASession(tstrWILC_WFIDrv *hWFIDrv, char *pBSSID, char TID)
7024 {
7025         s32 s32Error = 0;
7026         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
7027         struct host_if_msg msg;
7028         struct ba_session_info *pBASessionInfo = &msg.body.session_info;
7029
7030         if (pstrWFIDrv == NULL) {
7031                 PRINT_ER("driver is null\n");
7032                 return -EFAULT;
7033         }
7034
7035         memset(&msg, 0, sizeof(struct host_if_msg));
7036
7037         /* prepare the WiphyParams Message */
7038         msg.id = HOST_IF_MSG_DEL_ALL_RX_BA_SESSIONS;
7039
7040         memcpy(pBASessionInfo->au8Bssid, pBSSID, ETH_ALEN);
7041         pBASessionInfo->u8Ted = TID;
7042         msg.drvHandler = hWFIDrv;
7043
7044         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
7045         if (s32Error)
7046                 PRINT_ER("wilc_mq_send fail\n");
7047
7048         down(&hWaitResponse);
7049
7050         return s32Error;
7051 }
7052
7053 /**
7054  *  @brief              host_int_setup_ipaddress
7055  *  @details            setup IP in firmware
7056  *  @param[in]          Handle to wifi driver
7057  *  @return             Error code.
7058  *  @author             Abdelrahman Sobhy
7059  *  @date
7060  *  @version            1.0*/
7061 s32 host_int_setup_ipaddress(tstrWILC_WFIDrv *hWFIDrv, u8 *u16ipadd, u8 idx)
7062 {
7063         s32 s32Error = 0;
7064         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
7065         struct host_if_msg msg;
7066
7067         /* TODO: Enable This feature on softap firmware */
7068         return 0;
7069
7070         if (pstrWFIDrv == NULL) {
7071                 PRINT_ER("driver is null\n");
7072                 return -EFAULT;
7073         }
7074
7075         memset(&msg, 0, sizeof(struct host_if_msg));
7076
7077         /* prepare the WiphyParams Message */
7078         msg.id = HOST_IF_MSG_SET_IPADDRESS;
7079
7080         msg.body.ip_info.au8IPAddr = u16ipadd;
7081         msg.drvHandler = hWFIDrv;
7082         msg.body.ip_info.idx = idx;
7083
7084         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
7085         if (s32Error)
7086                 PRINT_ER("wilc_mq_send fail\n");
7087
7088         return s32Error;
7089
7090
7091 }
7092
7093 /**
7094  *  @brief              host_int_get_ipaddress
7095  *  @details            Get IP from firmware
7096  *  @param[in]          Handle to wifi driver
7097  *  @return             Error code.
7098  *  @author             Abdelrahman Sobhy
7099  *  @date
7100  *  @version            1.0*/
7101 s32 host_int_get_ipaddress(tstrWILC_WFIDrv *hWFIDrv, u8 *u16ipadd, u8 idx)
7102 {
7103         s32 s32Error = 0;
7104         tstrWILC_WFIDrv *pstrWFIDrv = (tstrWILC_WFIDrv *)hWFIDrv;
7105         struct host_if_msg msg;
7106
7107         if (pstrWFIDrv == NULL) {
7108                 PRINT_ER("driver is null\n");
7109                 return -EFAULT;
7110         }
7111
7112         memset(&msg, 0, sizeof(struct host_if_msg));
7113
7114         /* prepare the WiphyParams Message */
7115         msg.id = HOST_IF_MSG_GET_IPADDRESS;
7116
7117         msg.body.ip_info.au8IPAddr = u16ipadd;
7118         msg.drvHandler = hWFIDrv;
7119         msg.body.ip_info.idx = idx;
7120
7121         s32Error = wilc_mq_send(&gMsgQHostIF, &msg, sizeof(struct host_if_msg));
7122         if (s32Error)
7123                 PRINT_ER("wilc_mq_send fail\n");
7124
7125         return s32Error;
7126
7127
7128 }