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