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