tty: Remove tty_wait_until_sent_from_close()
[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 PHY_802_11n
21 #define MAX_CFG_PKTLEN     1450
22 #define MSG_HEADER_LEN     4
23 #define QUERY_MSG_TYPE     'Q'
24 #define WRITE_MSG_TYPE     'W'
25 #define RESP_MSG_TYPE      'R'
26 #define WRITE_RESP_SUCCESS 1
27 #define INVALID         255
28 #define MAC_ADDR_LEN    6
29 #define TAG_PARAM_OFFSET        (MAC_HDR_LEN + TIME_STAMP_LEN + \
30                                                         BEACON_INTERVAL_LEN + CAP_INFO_LEN)
31
32 /*****************************************************************************/
33 /* Function Macros                                                           */
34 /*****************************************************************************/
35
36
37 /*****************************************************************************/
38 /* Type Definitions                                                          */
39 /*****************************************************************************/
40
41 /* Basic Frame Type Codes (2-bit) */
42 typedef enum {
43         FRAME_TYPE_CONTROL     = 0x04,
44         FRAME_TYPE_DATA        = 0x08,
45         FRAME_TYPE_MANAGEMENT  = 0x00,
46         FRAME_TYPE_RESERVED    = 0x0C,
47         FRAME_TYPE_FORCE_32BIT = 0xFFFFFFFF
48 } tenuBasicFrmType;
49
50 /* Frame Type and Subtype Codes (6-bit) */
51 typedef enum {
52         ASSOC_REQ             = 0x00,
53         ASSOC_RSP             = 0x10,
54         REASSOC_REQ           = 0x20,
55         REASSOC_RSP           = 0x30,
56         PROBE_REQ             = 0x40,
57         PROBE_RSP             = 0x50,
58         BEACON                = 0x80,
59         ATIM                  = 0x90,
60         DISASOC               = 0xA0,
61         AUTH                  = 0xB0,
62         DEAUTH                = 0xC0,
63         ACTION                = 0xD0,
64         PS_POLL               = 0xA4,
65         RTS                   = 0xB4,
66         CTS                   = 0xC4,
67         ACK                   = 0xD4,
68         CFEND                 = 0xE4,
69         CFEND_ACK             = 0xF4,
70         DATA                  = 0x08,
71         DATA_ACK              = 0x18,
72         DATA_POLL             = 0x28,
73         DATA_POLL_ACK         = 0x38,
74         NULL_FRAME            = 0x48,
75         CFACK                 = 0x58,
76         CFPOLL                = 0x68,
77         CFPOLL_ACK            = 0x78,
78         QOS_DATA              = 0x88,
79         QOS_DATA_ACK          = 0x98,
80         QOS_DATA_POLL         = 0xA8,
81         QOS_DATA_POLL_ACK     = 0xB8,
82         QOS_NULL_FRAME        = 0xC8,
83         QOS_CFPOLL            = 0xE8,
84         QOS_CFPOLL_ACK        = 0xF8,
85         BLOCKACK_REQ          = 0x84,
86         BLOCKACK              = 0x94,
87         FRAME_SUBTYPE_FORCE_32BIT  = 0xFFFFFFFF
88 } tenuFrmSubtype;
89
90 /* Basic Frame Classes */
91 typedef enum {
92         CLASS1_FRAME_TYPE      = 0x00,
93         CLASS2_FRAME_TYPE      = 0x01,
94         CLASS3_FRAME_TYPE      = 0x02,
95         FRAME_CLASS_FORCE_32BIT  = 0xFFFFFFFF
96 } tenuFrameClass;
97
98 /* Element ID  of various Information Elements */
99 typedef enum {
100         ISSID               = 0,   /* Service Set Identifier         */
101         ISUPRATES           = 1,   /* Supported Rates                */
102         IFHPARMS            = 2,   /* FH parameter set               */
103         IDSPARMS            = 3,   /* DS parameter set               */
104         ICFPARMS            = 4,   /* CF parameter set               */
105         ITIM                = 5,   /* Traffic Information Map        */
106         IIBPARMS            = 6,   /* IBSS parameter set             */
107         ICOUNTRY            = 7,   /* Country element                */
108         IEDCAPARAMS         = 12,  /* EDCA parameter set             */
109         ITSPEC              = 13,  /* Traffic Specification          */
110         ITCLAS              = 14,  /* Traffic Classification         */
111         ISCHED              = 15,  /* Schedule                       */
112         ICTEXT              = 16,  /* Challenge Text                 */
113         IPOWERCONSTRAINT    = 32,  /* Power Constraint               */
114         IPOWERCAPABILITY    = 33,  /* Power Capability               */
115         ITPCREQUEST         = 34,  /* TPC Request                    */
116         ITPCREPORT          = 35,  /* TPC Report                     */
117         ISUPCHANNEL         = 36,  /* Supported channel list         */
118         ICHSWANNOUNC        = 37,  /* Channel Switch Announcement    */
119         IMEASUREMENTREQUEST = 38,  /* Measurement request            */
120         IMEASUREMENTREPORT  = 39,  /* Measurement report             */
121         IQUIET              = 40,  /* Quiet element Info             */
122         IIBSSDFS            = 41,  /* IBSS DFS                       */
123         IERPINFO            = 42,  /* ERP Information                */
124         ITSDELAY            = 43,  /* TS Delay                       */
125         ITCLASPROCESS       = 44,  /* TCLAS Processing               */
126         IHTCAP              = 45,  /* HT Capabilities                */
127         IQOSCAP             = 46,  /* QoS Capability                 */
128         IRSNELEMENT         = 48,  /* RSN Information Element        */
129         IEXSUPRATES         = 50,  /* Extended Supported Rates       */
130         IEXCHSWANNOUNC      = 60,  /* Extended Ch Switch Announcement*/
131         IHTOPERATION        = 61,  /* HT Information                 */
132         ISECCHOFF           = 62,  /* Secondary Channel Offeset      */
133         I2040COEX           = 72,  /* 20/40 Coexistence IE           */
134         I2040INTOLCHREPORT  = 73,  /* 20/40 Intolerant channel report*/
135         IOBSSSCAN           = 74,  /* OBSS Scan parameters           */
136         IEXTCAP             = 127, /* Extended capability            */
137         IWMM                = 221, /* WMM parameters                 */
138         IWPAELEMENT         = 221, /* WPA Information Element        */
139         INFOELEM_ID_FORCE_32BIT  = 0xFFFFFFFF
140 } tenuInfoElemID;
141
142
143 typedef struct {
144         char *pcRespBuffer;
145         s32 s32MaxRespBuffLen;
146         s32 s32BytesRead;
147         bool bRespRequired;
148 } tstrConfigPktInfo;
149
150
151
152 /*****************************************************************************/
153 /* Extern Variable Declarations                                              */
154 /*****************************************************************************/
155
156
157 /*****************************************************************************/
158 /* Extern Function Declarations                                              */
159 /*****************************************************************************/
160 extern s32 SendRawPacket(s8 *ps8Packet, s32 s32PacketLen);
161 extern void NetworkInfoReceived(u8 *pu8Buffer, u32 u32Length);
162 extern void GnrlAsyncInfoReceived(u8 *pu8Buffer, u32 u32Length);
163 extern void host_int_ScanCompleteReceived(u8 *pu8Buffer, u32 u32Length);
164 /*****************************************************************************/
165 /* Global Variables                                                          */
166 /*****************************************************************************/
167 static struct semaphore SemHandleSendPkt;
168 static struct semaphore SemHandlePktResp;
169
170
171 static tstrConfigPktInfo gstrConfigPktInfo;
172
173 static u8 g_seqno;
174
175 static s16 g_wid_num          = -1;
176
177 static u16 Res_Len;
178
179 static u8 g_oper_mode    = SET_CFG;
180
181 /* WID Switches */
182 static tstrWID gastrWIDs[] = {
183         {WID_FIRMWARE_VERSION,          WID_STR},
184         {WID_PHY_VERSION,               WID_STR},
185         {WID_HARDWARE_VERSION,          WID_STR},
186         {WID_BSS_TYPE,                  WID_CHAR},
187         {WID_QOS_ENABLE,                WID_CHAR},
188         {WID_11I_MODE,                  WID_CHAR},
189         {WID_CURRENT_TX_RATE,           WID_CHAR},
190         {WID_LINKSPEED,                 WID_CHAR},
191         {WID_RTS_THRESHOLD,             WID_SHORT},
192         {WID_FRAG_THRESHOLD,            WID_SHORT},
193         {WID_SSID,                      WID_STR},
194         {WID_BSSID,                     WID_ADR},
195         {WID_BEACON_INTERVAL,           WID_SHORT},
196         {WID_POWER_MANAGEMENT,          WID_CHAR},
197         {WID_LISTEN_INTERVAL,           WID_CHAR},
198         {WID_DTIM_PERIOD,               WID_CHAR},
199         {WID_CURRENT_CHANNEL,           WID_CHAR},
200         {WID_TX_POWER_LEVEL_11A,        WID_CHAR},
201         {WID_TX_POWER_LEVEL_11B,        WID_CHAR},
202         {WID_PREAMBLE,                  WID_CHAR},
203         {WID_11G_OPERATING_MODE,        WID_CHAR},
204         {WID_MAC_ADDR,                  WID_ADR},
205         {WID_IP_ADDRESS,                WID_ADR},
206         {WID_ACK_POLICY,                WID_CHAR},
207         {WID_PHY_ACTIVE_REG,            WID_CHAR},
208         {WID_AUTH_TYPE,                 WID_CHAR},
209         {WID_REKEY_POLICY,              WID_CHAR},
210         {WID_REKEY_PERIOD,              WID_INT},
211         {WID_REKEY_PACKET_COUNT,        WID_INT},
212         {WID_11I_PSK,                   WID_STR},
213         {WID_1X_KEY,                    WID_STR},
214         {WID_1X_SERV_ADDR,              WID_IP},
215         {WID_SUPP_USERNAME,             WID_STR},
216         {WID_SUPP_PASSWORD,             WID_STR},
217         {WID_USER_CONTROL_ON_TX_POWER,  WID_CHAR},
218         {WID_MEMORY_ADDRESS,            WID_INT},
219         {WID_MEMORY_ACCESS_32BIT,       WID_INT},
220         {WID_MEMORY_ACCESS_16BIT,       WID_SHORT},
221         {WID_MEMORY_ACCESS_8BIT,        WID_CHAR},
222         {WID_SITE_SURVEY_RESULTS,       WID_STR},
223         {WID_PMKID_INFO,                WID_STR},
224         {WID_ASSOC_RES_INFO,            WID_STR},
225         {WID_MANUFACTURER,              WID_STR}, /* 4 Wids added for the CAPI tool*/
226         {WID_MODEL_NAME,                WID_STR},
227         {WID_MODEL_NUM,                 WID_STR},
228         {WID_DEVICE_NAME,               WID_STR},
229         {WID_SSID_PROBE_REQ,            WID_STR},
230
231 #ifdef MAC_802_11N
232         {WID_11N_ENABLE,                WID_CHAR},
233         {WID_11N_CURRENT_TX_MCS,        WID_CHAR},
234         {WID_TX_POWER_LEVEL_11N,        WID_CHAR},
235         {WID_11N_OPERATING_MODE,        WID_CHAR},
236         {WID_11N_SMPS_MODE,             WID_CHAR},
237         {WID_11N_PROT_MECH,             WID_CHAR},
238         {WID_11N_ERP_PROT_TYPE,         WID_CHAR},
239         {WID_11N_HT_PROT_TYPE,          WID_CHAR},
240         {WID_11N_PHY_ACTIVE_REG_VAL,    WID_INT},
241         {WID_11N_PRINT_STATS,           WID_CHAR},
242         {WID_11N_AUTORATE_TABLE,        WID_BIN_DATA},
243         {WID_HOST_CONFIG_IF_TYPE,       WID_CHAR},
244         {WID_HOST_DATA_IF_TYPE,         WID_CHAR},
245         {WID_11N_SIG_QUAL_VAL,          WID_SHORT},
246         {WID_11N_IMMEDIATE_BA_ENABLED,  WID_CHAR},
247         {WID_11N_TXOP_PROT_DISABLE,     WID_CHAR},
248         {WID_11N_SHORT_GI_20MHZ_ENABLE, WID_CHAR},
249         {WID_SHORT_SLOT_ALLOWED,        WID_CHAR},
250         {WID_11W_ENABLE,                WID_CHAR},
251         {WID_11W_MGMT_PROT_REQ,         WID_CHAR},
252         {WID_2040_ENABLE,               WID_CHAR},
253         {WID_2040_COEXISTENCE,          WID_CHAR},
254         {WID_USER_SEC_CHANNEL_OFFSET,   WID_CHAR},
255         {WID_2040_CURR_CHANNEL_OFFSET,  WID_CHAR},
256         {WID_2040_40MHZ_INTOLERANT,     WID_CHAR},
257         {WID_HUT_RESTART,               WID_CHAR},
258         {WID_HUT_NUM_TX_PKTS,           WID_INT},
259         {WID_HUT_FRAME_LEN,             WID_SHORT},
260         {WID_HUT_TX_FORMAT,             WID_CHAR},
261         {WID_HUT_BANDWIDTH,             WID_CHAR},
262         {WID_HUT_OP_BAND,               WID_CHAR},
263         {WID_HUT_STBC,                  WID_CHAR},
264         {WID_HUT_ESS,                   WID_CHAR},
265         {WID_HUT_ANTSET,                WID_CHAR},
266         {WID_HUT_HT_OP_MODE,            WID_CHAR},
267         {WID_HUT_RIFS_MODE,             WID_CHAR},
268         {WID_HUT_SMOOTHING_REC,         WID_CHAR},
269         {WID_HUT_SOUNDING_PKT,          WID_CHAR},
270         {WID_HUT_HT_CODING,             WID_CHAR},
271         {WID_HUT_TEST_DIR,              WID_CHAR},
272         {WID_HUT_TXOP_LIMIT,            WID_SHORT},
273         {WID_HUT_DEST_ADDR,             WID_ADR},
274         {WID_HUT_TX_PATTERN,            WID_BIN_DATA},
275         {WID_HUT_TX_TIME_TAKEN,         WID_INT},
276         {WID_HUT_PHY_TEST_MODE,         WID_CHAR},
277         {WID_HUT_PHY_TEST_RATE_HI,      WID_CHAR},
278         {WID_HUT_PHY_TEST_RATE_LO,      WID_CHAR},
279         {WID_HUT_TX_TEST_TIME,          WID_INT},
280         {WID_HUT_LOG_INTERVAL,          WID_INT},
281         {WID_HUT_DISABLE_RXQ_REPLENISH, WID_CHAR},
282         {WID_HUT_TEST_ID,               WID_STR},
283         {WID_HUT_KEY_ORIGIN,            WID_CHAR},
284         {WID_HUT_BCST_PERCENT,          WID_CHAR},
285         {WID_HUT_GROUP_CIPHER_TYPE,     WID_CHAR},
286         {WID_HUT_STATS,                 WID_BIN_DATA},
287         {WID_HUT_TSF_TEST_MODE,         WID_CHAR},
288         {WID_HUT_SIG_QUAL_AVG,          WID_SHORT},
289         {WID_HUT_SIG_QUAL_AVG_CNT,      WID_SHORT},
290         {WID_HUT_TSSI_VALUE,            WID_CHAR},
291         {WID_HUT_MGMT_PERCENT,          WID_CHAR},
292         {WID_HUT_MGMT_BCST_PERCENT,     WID_CHAR},
293         {WID_HUT_MGMT_ALLOW_HT,         WID_CHAR},
294         {WID_HUT_UC_MGMT_TYPE,          WID_CHAR},
295         {WID_HUT_BC_MGMT_TYPE,          WID_CHAR},
296         {WID_HUT_UC_MGMT_FRAME_LEN,     WID_SHORT},
297         {WID_HUT_BC_MGMT_FRAME_LEN,     WID_SHORT},
298         {WID_HUT_11W_MFP_REQUIRED_TX,   WID_CHAR},
299         {WID_HUT_11W_MFP_PEER_CAPABLE,  WID_CHAR},
300         {WID_HUT_11W_TX_IGTK_ID,        WID_CHAR},
301         {WID_HUT_FC_TXOP_MOD,           WID_CHAR},
302         {WID_HUT_FC_PROT_TYPE,          WID_CHAR},
303         {WID_HUT_SEC_CCA_ASSERT,        WID_CHAR},
304 #endif /* MAC_802_11N */
305 };
306
307 u16 g_num_total_switches = (sizeof(gastrWIDs) / sizeof(tstrWID));
308 /*****************************************************************************/
309 /* Static Function Declarations                                              */
310 /*****************************************************************************/
311
312
313
314 /*****************************************************************************/
315 /* Functions                                                                 */
316 /*****************************************************************************/
317 INLINE u8 ascii_hex_to_dec(u8 num)
318 {
319         if ((num >= '0') && (num <= '9'))
320                 return (num - '0');
321         else if ((num >= 'A') && (num <= 'F'))
322                 return (10 + (num - 'A'));
323         else if ((num >= 'a') && (num <= 'f'))
324                 return (10 + (num - 'a'));
325
326         return INVALID;
327 }
328
329 INLINE u8 get_hex_char(u8 inp)
330 {
331         u8 *d2htab = "0123456789ABCDEF";
332
333         return d2htab[inp & 0xF];
334 }
335
336 /* This function extracts the MAC address held in a string in standard format */
337 /* into another buffer as integers.                                           */
338 INLINE u16 extract_mac_addr(char *str, u8 *buff)
339 {
340         *buff = 0;
341         while (*str != '\0') {
342                 if ((*str == ':') || (*str == '-'))
343                         *(++buff) = 0;
344                 else
345                         *buff = (*buff << 4) + ascii_hex_to_dec(*str);
346
347                 str++;
348         }
349
350         return MAC_ADDR_LEN;
351 }
352
353 /* This function creates MAC address in standard format from a buffer of      */
354 /* integers.                                                                  */
355 INLINE void create_mac_addr(u8 *str, u8 *buff)
356 {
357         u32 i = 0;
358         u32 j = 0;
359
360         for (i = 0; i < MAC_ADDR_LEN; i++) {
361                 str[j++] = get_hex_char((u8)((buff[i] >> 4) & 0x0F));
362                 str[j++] = get_hex_char((u8)(buff[i] & 0x0F));
363                 str[j++] = ':';
364         }
365         str[--j] = '\0';
366 }
367
368 /* This function converts the IP address string in dotted decimal format to */
369 /* unsigned integer. This functionality is similar to the library function  */
370 /* inet_addr() but is reimplemented here since I could not confirm that     */
371 /* inet_addr is platform independent.                                       */
372 /* ips=>IP Address String in dotted decimal format                          */
373 /* ipn=>Pointer to IP Address in integer format                             */
374 INLINE u8 conv_ip_to_int(u8 *ips, u32 *ipn)
375 {
376         u8 i   = 0;
377         u8 ipb = 0;
378         *ipn = 0;
379         /* Integer to string for each component */
380         while (ips[i] != '\0') {
381                 if (ips[i] == '.') {
382                         *ipn = ((*ipn) << 8) | ipb;
383                         ipb = 0;
384                 } else {
385                         ipb = ipb * 10 + ascii_hex_to_dec(ips[i]);
386                 }
387
388                 i++;
389         }
390
391         /* The last byte of the IP address is read in here */
392         *ipn = ((*ipn) << 8) | ipb;
393
394         return 0;
395 }
396
397 /* This function converts the IP address from integer format to dotted    */
398 /* decimal string format. Alternative to std library fn inet_ntoa().      */
399 /* ips=>Buffer to hold IP Address String dotted decimal format (Min 17B)  */
400 /* ipn=>IP Address in integer format                                      */
401 INLINE u8 conv_int_to_ip(u8 *ips, u32 ipn)
402 {
403         u8 i   = 0;
404         u8 ipb = 0;
405         u8 cnt = 0;
406         u8 ipbsize = 0;
407
408         for (cnt = 4; cnt > 0; cnt--) {
409                 ipb = (ipn >> (8 * (cnt - 1))) & 0xFF;
410
411                 if (ipb >= 100)
412                         ipbsize = 2;
413                 else if (ipb >= 10)
414                         ipbsize = 1;
415                 else
416                         ipbsize = 0;
417
418                 switch (ipbsize) {
419                 case 2:
420                         ips[i++] = get_hex_char(ipb / 100);
421                         ipb %= 100;
422
423                 case 1:
424                         ips[i++] = get_hex_char(ipb / 10);
425                         ipb %= 10;
426
427                 default:
428                         ips[i++] = get_hex_char(ipb);
429                 }
430
431                 if (cnt > 1)
432                         ips[i++] = '.';
433         }
434
435         ips[i] = '\0';
436
437         return i;
438 }
439
440 INLINE tenuWIDtype get_wid_type(u32 wid_num)
441 {
442         /* Check for iconfig specific WID types first */
443         if ((wid_num == WID_BSSID) ||
444             (wid_num == WID_MAC_ADDR) ||
445             (wid_num == WID_IP_ADDRESS) ||
446             (wid_num == WID_HUT_DEST_ADDR)) {
447                 return WID_ADR;
448         }
449
450         if ((WID_1X_SERV_ADDR == wid_num) ||
451             (WID_STACK_IP_ADDR == wid_num) ||
452             (WID_STACK_NETMASK_ADDR == wid_num)) {
453                 return WID_IP;
454         }
455
456         /* Next check for standard WID types */
457         if (wid_num < 0x1000)
458                 return WID_CHAR;
459         else if (wid_num < 0x2000)
460                 return WID_SHORT;
461         else if (wid_num < 0x3000)
462                 return WID_INT;
463         else if (wid_num < 0x4000)
464                 return WID_STR;
465         else if (wid_num < 0x5000)
466                 return WID_BIN_DATA;
467
468         return WID_UNDEF;
469 }
470
471
472 /* This function extracts the beacon period field from the beacon or probe   */
473 /* response frame.                                                           */
474 INLINE u16 get_beacon_period(u8 *data)
475 {
476         u16 bcn_per = 0;
477
478         bcn_per  = data[0];
479         bcn_per |= (data[1] << 8);
480
481         return bcn_per;
482 }
483
484 INLINE u32 get_beacon_timestamp_lo(u8 *data)
485 {
486         u32 time_stamp = 0;
487         u32 index    = MAC_HDR_LEN;
488
489         time_stamp |= data[index++];
490         time_stamp |= (data[index++] << 8);
491         time_stamp |= (data[index++] << 16);
492         time_stamp |= (data[index]   << 24);
493
494         return time_stamp;
495 }
496
497 INLINE u32 get_beacon_timestamp_hi(u8 *data)
498 {
499         u32 time_stamp = 0;
500         u32 index    = (MAC_HDR_LEN + 4);
501
502         time_stamp |= data[index++];
503         time_stamp |= (data[index++] << 8);
504         time_stamp |= (data[index++] << 16);
505         time_stamp |= (data[index]   << 24);
506
507         return time_stamp;
508 }
509
510 /* This function extracts the 'frame type' bits from the MAC header of the   */
511 /* input frame.                                                              */
512 /* Returns the value in the LSB of the returned value.                       */
513 INLINE tenuBasicFrmType get_type(u8 *header)
514 {
515         return ((tenuBasicFrmType)(header[0] & 0x0C));
516 }
517
518 /* This function extracts the 'frame type and sub type' bits from the MAC    */
519 /* header of the input frame.                                                */
520 /* Returns the value in the LSB of the returned value.                       */
521 INLINE tenuFrmSubtype get_sub_type(u8 *header)
522 {
523         return ((tenuFrmSubtype)(header[0] & 0xFC));
524 }
525
526 /* This function extracts the 'to ds' bit from the MAC header of the input   */
527 /* frame.                                                                    */
528 /* Returns the value in the LSB of the returned value.                       */
529 INLINE u8 get_to_ds(u8 *header)
530 {
531         return (header[1] & 0x01);
532 }
533
534 /* This function extracts the 'from ds' bit from the MAC header of the input */
535 /* frame.                                                                    */
536 /* Returns the value in the LSB of the returned value.                       */
537 INLINE u8 get_from_ds(u8 *header)
538 {
539         return ((header[1] & 0x02) >> 1);
540 }
541
542 /* This function extracts the MAC Address in 'address1' field of the MAC     */
543 /* header and updates the MAC Address in the allocated 'addr' variable.      */
544 INLINE void get_address1(u8 *pu8msa, u8 *addr)
545 {
546         memcpy(addr, pu8msa + 4, 6);
547 }
548
549 /* This function extracts the MAC Address in 'address2' field of the MAC     */
550 /* header and updates the MAC Address in the allocated 'addr' variable.      */
551 INLINE void get_address2(u8 *pu8msa, u8 *addr)
552 {
553         memcpy(addr, pu8msa + 10, 6);
554 }
555
556 /* This function extracts the MAC Address in 'address3' field of the MAC     */
557 /* header and updates the MAC Address in the allocated 'addr' variable.      */
558 INLINE void get_address3(u8 *pu8msa, u8 *addr)
559 {
560         memcpy(addr, pu8msa + 16, 6);
561 }
562
563 /* This function extracts the BSSID from the incoming WLAN packet based on   */
564 /* the 'from ds' bit, and updates the MAC Address in the allocated 'addr'    */
565 /* variable.                                                                 */
566 INLINE void get_BSSID(u8 *data, u8 *bssid)
567 {
568         if (get_from_ds(data) == 1)
569                 get_address2(data, bssid);
570         else if (get_to_ds(data) == 1)
571                 get_address1(data, bssid);
572         else
573                 get_address3(data, bssid);
574 }
575
576 /* This function extracts the SSID from a beacon/probe response frame        */
577 INLINE void get_ssid(u8 *data, u8 *ssid, u8 *p_ssid_len)
578 {
579         u8 len = 0;
580         u8 i   = 0;
581         u8 j   = 0;
582
583         len = data[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN +
584                    CAP_INFO_LEN + 1];
585         j   = MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN +
586                 CAP_INFO_LEN + 2;
587
588         /* If the SSID length field is set wrongly to a value greater than the   */
589         /* allowed maximum SSID length limit, reset the length to 0              */
590         if (len >= MAX_SSID_LEN)
591                 len = 0;
592
593         for (i = 0; i < len; i++, j++)
594                 ssid[i] = data[j];
595
596         ssid[len] = '\0';
597
598         *p_ssid_len = len;
599 }
600
601 /* This function extracts the capability info field from the beacon or probe */
602 /* response frame.                                                           */
603 INLINE u16 get_cap_info(u8 *data)
604 {
605         u16 cap_info = 0;
606         u16 index    = MAC_HDR_LEN;
607         tenuFrmSubtype st;
608
609         st = get_sub_type(data);
610
611         /* Location of the Capability field is different for Beacon and */
612         /* Association frames.                                          */
613         if ((st == BEACON) || (st == PROBE_RSP))
614                 index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN;
615
616         cap_info  = data[index];
617         cap_info |= (data[index + 1] << 8);
618
619         return cap_info;
620 }
621
622 /* This function extracts the capability info field from the Association */
623 /* response frame.                                                                       */
624 INLINE u16 get_assoc_resp_cap_info(u8 *data)
625 {
626         u16 cap_info = 0;
627
628         cap_info  = data[0];
629         cap_info |= (data[1] << 8);
630
631         return cap_info;
632 }
633
634 /* This funcion extracts the association status code from the incoming       */
635 /* association response frame and returns association status code            */
636 INLINE u16 get_asoc_status(u8 *data)
637 {
638         u16 asoc_status = 0;
639
640         asoc_status = data[3];
641         asoc_status = (asoc_status << 8) | data[2];
642
643         return asoc_status;
644 }
645
646 /* This function extracts association ID from the incoming association       */
647 /* response frame                                                                                            */
648 INLINE u16 get_asoc_id(u8 *data)
649 {
650         u16 asoc_id = 0;
651
652         asoc_id  = data[4];
653         asoc_id |= (data[5] << 8);
654
655         return asoc_id;
656 }
657
658 /**
659  *  @brief              initializes the Core Configurator
660  *  @details
661  *  @return     Error code indicating success/failure
662  *  @note
663  *  @author     mabubakr
664  *  @date               1 Mar 2012
665  *  @version            1.0
666  */
667
668 s32 CoreConfiguratorInit(void)
669 {
670         s32 s32Error = WILC_SUCCESS;
671         PRINT_D(CORECONFIG_DBG, "CoreConfiguratorInit()\n");
672
673         sema_init(&SemHandleSendPkt, 1);
674         sema_init(&SemHandlePktResp, 0);
675
676
677         memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
678         return s32Error;
679 }
680
681 u8 *get_tim_elm(u8 *pu8msa, u16 u16RxLen, u16 u16TagParamOffset)
682 {
683         u16 u16index = 0;
684
685         /*************************************************************************/
686         /*                       Beacon Frame - Frame Body                       */
687         /* --------------------------------------------------------------------- */
688         /* |Timestamp |BeaconInt |CapInfo |SSID |SupRates |DSParSet |TIM elm   | */
689         /* --------------------------------------------------------------------- */
690         /* |8         |2         |2       |2-34 |3-10     |3        |4-256     | */
691         /* --------------------------------------------------------------------- */
692         /*                                                                       */
693         /*************************************************************************/
694
695         u16index = u16TagParamOffset;
696
697         /* Search for the TIM Element Field and return if the element is found */
698         while (u16index < (u16RxLen - FCS_LEN)) {
699                 if (pu8msa[u16index] == ITIM)
700                         return &pu8msa[u16index];
701                 else
702                         u16index += (IE_HDR_LEN + pu8msa[u16index + 1]);
703         }
704
705         return 0;
706 }
707
708 /* This function gets the current channel information from
709  * the 802.11n beacon/probe response frame */
710 u8 get_current_channel_802_11n(u8 *pu8msa, u16 u16RxLen)
711 {
712         u16 index;
713
714         index = TAG_PARAM_OFFSET;
715         while (index < (u16RxLen - FCS_LEN)) {
716                 if (pu8msa[index] == IDSPARMS)
717                         return pu8msa[index + 2];
718                 else
719                         /* Increment index by length information and header */
720                         index += pu8msa[index + 1] + IE_HDR_LEN;
721         }
722
723         /* Return current channel information from the MIB, if beacon/probe  */
724         /* response frame does not contain the DS parameter set IE           */
725         /* return (mget_CurrentChannel() + 1); */
726         return 0;  /* no MIB here */
727 }
728
729 u8 get_current_channel(u8 *pu8msa, u16 u16RxLen)
730 {
731 #ifdef PHY_802_11n
732 #ifdef FIVE_GHZ_BAND
733         /* Get the current channel as its not set in */
734         /* 802.11a beacons/probe response            */
735         return (get_rf_channel() + 1);
736 #else /* FIVE_GHZ_BAND */
737         /* Extract current channel information from */
738         /* the beacon/probe response frame          */
739         return get_current_channel_802_11n(pu8msa, u16RxLen);
740 #endif /* FIVE_GHZ_BAND */
741 #else
742         return 0;
743 #endif /* PHY_802_11n */
744 }
745
746 /**
747  *  @brief                      parses the received 'N' message
748  *  @details
749  *  @param[in]  pu8MsgBuffer The message to be parsed
750  *  @param[out]         ppstrNetworkInfo pointer to pointer to the structure containing the parsed Network Info
751  *  @return             Error code indicating success/failure
752  *  @note
753  *  @author             mabubakr
754  *  @date                       1 Mar 2012
755  *  @version            1.0
756  */
757 s32 ParseNetworkInfo(u8 *pu8MsgBuffer, tstrNetworkInfo **ppstrNetworkInfo)
758 {
759         s32 s32Error = WILC_SUCCESS;
760         tstrNetworkInfo *pstrNetworkInfo = NULL;
761         u8 u8MsgType = 0;
762         u8 u8MsgID = 0;
763         u16 u16MsgLen = 0;
764
765         u16 u16WidID = (u16)WID_NIL;
766         u16 u16WidLen  = 0;
767         u8  *pu8WidVal = 0;
768
769         u8MsgType = pu8MsgBuffer[0];
770
771         /* Check whether the received message type is 'N' */
772         if ('N' != u8MsgType) {
773                 PRINT_ER("Received Message format incorrect.\n");
774                 WILC_ERRORREPORT(s32Error, WILC_FAIL);
775         }
776
777         /* Extract message ID */
778         u8MsgID = pu8MsgBuffer[1];
779
780         /* Extract message Length */
781         u16MsgLen = MAKE_WORD16(pu8MsgBuffer[2], pu8MsgBuffer[3]);
782
783         /* Extract WID ID */
784         u16WidID = MAKE_WORD16(pu8MsgBuffer[4], pu8MsgBuffer[5]);
785
786         /* Extract WID Length */
787         u16WidLen = MAKE_WORD16(pu8MsgBuffer[6], pu8MsgBuffer[7]);
788
789         /* Assign a pointer to the WID value */
790         pu8WidVal  = &pu8MsgBuffer[8];
791
792         /* parse the WID value of the WID "WID_NEWORK_INFO" */
793         {
794                 u8  *pu8msa = 0;
795                 u16 u16RxLen = 0;
796                 u8 *pu8TimElm = 0;
797                 u8 *pu8IEs = 0;
798                 u16 u16IEsLen = 0;
799                 u8 u8index = 0;
800                 u32 u32Tsf_Lo;
801                 u32 u32Tsf_Hi;
802
803                 pstrNetworkInfo = kmalloc(sizeof(tstrNetworkInfo), GFP_KERNEL);
804                 if (!pstrNetworkInfo)
805                         return -ENOMEM;
806
807                 memset((void *)(pstrNetworkInfo), 0, sizeof(tstrNetworkInfo));
808
809                 pstrNetworkInfo->s8rssi = pu8WidVal[0];
810
811                 /* Assign a pointer to msa "Mac Header Start Address" */
812                 pu8msa = &pu8WidVal[1];
813
814                 u16RxLen = u16WidLen - 1;
815
816                 /* parse msa*/
817
818                 /* Get the cap_info */
819                 pstrNetworkInfo->u16CapInfo = get_cap_info(pu8msa);
820                 #ifdef WILC_P2P
821                 /* Get time-stamp [Low only 32 bit] */
822                 pstrNetworkInfo->u32Tsf = get_beacon_timestamp_lo(pu8msa);
823                 PRINT_D(CORECONFIG_DBG, "TSF :%x\n", pstrNetworkInfo->u32Tsf);
824                 #endif
825
826                 /* Get full time-stamp [Low and High 64 bit] */
827                 u32Tsf_Lo = get_beacon_timestamp_lo(pu8msa);
828                 u32Tsf_Hi = get_beacon_timestamp_hi(pu8msa);
829
830                 pstrNetworkInfo->u64Tsf = u32Tsf_Lo | ((u64)u32Tsf_Hi << 32);
831
832                 /* Get SSID */
833                 get_ssid(pu8msa, pstrNetworkInfo->au8ssid, &(pstrNetworkInfo->u8SsidLen));
834
835                 /* Get BSSID */
836                 get_BSSID(pu8msa, pstrNetworkInfo->au8bssid);
837
838                 /* Get the current channel */
839                 pstrNetworkInfo->u8channel = get_current_channel(pu8msa, (u16RxLen + FCS_LEN));
840
841                 /* Get beacon period */
842                 u8index = (MAC_HDR_LEN + TIME_STAMP_LEN);
843
844                 pstrNetworkInfo->u16BeaconPeriod = get_beacon_period(pu8msa + u8index);
845
846                 u8index += BEACON_INTERVAL_LEN + CAP_INFO_LEN;
847
848                 /* Get DTIM Period */
849                 pu8TimElm = get_tim_elm(pu8msa, (u16RxLen + FCS_LEN), u8index);
850                 if (pu8TimElm != 0)
851                         pstrNetworkInfo->u8DtimPeriod = pu8TimElm[3];
852                 pu8IEs = &pu8msa[MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN];
853                 u16IEsLen = u16RxLen - (MAC_HDR_LEN + TIME_STAMP_LEN + BEACON_INTERVAL_LEN + CAP_INFO_LEN);
854
855                 if (u16IEsLen > 0) {
856                         pstrNetworkInfo->pu8IEs = kmalloc(u16IEsLen, GFP_KERNEL);
857                         if (!pstrNetworkInfo->pu8IEs)
858                                 return -ENOMEM;
859
860                         memset((void *)(pstrNetworkInfo->pu8IEs), 0, u16IEsLen);
861
862                         memcpy(pstrNetworkInfo->pu8IEs, pu8IEs, u16IEsLen);
863                 }
864                 pstrNetworkInfo->u16IEsLen = u16IEsLen;
865
866         }
867
868         *ppstrNetworkInfo = pstrNetworkInfo;
869
870 ERRORHANDLER:
871         return s32Error;
872 }
873
874 /**
875  *  @brief              Deallocates the parsed Network Info
876  *  @details
877  *  @param[in]  pstrNetworkInfo Network Info to be deallocated
878  *  @return             Error code indicating success/failure
879  *  @note
880  *  @author             mabubakr
881  *  @date               1 Mar 2012
882  *  @version            1.0
883  */
884 s32 DeallocateNetworkInfo(tstrNetworkInfo *pstrNetworkInfo)
885 {
886         s32 s32Error = WILC_SUCCESS;
887
888         if (pstrNetworkInfo != NULL) {
889                 if (pstrNetworkInfo->pu8IEs != NULL) {
890                         kfree(pstrNetworkInfo->pu8IEs);
891                         pstrNetworkInfo->pu8IEs = NULL;
892                 } else {
893                         s32Error = WILC_FAIL;
894                 }
895
896                 kfree(pstrNetworkInfo);
897                 pstrNetworkInfo = NULL;
898
899         } else {
900                 s32Error = WILC_FAIL;
901         }
902
903         return s32Error;
904 }
905
906 /**
907  *  @brief                      parses the received Association Response frame
908  *  @details
909  *  @param[in]  pu8Buffer The Association Response frame to be parsed
910  *  @param[out]         ppstrConnectRespInfo pointer to pointer to the structure containing the parsed Association Response Info
911  *  @return             Error code indicating success/failure
912  *  @note
913  *  @author             mabubakr
914  *  @date                       2 Apr 2012
915  *  @version            1.0
916  */
917 s32 ParseAssocRespInfo(u8 *pu8Buffer, u32 u32BufferLen,
918                                tstrConnectRespInfo **ppstrConnectRespInfo)
919 {
920         s32 s32Error = WILC_SUCCESS;
921         tstrConnectRespInfo *pstrConnectRespInfo = NULL;
922         u16 u16AssocRespLen = 0;
923         u8 *pu8IEs = 0;
924         u16 u16IEsLen = 0;
925
926         pstrConnectRespInfo = kmalloc(sizeof(tstrConnectRespInfo), GFP_KERNEL);
927         if (!pstrConnectRespInfo)
928                 return -ENOMEM;
929
930         memset((void *)(pstrConnectRespInfo), 0, sizeof(tstrConnectRespInfo));
931
932         /* u16AssocRespLen = pu8Buffer[0]; */
933         u16AssocRespLen = (u16)u32BufferLen;
934
935         /* get the status code */
936         pstrConnectRespInfo->u16ConnectStatus = get_asoc_status(pu8Buffer);
937         if (pstrConnectRespInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE) {
938
939                 /* get the capability */
940                 pstrConnectRespInfo->u16capability = get_assoc_resp_cap_info(pu8Buffer);
941
942                 /* get the Association ID */
943                 pstrConnectRespInfo->u16AssocID = get_asoc_id(pu8Buffer);
944
945                 /* get the Information Elements */
946                 pu8IEs = &pu8Buffer[CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN];
947                 u16IEsLen = u16AssocRespLen - (CAP_INFO_LEN + STATUS_CODE_LEN + AID_LEN);
948
949                 pstrConnectRespInfo->pu8RespIEs = kmalloc(u16IEsLen, GFP_KERNEL);
950                 if (!pstrConnectRespInfo->pu8RespIEs)
951                         return -ENOMEM;
952
953                 memset((void *)(pstrConnectRespInfo->pu8RespIEs), 0, u16IEsLen);
954
955                 memcpy(pstrConnectRespInfo->pu8RespIEs, pu8IEs, u16IEsLen);
956                 pstrConnectRespInfo->u16RespIEsLen = u16IEsLen;
957         }
958
959         *ppstrConnectRespInfo = pstrConnectRespInfo;
960
961
962         return s32Error;
963 }
964
965 /**
966  *  @brief                      Deallocates the parsed Association Response Info
967  *  @details
968  *  @param[in]  pstrNetworkInfo Network Info to be deallocated
969  *  @return             Error code indicating success/failure
970  *  @note
971  *  @author             mabubakr
972  *  @date                       2 Apr 2012
973  *  @version            1.0
974  */
975 s32 DeallocateAssocRespInfo(tstrConnectRespInfo *pstrConnectRespInfo)
976 {
977         s32 s32Error = WILC_SUCCESS;
978
979         if (pstrConnectRespInfo != NULL) {
980                 if (pstrConnectRespInfo->pu8RespIEs != NULL) {
981                         kfree(pstrConnectRespInfo->pu8RespIEs);
982                         pstrConnectRespInfo->pu8RespIEs = NULL;
983                 } else {
984                         s32Error = WILC_FAIL;
985                 }
986
987                 kfree(pstrConnectRespInfo);
988                 pstrConnectRespInfo = NULL;
989
990         } else {
991                 s32Error = WILC_FAIL;
992         }
993
994         return s32Error;
995 }
996
997 #ifndef CONNECT_DIRECT
998 s32 ParseSurveyResults(u8 ppu8RcvdSiteSurveyResults[][MAX_SURVEY_RESULT_FRAG_SIZE],
999                                wid_site_survey_reslts_s **ppstrSurveyResults,
1000                                u32 *pu32SurveyResultsCount)
1001 {
1002         s32 s32Error = WILC_SUCCESS;
1003         wid_site_survey_reslts_s *pstrSurveyResults = NULL;
1004         u32 u32SurveyResultsCount = 0;
1005         u32 u32SurveyBytesLength = 0;
1006         u8 *pu8BufferPtr;
1007         u32 u32RcvdSurveyResultsNum = 2;
1008         u8 u8ReadSurveyResFragNum;
1009         u32 i;
1010         u32 j;
1011
1012         for (i = 0; i < u32RcvdSurveyResultsNum; i++) {
1013                 u32SurveyBytesLength = ppu8RcvdSiteSurveyResults[i][0];
1014
1015
1016                 for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) {
1017                         u32SurveyResultsCount++;
1018                 }
1019         }
1020
1021         pstrSurveyResults = kmalloc_array(u32SurveyResultsCount,
1022                                 sizeof(wid_site_survey_reslts_s), GFP_KERNEL);
1023         if (!pstrSurveyResults)
1024                 return -ENOMEM;
1025
1026         memset((void *)(pstrSurveyResults), 0, u32SurveyResultsCount * sizeof(wid_site_survey_reslts_s));
1027
1028         u32SurveyResultsCount = 0;
1029
1030         for (i = 0; i < u32RcvdSurveyResultsNum; i++) {
1031                 pu8BufferPtr = ppu8RcvdSiteSurveyResults[i];
1032
1033                 u32SurveyBytesLength = pu8BufferPtr[0];
1034
1035                 /* TODO: mostafa: pu8BufferPtr[1] contains the fragment num */
1036                 u8ReadSurveyResFragNum = pu8BufferPtr[1];
1037
1038                 pu8BufferPtr += 2;
1039
1040                 for (j = 0; j < u32SurveyBytesLength; j += SURVEY_RESULT_LENGTH) {
1041                         memcpy(&pstrSurveyResults[u32SurveyResultsCount], pu8BufferPtr, SURVEY_RESULT_LENGTH);
1042                         pu8BufferPtr += SURVEY_RESULT_LENGTH;
1043                         u32SurveyResultsCount++;
1044                 }
1045         }
1046
1047 ERRORHANDLER:
1048         *ppstrSurveyResults = pstrSurveyResults;
1049         *pu32SurveyResultsCount = u32SurveyResultsCount;
1050
1051         return s32Error;
1052 }
1053
1054
1055 s32 DeallocateSurveyResults(wid_site_survey_reslts_s *pstrSurveyResults)
1056 {
1057         s32 s32Error = WILC_SUCCESS;
1058
1059         if (pstrSurveyResults != NULL) {
1060                 kfree(pstrSurveyResults);
1061         }
1062
1063         return s32Error;
1064 }
1065 #endif
1066
1067 /*****************************************************************************/
1068 /*                                                                           */
1069 /*  Function Name : ProcessCharWid                                         */
1070 /*                                                                           */
1071 /*  Description   : This function processes a WID of type WID_CHAR and       */
1072 /*                  updates the cfg packet with the supplied value.          */
1073 /*                                                                           */
1074 /*  Inputs        : 1) Pointer to WID cfg structure                          */
1075 /*                  2) Value to set                                          */
1076 /*                                                                           */
1077 /*  Globals       :                                                          */
1078 /*                                                                           */
1079 /*  Processing    :                                                          */
1080 /*                                                                           */
1081 /*  Outputs       : None                                                     */
1082 /*                                                                           */
1083 /*  Returns       : None                                                     */
1084 /*                                                                           */
1085 /*  Issues        : None                                                     */
1086 /*                                                                           */
1087 /*  Revision History:                                                        */
1088 /*                                                                           */
1089 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1090 /*         08 01 2008   Ittiam          Draft                                */
1091 /*                                                                           */
1092 /*****************************************************************************/
1093
1094 void ProcessCharWid(char *pcPacket, s32 *ps32PktLen,
1095                     tstrWID *pstrWID, s8 *ps8WidVal)
1096 {
1097         u8 *pu8val = (u8 *)ps8WidVal;
1098         u8 u8val = 0;
1099         s32 s32PktLen = *ps32PktLen;
1100         if (pstrWID == NULL) {
1101                 PRINT_WRN(CORECONFIG_DBG, "Can't set CHAR val 0x%x ,NULL structure\n", u8val);
1102                 return;
1103         }
1104
1105         /* WID */
1106         pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
1107         pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid >> 8) & 0xFF;
1108         if (g_oper_mode == SET_CFG) {
1109                 u8val = *pu8val;
1110
1111                 /* Length */
1112                 pcPacket[s32PktLen++] = sizeof(u8);
1113
1114
1115                 /* Value */
1116                 pcPacket[s32PktLen++] = u8val;
1117         }
1118         *ps32PktLen = s32PktLen;
1119 }
1120
1121 /*****************************************************************************/
1122 /*                                                                           */
1123 /*  Function Name : ProcessShortWid                                        */
1124 /*                                                                           */
1125 /*  Description   : This function processes a WID of type WID_SHORT and      */
1126 /*                  updates the cfg packet with the supplied value.          */
1127 /*                                                                           */
1128 /*  Inputs        : 1) Pointer to WID cfg structure                          */
1129 /*                  2) Value to set                                          */
1130 /*                                                                           */
1131 /*  Globals       :                                                          */
1132 /*                                                                           */
1133 /*  Processing    :                                                          */
1134 /*                                                                           */
1135 /*  Outputs       : None                                                     */
1136 /*                                                                           */
1137 /*  Returns       : None                                                     */
1138 /*                                                                           */
1139 /*  Issues        : None                                                     */
1140 /*                                                                           */
1141 /*  Revision History:                                                        */
1142 /*                                                                           */
1143 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1144 /*         08 01 2008   Ittiam          Draft                                */
1145 /*                                                                           */
1146 /*****************************************************************************/
1147
1148 void ProcessShortWid(char *pcPacket, s32 *ps32PktLen,
1149                      tstrWID *pstrWID, s8 *ps8WidVal)
1150 {
1151         u16 *pu16val = (u16 *)ps8WidVal;
1152         u16 u16val = 0;
1153         s32 s32PktLen = *ps32PktLen;
1154         if (pstrWID == NULL) {
1155                 PRINT_WRN(CORECONFIG_DBG, "Can't set SHORT val 0x%x ,NULL structure\n", u16val);
1156                 return;
1157         }
1158
1159         /* WID */
1160         pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
1161         pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
1162
1163         if (g_oper_mode == SET_CFG) {
1164                 u16val = *pu16val;
1165
1166                 /* Length */
1167                 pcPacket[s32PktLen++] = sizeof(u16);
1168
1169                 /* Value */
1170                 pcPacket[s32PktLen++] = (u8)(u16val & 0xFF);
1171                 pcPacket[s32PktLen++] = (u8)((u16val >> 8) & 0xFF);
1172         }
1173         *ps32PktLen = s32PktLen;
1174 }
1175
1176 /*****************************************************************************/
1177 /*                                                                           */
1178 /*  Function Name : ProcessIntWid                                          */
1179 /*                                                                           */
1180 /*  Description   : This function processes a WID of type WID_INT and        */
1181 /*                  updates the cfg packet with the supplied value.          */
1182 /*                                                                           */
1183 /*  Inputs        : 1) Pointer to WID cfg structure                          */
1184 /*                  2) Value to set                                          */
1185 /*                                                                           */
1186 /*  Globals       :                                                          */
1187 /*                                                                           */
1188 /*  Processing    :                                                          */
1189 /*                                                                           */
1190 /*  Outputs       : None                                                     */
1191 /*                                                                           */
1192 /*  Returns       : None                                                     */
1193 /*                                                                           */
1194 /*  Issues        : None                                                     */
1195 /*                                                                           */
1196 /*  Revision History:                                                        */
1197 /*                                                                           */
1198 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1199 /*         08 01 2008   Ittiam          Draft                                */
1200 /*                                                                           */
1201 /*****************************************************************************/
1202
1203 void ProcessIntWid(char *pcPacket, s32 *ps32PktLen,
1204                    tstrWID *pstrWID, s8 *ps8WidVal)
1205 {
1206         u32 *pu32val = (u32 *)ps8WidVal;
1207         u32 u32val = 0;
1208         s32 s32PktLen = *ps32PktLen;
1209         if (pstrWID == NULL) {
1210                 PRINT_WRN(CORECONFIG_DBG, "Can't set INT val 0x%x , NULL structure\n", u32val);
1211                 return;
1212         }
1213
1214         /* WID */
1215         pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
1216         pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
1217
1218         if (g_oper_mode == SET_CFG) {
1219                 u32val = *pu32val;
1220
1221                 /* Length */
1222                 pcPacket[s32PktLen++] = sizeof(u32);
1223
1224                 /* Value */
1225                 pcPacket[s32PktLen++] = (u8)(u32val & 0xFF);
1226                 pcPacket[s32PktLen++] = (u8)((u32val >> 8) & 0xFF);
1227                 pcPacket[s32PktLen++] = (u8)((u32val >> 16) & 0xFF);
1228                 pcPacket[s32PktLen++] = (u8)((u32val >> 24) & 0xFF);
1229         }
1230         *ps32PktLen = s32PktLen;
1231 }
1232
1233 /*****************************************************************************/
1234 /*                                                                           */
1235 /*  Function Name : ProcessIPwid                                           */
1236 /*                                                                           */
1237 /*  Description   : This function processes a WID of type WID_IP and         */
1238 /*                  updates the cfg packet with the supplied value.          */
1239 /*                                                                           */
1240 /*  Inputs        : 1) Pointer to WID cfg structure                          */
1241 /*                  2) Value to set                                          */
1242 /*                                                                           */
1243 /*  Globals       :                                                          */
1244 /*                                                                           */
1245 /*                                                                           */
1246 /*  Processing    :                                                          */
1247 /*                                                                           */
1248 /*  Outputs       : None                                                     */
1249 /*                                                                           */
1250 /*  Returns       : None                                                     */
1251 /*                                                                           */
1252 /*  Issues        : None                                                     */
1253 /*                                                                           */
1254 /*  Revision History:                                                        */
1255 /*                                                                           */
1256 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1257 /*         08 01 2008   Ittiam          Draft                                */
1258 /*                                                                           */
1259 /*****************************************************************************/
1260
1261 void ProcessIPwid(char *pcPacket, s32 *ps32PktLen,
1262                   tstrWID *pstrWID, u8 *pu8ip)
1263 {
1264         u32 u32val = 0;
1265         s32 s32PktLen = *ps32PktLen;
1266
1267         if (pstrWID == NULL) {
1268                 PRINT_WRN(CORECONFIG_DBG, "Can't set IP Addr , NULL structure\n");
1269                 return;
1270         }
1271
1272         /* WID */
1273         pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
1274         pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
1275
1276         if (g_oper_mode == SET_CFG) {
1277                 /* Length */
1278                 pcPacket[s32PktLen++] = sizeof(u32);
1279
1280                 /* Convert the IP Address String to Integer */
1281                 conv_ip_to_int(pu8ip, &u32val);
1282
1283                 /* Value */
1284                 pcPacket[s32PktLen++] = (u8)(u32val & 0xFF);
1285                 pcPacket[s32PktLen++] = (u8)((u32val >> 8) & 0xFF);
1286                 pcPacket[s32PktLen++] = (u8)((u32val >> 16) & 0xFF);
1287                 pcPacket[s32PktLen++] = (u8)((u32val >> 24) & 0xFF);
1288         }
1289         *ps32PktLen = s32PktLen;
1290 }
1291
1292 /*****************************************************************************/
1293 /*                                                                           */
1294 /*  Function Name : ProcessStrWid                                          */
1295 /*                                                                           */
1296 /*  Description   : This function processes a WID of type WID_STR and        */
1297 /*                  updates the cfg packet with the supplied value.          */
1298 /*                                                                           */
1299 /*  Inputs        : 1) Pointer to WID cfg structure                          */
1300 /*                  2) Value to set                                          */
1301 /*                                                                           */
1302 /*  Globals       :                                                          */
1303 /*                                                                           */
1304 /*  Processing    :                                                          */
1305 /*                                                                           */
1306 /*  Outputs       : None                                                     */
1307 /*                                                                           */
1308 /*  Returns       : None                                                     */
1309 /*                                                                           */
1310 /*  Issues        : None                                                     */
1311 /*                                                                           */
1312 /*  Revision History:                                                        */
1313 /*                                                                           */
1314 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1315 /*         08 01 2008   Ittiam          Draft                                */
1316 /*                                                                           */
1317 /*****************************************************************************/
1318
1319 void ProcessStrWid(char *pcPacket, s32 *ps32PktLen,
1320                    tstrWID *pstrWID, u8 *pu8val, s32 s32ValueSize)
1321 {
1322         u16 u16MsgLen = 0;
1323         u16 idx    = 0;
1324         s32 s32PktLen = *ps32PktLen;
1325         if (pstrWID == NULL) {
1326                 PRINT_WRN(CORECONFIG_DBG, "Can't set STR val, NULL structure\n");
1327                 return;
1328         }
1329
1330         /* WID */
1331         pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
1332         pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
1333
1334         if (g_oper_mode == SET_CFG) {
1335                 /* Message Length */
1336                 u16MsgLen = (u16)s32ValueSize;
1337
1338                 /* Length */
1339                 pcPacket[s32PktLen++] = (u8)u16MsgLen;
1340
1341                 /* Value */
1342                 for (idx = 0; idx < u16MsgLen; idx++)
1343                         pcPacket[s32PktLen++] = pu8val[idx];
1344         }
1345         *ps32PktLen = s32PktLen;
1346 }
1347
1348 /*****************************************************************************/
1349 /*                                                                           */
1350 /*  Function Name : ProcessAdrWid                                          */
1351 /*                                                                           */
1352 /*  Description   : This function processes a WID of type WID_ADR and        */
1353 /*                  updates the cfg packet with the supplied value.          */
1354 /*                                                                           */
1355 /*  Inputs        : 1) Pointer to WID cfg structure                          */
1356 /*                  2) Value to set                                          */
1357 /*                                                                           */
1358 /*  Globals       :                                                          */
1359 /*                                                                           */
1360 /*  Processing    :                                                          */
1361 /*                                                                           */
1362 /*  Outputs       : None                                                     */
1363 /*                                                                           */
1364 /*  Returns       : None                                                     */
1365 /*                                                                           */
1366 /*  Issues        : None                                                     */
1367 /*                                                                           */
1368 /*  Revision History:                                                        */
1369 /*                                                                           */
1370 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1371 /*         08 01 2008   Ittiam          Draft                                */
1372 /*                                                                           */
1373 /*****************************************************************************/
1374
1375 void ProcessAdrWid(char *pcPacket, s32 *ps32PktLen,
1376                    tstrWID *pstrWID, u8 *pu8val)
1377 {
1378         u16 u16MsgLen = 0;
1379         s32 s32PktLen = *ps32PktLen;
1380
1381         if (pstrWID == NULL) {
1382                 PRINT_WRN(CORECONFIG_DBG, "Can't set Addr WID, NULL structure\n");
1383                 return;
1384         }
1385
1386         /* WID */
1387         pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
1388         pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
1389
1390         if (g_oper_mode == SET_CFG) {
1391                 /* Message Length */
1392                 u16MsgLen = MAC_ADDR_LEN;
1393
1394                 /* Length */
1395                 pcPacket[s32PktLen++] = (u8)u16MsgLen;
1396
1397                 /* Value */
1398                 extract_mac_addr(pu8val, pcPacket + s32PktLen);
1399                 s32PktLen += u16MsgLen;
1400         }
1401         *ps32PktLen = s32PktLen;
1402 }
1403
1404 /*****************************************************************************/
1405 /*                                                                           */
1406 /*  Function Name : ProcessBinWid                                          */
1407 /*                                                                           */
1408 /*  Description   : This function processes a WID of type WID_BIN_DATA and        */
1409 /*                  updates the cfg packet with the supplied value.          */
1410 /*                                                                           */
1411 /*  Inputs        : 1) Pointer to WID cfg structure                          */
1412 /*                  2) Name of file containing the binary data in text mode  */
1413 /*                                                                           */
1414 /*  Globals       :                                                          */
1415 /*                                                                           */
1416 /*  Processing    : The binary data is expected to be supplied through a     */
1417 /*                  file in text mode. This file is expected to be in the    */
1418 /*                  finject format. It is parsed, converted to binary format */
1419 /*                  and copied into g_cfg_pkt for further processing. This   */
1420 /*                  is obviously a round-about way of processing involving   */
1421 /*                  multiple (re)conversions between bin & ascii formats.    */
1422 /*                  But it is done nevertheless to retain uniformity and for */
1423 /*                  ease of debugging.                                       */
1424 /*                                                                           */
1425 /*  Outputs       : None                                                     */
1426 /*                                                                           */
1427 /*  Returns       : None                                                     */
1428 /*                                                                           */
1429
1430 /*  Issues        : None                                                     */
1431 /*                                                                           */
1432 /*  Revision History:                                                        */
1433 /*                                                                           */
1434 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1435 /*         08 01 2008   Ittiam          Draft                                */
1436 /*                                                                           */
1437 /*****************************************************************************/
1438
1439 void ProcessBinWid(char *pcPacket, s32 *ps32PktLen,
1440                    tstrWID *pstrWID, u8 *pu8val, s32 s32ValueSize)
1441 {
1442         u16 u16MsgLen = 0;
1443         u16 idx    = 0;
1444         s32 s32PktLen = *ps32PktLen;
1445         u8 u8checksum = 0;
1446
1447         if (pstrWID == NULL) {
1448                 PRINT_WRN(CORECONFIG_DBG, "Can't set BIN val, NULL structure\n");
1449                 return;
1450         }
1451
1452         /* WID */
1453         pcPacket[s32PktLen++] = (u8)(pstrWID->u16WIDid & 0xFF);
1454         pcPacket[s32PktLen++] = (u8)((pstrWID->u16WIDid >> 8) & 0xFF);
1455
1456         if (g_oper_mode == SET_CFG) {
1457                 /* Message Length */
1458                 u16MsgLen = (u16)s32ValueSize;
1459
1460                 /* Length */
1461                 /* pcPacket[s32PktLen++] = (u8)u16MsgLen; */
1462                 pcPacket[s32PktLen++] = (u8)(u16MsgLen  & 0xFF);
1463                 pcPacket[s32PktLen++] = (u8)((u16MsgLen >> 8) & 0xFF);
1464
1465                 /* Value */
1466                 for (idx = 0; idx < u16MsgLen; idx++)
1467                         pcPacket[s32PktLen++] = pu8val[idx];
1468
1469                 /* checksum */
1470                 for (idx = 0; idx < u16MsgLen; idx++)
1471                         u8checksum += pcPacket[MSG_HEADER_LEN + idx + 4];
1472
1473                 pcPacket[s32PktLen++] = u8checksum;
1474         }
1475         *ps32PktLen = s32PktLen;
1476 }
1477
1478
1479 /*****************************************************************************/
1480 /*                                                                           */
1481 /*  Function Name : further_process_response                                 */
1482 /*                                                                           */
1483 /*  Description   : This function parses the response frame got from the     */
1484 /*                  device.                                                  */
1485 /*                                                                           */
1486 /*  Inputs        : 1) The received response frame                           */
1487 /*                  2) WID                                                   */
1488 /*                  3) WID Length                                            */
1489 /*                  4) Output file handle                                    */
1490 /*                  5) Process Wid Number(i.e wid from --widn switch)        */
1491 /*                  6) Index the array in the Global Wid Structure.          */
1492 /*                                                                           */
1493 /*  Globals       : g_wid_num, gastrWIDs                                     */
1494 /*                                                                           */
1495 /*  Processing    : This function parses the response of the device depending*/
1496 /*                  WID type and writes it to the output file in Hex or      */
1497 /*                  decimal notation depending on the --getx or --get switch.*/
1498 /*                                                                           */
1499 /*  Outputs       : None                                                     */
1500 /*                                                                           */
1501 /*  Returns       : 0 on Success & -2 on Failure                             */
1502 /*                                                                           */
1503 /*  Issues        : None                                                     */
1504 /*                                                                           */
1505 /*  Revision History:                                                        */
1506 /*                                                                           */
1507 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1508 /*         08 01 2009   Ittiam          Draft                                */
1509 /*                                                                           */
1510 /*****************************************************************************/
1511
1512 s32 further_process_response(u8 *resp,
1513                                      u16 u16WIDid,
1514                                      u16 cfg_len,
1515                                      bool process_wid_num,
1516                                      u32 cnt,
1517                                      tstrWID *pstrWIDresult)
1518 {
1519         u32 retval = 0;
1520         u32 idx = 0;
1521         u8 cfg_chr  = 0;
1522         u16 cfg_sht  = 0;
1523         u32 cfg_int  = 0;
1524         u8 cfg_str[256] = {0};
1525         tenuWIDtype enuWIDtype = WID_UNDEF;
1526
1527         if (process_wid_num)
1528                 enuWIDtype = get_wid_type(g_wid_num);
1529         else
1530                 enuWIDtype = gastrWIDs[cnt].enuWIDtype;
1531
1532
1533         switch (enuWIDtype) {
1534         case WID_CHAR:
1535                 cfg_chr = resp[idx];
1536                 /*Set local copy of WID*/
1537                 *(pstrWIDresult->ps8WidVal) = cfg_chr;
1538                 break;
1539
1540         case WID_SHORT:
1541         {
1542                 u16 *pu16val = (u16 *)(pstrWIDresult->ps8WidVal);
1543                 cfg_sht = MAKE_WORD16(resp[idx], resp[idx + 1]);
1544                 /*Set local copy of WID*/
1545                 /* pstrWIDresult->ps8WidVal = (s8*)(s32)cfg_sht; */
1546                 *pu16val = cfg_sht;
1547                 break;
1548         }
1549
1550         case WID_INT:
1551         {
1552                 u32 *pu32val = (u32 *)(pstrWIDresult->ps8WidVal);
1553                 cfg_int = MAKE_WORD32(
1554                                 MAKE_WORD16(resp[idx], resp[idx + 1]),
1555                                 MAKE_WORD16(resp[idx + 2], resp[idx + 3])
1556                                 );
1557                 /*Set local copy of WID*/
1558                 /* pstrWIDresult->ps8WidVal = (s8*)cfg_int; */
1559                 *pu32val = cfg_int;
1560                 break;
1561         }
1562
1563         case WID_STR:
1564                 memcpy(cfg_str, resp + idx, cfg_len);
1565                 /* cfg_str[cfg_len] = '\0'; //mostafa: no need currently for NULL termination */
1566                 if (pstrWIDresult->s32ValueSize >= cfg_len) {
1567                         memcpy(pstrWIDresult->ps8WidVal, cfg_str, cfg_len); /* mostafa: no need currently for the extra NULL byte */
1568                         pstrWIDresult->s32ValueSize = cfg_len;
1569                 } else {
1570                         PRINT_ER("allocated WID buffer length is smaller than the received WID Length\n");
1571                         retval = -2;
1572                 }
1573
1574                 break;
1575
1576         case WID_ADR:
1577                 create_mac_addr(cfg_str, resp + idx);
1578
1579                 strncpy(pstrWIDresult->ps8WidVal, cfg_str, strlen(cfg_str));
1580                 pstrWIDresult->ps8WidVal[strlen(cfg_str)] = '\0';
1581                 break;
1582
1583         case WID_IP:
1584                 cfg_int = MAKE_WORD32(
1585                                 MAKE_WORD16(resp[idx], resp[idx + 1]),
1586                                 MAKE_WORD16(resp[idx + 2], resp[idx + 3])
1587                                 );
1588                 conv_int_to_ip(cfg_str, cfg_int);
1589                 break;
1590
1591         case WID_BIN_DATA:
1592                 if (pstrWIDresult->s32ValueSize >= cfg_len) {
1593                         memcpy(pstrWIDresult->ps8WidVal, resp + idx, cfg_len);
1594                         pstrWIDresult->s32ValueSize = cfg_len;
1595                 } else {
1596                         PRINT_ER("Allocated WID buffer length is smaller than the received WID Length Err(%d)\n", retval);
1597                         retval = -2;
1598                 }
1599                 break;
1600
1601         default:
1602                 PRINT_ER("ERROR: Check config database: Error(%d)\n", retval);
1603                 retval = -2;
1604                 break;
1605         }
1606
1607         return retval;
1608 }
1609
1610 /*****************************************************************************/
1611 /*                                                                           */
1612 /*  Function Name : ParseResponse                                           */
1613 /*                                                                           */
1614 /*  Description   : This function parses the command-line options and        */
1615 /*                  creates the config packets which can be sent to the WLAN */
1616 /*                  station.                                                 */
1617 /*                                                                           */
1618 /*  Inputs        : 1) The received response frame                           */
1619 /*                                                                           */
1620 /*  Globals       : g_opt_list, gastrWIDs                                        */
1621 /*                                                                           */
1622 /*  Processing    : This function parses the options and creates different   */
1623 /*                  types of packets depending upon the WID-type             */
1624 /*                  corresponding to the option.                             */
1625 /*                                                                           */
1626 /*  Outputs       : None                                                     */
1627 /*                                                                           */
1628 /*  Returns       : 0 on Success & -1 on Failure                             */
1629 /*                                                                           */
1630 /*  Issues        : None                                                     */
1631 /*                                                                           */
1632 /*  Revision History:                                                        */
1633 /*                                                                           */
1634 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1635 /*         08 01 2008   Ittiam          Draft                                */
1636 /*                                                                           */
1637 /*****************************************************************************/
1638
1639 s32 ParseResponse(u8 *resp, tstrWID *pstrWIDcfgResult)
1640 {
1641         u16 u16RespLen = 0;
1642         u16 u16WIDid  = 0;
1643         u16 cfg_len  = 0;
1644         tenuWIDtype enuWIDtype = WID_UNDEF;
1645         bool num_wid_processed = false;
1646         u32 cnt = 0;
1647         u32 idx = 0;
1648         u32 ResCnt = 0;
1649         /* Check whether the received frame is a valid response */
1650         if (RESP_MSG_TYPE != resp[0]) {
1651                 PRINT_INFO(CORECONFIG_DBG, "Received Message format incorrect.\n");
1652                 return -1;
1653         }
1654
1655         /* Extract Response Length */
1656         u16RespLen = MAKE_WORD16(resp[2], resp[3]);
1657         Res_Len = u16RespLen;
1658
1659         for (idx = MSG_HEADER_LEN; idx < u16RespLen; ) {
1660                 u16WIDid = MAKE_WORD16(resp[idx], resp[idx + 1]);
1661                 cfg_len = resp[idx + 2];
1662                 /* Incase of Bin Type Wid, the length is given by two byte field      */
1663                 enuWIDtype = get_wid_type(u16WIDid);
1664                 if (WID_BIN_DATA == enuWIDtype) {
1665                         cfg_len |= ((u16)resp[idx + 3] << 8) & 0xFF00;
1666                         idx++;
1667                 }
1668                 idx += 3;
1669                 if ((u16WIDid == g_wid_num) && (!num_wid_processed)) {
1670                         num_wid_processed = true;
1671
1672                         if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, true, 0, &pstrWIDcfgResult[ResCnt])) {
1673                                 return -2;
1674                         }
1675                         ResCnt++;
1676                 } else {
1677                         for (cnt = 0; cnt < g_num_total_switches; cnt++) {
1678                                 if (gastrWIDs[cnt].u16WIDid == u16WIDid) {
1679                                         if (-2 == further_process_response(&resp[idx], u16WIDid, cfg_len, false, cnt,
1680                                                                            &pstrWIDcfgResult[ResCnt])) {
1681                                                 return -2;
1682                                         }
1683                                         ResCnt++;
1684                                 }
1685                         }
1686                 }
1687                 idx += cfg_len;
1688                 /* In case if BIN type Wid, The last byte of the Cfg packet is the    */
1689                 /* Checksum. The WID Length field does not accounts for the checksum. */
1690                 /* The Checksum is discarded.                                         */
1691                 if (WID_BIN_DATA == enuWIDtype) {
1692                         idx++;
1693                 }
1694         }
1695
1696         return 0;
1697 }
1698
1699 /**
1700  *  @brief              parses the write response [just detects its status: success or failure]
1701  *  @details
1702  *  @param[in]  pu8RespBuffer The Response to be parsed
1703  *  @return     Error code indicating Write Operation status:
1704  *                            WRITE_RESP_SUCCESS (1) => Write Success.
1705  *                            WILC_FAIL (-100)               => Write Failure.
1706  *  @note
1707  *  @author             Ittiam
1708  *  @date               11 Aug 2009
1709  *  @version    1.0
1710  */
1711
1712 s32 ParseWriteResponse(u8 *pu8RespBuffer)
1713 {
1714         s32 s32Error = WILC_FAIL;
1715         u16 u16WIDtype = (u16)WID_NIL;
1716
1717         /* Check whether the received frame is a valid response */
1718         if (RESP_MSG_TYPE != pu8RespBuffer[0]) {
1719                 PRINT_ER("Received Message format incorrect.\n");
1720                 return WILC_FAIL;
1721         }
1722
1723         u16WIDtype = MAKE_WORD16(pu8RespBuffer[4], pu8RespBuffer[5]);
1724
1725         /* Check for WID_STATUS ID and then check the length and status value */
1726         if ((u16WIDtype == WID_STATUS) &&
1727             (pu8RespBuffer[6] == 1) &&
1728             (pu8RespBuffer[7] == WRITE_RESP_SUCCESS)) {
1729                 s32Error = WRITE_RESP_SUCCESS;
1730                 return s32Error;
1731         }
1732
1733         /* If the length or status are not as expected return failure    */
1734         s32Error = WILC_FAIL;
1735         return s32Error;
1736
1737 }
1738
1739 /**
1740  *  @brief                      creates the header of the Configuration Packet
1741  *  @details
1742  *  @param[in,out] pcpacket The Configuration Packet
1743  *  @param[in,out] ps32PacketLength Length of the Configuration Packet
1744  *  @return             Error code indicating success/failure
1745  *  @note
1746  *  @author             aismail
1747  *  @date               18 Feb 2012
1748  *  @version            1.0
1749  */
1750
1751 s32 CreatePacketHeader(char *pcpacket, s32 *ps32PacketLength)
1752 {
1753         s32 s32Error = WILC_SUCCESS;
1754         u16 u16MsgLen = (u16)(*ps32PacketLength);
1755         u16 u16MsgInd = 0;
1756
1757         /* The format of the message is:                                         */
1758         /* +-------------------------------------------------------------------+ */
1759         /* | Message Type | Message ID |  Message Length |Message body         | */
1760         /* +-------------------------------------------------------------------+ */
1761         /* |     1 Byte   |   1 Byte   |     2 Bytes     | Message Length - 4  | */
1762         /* +-------------------------------------------------------------------+ */
1763
1764         /* The format of a message body of a message type 'W' is:                */
1765         /* +-------------------------------------------------------------------+ */
1766         /* | WID0      | WID0 Length | WID0 Value  | ......................... | */
1767         /* +-------------------------------------------------------------------+ */
1768         /* | 2 Bytes   | 1 Byte      | WID0 Length | ......................... | */
1769         /* +-------------------------------------------------------------------+ */
1770
1771
1772
1773         /* Message Type */
1774         if (g_oper_mode == SET_CFG)
1775                 pcpacket[u16MsgInd++] = WRITE_MSG_TYPE;
1776         else
1777                 pcpacket[u16MsgInd++] = QUERY_MSG_TYPE;
1778
1779         /* Sequence Number */
1780         pcpacket[u16MsgInd++] = g_seqno++;
1781
1782         /* Message Length */
1783         pcpacket[u16MsgInd++] = (u8)(u16MsgLen & 0xFF);
1784         pcpacket[u16MsgInd++] = (u8)((u16MsgLen >> 8) & 0xFF);
1785
1786         *ps32PacketLength = u16MsgLen;
1787
1788         return s32Error;
1789 }
1790
1791 /**
1792  *  @brief              creates Configuration packet based on the Input WIDs
1793  *  @details
1794  *  @param[in]  pstrWIDs WIDs to be sent in the configuration packet
1795  *  @param[in]  u32WIDsCount number of WIDs to be sent in the configuration packet
1796  *  @param[out]         ps8packet The created Configuration Packet
1797  *  @param[out]         ps32PacketLength Length of the created Configuration Packet
1798  *  @return     Error code indicating success/failure
1799  *  @note
1800  *  @author
1801  *  @date               1 Mar 2012
1802  *  @version    1.0
1803  */
1804
1805 s32 CreateConfigPacket(s8 *ps8packet, s32 *ps32PacketLength,
1806                                tstrWID *pstrWIDs, u32 u32WIDsCount)
1807 {
1808         s32 s32Error = WILC_SUCCESS;
1809         u32 u32idx = 0;
1810         *ps32PacketLength = MSG_HEADER_LEN;
1811         for (u32idx = 0; u32idx < u32WIDsCount; u32idx++) {
1812                 switch (pstrWIDs[u32idx].enuWIDtype) {
1813                 case WID_CHAR:
1814                         ProcessCharWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
1815                                        pstrWIDs[u32idx].ps8WidVal);
1816                         break;
1817
1818                 case WID_SHORT:
1819                         ProcessShortWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
1820                                         pstrWIDs[u32idx].ps8WidVal);
1821                         break;
1822
1823                 case WID_INT:
1824                         ProcessIntWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
1825                                       pstrWIDs[u32idx].ps8WidVal);
1826                         break;
1827
1828                 case WID_STR:
1829                         ProcessStrWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
1830                                       pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize);
1831                         break;
1832
1833                 case WID_IP:
1834                         ProcessIPwid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
1835                                      pstrWIDs[u32idx].ps8WidVal);
1836                         break;
1837
1838                 case WID_BIN_DATA:
1839                         ProcessBinWid(ps8packet, ps32PacketLength, &pstrWIDs[u32idx],
1840                                       pstrWIDs[u32idx].ps8WidVal, pstrWIDs[u32idx].s32ValueSize);
1841                         break;
1842
1843                 default:
1844                         PRINT_ER("ERROR: Check Config database\n");
1845                 }
1846         }
1847
1848         CreatePacketHeader(ps8packet, ps32PacketLength);
1849
1850         return s32Error;
1851 }
1852
1853 s32 ConfigWaitResponse(char *pcRespBuffer, s32 s32MaxRespBuffLen, s32 *ps32BytesRead,
1854                                bool bRespRequired)
1855 {
1856         s32 s32Error = WILC_SUCCESS;
1857         /*bug 3878*/
1858         /*removed to caller function*/
1859         /*gstrConfigPktInfo.pcRespBuffer = pcRespBuffer;
1860          * gstrConfigPktInfo.s32MaxRespBuffLen = s32MaxRespBuffLen;
1861          * gstrConfigPktInfo.bRespRequired = bRespRequired;*/
1862
1863
1864         if (gstrConfigPktInfo.bRespRequired) {
1865                 down(&SemHandlePktResp);
1866
1867                 *ps32BytesRead = gstrConfigPktInfo.s32BytesRead;
1868         }
1869
1870         memset((void *)(&gstrConfigPktInfo), 0, sizeof(tstrConfigPktInfo));
1871
1872         return s32Error;
1873 }
1874
1875 s32 ConfigProvideResponse(char *pcRespBuffer, s32 s32RespLen)
1876 {
1877         s32 s32Error = WILC_SUCCESS;
1878
1879         if (gstrConfigPktInfo.bRespRequired) {
1880                 if (s32RespLen <= gstrConfigPktInfo.s32MaxRespBuffLen) {
1881                         memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, s32RespLen);
1882                         gstrConfigPktInfo.s32BytesRead = s32RespLen;
1883                 } else {
1884                         memcpy(gstrConfigPktInfo.pcRespBuffer, pcRespBuffer, gstrConfigPktInfo.s32MaxRespBuffLen);
1885                         gstrConfigPktInfo.s32BytesRead = gstrConfigPktInfo.s32MaxRespBuffLen;
1886                         PRINT_ER("BusProvideResponse() Response greater than the prepared Buffer Size\n");
1887                 }
1888
1889                 up(&SemHandlePktResp);
1890         }
1891
1892         return s32Error;
1893 }
1894
1895 /**
1896  *  @brief              writes the received packet pu8RxPacket in the global Rx FIFO buffer
1897  *  @details
1898  *  @param[in]  pu8RxPacket The received packet
1899  *  @param[in]  s32RxPacketLen Length of the received packet
1900  *  @return     Error code indicating success/failure
1901  *  @note
1902  *
1903  *  @author     mabubakr
1904  *  @date               1 Mar 2012
1905  *  @version    1.0
1906  */
1907
1908 s32 ConfigPktReceived(u8 *pu8RxPacket, s32 s32RxPacketLen)
1909 {
1910         s32 s32Error = WILC_SUCCESS;
1911         u8 u8MsgType = 0;
1912
1913         u8MsgType = pu8RxPacket[0];
1914
1915         switch (u8MsgType) {
1916         case 'R':
1917                 ConfigProvideResponse(pu8RxPacket, s32RxPacketLen);
1918
1919                 break;
1920
1921         case 'N':
1922                 PRINT_INFO(CORECONFIG_DBG, "NetworkInfo packet received\n");
1923                 NetworkInfoReceived(pu8RxPacket, s32RxPacketLen);
1924                 break;
1925
1926         case 'I':
1927                 GnrlAsyncInfoReceived(pu8RxPacket, s32RxPacketLen);
1928                 break;
1929
1930         case 'S':
1931                 host_int_ScanCompleteReceived(pu8RxPacket, s32RxPacketLen);
1932                 break;
1933
1934         default:
1935                 PRINT_ER("ConfigPktReceived(): invalid received msg type at the Core Configurator\n");
1936                 break;
1937         }
1938
1939         return s32Error;
1940 }
1941
1942 /**
1943  *  @brief              Deinitializes the Core Configurator
1944  *  @details
1945  *  @return     Error code indicating success/failure
1946  *  @note
1947  *  @author     mabubakr
1948  *  @date               1 Mar 2012
1949  *  @version    1.0
1950  */
1951
1952 s32 CoreConfiguratorDeInit(void)
1953 {
1954         s32 s32Error = WILC_SUCCESS;
1955
1956         PRINT_D(CORECONFIG_DBG, "CoreConfiguratorDeInit()\n");
1957
1958
1959         return s32Error;
1960 }
1961
1962 /*Using the global handle of the driver*/
1963 extern wilc_wlan_oup_t *gpstrWlanOps;
1964 /**
1965  *  @brief              sends certain Configuration Packet based on the input WIDs pstrWIDs
1966  *  using driver config layer
1967  *
1968  *  @details
1969  *  @param[in]  pstrWIDs WIDs to be sent in the configuration packet
1970  *  @param[in]  u32WIDsCount number of WIDs to be sent in the configuration packet
1971  *  @param[out]         pu8RxResp The received Packet Response
1972  *  @param[out]         ps32RxRespLen Length of the received Packet Response
1973  *  @return     Error code indicating success/failure
1974  *  @note
1975  *  @author     mabubakr
1976  *  @date               1 Mar 2012
1977  *  @version    1.0
1978  */
1979 s32 SendConfigPkt(u8 u8Mode, tstrWID *pstrWIDs,
1980                           u32 u32WIDsCount, bool bRespRequired, u32 drvHandler)
1981 {
1982         s32 counter = 0, ret = 0;
1983         if (gpstrWlanOps == NULL) {
1984                 PRINT_D(CORECONFIG_DBG, "Net Dev is still not initialized\n");
1985                 return 1;
1986         } else {
1987                 PRINT_D(CORECONFIG_DBG, "Net Dev is initialized\n");
1988         }
1989         if (gpstrWlanOps->wlan_cfg_set == NULL ||
1990             gpstrWlanOps->wlan_cfg_get == NULL) {
1991                 PRINT_D(CORECONFIG_DBG, "Set and Get is still not initialized\n");
1992                 return 1;
1993         } else {
1994                 PRINT_D(CORECONFIG_DBG, "SET is initialized\n");
1995         }
1996         if (u8Mode == GET_CFG) {
1997                 for (counter = 0; counter < u32WIDsCount; counter++) {
1998                         PRINT_INFO(CORECONFIG_DBG, "Sending CFG packet [%d][%d]\n", !counter,
1999                                    (counter == u32WIDsCount - 1));
2000                         if (!gpstrWlanOps->wlan_cfg_get(!counter,
2001                                                         pstrWIDs[counter].u16WIDid,
2002                                                         (counter == u32WIDsCount - 1), drvHandler)) {
2003                                 ret = -1;
2004                                 printk("[Sendconfigpkt]Get Timed out\n");
2005                                 break;
2006                         }
2007                 }
2008                 /**
2009                  *      get the value
2010                  **/
2011                 counter = 0;
2012                 for (counter = 0; counter < u32WIDsCount; counter++) {
2013                         pstrWIDs[counter].s32ValueSize = gpstrWlanOps->wlan_cfg_get_value(
2014                                         pstrWIDs[counter].u16WIDid,
2015                                         pstrWIDs[counter].ps8WidVal, pstrWIDs[counter].s32ValueSize);
2016
2017                 }
2018         } else if (u8Mode == SET_CFG) {
2019                 for (counter = 0; counter < u32WIDsCount; counter++) {
2020                         PRINT_D(CORECONFIG_DBG, "Sending config SET PACKET WID:%x\n", pstrWIDs[counter].u16WIDid);
2021                         if (!gpstrWlanOps->wlan_cfg_set(!counter,
2022                                                         pstrWIDs[counter].u16WIDid, pstrWIDs[counter].ps8WidVal,
2023                                                         pstrWIDs[counter].s32ValueSize,
2024                                                         (counter == u32WIDsCount - 1), drvHandler)) {
2025                                 ret = -1;
2026                                 printk("[Sendconfigpkt]Set Timed out\n");
2027                                 break;
2028                         }
2029                 }
2030         }
2031
2032         return ret;
2033 }