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 #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 */
     92 TI_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 */
    118 TI_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 
    132 void 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 */
    146 int 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     }
   1485 cmd_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 */
   1495 int 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 */
   1519 static 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 */
   1542 static 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 */
   1561 static 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);
   1711 event_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 */
   1846 static 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 
   1929 void *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