From: wlanfae <wlanfae@realtek.com>
[deliverable/linux.git] / drivers / staging / rtl8192e / rtllib_rx.c
CommitLineData
94a79942
LF
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
16 Few modifications for Realtek's Wi-Fi drivers by
17 Andrea Merello <andreamrl@tiscali.it>
18
19 A special thanks goes to Realtek for their support !
20
21******************************************************************************/
22
23
24#include <linux/compiler.h>
25#include <linux/errno.h>
26#include <linux/if_arp.h>
27#include <linux/in6.h>
28#include <linux/in.h>
29#include <linux/ip.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/netdevice.h>
33#include <linux/pci.h>
34#include <linux/proc_fs.h>
35#include <linux/skbuff.h>
36#include <linux/slab.h>
37#include <linux/tcp.h>
38#include <linux/types.h>
39#include <linux/version.h>
40#include <linux/wireless.h>
41#include <linux/etherdevice.h>
42#include <asm/uaccess.h>
43#include <linux/ctype.h>
44
45#include "rtllib.h"
46#ifdef ENABLE_DOT11D
47#include "dot11d.h"
48#endif
49
50#if defined(RTLLIB_RADIOTAP) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
51#include <net/ieee80211_radiotap.h>
52#endif
53
54#if defined CONFIG_CFG_80211
55#include <linux/crc32.h>
56
57struct ieee80211_channel *rtllib_get_channel(struct wiphy *wiphy,
58 int freq)
59{
60 enum ieee80211_band band;
61 struct ieee80211_supported_band *sband;
62 int i;
63
64 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
65 sband = wiphy->bands[band];
66
67 if (!sband)
68 continue;
69
70 for (i = 0; i < sband->n_channels; i++) {
71 if (sband->channels[i].center_freq == freq)
72 return &sband->channels[i];
73 }
74 }
75
76 return NULL;
77}
78
79int rtllib_channel_to_frequency(int chan)
80{
81 if (chan < 14)
82 return 2407 + chan * 5;
83
84 if (chan == 14)
85 return 2484;
86
87 /* FIXME: 802.11j 17.3.8.3.2 */
88 return (chan + 1000) * 5;
89}
90
91u32 rtllib_parse_elems_crc(u8 *start, size_t len,
92 struct ieee802_11_elems *elems,
93 u64 filter, u32 crc)
94{
95 size_t left = len;
96 u8 *pos = start;
97 bool calc_crc = filter != 0;
98
99 memset(elems, 0, sizeof(*elems));
100 elems->ie_start = start;
101 elems->total_len = len;
102
103 while (left >= 2) {
104 u8 id, elen;
105
106 id = *pos++;
107 elen = *pos++;
108 left -= 2;
109
110 if (elen > left)
111 break;
112
113 if (calc_crc && id < 64 && (filter & BIT(id)))
114 crc = crc32_be(crc, pos - 2, elen + 2);
115
116 switch (id) {
117 case WLAN_EID_SSID:
118 elems->ssid = pos;
119 elems->ssid_len = elen;
120 break;
121 case WLAN_EID_SUPP_RATES:
122 elems->supp_rates = pos;
123 elems->supp_rates_len = elen;
124 break;
125 case WLAN_EID_FH_PARAMS:
126 elems->fh_params = pos;
127 elems->fh_params_len = elen;
128 break;
129 case WLAN_EID_DS_PARAMS:
130 elems->ds_params = pos;
131 elems->ds_params_len = elen;
132 break;
133 case WLAN_EID_CF_PARAMS:
134 elems->cf_params = pos;
135 elems->cf_params_len = elen;
136 break;
137 case WLAN_EID_TIM:
138 if (elen >= sizeof(struct ieee80211_tim_ie)) {
139 elems->tim = (void *)pos;
140 elems->tim_len = elen;
141 }
142 break;
143 case WLAN_EID_IBSS_PARAMS:
144 elems->ibss_params = pos;
145 elems->ibss_params_len = elen;
146 break;
147 case WLAN_EID_CHALLENGE:
148 elems->challenge = pos;
149 elems->challenge_len = elen;
150 break;
151 case WLAN_EID_VENDOR_SPECIFIC:
152 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
153 pos[2] == 0xf2) {
154 /* Microsoft OUI (00:50:F2) */
155
156 if (calc_crc)
157 crc = crc32_be(crc, pos - 2, elen + 2);
158
159 if (pos[3] == 1) {
160 /* OUI Type 1 - WPA IE */
161 elems->wpa = pos;
162 elems->wpa_len = elen;
163 } else if (elen >= 5 && pos[3] == 2) {
164 /* OUI Type 2 - WMM IE */
165 if (pos[4] == 0) {
166 elems->wmm_info = pos;
167 elems->wmm_info_len = elen;
168 } else if (pos[4] == 1) {
169 elems->wmm_param = pos;
170 elems->wmm_param_len = elen;
171 }
172 }
173 }
174 break;
175 case WLAN_EID_RSN:
176 elems->rsn = pos;
177 elems->rsn_len = elen;
178 break;
179 case WLAN_EID_ERP_INFO:
180 elems->erp_info = pos;
181 elems->erp_info_len = elen;
182 break;
183 case WLAN_EID_EXT_SUPP_RATES:
184 elems->ext_supp_rates = pos;
185 elems->ext_supp_rates_len = elen;
186 break;
187 case WLAN_EID_HT_CAPABILITY:
188 if (elen >= sizeof(struct ieee80211_ht_cap))
189 elems->ht_cap_elem = (void *)pos;
190 break;
191 case WLAN_EID_HT_INFORMATION:
192 if (elen >= sizeof(struct ieee80211_ht_info))
193 elems->ht_info_elem = (void *)pos;
194 break;
195 case WLAN_EID_MESH_ID:
196 elems->mesh_id = pos;
197 elems->mesh_id_len = elen;
198 break;
199 case WLAN_EID_MESH_CONFIG:
200 elems->mesh_config = pos;
201 elems->mesh_config_len = elen;
202 break;
203 case WLAN_EID_PEER_LINK:
204 elems->peer_link = pos;
205 elems->peer_link_len = elen;
206 break;
207 case WLAN_EID_PREQ:
208 elems->preq = pos;
209 elems->preq_len = elen;
210 break;
211 case WLAN_EID_PREP:
212 elems->prep = pos;
213 elems->prep_len = elen;
214 break;
215 case WLAN_EID_PERR:
216 elems->perr = pos;
217 elems->perr_len = elen;
218 break;
219 case WLAN_EID_CHANNEL_SWITCH:
220 elems->ch_switch_elem = pos;
221 elems->ch_switch_elem_len = elen;
222 break;
223 case WLAN_EID_QUIET:
224 if (!elems->quiet_elem) {
225 elems->quiet_elem = pos;
226 elems->quiet_elem_len = elen;
227 }
228 elems->num_of_quiet_elem++;
229 break;
230 case WLAN_EID_COUNTRY:
231 elems->country_elem = pos;
232 elems->country_elem_len = elen;
233 break;
234 case WLAN_EID_PWR_CONSTRAINT:
235 elems->pwr_constr_elem = pos;
236 elems->pwr_constr_elem_len = elen;
237 break;
238 case WLAN_EID_TIMEOUT_INTERVAL:
239 elems->timeout_int = pos;
240 elems->timeout_int_len = elen;
241 break;
242 default:
243 break;
244 }
245
246 left -= elen;
247 pos += elen;
248 }
249
250 return crc;
251}
252
253void rtllib_parse_elems(u8 *start, size_t len,
254 struct ieee802_11_elems *elems)
255{
256 rtllib_parse_elems_crc(start, len, elems, 0, 0);
257}
258
259void ieee80211_scan_rx(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_status)
260{
261 struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ;
262 struct ieee80211_mgmt *mgmt;
263 struct ieee80211_bss *bss;
264 u8 *elements;
265 struct ieee80211_channel *channel;
266 size_t baselen;
267 int freq;
268 __le16 fc;
269 bool presp, beacon = false;
270 struct ieee802_11_elems elems;
271 s32 signal = 0;
272
273 if (skb->len < 2)
274 return;
275
276 mgmt = (struct ieee80211_mgmt *) skb->data;
277 fc = mgmt->frame_control;
278
279 if (skb->len < 24)
280 return;
281
282 presp = (WLAN_FC_GET_STYPE(header->frame_ctl) == RTLLIB_STYPE_PROBE_RESP);
283 if (presp) {
284 /* ignore ProbeResp to foreign address */
285 if (memcmp(mgmt->da, ieee->dev->dev_addr, ETH_ALEN))
286 return ;;
287
288 presp = true;
289 elements = mgmt->u.probe_resp.variable;
290 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
291 } else {
292 beacon = (WLAN_FC_GET_STYPE(header->frame_ctl) == RTLLIB_STYPE_BEACON);
293 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
294 elements = mgmt->u.beacon.variable;
295 }
296
297 if (!presp && !beacon)
298 return;
299
300 if (baselen > skb->len)
301 return;
302
303 rtllib_parse_elems(elements, skb->len - baselen, &elems);
304
305 if (elems.ds_params && elems.ds_params_len == 1)
306 freq = rtllib_channel_to_frequency(elems.ds_params[0]);
307 else
308 return;
309
310 channel = rtllib_get_channel(ieee->wdev.wiphy, freq);
311
312 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
313 return;
314
315 signal = rx_status->signal * 100;
316
317 bss = (void *)cfg80211_inform_bss_frame(ieee->wdev.wiphy, channel,
318 mgmt, skb->len, signal, GFP_ATOMIC);
319
320 return;
321}
322#endif
323
324
325#if defined(RTLLIB_RADIOTAP) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
326static int rtllib_rx_radiotap_len(struct rtllib_device *ieee, struct rtllib_rx_stats *rx_status)
327{
328 int len;
329
330 /* always present fields */
331 len = sizeof(struct ieee80211_radiotap_header) +
332 8 + /* TSFT */
333 1 + /* FLAGS */
334 1 + /* RATE */
335 2 + /* CHANNEL IN MHZ */
336 2 + /* CHANNEL BITFIELD */
337 1 + /* HW SIGNAL DBM */
338 1 + /* HW NOISE DBM */
339 1; /* ANTENNA NUMBER */
340
341
342 if (len & 1) /* padding for RX_FLAGS if necessary */
343 len++;
344
345 /* make sure radiotap starts at a naturally aligned address */
346 if (len % 8)
347 len = roundup(len, 8);
348
349 return len;
350}
351
352static void rtllib_add_rx_radiotap_header(struct rtllib_device *ieee,
353 struct sk_buff *skb, int rtap_len, struct rtllib_rx_stats *rx_status)
354{
355 struct ieee80211_radiotap_header *rthdr;
356 unsigned char *pos;
357 printk("add header!\n");
358 rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len);
359 memset(rthdr, 0, rtap_len);
360
361 rthdr->it_version = PKTHDR_RADIOTAP_VERSION;
362 rthdr->it_pad = 0;
363 rthdr->it_len = cpu_to_le16(rtap_len);
364 /* radiotap header, set always present flags */
365 rthdr->it_present = cpu_to_le32(
366 (1 << IEEE80211_RADIOTAP_TSFT) |
367 (1 << IEEE80211_RADIOTAP_FLAGS) |
368 (1 << IEEE80211_RADIOTAP_RATE) |
369 (1 << IEEE80211_RADIOTAP_CHANNEL) |
370 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
371 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
372 (1 << IEEE80211_RADIOTAP_ANTENNA));
373
374 pos = (unsigned char *)(rthdr+1);
375 /* the order of the following fields is important */
376 /* IEEE80211_RADIOTAP_TSFT */
377 *(__le64 *)pos = cpu_to_le64(rx_status->TimeStampLow);
378 pos += 8;
379
380 /* IEEE80211_RADIOTAP_FLAGS */
381 if (rx_status->bCRC)
382 *pos |= IEEE80211_RADIOTAP_F_BADFCS;
383 if (rx_status->bShortPreamble)
384 *pos |= IEEE80211_RADIOTAP_F_SHORTPRE;
385 pos++;
386
387 /* IEEE80211_RADIOTAP_RATE */
388 *pos = rx_status->rate / 5;
389 pos++;
390
391 /* IEEE80211_RADIOTAP_CHANNEL */
392 *(__le16 *)pos = cpu_to_le16(rx_status->received_channel);
393 pos += 2;
394 pos += 2;
395
396
397 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
398 *pos = rx_status->RxPower;
399 pos++;
400
401 /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
402 *pos = rx_status->noise;
403 pos++;
404
405 /* IEEE80211_RADIOTAP_ANTENNA */
406 *pos = rx_status->Antenna;
407 pos++;
408
409 /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */
410
411 /* IEEE80211_RADIOTAP_RX_FLAGS */
412 /* ensure 2 byte alignment for the 2 byte field as required */
413}
414#endif
415
416static inline void rtllib_monitor_rx(struct rtllib_device *ieee,
417 struct sk_buff *skb,struct rtllib_rx_stats *rx_status,
418 size_t hdr_length)
419{
420
421#if defined(RTLLIB_RADIOTAP) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
422 int needed_headroom = 0;
423 struct sk_buff *radiotap_skb;
424
425 needed_headroom = rtllib_rx_radiotap_len(ieee, rx_status);
426 printk("needed_headroom = %d\n", needed_headroom);
427 radiotap_skb = skb_copy_expand(skb, needed_headroom, 0, GFP_ATOMIC);
428 dev_kfree_skb(skb);
429 if (!radiotap_skb) {
430 return;
431 }
432
433 rtllib_add_rx_radiotap_header(ieee, radiotap_skb, needed_headroom, rx_status);
434 radiotap_skb->dev = ieee->dev;
435#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
436 skb_reset_mac_header(radiotap_skb);
437#else
438 radiotap_skb->mac.raw = radiotap_skb->data;
439#endif
440 radiotap_skb->ip_summed = CHECKSUM_UNNECESSARY;
441 radiotap_skb->pkt_type = PACKET_OTHERHOST;
442 radiotap_skb->protocol = htons(ETH_P_802_2);
443 memset(radiotap_skb->cb, 0, sizeof(radiotap_skb->cb));
444 netif_rx(radiotap_skb);
445#else
446 skb->dev = ieee->dev;
447#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
448 skb_reset_mac_header(skb);
449#else
450 skb->mac.raw = skb->data;
451#endif
452 skb_pull(skb, hdr_length);
453 skb->pkt_type = PACKET_OTHERHOST;
454 skb->protocol = __constant_htons(ETH_P_80211_RAW);
455 memset(skb->cb, 0, sizeof(skb->cb));
456 netif_rx(skb);
457#endif
458}
459
460/* Called only as a tasklet (software IRQ) */
461static struct rtllib_frag_entry *
462rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq,
463 unsigned int frag, u8 tid,u8 *src, u8 *dst)
464{
465 struct rtllib_frag_entry *entry;
466 int i;
467
468 for (i = 0; i < RTLLIB_FRAG_CACHE_LEN; i++) {
469 entry = &ieee->frag_cache[tid][i];
470 if (entry->skb != NULL &&
471 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
472 RTLLIB_DEBUG_FRAG(
473 "expiring fragment cache entry "
474 "seq=%u last_frag=%u\n",
475 entry->seq, entry->last_frag);
476 dev_kfree_skb_any(entry->skb);
477 entry->skb = NULL;
478 }
479
480 if (entry->skb != NULL && entry->seq == seq &&
481 (entry->last_frag + 1 == frag || frag == -1) &&
482 memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
483 memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
484 return entry;
485 }
486
487 return NULL;
488}
489
490/* Called only as a tasklet (software IRQ) */
491static struct sk_buff *
492rtllib_frag_cache_get(struct rtllib_device *ieee,
493 struct rtllib_hdr_4addr *hdr)
494{
495 struct sk_buff *skb = NULL;
496 u16 fc = le16_to_cpu(hdr->frame_ctl);
497 u16 sc = le16_to_cpu(hdr->seq_ctl);
498 unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
499 unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
500 struct rtllib_frag_entry *entry;
501 struct rtllib_hdr_3addrqos *hdr_3addrqos;
502 struct rtllib_hdr_4addrqos *hdr_4addrqos;
503 u8 tid;
504
505 if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS)&&RTLLIB_QOS_HAS_SEQ(fc)) {
506 hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr;
507 tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID;
508 tid = UP2AC(tid);
509 tid ++;
510 } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
511 hdr_3addrqos = (struct rtllib_hdr_3addrqos *)hdr;
512 tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID;
513 tid = UP2AC(tid);
514 tid ++;
515 } else {
516 tid = 0;
517 }
518
519 if (frag == 0) {
520 /* Reserve enough space to fit maximum frame length */
521 skb = dev_alloc_skb(ieee->dev->mtu +
522 sizeof(struct rtllib_hdr_4addr) +
523 8 /* LLC */ +
524 2 /* alignment */ +
525 8 /* WEP */ +
526 ETH_ALEN /* WDS */ +
527 (RTLLIB_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
528 if (skb == NULL)
529 return NULL;
530
531 entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
532 ieee->frag_next_idx[tid]++;
533 if (ieee->frag_next_idx[tid] >= RTLLIB_FRAG_CACHE_LEN)
534 ieee->frag_next_idx[tid] = 0;
535
536 if (entry->skb != NULL)
537 dev_kfree_skb_any(entry->skb);
538
539 entry->first_frag_time = jiffies;
540 entry->seq = seq;
541 entry->last_frag = frag;
542 entry->skb = skb;
543 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
544 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
545 } else {
546 /* received a fragment of a frame for which the head fragment
547 * should have already been received */
548 entry = rtllib_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
549 hdr->addr1);
550 if (entry != NULL) {
551 entry->last_frag = frag;
552 skb = entry->skb;
553 }
554 }
555
556 return skb;
557}
558
559
560/* Called only as a tasklet (software IRQ) */
561static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee,
562 struct rtllib_hdr_4addr *hdr)
563{
564 u16 fc = le16_to_cpu(hdr->frame_ctl);
565 u16 sc = le16_to_cpu(hdr->seq_ctl);
566 unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
567 struct rtllib_frag_entry *entry;
568 struct rtllib_hdr_3addrqos *hdr_3addrqos;
569 struct rtllib_hdr_4addrqos *hdr_4addrqos;
570 u8 tid;
571
572 if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS)&&RTLLIB_QOS_HAS_SEQ(fc)) {
573 hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr;
574 tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID;
575 tid = UP2AC(tid);
576 tid ++;
577 } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
578 hdr_3addrqos = (struct rtllib_hdr_3addrqos *)hdr;
579 tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID;
580 tid = UP2AC(tid);
581 tid ++;
582 } else {
583 tid = 0;
584 }
585
586 entry = rtllib_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
587 hdr->addr1);
588
589 if (entry == NULL) {
590 RTLLIB_DEBUG_FRAG(
591 "could not invalidate fragment cache "
592 "entry (seq=%u)\n", seq);
593 return -1;
594 }
595
596 entry->skb = NULL;
597 return 0;
598}
599
600
601
602/* rtllib_rx_frame_mgtmt
603 *
604 * Responsible for handling management control frames
605 *
606 * Called by rtllib_rx */
607static inline int
608rtllib_rx_frame_mgmt(struct rtllib_device *ieee, struct sk_buff *skb,
609 struct rtllib_rx_stats *rx_stats, u16 type,
610 u16 stype)
611{
612 /* On the struct stats definition there is written that
613 * this is not mandatory.... but seems that the probe
614 * response parser uses it
615 */
616 struct rtllib_hdr_3addr * hdr = (struct rtllib_hdr_3addr *)skb->data;
617
618 rx_stats->len = skb->len;
619 rtllib_rx_mgt(ieee,skb,rx_stats);
620 if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN))) {
621 dev_kfree_skb_any(skb);
622 return 0;
623 }
624 rtllib_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
625
626 dev_kfree_skb_any(skb);
627
628 return 0;
629
630#ifdef NOT_YET
631 if (ieee->iw_mode == IW_MODE_MASTER) {
632 printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
633 ieee->dev->name);
634 return 0;
635/*
636 hostap_update_sta_ps(ieee, (struct hostap_rtllib_hdr_4addr *)
637 skb->data);*/
638 }
639
640 if (ieee->hostapd && type == RTLLIB_TYPE_MGMT) {
641 if (stype == WLAN_FC_STYPE_BEACON &&
642 ieee->iw_mode == IW_MODE_MASTER) {
643 struct sk_buff *skb2;
644 /* Process beacon frames also in kernel driver to
645 * update STA(AP) table statistics */
646 skb2 = skb_clone(skb, GFP_ATOMIC);
647 if (skb2)
648 hostap_rx(skb2->dev, skb2, rx_stats);
649 }
650
651 /* send management frames to the user space daemon for
652 * processing */
653 ieee->apdevstats.rx_packets++;
654 ieee->apdevstats.rx_bytes += skb->len;
655 prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
656 return 0;
657 }
658
659 if (ieee->iw_mode == IW_MODE_MASTER) {
660 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
661 printk(KERN_DEBUG "%s: unknown management frame "
662 "(type=0x%02x, stype=0x%02x) dropped\n",
663 skb->dev->name, type, stype);
664 return -1;
665 }
666
667 hostap_rx(skb->dev, skb, rx_stats);
668 return 0;
669 }
670
671 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
672 "received in non-Host AP mode\n", skb->dev->name);
673 return -1;
674#endif
675}
676
677#ifndef CONFIG_CFG_80211
678/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
679/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
680static unsigned char rfc1042_header[] =
681{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
682/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
683static unsigned char bridge_tunnel_header[] =
684{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
685/* No encapsulation header if EtherType < 0x600 (=length) */
686#endif
687
688/* Called by rtllib_rx_frame_decrypt */
689static int rtllib_is_eapol_frame(struct rtllib_device *ieee,
690 struct sk_buff *skb, size_t hdrlen)
691{
692 struct net_device *dev = ieee->dev;
693 u16 fc, ethertype;
694 struct rtllib_hdr_4addr *hdr;
695 u8 *pos;
696
697 if (skb->len < 24)
698 return 0;
699
700 hdr = (struct rtllib_hdr_4addr *) skb->data;
701 fc = le16_to_cpu(hdr->frame_ctl);
702
703 /* check that the frame is unicast frame to us */
704 if ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) ==
705 RTLLIB_FCTL_TODS &&
706 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
707 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
708 /* ToDS frame with own addr BSSID and DA */
709 } else if ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) ==
710 RTLLIB_FCTL_FROMDS &&
711 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
712 /* FromDS frame with own addr as DA */
713 } else
714 return 0;
715
716 if (skb->len < 24 + 8)
717 return 0;
718
719 /* check for port access entity Ethernet type */
720 pos = skb->data + hdrlen;
721 ethertype = (pos[6] << 8) | pos[7];
722 if (ethertype == ETH_P_PAE)
723 return 1;
724
725 return 0;
726}
727
728/* Called only as a tasklet (software IRQ), by rtllib_rx */
729static inline int
730rtllib_rx_frame_decrypt(struct rtllib_device* ieee, struct sk_buff *skb,
731 struct rtllib_crypt_data *crypt)
732{
733 struct rtllib_hdr_4addr *hdr;
734 int res, hdrlen;
735
736 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
737 return 0;
738#if 1
739 if (ieee->hwsec_active)
740 {
741 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
742 tcb_desc->bHwSec = 1;
743
744 if (ieee->need_sw_enc)
745 tcb_desc->bHwSec = 0;
746 }
747#endif
748 hdr = (struct rtllib_hdr_4addr *) skb->data;
749 hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
750
751#ifdef CONFIG_RTLLIB_CRYPT_TKIP
752 if (ieee->tkip_countermeasures &&
753 strcmp(crypt->ops->name, "TKIP") == 0) {
754 if (net_ratelimit()) {
755 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
756 "received packet from " MAC_FMT "\n",
757 ieee->dev->name, MAC_ARG(hdr->addr2));
758 }
759 return -1;
760 }
761#endif
762
763 atomic_inc(&crypt->refcnt);
764 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
765 atomic_dec(&crypt->refcnt);
766 if (res < 0) {
767 RTLLIB_DEBUG_DROP(
768 "decryption failed (SA=" MAC_FMT
769 ") res=%d\n", MAC_ARG(hdr->addr2), res);
770 if (res == -2)
771 RTLLIB_DEBUG_DROP("Decryption failed ICV "
772 "mismatch (key %d)\n",
773 skb->data[hdrlen + 3] >> 6);
774 ieee->ieee_stats.rx_discards_undecryptable++;
775 return -1;
776 }
777
778 return res;
779}
780
781
782/* Called only as a tasklet (software IRQ), by rtllib_rx */
783static inline int
784rtllib_rx_frame_decrypt_msdu(struct rtllib_device* ieee, struct sk_buff *skb,
785 int keyidx, struct rtllib_crypt_data *crypt)
786{
787 struct rtllib_hdr_4addr *hdr;
788 int res, hdrlen;
789
790 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
791 return 0;
792 if (ieee->hwsec_active)
793 {
794 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
795 tcb_desc->bHwSec = 1;
796
797 if (ieee->need_sw_enc)
798 tcb_desc->bHwSec = 0;
799 }
800
801 hdr = (struct rtllib_hdr_4addr *) skb->data;
802 hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
803
804 atomic_inc(&crypt->refcnt);
805 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv,ieee);
806 atomic_dec(&crypt->refcnt);
807 if (res < 0) {
808 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
809 " (SA=" MAC_FMT " keyidx=%d)\n",
810 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
811 return -1;
812 }
813
814 return 0;
815}
816
817
818/* this function is stolen from ipw2200 driver*/
819#define IEEE_PACKET_RETRY_TIME (5*HZ)
820static int is_duplicate_packet(struct rtllib_device *ieee,
821 struct rtllib_hdr_4addr *header)
822{
823 u16 fc = le16_to_cpu(header->frame_ctl);
824 u16 sc = le16_to_cpu(header->seq_ctl);
825 u16 seq = WLAN_GET_SEQ_SEQ(sc);
826 u16 frag = WLAN_GET_SEQ_FRAG(sc);
827 u16 *last_seq, *last_frag;
828 unsigned long *last_time;
829 struct rtllib_hdr_3addrqos *hdr_3addrqos;
830 struct rtllib_hdr_4addrqos *hdr_4addrqos;
831 u8 tid;
832
833 if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS)&&RTLLIB_QOS_HAS_SEQ(fc)) {
834 hdr_4addrqos = (struct rtllib_hdr_4addrqos *)header;
835 tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID;
836 tid = UP2AC(tid);
837 tid ++;
838 } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
839 hdr_3addrqos = (struct rtllib_hdr_3addrqos*)header;
840 tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID;
841 tid = UP2AC(tid);
842 tid ++;
843 } else {
844 tid = 0;
845 }
846
847 switch (ieee->iw_mode) {
848 case IW_MODE_ADHOC:
849 {
850 struct list_head *p;
851 struct ieee_ibss_seq *entry = NULL;
852 u8 *mac = header->addr2;
853 int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
854 list_for_each(p, &ieee->ibss_mac_hash[index]) {
855 entry = list_entry(p, struct ieee_ibss_seq, list);
856 if (!memcmp(entry->mac, mac, ETH_ALEN))
857 break;
858 }
859 if (p == &ieee->ibss_mac_hash[index]) {
860 entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
861 if (!entry) {
862 printk(KERN_WARNING "Cannot malloc new mac entry\n");
863 return 0;
864 }
865 memcpy(entry->mac, mac, ETH_ALEN);
866 entry->seq_num[tid] = seq;
867 entry->frag_num[tid] = frag;
868 entry->packet_time[tid] = jiffies;
869 list_add(&entry->list, &ieee->ibss_mac_hash[index]);
870 return 0;
871 }
872 last_seq = &entry->seq_num[tid];
873 last_frag = &entry->frag_num[tid];
874 last_time = &entry->packet_time[tid];
875 break;
876 }
877
878 case IW_MODE_INFRA:
879 last_seq = &ieee->last_rxseq_num[tid];
880 last_frag = &ieee->last_rxfrag_num[tid];
881 last_time = &ieee->last_packet_time[tid];
882 break;
883 default:
884 return 0;
885 }
886
887 if ((*last_seq == seq) &&
888 time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
889 if (*last_frag == frag){
890 goto drop;
891
892 }
893 if (*last_frag + 1 != frag)
894 /* out-of-order fragment */
895 goto drop;
896 } else
897 *last_seq = seq;
898
899 *last_frag = frag;
900 *last_time = jiffies;
901 return 0;
902
903drop:
904
905 return 1;
906}
907bool
908AddReorderEntry(
909 PRX_TS_RECORD pTS,
910 PRX_REORDER_ENTRY pReorderEntry
911 )
912{
913 struct list_head *pList = &pTS->RxPendingPktList;
914
915 while(pList->next != &pTS->RxPendingPktList)
916 {
917 if ( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
918 {
919 pList = pList->next;
920 }
921 else if ( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
922 {
923 return false;
924 }
925 else
926 {
927 break;
928 }
929 }
930 pReorderEntry->List.next = pList->next;
931 pReorderEntry->List.next->prev = &pReorderEntry->List;
932 pReorderEntry->List.prev = pList;
933 pList->next = &pReorderEntry->List;
934
935 return true;
936}
937
938void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb** prxbIndicateArray,u8 index)
939{
940 struct net_device_stats *stats = &ieee->stats;
941 u8 i = 0 , j=0;
942 u16 ethertype;
943 for (j = 0; j < index; j++) {
944 struct rtllib_rxb* prxb = prxbIndicateArray[j];
945 for (i = 0; i<prxb->nr_subframes; i++) {
946 struct sk_buff *sub_skb = prxb->subframes[i];
947
948 /* convert hdr + possible LLC headers into Ethernet header */
949 ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
950 if (sub_skb->len >= 8 &&
951 ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
952 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
953 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
954 /* remove RFC1042 or Bridge-Tunnel encapsulation and
955 * replace EtherType */
956 skb_pull(sub_skb, SNAP_SIZE);
957 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
958 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
959 } else {
960 u16 len;
961 /* Leave Ethernet header part of hdr and full payload */
962 len = htons(sub_skb->len);
963 memcpy(skb_push(sub_skb, 2), &len, 2);
964 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
965 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
966 }
967
968 /* Indicat the packets to upper layer */
969 if (sub_skb) {
970 stats->rx_packets++;
971 stats->rx_bytes += sub_skb->len;
972
973 memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
974 sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev);
975 sub_skb->dev = ieee->dev;
976 sub_skb->dev->stats.rx_packets++;
977 sub_skb->dev->stats.rx_bytes += sub_skb->len;
978#ifdef TCP_CSUM_OFFLOAD_RX
979 if ( prxb->tcp_csum_valid)
980 sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
981 else
982 sub_skb->ip_summed = CHECKSUM_NONE;
983
984#else
985 sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
986#endif
987 ieee->last_rx_ps_time = jiffies;
988 netif_rx(sub_skb);
989 }
990 }
991 kfree(prxb);
992 prxb = NULL;
993 }
994}
995
996void
997rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, PRX_TS_RECORD pTS)
998{
999 PRX_REORDER_ENTRY pRxReorderEntry;
1000 struct rtllib_rxb* RfdArray[REORDER_WIN_SIZE];
1001 u8 RfdCnt = 0;
1002
1003
1004 del_timer_sync(&pTS->RxPktPendingTimer);
1005 while(!list_empty(&pTS->RxPendingPktList))
1006 {
1007 if (RfdCnt >= REORDER_WIN_SIZE){
1008 printk("-------------->%s() error! RfdCnt >= REORDER_WIN_SIZE\n", __func__);
1009 break;
1010 }
1011
1012 pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
1013 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): Indicate SeqNum %d!\n",__func__, pRxReorderEntry->SeqNum);
1014 list_del_init(&pRxReorderEntry->List);
1015
1016 RfdArray[RfdCnt] = pRxReorderEntry->prxb;
1017
1018 RfdCnt = RfdCnt + 1;
1019 list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List);
1020 }
1021 rtllib_indicate_packets(ieee, RfdArray, RfdCnt);
1022
1023 pTS->RxIndicateSeq = 0xffff;
1024
1025#ifdef MERGE_TO_DO
1026#endif
1027}
1028
1029
1030void RxReorderIndicatePacket( struct rtllib_device *ieee,
1031 struct rtllib_rxb* prxb,
1032 PRX_TS_RECORD pTS,
1033 u16 SeqNum)
1034{
1035 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
1036 PRX_REORDER_ENTRY pReorderEntry = NULL;
1037 struct rtllib_rxb* prxbIndicateArray[REORDER_WIN_SIZE];
1038 u8 WinSize = pHTInfo->RxReorderWinSize;
1039 u16 WinEnd = 0;
1040 u8 index = 0;
1041 bool bMatchWinStart = false, bPktInBuf = false;
1042 unsigned long flags;
1043
1044 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__func__,SeqNum,pTS->RxIndicateSeq,WinSize);
1045
1046 spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
1047
1048 WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096;
1049 /* Rx Reorder initialize condition.*/
1050 if (pTS->RxIndicateSeq == 0xffff) {
1051 pTS->RxIndicateSeq = SeqNum;
1052 }
1053
1054 /* Drop out the packet which SeqNum is smaller than WinStart */
1055 if (SN_LESS(SeqNum, pTS->RxIndicateSeq)) {
1056 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n",
1057 pTS->RxIndicateSeq, SeqNum);
1058 pHTInfo->RxReorderDropCounter++;
1059 {
1060 int i;
1061 for (i =0; i < prxb->nr_subframes; i++) {
1062 dev_kfree_skb(prxb->subframes[i]);
1063 }
1064 kfree(prxb);
1065 prxb = NULL;
1066 }
1067 spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
1068 return;
1069 }
1070
1071 /*
1072 * Sliding window manipulation. Conditions includes:
1073 * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
1074 * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
1075 */
1076 if (SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) {
1077 pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
1078 bMatchWinStart = true;
1079 } else if (SN_LESS(WinEnd, SeqNum)) {
1080 if (SeqNum >= (WinSize - 1)) {
1081 pTS->RxIndicateSeq = SeqNum + 1 -WinSize;
1082 } else {
1083 pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1;
1084 }
1085 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
1086 }
1087
1088 /*
1089 * Indication process.
1090 * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets
1091 * with the SeqNum smaller than latest WinStart and buffer other packets.
1092 */
1093 /* For Rx Reorder condition:
1094 * 1. All packets with SeqNum smaller than WinStart => Indicate
1095 * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it.
1096 */
1097 if (bMatchWinStart) {
1098 /* Current packet is going to be indicated.*/
1099 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\
1100 pTS->RxIndicateSeq, SeqNum);
1101 prxbIndicateArray[0] = prxb;
1102 index = 1;
1103 } else {
1104 /* Current packet is going to be inserted into pending list.*/
1105 if (!list_empty(&ieee->RxReorder_Unused_List)) {
1106 pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List);
1107 list_del_init(&pReorderEntry->List);
1108
1109 /* Make a reorder entry and insert into a the packet list.*/
1110 pReorderEntry->SeqNum = SeqNum;
1111 pReorderEntry->prxb = prxb;
1112
1113#if 1
1114 if (!AddReorderEntry(pTS, pReorderEntry)) {
1115 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n",
1116 __func__, pTS->RxIndicateSeq, SeqNum);
1117 list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
1118 {
1119 int i;
1120 for (i =0; i < prxb->nr_subframes; i++) {
1121 dev_kfree_skb(prxb->subframes[i]);
1122 }
1123 kfree(prxb);
1124 prxb = NULL;
1125 }
1126 } else {
1127 RTLLIB_DEBUG(RTLLIB_DL_REORDER,
1128 "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
1129 }
1130#endif
1131 }
1132 else {
1133 /*
1134 * Packets are dropped if there is not enough reorder entries.
1135 * This part shall be modified!! We can just indicate all the
1136 * packets in buffer and get reorder entries.
1137 */
1138 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
1139 {
1140 int i;
1141 for (i =0; i < prxb->nr_subframes; i++) {
1142 dev_kfree_skb(prxb->subframes[i]);
1143 }
1144 kfree(prxb);
1145 prxb = NULL;
1146 }
1147 }
1148 }
1149
1150 /* Check if there is any packet need indicate.*/
1151 while(!list_empty(&pTS->RxPendingPktList)) {
1152 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): start RREORDER indicate\n",__func__);
1153#if 1
1154 pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
1155 if ( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) ||
1156 SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
1157 {
1158 /* This protect buffer from overflow. */
1159 if (index >= REORDER_WIN_SIZE) {
1160 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n");
1161 bPktInBuf = true;
1162 break;
1163 }
1164
1165 list_del_init(&pReorderEntry->List);
1166
1167 if (SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
1168 pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
1169
1170 prxbIndicateArray[index] = pReorderEntry->prxb;
1171 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): Indicate SeqNum %d!\n",__func__, pReorderEntry->SeqNum);
1172 index++;
1173
1174 list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
1175 } else {
1176 bPktInBuf = true;
1177 break;
1178 }
1179#endif
1180 }
1181
1182 /* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/
1183 if (index>0) {
1184 if (timer_pending(&pTS->RxPktPendingTimer)){
1185 del_timer_sync(&pTS->RxPktPendingTimer);
1186 }
1187 pTS->RxTimeoutIndicateSeq = 0xffff;
1188
1189 if (index>REORDER_WIN_SIZE){
1190 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
1191 spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
1192 return;
1193 }
1194 rtllib_indicate_packets(ieee, prxbIndicateArray, index);
1195 bPktInBuf = false;
1196 }
1197
1198 if (bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) {
1199 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): SET rx timeout timer\n", __func__);
1200 pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq;
1201 mod_timer(&pTS->RxPktPendingTimer, jiffies + MSECS(pHTInfo->RxReorderPendingTime));
1202 }
1203 spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
1204}
1205
1206u8 parse_subframe(struct rtllib_device* ieee,struct sk_buff *skb,
1207 struct rtllib_rx_stats *rx_stats,
1208 struct rtllib_rxb *rxb,u8* src,u8* dst)
1209{
1210 struct rtllib_hdr_3addr *hdr = (struct rtllib_hdr_3addr* )skb->data;
1211 u16 fc = le16_to_cpu(hdr->frame_ctl);
1212
1213 u16 LLCOffset= sizeof(struct rtllib_hdr_3addr);
1214 u16 ChkLength;
1215 bool bIsAggregateFrame = false;
1216 u16 nSubframe_Length;
1217 u8 nPadding_Length = 0;
1218 u16 SeqNum=0;
1219 struct sk_buff *sub_skb;
1220 u8 *data_ptr;
1221 /* just for debug purpose */
1222 SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl));
1223 if ((RTLLIB_QOS_HAS_SEQ(fc))&&\
1224 (((frameqos *)(skb->data + RTLLIB_3ADDR_LEN))->field.reserved)) {
1225 bIsAggregateFrame = true;
1226 }
1227
1228 if (RTLLIB_QOS_HAS_SEQ(fc)) {
1229 LLCOffset += 2;
1230 }
1231 if (rx_stats->bContainHTC) {
1232 LLCOffset += sHTCLng;
1233 }
1234
1235 ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/
1236
1237 if ( skb->len <= ChkLength ) {
1238 return 0;
1239 }
1240
1241 skb_pull(skb, LLCOffset);
1242 ieee->bIsAggregateFrame = bIsAggregateFrame;
1243 if (!bIsAggregateFrame) {
1244 rxb->nr_subframes = 1;
1245
1246 /* altered by clark 3/30/2010
1247 * The buffer size of the skb indicated to upper layer
1248 * must be less than 5000, or the defraged IP datagram
1249 * in the IP layer will exceed "ipfrag_high_tresh" and be
1250 * discarded. so there must not use the function
1251 * "skb_copy" and "skb_clone" for "skb".
1252 */
1253
1254 /* Allocate new skb for releasing to upper layer */
1255 sub_skb = dev_alloc_skb(RTLLIB_SKBBUFFER_SIZE);
1256 skb_reserve(sub_skb, 12);
1257 data_ptr = (u8 *)skb_put(sub_skb, skb->len);
1258 memcpy(data_ptr, skb->data, skb->len);
1259 sub_skb->dev = ieee->dev;
1260
1261 rxb->subframes[0] = sub_skb;
1262
1263 memcpy(rxb->src,src,ETH_ALEN);
1264 memcpy(rxb->dst,dst,ETH_ALEN);
1265 rxb->subframes[0]->dev = ieee->dev;
1266 return 1;
1267 } else {
1268 rxb->nr_subframes = 0;
1269 memcpy(rxb->src,src,ETH_ALEN);
1270 memcpy(rxb->dst,dst,ETH_ALEN);
1271 while(skb->len > ETHERNET_HEADER_SIZE) {
1272 /* Offset 12 denote 2 mac address */
1273 nSubframe_Length = *((u16*)(skb->data + 12));
1274 nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
1275
1276 if (skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) {
1277 printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
1278 __func__,rxb->nr_subframes);
1279 printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__func__, nSubframe_Length);
1280 printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length);
1281 printk("The Packet SeqNum is %d\n",SeqNum);
1282 return 0;
1283 }
1284
1285 /* move the data point to data content */
1286 skb_pull(skb, ETHERNET_HEADER_SIZE);
1287
1288 /* altered by clark 3/30/2010
1289 * The buffer size of the skb indicated to upper layer
1290 * must be less than 5000, or the defraged IP datagram
1291 * in the IP layer will exceed "ipfrag_high_tresh" and be
1292 * discarded. so there must not use the function
1293 * "skb_copy" and "skb_clone" for "skb".
1294 */
1295
1296 /* Allocate new skb for releasing to upper layer */
1297 sub_skb = dev_alloc_skb(nSubframe_Length + 12);
1298 skb_reserve(sub_skb, 12);
1299 data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
1300 memcpy(data_ptr,skb->data,nSubframe_Length);
1301
1302 sub_skb->dev = ieee->dev;
1303 rxb->subframes[rxb->nr_subframes++] = sub_skb;
1304 if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
1305 RTLLIB_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
1306 break;
1307 }
1308 skb_pull(skb,nSubframe_Length);
1309
1310 if (skb->len != 0) {
1311 nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4);
1312 if (nPadding_Length == 4) {
1313 nPadding_Length = 0;
1314 }
1315
1316 if (skb->len < nPadding_Length) {
1317 return 0;
1318 }
1319
1320 skb_pull(skb,nPadding_Length);
1321 }
1322 }
1323
1324 return rxb->nr_subframes;
1325 }
1326}
1327
1328
1329size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee, struct sk_buff *skb,
1330 struct rtllib_rx_stats *rx_stats)
1331{
1332 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1333 u16 fc = le16_to_cpu(hdr->frame_ctl);
1334 size_t hdrlen = 0;
1335
1336 hdrlen = rtllib_get_hdrlen(fc);
1337 if (HTCCheck(ieee, skb->data)) {
1338 if (net_ratelimit())
1339 printk("%s: find HTCControl!\n", __func__);
1340 hdrlen += 4;
1341 rx_stats->bContainHTC = 1;
1342 }
1343
1344 if (RTLLIB_QOS_HAS_SEQ(fc))
1345 rx_stats->bIsQosData = 1;
1346
1347 return hdrlen;
1348}
1349
1350int rtllib_rx_check_duplicate(struct rtllib_device *ieee, struct sk_buff *skb, u8 multicast)
1351{
1352 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1353 u16 fc, sc;
1354 u8 frag, type, stype;
1355
1356 fc = le16_to_cpu(hdr->frame_ctl);
1357 type = WLAN_FC_GET_TYPE(fc);
1358 stype = WLAN_FC_GET_STYPE(fc);
1359 sc = le16_to_cpu(hdr->seq_ctl);
1360 frag = WLAN_GET_SEQ_FRAG(sc);
1361
1362 if ( (ieee->pHTInfo->bCurRxReorderEnable == false) ||
1363 !ieee->current_network.qos_data.active ||
1364 !IsDataFrame(skb->data) ||
1365 IsLegacyDataFrame(skb->data)) {
1366 if (!((type == RTLLIB_FTYPE_MGMT) && (stype == RTLLIB_STYPE_BEACON))){
1367 if (is_duplicate_packet(ieee, hdr)){
1368 return -1;
1369 }
1370 }
1371 } else {
1372 PRX_TS_RECORD pRxTS = NULL;
1373 if (GetTs(ieee, (PTS_COMMON_INFO*) &pRxTS, hdr->addr2,
1374 (u8)Frame_QoSTID((u8*)(skb->data)), RX_DIR, true)) {
1375 if ((fc & (1<<11)) && (frag == pRxTS->RxLastFragNum) &&
1376 (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)) {
1377 return -1;
1378 } else {
1379 pRxTS->RxLastFragNum = frag;
1380 pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
1381 }
1382 } else {
1383 RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip the check!!\n",__func__);
1384 return -1;
1385 }
1386 }
1387
1388 return 0;
1389}
1390void rtllib_rx_extract_addr(struct rtllib_device *ieee, struct rtllib_hdr_4addr *hdr, u8 *dst, u8 *src, u8 *bssid)
1391{
1392 u16 fc = le16_to_cpu(hdr->frame_ctl);
1393
1394 switch (fc & (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) {
1395 case RTLLIB_FCTL_FROMDS:
1396 memcpy(dst, hdr->addr1, ETH_ALEN);
1397 memcpy(src, hdr->addr3, ETH_ALEN);
1398 memcpy(bssid, hdr->addr2, ETH_ALEN);
1399 break;
1400 case RTLLIB_FCTL_TODS:
1401 memcpy(dst, hdr->addr3, ETH_ALEN);
1402 memcpy(src, hdr->addr2, ETH_ALEN);
1403 memcpy(bssid, hdr->addr1, ETH_ALEN);
1404 break;
1405 case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS:
1406 memcpy(dst, hdr->addr3, ETH_ALEN);
1407 memcpy(src, hdr->addr4, ETH_ALEN);
1408 memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
1409 break;
1410 case 0:
1411 memcpy(dst, hdr->addr1, ETH_ALEN);
1412 memcpy(src, hdr->addr2, ETH_ALEN);
1413 memcpy(bssid, hdr->addr3, ETH_ALEN);
1414 break;
1415 }
1416}
1417int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, u8 *dst, u8 *src, u8 *bssid, u8 *addr2)
1418{
1419 u8 zero_addr[ETH_ALEN] = {0};
1420 u8 type, stype;
1421
1422 type = WLAN_FC_GET_TYPE(fc);
1423 stype = WLAN_FC_GET_STYPE(fc);
1424
1425 /* Filter frames from different BSS */
1426 if (((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS)
1427 && (compare_ether_addr(ieee->current_network.bssid, bssid) != 0)
1428 && memcmp(ieee->current_network.bssid, zero_addr, ETH_ALEN)) {
1429 return -1;
1430 }
1431
1432 /* Filter packets sent by an STA that will be forwarded by AP */
1433 if ( ieee->IntelPromiscuousModeInfo.bPromiscuousOn &&
1434 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame ) {
1435 if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) &&
1436 (compare_ether_addr(dst, ieee->current_network.bssid) != 0) &&
1437 (compare_ether_addr(bssid, ieee->current_network.bssid) == 0)) {
1438 return -1;
1439 }
1440 }
1441
1442 /* Nullfunc frames may have PS-bit set, so they must be passed to
1443 * hostap_handle_sta_rx() before being dropped here. */
1444 if (!ieee->IntelPromiscuousModeInfo.bPromiscuousOn){
1445 if (stype != RTLLIB_STYPE_DATA &&
1446 stype != RTLLIB_STYPE_DATA_CFACK &&
1447 stype != RTLLIB_STYPE_DATA_CFPOLL &&
1448 stype != RTLLIB_STYPE_DATA_CFACKPOLL&&
1449 stype != RTLLIB_STYPE_QOS_DATA
1450 ) {
1451 if (stype != RTLLIB_STYPE_NULLFUNC)
1452 RTLLIB_DEBUG_DROP(
1453 "RX: dropped data frame "
1454 "with no data (type=0x%02x, "
1455 "subtype=0x%02x)\n",
1456 type, stype);
1457 return -1;
1458 }
1459 }
1460
1461 if (ieee->iw_mode != IW_MODE_MESH) {
1462 /* packets from our adapter are dropped (echo) */
1463 if (!memcmp(src, ieee->dev->dev_addr, ETH_ALEN))
1464 return -1;
1465
1466 /* {broad,multi}cast packets to our BSS go through */
1467 if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) {
1468 if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) {
1469 return -1;
1470 }
1471 }
1472 }
1473 return 0;
1474}
1475int rtllib_rx_get_crypt(
1476 struct rtllib_device *ieee,
1477 struct sk_buff *skb,
1478 struct rtllib_crypt_data **crypt,
1479 size_t hdrlen)
1480{
1481 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1482 u16 fc = le16_to_cpu(hdr->frame_ctl);
1483 int idx = 0;
1484
1485 if (ieee->host_decrypt) {
1486 if (skb->len >= hdrlen + 3)
1487 idx = skb->data[hdrlen + 3] >> 6;
1488
1489 *crypt = ieee->crypt[idx];
1490 /* allow NULL decrypt to indicate an station specific override
1491 * for default encryption */
1492 if (*crypt && ((*crypt)->ops == NULL ||
1493 (*crypt)->ops->decrypt_mpdu == NULL))
1494 *crypt = NULL;
1495
1496 if (!*crypt && (fc & RTLLIB_FCTL_WEP)) {
1497 /* This seems to be triggered by some (multicast?)
1498 * frames from other than current BSS, so just drop the
1499 * frames silently instead of filling system log with
1500 * these reports. */
1501 RTLLIB_DEBUG_DROP("Decryption failed (not set)"
1502 " (SA=" MAC_FMT ")\n",
1503 MAC_ARG(hdr->addr2));
1504 ieee->ieee_stats.rx_discards_undecryptable++;
1505 return -1;
1506 }
1507 }
1508
1509 return 0;
1510}
1511int rtllib_rx_decrypt(
1512 struct rtllib_device *ieee,
1513 struct sk_buff *skb,
1514 struct rtllib_rx_stats *rx_stats,
1515 struct rtllib_crypt_data *crypt,
1516 size_t hdrlen)
1517{
1518 struct rtllib_hdr_4addr *hdr;
1519 int keyidx = 0;
1520 u16 fc, sc;
1521 u8 frag;
1522
1523 hdr = (struct rtllib_hdr_4addr *)skb->data;
1524 fc = le16_to_cpu(hdr->frame_ctl);
1525 sc = le16_to_cpu(hdr->seq_ctl);
1526 frag = WLAN_GET_SEQ_FRAG(sc);
1527
1528 if ((!rx_stats->Decrypted)){
1529 ieee->need_sw_enc = 1;
1530 }else{
1531 ieee->need_sw_enc = 0;
1532 }
1533
1534 if (ieee->host_decrypt && (fc & RTLLIB_FCTL_WEP) &&
1535 ((keyidx = rtllib_rx_frame_decrypt(ieee, skb, crypt)) < 0)) {
1536 printk("%s: decrypt frame error\n", __func__);
1537 return -1;
1538 }
1539
1540 hdr = (struct rtllib_hdr_4addr *) skb->data;
1541 if ((frag != 0 || (fc & RTLLIB_FCTL_MOREFRAGS))) {
1542 int flen;
1543 struct sk_buff *frag_skb = rtllib_frag_cache_get(ieee, hdr);
1544 RTLLIB_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
1545
1546 if (!frag_skb) {
1547 RTLLIB_DEBUG(RTLLIB_DL_RX | RTLLIB_DL_FRAG,
1548 "Rx cannot get skb from fragment "
1549 "cache (morefrag=%d seq=%u frag=%u)\n",
1550 (fc & RTLLIB_FCTL_MOREFRAGS) != 0,
1551 WLAN_GET_SEQ_SEQ(sc), frag);
1552 return -1;
1553 }
1554 flen = skb->len;
1555 if (frag != 0)
1556 flen -= hdrlen;
1557
1558 if (frag_skb->tail + flen > frag_skb->end) {
1559 printk(KERN_WARNING "%s: host decrypted and "
1560 "reassembled frame did not fit skb\n",
1561 __func__);
1562 rtllib_frag_cache_invalidate(ieee, hdr);
1563 return -1;
1564 }
1565
1566 if (frag == 0) {
1567 /* copy first fragment (including full headers) into
1568 * beginning of the fragment cache skb */
1569 memcpy(skb_put(frag_skb, flen), skb->data, flen);
1570 } else {
1571 /* append frame payload to the end of the fragment
1572 * cache skb */
1573 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
1574 flen);
1575 }
1576 dev_kfree_skb_any(skb);
1577 skb = NULL;
1578
1579 if (fc & RTLLIB_FCTL_MOREFRAGS) {
1580 /* more fragments expected - leave the skb in fragment
1581 * cache for now; it will be delivered to upper layers
1582 * after all fragments have been received */
1583 return -2;
1584 }
1585
1586 /* this was the last fragment and the frame will be
1587 * delivered, so remove skb from fragment cache */
1588 skb = frag_skb;
1589 hdr = (struct rtllib_hdr_4addr *) skb->data;
1590 rtllib_frag_cache_invalidate(ieee, hdr);
1591 }
1592
1593 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
1594 * encrypted/authenticated */
1595 if (ieee->host_decrypt && (fc & RTLLIB_FCTL_WEP) &&
1596 rtllib_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
1597 {
1598 printk("%s: ==>decrypt msdu error\n", __func__);
1599 return -1;
1600 }
1601
1602 hdr = (struct rtllib_hdr_4addr *) skb->data;
1603 if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep) {
1604 if (/*ieee->ieee802_1x &&*/
1605 rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1606
1607#ifdef CONFIG_RTLLIB_DEBUG
1608 /* pass unencrypted EAPOL frames even if encryption is
1609 * configured */
1610 struct eapol *eap = (struct eapol *)(skb->data +
1611 24);
1612 RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
1613 eap_get_type(eap->type));
1614#endif
1615 } else {
1616 RTLLIB_DEBUG_DROP(
1617 "encryption configured, but RX "
1618 "frame not encrypted (SA=" MAC_FMT ")\n",
1619 MAC_ARG(hdr->addr2));
1620 return -1;
1621 }
1622 }
1623
1624#ifdef CONFIG_RTLLIB_DEBUG
1625 if (crypt && !(fc & RTLLIB_FCTL_WEP) &&
1626 rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1627 struct eapol *eap = (struct eapol *)(skb->data +
1628 24);
1629 RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
1630 eap_get_type(eap->type));
1631 }
1632#endif
1633
1634 if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep &&
1635 !rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1636 RTLLIB_DEBUG_DROP(
1637 "dropped unencrypted RX data "
1638 "frame from " MAC_FMT
1639 " (drop_unencrypted=1)\n",
1640 MAC_ARG(hdr->addr2));
1641 return -1;
1642 }
1643
1644 if (rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1645 printk(KERN_WARNING "RX: IEEE802.1X EAPOL frame!\n");
1646 }
1647
1648 return 0;
1649}
1650void rtllib_rx_check_leave_lps(struct rtllib_device *ieee, u8 unicast, u8 nr_subframes)
1651{
1652#if !defined(RTL8192SU) && !defined(RTL8192U)
1653 if (unicast){
1654
1655 if ((ieee->state == RTLLIB_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
1656 {
1657 if ( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
1658 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
1659 {
1660 if (ieee->LeisurePSLeave)
1661 ieee->LeisurePSLeave(ieee->dev);
1662 }
1663 }
1664 }
1665#endif
1666 ieee->last_rx_ps_time = jiffies;
1667}
1668void rtllib_rx_indicate_pkt_legacy(
1669 struct rtllib_device *ieee,
1670 struct rtllib_rx_stats *rx_stats,
1671 struct rtllib_rxb* rxb,
1672 u8 *dst,
1673 u8 *src)
1674{
1675 struct net_device *dev = ieee->dev;
1676 u16 ethertype;
1677 int i = 0;
1678
1679 if (rxb == NULL){
1680 printk("%s: rxb is NULL!!\n", __func__);
1681 return ;
1682 }
1683
1684 for (i = 0; i<rxb->nr_subframes; i++) {
1685 struct sk_buff *sub_skb = rxb->subframes[i];
1686
1687 if (sub_skb) {
1688 /* convert hdr + possible LLC headers into Ethernet header */
1689 ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
1690 if (sub_skb->len >= 8 &&
1691 ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
1692 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1693 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
1694 /* remove RFC1042 or Bridge-Tunnel encapsulation and
1695 * replace EtherType */
1696 skb_pull(sub_skb, SNAP_SIZE);
1697 memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
1698 memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
1699 } else {
1700 u16 len;
1701 /* Leave Ethernet header part of hdr and full payload */
1702 len = htons(sub_skb->len);
1703 memcpy(skb_push(sub_skb, 2), &len, 2);
1704 memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
1705 memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
1706 }
1707
1708 ieee->stats.rx_packets++;
1709 ieee->stats.rx_bytes += sub_skb->len;
1710
1711 if (is_multicast_ether_addr(dst)) {
1712 ieee->stats.multicast++;
1713 }
1714
1715 /* Indicat the packets to upper layer */
1716 memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
1717 sub_skb->protocol = eth_type_trans(sub_skb, dev);
1718 sub_skb->dev = dev;
1719 sub_skb->dev->stats.rx_packets++;
1720 sub_skb->dev->stats.rx_bytes += sub_skb->len;
1721#ifdef TCP_CSUM_OFFLOAD_RX
1722 if ( rx_stats->tcp_csum_valid)
1723 sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
1724 else
1725 sub_skb->ip_summed = CHECKSUM_NONE;
1726#else
1727 sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
1728#endif
1729 netif_rx(sub_skb);
1730 }
1731 }
1732 kfree(rxb);
1733 rxb = NULL;
1734}
1735int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb,
1736 struct rtllib_rx_stats *rx_stats)
1737{
1738 struct net_device *dev = ieee->dev;
1739 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1740 struct rtllib_crypt_data *crypt = NULL;
1741#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
1742 struct sta_info * psta = NULL;
1743#endif
1744 struct rtllib_rxb* rxb = NULL;
1745 PRX_TS_RECORD pTS = NULL;
1746 u16 fc, sc, SeqNum = 0;
1747 u8 type, stype, multicast = 0, unicast = 0, nr_subframes = 0, TID = 0;
1748 u8 dst[ETH_ALEN], src[ETH_ALEN], bssid[ETH_ALEN] = {0}, *payload;
1749 size_t hdrlen = 0;
1750 bool bToOtherSTA = false;
1751 int ret = 0, i = 0;
1752
1753 hdr = (struct rtllib_hdr_4addr *)skb->data;
1754 fc = le16_to_cpu(hdr->frame_ctl);
1755 type = WLAN_FC_GET_TYPE(fc);
1756 stype = WLAN_FC_GET_STYPE(fc);
1757 sc = le16_to_cpu(hdr->seq_ctl);
1758
1759 /*Filter pkt not to me*/
1760 multicast = is_multicast_ether_addr(hdr->addr1)|is_broadcast_ether_addr(hdr->addr1);
1761 unicast = !multicast;
1762 if (unicast && (compare_ether_addr(dev->dev_addr, hdr->addr1) != 0)) {
1763 if (ieee->bNetPromiscuousMode)
1764 bToOtherSTA = true;
1765 else
1766 goto rx_dropped;
1767 }
1768
1769 /*Filter pkt has too small length */
1770 hdrlen = rtllib_rx_get_hdrlen(ieee, skb, rx_stats);
1771 if (skb->len < hdrlen){
1772 printk("%s():ERR!!! skb->len is smaller than hdrlen\n",__func__);
1773 goto rx_dropped;
1774 }
1775
1776 /* Filter Duplicate pkt */
1777 ret = rtllib_rx_check_duplicate(ieee, skb, multicast);
1778 if (ret < 0)
1779 goto rx_dropped;
1780
1781 /* Filter CTRL Frame */
1782 if (type == RTLLIB_FTYPE_CTL) {
1783 goto rx_dropped;
1784 }
1785
1786 /* Filter MGNT Frame */
1787 if (type == RTLLIB_FTYPE_MGMT) {
1788 if (bToOtherSTA)
1789 goto rx_dropped;
1790 if (rtllib_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
1791 goto rx_dropped;
1792 else
1793 goto rx_exit;
1794 }
1795
1796 /* Filter WAPI DATA Frame */
1797
1798 /* Update statstics for AP roaming */
1799 if (!bToOtherSTA){
1800 ieee->LinkDetectInfo.NumRecvDataInPeriod++;
1801 ieee->LinkDetectInfo.NumRxOkInPeriod++;
1802 }
1803 dev->last_rx = jiffies;
1804
1805 /* Data frame - extract src/dst addresses */
1806 rtllib_rx_extract_addr(ieee, hdr, dst, src, bssid);
1807
1808 /* Filter Data frames */
1809 ret = rtllib_rx_data_filter(ieee, fc, dst, src, bssid, hdr->addr2);
1810 if (ret < 0)
1811 goto rx_dropped;
1812
1813 if (skb->len == hdrlen){
1814 goto rx_dropped;
1815 }
1816
1817 /* Send pspoll based on moredata */
1818 if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == LPS_IS_SLEEP)
1819 && (ieee->polling) && (!bToOtherSTA)) {
1820 if (WLAN_FC_MORE_DATA(fc)) {
1821 /* more data bit is set, let's request a new frame from the AP */
1822 rtllib_sta_ps_send_pspoll_frame(ieee);
1823 } else {
1824 ieee->polling = false;
1825 }
1826 }
1827
1828#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
1829 if (ieee->iw_mode == IW_MODE_ADHOC){
1830 psta = GetStaInfo(ieee, src);
1831 if (NULL != psta)
1832 psta->LastActiveTime = jiffies;
1833 }
1834#endif
1835
1836 /* Get crypt if encrypted */
1837 ret = rtllib_rx_get_crypt(ieee, skb, &crypt, hdrlen);
1838 if (ret == -1)
1839 goto rx_dropped;
1840
1841 /* Decrypt data frame (including reassemble) */
1842 ret = rtllib_rx_decrypt(ieee, skb, rx_stats, crypt, hdrlen);
1843 if (ret == -1)
1844 goto rx_dropped;
1845 else if (ret == -2)
1846 goto rx_exit;
1847
1848 /* Get TS for Rx Reorder */
1849 hdr = (struct rtllib_hdr_4addr *) skb->data;
1850 if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data)
1851 && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1)
1852 && (!bToOtherSTA))
1853 {
1854 TID = Frame_QoSTID(skb->data);
1855 SeqNum = WLAN_GET_SEQ_SEQ(sc);
1856 GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true);
1857 if (TID !=0 && TID !=3){
1858 ieee->bis_any_nonbepkts = true;
1859 }
1860 }
1861
1862 /* Parse rx data frame (For AMSDU) */
1863 /* skb: hdr + (possible reassembled) full plaintext payload */
1864 payload = skb->data + hdrlen;
1865 rxb = (struct rtllib_rxb*)kmalloc(sizeof(struct rtllib_rxb),GFP_ATOMIC);
1866 if (rxb == NULL)
1867 {
1868 RTLLIB_DEBUG(RTLLIB_DL_ERR,"%s(): kmalloc rxb error\n",__func__);
1869 goto rx_dropped;
1870 }
1871 /* to parse amsdu packets */
1872 /* qos data packets & reserved bit is 1 */
1873 if (parse_subframe(ieee,skb,rx_stats,rxb,src,dst) == 0) {
1874 /* only to free rxb, and not submit the packets to upper layer */
1875 for (i =0; i < rxb->nr_subframes; i++) {
1876 dev_kfree_skb(rxb->subframes[i]);
1877 }
1878 kfree(rxb);
1879 rxb = NULL;
1880 goto rx_dropped;
1881 }
1882
1883 /* Update WAPI PN */
1884
1885 /* Check if leave LPS */
1886 if (!bToOtherSTA){
1887 if (ieee->bIsAggregateFrame)
1888 nr_subframes = rxb->nr_subframes;
1889 else
1890 nr_subframes = 1;
1891 if (unicast)
1892 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod += nr_subframes;
1893 rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes);
1894 }
1895
1896 /* Indicate packets to upper layer or Rx Reorder */
1897 if (ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL || bToOtherSTA){
1898 rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src);
1899 }else{
1900#ifdef TCP_CSUM_OFFLOAD_RX
1901 rxb->tcp_csum_valid = rx_stats->tcp_csum_valid;
1902#endif
1903 RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
1904 }
1905
1906 dev_kfree_skb(skb);
1907
1908 rx_exit:
1909 return 1;
1910
1911 rx_dropped:
1912 if (rxb != NULL)
1913 {
1914 kfree(rxb);
1915 rxb = NULL;
1916 }
1917 ieee->stats.rx_dropped++;
1918
1919 /* Returning 0 indicates to caller that we have not handled the SKB--
1920 * so it is still allocated and can be used again by underlying
1921 * hardware as a DMA target */
1922 return 0;
1923}
1924
1925int rtllib_rx_Master(struct rtllib_device *ieee, struct sk_buff *skb,
1926 struct rtllib_rx_stats *rx_stats)
1927{
1928 return 0;
1929}
1930int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb,
1931 struct rtllib_rx_stats *rx_stats)
1932{
1933 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1934 u16 fc = le16_to_cpu(hdr->frame_ctl);
1935 size_t hdrlen = rtllib_get_hdrlen(fc);
1936
1937 if (skb->len < hdrlen){
1938 printk("%s():ERR!!! skb->len is smaller than hdrlen\n", __func__);
1939 return 0;
1940 }
1941
1942 if (HTCCheck(ieee, skb->data)) {
1943 if (net_ratelimit())
1944 printk("%s: Find HTCControl!\n", __func__);
1945 hdrlen += 4;
1946 }
1947
1948#if WIRELESS_EXT > 15
1949 rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
1950 ieee->stats.rx_packets++;
1951 ieee->stats.rx_bytes += skb->len;
1952#endif
1953 return 1;
1954}
1955
1956int rtllib_rx_Mesh(struct rtllib_device *ieee, struct sk_buff *skb,
1957 struct rtllib_rx_stats *rx_stats)
1958{
1959 return 0;
1960}
1961
1962#if 1
1963/* All received frames are sent to this function. @skb contains the frame in
1964 * IEEE 802.11 format, i.e., in the format it was sent over air.
1965 * This function is called only as a tasklet (software IRQ). */
1966int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
1967 struct rtllib_rx_stats *rx_stats)
1968{
1969 int ret = 0;
1970
1971 if ((NULL==ieee) || (NULL==skb) || (NULL==rx_stats)){
1972 printk(KERN_INFO "%s: Input parameters NULL!\n", __func__);
1973 goto rx_dropped;
1974 }
1975 if (skb->len < 10) {
1976 printk(KERN_INFO "%s: SKB length < 10 \n", __func__);
1977 goto rx_dropped;
1978 }
1979
1980 switch (ieee->iw_mode) {
1981 case IW_MODE_ADHOC:
1982 case IW_MODE_INFRA:
1983 ret = rtllib_rx_InfraAdhoc(ieee, skb, rx_stats);
1984 break;
1985 case IW_MODE_MASTER:
1986 case IW_MODE_REPEAT:
1987 ret = rtllib_rx_Master(ieee, skb, rx_stats);
1988 break;
1989 case IW_MODE_MONITOR:
1990 ret = rtllib_rx_Monitor(ieee, skb, rx_stats);
1991 break;
1992 case IW_MODE_MESH:
1993 ret = rtllib_rx_Mesh(ieee, skb, rx_stats);
1994 break;
1995 default:
1996 printk(KERN_INFO"%s: ERR iw mode!!!\n", __func__);
1997 break;
1998 }
1999
2000 return ret;
2001
2002 rx_dropped:
2003 ieee->stats.rx_dropped++;
2004 return 0;
2005}
2006#else
2007int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
2008 struct rtllib_rx_stats *rx_stats)
2009{
2010 struct net_device *dev = ieee->dev;
2011 struct rtllib_hdr_4addr *hdr;
2012 size_t hdrlen;
2013 u16 fc, type, stype, sc;
2014 struct net_device_stats *stats = NULL;
2015 unsigned int frag;
2016 u8 *payload;
2017 u16 ethertype;
2018 u8 TID = 0;
2019 u16 SeqNum = 0;
2020 PRX_TS_RECORD pTS = NULL;
2021#ifdef NOT_YET
2022 struct net_device *wds = NULL;
2023 struct sk_buff *skb2 = NULL;
2024 struct net_device *wds = NULL;
2025 int frame_authorized = 0;
2026 int from_assoc_ap = 0;
2027 void *sta = NULL;
2028#endif
2029 u8 dst[ETH_ALEN];
2030 u8 src[ETH_ALEN];
2031 u8 bssid[ETH_ALEN] = {0};
2032 u8 zero_addr[ETH_ALEN] = {0};
2033 struct rtllib_crypt_data *crypt = NULL;
2034 int keyidx = 0;
2035#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
2036 struct sta_info * psta = NULL;
2037#endif
2038 bool unicast_packet = false;
2039 int i;
2040 struct rtllib_rxb* rxb = NULL;
2041 int multicast = 0;
2042 bool tmp_dump = false;
2043 bool bToOtherSTA = false;
2044 hdr = (struct rtllib_hdr_4addr *)skb->data;
2045 stats = &ieee->stats;
2046
2047 multicast = is_multicast_ether_addr(hdr->addr1)|is_broadcast_ether_addr(hdr->addr1);
2048 if (!multicast && (compare_ether_addr(dev->dev_addr, hdr->addr1) != 0)) {
2049 if ((ieee->iw_mode == IW_MODE_MONITOR) || ieee->bNetPromiscuousMode){
2050 bToOtherSTA = true;
2051 }else{
2052 goto rx_dropped;
2053 }
2054 }
2055
2056 fc = le16_to_cpu(hdr->frame_ctl);
2057 type = WLAN_FC_GET_TYPE(fc);
2058 stype = WLAN_FC_GET_STYPE(fc);
2059 sc = le16_to_cpu(hdr->seq_ctl);
2060 frag = WLAN_GET_SEQ_FRAG(sc);
2061
2062 ieee->need_sw_enc = 0;
2063
2064 hdrlen = rtllib_get_hdrlen(fc);
2065 if (skb->len < hdrlen){
2066 printk("%s():ERR!!! skb->len is smaller than hdrlen\n",__func__);
2067 goto rx_dropped;
2068 }
2069
2070 if (HTCCheck(ieee, skb->data)) {
2071 if (net_ratelimit())
2072 printk("find HTCControl\n");
2073 hdrlen += 4;
2074 rx_stats->bContainHTC = 1;
2075 }
2076 if (RTLLIB_QOS_HAS_SEQ(fc))
2077 rx_stats->bIsQosData = 1;
2078 if ((0) && (type == RTLLIB_FTYPE_DATA) && ((is_broadcast_ether_addr(hdr->addr1)) || (compare_ether_addr(dev->dev_addr, hdr->addr1) == 0))) {
2079 printk("===>RX data before decrypt\n");
2080 tmp_dump = true;
2081 dump_buf(skb->data,skb->len);
2082 }
2083#ifdef NOT_YET
2084 hostap_update_rx_stats(local->ap, hdr, rx_stats);
2085#endif
2086
2087 if (ieee->host_decrypt) {
2088 int idx = 0;
2089 if (skb->len >= hdrlen + 3)
2090 idx = skb->data[hdrlen + 3] >> 6;
2091 crypt = ieee->crypt[idx];
2092#ifdef NOT_YET
2093 sta = NULL;
2094
2095 /* Use station specific key to override default keys if the
2096 * receiver address is a unicast address ("individual RA"). If
2097 * bcrx_sta_key parameter is set, station specific key is used
2098 * even with broad/multicast targets (this is against IEEE
2099 * 802.11, but makes it easier to use different keys with
2100 * stations that do not support WEP key mapping). */
2101
2102 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
2103 (void) hostap_handle_sta_crypto(local, hdr, &crypt,
2104 &sta);
2105#endif
2106
2107 /* allow NULL decrypt to indicate an station specific override
2108 * for default encryption */
2109 if (crypt && (crypt->ops == NULL ||
2110 crypt->ops->decrypt_mpdu == NULL))
2111 crypt = NULL;
2112
2113 if (!crypt && (fc & RTLLIB_FCTL_WEP)) {
2114 /* This seems to be triggered by some (multicast?)
2115 * frames from other than current BSS, so just drop the
2116 * frames silently instead of filling system log with
2117 * these reports. */
2118 RTLLIB_DEBUG_DROP("Decryption failed (not set)"
2119 " (SA=" MAC_FMT ")\n",
2120 MAC_ARG(hdr->addr2));
2121 ieee->ieee_stats.rx_discards_undecryptable++;
2122 goto rx_dropped;
2123 }
2124 }
2125
2126 if (skb->len < RTLLIB_DATA_HDR3_LEN)
2127 goto rx_dropped;
2128
2129 if ( (ieee->pHTInfo->bCurRxReorderEnable == false) ||
2130 !ieee->current_network.qos_data.active ||
2131 !IsDataFrame(skb->data) ||
2132 IsLegacyDataFrame(skb->data)) {
2133 if (!((type == RTLLIB_FTYPE_MGMT) && (stype == RTLLIB_STYPE_BEACON))){
2134 if (is_duplicate_packet(ieee, hdr)){
2135 goto rx_dropped;
2136 }
2137 }
2138 } else {
2139 PRX_TS_RECORD pRxTS = NULL;
2140 if (GetTs(ieee, (PTS_COMMON_INFO*) &pRxTS, hdr->addr2,
2141 (u8)Frame_QoSTID((u8*)(skb->data)), RX_DIR, true)) {
2142 if ((fc & (1<<11)) && (frag == pRxTS->RxLastFragNum) &&
2143 (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)) {
2144 goto rx_dropped;
2145 } else {
2146 pRxTS->RxLastFragNum = frag;
2147 pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
2148 }
2149 } else {
2150 RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip the check!!\n",__func__);
2151 goto rx_dropped;
2152 }
2153 }
2154 if (type == RTLLIB_FTYPE_MGMT) {
2155 if (bToOtherSTA)
2156 goto rx_dropped;
2157 if (rtllib_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
2158 goto rx_dropped;
2159 else
2160 goto rx_exit;
2161 }
2162 if (type == RTLLIB_FTYPE_CTL) {
2163 goto rx_dropped;
2164 }
2165 /* Data frame - extract src/dst addresses */
2166 switch (fc & (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) {
2167 case RTLLIB_FCTL_FROMDS:
2168 memcpy(dst, hdr->addr1, ETH_ALEN);
2169 memcpy(src, hdr->addr3, ETH_ALEN);
2170 memcpy(bssid, hdr->addr2, ETH_ALEN);
2171 break;
2172 case RTLLIB_FCTL_TODS:
2173 memcpy(dst, hdr->addr3, ETH_ALEN);
2174 memcpy(src, hdr->addr2, ETH_ALEN);
2175 memcpy(bssid, hdr->addr1, ETH_ALEN);
2176 break;
2177 case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS:
2178 if (skb->len < RTLLIB_DATA_HDR4_LEN)
2179 goto rx_dropped;
2180 memcpy(dst, hdr->addr3, ETH_ALEN);
2181 memcpy(src, hdr->addr4, ETH_ALEN);
2182 memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
2183 break;
2184 case 0:
2185 memcpy(dst, hdr->addr1, ETH_ALEN);
2186 memcpy(src, hdr->addr2, ETH_ALEN);
2187 memcpy(bssid, hdr->addr3, ETH_ALEN);
2188 break;
2189 }
2190
2191 /* Filter frames from different BSS */
2192 if ((type != RTLLIB_FTYPE_CTL) && ((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS)
2193 && (compare_ether_addr(ieee->current_network.bssid, bssid) != 0) && memcmp(ieee->current_network.bssid, zero_addr, ETH_ALEN)) {
2194 goto rx_dropped;
2195 }
2196
2197 /* Filter packets sent by an STA that will be forwarded by AP */
2198 if ( ieee->IntelPromiscuousModeInfo.bPromiscuousOn &&
2199 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame ) {
2200 if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) &&
2201 (compare_ether_addr(dst, ieee->current_network.bssid) != 0) &&
2202 (compare_ether_addr(bssid, ieee->current_network.bssid) == 0)) {
2203 goto rx_dropped;
2204 }
2205 }
2206
2207#ifdef NOT_YET
2208 if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
2209 goto rx_dropped;
2210 if (wds) {
2211 skb->dev = dev = wds;
2212 stats = hostap_get_stats(dev);
2213 }
2214
2215 if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
2216 (fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) == RTLLIB_FCTL_FROMDS &&
2217 ieee->stadev &&
2218 memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
2219 /* Frame from BSSID of the AP for which we are a client */
2220 skb->dev = dev = ieee->stadev;
2221 stats = hostap_get_stats(dev);
2222 from_assoc_ap = 1;
2223 }
2224#endif
2225
2226 dev->last_rx = jiffies;
2227
2228#ifdef NOT_YET
2229 if ((ieee->iw_mode == IW_MODE_MASTER ||
2230 ieee->iw_mode == IW_MODE_REPEAT) &&
2231 !from_assoc_ap) {
2232 switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
2233 wds != NULL)) {
2234 case AP_RX_CONTINUE_NOT_AUTHORIZED:
2235 frame_authorized = 0;
2236 break;
2237 case AP_RX_CONTINUE:
2238 frame_authorized = 1;
2239 break;
2240 case AP_RX_DROP:
2241 goto rx_dropped;
2242 case AP_RX_EXIT:
2243 goto rx_exit;
2244 }
2245 }
2246#endif
2247 /* Nullfunc frames may have PS-bit set, so they must be passed to
2248 * hostap_handle_sta_rx() before being dropped here. */
2249 if (stype != RTLLIB_STYPE_DATA &&
2250 stype != RTLLIB_STYPE_DATA_CFACK &&
2251 stype != RTLLIB_STYPE_DATA_CFPOLL &&
2252 stype != RTLLIB_STYPE_DATA_CFACKPOLL&&
2253 stype != RTLLIB_STYPE_QOS_DATA
2254 ) {
2255 if (stype != RTLLIB_STYPE_NULLFUNC)
2256 RTLLIB_DEBUG_DROP(
2257 "RX: dropped data frame "
2258 "with no data (type=0x%02x, "
2259 "subtype=0x%02x, len=%d)\n",
2260 type, stype, skb->len);
2261 goto rx_dropped;
2262 }
2263
2264 if (skb->len == hdrlen){
2265 goto rx_dropped;
2266 }
2267
2268 {
2269 /* network filter more precisely */
2270 switch (ieee->iw_mode) {
2271 case IW_MODE_ADHOC:
2272 /* packets from our adapter are dropped (echo) */
2273 if (!memcmp(hdr->addr2, dev->dev_addr, ETH_ALEN))
2274 goto rx_dropped;
2275
2276 /* {broad,multi}cast packets to our BSSID go through */
2277 if (is_multicast_ether_addr(hdr->addr1)) {
2278 if (!memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))
2279 break;
2280 else
2281 goto rx_dropped;
2282 }
2283
2284 /* packets not to our adapter, just discard it */
2285 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
2286 if (bToOtherSTA)
2287 break;
2288 else
2289 goto rx_dropped;
2290 }
2291
2292 break;
2293
2294 case IW_MODE_INFRA:
2295 /* packets from our adapter are dropped (echo) */
2296 if (!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
2297 goto rx_dropped;
2298
2299 /* {broad,multi}cast packets to our BSS go through */
2300 if (is_multicast_ether_addr(hdr->addr1)) {
2301 if (!memcmp(hdr->addr2, ieee->current_network.bssid, ETH_ALEN))
2302 break;
2303 else
2304 goto rx_dropped;
2305 }
2306
2307 /* packets to our adapter go through */
2308 if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
2309 if (bToOtherSTA)
2310 break;
2311 else
2312 goto rx_dropped;
2313 }
2314
2315 break;
2316 }
2317
2318
2319 }
2320
2321 if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == LPS_IS_SLEEP)
2322 && (ieee->polling)) {
2323 if (WLAN_FC_MORE_DATA(fc)) {
2324 /* more data bit is set, let's request a new frame from the AP */
2325 rtllib_sta_ps_send_pspoll_frame(ieee);
2326 } else {
2327 ieee->polling = false;
2328 }
2329 }
2330
2331#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
2332 if (ieee->iw_mode == IW_MODE_ADHOC){
2333 psta = GetStaInfo(ieee, src);
2334 if (NULL != psta)
2335 psta->LastActiveTime = jiffies;
2336 }
2337#endif
2338 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
2339 if ((!rx_stats->Decrypted)){
2340 ieee->need_sw_enc = 1;
2341 }
2342
2343 if (ieee->host_decrypt && (fc & RTLLIB_FCTL_WEP) &&
2344 ((keyidx = rtllib_rx_frame_decrypt(ieee, skb, crypt)) < 0)) {
2345 printk("decrypt frame error\n");
2346 goto rx_dropped;
2347 }
2348 if (tmp_dump) {
2349 printk("************after decrypt\n");
2350 dump_buf(skb->data,skb->len);
2351 }
2352 hdr = (struct rtllib_hdr_4addr *) skb->data;
2353
2354 /* skb: hdr + (possibly fragmented) plaintext payload */
2355 if ((frag != 0 || (fc & RTLLIB_FCTL_MOREFRAGS))) {
2356 int flen;
2357 struct sk_buff *frag_skb = rtllib_frag_cache_get(ieee, hdr);
2358 RTLLIB_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
2359
2360 if (!frag_skb) {
2361 RTLLIB_DEBUG(RTLLIB_DL_RX | RTLLIB_DL_FRAG,
2362 "Rx cannot get skb from fragment "
2363 "cache (morefrag=%d seq=%u frag=%u)\n",
2364 (fc & RTLLIB_FCTL_MOREFRAGS) != 0,
2365 WLAN_GET_SEQ_SEQ(sc), frag);
2366 goto rx_dropped;
2367 }
2368 flen = skb->len;
2369 if (frag != 0)
2370 flen -= hdrlen;
2371
2372 if (frag_skb->tail + flen > frag_skb->end) {
2373 printk(KERN_WARNING "%s: host decrypted and "
2374 "reassembled frame did not fit skb\n",
2375 dev->name);
2376 rtllib_frag_cache_invalidate(ieee, hdr);
2377 goto rx_dropped;
2378 }
2379
2380 if (frag == 0) {
2381 /* copy first fragment (including full headers) into
2382 * beginning of the fragment cache skb */
2383 memcpy(skb_put(frag_skb, flen), skb->data, flen);
2384 } else {
2385 /* append frame payload to the end of the fragment
2386 * cache skb */
2387 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
2388 flen);
2389 }
2390 dev_kfree_skb_any(skb);
2391 skb = NULL;
2392
2393 if (fc & RTLLIB_FCTL_MOREFRAGS) {
2394 /* more fragments expected - leave the skb in fragment
2395 * cache for now; it will be delivered to upper layers
2396 * after all fragments have been received */
2397 goto rx_exit;
2398 }
2399
2400 /* this was the last fragment and the frame will be
2401 * delivered, so remove skb from fragment cache */
2402 skb = frag_skb;
2403 hdr = (struct rtllib_hdr_4addr *) skb->data;
2404 rtllib_frag_cache_invalidate(ieee, hdr);
2405 }
2406
2407 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
2408 * encrypted/authenticated */
2409 if (ieee->host_decrypt && (fc & RTLLIB_FCTL_WEP) &&
2410 rtllib_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) {
2411 printk("==>decrypt msdu error\n");
2412 goto rx_dropped;
2413 }
2414
2415 ieee->LinkDetectInfo.NumRecvDataInPeriod++;
2416 ieee->LinkDetectInfo.NumRxOkInPeriod++;
2417
2418 hdr = (struct rtllib_hdr_4addr *) skb->data;
2419 if ((!is_multicast_ether_addr(hdr->addr1)) && (!is_broadcast_ether_addr(hdr->addr1)))
2420 unicast_packet = true;
2421 if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep) {
2422 if (/*ieee->ieee802_1x &&*/
2423 rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
2424
2425#ifdef CONFIG_RTLLIB_DEBUG
2426 /* pass unencrypted EAPOL frames even if encryption is
2427 * configured */
2428 struct eapol *eap = (struct eapol *)(skb->data +
2429 24);
2430 RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
2431 eap_get_type(eap->type));
2432#endif
2433 } else {
2434 RTLLIB_DEBUG_DROP(
2435 "encryption configured, but RX "
2436 "frame not encrypted (SA=" MAC_FMT ")\n",
2437 MAC_ARG(hdr->addr2));
2438 goto rx_dropped;
2439 }
2440 }
2441
2442#ifdef CONFIG_RTLLIB_DEBUG
2443 if (crypt && !(fc & RTLLIB_FCTL_WEP) &&
2444 rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
2445 struct eapol *eap = (struct eapol *)(skb->data +
2446 24);
2447 RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
2448 eap_get_type(eap->type));
2449 }
2450#endif
2451
2452 if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep &&
2453 !rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
2454 RTLLIB_DEBUG_DROP(
2455 "dropped unencrypted RX data "
2456 "frame from " MAC_FMT
2457 " (drop_unencrypted=1)\n",
2458 MAC_ARG(hdr->addr2));
2459 goto rx_dropped;
2460 }
2461 if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data)
2462 && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1)) {
2463 TID = Frame_QoSTID(skb->data);
2464 SeqNum = WLAN_GET_SEQ_SEQ(sc);
2465 GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true);
2466 if (TID !=0 && TID !=3)
2467 ieee->bis_any_nonbepkts = true;
2468 }
2469 /* skb: hdr + (possible reassembled) full plaintext payload */
2470 payload = skb->data + hdrlen;
2471 rxb = (struct rtllib_rxb*)kmalloc(sizeof(struct rtllib_rxb),GFP_ATOMIC);
2472 if (rxb == NULL) {
2473 RTLLIB_DEBUG(RTLLIB_DL_ERR,"%s(): kmalloc rxb error\n",__func__);
2474 goto rx_dropped;
2475 }
2476 /* to parse amsdu packets */
2477 /* qos data packets & reserved bit is 1 */
2478 if (parse_subframe(ieee,skb,rx_stats,rxb,src,dst) == 0) {
2479 /* only to free rxb, and not submit the packets to upper layer */
2480 for (i =0; i < rxb->nr_subframes; i++) {
2481 dev_kfree_skb(rxb->subframes[i]);
2482 }
2483 kfree(rxb);
2484 rxb = NULL;
2485 goto rx_dropped;
2486 }
2487#if !defined(RTL8192SU) && !defined(RTL8192U)
2488 if (unicast_packet) {
2489 if (type == RTLLIB_FTYPE_DATA) {
2490 if (ieee->bIsAggregateFrame)
2491 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod+=rxb->nr_subframes;
2492 else
2493 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod++;
2494
2495 if ((ieee->state == RTLLIB_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) {
2496 if (((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
2497 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) {
2498 if (ieee->LeisurePSLeave)
2499 ieee->LeisurePSLeave(dev);
2500 }
2501 }
2502 }
2503 }
2504#endif
2505 ieee->last_rx_ps_time = jiffies;
2506 if (ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL || bToOtherSTA ){
2507 for (i = 0; i<rxb->nr_subframes; i++) {
2508 struct sk_buff *sub_skb = rxb->subframes[i];
2509
2510 if (sub_skb) {
2511 /* convert hdr + possible LLC headers into Ethernet header */
2512 ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
2513 if (sub_skb->len >= 8 &&
2514 ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
2515 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
2516 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
2517 /* remove RFC1042 or Bridge-Tunnel encapsulation and
2518 * replace EtherType */
2519 skb_pull(sub_skb, SNAP_SIZE);
2520 memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
2521 memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
2522 } else {
2523 u16 len;
2524 /* Leave Ethernet header part of hdr and full payload */
2525 len = htons(sub_skb->len);
2526 memcpy(skb_push(sub_skb, 2), &len, 2);
2527 memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
2528 memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
2529 }
2530
2531 stats->rx_packets++;
2532 stats->rx_bytes += sub_skb->len;
2533
2534 if (is_multicast_ether_addr(dst)) {
2535 stats->multicast++;
2536 }
2537
2538 /* Indicat the packets to upper layer */
2539 memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
2540 sub_skb->protocol = eth_type_trans(sub_skb, dev);
2541 sub_skb->dev = dev;
2542 sub_skb->dev->stats.rx_packets++;
2543 sub_skb->dev->stats.rx_bytes += sub_skb->len;
2544#ifdef TCP_CSUM_OFFLOAD_RX
2545 if ( rx_stats->tcp_csum_valid)
2546 sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
2547 else
2548 sub_skb->ip_summed = CHECKSUM_NONE;
2549#else
2550 sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
2551#endif
2552
2553 netif_rx(sub_skb);
2554 }
2555 }
2556 kfree(rxb);
2557 rxb = NULL;
2558
2559 }
2560 else
2561 {
2562 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__func__);
2563#ifdef TCP_CSUM_OFFLOAD_RX
2564 rxb->tcp_csum_valid = rx_stats->tcp_csum_valid;
2565#endif
2566 RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
2567 }
2568#ifndef JOHN_NOCPY
2569 dev_kfree_skb(skb);
2570#endif
2571
2572 rx_exit:
2573#ifdef NOT_YET
2574 if (sta)
2575 hostap_handle_sta_release(sta);
2576#endif
2577 return 1;
2578
2579 rx_dropped:
2580 if (rxb != NULL)
2581 {
2582 kfree(rxb);
2583 rxb = NULL;
2584 }
2585 stats->rx_dropped++;
2586
2587 /* Returning 0 indicates to caller that we have not handled the SKB--
2588 * so it is still allocated and can be used again by underlying
2589 * hardware as a DMA target */
2590 return 0;
2591}
2592#endif
2593
2594#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
2595
2596static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
2597
2598/*
2599* Make ther structure we read from the beacon packet has
2600* the right values
2601*/
2602static int rtllib_verify_qos_info(struct rtllib_qos_information_element
2603 *info_element, int sub_type)
2604{
2605
2606 if (info_element->qui_subtype != sub_type)
2607 return -1;
2608 if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
2609 return -1;
2610 if (info_element->qui_type != QOS_OUI_TYPE)
2611 return -1;
2612 if (info_element->version != QOS_VERSION_1)
2613 return -1;
2614
2615 return 0;
2616}
2617
2618
2619/*
2620 * Parse a QoS parameter element
2621 */
2622static int rtllib_read_qos_param_element(struct rtllib_qos_parameter_info
2623 *element_param, struct rtllib_info_element
2624 *info_element)
2625{
2626 int ret = 0;
2627 u16 size = sizeof(struct rtllib_qos_parameter_info) - 2;
2628
2629 if ((info_element == NULL) || (element_param == NULL))
2630 return -1;
2631
2632 if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
2633 memcpy(element_param->info_element.qui, info_element->data,
2634 info_element->len);
2635 element_param->info_element.elementID = info_element->id;
2636 element_param->info_element.length = info_element->len;
2637 } else
2638 ret = -1;
2639 if (ret == 0)
2640 ret = rtllib_verify_qos_info(&element_param->info_element,
2641 QOS_OUI_PARAM_SUB_TYPE);
2642 return ret;
2643}
2644
2645/*
2646 * Parse a QoS information element
2647 */
2648static int rtllib_read_qos_info_element(struct
2649 rtllib_qos_information_element
2650 *element_info, struct rtllib_info_element
2651 *info_element)
2652{
2653 int ret = 0;
2654 u16 size = sizeof(struct rtllib_qos_information_element) - 2;
2655
2656 if (element_info == NULL)
2657 return -1;
2658 if (info_element == NULL)
2659 return -1;
2660
2661 if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
2662 memcpy(element_info->qui, info_element->data,
2663 info_element->len);
2664 element_info->elementID = info_element->id;
2665 element_info->length = info_element->len;
2666 } else
2667 ret = -1;
2668
2669 if (ret == 0)
2670 ret = rtllib_verify_qos_info(element_info,
2671 QOS_OUI_INFO_SUB_TYPE);
2672 return ret;
2673}
2674
2675
2676/*
2677 * Write QoS parameters from the ac parameters.
2678 */
2679static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info *param_elm,
2680 struct rtllib_qos_data *qos_data)
2681{
2682 struct rtllib_qos_ac_parameter *ac_params;
2683 struct rtllib_qos_parameters *qos_param = &(qos_data->parameters);
2684 int rc = 0;
2685 int i;
2686 u8 aci;
2687 u8 acm;
2688
2689 qos_data->wmm_acm = 0;
2690 for (i = 0; i < QOS_QUEUE_NUM; i++) {
2691 ac_params = &(param_elm->ac_params_record[i]);
2692
2693 aci = (ac_params->aci_aifsn & 0x60) >> 5;
2694 acm = (ac_params->aci_aifsn & 0x10) >> 4;
2695
2696 if (aci >= QOS_QUEUE_NUM)
2697 continue;
2698 switch (aci) {
2699 case 1:
2700 /* BIT(0) | BIT(3) */
2701 if (acm)
2702 qos_data->wmm_acm |= (0x01<<0)|(0x01<<3);
2703 break;
2704 case 2:
2705 /* BIT(4) | BIT(5) */
2706 if (acm)
2707 qos_data->wmm_acm |= (0x01<<4)|(0x01<<5);
2708 break;
2709 case 3:
2710 /* BIT(6) | BIT(7) */
2711 if (acm)
2712 qos_data->wmm_acm |= (0x01<<6)|(0x01<<7);
2713 break;
2714 case 0:
2715 default:
2716 /* BIT(1) | BIT(2) */
2717 if (acm)
2718 qos_data->wmm_acm |= (0x01<<1)|(0x01<<2);
2719 break;
2720 }
2721
2722 qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
2723
2724 /* WMM spec P.11: The minimum value for AIFSN shall be 2 */
2725 qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci];
2726
2727 qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
2728
2729 qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
2730
2731 qos_param->flag[aci] =
2732 (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
2733 qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
2734 }
2735 return rc;
2736}
2737
2738/*
2739 * we have a generic data element which it may contain QoS information or
2740 * parameters element. check the information element length to decide
2741 * which type to read
2742 */
2743static int rtllib_parse_qos_info_param_IE(struct rtllib_info_element
2744 *info_element,
2745 struct rtllib_network *network)
2746{
2747 int rc = 0;
2748 struct rtllib_qos_information_element qos_info_element;
2749
2750 rc = rtllib_read_qos_info_element(&qos_info_element, info_element);
2751
2752 if (rc == 0) {
2753 network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
2754 network->flags |= NETWORK_HAS_QOS_INFORMATION;
2755 } else {
2756 struct rtllib_qos_parameter_info param_element;
2757
2758 rc = rtllib_read_qos_param_element(&param_element,
2759 info_element);
2760 if (rc == 0) {
2761 rtllib_qos_convert_ac_to_parameters(&param_element,
2762 &(network->qos_data));
2763 network->flags |= NETWORK_HAS_QOS_PARAMETERS;
2764 network->qos_data.param_count =
2765 param_element.info_element.ac_info & 0x0F;
2766 }
2767 }
2768
2769 if (rc == 0) {
2770 RTLLIB_DEBUG_QOS("QoS is supported\n");
2771 network->qos_data.supported = 1;
2772 }
2773 return rc;
2774}
2775
2776#ifdef CONFIG_RTLLIB_DEBUG
2777#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
2778
2779static const char *get_info_element_string(u16 id)
2780{
2781 switch (id) {
2782 MFIE_STRING(SSID);
2783 MFIE_STRING(RATES);
2784 MFIE_STRING(FH_SET);
2785 MFIE_STRING(DS_SET);
2786 MFIE_STRING(CF_SET);
2787 MFIE_STRING(TIM);
2788 MFIE_STRING(IBSS_SET);
2789 MFIE_STRING(COUNTRY);
2790 MFIE_STRING(HOP_PARAMS);
2791 MFIE_STRING(HOP_TABLE);
2792 MFIE_STRING(REQUEST);
2793 MFIE_STRING(CHALLENGE);
2794 MFIE_STRING(POWER_CONSTRAINT);
2795 MFIE_STRING(POWER_CAPABILITY);
2796 MFIE_STRING(TPC_REQUEST);
2797 MFIE_STRING(TPC_REPORT);
2798 MFIE_STRING(SUPP_CHANNELS);
2799 MFIE_STRING(CSA);
2800 MFIE_STRING(MEASURE_REQUEST);
2801 MFIE_STRING(MEASURE_REPORT);
2802 MFIE_STRING(QUIET);
2803 MFIE_STRING(IBSS_DFS);
2804 MFIE_STRING(RSN);
2805 MFIE_STRING(RATES_EX);
2806 MFIE_STRING(GENERIC);
2807 MFIE_STRING(QOS_PARAMETER);
2808 default:
2809 return "UNKNOWN";
2810 }
2811}
2812#endif
2813
2814#ifdef ENABLE_DOT11D
2815static inline void rtllib_extract_country_ie(
2816 struct rtllib_device *ieee,
2817 struct rtllib_info_element *info_element,
2818 struct rtllib_network *network,
2819 u8 * addr2)
2820{
2821 if (IS_DOT11D_ENABLE(ieee)) {
2822 if (info_element->len!= 0) {
2823 memcpy(network->CountryIeBuf, info_element->data, info_element->len);
2824 network->CountryIeLen = info_element->len;
2825
2826 if (!IS_COUNTRY_IE_VALID(ieee))
2827 {
2828 if ((rtllib_act_scanning(ieee,false) == true) && (ieee->FirstIe_InScan == 1))
2829 printk("Received beacon ContryIE, SSID: <%s>\n",network->ssid);
2830 Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
2831 }
2832 }
2833
2834 if (IS_EQUAL_CIE_SRC(ieee, addr2)) {
2835 UPDATE_CIE_WATCHDOG(ieee);
2836 }
2837 }
2838
2839}
2840#endif
2841
2842int rtllib_parse_info_param(struct rtllib_device *ieee,
2843 struct rtllib_info_element *info_element,
2844 u16 length,
2845 struct rtllib_network *network,
2846 struct rtllib_rx_stats *stats)
2847{
2848 u8 i;
2849 short offset;
2850 u16 tmp_htcap_len=0;
2851 u16 tmp_htinfo_len=0;
2852 u16 ht_realtek_agg_len=0;
2853 u8 ht_realtek_agg_buf[MAX_IE_LEN];
2854#ifdef CONFIG_RTLLIB_DEBUG
2855 char rates_str[64];
2856 char *p;
2857#endif
2858 while (length >= sizeof(*info_element)) {
2859 if (sizeof(*info_element) + info_element->len > length) {
2860 RTLLIB_DEBUG_MGMT("Info elem: parse failed: "
2861 "info_element->len + 2 > left : "
2862 "info_element->len+2=%zd left=%d, id=%d.\n",
2863 info_element->len +
2864 sizeof(*info_element),
2865 length, info_element->id);
2866 /* We stop processing but don't return an error here
2867 * because some misbehaviour APs break this rule. ie.
2868 * Orinoco AP1000. */
2869 break;
2870 }
2871
2872 switch (info_element->id) {
2873 case MFIE_TYPE_SSID:
2874 if (rtllib_is_empty_essid(info_element->data,
2875 info_element->len)) {
2876 network->flags |= NETWORK_EMPTY_ESSID;
2877 break;
2878 }
2879
2880 network->ssid_len = min(info_element->len,
2881 (u8) IW_ESSID_MAX_SIZE);
2882 memcpy(network->ssid, info_element->data, network->ssid_len);
2883 if (network->ssid_len < IW_ESSID_MAX_SIZE)
2884 memset(network->ssid + network->ssid_len, 0,
2885 IW_ESSID_MAX_SIZE - network->ssid_len);
2886
2887 RTLLIB_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
2888 network->ssid, network->ssid_len);
2889 break;
2890
2891 case MFIE_TYPE_RATES:
2892#ifdef CONFIG_RTLLIB_DEBUG
2893 p = rates_str;
2894#endif
2895 network->rates_len = min(info_element->len,
2896 MAX_RATES_LENGTH);
2897 for (i = 0; i < network->rates_len; i++) {
2898 network->rates[i] = info_element->data[i];
2899#ifdef CONFIG_RTLLIB_DEBUG
2900 p += snprintf(p, sizeof(rates_str) -
2901 (p - rates_str), "%02X ",
2902 network->rates[i]);
2903#endif
2904 if (rtllib_is_ofdm_rate
2905 (info_element->data[i])) {
2906 network->flags |= NETWORK_HAS_OFDM;
2907 if (info_element->data[i] &
2908 RTLLIB_BASIC_RATE_MASK)
2909 network->flags &=
2910 ~NETWORK_HAS_CCK;
2911 }
2912
2913 if (rtllib_is_cck_rate
2914 (info_element->data[i])) {
2915 network->flags |= NETWORK_HAS_CCK;
2916 }
2917 }
2918
2919 RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
2920 rates_str, network->rates_len);
2921 break;
2922
2923 case MFIE_TYPE_RATES_EX:
2924#ifdef CONFIG_RTLLIB_DEBUG
2925 p = rates_str;
2926#endif
2927 network->rates_ex_len = min(info_element->len,
2928 MAX_RATES_EX_LENGTH);
2929 for (i = 0; i < network->rates_ex_len; i++) {
2930 network->rates_ex[i] = info_element->data[i];
2931#ifdef CONFIG_RTLLIB_DEBUG
2932 p += snprintf(p, sizeof(rates_str) -
2933 (p - rates_str), "%02X ",
2934 network->rates[i]);
2935#endif
2936 if (rtllib_is_ofdm_rate
2937 (info_element->data[i])) {
2938 network->flags |= NETWORK_HAS_OFDM;
2939 if (info_element->data[i] &
2940 RTLLIB_BASIC_RATE_MASK)
2941 network->flags &=
2942 ~NETWORK_HAS_CCK;
2943 }
2944 }
2945
2946 RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
2947 rates_str, network->rates_ex_len);
2948 break;
2949
2950 case MFIE_TYPE_DS_SET:
2951 RTLLIB_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
2952 info_element->data[0]);
2953 network->channel = info_element->data[0];
2954 break;
2955
2956 case MFIE_TYPE_FH_SET:
2957 RTLLIB_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
2958 break;
2959
2960 case MFIE_TYPE_CF_SET:
2961 RTLLIB_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
2962 break;
2963
2964 case MFIE_TYPE_TIM:
2965 if (info_element->len < 4)
2966 break;
2967
2968 network->tim.tim_count = info_element->data[0];
2969 network->tim.tim_period = info_element->data[1];
2970
2971 network->dtim_period = info_element->data[1];
2972 if (ieee->state != RTLLIB_LINKED)
2973 break;
2974 network->last_dtim_sta_time[0] = jiffies;
2975 network->last_dtim_sta_time[1] = stats->mac_time[1];
2976
2977 network->dtim_data = RTLLIB_DTIM_VALID;
2978
2979
2980 if (info_element->data[2] & 1)
2981 network->dtim_data |= RTLLIB_DTIM_MBCAST;
2982
2983#if 1
2984 offset = (info_element->data[2] >> 1)*2;
2985
2986
2987 if (ieee->assoc_id < 8*offset ||
2988 ieee->assoc_id > 8*(offset + info_element->len -3))
2989
2990 break;
2991
2992 offset = (ieee->assoc_id / 8) - offset;
2993 if (info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
2994 network->dtim_data |= RTLLIB_DTIM_UCAST;
2995#else
2996 {
2997 u16 numSta = 0;
2998 u16 offset_byte = 0;
2999 u16 offset_bit = 0;
3000
3001 numSta = (info_element->data[2] &0xFE)*8;
3002
3003 if (ieee->assoc_id < numSta ||
3004 ieee->assoc_id > (numSta + (info_element->len -3)*8))
3005 break;
3006
3007 offset = ieee->assoc_id - numSta;
3008 offset_byte = offset / 8;
3009 offset_bit = offset % 8;
3010 if (info_element->data[3+offset_byte] & (0x01<<offset_bit))
3011 network->dtim_data |= RTLLIB_DTIM_UCAST;
3012 }
3013#endif
3014
3015 network->listen_interval = network->dtim_period;
3016 break;
3017
3018 case MFIE_TYPE_ERP:
3019 network->erp_value = info_element->data[0];
3020 network->flags |= NETWORK_HAS_ERP_VALUE;
3021 RTLLIB_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
3022 network->erp_value);
3023 break;
3024 case MFIE_TYPE_IBSS_SET:
3025 network->atim_window = info_element->data[0];
3026 RTLLIB_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
3027 network->atim_window);
3028 break;
3029
3030 case MFIE_TYPE_CHALLENGE:
3031 RTLLIB_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
3032 break;
3033
3034 case MFIE_TYPE_GENERIC:
3035 RTLLIB_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
3036 info_element->len);
3037 if (!rtllib_parse_qos_info_param_IE(info_element,
3038 network))
3039 break;
3040 if (info_element->len >= 4 &&
3041 info_element->data[0] == 0x00 &&
3042 info_element->data[1] == 0x50 &&
3043 info_element->data[2] == 0xf2 &&
3044 info_element->data[3] == 0x01) {
3045 network->wpa_ie_len = min(info_element->len + 2,
3046 MAX_WPA_IE_LEN);
3047 memcpy(network->wpa_ie, info_element,
3048 network->wpa_ie_len);
3049 break;
3050 }
3051 if (info_element->len == 7 &&
3052 info_element->data[0] == 0x00 &&
3053 info_element->data[1] == 0xe0 &&
3054 info_element->data[2] == 0x4c &&
3055 info_element->data[3] == 0x01 &&
3056 info_element->data[4] == 0x02)
3057 network->Turbo_Enable = 1;
3058
3059 if (tmp_htcap_len == 0) {
3060 if (info_element->len >= 4 &&
3061 info_element->data[0] == 0x00 &&
3062 info_element->data[1] == 0x90 &&
3063 info_element->data[2] == 0x4c &&
3064 info_element->data[3] == 0x033) {
3065
3066 tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
3067 if (tmp_htcap_len != 0){
3068 network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
3069 network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
3070 sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
3071 memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
3072 }
3073 }
3074 if (tmp_htcap_len != 0){
3075 network->bssht.bdSupportHT = true;
3076 network->bssht.bdHT1R = ((((PHT_CAPABILITY_ELE)(network->bssht.bdHTCapBuf))->MCS[1]) == 0);
3077 }else{
3078 network->bssht.bdSupportHT = false;
3079 network->bssht.bdHT1R = false;
3080 }
3081 }
3082
3083
3084 if (tmp_htinfo_len == 0){
3085 if (info_element->len >= 4 &&
3086 info_element->data[0] == 0x00 &&
3087 info_element->data[1] == 0x90 &&
3088 info_element->data[2] == 0x4c &&
3089 info_element->data[3] == 0x034){
3090
3091 tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
3092 if (tmp_htinfo_len != 0){
3093 network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
3094 if (tmp_htinfo_len){
3095 network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
3096 sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
3097 memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
3098 }
3099
3100 }
3101
3102 }
3103 }
3104
3105 if (ieee->aggregation){
3106 if (network->bssht.bdSupportHT){
3107 if (info_element->len >= 4 &&
3108 info_element->data[0] == 0x00 &&
3109 info_element->data[1] == 0xe0 &&
3110 info_element->data[2] == 0x4c &&
3111 info_element->data[3] == 0x02){
3112
3113 ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN);
3114 memcpy(ht_realtek_agg_buf,info_element->data,info_element->len);
3115
3116 }
3117 if (ht_realtek_agg_len >= 5){
3118 network->realtek_cap_exit = true;
3119 network->bssht.bdRT2RTAggregation = true;
3120
3121 if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02))
3122 network->bssht.bdRT2RTLongSlotTime = true;
3123
3124 if ((ht_realtek_agg_buf[4]==1) && (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE))
3125 {
3126 network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE;
3127 }
3128 }
3129 }
3130 if (ht_realtek_agg_len >= 5){
3131 if ((ht_realtek_agg_buf[5] & RT_HT_CAP_USE_SOFTAP))
3132 network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_SOFTAP;
3133 }
3134 }
3135
3136 {
3137 if ((info_element->len >= 3 &&
3138 info_element->data[0] == 0x00 &&
3139 info_element->data[1] == 0x05 &&
3140 info_element->data[2] == 0xb5) ||
3141 (info_element->len >= 3 &&
3142 info_element->data[0] == 0x00 &&
3143 info_element->data[1] == 0x0a &&
3144 info_element->data[2] == 0xf7) ||
3145 (info_element->len >= 3 &&
3146 info_element->data[0] == 0x00 &&
3147 info_element->data[1] == 0x10 &&
3148 info_element->data[2] == 0x18)){
3149
3150 network->broadcom_cap_exist = true;
3151
3152 }
3153 }
3154 if (info_element->len >= 3 &&
3155 info_element->data[0] == 0x00 &&
3156 info_element->data[1] == 0x0c &&
3157 info_element->data[2] == 0x43)
3158 {
3159 network->ralink_cap_exist = true;
3160 }
3161 if ((info_element->len >= 3 &&
3162 info_element->data[0] == 0x00 &&
3163 info_element->data[1] == 0x03 &&
3164 info_element->data[2] == 0x7f) ||
3165 (info_element->len >= 3 &&
3166 info_element->data[0] == 0x00 &&
3167 info_element->data[1] == 0x13 &&
3168 info_element->data[2] == 0x74))
3169 {
3170 network->atheros_cap_exist = true;
3171 }
3172
3173 if ((info_element->len >= 3 &&
3174 info_element->data[0] == 0x00 &&
3175 info_element->data[1] == 0x50 &&
3176 info_element->data[2] == 0x43) )
3177 {
3178 network->marvell_cap_exist = true;
3179 }
3180 if (info_element->len >= 3 &&
3181 info_element->data[0] == 0x00 &&
3182 info_element->data[1] == 0x40 &&
3183 info_element->data[2] == 0x96)
3184 {
3185 network->cisco_cap_exist = true;
3186 }
3187
3188
3189 if (info_element->len >= 3 &&
3190 info_element->data[0] == 0x00 &&
3191 info_element->data[1] == 0x0a &&
3192 info_element->data[2] == 0xf5)
3193 {
3194 network->airgo_cap_exist = true;
3195 }
3196
3197 if (info_element->len > 4 &&
3198 info_element->data[0] == 0x00 &&
3199 info_element->data[1] == 0x40 &&
3200 info_element->data[2] == 0x96 &&
3201 info_element->data[3] == 0x01)
3202 {
3203 if (info_element->len == 6)
3204 {
3205 memcpy(network->CcxRmState, &info_element[4], 2);
3206 if (network->CcxRmState[0] != 0)
3207 {
3208 network->bCcxRmEnable = true;
3209 }
3210 else
3211 network->bCcxRmEnable = false;
3212 network->MBssidMask = network->CcxRmState[1] & 0x07;
3213 if (network->MBssidMask != 0)
3214 {
3215 network->bMBssidValid = true;
3216 network->MBssidMask = 0xff << (network->MBssidMask);
3217 memcpy(network->MBssid, network->bssid, ETH_ALEN);
3218 network->MBssid[5] &= network->MBssidMask;
3219 }
3220 else
3221 {
3222 network->bMBssidValid = false;
3223 }
3224 }
3225 else
3226 {
3227 network->bCcxRmEnable = false;
3228 }
3229 }
3230 if (info_element->len > 4 &&
3231 info_element->data[0] == 0x00 &&
3232 info_element->data[1] == 0x40 &&
3233 info_element->data[2] == 0x96 &&
3234 info_element->data[3] == 0x03)
3235 {
3236 if (info_element->len == 5)
3237 {
3238 network->bWithCcxVerNum = true;
3239 network->BssCcxVerNumber = info_element->data[4];
3240 }
3241 else
3242 {
3243 network->bWithCcxVerNum = false;
3244 network->BssCcxVerNumber = 0;
3245 }
3246 }
3247 if (info_element->len > 4 &&
3248 info_element->data[0] == 0x00 &&
3249 info_element->data[1] == 0x50 &&
3250 info_element->data[2] == 0xf2 &&
3251 info_element->data[3] == 0x04)
3252 {
3253 RTLLIB_DEBUG_MGMT("MFIE_TYPE_WZC: %d bytes\n",
3254 info_element->len);
3255#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3256 network->wzc_ie_len = min(info_element->len+2,
3257 MAX_WZC_IE_LEN);
3258 memcpy(network->wzc_ie, info_element,
3259 network->wzc_ie_len);
3260#endif
3261 }
3262 break;
3263
3264 case MFIE_TYPE_RSN:
3265 RTLLIB_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
3266 info_element->len);
3267 network->rsn_ie_len = min(info_element->len + 2,
3268 MAX_WPA_IE_LEN);
3269 memcpy(network->rsn_ie, info_element,
3270 network->rsn_ie_len);
3271 break;
3272
3273 case MFIE_TYPE_HT_CAP:
3274 RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n",
3275 info_element->len);
3276 tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
3277 if (tmp_htcap_len != 0){
3278 network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
3279 network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
3280 sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
3281 memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
3282
3283 network->bssht.bdSupportHT = true;
3284 network->bssht.bdHT1R = ((((PHT_CAPABILITY_ELE)(network->bssht.bdHTCapBuf))->MCS[1]) == 0);
3285
3286 network->bssht.bdBandWidth = (HT_CHANNEL_WIDTH)(((PHT_CAPABILITY_ELE)(network->bssht.bdHTCapBuf))->ChlWidth);
3287 }
3288 else{
3289 network->bssht.bdSupportHT = false;
3290 network->bssht.bdHT1R = false;
3291 network->bssht.bdBandWidth = HT_CHANNEL_WIDTH_20 ;
3292 }
3293 break;
3294
3295
3296 case MFIE_TYPE_HT_INFO:
3297 RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n",
3298 info_element->len);
3299 tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
3300 if (tmp_htinfo_len){
3301 network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE;
3302 network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
3303 sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
3304 memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
3305 }
3306 break;
3307
3308 case MFIE_TYPE_AIRONET:
3309 RTLLIB_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n",
3310 info_element->len);
3311 if (info_element->len >IE_CISCO_FLAG_POSITION)
3312 {
3313 network->bWithAironetIE = true;
3314
3315 if ( (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC) ||
3316 (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK) )
3317 {
3318 network->bCkipSupported = true;
3319 }
3320 else
3321 {
3322 network->bCkipSupported = false;
3323 }
3324 }
3325 else
3326 {
3327 network->bWithAironetIE = false;
3328 network->bCkipSupported = false;
3329 }
3330 break;
3331 case MFIE_TYPE_QOS_PARAMETER:
3332 printk(KERN_ERR
3333 "QoS Error need to parse QOS_PARAMETER IE\n");
3334 break;
3335
3336#ifdef ENABLE_DOT11D
3337 case MFIE_TYPE_COUNTRY:
3338 RTLLIB_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
3339 info_element->len);
3340 rtllib_extract_country_ie(ieee, info_element, network, network->bssid);
3341 break;
3342#endif
3343/* TODO */
3344 default:
3345 RTLLIB_DEBUG_MGMT
3346 ("Unsupported info element: %s (%d)\n",
3347 get_info_element_string(info_element->id),
3348 info_element->id);
3349 break;
3350 }
3351
3352 length -= sizeof(*info_element) + info_element->len;
3353 info_element =
3354 (struct rtllib_info_element *)&info_element->
3355 data[info_element->len];
3356 }
3357
3358 if (!network->atheros_cap_exist && !network->broadcom_cap_exist &&
3359 !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation)
3360 {
3361 network->unknown_cap_exist = true;
3362 }
3363 else
3364 {
3365 network->unknown_cap_exist = false;
3366 }
3367 return 0;
3368}
3369
3370static inline u8 rtllib_SignalStrengthTranslate(
3371 u8 CurrSS
3372 )
3373{
3374 u8 RetSS;
3375
3376 if (CurrSS >= 71 && CurrSS <= 100)
3377 {
3378 RetSS = 90 + ((CurrSS - 70) / 3);
3379 }
3380 else if (CurrSS >= 41 && CurrSS <= 70)
3381 {
3382 RetSS = 78 + ((CurrSS - 40) / 3);
3383 }
3384 else if (CurrSS >= 31 && CurrSS <= 40)
3385 {
3386 RetSS = 66 + (CurrSS - 30);
3387 }
3388 else if (CurrSS >= 21 && CurrSS <= 30)
3389 {
3390 RetSS = 54 + (CurrSS - 20);
3391 }
3392 else if (CurrSS >= 5 && CurrSS <= 20)
3393 {
3394 RetSS = 42 + (((CurrSS - 5) * 2) / 3);
3395 }
3396 else if (CurrSS == 4)
3397 {
3398 RetSS = 36;
3399 }
3400 else if (CurrSS == 3)
3401 {
3402 RetSS = 27;
3403 }
3404 else if (CurrSS == 2)
3405 {
3406 RetSS = 18;
3407 }
3408 else if (CurrSS == 1)
3409 {
3410 RetSS = 9;
3411 }
3412 else
3413 {
3414 RetSS = CurrSS;
3415 }
3416
3417
3418
3419 return RetSS;
3420}
3421
3422long rtllib_translate_todbm(u8 signal_strength_index )
3423{
3424 long signal_power;
3425
3426 signal_power = (long)((signal_strength_index + 1) >> 1);
3427 signal_power -= 95;
3428
3429 return signal_power;
3430}
3431
3432static inline int rtllib_network_init(
3433 struct rtllib_device *ieee,
3434 struct rtllib_probe_response *beacon,
3435 struct rtllib_network *network,
3436 struct rtllib_rx_stats *stats)
3437{
3438#ifdef CONFIG_RTLLIB_DEBUG
3439#endif
3440
3441 /*
3442 network->qos_data.active = 0;
3443 network->qos_data.supported = 0;
3444 network->qos_data.param_count = 0;
3445 network->qos_data.old_param_count = 0;
3446 */
3447 memset(&network->qos_data, 0, sizeof(struct rtllib_qos_data));
3448
3449 /* Pull out fixed field data */
3450 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
3451 network->capability = le16_to_cpu(beacon->capability);
3452 network->last_scanned = jiffies;
3453 network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
3454 network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
3455 network->beacon_interval = le32_to_cpu(beacon->beacon_interval);
3456 /* Where to pull this? beacon->listen_interval;*/
3457 network->listen_interval = 0x0A;
3458 network->rates_len = network->rates_ex_len = 0;
3459 network->last_associate = 0;
3460 network->ssid_len = 0;
3461 network->hidden_ssid_len = 0;
3462 memset(network->hidden_ssid, 0, sizeof(network->hidden_ssid));
3463 network->flags = 0;
3464 network->atim_window = 0;
3465 network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
3466 0x3 : 0x0;
3467 network->berp_info_valid = false;
3468 network->broadcom_cap_exist = false;
3469 network->ralink_cap_exist = false;
3470 network->atheros_cap_exist = false;
3471 network->cisco_cap_exist = false;
3472 network->unknown_cap_exist = false;
3473 network->realtek_cap_exit = false;
3474 network->marvell_cap_exist = false;
3475 network->airgo_cap_exist = false;
3476 network->Turbo_Enable = 0;
3477 network->SignalStrength = stats->SignalStrength;
3478 network->RSSI = stats->SignalStrength;
3479#ifdef ENABLE_DOT11D
3480 network->CountryIeLen = 0;
3481 memset(network->CountryIeBuf, 0, MAX_IE_LEN);
3482#endif
3483 HTInitializeBssDesc(&network->bssht);
3484 if (stats->freq == RTLLIB_52GHZ_BAND) {
3485 /* for A band (No DS info) */
3486 network->channel = stats->received_channel;
3487 } else
3488 network->flags |= NETWORK_HAS_CCK;
3489
3490 network->wpa_ie_len = 0;
3491 network->rsn_ie_len = 0;
3492#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3493 network->wzc_ie_len = 0;
3494#endif
3495
3496 if (rtllib_parse_info_param(ieee,
3497 beacon->info_element,
3498 (stats->len - sizeof(*beacon)),
3499 network,
3500 stats))
3501 return 1;
3502
3503 network->mode = 0;
3504 if (stats->freq == RTLLIB_52GHZ_BAND)
3505 network->mode = IEEE_A;
3506 else {
3507 if (network->flags & NETWORK_HAS_OFDM)
3508 network->mode |= IEEE_G;
3509 if (network->flags & NETWORK_HAS_CCK)
3510 network->mode |= IEEE_B;
3511 }
3512
3513 if (network->mode == 0) {
3514 RTLLIB_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
3515 "network.\n",
3516 escape_essid(network->ssid,
3517 network->ssid_len),
3518 MAC_ARG(network->bssid));
3519 return 1;
3520 }
3521
3522 if (network->bssht.bdSupportHT){
3523 if (network->mode == IEEE_A)
3524 network->mode = IEEE_N_5G;
3525 else if (network->mode & (IEEE_G | IEEE_B))
3526 network->mode = IEEE_N_24G;
3527 }
3528 if (rtllib_is_empty_essid(network->ssid, network->ssid_len))
3529 network->flags |= NETWORK_EMPTY_ESSID;
3530 stats->signal = 30 + (stats->SignalStrength * 70) / 100;
3531 stats->noise = rtllib_translate_todbm((u8)(100-stats->signal)) -25;
3532
3533 memcpy(&network->stats, stats, sizeof(network->stats));
3534
3535 return 0;
3536}
3537
3538static inline int is_same_network(struct rtllib_network *src,
3539 struct rtllib_network *dst, u8 ssidbroad)
3540{
3541 /* A network is only a duplicate if the channel, BSSID, ESSID
3542 * and the capability field (in particular IBSS and BSS) all match.
3543 * We treat all <hidden> with the same BSSID and channel
3544 * as one network */
3545 return
3546 (((src->ssid_len == dst->ssid_len) || (!ssidbroad)) &&
3547 (src->channel == dst->channel) &&
3548 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
3549 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (!ssidbroad)) &&
3550 ((src->capability & WLAN_CAPABILITY_IBSS) ==
3551 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
3552 ((src->capability & WLAN_CAPABILITY_ESS) ==
3553 (dst->capability & WLAN_CAPABILITY_ESS)));
3554}
3555
3556static inline void update_ibss_network(struct rtllib_network *dst,
3557 struct rtllib_network *src)
3558{
3559 memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
3560 dst->last_scanned = jiffies;
3561}
3562
3563
3564static inline void update_network(struct rtllib_network *dst,
3565 struct rtllib_network *src)
3566{
3567 int qos_active;
3568 u8 old_param;
3569
3570 memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
3571 dst->capability = src->capability;
3572 memcpy(dst->rates, src->rates, src->rates_len);
3573 dst->rates_len = src->rates_len;
3574 memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
3575 dst->rates_ex_len = src->rates_ex_len;
3576 if (src->ssid_len > 0)
3577 {
3578 if (dst->ssid_len == 0)
3579 {
3580 memset(dst->hidden_ssid, 0, sizeof(dst->hidden_ssid));
3581 dst->hidden_ssid_len = src->ssid_len;
3582 memcpy(dst->hidden_ssid, src->ssid, src->ssid_len);
3583 }else{
3584 memset(dst->ssid, 0, dst->ssid_len);
3585 dst->ssid_len = src->ssid_len;
3586 memcpy(dst->ssid, src->ssid, src->ssid_len);
3587 }
3588 }
3589 dst->mode = src->mode;
3590 dst->flags = src->flags;
3591 dst->time_stamp[0] = src->time_stamp[0];
3592 dst->time_stamp[1] = src->time_stamp[1];
3593 if (src->flags & NETWORK_HAS_ERP_VALUE)
3594 {
3595 dst->erp_value = src->erp_value;
3596 dst->berp_info_valid = src->berp_info_valid = true;
3597 }
3598 dst->beacon_interval = src->beacon_interval;
3599 dst->listen_interval = src->listen_interval;
3600 dst->atim_window = src->atim_window;
3601 dst->dtim_period = src->dtim_period;
3602 dst->dtim_data = src->dtim_data;
3603 dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
3604 dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
3605 memcpy(&dst->tim, &src->tim, sizeof(struct rtllib_tim_parameters));
3606
3607 dst->bssht.bdSupportHT = src->bssht.bdSupportHT;
3608 dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation;
3609 dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen;
3610 memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen);
3611 dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen;
3612 memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen);
3613 dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer;
3614 dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime;
3615 dst->broadcom_cap_exist = src->broadcom_cap_exist;
3616 dst->ralink_cap_exist = src->ralink_cap_exist;
3617 dst->atheros_cap_exist = src->atheros_cap_exist;
3618 dst->realtek_cap_exit = src->realtek_cap_exit;
3619 dst->marvell_cap_exist = src->marvell_cap_exist;
3620 dst->cisco_cap_exist = src->cisco_cap_exist;
3621 dst->airgo_cap_exist = src->airgo_cap_exist;
3622 dst->unknown_cap_exist = src->unknown_cap_exist;
3623 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
3624 dst->wpa_ie_len = src->wpa_ie_len;
3625 memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
3626 dst->rsn_ie_len = src->rsn_ie_len;
3627#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3628 memcpy(dst->wzc_ie, src->wzc_ie, src->wzc_ie_len);
3629 dst->wzc_ie_len = src->wzc_ie_len;
3630#endif
3631
3632 dst->last_scanned = jiffies;
3633 /* qos related parameters */
3634 qos_active = dst->qos_data.active;
3635 old_param = dst->qos_data.param_count;
3636 dst->qos_data.supported = src->qos_data.supported;
3637 if (dst->flags & NETWORK_HAS_QOS_PARAMETERS)
3638 memcpy(&dst->qos_data, &src->qos_data, sizeof(struct rtllib_qos_data));
3639 if (dst->qos_data.supported == 1) {
3640 if (dst->ssid_len)
3641 RTLLIB_DEBUG_QOS
3642 ("QoS the network %s is QoS supported\n",
3643 dst->ssid);
3644 else
3645 RTLLIB_DEBUG_QOS
3646 ("QoS the network is QoS supported\n");
3647 }
3648 dst->qos_data.active = qos_active;
3649 dst->qos_data.old_param_count = old_param;
3650
3651 /* dst->last_associate is not overwritten */
3652 dst->wmm_info = src->wmm_info;
3653 if (src->wmm_param[0].ac_aci_acm_aifsn|| \
3654 src->wmm_param[1].ac_aci_acm_aifsn|| \
3655 src->wmm_param[2].ac_aci_acm_aifsn|| \
3656 src->wmm_param[1].ac_aci_acm_aifsn) {
3657 memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
3658 }
3659
3660 dst->SignalStrength = src->SignalStrength;
3661 dst->RSSI = src->RSSI;
3662 dst->Turbo_Enable = src->Turbo_Enable;
3663
3664#ifdef ENABLE_DOT11D
3665 dst->CountryIeLen = src->CountryIeLen;
3666 memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
3667#endif
3668
3669 dst->bWithAironetIE = src->bWithAironetIE;
3670 dst->bCkipSupported = src->bCkipSupported;
3671 memcpy(dst->CcxRmState,src->CcxRmState,2);
3672 dst->bCcxRmEnable = src->bCcxRmEnable;
3673 dst->MBssidMask = src->MBssidMask;
3674 dst->bMBssidValid = src->bMBssidValid;
3675 memcpy(dst->MBssid,src->MBssid,6);
3676 dst->bWithCcxVerNum = src->bWithCcxVerNum;
3677 dst->BssCcxVerNumber = src->BssCcxVerNumber;
3678
3679}
3680static inline int is_beacon(__le16 fc)
3681{
3682 return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == RTLLIB_STYPE_BEACON);
3683}
3684
3685#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
3686u8 AsocEntry_ComputeSum(u8 *paddr)
3687{
3688 u32 sum;
3689
3690 sum = paddr[0]+
3691 paddr[1]+
3692 paddr[2]+
3693 paddr[3]+
3694 paddr[4]+
3695 paddr[5];
3696
3697 return (u8)(sum % PEER_MAX_ASSOC);
3698}
3699u8 AsocEntry_AssignAvailableAID(struct rtllib_device *ieee, u8 *paddr)
3700{
3701 int i;
3702
3703 for (i = 0; i < PEER_MAX_ASSOC; i++)
3704 {
3705 if (ieee->AvailableAIDTable[i] == 99)
3706 {
3707 ieee->AvailableAIDTable[i] = AsocEntry_ComputeSum(paddr);
3708 return i+1;
3709 }
3710 }
3711
3712 return 1;
3713}
3714
3715void InitStaInfo(struct rtllib_device *ieee,int index)
3716{
3717 int idx = index;
3718 ieee->peer_assoc_list[idx]->StaDataRate = 0;
3719 ieee->peer_assoc_list[idx]->StaSS = 0;
3720 ieee->peer_assoc_list[idx]->RetryFrameCnt = 0;
3721 ieee->peer_assoc_list[idx]->NoRetryFrameCnt = 0;
3722 ieee->peer_assoc_list[idx]->LastRetryCnt = 0;
3723 ieee->peer_assoc_list[idx]->LastNoRetryCnt = 0;
3724 ieee->peer_assoc_list[idx]->AvgRetryRate = 0;
3725 ieee->peer_assoc_list[idx]->LastRetryRate = 0;
3726 ieee->peer_assoc_list[idx]->txRateIndex = 11;
3727 ieee->peer_assoc_list[idx]->APDataRate = 0x2;
3728 ieee->peer_assoc_list[idx]->ForcedDataRate = 0x2;
3729
3730}
3731static u8 IsStaInfoExist(struct rtllib_device *ieee, u8 *addr)
3732{
3733 int k=0;
3734 struct sta_info * psta = NULL;
3735 u8 sta_idx = PEER_MAX_ASSOC;
3736
3737 for (k=0; k<PEER_MAX_ASSOC; k++)
3738 {
3739 psta = ieee->peer_assoc_list[k];
3740 if (NULL != psta)
3741 {
3742 if (memcmp(addr, psta->macaddr, ETH_ALEN) == 0)
3743 {
3744 sta_idx = k;
3745 break;
3746 }
3747 }
3748 }
3749 return sta_idx;
3750}
3751static u8 GetFreeStaInfoIdx(struct rtllib_device *ieee, u8 *addr)
3752{
3753 int k = 0;
3754 while((ieee->peer_assoc_list[k] != NULL) && (k < PEER_MAX_ASSOC))
3755 k++;
3756 printk("%s: addr:"MAC_FMT" index: %d\n", __func__, MAC_ARG(addr), k);
3757 return k;
3758}
3759struct sta_info *GetStaInfo(struct rtllib_device *ieee, u8 *addr)
3760{
3761 int k=0;
3762 struct sta_info * psta = NULL;
3763 struct sta_info * psta_find = NULL;
3764
3765 for (k=0; k<PEER_MAX_ASSOC; k++)
3766 {
3767 psta = ieee->peer_assoc_list[k];
3768 if (NULL != psta)
3769 {
3770 if (memcmp(addr, psta->macaddr, ETH_ALEN) == 0)
3771 {
3772 psta_find = psta;
3773 break;
3774 }
3775 }
3776 }
3777 return psta_find;
3778}
3779void DelStaInfoList(struct rtllib_device *ieee)
3780{
3781 int idx = 0;
3782 struct sta_info * AsocEntry = NULL;
3783
3784 atomic_set(&ieee->AsocEntryNum, 0);
3785 for (idx=0; idx<PEER_MAX_ASSOC; idx++){
3786 AsocEntry = ieee->peer_assoc_list[idx];
3787 if (NULL != AsocEntry){
3788 kfree(AsocEntry);
3789 ieee->peer_assoc_list[idx] = NULL;
3790 }
3791 ieee->AvailableAIDTable[idx] = 99;
3792 }
3793}
3794void DelStaInfo(struct rtllib_device *ieee, u8 *addr)
3795{
3796 struct sta_info * psta = NULL;
3797 int k=0;
3798
3799 for (k=0; k<PEER_MAX_ASSOC; k++)
3800 {
3801 psta = ieee->peer_assoc_list[k];
3802 if (NULL != psta){
3803 if (memcmp(addr, psta->macaddr, ETH_ALEN) == 0){
3804 if (psta->aid > 0 && psta->aid-1 < PEER_MAX_ASSOC)
3805 ieee->AvailableAIDTable[psta->aid-1] = 99;
3806 else
3807 printk("%s(): clear non-existing entry AID\n", __func__);
3808
3809 kfree(psta);
3810 ieee->peer_assoc_list[k] = NULL;
3811 atomic_dec(&ieee->AsocEntryNum);
3812 }
3813 }
3814 }
3815}
3816void IbssAgeFunction(struct rtllib_device *ieee)
3817{
3818 struct sta_info* AsocEntry = NULL;
3819 int idx;
3820 unsigned long CurrentTime;
3821 signed long TimeDifference;
3822 struct rtllib_network *target;
3823
3824 CurrentTime = jiffies;
3825
3826 for (idx = 0; idx < PEER_MAX_ASSOC; idx++)
3827 {
3828 AsocEntry = ieee->peer_assoc_list[idx];
3829 if (AsocEntry)
3830 {
3831 TimeDifference = jiffies_to_msecs(CurrentTime - AsocEntry->LastActiveTime);
3832
3833 if (TimeDifference > 20000)
3834 {
3835 printk("IbssAgeFunction(): "MAC_FMT" timeout\n", MAC_ARG(AsocEntry->macaddr));
3836 kfree(AsocEntry);
3837 ieee->peer_assoc_list[idx] = NULL;
3838 atomic_dec(&ieee->AsocEntryNum);
3839
3840 if (atomic_read(&ieee->AsocEntryNum) == 0){
3841
3842 down(&ieee->wx_sem);
3843 rtllib_stop_protocol(ieee,true);
3844
3845 list_for_each_entry(target, &ieee->network_list, list) {
3846 if (is_same_network(target, &ieee->current_network,(target->ssid_len?1:0))){
3847 printk("delete sta of previous Ad-hoc\n");
3848 list_del(&target->list);
3849 break;
3850 }
3851 }
3852
3853 rtllib_start_protocol(ieee);
3854 up(&ieee->wx_sem);
3855 }
3856 }
3857 }
3858 }
3859
3860#ifdef TO_DO_LIST
3861 if (AsocEntry_AnyStationAssociated(pMgntInfo)==false)
3862 DrvIFIndicateDisassociation(Adapter, unspec_reason);
3863
3864 if (pMgntInfo->dot11CurrentWirelessMode == WIRELESS_MODE_G ||
3865 (IS_WIRELESS_MODE_N_24G(Adapter) && pMgntInfo->pHTInfo->bCurSuppCCK) )
3866 {
3867 if (nBModeStaCnt == 0)
3868 {
3869 pMgntInfo->bUseProtection = false;
3870 ActUpdate_mCapInfo(Adapter, pMgntInfo->mCap);
3871 }
3872 }
3873
3874 if (IS_WIRELESS_MODE_N_24G(Adapter) || IS_WIRELESS_MODE_N_5G(Adapter) )
3875 {
3876 if (nLegacyStaCnt > 0)
3877 {
3878 pMgntInfo->pHTInfo->CurrentOpMode = HT_OPMODE_MIXED;
3879 }
3880 else
3881 {
3882 if ((pMgntInfo->pHTInfo->bCurBW40MHz) && (n20MHzStaCnt > 0))
3883 pMgntInfo->pHTInfo->CurrentOpMode = HT_OPMODE_40MHZ_PROTECT;
3884 else
3885 pMgntInfo->pHTInfo->CurrentOpMode = HT_OPMODE_NO_PROTECT;
3886
3887 }
3888 }
3889
3890 if (IS_WIRELESS_MODE_G(Adapter) ||
3891 (IS_WIRELESS_MODE_N_24G(Adapter) && pMgntInfo->pHTInfo->bCurSuppCCK))
3892 {
3893 if (pMgntInfo->bUseProtection)
3894 {
3895 u8 CckRate[4] = { MGN_1M, MGN_2M, MGN_5_5M, MGN_11M };
3896 OCTET_STRING osCckRate;
3897 FillOctetString(osCckRate, CckRate, 4);
3898 FilterSupportRate(pMgntInfo->mBrates, &osCckRate, false);
3899 Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_BASIC_RATE, (pu1Byte)&osCckRate);
3900 }
3901 else
3902 {
3903 Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
3904 }
3905 }
3906#endif
3907}
3908#endif
3909
3910static int IsPassiveChannel( struct rtllib_device *rtllib, u8 channel)
3911{
3912 if (MAX_CHANNEL_NUMBER < channel) {
3913 printk("%s(): Invalid Channel\n", __func__);
3914 return 0;
3915 }
3916
3917 if (rtllib->active_channel_map[channel] == 2)
3918 return 1;
3919
3920 return 0;
3921}
3922
3923int IsLegalChannel( struct rtllib_device *rtllib, u8 channel)
3924{
3925 if (MAX_CHANNEL_NUMBER < channel) {
3926 printk("%s(): Invalid Channel\n", __func__);
3927 return 0;
3928 }
3929 if (rtllib->active_channel_map[channel] > 0)
3930 return 1;
3931
3932 return 0;
3933}
3934
3935
3936static inline void rtllib_process_probe_response(
3937 struct rtllib_device *ieee,
3938 struct rtllib_probe_response *beacon,
3939 struct rtllib_rx_stats *stats)
3940{
3941 struct rtllib_network *target;
3942 struct rtllib_network *oldest = NULL;
3943#ifdef CONFIG_RTLLIB_DEBUG
3944 struct rtllib_info_element *info_element = &beacon->info_element[0];
3945#endif
3946 unsigned long flags;
3947 short renew;
3948#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
3949 struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network), GFP_ATOMIC);
3950#else
3951 struct rtllib_network *network = kmalloc(sizeof(*network), GFP_ATOMIC);
3952 memset(network,0,sizeof(*network));
3953#endif
3954
3955 if (!network) {
3956 return;
3957 }
3958
3959 RTLLIB_DEBUG_SCAN(
3960 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
3961 escape_essid(info_element->data, info_element->len),
3962 MAC_ARG(beacon->header.addr3),
3963 (beacon->capability & (1<<0xf)) ? '1' : '0',
3964 (beacon->capability & (1<<0xe)) ? '1' : '0',
3965 (beacon->capability & (1<<0xd)) ? '1' : '0',
3966 (beacon->capability & (1<<0xc)) ? '1' : '0',
3967 (beacon->capability & (1<<0xb)) ? '1' : '0',
3968 (beacon->capability & (1<<0xa)) ? '1' : '0',
3969 (beacon->capability & (1<<0x9)) ? '1' : '0',
3970 (beacon->capability & (1<<0x8)) ? '1' : '0',
3971 (beacon->capability & (1<<0x7)) ? '1' : '0',
3972 (beacon->capability & (1<<0x6)) ? '1' : '0',
3973 (beacon->capability & (1<<0x5)) ? '1' : '0',
3974 (beacon->capability & (1<<0x4)) ? '1' : '0',
3975 (beacon->capability & (1<<0x3)) ? '1' : '0',
3976 (beacon->capability & (1<<0x2)) ? '1' : '0',
3977 (beacon->capability & (1<<0x1)) ? '1' : '0',
3978 (beacon->capability & (1<<0x0)) ? '1' : '0');
3979
3980 if (rtllib_network_init(ieee, beacon, network, stats)) {
3981 RTLLIB_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
3982 escape_essid(info_element->data,
3983 info_element->len),
3984 MAC_ARG(beacon->header.addr3),
3985 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
3986 RTLLIB_STYPE_PROBE_RESP ?
3987 "PROBE RESPONSE" : "BEACON");
3988 goto free_network;
3989 }
3990
3991
3992 if (!IsLegalChannel(ieee, network->channel))
3993 goto free_network;
3994
3995 if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == RTLLIB_STYPE_PROBE_RESP) {
3996 if (IsPassiveChannel(ieee, network->channel)) {
3997 printk("GetScanInfo(): For Global Domain, "
3998 "filter probe response at channel(%d).\n", network->channel);
3999 goto free_network;
4000 }
4001 }
4002
4003 /* The network parsed correctly -- so now we scan our known networks
4004 * to see if we can find it in our list.
4005 *
4006 * NOTE: This search is definitely not optimized. Once its doing
4007 * the "right thing" we'll optimize it for efficiency if
4008 * necessary */
4009
4010 /* Search for this entry in the list and update it if it is
4011 * already there. */
4012
4013 spin_lock_irqsave(&ieee->lock, flags);
4014#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
4015 if (is_beacon(beacon->header.frame_ctl)){
4016 if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->state == RTLLIB_LINKED))
4017 {
4018 if ((network->ssid_len == ieee->current_network.ssid_len)
4019 && (!memcmp(network->ssid,ieee->current_network.ssid,ieee->current_network.ssid_len))
4020 && (network->channel == ieee->current_network.channel)
4021 && (ieee->current_network.channel > 0)
4022 && (ieee->current_network.channel <= 14))
4023 {
4024 if (!memcmp(ieee->current_network.bssid,network->bssid,6))
4025 {
4026 int idx = 0;
4027 struct rtllib_hdr_3addr* header = NULL;
4028 int idx_exist = 0;
4029 if (timer_pending(&ieee->ibss_wait_timer))
4030 del_timer_sync(&ieee->ibss_wait_timer);
4031 header = (struct rtllib_hdr_3addr*)&(beacon->header);
4032 idx_exist = IsStaInfoExist(ieee,header->addr2);
4033 if (idx_exist >= PEER_MAX_ASSOC) {
4034 idx = GetFreeStaInfoIdx(ieee, header->addr2);
4035 } else {
4036 ieee->peer_assoc_list[idx_exist]->LastActiveTime = jiffies;
4037 goto no_alloc;
4038 }
4039 if (idx >= PEER_MAX_ASSOC - 1) {
4040 printk("\n%s():ERR!!!Buffer overflow - could not append!!!",__func__);
4041 goto free_network;
4042 } else {
4043 ieee->peer_assoc_list[idx] = (struct sta_info *)kmalloc(sizeof(struct sta_info), GFP_ATOMIC);
4044 memset(ieee->peer_assoc_list[idx], 0, sizeof(struct sta_info));
4045 ieee->peer_assoc_list[idx]->LastActiveTime = jiffies;
4046 memcpy(ieee->peer_assoc_list[idx]->macaddr,header->addr2,ETH_ALEN);
4047 ieee->peer_assoc_list[idx]->ratr_index = 8;
4048 InitStaInfo(ieee,idx);
4049 atomic_inc(&ieee->AsocEntryNum);
4050 ieee->peer_assoc_list[idx]->aid = AsocEntry_AssignAvailableAID(ieee, ieee->peer_assoc_list[idx]->macaddr);
4051 ieee->check_ht_cap(ieee->dev,ieee->peer_assoc_list[idx],network);
4052 queue_delayed_work_rsl(ieee->wq, &ieee->update_assoc_sta_info_wq, 0);
4053 ieee->Adhoc_InitRateAdaptive(ieee->dev,ieee->peer_assoc_list[idx]);
4054 }
4055 }
4056 }
4057 }
4058 }
4059 if (ieee->iw_mode == IW_MODE_ADHOC){
4060 if ((network->ssid_len == ieee->current_network.ssid_len)
4061 && (!memcmp(network->ssid,ieee->current_network.ssid,ieee->current_network.ssid_len))
4062 && (network->capability & WLAN_CAPABILITY_IBSS)
4063 && (ieee->state == RTLLIB_LINKED_SCANNING))
4064 {
4065 if (memcmp(ieee->current_network.bssid,network->bssid,6))
4066 {
4067 printk("%s(): SSID matched but BSSID mismatched.\n",__func__);
4068
4069 ieee->TargetTsf = beacon->time_stamp[1];
4070 ieee->TargetTsf <<= 32;
4071 ieee->TargetTsf |= beacon->time_stamp[0];
4072
4073 ieee->CurrTsf = stats->TimeStampLow;
4074
4075 queue_delayed_work_rsl(ieee->wq, &ieee->check_tsf_wq, 0);
4076 }
4077 }
4078 }
4079#endif
4080#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
4081no_alloc:
4082 if (ieee->iw_mode == IW_MODE_INFRA)
4083#endif
4084 {
4085 if (is_same_network(&ieee->current_network, network, (network->ssid_len?1:0))) {
4086 update_network(&ieee->current_network, network);
4087 if ((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G)
4088 && ieee->current_network.berp_info_valid){
4089 if (ieee->current_network.erp_value& ERP_UseProtection)
4090 ieee->current_network.buseprotection = true;
4091 else
4092 ieee->current_network.buseprotection = false;
4093 }
4094 if (is_beacon(beacon->header.frame_ctl))
4095 {
4096 if (ieee->state >= RTLLIB_LINKED)
4097 ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
4098 }
4099 }
4100 }
4101#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
4102 else if (ieee->iw_mode == IW_MODE_ADHOC)
4103 {
4104 if (is_same_network(&ieee->current_network, network, (network->ssid_len?1:0))) {
4105 update_ibss_network(&ieee->current_network, network);
4106 }
4107 }
4108#endif
4109 list_for_each_entry(target, &ieee->network_list, list) {
4110 if (is_same_network(target, network,(target->ssid_len?1:0)))
4111 break;
4112 if ((oldest == NULL) ||
4113 (target->last_scanned < oldest->last_scanned))
4114 oldest = target;
4115 }
4116
4117 /* If we didn't find a match, then get a new network slot to initialize
4118 * with this beacon's information */
4119 if (&target->list == &ieee->network_list) {
4120 if (list_empty(&ieee->network_free_list)) {
4121 /* If there are no more slots, expire the oldest */
4122 list_del(&oldest->list);
4123 target = oldest;
4124 RTLLIB_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
4125 "network list.\n",
4126 escape_essid(target->ssid,
4127 target->ssid_len),
4128 MAC_ARG(target->bssid));
4129 } else {
4130 /* Otherwise just pull from the free list */
4131 target = list_entry(ieee->network_free_list.next,
4132 struct rtllib_network, list);
4133 list_del(ieee->network_free_list.next);
4134 }
4135
4136
4137#ifdef CONFIG_RTLLIB_DEBUG
4138 RTLLIB_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
4139 escape_essid(network->ssid,
4140 network->ssid_len),
4141 MAC_ARG(network->bssid),
4142 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
4143 RTLLIB_STYPE_PROBE_RESP ?
4144 "PROBE RESPONSE" : "BEACON");
4145#endif
4146 memcpy(target, network, sizeof(*target));
4147 list_add_tail(&target->list, &ieee->network_list);
4148 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
4149 rtllib_softmac_new_net(ieee, network);
4150 } else {
4151 RTLLIB_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
4152 escape_essid(target->ssid,
4153 target->ssid_len),
4154 MAC_ARG(target->bssid),
4155 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
4156 RTLLIB_STYPE_PROBE_RESP ?
4157 "PROBE RESPONSE" : "BEACON");
4158
4159 /* we have an entry and we are going to update it. But this entry may
4160 * be already expired. In this case we do the same as we found a new
4161 * net and call the new_net handler
4162 */
4163 renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
4164 if ((!target->ssid_len) &&
4165 (((network->ssid_len > 0) && (target->hidden_ssid_len == 0))
4166 || ((ieee->current_network.ssid_len == network->ssid_len) &&
4167 (strncmp(ieee->current_network.ssid, network->ssid, network->ssid_len) == 0) &&
4168 (ieee->state == RTLLIB_NOLINK)))
4169 ) {
4170 renew = 1;
4171 }
4172 update_network(target, network);
4173 if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
4174 rtllib_softmac_new_net(ieee, network);
4175 }
4176
4177 spin_unlock_irqrestore(&ieee->lock, flags);
4178 if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, network, (network->ssid_len?1:0))&&\
4179 (ieee->state == RTLLIB_LINKED)) {
4180 if (ieee->handle_beacon != NULL) {
4181 ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network);
4182 }
4183 }
4184free_network:
4185 kfree(network);
4186 return;
4187}
4188
4189void rtllib_rx_mgt(struct rtllib_device *ieee,
4190 struct sk_buff *skb,
4191 struct rtllib_rx_stats *stats)
4192{
4193 struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ;
4194 if (WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_PROBE_RESP &&
4195 WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_BEACON)
4196 ieee->last_rx_ps_time = jiffies;
4197
4198 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
4199
4200 case RTLLIB_STYPE_BEACON:
4201 RTLLIB_DEBUG_MGMT("received BEACON (%d)\n",
4202 WLAN_FC_GET_STYPE(header->frame_ctl));
4203 RTLLIB_DEBUG_SCAN("Beacon\n");
4204 rtllib_process_probe_response(
4205 ieee, (struct rtllib_probe_response *)header, stats);
4206
4207 if (ieee->sta_sleep || (ieee->ps != RTLLIB_PS_DISABLED &&
4208 ieee->iw_mode == IW_MODE_INFRA &&
4209 ieee->state == RTLLIB_LINKED))
4210 tasklet_schedule(&ieee->ps_task);
4211
4212 break;
4213
4214 case RTLLIB_STYPE_PROBE_RESP:
4215 RTLLIB_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
4216 WLAN_FC_GET_STYPE(header->frame_ctl));
4217 RTLLIB_DEBUG_SCAN("Probe response\n");
4218 rtllib_process_probe_response(
4219 ieee, (struct rtllib_probe_response *)header, stats);
4220 break;
4221 case RTLLIB_STYPE_PROBE_REQ:
4222 RTLLIB_DEBUG_MGMT("received PROBE RESQUEST (%d)\n",
4223 WLAN_FC_GET_STYPE(header->frame_ctl));
4224 RTLLIB_DEBUG_SCAN("Probe request\n");
4225 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
4226 ((ieee->iw_mode == IW_MODE_ADHOC ||
4227 ieee->iw_mode == IW_MODE_MASTER) &&
4228 ieee->state == RTLLIB_LINKED)){
4229 rtllib_rx_probe_rq(ieee, skb);
4230 }
4231 break;
4232 }
4233
4234}
This page took 0.1828 seconds and 5 git commands to generate.