headers: remove sched.h from interrupt.h
[safe/jmp/linux-2.6] / drivers / net / wireless / prism54 / isl_ioctl.c
index 286325c..bc08464 100644 (file)
@@ -1,5 +1,4 @@
 /*
- *  
  *  Copyright (C) 2002 Intersil Americas Inc.
  *            (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
  *            (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
@@ -20,6 +19,7 @@
  *
  */
 
+#include <linux/capability.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
@@ -55,12 +55,12 @@ static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
  * prism54_mib_mode_helper - MIB change mode helper function
  * @mib: the &struct islpci_mib object to modify
  * @iw_mode: new mode (%IW_MODE_*)
- * 
+ *
  *  This is a helper function, hence it does not lock. Make sure
- *  caller deals with locking *if* necessary. This function sets the 
- *  mode-dependent mib values and does the mapping of the Linux 
- *  Wireless API modes to Device firmware modes. It also checks for 
- *  correct valid Linux wireless modes. 
+ *  caller deals with locking *if* necessary. This function sets the
+ *  mode-dependent mib values and does the mapping of the Linux
+ *  Wireless API modes to Device firmware modes. It also checks for
+ *  correct valid Linux wireless modes.
  */
 static int
 prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
@@ -72,7 +72,7 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
        if (iw_mode == IW_MODE_REPEAT || iw_mode == IW_MODE_SECOND) {
                printk(KERN_DEBUG
                       "%s(): Sorry, Repeater mode and Secondary mode "
-                      "are not yet supported by this driver.\n", __FUNCTION__);
+                      "are not yet supported by this driver.\n", __func__);
                return -EINVAL;
        }
 
@@ -118,7 +118,7 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
  *
  *  this function initializes the struct given as @mib with defaults,
  *  of which many are retrieved from the global module parameter
- *  variables.  
+ *  variables.
  */
 
 void
@@ -134,7 +134,7 @@ prism54_mib_init(islpci_private *priv)
        authen = CARD_DEFAULT_AUTHEN;
        wep = CARD_DEFAULT_WEP;
        filter = CARD_DEFAULT_FILTER; /* (0) Do not filter un-encrypted data */
-       dot1x = CARD_DEFAULT_DOT1X; 
+       dot1x = CARD_DEFAULT_DOT1X;
        mlme = CARD_DEFAULT_MLME_MODE;
        conformance = CARD_DEFAULT_CONFORMANCE;
        power = 127;
@@ -158,15 +158,15 @@ prism54_mib_init(islpci_private *priv)
  * schedule_work(), thus we can as well use sleeping semaphore
  * locking */
 void
