staging: wilc1000: remove unnecessary define FIVE_GHZ_BAND
[firefly-linux-kernel-4.4.55.git] / drivers / staging / wilc1000 / coreconfigurator.c
1
2 /*!
3  *  @file       coreconfigurator.c
4  *  @brief
5  *  @author
6  *  @sa         coreconfigurator.h
7  *  @date       1 Mar 2012
8  *  @version    1.0
9  */
10
11
12 /*****************************************************************************/
13 /* File Includes                                                             */
14 /*****************************************************************************/
15 #include "coreconfigurator.h"
16 /*****************************************************************************/
17 /* Constants                                                                 */
18 /*****************************************************************************/
19 #define INLINE static __inline
20 #define MAX_CFG_PKTLEN     1450
21 #define MSG_HEADER_LEN     4
22 #define QUERY_MSG_TYPE     'Q'
23 #define WRITE_MSG_TYPE     'W'
24 #define RESP_MSG_TYPE      'R'
25 #define WRITE_RESP_SUCCESS 1
26 #define INVALID         255
27 #define MAC_ADDR_LEN    6
28 #define TAG_PARAM_OFFSET        (MAC_HDR_LEN + TIME_STAMP_LEN + \
29                                                         BEACON_INTERVAL_LEN + CAP_INFO_LEN)
30
31 /*****************************************************************************/
32 /* Function Macros                                                           */
33 /*****************************************************************************/
34
35
36 /*****************************************************************************/
37 /* Type Definitions                                                          */
38 /*****************************************************************************/
39
40 /* Basic Frame Type Codes (2-bit) */
41 typedef enum {
42         FRAME_TYPE_CONTROL     = 0x04,
43         FRAME_TYPE_DATA        = 0x08,
44         FRAME_TYPE_MANAGEMENT  = 0x00,
45         FRAME_TYPE_RESERVED    = 0x0C,
46         FRAME_TYPE_FORCE_32BIT = 0xFFFFFFFF
47 } tenuBasicFrmType;
48
49 /* Frame Type and Subtype Codes (6-bit) */
50 typedef enum {
51         ASSOC_REQ             = 0x00,
52         ASSOC_RSP             = 0x10,
53         REASSOC_REQ           = 0x20,
54         REASSOC_RSP           = 0x30,
55         PROBE_REQ             = 0x40,
56         PROBE_RSP             = 0x50,
57         BEACON                = 0x80,
58         ATIM                  = 0x90,
59         DISASOC               = 0xA0,
60         AUTH                  = 0xB0,
61         DEAUTH                = 0xC0,
62         ACTION                = 0xD0,
63         PS_POLL               = 0xA4,
64         RTS                   = 0xB4,
65         CTS                   = 0xC4,
66         ACK                   = 0xD4,
67         CFEND                 = 0xE4,
68         CFEND_ACK             = 0xF4,
69         DATA                  = 0x08,
70         DATA_ACK              = 0x18,
71         DATA_POLL             = 0x28,
72         DATA_POLL_ACK         = 0x38,
73         NULL_FRAME            = 0x48,
74         CFACK                 = 0x58,
75         CFPOLL                = 0x68,
76         CFPOLL_ACK            = 0x78,
77         QOS_DATA              = 0x88,
78         QOS_DATA_ACK          = 0x98,
79         QOS_DATA_POLL         = 0xA8,
80         QOS_DATA_POLL_ACK     = 0xB8,
81         QOS_NULL_FRAME        = 0xC8,
82         QOS_CFPOLL            = 0xE8,
83         QOS_CFPOLL_ACK        = 0xF8,
84         BLOCKACK_REQ          = 0x84,
85         BLOCKACK              = 0x94,
86         FRAME_SUBTYPE_FORCE_32BIT  = 0xFFFFFFFF
87 } tenuFrmSubtype;
88
89 /* Element ID  of various Information Elements */
90 typedef enum {
91         ISSID               = 0,   /* Service Set Identifier         */
92         ISUPRATES           = 1,   /* Supported Rates                */
93         IFHPARMS            = 2,   /* FH parameter set               */
94         IDSPARMS            = 3,   /* DS parameter set               */
95         ICFPARMS            = 4,   /* CF parameter set               */
96         ITIM                = 5,   /* Traffic Information Map        */
97         IIBPARMS            = 6,   /* IBSS parameter set             */
98         ICOUNTRY            = 7,   /* Country element                */
99         IEDCAPARAMS         = 12,  /* EDCA parameter set             */
100         ITSPEC              = 13,  /* Traffic Specification          */
101         ITCLAS              = 14,  /* Traffic Classification         */
102         ISCHED              = 15,  /* Schedule                       */
103         ICTEXT              = 16,  /* Challenge Text                 */
104         IPOWERCONSTRAINT    = 32,  /* Power Constraint               */
105         IPOWERCAPABILITY    = 33,  /* Power Capability               */
106         ITPCREQUEST         = 34,  /* TPC Request                    */
107         ITPCREPORT          = 35,  /* TPC Report                     */
108         ISUPCHANNEL         = 36,  /* Supported channel list         */
109         ICHSWANNOUNC        = 37,  /* Channel Switch Announcement    */
110         IMEASUREMENTREQUEST = 38,  /* Measurement request            */
111         IMEASUREMENTREPORT  = 39,  /* Measurement report             */
112         IQUIET              = 40,  /* Quiet element Info             */
113         IIBSSDFS            = 41,  /* IBSS DFS                       */
114         IERPINFO            = 42,  /* ERP Information                */
115         ITSDELAY            = 43,  /* TS Delay                       */
116         ITCLASPROCESS       = 44,  /* TCLAS Processing               */
117         IHTCAP              = 45,  /* HT Capabilities                */
118         IQOSCAP             = 46,  /* QoS Capability                 */
119         IRSNELEMENT         = 48,  /* RSN Information Element        */
120         IEXSUPRATES         = 50,  /* Extended Supported Rates       */
121         IEXCHSWANNOUNC      = 60,  /* Extended Ch Switch Announcement*/
122         IHTOPERATION        = 61,  /* HT Information                 */
123         ISECCHOFF           = 62,  /* Secondary Channel Offeset      */
124         I2040COEX           = 72,  /* 20/40 Coexistence IE           */
125         I2040INTOLCHREPORT  = 73,  /* 20/40 Intolerant channel report*/
126         IOBSSSCAN           = 74,  /* OBSS Scan parameters           */
127         IEXTCAP             = 127, /* Extended capability            */
128         IWMM                = 221, /* WMM parameters                 */
129         IWPAELEMENT         = 221, /* WPA Information Element        */
130         INFOELEM_ID_FORCE_32BIT  = 0xFFFFFFFF
131 } tenuInfoElemID;
132
133
134 typedef struct {
135         char *pcRespBuffer;
136         s32 s32MaxRespBuffLen;
137         s32 s32BytesRead;
138         bool bRespRequired;
139 } tstrConfigPktInfo;
140
141
142
143 /*****************************************************************************/
144 /* Extern Variable Declarations                                              */
145 /*****************************************************************************/
146
147
148 /*****************************************************************************/
149 /* Extern Function Declarations                                              */
150 /*****************************************************************************/
151 extern s32 SendRawPacket(s8 *ps8Packet, s32 s32PacketLen);
152 extern void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length);
153 extern void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length);
154 extern void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length);
155 /*****************************************************************************/
156 /* Global Variables                                                          */
157 /*****************************************************************************/
158 static struct semaphore SemHandleSendPkt;
159 static struct semaphore SemHandlePktResp;
160
161
162 static tstrConfigPktInfo gstrConfigPktInfo;
163
164 /* WID Switches */
165 static tstrWID gastrWIDs[] = {
166         {WID_FIRMWARE_VERSION,          WID_STR},
167         {WID_PHY_VERSION,               WID_STR},
168         {WID_HARDWARE_VERSION,          WID_STR},
169         {WID_BSS_TYPE,                  WID_CHAR},
170         {WID_QOS_ENABLE,                WID_CHAR},
171         {WID_11I_MODE,                  WID_CHAR},
172         {WID_CURRENT_TX_RATE,           WID_CHAR},
173         {WID_LINKSPEED,                 WID_CHAR},
174         {WID_RTS_THRESHOLD,             WID_SHORT},
175         {WID_FRAG_THRESHOLD,            WID_SHORT},
176         {WID_SSID,                      WID_STR},
177         {WID_BSSID,                     WID_ADR},
178         {WID_BEACON_INTERVAL,           WID_SHORT},
179         {WID_POWER_MANAGEMENT,          WID_CHAR},
180         {WID_LISTEN_INTERVAL,           WID_CHAR},
181         {WID_DTIM_PERIOD,               WID_CHAR},
182         {WID_CURRENT_CHANNEL,           WID_CHAR},
183         {WID_TX_POWER_LEVEL_11A,        WID_CHAR},
184         {WID_TX_POWER_LEVEL_11B,        WID_CHAR},
185         {WID_PREAMBLE,                  WID_CHAR},
186         {WID_11G_OPERATING_MODE,        WID_CHAR},
187         {WID_MAC_ADDR,                  WID_ADR},
188         {WID_IP_ADDRESS,                WID_ADR},
189         {WID_ACK_POLICY,                WID_CHAR},
190         {WID_PHY_ACTIVE_REG,            WID_CHAR},
191         {WID_AUTH_TYPE,                 WID_CHAR},
192         {WID_REKEY_POLICY,              WID_CHAR},
193         {WID_REKEY_PERIOD,              WID_INT},
194         {WID_REKEY_PACKET_COUNT,        WID_INT},
195         {WID_11I_PSK,                   WID_STR},
196         {WID_1X_KEY,                    WID_STR},
197         {WID_1X_SERV_ADDR,              WID_IP},
198         {WID_SUPP_USERNAME,             WID_STR},
199         {WID_SUPP_PASSWORD,             WID_STR},
200         {WID_USER_CONTROL_ON_TX_POWER,  WID_CHAR},
201         {WID_MEMORY_ADDRESS,            WID_INT},
202         {WID_MEMORY_ACCESS_32BIT,       WID_INT},
203         {WID_MEMORY_ACCESS_16BIT,       WID_SHORT},
204         {WID_MEMORY_ACCESS_8BIT,        WID_CHAR},
205         {WID_SITE_SURVEY_RESULTS,       WID_STR},
206         {WID_PMKID_INFO,                WID_STR},
207         {WID_ASSOC_RES_INFO,            WID_STR},
208         {WID_MANUFACTURER,              WID_STR}, /* 4 Wids added for the CAPI tool*/
209         {WID_MODEL_NAME,                WID_STR},
210         {WID_MODEL_NUM,                 WID_STR},
211         {WID_DEVICE_NAME,               WID_STR},
212         {WID_SSID_PROBE_REQ,            WID_STR},
213
214 #ifdef MAC_802_11N
215         {WID_11N_ENABLE,                WID_CHAR},
216         {WID_11N_CURRENT_TX_MCS,        WID_CHAR},
217         {WID_TX_POWER_LEVEL_11N,        WID_CHAR},
218         {WID_11N_OPERATING_MODE,        WID_CHAR},
219         {WID_11N_SMPS_MODE,             WID_CHAR},
220         {WID_11N_PROT_MECH,             WID_CHAR},
221         {WID_11N_ERP_PROT_TYPE,         WID_CHAR},
222         {WID_11N_HT_PROT_TYPE,          WID_CHAR},
223         {WID_11N_PHY_ACTIVE_REG_VAL,    WID_INT},
224         {WID_11N_PRINT_STATS,           WID_CHAR},
225         {WID_11N_AUTORATE_TABLE,        WID_BIN_DATA},
226         {WID_HOST_CONFIG_IF_TYPE,       WID_CHAR},
227         {WID_HOST_DATA_IF_TYPE,         WID_CHAR},
228         {WID_11N_SIG_QUAL_VAL,          WID_SHORT},
229         {WID_11N_IMMEDIATE_BA_ENABLED,  WID_CHAR},
230         {WID_11N_TXOP_PROT_DISABLE,     WID_CHAR},
231         {WID_11N_SHORT_GI_20MHZ_ENABLE, WID_CHAR},
232         {WID_SHORT_SLOT_ALLOWED,        WID_CHAR},
233         {WID_11W_ENABLE,                WID_CHAR},
234         {WID_11W_MGMT_PROT_REQ,         WID_CHAR},
235         {WID_2040_ENABLE,               WID_CHAR},
236         {WID_2040_COEXISTENCE,          WID_CHAR},
237         {WID_USER_SEC_CHANNEL_OFFSET,   WID_CHAR},
238         {WID_2040_CURR_CHANNEL_OFFSET,  WID_CHAR},
239         {WID_2040_40MHZ_INTOLERANT,     WID_CHAR},
240         {WID_HUT_RESTART,               WID_CHAR},
241         {WID_HUT_NUM_TX_PKTS,           WID_INT},
242         {WID_HUT_FRAME_LEN,             WID_SHORT},
243         {WID_HUT_TX_FORMAT,             WID_CHAR},
244         {WID_HUT_BANDWIDTH,             WID_CHAR},
245         {WID_HUT_OP_BAND,               WID_CHAR},
246         {WID_HUT_STBC,                  WID_CHAR},
247         {WID_HUT_ESS,                   WID_CHAR},
248         {WID_HUT_ANTSET,                WID_CHAR},
249         {WID_HUT_HT_OP_MODE,            WID_CHAR},
250         {WID_HUT_RIFS_MODE,             WID_CHAR},
251         {WID_HUT_SMOOTHING_REC,         WID_CHAR},
252         {WID_HUT_SOUNDING_PKT,          WID_CHAR},
253         {WID_HUT_HT_CODING,             WID_CHAR},
254         {WID_HUT_TEST_DIR,              WID_CHAR},
255         {WID_HUT_TXOP_LIMIT,            WID_SHORT},
256         {WID_HUT_DEST_ADDR,             WID_ADR},
257         {WID_HUT_TX_PATTERN,            WID_BIN_DATA},
258         {WID_HUT_TX_TIME_TAKEN,         WID_INT},
259         {WID_HUT_PHY_TEST_MODE,         WID_CHAR},
260         {WID_HUT_PHY_TEST_RATE_HI,      WID_CHAR},
261         {WID_HUT_PHY_TEST_RATE_LO,      WID_CHAR},
262         {WID_HUT_TX_TEST_TIME,          WID_INT},
263         {WID_HUT_LOG_INTERVAL,          WID_INT},
264         {WID_HUT_DISABLE_RXQ_REPLENISH, WID_CHAR},
265         {WID_HUT_TEST_ID,               WID_STR},
266         {WID_HUT_KEY_ORIGIN,            WID_CHAR},
267         {WID_HUT_BCST_PERCENT,          WID_CHAR},
268         {WID_HUT_GROUP_CIPHER_TYPE,     WID_CHAR},
269         {WID_HUT_STATS,                 WID_BIN_DATA},
270         {WID_HUT_TSF_TEST_MODE,         WID_CHAR},
271         {WID_HUT_SIG_QUAL_AVG,          WID_SHORT},
272         {WID_HUT_SIG_QUAL_AVG_CNT,      WID_SHORT},
273         {WID_HUT_TSSI_VALUE,            WID_CHAR},
274         {WID_HUT_MGMT_PERCENT,          WID_CHAR},
275         {WID_HUT_MGMT_BCST_PERCENT,     WID_CHAR},
276         {WID_HUT_MGMT_ALLOW_HT,         WID_CHAR},
277         {WID_HUT_UC_MGMT_TYPE,          WID_CHAR},
278         {WID_HUT_BC_MGMT_TYPE,          WID_CHAR},
279         {WID_HUT_UC_MGMT_FRAME_LEN,     WID_SHORT},
280         {WID_HUT_BC_MGMT_FRAME_LEN,     WID_SHORT},
281         {WID_HUT_11W_MFP_REQUIRED_TX,   WID_CHAR},
282         {WID_HUT_11W_MFP_PEER_CAPABLE,  WID_CHAR},
283         {WID_HUT_11W_TX_IGTK_ID,        WID_CHAR},
284         {WID_HUT_FC_TXOP_MOD,           WID_CHAR},
285         {WID_HUT_FC_PROT_TYPE,          WID_CHAR},
286         {WID_HUT_SEC_CCA_ASSERT,        WID_CHAR},
287 #endif /* MAC_802_11N */
288 };
289
290 u16 g_num_total_switches = (sizeof(gastrWIDs) / sizeof(tstrWID));
291 /*****************************************************************************/
292 /* Static Function Declarations                                              */
293 /*****************************************************************************/
294
295
296
297 /*****************************************************************************/
298 /* Functions                                                                 */
299 /*****************************************************************************/
300
301 /* This function extracts the beacon period field from the beacon or probe   */
302 /* response frame.                                                           */
303 INLINE u16 get_beacon_period(u8 *data)
304 {
305         u16 bcn_per = 0;
306
307         bcn_per  = data[0];
308         bcn_per |= (data[1] << 8);
309
310         return bcn_per;
311 }
312
313 INLINE u32 get_beacon_timestamp_lo(u8 *data)
314 {
315         u32 time_stamp = 0;
316         u32 index    = MAC_HDR_LEN;
317
318         time_stamp |= data[index++];
319         time_stamp |= (data[index++] << 8);
320         time_stamp |= (data[index++] << 16);
321         time_stamp |= (data[index]   << 24);
322
323         return time_stamp;
324 }
325
326 INLINE u32 get_beacon_timestamp_hi(u8 *data)
327 {
328         u32 time_stamp = 0;
329         u32 index    = (MAC_HDR_LEN + 4);
330
331         time_stamp |= data[index++];
332         time_stamp |= (data[index++] << 8);
333         time_stamp |= (data[index++] << 16);
334         time_stamp |= (data[index]   << 24);
335
336         return time_stamp;
337 }
338
339 /* This function extracts the 'frame type and sub type' bits from the MAC    */
340 /* header of the input frame.                                                */
341 /* Returns the value in the LSB of the returned value.                       */
342 INLINE tenuFrmSubtype get_sub_type(u8 *header)
343 {
344         return ((tenuFrmSubtype)(header[0] & 0xFC));
345 }
346
347 /* This function extracts the 'to ds' bit from the MAC header of the input   */
348 /* frame.                                                                    */
349 /* Returns the value in the LSB of the returned value.                       */
350 INLINE u8 get_to_ds(u8 *header)
351 {
352         return (header[1] & 0x01);
353 }
354
355 /* This function extracts the 'from ds' bit from the MAC header of the input */
356 /* frame.                                                                    */
357 /* Returns the value in the LSB of the returned value.                       */
358 INLINE u8 get_from_ds(u8 *header)
359 {
360         return ((header[1] & 0x02) >> 1);
361 }
362
363 /* This function extracts the MAC Address in 'address1' field of the MAC     */
364 /* header and updates the MAC Address in the allocated 'addr' variable.      */
365 INLINE void get_address1(u8 *pu8msa, u8 *addr)
366 {
367         memcpy(addr, pu8msa + 4, 6);
368 }
369
370 /* This function extracts the MAC Address in 'address2' field of the MAC     */
371 /* header and updates the MAC Address in the allocated 'addr' variable.      */
372 INLINE void get_address2(u8 *pu8msa, u8 *addr)
373 {
374         memcpy(addr, pu8msa + 10, 6);
375 }
376
377 /* This function extracts the MAC Address in 'address3' field of the MAC     */
378 /* header and updates the MAC Address in the allocated 'addr' variable.      */
379 INLINE void get_address3(u8 *pu8msa, u8 *addr)
380 {
381         memcpy(addr, pu8msa + 16, 6);
382 }
383
384 /* This function extracts the BSSID from the incoming WLAN packet based on   */
385 /* the 'from ds' bit, and updates the MAC Address in the allocated 'addr'    */
386 /* variable.                                                                 */
387 INLINE void get_BSSID(u8 *data, u8 *bssid)
388 {
389         if (get_from_ds(data) == 1)
390                 get_address2(data, bssid);
391         else if (get_to_ds(data) == 1)
392                 get_address1(data, bssid);
393         else
394                 get_address3(data, bssid);
395 }
396
397 /* This function extracts the SSID from a beacon/probe response frame        */
398 INLINE void get_ssid(u8 *data, u8 *ssid, u8 *p_ssid_len)
399 {
400         u8 len = 0;
401         u8 i   = 0;
402         u8 j   = 0;
403
404         len = data[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN +
405                    CAP_INFO_LEN + 1];
406         j   = MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN +
407                 CAP_INFO_LEN + 2;
408
409         /* If the SSID length field is set wrongly to a value greater than the   */
410         /* allowed maximum SSID length limit, reset the length to 0              */
411         if (len >= MAX_SSID_LEN)
412                 len = 0;
413
414         for (i = 0; i < len; i++, j++)
415                 ssid[i] = data[j];
416
417         ssid[len] = '\0';
418
419         *p_ssid_len = len;
420 }
421
422 /* This function extracts the capability info field from the beacon or probe */
423 /* response frame.                                                           */
424 INLINE u16 get_cap_info(u8 *data)
425 {
426         u16 cap_info = 0;
427         u16 index    = MAC_HDR_LEN;
428         tenuFrmSubtype st;
429
430         st = get_sub_type(data);
431
432         /* Location of the Capability field is different for Beacon and */
433         /* Association frames.                                          */
434         if ((st == BEACON) || (st == PROBE_RSP))
435                 index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN;
436
437         cap_info  = data[index];
438         cap_info |= (data[index + 1] << 8);
439
440         return cap_info;
441 }
442
443 /* This function extracts the capability info field from the Association */
444 /* response frame.                                                                       */
445 INLINE u16 get_assoc_resp_cap_info(u8 *data)
446 {
447         u16 cap_info = 0;
448
449         cap_info  = data[0];
450         cap_info |= (data[1] << 8);
451
452         return cap_info;
453 }
454
455 /* This funcion extracts the association status code from the incoming       */
456 /* association response frame and returns association status code            */
457 INLINE u16 get_asoc_status(u8 *data)
458 {
459         u16 asoc_status = 0;
460
461         asoc_status = data[3];
462         asoc_status = (asoc_status << 8) | data[2];
463
464         return asoc_status;
465 }
466
467 /* This function extracts association ID from the incoming association       */
468 /* response frame                                                                                            */
469 INLINE u16 get_asoc_id(u8 *data)
470 {
471         u16 asoc_id = 0;
472
473         asoc_id  = data[4];
474         asoc_id |= (data[5] << 8);
475
476         return asoc_id;
477 }
478
479 /**
480  *  @brief              initializes the Core Configurator
481  *  @details
482  *  @return     Error code indicating success/failure
483  *  @note
484  *  @author     mabubakr
485  *  @date               1 Mar 2012
486  *  @version            1.0
487  */
488
489 s32 CoreConfiguratorInit(void)
490 {
491         s32 s32Error = WILC_SUCCESS;
492
493         PRINT_D(CORECONFIG_DBG, "CoreConfiguratorInit()\n");
494
495         sema_init(&SemHandleSendPkt, 1);
496         sema_init(&SemHandlePktResp, 0);
497
498
499         memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
500         return s32Error;
501 }
502
503 u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset)
504 {
505         u16 u16index = 0;
506
507         /*************************************************************************/
508         /*                       Beacon Frame - Frame Body                       */
509         /* --------------------------------------------------------------------- */
510         /* |Timestamp |BeaconInt |CapInfo |SSID |SupRates |DSParSet |TIM elm   | */
511         /* --------------------------------------------------------------------- */
512         /* |8         |2         |2       |2-34 |3-10     |3        |4-256     | */
513         /* --------------------------------------------------------------------- */
514         /*                                                                       */
515         /*************************************************************************/
516
517         u16index = u16TagParamOffset;
518
519         /* Search for the TIM Element Field and return if the element is found */
520         while (u16index < (u16RxLen - FCS_LEN)) {
521                 if (pu8msa[u16index] == ITIM)
522                         return &pu8msa[u16index];
523                 else
524                         u16index += (IE_HDR_LEN + pu8msa[u16index + 1]);
525         }
526
527         return NULL;
528 }
529
530 /* This function gets the current channel information from
531  * the 802.11n beacon/probe response frame */
532 u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen)
533 {
534         u16 index;
535
536         index = TAG_PARAM_OFFSET;
537         while (index < (u16RxLen - FCS_LEN)) {
538                 if (pu8msa[index] == IDSPARMS)
539                         return pu8msa[index + 2];
540                 else
541                         /* Increment index by length information and header */
542                         index += pu8msa[index + 1] + IE_HDR_LEN;
543         }
544
545         /* Return current channel information from the MIB, if beacon/probe  */
546         /* response frame does not contain the DS parameter set IE           */
547         /* return (mget_CurrentChannel() + 1); */
548         return 0;  /* no MIB here */
549 }
550
551 u8 get_current_channel(u8 *pu8msa, u16 u16RxLen)
552 {
553         /* Extract current channel information from */
554         /* the beacon/probe response frame          */
555         return get_current_channel_802_11n(pu8msa, u16RxLen);
556 }
557
558 /**
559  *  @brief                      parses the received 'N' message
560  *  @details
561  *  @param[in]  pu8MsgBuffer The message to be parsed
562  *  @param[out]         ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info
563  *  @return             Error code indicating success/failure
564  *  @note
565  *  @author             mabubakr
566  *  @date                       1 Mar 2012
567  *  @version            1.0
568  */
569 s32 ParseNetworkInfo(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo)
570 {
571         s32 s32Error = WILC_SUCCESS;
572         tstrNetworkInfo *pstrNetworkInfo = NULL;
573         u8 u8MsgType = 0;
574         u8 u8MsgID = 0;
575         u16 u16MsgLen = 0;
576
577         u16 u16WidID = (u16)WID_NIL;
578         u16 u16WidLen  = 0;
579         u8  *pu8WidVal = NULL;
580
581         u8MsgType = pu8MsgBuffer[0];
582
583         /* Check whether the received message type is 'N' */
584         if ('N' != u8MsgType) {
585                 PRINT_ER("Received Message format incorrect.\n");
586                 WILC_ERRORREPORT(s32Error, WILC_FAIL);
587         }
588
589         /* Extract message ID */
590         u8MsgID = pu8MsgBuffer[1];
591
592         /* Extract message Length */
593         u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]);
594
595         /* Extract WID ID */
596         u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]);
597
598         /* Extract WID Length */
599         u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]);
600
601         /* Assign a pointer to the WID value */
602         pu8WidVal  = &pu8MsgBuffer[8];
603
604         /* parse the WID value of the WID "WID_NEWORK_INFO" */
605         {
606                 u8  *pu8msa = NULL;
607                 u16 u16RxLen = 0;
608                 u8 *pu8TimElm = NULL;
609                 u8 *pu8IEs = NULL;
610                 u16 u16IEsLen = 0;
611                 u8 u8index = 0;
612                 u32 u32Tsf_Lo;
613                 u32 u32Tsf_Hi;
614
615                 pstrNetworkInfo = kmalloc(sizeof(tstrNetworkInfo), GFP_KERNEL);
616                 if (!pstrNetworkInfo)
617                         return -ENOMEM;
618
619                 memset((void *)(pstrNetworkInfo), 0, sizeof(tstrNetworkInfo));
620
621                 pstrNetworkInfo->s8rssi = pu8WidVal[0];
622
623                 /* Assign a pointer to msa "Mac Header Start Address" */
624                 pu8msa = &pu8WidVal[1];
625
626                 u16RxLen = u16WidLen - 1;
627
628                 /* parse msa*/
629
630                 /* Get the cap_info */
631                 pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa);
632                 #ifdef WILC_P2P
633                 /* Get time-stamp [Low only 32 bit] */
634                 pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa);
635                 PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf);
636                 #endif
637
638                 /* Get full time-stamp [Low and High 64 bit] */
639                 u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa);
640                 u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa);
641
642                 pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((u64)u32Tsf_Hi << 32);
643
644                 /* Get SSID */
645                 get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &(pstrNetworkInfo->u8SsidLen));
646
647                 /* Get BSSID */
648                 get_BSSID(pu8msa, pstrNetworkInfo->au8bssid);
649
650                 /* Get the current channel */
651                 pstrNetworkInfo->u8channel = get_current_channel(pu8msa, (u16RxLen + FCS_LEN));
652
653                 /* Get beacon period */
654                 u8index = (MAC_HDR_LEN + TIME_STAMP_LEN);
655
656                 pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index);
657
658                 u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN;
659
660                 /* Get DTIM Period */
661                 pu8TimElm = get_tim_elm(pu8msa, (u16RxLen + FCS_LEN), u8index);
662                 if (pu8TimElm != NULL)
663                         pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3];
664                 pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN];
665                 u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN);
666
667                 if (u16IEsLen > 0) {
668                         pstrNetworkInfo->pu8IEs = kmalloc(u16IEsLen, GFP_KERNEL);
669                         if (!pstrNetworkInfo->pu8IEs)
670                                 return -ENOMEM;
671
672                         memset((void *)(pstrNetworkInfo->pu8IEs), 0, u16IEsLen);
673
674                         memcpy(pstrNetworkInfo->pu8IEs, pu8IEs, u16IEsLen);
675                 }
676                 pstrNetworkInfo->u16IEsLen = u16IEsLen;
677
678         }
679
680         *ppstrNetworkInfo = pstrNetworkInfo;
681
682 ERRORHANDLER:
683         return s32Error;
684 }
685
686 /**
687  *  @brief              Deallocates the parsed Network Info
688  *  @details
689  *  @param[in]  pstrNetworkInfo Network Info to be deallocated
690  *  @return             Error code indicating success/failure
691  *  @note
692  *  @author             mabubakr
693  *  @date               1 Mar 2012
694  *  @version            1.0
695  */
696 s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo)
697 {
698         s32 s32Error = WILC_SUCCESS;
699
700         if (pstrNetworkInfo != NULL) {
701                 if (pstrNetworkInfo->pu8IEs != NULL) {
702                         kfree(pstrNetworkInfo->pu8IEs);
703                         pstrNetworkInfo->pu8IEs = NULL;
704                 } else {
705                         s32Error = WILC_FAIL;
706                 }
707
708                 kfree(pstrNetworkInfo);
709                 pstrNetworkInfo = NULL;
710
711         } else {
712                 s32Error = WILC_FAIL;
713         }
714
715         return s32Error;
716 }
717
718 /**
719  *  @brief                      parses the received Association Response frame
720  *  @details
721  *  @param[in]  pu8Buffer The Association Response frame to be parsed
722  *  @param[out]         ppstrConnectRespInfo pointer to pointer to the structure containing the parsed Association Response Info
723  *  @return             Error code indicating success/failure
724  *  @note
725  *  @author             mabubakr
726  *  @date                       2 Apr 2012
727  *  @version            1.0
728  */
729 s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen,
730                                tstrConnectRespInfo **ppstrConnectRespInfo)
731 {
732         s32 s32Error = WILC_SUCCESS;
733         tstrConnectRespInfo *pstrConnectRespInfo = NULL;
734         u16 u16AssocRespLen = 0;
735         u8 *pu8IEs = NULL;
736         u16 u16IEsLen = 0;
737
738         pstrConnectRespInfo = kmalloc(sizeof(tstrConnectRespInfo), GFP_KERNEL);
739         if (!pstrConnectRespInfo)
740                 return -ENOMEM;
741
742         memset((void *)(pstrConnectRespInfo), 0, sizeof(tstrConnectRespInfo));
743
744         /* u16AssocRespLen = pu8Buffer[0]; */
745         u16AssocRespLen = (u16)u32BufferLen;
746
747         /* get the status code */
748         pstrConnectRespInfo->u16ConnectStatus = get_asoc_status(pu8Buffer);
749         if (pstrConnectRespInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE) {
750
751                 /* get the capability */
752                 pstrConnectRespInfo->u16capability = get_assoc_resp_cap_info(pu8Buffer);
753
754                 /* get the Association ID */
755                 pstrConnectRespInfo->u16AssocID = get_asoc_id(pu8Buffer);
756
757                 /* get the Information Elements */
758                 pu8IEs = &pu8Buffer[CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN];
759                 u16IEsLen = u16AssocRespLen - (CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN);
760
761                 pstrConnectRespInfo->pu8RespIEs = kmalloc(u16IEsLen, GFP_KERNEL);
762                 if (!pstrConnectRespInfo->pu8RespIEs)
763                         return -ENOMEM;
764
765                 memset((void *)(pstrConnectRespInfo->pu8RespIEs), 0, u16IEsLen);
766
767                 memcpy(pstrConnectRespInfo->pu8RespIEs, pu8IEs, u16IEsLen);
768                 pstrConnectRespInfo->u16RespIEsLen = u16IEsLen;
769         }
770
771         *ppstrConnectRespInfo = pstrConnectRespInfo;
772
773
774         return s32Error;
775 }
776
777 /**
778  *  @brief                      Deallocates the parsed Association Response Info
779  *  @details
780  *  @param[in]  pstrNetworkInfo Network Info to be deallocated
781  *  @return             Error code indicating success/failure
782  *  @note
783  *  @author             mabubakr
784  *  @date                       2 Apr 2012
785  *  @version            1.0
786  */
787 s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo)
788 {
789         s32 s32Error = WILC_SUCCESS;
790
791         if (pstrConnectRespInfo != NULL) {
792                 if (pstrConnectRespInfo->pu8RespIEs != NULL) {
793                         kfree(pstrConnectRespInfo->pu8RespIEs);
794                         pstrConnectRespInfo->pu8RespIEs = NULL;
795                 } else {
796                         s32Error = WILC_FAIL;
797                 }
798
799                 kfree(pstrConnectRespInfo);
800                 pstrConnectRespInfo = NULL;
801
802         } else {
803                 s32Error = WILC_FAIL;
804         }
805
806         return s32Error;
807 }
808
809 #ifndef CONNECT_DIRECT
810 s32 ParseSurveyResults(u8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE],
811                                wid_site_survey_reslts_s **ppstrSurveyResults,
812                                u32 *pu32SurveyResultsCount)
813 {
814         s32 s32Error = WILC_SUCCESS;
815         wid_site_survey_reslts_s *pstrSurveyResults = NULL;
816         u32 u32SurveyResultsCount = 0;
817         u32 u32SurveyBytesLength = 0;
818         u8 *pu8BufferPtr;
819         u32 u32RcvdSurveyResultsNum = 2;
820         u8 u8ReadSurveyResFragNum;
821         u32 i;
822         u32 j;
823
824         for (i = 0; i < u32RcvdSurveyResultsNum; i++) {
825                 u32SurveyBytesLength = ppu8RcvdSiteSurveyResults[i][0];
826
827
828                 for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) {
829                         u32SurveyResultsCount++;
830                 }
831         }
832
833         pstrSurveyResults = kmalloc_array(u32SurveyResultsCount,
834                                 sizeof(wid_site_survey_reslts_s), GFP_KERNEL);
835         if (!pstrSurveyResults)
836                 return -ENOMEM;
837
838         memset((void *)(pstrSurveyResults), 0, u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s));
839
840         u32SurveyResultsCount = 0;
841
842         for (i = 0; i < u32RcvdSurveyResultsNum; i++) {
843                 pu8BufferPtr = ppu8RcvdSiteSurveyResults[i];
844
845                 u32SurveyBytesLength = pu8BufferPtr[0];
846
847                 /* TODO: mostafa: pu8BufferPtr[1] contains the fragment num */
848                 u8ReadSurveyResFragNum = pu8BufferPtr[1];
849
850                 pu8BufferPtr += 2;
851
852                 for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) {
853                         memcpy(&pstrSurveyResults[u32SurveyResultsCount], pu8BufferPtr, SURVEY_RESULT_LENGTH);
854                         pu8BufferPtr += SURVEY_RESULT_LENGTH;
855                         u32SurveyResultsCount++;
856                 }
857         }
858
859 ERRORHANDLER:
860         *ppstrSurveyResults = pstrSurveyResults;
861         *pu32SurveyResultsCount = u32SurveyResultsCount;
862
863         return s32Error;
864 }
865
866
867 s32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults)
868 {
869         s32 s32Error = WILC_SUCCESS;
870
871         if (pstrSurveyResults != NULL) {
872                 kfree(pstrSurveyResults);
873         }
874
875         return s32Error;
876 }
877 #endif
878
879 /**
880  *  @brief              Deinitializes the Core Configurator
881  *  @details
882  *  @return     Error code indicating success/failure
883  *  @note
884  *  @author     mabubakr
885  *  @date               1 Mar 2012
886  *  @version    1.0
887  */
888
889 s32 CoreConfiguratorDeInit(void)
890 {
891         s32 s32Error = WILC_SUCCESS;
892
893         PRINT_D(CORECONFIG_DBG, "CoreConfiguratorDeInit()\n");
894
895
896         return s32Error;
897 }
898
899 /*Using the global handle of the driver*/
900 extern wilc_wlan_oup_t *gpstrWlanOps;
901 /**
902  *  @brief              sends certain Configuration Packet based on the input WIDs pstrWIDs
903  *  using driver config layer
904  *
905  *  @details
906  *  @param[in]  pstrWIDs WIDs to be sent in the configuration packet
907  *  @param[in]  u32WIDsCount number of WIDs to be sent in the configuration packet
908  *  @param[out]         pu8RxResp The received Packet Response
909  *  @param[out]         ps32RxRespLen Length of the received Packet Response
910  *  @return     Error code indicating success/failure
911  *  @note
912  *  @author     mabubakr
913  *  @date               1 Mar 2012
914  *  @version    1.0
915  */
916 s32 SendConfigPkt(u8 u8Mode, tstrWID *pstrWIDs,
917                           u32 u32WIDsCount, bool bRespRequired, u32 drvHandler)
918 {
919         s32 counter = 0, ret = 0;
920
921         if (gpstrWlanOps == NULL) {
922                 PRINT_D(CORECONFIG_DBG, "Net Dev is still not initialized\n");
923                 return 1;
924         } else {
925                 PRINT_D(CORECONFIG_DBG, "Net Dev is initialized\n");
926         }
927         if (gpstrWlanOps->wlan_cfg_set == NULL ||
928             gpstrWlanOps->wlan_cfg_get == NULL) {
929                 PRINT_D(CORECONFIG_DBG, "Set and Get is still not initialized\n");
930                 return 1;
931         } else {
932                 PRINT_D(CORECONFIG_DBG, "SET is initialized\n");
933         }
934         if (u8Mode == GET_CFG) {
935                 for (counter = 0; counter < u32WIDsCount; counter++) {
936                         PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter,
937                                    (counter == u32WIDsCount - 1));
938                         if (!gpstrWlanOps->wlan_cfg_get(!counter,
939                                                         pstrWIDs[counter].u16WIDid,
940                                                         (counter == u32WIDsCount - 1), drvHandler)) {
941                                 ret = -1;
942                                 printk("[Sendconfigpkt]Get Timed out\n");
943                                 break;
944                         }
945                 }
946                 /**
947                  *      get the value
948                  **/
949                 counter = 0;
950                 for (counter = 0; counter < u32WIDsCount; counter++) {
951                         pstrWIDs[counter].s32ValueSize = gpstrWlanOps->wlan_cfg_get_value(
952                                         pstrWIDs[counter].u16WIDid,
953                                         pstrWIDs[counter].ps8WidVal, pstrWIDs[counter].s32ValueSize);
954
955                 }
956         } else if (u8Mode == SET_CFG) {
957                 for (counter = 0; counter < u32WIDsCount; counter++) {
958                         PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", pstrWIDs[counter].u16WIDid);
959                         if (!gpstrWlanOps->wlan_cfg_set(!counter,
960                                                         pstrWIDs[counter].u16WIDid, pstrWIDs[counter].ps8WidVal,
961                                                         pstrWIDs[counter].s32ValueSize,
962                                                         (counter == u32WIDsCount - 1), drvHandler)) {
963                                 ret = -1;
964                                 printk("[Sendconfigpkt]Set Timed out\n");
965                                 break;
966                         }
967                 }
968         }
969
970         return ret;
971 }