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

https://bitbucket.org/wisechild/galaxy-nexus · C · 3011 lines · 2017 code · 630 blank · 364 comment · 424 complexity · c30d5aace09055f9b59b3c0983c15bec MD5 · raw file

Large files are truncated click here to view the full file

  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 netw…