/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t · C · 1544 lines · 1156 code · 190 blank · 198 comment · 279 complexity · 4bc1cf794fcf1f615d5489aef1c86fe6 MD5 · raw file

  1. /*
  2. * Original code based Host AP (software wireless LAN access point) driver
  3. * for Intersil Prism2/2.5/3 - hostap.o module, common routines
  4. *
  5. * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  6. * <jkmaline@cc.hut.fi>
  7. * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
  8. * Copyright (c) 2004, Intel Corporation
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation. See README and COPYING for
  13. * more details.
  14. ******************************************************************************
  15. Few modifications for Realtek's Wi-Fi drivers by
  16. Andrea Merello <andreamrl@tiscali.it>
  17. A special thanks goes to Realtek for their support !
  18. ******************************************************************************/
  19. #include <linux/compiler.h>
  20. //#include <linux/config.h>
  21. #include <linux/errno.h>
  22. #include <linux/if_arp.h>
  23. #include <linux/in6.h>
  24. #include <linux/in.h>
  25. #include <linux/ip.h>
  26. #include <linux/kernel.h>
  27. #include <linux/module.h>
  28. #include <linux/netdevice.h>
  29. #include <linux/pci.h>
  30. #include <linux/proc_fs.h>
  31. #include <linux/skbuff.h>
  32. #include <linux/slab.h>
  33. #include <linux/tcp.h>
  34. #include <linux/types.h>
  35. #include <linux/wireless.h>
  36. #include <linux/etherdevice.h>
  37. #include <asm/uaccess.h>
  38. #include <linux/ctype.h>
  39. #include "ieee80211.h"
  40. #include "dot11d.h"
  41. static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
  42. struct sk_buff *skb,
  43. struct ieee80211_rx_stats *rx_stats)
  44. {
  45. struct ieee80211_hdr_4addr *hdr =
  46. (struct ieee80211_hdr_4addr *)skb->data;
  47. u16 fc = le16_to_cpu(hdr->frame_ctl);
  48. skb->dev = ieee->dev;
  49. skb_reset_mac_header(skb);
  50. skb_pull(skb, ieee80211_get_hdrlen(fc));
  51. skb->pkt_type = PACKET_OTHERHOST;
  52. skb->protocol = __constant_htons(ETH_P_80211_RAW);
  53. memset(skb->cb, 0, sizeof(skb->cb));
  54. netif_rx(skb);
  55. }
  56. /* Called only as a tasklet (software IRQ) */
  57. static struct ieee80211_frag_entry *
  58. ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
  59. unsigned int frag, u8 tid,u8 *src, u8 *dst)
  60. {
  61. struct ieee80211_frag_entry *entry;
  62. int i;
  63. for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
  64. entry = &ieee->frag_cache[tid][i];
  65. if (entry->skb != NULL &&
  66. time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
  67. IEEE80211_DEBUG_FRAG(
  68. "expiring fragment cache entry "
  69. "seq=%u last_frag=%u\n",
  70. entry->seq, entry->last_frag);
  71. dev_kfree_skb_any(entry->skb);
  72. entry->skb = NULL;
  73. }
  74. if (entry->skb != NULL && entry->seq == seq &&
  75. (entry->last_frag + 1 == frag || frag == -1) &&
  76. memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
  77. memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
  78. return entry;
  79. }
  80. return NULL;
  81. }
  82. /* Called only as a tasklet (software IRQ) */
  83. static struct sk_buff *
  84. ieee80211_frag_cache_get(struct ieee80211_device *ieee,
  85. struct ieee80211_hdr_4addr *hdr)
  86. {
  87. struct sk_buff *skb = NULL;
  88. u16 fc = le16_to_cpu(hdr->frame_ctl);
  89. u16 sc = le16_to_cpu(hdr->seq_ctl);
  90. unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
  91. unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
  92. struct ieee80211_frag_entry *entry;
  93. struct ieee80211_hdr_3addrqos *hdr_3addrqos;
  94. struct ieee80211_hdr_4addrqos *hdr_4addrqos;
  95. u8 tid;
  96. if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  97. hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
  98. tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
  99. tid = UP2AC(tid);
  100. tid ++;
  101. } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
  102. hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
  103. tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
  104. tid = UP2AC(tid);
  105. tid ++;
  106. } else {
  107. tid = 0;
  108. }
  109. if (frag == 0) {
  110. /* Reserve enough space to fit maximum frame length */
  111. skb = dev_alloc_skb(ieee->dev->mtu +
  112. sizeof(struct ieee80211_hdr_4addr) +
  113. 8 /* LLC */ +
  114. 2 /* alignment */ +
  115. 8 /* WEP */ +
  116. ETH_ALEN /* WDS */ +
  117. (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
  118. if (skb == NULL)
  119. return NULL;
  120. entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
  121. ieee->frag_next_idx[tid]++;
  122. if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
  123. ieee->frag_next_idx[tid] = 0;
  124. if (entry->skb != NULL)
  125. dev_kfree_skb_any(entry->skb);
  126. entry->first_frag_time = jiffies;
  127. entry->seq = seq;
  128. entry->last_frag = frag;
  129. entry->skb = skb;
  130. memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
  131. memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
  132. } else {
  133. /* received a fragment of a frame for which the head fragment
  134. * should have already been received */
  135. entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
  136. hdr->addr1);
  137. if (entry != NULL) {
  138. entry->last_frag = frag;
  139. skb = entry->skb;
  140. }
  141. }
  142. return skb;
  143. }
  144. /* Called only as a tasklet (software IRQ) */
  145. static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
  146. struct ieee80211_hdr_4addr *hdr)
  147. {
  148. u16 fc = le16_to_cpu(hdr->frame_ctl);
  149. u16 sc = le16_to_cpu(hdr->seq_ctl);
  150. unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
  151. struct ieee80211_frag_entry *entry;
  152. struct ieee80211_hdr_3addrqos *hdr_3addrqos;
  153. struct ieee80211_hdr_4addrqos *hdr_4addrqos;
  154. u8 tid;
  155. if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  156. hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
  157. tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
  158. tid = UP2AC(tid);
  159. tid ++;
  160. } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
  161. hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
  162. tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
  163. tid = UP2AC(tid);
  164. tid ++;
  165. } else {
  166. tid = 0;
  167. }
  168. entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
  169. hdr->addr1);
  170. if (entry == NULL) {
  171. IEEE80211_DEBUG_FRAG(
  172. "could not invalidate fragment cache "
  173. "entry (seq=%u)\n", seq);
  174. return -1;
  175. }
  176. entry->skb = NULL;
  177. return 0;
  178. }
  179. /* ieee80211_rx_frame_mgtmt
  180. *
  181. * Responsible for handling management control frames
  182. *
  183. * Called by ieee80211_rx */
  184. static inline int
  185. ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
  186. struct ieee80211_rx_stats *rx_stats, u16 type,
  187. u16 stype)
  188. {
  189. struct ieee80211_hdr_4addr *hdr;
  190. // cheat the the hdr type
  191. hdr = (struct ieee80211_hdr_4addr *)skb->data;
  192. /* On the struct stats definition there is written that
  193. * this is not mandatory.... but seems that the probe
  194. * response parser uses it
  195. */
  196. rx_stats->len = skb->len;
  197. ieee80211_rx_mgt(ieee, (struct ieee80211_hdr_4addr *)skb->data,
  198. rx_stats);
  199. if((ieee->state == IEEE80211_LINKED)&&(memcmp(hdr->addr3,ieee->current_network.bssid,ETH_ALEN))) {
  200. dev_kfree_skb_any(skb);
  201. return 0;
  202. }
  203. ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
  204. dev_kfree_skb_any(skb);
  205. return 0;
  206. }
  207. /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
  208. /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
  209. static unsigned char rfc1042_header[] =
  210. { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
  211. /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
  212. static unsigned char bridge_tunnel_header[] =
  213. { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
  214. /* No encapsulation header if EtherType < 0x600 (=length) */
  215. /* Called by ieee80211_rx_frame_decrypt */
  216. static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
  217. struct sk_buff *skb, size_t hdrlen)
  218. {
  219. struct net_device *dev = ieee->dev;
  220. u16 fc, ethertype;
  221. struct ieee80211_hdr_4addr *hdr;
  222. u8 *pos;
  223. if (skb->len < 24)
  224. return 0;
  225. hdr = (struct ieee80211_hdr_4addr *)skb->data;
  226. fc = le16_to_cpu(hdr->frame_ctl);
  227. /* check that the frame is unicast frame to us */
  228. if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  229. IEEE80211_FCTL_TODS &&
  230. memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
  231. memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
  232. /* ToDS frame with own addr BSSID and DA */
  233. } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
  234. IEEE80211_FCTL_FROMDS &&
  235. memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
  236. /* FromDS frame with own addr as DA */
  237. } else
  238. return 0;
  239. if (skb->len < 24 + 8)
  240. return 0;
  241. /* check for port access entity Ethernet type */
  242. // pos = skb->data + 24;
  243. pos = skb->data + hdrlen;
  244. ethertype = (pos[6] << 8) | pos[7];
  245. if (ethertype == ETH_P_PAE)
  246. return 1;
  247. return 0;
  248. }
  249. /* Called only as a tasklet (software IRQ), by ieee80211_rx */
  250. static inline int
  251. ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
  252. struct ieee80211_crypt_data *crypt)
  253. {
  254. struct ieee80211_hdr_4addr *hdr;
  255. int res, hdrlen;
  256. if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
  257. return 0;
  258. hdr = (struct ieee80211_hdr_4addr *)skb->data;
  259. hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
  260. #ifdef CONFIG_IEEE80211_CRYPT_TKIP
  261. if (ieee->tkip_countermeasures &&
  262. strcmp(crypt->ops->name, "TKIP") == 0) {
  263. if (net_ratelimit()) {
  264. printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
  265. "received packet from %pM\n",
  266. ieee->dev->name, hdr->addr2);
  267. }
  268. return -1;
  269. }
  270. #endif
  271. atomic_inc(&crypt->refcnt);
  272. res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
  273. atomic_dec(&crypt->refcnt);
  274. if (res < 0) {
  275. IEEE80211_DEBUG_DROP(
  276. "decryption failed (SA=%pM"
  277. ") res=%d\n", hdr->addr2, res);
  278. if (res == -2)
  279. IEEE80211_DEBUG_DROP("Decryption failed ICV "
  280. "mismatch (key %d)\n",
  281. skb->data[hdrlen + 3] >> 6);
  282. ieee->ieee_stats.rx_discards_undecryptable++;
  283. return -1;
  284. }
  285. return res;
  286. }
  287. /* Called only as a tasklet (software IRQ), by ieee80211_rx */
  288. static inline int
  289. ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
  290. int keyidx, struct ieee80211_crypt_data *crypt)
  291. {
  292. struct ieee80211_hdr_4addr *hdr;
  293. int res, hdrlen;
  294. if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
  295. return 0;
  296. hdr = (struct ieee80211_hdr_4addr *)skb->data;
  297. hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
  298. atomic_inc(&crypt->refcnt);
  299. res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
  300. atomic_dec(&crypt->refcnt);
  301. if (res < 0) {
  302. printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
  303. " (SA=%pM keyidx=%d)\n",
  304. ieee->dev->name, hdr->addr2, keyidx);
  305. return -1;
  306. }
  307. return 0;
  308. }
  309. /* this function is stolen from ipw2200 driver*/
  310. #define IEEE_PACKET_RETRY_TIME (5*HZ)
  311. static int is_duplicate_packet(struct ieee80211_device *ieee,
  312. struct ieee80211_hdr_4addr *header)
  313. {
  314. u16 fc = le16_to_cpu(header->frame_ctl);
  315. u16 sc = le16_to_cpu(header->seq_ctl);
  316. u16 seq = WLAN_GET_SEQ_SEQ(sc);
  317. u16 frag = WLAN_GET_SEQ_FRAG(sc);
  318. u16 *last_seq, *last_frag;
  319. unsigned long *last_time;
  320. struct ieee80211_hdr_3addrqos *hdr_3addrqos;
  321. struct ieee80211_hdr_4addrqos *hdr_4addrqos;
  322. u8 tid;
  323. //TO2DS and QoS
  324. if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
  325. hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
  326. tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
  327. tid = UP2AC(tid);
  328. tid ++;
  329. } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
  330. hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)header;
  331. tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
  332. tid = UP2AC(tid);
  333. tid ++;
  334. } else { // no QoS
  335. tid = 0;
  336. }
  337. switch (ieee->iw_mode) {
  338. case IW_MODE_ADHOC:
  339. {
  340. struct list_head *p;
  341. struct ieee_ibss_seq *entry = NULL;
  342. u8 *mac = header->addr2;
  343. int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
  344. //for (pos = (head)->next; pos != (head); pos = pos->next)
  345. __list_for_each(p, &ieee->ibss_mac_hash[index]) {
  346. entry = list_entry(p, struct ieee_ibss_seq, list);
  347. if (!memcmp(entry->mac, mac, ETH_ALEN))
  348. break;
  349. }
  350. // if (memcmp(entry->mac, mac, ETH_ALEN)){
  351. if (p == &ieee->ibss_mac_hash[index]) {
  352. entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
  353. if (!entry) {
  354. printk(KERN_WARNING "Cannot malloc new mac entry\n");
  355. return 0;
  356. }
  357. memcpy(entry->mac, mac, ETH_ALEN);
  358. entry->seq_num[tid] = seq;
  359. entry->frag_num[tid] = frag;
  360. entry->packet_time[tid] = jiffies;
  361. list_add(&entry->list, &ieee->ibss_mac_hash[index]);
  362. return 0;
  363. }
  364. last_seq = &entry->seq_num[tid];
  365. last_frag = &entry->frag_num[tid];
  366. last_time = &entry->packet_time[tid];
  367. break;
  368. }
  369. case IW_MODE_INFRA:
  370. last_seq = &ieee->last_rxseq_num[tid];
  371. last_frag = &ieee->last_rxfrag_num[tid];
  372. last_time = &ieee->last_packet_time[tid];
  373. break;
  374. default:
  375. return 0;
  376. }
  377. // if(tid != 0) {
  378. // printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
  379. // }
  380. if ((*last_seq == seq) &&
  381. time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
  382. if (*last_frag == frag){
  383. //printk(KERN_WARNING "[1] go drop!\n");
  384. goto drop;
  385. }
  386. if (*last_frag + 1 != frag)
  387. /* out-of-order fragment */
  388. //printk(KERN_WARNING "[2] go drop!\n");
  389. goto drop;
  390. } else
  391. *last_seq = seq;
  392. *last_frag = frag;
  393. *last_time = jiffies;
  394. return 0;
  395. drop:
  396. // BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
  397. // printk("DUP\n");
  398. return 1;
  399. }
  400. /* All received frames are sent to this function. @skb contains the frame in
  401. * IEEE 802.11 format, i.e., in the format it was sent over air.
  402. * This function is called only as a tasklet (software IRQ). */
  403. int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
  404. struct ieee80211_rx_stats *rx_stats)
  405. {
  406. struct net_device *dev = ieee->dev;
  407. //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
  408. struct ieee80211_hdr_4addr *hdr;
  409. size_t hdrlen;
  410. u16 fc, type, stype, sc;
  411. struct net_device_stats *stats;
  412. unsigned int frag;
  413. u8 *payload;
  414. u16 ethertype;
  415. u8 dst[ETH_ALEN];
  416. u8 src[ETH_ALEN];
  417. u8 bssid[ETH_ALEN];
  418. struct ieee80211_crypt_data *crypt = NULL;
  419. int keyidx = 0;
  420. // cheat the the hdr type
  421. hdr = (struct ieee80211_hdr_4addr *)skb->data;
  422. stats = &ieee->stats;
  423. if (skb->len < 10) {
  424. printk(KERN_INFO "%s: SKB length < 10\n",
  425. dev->name);
  426. goto rx_dropped;
  427. }
  428. fc = le16_to_cpu(hdr->frame_ctl);
  429. type = WLAN_FC_GET_TYPE(fc);
  430. stype = WLAN_FC_GET_STYPE(fc);
  431. sc = le16_to_cpu(hdr->seq_ctl);
  432. frag = WLAN_GET_SEQ_FRAG(sc);
  433. //YJ,add,080828,for keep alive
  434. if((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS)
  435. {
  436. if(!memcmp(hdr->addr1,dev->dev_addr, ETH_ALEN))
  437. {
  438. ieee->NumRxUnicast++;
  439. }
  440. }
  441. else
  442. {
  443. if(!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
  444. {
  445. ieee->NumRxUnicast++;
  446. }
  447. }
  448. //YJ,add,080828,for keep alive,end
  449. hdrlen = ieee80211_get_hdrlen(fc);
  450. if (ieee->iw_mode == IW_MODE_MONITOR) {
  451. ieee80211_monitor_rx(ieee, skb, rx_stats);
  452. stats->rx_packets++;
  453. stats->rx_bytes += skb->len;
  454. return 1;
  455. }
  456. if (ieee->host_decrypt) {
  457. int idx = 0;
  458. if (skb->len >= hdrlen + 3)
  459. idx = skb->data[hdrlen + 3] >> 6;
  460. crypt = ieee->crypt[idx];
  461. /* allow NULL decrypt to indicate an station specific override
  462. * for default encryption */
  463. if (crypt && (crypt->ops == NULL ||
  464. crypt->ops->decrypt_mpdu == NULL))
  465. crypt = NULL;
  466. if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
  467. /* This seems to be triggered by some (multicast?)
  468. * frames from other than current BSS, so just drop the
  469. * frames silently instead of filling system log with
  470. * these reports. */
  471. IEEE80211_DEBUG_DROP("Decryption failed (not set)"
  472. " (SA=%pM)\n",
  473. hdr->addr2);
  474. ieee->ieee_stats.rx_discards_undecryptable++;
  475. goto rx_dropped;
  476. }
  477. }
  478. if (skb->len < IEEE80211_DATA_HDR3_LEN)
  479. goto rx_dropped;
  480. // if QoS enabled, should check the sequence for each of the AC
  481. if (is_duplicate_packet(ieee, hdr))
  482. goto rx_dropped;
  483. if (type == IEEE80211_FTYPE_MGMT) {
  484. if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
  485. goto rx_dropped;
  486. else
  487. goto rx_exit;
  488. }
  489. /* Data frame - extract src/dst addresses */
  490. switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
  491. case IEEE80211_FCTL_FROMDS:
  492. memcpy(dst, hdr->addr1, ETH_ALEN);
  493. memcpy(src, hdr->addr3, ETH_ALEN);
  494. memcpy(bssid,hdr->addr2,ETH_ALEN);
  495. break;
  496. case IEEE80211_FCTL_TODS:
  497. memcpy(dst, hdr->addr3, ETH_ALEN);
  498. memcpy(src, hdr->addr2, ETH_ALEN);
  499. memcpy(bssid,hdr->addr1,ETH_ALEN);
  500. break;
  501. case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
  502. if (skb->len < IEEE80211_DATA_HDR4_LEN)
  503. goto rx_dropped;
  504. memcpy(dst, hdr->addr3, ETH_ALEN);
  505. memcpy(src, hdr->addr4, ETH_ALEN);
  506. memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
  507. break;
  508. case 0:
  509. memcpy(dst, hdr->addr1, ETH_ALEN);
  510. memcpy(src, hdr->addr2, ETH_ALEN);
  511. memcpy(bssid,hdr->addr3,ETH_ALEN);
  512. break;
  513. }
  514. dev->last_rx = jiffies;
  515. /* Nullfunc frames may have PS-bit set, so they must be passed to
  516. * hostap_handle_sta_rx() before being dropped here. */
  517. if (stype != IEEE80211_STYPE_DATA &&
  518. stype != IEEE80211_STYPE_DATA_CFACK &&
  519. stype != IEEE80211_STYPE_DATA_CFPOLL &&
  520. stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
  521. stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
  522. ) {
  523. if (stype != IEEE80211_STYPE_NULLFUNC)
  524. IEEE80211_DEBUG_DROP(
  525. "RX: dropped data frame "
  526. "with no data (type=0x%02x, "
  527. "subtype=0x%02x, len=%d)\n",
  528. type, stype, skb->len);
  529. goto rx_dropped;
  530. }
  531. if(memcmp(bssid,ieee->current_network.bssid,ETH_ALEN)) {
  532. goto rx_dropped;
  533. }
  534. ieee->NumRxDataInPeriod++;
  535. ieee->NumRxOkTotal++;
  536. /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
  537. if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  538. (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
  539. goto rx_dropped;
  540. hdr = (struct ieee80211_hdr_4addr *)skb->data;
  541. /* skb: hdr + (possibly fragmented) plaintext payload */
  542. // PR: FIXME: hostap has additional conditions in the "if" below:
  543. // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  544. if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
  545. int flen;
  546. struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
  547. IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
  548. if (!frag_skb) {
  549. IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
  550. "Rx cannot get skb from fragment "
  551. "cache (morefrag=%d seq=%u frag=%u)\n",
  552. (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
  553. WLAN_GET_SEQ_SEQ(sc), frag);
  554. goto rx_dropped;
  555. }
  556. flen = skb->len;
  557. if (frag != 0)
  558. flen -= hdrlen;
  559. if (frag_skb->tail + flen > frag_skb->end) {
  560. printk(KERN_WARNING "%s: host decrypted and "
  561. "reassembled frame did not fit skb\n",
  562. dev->name);
  563. ieee80211_frag_cache_invalidate(ieee, hdr);
  564. goto rx_dropped;
  565. }
  566. if (frag == 0) {
  567. /* copy first fragment (including full headers) into
  568. * beginning of the fragment cache skb */
  569. memcpy(skb_put(frag_skb, flen), skb->data, flen);
  570. } else {
  571. /* append frame payload to the end of the fragment
  572. * cache skb */
  573. memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
  574. flen);
  575. }
  576. dev_kfree_skb_any(skb);
  577. skb = NULL;
  578. if (fc & IEEE80211_FCTL_MOREFRAGS) {
  579. /* more fragments expected - leave the skb in fragment
  580. * cache for now; it will be delivered to upper layers
  581. * after all fragments have been received */
  582. goto rx_exit;
  583. }
  584. /* this was the last fragment and the frame will be
  585. * delivered, so remove skb from fragment cache */
  586. skb = frag_skb;
  587. hdr = (struct ieee80211_hdr_4addr *)skb->data;
  588. ieee80211_frag_cache_invalidate(ieee, hdr);
  589. }
  590. /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
  591. * encrypted/authenticated */
  592. if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
  593. ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
  594. goto rx_dropped;
  595. hdr = (struct ieee80211_hdr_4addr *)skb->data;
  596. if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
  597. if (/*ieee->ieee802_1x &&*/
  598. ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  599. #ifdef CONFIG_IEEE80211_DEBUG
  600. /* pass unencrypted EAPOL frames even if encryption is
  601. * configured */
  602. struct eapol *eap = (struct eapol *)(skb->data +
  603. 24);
  604. IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
  605. eap_get_type(eap->type));
  606. #endif
  607. } else {
  608. IEEE80211_DEBUG_DROP(
  609. "encryption configured, but RX "
  610. "frame not encrypted (SA=%pM)\n",
  611. hdr->addr2);
  612. goto rx_dropped;
  613. }
  614. }
  615. #ifdef CONFIG_IEEE80211_DEBUG
  616. if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
  617. ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  618. struct eapol *eap = (struct eapol *)(skb->data +
  619. 24);
  620. IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
  621. eap_get_type(eap->type));
  622. }
  623. #endif
  624. if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
  625. !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  626. IEEE80211_DEBUG_DROP(
  627. "dropped unencrypted RX data "
  628. "frame from %pM"
  629. " (drop_unencrypted=1)\n",
  630. hdr->addr2);
  631. goto rx_dropped;
  632. }
  633. /*
  634. if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
  635. printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
  636. }
  637. */
  638. /* skb: hdr + (possible reassembled) full plaintext payload */
  639. payload = skb->data + hdrlen;
  640. ethertype = (payload[6] << 8) | payload[7];
  641. /* convert hdr + possible LLC headers into Ethernet header */
  642. if (skb->len - hdrlen >= 8 &&
  643. ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
  644. ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
  645. memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
  646. /* remove RFC1042 or Bridge-Tunnel encapsulation and
  647. * replace EtherType */
  648. skb_pull(skb, hdrlen + SNAP_SIZE);
  649. memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  650. memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  651. } else {
  652. u16 len;
  653. /* Leave Ethernet header part of hdr and full payload */
  654. skb_pull(skb, hdrlen);
  655. len = htons(skb->len);
  656. memcpy(skb_push(skb, 2), &len, 2);
  657. memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
  658. memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
  659. }
  660. stats->rx_packets++;
  661. stats->rx_bytes += skb->len;
  662. if (skb) {
  663. skb->protocol = eth_type_trans(skb, dev);
  664. memset(skb->cb, 0, sizeof(skb->cb));
  665. skb->dev = dev;
  666. skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
  667. ieee->last_rx_ps_time = jiffies;
  668. netif_rx(skb);
  669. }
  670. rx_exit:
  671. return 1;
  672. rx_dropped:
  673. stats->rx_dropped++;
  674. /* Returning 0 indicates to caller that we have not handled the SKB--
  675. * so it is still allocated and can be used again by underlying
  676. * hardware as a DMA target */
  677. return 0;
  678. }
  679. #define MGMT_FRAME_FIXED_PART_LENGTH 0x24
  680. static inline int ieee80211_is_ofdm_rate(u8 rate)
  681. {
  682. switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
  683. case IEEE80211_OFDM_RATE_6MB:
  684. case IEEE80211_OFDM_RATE_9MB:
  685. case IEEE80211_OFDM_RATE_12MB:
  686. case IEEE80211_OFDM_RATE_18MB:
  687. case IEEE80211_OFDM_RATE_24MB:
  688. case IEEE80211_OFDM_RATE_36MB:
  689. case IEEE80211_OFDM_RATE_48MB:
  690. case IEEE80211_OFDM_RATE_54MB:
  691. return 1;
  692. }
  693. return 0;
  694. }
  695. static inline int ieee80211_SignalStrengthTranslate(
  696. int CurrSS
  697. )
  698. {
  699. int RetSS;
  700. // Step 1. Scale mapping.
  701. if(CurrSS >= 71 && CurrSS <= 100)
  702. {
  703. RetSS = 90 + ((CurrSS - 70) / 3);
  704. }
  705. else if(CurrSS >= 41 && CurrSS <= 70)
  706. {
  707. RetSS = 78 + ((CurrSS - 40) / 3);
  708. }
  709. else if(CurrSS >= 31 && CurrSS <= 40)
  710. {
  711. RetSS = 66 + (CurrSS - 30);
  712. }
  713. else if(CurrSS >= 21 && CurrSS <= 30)
  714. {
  715. RetSS = 54 + (CurrSS - 20);
  716. }
  717. else if(CurrSS >= 5 && CurrSS <= 20)
  718. {
  719. RetSS = 42 + (((CurrSS - 5) * 2) / 3);
  720. }
  721. else if(CurrSS == 4)
  722. {
  723. RetSS = 36;
  724. }
  725. else if(CurrSS == 3)
  726. {
  727. RetSS = 27;
  728. }
  729. else if(CurrSS == 2)
  730. {
  731. RetSS = 18;
  732. }
  733. else if(CurrSS == 1)
  734. {
  735. RetSS = 9;
  736. }
  737. else
  738. {
  739. RetSS = CurrSS;
  740. }
  741. //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  742. // Step 2. Smoothing.
  743. //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
  744. return RetSS;
  745. }
  746. static inline void ieee80211_extract_country_ie(
  747. struct ieee80211_device *ieee,
  748. struct ieee80211_info_element *info_element,
  749. struct ieee80211_network *network,
  750. u8 * addr2
  751. )
  752. {
  753. if(IS_DOT11D_ENABLE(ieee))
  754. {
  755. if(info_element->len!= 0)
  756. {
  757. memcpy(network->CountryIeBuf, info_element->data, info_element->len);
  758. network->CountryIeLen = info_element->len;
  759. if(!IS_COUNTRY_IE_VALID(ieee))
  760. {
  761. Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
  762. }
  763. }
  764. //
  765. // 070305, rcnjko: I update country IE watch dog here because
  766. // some AP (e.g. Cisco 1242) don't include country IE in their
  767. // probe response frame.
  768. //
  769. if(IS_EQUAL_CIE_SRC(ieee, addr2) )
  770. {
  771. UPDATE_CIE_WATCHDOG(ieee);
  772. }
  773. }
  774. }
  775. int
  776. ieee80211_TranslateToDbm(
  777. unsigned char SignalStrengthIndex // 0-100 index.
  778. )
  779. {
  780. unsigned char SignalPower; // in dBm.
  781. // Translate to dBm (x=0.5y-95).
  782. SignalPower = (int)SignalStrengthIndex * 7 / 10;
  783. SignalPower -= 95;
  784. return SignalPower;
  785. }
  786. inline int ieee80211_network_init(
  787. struct ieee80211_device *ieee,
  788. struct ieee80211_probe_response *beacon,
  789. struct ieee80211_network *network,
  790. struct ieee80211_rx_stats *stats)
  791. {
  792. #ifdef CONFIG_IEEE80211_DEBUG
  793. char rates_str[64];
  794. char *p;
  795. #endif
  796. struct ieee80211_info_element *info_element;
  797. u16 left;
  798. u8 i;
  799. short offset;
  800. u8 curRate = 0,hOpRate = 0,curRate_ex = 0;
  801. /* Pull out fixed field data */
  802. memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
  803. network->capability = beacon->capability;
  804. network->last_scanned = jiffies;
  805. network->time_stamp[0] = beacon->time_stamp[0];
  806. network->time_stamp[1] = beacon->time_stamp[1];
  807. network->beacon_interval = beacon->beacon_interval;
  808. /* Where to pull this? beacon->listen_interval;*/
  809. network->listen_interval = 0x0A;
  810. network->rates_len = network->rates_ex_len = 0;
  811. network->last_associate = 0;
  812. network->ssid_len = 0;
  813. network->flags = 0;
  814. network->atim_window = 0;
  815. network->QoS_Enable = 0;
  816. //by amy 080312
  817. network->HighestOperaRate = 0;
  818. //by amy 080312
  819. network->Turbo_Enable = 0;
  820. network->CountryIeLen = 0;
  821. memset(network->CountryIeBuf, 0, MAX_IE_LEN);
  822. if (stats->freq == IEEE80211_52GHZ_BAND) {
  823. /* for A band (No DS info) */
  824. network->channel = stats->received_channel;
  825. } else
  826. network->flags |= NETWORK_HAS_CCK;
  827. network->wpa_ie_len = 0;
  828. network->rsn_ie_len = 0;
  829. info_element = &beacon->info_element;
  830. left = stats->len - ((void *)info_element - (void *)beacon);
  831. while (left >= sizeof(struct ieee80211_info_element_hdr)) {
  832. if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
  833. IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
  834. info_element->len + sizeof(struct ieee80211_info_element),
  835. left);
  836. return 1;
  837. }
  838. switch (info_element->id) {
  839. case MFIE_TYPE_SSID:
  840. if (ieee80211_is_empty_essid(info_element->data,
  841. info_element->len)) {
  842. network->flags |= NETWORK_EMPTY_ESSID;
  843. break;
  844. }
  845. network->ssid_len = min(info_element->len,
  846. (u8)IW_ESSID_MAX_SIZE);
  847. memcpy(network->ssid, info_element->data, network->ssid_len);
  848. if (network->ssid_len < IW_ESSID_MAX_SIZE)
  849. memset(network->ssid + network->ssid_len, 0,
  850. IW_ESSID_MAX_SIZE - network->ssid_len);
  851. IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
  852. network->ssid, network->ssid_len);
  853. break;
  854. case MFIE_TYPE_RATES:
  855. #ifdef CONFIG_IEEE80211_DEBUG
  856. p = rates_str;
  857. #endif
  858. network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
  859. for (i = 0; i < network->rates_len; i++) {
  860. network->rates[i] = info_element->data[i];
  861. curRate = network->rates[i] & 0x7f;
  862. if( hOpRate < curRate )
  863. hOpRate = curRate;
  864. #ifdef CONFIG_IEEE80211_DEBUG
  865. p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
  866. #endif
  867. if (ieee80211_is_ofdm_rate(info_element->data[i])) {
  868. network->flags |= NETWORK_HAS_OFDM;
  869. if (info_element->data[i] &
  870. IEEE80211_BASIC_RATE_MASK)
  871. network->flags &=
  872. ~NETWORK_HAS_CCK;
  873. }
  874. }
  875. IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
  876. rates_str, network->rates_len);
  877. break;
  878. case MFIE_TYPE_RATES_EX:
  879. #ifdef CONFIG_IEEE80211_DEBUG
  880. p = rates_str;
  881. #endif
  882. network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
  883. for (i = 0; i < network->rates_ex_len; i++) {
  884. network->rates_ex[i] = info_element->data[i];
  885. curRate_ex = network->rates_ex[i] & 0x7f;
  886. if( hOpRate < curRate_ex )
  887. hOpRate = curRate_ex;
  888. #ifdef CONFIG_IEEE80211_DEBUG
  889. p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
  890. #endif
  891. if (ieee80211_is_ofdm_rate(info_element->data[i])) {
  892. network->flags |= NETWORK_HAS_OFDM;
  893. if (info_element->data[i] &
  894. IEEE80211_BASIC_RATE_MASK)
  895. network->flags &=
  896. ~NETWORK_HAS_CCK;
  897. }
  898. }
  899. IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
  900. rates_str, network->rates_ex_len);
  901. break;
  902. case MFIE_TYPE_DS_SET:
  903. IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
  904. info_element->data[0]);
  905. if (stats->freq == IEEE80211_24GHZ_BAND)
  906. network->channel = info_element->data[0];
  907. break;
  908. case MFIE_TYPE_FH_SET:
  909. IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
  910. break;
  911. case MFIE_TYPE_CF_SET:
  912. IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
  913. break;
  914. case MFIE_TYPE_TIM:
  915. if(info_element->len < 4)
  916. break;
  917. network->dtim_period = info_element->data[1];
  918. if(ieee->state != IEEE80211_LINKED)
  919. break;
  920. network->last_dtim_sta_time[0] = jiffies;
  921. network->last_dtim_sta_time[1] = stats->mac_time[1];
  922. network->dtim_data = IEEE80211_DTIM_VALID;
  923. if(info_element->data[0] != 0)
  924. break;
  925. if(info_element->data[2] & 1)
  926. network->dtim_data |= IEEE80211_DTIM_MBCAST;
  927. offset = (info_element->data[2] >> 1)*2;
  928. //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
  929. /* add and modified for ps 2008.1.22 */
  930. if(ieee->assoc_id < 8*offset ||
  931. ieee->assoc_id > 8*(offset + info_element->len -3)) {
  932. break;
  933. }
  934. offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ;
  935. // printk("offset:%x data:%x, ucast:%d\n", offset,
  936. // info_element->data[3+offset] ,
  937. // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
  938. if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) {
  939. network->dtim_data |= IEEE80211_DTIM_UCAST;
  940. }
  941. break;
  942. case MFIE_TYPE_IBSS_SET:
  943. IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
  944. break;
  945. case MFIE_TYPE_CHALLENGE:
  946. IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
  947. break;
  948. case MFIE_TYPE_GENERIC:
  949. //nic is 87B
  950. IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
  951. info_element->len);
  952. if (info_element->len >= 4 &&
  953. info_element->data[0] == 0x00 &&
  954. info_element->data[1] == 0x50 &&
  955. info_element->data[2] == 0xf2 &&
  956. info_element->data[3] == 0x01) {
  957. network->wpa_ie_len = min(info_element->len + 2,
  958. MAX_WPA_IE_LEN);
  959. memcpy(network->wpa_ie, info_element,
  960. network->wpa_ie_len);
  961. }
  962. if (info_element->len == 7 &&
  963. info_element->data[0] == 0x00 &&
  964. info_element->data[1] == 0xe0 &&
  965. info_element->data[2] == 0x4c &&
  966. info_element->data[3] == 0x01 &&
  967. info_element->data[4] == 0x02) {
  968. network->Turbo_Enable = 1;
  969. }
  970. if (1 == stats->nic_type) {//nic 87
  971. break;
  972. }
  973. if (info_element->len >= 5 &&
  974. info_element->data[0] == 0x00 &&
  975. info_element->data[1] == 0x50 &&
  976. info_element->data[2] == 0xf2 &&
  977. info_element->data[3] == 0x02 &&
  978. info_element->data[4] == 0x00) {
  979. //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
  980. //WMM Information Element
  981. network->wmm_info = info_element->data[6];
  982. network->QoS_Enable = 1;
  983. }
  984. if (info_element->len >= 8 &&
  985. info_element->data[0] == 0x00 &&
  986. info_element->data[1] == 0x50 &&
  987. info_element->data[2] == 0xf2 &&
  988. info_element->data[3] == 0x02 &&
  989. info_element->data[4] == 0x01) {
  990. // Not care about version at present.
  991. //WMM Information Element
  992. //printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
  993. network->wmm_info = info_element->data[6];
  994. //WMM Parameter Element
  995. memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
  996. network->QoS_Enable = 1;
  997. }
  998. break;
  999. case MFIE_TYPE_RSN:
  1000. IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
  1001. info_element->len);
  1002. network->rsn_ie_len = min(info_element->len + 2,
  1003. MAX_WPA_IE_LEN);
  1004. memcpy(network->rsn_ie, info_element,
  1005. network->rsn_ie_len);
  1006. break;
  1007. case MFIE_TYPE_COUNTRY:
  1008. IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
  1009. info_element->len);
  1010. // printk("=====>Receive <%s> Country IE\n",network->ssid);
  1011. ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
  1012. break;
  1013. default:
  1014. IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
  1015. info_element->id);
  1016. break;
  1017. }
  1018. left -= sizeof(struct ieee80211_info_element_hdr) +
  1019. info_element->len;
  1020. info_element = (struct ieee80211_info_element *)
  1021. &info_element->data[info_element->len];
  1022. }
  1023. //by amy 080312
  1024. network->HighestOperaRate = hOpRate;
  1025. //by amy 080312
  1026. network->mode = 0;
  1027. if (stats->freq == IEEE80211_52GHZ_BAND)
  1028. network->mode = IEEE_A;
  1029. else {
  1030. if (network->flags & NETWORK_HAS_OFDM)
  1031. network->mode |= IEEE_G;
  1032. if (network->flags & NETWORK_HAS_CCK)
  1033. network->mode |= IEEE_B;
  1034. }
  1035. if (network->mode == 0) {
  1036. IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
  1037. "network.\n",
  1038. escape_essid(network->ssid,
  1039. network->ssid_len),
  1040. network->bssid);
  1041. return 1;
  1042. }
  1043. if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
  1044. network->flags |= NETWORK_EMPTY_ESSID;
  1045. stats->signal = ieee80211_TranslateToDbm(stats->signalstrength);
  1046. //stats->noise = stats->signal - stats->noise;
  1047. stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25;
  1048. memcpy(&network->stats, stats, sizeof(network->stats));
  1049. return 0;
  1050. }
  1051. static inline int is_same_network(struct ieee80211_network *src,
  1052. struct ieee80211_network *dst,
  1053. struct ieee80211_device * ieee)
  1054. {
  1055. /* A network is only a duplicate if the channel, BSSID, ESSID
  1056. * and the capability field (in particular IBSS and BSS) all match.
  1057. * We treat all <hidden> with the same BSSID and channel
  1058. * as one network */
  1059. return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
  1060. //((src->ssid_len == dst->ssid_len) &&
  1061. (src->channel == dst->channel) &&
  1062. !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
  1063. (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
  1064. //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
  1065. ((src->capability & WLAN_CAPABILITY_IBSS) ==
  1066. (dst->capability & WLAN_CAPABILITY_IBSS)) &&
  1067. ((src->capability & WLAN_CAPABILITY_BSS) ==
  1068. (dst->capability & WLAN_CAPABILITY_BSS)));
  1069. }
  1070. inline void update_network(struct ieee80211_network *dst,
  1071. struct ieee80211_network *src)
  1072. {
  1073. unsigned char quality = src->stats.signalstrength;
  1074. unsigned char signal = 0;
  1075. unsigned char noise = 0;
  1076. if(dst->stats.signalstrength > 0) {
  1077. quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
  1078. }
  1079. signal = ieee80211_TranslateToDbm(quality);
  1080. //noise = signal - src->stats.noise;
  1081. if(dst->stats.noise > 0)
  1082. noise = (dst->stats.noise * 5 + src->stats.noise)/6;
  1083. //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
  1084. // printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
  1085. memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
  1086. dst->stats.signalstrength = quality;
  1087. dst->stats.signal = signal;
  1088. // printk("==================>stats.signal is %d\n",dst->stats.signal);
  1089. dst->stats.noise = noise;
  1090. dst->capability = src->capability;
  1091. memcpy(dst->rates, src->rates, src->rates_len);
  1092. dst->rates_len = src->rates_len;
  1093. memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
  1094. dst->rates_ex_len = src->rates_ex_len;
  1095. dst->HighestOperaRate= src->HighestOperaRate;
  1096. //printk("==========>in %s: src->ssid is %s,chan is %d\n",__func__,src->ssid,src->channel);
  1097. //YJ,add,080819,for hidden ap
  1098. if(src->ssid_len > 0)
  1099. {
  1100. //if(src->ssid_len == 13)
  1101. // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
  1102. memset(dst->ssid, 0, dst->ssid_len);
  1103. dst->ssid_len = src->ssid_len;
  1104. memcpy(dst->ssid, src->ssid, src->ssid_len);
  1105. }
  1106. //YJ,add,080819,for hidden ap,end
  1107. dst->channel = src->channel;
  1108. dst->mode = src->mode;
  1109. dst->flags = src->flags;
  1110. dst->time_stamp[0] = src->time_stamp[0];
  1111. dst->time_stamp[1] = src->time_stamp[1];
  1112. dst->beacon_interval = src->beacon_interval;
  1113. dst->listen_interval = src->listen_interval;
  1114. dst->atim_window = src->atim_window;
  1115. dst->dtim_period = src->dtim_period;
  1116. dst->dtim_data = src->dtim_data;
  1117. dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
  1118. dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
  1119. // printk("update:%s, dtim_period:%x, dtim_data:%x\n", src->ssid, src->dtim_period, src->dtim_data);
  1120. memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
  1121. dst->wpa_ie_len = src->wpa_ie_len;
  1122. memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
  1123. dst->rsn_ie_len = src->rsn_ie_len;
  1124. dst->last_scanned = jiffies;
  1125. /* dst->last_associate is not overwritten */
  1126. // disable QoS process now, added by David 2006/7/25
  1127. #if 1
  1128. dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
  1129. /*
  1130. if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
  1131. memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
  1132. }
  1133. */
  1134. if(src->wmm_param[0].ac_aci_acm_aifsn|| \
  1135. src->wmm_param[1].ac_aci_acm_aifsn|| \
  1136. src->wmm_param[2].ac_aci_acm_aifsn|| \
  1137. src->wmm_param[3].ac_aci_acm_aifsn) {
  1138. memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
  1139. }
  1140. dst->QoS_Enable = src->QoS_Enable;
  1141. #else
  1142. dst->QoS_Enable = 1;//for Rtl8187 simulation
  1143. #endif
  1144. dst->SignalStrength = src->SignalStrength;
  1145. dst->Turbo_Enable = src->Turbo_Enable;
  1146. dst->CountryIeLen = src->CountryIeLen;
  1147. memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
  1148. }
  1149. inline void ieee80211_process_probe_response(
  1150. struct ieee80211_device *ieee,
  1151. struct ieee80211_probe_response *beacon,
  1152. struct ieee80211_rx_stats *stats)
  1153. {
  1154. struct ieee80211_network network;
  1155. struct ieee80211_network *target;
  1156. struct ieee80211_network *oldest = NULL;
  1157. #ifdef CONFIG_IEEE80211_DEBUG
  1158. struct ieee80211_info_element *info_element = &beacon->info_element;
  1159. #endif
  1160. unsigned long flags;
  1161. short renew;
  1162. u8 wmm_info;
  1163. u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0; //YJ,add,080819,for hidden ap
  1164. memset(&network, 0, sizeof(struct ieee80211_network));
  1165. IEEE80211_DEBUG_SCAN(
  1166. "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
  1167. escape_essid(info_element->data, info_element->len),
  1168. beacon->header.addr3,
  1169. (beacon->capability & (1<<0xf)) ? '1' : '0',
  1170. (beacon->capability & (1<<0xe)) ? '1' : '0',
  1171. (beacon->capability & (1<<0xd)) ? '1' : '0',
  1172. (beacon->capability & (1<<0xc)) ? '1' : '0',
  1173. (beacon->capability & (1<<0xb)) ? '1' : '0',
  1174. (beacon->capability & (1<<0xa)) ? '1' : '0',
  1175. (beacon->capability & (1<<0x9)) ? '1' : '0',
  1176. (beacon->capability & (1<<0x8)) ? '1' : '0',
  1177. (beacon->capability & (1<<0x7)) ? '1' : '0',
  1178. (beacon->capability & (1<<0x6)) ? '1' : '0',
  1179. (beacon->capability & (1<<0x5)) ? '1' : '0',
  1180. (beacon->capability & (1<<0x4)) ? '1' : '0',
  1181. (beacon->capability & (1<<0x3)) ? '1' : '0',
  1182. (beacon->capability & (1<<0x2)) ? '1' : '0',
  1183. (beacon->capability & (1<<0x1)) ? '1' : '0',
  1184. (beacon->capability & (1<<0x0)) ? '1' : '0');
  1185. if (ieee80211_network_init(ieee, beacon, &network, stats)) {
  1186. IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
  1187. escape_essid(info_element->data,
  1188. info_element->len),
  1189. beacon->header.addr3,
  1190. WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  1191. IEEE80211_STYPE_PROBE_RESP ?
  1192. "PROBE RESPONSE" : "BEACON");
  1193. return;
  1194. }
  1195. // For Asus EeePc request,
  1196. // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
  1197. // wireless adapter should follow the country code.
  1198. // (2) If there is no any country code in beacon,
  1199. // then wireless adapter should do active scan from ch1~11 and
  1200. // passive scan from ch12~14
  1201. if(ieee->bGlobalDomain)
  1202. {
  1203. if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
  1204. {
  1205. // Case 1: Country code
  1206. if(IS_COUNTRY_IE_VALID(ieee) )
  1207. {
  1208. if( !IsLegalChannel(ieee, network.channel) )
  1209. {
  1210. printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
  1211. return;
  1212. }
  1213. }
  1214. // Case 2: No any country code.
  1215. else
  1216. {
  1217. // Filter over channel ch12~14
  1218. if(network.channel > 11)
  1219. {
  1220. printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
  1221. return;
  1222. }
  1223. }
  1224. }
  1225. else
  1226. {
  1227. // Case 1: Country code
  1228. if(IS_COUNTRY_IE_VALID(ieee) )
  1229. {
  1230. if( !IsLegalChannel(ieee, network.channel) )
  1231. {
  1232. printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
  1233. return;
  1234. }
  1235. }
  1236. // Case 2: No any country code.
  1237. else
  1238. {
  1239. // Filter over channel ch12~14
  1240. if(network.channel > 14)
  1241. {
  1242. printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
  1243. return;
  1244. }
  1245. }
  1246. }
  1247. }
  1248. /* The network parsed correctly -- so now we scan our known networks
  1249. * to see if we can find it in our list.
  1250. *
  1251. * NOTE: This search is definitely not optimized. Once its doing
  1252. * the "right thing" we'll optimize it for efficiency if
  1253. * necessary */
  1254. /* Search for this entry in the list and update it if it is
  1255. * already there. */
  1256. spin_lock_irqsave(&ieee->lock, flags);
  1257. if(is_same_network(&ieee->current_network, &network, ieee)) {
  1258. wmm_info = ieee->current_network.wmm_info;
  1259. //YJ,add,080819,for hidden ap
  1260. if(is_beacon == 0)
  1261. network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
  1262. else if(ieee->state == IEEE80211_LINKED)
  1263. ieee->NumRxBcnInPeriod++;
  1264. //YJ,add,080819,for hidden ap,end
  1265. //printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid);
  1266. update_network(&ieee->current_network, &network);
  1267. }
  1268. list_for_each_entry(target, &ieee->network_list, list) {
  1269. if (is_same_network(target, &network, ieee))
  1270. break;
  1271. if ((oldest == NULL) ||
  1272. (target->last_scanned < oldest->last_scanned))
  1273. oldest = target;
  1274. }
  1275. /* If we didn't find a match, then get a new network slot to initialize
  1276. * with this beacon's information */
  1277. if (&target->list == &ieee->network_list) {
  1278. if (list_empty(&ieee->network_free_list)) {
  1279. /* If there are no more slots, expire the oldest */
  1280. list_del(&oldest->list);
  1281. target = oldest;
  1282. IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
  1283. "network list.\n",
  1284. escape_essid(target->ssid,
  1285. target->ssid_len),
  1286. target->bssid);
  1287. } else {
  1288. /* Otherwise just pull from the free list */
  1289. target = list_entry(ieee->network_free_list.next,
  1290. struct ieee80211_network, list);
  1291. list_del(ieee->network_free_list.next);
  1292. }
  1293. #ifdef CONFIG_IEEE80211_DEBUG
  1294. IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
  1295. escape_essid(network.ssid,
  1296. network.ssid_len),
  1297. network.bssid,
  1298. WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  1299. IEEE80211_STYPE_PROBE_RESP ?
  1300. "PROBE RESPONSE" : "BEACON");
  1301. #endif
  1302. memcpy(target, &network, sizeof(*target));
  1303. list_add_tail(&target->list, &ieee->network_list);
  1304. } else {
  1305. IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
  1306. escape_essid(target->ssid,
  1307. target->ssid_len),
  1308. target->bssid,
  1309. WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
  1310. IEEE80211_STYPE_PROBE_RESP ?
  1311. "PROBE RESPONSE" : "BEACON");
  1312. /* we have an entry and we are going to update it. But this entry may
  1313. * be already expired. In this case we do the same as we found a new
  1314. * net and call the new_net handler
  1315. */
  1316. renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
  1317. //YJ,add,080819,for hidden ap
  1318. if(is_beacon == 0)
  1319. network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
  1320. //if(strncmp(network.ssid, "linksys-c",9) == 0)
  1321. // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
  1322. if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
  1323. && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
  1324. ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
  1325. renew = 1;
  1326. //YJ,add,080819,for hidden ap,end
  1327. update_network(target, &network);
  1328. }
  1329. spin_unlock_irqrestore(&ieee->lock, flags);
  1330. }
  1331. void ieee80211_rx_mgt(struct ieee80211_device *ieee,
  1332. struct ieee80211_hdr_4addr *header,
  1333. struct ieee80211_rx_stats *stats)
  1334. {
  1335. switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
  1336. case IEEE80211_STYPE_BEACON:
  1337. IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
  1338. WLAN_FC_GET_STYPE(header->frame_ctl));
  1339. IEEE80211_DEBUG_SCAN("Beacon\n");
  1340. ieee80211_process_probe_response(
  1341. ieee, (struct ieee80211_probe_response *)header, stats);
  1342. break;
  1343. case IEEE80211_STYPE_PROBE_RESP:
  1344. IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
  1345. WLAN_FC_GET_STYPE(header->frame_ctl));
  1346. IEEE80211_DEBUG_SCAN("Probe response\n");
  1347. ieee80211_process_probe_response(
  1348. ieee, (struct ieee80211_probe_response *)header, stats);
  1349. break;
  1350. }
  1351. }