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