]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ieee80211/ieee80211_rx.c
Merge branch 'master'
[linux-2.6-omap-h63xx.git] / net / ieee80211 / ieee80211_rx.c
index 3bf04d6d2b13479ca3112f2abf5450830a37f564..03efaacbdb737349999667995d092aaf96485491 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/slab.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
@@ -370,6 +369,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        /* Put this code here so that we avoid duplicating it in all
         * Rx paths. - Jean II */
 #ifdef IW_WIRELESS_SPY         /* defined in iw_handler.h */
+#ifdef CONFIG_NET_RADIO
        /* If spy monitoring on */
        if (ieee->spy_data.spy_number > 0) {
                struct iw_quality wstats;
@@ -396,6 +396,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                /* Update spy records */
                wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
        }
+#endif                         /* CONFIG_NET_RADIO */
 #endif                         /* IW_WIRELESS_SPY */
 
 #ifdef NOT_YET
@@ -409,7 +410,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                return 1;
        }
 
-       if (is_multicast_ether_addr(hdr->addr1) ? ieee->host_mc_decrypt :
+       if ((is_multicast_ether_addr(hdr->addr1) ||
+            is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt :
            ieee->host_decrypt) {
                int idx = 0;
                if (skb->len >= hdrlen + 3)
@@ -917,8 +919,9 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
        return rc;
 }
 
-static int ieee80211_parse_info_param(struct ieee80211_info_element *info_element,
-                                       u16 length, struct ieee80211_network *network)
+static int ieee80211_parse_info_param(struct ieee80211_info_element
+                                     *info_element, u16 length,
+                                     struct ieee80211_network *network)
 {
        u8 i;
 #ifdef CONFIG_IEEE80211_DEBUG
@@ -929,11 +932,11 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element *info_elemen
        while (length >= sizeof(*info_element)) {
                if (sizeof(*info_element) + info_element->len > length) {
                        IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
-                                           "info_element->len + 2 > left : "
-                                           "info_element->len+2=%zd left=%d, id=%d.\n",
-                                           info_element->len +
-                                           sizeof(*info_element),
-                                           length, info_element->id);
+                                            "info_element->len + 2 > left : "
+                                            "info_element->len+2=%zd left=%d, id=%d.\n",
+                                            info_element->len +
+                                            sizeof(*info_element),
+                                            length, info_element->id);
                        return 1;
                }
 
@@ -954,7 +957,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element *info_elemen
                                       IW_ESSID_MAX_SIZE - network->ssid_len);
 
                        IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
-                                           network->ssid, network->ssid_len);
+                                            network->ssid, network->ssid_len);
                        break;
 
                case MFIE_TYPE_RATES:
@@ -1074,17 +1077,20 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element *info_elemen
                        break;
 
                case MFIE_TYPE_QOS_PARAMETER:
-                       printk(KERN_ERR "QoS Error need to parse QOS_PARAMETER IE\n");
+                       printk(KERN_ERR
+                              "QoS Error need to parse QOS_PARAMETER IE\n");
                        break;
 
                default:
                        IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
-                                           info_element->id);
+                                            info_element->id);
                        break;
                }
 
                length -= sizeof(*info_element) + info_element->len;
-               info_element = (struct ieee80211_info_element *) &info_element->data[info_element->len];
+               info_element =
+                   (struct ieee80211_info_element *)&info_element->
+                   data[info_element->len];
        }
 
        return 0;
@@ -1106,10 +1112,43 @@ static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct iee
        //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
        network->atim_window = le16_to_cpu(frame->aid);
        network->listen_interval = le16_to_cpu(frame->status);
+       memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
+       network->capability = le16_to_cpu(frame->capability);
+       network->last_scanned = jiffies;
+       network->rates_len = network->rates_ex_len = 0;
+       network->last_associate = 0;
+       network->ssid_len = 0;
+       network->erp_value =
+           (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
 
-       if(ieee80211_parse_info_param(frame->info_element, stats->len - sizeof(*frame), network))
+       if (stats->freq == IEEE80211_52GHZ_BAND) {
+               /* for A band (No DS info) */
+               network->channel = stats->received_channel;
+       } else
+               network->flags |= NETWORK_HAS_CCK;
+
+       network->wpa_ie_len = 0;
+       network->rsn_ie_len = 0;
+
+       if (ieee80211_parse_info_param
+           (frame->info_element, stats->len - sizeof(*frame), network))
                return 1;
 
+       network->mode = 0;
+       if (stats->freq == IEEE80211_52GHZ_BAND)
+               network->mode = IEEE_A;
+       else {
+               if (network->flags & NETWORK_HAS_OFDM)
+                       network->mode |= IEEE_G;
+               if (network->flags & NETWORK_HAS_CCK)
+                       network->mode |= IEEE_B;
+       }
+
+       if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
+               network->flags |= NETWORK_EMPTY_ESSID;
+
+       memcpy(&network->stats, stats, sizeof(network->stats));
+
        if (ieee->handle_assoc_response != NULL)
                ieee->handle_assoc_response(dev, frame, network);
 
@@ -1126,6 +1165,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
        network->qos_data.active = 0;
        network->qos_data.supported = 0;
        network->qos_data.param_count = 0;
+       network->qos_data.old_param_count = 0;
 
        /* Pull out fixed field data */
        memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
@@ -1153,7 +1193,8 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
        network->wpa_ie_len = 0;
        network->rsn_ie_len = 0;
 
-       if(ieee80211_parse_info_param(beacon->info_element, stats->len - sizeof(*beacon), network))
+       if (ieee80211_parse_info_param
+           (beacon->info_element, stats->len - sizeof(*beacon), network))
                return 1;
 
        network->mode = 0;