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