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