ieee80211_softmac.c revision ad3a245c356d23f26fe637dd6d6402c2e1b3c03f
1/* IEEE 802.11 SoftMAC layer 2 * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it> 3 * 4 * Mostly extracted from the rtl8180-sa2400 driver for the 5 * in-kernel generic ieee802.11 stack. 6 * 7 * Few lines might be stolen from other part of the ieee80211 8 * stack. Copyright who own it's copyright 9 * 10 * WPA code stolen from the ipw2200 driver. 11 * Copyright who own it's copyright. 12 * 13 * released under the GPL 14 */ 15 16 17#include "ieee80211.h" 18 19#include <linux/random.h> 20#include <linux/delay.h> 21#include <linux/slab.h> 22#include <linux/version.h> 23#include <asm/uaccess.h> 24#include "dot11d.h" 25 26u8 rsn_authen_cipher_suite[16][4] = { 27 {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved 28 {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default 29 {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default} 30 {0x00,0x0F,0xAC,0x03}, //WRAP-historical 31 {0x00,0x0F,0xAC,0x04}, //CCMP 32 {0x00,0x0F,0xAC,0x05}, //WEP-104 33}; 34 35short ieee80211_is_54g(struct ieee80211_network net) 36{ 37 return ((net.rates_ex_len > 0) || (net.rates_len > 4)); 38} 39 40short ieee80211_is_shortslot(struct ieee80211_network net) 41{ 42 return (net.capability & WLAN_CAPABILITY_SHORT_SLOT); 43} 44 45/* returns the total length needed for pleacing the RATE MFIE 46 * tag and the EXTENDED RATE MFIE tag if needed. 47 * It encludes two bytes per tag for the tag itself and its len 48 */ 49unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee) 50{ 51 unsigned int rate_len = 0; 52 53 if (ieee->modulation & IEEE80211_CCK_MODULATION) 54 rate_len = IEEE80211_CCK_RATE_LEN + 2; 55 56 if (ieee->modulation & IEEE80211_OFDM_MODULATION) 57 58 rate_len += IEEE80211_OFDM_RATE_LEN + 2; 59 60 return rate_len; 61} 62 63/* pleace the MFIE rate, tag to the memory (double) poined. 64 * Then it updates the pointer so that 65 * it points after the new MFIE tag added. 66 */ 67void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p) 68{ 69 u8 *tag = *tag_p; 70 71 if (ieee->modulation & IEEE80211_CCK_MODULATION){ 72 *tag++ = MFIE_TYPE_RATES; 73 *tag++ = 4; 74 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; 75 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; 76 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; 77 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; 78 } 79 80 /* We may add an option for custom rates that specific HW might support */ 81 *tag_p = tag; 82} 83 84void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p) 85{ 86 u8 *tag = *tag_p; 87 88 if (ieee->modulation & IEEE80211_OFDM_MODULATION){ 89 90 *tag++ = MFIE_TYPE_RATES_EX; 91 *tag++ = 8; 92 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; 93 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; 94 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; 95 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; 96 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; 97 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; 98 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; 99 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; 100 101 } 102 103 /* We may add an option for custom rates that specific HW might support */ 104 *tag_p = tag; 105} 106 107 108void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) { 109 u8 *tag = *tag_p; 110 111 *tag++ = MFIE_TYPE_GENERIC; //0 112 *tag++ = 7; 113 *tag++ = 0x00; 114 *tag++ = 0x50; 115 *tag++ = 0xf2; 116 *tag++ = 0x02;//5 117 *tag++ = 0x00; 118 *tag++ = 0x01; 119#ifdef SUPPORT_USPD 120 if(ieee->current_network.wmm_info & 0x80) { 121 *tag++ = 0x0f|MAX_SP_Len; 122 } else { 123 *tag++ = MAX_SP_Len; 124 } 125#else 126 *tag++ = MAX_SP_Len; 127#endif 128 *tag_p = tag; 129} 130 131#ifdef THOMAS_TURBO 132void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) { 133 u8 *tag = *tag_p; 134 135 *tag++ = MFIE_TYPE_GENERIC; //0 136 *tag++ = 7; 137 *tag++ = 0x00; 138 *tag++ = 0xe0; 139 *tag++ = 0x4c; 140 *tag++ = 0x01;//5 141 *tag++ = 0x02; 142 *tag++ = 0x11; 143 *tag++ = 0x00; 144 145 *tag_p = tag; 146 printk(KERN_ALERT "This is enable turbo mode IE process\n"); 147} 148#endif 149 150void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb) 151{ 152 int nh; 153 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM; 154 155/* 156 * if the queue is full but we have newer frames then 157 * just overwrites the oldest. 158 * 159 * if (nh == ieee->mgmt_queue_tail) 160 * return -1; 161 */ 162 ieee->mgmt_queue_head = nh; 163 ieee->mgmt_queue_ring[nh] = skb; 164 165 //return 0; 166} 167 168struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee) 169{ 170 struct sk_buff *ret; 171 172 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head) 173 return NULL; 174 175 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail]; 176 177 ieee->mgmt_queue_tail = 178 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM; 179 180 return ret; 181} 182 183void init_mgmt_queue(struct ieee80211_device *ieee) 184{ 185 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0; 186} 187 188u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee) 189{ 190 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; 191 u8 rate; 192 193 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M. 194 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M) 195 rate = 0x0c; 196 else 197 rate = ieee->basic_rate & 0x7f; 198 199 if(rate == 0){ 200 // 2005.01.26, by rcnjko. 201 if(ieee->mode == IEEE_A|| 202 ieee->mode== IEEE_N_5G|| 203 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK)) 204 rate = 0x0c; 205 else 206 rate = 0x02; 207 } 208 209 /* 210 // Data rate of ProbeReq is already decided. Annie, 2005-03-31 211 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) ) 212 { 213 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A) 214 rate = 0x0c; 215 else 216 rate = 0x02; 217 } 218 */ 219 return rate; 220} 221 222 223void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl); 224 225inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) 226{ 227 unsigned long flags; 228 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; 229 struct ieee80211_hdr_3addr *header= 230 (struct ieee80211_hdr_3addr *) skb->data; 231 232 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8); 233 spin_lock_irqsave(&ieee->lock, flags); 234 235 /* called with 2nd param 0, no mgmt lock required */ 236 ieee80211_sta_wakeup(ieee,0); 237 238 tcb_desc->queue_index = MGNT_QUEUE; 239 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); 240 tcb_desc->RATRIndex = 7; 241 tcb_desc->bTxDisableRateFallBack = 1; 242 tcb_desc->bTxUseDriverAssingedRate = 1; 243 244 if(single){ 245 if(ieee->queue_stop){ 246 enqueue_mgmt(ieee,skb); 247 }else{ 248 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4); 249 250 if (ieee->seq_ctrl[0] == 0xFFF) 251 ieee->seq_ctrl[0] = 0; 252 else 253 ieee->seq_ctrl[0]++; 254 255 /* avoid watchdog triggers */ 256 ieee->dev->trans_start = jiffies; 257 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); 258 //dev_kfree_skb_any(skb);//edit by thomas 259 } 260 261 spin_unlock_irqrestore(&ieee->lock, flags); 262 }else{ 263 spin_unlock_irqrestore(&ieee->lock, flags); 264 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); 265 266 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 267 268 if (ieee->seq_ctrl[0] == 0xFFF) 269 ieee->seq_ctrl[0] = 0; 270 else 271 ieee->seq_ctrl[0]++; 272 273 /* check wether the managed packet queued greater than 5 */ 274 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\ 275 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\ 276 (ieee->queue_stop) ) { 277 /* insert the skb packet to the management queue */ 278 /* as for the completion function, it does not need 279 * to check it any more. 280 * */ 281 printk("%s():insert to waitqueue!\n",__FUNCTION__); 282 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb); 283 } else { 284 //printk("TX packet!\n"); 285 ieee->softmac_hard_start_xmit(skb,ieee->dev); 286 //dev_kfree_skb_any(skb);//edit by thomas 287 } 288 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); 289 } 290} 291 292inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) 293{ 294 295 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; 296 struct ieee80211_hdr_3addr *header = 297 (struct ieee80211_hdr_3addr *) skb->data; 298 299 300 if(single){ 301 302 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 303 304 if (ieee->seq_ctrl[0] == 0xFFF) 305 ieee->seq_ctrl[0] = 0; 306 else 307 ieee->seq_ctrl[0]++; 308 309 /* avoid watchdog triggers */ 310 ieee->dev->trans_start = jiffies; 311 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); 312 313 }else{ 314 315 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 316 317 if (ieee->seq_ctrl[0] == 0xFFF) 318 ieee->seq_ctrl[0] = 0; 319 else 320 ieee->seq_ctrl[0]++; 321 322 ieee->softmac_hard_start_xmit(skb,ieee->dev); 323 324 } 325 //dev_kfree_skb_any(skb);//edit by thomas 326} 327 328inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee) 329{ 330 unsigned int len,rate_len; 331 u8 *tag; 332 struct sk_buff *skb; 333 struct ieee80211_probe_request *req; 334 335 len = ieee->current_network.ssid_len; 336 337 rate_len = ieee80211_MFIE_rate_len(ieee); 338 339 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + 340 2 + len + rate_len + ieee->tx_headroom); 341 if (!skb) 342 return NULL; 343 344 skb_reserve(skb, ieee->tx_headroom); 345 346 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request)); 347 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); 348 req->header.duration_id = 0; //FIXME: is this OK ? 349 350 memset(req->header.addr1, 0xff, ETH_ALEN); 351 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 352 memset(req->header.addr3, 0xff, ETH_ALEN); 353 354 tag = (u8 *) skb_put(skb,len+2+rate_len); 355 356 *tag++ = MFIE_TYPE_SSID; 357 *tag++ = len; 358 memcpy(tag, ieee->current_network.ssid, len); 359 tag += len; 360 361 ieee80211_MFIE_Brate(ieee,&tag); 362 ieee80211_MFIE_Grate(ieee,&tag); 363 return skb; 364} 365 366struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee); 367void ieee80211_send_beacon(struct ieee80211_device *ieee) 368{ 369 struct sk_buff *skb; 370 if(!ieee->ieee_up) 371 return; 372 //unsigned long flags; 373 skb = ieee80211_get_beacon_(ieee); 374 375 if (skb){ 376 softmac_mgmt_xmit(skb, ieee); 377 ieee->softmac_stats.tx_beacons++; 378 //dev_kfree_skb_any(skb);//edit by thomas 379 } 380// ieee->beacon_timer.expires = jiffies + 381// (MSECS( ieee->current_network.beacon_interval -5)); 382 383 //spin_lock_irqsave(&ieee->beacon_lock,flags); 384 if(ieee->beacon_txing && ieee->ieee_up){ 385// if(!timer_pending(&ieee->beacon_timer)) 386// add_timer(&ieee->beacon_timer); 387 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5))); 388 } 389 //spin_unlock_irqrestore(&ieee->beacon_lock,flags); 390} 391 392 393void ieee80211_send_beacon_cb(unsigned long _ieee) 394{ 395 struct ieee80211_device *ieee = 396 (struct ieee80211_device *) _ieee; 397 unsigned long flags; 398 399 spin_lock_irqsave(&ieee->beacon_lock, flags); 400 ieee80211_send_beacon(ieee); 401 spin_unlock_irqrestore(&ieee->beacon_lock, flags); 402} 403 404 405void ieee80211_send_probe(struct ieee80211_device *ieee) 406{ 407 struct sk_buff *skb; 408 409 skb = ieee80211_probe_req(ieee); 410 if (skb){ 411 softmac_mgmt_xmit(skb, ieee); 412 ieee->softmac_stats.tx_probe_rq++; 413 //dev_kfree_skb_any(skb);//edit by thomas 414 } 415} 416 417void ieee80211_send_probe_requests(struct ieee80211_device *ieee) 418{ 419 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){ 420 ieee80211_send_probe(ieee); 421 ieee80211_send_probe(ieee); 422 } 423} 424 425/* this performs syncro scan blocking the caller until all channels 426 * in the allowed channel map has been checked. 427 */ 428void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) 429{ 430 short ch = 0; 431 u8 channel_map[MAX_CHANNEL_NUMBER+1]; 432 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); 433 down(&ieee->scan_sem); 434 435 while(1) 436 { 437 438 do{ 439 ch++; 440 if (ch > MAX_CHANNEL_NUMBER) 441 goto out; /* scan completed */ 442 }while(!channel_map[ch]); 443 444 /* this function can be called in two situations 445 * 1- We have switched to ad-hoc mode and we are 446 * performing a complete syncro scan before conclude 447 * there are no interesting cell and to create a 448 * new one. In this case the link state is 449 * IEEE80211_NOLINK until we found an interesting cell. 450 * If so the ieee8021_new_net, called by the RX path 451 * will set the state to IEEE80211_LINKED, so we stop 452 * scanning 453 * 2- We are linked and the root uses run iwlist scan. 454 * So we switch to IEEE80211_LINKED_SCANNING to remember 455 * that we are still logically linked (not interested in 456 * new network events, despite for updating the net list, 457 * but we are temporarly 'unlinked' as the driver shall 458 * not filter RX frames and the channel is changing. 459 * So the only situation in witch are interested is to check 460 * if the state become LINKED because of the #1 situation 461 */ 462 463 if (ieee->state == IEEE80211_LINKED) 464 goto out; 465 ieee->set_chan(ieee->dev, ch); 466 if(channel_map[ch] == 1) 467 ieee80211_send_probe_requests(ieee); 468 469 /* this prevent excessive time wait when we 470 * need to wait for a syncro scan to end.. 471 */ 472 if(ieee->state < IEEE80211_LINKED) 473 ; 474 else 475 if (ieee->sync_scan_hurryup) 476 goto out; 477 478 479 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME); 480 481 } 482out: 483 if(ieee->state < IEEE80211_LINKED){ 484 ieee->actscanning = false; 485 up(&ieee->scan_sem); 486 } 487 else{ 488 ieee->sync_scan_hurryup = 0; 489 if(IS_DOT11D_ENABLE(ieee)) 490 DOT11D_ScanComplete(ieee); 491 up(&ieee->scan_sem); 492} 493} 494 495 496void ieee80211_softmac_scan_wq(struct work_struct *work) 497{ 498 struct delayed_work *dwork = container_of(work, struct delayed_work, work); 499 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); 500 static short watchdog = 0; 501 u8 channel_map[MAX_CHANNEL_NUMBER+1]; 502 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); 503 if(!ieee->ieee_up) 504 return; 505 down(&ieee->scan_sem); 506 do{ 507 ieee->current_network.channel = 508 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER; 509 if (watchdog++ > MAX_CHANNEL_NUMBER) 510 { 511 //if current channel is not in channel map, set to default channel. 512 if (!channel_map[ieee->current_network.channel]) { 513 ieee->current_network.channel = 6; 514 goto out; /* no good chans */ 515 } 516 } 517 }while(!channel_map[ieee->current_network.channel]); 518 if (ieee->scanning == 0 ) 519 goto out; 520 ieee->set_chan(ieee->dev, ieee->current_network.channel); 521 if(channel_map[ieee->current_network.channel] == 1) 522 ieee80211_send_probe_requests(ieee); 523 524 525 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME); 526 527 up(&ieee->scan_sem); 528 return; 529out: 530 if(IS_DOT11D_ENABLE(ieee)) 531 DOT11D_ScanComplete(ieee); 532 ieee->actscanning = false; 533 watchdog = 0; 534 ieee->scanning = 0; 535 up(&ieee->scan_sem); 536} 537 538 539 540void ieee80211_beacons_start(struct ieee80211_device *ieee) 541{ 542 unsigned long flags; 543 spin_lock_irqsave(&ieee->beacon_lock,flags); 544 545 ieee->beacon_txing = 1; 546 ieee80211_send_beacon(ieee); 547 548 spin_unlock_irqrestore(&ieee->beacon_lock,flags); 549} 550 551void ieee80211_beacons_stop(struct ieee80211_device *ieee) 552{ 553 unsigned long flags; 554 555 spin_lock_irqsave(&ieee->beacon_lock,flags); 556 557 ieee->beacon_txing = 0; 558 del_timer_sync(&ieee->beacon_timer); 559 560 spin_unlock_irqrestore(&ieee->beacon_lock,flags); 561 562} 563 564 565void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) 566{ 567 if(ieee->stop_send_beacons) 568 ieee->stop_send_beacons(ieee->dev); 569 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) 570 ieee80211_beacons_stop(ieee); 571} 572 573 574void ieee80211_start_send_beacons(struct ieee80211_device *ieee) 575{ 576 if(ieee->start_send_beacons) 577 ieee->start_send_beacons(ieee->dev,ieee->basic_rate); 578 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS) 579 ieee80211_beacons_start(ieee); 580} 581 582 583void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee) 584{ 585// unsigned long flags; 586 587 //ieee->sync_scan_hurryup = 1; 588 589 down(&ieee->scan_sem); 590// spin_lock_irqsave(&ieee->lock, flags); 591 592 if (ieee->scanning == 1){ 593 ieee->scanning = 0; 594 595 cancel_delayed_work(&ieee->softmac_scan_wq); 596 } 597 598// spin_unlock_irqrestore(&ieee->lock, flags); 599 up(&ieee->scan_sem); 600} 601 602void ieee80211_stop_scan(struct ieee80211_device *ieee) 603{ 604 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) 605 ieee80211_softmac_stop_scan(ieee); 606 else 607 ieee->stop_scan(ieee->dev); 608} 609 610/* called with ieee->lock held */ 611void ieee80211_start_scan(struct ieee80211_device *ieee) 612{ 613 if(IS_DOT11D_ENABLE(ieee) ) 614 { 615 if(IS_COUNTRY_IE_VALID(ieee)) 616 { 617 RESET_CIE_WATCHDOG(ieee); 618 } 619 } 620 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){ 621 if (ieee->scanning == 0){ 622 ieee->scanning = 1; 623 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0); 624 } 625 }else 626 ieee->start_scan(ieee->dev); 627 628} 629 630/* called with wx_sem held */ 631void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) 632{ 633 if(IS_DOT11D_ENABLE(ieee) ) 634 { 635 if(IS_COUNTRY_IE_VALID(ieee)) 636 { 637 RESET_CIE_WATCHDOG(ieee); 638 } 639 } 640 ieee->sync_scan_hurryup = 0; 641 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) 642 ieee80211_softmac_scan_syncro(ieee); 643 else 644 ieee->scan_syncro(ieee->dev); 645 646} 647 648inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon, 649 struct ieee80211_device *ieee, int challengelen) 650{ 651 struct sk_buff *skb; 652 struct ieee80211_authentication *auth; 653 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom; 654 655 656 skb = dev_alloc_skb(len); 657 if (!skb) return NULL; 658 659 skb_reserve(skb, ieee->tx_headroom); 660 auth = (struct ieee80211_authentication *) 661 skb_put(skb, sizeof(struct ieee80211_authentication)); 662 663 auth->header.frame_ctl = IEEE80211_STYPE_AUTH; 664 if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP; 665 666 auth->header.duration_id = 0x013a; //FIXME 667 668 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); 669 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 670 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); 671 672 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; 673 if(ieee->auth_mode == 0) 674 auth->algorithm = WLAN_AUTH_OPEN; 675 else if(ieee->auth_mode == 1) 676 auth->algorithm = WLAN_AUTH_SHARED_KEY; 677 else if(ieee->auth_mode == 2) 678 auth->algorithm = WLAN_AUTH_OPEN;//0x80; 679 printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm); 680 auth->transaction = cpu_to_le16(ieee->associate_seq); 681 ieee->associate_seq++; 682 683 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS); 684 685 return skb; 686 687} 688 689 690static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest) 691{ 692 u8 *tag; 693 int beacon_size; 694 struct ieee80211_probe_response *beacon_buf; 695 struct sk_buff *skb = NULL; 696 int encrypt; 697 int atim_len,erp_len; 698 struct ieee80211_crypt_data* crypt; 699 700 char *ssid = ieee->current_network.ssid; 701 int ssid_len = ieee->current_network.ssid_len; 702 int rate_len = ieee->current_network.rates_len+2; 703 int rate_ex_len = ieee->current_network.rates_ex_len; 704 int wpa_ie_len = ieee->wpa_ie_len; 705 u8 erpinfo_content = 0; 706 707 u8* tmp_ht_cap_buf; 708 u8 tmp_ht_cap_len=0; 709 u8* tmp_ht_info_buf; 710 u8 tmp_ht_info_len=0; 711 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; 712 u8* tmp_generic_ie_buf=NULL; 713 u8 tmp_generic_ie_len=0; 714 715 if(rate_ex_len > 0) rate_ex_len+=2; 716 717 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) 718 atim_len = 4; 719 else 720 atim_len = 0; 721 722 if(ieee80211_is_54g(ieee->current_network)) 723 erp_len = 3; 724 else 725 erp_len = 0; 726 727 728 crypt = ieee->crypt[ieee->tx_keyidx]; 729 730 731 encrypt = ieee->host_encrypt && crypt && crypt->ops && 732 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len)); 733 //HT ralated element 734 tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap); 735 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); 736 tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo); 737 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo); 738 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt); 739 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt); 740 741 742 if(pHTInfo->bRegRT2RTAggregation) 743 { 744 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; 745 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer); 746 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len); 747 } 748// printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len); 749 beacon_size = sizeof(struct ieee80211_probe_response)+2+ 750 ssid_len 751 +3 //channel 752 +rate_len 753 +rate_ex_len 754 +atim_len 755 +erp_len 756 +wpa_ie_len 757 // +tmp_ht_cap_len 758 // +tmp_ht_info_len 759 // +tmp_generic_ie_len 760// +wmm_len+2 761 +ieee->tx_headroom; 762 skb = dev_alloc_skb(beacon_size); 763 if (!skb) 764 return NULL; 765 skb_reserve(skb, ieee->tx_headroom); 766 beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom)); 767 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN); 768 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 769 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); 770 771 beacon_buf->header.duration_id = 0; //FIXME 772 beacon_buf->beacon_interval = 773 cpu_to_le16(ieee->current_network.beacon_interval); 774 beacon_buf->capability = 775 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS); 776 beacon_buf->capability |= 777 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here 778 779 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) 780 cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT)); 781 782 crypt = ieee->crypt[ieee->tx_keyidx]; 783 if (encrypt) 784 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); 785 786 787 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP); 788 beacon_buf->info_element[0].id = MFIE_TYPE_SSID; 789 beacon_buf->info_element[0].len = ssid_len; 790 791 tag = (u8*) beacon_buf->info_element[0].data; 792 793 memcpy(tag, ssid, ssid_len); 794 795 tag += ssid_len; 796 797 *(tag++) = MFIE_TYPE_RATES; 798 *(tag++) = rate_len-2; 799 memcpy(tag,ieee->current_network.rates,rate_len-2); 800 tag+=rate_len-2; 801 802 *(tag++) = MFIE_TYPE_DS_SET; 803 *(tag++) = 1; 804 *(tag++) = ieee->current_network.channel; 805 806 if(atim_len){ 807 u16 val16; 808 *(tag++) = MFIE_TYPE_IBSS_SET; 809 *(tag++) = 2; 810 //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); 811 val16 = cpu_to_le16(ieee->current_network.atim_window); 812 memcpy((u8 *)tag, (u8 *)&val16, 2); 813 tag+=2; 814 } 815 816 if(erp_len){ 817 *(tag++) = MFIE_TYPE_ERP; 818 *(tag++) = 1; 819 *(tag++) = erpinfo_content; 820 } 821 if(rate_ex_len){ 822 *(tag++) = MFIE_TYPE_RATES_EX; 823 *(tag++) = rate_ex_len-2; 824 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2); 825 tag+=rate_ex_len-2; 826 } 827 828 if (wpa_ie_len) 829 { 830 if (ieee->iw_mode == IW_MODE_ADHOC) 831 {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07 832 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4); 833 } 834 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); 835 tag += wpa_ie_len; 836 } 837 838 //skb->dev = ieee->dev; 839 return skb; 840} 841 842 843struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest) 844{ 845 struct sk_buff *skb; 846 u8* tag; 847 848 struct ieee80211_crypt_data* crypt; 849 struct ieee80211_assoc_response_frame *assoc; 850 short encrypt; 851 852 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); 853 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom; 854 855 skb = dev_alloc_skb(len); 856 857 if (!skb) 858 return NULL; 859 860 skb_reserve(skb, ieee->tx_headroom); 861 862 assoc = (struct ieee80211_assoc_response_frame *) 863 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame)); 864 865 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP); 866 memcpy(assoc->header.addr1, dest,ETH_ALEN); 867 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); 868 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 869 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? 870 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS); 871 872 873 if(ieee->short_slot) 874 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); 875 876 if (ieee->host_encrypt) 877 crypt = ieee->crypt[ieee->tx_keyidx]; 878 else crypt = NULL; 879 880 encrypt = ( crypt && crypt->ops); 881 882 if (encrypt) 883 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); 884 885 assoc->status = 0; 886 assoc->aid = cpu_to_le16(ieee->assoc_id); 887 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0; 888 else ieee->assoc_id++; 889 890 tag = (u8*) skb_put(skb, rate_len); 891 892 ieee80211_MFIE_Brate(ieee, &tag); 893 ieee80211_MFIE_Grate(ieee, &tag); 894 895 return skb; 896} 897 898struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest) 899{ 900 struct sk_buff *skb; 901 struct ieee80211_authentication *auth; 902 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1; 903 904 skb = dev_alloc_skb(len); 905 906 if (!skb) 907 return NULL; 908 909 skb->len = sizeof(struct ieee80211_authentication); 910 911 auth = (struct ieee80211_authentication *)skb->data; 912 913 auth->status = cpu_to_le16(status); 914 auth->transaction = cpu_to_le16(2); 915 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); 916 917 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN); 918 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 919 memcpy(auth->header.addr1, dest, ETH_ALEN); 920 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); 921 return skb; 922 923 924} 925 926struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr) 927{ 928 struct sk_buff *skb; 929 struct ieee80211_hdr_3addr* hdr; 930 931 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr)); 932 933 if (!skb) 934 return NULL; 935 936 hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr)); 937 938 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN); 939 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); 940 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); 941 942 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | 943 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | 944 (pwr ? IEEE80211_FCTL_PM:0)); 945 946 return skb; 947 948 949} 950 951 952void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest) 953{ 954 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest); 955 956 if (buf) 957 softmac_mgmt_xmit(buf, ieee); 958} 959 960 961void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest) 962{ 963 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest); 964 965 if (buf) 966 softmac_mgmt_xmit(buf, ieee); 967} 968 969 970void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) 971{ 972 973 974 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest); 975 if (buf) 976 softmac_mgmt_xmit(buf, ieee); 977} 978 979 980inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee) 981{ 982 struct sk_buff *skb; 983 //unsigned long flags; 984 985 struct ieee80211_assoc_request_frame *hdr; 986 u8 *tag;//,*rsn_ie; 987 //short info_addr = 0; 988 //int i; 989 //u16 suite_count = 0; 990 //u8 suit_select = 0; 991 //unsigned int wpa_len = beacon->wpa_ie_len; 992 //for HT 993 u8* ht_cap_buf = NULL; 994 u8 ht_cap_len=0; 995 u8* realtek_ie_buf=NULL; 996 u8 realtek_ie_len=0; 997 int wpa_ie_len= ieee->wpa_ie_len; 998 unsigned int ckip_ie_len=0; 999 unsigned int ccxrm_ie_len=0; 1000 unsigned int cxvernum_ie_len=0; 1001 struct ieee80211_crypt_data* crypt; 1002 int encrypt; 1003 1004 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); 1005 unsigned int wmm_info_len = beacon->qos_data.supported?9:0; 1006#ifdef THOMAS_TURBO 1007 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0; 1008#endif 1009 1010 int len = 0; 1011 1012 crypt = ieee->crypt[ieee->tx_keyidx]; 1013 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len)); 1014 1015 //Include High Throuput capability && Realtek proprietary 1016 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT) 1017 { 1018 ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap); 1019 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); 1020 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt); 1021 if(ieee->pHTInfo->bCurrentRT2RTAggregation) 1022 { 1023 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; 1024 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer); 1025 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len); 1026 1027 } 1028 } 1029 if(ieee->qos_support){ 1030 wmm_info_len = beacon->qos_data.supported?9:0; 1031 } 1032 1033 1034 if(beacon->bCkipSupported) 1035 { 1036 ckip_ie_len = 30+2; 1037 } 1038 if(beacon->bCcxRmEnable) 1039 { 1040 ccxrm_ie_len = 6+2; 1041 } 1042 if( beacon->BssCcxVerNumber >= 2 ) 1043 { 1044 cxvernum_ie_len = 5+2; 1045 } 1046#ifdef THOMAS_TURBO 1047 len = sizeof(struct ieee80211_assoc_request_frame)+ 2 1048 + beacon->ssid_len//essid tagged val 1049 + rate_len//rates tagged val 1050 + wpa_ie_len 1051 + wmm_info_len 1052 + turbo_info_len 1053 + ht_cap_len 1054 + realtek_ie_len 1055 + ckip_ie_len 1056 + ccxrm_ie_len 1057 + cxvernum_ie_len 1058 + ieee->tx_headroom; 1059#else 1060 len = sizeof(struct ieee80211_assoc_request_frame)+ 2 1061 + beacon->ssid_len//essid tagged val 1062 + rate_len//rates tagged val 1063 + wpa_ie_len 1064 + wmm_info_len 1065 + ht_cap_len 1066 + realtek_ie_len 1067 + ckip_ie_len 1068 + ccxrm_ie_len 1069 + cxvernum_ie_len 1070 + ieee->tx_headroom; 1071#endif 1072 1073 skb = dev_alloc_skb(len); 1074 1075 if (!skb) 1076 return NULL; 1077 1078 skb_reserve(skb, ieee->tx_headroom); 1079 1080 hdr = (struct ieee80211_assoc_request_frame *) 1081 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2); 1082 1083 1084 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ; 1085 hdr->header.duration_id= 37; //FIXME 1086 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); 1087 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 1088 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); 1089 1090 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John 1091 1092 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS); 1093 if (beacon->capability & WLAN_CAPABILITY_PRIVACY ) 1094 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); 1095 1096 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 1097 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here 1098 1099 if(ieee->short_slot) 1100 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); 1101 if (wmm_info_len) //QOS 1102 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS); 1103 1104 hdr->listen_interval = 0xa; //FIXME 1105 1106 hdr->info_element[0].id = MFIE_TYPE_SSID; 1107 1108 hdr->info_element[0].len = beacon->ssid_len; 1109 tag = skb_put(skb, beacon->ssid_len); 1110 memcpy(tag, beacon->ssid, beacon->ssid_len); 1111 1112 tag = skb_put(skb, rate_len); 1113 1114 ieee80211_MFIE_Brate(ieee, &tag); 1115 ieee80211_MFIE_Grate(ieee, &tag); 1116 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14. 1117 if( beacon->bCkipSupported ) 1118 { 1119 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client" 1120 u8 CcxAironetBuf[30]; 1121 OCTET_STRING osCcxAironetIE; 1122 1123 memset(CcxAironetBuf, 0,30); 1124 osCcxAironetIE.Octet = CcxAironetBuf; 1125 osCcxAironetIE.Length = sizeof(CcxAironetBuf); 1126 // 1127 // Ref. CCX test plan v3.61, 3.2.3.1 step 13. 1128 // We want to make the device type as "4500-client". 060926, by CCW. 1129 // 1130 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui)); 1131 1132 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23): 1133 // "The CKIP negotiation is started with the associate request from the client to the access point, 1134 // containing an Aironet element with both the MIC and KP bits set." 1135 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ; 1136 tag = skb_put(skb, ckip_ie_len); 1137 *tag++ = MFIE_TYPE_AIRONET; 1138 *tag++ = osCcxAironetIE.Length; 1139 memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length); 1140 tag += osCcxAironetIE.Length; 1141 } 1142 1143 if(beacon->bCcxRmEnable) 1144 { 1145 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00}; 1146 OCTET_STRING osCcxRmCap; 1147 1148 osCcxRmCap.Octet = CcxRmCapBuf; 1149 osCcxRmCap.Length = sizeof(CcxRmCapBuf); 1150 tag = skb_put(skb,ccxrm_ie_len); 1151 *tag++ = MFIE_TYPE_GENERIC; 1152 *tag++ = osCcxRmCap.Length; 1153 memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length); 1154 tag += osCcxRmCap.Length; 1155 } 1156 1157 if( beacon->BssCcxVerNumber >= 2 ) 1158 { 1159 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00}; 1160 OCTET_STRING osCcxVerNum; 1161 CcxVerNumBuf[4] = beacon->BssCcxVerNumber; 1162 osCcxVerNum.Octet = CcxVerNumBuf; 1163 osCcxVerNum.Length = sizeof(CcxVerNumBuf); 1164 tag = skb_put(skb,cxvernum_ie_len); 1165 *tag++ = MFIE_TYPE_GENERIC; 1166 *tag++ = osCcxVerNum.Length; 1167 memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length); 1168 tag += osCcxVerNum.Length; 1169 } 1170 //HT cap element 1171 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){ 1172 if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) 1173 { 1174 tag = skb_put(skb, ht_cap_len); 1175 *tag++ = MFIE_TYPE_HT_CAP; 1176 *tag++ = ht_cap_len - 2; 1177 memcpy(tag, ht_cap_buf,ht_cap_len -2); 1178 tag += ht_cap_len -2; 1179 } 1180 } 1181 1182 1183 //choose what wpa_supplicant gives to associate. 1184 tag = skb_put(skb, wpa_ie_len); 1185 if (wpa_ie_len){ 1186 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); 1187 } 1188 1189 tag = skb_put(skb,wmm_info_len); 1190 if(wmm_info_len) { 1191 ieee80211_WMM_Info(ieee, &tag); 1192 } 1193#ifdef THOMAS_TURBO 1194 tag = skb_put(skb,turbo_info_len); 1195 if(turbo_info_len) { 1196 ieee80211_TURBO_Info(ieee, &tag); 1197 } 1198#endif 1199 1200 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){ 1201 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) 1202 { 1203 tag = skb_put(skb, ht_cap_len); 1204 *tag++ = MFIE_TYPE_GENERIC; 1205 *tag++ = ht_cap_len - 2; 1206 memcpy(tag, ht_cap_buf,ht_cap_len - 2); 1207 tag += ht_cap_len -2; 1208 } 1209 1210 if(ieee->pHTInfo->bCurrentRT2RTAggregation){ 1211 tag = skb_put(skb, realtek_ie_len); 1212 *tag++ = MFIE_TYPE_GENERIC; 1213 *tag++ = realtek_ie_len - 2; 1214 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 ); 1215 } 1216 } 1217// printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr); 1218// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); 1219 return skb; 1220} 1221 1222void ieee80211_associate_abort(struct ieee80211_device *ieee) 1223{ 1224 1225 unsigned long flags; 1226 spin_lock_irqsave(&ieee->lock, flags); 1227 1228 ieee->associate_seq++; 1229 1230 /* don't scan, and avoid to have the RX path possibily 1231 * try again to associate. Even do not react to AUTH or 1232 * ASSOC response. Just wait for the retry wq to be scheduled. 1233 * Here we will check if there are good nets to associate 1234 * with, so we retry or just get back to NO_LINK and scanning 1235 */ 1236 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){ 1237 IEEE80211_DEBUG_MGMT("Authentication failed\n"); 1238 ieee->softmac_stats.no_auth_rs++; 1239 }else{ 1240 IEEE80211_DEBUG_MGMT("Association failed\n"); 1241 ieee->softmac_stats.no_ass_rs++; 1242 } 1243 1244 ieee->state = IEEE80211_ASSOCIATING_RETRY; 1245 1246 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \ 1247 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME); 1248 1249 spin_unlock_irqrestore(&ieee->lock, flags); 1250} 1251 1252void ieee80211_associate_abort_cb(unsigned long dev) 1253{ 1254 ieee80211_associate_abort((struct ieee80211_device *) dev); 1255} 1256 1257 1258void ieee80211_associate_step1(struct ieee80211_device *ieee) 1259{ 1260 struct ieee80211_network *beacon = &ieee->current_network; 1261 struct sk_buff *skb; 1262 1263 IEEE80211_DEBUG_MGMT("Stopping scan\n"); 1264 1265 ieee->softmac_stats.tx_auth_rq++; 1266 skb=ieee80211_authentication_req(beacon, ieee, 0); 1267 1268 if (!skb) 1269 ieee80211_associate_abort(ieee); 1270 else{ 1271 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ; 1272 IEEE80211_DEBUG_MGMT("Sending authentication request\n"); 1273 //printk(KERN_WARNING "Sending authentication request\n"); 1274 softmac_mgmt_xmit(skb, ieee); 1275 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709 1276 if(!timer_pending(&ieee->associate_timer)){ 1277 ieee->associate_timer.expires = jiffies + (HZ / 2); 1278 add_timer(&ieee->associate_timer); 1279 } 1280 //dev_kfree_skb_any(skb);//edit by thomas 1281 } 1282} 1283 1284void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) 1285{ 1286 u8 *c; 1287 struct sk_buff *skb; 1288 struct ieee80211_network *beacon = &ieee->current_network; 1289// int hlen = sizeof(struct ieee80211_authentication); 1290 1291 ieee->associate_seq++; 1292 ieee->softmac_stats.tx_auth_rq++; 1293 1294 skb = ieee80211_authentication_req(beacon, ieee, chlen+2); 1295 if (!skb) 1296 ieee80211_associate_abort(ieee); 1297 else{ 1298 c = skb_put(skb, chlen+2); 1299 *(c++) = MFIE_TYPE_CHALLENGE; 1300 *(c++) = chlen; 1301 memcpy(c, challenge, chlen); 1302 1303 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n"); 1304 1305 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr )); 1306 1307 softmac_mgmt_xmit(skb, ieee); 1308 mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); 1309 //dev_kfree_skb_any(skb);//edit by thomas 1310 } 1311 kfree(challenge); 1312} 1313 1314void ieee80211_associate_step2(struct ieee80211_device *ieee) 1315{ 1316 struct sk_buff* skb; 1317 struct ieee80211_network *beacon = &ieee->current_network; 1318 1319 del_timer_sync(&ieee->associate_timer); 1320 1321 IEEE80211_DEBUG_MGMT("Sending association request\n"); 1322 1323 ieee->softmac_stats.tx_ass_rq++; 1324 skb=ieee80211_association_req(beacon, ieee); 1325 if (!skb) 1326 ieee80211_associate_abort(ieee); 1327 else{ 1328 softmac_mgmt_xmit(skb, ieee); 1329 mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); 1330 //dev_kfree_skb_any(skb);//edit by thomas 1331 } 1332} 1333void ieee80211_associate_complete_wq(struct work_struct *work) 1334{ 1335 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq); 1336 printk(KERN_INFO "Associated successfully\n"); 1337 if(ieee80211_is_54g(ieee->current_network) && 1338 (ieee->modulation & IEEE80211_OFDM_MODULATION)){ 1339 1340 ieee->rate = 108; 1341 printk(KERN_INFO"Using G rates:%d\n", ieee->rate); 1342 }else{ 1343 ieee->rate = 22; 1344 printk(KERN_INFO"Using B rates:%d\n", ieee->rate); 1345 } 1346 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT) 1347 { 1348 printk("Successfully associated, ht enabled\n"); 1349 HTOnAssocRsp(ieee); 1350 } 1351 else 1352 { 1353 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT); 1354 memset(ieee->dot11HTOperationalRateSet, 0, 16); 1355 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); 1356 } 1357 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500); 1358 // To prevent the immediately calling watch_dog after association. 1359 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) 1360 { 1361 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; 1362 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; 1363 } 1364 ieee->link_change(ieee->dev); 1365 if(ieee->is_silent_reset == 0){ 1366 printk("============>normal associate\n"); 1367 notify_wx_assoc_event(ieee); 1368 } 1369 else if(ieee->is_silent_reset == 1) 1370 { 1371 printk("==================>silent reset associate\n"); 1372 ieee->is_silent_reset = 0; 1373 } 1374 1375 if (ieee->data_hard_resume) 1376 ieee->data_hard_resume(ieee->dev); 1377 netif_carrier_on(ieee->dev); 1378} 1379 1380void ieee80211_associate_complete(struct ieee80211_device *ieee) 1381{ 1382// int i; 1383// struct net_device* dev = ieee->dev; 1384 del_timer_sync(&ieee->associate_timer); 1385 1386 ieee->state = IEEE80211_LINKED; 1387 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet); 1388 queue_work(ieee->wq, &ieee->associate_complete_wq); 1389} 1390 1391void ieee80211_associate_procedure_wq(struct work_struct *work) 1392{ 1393 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq); 1394 ieee->sync_scan_hurryup = 1; 1395 down(&ieee->wx_sem); 1396 1397 if (ieee->data_hard_stop) 1398 ieee->data_hard_stop(ieee->dev); 1399 1400 ieee80211_stop_scan(ieee); 1401 printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); 1402 //ieee->set_chan(ieee->dev, ieee->current_network.channel); 1403 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); 1404 1405 ieee->associate_seq = 1; 1406 ieee80211_associate_step1(ieee); 1407 1408 up(&ieee->wx_sem); 1409} 1410 1411inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net) 1412{ 1413 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1]; 1414 int tmp_ssid_len = 0; 1415 1416 short apset,ssidset,ssidbroad,apmatch,ssidmatch; 1417 1418 /* we are interested in new new only if we are not associated 1419 * and we are not associating / authenticating 1420 */ 1421 if (ieee->state != IEEE80211_NOLINK) 1422 return; 1423 1424 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS)) 1425 return; 1426 1427 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS)) 1428 return; 1429 1430 1431 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){ 1432 /* if the user specified the AP MAC, we need also the essid 1433 * This could be obtained by beacons or, if the network does not 1434 * broadcast it, it can be put manually. 1435 */ 1436 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 ); 1437 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0'; 1438 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0'); 1439 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0); 1440 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\ 1441 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len)); 1442 1443 1444 if ( /* if the user set the AP check if match. 1445 * if the network does not broadcast essid we check the user supplyed ANY essid 1446 * if the network does broadcast and the user does not set essid it is OK 1447 * if the network does broadcast and the user did set essid chech if essid match 1448 */ 1449 ( apset && apmatch && 1450 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) || 1451 /* if the ap is not set, check that the user set the bssid 1452 * and the network does bradcast and that those two bssid matches 1453 */ 1454 (!apset && ssidset && ssidbroad && ssidmatch) 1455 ){ 1456 /* if the essid is hidden replace it with the 1457 * essid provided by the user. 1458 */ 1459 if (!ssidbroad){ 1460 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE); 1461 tmp_ssid_len = ieee->current_network.ssid_len; 1462 } 1463 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network)); 1464 1465 if (!ssidbroad){ 1466 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE); 1467 ieee->current_network.ssid_len = tmp_ssid_len; 1468 } 1469 printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT); 1470 1471 //ieee->pHTInfo->IOTAction = 0; 1472 HTResetIOTSetting(ieee->pHTInfo); 1473 if (ieee->iw_mode == IW_MODE_INFRA){ 1474 /* Join the network for the first time */ 1475 ieee->AsocRetryCount = 0; 1476 //for HT by amy 080514 1477 if((ieee->current_network.qos_data.supported == 1) && 1478 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT)) 1479 ieee->current_network.bssht.bdSupportHT) 1480/*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/ 1481 { 1482 // ieee->pHTInfo->bCurrentHTSupport = true; 1483 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network)); 1484 } 1485 else 1486 { 1487 ieee->pHTInfo->bCurrentHTSupport = false; 1488 } 1489 1490 ieee->state = IEEE80211_ASSOCIATING; 1491 queue_work(ieee->wq, &ieee->associate_procedure_wq); 1492 }else{ 1493 if(ieee80211_is_54g(ieee->current_network) && 1494 (ieee->modulation & IEEE80211_OFDM_MODULATION)){ 1495 ieee->rate = 108; 1496 ieee->SetWirelessMode(ieee->dev, IEEE_G); 1497 printk(KERN_INFO"Using G rates\n"); 1498 }else{ 1499 ieee->rate = 22; 1500 ieee->SetWirelessMode(ieee->dev, IEEE_B); 1501 printk(KERN_INFO"Using B rates\n"); 1502 } 1503 memset(ieee->dot11HTOperationalRateSet, 0, 16); 1504 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); 1505 ieee->state = IEEE80211_LINKED; 1506 } 1507 1508 } 1509 } 1510 1511} 1512 1513void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) 1514{ 1515 unsigned long flags; 1516 struct ieee80211_network *target; 1517 1518 spin_lock_irqsave(&ieee->lock, flags); 1519 1520 list_for_each_entry(target, &ieee->network_list, list) { 1521 1522 /* if the state become different that NOLINK means 1523 * we had found what we are searching for 1524 */ 1525 1526 if (ieee->state != IEEE80211_NOLINK) 1527 break; 1528 1529 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies)) 1530 ieee80211_softmac_new_net(ieee, target); 1531 } 1532 1533 spin_unlock_irqrestore(&ieee->lock, flags); 1534 1535} 1536 1537 1538static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) 1539{ 1540 struct ieee80211_authentication *a; 1541 u8 *t; 1542 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ 1543 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len); 1544 return 0xcafe; 1545 } 1546 *challenge = NULL; 1547 a = (struct ieee80211_authentication*) skb->data; 1548 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){ 1549 t = skb->data + sizeof(struct ieee80211_authentication); 1550 1551 if(*(t++) == MFIE_TYPE_CHALLENGE){ 1552 *chlen = *(t++); 1553 *challenge = kmemdup(t, *chlen, GFP_ATOMIC); 1554 if (!*challenge) 1555 return -ENOMEM; 1556 } 1557 } 1558 1559 return cpu_to_le16(a->status); 1560 1561} 1562 1563 1564int auth_rq_parse(struct sk_buff *skb,u8* dest) 1565{ 1566 struct ieee80211_authentication *a; 1567 1568 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ 1569 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len); 1570 return -1; 1571 } 1572 a = (struct ieee80211_authentication*) skb->data; 1573 1574 memcpy(dest,a->header.addr2, ETH_ALEN); 1575 1576 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) 1577 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; 1578 1579 return WLAN_STATUS_SUCCESS; 1580} 1581 1582static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src) 1583{ 1584 u8 *tag; 1585 u8 *skbend; 1586 u8 *ssid=NULL; 1587 u8 ssidlen = 0; 1588 1589 struct ieee80211_hdr_3addr *header = 1590 (struct ieee80211_hdr_3addr *) skb->data; 1591 1592 if (skb->len < sizeof (struct ieee80211_hdr_3addr )) 1593 return -1; /* corrupted */ 1594 1595 memcpy(src,header->addr2, ETH_ALEN); 1596 1597 skbend = (u8*)skb->data + skb->len; 1598 1599 tag = skb->data + sizeof (struct ieee80211_hdr_3addr ); 1600 1601 while (tag+1 < skbend){ 1602 if (*tag == 0){ 1603 ssid = tag+2; 1604 ssidlen = *(tag+1); 1605 break; 1606 } 1607 tag++; /* point to the len field */ 1608 tag = tag + *(tag); /* point to the last data byte of the tag */ 1609 tag++; /* point to the next tag */ 1610 } 1611 1612 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src)); 1613 if (ssidlen == 0) return 1; 1614 1615 if (!ssid) return 1; /* ssid not found in tagged param */ 1616 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen)); 1617 1618} 1619 1620int assoc_rq_parse(struct sk_buff *skb,u8* dest) 1621{ 1622 struct ieee80211_assoc_request_frame *a; 1623 1624 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) - 1625 sizeof(struct ieee80211_info_element))) { 1626 1627 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len); 1628 return -1; 1629 } 1630 1631 a = (struct ieee80211_assoc_request_frame*) skb->data; 1632 1633 memcpy(dest,a->header.addr2,ETH_ALEN); 1634 1635 return 0; 1636} 1637 1638static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid) 1639{ 1640 struct ieee80211_assoc_response_frame *response_head; 1641 u16 status_code; 1642 1643 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){ 1644 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); 1645 return 0xcafe; 1646 } 1647 1648 response_head = (struct ieee80211_assoc_response_frame*) skb->data; 1649 *aid = le16_to_cpu(response_head->aid) & 0x3fff; 1650 1651 status_code = le16_to_cpu(response_head->status); 1652 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \ 1653 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&& 1654 ((ieee->mode == IEEE_G) && 1655 (ieee->current_network.mode == IEEE_N_24G) && 1656 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) { 1657 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE; 1658 }else { 1659 ieee->AsocRetryCount = 0; 1660 } 1661 1662 return le16_to_cpu(response_head->status); 1663} 1664 1665static inline void 1666ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb) 1667{ 1668 u8 dest[ETH_ALEN]; 1669 1670 //IEEE80211DMESG("Rx probe"); 1671 ieee->softmac_stats.rx_probe_rq++; 1672 //DMESG("Dest is "MACSTR, MAC2STR(dest)); 1673 if (probe_rq_parse(ieee, skb, dest)){ 1674 //IEEE80211DMESG("Was for me!"); 1675 ieee->softmac_stats.tx_probe_rs++; 1676 ieee80211_resp_to_probe(ieee, dest); 1677 } 1678} 1679 1680static inline void 1681ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) 1682{ 1683 u8 dest[ETH_ALEN]; 1684 int status; 1685 //IEEE80211DMESG("Rx probe"); 1686 ieee->softmac_stats.rx_auth_rq++; 1687 1688 status = auth_rq_parse(skb, dest); 1689 if (status != -1) { 1690 ieee80211_resp_to_auth(ieee, status, dest); 1691 } 1692 //DMESG("Dest is "MACSTR, MAC2STR(dest)); 1693 1694} 1695 1696static inline void 1697ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) 1698{ 1699 1700 u8 dest[ETH_ALEN]; 1701 //unsigned long flags; 1702 1703 ieee->softmac_stats.rx_ass_rq++; 1704 if (assoc_rq_parse(skb,dest) != -1){ 1705 ieee80211_resp_to_assoc_rq(ieee, dest); 1706 } 1707 1708 printk(KERN_INFO"New client associated: %pM\n", dest); 1709 //FIXME 1710} 1711 1712 1713 1714void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr) 1715{ 1716 1717 struct sk_buff *buf = ieee80211_null_func(ieee, pwr); 1718 1719 if (buf) 1720 softmac_ps_mgmt_xmit(buf, ieee); 1721 1722} 1723 1724 1725short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l) 1726{ 1727 int timeout = ieee->ps_timeout; 1728 u8 dtim; 1729 /*if(ieee->ps == IEEE80211_PS_DISABLED || 1730 ieee->iw_mode != IW_MODE_INFRA || 1731 ieee->state != IEEE80211_LINKED) 1732 1733 return 0; 1734 */ 1735 dtim = ieee->current_network.dtim_data; 1736 //printk("DTIM\n"); 1737 if(!(dtim & IEEE80211_DTIM_VALID)) 1738 return 0; 1739 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval 1740 //printk("VALID\n"); 1741 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; 1742 1743 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps)) 1744 return 2; 1745 1746 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))) 1747 return 0; 1748 1749 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))) 1750 return 0; 1751 1752 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) && 1753 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) 1754 return 0; 1755 1756 if(time_l){ 1757 *time_l = ieee->current_network.last_dtim_sta_time[0] 1758 + (ieee->current_network.beacon_interval 1759 * ieee->current_network.dtim_period) * 1000; 1760 } 1761 1762 if(time_h){ 1763 *time_h = ieee->current_network.last_dtim_sta_time[1]; 1764 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0]) 1765 *time_h += 1; 1766 } 1767 1768 return 1; 1769 1770 1771} 1772 1773inline void ieee80211_sta_ps(struct ieee80211_device *ieee) 1774{ 1775 1776 u32 th,tl; 1777 short sleep; 1778 1779 unsigned long flags,flags2; 1780 1781 spin_lock_irqsave(&ieee->lock, flags); 1782 1783 if((ieee->ps == IEEE80211_PS_DISABLED || 1784 ieee->iw_mode != IW_MODE_INFRA || 1785 ieee->state != IEEE80211_LINKED)){ 1786 1787 // #warning CHECK_LOCK_HERE 1788 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); 1789 1790 ieee80211_sta_wakeup(ieee, 1); 1791 1792 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); 1793 } 1794 1795 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl); 1796 /* 2 wake, 1 sleep, 0 do nothing */ 1797 if(sleep == 0) 1798 goto out; 1799 1800 if(sleep == 1){ 1801 1802 if(ieee->sta_sleep == 1) 1803 ieee->enter_sleep_state(ieee->dev,th,tl); 1804 1805 else if(ieee->sta_sleep == 0){ 1806 // printk("send null 1\n"); 1807 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); 1808 1809 if(ieee->ps_is_queue_empty(ieee->dev)){ 1810 1811 1812 ieee->sta_sleep = 2; 1813 1814 ieee->ps_request_tx_ack(ieee->dev); 1815 1816 ieee80211_sta_ps_send_null_frame(ieee,1); 1817 1818 ieee->ps_th = th; 1819 ieee->ps_tl = tl; 1820 } 1821 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); 1822 1823 } 1824 1825 1826 }else if(sleep == 2){ 1827//#warning CHECK_LOCK_HERE 1828 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); 1829 1830 ieee80211_sta_wakeup(ieee,1); 1831 1832 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); 1833 } 1834 1835out: 1836 spin_unlock_irqrestore(&ieee->lock, flags); 1837 1838} 1839 1840void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) 1841{ 1842 if(ieee->sta_sleep == 0){ 1843 if(nl){ 1844 printk("Warning: driver is probably failing to report TX ps error\n"); 1845 ieee->ps_request_tx_ack(ieee->dev); 1846 ieee80211_sta_ps_send_null_frame(ieee, 0); 1847 } 1848 return; 1849 1850 } 1851 1852 if(ieee->sta_sleep == 1) 1853 ieee->sta_wake_up(ieee->dev); 1854 1855 ieee->sta_sleep = 0; 1856 1857 if(nl){ 1858 ieee->ps_request_tx_ack(ieee->dev); 1859 ieee80211_sta_ps_send_null_frame(ieee, 0); 1860 } 1861} 1862 1863void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) 1864{ 1865 unsigned long flags,flags2; 1866 1867 spin_lock_irqsave(&ieee->lock, flags); 1868 1869 if(ieee->sta_sleep == 2){ 1870 /* Null frame with PS bit set */ 1871 if(success){ 1872 ieee->sta_sleep = 1; 1873 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl); 1874 } 1875 /* if the card report not success we can't be sure the AP 1876 * has not RXed so we can't assume the AP believe us awake 1877 */ 1878 } 1879 /* 21112005 - tx again null without PS bit if lost */ 1880 else { 1881 1882 if((ieee->sta_sleep == 0) && !success){ 1883 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); 1884 ieee80211_sta_ps_send_null_frame(ieee, 0); 1885 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); 1886 } 1887 } 1888 spin_unlock_irqrestore(&ieee->lock, flags); 1889} 1890void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb) 1891{ 1892 struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data; 1893 u8* act = ieee80211_get_payload(header); 1894 u8 tmp = 0; 1895// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); 1896 if (act == NULL) 1897 { 1898 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n"); 1899 return; 1900 } 1901 tmp = *act; 1902 act ++; 1903 switch (tmp) 1904 { 1905 case ACT_CAT_BA: 1906 if (*act == ACT_ADDBAREQ) 1907 ieee80211_rx_ADDBAReq(ieee, skb); 1908 else if (*act == ACT_ADDBARSP) 1909 ieee80211_rx_ADDBARsp(ieee, skb); 1910 else if (*act == ACT_DELBA) 1911 ieee80211_rx_DELBA(ieee, skb); 1912 break; 1913 default: 1914// if (net_ratelimit()) 1915// IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp); 1916 break; 1917 } 1918 return; 1919 1920} 1921inline int 1922ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, 1923 struct ieee80211_rx_stats *rx_stats, u16 type, 1924 u16 stype) 1925{ 1926 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data; 1927 u16 errcode; 1928 u8* challenge; 1929 int chlen=0; 1930 int aid; 1931 struct ieee80211_assoc_response_frame *assoc_resp; 1932// struct ieee80211_info_element *info_element; 1933 bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode 1934 1935 if(!ieee->proto_started) 1936 return 0; 1937 1938 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && 1939 ieee->iw_mode == IW_MODE_INFRA && 1940 ieee->state == IEEE80211_LINKED)) 1941 1942 tasklet_schedule(&ieee->ps_task); 1943 1944 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && 1945 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) 1946 ieee->last_rx_ps_time = jiffies; 1947 1948 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { 1949 1950 case IEEE80211_STYPE_ASSOC_RESP: 1951 case IEEE80211_STYPE_REASSOC_RESP: 1952 1953 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n", 1954 WLAN_FC_GET_STYPE(header->frame_ctl)); 1955 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && 1956 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED && 1957 ieee->iw_mode == IW_MODE_INFRA){ 1958 struct ieee80211_network network_resp; 1959 struct ieee80211_network *network = &network_resp; 1960 1961 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){ 1962 ieee->state=IEEE80211_LINKED; 1963 ieee->assoc_id = aid; 1964 ieee->softmac_stats.rx_ass_ok++; 1965 /* station support qos */ 1966 /* Let the register setting defaultly with Legacy station */ 1967 if(ieee->qos_support) { 1968 assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data; 1969 memset(network, 0, sizeof(*network)); 1970 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\ 1971 rx_stats->len - sizeof(*assoc_resp),\ 1972 network,rx_stats)){ 1973 return 1; 1974 } 1975 else 1976 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network. 1977 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen); 1978 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen); 1979 } 1980 if (ieee->handle_assoc_response != NULL) 1981 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network); 1982 } 1983 ieee80211_associate_complete(ieee); 1984 } else { 1985 /* aid could not been allocated */ 1986 ieee->softmac_stats.rx_ass_err++; 1987 printk( 1988 "Association response status code 0x%x\n", 1989 errcode); 1990 IEEE80211_DEBUG_MGMT( 1991 "Association response status code 0x%x\n", 1992 errcode); 1993 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) { 1994 queue_work(ieee->wq, &ieee->associate_procedure_wq); 1995 } else { 1996 ieee80211_associate_abort(ieee); 1997 } 1998 } 1999 } 2000 break; 2001 2002 case IEEE80211_STYPE_ASSOC_REQ: 2003 case IEEE80211_STYPE_REASSOC_REQ: 2004 2005 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && 2006 ieee->iw_mode == IW_MODE_MASTER) 2007 2008 ieee80211_rx_assoc_rq(ieee, skb); 2009 break; 2010 2011 case IEEE80211_STYPE_AUTH: 2012 2013 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){ 2014 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING && 2015 ieee->iw_mode == IW_MODE_INFRA){ 2016 2017 IEEE80211_DEBUG_MGMT("Received authentication response"); 2018 2019 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){ 2020 if(ieee->open_wep || !challenge){ 2021 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED; 2022 ieee->softmac_stats.rx_auth_rs_ok++; 2023 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE)) 2024 { 2025 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) 2026 { 2027 // WEP or TKIP encryption 2028 if(IsHTHalfNmodeAPs(ieee)) 2029 { 2030 bSupportNmode = true; 2031 bHalfSupportNmode = true; 2032 } 2033 else 2034 { 2035 bSupportNmode = false; 2036 bHalfSupportNmode = false; 2037 } 2038 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode); 2039 } 2040 } 2041 /* Dummy wirless mode setting to avoid encryption issue */ 2042 if(bSupportNmode) { 2043 //N mode setting 2044 ieee->SetWirelessMode(ieee->dev, \ 2045 ieee->current_network.mode); 2046 }else{ 2047 //b/g mode setting 2048 /*TODO*/ 2049 ieee->SetWirelessMode(ieee->dev, IEEE_G); 2050 } 2051 2052 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true) 2053 { 2054 printk("===============>entern half N mode\n"); 2055 ieee->bHalfWirelessN24GMode = true; 2056 } 2057 else 2058 ieee->bHalfWirelessN24GMode = false; 2059 2060 ieee80211_associate_step2(ieee); 2061 }else{ 2062 ieee80211_auth_challenge(ieee, challenge, chlen); 2063 } 2064 }else{ 2065 ieee->softmac_stats.rx_auth_rs_err++; 2066 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode); 2067 ieee80211_associate_abort(ieee); 2068 } 2069 2070 }else if (ieee->iw_mode == IW_MODE_MASTER){ 2071 ieee80211_rx_auth_rq(ieee, skb); 2072 } 2073 } 2074 break; 2075 2076 case IEEE80211_STYPE_PROBE_REQ: 2077 2078 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && 2079 ((ieee->iw_mode == IW_MODE_ADHOC || 2080 ieee->iw_mode == IW_MODE_MASTER) && 2081 ieee->state == IEEE80211_LINKED)){ 2082 ieee80211_rx_probe_rq(ieee, skb); 2083 } 2084 break; 2085 2086 case IEEE80211_STYPE_DISASSOC: 2087 case IEEE80211_STYPE_DEAUTH: 2088 /* FIXME for now repeat all the association procedure 2089 * both for disassociation and deauthentication 2090 */ 2091 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && 2092 ieee->state == IEEE80211_LINKED && 2093 ieee->iw_mode == IW_MODE_INFRA){ 2094 2095 ieee->state = IEEE80211_ASSOCIATING; 2096 ieee->softmac_stats.reassoc++; 2097 2098 notify_wx_assoc_event(ieee); 2099 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); 2100 RemovePeerTS(ieee, header->addr2); 2101 queue_work(ieee->wq, &ieee->associate_procedure_wq); 2102 } 2103 break; 2104 case IEEE80211_STYPE_MANAGE_ACT: 2105 ieee80211_process_action(ieee,skb); 2106 break; 2107 default: 2108 return -1; 2109 break; 2110 } 2111 2112 //dev_kfree_skb_any(skb); 2113 return 0; 2114} 2115 2116/* following are for a simpler TX queue management. 2117 * Instead of using netif_[stop/wake]_queue the driver 2118 * will uses these two function (plus a reset one), that 2119 * will internally uses the kernel netif_* and takes 2120 * care of the ieee802.11 fragmentation. 2121 * So the driver receives a fragment per time and might 2122 * call the stop function when it want without take care 2123 * to have enought room to TX an entire packet. 2124 * This might be useful if each fragment need it's own 2125 * descriptor, thus just keep a total free memory > than 2126 * the max fragmentation treshold is not enought.. If the 2127 * ieee802.11 stack passed a TXB struct then you needed 2128 * to keep N free descriptors where 2129 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD 2130 * In this way you need just one and the 802.11 stack 2131 * will take care of buffering fragments and pass them to 2132 * to the driver later, when it wakes the queue. 2133 */ 2134void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee) 2135{ 2136 2137 unsigned int queue_index = txb->queue_index; 2138 unsigned long flags; 2139 int i; 2140 cb_desc *tcb_desc = NULL; 2141 2142 spin_lock_irqsave(&ieee->lock,flags); 2143 2144 /* called with 2nd parm 0, no tx mgmt lock required */ 2145 ieee80211_sta_wakeup(ieee,0); 2146 2147 /* update the tx status */ 2148 ieee->stats.tx_bytes += txb->payload_size; 2149 ieee->stats.tx_packets++; 2150 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); 2151 if(tcb_desc->bMulticast) { 2152 ieee->stats.multicast++; 2153 } 2154 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */ 2155 for(i = 0; i < txb->nr_frags; i++) { 2156#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE 2157 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) || 2158#else 2159 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) || 2160#endif 2161 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\ 2162 (ieee->queue_stop)) { 2163 /* insert the skb packet to the wait queue */ 2164 /* as for the completion function, it does not need 2165 * to check it any more. 2166 * */ 2167 //printk("error:no descriptor left@queue_index %d\n", queue_index); 2168 //ieee80211_stop_queue(ieee); 2169#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE 2170 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); 2171#else 2172 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]); 2173#endif 2174 }else{ 2175 ieee->softmac_data_hard_start_xmit( 2176 txb->fragments[i], 2177 ieee->dev,ieee->rate); 2178 //ieee->stats.tx_packets++; 2179 //ieee->stats.tx_bytes += txb->fragments[i]->len; 2180 //ieee->dev->trans_start = jiffies; 2181 } 2182 } 2183 ieee80211_txb_free(txb); 2184 2185//exit: 2186 spin_unlock_irqrestore(&ieee->lock,flags); 2187 2188} 2189 2190/* called with ieee->lock acquired */ 2191void ieee80211_resume_tx(struct ieee80211_device *ieee) 2192{ 2193 int i; 2194 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) { 2195 2196 if (ieee->queue_stop){ 2197 ieee->tx_pending.frag = i; 2198 return; 2199 }else{ 2200 2201 ieee->softmac_data_hard_start_xmit( 2202 ieee->tx_pending.txb->fragments[i], 2203 ieee->dev,ieee->rate); 2204 //(i+1)<ieee->tx_pending.txb->nr_frags); 2205 ieee->stats.tx_packets++; 2206 ieee->dev->trans_start = jiffies; 2207 } 2208 } 2209 2210 2211 ieee80211_txb_free(ieee->tx_pending.txb); 2212 ieee->tx_pending.txb = NULL; 2213} 2214 2215 2216void ieee80211_reset_queue(struct ieee80211_device *ieee) 2217{ 2218 unsigned long flags; 2219 2220 spin_lock_irqsave(&ieee->lock,flags); 2221 init_mgmt_queue(ieee); 2222 if (ieee->tx_pending.txb){ 2223 ieee80211_txb_free(ieee->tx_pending.txb); 2224 ieee->tx_pending.txb = NULL; 2225 } 2226 ieee->queue_stop = 0; 2227 spin_unlock_irqrestore(&ieee->lock,flags); 2228 2229} 2230 2231void ieee80211_wake_queue(struct ieee80211_device *ieee) 2232{ 2233 2234 unsigned long flags; 2235 struct sk_buff *skb; 2236 struct ieee80211_hdr_3addr *header; 2237 2238 spin_lock_irqsave(&ieee->lock,flags); 2239 if (! ieee->queue_stop) goto exit; 2240 2241 ieee->queue_stop = 0; 2242 2243 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){ 2244 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){ 2245 2246 header = (struct ieee80211_hdr_3addr *) skb->data; 2247 2248 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 2249 2250 if (ieee->seq_ctrl[0] == 0xFFF) 2251 ieee->seq_ctrl[0] = 0; 2252 else 2253 ieee->seq_ctrl[0]++; 2254 2255 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); 2256 //dev_kfree_skb_any(skb);//edit by thomas 2257 } 2258 } 2259 if (!ieee->queue_stop && ieee->tx_pending.txb) 2260 ieee80211_resume_tx(ieee); 2261 2262 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){ 2263 ieee->softmac_stats.swtxawake++; 2264 netif_wake_queue(ieee->dev); 2265 } 2266 2267exit : 2268 spin_unlock_irqrestore(&ieee->lock,flags); 2269} 2270 2271 2272void ieee80211_stop_queue(struct ieee80211_device *ieee) 2273{ 2274 //unsigned long flags; 2275 //spin_lock_irqsave(&ieee->lock,flags); 2276 2277 if (! netif_queue_stopped(ieee->dev)){ 2278 netif_stop_queue(ieee->dev); 2279 ieee->softmac_stats.swtxstop++; 2280 } 2281 ieee->queue_stop = 1; 2282 //spin_unlock_irqrestore(&ieee->lock,flags); 2283 2284} 2285 2286 2287inline void ieee80211_randomize_cell(struct ieee80211_device *ieee) 2288{ 2289 2290 get_random_bytes(ieee->current_network.bssid, ETH_ALEN); 2291 2292 /* an IBSS cell address must have the two less significant 2293 * bits of the first byte = 2 2294 */ 2295 ieee->current_network.bssid[0] &= ~0x01; 2296 ieee->current_network.bssid[0] |= 0x02; 2297} 2298 2299/* called in user context only */ 2300void ieee80211_start_master_bss(struct ieee80211_device *ieee) 2301{ 2302 ieee->assoc_id = 1; 2303 2304 if (ieee->current_network.ssid_len == 0){ 2305 strncpy(ieee->current_network.ssid, 2306 IEEE80211_DEFAULT_TX_ESSID, 2307 IW_ESSID_MAX_SIZE); 2308 2309 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); 2310 ieee->ssid_set = 1; 2311 } 2312 2313 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); 2314 2315 ieee->set_chan(ieee->dev, ieee->current_network.channel); 2316 ieee->state = IEEE80211_LINKED; 2317 ieee->link_change(ieee->dev); 2318 notify_wx_assoc_event(ieee); 2319 2320 if (ieee->data_hard_resume) 2321 ieee->data_hard_resume(ieee->dev); 2322 2323 netif_carrier_on(ieee->dev); 2324} 2325 2326void ieee80211_start_monitor_mode(struct ieee80211_device *ieee) 2327{ 2328 if(ieee->raw_tx){ 2329 2330 if (ieee->data_hard_resume) 2331 ieee->data_hard_resume(ieee->dev); 2332 2333 netif_carrier_on(ieee->dev); 2334 } 2335} 2336void ieee80211_start_ibss_wq(struct work_struct *work) 2337{ 2338 2339 struct delayed_work *dwork = container_of(work, struct delayed_work, work); 2340 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq); 2341 /* iwconfig mode ad-hoc will schedule this and return 2342 * on the other hand this will block further iwconfig SET 2343 * operations because of the wx_sem hold. 2344 * Anyway some most set operations set a flag to speed-up 2345 * (abort) this wq (when syncro scanning) before sleeping 2346 * on the semaphore 2347 */ 2348 if(!ieee->proto_started){ 2349 printk("==========oh driver down return\n"); 2350 return; 2351 } 2352 down(&ieee->wx_sem); 2353 2354 if (ieee->current_network.ssid_len == 0){ 2355 strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID); 2356 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); 2357 ieee->ssid_set = 1; 2358 } 2359 2360 /* check if we have this cell in our network list */ 2361 ieee80211_softmac_check_all_nets(ieee); 2362 2363 2364// if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK)) 2365 if (ieee->state == IEEE80211_NOLINK) 2366 ieee->current_network.channel = 6; 2367 /* if not then the state is not linked. Maybe the user swithced to 2368 * ad-hoc mode just after being in monitor mode, or just after 2369 * being very few time in managed mode (so the card have had no 2370 * time to scan all the chans..) or we have just run up the iface 2371 * after setting ad-hoc mode. So we have to give another try.. 2372 * Here, in ibss mode, should be safe to do this without extra care 2373 * (in bss mode we had to make sure no-one tryed to associate when 2374 * we had just checked the ieee->state and we was going to start the 2375 * scan) beacause in ibss mode the ieee80211_new_net function, when 2376 * finds a good net, just set the ieee->state to IEEE80211_LINKED, 2377 * so, at worst, we waste a bit of time to initiate an unneeded syncro 2378 * scan, that will stop at the first round because it sees the state 2379 * associated. 2380 */ 2381 if (ieee->state == IEEE80211_NOLINK) 2382 ieee80211_start_scan_syncro(ieee); 2383 2384 /* the network definitively is not here.. create a new cell */ 2385 if (ieee->state == IEEE80211_NOLINK){ 2386 printk("creating new IBSS cell\n"); 2387 if(!ieee->wap_set) 2388 ieee80211_randomize_cell(ieee); 2389 2390 if(ieee->modulation & IEEE80211_CCK_MODULATION){ 2391 2392 ieee->current_network.rates_len = 4; 2393 2394 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; 2395 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; 2396 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; 2397 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; 2398 2399 }else 2400 ieee->current_network.rates_len = 0; 2401 2402 if(ieee->modulation & IEEE80211_OFDM_MODULATION){ 2403 ieee->current_network.rates_ex_len = 8; 2404 2405 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; 2406 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; 2407 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; 2408 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; 2409 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; 2410 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; 2411 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; 2412 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; 2413 2414 ieee->rate = 108; 2415 }else{ 2416 ieee->current_network.rates_ex_len = 0; 2417 ieee->rate = 22; 2418 } 2419 2420 // By default, WMM function will be disabled in IBSS mode 2421 ieee->current_network.QoS_Enable = 0; 2422 ieee->SetWirelessMode(ieee->dev, IEEE_G); 2423 ieee->current_network.atim_window = 0; 2424 ieee->current_network.capability = WLAN_CAPABILITY_IBSS; 2425 if(ieee->short_slot) 2426 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT; 2427 2428 } 2429 2430 ieee->state = IEEE80211_LINKED; 2431 2432 ieee->set_chan(ieee->dev, ieee->current_network.channel); 2433 ieee->link_change(ieee->dev); 2434 2435 notify_wx_assoc_event(ieee); 2436 2437 ieee80211_start_send_beacons(ieee); 2438 2439 if (ieee->data_hard_resume) 2440 ieee->data_hard_resume(ieee->dev); 2441 netif_carrier_on(ieee->dev); 2442 2443 up(&ieee->wx_sem); 2444} 2445 2446inline void ieee80211_start_ibss(struct ieee80211_device *ieee) 2447{ 2448 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150); 2449} 2450 2451/* this is called only in user context, with wx_sem held */ 2452void ieee80211_start_bss(struct ieee80211_device *ieee) 2453{ 2454 unsigned long flags; 2455 // 2456 // Ref: 802.11d 11.1.3.3 2457 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE. 2458 // 2459 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) 2460 { 2461 if(! ieee->bGlobalDomain) 2462 { 2463 return; 2464 } 2465 } 2466 /* check if we have already found the net we 2467 * are interested in (if any). 2468 * if not (we are disassociated and we are not 2469 * in associating / authenticating phase) start the background scanning. 2470 */ 2471 ieee80211_softmac_check_all_nets(ieee); 2472 2473 /* ensure no-one start an associating process (thus setting 2474 * the ieee->state to ieee80211_ASSOCIATING) while we 2475 * have just cheked it and we are going to enable scan. 2476 * The ieee80211_new_net function is always called with 2477 * lock held (from both ieee80211_softmac_check_all_nets and 2478 * the rx path), so we cannot be in the middle of such function 2479 */ 2480 spin_lock_irqsave(&ieee->lock, flags); 2481 2482 if (ieee->state == IEEE80211_NOLINK){ 2483 ieee->actscanning = true; 2484 ieee80211_start_scan(ieee); 2485 } 2486 spin_unlock_irqrestore(&ieee->lock, flags); 2487} 2488 2489/* called only in userspace context */ 2490void ieee80211_disassociate(struct ieee80211_device *ieee) 2491{ 2492 2493 2494 netif_carrier_off(ieee->dev); 2495 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) 2496 ieee80211_reset_queue(ieee); 2497 2498 if (ieee->data_hard_stop) 2499 ieee->data_hard_stop(ieee->dev); 2500 if(IS_DOT11D_ENABLE(ieee)) 2501 Dot11d_Reset(ieee); 2502 ieee->state = IEEE80211_NOLINK; 2503 ieee->is_set_key = false; 2504 ieee->link_change(ieee->dev); 2505 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); 2506 notify_wx_assoc_event(ieee); 2507 2508} 2509void ieee80211_associate_retry_wq(struct work_struct *work) 2510{ 2511 struct delayed_work *dwork = container_of(work, struct delayed_work, work); 2512 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq); 2513 unsigned long flags; 2514 2515 down(&ieee->wx_sem); 2516 if(!ieee->proto_started) 2517 goto exit; 2518 2519 if(ieee->state != IEEE80211_ASSOCIATING_RETRY) 2520 goto exit; 2521 2522 /* until we do not set the state to IEEE80211_NOLINK 2523 * there are no possibility to have someone else trying 2524 * to start an association procdure (we get here with 2525 * ieee->state = IEEE80211_ASSOCIATING). 2526 * When we set the state to IEEE80211_NOLINK it is possible 2527 * that the RX path run an attempt to associate, but 2528 * both ieee80211_softmac_check_all_nets and the 2529 * RX path works with ieee->lock held so there are no 2530 * problems. If we are still disassociated then start a scan. 2531 * the lock here is necessary to ensure no one try to start 2532 * an association procedure when we have just checked the 2533 * state and we are going to start the scan. 2534 */ 2535 ieee->state = IEEE80211_NOLINK; 2536 2537 ieee80211_softmac_check_all_nets(ieee); 2538 2539 spin_lock_irqsave(&ieee->lock, flags); 2540 2541 if(ieee->state == IEEE80211_NOLINK) 2542 ieee80211_start_scan(ieee); 2543 2544 spin_unlock_irqrestore(&ieee->lock, flags); 2545 2546exit: 2547 up(&ieee->wx_sem); 2548} 2549 2550struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee) 2551{ 2552 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff}; 2553 2554 struct sk_buff *skb; 2555 struct ieee80211_probe_response *b; 2556 2557 skb = ieee80211_probe_resp(ieee, broadcast_addr); 2558 2559 if (!skb) 2560 return NULL; 2561 2562 b = (struct ieee80211_probe_response *) skb->data; 2563 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON); 2564 2565 return skb; 2566 2567} 2568 2569struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee) 2570{ 2571 struct sk_buff *skb; 2572 struct ieee80211_probe_response *b; 2573 2574 skb = ieee80211_get_beacon_(ieee); 2575 if(!skb) 2576 return NULL; 2577 2578 b = (struct ieee80211_probe_response *) skb->data; 2579 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 2580 2581 if (ieee->seq_ctrl[0] == 0xFFF) 2582 ieee->seq_ctrl[0] = 0; 2583 else 2584 ieee->seq_ctrl[0]++; 2585 2586 return skb; 2587} 2588 2589void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee) 2590{ 2591 ieee->sync_scan_hurryup = 1; 2592 down(&ieee->wx_sem); 2593 ieee80211_stop_protocol(ieee); 2594 up(&ieee->wx_sem); 2595} 2596 2597 2598void ieee80211_stop_protocol(struct ieee80211_device *ieee) 2599{ 2600 if (!ieee->proto_started) 2601 return; 2602 2603 ieee->proto_started = 0; 2604 2605 ieee80211_stop_send_beacons(ieee); 2606 del_timer_sync(&ieee->associate_timer); 2607 cancel_delayed_work(&ieee->associate_retry_wq); 2608 cancel_delayed_work(&ieee->start_ibss_wq); 2609 ieee80211_stop_scan(ieee); 2610 2611 ieee80211_disassociate(ieee); 2612 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS 2613} 2614 2615void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee) 2616{ 2617 ieee->sync_scan_hurryup = 0; 2618 down(&ieee->wx_sem); 2619 ieee80211_start_protocol(ieee); 2620 up(&ieee->wx_sem); 2621} 2622 2623void ieee80211_start_protocol(struct ieee80211_device *ieee) 2624{ 2625 short ch = 0; 2626 int i = 0; 2627 if (ieee->proto_started) 2628 return; 2629 2630 ieee->proto_started = 1; 2631 2632 if (ieee->current_network.channel == 0){ 2633 do{ 2634 ch++; 2635 if (ch > MAX_CHANNEL_NUMBER) 2636 return; /* no channel found */ 2637 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]); 2638 ieee->current_network.channel = ch; 2639 } 2640 2641 if (ieee->current_network.beacon_interval == 0) 2642 ieee->current_network.beacon_interval = 100; 2643// printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); 2644// ieee->set_chan(ieee->dev,ieee->current_network.channel); 2645 2646 for(i = 0; i < 17; i++) { 2647 ieee->last_rxseq_num[i] = -1; 2648 ieee->last_rxfrag_num[i] = -1; 2649 ieee->last_packet_time[i] = 0; 2650 } 2651 2652 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers. 2653 2654 2655 /* if the user set the MAC of the ad-hoc cell and then 2656 * switch to managed mode, shall we make sure that association 2657 * attempts does not fail just because the user provide the essid 2658 * and the nic is still checking for the AP MAC ?? 2659 */ 2660 if (ieee->iw_mode == IW_MODE_INFRA) 2661 ieee80211_start_bss(ieee); 2662 2663 else if (ieee->iw_mode == IW_MODE_ADHOC) 2664 ieee80211_start_ibss(ieee); 2665 2666 else if (ieee->iw_mode == IW_MODE_MASTER) 2667 ieee80211_start_master_bss(ieee); 2668 2669 else if(ieee->iw_mode == IW_MODE_MONITOR) 2670 ieee80211_start_monitor_mode(ieee); 2671} 2672 2673 2674#define DRV_NAME "Ieee80211" 2675void ieee80211_softmac_init(struct ieee80211_device *ieee) 2676{ 2677 int i; 2678 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network)); 2679 2680 ieee->state = IEEE80211_NOLINK; 2681 ieee->sync_scan_hurryup = 0; 2682 for(i = 0; i < 5; i++) { 2683 ieee->seq_ctrl[i] = 0; 2684 } 2685 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); 2686 if (!ieee->pDot11dInfo) 2687 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n"); 2688 //added for AP roaming 2689 ieee->LinkDetectInfo.SlotNum = 2; 2690 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; 2691 ieee->LinkDetectInfo.NumRecvDataInPeriod=0; 2692 2693 ieee->assoc_id = 0; 2694 ieee->queue_stop = 0; 2695 ieee->scanning = 0; 2696 ieee->softmac_features = 0; //so IEEE2100-like driver are happy 2697 ieee->wap_set = 0; 2698 ieee->ssid_set = 0; 2699 ieee->proto_started = 0; 2700 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE; 2701 ieee->rate = 22; 2702 ieee->ps = IEEE80211_PS_DISABLED; 2703 ieee->sta_sleep = 0; 2704 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7 2705 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15 2706 ieee->Regdot11HTOperationalRateSet[4]= 0x01; 2707 //added by amy 2708 ieee->actscanning = false; 2709 ieee->beinretry = false; 2710 ieee->is_set_key = false; 2711 init_mgmt_queue(ieee); 2712 2713 ieee->sta_edca_param[0] = 0x0000A403; 2714 ieee->sta_edca_param[1] = 0x0000A427; 2715 ieee->sta_edca_param[2] = 0x005E4342; 2716 ieee->sta_edca_param[3] = 0x002F3262; 2717 ieee->aggregation = true; 2718 ieee->enable_rx_imm_BA = 1; 2719 ieee->tx_pending.txb = NULL; 2720 2721 init_timer(&ieee->associate_timer); 2722 ieee->associate_timer.data = (unsigned long)ieee; 2723 ieee->associate_timer.function = ieee80211_associate_abort_cb; 2724 2725 init_timer(&ieee->beacon_timer); 2726 ieee->beacon_timer.data = (unsigned long) ieee; 2727 ieee->beacon_timer.function = ieee80211_send_beacon_cb; 2728 2729 ieee->wq = create_workqueue(DRV_NAME); 2730 2731 INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq); 2732 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq); 2733 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq); 2734 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq); 2735 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq); 2736 INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq); 2737 2738 2739 sema_init(&ieee->wx_sem, 1); 2740 sema_init(&ieee->scan_sem, 1); 2741 2742 spin_lock_init(&ieee->mgmt_tx_lock); 2743 spin_lock_init(&ieee->beacon_lock); 2744 2745 tasklet_init(&ieee->ps_task, 2746 (void(*)(unsigned long)) ieee80211_sta_ps, 2747 (unsigned long)ieee); 2748 2749} 2750 2751void ieee80211_softmac_free(struct ieee80211_device *ieee) 2752{ 2753 down(&ieee->wx_sem); 2754 kfree(ieee->pDot11dInfo); 2755 ieee->pDot11dInfo = NULL; 2756 del_timer_sync(&ieee->associate_timer); 2757 2758 cancel_delayed_work(&ieee->associate_retry_wq); 2759 destroy_workqueue(ieee->wq); 2760 2761 up(&ieee->wx_sem); 2762} 2763 2764/******************************************************** 2765 * Start of WPA code. * 2766 * this is stolen from the ipw2200 driver * 2767 ********************************************************/ 2768 2769 2770static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value) 2771{ 2772 /* This is called when wpa_supplicant loads and closes the driver 2773 * interface. */ 2774 printk("%s WPA\n",value ? "enabling" : "disabling"); 2775 ieee->wpa_enabled = value; 2776 return 0; 2777} 2778 2779 2780void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len) 2781{ 2782 /* make sure WPA is enabled */ 2783 ieee80211_wpa_enable(ieee, 1); 2784 2785 ieee80211_disassociate(ieee); 2786} 2787 2788 2789static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason) 2790{ 2791 2792 int ret = 0; 2793 2794 switch (command) { 2795 case IEEE_MLME_STA_DEAUTH: 2796 // silently ignore 2797 break; 2798 2799 case IEEE_MLME_STA_DISASSOC: 2800 ieee80211_disassociate(ieee); 2801 break; 2802 2803 default: 2804 printk("Unknown MLME request: %d\n", command); 2805 ret = -EOPNOTSUPP; 2806 } 2807 2808 return ret; 2809} 2810 2811 2812static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, 2813 struct ieee_param *param, int plen) 2814{ 2815 u8 *buf; 2816 2817 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || 2818 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) 2819 return -EINVAL; 2820 2821 if (param->u.wpa_ie.len) { 2822 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len, 2823 GFP_KERNEL); 2824 if (buf == NULL) 2825 return -ENOMEM; 2826 2827 kfree(ieee->wpa_ie); 2828 ieee->wpa_ie = buf; 2829 ieee->wpa_ie_len = param->u.wpa_ie.len; 2830 } else { 2831 kfree(ieee->wpa_ie); 2832 ieee->wpa_ie = NULL; 2833 ieee->wpa_ie_len = 0; 2834 } 2835 2836 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len); 2837 return 0; 2838} 2839 2840#define AUTH_ALG_OPEN_SYSTEM 0x1 2841#define AUTH_ALG_SHARED_KEY 0x2 2842 2843static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) 2844{ 2845 2846 struct ieee80211_security sec = { 2847 .flags = SEC_AUTH_MODE, 2848 }; 2849 int ret = 0; 2850 2851 if (value & AUTH_ALG_SHARED_KEY) { 2852 sec.auth_mode = WLAN_AUTH_SHARED_KEY; 2853 ieee->open_wep = 0; 2854 ieee->auth_mode = 1; 2855 } else if (value & AUTH_ALG_OPEN_SYSTEM){ 2856 sec.auth_mode = WLAN_AUTH_OPEN; 2857 ieee->open_wep = 1; 2858 ieee->auth_mode = 0; 2859 } 2860 else if (value & IW_AUTH_ALG_LEAP){ 2861 sec.auth_mode = WLAN_AUTH_LEAP; 2862 ieee->open_wep = 1; 2863 ieee->auth_mode = 2; 2864 } 2865 2866 2867 if (ieee->set_security) 2868 ieee->set_security(ieee->dev, &sec); 2869 //else 2870 // ret = -EOPNOTSUPP; 2871 2872 return ret; 2873} 2874 2875static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value) 2876{ 2877 int ret=0; 2878 unsigned long flags; 2879 2880 switch (name) { 2881 case IEEE_PARAM_WPA_ENABLED: 2882 ret = ieee80211_wpa_enable(ieee, value); 2883 break; 2884 2885 case IEEE_PARAM_TKIP_COUNTERMEASURES: 2886 ieee->tkip_countermeasures=value; 2887 break; 2888 2889 case IEEE_PARAM_DROP_UNENCRYPTED: { 2890 /* HACK: 2891 * 2892 * wpa_supplicant calls set_wpa_enabled when the driver 2893 * is loaded and unloaded, regardless of if WPA is being 2894 * used. No other calls are made which can be used to 2895 * determine if encryption will be used or not prior to 2896 * association being expected. If encryption is not being 2897 * used, drop_unencrypted is set to false, else true -- we 2898 * can use this to determine if the CAP_PRIVACY_ON bit should 2899 * be set. 2900 */ 2901 struct ieee80211_security sec = { 2902 .flags = SEC_ENABLED, 2903 .enabled = value, 2904 }; 2905 ieee->drop_unencrypted = value; 2906 /* We only change SEC_LEVEL for open mode. Others 2907 * are set by ipw_wpa_set_encryption. 2908 */ 2909 if (!value) { 2910 sec.flags |= SEC_LEVEL; 2911 sec.level = SEC_LEVEL_0; 2912 } 2913 else { 2914 sec.flags |= SEC_LEVEL; 2915 sec.level = SEC_LEVEL_1; 2916 } 2917 if (ieee->set_security) 2918 ieee->set_security(ieee->dev, &sec); 2919 break; 2920 } 2921 2922 case IEEE_PARAM_PRIVACY_INVOKED: 2923 ieee->privacy_invoked=value; 2924 break; 2925 2926 case IEEE_PARAM_AUTH_ALGS: 2927 ret = ieee80211_wpa_set_auth_algs(ieee, value); 2928 break; 2929 2930 case IEEE_PARAM_IEEE_802_1X: 2931 ieee->ieee802_1x=value; 2932 break; 2933 case IEEE_PARAM_WPAX_SELECT: 2934 // added for WPA2 mixed mode 2935 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags); 2936 ieee->wpax_type_set = 1; 2937 ieee->wpax_type_notify = value; 2938 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags); 2939 break; 2940 2941 default: 2942 printk("Unknown WPA param: %d\n",name); 2943 ret = -EOPNOTSUPP; 2944 } 2945 2946 return ret; 2947} 2948 2949/* implementation borrowed from hostap driver */ 2950 2951static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, 2952 struct ieee_param *param, int param_len) 2953{ 2954 int ret = 0; 2955 2956 struct ieee80211_crypto_ops *ops; 2957 struct ieee80211_crypt_data **crypt; 2958 2959 struct ieee80211_security sec = { 2960 .flags = 0, 2961 }; 2962 2963 param->u.crypt.err = 0; 2964 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; 2965 2966 if (param_len != 2967 (int) ((char *) param->u.crypt.key - (char *) param) + 2968 param->u.crypt.key_len) { 2969 printk("Len mismatch %d, %d\n", param_len, 2970 param->u.crypt.key_len); 2971 return -EINVAL; 2972 } 2973 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 2974 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && 2975 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 2976 if (param->u.crypt.idx >= WEP_KEYS) 2977 return -EINVAL; 2978 crypt = &ieee->crypt[param->u.crypt.idx]; 2979 } else { 2980 return -EINVAL; 2981 } 2982 2983 if (strcmp(param->u.crypt.alg, "none") == 0) { 2984 if (crypt) { 2985 sec.enabled = 0; 2986 // FIXME FIXME 2987 //sec.encrypt = 0; 2988 sec.level = SEC_LEVEL_0; 2989 sec.flags |= SEC_ENABLED | SEC_LEVEL; 2990 ieee80211_crypt_delayed_deinit(ieee, crypt); 2991 } 2992 goto done; 2993 } 2994 sec.enabled = 1; 2995// FIXME FIXME 2996// sec.encrypt = 1; 2997 sec.flags |= SEC_ENABLED; 2998 2999 /* IPW HW cannot build TKIP MIC, host decryption still needed. */ 3000 if (!(ieee->host_encrypt || ieee->host_decrypt) && 3001 strcmp(param->u.crypt.alg, "TKIP")) 3002 goto skip_host_crypt; 3003 3004 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3005 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { 3006 request_module("ieee80211_crypt_wep"); 3007 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3008 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place 3009 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { 3010 request_module("ieee80211_crypt_tkip"); 3011 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3012 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { 3013 request_module("ieee80211_crypt_ccmp"); 3014 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3015 } 3016 if (ops == NULL) { 3017 printk("unknown crypto alg '%s'\n", param->u.crypt.alg); 3018 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; 3019 ret = -EINVAL; 3020 goto done; 3021 } 3022 3023 if (*crypt == NULL || (*crypt)->ops != ops) { 3024 struct ieee80211_crypt_data *new_crypt; 3025 3026 ieee80211_crypt_delayed_deinit(ieee, crypt); 3027 3028 new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); 3029 if (new_crypt == NULL) { 3030 ret = -ENOMEM; 3031 goto done; 3032 } 3033 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); 3034 new_crypt->ops = ops; 3035 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 3036 new_crypt->priv = 3037 new_crypt->ops->init(param->u.crypt.idx); 3038 3039 if (new_crypt->priv == NULL) { 3040 kfree(new_crypt); 3041 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED; 3042 ret = -EINVAL; 3043 goto done; 3044 } 3045 3046 *crypt = new_crypt; 3047 } 3048 3049 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && 3050 (*crypt)->ops->set_key(param->u.crypt.key, 3051 param->u.crypt.key_len, param->u.crypt.seq, 3052 (*crypt)->priv) < 0) { 3053 printk("key setting failed\n"); 3054 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED; 3055 ret = -EINVAL; 3056 goto done; 3057 } 3058 3059 skip_host_crypt: 3060 if (param->u.crypt.set_tx) { 3061 ieee->tx_keyidx = param->u.crypt.idx; 3062 sec.active_key = param->u.crypt.idx; 3063 sec.flags |= SEC_ACTIVE_KEY; 3064 } else 3065 sec.flags &= ~SEC_ACTIVE_KEY; 3066 3067 if (param->u.crypt.alg != NULL) { 3068 memcpy(sec.keys[param->u.crypt.idx], 3069 param->u.crypt.key, 3070 param->u.crypt.key_len); 3071 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; 3072 sec.flags |= (1 << param->u.crypt.idx); 3073 3074 if (strcmp(param->u.crypt.alg, "WEP") == 0) { 3075 sec.flags |= SEC_LEVEL; 3076 sec.level = SEC_LEVEL_1; 3077 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { 3078 sec.flags |= SEC_LEVEL; 3079 sec.level = SEC_LEVEL_2; 3080 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { 3081 sec.flags |= SEC_LEVEL; 3082 sec.level = SEC_LEVEL_3; 3083 } 3084 } 3085 done: 3086 if (ieee->set_security) 3087 ieee->set_security(ieee->dev, &sec); 3088 3089 /* Do not reset port if card is in Managed mode since resetting will 3090 * generate new IEEE 802.11 authentication which may end up in looping 3091 * with IEEE 802.1X. If your hardware requires a reset after WEP 3092 * configuration (for example... Prism2), implement the reset_port in 3093 * the callbacks structures used to initialize the 802.11 stack. */ 3094 if (ieee->reset_on_keychange && 3095 ieee->iw_mode != IW_MODE_INFRA && 3096 ieee->reset_port && 3097 ieee->reset_port(ieee->dev)) { 3098 printk("reset_port failed\n"); 3099 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED; 3100 return -EINVAL; 3101 } 3102 3103 return ret; 3104} 3105 3106inline struct sk_buff *ieee80211_disassociate_skb( 3107 struct ieee80211_network *beacon, 3108 struct ieee80211_device *ieee, 3109 u8 asRsn) 3110{ 3111 struct sk_buff *skb; 3112 struct ieee80211_disassoc *disass; 3113 3114 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc)); 3115 if (!skb) 3116 return NULL; 3117 3118 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc)); 3119 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC); 3120 disass->header.duration_id = 0; 3121 3122 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN); 3123 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 3124 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN); 3125 3126 disass->reason = asRsn; 3127 return skb; 3128} 3129 3130 3131void 3132SendDisassociation( 3133 struct ieee80211_device *ieee, 3134 u8* asSta, 3135 u8 asRsn 3136) 3137{ 3138 struct ieee80211_network *beacon = &ieee->current_network; 3139 struct sk_buff *skb; 3140 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn); 3141 if (skb){ 3142 softmac_mgmt_xmit(skb, ieee); 3143 //dev_kfree_skb_any(skb);//edit by thomas 3144 } 3145} 3146 3147int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p) 3148{ 3149 struct ieee_param *param; 3150 int ret=0; 3151 3152 down(&ieee->wx_sem); 3153 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length); 3154 3155 if (p->length < sizeof(struct ieee_param) || !p->pointer){ 3156 ret = -EINVAL; 3157 goto out; 3158 } 3159 3160 param = kmalloc(p->length, GFP_KERNEL); 3161 if (param == NULL){ 3162 ret = -ENOMEM; 3163 goto out; 3164 } 3165 if (copy_from_user(param, p->pointer, p->length)) { 3166 kfree(param); 3167 ret = -EFAULT; 3168 goto out; 3169 } 3170 3171 switch (param->cmd) { 3172 3173 case IEEE_CMD_SET_WPA_PARAM: 3174 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name, 3175 param->u.wpa_param.value); 3176 break; 3177 3178 case IEEE_CMD_SET_WPA_IE: 3179 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length); 3180 break; 3181 3182 case IEEE_CMD_SET_ENCRYPTION: 3183 ret = ieee80211_wpa_set_encryption(ieee, param, p->length); 3184 break; 3185 3186 case IEEE_CMD_MLME: 3187 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command, 3188 param->u.mlme.reason_code); 3189 break; 3190 3191 default: 3192 printk("Unknown WPA supplicant request: %d\n",param->cmd); 3193 ret = -EOPNOTSUPP; 3194 break; 3195 } 3196 3197 if (ret == 0 && copy_to_user(p->pointer, param, p->length)) 3198 ret = -EFAULT; 3199 3200 kfree(param); 3201out: 3202 up(&ieee->wx_sem); 3203 3204 return ret; 3205} 3206 3207void notify_wx_assoc_event(struct ieee80211_device *ieee) 3208{ 3209 union iwreq_data wrqu; 3210 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3211 if (ieee->state == IEEE80211_LINKED) 3212 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); 3213 else 3214 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 3215 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); 3216} 3217 3218EXPORT_SYMBOL(ieee80211_get_beacon); 3219EXPORT_SYMBOL(ieee80211_wake_queue); 3220EXPORT_SYMBOL(ieee80211_stop_queue); 3221EXPORT_SYMBOL(ieee80211_reset_queue); 3222EXPORT_SYMBOL(ieee80211_softmac_stop_protocol); 3223EXPORT_SYMBOL(ieee80211_softmac_start_protocol); 3224EXPORT_SYMBOL(ieee80211_is_shortslot); 3225EXPORT_SYMBOL(ieee80211_is_54g); 3226EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl); 3227EXPORT_SYMBOL(ieee80211_ps_tx_ack); 3228EXPORT_SYMBOL(ieee80211_softmac_xmit); 3229EXPORT_SYMBOL(ieee80211_stop_send_beacons); 3230EXPORT_SYMBOL(notify_wx_assoc_event); 3231EXPORT_SYMBOL(SendDisassociation); 3232EXPORT_SYMBOL(ieee80211_disassociate); 3233EXPORT_SYMBOL(ieee80211_start_send_beacons); 3234EXPORT_SYMBOL(ieee80211_stop_scan); 3235EXPORT_SYMBOL(ieee80211_send_probe_requests); 3236EXPORT_SYMBOL(ieee80211_softmac_scan_syncro); 3237EXPORT_SYMBOL(ieee80211_start_scan_syncro); 3238//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); 3239