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