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