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