1/* 2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * File: iwctl.c 20 * 21 * Purpose: wireless ext & ioctl functions 22 * 23 * Author: Lyndon Chen 24 * 25 * Date: July 5, 2006 26 * 27 * Functions: 28 * 29 * Revision History: 30 * 31 */ 32 33#include "device.h" 34#include "ioctl.h" 35#include "iocmd.h" 36#include "mac.h" 37#include "card.h" 38#include "hostap.h" 39#include "power.h" 40#include "rf.h" 41 42#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT 43#include "iowpa.h" 44#include "wpactl.h" 45#endif 46 47#include <net/iw_handler.h> 48extern unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester 49 50/*--------------------- Static Definitions -------------------------*/ 51 52//2008-0409-07, <Add> by Einsn Liu 53#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT 54#define SUPPORTED_WIRELESS_EXT 18 55#else 56#define SUPPORTED_WIRELESS_EXT 17 57#endif 58 59static const long frequency_list[] = { 60 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, 61 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, 62 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, 63 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 64 5700, 5745, 5765, 5785, 5805, 5825 65 }; 66 67 68/*--------------------- Static Classes ----------------------------*/ 69 70 71//static int msglevel =MSG_LEVEL_DEBUG; 72static int msglevel =MSG_LEVEL_INFO; 73 74 75/*--------------------- Static Variables --------------------------*/ 76/*--------------------- Static Functions --------------------------*/ 77 78/*--------------------- Export Variables --------------------------*/ 79 80struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) 81{ 82 PSDevice pDevice = netdev_priv(dev); 83 long ldBm; 84 85 pDevice->wstats.status = pDevice->eOPMode; 86 #ifdef Calcu_LinkQual 87 if(pDevice->scStatistic.LinkQuality > 100) 88 pDevice->scStatistic.LinkQuality = 100; 89 pDevice->wstats.qual.qual =(unsigned char) pDevice->scStatistic.LinkQuality; 90 #else 91 pDevice->wstats.qual.qual = pDevice->byCurrSQ; 92 #endif 93 RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); 94 pDevice->wstats.qual.level = ldBm; 95 //pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI; 96 pDevice->wstats.qual.noise = 0; 97 pDevice->wstats.qual.updated = 1; 98 pDevice->wstats.discard.nwid = 0; 99 pDevice->wstats.discard.code = 0; 100 pDevice->wstats.discard.fragment = 0; 101 pDevice->wstats.discard.retries = (unsigned long)pDevice->scStatistic.dwTsrErr; 102 pDevice->wstats.discard.misc = 0; 103 pDevice->wstats.miss.beacon = 0; 104 105 return &pDevice->wstats; 106} 107 108 109 110/*------------------------------------------------------------------*/ 111 112 113static int iwctl_commit(struct net_device *dev, 114 struct iw_request_info *info, 115 void *wrq, 116 char *extra) 117{ 118 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n"); 119 120 return 0; 121 122} 123/* 124 * Wireless Handler : get protocol name 125 */ 126 127int iwctl_giwname(struct net_device *dev, 128 struct iw_request_info *info, 129 char *wrq, 130 char *extra) 131{ 132 strcpy(wrq, "802.11-a/b/g"); 133 return 0; 134} 135 136int iwctl_giwnwid(struct net_device *dev, 137 struct iw_request_info *info, 138 struct iw_param *wrq, 139 char *extra) 140{ 141 //wrq->value = 0x100; 142 //wrq->disabled = 0; 143 //wrq->fixed = 1; 144 //return 0; 145 return -EOPNOTSUPP; 146} 147 148/* 149 * Wireless Handler : set scan 150 */ 151 152int iwctl_siwscan(struct net_device *dev, 153 struct iw_request_info *info, 154 struct iw_point *wrq, 155 char *extra) 156{ 157 PSDevice pDevice = (PSDevice)netdev_priv(dev); 158 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 159 struct iw_scan_req *req = (struct iw_scan_req *)extra; 160 unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; 161 PWLAN_IE_SSID pItemSSID=NULL; 162 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n"); 163 164 165if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! 166//send scan event to wpa_Supplicant 167 union iwreq_data wrqu; 168 PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n"); 169 memset(&wrqu, 0, sizeof(wrqu)); 170 wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); 171 return 0; 172} 173 174 spin_lock_irq(&pDevice->lock); 175 BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); 176 177//mike add: active scan OR passive scan OR desire_ssid scan 178 if(wrq->length == sizeof(struct iw_scan_req)) { 179 if (wrq->flags & IW_SCAN_THIS_ESSID) { //desire_ssid scan 180 memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 181 pItemSSID = (PWLAN_IE_SSID)abyScanSSID; 182 pItemSSID->byElementID = WLAN_EID_SSID; 183 memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len); 184 if (pItemSSID->abySSID[req->essid_len - 1] == '\0') { 185 if(req->essid_len>0) 186 pItemSSID->len = req->essid_len - 1; 187 } 188 else 189 pItemSSID->len = req->essid_len; 190 pMgmt->eScanType = WMAC_SCAN_PASSIVE; 191 PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID, 192 ((PWLAN_IE_SSID)abyScanSSID)->len); 193 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); 194 spin_unlock_irq(&pDevice->lock); 195 196 return 0; 197 } 198 else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) { //passive scan 199 pMgmt->eScanType = WMAC_SCAN_PASSIVE; 200 } 201 } 202 else { //active scan 203 pMgmt->eScanType = WMAC_SCAN_ACTIVE; 204 } 205 206 pMgmt->eScanType = WMAC_SCAN_PASSIVE; 207 //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n"); 208 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); 209 spin_unlock_irq(&pDevice->lock); 210 211 return 0; 212} 213 214 215/* 216 * Wireless Handler : get scan results 217 */ 218 219int iwctl_giwscan(struct net_device *dev, 220 struct iw_request_info *info, 221 struct iw_point *wrq, 222 char *extra) 223{ 224 int ii, jj, kk; 225 PSDevice pDevice = (PSDevice)netdev_priv(dev); 226 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 227 PKnownBSS pBSS; 228 PWLAN_IE_SSID pItemSSID; 229 PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates; 230 char *current_ev = extra; 231 char *end_buf = extra + IW_SCAN_MAX_DATA; 232 char *current_val = NULL; 233 struct iw_event iwe; 234 long ldBm; 235 char buf[MAX_WPA_IE_LEN * 2 + 30]; 236 237 238 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n"); 239 240 if (pMgmt->eScanState == WMAC_IS_SCANNING) { 241 // In scanning.. 242 return -EAGAIN; 243 } 244 pBSS = &(pMgmt->sBSSList[0]); 245 for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) { 246 if (current_ev >= end_buf) 247 break; 248 pBSS = &(pMgmt->sBSSList[jj]); 249 if (pBSS->bActive) { 250 //ADD mac address 251 memset(&iwe, 0, sizeof(iwe)); 252 iwe.cmd = SIOCGIWAP; 253 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 254 memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN); 255 current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); 256 //ADD ssid 257 memset(&iwe, 0, sizeof(iwe)); 258 iwe.cmd = SIOCGIWESSID; 259 pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; 260 iwe.u.data.length = pItemSSID->len; 261 iwe.u.data.flags = 1; 262 current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); 263 //ADD mode 264 memset(&iwe, 0, sizeof(iwe)); 265 iwe.cmd = SIOCGIWMODE; 266 if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) { 267 iwe.u.mode = IW_MODE_INFRA; 268 } 269 else { 270 iwe.u.mode = IW_MODE_ADHOC; 271 } 272 iwe.len = IW_EV_UINT_LEN; 273 current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_UINT_LEN); 274 //ADD frequency 275 pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates; 276 pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates; 277 memset(&iwe, 0, sizeof(iwe)); 278 iwe.cmd = SIOCGIWFREQ; 279 iwe.u.freq.m = pBSS->uChannel; 280 iwe.u.freq.e = 0; 281 iwe.u.freq.i = 0; 282 current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); 283 //2008-0409-04, <Add> by Einsn Liu 284 { 285 int f = (int)pBSS->uChannel - 1; 286 if(f < 0)f = 0; 287 iwe.u.freq.m = frequency_list[f] * 100000; 288 iwe.u.freq.e = 1; 289 } 290 current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN); 291 //ADD quality 292 memset(&iwe, 0, sizeof(iwe)); 293 iwe.cmd = IWEVQUAL; 294 RFvRSSITodBm(pDevice, (unsigned char)(pBSS->uRSSI), &ldBm); 295 iwe.u.qual.level = ldBm; 296 iwe.u.qual.noise = 0; 297//2008-0409-01, <Add> by Einsn Liu 298 if(-ldBm<50){ 299 iwe.u.qual.qual = 100; 300 }else if(-ldBm > 90) { 301 iwe.u.qual.qual = 0; 302 }else { 303 iwe.u.qual.qual=(40-(-ldBm-50))*100/40; 304 } 305 iwe.u.qual.updated=7; 306 307 // iwe.u.qual.qual = 0; 308 current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 309 310 memset(&iwe, 0, sizeof(iwe)); 311 iwe.cmd = SIOCGIWENCODE; 312 iwe.u.data.length = 0; 313 if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) { 314 iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 315 }else { 316 iwe.u.data.flags = IW_ENCODE_DISABLED; 317 } 318 current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID); 319 320 memset(&iwe, 0, sizeof(iwe)); 321 iwe.cmd = SIOCGIWRATE; 322 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; 323 current_val = current_ev + IW_EV_LCP_LEN; 324 325 for (kk = 0 ; kk < 12 ; kk++) { 326 if (pSuppRates->abyRates[kk] == 0) 327 break; 328 // Bit rate given in 500 kb/s units (+ 0x80) 329 iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000); 330 current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); 331 } 332 for (kk = 0 ; kk < 8 ; kk++) { 333 if (pExtSuppRates->abyRates[kk] == 0) 334 break; 335 // Bit rate given in 500 kb/s units (+ 0x80) 336 iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000); 337 current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); 338 } 339 340 if((current_val - current_ev) > IW_EV_LCP_LEN) 341 current_ev = current_val; 342 343 memset(&iwe, 0, sizeof(iwe)); 344 iwe.cmd = IWEVCUSTOM; 345 sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval); 346 iwe.u.data.length = strlen(buf); 347 current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf); 348 349 if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) { 350 memset(&iwe, 0, sizeof(iwe)); 351 iwe.cmd = IWEVGENIE; 352 iwe.u.data.length = pBSS->wWPALen; 353 current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE); 354 } 355 356 if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) { 357 memset(&iwe, 0, sizeof(iwe)); 358 iwe.cmd = IWEVGENIE; 359 iwe.u.data.length = pBSS->wRSNLen; 360 current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE); 361 } 362 363 } 364 }// for 365 366 wrq->length = current_ev - extra; 367 return 0; 368 369} 370 371 372/* 373 * Wireless Handler : set frequence or channel 374 */ 375 376int iwctl_siwfreq(struct net_device *dev, 377 struct iw_request_info *info, 378 struct iw_freq *wrq, 379 char *extra) 380{ 381 PSDevice pDevice = (PSDevice)netdev_priv(dev); 382 int rc = 0; 383 384 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n"); 385 386 // If setting by frequency, convert to a channel 387 if((wrq->e == 1) && 388 (wrq->m >= (int) 2.412e8) && 389 (wrq->m <= (int) 2.487e8)) { 390 int f = wrq->m / 100000; 391 int c = 0; 392 while((c < 14) && (f != frequency_list[c])) 393 c++; 394 wrq->e = 0; 395 wrq->m = c + 1; 396 } 397 // Setting by channel number 398 if((wrq->m > 14) || (wrq->e > 0)) 399 rc = -EOPNOTSUPP; 400 else { 401 int channel = wrq->m; 402 if((channel < 1) || (channel > 14)) { 403 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m); 404 rc = -EINVAL; 405 } else { 406 // Yes ! We can set it !!! 407 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel); 408 pDevice->uChannel = channel; 409 //2007-0207-04,<Add> by EinsnLiu 410 //Make change effect at once 411 pDevice->bCommit = true; 412 } 413 } 414 415 return rc; 416} 417 418/* 419 * Wireless Handler : get frequence or channel 420 */ 421 422int iwctl_giwfreq(struct net_device *dev, 423 struct iw_request_info *info, 424 struct iw_freq *wrq, 425 char *extra) 426{ 427 PSDevice pDevice = (PSDevice)netdev_priv(dev); 428 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 429 430 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n"); 431 432#ifdef WEXT_USECHANNELS 433 wrq->m = (int)pMgmt->uCurrChannel; 434 wrq->e = 0; 435#else 436 { 437 int f = (int)pMgmt->uCurrChannel - 1; 438 if(f < 0) 439 f = 0; 440 wrq->m = frequency_list[f] * 100000; 441 wrq->e = 1; 442 } 443#endif 444 445 return 0; 446} 447 448/* 449 * Wireless Handler : set operation mode 450 */ 451 452int iwctl_siwmode(struct net_device *dev, 453 struct iw_request_info *info, 454 __u32 *wmode, 455 char *extra) 456{ 457 PSDevice pDevice = (PSDevice)netdev_priv(dev); 458 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 459 int rc = 0; 460 461 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n"); 462 463 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) { 464 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n"); 465 return rc; 466 } 467 468 switch(*wmode) { 469 470 case IW_MODE_ADHOC: 471 if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) { 472 pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; 473 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 474 pDevice->bCommit = true; 475 } 476 } 477 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n"); 478 break; 479 case IW_MODE_AUTO: 480 case IW_MODE_INFRA: 481 if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) { 482 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; 483 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 484 pDevice->bCommit = true; 485 } 486 } 487 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n"); 488 break; 489 case IW_MODE_MASTER: 490 491 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; 492 rc = -EOPNOTSUPP; 493 break; 494 495 if (pMgmt->eConfigMode != WMAC_CONFIG_AP) { 496 pMgmt->eConfigMode = WMAC_CONFIG_AP; 497 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 498 pDevice->bCommit = true; 499 } 500 } 501 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n"); 502 break; 503 504 case IW_MODE_REPEAT: 505 pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; 506 rc = -EOPNOTSUPP; 507 break; 508 default: 509 rc = -EINVAL; 510 } 511 512 return rc; 513} 514 515/* 516 * Wireless Handler : get operation mode 517 */ 518 519int iwctl_giwmode(struct net_device *dev, 520 struct iw_request_info *info, 521 __u32 *wmode, 522 char *extra) 523{ 524 PSDevice pDevice = (PSDevice)netdev_priv(dev); 525 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 526 527 528 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n"); 529 // If not managed, assume it's ad-hoc 530 switch (pMgmt->eConfigMode) { 531 case WMAC_CONFIG_ESS_STA: 532 *wmode = IW_MODE_INFRA; 533 break; 534 case WMAC_CONFIG_IBSS_STA: 535 *wmode = IW_MODE_ADHOC; 536 break; 537 case WMAC_CONFIG_AUTO: 538 *wmode = IW_MODE_INFRA; 539 break; 540 case WMAC_CONFIG_AP: 541 *wmode = IW_MODE_MASTER; 542 break; 543 default: 544 *wmode = IW_MODE_ADHOC; 545 } 546 547 return 0; 548} 549 550 551/* 552 * Wireless Handler : get capability range 553 */ 554 555int iwctl_giwrange(struct net_device *dev, 556 struct iw_request_info *info, 557 struct iw_point *wrq, 558 char *extra) 559{ 560 struct iw_range *range = (struct iw_range *) extra; 561 int i,k; 562 unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; 563 564 565 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n"); 566 if (wrq->pointer) { 567 wrq->length = sizeof(struct iw_range); 568 memset(range, 0, sizeof(struct iw_range)); 569 range->min_nwid = 0x0000; 570 range->max_nwid = 0x0000; 571 range->num_channels = 14; 572 // Should be based on cap_rid.country to give only 573 // what the current card support 574 k = 0; 575 for(i = 0; i < 14; i++) { 576 range->freq[k].i = i + 1; // List index 577 range->freq[k].m = frequency_list[i] * 100000; 578 range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10 579 } 580 range->num_frequency = k; 581 // Hum... Should put the right values there 582 #ifdef Calcu_LinkQual 583 range->max_qual.qual = 100; 584 #else 585 range->max_qual.qual = 255; 586 #endif 587 range->max_qual.level = 0; 588 range->max_qual.noise = 0; 589 range->sensitivity = 255; 590 591 for(i = 0 ; i < 13 ; i++) { 592 range->bitrate[i] = abySupportedRates[i] * 500000; 593 if(range->bitrate[i] == 0) 594 break; 595 } 596 range->num_bitrates = i; 597 598 // Set an indication of the max TCP throughput 599 // in bit/s that we can expect using this interface. 600 // May be use for QoS stuff... Jean II 601 if(i > 2) 602 range->throughput = 5 * 1000 * 1000; 603 else 604 range->throughput = 1.5 * 1000 * 1000; 605 606 range->min_rts = 0; 607 range->max_rts = 2312; 608 range->min_frag = 256; 609 range->max_frag = 2312; 610 611 612 // the encoding capabilities 613 range->num_encoding_sizes = 3; 614 // 64(40) bits WEP 615 range->encoding_size[0] = 5; 616 // 128(104) bits WEP 617 range->encoding_size[1] = 13; 618 // 256 bits for WPA-PSK 619 range->encoding_size[2] = 32; 620 // 4 keys are allowed 621 range->max_encoding_tokens = 4; 622 623 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | 624 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; 625 626 range->min_pmp = 0; 627 range->max_pmp = 1000000;// 1 secs 628 range->min_pmt = 0; 629 range->max_pmt = 1000000;// 1 secs 630 range->pmp_flags = IW_POWER_PERIOD; 631 range->pmt_flags = IW_POWER_TIMEOUT; 632 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; 633 634 // Transmit Power - values are in mW 635 636 range->txpower[0] = 100; 637 range->num_txpower = 1; 638 range->txpower_capa = IW_TXPOW_MWATT; 639 range->we_version_source = SUPPORTED_WIRELESS_EXT; 640 range->we_version_compiled = WIRELESS_EXT; 641 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME; 642 range->retry_flags = IW_RETRY_LIMIT; 643 range->r_time_flags = IW_RETRY_LIFETIME; 644 range->min_retry = 1; 645 range->max_retry = 65535; 646 range->min_r_time = 1024; 647 range->max_r_time = 65535 * 1024; 648 // Experimental measurements - boundary 11/5.5 Mb/s 649 // Note : with or without the (local->rssi), results 650 // are somewhat different. - Jean II 651 range->avg_qual.qual = 6; 652 range->avg_qual.level = 176; // -80 dBm 653 range->avg_qual.noise = 0; 654 } 655 656 657 return 0; 658} 659 660 661/* 662 * Wireless Handler : set ap mac address 663 */ 664 665int iwctl_siwap(struct net_device *dev, 666 struct iw_request_info *info, 667 struct sockaddr *wrq, 668 char *extra) 669{ 670 PSDevice pDevice = (PSDevice)netdev_priv(dev); 671 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 672 int rc = 0; 673 unsigned char ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00}; 674 675 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP \n"); 676if (pMgmt->eScanState == WMAC_IS_SCANNING) { 677 // In scanning.. 678 printk("SIOCSIWAP(??)-->In scanning...\n"); 679 // return -EAGAIN; 680 } 681 if (wrq->sa_family != ARPHRD_ETHER) 682 rc = -EINVAL; 683 else { 684 memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); 685 //2008-0409-05, <Add> by Einsn Liu 686 if((pDevice->bLinkPass == true) && 687 (memcmp(pMgmt->abyDesireBSSID, pMgmt->abyCurrBSSID, 6)== 0)){ 688 return rc; 689 } 690 //mike :add 691 if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) || 692 (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){ 693 PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n"); 694 return rc; 695 } 696 //mike add: if desired AP is hidden ssid(there are two same BSSID in list), 697 // then ignore,because you don't known which one to be connect with?? 698 { 699 unsigned int ii , uSameBssidNum=0; 700 for (ii = 0; ii < MAX_BSS_NUM; ii++) { 701 if (pMgmt->sBSSList[ii].bActive && 702 !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyDesireBSSID)) { 703 uSameBssidNum++; 704 } 705 } 706 if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! 707 PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n"); 708 return rc; 709 } 710 } 711 712 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 713 pDevice->bCommit = true; 714 } 715 } 716 return rc; 717} 718 719/* 720 * Wireless Handler : get ap mac address 721 */ 722 723int iwctl_giwap(struct net_device *dev, 724 struct iw_request_info *info, 725 struct sockaddr *wrq, 726 char *extra) 727{ 728 PSDevice pDevice = (PSDevice)netdev_priv(dev); 729 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 730 731 732 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n"); 733 734 memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); 735 //2008-0410,<Modify> by Einsn Liu 736 if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)) 737 memset(wrq->sa_data, 0, 6); 738 739 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { 740 memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); 741 } 742 743 wrq->sa_family = ARPHRD_ETHER; 744 745 return 0; 746 747} 748 749 750/* 751 * Wireless Handler : get ap list 752 */ 753 754int iwctl_giwaplist(struct net_device *dev, 755 struct iw_request_info *info, 756 struct iw_point *wrq, 757 char *extra) 758{ 759 int ii,jj, rc = 0; 760 struct sockaddr sock[IW_MAX_AP]; 761 struct iw_quality qual[IW_MAX_AP]; 762 PSDevice pDevice = (PSDevice)netdev_priv(dev); 763 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 764 765 766 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); 767 // Only super-user can see AP list 768 769 if (!capable(CAP_NET_ADMIN)) { 770 rc = -EPERM; 771 return rc; 772 } 773 774 if (wrq->pointer) { 775 776 PKnownBSS pBSS = &(pMgmt->sBSSList[0]); 777 778 for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) { 779 pBSS = &(pMgmt->sBSSList[ii]); 780 if (!pBSS->bActive) 781 continue; 782 if ( jj >= IW_MAX_AP) 783 break; 784 memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6); 785 sock[jj].sa_family = ARPHRD_ETHER; 786 qual[jj].level = pBSS->uRSSI; 787 qual[jj].qual = qual[jj].noise = 0; 788 qual[jj].updated = 2; 789 jj++; 790 } 791 792 wrq->flags = 1; // Should be define'd 793 wrq->length = jj; 794 memcpy(extra, sock, sizeof(struct sockaddr)*jj); 795 memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj); 796 } 797 798 return rc; 799} 800 801 802/* 803 * Wireless Handler : set essid 804 */ 805 806int iwctl_siwessid(struct net_device *dev, 807 struct iw_request_info *info, 808 struct iw_point *wrq, 809 char *extra) 810{ 811 PSDevice pDevice = (PSDevice)netdev_priv(dev); 812 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 813 PWLAN_IE_SSID pItemSSID; 814 //2008-0409-05, <Add> by Einsn Liu 815 unsigned char len; 816 817 818 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID \n"); 819 pDevice->fWPA_Authened = false; 820if (pMgmt->eScanState == WMAC_IS_SCANNING) { 821 // In scanning.. 822 printk("SIOCSIWESSID(??)-->In scanning...\n"); 823 // return -EAGAIN; 824 } 825 // Check if we asked for `any' 826 if(wrq->flags == 0) { 827 // Just send an empty SSID list 828 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 829 memset(pMgmt->abyDesireBSSID, 0xFF,6); 830 PRINT_K("set essid to 'any' \n"); 831 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT 832 //Unknown desired AP,so here need not associate?? 833 //if(pDevice->bWPASuppWextEnabled == true) { 834 return 0; 835 // } 836 #endif 837 } else { 838 // Set the SSID 839 memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); 840 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; 841 pItemSSID->byElementID = WLAN_EID_SSID; 842 843 memcpy(pItemSSID->abySSID, extra, wrq->length); 844 if (pItemSSID->abySSID[wrq->length - 1] == '\0') { 845 if(wrq->length>0) 846 pItemSSID->len = wrq->length - 1; 847 } 848 else 849 pItemSSID->len = wrq->length; 850 printk("set essid to %s \n",pItemSSID->abySSID); 851 //2008-0409-05, <Add> by Einsn Liu 852 len=(pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)?pItemSSID->len:((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len; 853 if((pDevice->bLinkPass == true) && 854 (memcmp(pItemSSID->abySSID,((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,len)==0)) 855 return 0; 856 857 //mike:need clear desiredBSSID 858 if(pItemSSID->len==0) { 859 memset(pMgmt->abyDesireBSSID, 0xFF,6); 860 return 0; 861 } 862 863#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT 864 //Wext wil order another command of siwap to link with desired AP, 865 //so here need not associate?? 866 if(pDevice->bWPASuppWextEnabled == true) { 867 /*******search if in hidden ssid mode ****/ 868 { 869 PKnownBSS pCurr = NULL; 870 unsigned char abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; 871 unsigned int ii , uSameBssidNum=0; 872 873 memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); 874 pCurr = BSSpSearchBSSList(pDevice, 875 NULL, 876 abyTmpDesireSSID, 877 pMgmt->eConfigPHYMode 878 ); 879 880 if (pCurr == NULL){ 881 PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); 882 vResetCommandTimer((void *) pDevice); 883 pMgmt->eScanType = WMAC_SCAN_ACTIVE; 884 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); 885 bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); 886 } 887 else { //mike:to find out if that desired SSID is a hidden-ssid AP , 888 // by means of judging if there are two same BSSID exist in list ? 889 for (ii = 0; ii < MAX_BSS_NUM; ii++) { 890 if (pMgmt->sBSSList[ii].bActive && 891 !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) { 892 uSameBssidNum++; 893 } 894 } 895 if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! 896 printk("SIOCSIWESSID:hidden ssid directly associate.......\n"); 897 vResetCommandTimer((void *) pDevice); 898 pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! 899 bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); 900 bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); 901 } 902 } 903 } 904 return 0; 905 } 906 #endif 907 908 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID); 909 } 910 911 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 912 pDevice->bCommit = true; 913 } 914 915 916 return 0; 917} 918 919 920/* 921 * Wireless Handler : get essid 922 */ 923 924int iwctl_giwessid(struct net_device *dev, 925 struct iw_request_info *info, 926 struct iw_point *wrq, 927 char *extra) 928{ 929 930 PSDevice pDevice = (PSDevice)netdev_priv(dev); 931 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 932 PWLAN_IE_SSID pItemSSID; 933 934 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n"); 935 936 // Note : if wrq->u.data.flags != 0, we should 937 // get the relevant SSID from the SSID list... 938 939 // Get the current SSID 940 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; 941 //pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; 942 memcpy(extra, pItemSSID->abySSID , pItemSSID->len); 943 extra[pItemSSID->len] = '\0'; 944 wrq->length = pItemSSID->len + 1; 945 //2008-0409-03, <Add> by Einsn Liu 946 wrq->length = pItemSSID->len; 947 wrq->flags = 1; // active 948 949 950 return 0; 951} 952 953/* 954 * Wireless Handler : set data rate 955 */ 956 957int iwctl_siwrate(struct net_device *dev, 958 struct iw_request_info *info, 959 struct iw_param *wrq, 960 char *extra) 961{ 962 PSDevice pDevice = (PSDevice)netdev_priv(dev); 963 int rc = 0; 964 u8 brate = 0; 965 int i; 966 unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; 967 968 969 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n"); 970 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { 971 rc = -EINVAL; 972 return rc; 973 } 974 975 // First : get a valid bit rate value 976 977 // Which type of value 978 if((wrq->value < 13) && 979 (wrq->value >= 0)) { 980 // Setting by rate index 981 // Find value in the magic rate table 982 brate = wrq->value; 983 } else { 984 // Setting by frequency value 985 u8 normvalue = (u8) (wrq->value/500000); 986 987 // Check if rate is valid 988 for(i = 0 ; i < 13 ; i++) { 989 if(normvalue == abySupportedRates[i]) { 990 brate = i; 991 break; 992 } 993 } 994 } 995 // -1 designed the max rate (mostly auto mode) 996 if(wrq->value == -1) { 997 // Get the highest available rate 998 for(i = 0 ; i < 13 ; i++) { 999 if(abySupportedRates[i] == 0) 1000 break; 1001 } 1002 if(i != 0) 1003 brate = i - 1; 1004 1005 } 1006 // Check that it is valid 1007 // brate is index of abySupportedRates[] 1008 if(brate > 13 ) { 1009 rc = -EINVAL; 1010 return rc; 1011 } 1012 1013 // Now, check if we want a fixed or auto value 1014 if(wrq->fixed != 0) { 1015 // Fixed mode 1016 // One rate, fixed 1017 printk("Rate Fix\n"); 1018 pDevice->bFixRate = true; 1019 if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) { 1020 pDevice->uConnectionRate = 3; 1021 } 1022 else { 1023 pDevice->uConnectionRate = brate; 1024 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate); 1025 } 1026 1027 } 1028 else { 1029 pDevice->bFixRate = false; 1030 pDevice->uConnectionRate = 13; 1031 printk("auto rate:connection_rate is 13\n"); 1032 } 1033 1034 return rc; 1035} 1036 1037/* 1038 * Wireless Handler : get data rate 1039 */ 1040 1041int iwctl_giwrate(struct net_device *dev, 1042 struct iw_request_info *info, 1043 struct iw_param *wrq, 1044 char *extra) 1045{ 1046 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1047//2007-0118-05,<Mark> by EinsnLiu 1048//Mark the unnecessary sentences. 1049// PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1050 1051 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n"); 1052 { 1053 unsigned char abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; 1054 int brate = 0; 1055//2008-5-8 <modify> by chester 1056if(pDevice->bLinkPass){ 1057if(pDevice->bFixRate == true){ 1058 if (pDevice->uConnectionRate < 13) { 1059 brate = abySupportedRates[pDevice->uConnectionRate]; 1060 }else { 1061 if (pDevice->byBBType == BB_TYPE_11B) 1062 brate = 0x16; 1063 if (pDevice->byBBType == BB_TYPE_11G) 1064 brate = 0x6C; 1065 if (pDevice->byBBType == BB_TYPE_11A) 1066 brate = 0x6C; 1067 } 1068} 1069else 1070{ 1071 1072 brate = abySupportedRates[TxRate_iwconfig]; 1073} 1074} 1075else brate =0; 1076//2007-0118-05,<Mark> by EinsnLiu 1077//Mark the unnecessary sentences. 1078/* 1079 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { 1080 if (pDevice->byBBType == BB_TYPE_11B) 1081 brate = 0x16; 1082 if (pDevice->byBBType == BB_TYPE_11G) 1083 brate = 0x6C; 1084 if (pDevice->byBBType == BB_TYPE_11A) 1085 brate = 0x6C; 1086 } 1087*/ 1088 1089// if (pDevice->uConnectionRate == 13) 1090// brate = abySupportedRates[pDevice->wCurrentRate]; 1091 wrq->value = brate * 500000; 1092 // If more than one rate, set auto 1093 if (pDevice->bFixRate == true) 1094 wrq->fixed = true; 1095 } 1096 1097 1098 return 0; 1099} 1100 1101 1102 1103/* 1104 * Wireless Handler : set rts threshold 1105 */ 1106 1107int iwctl_siwrts(struct net_device *dev, 1108 struct iw_request_info *info, 1109 struct iw_param *wrq, 1110 char *extra) 1111{ 1112 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1113 int rc = 0; 1114 1115 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n"); 1116 1117 { 1118 int rthr = wrq->value; 1119 if(wrq->disabled) 1120 rthr = 2312; 1121 if((rthr < 0) || (rthr > 2312)) { 1122 rc = -EINVAL; 1123 }else { 1124 pDevice->wRTSThreshold = rthr; 1125 } 1126 } 1127 1128 return 0; 1129} 1130 1131/* 1132 * Wireless Handler : get rts 1133 */ 1134 1135int iwctl_giwrts(struct net_device *dev, 1136 struct iw_request_info *info, 1137 struct iw_param *wrq, 1138 char *extra) 1139{ 1140 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1141 1142 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n"); 1143 wrq->value = pDevice->wRTSThreshold; 1144 wrq->disabled = (wrq->value >= 2312); 1145 wrq->fixed = 1; 1146 1147 return 0; 1148} 1149 1150/* 1151 * Wireless Handler : set fragment threshold 1152 */ 1153 1154int iwctl_siwfrag(struct net_device *dev, 1155 struct iw_request_info *info, 1156 struct iw_param *wrq, 1157 char *extra) 1158{ 1159 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1160 int rc = 0; 1161 int fthr = wrq->value; 1162 1163 1164 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n"); 1165 1166 1167 if (wrq->disabled) 1168 fthr = 2312; 1169 if((fthr < 256) || (fthr > 2312)) { 1170 rc = -EINVAL; 1171 }else { 1172 fthr &= ~0x1; // Get an even value 1173 pDevice->wFragmentationThreshold = (u16)fthr; 1174 } 1175 1176 return rc; 1177} 1178 1179/* 1180 * Wireless Handler : get fragment threshold 1181 */ 1182 1183int iwctl_giwfrag(struct net_device *dev, 1184 struct iw_request_info *info, 1185 struct iw_param *wrq, 1186 char *extra) 1187{ 1188 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1189 1190 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n"); 1191 wrq->value = pDevice->wFragmentationThreshold; 1192 wrq->disabled = (wrq->value >= 2312); 1193 wrq->fixed = 1; 1194 1195 return 0; 1196} 1197 1198 1199 1200/* 1201 * Wireless Handler : set retry threshold 1202 */ 1203int iwctl_siwretry(struct net_device *dev, 1204 struct iw_request_info *info, 1205 struct iw_param *wrq, 1206 char *extra) 1207{ 1208 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1209 int rc = 0; 1210 1211 1212 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n"); 1213 1214 if (wrq->disabled) { 1215 rc = -EINVAL; 1216 return rc; 1217 } 1218 1219 if (wrq->flags & IW_RETRY_LIMIT) { 1220 if(wrq->flags & IW_RETRY_MAX) 1221 pDevice->byLongRetryLimit = wrq->value; 1222 else if (wrq->flags & IW_RETRY_MIN) 1223 pDevice->byShortRetryLimit = wrq->value; 1224 else { 1225 // No modifier : set both 1226 pDevice->byShortRetryLimit = wrq->value; 1227 pDevice->byLongRetryLimit = wrq->value; 1228 } 1229 } 1230 if (wrq->flags & IW_RETRY_LIFETIME) { 1231 pDevice->wMaxTransmitMSDULifetime = wrq->value; 1232 } 1233 1234 1235 return rc; 1236} 1237 1238/* 1239 * Wireless Handler : get retry threshold 1240 */ 1241int iwctl_giwretry(struct net_device *dev, 1242 struct iw_request_info *info, 1243 struct iw_param *wrq, 1244 char *extra) 1245{ 1246 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1247 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n"); 1248 wrq->disabled = 0; // Can't be disabled 1249 1250 // Note : by default, display the min retry number 1251 if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { 1252 wrq->flags = IW_RETRY_LIFETIME; 1253 wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms 1254 } else if((wrq->flags & IW_RETRY_MAX)) { 1255 wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; 1256 wrq->value = (int)pDevice->byLongRetryLimit; 1257 } else { 1258 wrq->flags = IW_RETRY_LIMIT; 1259 wrq->value = (int)pDevice->byShortRetryLimit; 1260 if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit) 1261 wrq->flags |= IW_RETRY_MIN; 1262 } 1263 1264 1265 return 0; 1266} 1267 1268 1269/* 1270 * Wireless Handler : set encode mode 1271 */ 1272int iwctl_siwencode(struct net_device *dev, 1273 struct iw_request_info *info, 1274 struct iw_point *wrq, 1275 char *extra) 1276{ 1277 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1278 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1279 unsigned long dwKeyIndex = (unsigned long)(wrq->flags & IW_ENCODE_INDEX); 1280 int ii,uu, rc = 0; 1281 int index = (wrq->flags & IW_ENCODE_INDEX); 1282 1283//2007-0207-07,<Modify> by EinsnLiu 1284//There are some problems when using iwconfig encode/key command to set the WEP key. 1285//I almost rewrite this function. 1286//now it support:(assume the wireless interface's name is eth0) 1287//iwconfig eth0 key [1] 1122334455 open /*set key stirng to index 1,and driver using key index is set to 1*/ 1288//iwconfig eth0 key [3] /*set driver using key index to 3,the key string no change */ 1289//iwconfig eth0 key 1122334455 /*set key string to driver using index*/ 1290//iwconfig eth0 key restricted /*enable share key*/ 1291 1292 PSKeyTable pkeytab; 1293 1294 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); 1295 1296if((wrq->flags & IW_ENCODE_DISABLED)==0){ 1297 //Not disable encryption 1298 1299 if (dwKeyIndex > WLAN_WEP_NKEYS) { 1300 rc = -EINVAL; 1301 return rc; 1302 } 1303 1304 if(dwKeyIndex<1&&((wrq->flags&IW_ENCODE_NOKEY)==0)){//set default key 1305 if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){ 1306 dwKeyIndex=pDevice->byKeyIndex; 1307 } 1308 else dwKeyIndex=0; 1309 }else dwKeyIndex--; 1310 1311 1312 // Check the size of the key 1313 if (wrq->length > WLAN_WEP232_KEYLEN) { 1314 rc = -EINVAL; 1315 return rc; 1316 } 1317 1318 if(wrq->length>0){//have key 1319 1320 if (wrq->length == WLAN_WEP232_KEYLEN) { 1321 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); 1322 } 1323 else if (wrq->length == WLAN_WEP104_KEYLEN) { 1324 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); 1325 } 1326 else if (wrq->length == WLAN_WEP40_KEYLEN) { 1327 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); 1328 }else {//no support length 1329 rc = -EINVAL; 1330 return rc; 1331 } 1332 memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); 1333 memcpy(pDevice->abyKey, extra, wrq->length); 1334 1335 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: "); 1336 for (ii = 0; ii < wrq->length; ii++) { 1337 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); 1338 } 1339 1340 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 1341 spin_lock_irq(&pDevice->lock); 1342 KeybSetDefaultKey(&(pDevice->sKey), 1343 (unsigned long)(dwKeyIndex | (1 << 31)), 1344 wrq->length, 1345 NULL, 1346 pDevice->abyKey, 1347 KEY_CTL_WEP, 1348 pDevice->PortOffset, 1349 pDevice->byLocalID 1350 ); 1351 spin_unlock_irq(&pDevice->lock); 1352 } 1353 pDevice->byKeyIndex = (unsigned char)dwKeyIndex; 1354 pDevice->uKeyLength = wrq->length; 1355 pDevice->bTransmitKey = true; 1356 pDevice->bEncryptionEnable = true; 1357 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 1358 1359 }else if(index>0){ 1360 //when the length is 0 the request only changes the default transmit key index 1361 //check the new key has a non zero lenget 1362 if(pDevice->bEncryptionEnable==false) 1363 { 1364 rc = -EINVAL; 1365 return rc; 1366 } 1367 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Just set Default key Index:\n"); 1368 pkeytab=&(pDevice->sKey.KeyTable[MAX_KEY_TABLE-1]); 1369 if(pkeytab->GroupKey[(unsigned char)dwKeyIndex].uKeyLength==0){ 1370 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Default key len is 0\n"); 1371 rc = -EINVAL; 1372 return rc; 1373 } 1374 pDevice->byKeyIndex =(unsigned char)dwKeyIndex; 1375 pkeytab->dwGTKeyIndex =dwKeyIndex | (1 << 31); 1376 pkeytab->GroupKey[(unsigned char)dwKeyIndex].dwKeyIndex=dwKeyIndex | (1 << 31); 1377 } 1378 1379}else {//disable the key 1380 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); 1381 if(pDevice->bEncryptionEnable==false) 1382 return 0; 1383 pMgmt->bShareKeyAlgorithm = false; 1384 pDevice->bEncryptionEnable = false; 1385 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 1386 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 1387 spin_lock_irq(&pDevice->lock); 1388 for(uu=0;uu<MAX_KEY_TABLE;uu++) 1389 MACvDisableKeyEntry(pDevice->PortOffset, uu); 1390 spin_unlock_irq(&pDevice->lock); 1391 } 1392} 1393//End Modify,Einsn 1394 1395/* 1396 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n"); 1397 1398 // Check the size of the key 1399 if (wrq->length > WLAN_WEP232_KEYLEN) { 1400 rc = -EINVAL; 1401 return rc; 1402 } 1403 1404 if (dwKeyIndex > WLAN_WEP_NKEYS) { 1405 rc = -EINVAL; 1406 return rc; 1407 } 1408 1409 if (dwKeyIndex > 0) 1410 dwKeyIndex--; 1411 1412 // Send the key to the card 1413 if (wrq->length > 0) { 1414 1415 if (wrq->length == WLAN_WEP232_KEYLEN) { 1416 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); 1417 } 1418 else if (wrq->length == WLAN_WEP104_KEYLEN) { 1419 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); 1420 } 1421 else if (wrq->length == WLAN_WEP40_KEYLEN) { 1422 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); 1423 } 1424 memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); 1425 memcpy(pDevice->abyKey, extra, wrq->length); 1426 1427 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: "); 1428 for (ii = 0; ii < wrq->length; ii++) { 1429 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); 1430 } 1431 1432 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 1433 spin_lock_irq(&pDevice->lock); 1434 KeybSetDefaultKey(&(pDevice->sKey), 1435 (unsigned long)(pDevice->byKeyIndex | (1 << 31)), 1436 pDevice->uKeyLength, 1437 NULL, 1438 pDevice->abyKey, 1439 KEY_CTL_WEP, 1440 pDevice->PortOffset, 1441 pDevice->byLocalID 1442 ); 1443 spin_unlock_irq(&pDevice->lock); 1444 } 1445 pDevice->byKeyIndex = (unsigned char)dwKeyIndex; 1446 pDevice->uKeyLength = wrq->length; 1447 pDevice->bTransmitKey = true; 1448 pDevice->bEncryptionEnable = true; 1449 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 1450 1451 // Do we want to just set the transmit key index ? 1452 if ( index < 4 ) { 1453 pDevice->byKeyIndex = index; 1454 } 1455 else if(!(wrq->flags & IW_ENCODE_MODE)) { 1456 rc = -EINVAL; 1457 return rc; 1458 } 1459 } 1460 // Read the flags 1461 if(wrq->flags & IW_ENCODE_DISABLED){ 1462 1463 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); 1464 pMgmt->bShareKeyAlgorithm = false; 1465 pDevice->bEncryptionEnable = false; 1466 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 1467 if (pDevice->flags & DEVICE_FLAGS_OPENED) { 1468 spin_lock_irq(&pDevice->lock); 1469 for(uu=0;uu<MAX_KEY_TABLE;uu++) 1470 MACvDisableKeyEntry(pDevice->PortOffset, uu); 1471 spin_unlock_irq(&pDevice->lock); 1472 } 1473 } 1474*/ 1475 1476 if(wrq->flags & IW_ENCODE_RESTRICTED) { 1477 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n"); 1478 pMgmt->bShareKeyAlgorithm = true; 1479 } 1480 if(wrq->flags & IW_ENCODE_OPEN) { 1481 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n"); 1482 pMgmt->bShareKeyAlgorithm = false; 1483 } 1484 return rc; 1485} 1486 1487/* 1488 * Wireless Handler : get encode mode 1489 */ 1490 /* 1491int iwctl_giwencode(struct net_device *dev, 1492 struct iw_request_info *info, 1493 struct iw_point *wrq, 1494 char *extra) 1495{ 1496 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1497 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1498 int rc = 0; 1499 char abyKey[WLAN_WEP232_KEYLEN]; 1500 unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); 1501 PSKeyItem pKey = NULL; 1502 1503 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); 1504//2007-0207-06,<Add> by EinsnLiu 1505//the key index in iwconfig is 1-4 when our driver is 0-3 1506//so it can't be used directly. 1507//if the index is 0,we should used the index set by driver. 1508 if (index > WLAN_WEP_NKEYS) { 1509 rc = -EINVAL; 1510 return rc; 1511 } 1512 if(index<1){//set default key 1513 if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){ 1514 index=pDevice->byKeyIndex; 1515 } 1516 else index=0; 1517 }else index--; 1518//End Add,Einsn 1519 1520 memset(abyKey, 0, sizeof(abyKey)); 1521 // Check encryption mode 1522 wrq->flags = IW_ENCODE_NOKEY; 1523 // Is WEP enabled ??? 1524 if (pDevice->bEncryptionEnable) 1525 wrq->flags |= IW_ENCODE_ENABLED; 1526 else 1527 wrq->flags |= IW_ENCODE_DISABLED; 1528 1529 if (pMgmt->bShareKeyAlgorithm) 1530 wrq->flags |= IW_ENCODE_RESTRICTED; 1531 else 1532 wrq->flags |= IW_ENCODE_OPEN; 1533 1534 if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)){ 1535 wrq->length = pKey->uKeyLength; 1536 memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); 1537//2007-0207-06,<Modify> by EinsnLiu 1538//only get key success need to copy data 1539//index should +1. 1540//there is not necessary to return -EINVAL when get key failed 1541//if return -EINVAL,the encryption item can't be display by the command "iwconfig". 1542 wrq->flags |= index+1; 1543 memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); 1544 } 1545 1546 //else { 1547 // rc = -EINVAL; 1548 // return rc; 1549 // } 1550 1551 1552//End Modify,Einsn 1553 1554 return 0; 1555} 1556*/ 1557 1558//2008-0409-06, <Add> by Einsn Liu 1559 1560int iwctl_giwencode(struct net_device *dev, 1561 struct iw_request_info *info, 1562 struct iw_point *wrq, 1563 char *extra) 1564{ 1565 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1566 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1567 char abyKey[WLAN_WEP232_KEYLEN]; 1568 1569 unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); 1570 PSKeyItem pKey = NULL; 1571 1572 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); 1573 1574 if (index > WLAN_WEP_NKEYS) { 1575 return -EINVAL; 1576 } 1577 if(index<1){//get default key 1578 if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){ 1579 index=pDevice->byKeyIndex; 1580 } else 1581 index=0; 1582 }else 1583 index--; 1584 1585 memset(abyKey, 0, WLAN_WEP232_KEYLEN); 1586 // Check encryption mode 1587 wrq->flags = IW_ENCODE_NOKEY; 1588 // Is WEP enabled ??? 1589 if (pDevice->bEncryptionEnable) 1590 wrq->flags |= IW_ENCODE_ENABLED; 1591 else 1592 wrq->flags |= IW_ENCODE_DISABLED; 1593 1594 if (pMgmt->bShareKeyAlgorithm) 1595 wrq->flags |= IW_ENCODE_RESTRICTED; 1596 else 1597 wrq->flags |= IW_ENCODE_OPEN; 1598 wrq->length=0; 1599 1600 if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled|| 1601 pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise key 1602 if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){ 1603 wrq->length = pKey->uKeyLength; 1604 memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); 1605 memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); 1606 } 1607 }else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (unsigned char)index , &pKey)){ 1608 wrq->length = pKey->uKeyLength; 1609 memcpy(abyKey, pKey->abyKey, pKey->uKeyLength); 1610 memcpy(extra, abyKey, WLAN_WEP232_KEYLEN); 1611 } 1612 1613 wrq->flags |= index+1; 1614 1615 return 0; 1616} 1617 1618 1619/* 1620 * Wireless Handler : set power mode 1621 */ 1622int iwctl_siwpower(struct net_device *dev, 1623 struct iw_request_info *info, 1624 struct iw_param *wrq, 1625 char *extra) 1626{ 1627 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1628 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1629 int rc = 0; 1630 1631 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n"); 1632 1633 if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { 1634 rc = -EINVAL; 1635 return rc; 1636 } 1637 1638 if (wrq->disabled) { 1639 pDevice->ePSMode = WMAC_POWER_CAM; 1640 PSvDisablePowerSaving(pDevice); 1641 return rc; 1642 } 1643 if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { 1644 pDevice->ePSMode = WMAC_POWER_FAST; 1645 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); 1646 1647 } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { 1648 pDevice->ePSMode = WMAC_POWER_FAST; 1649 PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); 1650 } 1651 switch (wrq->flags & IW_POWER_MODE) { 1652 case IW_POWER_UNICAST_R: 1653 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n"); 1654 rc = -EINVAL; 1655 break; 1656 case IW_POWER_ALL_R: 1657 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n"); 1658 rc = -EINVAL; 1659 case IW_POWER_ON: 1660 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n"); 1661 break; 1662 default: 1663 rc = -EINVAL; 1664 } 1665 1666 return rc; 1667} 1668 1669/* 1670 * Wireless Handler : get power mode 1671 */ 1672int iwctl_giwpower(struct net_device *dev, 1673 struct iw_request_info *info, 1674 struct iw_param *wrq, 1675 char *extra) 1676{ 1677 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1678 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1679 int mode = pDevice->ePSMode; 1680 1681 1682 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n"); 1683 1684 1685 wrq->disabled = (mode == WMAC_POWER_CAM); 1686 if (wrq->disabled) 1687 return 0; 1688 1689 if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { 1690 wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10); 1691 wrq->flags = IW_POWER_TIMEOUT; 1692 } else { 1693 wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10); 1694 wrq->flags = IW_POWER_PERIOD; 1695 } 1696 wrq->flags |= IW_POWER_ALL_R; 1697 1698 return 0; 1699} 1700 1701 1702/* 1703 * Wireless Handler : get Sensitivity 1704 */ 1705int iwctl_giwsens(struct net_device *dev, 1706 struct iw_request_info *info, 1707 struct iw_param *wrq, 1708 char *extra) 1709{ 1710 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1711 long ldBm; 1712 1713 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n"); 1714 if (pDevice->bLinkPass == true) { 1715 RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); 1716 wrq->value = ldBm; 1717 } 1718 else { 1719 wrq->value = 0; 1720 }; 1721 wrq->disabled = (wrq->value == 0); 1722 wrq->fixed = 1; 1723 1724 1725 return 0; 1726} 1727 1728//2008-0409-07, <Add> by Einsn Liu 1729#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT 1730 1731int iwctl_siwauth(struct net_device *dev, 1732 struct iw_request_info *info, 1733 struct iw_param *wrq, 1734 char *extra) 1735{ 1736 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1737 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1738 int ret=0; 1739 static int wpa_version=0; //must be static to save the last value,einsn liu 1740 static int pairwise=0; 1741 1742 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n"); 1743 switch (wrq->flags & IW_AUTH_INDEX) { 1744 case IW_AUTH_WPA_VERSION: 1745 wpa_version = wrq->value; 1746 if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) { 1747 PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n"); 1748 //pDevice->bWPADevEnable = false; 1749 } 1750 else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) { 1751 PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n"); 1752 } 1753 else { 1754 PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n"); 1755 } 1756 //pDevice->bWPASuppWextEnabled =true; 1757 break; 1758 case IW_AUTH_CIPHER_PAIRWISE: 1759 pairwise = wrq->value; 1760 if(pairwise == IW_AUTH_CIPHER_CCMP){ 1761 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; 1762 }else if(pairwise == IW_AUTH_CIPHER_TKIP){ 1763 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; 1764 }else if(pairwise == IW_AUTH_CIPHER_WEP40||pairwise == IW_AUTH_CIPHER_WEP104){ 1765 pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; 1766 }else if(pairwise == IW_AUTH_CIPHER_NONE){ 1767 //do nothing,einsn liu 1768 }else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 1769 1770 break; 1771 case IW_AUTH_CIPHER_GROUP: 1772 if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED) 1773 break; 1774 if(pairwise == IW_AUTH_CIPHER_NONE){ 1775 if(wrq->value == IW_AUTH_CIPHER_CCMP){ 1776 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; 1777 }else { 1778 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; 1779 } 1780 } 1781 break; 1782 case IW_AUTH_KEY_MGMT: 1783 1784 if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){ 1785 if(wrq->value == IW_AUTH_KEY_MGMT_PSK) 1786 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK; 1787 else pMgmt->eAuthenMode = WMAC_AUTH_WPA2; 1788 }else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){ 1789 if(wrq->value == 0){ 1790 pMgmt->eAuthenMode = WMAC_AUTH_WPANONE; 1791 }else if(wrq->value == IW_AUTH_KEY_MGMT_PSK) 1792 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK; 1793 else pMgmt->eAuthenMode = WMAC_AUTH_WPA; 1794 } 1795 1796 break; 1797 case IW_AUTH_TKIP_COUNTERMEASURES: 1798 break; 1799 case IW_AUTH_DROP_UNENCRYPTED: 1800 break; 1801 case IW_AUTH_80211_AUTH_ALG: 1802 if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){ 1803 pMgmt->bShareKeyAlgorithm=false; 1804 }else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){ 1805 pMgmt->bShareKeyAlgorithm=true; 1806 } 1807 break; 1808 case IW_AUTH_WPA_ENABLED: 1809 //pDevice->bWPADevEnable = !! wrq->value; 1810 break; 1811 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1812 break; 1813 case IW_AUTH_ROAMING_CONTROL: 1814 ret = -EOPNOTSUPP; 1815 break; 1816 case IW_AUTH_PRIVACY_INVOKED: 1817 pDevice->bEncryptionEnable = !!wrq->value; 1818 if(pDevice->bEncryptionEnable == false){ 1819 wpa_version = 0; 1820 pairwise = 0; 1821 pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; 1822 pMgmt->bShareKeyAlgorithm = false; 1823 pMgmt->eAuthenMode = false; 1824 //pDevice->bWPADevEnable = false; 1825 } 1826 1827 break; 1828 default: 1829 ret = -EOPNOTSUPP; 1830 break; 1831 } 1832/* 1833 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version); 1834 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise); 1835 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus); 1836 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode = %d\n",pMgmt->eAuthenMode); 1837 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"true":"false"); 1838 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"true":"false"); 1839 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADevEnable = %s\n",pDevice->bWPADevEnable?"true":"false"); 1840*/ 1841 return ret; 1842} 1843 1844 1845int iwctl_giwauth(struct net_device *dev, 1846 struct iw_request_info *info, 1847 struct iw_param *wrq, 1848 char *extra) 1849{ 1850 return -EOPNOTSUPP; 1851} 1852 1853 1854 1855int iwctl_siwgenie(struct net_device *dev, 1856 struct iw_request_info *info, 1857 struct iw_point *wrq, 1858 char *extra) 1859{ 1860 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1861 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1862 int ret=0; 1863 1864 if(wrq->length){ 1865 if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) { 1866 ret = -EINVAL; 1867 goto out; 1868 } 1869 if(wrq->length > MAX_WPA_IE_LEN){ 1870 ret = -ENOMEM; 1871 goto out; 1872 } 1873 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); 1874 if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){ 1875 ret = -EFAULT; 1876 goto out; 1877 } 1878 pMgmt->wWPAIELen = wrq->length; 1879 }else { 1880 memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN); 1881 pMgmt->wWPAIELen = 0; 1882 } 1883 1884 out://not completely ...not necessary in wpa_supplicant 0.5.8 1885 return 0; 1886} 1887 1888int iwctl_giwgenie(struct net_device *dev, 1889 struct iw_request_info *info, 1890 struct iw_point *wrq, 1891 char *extra) 1892{ 1893 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1894 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 1895 int ret=0; 1896 int space = wrq->length; 1897 1898 wrq->length = 0; 1899 if(pMgmt->wWPAIELen > 0){ 1900 wrq->length = pMgmt->wWPAIELen; 1901 if(pMgmt->wWPAIELen <= space){ 1902 if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){ 1903 ret = -EFAULT; 1904 } 1905 }else 1906 ret = -E2BIG; 1907 } 1908 1909 return ret; 1910} 1911 1912 1913int iwctl_siwencodeext(struct net_device *dev, 1914 struct iw_request_info *info, 1915 struct iw_point *wrq, 1916 char *extra) 1917{ 1918 PSDevice pDevice = (PSDevice)netdev_priv(dev); 1919 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; 1920 struct viawget_wpa_param *param=NULL; 1921//original member 1922 wpa_alg alg_name; 1923 u8 addr[6]; 1924 int key_idx, set_tx=0; 1925 u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; 1926 u8 key[64]; 1927 size_t seq_len=0,key_len=0; 1928// 1929 // int ii; 1930 u8 *buf; 1931 size_t blen; 1932 u8 key_array[64]; 1933 int ret=0; 1934 1935PRINT_K("SIOCSIWENCODEEXT...... \n"); 1936 1937blen = sizeof(*param); 1938buf = kmalloc((int)blen, (int)GFP_KERNEL); 1939if (buf == NULL) 1940 return -ENOMEM; 1941memset(buf, 0, blen); 1942param = (struct viawget_wpa_param *) buf; 1943 1944//recover alg_name 1945switch (ext->alg) { 1946 case IW_ENCODE_ALG_NONE: 1947 alg_name = WPA_ALG_NONE; 1948 break; 1949 case IW_ENCODE_ALG_WEP: 1950 alg_name = WPA_ALG_WEP; 1951 break; 1952 case IW_ENCODE_ALG_TKIP: 1953 alg_name = WPA_ALG_TKIP; 1954 break; 1955 case IW_ENCODE_ALG_CCMP: 1956 alg_name = WPA_ALG_CCMP; 1957 break; 1958 default: 1959 PRINT_K("Unknown alg = %d\n",ext->alg); 1960 ret= -ENOMEM; 1961 goto error; 1962 } 1963//recover addr 1964 memcpy(addr, ext->addr.sa_data, ETH_ALEN); 1965//recover key_idx 1966 key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1; 1967//recover set_tx 1968if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 1969 set_tx = 1; 1970//recover seq,seq_len 1971 if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { 1972 seq_len=IW_ENCODE_SEQ_MAX_SIZE; 1973 memcpy(seq, ext->rx_seq, seq_len); 1974 } 1975//recover key,key_len 1976if(ext->key_len) { 1977 key_len=ext->key_len; 1978 memcpy(key, &ext->key[0], key_len); 1979 } 1980 1981memset(key_array, 0, 64); 1982if ( key_len > 0) { 1983 memcpy(key_array, key, key_len); 1984 if (key_len == 32) { 1985 // notice ! the oder 1986 memcpy(&key_array[16], &key[24], 8); 1987 memcpy(&key_array[24], &key[16], 8); 1988 } 1989 } 1990 1991/**************Translate iw_encode_ext to viawget_wpa_param****************/ 1992memcpy(param->addr, addr, ETH_ALEN); 1993param->u.wpa_key.alg_name = (int)alg_name; 1994param->u.wpa_key.set_tx = set_tx; 1995param->u.wpa_key.key_index = key_idx; 1996param->u.wpa_key.key_len = key_len; 1997param->u.wpa_key.key = (u8 *)key_array; 1998param->u.wpa_key.seq = (u8 *)seq; 1999param->u.wpa_key.seq_len = seq_len; 2000 2001//****set if current action is Network Manager count?? 2002//****this method is so foolish,but there is no other way??? 2003if(param->u.wpa_key.alg_name == WPA_ALG_NONE) { 2004 if(param->u.wpa_key.key_index ==0) { 2005 pDevice->bwextcount++; 2006 } 2007 if((pDevice->bwextcount == 1)&&(param->u.wpa_key.key_index ==1)) { 2008 pDevice->bwextcount++; 2009 } 2010 if((pDevice->bwextcount ==2)&&(param->u.wpa_key.key_index ==2)) { 2011 pDevice->bwextcount++; 2012 } 2013 if((pDevice->bwextcount ==3)&&(param->u.wpa_key.key_index ==3)) { 2014 pDevice->bwextcount++; 2015 } 2016 } 2017if( pDevice->bwextcount == 4) { 2018 printk("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n"); 2019 pDevice->bwextcount=0; 2020 pDevice->bWPASuppWextEnabled = true; 2021 } 2022//****** 2023 2024 spin_lock_irq(&pDevice->lock); 2025 ret = wpa_set_keys(pDevice, param, true); 2026 spin_unlock_irq(&pDevice->lock); 2027 2028error: 2029kfree(param); 2030 return ret; 2031} 2032 2033 2034 2035int iwctl_giwencodeext(struct net_device *dev, 2036 struct iw_request_info *info, 2037 struct iw_point *wrq, 2038 char *extra) 2039{ 2040 return -EOPNOTSUPP;; 2041} 2042 2043int iwctl_siwmlme(struct net_device *dev, 2044 struct iw_request_info * info, 2045 struct iw_point *wrq, 2046 char *extra) 2047{ 2048 PSDevice pDevice = (PSDevice)netdev_priv(dev); 2049 PSMgmtObject pMgmt = &(pDevice->sMgmtObj); 2050 struct iw_mlme *mlme = (struct iw_mlme *)extra; 2051 //u16 reason = cpu_to_le16(mlme->reason_code); 2052 int ret = 0; 2053 2054 if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){ 2055 ret = -EINVAL; 2056 return ret; 2057 } 2058 switch(mlme->cmd){ 2059 case IW_MLME_DEAUTH: 2060 //this command seems to be not complete,please test it --einsnliu 2061 //bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason); 2062 break; 2063 case IW_MLME_DISASSOC: 2064 if(pDevice->bLinkPass == true){ 2065 printk("iwctl_siwmlme--->send DISASSOCIATE\n"); 2066 //clear related flags 2067 memset(pMgmt->abyDesireBSSID, 0xFF,6); 2068 KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); 2069 bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); 2070 } 2071 break; 2072 default: 2073 ret = -EOPNOTSUPP; 2074 } 2075 2076 return ret; 2077 2078} 2079 2080#endif 2081 2082 2083/*------------------------------------------------------------------*/ 2084/* 2085 * Structures to export the Wireless Handlers 2086 */ 2087 2088 2089/* 2090static const iw_handler iwctl_handler[] = 2091{ 2092 (iw_handler) iwctl_commit, // SIOCSIWCOMMIT 2093 (iw_handler) iwctl_giwname, // SIOCGIWNAME 2094 (iw_handler) NULL, // SIOCSIWNWID 2095 (iw_handler) NULL, // SIOCGIWNWID 2096 (iw_handler) iwctl_siwfreq, // SIOCSIWFREQ 2097 (iw_handler) iwctl_giwfreq, // SIOCGIWFREQ 2098 (iw_handler) iwctl_siwmode, // SIOCSIWMODE 2099 (iw_handler) iwctl_giwmode, // SIOCGIWMODE 2100 (iw_handler) NULL, // SIOCSIWSENS 2101 (iw_handler) iwctl_giwsens, // SIOCGIWSENS 2102 (iw_handler) NULL, // SIOCSIWRANGE 2103 (iw_handler) iwctl_giwrange, // SIOCGIWRANGE 2104 (iw_handler) NULL, // SIOCSIWPRIV 2105 (iw_handler) NULL, // SIOCGIWPRIV 2106 (iw_handler) NULL, // SIOCSIWSTATS 2107 (iw_handler) NULL, // SIOCGIWSTATS 2108 (iw_handler) NULL, // SIOCSIWSPY 2109 (iw_handler) NULL, // SIOCGIWSPY 2110 (iw_handler) NULL, // -- hole -- 2111 (iw_handler) NULL, // -- hole -- 2112 (iw_handler) iwctl_siwap, // SIOCSIWAP 2113 (iw_handler) iwctl_giwap, // SIOCGIWAP 2114 (iw_handler) NULL, // -- hole -- 0x16 2115 (iw_handler) iwctl_giwaplist, // SIOCGIWAPLIST 2116 (iw_handler) iwctl_siwscan, // SIOCSIWSCAN 2117 (iw_handler) iwctl_giwscan, // SIOCGIWSCAN 2118 (iw_handler) iwctl_siwessid, // SIOCSIWESSID 2119 (iw_handler) iwctl_giwessid, // SIOCGIWESSID 2120 (iw_handler) NULL, // SIOCSIWNICKN 2121 (iw_handler) NULL, // SIOCGIWNICKN 2122 (iw_handler) NULL, // -- hole -- 2123 (iw_handler) NULL, // -- hole -- 2124 (iw_handler) iwctl_siwrate, // SIOCSIWRATE 0x20 2125 (iw_handler) iwctl_giwrate, // SIOCGIWRATE 2126 (iw_handler) iwctl_siwrts, // SIOCSIWRTS 2127 (iw_handler) iwctl_giwrts, // SIOCGIWRTS 2128 (iw_handler) iwctl_siwfrag, // SIOCSIWFRAG 2129 (iw_handler) iwctl_giwfrag, // SIOCGIWFRAG 2130 (iw_handler) NULL, // SIOCSIWTXPOW 2131 (iw_handler) NULL, // SIOCGIWTXPOW 2132 (iw_handler) iwctl_siwretry, // SIOCSIWRETRY 2133 (iw_handler) iwctl_giwretry, // SIOCGIWRETRY 2134 (iw_handler) iwctl_siwencode, // SIOCSIWENCODE 2135 (iw_handler) iwctl_giwencode, // SIOCGIWENCODE 2136 (iw_handler) iwctl_siwpower, // SIOCSIWPOWER 2137 (iw_handler) iwctl_giwpower, // SIOCGIWPOWER 2138 (iw_handler) NULL, // -- hole -- 2139 (iw_handler) NULL, // -- hole -- 2140 (iw_handler) iwctl_siwgenie, // SIOCSIWGENIE 2141 (iw_handler) iwctl_giwgenie, // SIOCGIWGENIE 2142 (iw_handler) iwctl_siwauth, // SIOCSIWAUTH 2143 (iw_handler) iwctl_giwauth, // SIOCGIWAUTH 2144 (iw_handler) iwctl_siwencodeext, // SIOCSIWENCODEEXT 2145 (iw_handler) iwctl_giwencodeext, // SIOCGIWENCODEEXT 2146 (iw_handler) NULL, // SIOCSIWPMKSA 2147 (iw_handler) NULL, // -- hole -- 2148 2149}; 2150*/ 2151 2152static const iw_handler iwctl_handler[] = 2153{ 2154 (iw_handler) iwctl_commit, // SIOCSIWCOMMIT 2155 (iw_handler) NULL, // SIOCGIWNAME 2156 (iw_handler) NULL, // SIOCSIWNWID 2157 (iw_handler) NULL, // SIOCGIWNWID 2158 (iw_handler) NULL, // SIOCSIWFREQ 2159 (iw_handler) NULL, // SIOCGIWFREQ 2160 (iw_handler) NULL, // SIOCSIWMODE 2161 (iw_handler) NULL, // SIOCGIWMODE 2162 (iw_handler) NULL, // SIOCSIWSENS 2163 (iw_handler) NULL, // SIOCGIWSENS 2164 (iw_handler) NULL, // SIOCSIWRANGE 2165 (iw_handler) iwctl_giwrange, // SIOCGIWRANGE 2166 (iw_handler) NULL, // SIOCSIWPRIV 2167 (iw_handler) NULL, // SIOCGIWPRIV 2168 (iw_handler) NULL, // SIOCSIWSTATS 2169 (iw_handler) NULL, // SIOCGIWSTATS 2170 (iw_handler) NULL, // SIOCSIWSPY 2171 (iw_handler) NULL, // SIOCGIWSPY 2172 (iw_handler) NULL, // -- hole -- 2173 (iw_handler) NULL, // -- hole -- 2174 (iw_handler) NULL, // SIOCSIWAP 2175 (iw_handler) NULL, // SIOCGIWAP 2176 (iw_handler) NULL, // -- hole -- 0x16 2177 (iw_handler) NULL, // SIOCGIWAPLIST 2178 (iw_handler) iwctl_siwscan, // SIOCSIWSCAN 2179 (iw_handler) iwctl_giwscan, // SIOCGIWSCAN 2180 (iw_handler) NULL, // SIOCSIWESSID 2181 (iw_handler) NULL, // SIOCGIWESSID 2182 (iw_handler) NULL, // SIOCSIWNICKN 2183 (iw_handler) NULL, // SIOCGIWNICKN 2184 (iw_handler) NULL, // -- hole -- 2185 (iw_handler) NULL, // -- hole -- 2186 (iw_handler) NULL, // SIOCSIWRATE 0x20 2187 (iw_handler) NULL, // SIOCGIWRATE 2188 (iw_handler) NULL, // SIOCSIWRTS 2189 (iw_handler) NULL, // SIOCGIWRTS 2190 (iw_handler) NULL, // SIOCSIWFRAG 2191 (iw_handler) NULL, // SIOCGIWFRAG 2192 (iw_handler) NULL, // SIOCSIWTXPOW 2193 (iw_handler) NULL, // SIOCGIWTXPOW 2194 (iw_handler) NULL, // SIOCSIWRETRY 2195 (iw_handler) NULL, // SIOCGIWRETRY 2196 (iw_handler) NULL, // SIOCSIWENCODE 2197 (iw_handler) NULL, // SIOCGIWENCODE 2198 (iw_handler) NULL, // SIOCSIWPOWER 2199 (iw_handler) NULL, // SIOCGIWPOWER 2200 2201//2008-0409-07, <Add> by Einsn Liu 2202 (iw_handler) NULL, // -- hole -- 2203 (iw_handler) NULL, // -- hole -- 2204 (iw_handler) NULL, // SIOCSIWGENIE 2205 (iw_handler) NULL, // SIOCGIWGENIE 2206 (iw_handler) NULL, // SIOCSIWAUTH 2207 (iw_handler) NULL, // SIOCGIWAUTH 2208 (iw_handler) NULL, // SIOCSIWENCODEEXT 2209 (iw_handler) NULL, // SIOCGIWENCODEEXT 2210 (iw_handler) NULL, // SIOCSIWPMKSA 2211 (iw_handler) NULL, // -- hole -- 2212}; 2213 2214 2215static const iw_handler iwctl_private_handler[] = 2216{ 2217 NULL, // SIOCIWFIRSTPRIV 2218}; 2219 2220 2221struct iw_priv_args iwctl_private_args[] = { 2222{ IOCTL_CMD_SET, 2223 IW_PRIV_TYPE_CHAR | 1024, 0, 2224 "set"}, 2225}; 2226 2227 2228 2229const struct iw_handler_def iwctl_handler_def = 2230{ 2231 .get_wireless_stats = &iwctl_get_wireless_stats, 2232 .num_standard = sizeof(iwctl_handler)/sizeof(iw_handler), 2233// .num_private = sizeof(iwctl_private_handler)/sizeof(iw_handler), 2234// .num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args), 2235 .num_private = 0, 2236 .num_private_args = 0, 2237 .standard = (iw_handler *) iwctl_handler, 2238// .private = (iw_handler *) iwctl_private_handler, 2239// .private_args = (struct iw_priv_args *)iwctl_private_args, 2240 .private = NULL, 2241 .private_args = NULL, 2242}; 2243