-prism54_update_stats(islpci_private *priv)
+prism54_update_stats(struct work_struct *work)
 {
+       islpci_private *priv = container_of(work, islpci_private, stats_work);
        char *data;
        int j;
        struct obj_bss bss, *bss2;
        union oid_res_t r;
 
-       if (down_interruptible(&priv->stats_sem))
-               return;
+       mutex_lock(&priv->stats_lock);
 
 /* Noise floor.
  * I'm not sure if the unit is dBm.
@@ -208,7 +208,7 @@ prism54_update_stats(islpci_private *priv)
        mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
        priv->local_iwstatistics.discard.retries = r.u;
 
-       up(&priv->stats_sem);
+       mutex_unlock(&priv->stats_lock);
 
        return;
 }
@@ -219,16 +219,16 @@ prism54_get_wireless_stats(struct net_device *ndev)
        islpci_private *priv = netdev_priv(ndev);
 
        /* If the stats are being updated return old data */
-       if (down_trylock(&priv->stats_sem) == 0) {
+       if (mutex_trylock(&priv->stats_lock)) {
                memcpy(&priv->iwstatistics, &priv->local_iwstatistics,
                       sizeof (struct iw_statistics));
                /* They won't be marked updated for the next time */
                priv->local_iwstatistics.qual.updated = 0;
-               up(&priv->stats_sem);
+               mutex_unlock(&priv->stats_lock);
        } else
                priv->iwstatistics.qual.updated = 0;
 
-       /* Update our wireless stats, but do not schedule to often 
+       /* Update our wireless stats, but do not schedule to often
         * (max 1 HZ) */
        if ((priv->stats_timestamp == 0) ||
            time_after(jiffies, priv->stats_timestamp + 1 * HZ)) {
@@ -334,7 +334,7 @@ prism54_set_mode(struct net_device *ndev, struct iw_request_info *info,
        if (*uwrq > IW_MODE_MONITOR || *uwrq < IW_MODE_AUTO) {
                printk(KERN_DEBUG
                       "%s: %s() You passed a non-valid init_mode.\n",
-                      priv->ndev->name, __FUNCTION__);
+                      priv->ndev->name, __func__);
                return -EINVAL;
        }
 
@@ -572,8 +572,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
  */
 
 static char *
-prism54_translate_bss(struct net_device *ndev, char *current_ev,
-                     char *end_buf, struct obj_bss *bss, char noise)
+prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
+                     char *current_ev, char *end_buf, struct obj_bss *bss,
+                     char noise)
 {
        struct iw_event iwe;    /* Temporary buffer */
        short cap;
@@ -585,8 +586,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
        memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
        iwe.cmd = SIOCGIWAP;
-       current_ev =
-           iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                         &iwe, IW_EV_ADDR_LEN);
 
        /* The following entries will be displayed in the same order we give them */
 
@@ -594,7 +595,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
        iwe.u.data.length = bss->ssid.length;
        iwe.u.data.flags = 1;
        iwe.cmd = SIOCGIWESSID;
-       current_ev = iwe_stream_add_point(current_ev, end_buf,
+       current_ev = iwe_stream_add_point(info, current_ev, end_buf,
                                          &iwe, bss->ssid.octets);
 
        /* Capabilities */
@@ -611,9 +612,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
                iwe.u.mode = IW_MODE_ADHOC;
        iwe.cmd = SIOCGIWMODE;
        if (iwe.u.mode)
-               current_ev =
-                   iwe_stream_add_event(current_ev, end_buf, &iwe,
-                                        IW_EV_UINT_LEN);
+               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                                 &iwe, IW_EV_UINT_LEN);
 
        /* Encryption capability */
        if (cap & CAP_CRYPT)
@@ -622,14 +622,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
                iwe.u.data.flags = IW_ENCODE_DISABLED;
        iwe.u.data.length = 0;
        iwe.cmd = SIOCGIWENCODE;
-       current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
+       current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                         &iwe, NULL);
 
        /* Add frequency. (short) bss->channel is the frequency in MHz */
        iwe.u.freq.m = bss->channel;
        iwe.u.freq.e = 6;
        iwe.cmd = SIOCGIWFREQ;
-       current_ev =
-           iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                         &iwe, IW_EV_FREQ_LEN);
 
        /* Add quality statistics */
        iwe.u.qual.level = bss->rssi;
@@ -637,20 +638,20 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
        /* do a simple SNR for quality */
        iwe.u.qual.qual = bss->rssi - noise;
        iwe.cmd = IWEVQUAL;
-       current_ev =
-           iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                         &iwe, IW_EV_QUAL_LEN);
 
        /* Add WPA/RSN Information Element, if any */
        wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
        if (wpa_ie_len > 0) {
                iwe.cmd = IWEVGENIE;
                iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
-               current_ev = iwe_stream_add_point(current_ev, end_buf,
-                               &iwe, wpa_ie);
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, wpa_ie);
        }
        /* Do the bitrates */
        {
-               char *  current_val = current_ev + IW_EV_LCP_LEN;
+               char *current_val = current_ev + iwe_stream_lcp_len(info);
                int i;
                int mask;
 
@@ -663,14 +664,14 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
                for(i = 0; i < sizeof(scan_rate_list); i++) {
                        if(bss->rates & mask) {
                                iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
-                               current_val = iwe_stream_add_value(current_ev, current_val,
-                                                                  end_buf, &iwe,
-                                                                  IW_EV_PARAM_LEN);
+                               current_val = iwe_stream_add_value(
+                                       info, current_ev, current_val,
+                                       end_buf, &iwe, IW_EV_PARAM_LEN);
                        }
                        mask <<= 1;
                }
                /* Check if we added any event */
-               if ((current_val - current_ev) > IW_EV_LCP_LEN)
+               if ((current_val - current_ev) > iwe_stream_lcp_len(info))
                        current_ev = current_val;
        }
 
