• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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