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