@@ -705,13 +706,13 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
        * Starting with WE-17, the buffer can be as big as needed.
        * But the device won't repport anything if you change the value
        * of IWMAX_BSS=24. */
-       
+
        rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
        bsslist = r.ptr;
 
        /* ok now, scan the list and translate its info */
        for (i = 0; i < (int) bsslist->nr; i++) {
-               current_ev = prism54_translate_bss(ndev, current_ev,
+               current_ev = prism54_translate_bss(ndev, info, current_ev,
                                                   extra + dwrq->length,
                                                   &(bsslist->bsslist[i]),
                                                   noise);
@@ -785,7 +786,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
        return rvalue;
 }
 
-/* Provides no functionality, just completes the ioctl. In essence this is a 
+/* Provides no functionality, just completes the ioctl. In essence this is a
  * just a cosmetic ioctl.
  */
 static int
@@ -1104,7 +1105,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
                                            &key);
                }
                /*
-                * If a valid key is set, encryption should be enabled 
+                * If a valid key is set, encryption should be enabled
                 * (user may turn it off later).
                 * This is also how "iwconfig ethX key on" works
                 */
@@ -1118,7 +1119,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
                            mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
                                            &index);
                } else {
-                       if (!dwrq->flags & IW_ENCODE_MODE) {
+                       if (!(dwrq->flags & IW_ENCODE_MODE)) {
                                /* we cannot do anything. Complain. */
                                return -EINVAL;
                        }
@@ -1126,7 +1127,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
        }
        /* now read the flags */
        if (dwrq->flags & IW_ENCODE_DISABLED) {
-               /* Encoding disabled, 
+               /* Encoding disabled,
                 * authen = DOT11_AUTH_OS;
                 * invoke = 0;
                 * exunencrypt = 0; */
@@ -1187,7 +1188,7 @@ prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
        rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
        devindex = r.u;
        /* Now get the key, return it */
-       if ((index < 0) || (index > 3))
+       if (index == -1 || index > 3)
                /* no index provided, use the current one */
                index = devindex;
        rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
@@ -1214,7 +1215,7 @@ prism54_get_txpower(struct net_device *ndev, struct iw_request_info *info,
        vwrq->value = (s32) r.u / 4;
        vwrq->fixed = 1;
        /* radio is not turned of
-        * btw: how is possible to turn off only the radio 
+        * btw: how is possible to turn off only the radio
         */
        vwrq->disabled = 0;
 
@@ -1234,7 +1235,7 @@ prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,
                /* don't know how to disable radio */
                printk(KERN_DEBUG
                       "%s: %s() disabling radio is not yet supported.\n",
-                      priv->ndev->name, __FUNCTION__);
+                      priv->ndev->name, __func__);
                return -ENOTSUPP;
        } else if (vwrq->fixed)
                /* currently only fixed value is supported */
@@ -1242,7 +1243,7 @@ prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,
        else {
                printk(KERN_DEBUG
                       "%s: %s() auto power will be implemented later.\n",
-                      priv->ndev->name, __FUNCTION__);
+                      priv->ndev->name, __func__);
                return -ENOTSUPP;
        }
 }
@@ -1395,11 +1396,16 @@ static int prism54_set_auth(struct net_device *ndev,
                break;
 
        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-               dot1x = param->value ? 1 : 0;
+               /* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL;
+                * turn off dot1x when allowing receipt of unencrypted EAPOL
+                * frames, turn on dot1x when receipt should be disallowed
+                */
+               dot1x = param->value ? 0 : 0x01;
                break;
 
        case IW_AUTH_PRIVACY_INVOKED:
                privinvoked = param->value ? 1 : 0;
+               break;
 
        case IW_AUTH_DROP_UNENCRYPTED:
                exunencrypt = param->value ? 1 : 0;
@@ -1589,6 +1595,7 @@ static int prism54_set_encodeext(struct net_device *ndev,
                        }
                        key.type = DOT11_PRIV_TKIP;
                        key.length = KEY_SIZE_TKIP;
+                       break;
                default:
                        return -EINVAL;
                }
