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