2 * Original code based Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3 - hostap.o module, common routines
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8 * Copyright (c) 2004, Intel Corporation
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
14 ******************************************************************************
16 Few modifications for Realtek's Wi-Fi drivers by
17 Andrea Merello <andreamrl@tiscali.it>
19 A special thanks goes to Realtek for their support !
21 ******************************************************************************/
24 #include <linux/compiler.h>
25 #include <linux/errno.h>
26 #include <linux/if_arp.h>
27 #include <linux/in6.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>
50 #if defined CONFIG_CFG_80211
51 #include <linux/crc32.h>
53 struct ieee80211_channel *rtllib_get_channel(struct wiphy *wiphy,
56 enum ieee80211_band band;
57 struct ieee80211_supported_band *sband;
60 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
61 sband = wiphy->bands[band];
66 for (i = 0; i < sband->n_channels; i++) {
67 if (sband->channels[i].center_freq == freq)
68 return &sband->channels[i];
75 int rtllib_channel_to_frequency(int chan)
78 return 2407 + chan * 5;
83 /* FIXME: 802.11j 17.3.8.3.2 */
84 return (chan + 1000) * 5;
87 u32 rtllib_parse_elems_crc(u8 *start, size_t len,
88 struct ieee802_11_elems *elems,
93 bool calc_crc = filter != 0;
95 memset(elems, 0, sizeof(*elems));
96 elems->ie_start = start;
97 elems->total_len = len;
109 if (calc_crc && id < 64 && (filter & BIT(id)))
110 crc = crc32_be(crc, pos - 2, elen + 2);
115 elems->ssid_len = elen;
117 case WLAN_EID_SUPP_RATES:
118 elems->supp_rates = pos;
119 elems->supp_rates_len = elen;
121 case WLAN_EID_FH_PARAMS:
122 elems->fh_params = pos;
123 elems->fh_params_len = elen;
125 case WLAN_EID_DS_PARAMS:
126 elems->ds_params = pos;
127 elems->ds_params_len = elen;
129 case WLAN_EID_CF_PARAMS:
130 elems->cf_params = pos;
131 elems->cf_params_len = elen;
134 if (elen >= sizeof(struct ieee80211_tim_ie)) {
135 elems->tim = (void *)pos;
136 elems->tim_len = elen;
139 case WLAN_EID_IBSS_PARAMS:
140 elems->ibss_params = pos;
141 elems->ibss_params_len = elen;
143 case WLAN_EID_CHALLENGE:
144 elems->challenge = pos;
145 elems->challenge_len = elen;
147 case WLAN_EID_VENDOR_SPECIFIC:
148 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
150 /* Microsoft OUI (00:50:F2) */
153 crc = crc32_be(crc, pos - 2, elen + 2);
156 /* OUI Type 1 - WPA IE */
158 elems->wpa_len = elen;
159 } else if (elen >= 5 && pos[3] == 2) {
160 /* OUI Type 2 - WMM IE */
162 elems->wmm_info = pos;
163 elems->wmm_info_len = elen;
164 } else if (pos[4] == 1) {
165 elems->wmm_param = pos;
166 elems->wmm_param_len = elen;
173 elems->rsn_len = elen;
175 case WLAN_EID_ERP_INFO:
176 elems->erp_info = pos;
177 elems->erp_info_len = elen;
179 case WLAN_EID_EXT_SUPP_RATES:
180 elems->ext_supp_rates = pos;
181 elems->ext_supp_rates_len = elen;
183 case WLAN_EID_HT_CAPABILITY:
184 if (elen >= sizeof(struct ieee80211_ht_cap))
185 elems->ht_cap_elem = (void *)pos;
187 case WLAN_EID_HT_INFORMATION:
188 if (elen >= sizeof(struct ieee80211_ht_info))
189 elems->ht_info_elem = (void *)pos;
191 case WLAN_EID_MESH_ID:
192 elems->mesh_id = pos;
193 elems->mesh_id_len = elen;
195 case WLAN_EID_MESH_CONFIG:
196 elems->mesh_config = pos;
197 elems->mesh_config_len = elen;
199 case WLAN_EID_PEER_LINK:
200 elems->peer_link = pos;
201 elems->peer_link_len = elen;
205 elems->preq_len = elen;
209 elems->prep_len = elen;
213 elems->perr_len = elen;
215 case WLAN_EID_CHANNEL_SWITCH:
216 elems->ch_switch_elem = pos;
217 elems->ch_switch_elem_len = elen;
220 if (!elems->quiet_elem) {
221 elems->quiet_elem = pos;
222 elems->quiet_elem_len = elen;
224 elems->num_of_quiet_elem++;
226 case WLAN_EID_COUNTRY:
227 elems->country_elem = pos;
228 elems->country_elem_len = elen;
230 case WLAN_EID_PWR_CONSTRAINT:
231 elems->pwr_constr_elem = pos;
232 elems->pwr_constr_elem_len = elen;
234 case WLAN_EID_TIMEOUT_INTERVAL:
235 elems->timeout_int = pos;
236 elems->timeout_int_len = elen;
249 void rtllib_parse_elems(u8 *start, size_t len,
250 struct ieee802_11_elems *elems)
252 rtllib_parse_elems_crc(start, len, elems, 0, 0);
255 void ieee80211_scan_rx(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_status)
257 struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ;
258 struct ieee80211_mgmt *mgmt;
259 struct ieee80211_bss *bss;
261 struct ieee80211_channel *channel;
265 bool presp, beacon = false;
266 struct ieee802_11_elems elems;
272 mgmt = (struct ieee80211_mgmt *) skb->data;
273 fc = mgmt->frame_control;
278 presp = (WLAN_FC_GET_STYPE(header->frame_ctl) == RTLLIB_STYPE_PROBE_RESP);
280 /* ignore ProbeResp to foreign address */
281 if (memcmp(mgmt->da, ieee->dev->dev_addr, ETH_ALEN))
285 elements = mgmt->u.probe_resp.variable;
286 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
288 beacon = (WLAN_FC_GET_STYPE(header->frame_ctl) == RTLLIB_STYPE_BEACON);
289 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
290 elements = mgmt->u.beacon.variable;
293 if (!presp && !beacon)
296 if (baselen > skb->len)
299 rtllib_parse_elems(elements, skb->len - baselen, &elems);
301 if (elems.ds_params && elems.ds_params_len == 1)
302 freq = rtllib_channel_to_frequency(elems.ds_params[0]);
306 channel = rtllib_get_channel(ieee->wdev.wiphy, freq);
308 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
311 signal = rx_status->signal * 100;
313 bss = (void *)cfg80211_inform_bss_frame(ieee->wdev.wiphy, channel,
314 mgmt, skb->len, signal, GFP_ATOMIC);
320 static inline void rtllib_monitor_rx(struct rtllib_device *ieee,
321 struct sk_buff *skb,struct rtllib_rx_stats *rx_status,
324 skb->dev = ieee->dev;
325 skb_reset_mac_header(skb);
326 skb_pull(skb, hdr_length);
327 skb->pkt_type = PACKET_OTHERHOST;
328 skb->protocol = __constant_htons(ETH_P_80211_RAW);
329 memset(skb->cb, 0, sizeof(skb->cb));
333 /* Called only as a tasklet (software IRQ) */
334 static struct rtllib_frag_entry *
335 rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq,
336 unsigned int frag, u8 tid,u8 *src, u8 *dst)
338 struct rtllib_frag_entry *entry;
341 for (i = 0; i < RTLLIB_FRAG_CACHE_LEN; i++) {
342 entry = &ieee->frag_cache[tid][i];
343 if (entry->skb != NULL &&
344 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
346 "expiring fragment cache entry "
347 "seq=%u last_frag=%u\n",
348 entry->seq, entry->last_frag);
349 dev_kfree_skb_any(entry->skb);
353 if (entry->skb != NULL && entry->seq == seq &&
354 (entry->last_frag + 1 == frag || frag == -1) &&
355 memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
356 memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
363 /* Called only as a tasklet (software IRQ) */
364 static struct sk_buff *
365 rtllib_frag_cache_get(struct rtllib_device *ieee,
366 struct rtllib_hdr_4addr *hdr)
368 struct sk_buff *skb = NULL;
369 u16 fc = le16_to_cpu(hdr->frame_ctl);
370 u16 sc = le16_to_cpu(hdr->seq_ctl);
371 unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
372 unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
373 struct rtllib_frag_entry *entry;
374 struct rtllib_hdr_3addrqos *hdr_3addrqos;
375 struct rtllib_hdr_4addrqos *hdr_4addrqos;
378 if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS)&&RTLLIB_QOS_HAS_SEQ(fc)) {
379 hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr;
380 tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID;
383 } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
384 hdr_3addrqos = (struct rtllib_hdr_3addrqos *)hdr;
385 tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID;
393 /* Reserve enough space to fit maximum frame length */
394 skb = dev_alloc_skb(ieee->dev->mtu +
395 sizeof(struct rtllib_hdr_4addr) +
400 (RTLLIB_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
404 entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
405 ieee->frag_next_idx[tid]++;
406 if (ieee->frag_next_idx[tid] >= RTLLIB_FRAG_CACHE_LEN)
407 ieee->frag_next_idx[tid] = 0;
409 if (entry->skb != NULL)
410 dev_kfree_skb_any(entry->skb);
412 entry->first_frag_time = jiffies;
414 entry->last_frag = frag;
416 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
417 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
419 /* received a fragment of a frame for which the head fragment
420 * should have already been received */
421 entry = rtllib_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
424 entry->last_frag = frag;
433 /* Called only as a tasklet (software IRQ) */
434 static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee,
435 struct rtllib_hdr_4addr *hdr)
437 u16 fc = le16_to_cpu(hdr->frame_ctl);
438 u16 sc = le16_to_cpu(hdr->seq_ctl);
439 unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
440 struct rtllib_frag_entry *entry;
441 struct rtllib_hdr_3addrqos *hdr_3addrqos;
442 struct rtllib_hdr_4addrqos *hdr_4addrqos;
445 if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS)&&RTLLIB_QOS_HAS_SEQ(fc)) {
446 hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr;
447 tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID;
450 } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
451 hdr_3addrqos = (struct rtllib_hdr_3addrqos *)hdr;
452 tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID;
459 entry = rtllib_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
464 "could not invalidate fragment cache "
465 "entry (seq=%u)\n", seq);
475 /* rtllib_rx_frame_mgtmt
477 * Responsible for handling management control frames
479 * Called by rtllib_rx */
481 rtllib_rx_frame_mgmt(struct rtllib_device *ieee, struct sk_buff *skb,
482 struct rtllib_rx_stats *rx_stats, u16 type,
485 /* On the struct stats definition there is written that
486 * this is not mandatory.... but seems that the probe
487 * response parser uses it
489 struct rtllib_hdr_3addr * hdr = (struct rtllib_hdr_3addr *)skb->data;
491 rx_stats->len = skb->len;
492 rtllib_rx_mgt(ieee,skb,rx_stats);
493 if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN))) {
494 dev_kfree_skb_any(skb);
497 rtllib_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
499 dev_kfree_skb_any(skb);
504 if (ieee->iw_mode == IW_MODE_MASTER) {
505 printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
509 hostap_update_sta_ps(ieee, (struct hostap_rtllib_hdr_4addr *)
513 if (ieee->hostapd && type == RTLLIB_TYPE_MGMT) {
514 if (stype == WLAN_FC_STYPE_BEACON &&
515 ieee->iw_mode == IW_MODE_MASTER) {
516 struct sk_buff *skb2;
517 /* Process beacon frames also in kernel driver to
518 * update STA(AP) table statistics */
519 skb2 = skb_clone(skb, GFP_ATOMIC);
521 hostap_rx(skb2->dev, skb2, rx_stats);
524 /* send management frames to the user space daemon for
526 ieee->apdevstats.rx_packets++;
527 ieee->apdevstats.rx_bytes += skb->len;
528 prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
532 if (ieee->iw_mode == IW_MODE_MASTER) {
533 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
534 printk(KERN_DEBUG "%s: unknown management frame "
535 "(type=0x%02x, stype=0x%02x) dropped\n",
536 skb->dev->name, type, stype);
540 hostap_rx(skb->dev, skb, rx_stats);
544 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
545 "received in non-Host AP mode\n", skb->dev->name);
550 #ifndef CONFIG_CFG_80211
551 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
552 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
553 static unsigned char rfc1042_header[] =
554 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
555 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
556 static unsigned char bridge_tunnel_header[] =
557 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
558 /* No encapsulation header if EtherType < 0x600 (=length) */
561 /* Called by rtllib_rx_frame_decrypt */
562 static int rtllib_is_eapol_frame(struct rtllib_device *ieee,
563 struct sk_buff *skb, size_t hdrlen)
565 struct net_device *dev = ieee->dev;
567 struct rtllib_hdr_4addr *hdr;
573 hdr = (struct rtllib_hdr_4addr *) skb->data;
574 fc = le16_to_cpu(hdr->frame_ctl);
576 /* check that the frame is unicast frame to us */
577 if ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) ==
579 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
580 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
581 /* ToDS frame with own addr BSSID and DA */
582 } else if ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) ==
583 RTLLIB_FCTL_FROMDS &&
584 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
585 /* FromDS frame with own addr as DA */
589 if (skb->len < 24 + 8)
592 /* check for port access entity Ethernet type */
593 pos = skb->data + hdrlen;
594 ethertype = (pos[6] << 8) | pos[7];
595 if (ethertype == ETH_P_PAE)
601 /* Called only as a tasklet (software IRQ), by rtllib_rx */
603 rtllib_rx_frame_decrypt(struct rtllib_device* ieee, struct sk_buff *skb,
604 struct rtllib_crypt_data *crypt)
606 struct rtllib_hdr_4addr *hdr;
609 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
612 if (ieee->hwsec_active)
614 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
615 tcb_desc->bHwSec = 1;
617 if (ieee->need_sw_enc)
618 tcb_desc->bHwSec = 0;
621 hdr = (struct rtllib_hdr_4addr *) skb->data;
622 hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
624 #ifdef CONFIG_RTLLIB_CRYPT_TKIP
625 if (ieee->tkip_countermeasures &&
626 strcmp(crypt->ops->name, "TKIP") == 0) {
627 if (net_ratelimit()) {
628 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
629 "received packet from " MAC_FMT "\n",
630 ieee->dev->name, MAC_ARG(hdr->addr2));
636 atomic_inc(&crypt->refcnt);
637 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
638 atomic_dec(&crypt->refcnt);
641 "decryption failed (SA=" MAC_FMT
642 ") res=%d\n", MAC_ARG(hdr->addr2), res);
644 RTLLIB_DEBUG_DROP("Decryption failed ICV "
645 "mismatch (key %d)\n",
646 skb->data[hdrlen + 3] >> 6);
647 ieee->ieee_stats.rx_discards_undecryptable++;
655 /* Called only as a tasklet (software IRQ), by rtllib_rx */
657 rtllib_rx_frame_decrypt_msdu(struct rtllib_device* ieee, struct sk_buff *skb,
658 int keyidx, struct rtllib_crypt_data *crypt)
660 struct rtllib_hdr_4addr *hdr;
663 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
665 if (ieee->hwsec_active)
667 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
668 tcb_desc->bHwSec = 1;
670 if (ieee->need_sw_enc)
671 tcb_desc->bHwSec = 0;
674 hdr = (struct rtllib_hdr_4addr *) skb->data;
675 hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
677 atomic_inc(&crypt->refcnt);
678 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv,ieee);
679 atomic_dec(&crypt->refcnt);
681 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
682 " (SA=" MAC_FMT " keyidx=%d)\n",
683 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
691 /* this function is stolen from ipw2200 driver*/
692 #define IEEE_PACKET_RETRY_TIME (5*HZ)
693 static int is_duplicate_packet(struct rtllib_device *ieee,
694 struct rtllib_hdr_4addr *header)
696 u16 fc = le16_to_cpu(header->frame_ctl);
697 u16 sc = le16_to_cpu(header->seq_ctl);
698 u16 seq = WLAN_GET_SEQ_SEQ(sc);
699 u16 frag = WLAN_GET_SEQ_FRAG(sc);
700 u16 *last_seq, *last_frag;
701 unsigned long *last_time;
702 struct rtllib_hdr_3addrqos *hdr_3addrqos;
703 struct rtllib_hdr_4addrqos *hdr_4addrqos;
706 if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS)&&RTLLIB_QOS_HAS_SEQ(fc)) {
707 hdr_4addrqos = (struct rtllib_hdr_4addrqos *)header;
708 tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID;
711 } else if (RTLLIB_QOS_HAS_SEQ(fc)) {
712 hdr_3addrqos = (struct rtllib_hdr_3addrqos*)header;
713 tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID;
720 switch (ieee->iw_mode) {
724 struct ieee_ibss_seq *entry = NULL;
725 u8 *mac = header->addr2;
726 int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
727 list_for_each(p, &ieee->ibss_mac_hash[index]) {
728 entry = list_entry(p, struct ieee_ibss_seq, list);
729 if (!memcmp(entry->mac, mac, ETH_ALEN))
732 if (p == &ieee->ibss_mac_hash[index]) {
733 entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
735 printk(KERN_WARNING "Cannot malloc new mac entry\n");
738 memcpy(entry->mac, mac, ETH_ALEN);
739 entry->seq_num[tid] = seq;
740 entry->frag_num[tid] = frag;
741 entry->packet_time[tid] = jiffies;
742 list_add(&entry->list, &ieee->ibss_mac_hash[index]);
745 last_seq = &entry->seq_num[tid];
746 last_frag = &entry->frag_num[tid];
747 last_time = &entry->packet_time[tid];
752 last_seq = &ieee->last_rxseq_num[tid];
753 last_frag = &ieee->last_rxfrag_num[tid];
754 last_time = &ieee->last_packet_time[tid];
760 if ((*last_seq == seq) &&
761 time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
762 if (*last_frag == frag){
766 if (*last_frag + 1 != frag)
767 /* out-of-order fragment */
773 *last_time = jiffies;
783 PRX_REORDER_ENTRY pReorderEntry
786 struct list_head *pList = &pTS->RxPendingPktList;
788 while(pList->next != &pTS->RxPendingPktList)
790 if ( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
794 else if ( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
803 pReorderEntry->List.next = pList->next;
804 pReorderEntry->List.next->prev = &pReorderEntry->List;
805 pReorderEntry->List.prev = pList;
806 pList->next = &pReorderEntry->List;
811 void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb** prxbIndicateArray,u8 index)
813 struct net_device_stats *stats = &ieee->stats;
816 for (j = 0; j < index; j++) {
817 struct rtllib_rxb* prxb = prxbIndicateArray[j];
818 for (i = 0; i<prxb->nr_subframes; i++) {
819 struct sk_buff *sub_skb = prxb->subframes[i];
821 /* convert hdr + possible LLC headers into Ethernet header */
822 ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
823 if (sub_skb->len >= 8 &&
824 ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
825 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
826 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
827 /* remove RFC1042 or Bridge-Tunnel encapsulation and
828 * replace EtherType */
829 skb_pull(sub_skb, SNAP_SIZE);
830 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
831 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
834 /* Leave Ethernet header part of hdr and full payload */
835 len = htons(sub_skb->len);
836 memcpy(skb_push(sub_skb, 2), &len, 2);
837 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
838 memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
841 /* Indicat the packets to upper layer */
844 stats->rx_bytes += sub_skb->len;
846 memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
847 sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev);
848 sub_skb->dev = ieee->dev;
849 sub_skb->dev->stats.rx_packets++;
850 sub_skb->dev->stats.rx_bytes += sub_skb->len;
851 #ifdef TCP_CSUM_OFFLOAD_RX
852 if ( prxb->tcp_csum_valid)
853 sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
855 sub_skb->ip_summed = CHECKSUM_NONE;
858 sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
860 ieee->last_rx_ps_time = jiffies;
870 rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, PRX_TS_RECORD pTS)
872 PRX_REORDER_ENTRY pRxReorderEntry;
873 struct rtllib_rxb* RfdArray[REORDER_WIN_SIZE];
877 del_timer_sync(&pTS->RxPktPendingTimer);
878 while(!list_empty(&pTS->RxPendingPktList))
880 if (RfdCnt >= REORDER_WIN_SIZE){
881 printk("-------------->%s() error! RfdCnt >= REORDER_WIN_SIZE\n", __func__);
885 pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
886 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): Indicate SeqNum %d!\n",__func__, pRxReorderEntry->SeqNum);
887 list_del_init(&pRxReorderEntry->List);
889 RfdArray[RfdCnt] = pRxReorderEntry->prxb;
892 list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List);
894 rtllib_indicate_packets(ieee, RfdArray, RfdCnt);
896 pTS->RxIndicateSeq = 0xffff;
900 void RxReorderIndicatePacket( struct rtllib_device *ieee,
901 struct rtllib_rxb* prxb,
905 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
906 PRX_REORDER_ENTRY pReorderEntry = NULL;
907 struct rtllib_rxb* prxbIndicateArray[REORDER_WIN_SIZE];
908 u8 WinSize = pHTInfo->RxReorderWinSize;
911 bool bMatchWinStart = false, bPktInBuf = false;
914 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__func__,SeqNum,pTS->RxIndicateSeq,WinSize);
916 spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
918 WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096;
919 /* Rx Reorder initialize condition.*/
920 if (pTS->RxIndicateSeq == 0xffff) {
921 pTS->RxIndicateSeq = SeqNum;
924 /* Drop out the packet which SeqNum is smaller than WinStart */
925 if (SN_LESS(SeqNum, pTS->RxIndicateSeq)) {
926 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n",
927 pTS->RxIndicateSeq, SeqNum);
928 pHTInfo->RxReorderDropCounter++;
931 for (i =0; i < prxb->nr_subframes; i++) {
932 dev_kfree_skb(prxb->subframes[i]);
937 spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
942 * Sliding window manipulation. Conditions includes:
943 * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
944 * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
946 if (SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) {
947 pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
948 bMatchWinStart = true;
949 } else if (SN_LESS(WinEnd, SeqNum)) {
950 if (SeqNum >= (WinSize - 1)) {
951 pTS->RxIndicateSeq = SeqNum + 1 -WinSize;
953 pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1;
955 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
959 * Indication process.
960 * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets
961 * with the SeqNum smaller than latest WinStart and buffer other packets.
963 /* For Rx Reorder condition:
964 * 1. All packets with SeqNum smaller than WinStart => Indicate
965 * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it.
967 if (bMatchWinStart) {
968 /* Current packet is going to be indicated.*/
969 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\
970 pTS->RxIndicateSeq, SeqNum);
971 prxbIndicateArray[0] = prxb;
974 /* Current packet is going to be inserted into pending list.*/
975 if (!list_empty(&ieee->RxReorder_Unused_List)) {
976 pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List);
977 list_del_init(&pReorderEntry->List);
979 /* Make a reorder entry and insert into a the packet list.*/
980 pReorderEntry->SeqNum = SeqNum;
981 pReorderEntry->prxb = prxb;
983 if (!AddReorderEntry(pTS, pReorderEntry)) {
984 RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n",
985 __func__, pTS->RxIndicateSeq, SeqNum);
986 list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
989 for (i =0; i < prxb->nr_subframes; i++) {
990 dev_kfree_skb(prxb->subframes[i]);
996 RTLLIB_DEBUG(RTLLIB_DL_REORDER,
997 "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
1002 * Packets are dropped if there is not enough reorder entries.
1003 * This part shall be modified!! We can just indicate all the
1004 * packets in buffer and get reorder entries.
1006 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
1009 for (i =0; i < prxb->nr_subframes; i++) {
1010 dev_kfree_skb(prxb->subframes[i]);
1018 /* Check if there is any packet need indicate.*/
1019 while(!list_empty(&pTS->RxPendingPktList)) {
1020 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): start RREORDER indicate\n",__func__);
1022 pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
1023 if ( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) ||
1024 SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
1026 /* This protect buffer from overflow. */
1027 if (index >= REORDER_WIN_SIZE) {
1028 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n");
1033 list_del_init(&pReorderEntry->List);
1035 if (SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
1036 pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
1038 prxbIndicateArray[index] = pReorderEntry->prxb;
1039 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): Indicate SeqNum %d!\n",__func__, pReorderEntry->SeqNum);
1042 list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
1049 /* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/
1051 if (timer_pending(&pTS->RxPktPendingTimer)){
1052 del_timer_sync(&pTS->RxPktPendingTimer);
1054 pTS->RxTimeoutIndicateSeq = 0xffff;
1056 if (index>REORDER_WIN_SIZE){
1057 RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
1058 spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
1061 rtllib_indicate_packets(ieee, prxbIndicateArray, index);
1065 if (bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) {
1066 RTLLIB_DEBUG(RTLLIB_DL_REORDER,"%s(): SET rx timeout timer\n", __func__);
1067 pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq;
1068 mod_timer(&pTS->RxPktPendingTimer, jiffies + MSECS(pHTInfo->RxReorderPendingTime));
1070 spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
1073 u8 parse_subframe(struct rtllib_device* ieee,struct sk_buff *skb,
1074 struct rtllib_rx_stats *rx_stats,
1075 struct rtllib_rxb *rxb,u8* src,u8* dst)
1077 struct rtllib_hdr_3addr *hdr = (struct rtllib_hdr_3addr* )skb->data;
1078 u16 fc = le16_to_cpu(hdr->frame_ctl);
1080 u16 LLCOffset= sizeof(struct rtllib_hdr_3addr);
1082 bool bIsAggregateFrame = false;
1083 u16 nSubframe_Length;
1084 u8 nPadding_Length = 0;
1086 struct sk_buff *sub_skb;
1088 /* just for debug purpose */
1089 SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl));
1090 if ((RTLLIB_QOS_HAS_SEQ(fc))&&\
1091 (((frameqos *)(skb->data + RTLLIB_3ADDR_LEN))->field.reserved)) {
1092 bIsAggregateFrame = true;
1095 if (RTLLIB_QOS_HAS_SEQ(fc)) {
1098 if (rx_stats->bContainHTC) {
1099 LLCOffset += sHTCLng;
1102 ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/
1104 if ( skb->len <= ChkLength ) {
1108 skb_pull(skb, LLCOffset);
1109 ieee->bIsAggregateFrame = bIsAggregateFrame;
1110 if (!bIsAggregateFrame) {
1111 rxb->nr_subframes = 1;
1113 /* altered by clark 3/30/2010
1114 * The buffer size of the skb indicated to upper layer
1115 * must be less than 5000, or the defraged IP datagram
1116 * in the IP layer will exceed "ipfrag_high_tresh" and be
1117 * discarded. so there must not use the function
1118 * "skb_copy" and "skb_clone" for "skb".
1121 /* Allocate new skb for releasing to upper layer */
1122 sub_skb = dev_alloc_skb(RTLLIB_SKBBUFFER_SIZE);
1123 skb_reserve(sub_skb, 12);
1124 data_ptr = (u8 *)skb_put(sub_skb, skb->len);
1125 memcpy(data_ptr, skb->data, skb->len);
1126 sub_skb->dev = ieee->dev;
1128 rxb->subframes[0] = sub_skb;
1130 memcpy(rxb->src,src,ETH_ALEN);
1131 memcpy(rxb->dst,dst,ETH_ALEN);
1132 rxb->subframes[0]->dev = ieee->dev;
1135 rxb->nr_subframes = 0;
1136 memcpy(rxb->src,src,ETH_ALEN);
1137 memcpy(rxb->dst,dst,ETH_ALEN);
1138 while(skb->len > ETHERNET_HEADER_SIZE) {
1139 /* Offset 12 denote 2 mac address */
1140 nSubframe_Length = *((u16*)(skb->data + 12));
1141 nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
1143 if (skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) {
1144 printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
1145 __func__,rxb->nr_subframes);
1146 printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__func__, nSubframe_Length);
1147 printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length);
1148 printk("The Packet SeqNum is %d\n",SeqNum);
1152 /* move the data point to data content */
1153 skb_pull(skb, ETHERNET_HEADER_SIZE);
1155 /* altered by clark 3/30/2010
1156 * The buffer size of the skb indicated to upper layer
1157 * must be less than 5000, or the defraged IP datagram
1158 * in the IP layer will exceed "ipfrag_high_tresh" and be
1159 * discarded. so there must not use the function
1160 * "skb_copy" and "skb_clone" for "skb".
1163 /* Allocate new skb for releasing to upper layer */
1164 sub_skb = dev_alloc_skb(nSubframe_Length + 12);
1165 skb_reserve(sub_skb, 12);
1166 data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
1167 memcpy(data_ptr,skb->data,nSubframe_Length);
1169 sub_skb->dev = ieee->dev;
1170 rxb->subframes[rxb->nr_subframes++] = sub_skb;
1171 if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
1172 RTLLIB_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
1175 skb_pull(skb,nSubframe_Length);
1177 if (skb->len != 0) {
1178 nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4);
1179 if (nPadding_Length == 4) {
1180 nPadding_Length = 0;
1183 if (skb->len < nPadding_Length) {
1187 skb_pull(skb,nPadding_Length);
1191 return rxb->nr_subframes;
1196 size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee, struct sk_buff *skb,
1197 struct rtllib_rx_stats *rx_stats)
1199 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1200 u16 fc = le16_to_cpu(hdr->frame_ctl);
1203 hdrlen = rtllib_get_hdrlen(fc);
1204 if (HTCCheck(ieee, skb->data)) {
1205 if (net_ratelimit())
1206 printk("%s: find HTCControl!\n", __func__);
1208 rx_stats->bContainHTC = 1;
1211 if (RTLLIB_QOS_HAS_SEQ(fc))
1212 rx_stats->bIsQosData = 1;
1217 int rtllib_rx_check_duplicate(struct rtllib_device *ieee, struct sk_buff *skb, u8 multicast)
1219 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1221 u8 frag, type, stype;
1223 fc = le16_to_cpu(hdr->frame_ctl);
1224 type = WLAN_FC_GET_TYPE(fc);
1225 stype = WLAN_FC_GET_STYPE(fc);
1226 sc = le16_to_cpu(hdr->seq_ctl);
1227 frag = WLAN_GET_SEQ_FRAG(sc);
1229 if ( (ieee->pHTInfo->bCurRxReorderEnable == false) ||
1230 !ieee->current_network.qos_data.active ||
1231 !IsDataFrame(skb->data) ||
1232 IsLegacyDataFrame(skb->data)) {
1233 if (!((type == RTLLIB_FTYPE_MGMT) && (stype == RTLLIB_STYPE_BEACON))){
1234 if (is_duplicate_packet(ieee, hdr)){
1239 PRX_TS_RECORD pRxTS = NULL;
1240 if (GetTs(ieee, (PTS_COMMON_INFO*) &pRxTS, hdr->addr2,
1241 (u8)Frame_QoSTID((u8*)(skb->data)), RX_DIR, true)) {
1242 if ((fc & (1<<11)) && (frag == pRxTS->RxLastFragNum) &&
1243 (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)) {
1246 pRxTS->RxLastFragNum = frag;
1247 pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
1250 RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip the check!!\n",__func__);
1257 void rtllib_rx_extract_addr(struct rtllib_device *ieee, struct rtllib_hdr_4addr *hdr, u8 *dst, u8 *src, u8 *bssid)
1259 u16 fc = le16_to_cpu(hdr->frame_ctl);
1261 switch (fc & (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) {
1262 case RTLLIB_FCTL_FROMDS:
1263 memcpy(dst, hdr->addr1, ETH_ALEN);
1264 memcpy(src, hdr->addr3, ETH_ALEN);
1265 memcpy(bssid, hdr->addr2, ETH_ALEN);
1267 case RTLLIB_FCTL_TODS:
1268 memcpy(dst, hdr->addr3, ETH_ALEN);
1269 memcpy(src, hdr->addr2, ETH_ALEN);
1270 memcpy(bssid, hdr->addr1, ETH_ALEN);
1272 case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS:
1273 memcpy(dst, hdr->addr3, ETH_ALEN);
1274 memcpy(src, hdr->addr4, ETH_ALEN);
1275 memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
1278 memcpy(dst, hdr->addr1, ETH_ALEN);
1279 memcpy(src, hdr->addr2, ETH_ALEN);
1280 memcpy(bssid, hdr->addr3, ETH_ALEN);
1284 int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, u8 *dst, u8 *src, u8 *bssid, u8 *addr2)
1286 u8 zero_addr[ETH_ALEN] = {0};
1289 type = WLAN_FC_GET_TYPE(fc);
1290 stype = WLAN_FC_GET_STYPE(fc);
1292 /* Filter frames from different BSS */
1293 if (((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS)
1294 && (compare_ether_addr(ieee->current_network.bssid, bssid) != 0)
1295 && memcmp(ieee->current_network.bssid, zero_addr, ETH_ALEN)) {
1299 /* Filter packets sent by an STA that will be forwarded by AP */
1300 if ( ieee->IntelPromiscuousModeInfo.bPromiscuousOn &&
1301 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame ) {
1302 if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) &&
1303 (compare_ether_addr(dst, ieee->current_network.bssid) != 0) &&
1304 (compare_ether_addr(bssid, ieee->current_network.bssid) == 0)) {
1309 /* Nullfunc frames may have PS-bit set, so they must be passed to
1310 * hostap_handle_sta_rx() before being dropped here. */
1311 if (!ieee->IntelPromiscuousModeInfo.bPromiscuousOn){
1312 if (stype != RTLLIB_STYPE_DATA &&
1313 stype != RTLLIB_STYPE_DATA_CFACK &&
1314 stype != RTLLIB_STYPE_DATA_CFPOLL &&
1315 stype != RTLLIB_STYPE_DATA_CFACKPOLL&&
1316 stype != RTLLIB_STYPE_QOS_DATA
1318 if (stype != RTLLIB_STYPE_NULLFUNC)
1320 "RX: dropped data frame "
1321 "with no data (type=0x%02x, "
1322 "subtype=0x%02x)\n",
1328 if (ieee->iw_mode != IW_MODE_MESH) {
1329 /* packets from our adapter are dropped (echo) */
1330 if (!memcmp(src, ieee->dev->dev_addr, ETH_ALEN))
1333 /* {broad,multi}cast packets to our BSS go through */
1334 if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) {
1335 if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) {
1342 int rtllib_rx_get_crypt(
1343 struct rtllib_device *ieee,
1344 struct sk_buff *skb,
1345 struct rtllib_crypt_data **crypt,
1348 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1349 u16 fc = le16_to_cpu(hdr->frame_ctl);
1352 if (ieee->host_decrypt) {
1353 if (skb->len >= hdrlen + 3)
1354 idx = skb->data[hdrlen + 3] >> 6;
1356 *crypt = ieee->crypt[idx];
1357 /* allow NULL decrypt to indicate an station specific override
1358 * for default encryption */
1359 if (*crypt && ((*crypt)->ops == NULL ||
1360 (*crypt)->ops->decrypt_mpdu == NULL))
1363 if (!*crypt && (fc & RTLLIB_FCTL_WEP)) {
1364 /* This seems to be triggered by some (multicast?)
1365 * frames from other than current BSS, so just drop the
1366 * frames silently instead of filling system log with
1368 RTLLIB_DEBUG_DROP("Decryption failed (not set)"
1369 " (SA=" MAC_FMT ")\n",
1370 MAC_ARG(hdr->addr2));
1371 ieee->ieee_stats.rx_discards_undecryptable++;
1378 int rtllib_rx_decrypt(
1379 struct rtllib_device *ieee,
1380 struct sk_buff *skb,
1381 struct rtllib_rx_stats *rx_stats,
1382 struct rtllib_crypt_data *crypt,
1385 struct rtllib_hdr_4addr *hdr;
1390 hdr = (struct rtllib_hdr_4addr *)skb->data;
1391 fc = le16_to_cpu(hdr->frame_ctl);
1392 sc = le16_to_cpu(hdr->seq_ctl);
1393 frag = WLAN_GET_SEQ_FRAG(sc);
1395 if ((!rx_stats->Decrypted)){
1396 ieee->need_sw_enc = 1;
1398 ieee->need_sw_enc = 0;
1401 if (ieee->host_decrypt && (fc & RTLLIB_FCTL_WEP) &&
1402 ((keyidx = rtllib_rx_frame_decrypt(ieee, skb, crypt)) < 0)) {
1403 printk("%s: decrypt frame error\n", __func__);
1407 hdr = (struct rtllib_hdr_4addr *) skb->data;
1408 if ((frag != 0 || (fc & RTLLIB_FCTL_MOREFRAGS))) {
1410 struct sk_buff *frag_skb = rtllib_frag_cache_get(ieee, hdr);
1411 RTLLIB_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
1414 RTLLIB_DEBUG(RTLLIB_DL_RX | RTLLIB_DL_FRAG,
1415 "Rx cannot get skb from fragment "
1416 "cache (morefrag=%d seq=%u frag=%u)\n",
1417 (fc & RTLLIB_FCTL_MOREFRAGS) != 0,
1418 WLAN_GET_SEQ_SEQ(sc), frag);
1425 if (frag_skb->tail + flen > frag_skb->end) {
1426 printk(KERN_WARNING "%s: host decrypted and "
1427 "reassembled frame did not fit skb\n",
1429 rtllib_frag_cache_invalidate(ieee, hdr);
1434 /* copy first fragment (including full headers) into
1435 * beginning of the fragment cache skb */
1436 memcpy(skb_put(frag_skb, flen), skb->data, flen);
1438 /* append frame payload to the end of the fragment
1440 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
1443 dev_kfree_skb_any(skb);
1446 if (fc & RTLLIB_FCTL_MOREFRAGS) {
1447 /* more fragments expected - leave the skb in fragment
1448 * cache for now; it will be delivered to upper layers
1449 * after all fragments have been received */
1453 /* this was the last fragment and the frame will be
1454 * delivered, so remove skb from fragment cache */
1456 hdr = (struct rtllib_hdr_4addr *) skb->data;
1457 rtllib_frag_cache_invalidate(ieee, hdr);
1460 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
1461 * encrypted/authenticated */
1462 if (ieee->host_decrypt && (fc & RTLLIB_FCTL_WEP) &&
1463 rtllib_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
1465 printk("%s: ==>decrypt msdu error\n", __func__);
1469 hdr = (struct rtllib_hdr_4addr *) skb->data;
1470 if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep) {
1471 if (/*ieee->ieee802_1x &&*/
1472 rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1474 #ifdef CONFIG_RTLLIB_DEBUG
1475 /* pass unencrypted EAPOL frames even if encryption is
1477 struct eapol *eap = (struct eapol *)(skb->data +
1479 RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
1480 eap_get_type(eap->type));
1484 "encryption configured, but RX "
1485 "frame not encrypted (SA=" MAC_FMT ")\n",
1486 MAC_ARG(hdr->addr2));
1491 #ifdef CONFIG_RTLLIB_DEBUG
1492 if (crypt && !(fc & RTLLIB_FCTL_WEP) &&
1493 rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1494 struct eapol *eap = (struct eapol *)(skb->data +
1496 RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
1497 eap_get_type(eap->type));
1501 if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep &&
1502 !rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1504 "dropped unencrypted RX data "
1505 "frame from " MAC_FMT
1506 " (drop_unencrypted=1)\n",
1507 MAC_ARG(hdr->addr2));
1511 if (rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
1512 printk(KERN_WARNING "RX: IEEE802.1X EAPOL frame!\n");
1517 void rtllib_rx_check_leave_lps(struct rtllib_device *ieee, u8 unicast, u8 nr_subframes)
1521 if ((ieee->state == RTLLIB_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
1523 if ( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
1524 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
1526 if (ieee->LeisurePSLeave)
1527 ieee->LeisurePSLeave(ieee->dev);
1531 ieee->last_rx_ps_time = jiffies;
1533 void rtllib_rx_indicate_pkt_legacy(
1534 struct rtllib_device *ieee,
1535 struct rtllib_rx_stats *rx_stats,
1536 struct rtllib_rxb* rxb,
1540 struct net_device *dev = ieee->dev;
1545 printk("%s: rxb is NULL!!\n", __func__);
1549 for (i = 0; i<rxb->nr_subframes; i++) {
1550 struct sk_buff *sub_skb = rxb->subframes[i];
1553 /* convert hdr + possible LLC headers into Ethernet header */
1554 ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
1555 if (sub_skb->len >= 8 &&
1556 ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
1557 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1558 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
1559 /* remove RFC1042 or Bridge-Tunnel encapsulation and
1560 * replace EtherType */
1561 skb_pull(sub_skb, SNAP_SIZE);
1562 memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
1563 memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
1566 /* Leave Ethernet header part of hdr and full payload */
1567 len = htons(sub_skb->len);
1568 memcpy(skb_push(sub_skb, 2), &len, 2);
1569 memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
1570 memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
1573 ieee->stats.rx_packets++;
1574 ieee->stats.rx_bytes += sub_skb->len;
1576 if (is_multicast_ether_addr(dst)) {
1577 ieee->stats.multicast++;
1580 /* Indicat the packets to upper layer */
1581 memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
1582 sub_skb->protocol = eth_type_trans(sub_skb, dev);
1584 sub_skb->dev->stats.rx_packets++;
1585 sub_skb->dev->stats.rx_bytes += sub_skb->len;
1586 #ifdef TCP_CSUM_OFFLOAD_RX
1587 if ( rx_stats->tcp_csum_valid)
1588 sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
1590 sub_skb->ip_summed = CHECKSUM_NONE;
1592 sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
1600 int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb,
1601 struct rtllib_rx_stats *rx_stats)
1603 struct net_device *dev = ieee->dev;
1604 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1605 struct rtllib_crypt_data *crypt = NULL;
1606 struct rtllib_rxb* rxb = NULL;
1607 PRX_TS_RECORD pTS = NULL;
1608 u16 fc, sc, SeqNum = 0;
1609 u8 type, stype, multicast = 0, unicast = 0, nr_subframes = 0, TID = 0;
1610 u8 dst[ETH_ALEN], src[ETH_ALEN], bssid[ETH_ALEN] = {0}, *payload;
1612 bool bToOtherSTA = false;
1615 hdr = (struct rtllib_hdr_4addr *)skb->data;
1616 fc = le16_to_cpu(hdr->frame_ctl);
1617 type = WLAN_FC_GET_TYPE(fc);
1618 stype = WLAN_FC_GET_STYPE(fc);
1619 sc = le16_to_cpu(hdr->seq_ctl);
1621 /*Filter pkt not to me*/
1622 multicast = is_multicast_ether_addr(hdr->addr1)|is_broadcast_ether_addr(hdr->addr1);
1623 unicast = !multicast;
1624 if (unicast && (compare_ether_addr(dev->dev_addr, hdr->addr1) != 0)) {
1625 if (ieee->bNetPromiscuousMode)
1631 /*Filter pkt has too small length */
1632 hdrlen = rtllib_rx_get_hdrlen(ieee, skb, rx_stats);
1633 if (skb->len < hdrlen){
1634 printk("%s():ERR!!! skb->len is smaller than hdrlen\n",__func__);
1638 /* Filter Duplicate pkt */
1639 ret = rtllib_rx_check_duplicate(ieee, skb, multicast);
1643 /* Filter CTRL Frame */
1644 if (type == RTLLIB_FTYPE_CTL) {
1648 /* Filter MGNT Frame */
1649 if (type == RTLLIB_FTYPE_MGMT) {
1652 if (rtllib_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
1658 /* Filter WAPI DATA Frame */
1660 /* Update statstics for AP roaming */
1662 ieee->LinkDetectInfo.NumRecvDataInPeriod++;
1663 ieee->LinkDetectInfo.NumRxOkInPeriod++;
1665 dev->last_rx = jiffies;
1667 /* Data frame - extract src/dst addresses */
1668 rtllib_rx_extract_addr(ieee, hdr, dst, src, bssid);
1670 /* Filter Data frames */
1671 ret = rtllib_rx_data_filter(ieee, fc, dst, src, bssid, hdr->addr2);
1675 if (skb->len == hdrlen){
1679 /* Send pspoll based on moredata */
1680 if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == LPS_IS_SLEEP)
1681 && (ieee->polling) && (!bToOtherSTA)) {
1682 if (WLAN_FC_MORE_DATA(fc)) {
1683 /* more data bit is set, let's request a new frame from the AP */
1684 rtllib_sta_ps_send_pspoll_frame(ieee);
1686 ieee->polling = false;
1690 /* Get crypt if encrypted */
1691 ret = rtllib_rx_get_crypt(ieee, skb, &crypt, hdrlen);
1695 /* Decrypt data frame (including reassemble) */
1696 ret = rtllib_rx_decrypt(ieee, skb, rx_stats, crypt, hdrlen);
1702 /* Get TS for Rx Reorder */
1703 hdr = (struct rtllib_hdr_4addr *) skb->data;
1704 if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data)
1705 && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1)
1708 TID = Frame_QoSTID(skb->data);
1709 SeqNum = WLAN_GET_SEQ_SEQ(sc);
1710 GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true);
1711 if (TID !=0 && TID !=3){
1712 ieee->bis_any_nonbepkts = true;
1716 /* Parse rx data frame (For AMSDU) */
1717 /* skb: hdr + (possible reassembled) full plaintext payload */
1718 payload = skb->data + hdrlen;
1719 rxb = (struct rtllib_rxb*)kmalloc(sizeof(struct rtllib_rxb),GFP_ATOMIC);
1722 RTLLIB_DEBUG(RTLLIB_DL_ERR,"%s(): kmalloc rxb error\n",__func__);
1725 /* to parse amsdu packets */
1726 /* qos data packets & reserved bit is 1 */
1727 if (parse_subframe(ieee,skb,rx_stats,rxb,src,dst) == 0) {
1728 /* only to free rxb, and not submit the packets to upper layer */
1729 for (i =0; i < rxb->nr_subframes; i++) {
1730 dev_kfree_skb(rxb->subframes[i]);
1737 /* Update WAPI PN */
1739 /* Check if leave LPS */
1741 if (ieee->bIsAggregateFrame)
1742 nr_subframes = rxb->nr_subframes;
1746 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod += nr_subframes;
1747 rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes);
1750 /* Indicate packets to upper layer or Rx Reorder */
1751 if (ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL || bToOtherSTA){
1752 rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src);
1754 #ifdef TCP_CSUM_OFFLOAD_RX
1755 rxb->tcp_csum_valid = rx_stats->tcp_csum_valid;
1757 RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
1771 ieee->stats.rx_dropped++;
1773 /* Returning 0 indicates to caller that we have not handled the SKB--
1774 * so it is still allocated and can be used again by underlying
1775 * hardware as a DMA target */
1779 int rtllib_rx_Master(struct rtllib_device *ieee, struct sk_buff *skb,
1780 struct rtllib_rx_stats *rx_stats)
1784 int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb,
1785 struct rtllib_rx_stats *rx_stats)
1787 struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data;
1788 u16 fc = le16_to_cpu(hdr->frame_ctl);
1789 size_t hdrlen = rtllib_get_hdrlen(fc);
1791 if (skb->len < hdrlen){
1792 printk("%s():ERR!!! skb->len is smaller than hdrlen\n", __func__);
1796 if (HTCCheck(ieee, skb->data)) {
1797 if (net_ratelimit())
1798 printk("%s: Find HTCControl!\n", __func__);
1802 rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
1803 ieee->stats.rx_packets++;
1804 ieee->stats.rx_bytes += skb->len;
1809 int rtllib_rx_Mesh(struct rtllib_device *ieee, struct sk_buff *skb,
1810 struct rtllib_rx_stats *rx_stats)
1815 /* All received frames are sent to this function. @skb contains the frame in
1816 * IEEE 802.11 format, i.e., in the format it was sent over air.
1817 * This function is called only as a tasklet (software IRQ). */
1818 int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
1819 struct rtllib_rx_stats *rx_stats)
1823 if ((NULL==ieee) || (NULL==skb) || (NULL==rx_stats)){
1824 printk(KERN_INFO "%s: Input parameters NULL!\n", __func__);
1827 if (skb->len < 10) {
1828 printk(KERN_INFO "%s: SKB length < 10 \n", __func__);
1832 switch (ieee->iw_mode) {
1835 ret = rtllib_rx_InfraAdhoc(ieee, skb, rx_stats);
1837 case IW_MODE_MASTER:
1838 case IW_MODE_REPEAT:
1839 ret = rtllib_rx_Master(ieee, skb, rx_stats);
1841 case IW_MODE_MONITOR:
1842 ret = rtllib_rx_Monitor(ieee, skb, rx_stats);
1845 ret = rtllib_rx_Mesh(ieee, skb, rx_stats);
1848 printk(KERN_INFO"%s: ERR iw mode!!!\n", __func__);
1855 ieee->stats.rx_dropped++;
1859 static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
1862 * Make ther structure we read from the beacon packet has
1865 static int rtllib_verify_qos_info(struct rtllib_qos_information_element
1866 *info_element, int sub_type)
1869 if (info_element->qui_subtype != sub_type)
1871 if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
1873 if (info_element->qui_type != QOS_OUI_TYPE)
1875 if (info_element->version != QOS_VERSION_1)
1883 * Parse a QoS parameter element
1885 static int rtllib_read_qos_param_element(struct rtllib_qos_parameter_info
1886 *element_param, struct rtllib_info_element
1890 u16 size = sizeof(struct rtllib_qos_parameter_info) - 2;
1892 if ((info_element == NULL) || (element_param == NULL))
1895 if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
1896 memcpy(element_param->info_element.qui, info_element->data,
1898 element_param->info_element.elementID = info_element->id;
1899 element_param->info_element.length = info_element->len;
1903 ret = rtllib_verify_qos_info(&element_param->info_element,
1904 QOS_OUI_PARAM_SUB_TYPE);
1909 * Parse a QoS information element
1911 static int rtllib_read_qos_info_element(struct
1912 rtllib_qos_information_element
1913 *element_info, struct rtllib_info_element
1917 u16 size = sizeof(struct rtllib_qos_information_element) - 2;
1919 if (element_info == NULL)
1921 if (info_element == NULL)
1924 if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
1925 memcpy(element_info->qui, info_element->data,
1927 element_info->elementID = info_element->id;
1928 element_info->length = info_element->len;
1933 ret = rtllib_verify_qos_info(element_info,
1934 QOS_OUI_INFO_SUB_TYPE);
1940 * Write QoS parameters from the ac parameters.
1942 static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info *param_elm,
1943 struct rtllib_qos_data *qos_data)
1945 struct rtllib_qos_ac_parameter *ac_params;
1946 struct rtllib_qos_parameters *qos_param = &(qos_data->parameters);
1952 qos_data->wmm_acm = 0;
1953 for (i = 0; i < QOS_QUEUE_NUM; i++) {
1954 ac_params = &(param_elm->ac_params_record[i]);
1956 aci = (ac_params->aci_aifsn & 0x60) >> 5;
1957 acm = (ac_params->aci_aifsn & 0x10) >> 4;
1959 if (aci >= QOS_QUEUE_NUM)
1963 /* BIT(0) | BIT(3) */
1965 qos_data->wmm_acm |= (0x01<<0)|(0x01<<3);
1968 /* BIT(4) | BIT(5) */
1970 qos_data->wmm_acm |= (0x01<<4)|(0x01<<5);
1973 /* BIT(6) | BIT(7) */
1975 qos_data->wmm_acm |= (0x01<<6)|(0x01<<7);
1979 /* BIT(1) | BIT(2) */
1981 qos_data->wmm_acm |= (0x01<<1)|(0x01<<2);
1985 qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
1987 /* WMM spec P.11: The minimum value for AIFSN shall be 2 */
1988 qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci];
1990 qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
1992 qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
1994 qos_param->flag[aci] =
1995 (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
1996 qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
2002 * we have a generic data element which it may contain QoS information or
2003 * parameters element. check the information element length to decide
2004 * which type to read
2006 static int rtllib_parse_qos_info_param_IE(struct rtllib_info_element
2008 struct rtllib_network *network)
2011 struct rtllib_qos_information_element qos_info_element;
2013 rc = rtllib_read_qos_info_element(&qos_info_element, info_element);
2016 network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
2017 network->flags |= NETWORK_HAS_QOS_INFORMATION;
2019 struct rtllib_qos_parameter_info param_element;
2021 rc = rtllib_read_qos_param_element(¶m_element,
2024 rtllib_qos_convert_ac_to_parameters(¶m_element,
2025 &(network->qos_data));
2026 network->flags |= NETWORK_HAS_QOS_PARAMETERS;
2027 network->qos_data.param_count =
2028 param_element.info_element.ac_info & 0x0F;
2033 RTLLIB_DEBUG_QOS("QoS is supported\n");
2034 network->qos_data.supported = 1;
2039 #ifdef CONFIG_RTLLIB_DEBUG
2040 #define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
2042 static const char *get_info_element_string(u16 id)
2047 MFIE_STRING(FH_SET);
2048 MFIE_STRING(DS_SET);
2049 MFIE_STRING(CF_SET);
2051 MFIE_STRING(IBSS_SET);
2052 MFIE_STRING(COUNTRY);
2053 MFIE_STRING(HOP_PARAMS);
2054 MFIE_STRING(HOP_TABLE);
2055 MFIE_STRING(REQUEST);
2056 MFIE_STRING(CHALLENGE);
2057 MFIE_STRING(POWER_CONSTRAINT);
2058 MFIE_STRING(POWER_CAPABILITY);
2059 MFIE_STRING(TPC_REQUEST);
2060 MFIE_STRING(TPC_REPORT);
2061 MFIE_STRING(SUPP_CHANNELS);
2063 MFIE_STRING(MEASURE_REQUEST);
2064 MFIE_STRING(MEASURE_REPORT);
2066 MFIE_STRING(IBSS_DFS);
2068 MFIE_STRING(RATES_EX);
2069 MFIE_STRING(GENERIC);
2070 MFIE_STRING(QOS_PARAMETER);
2077 #ifdef ENABLE_DOT11D
2078 static inline void rtllib_extract_country_ie(
2079 struct rtllib_device *ieee,
2080 struct rtllib_info_element *info_element,
2081 struct rtllib_network *network,
2084 if (IS_DOT11D_ENABLE(ieee)) {
2085 if (info_element->len!= 0) {
2086 memcpy(network->CountryIeBuf, info_element->data, info_element->len);
2087 network->CountryIeLen = info_element->len;
2089 if (!IS_COUNTRY_IE_VALID(ieee))
2091 if ((rtllib_act_scanning(ieee,false) == true) && (ieee->FirstIe_InScan == 1))
2092 printk("Received beacon ContryIE, SSID: <%s>\n",network->ssid);
2093 Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
2097 if (IS_EQUAL_CIE_SRC(ieee, addr2)) {
2098 UPDATE_CIE_WATCHDOG(ieee);
2105 int rtllib_parse_info_param(struct rtllib_device *ieee,
2106 struct rtllib_info_element *info_element,
2108 struct rtllib_network *network,
2109 struct rtllib_rx_stats *stats)
2113 u16 tmp_htcap_len=0;
2114 u16 tmp_htinfo_len=0;
2115 u16 ht_realtek_agg_len=0;
2116 u8 ht_realtek_agg_buf[MAX_IE_LEN];
2117 #ifdef CONFIG_RTLLIB_DEBUG
2121 while (length >= sizeof(*info_element)) {
2122 if (sizeof(*info_element) + info_element->len > length) {
2123 RTLLIB_DEBUG_MGMT("Info elem: parse failed: "
2124 "info_element->len + 2 > left : "
2125 "info_element->len+2=%zd left=%d, id=%d.\n",
2127 sizeof(*info_element),
2128 length, info_element->id);
2129 /* We stop processing but don't return an error here
2130 * because some misbehaviour APs break this rule. ie.
2131 * Orinoco AP1000. */
2135 switch (info_element->id) {
2136 case MFIE_TYPE_SSID:
2137 if (rtllib_is_empty_essid(info_element->data,
2138 info_element->len)) {
2139 network->flags |= NETWORK_EMPTY_ESSID;
2143 network->ssid_len = min(info_element->len,
2144 (u8) IW_ESSID_MAX_SIZE);
2145 memcpy(network->ssid, info_element->data, network->ssid_len);
2146 if (network->ssid_len < IW_ESSID_MAX_SIZE)
2147 memset(network->ssid + network->ssid_len, 0,
2148 IW_ESSID_MAX_SIZE - network->ssid_len);
2150 RTLLIB_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
2151 network->ssid, network->ssid_len);
2154 case MFIE_TYPE_RATES:
2155 #ifdef CONFIG_RTLLIB_DEBUG
2158 network->rates_len = min(info_element->len,
2160 for (i = 0; i < network->rates_len; i++) {
2161 network->rates[i] = info_element->data[i];
2162 #ifdef CONFIG_RTLLIB_DEBUG
2163 p += snprintf(p, sizeof(rates_str) -
2164 (p - rates_str), "%02X ",
2167 if (rtllib_is_ofdm_rate
2168 (info_element->data[i])) {
2169 network->flags |= NETWORK_HAS_OFDM;
2170 if (info_element->data[i] &
2171 RTLLIB_BASIC_RATE_MASK)
2176 if (rtllib_is_cck_rate
2177 (info_element->data[i])) {
2178 network->flags |= NETWORK_HAS_CCK;
2182 RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
2183 rates_str, network->rates_len);
2186 case MFIE_TYPE_RATES_EX:
2187 #ifdef CONFIG_RTLLIB_DEBUG
2190 network->rates_ex_len = min(info_element->len,
2191 MAX_RATES_EX_LENGTH);
2192 for (i = 0; i < network->rates_ex_len; i++) {
2193 network->rates_ex[i] = info_element->data[i];
2194 #ifdef CONFIG_RTLLIB_DEBUG
2195 p += snprintf(p, sizeof(rates_str) -
2196 (p - rates_str), "%02X ",
2199 if (rtllib_is_ofdm_rate
2200 (info_element->data[i])) {
2201 network->flags |= NETWORK_HAS_OFDM;
2202 if (info_element->data[i] &
2203 RTLLIB_BASIC_RATE_MASK)
2209 RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
2210 rates_str, network->rates_ex_len);
2213 case MFIE_TYPE_DS_SET:
2214 RTLLIB_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
2215 info_element->data[0]);
2216 network->channel = info_element->data[0];
2219 case MFIE_TYPE_FH_SET:
2220 RTLLIB_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
2223 case MFIE_TYPE_CF_SET:
2224 RTLLIB_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
2228 if (info_element->len < 4)
2231 network->tim.tim_count = info_element->data[0];
2232 network->tim.tim_period = info_element->data[1];
2234 network->dtim_period = info_element->data[1];
2235 if (ieee->state != RTLLIB_LINKED)
2237 network->last_dtim_sta_time[0] = jiffies;
2238 network->last_dtim_sta_time[1] = stats->mac_time[1];
2240 network->dtim_data = RTLLIB_DTIM_VALID;
2243 if (info_element->data[2] & 1)
2244 network->dtim_data |= RTLLIB_DTIM_MBCAST;
2246 offset = (info_element->data[2] >> 1)*2;
2249 if (ieee->assoc_id < 8*offset ||
2250 ieee->assoc_id > 8*(offset + info_element->len -3))
2254 offset = (ieee->assoc_id / 8) - offset;
2255 if (info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
2256 network->dtim_data |= RTLLIB_DTIM_UCAST;
2258 network->listen_interval = network->dtim_period;
2262 network->erp_value = info_element->data[0];
2263 network->flags |= NETWORK_HAS_ERP_VALUE;
2264 RTLLIB_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
2265 network->erp_value);
2267 case MFIE_TYPE_IBSS_SET:
2268 network->atim_window = info_element->data[0];
2269 RTLLIB_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
2270 network->atim_window);
2273 case MFIE_TYPE_CHALLENGE:
2274 RTLLIB_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
2277 case MFIE_TYPE_GENERIC:
2278 RTLLIB_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
2280 if (!rtllib_parse_qos_info_param_IE(info_element,
2283 if (info_element->len >= 4 &&
2284 info_element->data[0] == 0x00 &&
2285 info_element->data[1] == 0x50 &&
2286 info_element->data[2] == 0xf2 &&
2287 info_element->data[3] == 0x01) {
2288 network->wpa_ie_len = min(info_element->len + 2,
2290 memcpy(network->wpa_ie, info_element,
2291 network->wpa_ie_len);
2294 if (info_element->len == 7 &&
2295 info_element->data[0] == 0x00 &&
2296 info_element->data[1] == 0xe0 &&
2297 info_element->data[2] == 0x4c &&
2298 info_element->data[3] == 0x01 &&
2299 info_element->data[4] == 0x02)
2300 network->Turbo_Enable = 1;
2302 if (tmp_htcap_len == 0) {
2303 if (info_element->len >= 4 &&
2304 info_element->data[0] == 0x00 &&
2305 info_element->data[1] == 0x90 &&
2306 info_element->data[2] == 0x4c &&
2307 info_element->data[3] == 0x033) {
2309 tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
2310 if (tmp_htcap_len != 0){
2311 network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
2312 network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
2313 sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
2314 memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
2317 if (tmp_htcap_len != 0){
2318 network->bssht.bdSupportHT = true;
2319 network->bssht.bdHT1R = ((((PHT_CAPABILITY_ELE)(network->bssht.bdHTCapBuf))->MCS[1]) == 0);
2321 network->bssht.bdSupportHT = false;
2322 network->bssht.bdHT1R = false;
2327 if (tmp_htinfo_len == 0){
2328 if (info_element->len >= 4 &&
2329 info_element->data[0] == 0x00 &&
2330 info_element->data[1] == 0x90 &&
2331 info_element->data[2] == 0x4c &&
2332 info_element->data[3] == 0x034){
2334 tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
2335 if (tmp_htinfo_len != 0){
2336 network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
2337 if (tmp_htinfo_len){
2338 network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
2339 sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
2340 memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
2348 if (ieee->aggregation){
2349 if (network->bssht.bdSupportHT){
2350 if (info_element->len >= 4 &&
2351 info_element->data[0] == 0x00 &&
2352 info_element->data[1] == 0xe0 &&
2353 info_element->data[2] == 0x4c &&
2354 info_element->data[3] == 0x02){
2356 ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN);
2357 memcpy(ht_realtek_agg_buf,info_element->data,info_element->len);
2360 if (ht_realtek_agg_len >= 5){
2361 network->realtek_cap_exit = true;
2362 network->bssht.bdRT2RTAggregation = true;
2364 if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02))
2365 network->bssht.bdRT2RTLongSlotTime = true;
2367 if ((ht_realtek_agg_buf[4]==1) && (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE))
2369 network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE;
2373 if (ht_realtek_agg_len >= 5){
2374 if ((ht_realtek_agg_buf[5] & RT_HT_CAP_USE_SOFTAP))
2375 network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_SOFTAP;
2380 if ((info_element->len >= 3 &&
2381 info_element->data[0] == 0x00 &&
2382 info_element->data[1] == 0x05 &&
2383 info_element->data[2] == 0xb5) ||
2384 (info_element->len >= 3 &&
2385 info_element->data[0] == 0x00 &&
2386 info_element->data[1] == 0x0a &&
2387 info_element->data[2] == 0xf7) ||
2388 (info_element->len >= 3 &&
2389 info_element->data[0] == 0x00 &&
2390 info_element->data[1] == 0x10 &&
2391 info_element->data[2] == 0x18)){
2393 network->broadcom_cap_exist = true;
2397 if (info_element->len >= 3 &&
2398 info_element->data[0] == 0x00 &&
2399 info_element->data[1] == 0x0c &&
2400 info_element->data[2] == 0x43)
2402 network->ralink_cap_exist = true;
2404 if ((info_element->len >= 3 &&
2405 info_element->data[0] == 0x00 &&
2406 info_element->data[1] == 0x03 &&
2407 info_element->data[2] == 0x7f) ||
2408 (info_element->len >= 3 &&
2409 info_element->data[0] == 0x00 &&
2410 info_element->data[1] == 0x13 &&
2411 info_element->data[2] == 0x74))
2413 network->atheros_cap_exist = true;
2416 if ((info_element->len >= 3 &&
2417 info_element->data[0] == 0x00 &&
2418 info_element->data[1] == 0x50 &&
2419 info_element->data[2] == 0x43) )
2421 network->marvell_cap_exist = true;
2423 if (info_element->len >= 3 &&
2424 info_element->data[0] == 0x00 &&
2425 info_element->data[1] == 0x40 &&
2426 info_element->data[2] == 0x96)
2428 network->cisco_cap_exist = true;
2432 if (info_element->len >= 3 &&
2433 info_element->data[0] == 0x00 &&
2434 info_element->data[1] == 0x0a &&
2435 info_element->data[2] == 0xf5)
2437 network->airgo_cap_exist = true;
2440 if (info_element->len > 4 &&
2441 info_element->data[0] == 0x00 &&
2442 info_element->data[1] == 0x40 &&
2443 info_element->data[2] == 0x96 &&
2444 info_element->data[3] == 0x01)
2446 if (info_element->len == 6)
2448 memcpy(network->CcxRmState, &info_element[4], 2);
2449 if (network->CcxRmState[0] != 0)
2451 network->bCcxRmEnable = true;
2454 network->bCcxRmEnable = false;
2455 network->MBssidMask = network->CcxRmState[1] & 0x07;
2456 if (network->MBssidMask != 0)
2458 network->bMBssidValid = true;
2459 network->MBssidMask = 0xff << (network->MBssidMask);
2460 memcpy(network->MBssid, network->bssid, ETH_ALEN);
2461 network->MBssid[5] &= network->MBssidMask;
2465 network->bMBssidValid = false;
2470 network->bCcxRmEnable = false;
2473 if (info_element->len > 4 &&
2474 info_element->data[0] == 0x00 &&
2475 info_element->data[1] == 0x40 &&
2476 info_element->data[2] == 0x96 &&
2477 info_element->data[3] == 0x03)
2479 if (info_element->len == 5)
2481 network->bWithCcxVerNum = true;
2482 network->BssCcxVerNumber = info_element->data[4];
2486 network->bWithCcxVerNum = false;
2487 network->BssCcxVerNumber = 0;
2490 if (info_element->len > 4 &&
2491 info_element->data[0] == 0x00 &&
2492 info_element->data[1] == 0x50 &&
2493 info_element->data[2] == 0xf2 &&
2494 info_element->data[3] == 0x04)
2496 RTLLIB_DEBUG_MGMT("MFIE_TYPE_WZC: %d bytes\n",
2498 network->wzc_ie_len = min(info_element->len+2,
2500 memcpy(network->wzc_ie, info_element,
2501 network->wzc_ie_len);
2506 RTLLIB_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
2508 network->rsn_ie_len = min(info_element->len + 2,
2510 memcpy(network->rsn_ie, info_element,
2511 network->rsn_ie_len);
2514 case MFIE_TYPE_HT_CAP:
2515 RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n",
2517 tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
2518 if (tmp_htcap_len != 0){
2519 network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
2520 network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
2521 sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
2522 memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
2524 network->bssht.bdSupportHT = true;
2525 network->bssht.bdHT1R = ((((PHT_CAPABILITY_ELE)(network->bssht.bdHTCapBuf))->MCS[1]) == 0);
2527 network->bssht.bdBandWidth = (HT_CHANNEL_WIDTH)(((PHT_CAPABILITY_ELE)(network->bssht.bdHTCapBuf))->ChlWidth);
2530 network->bssht.bdSupportHT = false;
2531 network->bssht.bdHT1R = false;
2532 network->bssht.bdBandWidth = HT_CHANNEL_WIDTH_20 ;
2537 case MFIE_TYPE_HT_INFO:
2538 RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n",
2540 tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
2541 if (tmp_htinfo_len){
2542 network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE;
2543 network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
2544 sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
2545 memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
2549 case MFIE_TYPE_AIRONET:
2550 RTLLIB_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n",
2552 if (info_element->len >IE_CISCO_FLAG_POSITION)
2554 network->bWithAironetIE = true;
2556 if ( (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC) ||
2557 (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK) )
2559 network->bCkipSupported = true;
2563 network->bCkipSupported = false;
2568 network->bWithAironetIE = false;
2569 network->bCkipSupported = false;
2572 case MFIE_TYPE_QOS_PARAMETER:
2574 "QoS Error need to parse QOS_PARAMETER IE\n");
2577 #ifdef ENABLE_DOT11D
2578 case MFIE_TYPE_COUNTRY:
2579 RTLLIB_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
2581 rtllib_extract_country_ie(ieee, info_element, network, network->bssid);
2587 ("Unsupported info element: %s (%d)\n",
2588 get_info_element_string(info_element->id),
2593 length -= sizeof(*info_element) + info_element->len;
2595 (struct rtllib_info_element *)&info_element->
2596 data[info_element->len];
2599 if (!network->atheros_cap_exist && !network->broadcom_cap_exist &&
2600 !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation)
2602 network->unknown_cap_exist = true;
2606 network->unknown_cap_exist = false;
2611 static inline u8 rtllib_SignalStrengthTranslate(
2617 if (CurrSS >= 71 && CurrSS <= 100)
2619 RetSS = 90 + ((CurrSS - 70) / 3);
2621 else if (CurrSS >= 41 && CurrSS <= 70)
2623 RetSS = 78 + ((CurrSS - 40) / 3);
2625 else if (CurrSS >= 31 && CurrSS <= 40)
2627 RetSS = 66 + (CurrSS - 30);
2629 else if (CurrSS >= 21 && CurrSS <= 30)
2631 RetSS = 54 + (CurrSS - 20);
2633 else if (CurrSS >= 5 && CurrSS <= 20)
2635 RetSS = 42 + (((CurrSS - 5) * 2) / 3);
2637 else if (CurrSS == 4)
2641 else if (CurrSS == 3)
2645 else if (CurrSS == 2)
2649 else if (CurrSS == 1)
2663 long rtllib_translate_todbm(u8 signal_strength_index )
2667 signal_power = (long)((signal_strength_index + 1) >> 1);
2670 return signal_power;
2673 static inline int rtllib_network_init(
2674 struct rtllib_device *ieee,
2675 struct rtllib_probe_response *beacon,
2676 struct rtllib_network *network,
2677 struct rtllib_rx_stats *stats)
2679 #ifdef CONFIG_RTLLIB_DEBUG
2683 network->qos_data.active = 0;
2684 network->qos_data.supported = 0;
2685 network->qos_data.param_count = 0;
2686 network->qos_data.old_param_count = 0;
2688 memset(&network->qos_data, 0, sizeof(struct rtllib_qos_data));
2690 /* Pull out fixed field data */
2691 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
2692 network->capability = le16_to_cpu(beacon->capability);
2693 network->last_scanned = jiffies;
2694 network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
2695 network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
2696 network->beacon_interval = le32_to_cpu(beacon->beacon_interval);
2697 /* Where to pull this? beacon->listen_interval;*/
2698 network->listen_interval = 0x0A;
2699 network->rates_len = network->rates_ex_len = 0;
2700 network->last_associate = 0;
2701 network->ssid_len = 0;
2702 network->hidden_ssid_len = 0;
2703 memset(network->hidden_ssid, 0, sizeof(network->hidden_ssid));
2705 network->atim_window = 0;
2706 network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
2708 network->berp_info_valid = false;
2709 network->broadcom_cap_exist = false;
2710 network->ralink_cap_exist = false;
2711 network->atheros_cap_exist = false;
2712 network->cisco_cap_exist = false;
2713 network->unknown_cap_exist = false;
2714 network->realtek_cap_exit = false;
2715 network->marvell_cap_exist = false;
2716 network->airgo_cap_exist = false;
2717 network->Turbo_Enable = 0;
2718 network->SignalStrength = stats->SignalStrength;
2719 network->RSSI = stats->SignalStrength;
2720 #ifdef ENABLE_DOT11D
2721 network->CountryIeLen = 0;
2722 memset(network->CountryIeBuf, 0, MAX_IE_LEN);
2724 HTInitializeBssDesc(&network->bssht);
2725 if (stats->freq == RTLLIB_52GHZ_BAND) {
2726 /* for A band (No DS info) */
2727 network->channel = stats->received_channel;
2729 network->flags |= NETWORK_HAS_CCK;
2731 network->wpa_ie_len = 0;
2732 network->rsn_ie_len = 0;
2733 network->wzc_ie_len = 0;
2735 if (rtllib_parse_info_param(ieee,
2736 beacon->info_element,
2737 (stats->len - sizeof(*beacon)),
2743 if (stats->freq == RTLLIB_52GHZ_BAND)
2744 network->mode = IEEE_A;
2746 if (network->flags & NETWORK_HAS_OFDM)
2747 network->mode |= IEEE_G;
2748 if (network->flags & NETWORK_HAS_CCK)
2749 network->mode |= IEEE_B;
2752 if (network->mode == 0) {
2753 RTLLIB_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
2755 escape_essid(network->ssid,
2757 MAC_ARG(network->bssid));
2761 if (network->bssht.bdSupportHT){
2762 if (network->mode == IEEE_A)
2763 network->mode = IEEE_N_5G;
2764 else if (network->mode & (IEEE_G | IEEE_B))
2765 network->mode = IEEE_N_24G;
2767 if (rtllib_is_empty_essid(network->ssid, network->ssid_len))
2768 network->flags |= NETWORK_EMPTY_ESSID;
2769 stats->signal = 30 + (stats->SignalStrength * 70) / 100;
2770 stats->noise = rtllib_translate_todbm((u8)(100-stats->signal)) -25;
2772 memcpy(&network->stats, stats, sizeof(network->stats));
2777 static inline int is_same_network(struct rtllib_network *src,
2778 struct rtllib_network *dst, u8 ssidbroad)
2780 /* A network is only a duplicate if the channel, BSSID, ESSID
2781 * and the capability field (in particular IBSS and BSS) all match.
2782 * We treat all <hidden> with the same BSSID and channel
2785 (((src->ssid_len == dst->ssid_len) || (!ssidbroad)) &&
2786 (src->channel == dst->channel) &&
2787 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
2788 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (!ssidbroad)) &&
2789 ((src->capability & WLAN_CAPABILITY_IBSS) ==
2790 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
2791 ((src->capability & WLAN_CAPABILITY_ESS) ==
2792 (dst->capability & WLAN_CAPABILITY_ESS)));
2795 static inline void update_ibss_network(struct rtllib_network *dst,
2796 struct rtllib_network *src)
2798 memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
2799 dst->last_scanned = jiffies;
2803 static inline void update_network(struct rtllib_network *dst,
2804 struct rtllib_network *src)
2809 memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
2810 dst->capability = src->capability;
2811 memcpy(dst->rates, src->rates, src->rates_len);
2812 dst->rates_len = src->rates_len;
2813 memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
2814 dst->rates_ex_len = src->rates_ex_len;
2815 if (src->ssid_len > 0)
2817 if (dst->ssid_len == 0)
2819 memset(dst->hidden_ssid, 0, sizeof(dst->hidden_ssid));
2820 dst->hidden_ssid_len = src->ssid_len;
2821 memcpy(dst->hidden_ssid, src->ssid, src->ssid_len);
2823 memset(dst->ssid, 0, dst->ssid_len);
2824 dst->ssid_len = src->ssid_len;
2825 memcpy(dst->ssid, src->ssid, src->ssid_len);
2828 dst->mode = src->mode;
2829 dst->flags = src->flags;
2830 dst->time_stamp[0] = src->time_stamp[0];
2831 dst->time_stamp[1] = src->time_stamp[1];
2832 if (src->flags & NETWORK_HAS_ERP_VALUE)
2834 dst->erp_value = src->erp_value;
2835 dst->berp_info_valid = src->berp_info_valid = true;
2837 dst->beacon_interval = src->beacon_interval;
2838 dst->listen_interval = src->listen_interval;
2839 dst->atim_window = src->atim_window;
2840 dst->dtim_period = src->dtim_period;
2841 dst->dtim_data = src->dtim_data;
2842 dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
2843 dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
2844 memcpy(&dst->tim, &src->tim, sizeof(struct rtllib_tim_parameters));
2846 dst->bssht.bdSupportHT = src->bssht.bdSupportHT;
2847 dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation;
2848 dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen;
2849 memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen);
2850 dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen;
2851 memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen);
2852 dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer;
2853 dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime;
2854 dst->broadcom_cap_exist = src->broadcom_cap_exist;
2855 dst->ralink_cap_exist = src->ralink_cap_exist;
2856 dst->atheros_cap_exist = src->atheros_cap_exist;
2857 dst->realtek_cap_exit = src->realtek_cap_exit;
2858 dst->marvell_cap_exist = src->marvell_cap_exist;
2859 dst->cisco_cap_exist = src->cisco_cap_exist;
2860 dst->airgo_cap_exist = src->airgo_cap_exist;
2861 dst->unknown_cap_exist = src->unknown_cap_exist;
2862 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
2863 dst->wpa_ie_len = src->wpa_ie_len;
2864 memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
2865 dst->rsn_ie_len = src->rsn_ie_len;
2866 memcpy(dst->wzc_ie, src->wzc_ie, src->wzc_ie_len);
2867 dst->wzc_ie_len = src->wzc_ie_len;
2869 dst->last_scanned = jiffies;
2870 /* qos related parameters */
2871 qos_active = dst->qos_data.active;
2872 old_param = dst->qos_data.param_count;
2873 dst->qos_data.supported = src->qos_data.supported;
2874 if (dst->flags & NETWORK_HAS_QOS_PARAMETERS)
2875 memcpy(&dst->qos_data, &src->qos_data, sizeof(struct rtllib_qos_data));
2876 if (dst->qos_data.supported == 1) {
2879 ("QoS the network %s is QoS supported\n",
2883 ("QoS the network is QoS supported\n");
2885 dst->qos_data.active = qos_active;
2886 dst->qos_data.old_param_count = old_param;
2888 /* dst->last_associate is not overwritten */
2889 dst->wmm_info = src->wmm_info;
2890 if (src->wmm_param[0].ac_aci_acm_aifsn|| \
2891 src->wmm_param[1].ac_aci_acm_aifsn|| \
2892 src->wmm_param[2].ac_aci_acm_aifsn|| \
2893 src->wmm_param[1].ac_aci_acm_aifsn) {
2894 memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
2897 dst->SignalStrength = src->SignalStrength;
2898 dst->RSSI = src->RSSI;
2899 dst->Turbo_Enable = src->Turbo_Enable;
2901 #ifdef ENABLE_DOT11D
2902 dst->CountryIeLen = src->CountryIeLen;
2903 memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
2906 dst->bWithAironetIE = src->bWithAironetIE;
2907 dst->bCkipSupported = src->bCkipSupported;
2908 memcpy(dst->CcxRmState,src->CcxRmState,2);
2909 dst->bCcxRmEnable = src->bCcxRmEnable;
2910 dst->MBssidMask = src->MBssidMask;
2911 dst->bMBssidValid = src->bMBssidValid;
2912 memcpy(dst->MBssid,src->MBssid,6);
2913 dst->bWithCcxVerNum = src->bWithCcxVerNum;
2914 dst->BssCcxVerNumber = src->BssCcxVerNumber;
2917 static inline int is_beacon(__le16 fc)
2919 return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == RTLLIB_STYPE_BEACON);
2922 static int IsPassiveChannel( struct rtllib_device *rtllib, u8 channel)
2924 if (MAX_CHANNEL_NUMBER < channel) {
2925 printk("%s(): Invalid Channel\n", __func__);
2929 if (rtllib->active_channel_map[channel] == 2)
2935 int IsLegalChannel( struct rtllib_device *rtllib, u8 channel)
2937 if (MAX_CHANNEL_NUMBER < channel) {
2938 printk("%s(): Invalid Channel\n", __func__);
2941 if (rtllib->active_channel_map[channel] > 0)
2948 static inline void rtllib_process_probe_response(
2949 struct rtllib_device *ieee,
2950 struct rtllib_probe_response *beacon,
2951 struct rtllib_rx_stats *stats)
2953 struct rtllib_network *target;
2954 struct rtllib_network *oldest = NULL;
2955 #ifdef CONFIG_RTLLIB_DEBUG
2956 struct rtllib_info_element *info_element = &beacon->info_element[0];
2958 unsigned long flags;
2960 struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network), GFP_ATOMIC);
2966 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
2967 escape_essid(info_element->data, info_element->len),
2968 MAC_ARG(beacon->header.addr3),
2969 (beacon->capability & (1<<0xf)) ? '1' : '0',
2970 (beacon->capability & (1<<0xe)) ? '1' : '0',
2971 (beacon->capability & (1<<0xd)) ? '1' : '0',
2972 (beacon->capability & (1<<0xc)) ? '1' : '0',
2973 (beacon->capability & (1<<0xb)) ? '1' : '0',
2974 (beacon->capability & (1<<0xa)) ? '1' : '0',
2975 (beacon->capability & (1<<0x9)) ? '1' : '0',
2976 (beacon->capability & (1<<0x8)) ? '1' : '0',
2977 (beacon->capability & (1<<0x7)) ? '1' : '0',
2978 (beacon->capability & (1<<0x6)) ? '1' : '0',
2979 (beacon->capability & (1<<0x5)) ? '1' : '0',
2980 (beacon->capability & (1<<0x4)) ? '1' : '0',
2981 (beacon->capability & (1<<0x3)) ? '1' : '0',
2982 (beacon->capability & (1<<0x2)) ? '1' : '0',
2983 (beacon->capability & (1<<0x1)) ? '1' : '0',
2984 (beacon->capability & (1<<0x0)) ? '1' : '0');
2986 if (rtllib_network_init(ieee, beacon, network, stats)) {
2987 RTLLIB_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
2988 escape_essid(info_element->data,
2990 MAC_ARG(beacon->header.addr3),
2991 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2992 RTLLIB_STYPE_PROBE_RESP ?
2993 "PROBE RESPONSE" : "BEACON");
2998 if (!IsLegalChannel(ieee, network->channel))
3001 if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == RTLLIB_STYPE_PROBE_RESP) {
3002 if (IsPassiveChannel(ieee, network->channel)) {
3003 printk("GetScanInfo(): For Global Domain, "
3004 "filter probe response at channel(%d).\n", network->channel);
3009 /* The network parsed correctly -- so now we scan our known networks
3010 * to see if we can find it in our list.
3012 * NOTE: This search is definitely not optimized. Once its doing
3013 * the "right thing" we'll optimize it for efficiency if
3016 /* Search for this entry in the list and update it if it is
3019 spin_lock_irqsave(&ieee->lock, flags);
3021 if (is_same_network(&ieee->current_network, network, (network->ssid_len?1:0))) {
3022 update_network(&ieee->current_network, network);
3023 if ((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G)
3024 && ieee->current_network.berp_info_valid){
3025 if (ieee->current_network.erp_value& ERP_UseProtection)
3026 ieee->current_network.buseprotection = true;
3028 ieee->current_network.buseprotection = false;
3030 if (is_beacon(beacon->header.frame_ctl))
3032 if (ieee->state >= RTLLIB_LINKED)
3033 ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
3037 list_for_each_entry(target, &ieee->network_list, list) {
3038 if (is_same_network(target, network,(target->ssid_len?1:0)))
3040 if ((oldest == NULL) ||
3041 (target->last_scanned < oldest->last_scanned))
3045 /* If we didn't find a match, then get a new network slot to initialize
3046 * with this beacon's information */
3047 if (&target->list == &ieee->network_list) {
3048 if (list_empty(&ieee->network_free_list)) {
3049 /* If there are no more slots, expire the oldest */
3050 list_del(&oldest->list);
3052 RTLLIB_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
3054 escape_essid(target->ssid,
3056 MAC_ARG(target->bssid));
3058 /* Otherwise just pull from the free list */
3059 target = list_entry(ieee->network_free_list.next,
3060 struct rtllib_network, list);
3061 list_del(ieee->network_free_list.next);
3065 #ifdef CONFIG_RTLLIB_DEBUG
3066 RTLLIB_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
3067 escape_essid(network->ssid,
3069 MAC_ARG(network->bssid),
3070 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
3071 RTLLIB_STYPE_PROBE_RESP ?
3072 "PROBE RESPONSE" : "BEACON");
3074 memcpy(target, network, sizeof(*target));
3075 list_add_tail(&target->list, &ieee->network_list);
3076 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
3077 rtllib_softmac_new_net(ieee, network);
3079 RTLLIB_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
3080 escape_essid(target->ssid,
3082 MAC_ARG(target->bssid),
3083 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
3084 RTLLIB_STYPE_PROBE_RESP ?
3085 "PROBE RESPONSE" : "BEACON");
3087 /* we have an entry and we are going to update it. But this entry may
3088 * be already expired. In this case we do the same as we found a new
3089 * net and call the new_net handler
3091 renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
3092 if ((!target->ssid_len) &&
3093 (((network->ssid_len > 0) && (target->hidden_ssid_len == 0))
3094 || ((ieee->current_network.ssid_len == network->ssid_len) &&
3095 (strncmp(ieee->current_network.ssid, network->ssid, network->ssid_len) == 0) &&
3096 (ieee->state == RTLLIB_NOLINK)))
3100 update_network(target, network);
3101 if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
3102 rtllib_softmac_new_net(ieee, network);
3105 spin_unlock_irqrestore(&ieee->lock, flags);
3106 if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, network, (network->ssid_len?1:0))&&\
3107 (ieee->state == RTLLIB_LINKED)) {
3108 if (ieee->handle_beacon != NULL) {
3109 ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network);
3117 void rtllib_rx_mgt(struct rtllib_device *ieee,
3118 struct sk_buff *skb,
3119 struct rtllib_rx_stats *stats)
3121 struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ;
3122 if (WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_PROBE_RESP &&
3123 WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_BEACON)
3124 ieee->last_rx_ps_time = jiffies;
3126 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
3128 case RTLLIB_STYPE_BEACON:
3129 RTLLIB_DEBUG_MGMT("received BEACON (%d)\n",
3130 WLAN_FC_GET_STYPE(header->frame_ctl));
3131 RTLLIB_DEBUG_SCAN("Beacon\n");
3132 rtllib_process_probe_response(
3133 ieee, (struct rtllib_probe_response *)header, stats);
3135 if (ieee->sta_sleep || (ieee->ps != RTLLIB_PS_DISABLED &&
3136 ieee->iw_mode == IW_MODE_INFRA &&
3137 ieee->state == RTLLIB_LINKED))
3138 tasklet_schedule(&ieee->ps_task);
3142 case RTLLIB_STYPE_PROBE_RESP:
3143 RTLLIB_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
3144 WLAN_FC_GET_STYPE(header->frame_ctl));
3145 RTLLIB_DEBUG_SCAN("Probe response\n");
3146 rtllib_process_probe_response(
3147 ieee, (struct rtllib_probe_response *)header, stats);
3149 case RTLLIB_STYPE_PROBE_REQ:
3150 RTLLIB_DEBUG_MGMT("received PROBE RESQUEST (%d)\n",
3151 WLAN_FC_GET_STYPE(header->frame_ctl));
3152 RTLLIB_DEBUG_SCAN("Probe request\n");
3153 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
3154 ((ieee->iw_mode == IW_MODE_ADHOC ||
3155 ieee->iw_mode == IW_MODE_MASTER) &&
3156 ieee->state == RTLLIB_LINKED)){
3157 rtllib_rx_probe_rq(ieee, skb);