@@ -1747,7 +1754,7 @@ prism54_get_oid(struct net_device *ndev, struct iw_request_info *info,
        int rvalue;
        enum oid_num_t n = dwrq->flags;
 
-       rvalue = mgt_get_request((islpci_private *) ndev->priv, n, 0, NULL, &r);
+       rvalue = mgt_get_request(netdev_priv(ndev), n, 0, NULL, &r);
        dwrq->length = mgt_response_to_str(n, &r, extra);
        if ((isl_oid[n].flags & OID_FLAG_TYPE) != OID_TYPE_U32)
                kfree(r.ptr);
@@ -1760,7 +1767,7 @@ prism54_set_u32(struct net_device *ndev, struct iw_request_info *info,
 {
        u32 oid = uwrq[0], u = uwrq[1];
 
-       return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u);
+       return mgt_set_request(netdev_priv(ndev), oid, 0, &u);
 }
 
 static int
@@ -1769,13 +1776,13 @@ prism54_set_raw(struct net_device *ndev, struct iw_request_info *info,
 {
        u32 oid = dwrq->flags;
 
-       return mgt_set_request((islpci_private *) ndev->priv, oid, 0, extra);
+       return mgt_set_request(netdev_priv(ndev), oid, 0, extra);
 }
 
 void
 prism54_acl_init(struct islpci_acl *acl)
 {
-       sema_init(&acl->sem, 1);
+       mutex_init(&acl->lock);
        INIT_LIST_HEAD(&acl->mac_list);
        acl->size = 0;
        acl->policy = MAC_POLICY_OPEN;
@@ -1787,11 +1794,10 @@ prism54_clear_mac(struct islpci_acl *acl)
        struct list_head *ptr, *next;
        struct mac_entry *entry;
 
-       if (down_interruptible(&acl->sem))
-               return;
+       mutex_lock(&acl->lock);
 
        if (acl->size == 0) {
-               up(&acl->sem);
+               mutex_unlock(&acl->lock);
                return;
        }
 
@@ -1802,7 +1808,7 @@ prism54_clear_mac(struct islpci_acl *acl)
                kfree(entry);
        }
        acl->size = 0;
-       up(&acl->sem);
+       mutex_unlock(&acl->lock);
 }
 
 void
@@ -1829,13 +1835,13 @@ prism54_add_mac(struct net_device *ndev, struct iw_request_info *info,
 
        memcpy(entry->addr, addr->sa_data, ETH_ALEN);
 
-       if (down_interruptible(&acl->sem)) {
+       if (mutex_lock_interruptible(&acl->lock)) {
                kfree(entry);
                return -ERESTARTSYS;
        }
        list_add_tail(&entry->_list, &acl->mac_list);
        acl->size++;
-       up(&acl->sem);
+       mutex_unlock(&acl->lock);
 
        return 0;
 }
@@ -1847,26 +1853,23 @@ prism54_del_mac(struct net_device *ndev, struct iw_request_info *info,
        islpci_private *priv = netdev_priv(ndev);
        struct islpci_acl *acl = &priv->acl;
        struct mac_entry *entry;
-       struct list_head *ptr;
        struct sockaddr *addr = (struct sockaddr *) extra;
 
        if (addr->sa_family != ARPHRD_ETHER)
                return -EOPNOTSUPP;
 
-       if (down_interruptible(&acl->sem))
+       if (mutex_lock_interruptible(&acl->lock))
                return -ERESTARTSYS;
-       for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
-               entry = list_entry(ptr, struct mac_entry, _list);
-
+       list_for_each_entry(entry, &acl->mac_list, _list) {
                if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) {
-                       list_del(ptr);
+                       list_del(&entry->_list);
                        acl->size--;
                        kfree(entry);
-                       up(&acl->sem);
+                       mutex_unlock(&acl->lock);
                        return 0;
                }
        }
-       up(&acl->sem);
+       mutex_unlock(&acl->lock);
        return -EINVAL;
 }
 
@@ -1877,23 +1880,20 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info,
        islpci_private *priv = netdev_priv(ndev);
        struct islpci_acl *acl = &priv->acl;
        struct mac_entry *entry;
-       struct list_head *ptr;
        struct sockaddr *dst = (struct sockaddr *) extra;
 
        dwrq->length = 0;
 
-       if (down_interruptible(&acl->sem))
+       if (mutex_lock_interruptible(&acl->lock))
                return -ERESTARTSYS;
 
-       for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
-               entry = list_entry(ptr, struct mac_entry, _list);
-
+       list_for_each_entry(entry, &acl->mac_list, _list) {
                memcpy(dst->sa_data, entry->addr, ETH_ALEN);
                dst->sa_family = ARPHRD_ETHER;
                dwrq->length++;
                dst++;
        }
-       up(&acl->sem);
+       mutex_unlock(&acl->lock);
        return 0;
 }
 
