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