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