PageRenderTime 74ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c

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