@@ -1954,27 +1954,25 @@ prism54_get_policy(struct net_device *ndev, struct iw_request_info *info,
 static int
 prism54_mac_accept(struct islpci_acl *acl, char *mac)
 {
-       struct list_head *ptr;
        struct mac_entry *entry;
        int res = 0;
 
-       if (down_interruptible(&acl->sem))
+       if (mutex_lock_interruptible(&acl->lock))
                return -ERESTARTSYS;
 
        if (acl->policy == MAC_POLICY_OPEN) {
-               up(&acl->sem);
+               mutex_unlock(&acl->lock);
                return 1;
        }
 
-       for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
-               entry = list_entry(ptr, struct mac_entry, _list);
+       list_for_each_entry(entry, &acl->mac_list, _list) {
                if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
                        res = 1;
                        break;
                }
        }
        res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res;
-       up(&acl->sem);
+       mutex_unlock(&acl->lock);
 
        return res;
 }
@@ -2031,12 +2029,11 @@ static void
 format_event(islpci_private *priv, char *dest, const char *str,
             const struct obj_mlme *mlme, u16 *length, int error)
 {
-       const u8 *a = mlme->address;
        int n = snprintf(dest, IW_CUSTOM_MAX,
-                        "%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s (%2.2X)",
+                        "%s %s %pM %s (%2.2X)",
                         str,
                         ((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
-                        a[0], a[1], a[2], a[3], a[4], a[5],
+                        mlme->address,
                         (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
                          : ""), mlme->code);
        BUG_ON(n > IW_CUSTOM_MAX);
@@ -2085,6 +2082,7 @@ link_changed(struct net_device *ndev, u32 bitrate)
        islpci_private *priv = netdev_priv(ndev);
 
        if (bitrate) {
+               netif_carrier_on(ndev);
                if (priv->iw_mode == IW_MODE_INFRA) {
                        union iwreq_data uwrq;
                        prism54_get_wap(ndev, NULL, (struct sockaddr *) &uwrq,
@@ -2093,8 +2091,10 @@ link_changed(struct net_device *ndev, u32 bitrate)
                } else
                        send_simple_event(netdev_priv(ndev),
                                          "Link established");
-       } else
+       } else {
+               netif_carrier_off(ndev);
                send_simple_event(netdev_priv(ndev), "Link lost");
+       }
 }
 
 /* Beacon/ProbeResp payload header */
@@ -2107,9 +2107,6 @@ struct ieee80211_beacon_phdr {
 #define WLAN_EID_GENERIC 0xdd
 static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
 
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
-
 static void
 prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
                       u8 *wpa_ie, size_t wpa_ie_len)
@@ -2120,8 +2117,7 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
        if (wpa_ie_len > MAX_WPA_IE_LEN)
                wpa_ie_len = MAX_WPA_IE_LEN;
 
-       if (down_interruptible(&priv->wpa_sem))
-               return;
+       mutex_lock(&priv->wpa_lock);
 
        /* try to use existing entry */
        list_for_each(ptr, &priv->bss_wpa_list) {
@@ -2141,11 +2137,9 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
                                         struct islpci_bss_wpa_ie, list);
                        list_del(&bss->list);
                } else {
-                       bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
-                       if (bss != NULL) {
+                       bss = kzalloc(sizeof (*bss), GFP_ATOMIC);
+                       if (bss != NULL)
                                priv->num_bss_wpa++;
-                               memset(bss, 0, sizeof (*bss));
-                       }
                }
                if (bss != NULL) {
                        memcpy(bss->bssid, bssid, ETH_ALEN);
@@ -2158,8 +2152,8 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
                bss->wpa_ie_len = wpa_ie_len;
                bss->last_update = jiffies;
        } else {
-               printk(KERN_DEBUG "Failed to add BSS WPA entry for " MACSTR
-                      "\n", MAC2STR(bssid));
+               printk(KERN_DEBUG "Failed to add BSS WPA entry for "
+                      "%pM\n", bssid);
        }
 
        /* expire old entries from WPA list */
@@ -2174,7 +2168,7 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
                kfree(bss);
        }
 
