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