[PATCH] hostap update
[powerpc.git] / drivers / net / wireless / hostap / hostap_ioctl.c
index e545ac9..bbed1e6 100644 (file)
@@ -663,7 +663,7 @@ static int hostap_join_ap(struct net_device *dev)
        struct hfa384x_join_request req;
        unsigned long flags;
        int i;
-       struct hfa384x_scan_result *entry;
+       struct hfa384x_hostscan_result *entry;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -1182,7 +1182,8 @@ static int prism2_ioctl_siwmode(struct net_device *dev,
        if (local->iw_mode == IW_MODE_MONITOR)
                hostap_monitor_mode_disable(local);
 
-       if (local->iw_mode == IW_MODE_ADHOC && *mode == IW_MODE_MASTER) {
+       if ((local->iw_mode == IW_MODE_ADHOC ||
+            local->iw_mode == IW_MODE_MONITOR) && *mode == IW_MODE_MASTER) {
                /* There seems to be a firmware bug in at least STA f/w v1.5.6
                 * that leaves beacon frames to use IBSS type when moving from
                 * IBSS to Host AP mode. Doing double Port0 reset seems to be
@@ -1664,7 +1665,8 @@ static int prism2_request_hostscan(struct net_device *dev,
        local = iface->local;
 
        memset(&scan_req, 0, sizeof(scan_req));
-       scan_req.channel_list = __constant_cpu_to_le16(local->channel_mask);
+       scan_req.channel_list = cpu_to_le16(local->channel_mask &
+                                           local->scan_channel_mask);
        scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
        if (ssid) {
                if (ssid_len > 32)
@@ -1693,7 +1695,8 @@ static int prism2_request_scan(struct net_device *dev)
        local = iface->local;
 
        memset(&scan_req, 0, sizeof(scan_req));
-       scan_req.channel_list = __constant_cpu_to_le16(local->channel_mask);
+       scan_req.channel_list = cpu_to_le16(local->channel_mask &
+                                           local->scan_channel_mask);
        scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
 
        /* FIX:
@@ -1793,10 +1796,8 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
 
 #ifndef PRISM2_NO_STATION_MODES
 static char * __prism2_translate_scan(local_info_t *local,
-                                     struct hfa384x_scan_result *scan,
-                                     struct hfa384x_hostscan_result *hscan,
-                                     int hostscan,
-                                     struct hostap_bss_info *bss, u8 *bssid,
+                                     struct hfa384x_hostscan_result *scan,
+                                     struct hostap_bss_info *bss,
                                      char *current_ev, char *end_buf)
 {
        int i, chan;
@@ -1804,17 +1805,18 @@ static char * __prism2_translate_scan(local_info_t *local,
        char *current_val;
        u16 capabilities;
        u8 *pos;
-       u8 *ssid;
+       u8 *ssid, *bssid;
        size_t ssid_len;
        char *buf;
 
        if (bss) {
                ssid = bss->ssid;
                ssid_len = bss->ssid_len;
+               bssid = bss->bssid;
        } else {
-               ssid = hostscan ? hscan->ssid : scan->ssid;
-               ssid_len = le16_to_cpu(hostscan ? hscan->ssid_len :
-                                      scan->ssid_len);
+               ssid = scan->ssid;
+               ssid_len = le16_to_cpu(scan->ssid_len);
+               bssid = scan->bssid;
        }
        if (ssid_len > 32)
                ssid_len = 32;
@@ -1848,8 +1850,7 @@ static char * __prism2_translate_scan(local_info_t *local,
        if (bss) {
                capabilities = bss->capab_info;
        } else {
-               capabilities = le16_to_cpu(hostscan ? hscan->capability :
-                                          scan->capability);
+               capabilities = le16_to_cpu(scan->capability);
        }
        if (capabilities & (WLAN_CAPABILITY_ESS |
                            WLAN_CAPABILITY_IBSS)) {
@@ -1864,8 +1865,8 @@ static char * __prism2_translate_scan(local_info_t *local,
 
        memset(&iwe, 0, sizeof(iwe));
        iwe.cmd = SIOCGIWFREQ;
-       if (hscan || scan) {
-               chan = hostscan ? hscan->chid : scan->chid;
+       if (scan) {
+               chan = scan->chid;
        } else if (bss) {
                chan = bss->chan;
        } else {
@@ -1880,12 +1881,12 @@ static char * __prism2_translate_scan(local_info_t *local,
                                                  IW_EV_FREQ_LEN);
        }
 
-       if (scan || hscan) {
+       if (scan) {
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVQUAL;
-               if (hostscan) {
-                       iwe.u.qual.level = le16_to_cpu(hscan->sl);
-                       iwe.u.qual.noise = le16_to_cpu(hscan->anl);
+               if (local->last_scan_type == PRISM2_HOSTSCAN) {
+                       iwe.u.qual.level = le16_to_cpu(scan->sl);
+                       iwe.u.qual.noise = le16_to_cpu(scan->anl);
                } else {
                        iwe.u.qual.level =
                                HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->sl));
@@ -1908,11 +1909,11 @@ static char * __prism2_translate_scan(local_info_t *local,
        current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
 
        /* TODO: add SuppRates into BSS table */
-       if (scan || hscan) {
+       if (scan) {
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = SIOCGIWRATE;
                current_val = current_ev + IW_EV_LCP_LEN;
-               pos = hostscan ? hscan->sup_rates : scan->sup_rates;
+               pos = scan->sup_rates;
                for (i = 0; i < sizeof(scan->sup_rates); i++) {
                        if (pos[i] == 0)
                                break;
@@ -1929,29 +1930,26 @@ static char * __prism2_translate_scan(local_info_t *local,
 
        /* TODO: add BeaconInt,resp_rate,atim into BSS table */
        buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
-       if (buf && (scan || hscan)) {
+       if (buf && scan) {
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVCUSTOM;
-               sprintf(buf, "bcn_int=%d",
-                       le16_to_cpu(hostscan ? hscan->beacon_interval :
-                                   scan->beacon_interval));
+               sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
                iwe.u.data.length = strlen(buf);
                current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
                                                  buf);
 
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVCUSTOM;
-               sprintf(buf, "resp_rate=%d", le16_to_cpu(hostscan ?
-                                                        hscan->rate :
-                                                        scan->rate));
+               sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
                iwe.u.data.length = strlen(buf);
                current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
                                                  buf);
 
-               if (hostscan && (capabilities & WLAN_CAPABILITY_IBSS)) {
+               if (local->last_scan_type == PRISM2_HOSTSCAN &&
+                   (capabilities & WLAN_CAPABILITY_IBSS)) {
                        memset(&iwe, 0, sizeof(iwe));
                        iwe.cmd = IWEVCUSTOM;
-                       sprintf(buf, "atim=%d", le16_to_cpu(hscan->atim));
+                       sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
                        iwe.u.data.length = strlen(buf);
                        current_ev = iwe_stream_add_point(current_ev, end_buf,
                                                          &iwe, buf);
@@ -1984,12 +1982,10 @@ static char * __prism2_translate_scan(local_info_t *local,
 static inline int prism2_translate_scan(local_info_t *local,
                                        char *buffer, int buflen)
 {
-       struct hfa384x_scan_result *scan;
-       struct hfa384x_hostscan_result *hscan;
-       int entries, entry, hostscan;
+       struct hfa384x_hostscan_result *scan;
+       int entry, hostscan;
        char *current_ev = buffer;
        char *end_buf = buffer + buflen;
-       u8 *bssid;
        struct list_head *ptr;
 
        spin_lock_bh(&local->lock);
@@ -2001,14 +1997,9 @@ static inline int prism2_translate_scan(local_info_t *local,
        }
 
        hostscan = local->last_scan_type == PRISM2_HOSTSCAN;
-       entries = hostscan ? local->last_hostscan_results_count :
-               local->last_scan_results_count;
-       for (entry = 0; entry < entries; entry++) {
+       for (entry = 0; entry < local->last_scan_results_count; entry++) {
                int found = 0;
                scan = &local->last_scan_results[entry];
-               hscan = &local->last_hostscan_results[entry];
-
-               bssid = hostscan ? hscan->bssid : scan->bssid;
 
                /* Report every SSID if the AP is using multiple SSIDs. If no
                 * BSS record is found (e.g., when WPA mode is disabled),
@@ -2016,18 +2007,16 @@ static inline int prism2_translate_scan(local_info_t *local,
                list_for_each(ptr, &local->bss_list) {
                        struct hostap_bss_info *bss;
                        bss = list_entry(ptr, struct hostap_bss_info, list);
-                       if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
+                       if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
                                bss->included = 1;
                                current_ev = __prism2_translate_scan(
-                                       local, scan, hscan, hostscan, bss,
-                                       bssid, current_ev, end_buf);
+                                       local, scan, bss, current_ev, end_buf);
                                found++;
                        }
                }
                if (!found) {
                        current_ev = __prism2_translate_scan(
-                               local, scan, hscan, hostscan, NULL, bssid,
-                               current_ev, end_buf);
+                               local, scan, NULL, current_ev, end_buf);
                }
                /* Check if there is space for one more entry */
                if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2045,9 +2034,8 @@ static inline int prism2_translate_scan(local_info_t *local,
                bss = list_entry(ptr, struct hostap_bss_info, list);
                if (bss->included)
                        continue;
-               current_ev = __prism2_translate_scan(local, NULL, NULL, 0, bss,
-                                                    bss->bssid, current_ev,
-                                                    end_buf);
+               current_ev = __prism2_translate_scan(local, NULL, bss,
+                                                    current_ev, end_buf);
                /* Check if there is space for one more entry */
                if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
                        /* Ask user space to try again with a bigger buffer */
@@ -2338,6 +2326,10 @@ static const struct iw_priv_args prism2_priv[] = {
          IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "drop_unencrypte" },
        { PRISM2_PARAM_DROP_UNENCRYPTED,
          0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdrop_unencry" },
+       { PRISM2_PARAM_SCAN_CHANNEL_MASK,
+         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "scan_channels" },
+       { PRISM2_PARAM_SCAN_CHANNEL_MASK,
+         0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getscan_channel" },
 };
 
 
@@ -2699,6 +2691,10 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
                local->drop_unencrypted = value;
                break;
 
+       case PRISM2_PARAM_SCAN_CHANNEL_MASK:
+               local->scan_channel_mask = value;
+               break;
+
        default:
                printk(KERN_DEBUG "%s: prism2_param: unknown param %d\n",
                       dev->name, param);
@@ -2890,6 +2886,10 @@ static int prism2_ioctl_priv_get_prism2_param(struct net_device *dev,
                *param = local->drop_unencrypted;
                break;
 
+       case PRISM2_PARAM_SCAN_CHANNEL_MASK:
+               *param = local->scan_channel_mask;
+               break;
+
        default:
                printk(KERN_DEBUG "%s: get_prism2_param: unknown param %d\n",
                       dev->name, *param);