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