-       up(&priv->wpa_sem);
+       mutex_unlock(&priv->wpa_lock);
 }
 
 static size_t
@@ -2184,8 +2178,7 @@ prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
        struct islpci_bss_wpa_ie *bss = NULL;
        size_t len = 0;
 
-       if (down_interruptible(&priv->wpa_sem))
-               return 0;
+       mutex_lock(&priv->wpa_lock);
 
        list_for_each(ptr, &priv->bss_wpa_list) {
                bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
@@ -2197,7 +2190,7 @@ prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
                len = bss->wpa_ie_len;
                memcpy(wpa_ie, bss->wpa_ie, len);
        }
-       up(&priv->wpa_sem);
+       mutex_unlock(&priv->wpa_lock);
 
        return len;
 }
@@ -2206,17 +2199,15 @@ void
 prism54_wpa_bss_ie_init(islpci_private *priv)
 {
        INIT_LIST_HEAD(&priv->bss_wpa_list);
-       sema_init(&priv->wpa_sem, 1);
+       mutex_init(&priv->wpa_lock);
 }
 
 void
 prism54_wpa_bss_ie_clean(islpci_private *priv)
 {
-       struct list_head *ptr, *n;
+       struct islpci_bss_wpa_ie *bss, *n;
 
-       list_for_each_safe(ptr, n, &priv->bss_wpa_list) {
-               struct islpci_bss_wpa_ie *bss;
-               bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
+       list_for_each_entry_safe(bss, n, &priv->bss_wpa_list, list) {
                kfree(bss);
        }
 }
@@ -2237,7 +2228,7 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
        while (pos < end) {
                if (pos + 2 + pos[1] > end) {
                        printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
-                              "for " MACSTR "\n", MAC2STR(addr));
+                              "for %pM\n", addr);
                        return;
                }
                if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
@@ -2354,24 +2345,18 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                handle_request(priv, mlme, oid);
                send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
 
-               if (priv->iw_mode != IW_MODE_MASTER 
+               if (priv->iw_mode != IW_MODE_MASTER
                                && mlmeex->state != DOT11_STATE_AUTHING)
                        break;
 
                confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
 
-               if (!confirm) 
+               if (!confirm)
                        break;
 
                memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-               printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 
-                               mlmeex->address[0],
-                               mlmeex->address[1],
-                               mlmeex->address[2],
-                               mlmeex->address[3],
-                               mlmeex->address[4],
-                               mlmeex->address[5]
-                               );
+               printk(KERN_DEBUG "Authenticate from: address:\t%pM\n",
+                      mlmeex->address);
                confirm->id = -1; /* or mlmeex->id ? */
                confirm->state = 0; /* not used */
                confirm->code = 0;
@@ -2398,10 +2383,10 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                handle_request(priv, mlme, oid);
                send_formatted_event(priv, "Associate request (ex)", mlme, 1);
 
