Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-drm-fsl-dcu.git] / drivers / net / wireless / prism54 / isl_ioctl.c
index 0c30fe7e8f7fed8289036584a015f7293315da72..a87eb51886c89e3d5122a20ace2506897bbbbd23 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>
@@ -46,17 +45,21 @@ static size_t prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie
 static int prism54_set_wpa(struct net_device *, struct iw_request_info *,
                                __u32 *, char *);
 
+/* In 500 kbps */
+static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
+                                               12, 18, 24, 36,
+                                               48, 72, 96, 108 };
 
 /**
  * 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)
@@ -114,7 +117,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
@@ -130,7 +133,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;
@@ -154,8 +157,9 @@ 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;
@@ -224,7 +228,7 @@ prism54_get_wireless_stats(struct net_device *ndev)
        } 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)) {
@@ -644,6 +648,32 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
                current_ev = iwe_stream_add_point(current_ev, end_buf,
                                &iwe, wpa_ie);
        }
+       /* Do the bitrates */
+       {
+               char *  current_val = current_ev + IW_EV_LCP_LEN;
+               int i;
+               int mask;
+
+               iwe.cmd = SIOCGIWRATE;
+               /* Those two flags are ignored... */
+               iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+               /* Parse the bitmask */
+               mask = 0x1;
+               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);
+                       }
+                       mask <<= 1;
+               }
+               /* Check if we added any event */
+               if ((current_val - current_ev) > IW_EV_LCP_LEN)
+                       current_ev = current_val;
+       }
+
        return current_ev;
 }
 
@@ -675,7 +705,7 @@ 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;
 
@@ -712,9 +742,9 @@ prism54_set_essid(struct net_device *ndev, struct iw_request_info *info,
 
        /* Check if we were asked for `any' */
        if (dwrq->flags && dwrq->length) {
-               if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1))
+               if (dwrq->length > 32)
                        return -E2BIG;
-               essid.length = dwrq->length - 1;
+               essid.length = dwrq->length;
                memcpy(essid.octets, extra, dwrq->length);
        } else
                essid.length = 0;
@@ -755,7 +785,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
@@ -784,7 +814,7 @@ prism54_get_nick(struct net_device *ndev, struct iw_request_info *info,
        dwrq->length = 0;
 
        down_read(&priv->mib_sem);
-       dwrq->length = strlen(priv->nickname) + 1;
+       dwrq->length = strlen(priv->nickname);
        memcpy(extra, priv->nickname, dwrq->length);
        up_read(&priv->mib_sem);
 
@@ -962,9 +992,9 @@ prism54_set_retry(struct net_device *ndev, struct iw_request_info *info,
                return -EINVAL;
 
        if (vwrq->flags & IW_RETRY_LIMIT) {
-               if (vwrq->flags & IW_RETRY_MIN)
+               if (vwrq->flags & IW_RETRY_SHORT)
                        slimit = vwrq->value;
-               else if (vwrq->flags & IW_RETRY_MAX)
+               else if (vwrq->flags & IW_RETRY_LONG)
                        llimit = vwrq->value;
                else {
                        /* we are asked to set both */
@@ -1005,18 +1035,18 @@ prism54_get_retry(struct net_device *ndev, struct iw_request_info *info,
                    mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r);
                vwrq->value = r.u * 1024;
                vwrq->flags = IW_RETRY_LIFETIME;
-       } else if ((vwrq->flags & IW_RETRY_MAX)) {
+       } else if ((vwrq->flags & IW_RETRY_LONG)) {
                /* we are asked for the long retry limit */
                rvalue |=
                    mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r);
                vwrq->value = r.u;
-               vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+               vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
        } else {
                /* default. get the  short retry limit */
                rvalue |=
                    mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r);
                vwrq->value = r.u;
-               vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
+               vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
        }
 
        return rvalue;
@@ -1074,7 +1104,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
                 */
@@ -1096,7 +1126,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; */
@@ -1184,7 +1214,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;
 
@@ -2324,17 +2354,17 @@ 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", 
+               printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
                                mlmeex->address[0],
                                mlmeex->address[1],
                                mlmeex->address[2],
@@ -2368,10 +2398,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)
@@ -2387,7 +2417,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
 
                if (!wpa_ie_len) {
                        printk(KERN_DEBUG "No WPA IE found from "
-                                       "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 
+                                       "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
                                mlmeex->address[0],
                                mlmeex->address[1],
                                mlmeex->address[2],
@@ -2405,14 +2435,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;
 
@@ -2431,7 +2461,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
 
                if (!wpa_ie_len) {
                        printk(KERN_DEBUG "No WPA IE found from "
-                                       "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 
+                                       "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
                                mlmeex->address[0],
                                mlmeex->address[1],
                                mlmeex->address[2],
@@ -2443,13 +2473,13 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                        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:
@@ -2464,9 +2494,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);
 
@@ -2515,10 +2546,10 @@ enum {
 #define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
 ((int) (&((struct prism2_hostapd_param *) 0)->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];
@@ -2591,7 +2622,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
                 */
@@ -2613,7 +2644,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; */
@@ -2680,7 +2711,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);
        }
@@ -2840,7 +2871,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;