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