-               if (priv->iw_mode != IW_MODE_MASTER 
+               if (priv->iw_mode != IW_MODE_MASTER
                                && mlmeex->state != DOT11_STATE_ASSOCING)
                        break;
-               
+
                confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
 
                if (!confirm)
@@ -2416,15 +2401,8 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
 
                if (!wpa_ie_len) {
-                       printk(KERN_DEBUG "No WPA IE found from "
-                                       "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 
-                               mlmeex->address[0],
-                               mlmeex->address[1],
-                               mlmeex->address[2],
-                               mlmeex->address[3],
-                               mlmeex->address[4],
-                               mlmeex->address[5]
-                               );
+                       printk(KERN_DEBUG "No WPA IE found from address:\t%pM\n",
+                              mlmeex->address);
                        kfree(confirm);
                        break;
                }
@@ -2435,14 +2413,14 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
 
                kfree(confirm);
-               
+
                break;
 
        case DOT11_OID_REASSOCIATEEX:
                handle_request(priv, mlme, oid);
                send_formatted_event(priv, "Reassociate request (ex)", mlme, 1);
 
-               if (priv->iw_mode != IW_MODE_MASTER 
+               if (priv->iw_mode != IW_MODE_MASTER
                                && mlmeex->state != DOT11_STATE_ASSOCING)
                        break;
 
@@ -2460,26 +2438,19 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
 
                if (!wpa_ie_len) {
-                       printk(KERN_DEBUG "No WPA IE found from "
-                                       "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 
-                               mlmeex->address[0],
-                               mlmeex->address[1],
-                               mlmeex->address[2],
-                               mlmeex->address[3],
-                               mlmeex->address[4],
-                               mlmeex->address[5]
-                               );
+                       printk(KERN_DEBUG "No WPA IE found from address:\t%pM\n",
+                              mlmeex->address);
                        kfree(confirm);
                        break;
                }
 
-               confirm->size = wpa_ie_len; 
+               confirm->size = wpa_ie_len;
                memcpy(&confirm->data, wpa_ie, wpa_ie_len);
 
                mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
 
                kfree(confirm);
-               
+
                break;
 
        default:
@@ -2494,9 +2465,10 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
  * interrupt context, no locks held.
  */
 void
-prism54_process_trap(void *data)
+prism54_process_trap(struct work_struct *work)
 {
-       struct islpci_mgmtframe *frame = data;
+       struct islpci_mgmtframe *frame =
+               container_of(work, struct islpci_mgmtframe, ws);
        struct net_device *ndev = frame->ndev;
        enum oid_num_t n = mgt_oidtonum(frame->header->oid);
 
@@ -2543,12 +2515,12 @@ enum {
 
 #define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
 #define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
-((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
+       offsetof(struct prism2_hostapd_param, u.generic_elem.data)
 
-/* Maximum length for algorithm names (-1 for nul termination) 
+/* Maximum length for algorithm names (-1 for nul termination)
  * used in ioctl() */
 #define HOSTAP_CRYPT_ALG_NAME_LEN 16
-       
+
 struct prism2_hostapd_param {
        u32 cmd;
        u8 sta_addr[ETH_ALEN];
@@ -2621,7 +2593,7 @@ prism2_ioctl_set_encryption(struct net_device *dev,
                                            &key);
                }
                /*
-                * If a valid key is set, encryption should be enabled 
+                * If a valid key is set, encryption should be enabled
                 * (user may turn it off later).
                 * This is also how "iwconfig ethX key on" works
                 */
@@ -2635,7 +2607,7 @@ prism2_ioctl_set_encryption(struct net_device *dev,
                            mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
                                            &index);
                } else {
-                       if (!param->u.crypt.flags & IW_ENCODE_MODE) {
+                       if (!(param->u.crypt.flags & IW_ENCODE_MODE)) {
                                /* we cannot do anything. Complain. */
                                return -EINVAL;
                        }
@@ -2643,7 +2615,7 @@ prism2_ioctl_set_encryption(struct net_device *dev,
        }
        /* now read the flags */
        if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
-               /* Encoding disabled, 
+               /* Encoding disabled,
                 * authen = DOT11_AUTH_OS;
                 * invoke = 0;
                 * exunencrypt = 0; */
@@ -2685,11 +2657,10 @@ prism2_ioctl_set_generic_element(struct net_device *ndev,
                return -EINVAL;
 
        alen = sizeof(*attach) + len;
-       attach = kmalloc(alen, GFP_KERNEL);
+       attach = kzalloc(alen, GFP_KERNEL);
        if (attach == NULL)
                return -ENOMEM;
 
-       memset(attach, 0, alen);
 #define WLAN_FC_TYPE_MGMT 0
 #define WLAN_FC_STYPE_ASSOC_REQ 0
 #define WLAN_FC_STYPE_REASSOC_REQ 2
@@ -2710,7 +2681,7 @@ prism2_ioctl_set_generic_element(struct net_device *ndev,
 
               ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
 
-              if (ret == 0) 
+              if (ret == 0)
                       printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
                                       ndev->name);
        }
@@ -2731,6 +2702,7 @@ prism2_ioctl_scan_req(struct net_device *ndev,
                      struct prism2_hostapd_param *param)
 {
        islpci_private *priv = netdev_priv(ndev);
+       struct iw_request_info info;
        int i, rvalue;
        struct obj_bsslist *bsslist;
        u32 noise = 0;
@@ -2754,9 +2726,12 @@ prism2_ioctl_scan_req(struct net_device *ndev,
        rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
        bsslist = r.ptr;
 
+       info.cmd = PRISM54_HOSTAPD;
+       info.flags = 0;
+
        /* ok now, scan the list and translate its info */
        for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
-               current_ev = prism54_translate_bss(ndev, current_ev,
+               current_ev = prism54_translate_bss(ndev, &info, current_ev,
                                                   extra + IW_SCAN_MAX_DATA,
                                                   &(bsslist->bsslist[i]),
                                                   noise);
@@ -2777,7 +2752,7 @@ prism54_hostapd(struct net_device *ndev, struct iw_point *p)
            p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
                return -EINVAL;
 
-       param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
+       param = kmalloc(p->length, GFP_KERNEL);
        if (param == NULL)
                return -ENOMEM;
 
@@ -2870,7 +2845,7 @@ prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
                        mlme = DOT11_MLME_AUTO;
                        printk("%s: Disabling WPA\n", ndev->name);
                        break;
-               case 2: 
+               case 2:
                case 1: /* WPA */
                        printk("%s: Enabling WPA\n", ndev->name);
                        break;
@@ -3007,7 +2982,8 @@ prism54_set_spy(struct net_device *ndev,
                union iwreq_data *uwrq, char *extra)
 {
        islpci_private *priv = netdev_priv(ndev);
-       u32 u, oid = OID_INL_CONFIG;
+       u32 u;
+       enum oid_num_t oid = OID_INL_CONFIG;
 
        down_write(&priv->mib_sem);
        mgt_get(priv, OID_INL_CONFIG, &u);
@@ -3050,7 +3026,7 @@ static const iw_handler prism54_handler[] = {
        (iw_handler) prism54_set_wap,   /* SIOCSIWAP */
        (iw_handler) prism54_get_wap,   /* SIOCGIWAP */
        (iw_handler) NULL,      /* -- hole -- */
-       (iw_handler) NULL,      /* SIOCGIWAPLIST depreciated */
+       (iw_handler) NULL,      /* SIOCGIWAPLIST deprecated */
        (iw_handler) prism54_set_scan,  /* SIOCSIWSCAN */
        (iw_handler) prism54_get_scan,  /* SIOCGIWSCAN */
        (iw_handler) prism54_set_essid, /* SIOCSIWESSID */
@@ -3245,10 +3221,9 @@ static const iw_handler prism54_private_handler[] = {
 };
 
 const struct iw_handler_def prism54_handler_def = {
-       .num_standard = sizeof (prism54_handler) / sizeof (iw_handler),
-       .num_private = sizeof (prism54_private_handler) / sizeof (iw_handler),
-       .num_private_args =
-           sizeof (prism54_private_args) / sizeof (struct iw_priv_args),
+       .num_standard = ARRAY_SIZE(prism54_handler),
+       .num_private = ARRAY_SIZE(prism54_private_handler),
+       .num_private_args = ARRAY_SIZE(prism54_private_args),
        .standard = (iw_handler *) prism54_handler,
        .private = (iw_handler *) prism54_private_handler,
        .private_args = (struct iw_priv_args *) prism54_private_args,