1 /*
2 * CmdInterpretWext.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35 #include "tidef.h"
36 #include "WlanDrvIf.h"
37 #include "tiwlnif.h"
38 #include "osDot11.h"
39 #include "802_11Defs.h"
40 #include "paramOut.h"
41 #include "coreDefaultParams.h"
42 #include "version.h"
43 #include "osApi.h"
44 #include "CmdHndlr.h"
45 #include "CmdInterpret.h"
46 #include "CmdInterpretWext.h"
47 #include "TI_IPC_Api.h"
48 #include "WlanDrvIf.h"
49 #include <linux/wireless.h>
50 #include <linux/if_arp.h>
51 #include <asm/uaccess.h>
52 #include <net/iw_handler.h>
53 #include "privateCmd.h"
54 #include "DrvMain.h"
55 #include "CmdDispatcher.h"
56 #include "EvHandler.h"
57 #include "admCtrl.h"
58
59
60 static TI_INT32 cmdInterpret_Event(IPC_EV_DATA* pData);
61 static int cmdInterpret_setSecurityParams (TI_HANDLE hCmdInterpret);
62 static int cmdInterpret_initEvents(TI_HANDLE hCmdInterpret);
63 static int cmdInterpret_unregisterEvents(TI_HANDLE hCmdInterpret, TI_HANDLE hEvHandler);
64
65 #define CHECK_PENDING_RESULT(x,y) if (x == COMMAND_PENDING) { os_printf ("Unexpected COMMAND PENDING result (cmd = 0x%x)\n",y->paramType); break; }
66
67 static const char *ieee80211_modes[] = {
68 "?", "IEEE 802.11 B", "IEEE 802.11 A", "IEEE 802.11 BG", "IEEE 802.11 ABG"
69 };
70 #ifdef XCC_MODULE_INCLUDED
71 typedef struct
72 {
73
74 TI_UINT8 *assocRespBuffer;
75 TI_UINT32 assocRespLen;
76 } cckm_assocInformation_t;
77
78 #define ASSOC_RESP_FIXED_DATA_LEN 6
79 #define MAX_BEACON_BODY_LENGTH 350
80 #define BEACON_HEADER_FIX_SIZE 12
81 #define CCKM_START_EVENT_SIZE 23 /* cckm-start string + timestamp + bssid + null */
82 #endif
83
84 /* Initialize the CmdInterpreter module */
cmdInterpret_Create(TI_HANDLE hOs)85 TI_HANDLE cmdInterpret_Create (TI_HANDLE hOs)
86 {
87 cmdInterpret_t *pCmdInterpret;
88
89 /* Allocate memory for object */
90 pCmdInterpret = os_memoryAlloc (hOs, sizeof(cmdInterpret_t));
91
92 /* In case of failure -> return NULL */
93 if (!pCmdInterpret)
94 {
95 os_printf ("cmdInterpret_init: failed to allocate memory...aborting\n");
96 return NULL;
97 }
98
99 /* Clear all fields in cmdInterpreter module object */
100 os_memoryZero (hOs, pCmdInterpret, sizeof (cmdInterpret_t));
101
102 /* Save handlers */
103 pCmdInterpret->hOs = hOs;
104
105 /* Return pointer to object */
106 return (TI_HANDLE)pCmdInterpret;
107 }
108
109
110 /* Deinitialize the cmdInterpreter module */
cmdInterpret_Destroy(TI_HANDLE hCmdInterpret,TI_HANDLE hEvHandler)111 TI_STATUS cmdInterpret_Destroy (TI_HANDLE hCmdInterpret, TI_HANDLE hEvHandler)
112 {
113 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret;
114
115 /* Unregister events */
116 cmdInterpret_unregisterEvents ((TI_HANDLE)pCmdInterpret, hEvHandler);
117
118 /* Release allocated memory */
119 os_memoryFree (pCmdInterpret->hOs, pCmdInterpret, sizeof(cmdInterpret_t));
120
121 return TI_OK;
122 }
123
124
cmdInterpret_Init(TI_HANDLE hCmdInterpret,TStadHandlesList * pStadHandles)125 void cmdInterpret_Init (TI_HANDLE hCmdInterpret, TStadHandlesList *pStadHandles)
126 {
127 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret;
128
129 pCmdInterpret->hCmdHndlr = pStadHandles->hCmdHndlr;
130 pCmdInterpret->hEvHandler = pStadHandles->hEvHandler;
131 pCmdInterpret->hCmdDispatch = pStadHandles->hCmdDispatch;
132
133 /* Register to driver events */
134 cmdInterpret_initEvents (hCmdInterpret);
135 }
136
137
138 /* Handle a single command */
cmdInterpret_convertAndExecute(TI_HANDLE hCmdInterpret,TConfigCommand * cmdObj)139 int cmdInterpret_convertAndExecute(TI_HANDLE hCmdInterpret, TConfigCommand *cmdObj)
140 {
141 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret;
142 paramInfo_t *pParam;
143 TI_STATUS res = TI_NOK;
144 int i,j;
145
146 union iwreq_data *wrqu = (union iwreq_data *)cmdObj->buffer1;
147
148 cmdObj->return_code = WEXT_NOT_SUPPORTED;
149 pParam = (paramInfo_t *)os_memoryAlloc(pCmdInterpret->hOs, sizeof(paramInfo_t));
150 if (!pParam)
151 return res;
152 /* Check user request */
153 switch (cmdObj->cmd)
154 {
155
156 /* get name == wireless protocol - used to verify the presence of Wireless Extensions*/
157 case SIOCGIWNAME:
158 os_memoryCopy(pCmdInterpret->hOs, cmdObj->buffer1, WLAN_PROTOCOL_NAME, IFNAMSIZ);
159 res = TI_OK;
160 break;
161
162 /* Set channel / frequency */
163 case SIOCSIWFREQ:
164 {
165 /* If there is a given channel */
166 if (wrqu->freq.m != 0)
167 {
168 pParam->paramType = SITE_MGR_DESIRED_CHANNEL_PARAM;
169 pParam->paramLength = sizeof(TI_UINT32);
170 pParam->content.siteMgrDesiredChannel = wrqu->freq.m;
171
172 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam);
173 CHECK_PENDING_RESULT(res,pParam)
174 }
175 break;
176 }
177
178 /* Get channel / frequency */
179 case SIOCGIWFREQ:
180 {
181 pParam->paramType = SITE_MGR_CURRENT_CHANNEL_PARAM;
182 pParam->paramLength = sizeof(TI_UINT32);
183
184 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch, pParam);
185 if(res == NO_SITE_SELECTED_YET)
186 res = TI_OK;
187
188 CHECK_PENDING_RESULT(res,pParam)
189
190 if (res == TI_OK)
191 {
192 wrqu->freq.m = pParam->content.siteMgrCurrentChannel;
193 wrqu->freq.e = 3;
194 wrqu->freq.i = 0;
195 }
196 break;
197 }
198
199 /* Set Mode (Adhoc / infrastructure) */
200 case SIOCSIWMODE:
201 {
202 pParam->paramType = SME_DESIRED_BSS_TYPE_PARAM;
203 pParam->paramLength = sizeof(ScanBssType_e);
204
205 switch (wrqu->mode)
206 {
207 case IW_MODE_AUTO:
208 pParam->content.smeDesiredBSSType = BSS_ANY;
209 break;
210 case IW_MODE_ADHOC:
211 pParam->content.smeDesiredBSSType = BSS_INDEPENDENT;
212 break;
213 case IW_MODE_INFRA:
214 pParam->content.smeDesiredBSSType = BSS_INFRASTRUCTURE;
215 break;
216 default:
217 res = -EOPNOTSUPP;
218 goto cmd_end;
219 }
220
221 res = cmdDispatch_SetParam(pCmdInterpret->hCmdDispatch, pParam);
222 CHECK_PENDING_RESULT(res,pParam)
223
224 /* also set the site mgr desired mode */
225 pParam->paramType = SITE_MGR_DESIRED_BSS_TYPE_PARAM;
226 res = cmdDispatch_SetParam(pCmdInterpret->hCmdDispatch, pParam);
227 CHECK_PENDING_RESULT(res,pParam)
228
229 break;
230 }
231
232 /* Get Mode (Adhoc / infrastructure) */
233 case SIOCGIWMODE:
234 {
235 pParam->paramType = SME_DESIRED_BSS_TYPE_PARAM;
236 pParam->paramLength = sizeof(ScanBssType_e);
237 res = cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam);
238 CHECK_PENDING_RESULT(res,pParam)
239
240 switch (pParam->content.smeDesiredBSSType)
241 {
242 case BSS_ANY:
243 wrqu->mode = IW_MODE_AUTO;
244 break;
245 case BSS_INDEPENDENT:
246 wrqu->mode = IW_MODE_ADHOC;
247 break;
248 case BSS_INFRASTRUCTURE:
249 wrqu->mode = IW_MODE_INFRA;
250 break;
251 default:
252 break;
253 }
254
255 break;
256 }
257
258 /* Set sensitivity (Rssi roaming threshold)*/
259 case SIOCSIWSENS:
260 {
261 /* First get the current roaming configuration as a whole */
262 pParam->paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION;
263 pParam->paramLength = sizeof (roamingMngrConfigParams_t);
264 res = cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam);
265
266 CHECK_PENDING_RESULT(res,pParam)
267
268 /* Now change the low rssi threshold supplied by the user */
269 pParam->content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowRssiThreshold = wrqu->param.value;
270
271 /* And set the parameters back to the roaming module */
272 res = cmdDispatch_SetParam(pCmdInterpret->hCmdDispatch, pParam);
273
274 CHECK_PENDING_RESULT(res,pParam)
275
276 break;
277 }
278
279 /* Get sensitivity (Rssi threshold OR CCA?)*/
280 case SIOCGIWSENS:
281 {
282 pParam->paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION;
283 pParam->paramLength = sizeof (roamingMngrConfigParams_t);
284 res = cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam);
285
286 CHECK_PENDING_RESULT(res,pParam)
287
288 if (res == TI_OK)
289 {
290 wrqu->param.value = pParam->content.roamingConfigBuffer.roamingMngrThresholdsConfig.lowRssiThreshold;
291 wrqu->param.disabled = (wrqu->param.value == 0);
292 wrqu->param.fixed = 1;
293 }
294
295 break;
296 }
297
298 /* Get a range of parameters regarding the device capabilities */
299 case SIOCGIWRANGE:
300 {
301 struct iw_point *data = (struct iw_point *) cmdObj->buffer1;
302 struct iw_range *range = (struct iw_range *) cmdObj->buffer2;
303 int i;
304
305 /* Reset structure */
306 data->length = sizeof(struct iw_range);
307 os_memorySet(pCmdInterpret->hOs, range, 0, sizeof(struct iw_range));
308
309 /* Wireless Extension version info */
310 range->we_version_compiled = WIRELESS_EXT; /* Must be WIRELESS_EXT */
311 range->we_version_source = 19; /* Last update of source */
312
313 /* estimated maximum TCP throughput values (bps) */
314 range->throughput = MAX_THROUGHPUT;
315
316 /* NWID (or domain id) */
317 range->min_nwid = 0; /* Minimal NWID we are able to set */
318 range->max_nwid = 0; /* Maximal NWID we are able to set */
319
320 /* Old Frequency - no need to support this*/
321 range->old_num_channels = 0;
322 range->old_num_frequency = 0;
323
324 /* Wireless event capability bitmasks */
325 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
326 IW_EVENT_CAPA_SET(range->event_capa, IWEVREGISTERED);
327 IW_EVENT_CAPA_SET(range->event_capa, IWEVEXPIRED);
328
329 /* signal level threshold range */
330 range->sensitivity = 0;
331
332 /* Rates */
333 pParam->paramType = SITE_MGR_DESIRED_SUPPORTED_RATE_SET_PARAM;
334 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch, pParam );
335
336 CHECK_PENDING_RESULT(res,pParam)
337
338 /* Number of entries in the rates list */
339 range->num_bitrates = pParam->content.siteMgrDesiredSupportedRateSet.len;
340 for (i=0; i<pParam->content.siteMgrDesiredSupportedRateSet.len; i++)
341 {
342 range->bitrate[i] = ((pParam->content.siteMgrDesiredSupportedRateSet.ratesString[i] & 0x7F) * 500000);
343 }
344
345 /* RTS threshold */
346 range->min_rts = TWD_RTS_THRESHOLD_MIN; /* Minimal RTS threshold */
347 range->max_rts = TWD_RTS_THRESHOLD_DEF; /* Maximal RTS threshold */
348
349 /* Frag threshold */
350 range->min_frag = TWD_FRAG_THRESHOLD_MIN; /* Minimal frag threshold */
351 range->max_frag = TWD_FRAG_THRESHOLD_DEF; /* Maximal frag threshold */
352
353 /* Power Management duration & timeout */
354 range->min_pmp = 0; /* Minimal PM period */
355 range->max_pmp = 0; /* Maximal PM period */
356 range->min_pmt = 0; /* Minimal PM timeout */
357 range->max_pmt = 0; /* Maximal PM timeout */
358 range->pmp_flags = IW_POWER_ON; /* How to decode max/min PM period */
359 range->pmt_flags = IW_POWER_ON; /* How to decode max/min PM timeout */
360
361 /* What Power Management options are supported */
362 range->pm_capa = IW_POWER_UNICAST_R | /* Receive only unicast messages */
363 IW_POWER_MULTICAST_R | /* Receive only multicast messages */
364 IW_POWER_ALL_R | /* Receive all messages though PM */
365 IW_POWER_FORCE_S | /* Force PM procedure for sending unicast */
366 IW_POWER_PERIOD | /* Value is a period/duration of */
367 IW_POWER_TIMEOUT; /* Value is a timeout (to go asleep) */
368
369 /* Transmit power */
370 range->txpower_capa = IW_TXPOW_RELATIVE | IW_TXPOW_RANGE; /* What options are supported */
371 range->num_txpower = 5; /* Number of entries in the list */
372 range->txpower[0] = 1; /* list of values (maximum is IW_MAX_TXPOWER = 8) */
373 range->txpower[1] = 2; /* list of values (maximum is IW_MAX_TXPOWER = 8) */
374 range->txpower[2] = 3; /* list of values (maximum is IW_MAX_TXPOWER = 8) */
375 range->txpower[3] = 4; /* list of values (maximum is IW_MAX_TXPOWER = 8) */
376 range->txpower[4] = 5; /* list of values (maximum is IW_MAX_TXPOWER = 8) */
377
378 /* Retry limits and lifetime */
379 range->retry_capa = 0; /* What retry options are supported */
380 range->retry_flags = 0; /* How to decode max/min retry limit */
381 range->r_time_flags = 0; /* How to decode max/min retry life */
382 range->min_retry = 0; /* Minimal number of retries */
383 range->max_retry = 0; /* Maximal number of retries */
384 range->min_r_time = 0; /* Minimal retry lifetime */
385 range->max_r_time = 0; /* Maximal retry lifetime */
386
387 /* Get Supported channels */
388 pParam->paramType = SITE_MGR_RADIO_BAND_PARAM;
389 res = cmdDispatch_GetParam( pCmdInterpret->hCmdDispatch, pParam );
390
391 CHECK_PENDING_RESULT(res,pParam)
392
393 /* pParam->content.siteMgrRadioBand contains the current band, now get list of supported channels */
394 pParam->paramType = REGULATORY_DOMAIN_ALL_SUPPORTED_CHANNELS;
395 res = cmdDispatch_GetParam( pCmdInterpret->hCmdDispatch, pParam );
396
397 CHECK_PENDING_RESULT(res,pParam)
398
399 range->num_channels = pParam->content.supportedChannels.sizeOfList; /* Number of channels [0; num - 1] */
400 range->num_frequency = pParam->content.supportedChannels.sizeOfList; /* Number of entry in the list */
401
402 for (i=0; i<pParam->content.supportedChannels.sizeOfList; i++)
403 {
404 range->freq[i].e = 0;
405 range->freq[i].m = i;
406 range->freq[i].i = pParam->content.supportedChannels.listOfChannels[i]+1;
407 }
408
409 /* Encoder (Encryption) capabilities */
410 range->num_encoding_sizes = 4;
411 /* 64(40) bits WEP */
412 range->encoding_size[0] = WEP_KEY_LENGTH_40;
413 /* 128(104) bits WEP */
414 range->encoding_size[1] = WEP_KEY_LENGTH_104;
415 /* 256 bits for WPA-PSK */
416 range->encoding_size[2] = TKIP_KEY_LENGTH;
417 /* 128 bits for WPA2-PSK */
418 range->encoding_size[3] = AES_KEY_LENGTH;
419 /* 4 keys are allowed */
420 range->max_encoding_tokens = 4;
421
422 range->encoding_login_index = 0; /* token index for login token */
423
424 /* Encryption capabilities */
425 range->enc_capa = IW_ENC_CAPA_WPA |
426 IW_ENC_CAPA_WPA2 |
427 IW_ENC_CAPA_CIPHER_TKIP |
428 IW_ENC_CAPA_CIPHER_CCMP; /* IW_ENC_CAPA_* bit field */
429
430 }
431 break;
432
433 /* Set desired BSSID */
434 case SIOCSIWAP:
435 {
436
437 /* If MAC address is zeroes -> connect to "ANY" BSSID */
438 if (MAC_NULL (wrqu->ap_addr.sa_data))
439 {
440 /* Convert to "FF:FF:FF:FF:FF:FF" since this driver requires this value */
441 MAC_COPY (pParam->content.siteMgrDesiredBSSID, "\xff\xff\xff\xff\xff\xff");
442 }
443 else
444 {
445 MAC_COPY (pParam->content.siteMgrDesiredBSSID, wrqu->ap_addr.sa_data);
446 }
447
448 pParam->paramType = SITE_MGR_DESIRED_BSSID_PARAM;
449 res = cmdDispatch_SetParam ( pCmdInterpret->hCmdDispatch, pParam );
450 CHECK_PENDING_RESULT(res,pParam)
451
452 /* also set it to the SME */
453 pParam->paramType = SME_DESIRED_BSSID_PARAM;
454 res = cmdDispatch_SetParam ( pCmdInterpret->hCmdDispatch, pParam );
455 CHECK_PENDING_RESULT(res,pParam)
456
457 break;
458 }
459
460
461 /* Get current BSSID */
462 case SIOCGIWAP:
463 {
464 /* Get current AP BSSID */
465 pParam->paramType = SITE_MGR_CURRENT_BSSID_PARAM;
466 res = cmdDispatch_GetParam ( pCmdInterpret->hCmdDispatch, pParam );
467
468 CHECK_PENDING_RESULT(res,pParam)
469
470 /* In case we are not associated - copy zeroes into bssid */
471 if (res == NO_SITE_SELECTED_YET)
472 {
473 MAC_COPY (wrqu->ap_addr.sa_data, "\x00\x00\x00\x00\x00\x00");
474 cmdObj->return_code = WEXT_OK;
475 }
476 else if (res == TI_OK)
477 {
478 MAC_COPY (wrqu->ap_addr.sa_data, pParam->content.siteMgrDesiredBSSID);
479 }
480
481 break;
482 }
483
484
485 /* request MLME operation (Deauthenticate / Disassociate) */
486 case SIOCSIWMLME:
487 {
488 struct iw_mlme *mlme = (struct iw_mlme *)cmdObj->param3;
489
490 pParam->paramType = SITE_MGR_DESIRED_SSID_PARAM;
491
492 /* In either case - we need to disconnect, so prepare "junk" SSID */
493 for (i = 0; i < MAX_SSID_LEN; i++)
494 pParam->content.siteMgrDesiredSSID.str[i] = (i+1);
495 pParam->content.siteMgrDesiredSSID.len = MAX_SSID_LEN;
496
497 switch (mlme->cmd)
498 {
499 case IW_MLME_DEAUTH:
500 case IW_MLME_DISASSOC:
501 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam );
502 CHECK_PENDING_RESULT(res,pParam)
503 /* now also set it to the SME */
504 pParam->paramType = SME_DESIRED_SSID_ACT_PARAM;
505 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam );
506 CHECK_PENDING_RESULT(res,pParam)
507 break;
508 default:
509 res = -EOPNOTSUPP;
510 goto cmd_end;
511 }
512 break;
513 }
514
515 /* trigger scanning (list cells) */
516 case SIOCSIWSCAN:
517 {
518 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
519 {
520 struct iw_scan_req scanReq;
521
522 if(copy_from_user(&scanReq, wrqu->data.pointer, sizeof(scanReq)))
523 {
524 printk("CRITICAL: Could not copy data from user space!!!");
525 res = -EFAULT;
526 goto cmd_end;
527 }
528
529 pParam->content.tScanDesiredSSID.len = scanReq.essid_len;
530 os_memoryCopy(pCmdInterpret->hOs, pParam->content.tScanDesiredSSID.str, scanReq.essid, scanReq.essid_len);
531 }
532 else
533 {
534 pParam->content.tScanDesiredSSID.len = 0;
535 }
536
537 pParam->paramType = SCAN_CNCN_BSSID_LIST_SCAN_PARAM;
538 pParam->paramLength = sizeof(pParam->content.tScanDesiredSSID);
539 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam );
540 CHECK_PENDING_RESULT(res,pParam)
541 }
542 break;
543
544 /* get scanning results */
545 case SIOCGIWSCAN:
546 {
547 unsigned char ies[256];
548 unsigned char buf[30];
549 char *event = (char *)cmdObj->buffer2;
550 struct iw_event iwe;
551 char *end_buf, *current_val;
552 int allocated_size;
553 OS_802_11_BSSID_LIST_EX *my_list;
554 OS_802_11_BSSID_EX *my_current;
555 int offset;
556 OS_802_11_VARIABLE_IEs *pRsnIes;
557 int ies_offset;
558 int i;
559
560 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
561 struct iw_request_info info;
562 info.cmd = SIOCGIWSCAN;
563 info.flags = 0;
564 #endif
565 end_buf = (char *)(cmdObj->buffer2 + wrqu->data.length);
566
567 /* First get the amount of memory required to hold the entire BSSID list by setting the length to 0 */
568 pParam->paramType = SCAN_CNCN_BSSID_LIST_SIZE_PARAM;
569 pParam->paramLength = 0;
570 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch, pParam );
571 CHECK_PENDING_RESULT(res,pParam)
572
573 allocated_size = pParam->content.uBssidListSize;
574
575 /* Allocate required memory */
576 my_list = os_memoryAlloc (pCmdInterpret->hOs, allocated_size);
577 if (!my_list) {
578 res = -ENOMEM;
579 goto cmd_end;
580 }
581
582 /* And retrieve the list */
583 pParam->paramType = SCAN_CNCN_BSSID_LIST_PARAM;
584 pParam->content.pBssidList = my_list;
585 pParam->paramLength = allocated_size;
586 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch, pParam );
587 CHECK_PENDING_RESULT(res,pParam)
588
589 my_current = &my_list->Bssid[0];
590 i=0;
591 if(wrqu->data.flags)
592 {
593 for (i=0; i<wrqu->data.flags; i++)
594 my_current = (OS_802_11_BSSID_EX *) (((char *) my_current) + my_current->Length);
595 }
596 /* Now send a wireless event per BSSID with "tokens" describing it */
597
598 for (; i<my_list->NumberOfItems; i++)
599 {
600
601 if (event + my_current->Length > end_buf)
602 {
603 break;
604 }
605
606 /* The first entry MUST be the AP BSSID */
607 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe));
608 iwe.cmd = SIOCGIWAP;
609 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
610 iwe.len = IW_EV_ADDR_LEN;
611 os_memoryCopy(pCmdInterpret->hOs, iwe.u.ap_addr.sa_data, &my_current->MacAddress, ETH_ALEN);
612 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
613 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_ADDR_LEN);
614 #else
615 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_ADDR_LEN);
616 #endif
617 /* Add SSID */
618 iwe.cmd = SIOCGIWESSID;
619 iwe.u.data.flags = 1;
620 iwe.u.data.length = min((TI_UINT8)my_current->Ssid.SsidLength, (TI_UINT8)32);
621 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
622 event = iwe_stream_add_point(event, end_buf, &iwe, my_current->Ssid.Ssid);
623 #else
624 event = iwe_stream_add_point(&info,event, end_buf, &iwe, my_current->Ssid.Ssid);
625 #endif
626 /* Add the protocol name (BSS support for A/B/G) */
627 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe));
628 iwe.cmd = SIOCGIWNAME;
629 os_memoryCopy(pCmdInterpret->hOs, (void*)iwe.u.name, (void*)ieee80211_modes[my_current->NetworkTypeInUse], IFNAMSIZ);
630 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
631 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_CHAR_LEN);
632 #else
633 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_CHAR_LEN);
634 #endif
635 /* add mode (infrastructure or Adhoc) */
636 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe));
637 iwe.cmd = SIOCGIWMODE;
638 if (my_current->InfrastructureMode == os802_11IBSS)
639 iwe.u.mode = IW_MODE_ADHOC;
640 else if (my_current->InfrastructureMode == os802_11Infrastructure)
641 iwe.u.mode = IW_MODE_INFRA;
642 else
643 iwe.u.mode = IW_MODE_AUTO;
644 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
645 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_UINT_LEN);
646 #else
647 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_UINT_LEN);
648 #endif
649
650 /* add freq */
651 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe));
652 iwe.cmd = SIOCGIWFREQ;
653 iwe.u.freq.m = my_current->Configuration.Union.channel;
654 iwe.u.freq.e = 3; /* Frequency divider */
655 iwe.u.freq.i = 0;
656 iwe.len = IW_EV_FREQ_LEN;
657 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
658 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_FREQ_LEN);
659 #else
660 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_FREQ_LEN);
661 #endif
662 /* Add quality statistics */
663 iwe.cmd = IWEVQUAL;
664 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID | IW_QUAL_DBM;
665 iwe.u.qual.qual = 0;
666 iwe.u.qual.level = my_current->Rssi;
667 iwe.u.qual.noise = 0;
668 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
669 event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_QUAL_LEN);
670 #else
671 event = iwe_stream_add_event(&info,event, end_buf, &iwe, IW_EV_QUAL_LEN);
672 #endif
673 /* Add encryption capability */
674 iwe.cmd = SIOCGIWENCODE;
675 if ((my_current->Capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK)
676 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
677 else
678 iwe.u.data.flags = IW_ENCODE_DISABLED;
679 iwe.u.data.length = 0;
680 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
681 event = iwe_stream_add_point(event, end_buf, &iwe, NULL);
682 #else
683 event = iwe_stream_add_point(&info,event, end_buf, &iwe, NULL);
684 #endif
685
686 /* add rate */
687 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe));
688 iwe.cmd = SIOCGIWRATE;
689 current_val = event + IW_EV_LCP_LEN;
690 for (j=0; j<16; j++)
691 {
692 if (my_current->SupportedRates[j])
693 {
694 iwe.u.bitrate.value = ((my_current->SupportedRates[j] & 0x7f) * 500000);
695 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
696 current_val = iwe_stream_add_value(event, current_val, end_buf, &iwe,IW_EV_PARAM_LEN);
697 #else
698 current_val = iwe_stream_add_value(&info,event, current_val,end_buf, &iwe,IW_EV_PARAM_LEN);
699 #endif
700 }
701 }
702
703 event = current_val;
704
705 /* CUSTOM - Add beacon interval */
706 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe));
707 iwe.cmd = IWEVCUSTOM;
708 sprintf(buf, "Bcn int = %d ms ", my_current->Configuration.BeaconPeriod);
709 iwe.u.data.length = strlen(buf);
710 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
711 event = iwe_stream_add_point(event, end_buf, &iwe, buf);
712 #else
713 event = iwe_stream_add_point(&info,event, end_buf, &iwe, buf);
714 #endif
715 /* add RSN IE */
716 os_memorySet (pCmdInterpret->hOs, &iwe, 0, sizeof(iwe));
717 os_memorySet (pCmdInterpret->hOs, ies, 0, 256);
718 iwe.cmd = IWEVGENIE;
719 offset = sizeof(OS_802_11_FIXED_IEs);
720 ies_offset = 0;
721
722 while(offset < my_current->IELength)
723 {
724 pRsnIes = (OS_802_11_VARIABLE_IEs*)&(my_current->IEs[offset]);
725 if((pRsnIes->ElementID == RSN_IE_ID) || (pRsnIes->ElementID == WPA_IE_ID))
726 {
727 os_memoryCopy (pCmdInterpret->hOs, ies + ies_offset, (char *)&(my_current->IEs[offset]), pRsnIes->Length + 2);
728 ies_offset += pRsnIes->Length + 2;
729 }
730 offset += pRsnIes->Length + 2;
731 }
732 if (ies_offset)
733 {
734 iwe.u.data.flags = 1;
735 iwe.u.data.length = ies_offset;
736 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
737 event = iwe_stream_add_point(event, end_buf, &iwe, (char *)ies);
738 #else
739 event = iwe_stream_add_point(&info, event, end_buf, &iwe, (char *)ies);
740 #endif
741 }
742
743 my_current = (OS_802_11_BSSID_EX *) (((char *) my_current) + my_current->Length);
744 }
745
746 wrqu->data.length = event - ((char *)cmdObj->buffer2);
747 if(i == my_list->NumberOfItems)
748 {
749 wrqu->data.flags = 0;
750 }
751 else
752 {
753 wrqu->data.flags = i;
754 }
755
756 os_memoryFree (pCmdInterpret->hOs, my_list, allocated_size);
757 cmdObj->return_code = WEXT_OK;
758 }
759
760 break;
761
762 /* Set ESSID */
763 case SIOCSIWESSID:
764 {
765 char *extra = cmdObj->buffer2;
766 int length;
767
768 if (wrqu->essid.flags & SET_SSID_WITHOUT_SUPPL)
769 wrqu->essid.flags &= ~SET_SSID_WITHOUT_SUPPL;
770 else
771 cmdInterpret_setSecurityParams (hCmdInterpret);
772
773 os_memoryZero (pCmdInterpret->hOs, &pParam->content.siteMgrDesiredSSID.str, MAX_SSID_LEN);
774
775 pParam->content.siteMgrCurrentSSID.len = 0;
776
777 if (wrqu->essid.flags == 0)
778 {
779 /* Connect to ANY ESSID - use empty */
780 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.siteMgrCurrentSSID.str, "\00", 1);
781 pParam->content.siteMgrCurrentSSID.len = 0;;
782 } else
783 {
784 /* Handle ESSID length issue in WEXT (backward compatibility with old/new versions) */
785 length = wrqu->essid.length - 1;
786 if (length > 0)
787 length--;
788 while (length < wrqu->essid.length && extra[length])
789 length++;
790
791 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.siteMgrCurrentSSID.str, cmdObj->buffer2, length);
792 pParam->content.siteMgrCurrentSSID.len = length;
793 }
794
795 pParam->paramType = SITE_MGR_DESIRED_SSID_PARAM;
796 pParam->paramLength = sizeof (TSsid);
797 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam );
798 CHECK_PENDING_RESULT(res,pParam)
799 /* also set it to the SME */
800 pParam->paramType = SME_DESIRED_SSID_ACT_PARAM;
801 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam );
802 CHECK_PENDING_RESULT(res,pParam)
803 }
804 break;
805
806 /* get ESSID */
807 case SIOCGIWESSID:
808 {
809 char *extra = (char *)cmdObj->buffer2;
810
811 pParam->paramType = SITE_MGR_CURRENT_SSID_PARAM;
812 res = cmdDispatch_GetParam ( pCmdInterpret->hCmdDispatch, pParam );
813 if(res == NO_SITE_SELECTED_YET)
814 res = WEXT_OK;
815
816 CHECK_PENDING_RESULT(res,pParam)
817
818 wrqu->essid.flags = 1;
819
820 os_memoryCopy(pCmdInterpret->hOs, cmdObj->buffer2, &pParam->content.siteMgrCurrentSSID.str, pParam->content.siteMgrCurrentSSID.len );
821
822 if (pParam->content.siteMgrCurrentSSID.len < MAX_SSID_LEN)
823 {
824 extra[pParam->content.siteMgrCurrentSSID.len] = 0;
825 }
826 wrqu->essid.length = pParam->content.siteMgrCurrentSSID.len;
827 }
828
829 break;
830
831 /* set node name/nickname */
832 case SIOCSIWNICKN:
833 {
834 if (wrqu->data.length > IW_ESSID_MAX_SIZE) {
835 res = -EINVAL;
836 goto cmd_end;
837 }
838 os_memoryCopy(pCmdInterpret->hOs, pCmdInterpret->nickName, cmdObj->buffer2, wrqu->data.length);
839 pCmdInterpret->nickName[IW_ESSID_MAX_SIZE] = 0;
840 res = TI_OK;
841 }
842
843 break;
844
845 /* get node name/nickname */
846 case SIOCGIWNICKN:
847 {
848 struct iw_point *data = (struct iw_point *) cmdObj->buffer1;
849
850 data->length = strlen(pCmdInterpret->nickName);
851 os_memoryCopy(pCmdInterpret->hOs, cmdObj->buffer2, &pCmdInterpret->nickName, data->length);
852
853 res = TI_OK;
854 }
855 break;
856
857 /* Set RTS Threshold */
858 case SIOCSIWRTS:
859 {
860 pParam->paramType = TWD_RTS_THRESHOLD_PARAM;
861
862 if (wrqu->rts.disabled)
863 pParam->content.halCtrlRtsThreshold = TWD_RTS_THRESHOLD_DEF;
864 else
865 pParam->content.halCtrlRtsThreshold = wrqu->rts.value;
866
867 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch,pParam);
868 CHECK_PENDING_RESULT(res,pParam)
869 break;
870 }
871
872 /* Get RTS Threshold */
873 case SIOCGIWRTS:
874 {
875 pParam->paramType = TWD_RTS_THRESHOLD_PARAM;
876 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam);
877
878 CHECK_PENDING_RESULT(res,pParam)
879
880 wrqu->rts.value = pParam->content.halCtrlRtsThreshold;
881 wrqu->rts.fixed = 1;
882 cmdObj->return_code = WEXT_OK;
883 break;
884 }
885
886 /* Set Fragmentation threshold */
887 case SIOCSIWFRAG:
888 {
889 pParam->paramType = TWD_FRAG_THRESHOLD_PARAM;
890 pParam->content.halCtrlFragThreshold = ((wrqu->frag.value+1)>>1) << 1; /* make it always even */
891
892 res = cmdDispatch_SetParam(pCmdInterpret->hCmdDispatch, pParam);
893 CHECK_PENDING_RESULT(res,pParam)
894
895 break;
896 }
897
898 /* Get Fragmentation threshold */
899 case SIOCGIWFRAG:
900 {
901 pParam->paramType = TWD_FRAG_THRESHOLD_PARAM;
902 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam);
903
904 CHECK_PENDING_RESULT(res,pParam)
905
906 wrqu->rts.value = pParam->content.halCtrlFragThreshold;
907 wrqu->rts.fixed = 1;
908 cmdObj->return_code = WEXT_OK;
909 break;
910 }
911
912 /* Set TX power level */
913 case SIOCSIWTXPOW:
914 if (wrqu->txpower.disabled == 1)
915 {
916 cmdObj->return_code = WEXT_INVALID_PARAMETER;
917 }
918 else
919 {
920 pParam->paramType = REGULATORY_DOMAIN_CURRENT_TX_POWER_LEVEL_PARAM;
921 pParam->content.desiredTxPower = wrqu->txpower.value;
922 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch,pParam);
923 CHECK_PENDING_RESULT(res,pParam)
924 }
925 break;
926
927 /* Get TX power level */
928 case SIOCGIWTXPOW:
929 {
930 pParam->paramType = REGULATORY_DOMAIN_CURRENT_TX_POWER_IN_DBM_PARAM;
931 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam);
932
933 CHECK_PENDING_RESULT(res,pParam)
934
935 wrqu->txpower.flags = IW_TXPOW_RELATIVE | IW_TXPOW_RANGE;
936 wrqu->txpower.disabled = 0;
937 wrqu->txpower.fixed = 0;
938 wrqu->txpower.value = pParam->content.desiredTxPower;
939
940 break;
941 }
942
943 /* set encoding token & mode - WEP only */
944 case SIOCSIWENCODE:
945 {
946 int index;
947
948 index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
949
950 /* iwconfig gives index as 1 - N */
951 if (index > 0)
952 index--;
953 else
954 {
955 pParam->paramType = RSN_DEFAULT_KEY_ID;
956 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam);
957 CHECK_PENDING_RESULT(res,pParam)
958 index = pParam->content.rsnDefaultKeyID;
959 }
960
961 pParam->paramType = RSN_ADD_KEY_PARAM;
962 /* remove key if disabled */
963 if (wrqu->data.flags & IW_ENCODE_DISABLED)
964 {
965 pParam->paramType = RSN_REMOVE_KEY_PARAM;
966 }
967
968 pParam->content.rsnOsKey.KeyIndex = index;
969
970 if (wrqu->data.length)
971 {
972 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnOsKey.KeyMaterial, cmdObj->buffer2, wrqu->data.length);
973 pParam->content.rsnOsKey.KeyLength = wrqu->data.length;
974 } else
975 {
976 /* No key material is provided, just set given index as default TX key */
977 pParam->paramType = RSN_DEFAULT_KEY_ID;
978 pParam->content.rsnDefaultKeyID = index;
979 }
980
981 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam);
982 CHECK_PENDING_RESULT(res,pParam)
983
984 break;
985 }
986
987
988 /* get encoding token & mode */
989 case SIOCGIWENCODE:
990 {
991 int index, encr_mode;
992 char *extra = (char *)cmdObj->buffer2;
993 TSecurityKeys myKeyInfo;
994
995 wrqu->data.length = 0;
996 extra[0] = 0;
997
998 /* Get Index from user request */
999 index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
1000 if (index > 0)
1001 index--;
1002 else
1003 {
1004 pParam->paramType = RSN_DEFAULT_KEY_ID;
1005 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam);
1006 CHECK_PENDING_RESULT(res,pParam)
1007 index = pParam->content.rsnDefaultKeyID;
1008 wrqu->data.flags = (index+1);
1009 }
1010
1011 pParam->content.pRsnKey = &myKeyInfo;
1012
1013 pParam->paramType = RSN_KEY_PARAM;
1014 pParam->content.pRsnKey->keyIndex = index;
1015 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam);
1016 CHECK_PENDING_RESULT(res,pParam)
1017
1018 if ((pParam->content.pRsnKey) && (pParam->content.pRsnKey->encLen))
1019 {
1020 wrqu->data.flags |= IW_ENCODE_ENABLED;
1021 wrqu->data.length = pParam->content.pRsnKey->encLen;
1022 os_memoryCopy(pCmdInterpret->hOs,extra, &pParam->content.pRsnKey->encKey,wrqu->data.length);
1023 }
1024
1025 /* Convert from driver (OID-like) authentication parameters to WEXT */
1026 if (pCmdInterpret->wai.iw_auth_cipher_pairwise & IW_AUTH_CIPHER_CCMP)
1027 encr_mode = os802_11Encryption3Enabled;
1028 else if (pCmdInterpret->wai.iw_auth_cipher_pairwise & IW_AUTH_CIPHER_TKIP)
1029 encr_mode = os802_11Encryption2Enabled;
1030 else if (pCmdInterpret->wai.iw_auth_cipher_pairwise & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
1031 encr_mode = os802_11Encryption1Enabled;
1032 else if (pCmdInterpret->wai.iw_auth_cipher_group & IW_AUTH_CIPHER_CCMP)
1033 encr_mode = os802_11Encryption3Enabled;
1034 else if (pCmdInterpret->wai.iw_auth_cipher_group & IW_AUTH_CIPHER_TKIP)
1035 encr_mode = os802_11Encryption2Enabled;
1036 else
1037 encr_mode = os802_11EncryptionDisabled;
1038
1039 if (encr_mode == os802_11EncryptionDisabled)
1040 wrqu->data.flags |= IW_ENCODE_OPEN;
1041 else
1042 wrqu->data.flags |= IW_ENCODE_RESTRICTED;
1043
1044 cmdObj->return_code = WEXT_OK;
1045
1046 }
1047 break;
1048
1049 /* Set Authentication */
1050 case SIOCSIWAUTH:
1051 res = TI_OK;
1052 switch (wrqu->param.flags & IW_AUTH_INDEX)
1053 {
1054 case IW_AUTH_WPA_VERSION:
1055 pCmdInterpret->wai.iw_auth_wpa_version = wrqu->param.value;
1056 break;
1057 case IW_AUTH_CIPHER_PAIRWISE:
1058 pCmdInterpret->wai.iw_auth_cipher_pairwise = wrqu->param.value;
1059 break;
1060 case IW_AUTH_CIPHER_GROUP:
1061 pCmdInterpret->wai.iw_auth_cipher_group = wrqu->param.value;
1062 break;
1063 case IW_AUTH_KEY_MGMT:
1064 pCmdInterpret->wai.iw_auth_key_mgmt = wrqu->param.value;
1065 break;
1066 case IW_AUTH_80211_AUTH_ALG:
1067 pCmdInterpret->wai.iw_auth_80211_auth_alg = wrqu->param.value;
1068 break;
1069 case IW_AUTH_WPA_ENABLED:
1070 break;
1071 case IW_AUTH_TKIP_COUNTERMEASURES:
1072 break;
1073 case IW_AUTH_DROP_UNENCRYPTED:
1074 break;
1075 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1076 break;
1077 case IW_AUTH_PRIVACY_INVOKED:
1078 break;
1079 default:
1080 res = -EOPNOTSUPP;
1081 }
1082 break;
1083
1084 /* Get Authentication */
1085 case SIOCGIWAUTH:
1086 res = TI_OK;
1087 {
1088 switch (wrqu->param.flags & IW_AUTH_INDEX)
1089 {
1090 case IW_AUTH_WPA_VERSION:
1091 wrqu->param.value = pCmdInterpret->wai.iw_auth_wpa_version;
1092 break;
1093 case IW_AUTH_CIPHER_PAIRWISE:
1094 wrqu->param.value = pCmdInterpret->wai.iw_auth_cipher_pairwise;
1095 break;
1096 case IW_AUTH_CIPHER_GROUP:
1097 wrqu->param.value = pCmdInterpret->wai.iw_auth_cipher_group;
1098 break;
1099 case IW_AUTH_KEY_MGMT:
1100 wrqu->param.value = pCmdInterpret->wai.iw_auth_key_mgmt;
1101 break;
1102 case IW_AUTH_80211_AUTH_ALG:
1103 wrqu->param.value = pCmdInterpret->wai.iw_auth_80211_auth_alg;
1104 break;
1105 default:
1106 res = -EOPNOTSUPP;
1107 }
1108 }
1109 break;
1110
1111 /* set encoding token & mode */
1112 case SIOCSIWENCODEEXT:
1113 {
1114 struct iw_encode_ext *ext = (struct iw_encode_ext *)cmdObj->buffer2;
1115 TI_UINT8 *addr;
1116 TI_UINT8 temp[32];
1117
1118 addr = ext->addr.sa_data;
1119
1120 /*
1121 os_printf ("\next->address = %02x:%02x:%02x:%02x:%02x:%02x \n",addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);
1122 os_printf ("ext->alg = 0x%x\n",ext->alg);
1123 os_printf ("ext->ext_flags = 0x%x\n",ext->ext_flags);
1124 os_printf ("ext->key_len = 0x%x\n",ext->key_len);
1125 os_printf ("ext->key_idx = 0x%x\n",(wrqu->encoding.flags & IW_ENCODE_INDEX));
1126
1127 os_printf ("key = ");
1128 for (i=0; i<ext->key_len; i++)
1129 {
1130 os_printf ("0x%02x:",ext->key[i]);
1131 }
1132 os_printf ("\n");
1133 */
1134
1135 MAC_COPY (pParam->content.rsnOsKey.BSSID, addr);
1136
1137 pParam->content.rsnOsKey.KeyLength = ext->key_len;
1138
1139 pParam->content.rsnOsKey.KeyIndex = wrqu->encoding.flags & IW_ENCODE_INDEX;
1140 pParam->content.rsnOsKey.KeyIndex -= 1;
1141
1142 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1143 {
1144 pParam->content.rsnOsKey.KeyIndex |= TIWLAN_KEY_FLAGS_TRANSMIT;
1145 }
1146
1147 if (addr[0]!=0xFF)
1148 {
1149 pParam->content.rsnOsKey.KeyIndex |= TIWLAN_KEY_FLAGS_PAIRWISE;
1150 }
1151
1152 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1153 {
1154 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnOsKey.KeyRSC, &ext->rx_seq, IW_ENCODE_SEQ_MAX_SIZE);
1155 pParam->content.rsnOsKey.KeyIndex |= TIWLAN_KEY_FLAGS_SET_KEY_RSC;
1156 }
1157
1158 /* If key is TKIP - need to switch RX and TX MIC (to match driver API) */
1159 if (ext->alg == IW_ENCODE_ALG_TKIP)
1160 {
1161 os_memoryCopy(pCmdInterpret->hOs,(TI_UINT8*)(((TI_UINT8*)&temp)+24),(TI_UINT8*)(((TI_UINT8*)&ext->key)+16),8);
1162 os_memoryCopy(pCmdInterpret->hOs,(TI_UINT8*)(((TI_UINT8*)&temp)+16),(TI_UINT8*)(((TI_UINT8*)&ext->key)+24),8);
1163 os_memoryCopy(pCmdInterpret->hOs,&temp,&ext->key,16);
1164 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnOsKey.KeyMaterial, &temp, ext->key_len);
1165 } else
1166 {
1167 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnOsKey.KeyMaterial, &ext->key, ext->key_len);
1168 }
1169
1170 if (ext->key_len == 0)
1171 pParam->paramType = RSN_REMOVE_KEY_PARAM;
1172 else
1173 pParam->paramType = RSN_ADD_KEY_PARAM;
1174
1175 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam);
1176 CHECK_PENDING_RESULT(res,pParam)
1177
1178 }
1179 break;
1180
1181 /* SIOCSIWPMKSA - PMKSA cache operation */
1182 case SIOCSIWPMKSA:
1183 {
1184 struct iw_pmksa *pmksa = (struct iw_pmksa *) cmdObj->buffer2;
1185
1186 switch (pmksa->cmd)
1187 {
1188 case IW_PMKSA_ADD:
1189 pParam->paramType = RSN_PMKID_LIST;
1190 pParam->content.rsnPMKIDList.BSSIDInfoCount = 1;
1191 pParam->content.rsnPMKIDList.Length = 2*sizeof(TI_UINT32) + MAC_ADDR_LEN + PMKID_VALUE_SIZE;
1192 MAC_COPY (pParam->content.rsnPMKIDList.osBSSIDInfo[0].BSSID, pmksa->bssid.sa_data);
1193 os_memoryCopy(pCmdInterpret->hOs, &pParam->content.rsnPMKIDList.osBSSIDInfo[0].PMKID, pmksa->pmkid, IW_PMKID_LEN);
1194
1195 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam);
1196 CHECK_PENDING_RESULT(res,pParam)
1197
1198 break;
1199 case IW_PMKSA_REMOVE:
1200 /* Not supported yet */
1201 break;
1202 case IW_PMKSA_FLUSH:
1203 pParam->paramType = RSN_PMKID_LIST;
1204 /* By using info count=0, RSN knows to clear its tables */
1205 /* It's also possible to call rsn_resetPMKIDList directly, but cmdDispatcher should be the interface */
1206 pParam->content.rsnPMKIDList.BSSIDInfoCount = 0;
1207 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch, pParam);
1208 CHECK_PENDING_RESULT(res,pParam)
1209
1210 break;
1211 default:
1212 cmdObj->return_code = WEXT_NOT_SUPPORTED;
1213 break;
1214 }
1215 }
1216
1217 break;
1218
1219 case SIOCIWFIRSTPRIV:
1220 {
1221 ti_private_cmd_t *my_command = (ti_private_cmd_t *)cmdObj->param3;
1222
1223 /*
1224 os_printf ("cmd = 0x%x flags = 0x%x\n",(unsigned int)my_command->cmd,(unsigned int)my_command->flags);
1225 os_printf ("in_buffer = 0x%x (len = %d)\n",my_command->in_buffer,(unsigned int)my_command->in_buffer_len);
1226 os_printf ("out_buffer = 0x%x (len = %d)\n",my_command->out_buffer,(unsigned int)my_command->out_buffer_len);
1227 */
1228
1229 pParam->paramType = my_command->cmd;
1230
1231 if (IS_PARAM_ASYNC(my_command->cmd))
1232 {
1233 /* os_printf ("Detected ASYNC command - setting CB \n"); */
1234 pParam->content.interogateCmdCBParams.hCb = (TI_HANDLE)pCmdInterpret;
1235 pParam->content.interogateCmdCBParams.fCb = (void*)cmdInterpret_ServiceCompleteCB;
1236 pParam->content.interogateCmdCBParams.pCb = my_command->out_buffer;
1237 if (my_command->out_buffer)
1238 {
1239 /* the next copy is need for PLT commands */
1240 os_memoryCopy(pCmdInterpret->hOs, my_command->out_buffer, my_command->in_buffer, min(my_command->in_buffer_len,my_command->out_buffer_len));
1241 }
1242 }
1243 else if ((my_command->in_buffer) && (my_command->in_buffer_len))
1244 {
1245 /*
1246 this cmd doesnt have the structure allocated as part of the paramInfo_t structure.
1247 as a result we need to allocate the memory internally.
1248 */
1249 if(IS_ALLOC_NEEDED_PARAM(my_command->cmd))
1250 {
1251 *(void **)&pParam->content = os_memoryAlloc(pCmdInterpret->hOs, my_command->in_buffer_len);
1252 os_memoryCopy(pCmdInterpret->hOs, *(void **)&pParam->content, my_command->in_buffer, my_command->in_buffer_len);
1253 }
1254 else
1255 os_memoryCopy(pCmdInterpret->hOs,&pParam->content,my_command->in_buffer,my_command->in_buffer_len);
1256 }
1257
1258 if (my_command->flags & PRIVATE_CMD_SET_FLAG)
1259 {
1260 /* os_printf ("Calling setParam\n"); */
1261 pParam->paramLength = my_command->in_buffer_len;
1262 res = cmdDispatch_SetParam (pCmdInterpret->hCmdDispatch,pParam);
1263 }
1264 else if (my_command->flags & PRIVATE_CMD_GET_FLAG)
1265 {
1266 /* os_printf ("Calling getParam\n"); */
1267 pParam->paramLength = my_command->out_buffer_len;
1268 res = cmdDispatch_GetParam (pCmdInterpret->hCmdDispatch,pParam);
1269 if(res == EXTERNAL_GET_PARAM_DENIED)
1270 {
1271 cmdObj->return_code = WEXT_INVALID_PARAMETER;
1272 goto cmd_end;
1273 }
1274
1275 /*
1276 this is for cmd that want to check the size of memory that they need to
1277 allocate for the actual data.
1278 */
1279 if(pParam->paramLength && (my_command->out_buffer_len == 0))
1280 {
1281 my_command->out_buffer_len = pParam->paramLength;
1282 }
1283 }
1284 else
1285 {
1286 res = TI_NOK;
1287 }
1288
1289 if (res == TI_OK)
1290 {
1291 if(IS_PARAM_ASYNC(my_command->cmd))
1292 {
1293 pCmdInterpret->pAsyncCmd = cmdObj; /* Save command handle for completion CB */
1294 res = COMMAND_PENDING;
1295 }
1296 else
1297 {
1298 if ((my_command->out_buffer) && (my_command->out_buffer_len))
1299 {
1300 if(IS_ALLOC_NEEDED_PARAM(my_command->cmd))
1301 {
1302 os_memoryCopy(pCmdInterpret->hOs,my_command->out_buffer,*(void **)&pParam->content,my_command->out_buffer_len);
1303 }
1304 else
1305 {
1306 os_memoryCopy(pCmdInterpret->hOs,my_command->out_buffer,&pParam->content,my_command->out_buffer_len);
1307 }
1308 }
1309 }
1310 }
1311
1312 /* need to free the allocated memory */
1313 if(IS_ALLOC_NEEDED_PARAM(my_command->cmd))
1314 {
1315 os_memoryFree(pCmdInterpret->hOs, *(void **)&pParam->content, my_command->in_buffer_len);
1316 }
1317 }
1318
1319 break;
1320
1321 default:
1322 break;
1323
1324 }
1325
1326 if (res == TI_OK)
1327 {
1328 cmdObj->return_code = WEXT_OK;
1329 }
1330 cmd_end:
1331 os_memoryFree(pCmdInterpret->hOs, pParam, sizeof(paramInfo_t));
1332 /* Return with return code */
1333 return res;
1334
1335 }
1336
1337
1338
1339 /* This routine is called by the command mailbox module to signal an ASYNC command has complete */
cmdInterpret_ServiceCompleteCB(TI_HANDLE hCmdInterpret,int status,void * buffer)1340 int cmdInterpret_ServiceCompleteCB (TI_HANDLE hCmdInterpret, int status, void *buffer)
1341 {
1342 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret;
1343
1344 if (pCmdInterpret->pAsyncCmd == NULL)
1345 {
1346 os_printf ("cmdInterpret_ServiceCompleteCB: AsyncCmd is NULL!!\n");
1347 return TI_NOK;
1348 }
1349
1350 pCmdInterpret->pAsyncCmd->return_code = status;
1351
1352 pCmdInterpret->pAsyncCmd = NULL;
1353
1354 /* Call the Cmd module to complete command processing */
1355 cmdHndlr_Complete (pCmdInterpret->hCmdHndlr);
1356
1357 /* Call commands handler to continue handling further commands if queued */
1358 cmdHndlr_HandleCommands (pCmdInterpret->hCmdHndlr);
1359
1360 return TI_OK;
1361 }
1362
1363 /* Register to receive events */
cmdInterpret_initEvents(TI_HANDLE hCmdInterpret)1364 static int cmdInterpret_initEvents(TI_HANDLE hCmdInterpret)
1365 {
1366 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)(hCmdInterpret);
1367 IPC_EVENT_PARAMS evParams;
1368 int i = 0;
1369
1370 for (i=0; i<IPC_EVENT_MAX; i++)
1371 {
1372 evParams.uDeliveryType = DELIVERY_PUSH;
1373 evParams.uProcessID = 0;
1374 evParams.uEventID = 0;
1375 evParams.hUserParam = hCmdInterpret;
1376 evParams.pfEventCallback = cmdInterpret_Event;
1377 evParams.uEventType = i;
1378 EvHandlerRegisterEvent (pCmdInterpret->hEvHandler, (TI_UINT8*) &evParams, sizeof(IPC_EVENT_PARAMS));
1379 pCmdInterpret->hEvents[i] = evParams.uEventID;
1380 }
1381
1382 return TI_OK;
1383 }
1384
1385
1386 /* Unregister events */
cmdInterpret_unregisterEvents(TI_HANDLE hCmdInterpret,TI_HANDLE hEvHandler)1387 static int cmdInterpret_unregisterEvents(TI_HANDLE hCmdInterpret, TI_HANDLE hEvHandler)
1388 {
1389 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)(hCmdInterpret);
1390 IPC_EVENT_PARAMS evParams;
1391 int i = 0;
1392 os_setDebugOutputToLogger(TI_FALSE);
1393
1394 for (i=0; i<IPC_EVENT_MAX; i++)
1395 {
1396 evParams.uEventType = i;
1397 evParams.uEventID = pCmdInterpret->hEvents[i];
1398 EvHandlerUnRegisterEvent (pCmdInterpret->hEvHandler, &evParams);
1399 }
1400
1401 return TI_OK;
1402 }
1403
1404
1405 /* Handle driver events and convert to WEXT format */
cmdInterpret_Event(IPC_EV_DATA * pData)1406 static TI_INT32 cmdInterpret_Event(IPC_EV_DATA* pData)
1407 {
1408 IPC_EVENT_PARAMS * pInParam = (IPC_EVENT_PARAMS *)pData;
1409 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)(pInParam->hUserParam);
1410 OS_802_11_ASSOCIATION_INFORMATION *assocInformation;
1411 TI_UINT8 *requestIEs;
1412 TI_UINT8 *responseIEs;
1413 union iwreq_data wrqu;
1414 char *memptr;
1415 int TotalLength, res = TI_OK;
1416 #ifdef XCC_MODULE_INCLUDED
1417 cckm_assocInformation_t cckm_assoc;
1418 unsigned char beaconIE[MAX_BEACON_BODY_LENGTH];
1419 unsigned char Cckmstart[CCKM_START_EVENT_SIZE * 2];
1420 int i,len,n;
1421 OS_802_11_BSSID_EX *my_current;
1422 #endif
1423 /* indicate to the OS */
1424 os_IndicateEvent (pCmdInterpret->hOs, pData);
1425
1426
1427 switch (pData->EvParams.uEventType)
1428 {
1429 case IPC_EVENT_ASSOCIATED:
1430 {
1431 paramInfo_t *pParam;
1432
1433 pParam = (paramInfo_t *)os_memoryAlloc(pCmdInterpret->hOs, sizeof(paramInfo_t));
1434 if (!pParam)
1435 return TI_NOK;
1436
1437 /* Get Association information */
1438
1439 /* first check if this is ADHOC or INFRA (to avoid retrieving ASSOC INFO for ADHOC)*/
1440
1441 pParam->paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM;
1442 cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam);
1443 if (pParam->content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE)
1444 {
1445
1446 /* First get length of data */
1447 pParam->paramType = ASSOC_ASSOCIATION_INFORMATION_PARAM;
1448 pParam->paramLength = 0;
1449 res = cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam);
1450
1451 if (res != TI_NOK)
1452 {
1453 TotalLength = sizeof(OS_802_11_ASSOCIATION_INFORMATION) + pParam->content.assocAssociationInformation.RequestIELength +
1454 pParam->content.assocAssociationInformation.ResponseIELength;
1455
1456 memptr = os_memoryAlloc (pCmdInterpret->hOs, TotalLength);
1457
1458 /* Get actual data */
1459
1460 pParam->paramType = ASSOC_ASSOCIATION_INFORMATION_PARAM;
1461 pParam->paramLength = TotalLength;
1462 cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam);
1463
1464 os_memoryCopy(pCmdInterpret->hOs, memptr, &pParam->content, TotalLength);
1465
1466 assocInformation = (OS_802_11_ASSOCIATION_INFORMATION*)memptr;
1467 requestIEs = (TI_UINT8*)memptr + sizeof(OS_802_11_ASSOCIATION_INFORMATION);
1468
1469 if (assocInformation->RequestIELength > 0)
1470 {
1471 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1472 wrqu.data.length = assocInformation->RequestIELength;
1473 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVASSOCREQIE, &wrqu, (char *)assocInformation->OffsetRequestIEs);
1474 }
1475
1476 responseIEs = (char *)assocInformation->OffsetRequestIEs + assocInformation->RequestIELength;
1477
1478 if (assocInformation->ResponseIELength > 0)
1479 {
1480 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1481 wrqu.data.length = assocInformation->ResponseIELength;
1482 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVASSOCRESPIE, &wrqu, (char *)responseIEs);
1483 }
1484
1485 os_memoryFree (pCmdInterpret->hOs, memptr, TotalLength);
1486
1487 }
1488 }
1489
1490 #ifdef XCC_MODULE_INCLUDED
1491 /*
1492 the driver must provide BEACON IE for calculate MIC in case of fast roaming
1493 the data is an ASCII NUL terminated string
1494 */
1495
1496
1497 my_current = os_memoryAlloc (pCmdInterpret->hOs,MAX_BEACON_BODY_LENGTH);
1498 if (!my_current) {
1499 res = TI_NOK;
1500 goto event_end;
1501 }
1502 pParam->paramType = SITE_MGR_GET_SELECTED_BSSID_INFO_EX;
1503 pParam->content.pSiteMgrSelectedSiteInfo = my_current;
1504 pParam->paramLength = MAX_BEACON_BODY_LENGTH;
1505 cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam);
1506
1507 len = pParam->content.pSiteMgrSelectedSiteInfo->IELength - BEACON_HEADER_FIX_SIZE;
1508
1509 n = sprintf(beaconIE, "BEACONIE=");
1510 for (i = 0; i < len; i++)
1511 {
1512 n += sprintf(beaconIE + n, "%02x", pParam->content.pSiteMgrSelectedSiteInfo->IEs[BEACON_HEADER_FIX_SIZE+i] & 0xff);
1513 }
1514
1515 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1516 wrqu.data.length = n;
1517 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, beaconIE);
1518 os_memoryFree(pCmdInterpret->hOs,my_current,MAX_BEACON_BODY_LENGTH);
1519
1520
1521 /*
1522 The driver should be sending the Association Resp IEs
1523 This informs the supplicant of the IEs used in the association exchanged which are required to proceed with CCKM.
1524 */
1525
1526
1527 pParam->paramType = ASSOC_ASSOCIATION_RESP_PARAM;
1528 pParam->paramLength = sizeof(TAssocReqBuffer);
1529 cmdDispatch_GetParam(pCmdInterpret->hCmdDispatch, pParam);
1530
1531 cckm_assoc.assocRespLen = Param.content.assocReqBuffer.bufferSize - ASSOC_RESP_FIXED_DATA_LEN ;
1532 cckm_assoc.assocRespBuffer = os_memoryAlloc (pCmdInterpret->hOs, cckm_assoc.assocRespLen);
1533 if (!cckm_assoc.assocRespBuffer) {
1534 res = TI_NOK;
1535 goto event_end;
1536 }
1537 memcpy(cckm_assoc.assocRespBuffer,(pParam->content.assocReqBuffer.buffer)+ASSOC_RESP_FIXED_DATA_LEN,cckm_assoc.assocRespLen);
1538 wrqu.data.length = cckm_assoc.assocRespLen;
1539 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVASSOCRESPIE, &wrqu, (TI_UINT8*)cckm_assoc.assocRespBuffer);
1540 os_memoryFree(pCmdInterpret->hOs,cckm_assoc.assocRespBuffer,cckm_assoc.assocRespLen);
1541
1542 #endif
1543 /* Send associated event (containing BSSID of AP) */
1544
1545 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1546 pParam->paramType = SITE_MGR_CURRENT_BSSID_PARAM;
1547 cmdDispatch_GetParam ( pCmdInterpret->hCmdDispatch, pParam );
1548 MAC_COPY (wrqu.ap_addr.sa_data, pParam->content.siteMgrDesiredBSSID);
1549 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1550 wireless_send_event(NETDEV(pCmdInterpret->hOs), SIOCGIWAP, &wrqu, NULL);
1551 #ifdef XCC_MODULE_INCLUDED
1552 event_end:
1553 #endif
1554 os_memoryFree(pCmdInterpret->hOs, pParam, sizeof(paramInfo_t));
1555 }
1556 break;
1557 case IPC_EVENT_DISASSOCIATED:
1558 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1559 os_memorySet (pCmdInterpret->hOs,wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1560
1561 wireless_send_event(NETDEV(pCmdInterpret->hOs), SIOCGIWAP, &wrqu, NULL);
1562
1563 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1564 wrqu.data.length = sizeof(IPC_EV_DATA);
1565 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, (TI_UINT8 *)pData);
1566
1567 break;
1568
1569 case IPC_EVENT_SCAN_COMPLETE:
1570 {
1571 TI_UINT8 *buf;
1572 wrqu.data.length = 0;
1573 wrqu.data.flags = 0;
1574 buf = pData->uBuffer;
1575
1576 if (*(TI_UINT32*)buf == SCAN_STATUS_COMPLETE)
1577 wireless_send_event(NETDEV(pCmdInterpret->hOs), SIOCGIWSCAN, &wrqu, NULL);
1578 else
1579 {
1580 if (*(TI_UINT32*)buf == SCAN_STATUS_STOPPED) // scan is stopped successfully
1581 pData->EvParams.uEventType = IPC_EVENT_SCAN_STOPPED;
1582 else if (*(TI_UINT32*)buf == SCAN_STATUS_FAILED) // scan is stopped successfully
1583 pData->EvParams.uEventType = IPC_EVENT_SCAN_FAILED;
1584 else
1585 break;
1586
1587 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1588 wrqu.data.length = sizeof(IPC_EV_DATA);
1589 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, (u8 *)pData);
1590 }
1591 }
1592 break;
1593
1594 case IPC_EVENT_MEDIA_SPECIFIC:
1595 {
1596 TI_UINT8 *buf;
1597 OS_802_11_AUTHENTICATION_REQUEST *request;
1598 struct iw_michaelmicfailure ev;
1599 struct iw_pmkid_cand pcand;
1600
1601 buf = pData->uBuffer;
1602
1603 if (*(TI_UINT32*)buf == os802_11StatusType_Authentication)
1604 {
1605 request = (OS_802_11_AUTHENTICATION_REQUEST *) (buf + sizeof(TI_UINT32));
1606 if ( request->Flags == OS_802_11_REQUEST_PAIRWISE_ERROR || request->Flags == OS_802_11_REQUEST_GROUP_ERROR)
1607 {
1608 os_printf ("MIC failure detected\n");
1609
1610 os_memorySet (pCmdInterpret->hOs,&ev, 0, sizeof(ev));
1611
1612 ev.flags = 0 & IW_MICFAILURE_KEY_ID;
1613
1614 if (request->Flags == OS_802_11_REQUEST_GROUP_ERROR)
1615 ev.flags |= IW_MICFAILURE_GROUP;
1616 else
1617 ev.flags |= IW_MICFAILURE_PAIRWISE;
1618
1619 ev.src_addr.sa_family = ARPHRD_ETHER;
1620 MAC_COPY (ev.src_addr.sa_data, request->BSSID);
1621 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1622 wrqu.data.length = sizeof(ev);
1623 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
1624 }
1625
1626 } else if (*(TI_UINT32*)buf == os802_11StatusType_PMKID_CandidateList)
1627 {
1628 OS_802_11_PMKID_CANDIDATELIST *pCandList = (OS_802_11_PMKID_CANDIDATELIST *) (buf + sizeof(TI_UINT32));
1629 int i;
1630
1631 os_printf ("Preauthentication list (%d entries)!\n",pCandList->NumCandidates);
1632
1633 for (i=0; i<pCandList->NumCandidates; i++)
1634 {
1635 os_memorySet (pCmdInterpret->hOs,&pcand, 0, sizeof(pcand));
1636 pcand.flags |= IW_PMKID_CAND_PREAUTH;
1637
1638 pcand.index = i;
1639
1640 MAC_COPY (pcand.bssid.sa_data, pCandList->CandidateList[i].BSSID);
1641
1642 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1643
1644 wrqu.data.length = sizeof(pcand);
1645
1646 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVPMKIDCAND,
1647 &wrqu, (TI_UINT8 *)&pcand);
1648 }
1649
1650 }
1651
1652 }
1653
1654 break;
1655 #ifdef XCC_MODULE_INCLUDED
1656 case IPC_EVENT_CCKM_START:
1657
1658 n = sprintf(Cckmstart, "CCKM-Start=");
1659 for (i = 0; i < 14; i++)
1660 {
1661 n += sprintf(Cckmstart + n, "%02x", pData->uBuffer[i] & 0xff);
1662 }
1663
1664 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1665 wrqu.data.length = n;
1666 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, Cckmstart);
1667
1668 break;
1669 #endif
1670
1671 default:
1672 /* Other event? probably private and does not need interface-specific conversion */
1673 /* Send as "custom" event */
1674 {
1675 os_memorySet (pCmdInterpret->hOs,&wrqu, 0, sizeof(wrqu));
1676 wrqu.data.length = sizeof(IPC_EV_DATA);
1677 wireless_send_event(NETDEV(pCmdInterpret->hOs), IWEVCUSTOM, &wrqu, (TI_UINT8 *)pData);
1678 }
1679
1680 break;
1681 }
1682
1683 return res;
1684 }
1685
1686
1687 /* Configure driver authentication and security by converting from WEXT interface to driver (OID-like) settings */
cmdInterpret_setSecurityParams(TI_HANDLE hCmdInterpret)1688 static int cmdInterpret_setSecurityParams (TI_HANDLE hCmdInterpret)
1689 {
1690 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret;
1691 paramInfo_t *pParam;
1692 int auth_mode, encr_mode;
1693
1694 /*
1695 printk ("wpa_version=0x%x auth_alg=0x%x key_mgmt=0x%x "
1696 "cipher_pairwise=0x%x cipher_group=0x%x\n",
1697 pCmdInterpret->wai.iw_auth_wpa_version, pCmdInterpret->wai.iw_auth_80211_auth_alg,
1698 pCmdInterpret->wai.iw_auth_key_mgmt, pCmdInterpret->wai.iw_auth_cipher_pairwise,
1699 pCmdInterpret->wai.iw_auth_cipher_group);
1700 */
1701 pParam = (paramInfo_t *)os_memoryAlloc(pCmdInterpret->hOs, sizeof(paramInfo_t));
1702 if (!pParam)
1703 return TI_NOK;
1704 if (pCmdInterpret->wai.iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2)
1705 {
1706 if (pCmdInterpret->wai.iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X)
1707 auth_mode = os802_11AuthModeWPA2;
1708 else
1709 auth_mode = os802_11AuthModeWPA2PSK;
1710 } else if (pCmdInterpret->wai.iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA)
1711 {
1712 if (pCmdInterpret->wai.iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X)
1713 auth_mode = os802_11AuthModeWPA;
1714 else if (pCmdInterpret->wai.iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_PSK)
1715 auth_mode = os802_11AuthModeWPAPSK;
1716 else
1717 auth_mode = os802_11AuthModeWPANone;
1718 } else if (pCmdInterpret->wai.iw_auth_80211_auth_alg & IW_AUTH_ALG_SHARED_KEY)
1719 {
1720 if (pCmdInterpret->wai.iw_auth_80211_auth_alg & IW_AUTH_ALG_OPEN_SYSTEM)
1721 auth_mode = os802_11AuthModeAutoSwitch;
1722 else
1723 auth_mode = os802_11AuthModeShared;
1724 } else
1725 auth_mode = os802_11AuthModeOpen;
1726
1727 if (pCmdInterpret->wai.iw_auth_cipher_pairwise & IW_AUTH_CIPHER_CCMP)
1728 encr_mode = os802_11Encryption3Enabled;
1729 else if (pCmdInterpret->wai.iw_auth_cipher_pairwise & IW_AUTH_CIPHER_TKIP)
1730 encr_mode = os802_11Encryption2Enabled;
1731 else if (pCmdInterpret->wai.iw_auth_cipher_pairwise &
1732 (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
1733 encr_mode = os802_11Encryption1Enabled;
1734 else if (pCmdInterpret->wai.iw_auth_cipher_group & IW_AUTH_CIPHER_CCMP)
1735 encr_mode = os802_11Encryption3Enabled;
1736 else if (pCmdInterpret->wai.iw_auth_cipher_group & IW_AUTH_CIPHER_TKIP)
1737 encr_mode = os802_11Encryption2Enabled;
1738 else
1739 encr_mode = os802_11EncryptionDisabled;
1740
1741 switch (encr_mode)
1742 {
1743 case os802_11WEPDisabled:
1744 encr_mode = TWD_CIPHER_NONE;
1745 break;
1746 case os802_11WEPEnabled:
1747 encr_mode = TWD_CIPHER_WEP;
1748 break;
1749 case os802_11Encryption2Enabled:
1750 encr_mode = TWD_CIPHER_TKIP;
1751 break;
1752 case os802_11Encryption3Enabled:
1753 encr_mode = TWD_CIPHER_AES_CCMP;
1754 break;
1755 default:
1756 break;
1757 }
1758
1759 pParam->paramType = RSN_EXT_AUTHENTICATION_MODE;
1760 pParam->content.rsnExtAuthneticationMode = auth_mode;
1761 cmdDispatch_SetParam ( pCmdInterpret->hCmdDispatch, pParam );
1762
1763 pParam->paramType = RSN_ENCRYPTION_STATUS_PARAM;
1764 pParam->content.rsnEncryptionStatus = encr_mode;
1765 cmdDispatch_SetParam ( pCmdInterpret->hCmdDispatch, pParam );
1766 os_memoryFree(pCmdInterpret->hOs, pParam, sizeof(paramInfo_t));
1767 return TI_OK;
1768 }
1769
1770
cmdInterpret_GetStat(TI_HANDLE hCmdInterpret)1771 void *cmdInterpret_GetStat (TI_HANDLE hCmdInterpret)
1772 {
1773 cmdInterpret_t *pCmdInterpret = (cmdInterpret_t *)hCmdInterpret;
1774
1775 /* Check if driver is initialized - If not - return empty statistics */
1776 if (hCmdInterpret)
1777 {
1778 pCmdInterpret->wstats.status = 0;
1779 pCmdInterpret->wstats.miss.beacon = 0;
1780 pCmdInterpret->wstats.discard.retries = 0; /* Tx : Max MAC retries num reached */
1781 pCmdInterpret->wstats.discard.nwid = 0; /* Rx : Wrong nwid/essid */
1782 pCmdInterpret->wstats.discard.code = 0; /* Rx : Unable to code/decode (WEP) */
1783 pCmdInterpret->wstats.discard.fragment = 0; /* Rx : Can't perform MAC reassembly */
1784 pCmdInterpret->wstats.discard.misc = 0; /* Others cases */
1785
1786 pCmdInterpret->wstats.qual.qual = 0;
1787 pCmdInterpret->wstats.qual.level = 0;
1788 pCmdInterpret->wstats.qual.noise = 0;
1789 pCmdInterpret->wstats.qual.updated = IW_QUAL_NOISE_INVALID | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
1790 return &pCmdInterpret->wstats;
1791 }
1792 return (void *)NULL;
1793 }
1794