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